Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.rubocop_todo/gettext/static_identifier.yml1
-rw-r--r--.rubocop_todo/layout/line_end_string_concatenation_indentation.yml2
-rw-r--r--.rubocop_todo/layout/line_length.yml1
-rw-r--r--.rubocop_todo/rspec/before_all_role_assignment.yml1
-rw-r--r--.rubocop_todo/style/empty_method.yml1
-rw-r--r--.rubocop_todo/style/format_string.yml1
-rw-r--r--.rubocop_todo/style/guard_clause.yml1
-rw-r--r--GITALY_SERVER_VERSION2
-rw-r--r--Gemfile4
-rw-r--r--Gemfile.checksum4
-rw-r--r--Gemfile.lock10
-rw-r--r--app/controllers/admin/runners_controller.rb2
-rw-r--r--app/models/ci/stage.rb2
-rw-r--r--app/models/service_desk_setting.rb9
-rw-r--r--app/presenters/blob_presenter.rb21
-rw-r--r--app/services/import/github_service.rb11
-rw-r--r--config/feature_flags/development/runners_dashboard.yml8
-rw-r--r--doc/api/graphql/reference/index.md25
-rw-r--r--doc/api/import.md22
-rw-r--r--doc/ci/runners/index.md10
-rw-r--r--doc/user/admin_area/moderate_users.md4
-rw-r--r--doc/user/project/ml/experiment_tracking/index.md2
-rw-r--r--lib/api/import_github.rb10
-rw-r--r--lib/gitlab/github_import.rb12
-rw-r--r--lib/gitlab/github_import/client_pool.rb39
-rw-r--r--lib/gitlab/github_import/settings.rb14
-rw-r--r--lib/gitlab/sidekiq_logging/structured_logger.rb6
-rw-r--r--locale/gitlab.pot3
-rw-r--r--spec/features/invites_spec.rb3
-rw-r--r--spec/features/issues/service_desk_spec.rb2
-rw-r--r--spec/frontend/vue_compat_test_setup.js54
-rw-r--r--spec/graphql/types/ci/detailed_status_type_spec.rb2
-rw-r--r--spec/lib/gitlab/ci/status/stage/factory_spec.rb4
-rw-r--r--spec/lib/gitlab/ci/status/stage/play_manual_spec.rb4
-rw-r--r--spec/lib/gitlab/github_import/client_pool_spec.rb41
-rw-r--r--spec/lib/gitlab/github_import/settings_spec.rb21
-rw-r--r--spec/lib/gitlab/github_import_spec.rb25
-rw-r--r--spec/lib/gitlab/sidekiq_logging/structured_logger_spec.rb22
-rw-r--r--spec/mailers/notify_spec.rb23
-rw-r--r--spec/models/ci/stage_spec.rb2
-rw-r--r--spec/models/service_desk_setting_spec.rb59
-rw-r--r--spec/presenters/blob_presenter_spec.rb108
-rw-r--r--spec/requests/api/import_github_spec.rb27
-rw-r--r--spec/serializers/stage_entity_spec.rb6
-rw-r--r--spec/services/import/github_service_spec.rb44
-rw-r--r--spec/support/rspec_order_todo.yml1
-rw-r--r--spec/support/shared_contexts/lib/gitlab/sidekiq_logging/structured_logger_shared_context.rb11
-rw-r--r--spec/support/shared_examples/ci/stage_shared_examples.rb2
-rw-r--r--spec/workers/gitlab/github_import/stage/import_attachments_worker_spec.rb2
-rw-r--r--spec/workers/gitlab/github_import/stage/import_collaborators_worker_spec.rb2
-rw-r--r--spec/workers/gitlab/github_import/stage/import_issue_events_worker_spec.rb2
-rw-r--r--spec/workers/gitlab/github_import/stage/import_issues_and_diff_notes_worker_spec.rb2
-rw-r--r--spec/workers/gitlab/github_import/stage/import_notes_worker_spec.rb2
53 files changed, 556 insertions, 143 deletions
diff --git a/.rubocop_todo/gettext/static_identifier.yml b/.rubocop_todo/gettext/static_identifier.yml
index f14c4884102..2db2a2f130f 100644
--- a/.rubocop_todo/gettext/static_identifier.yml
+++ b/.rubocop_todo/gettext/static_identifier.yml
@@ -13,7 +13,6 @@ Gettext/StaticIdentifier:
- 'app/services/users/banned_user_base_service.rb'
- 'app/services/work_items/widgets/hierarchy_service/base_service.rb'
- 'ee/app/controllers/admin/licenses_controller.rb'
- - 'ee/app/controllers/subscriptions/groups_controller.rb'
- 'ee/app/mailers/ee/emails/admin_notification.rb'
- 'ee/app/mailers/emails/namespace_storage_usage_mailer.rb'
- 'ee/app/models/ee/member.rb'
diff --git a/.rubocop_todo/layout/line_end_string_concatenation_indentation.yml b/.rubocop_todo/layout/line_end_string_concatenation_indentation.yml
index 7a1dd906310..62bf63d1bb9 100644
--- a/.rubocop_todo/layout/line_end_string_concatenation_indentation.yml
+++ b/.rubocop_todo/layout/line_end_string_concatenation_indentation.yml
@@ -78,7 +78,6 @@ Layout/LineEndStringConcatenationIndentation:
- 'ee/lib/ee/gitlab/auth/ldap/access.rb'
- 'ee/lib/ee/gitlab/ci/pipeline/quota/size.rb'
- 'ee/lib/ee/gitlab/git_access.rb'
- - 'ee/lib/ee/gitlab/namespace_storage_size_error_message.rb'
- 'ee/lib/gitlab/manual_quarterly_co_term_banner.rb'
- 'ee/lib/tasks/gitlab/geo.rake'
- 'ee/spec/controllers/admin/licenses_controller_spec.rb'
@@ -102,7 +101,6 @@ Layout/LineEndStringConcatenationIndentation:
- 'ee/spec/lib/audit/group_merge_request_approval_setting_changes_auditor_spec.rb'
- 'ee/spec/lib/ee/gitlab/ci/parsers/security/validators/schema_validator_spec.rb'
- 'ee/spec/lib/ee/gitlab/ci/pipeline/quota/size_spec.rb'
- - 'ee/spec/lib/ee/gitlab/namespace_storage_size_error_message_spec.rb'
- 'ee/spec/lib/gitlab/ci/pipeline/chain/limit/size_spec.rb'
- 'ee/spec/lib/gitlab/ci/templates/api_security_gitlab_ci_yaml_spec.rb'
- 'ee/spec/lib/gitlab/ci/templates/api_security_latest_gitlab_ci_yaml_spec.rb'
diff --git a/.rubocop_todo/layout/line_length.yml b/.rubocop_todo/layout/line_length.yml
index 72f43c7779e..2b489861db7 100644
--- a/.rubocop_todo/layout/line_length.yml
+++ b/.rubocop_todo/layout/line_length.yml
@@ -1350,7 +1350,6 @@ Layout/LineLength:
- 'ee/spec/controllers/projects/subscriptions_controller_spec.rb'
- 'ee/spec/controllers/projects/vulnerability_feedback_controller_spec.rb'
- 'ee/spec/controllers/projects_controller_spec.rb'
- - 'ee/spec/controllers/subscriptions/groups_controller_spec.rb'
- 'ee/spec/controllers/subscriptions_controller_spec.rb'
- 'ee/spec/elastic/migrate/migration_shared_examples.rb'
- 'ee/spec/factories/ci/builds.rb'
diff --git a/.rubocop_todo/rspec/before_all_role_assignment.yml b/.rubocop_todo/rspec/before_all_role_assignment.yml
index 8e3f8de920c..4b58f6fc52f 100644
--- a/.rubocop_todo/rspec/before_all_role_assignment.yml
+++ b/.rubocop_todo/rspec/before_all_role_assignment.yml
@@ -61,7 +61,6 @@ RSpec/BeforeAllRoleAssignment:
- 'ee/spec/controllers/projects_controller_spec.rb'
- 'ee/spec/controllers/registrations/groups_controller_spec.rb'
- 'ee/spec/controllers/security/projects_controller_spec.rb'
- - 'ee/spec/controllers/subscriptions/groups_controller_spec.rb'
- 'ee/spec/controllers/subscriptions_controller_spec.rb'
- 'ee/spec/features/admin/admin_sends_notification_spec.rb'
- 'ee/spec/features/analytics/code_analytics_spec.rb'
diff --git a/.rubocop_todo/style/empty_method.yml b/.rubocop_todo/style/empty_method.yml
index cb3896f0e5a..723a3adf412 100644
--- a/.rubocop_todo/style/empty_method.yml
+++ b/.rubocop_todo/style/empty_method.yml
@@ -91,7 +91,6 @@ Style/EmptyMethod:
- 'ee/app/controllers/projects/security/dast_scanner_profiles_controller.rb'
- 'ee/app/controllers/projects/security/dast_site_profiles_controller.rb'
- 'ee/app/controllers/projects/security/sast_configuration_controller.rb'
- - 'ee/app/controllers/subscriptions/groups_controller.rb'
- 'ee/app/models/ee/epic.rb'
- 'ee/app/services/feature_flag_issues/destroy_service.rb'
- 'ee/db/geo/migrate/20170906174622_remove_duplicates_from_project_registry.rb'
diff --git a/.rubocop_todo/style/format_string.yml b/.rubocop_todo/style/format_string.yml
index d03718c0d51..a45c6b39c25 100644
--- a/.rubocop_todo/style/format_string.yml
+++ b/.rubocop_todo/style/format_string.yml
@@ -170,7 +170,6 @@ Style/FormatString:
- 'ee/app/controllers/groups/saml_group_links_controller.rb'
- 'ee/app/controllers/groups/sso_controller.rb'
- 'ee/app/controllers/projects/requirements_management/requirements_controller.rb'
- - 'ee/app/controllers/subscriptions/groups_controller.rb'
- 'ee/app/helpers/admin/emails_helper.rb'
- 'ee/app/helpers/billing_plans_helper.rb'
- 'ee/app/helpers/ee/application_helper.rb'
diff --git a/.rubocop_todo/style/guard_clause.yml b/.rubocop_todo/style/guard_clause.yml
index abd7fe7af98..302c477af53 100644
--- a/.rubocop_todo/style/guard_clause.yml
+++ b/.rubocop_todo/style/guard_clause.yml
@@ -372,7 +372,6 @@ Style/GuardClause:
- 'ee/app/services/iterations/delete_service.rb'
- 'ee/app/services/merge_trains/check_status_service.rb'
- 'ee/app/services/merge_trains/refresh_merge_request_service.rb'
- - 'ee/app/services/namespaces/storage/email_notification_service.rb'
- 'ee/app/services/projects/update_mirror_service.rb'
- 'ee/app/services/security/override_uuids_service.rb'
- 'ee/app/services/timebox_report_service.rb'
diff --git a/GITALY_SERVER_VERSION b/GITALY_SERVER_VERSION
index 6bc06509d4b..cb201d05306 100644
--- a/GITALY_SERVER_VERSION
+++ b/GITALY_SERVER_VERSION
@@ -1 +1 @@
-e8a0d0187f11908018a4f639d0b845501153eddb
+6ca31a17e3225737d5cf9deba18c9b18951120a8
diff --git a/Gemfile b/Gemfile
index 189572814b4..467c28dc21a 100644
--- a/Gemfile
+++ b/Gemfile
@@ -182,9 +182,9 @@ gem 'seed-fu', '~> 2.3.7'
gem 'elasticsearch-model', '~> 7.2'
gem 'elasticsearch-rails', '~> 7.2', require: 'elasticsearch/rails/instrumentation'
gem 'elasticsearch-api', '7.13.3'
-gem 'aws-sdk-core', '~> 3.176.1'
+gem 'aws-sdk-core', '~> 3.177.0'
gem 'aws-sdk-cloudformation', '~> 1'
-gem 'aws-sdk-s3', '~> 1.127.0'
+gem 'aws-sdk-s3', '~> 1.128.0'
gem 'faraday_middleware-aws-sigv4', '~>0.3.0'
gem 'typhoeus', '~> 1.4.0' # Used with Elasticsearch to support http keep-alive connections
diff --git a/Gemfile.checksum b/Gemfile.checksum
index ce558e0768a..9814160bc2f 100644
--- a/Gemfile.checksum
+++ b/Gemfile.checksum
@@ -37,9 +37,9 @@
{"name":"aws-eventstream","version":"1.2.0","platform":"ruby","checksum":"ffa53482c92880b001ff2fb06919b9bb82fd847cbb0fa244985d2ebb6dd0d1df"},
{"name":"aws-partitions","version":"1.761.0","platform":"ruby","checksum":"291e444e1edfc92c5521a6dbdd1236ccc3f122b3520163b2be6ec5b6ef350ef2"},
{"name":"aws-sdk-cloudformation","version":"1.41.0","platform":"ruby","checksum":"31e47539719734413671edf9b1a31f8673fbf9688549f50c41affabbcb1c6b26"},
-{"name":"aws-sdk-core","version":"3.176.1","platform":"ruby","checksum":"bc312a5fec3991896456653104ee996356ee6eaca6dd5eb6fb251270ed13be8a"},
+{"name":"aws-sdk-core","version":"3.177.0","platform":"ruby","checksum":"c884ac2c5c7b53c3ef5219451aa2d3313881afee0fa7d22ef16ad8b848ccd125"},
{"name":"aws-sdk-kms","version":"1.64.0","platform":"ruby","checksum":"40de596c95047bfc6e1aacea24f3df6241aa716b6f7ce08ac4c5f7e3120395ad"},
-{"name":"aws-sdk-s3","version":"1.127.0","platform":"ruby","checksum":"d3e0f22c505d1fee4648df0992b8e582d5440d0efcbc171a89c908ab21b68dc0"},
+{"name":"aws-sdk-s3","version":"1.128.0","platform":"ruby","checksum":"5b1420d5be9654a9b1b5c8309d75ce72592f3a1e29def15ea07a853b96999d85"},
{"name":"aws-sigv4","version":"1.6.0","platform":"ruby","checksum":"ca9e6a15cd424f1f32b524b9760995331459bc22e67d3daad4fcf0c0084b087d"},
{"name":"axe-core-api","version":"4.6.0","platform":"ruby","checksum":"1b0ddec3353f108dc10363baf2282f43a5ff7f13d4e25f99071294e78f8a6c62"},
{"name":"axe-core-rspec","version":"4.6.0","platform":"ruby","checksum":"11c25bc9dd388c137ba4e5e63d64d20092bf22c884d8ffc829a22acfbacd747f"},
diff --git a/Gemfile.lock b/Gemfile.lock
index 888fe7feae6..eb62c3238ff 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -245,7 +245,7 @@ GEM
aws-sdk-cloudformation (1.41.0)
aws-sdk-core (~> 3, >= 3.99.0)
aws-sigv4 (~> 1.1)
- aws-sdk-core (3.176.1)
+ aws-sdk-core (3.177.0)
aws-eventstream (~> 1, >= 1.0.2)
aws-partitions (~> 1, >= 1.651.0)
aws-sigv4 (~> 1.5)
@@ -253,8 +253,8 @@ GEM
aws-sdk-kms (1.64.0)
aws-sdk-core (~> 3, >= 3.165.0)
aws-sigv4 (~> 1.1)
- aws-sdk-s3 (1.127.0)
- aws-sdk-core (~> 3, >= 3.176.0)
+ aws-sdk-s3 (1.128.0)
+ aws-sdk-core (~> 3, >= 3.177.0)
aws-sdk-kms (~> 1)
aws-sigv4 (~> 1.6)
aws-sigv4 (1.6.0)
@@ -1730,8 +1730,8 @@ DEPENDENCIES
autoprefixer-rails (= 10.2.5.1)
awesome_print
aws-sdk-cloudformation (~> 1)
- aws-sdk-core (~> 3.176.1)
- aws-sdk-s3 (~> 1.127.0)
+ aws-sdk-core (~> 3.177.0)
+ aws-sdk-s3 (~> 1.128.0)
axe-core-rspec
babosa (~> 2.0)
base32 (~> 0.3.0)
diff --git a/app/controllers/admin/runners_controller.rb b/app/controllers/admin/runners_controller.rb
index d312dcc3563..b368ba6e495 100644
--- a/app/controllers/admin/runners_controller.rb
+++ b/app/controllers/admin/runners_controller.rb
@@ -3,7 +3,7 @@
class Admin::RunnersController < Admin::ApplicationController
include RunnerSetupScripts
- before_action :runner, except: [:index, :new, :tag_list, :runner_setup_scripts]
+ before_action :runner, only: [:show, :edit, :register, :update]
feature_category :runner
urgency :low
diff --git a/app/models/ci/stage.rb b/app/models/ci/stage.rb
index d61760bd0fc..af0eee97481 100644
--- a/app/models/ci/stage.rb
+++ b/app/models/ci/stage.rb
@@ -148,7 +148,7 @@ module Ci
end
def manual_playable?
- blocked? || skipped?
+ blocked?
end
# This will be removed with ci_remove_ensure_stage_service
diff --git a/app/models/service_desk_setting.rb b/app/models/service_desk_setting.rb
index 4216ad7e70f..6560b25b39c 100644
--- a/app/models/service_desk_setting.rb
+++ b/app/models/service_desk_setting.rb
@@ -21,6 +21,7 @@ class ServiceDeskSetting < ApplicationRecord
validates :project_id, presence: true
validate :valid_issue_template
validate :valid_project_key
+ validate :custom_email_enabled_state
validates :outgoing_name, length: { maximum: 255 }, allow_blank: true
validates :project_key,
length: { maximum: 255 },
@@ -86,6 +87,14 @@ class ServiceDeskSetting < ApplicationRecord
end
end
+ def custom_email_enabled_state
+ return unless custom_email_enabled?
+
+ if custom_email_verification.blank? || !custom_email_verification.finished?
+ errors.add(:custom_email_enabled, 'cannot be enabled until verification process has finished.')
+ end
+ end
+
private
def source_template_project
diff --git a/app/presenters/blob_presenter.rb b/app/presenters/blob_presenter.rb
index cd473152b41..bc12d210334 100644
--- a/app/presenters/blob_presenter.rb
+++ b/app/presenters/blob_presenter.rb
@@ -86,7 +86,7 @@ class BlobPresenter < Gitlab::View::Presenter::Delegated
end
def find_file_path
- url_helpers.project_find_file_path(project, blob.commit_id)
+ url_helpers.project_find_file_path(project, commit_id, ref_type: ref_type)
end
def blame_path
@@ -131,13 +131,13 @@ class BlobPresenter < Gitlab::View::Presenter::Delegated
end
def can_modify_blob?
- super(blob, project, blob.commit_id)
+ super(blob, project, commit_id)
end
def can_current_user_push_to_branch?
- return false unless current_user && project.repository.branch_exists?(blob.commit_id)
+ return false unless current_user && project.repository.branch_exists?(commit_id)
- user_access(project).can_push_to_branch?(blob.commit_id)
+ user_access(project).can_push_to_branch?(commit_id)
end
def archived?
@@ -145,7 +145,7 @@ class BlobPresenter < Gitlab::View::Presenter::Delegated
end
def ide_edit_path
- super(project, blob.commit_id, blob.path)
+ super(project, commit_id, blob.path)
end
def external_storage_url
@@ -159,7 +159,7 @@ class BlobPresenter < Gitlab::View::Presenter::Delegated
end
def project_blob_path_root
- project_blob_path(project, blob.commit_id)
+ project_blob_path(project, commit_id)
end
private
@@ -181,7 +181,7 @@ class BlobPresenter < Gitlab::View::Presenter::Delegated
end
def environment
- environment_params = project.repository.branch_exists?(blob.commit_id) ? { ref: blob.commit_id } : { sha: blob.commit_id }
+ environment_params = project.repository.branch_exists?(commit_id) ? { ref: commit_id } : { sha: commit_id }
environment_params[:find_latest] = true
::Environments::EnvironmentsByDeploymentsFinder.new(project, current_user, environment_params).execute.last
end
@@ -190,12 +190,13 @@ class BlobPresenter < Gitlab::View::Presenter::Delegated
blob.repository.project
end
- def ref_qualified_path
+ def commit_id
# If `ref_type` is present the commit_id will include the ref qualifier e.g. `refs/heads/`.
# We only accept/return unqualified refs so we need to remove the qualifier from the `commit_id`.
+ ExtractsRef.unqualify_ref(blob.commit_id, ref_type)
+ end
- commit_id = ExtractsRef.unqualify_ref(blob.commit_id, ref_type)
-
+ def ref_qualified_path
File.join(commit_id, blob.path)
end
diff --git a/app/services/import/github_service.rb b/app/services/import/github_service.rb
index 7e7f7ea9810..df255a7ae24 100644
--- a/app/services/import/github_service.rb
+++ b/app/services/import/github_service.rb
@@ -16,7 +16,7 @@ module Import
track_access_level('github')
if project.persisted?
- store_import_settings(project)
+ store_import_settings(project, access_params)
success(project)
elsif project.errors[:import_source_disabled].present?
error(project.errors[:import_source_disabled], :forbidden)
@@ -134,8 +134,13 @@ module Import
error(translated_message, http_status)
end
- def store_import_settings(project)
- Gitlab::GithubImport::Settings.new(project).write(params[:optional_stages])
+ def store_import_settings(project, access_params)
+ Gitlab::GithubImport::Settings
+ .new(project)
+ .write(
+ optional_stages: params[:optional_stages],
+ additional_access_tokens: access_params[:additional_access_tokens]
+ )
end
end
end
diff --git a/config/feature_flags/development/runners_dashboard.yml b/config/feature_flags/development/runners_dashboard.yml
new file mode 100644
index 00000000000..dd773c5e337
--- /dev/null
+++ b/config/feature_flags/development/runners_dashboard.yml
@@ -0,0 +1,8 @@
+---
+name: runners_dashboard
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/125301
+rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/417002
+milestone: '16.2'
+type: development
+group: group::runner
+default_enabled: false
diff --git a/doc/api/graphql/reference/index.md b/doc/api/graphql/reference/index.md
index 65c3072fa8b..8c21767f583 100644
--- a/doc/api/graphql/reference/index.md
+++ b/doc/api/graphql/reference/index.md
@@ -6881,6 +6881,31 @@ Input type: `UserSetNamespaceCommitEmailInput`
| <a id="mutationusersetnamespacecommitemailerrors"></a>`errors` | [`[String!]!`](#string) | Errors encountered during execution of the mutation. |
| <a id="mutationusersetnamespacecommitemailnamespacecommitemail"></a>`namespaceCommitEmail` | [`NamespaceCommitEmail`](#namespacecommitemail) | User namespace commit email after mutation. |
+### `Mutation.vulnerabilitiesDismiss`
+
+WARNING:
+**Introduced** in 16.2.
+This feature is an Experiment. It can be changed or removed at any time.
+
+Input type: `VulnerabilitiesDismissInput`
+
+#### Arguments
+
+| Name | Type | Description |
+| ---- | ---- | ----------- |
+| <a id="mutationvulnerabilitiesdismissclientmutationid"></a>`clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. |
+| <a id="mutationvulnerabilitiesdismisscomment"></a>`comment` | [`String`](#string) | Comment why vulnerability was dismissed (maximum 50,000 characters). |
+| <a id="mutationvulnerabilitiesdismissdismissalreason"></a>`dismissalReason` | [`VulnerabilityDismissalReason`](#vulnerabilitydismissalreason) | Reason why vulnerability should be dismissed. |
+| <a id="mutationvulnerabilitiesdismissvulnerabilityids"></a>`vulnerabilityIds` | [`[VulnerabilityID!]!`](#vulnerabilityid) | IDs of the vulnerabilities to be dismissed. |
+
+#### Fields
+
+| Name | Type | Description |
+| ---- | ---- | ----------- |
+| <a id="mutationvulnerabilitiesdismissclientmutationid"></a>`clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. |
+| <a id="mutationvulnerabilitiesdismisserrors"></a>`errors` | [`[String!]!`](#string) | Errors encountered during execution of the mutation. |
+| <a id="mutationvulnerabilitiesdismissvulnerabilities"></a>`vulnerabilities` **{warning-solid}** | [`[Vulnerability!]!`](#vulnerability) | **Deprecated:** This feature is an Experiment. It can be changed or removed at any time. Introduced in 16.2. |
+
### `Mutation.vulnerabilityConfirm`
Input type: `VulnerabilityConfirmInput`
diff --git a/doc/api/import.md b/doc/api/import.md
index be70868cca5..7bbc19cb36a 100644
--- a/doc/api/import.md
+++ b/doc/api/import.md
@@ -26,14 +26,15 @@ Prerequisites:
POST /import/github
```
-| Attribute | Type | Required | Description |
-|-------------------------|---------|----------|-------------------------------------------------------------------------------------|
-| `personal_access_token` | string | yes | GitHub personal access token |
-| `repo_id` | integer | yes | GitHub repository ID |
-| `new_name` | string | no | New repository name |
-| `target_namespace` | string | yes | Namespace to import repository into. Supports subgroups like `/namespace/subgroup`. In GitLab 15.8 and later, must not be blank |
-| `github_hostname` | string | no | Custom GitHub Enterprise hostname. Do not set for GitHub.com. |
-| `optional_stages` | object | no | [Additional items to import](../user/project/import/github.md#select-additional-items-to-import). [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/373705) in GitLab 15.5 |
+| Attribute | Type | Required | Description |
+|----------------------------|---------|----------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
+| `personal_access_token` | string | yes | GitHub personal access token |
+| `repo_id` | integer | yes | GitHub repository ID |
+| `new_name` | string | no | New repository name |
+| `target_namespace` | string | yes | Namespace to import repository into. Supports subgroups like `/namespace/subgroup`. In GitLab 15.8 and later, must not be blank |
+| `github_hostname` | string | no | Custom GitHub Enterprise hostname. Do not set for GitHub.com. |
+| `optional_stages` | object | no | [Additional items to import](../user/project/import/github.md#select-additional-items-to-import). [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/373705) in GitLab 15.5 |
+| `additional_access_tokens` | string | no | Additional list of comma-separated personal access tokens. [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/337232) in GitLab 16.2 |
```shell
curl --request POST \
@@ -51,7 +52,8 @@ curl --request POST \
"single_endpoint_notes_import": true,
"attachments_import": true,
"collaborators_import": true
- }
+ },
+ "additional_access_tokens": "foo,bar"
}'
```
@@ -64,6 +66,8 @@ The following keys are available for `optional_stages`:
For more information, see [Select additional items to import](../user/project/import/github.md#select-additional-items-to-import).
+You can supply multiple personal access tokens in `additional_access_tokens` from different user accounts to import projects faster.
+
Example response:
```json
diff --git a/doc/ci/runners/index.md b/doc/ci/runners/index.md
index 19c5be88c1b..99327b2de4f 100644
--- a/doc/ci/runners/index.md
+++ b/doc/ci/runners/index.md
@@ -17,15 +17,10 @@ Your jobs can run on:
- [Windows runners](saas/windows_saas_runner.md) ([Beta](../../policy/experiment-beta-support.md#beta))
- [macOS runners](saas/macos_saas_runner.md) ([Beta](../../policy/experiment-beta-support.md#beta))
-Refer to the Compute [cost factor](../../ci/pipelines/cicd_minutes.md#cost-factor) for the cost factor applied to the machine type based on size.
+Refer to the compute minutes [cost factor](../../ci/pipelines/cicd_minutes.md#cost-factor) for the cost factor applied to the machine type based on size.
The number of minutes you can use on these runners depends on the [maximum number of units of compute](../pipelines/cicd_minutes.md)
in your [subscription plan](https://about.gitlab.com/pricing/).
-[Untagged](../../ci/runners/configure_runners.md#use-tags-to-control-which-jobs-a-runner-can-run) jobs automatically run in containers
-on the `small` Linux runners.
-
-The objective is to make 90% of CI jobs start executing in 120 seconds or less. The error rate should be less than 0.5%.
-
## How SaaS runners work
When you use SaaS runners:
@@ -35,6 +30,9 @@ When you use SaaS runners:
- The virtual machine where your job runs has `sudo` access with no password.
- The storage is shared by the operating system, the image with pre-installed software, and a copy of your cloned repository.
This means that the available free disk space for your jobs to use is reduced.
+- [Untagged](../../ci/runners/configure_runners.md#use-tags-to-control-which-jobs-a-runner-can-run) jobs automatically run in containers
+on the `small` Linux runners.
+- The objective is to make 90% of CI jobs start executing in 120 seconds or less. The error rate target will be less than 0.5%.
NOTE:
Jobs handled by SaaS runners on GitLab.com **time out after 3 hours**, regardless of the timeout configured in a project.
diff --git a/doc/user/admin_area/moderate_users.md b/doc/user/admin_area/moderate_users.md
index bbec556db88..9869fdfc5e6 100644
--- a/doc/user/admin_area/moderate_users.md
+++ b/doc/user/admin_area/moderate_users.md
@@ -178,6 +178,7 @@ Users can also be deactivated using the [GitLab API](../../api/users.md#deactiva
### Automatically deactivate dormant users
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/320875) in GitLab 14.0.
+> - Exclusion of GitLab generate bots [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/340346) in GitLab 14.5
> - Customizable time period [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/336747) in GitLab 15.4
> - The lower limit for inactive period set to 90 days [introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/100793) in GitLab 15.5
@@ -200,6 +201,9 @@ When this feature is enabled, GitLab runs a job once a day to deactivate the dor
A maximum of 100,000 users can be deactivated per day.
+NOTE:
+GitLab generated bots are excluded from the automatic deactivation of dormant users.
+
### Automatically delete unconfirmed users **(PREMIUM SELF)**
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/352514) in GitLab 16.1 [with a flag](../../administration/feature_flags.md) named `delete_unconfirmed_users_setting`. Disabled by default.
diff --git a/doc/user/project/ml/experiment_tracking/index.md b/doc/user/project/ml/experiment_tracking/index.md
index 81c4bc20301..584a6c0df59 100644
--- a/doc/user/project/ml/experiment_tracking/index.md
+++ b/doc/user/project/ml/experiment_tracking/index.md
@@ -9,7 +9,7 @@ info: Machine Learning Experiment Tracking is a GitLab Incubation Engineering pr
FLAG:
On self-managed GitLab, model experiment tracking is disabled by default.
To enable the feature, ask an administrator to [enable the feature flag](../../../../administration/feature_flags.md) named `ml_experiment_tracking`.
-On GitLab.com, this feature is in private testing only.
+On GitLab.com, this feature is enabled on all projects.
NOTE:
Model experiment tracking is an [experimental feature](../../../../policy/experiment-beta-support.md). Refer to <https://gitlab.com/gitlab-org/gitlab/-/issues/381660> for feedback and feature requests.
diff --git a/lib/api/import_github.rb b/lib/api/import_github.rb
index 6550808a563..ab7ac6624a8 100644
--- a/lib/api/import_github.rb
+++ b/lib/api/import_github.rb
@@ -20,7 +20,10 @@ module API
end
def access_params
- { github_access_token: params[:personal_access_token] }
+ {
+ github_access_token: params[:personal_access_token],
+ additional_access_tokens: params[:additional_access_tokens]
+ }
end
def client_options
@@ -59,6 +62,11 @@ module API
requires :target_namespace, type: String, allow_blank: false, desc: 'Namespace or group to import repository into'
optional :github_hostname, type: String, desc: 'Custom GitHub enterprise hostname'
optional :optional_stages, type: Hash, desc: 'Optional stages of import to be performed'
+ optional :additional_access_tokens,
+ type: Array[String],
+ coerce_with: ::API::Validations::Types::CommaSeparatedToArray.coerce,
+ desc: 'Additional list of personal access tokens',
+ documentation: { example: 'foo,bar' }
end
post 'import/github' do
result = Import::GithubService.new(client, current_user, params).execute(access_params, provider)
diff --git a/lib/gitlab/github_import.rb b/lib/gitlab/github_import.rb
index 9556a9e98ba..24e77363e1b 100644
--- a/lib/gitlab/github_import.rb
+++ b/lib/gitlab/github_import.rb
@@ -8,12 +8,18 @@ module Gitlab
def self.new_client_for(project, token: nil, host: nil, parallel: true)
token_to_use = token || project.import_data&.credentials&.fetch(:user)
- Client.new(
- token_to_use,
+ token_pool = project.import_data&.credentials&.dig(:additional_access_tokens)
+ options = {
host: host.presence || self.formatted_import_url(project),
per_page: self.per_page(project),
parallel: parallel
- )
+ }
+
+ if token_pool
+ ClientPool.new(token_pool: token_pool, **options)
+ else
+ Client.new(token_to_use, **options)
+ end
end
# Returns the ID of the ghost user.
diff --git a/lib/gitlab/github_import/client_pool.rb b/lib/gitlab/github_import/client_pool.rb
new file mode 100644
index 00000000000..e8414942d1b
--- /dev/null
+++ b/lib/gitlab/github_import/client_pool.rb
@@ -0,0 +1,39 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module GithubImport
+ class ClientPool
+ delegate_missing_to :best_client
+
+ def initialize(token_pool:, per_page:, parallel:, host: nil)
+ @token_pool = token_pool
+ @host = host
+ @per_page = per_page
+ @parallel = parallel
+ end
+
+ # Returns the client with the most remaining requests, or the client with
+ # the closest rate limit reset time, if all clients are rate limited.
+ def best_client
+ clients_with_requests_remaining = clients.select(&:requests_remaining?)
+
+ return clients_with_requests_remaining.max_by(&:remaining_requests) if clients_with_requests_remaining.any?
+
+ clients.min_by(&:rate_limit_resets_in)
+ end
+
+ private
+
+ def clients
+ @clients ||= @token_pool.map do |token|
+ Client.new(
+ token,
+ host: @host,
+ per_page: @per_page,
+ parallel: @parallel
+ )
+ end
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/github_import/settings.rb b/lib/gitlab/github_import/settings.rb
index 0b883de8ed0..73a5f49a9e3 100644
--- a/lib/gitlab/github_import/settings.rb
+++ b/lib/gitlab/github_import/settings.rb
@@ -56,8 +56,16 @@ module Gitlab
def write(user_settings)
user_settings = user_settings.to_h.with_indifferent_access
- optional_stages = fetch_stages_from_params(user_settings)
- import_data = project.create_or_update_import_data(data: { optional_stages: optional_stages })
+ optional_stages = fetch_stages_from_params(user_settings[:optional_stages])
+ credentials = project.import_data&.credentials&.merge(
+ additional_access_tokens: user_settings[:additional_access_tokens]
+ )
+
+ import_data = project.create_or_update_import_data(
+ data: { optional_stages: optional_stages },
+ credentials: credentials
+ )
+
import_data.save!
end
@@ -74,6 +82,8 @@ module Gitlab
attr_reader :project
def fetch_stages_from_params(user_settings)
+ user_settings = user_settings.to_h.with_indifferent_access
+
OPTIONAL_STAGES.keys.to_h do |stage_name|
enabled = Gitlab::Utils.to_boolean(user_settings[stage_name], default: false)
[stage_name, enabled]
diff --git a/lib/gitlab/sidekiq_logging/structured_logger.rb b/lib/gitlab/sidekiq_logging/structured_logger.rb
index 64f1ab0554a..56762c0fb4b 100644
--- a/lib/gitlab/sidekiq_logging/structured_logger.rb
+++ b/lib/gitlab/sidekiq_logging/structured_logger.rb
@@ -96,6 +96,12 @@ module Gitlab
db_duration = ActiveRecord::LogSubscriber.runtime
payload['db_duration_s'] = Gitlab::Utils.ms_to_round_sec(db_duration)
+ job_urgency = payload['class'].safe_constantize&.get_urgency.to_s
+ unless job_urgency.empty?
+ payload['urgency'] = job_urgency
+ payload['target_duration_s'] = Gitlab::Metrics::SidekiqSlis.execution_duration_for_urgency(job_urgency)
+ end
+
payload
end
diff --git a/locale/gitlab.pot b/locale/gitlab.pot
index 6d2c46303bd..ea64c1b5b42 100644
--- a/locale/gitlab.pot
+++ b/locale/gitlab.pot
@@ -39533,6 +39533,9 @@ msgstr ""
msgid "Runners|Created %{timeAgo} by %{avatar}"
msgstr ""
+msgid "Runners|Dashboard"
+msgstr ""
+
msgid "Runners|Delete %d runner"
msgid_plural "Runners|Delete %d runners"
msgstr[0] ""
diff --git a/spec/features/invites_spec.rb b/spec/features/invites_spec.rb
index a1e75a94326..03ec72980e5 100644
--- a/spec/features/invites_spec.rb
+++ b/spec/features/invites_spec.rb
@@ -232,7 +232,8 @@ RSpec.describe 'Group or Project invitations', :aggregate_failures, feature_cate
end
context 'when the user signs up for an account with the invitation email address' do
- it 'redirects to the most recent membership activity page with all invitations automatically accepted' do
+ it 'redirects to the most recent membership activity page with all invitations automatically accepted',
+ quarantine: 'https://gitlab.com/gitlab-org/gitlab/-/issues/417092' do
fill_in_sign_up_form(new_user)
fill_in_welcome_form
diff --git a/spec/features/issues/service_desk_spec.rb b/spec/features/issues/service_desk_spec.rb
index 0319eaad478..8b52a0c2ab0 100644
--- a/spec/features/issues/service_desk_spec.rb
+++ b/spec/features/issues/service_desk_spec.rb
@@ -194,7 +194,7 @@ RSpec.describe 'Service Desk Issue Tracker', :js, feature_category: :team_planni
visit service_desk_project_issues_path(project)
end
- it 'only displays issues created by support bot' do
+ it 'only displays issues created by support bot', quarantine: 'https://gitlab.com/gitlab-org/gitlab/-/issues/417200' do
expect(page).to have_selector('.issues-list .issue', count: 1)
expect(page).to have_text('Help from email')
expect(page).not_to have_text('Unrelated issue')
diff --git a/spec/frontend/vue_compat_test_setup.js b/spec/frontend/vue_compat_test_setup.js
index 6eba9465c80..ddf75bcc017 100644
--- a/spec/frontend/vue_compat_test_setup.js
+++ b/spec/frontend/vue_compat_test_setup.js
@@ -76,9 +76,57 @@ if (global.document) {
Vue.configureCompat(compatConfig);
installVTUCompat(VTU, fullCompatConfig, compatH);
+
+ jest.mock('vue', () => {
+ const actualVue = jest.requireActual('vue');
+ actualVue.configureCompat(compatConfig);
+ return actualVue;
+ });
+
+ jest.mock('portal-vue', () => ({
+ __esModule: true,
+ default: {
+ install: jest.fn(),
+ },
+ Portal: {},
+ PortalTarget: {},
+ MountingPortal: {
+ template: '<h1>MOUNTING-PORTAL</h1>',
+ },
+ Wormhole: {},
+ }));
+
VTU.config.global.renderStubDefaultSlot = true;
const noop = () => {};
+ const invalidProperties = new Set();
+
+ const getDescriptor = (root, prop) => {
+ let obj = root;
+ while (obj != null) {
+ const desc = Object.getOwnPropertyDescriptor(obj, prop);
+ if (desc) {
+ return desc;
+ }
+ obj = Object.getPrototypeOf(obj);
+ }
+ return null;
+ };
+
+ const isPropertyValidOnDomNode = (prop) => {
+ if (invalidProperties.has(prop)) {
+ return false;
+ }
+
+ const domNode = document.createElement('anonymous-stub');
+ const descriptor = getDescriptor(domNode, prop);
+ if (descriptor && descriptor.get && !descriptor.set) {
+ invalidProperties.add(prop);
+ return false;
+ }
+
+ return true;
+ };
VTU.config.plugins.createStubs = ({ name, component: rawComponent, registerStub }) => {
const component = unwrapLegacyVueExtendComponent(rawComponent);
@@ -126,7 +174,11 @@ if (global.document) {
.filter(Boolean)
: renderSlotByName('default');
- return Vue.h(`${hyphenatedName || 'anonymous'}-stub`, this.$props, slotContents);
+ const props = Object.fromEntries(
+ Object.entries(this.$props).filter(([prop]) => isPropertyValidOnDomNode(prop)),
+ );
+
+ return Vue.h(`${hyphenatedName || 'anonymous'}-stub`, props, slotContents);
},
});
diff --git a/spec/graphql/types/ci/detailed_status_type_spec.rb b/spec/graphql/types/ci/detailed_status_type_spec.rb
index 81ab1b52552..69fb2bc43c0 100644
--- a/spec/graphql/types/ci/detailed_status_type_spec.rb
+++ b/spec/graphql/types/ci/detailed_status_type_spec.rb
@@ -5,7 +5,7 @@ require 'spec_helper'
RSpec.describe Types::Ci::DetailedStatusType do
include GraphqlHelpers
- let_it_be(:stage) { create(:ci_stage, status: :skipped) }
+ let_it_be(:stage) { create(:ci_stage, status: :manual) }
specify { expect(described_class.graphql_name).to eq('DetailedStatus') }
diff --git a/spec/lib/gitlab/ci/status/stage/factory_spec.rb b/spec/lib/gitlab/ci/status/stage/factory_spec.rb
index 35d44281072..702341a7ea7 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) }
@@ -62,7 +62,7 @@ RSpec.describe Gitlab::Ci::Status::Stage::Factory do
end
context 'when stage has manual builds' do
- (Ci::HasStatus::BLOCKED_STATUS + ['skipped']).each do |core_status|
+ Ci::HasStatus::BLOCKED_STATUS.each do |core_status|
context "when status is #{core_status}" do
let(:stage) { create(:ci_stage, pipeline: pipeline, status: core_status) }
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..e23645c106b 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) }
@@ -48,7 +48,7 @@ RSpec.describe Gitlab::Ci::Status::Stage::PlayManual do
context 'when stage is skipped' do
let(:stage) { create(:ci_stage, status: :skipped) }
- it { is_expected.to be_truthy }
+ it { is_expected.to be_falsy }
end
context 'when stage is manual' do
diff --git a/spec/lib/gitlab/github_import/client_pool_spec.rb b/spec/lib/gitlab/github_import/client_pool_spec.rb
new file mode 100644
index 00000000000..aabb47c2cf1
--- /dev/null
+++ b/spec/lib/gitlab/github_import/client_pool_spec.rb
@@ -0,0 +1,41 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Gitlab::GithubImport::ClientPool, feature_category: :importers do
+ subject(:pool) { described_class.new(token_pool: %w[foo bar], per_page: 1, parallel: true) }
+
+ describe '#best_client' do
+ it 'returns the client with the most remaining requests' do
+ allow(Gitlab::GithubImport::Client).to receive(:new).and_return(
+ instance_double(
+ Gitlab::GithubImport::Client,
+ requests_remaining?: true, remaining_requests: 10, rate_limit_resets_in: 1
+ ),
+ instance_double(
+ Gitlab::GithubImport::Client,
+ requests_remaining?: true, remaining_requests: 20, rate_limit_resets_in: 2
+ )
+ )
+
+ expect(pool.best_client.remaining_requests).to eq(20)
+ end
+
+ context 'when all clients are rate limited' do
+ it 'returns the client with the closest rate limit reset time' do
+ allow(Gitlab::GithubImport::Client).to receive(:new).and_return(
+ instance_double(
+ Gitlab::GithubImport::Client,
+ requests_remaining?: false, remaining_requests: 10, rate_limit_resets_in: 10
+ ),
+ instance_double(
+ Gitlab::GithubImport::Client,
+ requests_remaining?: false, remaining_requests: 20, rate_limit_resets_in: 20
+ )
+ )
+
+ expect(pool.best_client.rate_limit_resets_in).to eq(10)
+ end
+ end
+ end
+end
diff --git a/spec/lib/gitlab/github_import/settings_spec.rb b/spec/lib/gitlab/github_import/settings_spec.rb
index 43e096863b8..d670aaea482 100644
--- a/spec/lib/gitlab/github_import/settings_spec.rb
+++ b/spec/lib/gitlab/github_import/settings_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe Gitlab::GithubImport::Settings do
+RSpec.describe Gitlab::GithubImport::Settings, feature_category: :importers do
subject(:settings) { described_class.new(project) }
let_it_be(:project) { create(:project) }
@@ -55,19 +55,26 @@ RSpec.describe Gitlab::GithubImport::Settings do
describe '#write' do
let(:data_input) do
{
- single_endpoint_issue_events_import: true,
- single_endpoint_notes_import: 'false',
- attachments_import: nil,
- collaborators_import: false,
- foo: :bar
+ optional_stages: {
+ single_endpoint_issue_events_import: true,
+ single_endpoint_notes_import: 'false',
+ attachments_import: nil,
+ collaborators_import: false,
+ foo: :bar
+ },
+ additional_access_tokens: %w[foo bar]
}.stringify_keys
end
- it 'puts optional steps flags into projects import_data' do
+ it 'puts optional steps & access tokens into projects import_data' do
+ project.create_or_update_import_data(credentials: { user: 'token' })
+
settings.write(data_input)
expect(project.import_data.data['optional_stages'])
.to eq optional_stages.stringify_keys
+ expect(project.import_data.credentials.fetch(:additional_access_tokens))
+ .to eq(data_input['additional_access_tokens'])
end
end
diff --git a/spec/lib/gitlab/github_import_spec.rb b/spec/lib/gitlab/github_import_spec.rb
index 1ea9f003098..c4ed4b09f04 100644
--- a/spec/lib/gitlab/github_import_spec.rb
+++ b/spec/lib/gitlab/github_import_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe Gitlab::GithubImport do
+RSpec.describe Gitlab::GithubImport, feature_category: :importers do
before do
stub_feature_flags(github_importer_lower_per_page_limit: false)
end
@@ -11,6 +11,8 @@ RSpec.describe Gitlab::GithubImport do
let(:project) { double(:project, import_url: 'http://t0ken@github.com/user/repo.git', id: 1, group: nil) }
it 'returns a new Client with a custom token' do
+ allow(project).to receive(:import_data)
+
expect(described_class::Client)
.to receive(:new)
.with('123', host: nil, parallel: true, per_page: 100)
@@ -24,6 +26,7 @@ RSpec.describe Gitlab::GithubImport do
expect(project)
.to receive(:import_data)
.and_return(import_data)
+ .twice
expect(described_class::Client)
.to receive(:new)
@@ -46,12 +49,31 @@ RSpec.describe Gitlab::GithubImport do
described_class.ghost_user_id
end
end
+
+ context 'when there are additional access tokens' do
+ it 'returns a new ClientPool containing all tokens' do
+ import_data = double(:import_data, credentials: { user: '123', additional_access_tokens: %w[foo bar] })
+
+ expect(project)
+ .to receive(:import_data)
+ .and_return(import_data)
+ .twice
+
+ expect(described_class::ClientPool)
+ .to receive(:new)
+ .with(token_pool: %w[foo bar], host: nil, parallel: true, per_page: 100)
+
+ described_class.new_client_for(project)
+ end
+ end
end
context 'GitHub Enterprise' do
let(:project) { double(:project, import_url: 'http://t0ken@github.another-domain.com/repo-org/repo.git', group: nil) }
it 'returns a new Client with a custom token' do
+ allow(project).to receive(:import_data)
+
expect(described_class::Client)
.to receive(:new)
.with('123', host: 'http://github.another-domain.com/api/v3', parallel: true, per_page: 100)
@@ -65,6 +87,7 @@ RSpec.describe Gitlab::GithubImport do
expect(project)
.to receive(:import_data)
.and_return(import_data)
+ .twice
expect(described_class::Client)
.to receive(:new)
diff --git a/spec/lib/gitlab/sidekiq_logging/structured_logger_spec.rb b/spec/lib/gitlab/sidekiq_logging/structured_logger_spec.rb
index e1c7cf3226b..4e46a26e89f 100644
--- a/spec/lib/gitlab/sidekiq_logging/structured_logger_spec.rb
+++ b/spec/lib/gitlab/sidekiq_logging/structured_logger_spec.rb
@@ -456,6 +456,28 @@ RSpec.describe Gitlab::SidekiqLogging::StructuredLogger do
end
end
end
+
+ context 'with a real worker' do
+ let(:worker_class) { AuthorizedKeysWorker.name }
+
+ let(:expected_end_payload) do
+ end_payload.merge(
+ 'urgency' => 'high',
+ 'target_duration_s' => 10
+ )
+ end
+
+ it 'logs job done with urgency and target_duration_s fields' do
+ travel_to(timestamp) do
+ expect(logger).to receive(:info).with(start_payload).ordered
+ expect(logger).to receive(:info).with(expected_end_payload).ordered
+ expect(subject).to receive(:log_job_start).and_call_original
+ expect(subject).to receive(:log_job_done).and_call_original
+
+ call_subject(job, 'test_queue') {}
+ end
+ end
+ end
end
describe '#add_time_keys!' do
diff --git a/spec/mailers/notify_spec.rb b/spec/mailers/notify_spec.rb
index 372808b64d3..76771360e1f 100644
--- a/spec/mailers/notify_spec.rb
+++ b/spec/mailers/notify_spec.rb
@@ -1572,16 +1572,22 @@ RSpec.describe Notify do
context 'when custom email is enabled' do
let_it_be(:credentials) { create(:service_desk_custom_email_credential, project: project) }
+ let_it_be(:verification) { create(:service_desk_custom_email_verification, project: project) }
let_it_be(:settings) do
create(
:service_desk_setting,
project: project,
- custom_email_enabled: true,
custom_email: 'supersupport@example.com'
)
end
+ before_all do
+ verification.mark_as_finished!
+ project.reset
+ settings.update!(custom_email_enabled: true)
+ end
+
it 'uses custom email and service bot name in "from" header' do
expect_sender(User.support_bot, sender_email: 'supersupport@example.com')
end
@@ -1630,22 +1636,23 @@ RSpec.describe Notify do
end
context 'when custom email is enabled' do
- let_it_be(:credentials) do
- create(
- :service_desk_custom_email_credential,
- project: project
- )
- end
+ let_it_be(:credentials) { create(:service_desk_custom_email_credential, project: project) }
+ let_it_be(:verification) { create(:service_desk_custom_email_verification, project: project) }
let_it_be(:settings) do
create(
:service_desk_setting,
project: project,
- custom_email_enabled: true,
custom_email: 'supersupport@example.com'
)
end
+ before_all do
+ verification.mark_as_finished!
+ project.reset
+ settings.update!(custom_email_enabled: true)
+ end
+
it 'uses custom email and author\'s name in "from" header' do
expect_sender(first_note.author, sender_email: project.service_desk_setting.custom_email)
end
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/service_desk_setting_spec.rb b/spec/models/service_desk_setting_spec.rb
index b9679b82bd0..34165fc2bf3 100644
--- a/spec/models/service_desk_setting_spec.rb
+++ b/spec/models/service_desk_setting_spec.rb
@@ -3,12 +3,9 @@
require 'spec_helper'
RSpec.describe ServiceDeskSetting, feature_category: :service_desk do
- let(:verification) { build(:service_desk_custom_email_verification) }
- let(:project) { build(:project) }
+ subject(:setting) { build(:service_desk_setting) }
describe 'validations' do
- subject(:service_desk_setting) { create(:service_desk_setting) }
-
it { is_expected.to validate_presence_of(:project_id) }
it { is_expected.to validate_length_of(:outgoing_name).is_at_most(255) }
it { is_expected.to validate_length_of(:project_key).is_at_most(255) }
@@ -18,14 +15,56 @@ RSpec.describe ServiceDeskSetting, feature_category: :service_desk do
it { is_expected.to validate_length_of(:custom_email).is_at_most(255) }
describe '#custom_email_enabled' do
- it { expect(subject.custom_email_enabled).to be_falsey }
+ it { expect(setting.custom_email_enabled).to be_falsey }
it { expect(described_class.new(custom_email_enabled: true).custom_email_enabled).to be_truthy }
+
+ context 'when set to true' do
+ let(:expected_error_part) { 'cannot be enabled until verification process has finished.' }
+
+ before do
+ setting.custom_email = 'user@example.com'
+ setting.custom_email_enabled = true
+ end
+
+ it 'is not valid' do
+ is_expected.not_to be_valid
+ expect(setting.errors[:custom_email_enabled].join).to include(expected_error_part)
+ end
+
+ context 'when custom email records exist' do
+ let_it_be(:project) { create(:project) }
+ let_it_be(:credential) { create(:service_desk_custom_email_credential, project: project) }
+
+ let!(:verification) { create(:service_desk_custom_email_verification, project: project) }
+
+ subject(:setting) { build_stubbed(:service_desk_setting, project: project) }
+
+ before do
+ project.reset
+ end
+
+ context 'when custom email verification started' do
+ it 'is not valid' do
+ is_expected.not_to be_valid
+ expect(setting.errors[:custom_email_enabled].join).to include(expected_error_part)
+ end
+ end
+
+ context 'when custom email verification has been finished' do
+ before do
+ verification.mark_as_finished!
+ end
+
+ it { is_expected.to be_valid }
+ end
+ end
+ end
end
context 'when custom_email_enabled is true' do
before do
# Test without ServiceDesk::CustomEmailVerification for simplicity
- subject.custom_email_enabled = true
+ setting.custom_email_enabled = true
end
it { is_expected.to validate_presence_of(:custom_email) }
@@ -66,13 +105,13 @@ RSpec.describe ServiceDeskSetting, feature_category: :service_desk do
describe '#custom_email_address_for_verification' do
it 'returns nil' do
- expect(subject.custom_email_address_for_verification).to be_nil
+ expect(setting.custom_email_address_for_verification).to be_nil
end
context 'when custom_email exists' do
it 'returns correct verification address' do
- subject.custom_email = 'support@example.com'
- expect(subject.custom_email_address_for_verification).to eq('support+verify@example.com')
+ setting.custom_email = 'support@example.com'
+ expect(setting.custom_email_address_for_verification).to eq('support+verify@example.com')
end
end
end
@@ -114,6 +153,8 @@ RSpec.describe ServiceDeskSetting, feature_category: :service_desk do
end
describe 'associations' do
+ let(:project) { build(:project) }
+ let(:verification) { build(:service_desk_custom_email_verification) }
let(:custom_email_settings) do
build_stubbed(
:service_desk_setting,
diff --git a/spec/presenters/blob_presenter_spec.rb b/spec/presenters/blob_presenter_spec.rb
index e776716bd2d..150c7bd5f3e 100644
--- a/spec/presenters/blob_presenter_spec.rb
+++ b/spec/presenters/blob_presenter_spec.rb
@@ -7,28 +7,52 @@ RSpec.describe BlobPresenter do
let_it_be(:user) { project.first_owner }
let(:repository) { project.repository }
- let(:blob) { repository.blob_at('HEAD', 'files/ruby/regex.rb') }
+ let(:blob) { repository.blob_at(ref, path) }
+ let(:ref) { 'HEAD' }
+ let(:path) { 'files/ruby/regex.rb' }
subject(:presenter) { described_class.new(blob, current_user: user) }
describe '#web_url' do
- it { expect(presenter.web_url).to eq("http://localhost/#{project.full_path}/-/blob/#{blob.commit_id}/#{blob.path}") }
+ it { expect(presenter.web_url).to eq("http://localhost/#{project.full_path}/-/blob/#{ref}/#{path}") }
end
describe '#web_path' do
- it { expect(presenter.web_path).to eq("/#{project.full_path}/-/blob/#{blob.commit_id}/#{blob.path}") }
+ it { expect(presenter.web_path).to eq("/#{project.full_path}/-/blob/#{ref}/#{path}") }
end
describe '#edit_blob_path' do
- it { expect(presenter.edit_blob_path).to eq("/#{project.full_path}/-/edit/#{blob.commit_id}/#{blob.path}") }
+ it { expect(presenter.edit_blob_path).to eq("/#{project.full_path}/-/edit/#{ref}/#{path}") }
end
describe '#raw_path' do
- it { expect(presenter.raw_path).to eq("/#{project.full_path}/-/raw/#{blob.commit_id}/#{blob.path}") }
+ it { expect(presenter.raw_path).to eq("/#{project.full_path}/-/raw/#{ref}/#{path}") }
end
describe '#replace_path' do
- it { expect(presenter.replace_path).to eq("/#{project.full_path}/-/update/#{blob.commit_id}/#{blob.path}") }
+ it { expect(presenter.replace_path).to eq("/#{project.full_path}/-/update/#{ref}/#{path}") }
+ end
+
+ shared_examples_for '#can_current_user_push_to_branch?' do
+ let(:branch_exists) { true }
+
+ before do
+ allow(project.repository).to receive(:branch_exists?).with(blob.commit_id).and_return(branch_exists)
+ end
+
+ it { expect(presenter.can_current_user_push_to_branch?).to eq(true) }
+
+ context 'current_user is nil' do
+ let(:user) { nil }
+
+ it { expect(presenter.can_current_user_push_to_branch?).to eq(false) }
+ end
+
+ context 'branch does not exist' do
+ let(:branch_exists) { false }
+
+ it { expect(presenter.can_current_user_push_to_branch?).to eq(false) }
+ end
end
context 'when blob has ref_type' do
@@ -37,46 +61,67 @@ RSpec.describe BlobPresenter do
end
describe '#web_url' do
- it { expect(presenter.web_url).to eq("http://localhost/#{project.full_path}/-/blob/#{blob.commit_id}/#{blob.path}?ref_type=heads") }
+ it { expect(presenter.web_url).to eq("http://localhost/#{project.full_path}/-/blob/#{ref}/#{path}?ref_type=heads") }
end
describe '#web_path' do
- it { expect(presenter.web_path).to eq("/#{project.full_path}/-/blob/#{blob.commit_id}/#{blob.path}?ref_type=heads") }
+ it { expect(presenter.web_path).to eq("/#{project.full_path}/-/blob/#{ref}/#{path}?ref_type=heads") }
end
describe '#edit_blob_path' do
- it { expect(presenter.edit_blob_path).to eq("/#{project.full_path}/-/edit/#{blob.commit_id}/#{blob.path}?ref_type=heads") }
+ it { expect(presenter.edit_blob_path).to eq("/#{project.full_path}/-/edit/#{ref}/#{path}?ref_type=heads") }
end
describe '#raw_path' do
- it { expect(presenter.raw_path).to eq("/#{project.full_path}/-/raw/#{blob.commit_id}/#{blob.path}?ref_type=heads") }
+ it { expect(presenter.raw_path).to eq("/#{project.full_path}/-/raw/#{ref}/#{path}?ref_type=heads") }
end
describe '#replace_path' do
- it { expect(presenter.replace_path).to eq("/#{project.full_path}/-/update/#{blob.commit_id}/#{blob.path}?ref_type=heads") }
+ it { expect(presenter.replace_path).to eq("/#{project.full_path}/-/update/#{ref}/#{path}?ref_type=heads") }
end
+
+ it_behaves_like '#can_current_user_push_to_branch?'
end
- describe '#can_current_user_push_to_branch' do
- let(:branch_exists) { true }
+ describe '#can_modify_blob?' do
+ context 'when blob is store externally' do
+ before do
+ allow(blob).to receive(:stored_externally?).and_return(true)
+ end
- before do
- allow(project.repository).to receive(:branch_exists?).with(blob.commit_id).and_return(branch_exists)
+ it { expect(presenter.can_modify_blob?).to be_falsey }
end
- it { expect(presenter.can_current_user_push_to_branch?).to eq(true) }
+ context 'when the user cannot edit the tree' do
+ before do
+ allow(presenter).to receive(:can_edit_tree?).with(project, ref).and_return(false)
+ end
- context 'current_user is nil' do
- let(:user) { nil }
+ it { expect(presenter.can_modify_blob?).to be_falsey }
+ end
- it { expect(presenter.can_current_user_push_to_branch?).to eq(false) }
+ context 'when ref is a branch' do
+ let(:ref) { 'feature' }
+
+ it { expect(presenter.can_modify_blob?).to be_truthy }
end
+ end
- context 'branch does not exist' do
- let(:branch_exists) { false }
+ describe '#can_current_user_push_to_branch?' do
+ context 'when ref is a branch' do
+ let(:ref) { 'feature' }
- it { expect(presenter.can_current_user_push_to_branch?).to eq(false) }
+ it 'delegates to UserAccess' do
+ allow_next_instance_of(Gitlab::UserAccess) do |instance|
+ expect(instance).to receive(:can_push_to_branch?).with(ref).and_call_original
+ end
+ expect(presenter.can_current_user_push_to_branch?).to be_truthy
+ end
end
+
+ it_behaves_like '#can_current_user_push_to_branch?'
+
+ it { expect(presenter.can_current_user_push_to_branch?).to be_falsey }
end
describe '#archived?' do
@@ -95,9 +140,10 @@ RSpec.describe BlobPresenter do
)
end
- let(:blob) { repository.blob_at('main', '.gitlab-ci.yml') }
+ let(:ref) { 'main' }
+ let(:path) { '.gitlab-ci.yml' }
- it { expect(presenter.pipeline_editor_path).to eq("/#{project.full_path}/-/ci/editor?branch_name=#{blob.commit_id}") }
+ it { expect(presenter.pipeline_editor_path).to eq("/#{project.full_path}/-/ci/editor?branch_name=#{ref}") }
end
end
@@ -114,7 +160,7 @@ RSpec.describe BlobPresenter do
context 'Gitpod enabled for application and user' do
describe '#gitpod_blob_url' do
- it { expect(presenter.gitpod_blob_url).to eq("#{gitpod_url}##{"http://localhost/#{project.full_path}/-/tree/#{blob.commit_id}/#{blob.path}"}") }
+ it { expect(presenter.gitpod_blob_url).to eq("#{gitpod_url}##{"http://localhost/#{project.full_path}/-/tree/#{ref}/#{path}"}") }
end
end
@@ -157,7 +203,7 @@ RSpec.describe BlobPresenter do
let!(:deployment) { create(:deployment, :success, environment: environment, project: project, sha: blob.commit_id) }
before do
- allow(project).to receive(:public_path_for_source_path).with(blob.path, blob.commit_id).and_return(blob.path)
+ allow(project).to receive(:public_path_for_source_path).with(path, blob.commit_id).and_return(path)
end
describe '#environment_formatted_external_url' do
@@ -165,7 +211,7 @@ RSpec.describe BlobPresenter do
end
describe '#environment_external_url_for_route_map' do
- it { expect(presenter.environment_external_url_for_route_map).to eq("#{external_url}/#{blob.path}") }
+ it { expect(presenter.environment_external_url_for_route_map).to eq("#{external_url}/#{path}") }
end
describe 'chooses the latest deployed environment for #environment_formatted_external_url and #environment_external_url_for_route_map' do
@@ -174,7 +220,7 @@ RSpec.describe BlobPresenter do
let!(:another_deployment) { create(:deployment, :success, environment: another_environment, project: project, sha: blob.commit_id) }
it { expect(presenter.environment_formatted_external_url).to eq("another.environment") }
- it { expect(presenter.environment_external_url_for_route_map).to eq("#{another_external_url}/#{blob.path}") }
+ it { expect(presenter.environment_external_url_for_route_map).to eq("#{another_external_url}/#{path}") }
end
end
@@ -219,7 +265,7 @@ RSpec.describe BlobPresenter do
end
describe '#code_navigation_path' do
- let(:code_navigation_path) { Gitlab::CodeNavigationPath.new(project, blob.commit_id).full_json_path_for(blob.path) }
+ let(:code_navigation_path) { Gitlab::CodeNavigationPath.new(project, blob.commit_id).full_json_path_for(path) }
it { expect(presenter.code_navigation_path).to eq(code_navigation_path) }
end
@@ -232,11 +278,11 @@ RSpec.describe BlobPresenter do
let(:blob) { Gitlab::Graphql::Representation::TreeEntry.new(super(), repository) }
describe '#web_url' do
- it { expect(presenter.web_url).to eq("http://localhost/#{project.full_path}/-/blob/#{blob.commit_id}/#{blob.path}") }
+ it { expect(presenter.web_url).to eq("http://localhost/#{project.full_path}/-/blob/#{ref}/#{path}") }
end
describe '#web_path' do
- it { expect(presenter.web_path).to eq("/#{project.full_path}/-/blob/#{blob.commit_id}/#{blob.path}") }
+ it { expect(presenter.web_path).to eq("/#{project.full_path}/-/blob/#{ref}/#{path}") }
end
end
diff --git a/spec/requests/api/import_github_spec.rb b/spec/requests/api/import_github_spec.rb
index 9b5ae72526c..e394b92c0a2 100644
--- a/spec/requests/api/import_github_spec.rb
+++ b/spec/requests/api/import_github_spec.rb
@@ -5,7 +5,8 @@ require 'spec_helper'
RSpec.describe API::ImportGithub, feature_category: :importers do
let(:token) { "asdasd12345" }
let(:provider) { :github }
- let(:access_params) { { github_access_token: token } }
+ let(:access_params) { { github_access_token: token, additional_access_tokens: additional_access_tokens } }
+ let(:additional_access_tokens) { nil }
let(:provider_username) { user.username }
let(:provider_user) { double('provider', login: provider_username).as_null_object }
let(:provider_repo) do
@@ -51,7 +52,7 @@ RSpec.describe API::ImportGithub, feature_category: :importers do
it 'returns 201 response when the project is imported successfully' do
allow(Gitlab::LegacyGithubImport::ProjectCreator)
.to receive(:new).with(provider_repo, provider_repo[:name], user.namespace, user, type: provider, **access_params)
- .and_return(double(execute: project))
+ .and_return(double(execute: project))
post api("/import/github", user), params: {
target_namespace: user.namespace_path,
@@ -120,6 +121,28 @@ RSpec.describe API::ImportGithub, feature_category: :importers do
expect(response).to have_gitlab_http_status(:unauthorized)
end
end
+
+ context 'when additional access tokens are provided' do
+ let(:additional_access_tokens) { 'token1,token2' }
+
+ it 'returns 201' do
+ expected_access_params = { github_access_token: token, additional_access_tokens: %w[token1 token2] }
+
+ expect(Gitlab::LegacyGithubImport::ProjectCreator)
+ .to receive(:new)
+ .with(provider_repo, provider_repo[:name], user.namespace, user, type: provider, **expected_access_params)
+ .and_return(double(execute: project))
+
+ post api("/import/github", user), params: {
+ target_namespace: user.namespace_path,
+ personal_access_token: token,
+ repo_id: non_existing_record_id,
+ additional_access_tokens: 'token1,token2'
+ }
+
+ expect(response).to have_gitlab_http_status(:created)
+ end
+ end
end
describe "POST /import/github/cancel" do
diff --git a/spec/serializers/stage_entity_spec.rb b/spec/serializers/stage_entity_spec.rb
index 5cb5724ebdc..fe8ee027245 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) }
@@ -76,8 +76,8 @@ RSpec.describe StageEntity do
context 'with a skipped stage ' do
let(:stage) { create(:ci_stage, status: 'skipped') }
- it 'contains play_all_manual' do
- expect(subject[:status][:action]).to be_present
+ it 'does not contain play_all_manual' do
+ expect(subject[:status][:action]).not_to be_present
end
end
diff --git a/spec/services/import/github_service_spec.rb b/spec/services/import/github_service_spec.rb
index 21dc24e28f6..982b8b11383 100644
--- a/spec/services/import/github_service_spec.rb
+++ b/spec/services/import/github_service_spec.rb
@@ -5,7 +5,13 @@ require 'spec_helper'
RSpec.describe Import::GithubService, feature_category: :importers do
let_it_be(:user) { create(:user) }
let_it_be(:token) { 'complex-token' }
- let_it_be(:access_params) { { github_access_token: 'github-complex-token' } }
+ let_it_be(:access_params) do
+ {
+ github_access_token: 'github-complex-token',
+ additional_access_tokens: %w[foo bar]
+ }
+ end
+
let(:settings) { instance_double(Gitlab::GithubImport::Settings) }
let(:user_namespace_path) { user.namespace_path }
let(:optional_stages) { nil }
@@ -26,7 +32,12 @@ RSpec.describe Import::GithubService, feature_category: :importers do
before do
allow(Gitlab::GithubImport::Settings).to receive(:new).with(project_double).and_return(settings)
- allow(settings).to receive(:write).with(optional_stages)
+ allow(settings)
+ .to receive(:write)
+ .with(
+ optional_stages: optional_stages,
+ additional_access_tokens: access_params[:additional_access_tokens]
+ )
end
context 'do not raise an exception on input error' do
@@ -82,7 +93,9 @@ RSpec.describe Import::GithubService, feature_category: :importers do
context 'when there is no repository size limit defined' do
it 'skips the check, succeeds, and tracks an access level' do
expect(subject.execute(access_params, :github)).to include(status: :success)
- expect(settings).to have_received(:write).with(nil)
+ expect(settings)
+ .to have_received(:write)
+ .with(optional_stages: nil, additional_access_tokens: access_params[:additional_access_tokens])
expect_snowplow_event(
category: 'Import::GithubService',
action: 'create',
@@ -102,7 +115,9 @@ RSpec.describe Import::GithubService, feature_category: :importers do
it 'succeeds when the repository is smaller than the limit' do
expect(subject.execute(access_params, :github)).to include(status: :success)
- expect(settings).to have_received(:write).with(nil)
+ expect(settings)
+ .to have_received(:write)
+ .with(optional_stages: nil, additional_access_tokens: access_params[:additional_access_tokens])
expect_snowplow_event(
category: 'Import::GithubService',
action: 'create',
@@ -129,7 +144,9 @@ RSpec.describe Import::GithubService, feature_category: :importers do
context 'when application size limit is defined' do
it 'succeeds when the repository is smaller than the limit' do
expect(subject.execute(access_params, :github)).to include(status: :success)
- expect(settings).to have_received(:write).with(nil)
+ expect(settings)
+ .to have_received(:write)
+ .with(optional_stages: nil, additional_access_tokens: access_params[:additional_access_tokens])
expect_snowplow_event(
category: 'Import::GithubService',
action: 'create',
@@ -160,7 +177,22 @@ RSpec.describe Import::GithubService, feature_category: :importers do
it 'saves optional stages choice to import_data' do
subject.execute(access_params, :github)
- expect(settings).to have_received(:write).with(optional_stages)
+ expect(settings)
+ .to have_received(:write)
+ .with(
+ optional_stages: optional_stages,
+ additional_access_tokens: access_params[:additional_access_tokens]
+ )
+ end
+ end
+
+ context 'when additional access tokens are present' do
+ it 'saves additional access tokens to import_data' do
+ subject.execute(access_params, :github)
+
+ expect(settings)
+ .to have_received(:write)
+ .with(optional_stages: optional_stages, additional_access_tokens: %w[foo bar])
end
end
end
diff --git a/spec/support/rspec_order_todo.yml b/spec/support/rspec_order_todo.yml
index 0f91ff5f12c..9197f2ec236 100644
--- a/spec/support/rspec_order_todo.yml
+++ b/spec/support/rspec_order_todo.yml
@@ -166,7 +166,6 @@
- './ee/spec/controllers/security/vulnerabilities_controller_spec.rb'
- './ee/spec/controllers/sitemap_controller_spec.rb'
- './ee/spec/controllers/subscriptions_controller_spec.rb'
-- './ee/spec/controllers/subscriptions/groups_controller_spec.rb'
- './ee/spec/controllers/trial_registrations_controller_spec.rb'
- './ee/spec/controllers/users_controller_spec.rb'
- './ee/spec/db/production/license_spec.rb'
diff --git a/spec/support/shared_contexts/lib/gitlab/sidekiq_logging/structured_logger_shared_context.rb b/spec/support/shared_contexts/lib/gitlab/sidekiq_logging/structured_logger_shared_context.rb
index f1dce9fa8cd..69c20a00c5a 100644
--- a/spec/support/shared_contexts/lib/gitlab/sidekiq_logging/structured_logger_shared_context.rb
+++ b/spec/support/shared_contexts/lib/gitlab/sidekiq_logging/structured_logger_shared_context.rb
@@ -4,10 +4,11 @@ RSpec.shared_context 'structured_logger' do
let(:timestamp) { Time.iso8601('2018-01-01T12:00:00.000Z') }
let(:created_at) { timestamp - 1.second }
let(:scheduling_latency_s) { 1.0 }
+ let(:worker_class) { "TestWorker" }
let(:job) do
{
- "class" => "TestWorker",
+ "class" => worker_class,
"args" => [1234, 'hello', { 'key' => 'value' }],
"retry" => false,
"queue" => "cronjob:test_queue",
@@ -31,7 +32,7 @@ RSpec.shared_context 'structured_logger' do
job.except(
'exception.backtrace', 'exception.class', 'exception.message'
).merge(
- 'message' => 'TestWorker JID-da883554ee4fe414012f5f42: start',
+ 'message' => "#{worker_class} JID-da883554ee4fe414012f5f42: start",
'job_status' => 'start',
'pid' => Process.pid,
'created_at' => created_at.to_f,
@@ -55,7 +56,7 @@ RSpec.shared_context 'structured_logger' do
let(:end_payload) do
start_payload.merge(db_payload_defaults).merge(
- 'message' => 'TestWorker JID-da883554ee4fe414012f5f42: done: 0.0 sec',
+ 'message' => "#{worker_class} JID-da883554ee4fe414012f5f42: done: 0.0 sec",
'job_status' => 'done',
'duration_s' => 0.0,
'completed_at' => timestamp.to_f,
@@ -67,7 +68,7 @@ RSpec.shared_context 'structured_logger' do
let(:deferred_payload) do
end_payload.merge(
- 'message' => 'TestWorker JID-da883554ee4fe414012f5f42: deferred: 0.0 sec',
+ 'message' => "#{worker_class} JID-da883554ee4fe414012f5f42: deferred: 0.0 sec",
'job_status' => 'deferred',
'job_deferred_by' => :feature_flag,
'deferred_count' => 1
@@ -83,7 +84,7 @@ RSpec.shared_context 'structured_logger' do
let(:exception_payload) do
end_payload.merge(
- 'message' => 'TestWorker JID-da883554ee4fe414012f5f42: fail: 0.0 sec',
+ 'message' => "#{worker_class} JID-da883554ee4fe414012f5f42: fail: 0.0 sec",
'job_status' => 'fail',
'exception.class' => 'ArgumentError',
'exception.message' => 'Something went wrong',
diff --git a/spec/support/shared_examples/ci/stage_shared_examples.rb b/spec/support/shared_examples/ci/stage_shared_examples.rb
index a2849e00d27..cdb1058e584 100644
--- a/spec/support/shared_examples/ci/stage_shared_examples.rb
+++ b/spec/support/shared_examples/ci/stage_shared_examples.rb
@@ -21,7 +21,7 @@ RSpec.shared_examples 'manual playable stage' do |stage_type|
context 'when is skipped' do
let(:status) { 'skipped' }
- it { is_expected.to be_truthy }
+ it { is_expected.to be_falsy }
end
end
end
diff --git a/spec/workers/gitlab/github_import/stage/import_attachments_worker_spec.rb b/spec/workers/gitlab/github_import/stage/import_attachments_worker_spec.rb
index 2945bcbe641..e385a5aaf3f 100644
--- a/spec/workers/gitlab/github_import/stage/import_attachments_worker_spec.rb
+++ b/spec/workers/gitlab/github_import/stage/import_attachments_worker_spec.rb
@@ -10,7 +10,7 @@ RSpec.describe Gitlab::GithubImport::Stage::ImportAttachmentsWorker, feature_cat
let(:stage_enabled) { true }
before do
- settings.write({ attachments_import: stage_enabled })
+ settings.write({ optional_stages: { attachments_import: stage_enabled } })
end
describe '#import' do
diff --git a/spec/workers/gitlab/github_import/stage/import_collaborators_worker_spec.rb b/spec/workers/gitlab/github_import/stage/import_collaborators_worker_spec.rb
index 33ecf848997..808f6e827ed 100644
--- a/spec/workers/gitlab/github_import/stage/import_collaborators_worker_spec.rb
+++ b/spec/workers/gitlab/github_import/stage/import_collaborators_worker_spec.rb
@@ -16,7 +16,7 @@ RSpec.describe Gitlab::GithubImport::Stage::ImportCollaboratorsWorker, feature_c
let(:push_rights_granted) { true }
before do
- settings.write({ collaborators_import: stage_enabled })
+ settings.write({ optional_stages: { collaborators_import: stage_enabled } })
allow(client).to receive(:repository).with(project.import_source)
.and_return({ permissions: { push: push_rights_granted } })
end
diff --git a/spec/workers/gitlab/github_import/stage/import_issue_events_worker_spec.rb b/spec/workers/gitlab/github_import/stage/import_issue_events_worker_spec.rb
index c70ee0250e8..7b0cf77bbbe 100644
--- a/spec/workers/gitlab/github_import/stage/import_issue_events_worker_spec.rb
+++ b/spec/workers/gitlab/github_import/stage/import_issue_events_worker_spec.rb
@@ -11,7 +11,7 @@ RSpec.describe Gitlab::GithubImport::Stage::ImportIssueEventsWorker, feature_cat
let(:stage_enabled) { true }
before do
- settings.write({ single_endpoint_issue_events_import: stage_enabled })
+ settings.write({ optional_stages: { single_endpoint_issue_events_import: stage_enabled } })
end
describe '#import' do
diff --git a/spec/workers/gitlab/github_import/stage/import_issues_and_diff_notes_worker_spec.rb b/spec/workers/gitlab/github_import/stage/import_issues_and_diff_notes_worker_spec.rb
index 872201ece93..188cf3530f7 100644
--- a/spec/workers/gitlab/github_import/stage/import_issues_and_diff_notes_worker_spec.rb
+++ b/spec/workers/gitlab/github_import/stage/import_issues_and_diff_notes_worker_spec.rb
@@ -10,7 +10,7 @@ RSpec.describe Gitlab::GithubImport::Stage::ImportIssuesAndDiffNotesWorker, feat
let(:single_endpoint_optional_stage) { true }
before do
- settings.write({ single_endpoint_notes_import: single_endpoint_optional_stage })
+ settings.write({ optional_stages: { single_endpoint_notes_import: single_endpoint_optional_stage } })
end
describe '#import' do
diff --git a/spec/workers/gitlab/github_import/stage/import_notes_worker_spec.rb b/spec/workers/gitlab/github_import/stage/import_notes_worker_spec.rb
index 8c0004c0f3f..dcceeb1d6c2 100644
--- a/spec/workers/gitlab/github_import/stage/import_notes_worker_spec.rb
+++ b/spec/workers/gitlab/github_import/stage/import_notes_worker_spec.rb
@@ -10,7 +10,7 @@ RSpec.describe Gitlab::GithubImport::Stage::ImportNotesWorker, feature_category:
let(:single_endpoint_optional_stage) { true }
before do
- settings.write({ single_endpoint_notes_import: single_endpoint_optional_stage })
+ settings.write({ optional_stages: { single_endpoint_notes_import: single_endpoint_optional_stage } })
end
describe '#import' do