summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2021-01-08 00:32:37 +0000
committerGitLab Bot <gitlab-bot@gitlab.com>2021-01-08 00:32:37 +0000
commit469a50879c1085ec77c95d650b7f135fee2c9e13 (patch)
tree0d639a63294b5abdb4e4a7bf1ed5a497d5e6869f
parentaa5ca44f172f02f04cca448b1f9c17d6d933de40 (diff)
downloadgitlab-ce-469a50879c1085ec77c95d650b7f135fee2c9e13.tar.gz
Add latest changes from gitlab-org/gitlab@13-7-stable-ee
-rw-r--r--app/assets/javascripts/jobs/store/actions.js24
-rw-r--r--app/assets/javascripts/jobs/store/mutations.js1
-rw-r--r--app/assets/javascripts/registry/explorer/components/details_page/tags_list_row.vue4
-rw-r--r--app/controllers/projects/jobs_controller.rb30
-rw-r--r--app/graphql/types/container_repository_tag_type.rb10
-rw-r--r--app/models/clusters/applications/helm.rb2
-rw-r--r--app/models/environment.rb5
-rw-r--r--app/policies/project_policy.rb6
-rw-r--r--app/services/environments/canary_ingress/update_service.rb1
-rw-r--r--changelogs/unreleased/13-7-stable-ee-patch_10io-fix-graphql-container-repository-tag-size-type.yml5
-rw-r--r--changelogs/unreleased/289925-subscription-expiration-banner-not-dismissable.yml5
-rw-r--r--changelogs/unreleased/293845-allow-nullable-digest.yml5
-rw-r--r--changelogs/unreleased/294221-gitlab-pages-deployments-over-the-max-int-size-in-bytes-fail-to-up.yml5
-rw-r--r--changelogs/unreleased/296563-follow-up-from-fix-project-access-token-regression.yml5
-rw-r--r--changelogs/unreleased/fix-canary-update-service-to-invalidate-cache.yml5
-rw-r--r--changelogs/unreleased/update-helm-2-to-2-17-0.yml5
-rw-r--r--db/migrate/20201217111448_change_pages_deployment_size_to_bigint.rb17
-rw-r--r--db/post_migrate/20201217112249_change_pages_deployment_size_to_bigint_cleanup.rb17
-rw-r--r--db/schema_migrations/202012171114481
-rw-r--r--db/schema_migrations/202012171122491
-rw-r--r--db/structure.sql3
-rw-r--r--doc/api/graphql/reference/gitlab_schema.graphql16
-rw-r--r--doc/api/graphql/reference/gitlab_schema.json60
-rw-r--r--doc/api/graphql/reference/index.md10
-rw-r--r--doc/subscriptions/self_managed/index.md2
-rw-r--r--doc/user/admin_area/settings/sign_up_restrictions.md29
-rw-r--r--lib/gitlab/auth.rb6
-rw-r--r--lib/gitlab/database/migration_helpers.rb10
-rw-r--r--lib/gitlab/kubernetes/helm.rb1
-rw-r--r--lib/gitlab/kubernetes/helm/v2/base_command.rb2
-rw-r--r--locale/gitlab.pot6
-rw-r--r--spec/controllers/projects/jobs_controller_spec.rb24
-rw-r--r--spec/features/projects/container_registry_spec.rb16
-rw-r--r--spec/features/projects/jobs_spec.rb4
-rw-r--r--spec/features/security/project/internal_access_spec.rb2
-rw-r--r--spec/features/security/project/private_access_spec.rb2
-rw-r--r--spec/features/security/project/public_access_spec.rb2
-rw-r--r--spec/fixtures/api/schemas/graphql/container_repository_details.json4
-rw-r--r--spec/frontend/jobs/store/actions_spec.js66
-rw-r--r--spec/frontend/jobs/store/mutations_spec.js1
-rw-r--r--spec/frontend/registry/explorer/components/details_page/tags_list_row_spec.js14
-rw-r--r--spec/frontend/registry/explorer/mock_data.js4
-rw-r--r--spec/lib/gitlab/database/migration_helpers_spec.rb11
-rw-r--r--spec/lib/gitlab/kubernetes/helm/pod_spec.rb2
-rw-r--r--spec/models/environment_spec.rb14
-rw-r--r--spec/policies/project_policy_spec.rb34
-rw-r--r--spec/requests/api/graphql/container_repository/container_repository_details_spec.rb50
-rw-r--r--spec/services/environments/canary_ingress/update_service_spec.rb6
-rw-r--r--spec/support/shared_contexts/lib/container_registry/tags_shared_context.rb9
49 files changed, 333 insertions, 231 deletions
diff --git a/app/assets/javascripts/jobs/store/actions.js b/app/assets/javascripts/jobs/store/actions.js
index cac9dc06284..e3ded725168 100644
--- a/app/assets/javascripts/jobs/store/actions.js
+++ b/app/assets/javascripts/jobs/store/actions.js
@@ -21,7 +21,8 @@ export const init = ({ dispatch }, { endpoint, logState, pagePath }) => {
logState,
pagePath,
});
- dispatch('fetchJob');
+
+ return Promise.all([dispatch('fetchJob'), dispatch('fetchTrace')]);
};
export const setJobEndpoint = ({ commit }, endpoint) => commit(types.SET_JOB_ENDPOINT, endpoint);
@@ -39,7 +40,6 @@ export const toggleSidebar = ({ dispatch, state }) => {
};
let eTagPoll;
-let isTraceReadyForRender;
export const clearEtagPoll = () => {
eTagPoll = null;
@@ -71,14 +71,7 @@ export const fetchJob = ({ state, dispatch }) => {
});
if (!Visibility.hidden()) {
- // eslint-disable-next-line promise/catch-or-return
- eTagPoll.makeRequest().then(() => {
- // if a job is canceled we still need to dispatch
- // fetchTrace to get the trace so we check for has_trace
- if (state.job.started || state.job.has_trace) {
- dispatch('fetchTrace');
- }
- });
+ eTagPoll.makeRequest();
} else {
axios
.get(state.jobEndpoint)
@@ -88,15 +81,9 @@ export const fetchJob = ({ state, dispatch }) => {
Visibility.change(() => {
if (!Visibility.hidden()) {
- // This check is needed to ensure the loading icon
- // is not shown for a finished job during a visibility change
- if (!isTraceReadyForRender && state.job.started) {
- dispatch('startPollingTrace');
- }
dispatch('restartPolling');
} else {
dispatch('stopPolling');
- dispatch('stopPollingTrace');
}
});
};
@@ -177,8 +164,6 @@ export const fetchTrace = ({ dispatch, state }) =>
params: { state: state.traceState },
})
.then(({ data }) => {
- isTraceReadyForRender = data.complete;
-
dispatch('toggleScrollisInBottom', isScrolledToBottom());
dispatch('receiveTraceSuccess', data);
@@ -258,7 +243,7 @@ export const receiveJobsForStageError = ({ commit }) => {
flash(__('An error occurred while fetching the jobs.'));
};
-export const triggerManualJob = ({ state, dispatch }, variables) => {
+export const triggerManualJob = ({ state }, variables) => {
const parsedVariables = variables.map(variable => {
const copyVar = { ...variable };
delete copyVar.id;
@@ -269,6 +254,5 @@ export const triggerManualJob = ({ state, dispatch }, variables) => {
.post(state.job.status.action.path, {
job_variables_attributes: parsedVariables,
})
- .then(() => dispatch('fetchTrace'))
.catch(() => flash(__('An error occurred while triggering the job.')));
};
diff --git a/app/assets/javascripts/jobs/store/mutations.js b/app/assets/javascripts/jobs/store/mutations.js
index dea53f715a7..924b811d0d6 100644
--- a/app/assets/javascripts/jobs/store/mutations.js
+++ b/app/assets/javascripts/jobs/store/mutations.js
@@ -49,7 +49,6 @@ export default {
[types.SET_TRACE_TIMEOUT](state, id) {
state.traceTimeout = id;
- state.isTraceComplete = false;
},
/**
diff --git a/app/assets/javascripts/registry/explorer/components/details_page/tags_list_row.vue b/app/assets/javascripts/registry/explorer/components/details_page/tags_list_row.vue
index 5aeafd318aa..3a5cccc7d08 100644
--- a/app/assets/javascripts/registry/explorer/components/details_page/tags_list_row.vue
+++ b/app/assets/javascripts/registry/explorer/components/details_page/tags_list_row.vue
@@ -63,7 +63,9 @@ export default {
},
computed: {
formattedSize() {
- return this.tag.totalSize ? numberToHumanSize(this.tag.totalSize) : NOT_AVAILABLE_SIZE;
+ return this.tag.totalSize
+ ? numberToHumanSize(Number(this.tag.totalSize))
+ : NOT_AVAILABLE_SIZE;
},
layers() {
return this.tag.layers ? n__('%d layer', '%d layers', this.tag.layers) : '';
diff --git a/app/controllers/projects/jobs_controller.rb b/app/controllers/projects/jobs_controller.rb
index 900ebc61856..d2703f5cc38 100644
--- a/app/controllers/projects/jobs_controller.rb
+++ b/app/controllers/projects/jobs_controller.rb
@@ -49,21 +49,25 @@ class Projects::JobsController < Projects::ApplicationController
# rubocop: enable CodeReuse/ActiveRecord
def trace
- @build.trace.read do |stream|
- respond_to do |format|
- format.json do
- @build.trace.being_watched!
-
- build_trace = Ci::BuildTrace.new(
- build: @build,
- stream: stream,
- state: params[:state])
-
- render json: BuildTraceSerializer
- .new(project: @project, current_user: @current_user)
- .represent(build_trace)
+ @build.trace.being_watched! if @build.running?
+
+ if @build.has_trace?
+ @build.trace.read do |stream|
+ respond_to do |format|
+ format.json do
+ build_trace = Ci::BuildTrace.new(
+ build: @build,
+ stream: stream,
+ state: params[:state])
+
+ render json: BuildTraceSerializer
+ .new(project: @project, current_user: @current_user)
+ .represent(build_trace)
+ end
end
end
+ else
+ head :no_content
end
end
diff --git a/app/graphql/types/container_repository_tag_type.rb b/app/graphql/types/container_repository_tag_type.rb
index 25e605b689d..6de16416395 100644
--- a/app/graphql/types/container_repository_tag_type.rb
+++ b/app/graphql/types/container_repository_tag_type.rb
@@ -11,11 +11,11 @@ module Types
field :name, GraphQL::STRING_TYPE, null: false, description: 'Name of the tag.'
field :path, GraphQL::STRING_TYPE, null: false, description: 'Path of the tag.'
field :location, GraphQL::STRING_TYPE, null: false, description: 'URL of the tag.'
- field :digest, GraphQL::STRING_TYPE, null: false, description: 'Digest of the tag.'
- field :revision, GraphQL::STRING_TYPE, null: false, description: 'Revision of the tag.'
- field :short_revision, GraphQL::STRING_TYPE, null: false, description: 'Short revision of the tag.'
- field :total_size, GraphQL::INT_TYPE, null: false, description: 'The size of the tag.'
- field :created_at, Types::TimeType, null: false, description: 'Timestamp when the tag was created.'
+ field :digest, GraphQL::STRING_TYPE, null: true, description: 'Digest of the tag.'
+ field :revision, GraphQL::STRING_TYPE, null: true, description: 'Revision of the tag.'
+ field :short_revision, GraphQL::STRING_TYPE, null: true, description: 'Short revision of the tag.'
+ field :total_size, GraphQL::Types::BigInt, null: true, description: 'The size of the tag.'
+ field :created_at, Types::TimeType, null: true, description: 'Timestamp when the tag was created.'
field :can_delete, GraphQL::BOOLEAN_TYPE, null: false, description: 'Can the current user delete this tag.'
def can_delete
diff --git a/app/models/clusters/applications/helm.rb b/app/models/clusters/applications/helm.rb
index 6f4b273a2c8..e89cb8be1e7 100644
--- a/app/models/clusters/applications/helm.rb
+++ b/app/models/clusters/applications/helm.rb
@@ -18,7 +18,7 @@ module Clusters
include ::Clusters::Concerns::ApplicationStatus
include ::Gitlab::Utils::StrongMemoize
- default_value_for :version, Gitlab::Kubernetes::Helm::HELM_VERSION
+ default_value_for :version, Gitlab::Kubernetes::Helm::V2::BaseCommand::HELM_VERSION
before_create :create_keys_and_certs
diff --git a/app/models/environment.rb b/app/models/environment.rb
index 31a95bb1b5d..4f7f688a040 100644
--- a/app/models/environment.rb
+++ b/app/models/environment.rb
@@ -405,6 +405,11 @@ class Environment < ApplicationRecord
deployment_platform.patch_ingress(deployment_namespace, ingress, data)
end
+ def clear_all_caches
+ expire_etag_cache
+ clear_reactive_cache!
+ end
+
private
def rollout_status_available?
diff --git a/app/policies/project_policy.rb b/app/policies/project_policy.rb
index 403fb34803e..3b8c59c6bf8 100644
--- a/app/policies/project_policy.rb
+++ b/app/policies/project_policy.rb
@@ -135,10 +135,6 @@ class ProjectPolicy < BasePolicy
::Feature.enabled?(:build_service_proxy, @subject)
end
- condition(:project_bot_is_member) do
- user.project_bot? & team_member?
- end
-
with_scope :subject
condition(:packages_disabled) { !@subject.packages_enabled }
@@ -619,8 +615,6 @@ class ProjectPolicy < BasePolicy
enable :admin_resource_access_tokens
end
- rule { project_bot_is_member & ~blocked }.enable :bot_log_in
-
private
def user_is_user?
diff --git a/app/services/environments/canary_ingress/update_service.rb b/app/services/environments/canary_ingress/update_service.rb
index 474c3de23d9..2b510280873 100644
--- a/app/services/environments/canary_ingress/update_service.rb
+++ b/app/services/environments/canary_ingress/update_service.rb
@@ -24,6 +24,7 @@ module Environments
end
if environment.patch_ingress(canary_ingress, patch_data)
+ environment.clear_all_caches
success
else
error(_('Failed to update the Canary Ingress.'), :bad_request)
diff --git a/changelogs/unreleased/13-7-stable-ee-patch_10io-fix-graphql-container-repository-tag-size-type.yml b/changelogs/unreleased/13-7-stable-ee-patch_10io-fix-graphql-container-repository-tag-size-type.yml
new file mode 100644
index 00000000000..5323ac46f9f
--- /dev/null
+++ b/changelogs/unreleased/13-7-stable-ee-patch_10io-fix-graphql-container-repository-tag-size-type.yml
@@ -0,0 +1,5 @@
+---
+title: Fix the graphQL type for container repository tags
+merge_request: 50419
+author:
+type: fixed
diff --git a/changelogs/unreleased/289925-subscription-expiration-banner-not-dismissable.yml b/changelogs/unreleased/289925-subscription-expiration-banner-not-dismissable.yml
new file mode 100644
index 00000000000..311784e05f8
--- /dev/null
+++ b/changelogs/unreleased/289925-subscription-expiration-banner-not-dismissable.yml
@@ -0,0 +1,5 @@
+---
+title: 'Fix(eetrialbanner): fix EE trial banner to allow dismiss'
+merge_request: 50436
+author:
+type: fixed
diff --git a/changelogs/unreleased/293845-allow-nullable-digest.yml b/changelogs/unreleased/293845-allow-nullable-digest.yml
new file mode 100644
index 00000000000..cc3d1198a1c
--- /dev/null
+++ b/changelogs/unreleased/293845-allow-nullable-digest.yml
@@ -0,0 +1,5 @@
+---
+title: Fix viewing container repositories with tags with corrupted manifest
+merge_request: 50362
+author:
+type: fixed
diff --git a/changelogs/unreleased/294221-gitlab-pages-deployments-over-the-max-int-size-in-bytes-fail-to-up.yml b/changelogs/unreleased/294221-gitlab-pages-deployments-over-the-max-int-size-in-bytes-fail-to-up.yml
new file mode 100644
index 00000000000..233d52f0df5
--- /dev/null
+++ b/changelogs/unreleased/294221-gitlab-pages-deployments-over-the-max-int-size-in-bytes-fail-to-up.yml
@@ -0,0 +1,5 @@
+---
+title: Change pages deployments size to bigint
+merge_request: 50262
+author:
+type: fixed
diff --git a/changelogs/unreleased/296563-follow-up-from-fix-project-access-token-regression.yml b/changelogs/unreleased/296563-follow-up-from-fix-project-access-token-regression.yml
new file mode 100644
index 00000000000..c280ccb21ec
--- /dev/null
+++ b/changelogs/unreleased/296563-follow-up-from-fix-project-access-token-regression.yml
@@ -0,0 +1,5 @@
+---
+title: Fix project access token regression
+merge_request: 50800
+author:
+type: fixed
diff --git a/changelogs/unreleased/fix-canary-update-service-to-invalidate-cache.yml b/changelogs/unreleased/fix-canary-update-service-to-invalidate-cache.yml
new file mode 100644
index 00000000000..aea2dec8268
--- /dev/null
+++ b/changelogs/unreleased/fix-canary-update-service-to-invalidate-cache.yml
@@ -0,0 +1,5 @@
+---
+title: Fix Canary Ingress weight is not reflected on UI immediately
+merge_request: 50246
+author:
+type: fixed
diff --git a/changelogs/unreleased/update-helm-2-to-2-17-0.yml b/changelogs/unreleased/update-helm-2-to-2-17-0.yml
new file mode 100644
index 00000000000..d6941878b48
--- /dev/null
+++ b/changelogs/unreleased/update-helm-2-to-2-17-0.yml
@@ -0,0 +1,5 @@
+---
+title: Update Helm 2 version to 2.17.0
+merge_request: 50547
+author:
+type: fixed
diff --git a/db/migrate/20201217111448_change_pages_deployment_size_to_bigint.rb b/db/migrate/20201217111448_change_pages_deployment_size_to_bigint.rb
new file mode 100644
index 00000000000..75420166b87
--- /dev/null
+++ b/db/migrate/20201217111448_change_pages_deployment_size_to_bigint.rb
@@ -0,0 +1,17 @@
+# frozen_string_literal: true
+
+class ChangePagesDeploymentSizeToBigint < ActiveRecord::Migration[6.0]
+ include Gitlab::Database::MigrationHelpers
+
+ DOWNTIME = false
+
+ disable_ddl_transaction!
+
+ def up
+ change_column_type_concurrently :pages_deployments, :size, :bigint
+ end
+
+ def down
+ undo_change_column_type_concurrently :pages_deployments, :size
+ end
+end
diff --git a/db/post_migrate/20201217112249_change_pages_deployment_size_to_bigint_cleanup.rb b/db/post_migrate/20201217112249_change_pages_deployment_size_to_bigint_cleanup.rb
new file mode 100644
index 00000000000..4ed29ba61f9
--- /dev/null
+++ b/db/post_migrate/20201217112249_change_pages_deployment_size_to_bigint_cleanup.rb
@@ -0,0 +1,17 @@
+# frozen_string_literal: true
+
+class ChangePagesDeploymentSizeToBigintCleanup < ActiveRecord::Migration[6.0]
+ include Gitlab::Database::MigrationHelpers
+
+ DOWNTIME = false
+
+ disable_ddl_transaction!
+
+ def up
+ cleanup_concurrent_column_type_change :pages_deployments, :size
+ end
+
+ def down
+ undo_cleanup_concurrent_column_type_change :pages_deployments, :size, :integer, limit: 4
+ end
+end
diff --git a/db/schema_migrations/20201217111448 b/db/schema_migrations/20201217111448
new file mode 100644
index 00000000000..02526b55a3d
--- /dev/null
+++ b/db/schema_migrations/20201217111448
@@ -0,0 +1 @@
+32330327aa8db01b5bc2c533af5387e77ad3dc0c34eacaac16a793df75634ce6 \ No newline at end of file
diff --git a/db/schema_migrations/20201217112249 b/db/schema_migrations/20201217112249
new file mode 100644
index 00000000000..b5b280bbf07
--- /dev/null
+++ b/db/schema_migrations/20201217112249
@@ -0,0 +1 @@
+938aa97919e5a15143a72f33bebb27e501d5ef7cc53cf4e7debe9dee398b7255 \ No newline at end of file
diff --git a/db/structure.sql b/db/structure.sql
index 6380f64c64c..9bf6799dc85 100644
--- a/db/structure.sql
+++ b/db/structure.sql
@@ -14809,10 +14809,11 @@ CREATE TABLE pages_deployments (
project_id bigint NOT NULL,
ci_build_id bigint,
file_store smallint NOT NULL,
- size integer NOT NULL,
file text NOT NULL,
file_count integer NOT NULL,
file_sha256 bytea NOT NULL,
+ size bigint,
+ CONSTRAINT check_5f9132a958 CHECK ((size IS NOT NULL)),
CONSTRAINT check_f0fe8032dd CHECK ((char_length(file) <= 255))
);
diff --git a/doc/api/graphql/reference/gitlab_schema.graphql b/doc/api/graphql/reference/gitlab_schema.graphql
index d7ad70c808e..8218d792fe8 100644
--- a/doc/api/graphql/reference/gitlab_schema.graphql
+++ b/doc/api/graphql/reference/gitlab_schema.graphql
@@ -1144,6 +1144,12 @@ type BaseService implements Service {
type: String
}
+"""
+Represents non-fractional signed whole numeric values. Since the value may
+exceed the size of a 32-bit integer, it's encoded as a string.
+"""
+scalar BigInt
+
type Blob implements Entry {
"""
Flat path of the entry
@@ -3788,12 +3794,12 @@ type ContainerRepositoryTag {
"""
Timestamp when the tag was created.
"""
- createdAt: Time!
+ createdAt: Time
"""
Digest of the tag.
"""
- digest: String!
+ digest: String
"""
URL of the tag.
@@ -3813,17 +3819,17 @@ type ContainerRepositoryTag {
"""
Revision of the tag.
"""
- revision: String!
+ revision: String
"""
Short revision of the tag.
"""
- shortRevision: String!
+ shortRevision: String
"""
The size of the tag.
"""
- totalSize: Int!
+ totalSize: BigInt
}
"""
diff --git a/doc/api/graphql/reference/gitlab_schema.json b/doc/api/graphql/reference/gitlab_schema.json
index 4adb92d351e..3494e0c8300 100644
--- a/doc/api/graphql/reference/gitlab_schema.json
+++ b/doc/api/graphql/reference/gitlab_schema.json
@@ -3000,6 +3000,16 @@
"possibleTypes": null
},
{
+ "kind": "SCALAR",
+ "name": "BigInt",
+ "description": "Represents non-fractional signed whole numeric values. Since the value may exceed the size of a 32-bit integer, it's encoded as a string.",
+ "fields": null,
+ "inputFields": null,
+ "interfaces": null,
+ "enumValues": null,
+ "possibleTypes": null
+ },
+ {
"kind": "OBJECT",
"name": "Blob",
"description": null,
@@ -10347,13 +10357,9 @@
],
"type": {
- "kind": "NON_NULL",
- "name": null,
- "ofType": {
- "kind": "SCALAR",
- "name": "Time",
- "ofType": null
- }
+ "kind": "SCALAR",
+ "name": "Time",
+ "ofType": null
},
"isDeprecated": false,
"deprecationReason": null
@@ -10365,13 +10371,9 @@
],
"type": {
- "kind": "NON_NULL",
- "name": null,
- "ofType": {
- "kind": "SCALAR",
- "name": "String",
- "ofType": null
- }
+ "kind": "SCALAR",
+ "name": "String",
+ "ofType": null
},
"isDeprecated": false,
"deprecationReason": null
@@ -10437,13 +10439,9 @@
],
"type": {
- "kind": "NON_NULL",
- "name": null,
- "ofType": {
- "kind": "SCALAR",
- "name": "String",
- "ofType": null
- }
+ "kind": "SCALAR",
+ "name": "String",
+ "ofType": null
},
"isDeprecated": false,
"deprecationReason": null
@@ -10455,13 +10453,9 @@
],
"type": {
- "kind": "NON_NULL",
- "name": null,
- "ofType": {
- "kind": "SCALAR",
- "name": "String",
- "ofType": null
- }
+ "kind": "SCALAR",
+ "name": "String",
+ "ofType": null
},
"isDeprecated": false,
"deprecationReason": null
@@ -10473,13 +10467,9 @@
],
"type": {
- "kind": "NON_NULL",
- "name": null,
- "ofType": {
- "kind": "SCALAR",
- "name": "Int",
- "ofType": null
- }
+ "kind": "SCALAR",
+ "name": "BigInt",
+ "ofType": null
},
"isDeprecated": false,
"deprecationReason": null
diff --git a/doc/api/graphql/reference/index.md b/doc/api/graphql/reference/index.md
index 2842f7893bf..4cb79d71ab5 100644
--- a/doc/api/graphql/reference/index.md
+++ b/doc/api/graphql/reference/index.md
@@ -632,14 +632,14 @@ A tag from a container repository.
| Field | Type | Description |
| ----- | ---- | ----------- |
| `canDelete` | Boolean! | Can the current user delete this tag. |
-| `createdAt` | Time! | Timestamp when the tag was created. |
-| `digest` | String! | Digest of the tag. |
+| `createdAt` | Time | Timestamp when the tag was created. |
+| `digest` | String | Digest of the tag. |
| `location` | String! | URL of the tag. |
| `name` | String! | Name of the tag. |
| `path` | String! | Path of the tag. |
-| `revision` | String! | Revision of the tag. |
-| `shortRevision` | String! | Short revision of the tag. |
-| `totalSize` | Int! | The size of the tag. |
+| `revision` | String | Revision of the tag. |
+| `shortRevision` | String | Short revision of the tag. |
+| `totalSize` | BigInt | The size of the tag. |
### CreateAlertIssuePayload
diff --git a/doc/subscriptions/self_managed/index.md b/doc/subscriptions/self_managed/index.md
index a4affff92e4..301d78b708a 100644
--- a/doc/subscriptions/self_managed/index.md
+++ b/doc/subscriptions/self_managed/index.md
@@ -59,7 +59,7 @@ GitLab has several features which can help you manage the number of users:
- Enable the [**Require administrator approval for new sign ups**](../../user/admin_area/settings/sign_up_restrictions.md#require-administrator-approval-for-new-sign-ups)
option.
- Enable the [User cap](../../user/admin_area/settings/sign_up_restrictions.md#user-cap)
- option. **Available in GitLab 13.6 and later**.
+ option. **Available in GitLab 13.7 and later**.
- [Disable new sign-ups](../../user/admin_area/settings/sign_up_restrictions.md), and instead manage new
users manually.
- View a breakdown of users by role in the [Users statistics](../../user/admin_area/index.md#users-statistics) page.
diff --git a/doc/user/admin_area/settings/sign_up_restrictions.md b/doc/user/admin_area/settings/sign_up_restrictions.md
index 213c8c4116a..ddd3dbda9cc 100644
--- a/doc/user/admin_area/settings/sign_up_restrictions.md
+++ b/doc/user/admin_area/settings/sign_up_restrictions.md
@@ -37,6 +37,9 @@ To require administrator approval for new sign ups:
1. Go to **Admin Area > Settings > General** and expand **Sign-up restrictions**.
1. Select the **Require admin approval for new sign-ups** checkbox, then select **Save changes**.
+In [GitLab 13.7 and later](https://gitlab.com/gitlab-org/gitlab/-/issues/273258), if an administrator disables this setting, the users in pending approval state are
+automatically approved in a background job.
+
## Require email confirmation
You can send confirmation emails during sign up and require that users confirm
@@ -49,15 +52,37 @@ To enforce confirmation of the email address used for new sign ups:
## User cap **(CORE ONLY)**
-> [Introduced](https://gitlab.com/groups/gitlab-org/-/epics/4315) in GitLab 13.6.
+> - [Introduced](https://gitlab.com/groups/gitlab-org/-/epics/4315) in GitLab 13.7.
+> - It's [deployed behind a feature flag](../../feature_flags.md), enabled by default.
+> - It's recommended for production use.
+> - For GitLab self-managed instances, GitLab administrators can opt to [disable it](#enable-or-disable-user-cap). **(CORE ONLY)**
When the number of billable users reaches the user cap, any user who is added or requests access must be
[approved](../approving_users.md#approving-a-user) by an administrator before they can start using
their account.
-If an administrator increases or removes the user cap, the users in pending approval state will be
+If an administrator increases or removes the user cap, the users in pending approval state are
automatically approved in a background job.
+### Enable or disable User cap **(CORE ONLY)**
+
+User cap is under development but ready for production use.
+It is deployed behind a feature flag that is **enabled by default**.
+[GitLab administrators with access to the GitLab Rails console](../../../administration/feature_flags.md)
+can opt to disable it.
+
+To disable it:
+
+```ruby
+Feature.disable(:admin_new_user_signups_cap)
+```
+
+To enable it:
+
+```ruby
+Feature.enable(:admin_new_user_signups_cap)
+```
+
## Soft email confirmation
> - [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/47003) in GitLab 12.2.
diff --git a/lib/gitlab/auth.rb b/lib/gitlab/auth.rb
index 1aabb05f19e..1f5cce249d8 100644
--- a/lib/gitlab/auth.rb
+++ b/lib/gitlab/auth.rb
@@ -198,7 +198,9 @@ module Gitlab
return unless valid_scoped_token?(token, all_available_scopes)
- if token.user.can?(:log_in) || token.user.can?(:bot_log_in, project)
+ return if project && token.user.project_bot? && !project.bots.include?(token.user)
+
+ if token.user.can?(:log_in) || token.user.project_bot?
Gitlab::Auth::Result.new(token.user, nil, :personal_access_token, abilities_for_scopes(token.scopes))
end
end
@@ -283,7 +285,7 @@ module Gitlab
return unless build.project.builds_enabled?
if build.user
- return unless build.user.can?(:log_in) || build.user.can?(:bot_log_in, build.project)
+ return unless build.user.can?(:log_in) || (build.user.project_bot? && build.project.bots&.include?(build.user))
# If user is assigned to build, use restricted credentials of user
Gitlab::Auth::Result.new(build.user, build.project, :build, build_authentication_abilities)
diff --git a/lib/gitlab/database/migration_helpers.rb b/lib/gitlab/database/migration_helpers.rb
index 66b6ce1ec55..164fce5a5a3 100644
--- a/lib/gitlab/database/migration_helpers.rb
+++ b/lib/gitlab/database/migration_helpers.rb
@@ -578,7 +578,7 @@ module Gitlab
# type_cast_function - Required if the conversion back to the original type is not automatic
# batch_column_name - option for tables without a primary key, in this case
# another unique integer column can be used. Example: :user_id
- def undo_cleanup_concurrent_column_type_change(table, column, old_type, type_cast_function: nil, batch_column_name: :id)
+ def undo_cleanup_concurrent_column_type_change(table, column, old_type, type_cast_function: nil, batch_column_name: :id, limit: nil)
temp_column = "#{column}_for_type_change"
# Using a descriptive name that includes orinal column's name risks
@@ -604,7 +604,8 @@ module Gitlab
temp_undo_cleanup_column,
type: old_type,
batch_column_name: batch_column_name,
- type_cast_function: type_cast_function
+ type_cast_function: type_cast_function,
+ limit: limit
)
transaction do
@@ -1489,12 +1490,13 @@ into similar problems in the future (e.g. when new tables are created).
"ON DELETE #{on_delete.upcase}"
end
- def create_column_from(table, old, new, type: nil, batch_column_name: :id, type_cast_function: nil)
+ def create_column_from(table, old, new, type: nil, batch_column_name: :id, type_cast_function: nil, limit: nil)
old_col = column_for(table, old)
new_type = type || old_col.type
+ new_limit = limit || old_col.limit
add_column(table, new, new_type,
- limit: old_col.limit,
+ limit: new_limit,
precision: old_col.precision,
scale: old_col.scale)
diff --git a/lib/gitlab/kubernetes/helm.rb b/lib/gitlab/kubernetes/helm.rb
index 39bd8d5a01f..f67dfd41e22 100644
--- a/lib/gitlab/kubernetes/helm.rb
+++ b/lib/gitlab/kubernetes/helm.rb
@@ -3,7 +3,6 @@
module Gitlab
module Kubernetes
module Helm
- HELM_VERSION = '2.16.9'
KUBECTL_VERSION = '1.13.12'
NAMESPACE = 'gitlab-managed-apps'
NAMESPACE_LABELS = { 'app.gitlab.com/managed_by' => :gitlab }.freeze
diff --git a/lib/gitlab/kubernetes/helm/v2/base_command.rb b/lib/gitlab/kubernetes/helm/v2/base_command.rb
index 931c2248310..26c77b2149e 100644
--- a/lib/gitlab/kubernetes/helm/v2/base_command.rb
+++ b/lib/gitlab/kubernetes/helm/v2/base_command.rb
@@ -7,7 +7,7 @@ module Gitlab
class BaseCommand
attr_reader :name, :files
- HELM_VERSION = '2.16.9'
+ HELM_VERSION = '2.17.0'
def initialize(rbac:, name:, files:)
@rbac = rbac
diff --git a/locale/gitlab.pot b/locale/gitlab.pot
index f641d86bffc..7d1a5301247 100644
--- a/locale/gitlab.pot
+++ b/locale/gitlab.pot
@@ -23276,6 +23276,9 @@ msgstr ""
msgid "Rename/Move"
msgstr ""
+msgid "Renew subscription"
+msgstr ""
+
msgid "Reopen"
msgstr ""
@@ -27443,6 +27446,9 @@ msgstr ""
msgid "Thanks for your purchase!"
msgstr ""
+msgid "That is ok, I do not want to renew"
+msgstr ""
+
msgid "That's it, well done!"
msgstr ""
diff --git a/spec/controllers/projects/jobs_controller_spec.rb b/spec/controllers/projects/jobs_controller_spec.rb
index 3309b15b276..eb5e62f3d44 100644
--- a/spec/controllers/projects/jobs_controller_spec.rb
+++ b/spec/controllers/projects/jobs_controller_spec.rb
@@ -700,10 +700,22 @@ RSpec.describe Projects::JobsController, :clean_gitlab_redis_shared_state do
expect(json_response['lines']).to eq [{ 'content' => [{ 'text' => 'BUILD TRACE' }], 'offset' => 0 }]
end
- it 'sets being-watched flag for the job' do
- expect(response).to have_gitlab_http_status(:ok)
+ context 'when job is running' do
+ let(:job) { create(:ci_build, :trace_live, :running, pipeline: pipeline) }
+
+ it 'sets being-watched flag for the job' do
+ expect(response).to have_gitlab_http_status(:ok)
+
+ expect(job.trace.being_watched?).to be(true)
+ end
+ end
- expect(job.trace.being_watched?).to be(true)
+ context 'when job is not running' do
+ it 'does not set being-watched flag for the job' do
+ expect(response).to have_gitlab_http_status(:ok)
+
+ expect(job.trace.being_watched?).to be(false)
+ end
end
end
@@ -711,11 +723,7 @@ RSpec.describe Projects::JobsController, :clean_gitlab_redis_shared_state do
let(:job) { create(:ci_build, pipeline: pipeline) }
it 'returns no traces' do
- expect(response).to have_gitlab_http_status(:ok)
- expect(response).to match_response_schema('job/build_trace')
- expect(json_response['id']).to eq job.id
- expect(json_response['status']).to eq job.status
- expect(json_response['lines']).to be_nil
+ expect(response).to have_gitlab_http_status(:no_content)
end
end
diff --git a/spec/features/projects/container_registry_spec.rb b/spec/features/projects/container_registry_spec.rb
index ee453aa7bbf..d0ad6668c07 100644
--- a/spec/features/projects/container_registry_spec.rb
+++ b/spec/features/projects/container_registry_spec.rb
@@ -3,6 +3,8 @@
require 'spec_helper'
RSpec.describe 'Container Registry', :js do
+ include_context 'container registry tags'
+
let(:user) { create(:user) }
let(:project) { create(:project) }
@@ -99,6 +101,20 @@ RSpec.describe 'Container Registry', :js do
expect(page).to have_content '20'
end
end
+
+ describe 'with a tag missing digest' do
+ before do
+ stub_container_registry_tags(repository: %r{my/image}, tags: %w[latest stable])
+ stub_next_container_registry_tags_call(:digest, nil)
+ visit_container_registry_details 'my/image'
+ end
+
+ it 'renders the tags list correctly' do
+ expect(page).to have_content('latest')
+ expect(page).to have_content('stable')
+ expect(page).to have_content('Digest: N/A')
+ end
+ end
end
describe 'image repo details when image has no name' do
diff --git a/spec/features/projects/jobs_spec.rb b/spec/features/projects/jobs_spec.rb
index 4edda9febbe..1557a8a2d72 100644
--- a/spec/features/projects/jobs_spec.rb
+++ b/spec/features/projects/jobs_spec.rb
@@ -1212,9 +1212,11 @@ RSpec.describe 'Jobs', :clean_gitlab_redis_shared_state do
end
describe "GET /:project/jobs/:id/trace.json" do
+ let(:build) { create(:ci_build, :trace_artifact, pipeline: pipeline) }
+
context "Job from project" do
before do
- visit trace_project_job_path(project, job, format: :json)
+ visit trace_project_job_path(project, build, format: :json)
end
it { expect(page.status_code).to eq(200) }
diff --git a/spec/features/security/project/internal_access_spec.rb b/spec/features/security/project/internal_access_spec.rb
index cb9f9a6e680..2440b738db3 100644
--- a/spec/features/security/project/internal_access_spec.rb
+++ b/spec/features/security/project/internal_access_spec.rb
@@ -430,7 +430,7 @@ RSpec.describe "Internal Project Access" do
describe 'GET /:project_path/builds/:id/trace' do
let(:pipeline) { create(:ci_pipeline, project: project) }
- let(:build) { create(:ci_build, pipeline: pipeline) }
+ let(:build) { create(:ci_build, :trace_artifact, pipeline: pipeline) }
subject { trace_project_job_path(project, build.id) }
diff --git a/spec/features/security/project/private_access_spec.rb b/spec/features/security/project/private_access_spec.rb
index dda218c5de5..9d3109b92e6 100644
--- a/spec/features/security/project/private_access_spec.rb
+++ b/spec/features/security/project/private_access_spec.rb
@@ -423,7 +423,7 @@ RSpec.describe "Private Project Access" do
describe 'GET /:project_path/builds/:id/trace' do
let(:pipeline) { create(:ci_pipeline, project: project) }
- let(:build) { create(:ci_build, pipeline: pipeline) }
+ let(:build) { create(:ci_build, :trace_artifact, pipeline: pipeline) }
subject { trace_project_job_path(project, build.id) }
diff --git a/spec/features/security/project/public_access_spec.rb b/spec/features/security/project/public_access_spec.rb
index f2dbab72a48..28a1f1cda7f 100644
--- a/spec/features/security/project/public_access_spec.rb
+++ b/spec/features/security/project/public_access_spec.rb
@@ -238,7 +238,7 @@ RSpec.describe "Public Project Access" do
describe 'GET /:project_path/builds/:id/trace' do
let(:pipeline) { create(:ci_pipeline, project: project) }
- let(:build) { create(:ci_build, pipeline: pipeline) }
+ let(:build) { create(:ci_build, :trace_artifact, pipeline: pipeline) }
subject { trace_project_job_path(project, build.id) }
diff --git a/spec/fixtures/api/schemas/graphql/container_repository_details.json b/spec/fixtures/api/schemas/graphql/container_repository_details.json
index 3db91796fc6..3156b6d58d5 100644
--- a/spec/fixtures/api/schemas/graphql/container_repository_details.json
+++ b/spec/fixtures/api/schemas/graphql/container_repository_details.json
@@ -11,7 +11,7 @@
"type": "array",
"items": {
"type": "object",
- "required": ["name", "path", "location", "digest", "revision", "shortRevision", "totalSize", "createdAt", "canDelete"],
+ "required": ["name", "path", "location", "canDelete"],
"properties": {
"name": {
"type": "string"
@@ -32,7 +32,7 @@
"type": "string"
},
"totalSize": {
- "type": "integer"
+ "type": "string"
},
"createdAt": {
"type": "string"
diff --git a/spec/frontend/jobs/store/actions_spec.js b/spec/frontend/jobs/store/actions_spec.js
index 26547d12ac7..91bd5521f70 100644
--- a/spec/frontend/jobs/store/actions_spec.js
+++ b/spec/frontend/jobs/store/actions_spec.js
@@ -27,7 +27,6 @@ import {
hideSidebar,
showSidebar,
toggleSidebar,
- triggerManualJob,
} from '~/jobs/store/actions';
import state from '~/jobs/store/state';
import * as types from '~/jobs/store/mutation_types';
@@ -159,32 +158,6 @@ describe('Job State actions', () => {
);
});
});
-
- it('fetchTrace is called only if the job has started or has a trace', done => {
- mock.onGet(`${TEST_HOST}/endpoint.json`).replyOnce(200, { id: 121212, name: 'karma' });
-
- mockedState.job.started = true;
-
- testAction(
- fetchJob,
- null,
- mockedState,
- [],
- [
- {
- type: 'requestJob',
- },
- {
- payload: { id: 121212, name: 'karma' },
- type: 'receiveJobSuccess',
- },
- {
- type: 'fetchTrace',
- },
- ],
- done,
- );
- });
});
describe('receiveJobSuccess', () => {
@@ -536,43 +509,4 @@ describe('Job State actions', () => {
);
});
});
-
- describe('triggerManualJob', () => {
- let mock;
-
- beforeEach(() => {
- mock = new MockAdapter(axios);
- });
-
- afterEach(() => {
- mock.restore();
- });
-
- it('should dispatch fetchTrace', done => {
- const playManualJobEndpoint = `${TEST_HOST}/manual-job/jobs/1000/play`;
-
- mock.onPost(playManualJobEndpoint).reply(200);
-
- mockedState.job = {
- status: {
- action: {
- path: playManualJobEndpoint,
- },
- },
- };
-
- testAction(
- triggerManualJob,
- [{ id: '1', key: 'test_var', secret_value: 'test_value' }],
- mockedState,
- [],
- [
- {
- type: 'fetchTrace',
- },
- ],
- done,
- );
- });
- });
});
diff --git a/spec/frontend/jobs/store/mutations_spec.js b/spec/frontend/jobs/store/mutations_spec.js
index a8146ba93eb..608abc8f7c4 100644
--- a/spec/frontend/jobs/store/mutations_spec.js
+++ b/spec/frontend/jobs/store/mutations_spec.js
@@ -153,7 +153,6 @@ describe('Jobs Store Mutations', () => {
mutations[types.SET_TRACE_TIMEOUT](stateCopy, id);
expect(stateCopy.traceTimeout).toEqual(id);
- expect(stateCopy.isTraceComplete).toBe(false);
});
});
diff --git a/spec/frontend/registry/explorer/components/details_page/tags_list_row_spec.js b/spec/frontend/registry/explorer/components/details_page/tags_list_row_spec.js
index e1b75636735..94944643e8b 100644
--- a/spec/frontend/registry/explorer/components/details_page/tags_list_row_spec.js
+++ b/spec/frontend/registry/explorer/components/details_page/tags_list_row_spec.js
@@ -172,25 +172,31 @@ describe('tags list row', () => {
});
it('contains the totalSize and layers', () => {
- mountComponent({ ...defaultProps, tag: { ...tag, totalSize: 1024, layers: 10 } });
+ mountComponent({ ...defaultProps, tag: { ...tag, totalSize: '1024', layers: 10 } });
expect(findSize().text()).toMatchInterpolatedText('1.00 KiB · 10 layers');
});
+ it('when totalSize is giantic', () => {
+ mountComponent({ ...defaultProps, tag: { ...tag, totalSize: '1099511627776', layers: 2 } });
+
+ expect(findSize().text()).toMatchInterpolatedText('1024.00 GiB · 2 layers');
+ });
+
it('when totalSize is missing', () => {
- mountComponent({ ...defaultProps, tag: { ...tag, totalSize: 0, layers: 10 } });
+ mountComponent({ ...defaultProps, tag: { ...tag, totalSize: '0', layers: 10 } });
expect(findSize().text()).toMatchInterpolatedText(`${NOT_AVAILABLE_SIZE} · 10 layers`);
});
it('when layers are missing', () => {
- mountComponent({ ...defaultProps, tag: { ...tag, totalSize: 1024 } });
+ mountComponent({ ...defaultProps, tag: { ...tag, totalSize: '1024' } });
expect(findSize().text()).toMatchInterpolatedText('1.00 KiB');
});
it('when there is 1 layer', () => {
- mountComponent({ ...defaultProps, tag: { ...tag, totalSize: 0, layers: 1 } });
+ mountComponent({ ...defaultProps, tag: { ...tag, totalSize: '0', layers: 1 } });
expect(findSize().text()).toMatchInterpolatedText(`${NOT_AVAILABLE_SIZE} · 1 layer`);
});
diff --git a/spec/frontend/registry/explorer/mock_data.js b/spec/frontend/registry/explorer/mock_data.js
index 992d880581a..72a9bff8a47 100644
--- a/spec/frontend/registry/explorer/mock_data.js
+++ b/spec/frontend/registry/explorer/mock_data.js
@@ -140,7 +140,7 @@ export const tagsMock = [
revision: 'c2613843ab33aabf847965442b13a8b55a56ae28837ce182627c0716eb08c02b',
shortRevision: 'c2613843a',
createdAt: '2020-11-03T13:29:38+00:00',
- totalSize: 105,
+ totalSize: '1099511627776',
canDelete: true,
__typename: 'ContainerRepositoryTag',
},
@@ -152,7 +152,7 @@ export const tagsMock = [
revision: 'df44e7228f0f255c73e35b6f0699624a615f42746e3e8e2e4b3804a6d6fc3292',
shortRevision: 'df44e7228',
createdAt: '2020-11-03T13:29:32+00:00',
- totalSize: 104,
+ totalSize: '536870912000',
canDelete: true,
__typename: 'ContainerRepositoryTag',
},
diff --git a/spec/lib/gitlab/database/migration_helpers_spec.rb b/spec/lib/gitlab/database/migration_helpers_spec.rb
index ff6e5437559..a763dc08b73 100644
--- a/spec/lib/gitlab/database/migration_helpers_spec.rb
+++ b/spec/lib/gitlab/database/migration_helpers_spec.rb
@@ -992,7 +992,8 @@ RSpec.describe Gitlab::Database::MigrationHelpers do
temp_undo_cleanup_column,
type: :string,
batch_column_name: :id,
- type_cast_function: nil
+ type_cast_function: nil,
+ limit: nil
).and_return(true)
expect(model).to receive(:rename_column)
@@ -1007,7 +1008,7 @@ RSpec.describe Gitlab::Database::MigrationHelpers do
model.undo_cleanup_concurrent_column_type_change(:users, :old, :string)
end
- it 'passes the type_cast_function and batch_column_name' do
+ it 'passes the type_cast_function, batch_column_name and limit' do
expect(model).to receive(:column_exists?).with(:users, :other_batch_column).and_return(true)
expect(model).to receive(:check_trigger_permissions!).with(:users)
@@ -1017,7 +1018,8 @@ RSpec.describe Gitlab::Database::MigrationHelpers do
temp_undo_cleanup_column,
type: :string,
batch_column_name: :other_batch_column,
- type_cast_function: :custom_type_cast_function
+ type_cast_function: :custom_type_cast_function,
+ limit: 8
).and_return(true)
expect(model).to receive(:rename_column)
@@ -1034,7 +1036,8 @@ RSpec.describe Gitlab::Database::MigrationHelpers do
:old,
:string,
type_cast_function: :custom_type_cast_function,
- batch_column_name: :other_batch_column
+ batch_column_name: :other_batch_column,
+ limit: 8
)
end
diff --git a/spec/lib/gitlab/kubernetes/helm/pod_spec.rb b/spec/lib/gitlab/kubernetes/helm/pod_spec.rb
index 6d97790fc8b..e3763977add 100644
--- a/spec/lib/gitlab/kubernetes/helm/pod_spec.rb
+++ b/spec/lib/gitlab/kubernetes/helm/pod_spec.rb
@@ -7,7 +7,7 @@ RSpec.describe Gitlab::Kubernetes::Helm::Pod do
using RSpec::Parameterized::TableSyntax
where(:helm_major_version, :expected_helm_version, :expected_command_env) do
- 2 | '2.16.9' | [:TILLER_NAMESPACE]
+ 2 | '2.17.0' | [:TILLER_NAMESPACE]
3 | '3.2.4' | nil
end
diff --git a/spec/models/environment_spec.rb b/spec/models/environment_spec.rb
index 3e10ea847ba..0c7d8e2969d 100644
--- a/spec/models/environment_spec.rb
+++ b/spec/models/environment_spec.rb
@@ -1547,4 +1547,18 @@ RSpec.describe Environment, :use_clean_rails_memory_store_caching do
end
end
end
+
+ describe '#clear_all_caches' do
+ subject { environment.clear_all_caches }
+
+ it 'clears all caches on the environment' do
+ expect_next_instance_of(Gitlab::EtagCaching::Store) do |store|
+ expect(store).to receive(:touch).with(environment.etag_cache_key)
+ end
+
+ expect(environment).to receive(:clear_reactive_cache!)
+
+ subject
+ end
+ end
end
diff --git a/spec/policies/project_policy_spec.rb b/spec/policies/project_policy_spec.rb
index 7f6c47d675b..c21d3b0939f 100644
--- a/spec/policies/project_policy_spec.rb
+++ b/spec/policies/project_policy_spec.rb
@@ -401,40 +401,6 @@ RSpec.describe ProjectPolicy do
end
end
- describe 'bot_log_in' do
- let(:bot_user) { create(:user, :project_bot) }
- let(:project) { private_project }
-
- context 'when bot is in project and is not blocked' do
- before do
- project.add_maintainer(bot_user)
- end
-
- it 'is a valid project bot' do
- expect(bot_user.can?(:bot_log_in, project)).to be_truthy
- end
- end
-
- context 'when project bot is invalid' do
- context 'when bot is not in project' do
- it 'is not a valid project bot' do
- expect(bot_user.can?(:bot_log_in, project)).to be_falsy
- end
- end
-
- context 'when bot user is blocked' do
- before do
- project.add_maintainer(bot_user)
- bot_user.block!
- end
-
- it 'is not a valid project bot' do
- expect(bot_user.can?(:bot_log_in, project)).to be_falsy
- end
- end
- end
- end
-
context 'support bot' do
let(:current_user) { User.support_bot }
diff --git a/spec/requests/api/graphql/container_repository/container_repository_details_spec.rb b/spec/requests/api/graphql/container_repository/container_repository_details_spec.rb
index 3c1c63c1670..44f924d8ae5 100644
--- a/spec/requests/api/graphql/container_repository/container_repository_details_spec.rb
+++ b/spec/requests/api/graphql/container_repository/container_repository_details_spec.rb
@@ -2,6 +2,7 @@
require 'spec_helper'
RSpec.describe 'container repository details' do
+ include_context 'container registry tags'
using RSpec::Parameterized::TableSyntax
include GraphqlHelpers
@@ -18,7 +19,7 @@ RSpec.describe 'container repository details' do
let(:user) { project.owner }
let(:variables) { {} }
- let(:tags) { %w(latest tag1 tag2 tag3 tag4 tag5) }
+ let(:tags) { %w[latest tag1 tag2 tag3 tag4 tag5] }
let(:container_repository_global_id) { container_repository.to_global_id.to_s }
let(:container_repository_details_response) { graphql_data.dig('containerRepository') }
@@ -76,6 +77,37 @@ RSpec.describe 'container repository details' do
end
end
+ context 'with a giant size tag' do
+ let(:tags) { %w[latest] }
+ let(:giant_size) { 1.terabyte }
+ let(:tag_sizes_response) { graphql_data_at('containerRepository', 'tags', 'nodes', 'totalSize') }
+ let(:fields) do
+ <<~GQL
+ tags {
+ nodes {
+ totalSize
+ }
+ }
+ GQL
+ end
+
+ let(:query) do
+ graphql_query_for(
+ 'containerRepository',
+ { id: container_repository_global_id },
+ fields
+ )
+ end
+
+ it 'returns the expected value as a string' do
+ stub_next_container_registry_tags_call(:total_size, giant_size)
+
+ subject
+
+ expect(tag_sizes_response.first).to eq(giant_size.to_s)
+ end
+ end
+
context 'limiting the number of tags' do
let(:limit) { 2 }
let(:tags_response) { container_repository_details_response.dig('tags', 'edges') }
@@ -105,4 +137,20 @@ RSpec.describe 'container repository details' do
expect(tags_response.size).to eq(limit)
end
end
+
+ context 'with tags with a manifest containing nil fields' do
+ let(:tags_response) { container_repository_details_response.dig('tags', 'nodes') }
+ let(:errors) { container_repository_details_response.dig('errors') }
+
+ %i[digest revision short_revision total_size created_at].each do |nilable_field|
+ it "returns a list of tags with a nil #{nilable_field}" do
+ stub_next_container_registry_tags_call(nilable_field, nil)
+
+ subject
+
+ expect(tags_response.size).to eq(tags.size)
+ expect(graphql_errors).to eq(nil)
+ end
+ end
+ end
end
diff --git a/spec/services/environments/canary_ingress/update_service_spec.rb b/spec/services/environments/canary_ingress/update_service_spec.rb
index 31d6f543817..5ba62e7104c 100644
--- a/spec/services/environments/canary_ingress/update_service_spec.rb
+++ b/spec/services/environments/canary_ingress/update_service_spec.rb
@@ -117,6 +117,12 @@ RSpec.describe Environments::CanaryIngress::UpdateService, :clean_gitlab_redis_c
expect(subject[:status]).to eq(:success)
expect(subject[:message]).to be_nil
end
+
+ it 'clears all caches' do
+ expect(environment).to receive(:clear_all_caches)
+
+ subject
+ end
end
context 'when patch request does not succeed' do
diff --git a/spec/support/shared_contexts/lib/container_registry/tags_shared_context.rb b/spec/support/shared_contexts/lib/container_registry/tags_shared_context.rb
new file mode 100644
index 00000000000..e0a746ec741
--- /dev/null
+++ b/spec/support/shared_contexts/lib/container_registry/tags_shared_context.rb
@@ -0,0 +1,9 @@
+# frozen_string_literal: true
+
+RSpec.shared_context 'container registry tags' do
+ def stub_next_container_registry_tags_call(method_name, mock_value)
+ allow_next_instance_of(ContainerRegistry::Tag) do |tag|
+ allow(tag).to receive(method_name).and_return(mock_value)
+ end
+ end
+end