diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2021-01-08 00:32:37 +0000 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2021-01-08 00:32:37 +0000 |
commit | 469a50879c1085ec77c95d650b7f135fee2c9e13 (patch) | |
tree | 0d639a63294b5abdb4e4a7bf1ed5a497d5e6869f | |
parent | aa5ca44f172f02f04cca448b1f9c17d6d933de40 (diff) | |
download | gitlab-ce-469a50879c1085ec77c95d650b7f135fee2c9e13.tar.gz |
Add latest changes from gitlab-org/gitlab@13-7-stable-ee
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 |