diff --git a/.eslintrc.yml b/.eslintrc.yml index d29af93319e..1dec5db472a 100644 --- a/.eslintrc.yml +++ b/.eslintrc.yml @@ -150,8 +150,7 @@ overrides: parser: '@graphql-eslint/eslint-plugin' operations: - '{,ee/,jh/}app/**/*.graphql' - # You can run `bundle exec rake gitlab:graphql:schema:dump` and then uncomment this line - # schema: './tmp/tests/graphql/gitlab_schema.graphql' + schema: './tmp/tests/graphql/gitlab_schema_apollo.graphql' rules: filenames/match-regex: off spaced-comment: off diff --git a/.gitlab/ci/static-analysis.gitlab-ci.yml b/.gitlab/ci/static-analysis.gitlab-ci.yml index f4cfdc1b1b9..e1257e778bd 100644 --- a/.gitlab/ci/static-analysis.gitlab-ci.yml +++ b/.gitlab/ci/static-analysis.gitlab-ci.yml @@ -76,7 +76,7 @@ eslint: USE_BUNDLE_INSTALL: "false" script: - run_timed_command "retry yarn install --frozen-lockfile" - - run_timed_command "yarn run lint:eslint:all --parser-options=schema:${GRAPHQL_SCHEMA_APOLLO_FILE}" + - run_timed_command "yarn run lint:eslint:all" eslint as-if-foss: extends: diff --git a/app/controllers/admin/groups_controller.rb b/app/controllers/admin/groups_controller.rb index 9abb244bc92..4d163824ef6 100644 --- a/app/controllers/admin/groups_controller.rb +++ b/app/controllers/admin/groups_controller.rb @@ -61,7 +61,7 @@ class Admin::GroupsController < Admin::ApplicationController end def members_update - member_params = params.permit(:user_ids, :access_level, :expires_at) + member_params = params.permit(:user_id, :access_level, :expires_at) result = Members::CreateService.new(current_user, member_params.merge(limit: -1, source: @group, invite_source: 'admin-group-page')).execute if result[:status] == :success diff --git a/app/services/members/create_service.rb b/app/services/members/create_service.rb index 8f7b63c32c8..8485e7cbafa 100644 --- a/app/services/members/create_service.rb +++ b/app/services/members/create_service.rb @@ -46,9 +46,11 @@ module Members :tasks_to_be_done_members, :member_created_member_task_id def invites_from_params - return params[:user_ids] if params[:user_ids].is_a?(Array) + # String, Nil, Array, Integer + return params[:user_id] if params[:user_id].is_a?(Array) + return [] unless params[:user_id] - params[:user_ids]&.to_s&.split(',')&.uniq&.flatten || [] + params[:user_id].to_s.split(',').uniq end def validate_invite_source! diff --git a/app/views/admin/groups/show.html.haml b/app/views/admin/groups/show.html.haml index 09f2d431197..39b2fa41c80 100644 --- a/app/views/admin/groups/show.html.haml +++ b/app/views/admin/groups/show.html.haml @@ -112,7 +112,7 @@ = form_tag admin_group_members_update_path(@group), id: "new_project_member", class: "bulk_import", method: :put do %div - = users_select_tag(:user_ids, multiple: true, email_user: true, skip_ldap: @group.ldap_synced?, scope: :all) + = users_select_tag(:user_id, multiple: true, email_user: true, skip_ldap: @group.ldap_synced?, scope: :all) .gl-mt-3 = select_tag :access_level, options_for_select(@group.access_level_roles), class: "project-access-select select2" %hr diff --git a/app/views/profiles/preferences/show.html.haml b/app/views/profiles/preferences/show.html.haml index 3fb48f3d3e3..8c799a5e3fe 100644 --- a/app/views/profiles/preferences/show.html.haml +++ b/app/views/profiles/preferences/show.html.haml @@ -127,7 +127,12 @@ = _('Language') = f.select :preferred_language, language_choices, {}, class: 'select2' .form-text.text-muted - = s_('Preferences|This feature is experimental and translations are not complete yet') + = s_('Preferences|This feature is experimental and translations are not yet complete.') + %p + = link_to help_page_url('development/i18n/translation'), class: 'text-nowrap', target: '_blank', rel: 'noopener noreferrer' do + = _("Help translate GitLab into your language") + %span{ aria: { label: _('Open new window') } } + = sprite_icon('external-link') .form-group = f.label :first_day_of_week, class: 'label-bold' do = _('First day of the week') diff --git a/app/workers/container_registry/migration/enqueuer_worker.rb b/app/workers/container_registry/migration/enqueuer_worker.rb index c960d74367d..a0babb98e82 100644 --- a/app/workers/container_registry/migration/enqueuer_worker.rb +++ b/app/workers/container_registry/migration/enqueuer_worker.rb @@ -150,7 +150,11 @@ module ContainerRegistry def next_repository strong_memoize(:next_repository) do - ContainerRepository.ready_for_import.take # rubocop:disable CodeReuse/ActiveRecord + # Using .limit(2)[0] instead of take here. Using a LIMIT 1 caused the query planner to + # use an inefficient sequential scan instead of picking an index. LIMIT 2 works around + # this issue. + # See https://gitlab.com/gitlab-org/gitlab/-/merge_requests/87733 for details. + ContainerRepository.ready_for_import.limit(2)[0] # rubocop:disable CodeReuse/ActiveRecord end end diff --git a/config/feature_flags/development/filter_quarantined_commits.yml b/config/feature_flags/development/filter_quarantined_commits.yml index 00696314298..2c18e83d947 100644 --- a/config/feature_flags/development/filter_quarantined_commits.yml +++ b/config/feature_flags/development/filter_quarantined_commits.yml @@ -5,4 +5,4 @@ rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/361174 milestone: '15.0' type: development group: group::gitaly -default_enabled: false +default_enabled: true diff --git a/config/feature_flags/development/geo_use_clone_on_first_sync.yml b/config/feature_flags/development/geo_use_clone_on_first_sync.yml index 6eb41ee2f56..ae9dcf9a7bb 100644 --- a/config/feature_flags/development/geo_use_clone_on_first_sync.yml +++ b/config/feature_flags/development/geo_use_clone_on_first_sync.yml @@ -5,4 +5,4 @@ rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/357462 milestone: '14.10' type: development group: group::geo -default_enabled: false +default_enabled: true diff --git a/data/removals/15_0/15-0-runner-disable-strict-host-key-check.yml b/data/removals/15_0/15-0-runner-disable-strict-host-key-check.yml new file mode 100644 index 00000000000..384d025ad66 --- /dev/null +++ b/data/removals/15_0/15-0-runner-disable-strict-host-key-check.yml @@ -0,0 +1,14 @@ +- name: "Known host required for GitLab Runner SSH executor" + announcement_milestone: "14.5" # The milestone when this feature was first announced as deprecated. + removal_milestone: "15.0" # the milestone when this feature is planned to be removed + removal_date: "2022-05-22" + breaking_change: true + body: | # Do not modify this line, instead modify the lines below. + In [GitLab 14.3](https://gitlab.com/gitlab-org/gitlab-runner/-/merge_requests/3074), we added a configuration setting in the GitLab Runner `config.toml`. This setting, [`[runners.ssh.disable_strict_host_key_checking]`](https://docs.gitlab.com/runner/executors/ssh.html#security), controls whether or not to use strict host key checking with the SSH executor. + + In GitLab 15.0, the default value for this configuration option has changed from `true` to `false`. This means that strict host key checking will be enforced when using the GitLab Runner SSH executor. + stage: Verify + tiers: [Core, Premium, Ultimate] + issue_url: https://gitlab.com/gitlab-org/gitlab-runner/-/issues/28192 + documentation_url: https://docs.gitlab.com/runner/executors/ssh.html#security + announcement_date: "2021-11-22" diff --git a/db/post_migrate/20220502173045_reset_too_many_tags_skipped_registry_imports.rb b/db/post_migrate/20220502173045_reset_too_many_tags_skipped_registry_imports.rb new file mode 100644 index 00000000000..e327035d6c9 --- /dev/null +++ b/db/post_migrate/20220502173045_reset_too_many_tags_skipped_registry_imports.rb @@ -0,0 +1,27 @@ +# frozen_string_literal: true + +class ResetTooManyTagsSkippedRegistryImports < Gitlab::Database::Migration[2.0] + MIGRATION = 'ResetTooManyTagsSkippedRegistryImports' + DELAY_INTERVAL = 2.minutes.to_i + BATCH_SIZE = 10_000 + + disable_ddl_transaction! + restrict_gitlab_migration gitlab_schema: :gitlab_main + + def up + queue_background_migration_jobs_by_range_at_intervals( + define_batchable_model('container_repositories').where( + migration_state: 'import_skipped', + migration_skipped_reason: 2 + ), + MIGRATION, + DELAY_INTERVAL, + batch_size: BATCH_SIZE, + track_jobs: true + ) + end + + def down + # no-op + end +end diff --git a/db/schema_migrations/20220502173045 b/db/schema_migrations/20220502173045 new file mode 100644 index 00000000000..d17f403df8d --- /dev/null +++ b/db/schema_migrations/20220502173045 @@ -0,0 +1 @@ +893f211ebd0dceae4e375e644ed6213a066fe8b5985f226f5f256651fdd4b483 \ No newline at end of file diff --git a/doc/.vale/gitlab/SubstitutionWarning.yml b/doc/.vale/gitlab/SubstitutionWarning.yml index 5272523775c..d17015b97fd 100644 --- a/doc/.vale/gitlab/SubstitutionWarning.yml +++ b/doc/.vale/gitlab/SubstitutionWarning.yml @@ -23,6 +23,7 @@ swap: filesystem: file system GFM: GLFM info: information + n/a: not applicable repo: repository timezone: time zone utilize: use diff --git a/doc/ci/pipelines/merge_request_pipelines.md b/doc/ci/pipelines/merge_request_pipelines.md index 77513dcdf04..89839de718b 100644 --- a/doc/ci/pipelines/merge_request_pipelines.md +++ b/doc/ci/pipelines/merge_request_pipelines.md @@ -127,12 +127,12 @@ Pipelines for forks display with the **fork** badge in the parent project: ### Run pipelines in the parent project **(PREMIUM)** -Project members in the parent project can choose to run a merge request pipeline +Project members in the parent project can trigger a merge request pipeline for a merge request submitted from a fork project. This pipeline: - Is created and runs in the parent (target) project, not the fork (source) project. -- Uses the CI/CD configuration present in the fork project's branch -- Uses the parent project's CI/CD configuration, resources, and project CI/CD variables. +- Uses the CI/CD configuration present in the fork project's branch. +- Uses the parent project's CI/CD settings, resources, and project CI/CD variables. - Uses the permissions of the parent project member that triggers the pipeline. Run pipelines in fork project MRs to ensure that the post-merge pipeline passes in @@ -142,8 +142,12 @@ running the pipeline in the parent project uses the parent project's trusted run WARNING: Fork merge requests can contain malicious code that tries to steal secrets in the parent project when the pipeline runs, even before merge. As a reviewer, carefully -check the changes in the merge request before triggering the pipeline. GitLab shows -a warning that you must accept before you can trigger the pipeline. +check the changes in the merge request before triggering the pipeline. If you trigger +the pipeline by selecting **Run pipeline** or applying a suggestion, GitLab shows +a warning that you must accept before the pipeline runs. If you trigger the pipeline +by using any other method, including the API, [`/rebase` quick action](../../user/project/quick_actions.md#issues-merge-requests-and-epics), +or [**Rebase** option](../../user/project/merge_requests/methods/index.md#rebasing-in-semi-linear-merge-methods), +**no warning displays**. Prerequisites: @@ -152,10 +156,10 @@ Prerequisites: user running the pipeline. Otherwise, the **Pipelines** tab does not display in the merge request. -To run a pipeline in the parent project for a merge request from a fork project: +To use the UI to run a pipeline in the parent project for a merge request from a fork project: 1. In the merge request, go to the **Pipelines** tab. -1. Select **Run pipeline**. You must accept the warning, or the pipeline does not run. +1. Select **Run pipeline**. You must read and accept the warning, or the pipeline does not run. ## Available predefined variables diff --git a/doc/development/fe_guide/tooling.md b/doc/development/fe_guide/tooling.md index 1ab97d8a1f5..1c32647eefd 100644 --- a/doc/development/fe_guide/tooling.md +++ b/doc/development/fe_guide/tooling.md @@ -155,6 +155,13 @@ $ grep "eslint-disable.*import/no-deprecated" -r . ./app/assets/javascripts/issuable_form.js: // eslint-disable-next-line import/no-deprecated ``` +### GraphQL schema and operations validation + +We use [`@graphql-eslint/eslint-plugin`](https://www.npmjs.com/package/@graphql-eslint/eslint-plugin) +to lint GraphQL schema and operations. This plugin requires the entire schema to function properly. +It is thus recommended to generate an up-to-date dump of the schema when running ESLint locally. +You can do this by running the `./scripts/dump_graphql_schema` script. + ## Formatting with Prettier > Support for `.graphql` [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/227280) in GitLab 13.2. diff --git a/doc/integration/gitpod.md b/doc/integration/gitpod.md index f54542ff43f..84294a99ef9 100644 --- a/doc/integration/gitpod.md +++ b/doc/integration/gitpod.md @@ -61,7 +61,7 @@ Your users can then [enable it for themselves](#enable-gitpod-in-your-user-setti You can launch Gitpod directly from GitLab in one of these ways: - *From your project's page:* - 1. Go to your project, and navigate to the page you want to edit. + 1. Go to your project, then go to the page you want to edit. 1. Select the caret **(angle-down)** next to **Web IDE**, and select **Gitpod** from the list: @@ -69,13 +69,7 @@ You can launch Gitpod directly from GitLab in one of these ways: 1. Select **Open in Gitpod**. - *From a merge request:* - 1. Go to your merge request, and select **Overview** in the tab menu. - 1. Scroll to the end of the merge request description. - 1. Select the caret **(angle-down)** next to **Web IDE**, then select **Gitpod** - from the list: - - ![Gitpod button on the merge request page](img/gitpod-button_v14_2.png) - - 1. Select **Open in Gitpod**. + 1. Go to your merge request. + 1. In the upper right corner, select **Code**, then select **Open in Gitpod**. Gitpod builds your development environment for your branch. diff --git a/doc/integration/img/gitpod-button_v14_2.png b/doc/integration/img/gitpod-button_v14_2.png deleted file mode 100644 index 04dd5b50a7f..00000000000 Binary files a/doc/integration/img/gitpod-button_v14_2.png and /dev/null differ diff --git a/doc/policy/alpha-beta-support.md b/doc/policy/alpha-beta-support.md index ba988b38af2..1e3b591735c 100644 --- a/doc/policy/alpha-beta-support.md +++ b/doc/policy/alpha-beta-support.md @@ -6,7 +6,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w -# Support for Alpha, Beta, and Generally Available Features **(PREMIUM)** +# Support for Alpha, Beta, Limited Availability, and Generally Available Features **(PREMIUM)** Some GitLab features are released as [Alpha or Beta versions](https://about.gitlab.com/support/statement-of-support.html#alpha--beta-features) which are not fully supported. All other features are considered to be Generally Available (GA). @@ -34,6 +34,14 @@ Characteristics of beta features: Your Support Contract provides **commercially-reasonable effort** support for Beta features, with the expectation that issues will require extra time and assistance from development to troubleshoot. +## Limited Availability (LA) + +Characteristics of limited availability features: + +- Ready for production use by a small set of customers. +- Can be booked by Deal Desk as part of an order. +- Fully documented and [supported](https://about.gitlab.com/support/statement-of-support/#starter-premium-and-ultimate-users). + ## Generally Available (GA) Generally Available features means that they passed the [Production Readiness Review](https://gitlab.com/gitlab-com/gl-infra/readiness/-/blob/master/.gitlab/issue_templates/production_readiness.md) for GitLab.com, and are: diff --git a/doc/topics/autodevops/quick_start_guide.md b/doc/topics/autodevops/quick_start_guide.md index 13d831aa00d..8d1bf7adc7f 100644 --- a/doc/topics/autodevops/quick_start_guide.md +++ b/doc/topics/autodevops/quick_start_guide.md @@ -296,7 +296,8 @@ bin/rails test test/controllers/welcome_controller_test.rb:4 To fix the broken test: -1. Return to the **Overview** page for your merge request, and select **Open in Web IDE**. +1. Return to your merge request. +1. In the upper right corner, select **Code**, then select **Open in Gitpod**. 1. In the left-hand directory of files, find the `test/controllers/welcome_controller_test.rb` file, and select it to open it. 1. Change line 7 to say `You're on Rails! Powered by GitLab Auto DevOps.` diff --git a/doc/update/index.md b/doc/update/index.md index 0273b8dd2e9..24afb01396a 100644 --- a/doc/update/index.md +++ b/doc/update/index.md @@ -406,6 +406,10 @@ NOTE: Specific information that follow related to Ruby and Git versions do not apply to [Omnibus installations](https://docs.gitlab.com/omnibus/) and [Helm Chart deployments](https://docs.gitlab.com/charts/). They come with appropriate Ruby and Git versions and are not using system binaries for Ruby and Git. There is no need to install Ruby or Git when utilizing these two approaches. +### 15.0.0 + +- Elasticsearch 6.8 [is no longer supported](../integration/elasticsearch.md#version-requirements). Before you upgrade to GitLab 15.0, [update Elasticsearch to any 7.x version](../integration/elasticsearch.md#upgrade-to-a-new-elasticsearch-major-version). + ### 14.10.0 - Before upgrading to GitLab 14.10, you need to already have the latest 14.9.Z installed on your instance. diff --git a/doc/update/removals.md b/doc/update/removals.md index 73f89be8c4f..c6924388999 100644 --- a/doc/update/removals.md +++ b/doc/update/removals.md @@ -253,6 +253,18 @@ changes to your code, settings, or workflow. Tracing in GitLab is an integration with Jaeger, an open-source end-to-end distributed tracing system. GitLab users could previously navigate to their Jaeger instance to gain insight into the performance of a deployed application, tracking each function or microservice that handles a given request. Tracing in GitLab was deprecated in GitLab 14.7, and removed in 15.0. To track work on a possible replacement, see the issue for [Opstrace integration with GitLab](https://gitlab.com/groups/gitlab-org/-/epics/6976). +### Known host required for GitLab Runner SSH executor + +WARNING: +This feature was changed or removed in 15.0 +as a [breaking change](https://docs.gitlab.com/ee/development/contributing/#breaking-changes). +Before updating GitLab, review the details carefully to determine if you need to make any +changes to your code, settings, or workflow. + +In [GitLab 14.3](https://gitlab.com/gitlab-org/gitlab-runner/-/merge_requests/3074), we added a configuration setting in the GitLab Runner `config.toml`. This setting, [`[runners.ssh.disable_strict_host_key_checking]`](https://docs.gitlab.com/runner/executors/ssh.html#security), controls whether or not to use strict host key checking with the SSH executor. + +In GitLab 15.0, the default value for this configuration option has changed from `true` to `false`. This means that strict host key checking will be enforced when using the GitLab Runner SSH executor. + ### Legacy Geo Admin UI routes In GitLab 13.0, we introduced new project and design replication details routes in the Geo Admin UI. These routes are `/admin/geo/replication/projects` and `/admin/geo/replication/designs`. We kept the legacy routes and redirected them to the new routes. These legacy routes `/admin/geo/projects` and `/admin/geo/designs` have been removed in GitLab 15.0. Please update any bookmarks or scripts that may use the legacy routes. diff --git a/doc/user/project/merge_requests/allow_collaboration.md b/doc/user/project/merge_requests/allow_collaboration.md index 5826ebcab49..d06c8182e22 100644 --- a/doc/user/project/merge_requests/allow_collaboration.md +++ b/doc/user/project/merge_requests/allow_collaboration.md @@ -60,10 +60,10 @@ In the following example: To change or add a commit to the contributor's merge request: -1. Open the merge request page, and select the **Overview** tab. -1. Scroll to the merge request widget, and select **Check out branch**. +1. Go to the merge request. +1. In the upper right corner, select **Code**, then select **Check out branch**. 1. In the modal window, select **Copy** (**{copy-to-clipboard}**). -1. In your terminal, navigate to your cloned version of the repository, and +1. In your terminal, go to your cloned version of the repository, and paste the commands. For example: ```shell diff --git a/doc/user/project/web_ide/index.md b/doc/user/project/web_ide/index.md index 96d01c7c2be..9db30ee2ab6 100644 --- a/doc/user/project/web_ide/index.md +++ b/doc/user/project/web_ide/index.md @@ -23,13 +23,8 @@ and from merge requests: 1. Select **Open in Web IDE** from the list to display it as the editing option. 1. Select **Open in Web IDE** to open the editor. - *When viewing a merge request* - - 1. Go to your merge request, and select the **Overview** tab. - 1. Scroll to the widgets section, after the merge request description. - 1. Select **Open in Web IDE** if it is visible. - 1. If **Open in Web IDE** is not visible: - 1. Select the **(angle-down)** next to **Open in Gitpod**. - 1. Select **Open in Web IDE** from the list to display it as the editing option. - 1. Select **Open in Web IDE** to open the editor. + 1. Go to your merge request. + 1. In the upper right corner, select **Code**, then select **Open in Gitpod**. ## File finder diff --git a/lib/api/helpers/members_helpers.rb b/lib/api/helpers/members_helpers.rb index f26ac1318b1..c91e153c7b9 100644 --- a/lib/api/helpers/members_helpers.rb +++ b/lib/api/helpers/members_helpers.rb @@ -63,7 +63,7 @@ module API def add_single_member_by_user_id(create_service_params) source = create_service_params[:source] - user_id = create_service_params[:user_ids] + user_id = create_service_params[:user_id] user = User.find_by(id: user_id) # rubocop: disable CodeReuse/ActiveRecord if user diff --git a/lib/api/invitations.rb b/lib/api/invitations.rb index 53c3e7403bb..6fb3eca0ba8 100644 --- a/lib/api/invitations.rb +++ b/lib/api/invitations.rb @@ -36,7 +36,7 @@ module API source = find_source(source_type, params[:id]) authorize_admin_source!(source_type, source) - create_service_params = params.except(:user_id).merge({ user_ids: params[:user_id], source: source }) + create_service_params = params.merge(source: source) ::Members::InviteService.new(current_user, create_service_params).execute end diff --git a/lib/api/members.rb b/lib/api/members.rb index fbac6a96c1e..e2045c6def7 100644 --- a/lib/api/members.rb +++ b/lib/api/members.rb @@ -106,12 +106,11 @@ module API source = find_source(source_type, params[:id]) authorize_admin_source!(source_type, source) - user_id = params[:user_id].to_s - create_service_params = params.except(:user_id).merge({ user_ids: user_id, source: source }) + create_service_params = params.merge(source: source) - if add_multiple_members?(user_id) + if add_multiple_members?(params[:user_id].to_s) ::Members::CreateService.new(current_user, create_service_params).execute - elsif add_single_member?(user_id) + elsif add_single_member?(params[:user_id].to_s) add_single_member_by_user_id(create_service_params) end end diff --git a/lib/gitlab/background_migration/reset_too_many_tags_skipped_registry_imports.rb b/lib/gitlab/background_migration/reset_too_many_tags_skipped_registry_imports.rb new file mode 100644 index 00000000000..83a7eb0b4cc --- /dev/null +++ b/lib/gitlab/background_migration/reset_too_many_tags_skipped_registry_imports.rb @@ -0,0 +1,45 @@ +# frozen_string_literal: true + +module Gitlab + module BackgroundMigration + # A job to reset container_repositories that were skipped in the phase 2 registry + # migration due to too many tags. + class ResetTooManyTagsSkippedRegistryImports # rubocop:disable Migration/BackgroundMigrationBaseClass + class ContainerRepository < ::ApplicationRecord # rubocop:disable Style/Documentation + include EachBatch + + self.table_name = 'container_repositories' + + scope :base_query, -> { where(migration_state: 'import_skipped', migration_skipped_reason: 2) } + end + + def perform(start_id, end_id) + ContainerRepository.base_query.where(id: start_id..end_id).each_batch(of: 100) do |sub_batch| + sub_batch.update_all( + migration_pre_import_started_at: nil, + migration_pre_import_done_at: nil, + migration_import_started_at: nil, + migration_import_done_at: nil, + migration_aborted_at: nil, + migration_skipped_at: nil, + migration_retries_count: 0, + migration_skipped_reason: nil, + migration_state: 'default', + migration_aborted_in_state: nil + ) + end + + mark_job_as_succeeded(start_id, end_id) + end + + private + + def mark_job_as_succeeded(*arguments) + ::Gitlab::Database::BackgroundMigrationJob.mark_all_as_succeeded( + self.class.name.demodulize, + arguments + ) + end + end + end +end diff --git a/locale/gitlab.pot b/locale/gitlab.pot index ac085946e36..96137675f03 100644 --- a/locale/gitlab.pot +++ b/locale/gitlab.pot @@ -6040,6 +6040,9 @@ msgstr "" msgid "Billings|Validate user account" msgstr "" +msgid "Billings|You can't change the seat status of a user who was invited via a group or project." +msgstr "" + msgid "Billings|You'll now be able to take advantage of free CI/CD minutes on shared runners." msgstr "" @@ -18714,6 +18717,9 @@ msgstr "" msgid "Help" msgstr "" +msgid "Help translate GitLab into your language" +msgstr "" + msgid "Helps prevent bots from brute-force attacks." msgstr "" @@ -18916,9 +18922,6 @@ msgstr "" msgid "How do I use file templates?" msgstr "" -msgid "How many days need to pass between marking entity for deletion and actual removing it." -msgstr "" - msgid "How many seconds an IP counts toward the IP address limit." msgstr "" @@ -26588,6 +26591,9 @@ msgstr "" msgid "Open in your IDE" msgstr "" +msgid "Open new window" +msgstr "" + msgid "Open raw" msgstr "" @@ -28678,7 +28684,7 @@ msgstr "" msgid "Preferences|Tab width" msgstr "" -msgid "Preferences|This feature is experimental and translations are not complete yet" +msgid "Preferences|This feature is experimental and translations are not yet complete." msgstr "" msgid "Preferences|This setting allows you to customize the appearance of the syntax." @@ -37923,6 +37929,9 @@ msgstr "" msgid "The number of changes to fetch from GitLab when cloning a repository. Lower values can speed up pipeline execution. Set to %{code_open}0%{code_close} or blank to fetch all branches and tags for each job" msgstr "" +msgid "The number of days that must pass between marking an entity for deletion and actually removing it. The delay can be between 0 and 90 days." +msgstr "" + msgid "The number of merge requests merged by month." msgstr "" diff --git a/package.json b/package.json index 90c4767fc86..73778428426 100644 --- a/package.json +++ b/package.json @@ -17,11 +17,11 @@ "jest:ci:minimal": "jest --config jest.config.js --ci --coverage --findRelatedTests $(cat tmp/changed_files.txt) --passWithNoTests --testSequencer ./scripts/frontend/parallel_ci_sequencer.js", "jest:integration": "jest --config jest.config.integration.js", "jsdoc": "jsdoc -c config/jsdocs.config.js", - "lint:eslint": "yarn run internal:eslint", - "lint:eslint:fix": "yarn run internal:eslint --fix", - "lint:eslint:all": "yarn run internal:eslint .", + "lint:eslint": "node scripts/frontend/eslint.js", + "lint:eslint:fix": "node scripts/frontend/eslint.js --fix", + "lint:eslint:all": "node scripts/frontend/eslint.js .", "lint:eslint:all:fix": "yarn run lint:eslint:all --fix", - "lint:eslint:report": "yarn run internal:eslint --format html --output-file ./eslint-report.html --no-inline-config .", + "lint:eslint:report": "node scripts/frontend/eslint.js --format html --output-file ./eslint-report.html --no-inline-config .", "lint:eslint:staged": "scripts/frontend/execute-on-staged-files.sh internal:eslint '(js|vue)'", "lint:eslint:staged:fix": "yarn run lint:eslint:staged --fix", "lint:prettier": "yarn run prettier --check '**/*.{graphql,js,vue}'", diff --git a/scripts/dump_graphql_schema b/scripts/dump_graphql_schema new file mode 100755 index 00000000000..7a8bd5652e1 --- /dev/null +++ b/scripts/dump_graphql_schema @@ -0,0 +1,25 @@ +#!/usr/bin/env bash + +GITLAB_DIR="$(cd "$(dirname "$0")/.." || exit ; pwd -P)" +DOCKER_IMAGE="registry.gitlab.com/gitlab-org/gitlab-build-images:apollo" +CONFIG_FILE="config/apollo.config.js" +SCHEMA_DUMP_PATH="tmp/tests/graphql/gitlab_schema_apollo.graphql" + +if [ "$CI" = true ]; then + echo "Not dumping the GraphQL schema in CI" +else + echo "Dumping GraphQL schema" + cd "$GITLAB_DIR" || exit 1 + if command -v docker >/dev/null; then + bundle exec rake gitlab:graphql:schema:dump && + docker run --rm -it \ + -v "$GITLAB_DIR/config":/config \ + -v "$GITLAB_DIR/tmp":/tmp \ + -v "$GITLAB_DIR/app":/app \ + -v "$GITLAB_DIR/ee":/ee \ + "$DOCKER_IMAGE" client:download-schema --config="$CONFIG_FILE" "$SCHEMA_DUMP_PATH" + else + echo "Docker must be installed to run this script." + exit 1 + fi +fi diff --git a/scripts/frontend/eslint.js b/scripts/frontend/eslint.js new file mode 100644 index 00000000000..2ba5976d1b9 --- /dev/null +++ b/scripts/frontend/eslint.js @@ -0,0 +1,22 @@ +const { spawn } = require('child_process'); + +const runEslint = () => { + const [, , ...args] = process.argv; + const child = spawn(`yarn`, ['internal:eslint', ...args], { + stdio: 'inherit', + }); + + child.on('exit', (code) => { + process.exitCode = code; + + if (code === 0) { + return; + } + console.log(` +If you are seeing @graphql-eslint offences, the local GraphQL schema dump might be outdated. +Consider updating it by running \`./scripts/dump_graphql_schema\`. + `); + }); +}; + +runEslint(); diff --git a/spec/controllers/admin/groups_controller_spec.rb b/spec/controllers/admin/groups_controller_spec.rb index d9b7e00fd75..fb843ac6a7a 100644 --- a/spec/controllers/admin/groups_controller_spec.rb +++ b/spec/controllers/admin/groups_controller_spec.rb @@ -51,7 +51,7 @@ RSpec.describe Admin::GroupsController do it 'adds user to members', :aggregate_failures, :snowplow do put :members_update, params: { id: group, - user_ids: group_user.id, + user_id: group_user.id, access_level: Gitlab::Access::GUEST } @@ -70,7 +70,7 @@ RSpec.describe Admin::GroupsController do it 'can add unlimited members', :aggregate_failures do put :members_update, params: { id: group, - user_ids: 1.upto(1000).to_a.join(','), + user_id: 1.upto(1000).to_a.join(','), access_level: Gitlab::Access::GUEST } @@ -81,7 +81,7 @@ RSpec.describe Admin::GroupsController do it 'adds no user to members', :aggregate_failures do put :members_update, params: { id: group, - user_ids: '', + user_id: '', access_level: Gitlab::Access::GUEST } diff --git a/spec/features/admin/admin_groups_spec.rb b/spec/features/admin/admin_groups_spec.rb index 3b3289a8487..90dde7340d5 100644 --- a/spec/features/admin/admin_groups_spec.rb +++ b/spec/features/admin/admin_groups_spec.rb @@ -212,7 +212,7 @@ RSpec.describe 'Admin Groups' do it do visit admin_group_path(group) - select2(user_selector, from: '#user_ids', multiple: true) + select2(user_selector, from: '#user_id', multiple: true) page.within '#new_project_member' do select2(Gitlab::Access::REPORTER, from: '#access_level') end diff --git a/spec/lib/gitlab/background_migration/reset_too_many_tags_skipped_registry_imports_spec.rb b/spec/lib/gitlab/background_migration/reset_too_many_tags_skipped_registry_imports_spec.rb new file mode 100644 index 00000000000..3f59b0a24a3 --- /dev/null +++ b/spec/lib/gitlab/background_migration/reset_too_many_tags_skipped_registry_imports_spec.rb @@ -0,0 +1,85 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe Gitlab::BackgroundMigration::ResetTooManyTagsSkippedRegistryImports, :migration, + :aggregate_failures, + schema: 20220502173045 do + let(:namespaces) { table(:namespaces) } + let(:projects) { table(:projects) } + let(:container_repositories) { table(:container_repositories) } + + subject(:background_migration) { described_class.new } + + let!(:namespace) { namespaces.create!(id: 1, path: 'foo', name: 'foo') } + let!(:project) { projects.create!(id: 1, project_namespace_id: 1, namespace_id: 1, path: 'bar', name: 'bar') } + + let!(:container_repository1) do + container_repositories.create!(id: 1, + project_id: 1, + name: 'a', + migration_state: 'import_skipped', + migration_skipped_at: Time.zone.now, + migration_skipped_reason: 2, + migration_pre_import_started_at: Time.zone.now, + migration_pre_import_done_at: Time.zone.now, + migration_import_started_at: Time.zone.now, + migration_import_done_at: Time.zone.now, + migration_aborted_at: Time.zone.now, + migration_retries_count: 2, + migration_aborted_in_state: 'importing') + end + + let!(:container_repository2) do + container_repositories.create!(id: 2, + project_id: 1, + name: 'b', + migration_state: 'import_skipped', + migration_skipped_at: Time.zone.now, + migration_skipped_reason: 2) + end + + let!(:container_repository3) do + container_repositories.create!(id: 3, + project_id: 1, + name: 'c', + migration_state: 'import_skipped', + migration_skipped_at: Time.zone.now, + migration_skipped_reason: 1) + end + + # This is an unlikely state, but included here to test the edge case + let!(:container_repository4) do + container_repositories.create!(id: 4, + project_id: 1, + name: 'd', + migration_state: 'default', + migration_skipped_reason: 2) + end + + describe '#up' do + it 'resets only qualified container repositories', :aggregate_failures do + background_migration.perform(1, 4) + + expect(container_repository1.reload.migration_state).to eq('default') + expect(container_repository1.migration_skipped_reason).to eq(nil) + expect(container_repository1.migration_pre_import_started_at).to eq(nil) + expect(container_repository1.migration_pre_import_done_at).to eq(nil) + expect(container_repository1.migration_import_started_at).to eq(nil) + expect(container_repository1.migration_import_done_at).to eq(nil) + expect(container_repository1.migration_aborted_at).to eq(nil) + expect(container_repository1.migration_skipped_at).to eq(nil) + expect(container_repository1.migration_retries_count).to eq(0) + expect(container_repository1.migration_aborted_in_state).to eq(nil) + + expect(container_repository2.reload.migration_state).to eq('default') + expect(container_repository2.migration_skipped_reason).to eq(nil) + + expect(container_repository3.reload.migration_state).to eq('import_skipped') + expect(container_repository3.migration_skipped_reason).to eq(1) + + expect(container_repository4.reload.migration_state).to eq('default') + expect(container_repository4.migration_skipped_reason).to eq(2) + end + end +end diff --git a/spec/migrations/20220502173045_reset_too_many_tags_skipped_registry_imports_spec.rb b/spec/migrations/20220502173045_reset_too_many_tags_skipped_registry_imports_spec.rb new file mode 100644 index 00000000000..cc4041fe151 --- /dev/null +++ b/spec/migrations/20220502173045_reset_too_many_tags_skipped_registry_imports_spec.rb @@ -0,0 +1,68 @@ +# frozen_string_literal: true + +require 'spec_helper' +require_migration! + +RSpec.describe ResetTooManyTagsSkippedRegistryImports, :aggregate_failures do + let(:migration) { described_class::MIGRATION } + let(:namespaces) { table(:namespaces) } + let(:projects) { table(:projects) } + let(:container_repositories) { table(:container_repositories) } + + let!(:namespace) { namespaces.create!(id: 1, name: 'namespace', path: 'namespace') } + let!(:project) { projects.create!(id: 1, name: 'project', path: 'project', project_namespace_id: 1, namespace_id: 1) } + + let!(:container_repository1) do + container_repositories.create!( + name: 'container_repository1', + project_id: 1, + migration_state: 'import_skipped', + migration_skipped_reason: 2 + ) + end + + let!(:container_repository2) do + container_repositories.create!( + name: 'container_repository2', + project_id: 1, + migration_state: 'import_skipped', + migration_skipped_reason: 2 + ) + end + + let!(:container_repository3) do + container_repositories.create!( + name: 'container_repository3', + project_id: 1, + migration_state: 'import_skipped', + migration_skipped_reason: 2 + ) + end + + # this should not qualify for the migration + let!(:container_repository4) do + container_repositories.create!( + name: 'container_repository4', + project_id: 1, + migration_state: 'default' + ) + end + + before do + stub_const("#{described_class.name}::BATCH_SIZE", 2) + end + + it 'schedules jobs to reset skipped registry imports' do + Sidekiq::Testing.fake! do + freeze_time do + migrate! + + expect(migration).to be_scheduled_delayed_migration( + 2.minutes, container_repository1.id, container_repository2.id) + expect(migration).to be_scheduled_delayed_migration( + 4.minutes, container_repository3.id, container_repository3.id) + expect(BackgroundMigrationWorker.jobs.size).to eq(2) + end + end + end +end diff --git a/spec/services/members/create_service_spec.rb b/spec/services/members/create_service_spec.rb index 25437be1e78..730175af0bb 100644 --- a/spec/services/members/create_service_spec.rb +++ b/spec/services/members/create_service_spec.rb @@ -7,11 +7,11 @@ RSpec.describe Members::CreateService, :aggregate_failures, :clean_gitlab_redis_ let_it_be(:user) { create(:user) } let_it_be(:member) { create(:user) } let_it_be(:user_invited_by_id) { create(:user) } - let_it_be(:user_ids) { member.id.to_s } + let_it_be(:user_id) { member.id.to_s } let_it_be(:access_level) { Gitlab::Access::GUEST } let(:additional_params) { { invite_source: '_invite_source_' } } - let(:params) { { user_ids: user_ids, access_level: access_level }.merge(additional_params) } + let(:params) { { user_id: user_id, access_level: access_level }.merge(additional_params) } let(:current_user) { user } subject(:execute_service) { described_class.new(current_user, params.merge({ source: source })).execute } @@ -51,7 +51,7 @@ RSpec.describe Members::CreateService, :aggregate_failures, :clean_gitlab_redis_ end context 'when user_id is passed as an integer' do - let(:user_ids) { member.id } + let(:user_id) { member.id } it 'successfully creates member' do expect(execute_service[:status]).to eq(:success) @@ -60,8 +60,8 @@ RSpec.describe Members::CreateService, :aggregate_failures, :clean_gitlab_redis_ end end - context 'with user_ids as an array of integers' do - let(:user_ids) { [member.id, user_invited_by_id.id] } + context 'with user_id as an array of integers' do + let(:user_id) { [member.id, user_invited_by_id.id] } it 'successfully creates members' do expect(execute_service[:status]).to eq(:success) @@ -70,8 +70,8 @@ RSpec.describe Members::CreateService, :aggregate_failures, :clean_gitlab_redis_ end end - context 'with user_ids as an array of strings' do - let(:user_ids) { [member.id.to_s, user_invited_by_id.id.to_s] } + context 'with user_id as an array of strings' do + let(:user_id) { [member.id.to_s, user_invited_by_id.id.to_s] } it 'successfully creates members' do expect(execute_service[:status]).to eq(:success) @@ -101,7 +101,7 @@ RSpec.describe Members::CreateService, :aggregate_failures, :clean_gitlab_redis_ end context 'when passing no user ids' do - let(:user_ids) { '' } + let(:user_id) { '' } it 'does not add a member' do expect(execute_service[:status]).to eq(:error) @@ -112,7 +112,7 @@ RSpec.describe Members::CreateService, :aggregate_failures, :clean_gitlab_redis_ end context 'when passing many user ids' do - let(:user_ids) { 1.upto(101).to_a.join(',') } + let(:user_id) { 1.upto(101).to_a.join(',') } it 'limits the number of users to 100' do expect(execute_service[:status]).to eq(:error) @@ -134,7 +134,7 @@ RSpec.describe Members::CreateService, :aggregate_failures, :clean_gitlab_redis_ end context 'when passing an existing invite user id' do - let(:user_ids) { create(:project_member, :invited, project: source).invite_email } + let(:user_id) { create(:project_member, :invited, project: source).invite_email } it 'does not add a member' do expect(execute_service[:status]).to eq(:error) @@ -146,7 +146,7 @@ RSpec.describe Members::CreateService, :aggregate_failures, :clean_gitlab_redis_ context 'when adding a project_bot' do let_it_be(:project_bot) { create(:user, :project_bot) } - let(:user_ids) { project_bot.id } + let(:user_id) { project_bot.id } context 'when project_bot is already a member' do before do @@ -213,7 +213,7 @@ RSpec.describe Members::CreateService, :aggregate_failures, :clean_gitlab_redis_ end context 'when it is a net_new_user' do - let(:additional_params) { { invite_source: '_invite_source_', user_ids: 'email@example.org' } } + let(:additional_params) { { invite_source: '_invite_source_', user_id: 'email@example.org' } } it 'tracks the invite source from params' do execute_service @@ -248,8 +248,8 @@ RSpec.describe Members::CreateService, :aggregate_failures, :clean_gitlab_redis_ ) end - context 'when it is an invite by email passed to user_ids' do - let(:user_ids) { 'email@example.org' } + context 'when it is an invite by email passed to user_id' do + let(:user_id) { 'email@example.org' } it 'does not create task issues' do expect(TasksToBeDone::CreateWorker).not_to receive(:perform_async) @@ -263,7 +263,7 @@ RSpec.describe Members::CreateService, :aggregate_failures, :clean_gitlab_redis_ end let(:another_user) { create(:user) } - let(:user_ids) { [member.id, another_user.id].join(',') } + let(:user_id) { [member.id, another_user.id].join(',') } it 'still creates 2 task issues', :aggregate_failures do expect(TasksToBeDone::CreateWorker) @@ -326,7 +326,7 @@ RSpec.describe Members::CreateService, :aggregate_failures, :clean_gitlab_redis_ end context 'when a member was already invited' do - let(:user_ids) { create(:project_member, :invited, project: source).invite_email } + let(:user_id) { create(:project_member, :invited, project: source).invite_email } let(:additional_params) do { invite_source: '_invite_source_', tasks_project_id: source.id, tasks_to_be_done: %w(ci code) } end diff --git a/spec/services/members/invite_service_spec.rb b/spec/services/members/invite_service_spec.rb index ab740138a8b..8213e8baae0 100644 --- a/spec/services/members/invite_service_spec.rb +++ b/spec/services/members/invite_service_spec.rb @@ -52,8 +52,8 @@ RSpec.describe Members::InviteService, :aggregate_failures, :clean_gitlab_redis_ end end - context 'with user_ids as integers' do - let(:params) { { user_ids: [project_user.id, user_invited_by_id.id] } } + context 'with user_id as integers' do + let(:params) { { user_id: [project_user.id, user_invited_by_id.id] } } it 'successfully creates members' do expect_to_create_members(count: 2) @@ -61,8 +61,8 @@ RSpec.describe Members::InviteService, :aggregate_failures, :clean_gitlab_redis_ end end - context 'with user_ids as strings' do - let(:params) { { user_ids: [project_user.id.to_s, user_invited_by_id.id.to_s] } } + context 'with user_id as strings' do + let(:params) { { user_id: [project_user.id.to_s, user_invited_by_id.id.to_s] } } it 'successfully creates members' do expect_to_create_members(count: 2) @@ -70,9 +70,9 @@ RSpec.describe Members::InviteService, :aggregate_failures, :clean_gitlab_redis_ end end - context 'with a mixture of emails and user_ids' do + context 'with a mixture of emails and user_id' do let(:params) do - { user_ids: [project_user.id, user_invited_by_id.id], email: %w[email@example.org email2@example.org] } + { user_id: [project_user.id, user_invited_by_id.id], email: %w[email@example.org email2@example.org] } end it 'successfully creates members' do @@ -92,8 +92,8 @@ RSpec.describe Members::InviteService, :aggregate_failures, :clean_gitlab_redis_ end end - context 'with user_ids' do - let(:params) { { user_ids: "#{project_user.id},#{user_invited_by_id.id}" } } + context 'with user_id' do + let(:params) { { user_id: "#{project_user.id},#{user_invited_by_id.id}" } } it 'successfully creates members' do expect_to_create_members(count: 2) @@ -101,9 +101,9 @@ RSpec.describe Members::InviteService, :aggregate_failures, :clean_gitlab_redis_ end end - context 'with a mixture of emails and user_ids' do + context 'with a mixture of emails and user_id' do let(:params) do - { user_ids: "#{project_user.id},#{user_invited_by_id.id}", email: 'email@example.org,email2@example.org' } + { user_id: "#{project_user.id},#{user_invited_by_id.id}", email: 'email@example.org,email2@example.org' } end it 'successfully creates members' do @@ -114,9 +114,9 @@ RSpec.describe Members::InviteService, :aggregate_failures, :clean_gitlab_redis_ end context 'when invites formats are mixed' do - context 'when user_ids is an array and emails is a string' do + context 'when user_id is an array and emails is a string' do let(:params) do - { user_ids: [project_user.id, user_invited_by_id.id], email: 'email@example.org,email2@example.org' } + { user_id: [project_user.id, user_invited_by_id.id], email: 'email@example.org,email2@example.org' } end it 'successfully creates members' do @@ -125,9 +125,9 @@ RSpec.describe Members::InviteService, :aggregate_failures, :clean_gitlab_redis_ end end - context 'when user_ids is a string and emails is an array' do + context 'when user_id is a string and emails is an array' do let(:params) do - { user_ids: "#{project_user.id},#{user_invited_by_id.id}", email: %w[email@example.org email2@example.org] } + { user_id: "#{project_user.id},#{user_invited_by_id.id}", email: %w[email@example.org email2@example.org] } end it 'successfully creates members' do @@ -147,8 +147,8 @@ RSpec.describe Members::InviteService, :aggregate_failures, :clean_gitlab_redis_ end end - context 'when user_ids are passed as an empty string' do - let(:params) { { user_ids: '' } } + context 'when user_id are passed as an empty string' do + let(:params) { { user_id: '' } } it 'returns an error' do expect_not_to_create_members @@ -156,8 +156,8 @@ RSpec.describe Members::InviteService, :aggregate_failures, :clean_gitlab_redis_ end end - context 'when user_ids and emails are both passed as empty strings' do - let(:params) { { user_ids: '', email: '' } } + context 'when user_id and emails are both passed as empty strings' do + let(:params) { { user_id: '', email: '' } } it 'returns an error' do expect_not_to_create_members @@ -166,7 +166,7 @@ RSpec.describe Members::InviteService, :aggregate_failures, :clean_gitlab_redis_ end context 'when user_id is passed as an integer' do - let(:params) { { user_ids: project_user.id } } + let(:params) { { user_id: project_user.id } } it 'successfully creates member' do expect_to_create_members(count: 1) @@ -196,7 +196,7 @@ RSpec.describe Members::InviteService, :aggregate_failures, :clean_gitlab_redis_ end context 'with user_id and singular invalid email' do - let(:params) { { user_ids: project_user.id, email: '_bogus_' } } + let(:params) { { user_id: project_user.id, email: '_bogus_' } } it 'has partial success' do expect_to_create_members(count: 1) @@ -219,7 +219,7 @@ RSpec.describe Members::InviteService, :aggregate_failures, :clean_gitlab_redis_ end context 'with duplicate user ids' do - let(:params) { { user_ids: "#{project_user.id},#{project_user.id}" } } + let(:params) { { user_id: "#{project_user.id},#{project_user.id}" } } it 'only creates one member per unique invite' do expect_to_create_members(count: 1) @@ -228,7 +228,7 @@ RSpec.describe Members::InviteService, :aggregate_failures, :clean_gitlab_redis_ end context 'with duplicate member by adding as user id and email' do - let(:params) { { user_ids: project_user.id, email: project_user.email } } + let(:params) { { user_id: project_user.id, email: project_user.email } } it 'only creates one member per unique invite' do expect_to_create_members(count: 1) @@ -269,9 +269,9 @@ RSpec.describe Members::InviteService, :aggregate_failures, :clean_gitlab_redis_ end end - context 'with user_ids' do - let(:user_ids) { 1.upto(101).to_a.join(',') } - let(:params) { { user_ids: user_ids } } + context 'with user_id' do + let(:user_id) { 1.upto(101).to_a.join(',') } + let(:params) { { user_id: user_id } } it 'limits the number of users to 100' do expect_not_to_create_members @@ -292,7 +292,7 @@ RSpec.describe Members::InviteService, :aggregate_failures, :clean_gitlab_redis_ end context 'with user_id' do - let(:params) { { user_ids: project_user.id } } + let(:params) { { user_id: project_user.id } } it_behaves_like 'records an onboarding progress action', :user_added @@ -304,7 +304,7 @@ RSpec.describe Members::InviteService, :aggregate_failures, :clean_gitlab_redis_ context 'when assigning tasks to be done' do let(:params) do - { user_ids: project_user.id, tasks_to_be_done: %w(ci code), tasks_project_id: project.id } + { user_id: project_user.id, tasks_to_be_done: %w(ci code), tasks_project_id: project.id } end it 'creates 2 task issues', :aggregate_failures do @@ -332,7 +332,7 @@ RSpec.describe Members::InviteService, :aggregate_failures, :clean_gitlab_redis_ end context 'with user_id' do - let(:params) { { user_ids: user_invited_by_id.id, access_level: -1 } } + let(:params) { { user_id: user_invited_by_id.id, access_level: -1 } } it 'returns an error' do expect_not_to_create_members @@ -341,7 +341,7 @@ RSpec.describe Members::InviteService, :aggregate_failures, :clean_gitlab_redis_ end context 'with a mix of user_id and email' do - let(:params) { { user_ids: user_invited_by_id.id, email: project_user.email, access_level: -1 } } + let(:params) { { user_id: user_invited_by_id.id, email: project_user.email, access_level: -1 } } it 'returns errors' do expect_not_to_create_members @@ -387,7 +387,7 @@ RSpec.describe Members::InviteService, :aggregate_failures, :clean_gitlab_redis_ context 'with user_id that already exists' do let!(:existing_member) { create(:project_member, project: project, user: project_user) } - let(:params) { { user_ids: existing_member.user_id } } + let(:params) { { user_id: existing_member.user_id } } it 'does not add the member again and is successful' do expect_to_create_members(count: 0) @@ -397,7 +397,7 @@ RSpec.describe Members::InviteService, :aggregate_failures, :clean_gitlab_redis_ context 'with user_id that already exists with a lower access_level' do let!(:existing_member) { create(:project_member, :developer, project: project, user: project_user) } - let(:params) { { user_ids: existing_member.user_id, access_level: ProjectMember::MAINTAINER } } + let(:params) { { user_id: existing_member.user_id, access_level: ProjectMember::MAINTAINER } } it 'does not add the member again and updates the access_level' do expect_to_create_members(count: 0) @@ -408,7 +408,7 @@ RSpec.describe Members::InviteService, :aggregate_failures, :clean_gitlab_redis_ context 'with user_id that already exists with a higher access_level' do let!(:existing_member) { create(:project_member, :developer, project: project, user: project_user) } - let(:params) { { user_ids: existing_member.user_id, access_level: ProjectMember::GUEST } } + let(:params) { { user_id: existing_member.user_id, access_level: ProjectMember::GUEST } } it 'does not add the member again and updates the access_level' do expect_to_create_members(count: 0) @@ -428,7 +428,7 @@ RSpec.describe Members::InviteService, :aggregate_failures, :clean_gitlab_redis_ end context 'when access_level is lower than inheriting member' do - let(:params) { { user_ids: group_member.user_id, access_level: ProjectMember::GUEST }} + let(:params) { { user_id: group_member.user_id, access_level: ProjectMember::GUEST }} it 'does not add the member and returns an error' do msg = "Access level should be greater than or equal " \ @@ -440,7 +440,7 @@ RSpec.describe Members::InviteService, :aggregate_failures, :clean_gitlab_redis_ end context 'when access_level is the same as the inheriting member' do - let(:params) { { user_ids: group_member.user_id, access_level: ProjectMember::DEVELOPER }} + let(:params) { { user_id: group_member.user_id, access_level: ProjectMember::DEVELOPER }} it 'adds the member with correct access_level' do expect_to_create_members(count: 1) @@ -450,7 +450,7 @@ RSpec.describe Members::InviteService, :aggregate_failures, :clean_gitlab_redis_ end context 'when access_level is greater than the inheriting member' do - let(:params) { { user_ids: group_member.user_id, access_level: ProjectMember::MAINTAINER }} + let(:params) { { user_id: group_member.user_id, access_level: ProjectMember::MAINTAINER }} it 'adds the member with correct access_level' do expect_to_create_members(count: 1) diff --git a/spec/workers/container_registry/migration/enqueuer_worker_spec.rb b/spec/workers/container_registry/migration/enqueuer_worker_spec.rb index 9977cc1a5f0..a57a9e3b2e8 100644 --- a/spec/workers/container_registry/migration/enqueuer_worker_spec.rb +++ b/spec/workers/container_registry/migration/enqueuer_worker_spec.rb @@ -94,7 +94,7 @@ RSpec.describe ContainerRegistry::Migration::EnqueuerWorker, :aggregate_failures container_repository_migration_state: 'pre_importing' ) - subject + expect { subject }.to make_queries_matching(/LIMIT 2/) expect(container_repository.reload).to be_pre_importing end @@ -462,7 +462,7 @@ RSpec.describe ContainerRegistry::Migration::EnqueuerWorker, :aggregate_failures expect(worker).to receive(:handle_next_migration).exactly(3).times.and_call_original - subject + expect { subject }.to make_queries_matching(/LIMIT 2/) expect(container_repository.reload).to be_pre_importing expect(container_repository2.reload).to be_pre_importing