diff --git a/.gitlab/CODEOWNERS b/.gitlab/CODEOWNERS index 9e0c52b9deb..b0171c86bd6 100644 --- a/.gitlab/CODEOWNERS +++ b/.gitlab/CODEOWNERS @@ -59,16 +59,6 @@ GITALY_SERVER_VERSION @project_278964_bot6 @gitlab-org/maintainers/rails-backend /ee/app/finders/ /rubocop/rubocop-migrations.yml -[Create::IDE - Remote Development Scripts] @gitlab-org/maintainers/remote-development/backend -# This entry must occur before `/scripts/` in order to be matched first -/scripts/remote_development/ - -# This entry must occur before `/scripts/glfm/**/*`/`/scripts/lib/glfm/**/*` in order to be matched first -/scripts/glfm/**/*.js @gitlab-org/maintainers/frontend -/scripts/lib/glfm/**/*.js @gitlab-org/maintainers/frontend -/scripts/glfm/**/* @gitlab-org/maintainers/rails-backend -/scripts/lib/glfm/**/* @gitlab-org/maintainers/rails-backend - [Pipeline configuration] @gl-quality/eng-prod /.gitlab-ci.yml /.gitlab/ci/ @@ -84,14 +74,15 @@ GITALY_SERVER_VERSION @project_278964_bot6 @gitlab-org/maintainers/rails-backend /gems/gem.gitlab-ci.yml [Tooling] @gl-quality/eng-prod -/.gitlab/CODEOWNERS Dangerfile /danger/ /tooling/danger/ /scripts/ /scripts/**/*.rb @gl-quality/eng-prod @gitlab-org/maintainers/rails-backend +/scripts/**/glfm/**/* @gl-quality/eng-prod @gitlab-org/maintainers/rails-backend /scripts/**/*.js @gl-quality/eng-prod @gitlab-org/maintainers/frontend /scripts/frontend/ @gl-quality/eng-prod @gitlab-org/maintainers/frontend +/scripts/remote_development/ @gitlab-org/maintainers/remote-development/backend /scripts/review_apps/seed-dast-test-data.sh @gl-quality/eng-prod @dappelt @ngeorge1 /.codeclimate.yml /.dockerignore @@ -1491,12 +1482,14 @@ ee/lib/ee/api/entities/project.rb /ee/app/graphql/resolvers/remote_development/ /ee/app/controllers/remote_development/ /ee/app/services/remote_development/ +/ee/lib/remote_development/ /ee/spec/frontend/remote_development/ /ee/spec/features/remote_development/ /ee/spec/models/remote_development/ /ee/spec/policies/remote_development/ /ee/spec/requests/api/graphql/mutations/remote_development/ /ee/spec/requests/api/graphql/remote_development/ +/ee/spec/features/remote_development/ @gitlab-org/maintainers/remote-development/backend @gitlab-org/maintainers/remote-development/frontend /ee/spec/finders/remote_development/ /ee/spec/support/shared_contexts/remote_development/ /ee/spec/graphql/types/remote_development/ @@ -1505,13 +1498,12 @@ ee/lib/ee/api/entities/project.rb /ee/spec/fixtures/remote_development/ /ee/spec/controllers/remote_development/ /ee/spec/services/remote_development/ -/ee/lib/remote_development/ -/qa/qa/specs/features/ee/browser_ui/3_create/remote_development/ +/qa/qa/specs/features/**/remote_development/ @gitlab-org/maintainers/remote-development/backend @gl-quality/qe-maintainers [Create::IDE - Remote Development Frontend] @gitlab-org/maintainers/remote-development/frontend +/ee/app/assets/**/remote_development/ /ee/app/views/remote_development/ -/ee/app/assets/javascripts/remote_development/ -/ee/app/assets/javascripts/pages/remote_development/ +/ee/spec/frontend/**/remote_development/ # JiHu GitLab rules. See https://gitlab.com/gitlab-jh/gitlab-jh-enablement/-/issues/213#note_1024367528 diff --git a/.rubocop_todo/layout/argument_alignment.yml b/.rubocop_todo/layout/argument_alignment.yml index 014b9a3f551..f5177f86a29 100644 --- a/.rubocop_todo/layout/argument_alignment.yml +++ b/.rubocop_todo/layout/argument_alignment.yml @@ -4,18 +4,6 @@ Layout/ArgumentAlignment: Exclude: - 'app/graphql/mutations/achievements/create.rb' - 'app/graphql/mutations/admin/sidekiq_queues/delete_jobs.rb' - - 'app/graphql/mutations/alert_management/alerts/set_assignees.rb' - - 'app/graphql/mutations/alert_management/base.rb' - - 'app/graphql/mutations/alert_management/http_integration/create.rb' - - 'app/graphql/mutations/alert_management/http_integration/destroy.rb' - - 'app/graphql/mutations/alert_management/http_integration/http_integration_base.rb' - - 'app/graphql/mutations/alert_management/http_integration/reset_token.rb' - - 'app/graphql/mutations/alert_management/http_integration/update.rb' - - 'app/graphql/mutations/alert_management/prometheus_integration/create.rb' - - 'app/graphql/mutations/alert_management/prometheus_integration/prometheus_integration_base.rb' - - 'app/graphql/mutations/alert_management/prometheus_integration/reset_token.rb' - - 'app/graphql/mutations/alert_management/prometheus_integration/update.rb' - - 'app/graphql/mutations/alert_management/update_alert_status.rb' - 'app/graphql/mutations/award_emojis/base.rb' - 'app/graphql/mutations/base_mutation.rb' - 'app/graphql/mutations/boards/common_mutation_arguments.rb' diff --git a/CHANGELOG.md b/CHANGELOG.md index 0ee1d5da0cc..56a2e9dd2f2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,13 @@ documentation](doc/development/changelog.md) for instructions on adding your own entry. +## 16.2.4 (2023-08-11) + +### Fixed (2 changes) + +- [Replace vscode-cdn.net with web-ide.gitlab-static.net](gitlab-org/gitlab@b19d3d6412b4e349b932775d0736c8727d98b1b2) ([merge request](gitlab-org/gitlab!128950)) +- [Revert "Remove log_response_length feature flag"](gitlab-org/gitlab@03a2a38a822da8c303a3ccefd9a4b8de818c2ca2) ([merge request](gitlab-org/gitlab!128778)) + ## 16.2.3 (2023-08-03) No changes. diff --git a/app/assets/javascripts/ci/runner/admin_runners/provide.js b/app/assets/javascripts/ci/runner/admin_runners/provide.js index 6f2f66ed72e..81a39801718 100644 --- a/app/assets/javascripts/ci/runner/admin_runners/provide.js +++ b/app/assets/javascripts/ci/runner/admin_runners/provide.js @@ -6,11 +6,17 @@ * See EE version */ export const provide = (elDataset) => { - const { runnerInstallHelpPage, onlineContactTimeoutSecs, staleTimeoutSecs } = elDataset; + const { + runnerInstallHelpPage, + onlineContactTimeoutSecs, + staleTimeoutSecs, + tagSuggestionsPath, + } = elDataset; return { runnerInstallHelpPage, onlineContactTimeoutSecs, staleTimeoutSecs, + tagSuggestionsPath, }; }; diff --git a/app/assets/javascripts/ci/runner/components/search_tokens/tag_token.vue b/app/assets/javascripts/ci/runner/components/search_tokens/tag_token.vue index 1de7775090a..dd1cca0a05c 100644 --- a/app/assets/javascripts/ci/runner/components/search_tokens/tag_token.vue +++ b/app/assets/javascripts/ci/runner/components/search_tokens/tag_token.vue @@ -7,20 +7,13 @@ import { s__ } from '~/locale'; import BaseToken from '~/vue_shared/components/filtered_search_bar/tokens/base_token.vue'; import { RUNNER_TAG_BG_CLASS } from '../../constants'; -// TODO This should be implemented via a GraphQL API -// The API should -// 1) scope to the rights of the user -// 2) stay up to date to the removal of old tags -// 3) consider the scope of search, like searching within the tags of a group -// See: https://gitlab.com/gitlab-org/gitlab/-/issues/333796 -export const TAG_SUGGESTIONS_PATH = '/admin/runners/tag_list.json'; - export default { components: { BaseToken, GlFilteredSearchSuggestion, GlToken, }, + inject: ['tagSuggestionsPath'], props: { config: { type: Object, @@ -36,7 +29,7 @@ export default { methods: { getTagsOptions(search) { return axios - .get(TAG_SUGGESTIONS_PATH, { + .get(this.tagSuggestionsPath, { params: { search, }, diff --git a/app/assets/stylesheets/framework/buttons.scss b/app/assets/stylesheets/framework/buttons.scss index 866e6fb40d2..8a64b0999b6 100644 --- a/app/assets/stylesheets/framework/buttons.scss +++ b/app/assets/stylesheets/framework/buttons.scss @@ -134,13 +134,6 @@ } } -@mixin btn-svg { - height: $gl-padding; - width: $gl-padding; - top: 0; - vertical-align: text-top; -} - .btn { @include btn-default; @include btn-white; @@ -344,14 +337,6 @@ } } -// The .btn-svg class is available for legacy icon buttons to -// preserve a 34px height and have 16x16 icons at the same time. -// Once a button is migrated (to the current 32px height) -// please remove this class from the new button. -.btn-svg svg { - @include btn-svg; -} - // All disabled buttons, regardless of color, type, etc .btn.disabled, .btn[disabled], diff --git a/app/assets/stylesheets/framework/mixins.scss b/app/assets/stylesheets/framework/mixins.scss index aee06a04351..edebe9c95ad 100644 --- a/app/assets/stylesheets/framework/mixins.scss +++ b/app/assets/stylesheets/framework/mixins.scss @@ -326,11 +326,6 @@ color: $gray-500; fill: $gray-500; - svg { - @include btn-svg; - margin: 0; - } - .award-control-icon-positive, .award-control-icon-super-positive { position: absolute; @@ -474,10 +469,3 @@ margin-left: $gl-padding; } } - -@mixin btn-svg { - height: $gl-padding; - width: $gl-padding; - top: 0; - vertical-align: text-top; -} diff --git a/app/graphql/mutations/alert_management/alerts/set_assignees.rb b/app/graphql/mutations/alert_management/alerts/set_assignees.rb index 500e2b868b1..a8513417c1c 100644 --- a/app/graphql/mutations/alert_management/alerts/set_assignees.rb +++ b/app/graphql/mutations/alert_management/alerts/set_assignees.rb @@ -7,14 +7,14 @@ module Mutations graphql_name 'AlertSetAssignees' argument :assignee_usernames, - [GraphQL::Types::String], - required: true, - description: 'Usernames to assign to the alert. Replaces existing assignees by default.' + [GraphQL::Types::String], + required: true, + description: 'Usernames to assign to the alert. Replaces existing assignees by default.' argument :operation_mode, - Types::MutationOperationModeEnum, - required: false, - description: 'Operation to perform. Defaults to REPLACE.' + Types::MutationOperationModeEnum, + required: false, + description: 'Operation to perform. Defaults to REPLACE.' def resolve(args) alert = authorized_find!(project_path: args[:project_path], iid: args[:iid]) diff --git a/app/graphql/mutations/alert_management/base.rb b/app/graphql/mutations/alert_management/base.rb index 771ace5510f..615c0f43a15 100644 --- a/app/graphql/mutations/alert_management/base.rb +++ b/app/graphql/mutations/alert_management/base.rb @@ -6,27 +6,27 @@ module Mutations include Gitlab::Utils::UsageData argument :project_path, GraphQL::Types::ID, - required: true, - description: "Project the alert to mutate is in." + required: true, + description: "Project the alert to mutate is in." argument :iid, GraphQL::Types::String, - required: true, - description: "IID of the alert to mutate." + required: true, + description: "IID of the alert to mutate." field :alert, - Types::AlertManagement::AlertType, - null: true, - description: "Alert after mutation." + Types::AlertManagement::AlertType, + null: true, + description: "Alert after mutation." field :todo, - Types::TodoType, - null: true, - description: "To-do item after mutation." + Types::TodoType, + null: true, + description: "To-do item after mutation." field :issue, - Types::IssueType, - null: true, - description: "Issue created after mutation." + Types::IssueType, + null: true, + description: "Issue created after mutation." authorize :update_alert_management_alert diff --git a/app/graphql/mutations/alert_management/http_integration/create.rb b/app/graphql/mutations/alert_management/http_integration/create.rb index f8d1a383706..fccef8cd3ad 100644 --- a/app/graphql/mutations/alert_management/http_integration/create.rb +++ b/app/graphql/mutations/alert_management/http_integration/create.rb @@ -9,16 +9,16 @@ module Mutations include FindsProject argument :project_path, GraphQL::Types::ID, - required: true, - description: 'Project to create the integration in.' + required: true, + description: 'Project to create the integration in.' argument :name, GraphQL::Types::String, - required: true, - description: 'Name of the integration.' + required: true, + description: 'Name of the integration.' argument :active, GraphQL::Types::Boolean, - required: true, - description: 'Whether the integration is receiving alerts.' + required: true, + description: 'Whether the integration is receiving alerts.' def resolve(args) project = authorized_find!(args[:project_path]) diff --git a/app/graphql/mutations/alert_management/http_integration/destroy.rb b/app/graphql/mutations/alert_management/http_integration/destroy.rb index dc5c73ecff6..9da50a4c4ce 100644 --- a/app/graphql/mutations/alert_management/http_integration/destroy.rb +++ b/app/graphql/mutations/alert_management/http_integration/destroy.rb @@ -7,8 +7,8 @@ module Mutations graphql_name 'HttpIntegrationDestroy' argument :id, Types::GlobalIDType[::AlertManagement::HttpIntegration], - required: true, - description: "ID of the integration to remove." + required: true, + description: "ID of the integration to remove." def resolve(id:) integration = authorized_find!(id: id) diff --git a/app/graphql/mutations/alert_management/http_integration/http_integration_base.rb b/app/graphql/mutations/alert_management/http_integration/http_integration_base.rb index 2f25d315d2e..9434ac1637e 100644 --- a/app/graphql/mutations/alert_management/http_integration/http_integration_base.rb +++ b/app/graphql/mutations/alert_management/http_integration/http_integration_base.rb @@ -5,9 +5,9 @@ module Mutations module HttpIntegration class HttpIntegrationBase < BaseMutation field :integration, - Types::AlertManagement::HttpIntegrationType, - null: true, - description: "HTTP integration." + Types::AlertManagement::HttpIntegrationType, + null: true, + description: "HTTP integration." authorize :admin_operations diff --git a/app/graphql/mutations/alert_management/http_integration/reset_token.rb b/app/graphql/mutations/alert_management/http_integration/reset_token.rb index 83ad7762408..bed3cf08674 100644 --- a/app/graphql/mutations/alert_management/http_integration/reset_token.rb +++ b/app/graphql/mutations/alert_management/http_integration/reset_token.rb @@ -7,8 +7,8 @@ module Mutations graphql_name 'HttpIntegrationResetToken' argument :id, Types::GlobalIDType[::AlertManagement::HttpIntegration], - required: true, - description: "ID of the integration to mutate." + required: true, + description: "ID of the integration to mutate." def resolve(id:) integration = authorized_find!(id: id) diff --git a/app/graphql/mutations/alert_management/http_integration/update.rb b/app/graphql/mutations/alert_management/http_integration/update.rb index 78424e317b8..06d0b7163b0 100644 --- a/app/graphql/mutations/alert_management/http_integration/update.rb +++ b/app/graphql/mutations/alert_management/http_integration/update.rb @@ -7,16 +7,16 @@ module Mutations graphql_name 'HttpIntegrationUpdate' argument :id, Types::GlobalIDType[::AlertManagement::HttpIntegration], - required: true, - description: "ID of the integration to mutate." + required: true, + description: "ID of the integration to mutate." argument :name, GraphQL::Types::String, - required: false, - description: "Name of the integration." + required: false, + description: "Name of the integration." argument :active, GraphQL::Types::Boolean, - required: false, - description: "Whether the integration is receiving alerts." + required: false, + description: "Whether the integration is receiving alerts." def resolve(args) integration = authorized_find!(id: args[:id]) diff --git a/app/graphql/mutations/alert_management/prometheus_integration/create.rb b/app/graphql/mutations/alert_management/prometheus_integration/create.rb index b06a4f58df5..665ce96f0f9 100644 --- a/app/graphql/mutations/alert_management/prometheus_integration/create.rb +++ b/app/graphql/mutations/alert_management/prometheus_integration/create.rb @@ -9,16 +9,16 @@ module Mutations include FindsProject argument :project_path, GraphQL::Types::ID, - required: true, - description: 'Project to create the integration in.' + required: true, + description: 'Project to create the integration in.' argument :active, GraphQL::Types::Boolean, - required: true, - description: 'Whether the integration is receiving alerts.' + required: true, + description: 'Whether the integration is receiving alerts.' argument :api_url, GraphQL::Types::String, - required: false, - description: 'Endpoint at which Prometheus can be queried.' + required: false, + description: 'Endpoint at which Prometheus can be queried.' def resolve(args) project = authorized_find!(args[:project_path]) diff --git a/app/graphql/mutations/alert_management/prometheus_integration/prometheus_integration_base.rb b/app/graphql/mutations/alert_management/prometheus_integration/prometheus_integration_base.rb index 29834d63f35..28729ec70cd 100644 --- a/app/graphql/mutations/alert_management/prometheus_integration/prometheus_integration_base.rb +++ b/app/graphql/mutations/alert_management/prometheus_integration/prometheus_integration_base.rb @@ -5,9 +5,9 @@ module Mutations module PrometheusIntegration class PrometheusIntegrationBase < BaseMutation field :integration, - Types::AlertManagement::PrometheusIntegrationType, - null: true, - description: "Newly created integration." + Types::AlertManagement::PrometheusIntegrationType, + null: true, + description: "Newly created integration." authorize :admin_project diff --git a/app/graphql/mutations/alert_management/prometheus_integration/reset_token.rb b/app/graphql/mutations/alert_management/prometheus_integration/reset_token.rb index 71c02efdc03..15e6763b1ee 100644 --- a/app/graphql/mutations/alert_management/prometheus_integration/reset_token.rb +++ b/app/graphql/mutations/alert_management/prometheus_integration/reset_token.rb @@ -7,8 +7,8 @@ module Mutations graphql_name 'PrometheusIntegrationResetToken' argument :id, Types::GlobalIDType[::Integrations::Prometheus], - required: true, - description: "ID of the integration to mutate." + required: true, + description: "ID of the integration to mutate." def resolve(id:) integration = authorized_find!(id: id) diff --git a/app/graphql/mutations/alert_management/prometheus_integration/update.rb b/app/graphql/mutations/alert_management/prometheus_integration/update.rb index 50aafdc26a6..593624aaafd 100644 --- a/app/graphql/mutations/alert_management/prometheus_integration/update.rb +++ b/app/graphql/mutations/alert_management/prometheus_integration/update.rb @@ -7,16 +7,16 @@ module Mutations graphql_name 'PrometheusIntegrationUpdate' argument :id, Types::GlobalIDType[::Integrations::Prometheus], - required: true, - description: "ID of the integration to mutate." + required: true, + description: "ID of the integration to mutate." argument :active, GraphQL::Types::Boolean, - required: false, - description: "Whether the integration is receiving alerts." + required: false, + description: "Whether the integration is receiving alerts." argument :api_url, GraphQL::Types::String, - required: false, - description: "Endpoint at which Prometheus can be queried." + required: false, + description: "Endpoint at which Prometheus can be queried." def resolve(args) integration = authorized_find!(id: args[:id]) diff --git a/app/graphql/mutations/alert_management/update_alert_status.rb b/app/graphql/mutations/alert_management/update_alert_status.rb index be271a7d795..a0d06ebf221 100644 --- a/app/graphql/mutations/alert_management/update_alert_status.rb +++ b/app/graphql/mutations/alert_management/update_alert_status.rb @@ -6,8 +6,8 @@ module Mutations graphql_name 'UpdateAlertStatus' argument :status, Types::AlertManagement::StatusEnum, - required: true, - description: 'Status to set the alert.' + required: true, + description: 'Status to set the alert.' def resolve(project_path:, iid:, status:) alert = authorized_find!(project_path: project_path, iid: iid) diff --git a/app/helpers/ci/runners_helper.rb b/app/helpers/ci/runners_helper.rb index 9085ff5f45a..cfb7bc8b0f4 100644 --- a/app/helpers/ci/runners_helper.rb +++ b/app/helpers/ci/runners_helper.rb @@ -71,7 +71,8 @@ module Ci new_runner_path: new_admin_runner_path, registration_token: Gitlab::CurrentSettings.runners_registration_token, online_contact_timeout_secs: ::Ci::Runner::ONLINE_CONTACT_TIMEOUT.to_i, - stale_timeout_secs: ::Ci::Runner::STALE_TIMEOUT.to_i + stale_timeout_secs: ::Ci::Runner::STALE_TIMEOUT.to_i, + tag_suggestions_path: tag_list_admin_runners_path(format: :json) } end diff --git a/app/models/application_setting.rb b/app/models/application_setting.rb index 0f407e15fc1..b3366c9300f 100644 --- a/app/models/application_setting.rb +++ b/app/models/application_setting.rb @@ -39,8 +39,12 @@ class ApplicationSetting < MainClusterwide::ApplicationRecord encrypted_tofa_url_iv vertex_project ], remove_with: '16.3', remove_after: '2023-07-22' - ignore_column :dashboard_notification_limit, remove_with: '16.5', remove_after: '2023-08-22' ignore_column :database_apdex_settings, remove_with: '16.4', remove_after: '2023-08-22' + ignore_columns %i[ + dashboard_notification_limit + dashboard_enforcement_limit + dashboard_limit_new_namespace_creation_enforcement_date + ], remove_with: '16.5', remove_after: '2023-08-22' INSTANCE_REVIEW_MIN_USERS = 50 GRAFANA_URL_ERROR_MESSAGE = 'Please check your Grafana URL setting in ' \ diff --git a/app/models/operations/feature_flag.rb b/app/models/operations/feature_flag.rb index 6876af09c2c..01db0a5cf8b 100644 --- a/app/models/operations/feature_flag.rb +++ b/app/models/operations/feature_flag.rb @@ -30,7 +30,9 @@ module Operations length: 2..63, format: { with: Gitlab::Regex.feature_flag_regex, - message: Gitlab::Regex.feature_flag_regex_message + message: ->(_object, _data) { + s_("Validation|can contain only lowercase letters, digits, '_' and '-'. Must start with a letter, and cannot end with '-' or '_'") + } } validates :name, uniqueness: { scope: :project_id } validates :description, allow_blank: true, length: 0..255 diff --git a/app/models/operations/feature_flags/strategy.rb b/app/models/operations/feature_flags/strategy.rb index ed9400dde8f..5dc6de7dfc1 100644 --- a/app/models/operations/feature_flags/strategy.rb +++ b/app/models/operations/feature_flags/strategy.rb @@ -28,7 +28,7 @@ module Operations validates :name, inclusion: { in: STRATEGIES.keys, - message: 'strategy name is invalid' + message: ->(_object, _data) { s_('Validation|strategy name is invalid') } } validate :parameters_validations, if: -> { errors[:name].blank? } @@ -46,7 +46,7 @@ module Operations def same_project_validation unless user_list.project_id == feature_flag.project_id - errors.add(:user_list, 'must belong to the same project') + errors.add(:user_list, s_('Validation|must belong to the same project')) end end @@ -57,13 +57,13 @@ module Operations end def validate_parameters_type - parameters.is_a?(Hash) || parameters_error('parameters are invalid') + parameters.is_a?(Hash) || parameters_error(s_('Validation|parameters are invalid')) end def validate_parameters_keys actual_keys = parameters.keys.sort expected_keys = STRATEGIES[name].sort - expected_keys == actual_keys || parameters_error('parameters are invalid') + expected_keys == actual_keys || parameters_error(s_('Validation|parameters are invalid')) end def validate_parameters_values @@ -89,11 +89,11 @@ module Operations group_id = parameters['groupId'] unless within_range?(percentage, 0, 100) - parameters_error('percentage must be a string between 0 and 100 inclusive') + parameters_error(s_('Validation|percentage must be a string between 0 and 100 inclusive')) end unless group_id.is_a?(String) && group_id.match(/\A[a-z]{1,32}\z/) - parameters_error('groupId parameter is invalid') + parameters_error(s_('Validation|groupId parameter is invalid')) end end @@ -108,11 +108,11 @@ module Operations end unless group_id.is_a?(String) && group_id.match(/\A[a-z]{1,32}\z/) - parameters_error('groupId parameter is invalid') + parameters_error(s_('Validation|groupId parameter is invalid')) end unless within_range?(rollout, 0, 100) - parameters_error('rollout must be a string between 0 and 100 inclusive') + parameters_error(s_('Validation|rollout must be a string between 0 and 100 inclusive')) end end diff --git a/db/docs/p_ci_builds.yml b/db/docs/p_ci_builds.yml index ca01e89de09..757d609dd4b 100644 --- a/db/docs/p_ci_builds.yml +++ b/db/docs/p_ci_builds.yml @@ -2,10 +2,15 @@ table_name: p_ci_builds classes: - Ci::Bridge +- Ci::Bridge::Partitioned - Ci::Build +- Ci::Build::Partitioned - Ci::Processable +- Ci::Processable::Partitioned - CommitStatus +- CommitStatus::Partitioned - GenericCommitStatus +- GenericCommitStatus::Partitioned feature_categories: - continuous_integration description: Routing table for ci_builds diff --git a/db/post_migrate/20230809090349_ensure_id_uniqueness_for_p_ci_builds_v2.rb b/db/post_migrate/20230809090349_ensure_id_uniqueness_for_p_ci_builds_v2.rb new file mode 100644 index 00000000000..8170059624c --- /dev/null +++ b/db/post_migrate/20230809090349_ensure_id_uniqueness_for_p_ci_builds_v2.rb @@ -0,0 +1,50 @@ +# frozen_string_literal: true + +class EnsureIdUniquenessForPCiBuildsV2 < Gitlab::Database::Migration[2.1] + include Gitlab::Database::SchemaHelpers + include Gitlab::Database::MigrationHelpers::WraparoundAutovacuum + + enable_lock_retries! + + TABLE_NAME = :p_ci_builds + FUNCTION_NAME = :assign_p_ci_builds_id_value + TRIGGER_NAME = :assign_p_ci_builds_id_trigger + + def up + return unless should_run? + return if trigger_exists?(:ci_builds, TRIGGER_NAME) + + change_column_default(TABLE_NAME, :id, nil) + + create_trigger_function(FUNCTION_NAME) do + <<~SQL + IF NEW."id" IS NOT NULL THEN + RAISE WARNING 'Manually assigning ids is not allowed, the value will be ignored'; + END IF; + NEW."id" := nextval('ci_builds_id_seq'::regclass); + RETURN NEW; + SQL + end + + Gitlab::Database::PostgresPartitionedTable.each_partition(TABLE_NAME) do |partition| + create_trigger(partition.identifier, TRIGGER_NAME, FUNCTION_NAME, fires: 'BEFORE INSERT') + end + end + + def down + return unless should_run? + + execute(<<~SQL.squish) + ALTER TABLE #{TABLE_NAME} + ALTER COLUMN id SET DEFAULT nextval('ci_builds_id_seq'::regclass); + + DROP FUNCTION IF EXISTS #{FUNCTION_NAME} CASCADE; + SQL + end + + private + + def should_run? + can_execute_on?(:ci_builds) + end +end diff --git a/db/schema_migrations/20230809090349 b/db/schema_migrations/20230809090349 new file mode 100644 index 00000000000..4ed6a71b429 --- /dev/null +++ b/db/schema_migrations/20230809090349 @@ -0,0 +1 @@ +45c2aeda5ea7ef5422974f85b900cc871e056a04f32733da7e45e202bac4d701 \ No newline at end of file diff --git a/doc/api/draft_notes.md b/doc/api/draft_notes.md index 8c88c04d9fd..f30bb52e134 100644 --- a/doc/api/draft_notes.md +++ b/doc/api/draft_notes.md @@ -108,7 +108,7 @@ POST /projects/:id/merge_requests/:merge_request_iid/draft_notes | `merge_request_iid` | integer | yes | The IID of a project merge request. | `note` | string | yes | The content of a note. | `commit_id` | string | no | The SHA of a commit to associate the draft note to. -| `in_reply_to_discussion_id` | integer | no | The ID of a discussion the draft note replies to. +| `in_reply_to_discussion_id` | string | no | The ID of a discussion the draft note replies to. | `resolve_discussion` | boolean | no | The associated discussion should be resolved. | `position[base_sha]` | string | yes | Base commit SHA in the source branch. | | `position[head_sha]` | string | yes | SHA referencing HEAD of this merge request. | diff --git a/doc/development/geo.md b/doc/development/geo.md index e8eb19b1572..ceaa2dbb056 100644 --- a/doc/development/geo.md +++ b/doc/development/geo.md @@ -48,8 +48,7 @@ for new events and creates background jobs for each specific event type. For example when a repository is updated, the Geo **primary** site creates a Geo event with an associated repository updated event. The Geo Log Cursor daemon picks the event up and schedules a `Geo::ProjectSyncWorker` job which -uses the `Geo::RepositorySyncService` to update the repository -and `Geo::WikiSyncService` classes to update the wiki. +uses the `Geo::RepositorySyncService` to update the repository. The Geo Log Cursor daemon can operate in High Availability mode automatically. The daemon tries to acquire a lock from time to time and once acquired, it diff --git a/doc/user/application_security/offline_deployments/index.md b/doc/user/application_security/offline_deployments/index.md index 63f3763cab9..3f3da69cbc9 100644 --- a/doc/user/application_security/offline_deployments/index.md +++ b/doc/user/application_security/offline_deployments/index.md @@ -5,7 +5,7 @@ group: Static Analysis info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/product/ux/technical-writing/#assignments --- -# Offline environments **(ULTIMATE SELF)** +# Offline environments **(FREE SELF)** NOTE: To set up an offline environment, you must receive an [opt-out exemption of cloud licensing](https://about.gitlab.com/pricing/licensing-faq/cloud-licensing/#offline-cloud-licensing) prior to purchase. For more details, contact your GitLab sales representative. diff --git a/lib/api/draft_notes.rb b/lib/api/draft_notes.rb index ff71d6bebb5..6fadc68233d 100644 --- a/lib/api/draft_notes.rb +++ b/lib/api/draft_notes.rb @@ -137,7 +137,7 @@ module API requires :id, type: String, desc: "The ID of a project." requires :merge_request_iid, type: Integer, desc: "The ID of a merge request." requires :note, type: String, desc: 'The content of a note.' - optional :in_reply_to_discussion_id, type: Integer, desc: 'The ID of a discussion the draft note replies to.' + optional :in_reply_to_discussion_id, type: String, desc: 'The ID of a discussion the draft note replies to.' optional :commit_id, type: String, desc: 'The sha of a commit to associate the draft note to.' optional :resolve_discussion, type: Boolean, desc: 'The associated discussion should be resolved.' use :positional diff --git a/lib/gitlab/regex.rb b/lib/gitlab/regex.rb index c5b93cf58d6..40facabff23 100644 --- a/lib/gitlab/regex.rb +++ b/lib/gitlab/regex.rb @@ -312,11 +312,6 @@ module Gitlab /\A[a-z]([-_a-z0-9]*[a-z0-9])?\z/ end - def feature_flag_regex_message - "can contain only lowercase letters, digits, '_' and '-'. " \ - "Must start with a letter, and cannot end with '-' or '_'" - end - # One or more `part`s, separated by separator def sep_by_1(separator, part) %r(#{part} (#{separator} #{part})*)x diff --git a/locale/gitlab.pot b/locale/gitlab.pot index ee57f7546f0..6910926d991 100644 --- a/locale/gitlab.pot +++ b/locale/gitlab.pot @@ -51289,6 +51289,27 @@ msgstr "" msgid "Validations failed." msgstr "" +msgid "Validation|can contain only lowercase letters, digits, '_' and '-'. Must start with a letter, and cannot end with '-' or '_'" +msgstr "" + +msgid "Validation|groupId parameter is invalid" +msgstr "" + +msgid "Validation|must belong to the same project" +msgstr "" + +msgid "Validation|parameters are invalid" +msgstr "" + +msgid "Validation|percentage must be a string between 0 and 100 inclusive" +msgstr "" + +msgid "Validation|rollout must be a string between 0 and 100 inclusive" +msgstr "" + +msgid "Validation|strategy name is invalid" +msgstr "" + msgid "Value" msgstr "" @@ -52994,9 +53015,6 @@ msgstr "" msgid "WikiPage|Write your content or drag files here…" msgstr "" -msgid "Wikis" -msgstr "" - msgid "Wiki|Create New Page" msgstr "" diff --git a/spec/frontend/ci/runner/components/search_tokens/tag_token_spec.js b/spec/frontend/ci/runner/components/search_tokens/tag_token_spec.js index e9f2e888b9a..91d2a20ec8a 100644 --- a/spec/frontend/ci/runner/components/search_tokens/tag_token_spec.js +++ b/spec/frontend/ci/runner/components/search_tokens/tag_token_spec.js @@ -6,7 +6,7 @@ import waitForPromises from 'helpers/wait_for_promises'; import { createAlert } from '~/alert'; import axios from '~/lib/utils/axios_utils'; import { HTTP_STATUS_INTERNAL_SERVER_ERROR, HTTP_STATUS_OK } from '~/lib/utils/http_status'; -import TagToken, { TAG_SUGGESTIONS_PATH } from '~/ci/runner/components/search_tokens/tag_token.vue'; +import TagToken from '~/ci/runner/components/search_tokens/tag_token.vue'; import { OPERATORS_IS } from '~/vue_shared/components/filtered_search_bar/constants'; import { getRecentlyUsedSuggestions } from '~/vue_shared/components/filtered_search_bar/filtered_search_utils'; @@ -45,6 +45,8 @@ const mockTagTokenConfig = { operators: OPERATORS_IS, }; +const mockTagSuggestionsPath = '/path/runners/tag_list'; + describe('TagToken', () => { let mock; let wrapper; @@ -59,7 +61,8 @@ describe('TagToken', () => { }, provide: { portalName: 'fake target', - alignSuggestions: function fakeAlignSuggestions() {}, + tagSuggestionsPath: mockTagSuggestionsPath, + alignSuggestions: function fakeAligxnSuggestions() {}, filteredSearchSuggestionListInstance: { register: jest.fn(), unregister: jest.fn(), @@ -80,9 +83,9 @@ describe('TagToken', () => { beforeEach(() => { mock = new MockAdapter(axios); - mock.onGet(TAG_SUGGESTIONS_PATH, { params: { search: '' } }).reply(HTTP_STATUS_OK, mockTags); + mock.onGet(mockTagSuggestionsPath, { params: { search: '' } }).reply(HTTP_STATUS_OK, mockTags); mock - .onGet(TAG_SUGGESTIONS_PATH, { params: { search: mockSearchTerm } }) + .onGet(mockTagSuggestionsPath, { params: { search: mockSearchTerm } }) .reply(HTTP_STATUS_OK, mockTagsFiltered); getRecentlyUsedSuggestions.mockReturnValue([]); @@ -163,7 +166,7 @@ describe('TagToken', () => { describe('when suggestions cannot be loaded', () => { beforeEach(async () => { mock - .onGet(TAG_SUGGESTIONS_PATH, { params: { search: '' } }) + .onGet(mockTagSuggestionsPath, { params: { search: '' } }) .reply(HTTP_STATUS_INTERNAL_SERVER_ERROR); createComponent(); diff --git a/spec/lib/gitlab/ci/status/stage/factory_spec.rb b/spec/lib/gitlab/ci/status/stage/factory_spec.rb index 35d44281072..34e430202c9 100644 --- a/spec/lib/gitlab/ci/status/stage/factory_spec.rb +++ b/spec/lib/gitlab/ci/status/stage/factory_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' -RSpec.describe Gitlab::Ci::Status::Stage::Factory do +RSpec.describe Gitlab::Ci::Status::Stage::Factory, feature_category: :continuous_integration do let(:user) { create(:user) } let(:project) { create(:project) } let(:pipeline) { create(:ci_empty_pipeline, project: project) } diff --git a/spec/lib/gitlab/ci/status/stage/play_manual_spec.rb b/spec/lib/gitlab/ci/status/stage/play_manual_spec.rb index 9fdaddc083e..fc52b7bf9d4 100644 --- a/spec/lib/gitlab/ci/status/stage/play_manual_spec.rb +++ b/spec/lib/gitlab/ci/status/stage/play_manual_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' -RSpec.describe Gitlab::Ci::Status::Stage::PlayManual do +RSpec.describe Gitlab::Ci::Status::Stage::PlayManual, feature_category: :continuous_integration do let(:stage) { double('stage') } let(:play_manual) { described_class.new(stage) } diff --git a/spec/models/ci/stage_spec.rb b/spec/models/ci/stage_spec.rb index 79e92082ee1..1be50083cd4 100644 --- a/spec/models/ci/stage_spec.rb +++ b/spec/models/ci/stage_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' -RSpec.describe Ci::Stage, :models do +RSpec.describe Ci::Stage, :models, feature_category: :continuous_integration do let_it_be(:pipeline) { create(:ci_empty_pipeline) } let(:stage) { create(:ci_stage, pipeline: pipeline, project: pipeline.project) } diff --git a/spec/models/concerns/ci/partitionable/switch_spec.rb b/spec/models/concerns/ci/partitionable/switch_spec.rb index 4aaf69bb585..0041a33e50e 100644 --- a/spec/models/concerns/ci/partitionable/switch_spec.rb +++ b/spec/models/concerns/ci/partitionable/switch_spec.rb @@ -192,11 +192,11 @@ RSpec.describe Ci::Partitionable::Switch, :aggregate_failures do it 'writes' do rollout_and_rollback_flag( -> { - expect(sql(filter: /INSERT .* jobs_metadata/) { jobs_model.find(job.id).create_metadata! }) + expect(sql(filter: [/INSERT/, /jobs_metadata/]) { jobs_model.find(job.id).create_metadata! }) .to all match(/INSERT INTO "_test_ci_jobs_metadata"/) }, -> { - expect(sql(filter: /INSERT .* jobs_metadata/) { jobs_model.find(job.id).create_metadata! }) + expect(sql(filter: [/INSERT/, /jobs_metadata/]) { jobs_model.find(job.id).create_metadata! }) .to all match(/INSERT INTO "_test_p_ci_jobs_metadata"/) } ) @@ -210,11 +210,11 @@ RSpec.describe Ci::Partitionable::Switch, :aggregate_failures do rollout_and_rollback_flag( -> { - expect(sql(filter: /DELETE .* jobs_metadata/) { jobs_model.last.destroy! }) + expect(sql(filter: [/DELETE/, /jobs_metadata/]) { jobs_model.last.destroy! }) .to all match(/DELETE FROM "_test_ci_jobs_metadata"/) }, -> { - expect(sql(filter: /DELETE .* jobs_metadata/) { jobs_model.last.destroy! }) + expect(sql(filter: [/DELETE/, /jobs_metadata/]) { jobs_model.last.destroy! }) .to all match(/DELETE FROM "_test_p_ci_jobs_metadata"/) } ) @@ -272,11 +272,11 @@ RSpec.describe Ci::Partitionable::Switch, :aggregate_failures do rollout_and_rollback_flag( -> { - expect(sql(filter: /INSERT .* jobs_metadata/) { jobs_model.create!(attrs) }) + expect(sql(filter: [/INSERT/, /jobs_metadata/]) { jobs_model.create!(attrs) }) .to all match(/INSERT INTO "_test_ci_jobs_metadata" .* 'test_env_name'/) }, -> { - expect(sql(filter: /INSERT .* jobs_metadata/) { jobs_model.create!(attrs) }) + expect(sql(filter: [/INSERT/, /jobs_metadata/]) { jobs_model.create!(attrs) }) .to all match(/INSERT INTO "_test_p_ci_jobs_metadata" .* 'test_env_name'/) } ) @@ -327,11 +327,9 @@ RSpec.describe Ci::Partitionable::Switch, :aggregate_failures do end def sql(filter: nil, &block) - result = ActiveRecord::QueryRecorder.new(&block) - result = result.log - - return result unless filter - - result.select { |statement| statement.match?(filter) } + ActiveRecord::QueryRecorder.new(&block) + .log + .select { |statement| Array.wrap(filter).all? { |regex| statement.match?(regex) } } + .tap { |result| expect(result).not_to be_empty } end end diff --git a/spec/models/operations/feature_flags/strategy_spec.rb b/spec/models/operations/feature_flags/strategy_spec.rb index 91a465025a2..6d55f94b496 100644 --- a/spec/models/operations/feature_flags/strategy_spec.rb +++ b/spec/models/operations/feature_flags/strategy_spec.rb @@ -29,7 +29,7 @@ RSpec.describe Operations::FeatureFlags::Strategy do expect(strategy).to be_invalid - expect(strategy.errors[:name]).to eq(['strategy name is invalid']) + expect(strategy.errors[:name]).to eq([s_('Validation|strategy name is invalid')]) expect(strategy.errors[:parameters]).to be_empty end end @@ -51,7 +51,7 @@ RSpec.describe Operations::FeatureFlags::Strategy do expect(strategy).to be_invalid - expect(strategy.errors[:parameters]).to eq(['parameters are invalid']) + expect(strategy.errors[:parameters]).to eq([s_('Validation|parameters are invalid')]) end end @@ -83,7 +83,9 @@ RSpec.describe Operations::FeatureFlags::Strategy do expect(strategy).to be_invalid - expect(strategy.errors[:parameters]).to eq(['percentage must be a string between 0 and 100 inclusive']) + expect(strategy.errors[:parameters]).to eq([ + s_('Validation|percentage must be a string between 0 and 100 inclusive') + ]) end end @@ -120,7 +122,7 @@ RSpec.describe Operations::FeatureFlags::Strategy do expect(strategy).to be_invalid - expect(strategy.errors[:parameters]).to eq(['groupId parameter is invalid']) + expect(strategy.errors[:parameters]).to eq([s_('Validation|groupId parameter is invalid')]) end end @@ -164,7 +166,7 @@ RSpec.describe Operations::FeatureFlags::Strategy do expect(strategy).to be_invalid - expect(strategy.errors[:parameters]).to eq(['parameters are invalid']) + expect(strategy.errors[:parameters]).to eq([s_('Validation|parameters are invalid')]) end end @@ -201,7 +203,9 @@ RSpec.describe Operations::FeatureFlags::Strategy do expect(strategy).to be_invalid - expect(strategy.errors[:parameters]).to eq(['rollout must be a string between 0 and 100 inclusive']) + expect(strategy.errors[:parameters]).to eq([ + s_('Validation|rollout must be a string between 0 and 100 inclusive') + ]) end end @@ -307,7 +311,7 @@ RSpec.describe Operations::FeatureFlags::Strategy do expect(strategy).to be_invalid - expect(strategy.errors[:parameters]).to eq(['parameters are invalid']) + expect(strategy.errors[:parameters]).to eq([s_('Validation|parameters are invalid')]) end end @@ -365,7 +369,7 @@ RSpec.describe Operations::FeatureFlags::Strategy do expect(strategy).to be_invalid - expect(strategy.errors[:parameters]).to eq(['parameters are invalid']) + expect(strategy.errors[:parameters]).to eq([s_('Validation|parameters are invalid')]) end end @@ -394,7 +398,7 @@ RSpec.describe Operations::FeatureFlags::Strategy do expect(strategy).to be_invalid - expect(strategy.errors[:parameters]).to eq(['parameters are invalid']) + expect(strategy.errors[:parameters]).to eq([s_('Validation|parameters are invalid')]) end end @@ -435,7 +439,7 @@ RSpec.describe Operations::FeatureFlags::Strategy do expect(strategy).to be_invalid - expect(strategy.errors[:user_list]).to eq(['must belong to the same project']) + expect(strategy.errors[:user_list]).to eq([s_('Validation|must belong to the same project')]) end end diff --git a/spec/serializers/stage_entity_spec.rb b/spec/serializers/stage_entity_spec.rb index 5cb5724ebdc..81cb89d0c38 100644 --- a/spec/serializers/stage_entity_spec.rb +++ b/spec/serializers/stage_entity_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' -RSpec.describe StageEntity do +RSpec.describe StageEntity, feature_category: :continuous_integration do let(:pipeline) { create(:ci_pipeline) } let(:request) { double('request') } let(:user) { create(:user) }