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:
authorGitLab Bot <gitlab-bot@gitlab.com>2024-01-16 21:09:25 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2024-01-16 21:09:25 +0300
commite18006fc6313b1d04128416cdb5f1533adcdb53e (patch)
treead418c4afbfcc8f83bcf5b4a9c897a2139e79e13
parentcb8835f38a3e4c188e9a73adf45936e2a95f40ae (diff)
Add latest changes from gitlab-org/gitlab@master
-rw-r--r--.gitlab-ci.yml2
-rw-r--r--.gitlab/ci/rules.gitlab-ci.yml3
-rw-r--r--app/assets/javascripts/issues/show/components/description.vue4
-rw-r--r--app/assets/javascripts/work_items/components/notes/work_item_comment_form.vue12
-rw-r--r--app/assets/javascripts/work_items/components/notes/work_item_comment_locked.vue4
-rw-r--r--app/assets/javascripts/work_items/components/shared/work_item_link_child_contents.vue6
-rw-r--r--app/assets/javascripts/work_items/components/work_item_links/work_item_link_child.vue8
-rw-r--r--app/assets/javascripts/work_items/constants.js5
-rw-r--r--app/graphql/mutations/notes/create/discussion.rb17
-rw-r--r--app/graphql/mutations/work_items/create.rb10
-rw-r--r--app/graphql/types/mutation_type.rb1
-rw-r--r--app/helpers/auth_helper.rb3
-rw-r--r--app/helpers/groups_helper.rb2
-rw-r--r--app/helpers/work_items_helper.rb2
-rw-r--r--app/models/application_setting.rb6
-rw-r--r--app/models/namespace_setting.rb2
-rw-r--r--app/services/google_cloud_platform/artifact_registry/list_docker_images_service.rb2
-rw-r--r--app/services/import/github_service.rb21
-rw-r--r--app/views/groups/settings/_git_access_protocols.html.haml2
-rw-r--r--app/views/groups/work_items/show.html.haml2
-rw-r--r--app/views/projects/issues/_work_item_links.html.haml2
-rw-r--r--app/views/projects/work_items/show.html.haml2
-rw-r--r--app/workers/concerns/gitlab/bitbucket_import/stage_methods.rb2
-rw-r--r--app/workers/concerns/gitlab/bitbucket_server_import/stage_methods.rb2
-rw-r--r--app/workers/concerns/gitlab/jira_import/import_worker.rb2
-rw-r--r--app/workers/gitlab/bitbucket_import/advance_stage_worker.rb4
-rw-r--r--app/workers/gitlab/bitbucket_server_import/advance_stage_worker.rb4
-rw-r--r--app/workers/gitlab/github_import/advance_stage_worker.rb2
-rw-r--r--app/workers/gitlab/import/advance_stage.rb7
-rw-r--r--app/workers/gitlab/jira_import/advance_stage_worker.rb1
-rw-r--r--app/workers/gitlab/jira_import/stage/start_import_worker.rb3
-rw-r--r--config/feature_flags/development/enforce_ssh_certificates.yml8
-rw-r--r--config/feature_flags/development/lfs_check.yml8
-rw-r--r--data/whats_new/202401180001_16_8.yml47
-rw-r--r--doc/administration/settings/sign_up_restrictions.md2
-rw-r--r--doc/api/graphql/reference/index.md22
-rw-r--r--doc/user/clusters/agent/gitops.md7
-rw-r--r--doc/user/index.md4
-rw-r--r--doc/user/project/repository/code_suggestions/repository_xray.md6
-rw-r--r--gems/click_house-client/lib/click_house/client/formatter.rb7
-rw-r--r--gems/click_house-client/spec/click_house/client/formatter_spec.rb20
-rw-r--r--lib/gitlab/bitbucket_server_import/importers/pull_request_importer.rb2
-rw-r--r--lib/gitlab/bitbucket_server_import/importers/pull_request_notes_importer.rb2
-rw-r--r--lib/gitlab/bitbucket_server_import/importers/users_importer.rb4
-rw-r--r--lib/gitlab/checks/lfs_check.rb4
-rw-r--r--lib/gitlab/import/mentions_converter.rb (renamed from lib/gitlab/bitbucket_server_import/mentions_converter.rb)7
-rw-r--r--lib/gitlab/import/user_from_mention.rb (renamed from lib/gitlab/bitbucket_server_import/user_from_mention.rb)10
-rw-r--r--lib/gitlab/observability.rb4
-rw-r--r--lib/google_cloud_platform/artifact_registry/client.rb57
-rw-r--r--lib/google_cloud_platform/base_client.rb30
-rw-r--r--lib/google_cloud_platform/jwt.rb86
-rw-r--r--lib/integrations/google_cloud_platform/artifact_registry/client.rb59
-rw-r--r--lib/integrations/google_cloud_platform/base_client.rb32
-rw-r--r--lib/integrations/google_cloud_platform/jwt.rb88
-rw-r--r--locale/gitlab.pot9
-rw-r--r--qa/qa/fixtures/files/one_bbin512 -> 0 bytes
-rw-r--r--qa/qa/page/main/login.rb6
-rw-r--r--qa/qa/runtime/env.rb8
-rw-r--r--qa/qa/specs/features/browser_ui/10_govern/login/oauth_login_with_facebook_spec.rb22
-rw-r--r--qa/qa/vendor/facebook/page/login.rb23
-rw-r--r--spec/frontend/authentication/password/components/password_input_spec.js1
-rw-r--r--spec/frontend/members/components/table/members_table_spec.js13
-rw-r--r--spec/frontend/members/index_spec.js4
-rw-r--r--spec/frontend/work_items/components/work_item_assignees_spec.js6
-rw-r--r--spec/frontend/work_items/components/work_item_links/work_item_link_child_spec.js4
-rw-r--r--spec/helpers/groups_helper_spec.rb12
-rw-r--r--spec/helpers/work_items_helper_spec.rb6
-rw-r--r--spec/lib/gitlab/auth_spec.rb76
-rw-r--r--spec/lib/gitlab/bitbucket_server_import/importers/pull_request_importer_spec.rb5
-rw-r--r--spec/lib/gitlab/bitbucket_server_import/importers/pull_request_notes_importer_spec.rb4
-rw-r--r--spec/lib/gitlab/checks/lfs_check_spec.rb12
-rw-r--r--spec/lib/gitlab/import/mentions_converter_spec.rb (renamed from spec/lib/gitlab/bitbucket_server_import/mentions_converter_spec.rb)5
-rw-r--r--spec/lib/gitlab/import/user_from_mention_spec.rb (renamed from spec/lib/gitlab/bitbucket_server_import/user_from_mention_spec.rb)14
-rw-r--r--spec/lib/gitlab/observability_spec.rb47
-rw-r--r--spec/lib/gitlab/protocol_access_spec.rb47
-rw-r--r--spec/lib/google_cloud_platform/artifact_registry/client_spec.rb (renamed from spec/lib/integrations/google_cloud_platform/artifact_registry/client_spec.rb)2
-rw-r--r--spec/lib/google_cloud_platform/jwt_spec.rb (renamed from spec/lib/integrations/google_cloud_platform/jwt_spec.rb)2
-rw-r--r--spec/models/namespace_setting_spec.rb2
-rw-r--r--spec/requests/api/graphql/mutations/notes/create/discussion_spec.rb45
-rw-r--r--spec/requests/api/graphql/mutations/work_items/create_spec.rb12
-rw-r--r--spec/services/google_cloud_platform/artifact_registry/list_docker_images_service_spec.rb4
-rw-r--r--spec/services/import/github_service_spec.rb34
-rw-r--r--spec/workers/every_sidekiq_worker_spec.rb44
83 files changed, 565 insertions, 565 deletions
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 7998dbd8b96..d2f1fc8c2ff 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -56,7 +56,7 @@ default:
workflow:
name: '$PIPELINE_NAME'
rules:
- - if: '$CI_PROJECT_PATH == "gitlab-org/gitaly" && $CI_PIPELINE_SOURCE == "parent_pipeline" && $GITALY_TEST'
+ - if: '$CI_PIPELINE_SOURCE == "pipeline" && $GITALY_TEST'
variables:
<<: *default-ruby-variables
PIPELINE_NAME: 'Gitaly Rails Test Pipeline'
diff --git a/.gitlab/ci/rules.gitlab-ci.yml b/.gitlab/ci/rules.gitlab-ci.yml
index ab603ecb9f2..539d1a0bdf1 100644
--- a/.gitlab/ci/rules.gitlab-ci.yml
+++ b/.gitlab/ci/rules.gitlab-ci.yml
@@ -1151,6 +1151,7 @@
when: never
# If any of the files that are DIRECTLY related to generating or managing the GLFM specification change,
# run `glfm-verify` to get quick feedback on any needed updates, even if the MR is not yet approved
+ - <<: *if-default-refs
- changes: *glfm-patterns
# Otherwise do not run `glfm-verify` if the MR is not approved
- <<: *if-merge-request-not-approved
@@ -1158,6 +1159,7 @@
# If we passed all the previous rules, run `glfm-verify` if there are any changes that could impact `glfm-verify`.
# This could potentially be a wide range of files, so we reuse `setup-test-env-patterns`, which includes
# almost all app files except docs files.
+ - <<: *if-default-refs
- changes: *setup-test-env-patterns
# If we are forcing all rspec to run, run this job too.
- <<: *if-merge-request-labels-run-all-rspec
@@ -1233,6 +1235,7 @@
.frontend:rules:compile-test-assets:
rules:
- if: '$ENABLE_COMPILE_TEST_ASSETS == "true"'
+ - if: '$ENABLE_RSPEC == "true"'
- <<: *if-merge-request-labels-run-all-rspec
- <<: *if-merge-request
changes: *backend-patterns
diff --git a/app/assets/javascripts/issues/show/components/description.vue b/app/assets/javascripts/issues/show/components/description.vue
index 369aa694739..a0bc76537fa 100644
--- a/app/assets/javascripts/issues/show/components/description.vue
+++ b/app/assets/javascripts/issues/show/components/description.vue
@@ -20,7 +20,7 @@ import {
sprintfWorkItem,
I18N_WORK_ITEM_ERROR_CREATING,
I18N_WORK_ITEM_ERROR_DELETING,
- TASK_TYPE_NAME,
+ WORK_ITEM_TYPE_VALUE_TASK,
} from '~/work_items/constants';
import { renderGFM } from '~/behaviors/markdown/render_gfm';
import eventHub from '../event_hub';
@@ -129,7 +129,7 @@ export default {
},
computed: {
taskWorkItemTypeId() {
- return this.workItemTypes.find((type) => type.name === TASK_TYPE_NAME)?.id;
+ return this.workItemTypes.find((type) => type.name === WORK_ITEM_TYPE_VALUE_TASK)?.id;
},
issueGid() {
return this.issueId ? convertToGraphQLId(TYPENAME_WORK_ITEM, this.issueId) : null;
diff --git a/app/assets/javascripts/work_items/components/notes/work_item_comment_form.vue b/app/assets/javascripts/work_items/components/notes/work_item_comment_form.vue
index 9ede327b2f1..480549452ad 100644
--- a/app/assets/javascripts/work_items/components/notes/work_item_comment_form.vue
+++ b/app/assets/javascripts/work_items/components/notes/work_item_comment_form.vue
@@ -4,7 +4,11 @@ import { helpPagePath } from '~/helpers/help_page_helper';
import { s__, __ } from '~/locale';
import Tracking from '~/tracking';
import { capitalizeFirstCharacter } from '~/lib/utils/text_utility';
-import { STATE_OPEN, TRACKING_CATEGORY_SHOW, TASK_TYPE_NAME } from '~/work_items/constants';
+import {
+ STATE_OPEN,
+ TRACKING_CATEGORY_SHOW,
+ WORK_ITEM_TYPE_VALUE_TASK,
+} from '~/work_items/constants';
import { getDraft, clearDraft, updateDraft } from '~/lib/utils/autosave';
import { confirmAction } from '~/lib/utils/confirm_via_gl_modal/confirm_via_gl_modal';
import MarkdownEditor from '~/vue_shared/components/markdown/markdown_editor.vue';
@@ -127,10 +131,12 @@ export default {
return this.isNoteInternal ? this.$options.i18n.addInternalNote : this.commentButtonText;
},
workItemDocPath() {
- return this.workItemType === TASK_TYPE_NAME ? 'user/tasks.html' : 'user/okrs.html';
+ return this.workItemType === WORK_ITEM_TYPE_VALUE_TASK ? 'user/tasks.html' : 'user/okrs.html';
},
workItemDocAnchor() {
- return this.workItemType === TASK_TYPE_NAME ? 'confidential-tasks' : 'confidential-okrs';
+ return this.workItemType === WORK_ITEM_TYPE_VALUE_TASK
+ ? 'confidential-tasks'
+ : 'confidential-okrs';
},
getWorkItemData() {
return {
diff --git a/app/assets/javascripts/work_items/components/notes/work_item_comment_locked.vue b/app/assets/javascripts/work_items/components/notes/work_item_comment_locked.vue
index c1b6903cf17..31330204b7e 100644
--- a/app/assets/javascripts/work_items/components/notes/work_item_comment_locked.vue
+++ b/app/assets/javascripts/work_items/components/notes/work_item_comment_locked.vue
@@ -2,7 +2,7 @@
import { GlLink, GlIcon } from '@gitlab/ui';
import { __, sprintf } from '~/locale';
import { helpPagePath } from '~/helpers/help_page_helper';
-import { TASK_TYPE_NAME } from '~/work_items/constants';
+import { WORK_ITEM_TYPE_VALUE_TASK } from '~/work_items/constants';
export default {
components: {
@@ -13,7 +13,7 @@ export default {
workItemType: {
required: false,
type: String,
- default: TASK_TYPE_NAME,
+ default: WORK_ITEM_TYPE_VALUE_TASK,
},
isProjectArchived: {
required: false,
diff --git a/app/assets/javascripts/work_items/components/shared/work_item_link_child_contents.vue b/app/assets/javascripts/work_items/components/shared/work_item_link_child_contents.vue
index 78afb9a04ef..7ea2b7ff86a 100644
--- a/app/assets/javascripts/work_items/components/shared/work_item_link_child_contents.vue
+++ b/app/assets/javascripts/work_items/components/shared/work_item_link_child_contents.vue
@@ -6,7 +6,6 @@ import RichTimestampTooltip from '~/vue_shared/components/rich_timestamp_tooltip
import WorkItemLinkChildMetadata from 'ee_else_ce/work_items/components/shared/work_item_link_child_metadata.vue';
import {
STATE_OPEN,
- TASK_TYPE_NAME,
WIDGET_TYPE_PROGRESS,
WIDGET_TYPE_HIERARCHY,
WIDGET_TYPE_HEALTH_STATUS,
@@ -14,6 +13,7 @@ import {
WIDGET_TYPE_ASSIGNEES,
WIDGET_TYPE_LABELS,
WORK_ITEM_NAME_TO_ICON_MAP,
+ WORK_ITEM_TYPE_VALUE_TASK,
} from '../../constants';
export default {
@@ -79,7 +79,7 @@ export default {
return this.childItem.state === STATE_OPEN;
},
iconName() {
- if (this.childItemType === TASK_TYPE_NAME && !this.showTaskIcon) {
+ if (this.childItemType === WORK_ITEM_TYPE_VALUE_TASK && !this.showTaskIcon) {
return this.isChildItemOpen ? 'issue-open-m' : 'issue-close';
}
return WORK_ITEM_NAME_TO_ICON_MAP[this.childItemType];
@@ -88,7 +88,7 @@ export default {
return this.childItem.workItemType.name;
},
iconClass() {
- if (this.childItemType === TASK_TYPE_NAME && !this.showTaskIcon) {
+ if (this.childItemType === WORK_ITEM_TYPE_VALUE_TASK && !this.showTaskIcon) {
return this.isChildItemOpen ? 'gl-text-green-500' : 'gl-text-blue-500';
}
return '';
diff --git a/app/assets/javascripts/work_items/components/work_item_links/work_item_link_child.vue b/app/assets/javascripts/work_items/components/work_item_links/work_item_link_child.vue
index f43718c4cb8..1de737765e2 100644
--- a/app/assets/javascripts/work_items/components/work_item_links/work_item_link_child.vue
+++ b/app/assets/javascripts/work_items/components/work_item_links/work_item_link_child.vue
@@ -8,10 +8,10 @@ import { createAlert } from '~/alert';
import updateWorkItemMutation from '../../graphql/update_work_item.mutation.graphql';
import {
STATE_OPEN,
- TASK_TYPE_NAME,
- WORK_ITEM_TYPE_VALUE_OBJECTIVE,
WIDGET_TYPE_HIERARCHY,
WORK_ITEM_NAME_TO_ICON_MAP,
+ WORK_ITEM_TYPE_VALUE_OBJECTIVE,
+ WORK_ITEM_TYPE_VALUE_TASK,
} from '../../constants';
import getWorkItemTreeQuery from '../../graphql/work_item_tree.query.graphql';
import WorkItemLinkChildContents from '../shared/work_item_link_child_contents.vue';
@@ -76,13 +76,13 @@ export default {
return this.childItem.workItemType.name;
},
iconName() {
- if (this.childItemType === TASK_TYPE_NAME) {
+ if (this.childItemType === WORK_ITEM_TYPE_VALUE_TASK) {
return this.isItemOpen ? 'issue-open-m' : 'issue-close';
}
return WORK_ITEM_NAME_TO_ICON_MAP[this.childItemType];
},
iconClass() {
- if (this.childItemType === TASK_TYPE_NAME) {
+ if (this.childItemType === WORK_ITEM_TYPE_VALUE_TASK) {
return this.isItemOpen ? 'gl-text-green-500' : 'gl-text-blue-500';
}
return '';
diff --git a/app/assets/javascripts/work_items/constants.js b/app/assets/javascripts/work_items/constants.js
index 62fdc8a21c2..fcf73e5f822 100644
--- a/app/assets/javascripts/work_items/constants.js
+++ b/app/assets/javascripts/work_items/constants.js
@@ -10,8 +10,6 @@ export const STATE_EVENT_CLOSE = 'CLOSE';
export const TRACKING_CATEGORY_SHOW = 'workItems:show';
-export const TASK_TYPE_NAME = 'Task';
-
export const WIDGET_TYPE_ASSIGNEES = 'ASSIGNEES';
export const WIDGET_TYPE_DESCRIPTION = 'DESCRIPTION';
export const WIDGET_TYPE_AWARD_EMOJI = 'AWARD_EMOJI';
@@ -46,9 +44,6 @@ export const WORK_ITEM_TYPE_VALUE_REQUIREMENTS = 'Requirements';
export const WORK_ITEM_TYPE_VALUE_KEY_RESULT = 'Key Result';
export const WORK_ITEM_TYPE_VALUE_OBJECTIVE = 'Objective';
-export const NAMESPACE_GROUP = 'group';
-export const NAMESPACE_PROJECT = 'project';
-
export const WORK_ITEM_TITLE_MAX_LENGTH = 255;
export const i18n = {
diff --git a/app/graphql/mutations/notes/create/discussion.rb b/app/graphql/mutations/notes/create/discussion.rb
new file mode 100644
index 00000000000..c90f5565284
--- /dev/null
+++ b/app/graphql/mutations/notes/create/discussion.rb
@@ -0,0 +1,17 @@
+# frozen_string_literal: true
+
+module Mutations
+ module Notes
+ module Create
+ class Discussion < Base
+ graphql_name 'CreateDiscussion'
+
+ private
+
+ def create_note_params(noteable, args)
+ super(noteable, args).merge({ type: 'DiscussionNote' })
+ end
+ end
+ end
+ end
+end
diff --git a/app/graphql/mutations/work_items/create.rb b/app/graphql/mutations/work_items/create.rb
index 754b453ce5d..7ce508e5ef1 100644
--- a/app/graphql/mutations/work_items/create.rb
+++ b/app/graphql/mutations/work_items/create.rb
@@ -60,7 +60,6 @@ module Mutations
def resolve(project_path: nil, namespace_path: nil, **attributes)
container_path = project_path || namespace_path
container = authorized_find!(container_path)
- check_env_feature_available!(container)
check_feature_available!(container)
params = global_id_compatibility_params(attributes).merge(author_id: current_user.id)
@@ -84,15 +83,6 @@ module Mutations
private
- # This is just a temporary measure while we migrate and backfill epic internal_ids
- # More info in https://gitlab.com/gitlab-org/gitlab/-/merge_requests/139367
- def check_env_feature_available!(container)
- return unless container.is_a?(::Group) && Rails.env.production?
-
- message = 'Group level work items are disabled. Only project paths allowed in `namespacePath`.'
- raise Gitlab::Graphql::Errors::ArgumentError, message
- end
-
def check_feature_available!(container)
return unless container.is_a?(::Group) && Feature.disabled?(:namespace_level_work_items, container)
diff --git a/app/graphql/types/mutation_type.rb b/app/graphql/types/mutation_type.rb
index 0a725c2e0a7..51ab6880b1a 100644
--- a/app/graphql/types/mutation_type.rb
+++ b/app/graphql/types/mutation_type.rb
@@ -102,6 +102,7 @@ module Types
mount_mutation Mutations::Notes::Create::Note, calls_gitaly: true
mount_mutation Mutations::Notes::Create::DiffNote, calls_gitaly: true
mount_mutation Mutations::Notes::Create::ImageDiffNote, calls_gitaly: true
+ mount_mutation Mutations::Notes::Create::Discussion, calls_gitaly: true
mount_mutation Mutations::Notes::Update::Note
mount_mutation Mutations::Notes::Update::ImageDiffNote
mount_mutation Mutations::Notes::RepositionImageDiffNote
diff --git a/app/helpers/auth_helper.rb b/app/helpers/auth_helper.rb
index d0a9197db0a..61fe9e133ea 100644
--- a/app/helpers/auth_helper.rb
+++ b/app/helpers/auth_helper.rb
@@ -52,8 +52,7 @@ module AuthHelper
saml: 'saml-login-button',
openid_connect: 'oidc-login-button',
github: 'github-login-button',
- gitlab: 'gitlab-oauth-login-button',
- facebook: 'facebook-login-button'
+ gitlab: 'gitlab-oauth-login-button'
}[provider.to_sym]
end
diff --git a/app/helpers/groups_helper.rb b/app/helpers/groups_helper.rb
index 96ae7be5fdc..7db833edff5 100644
--- a/app/helpers/groups_helper.rb
+++ b/app/helpers/groups_helper.rb
@@ -184,7 +184,7 @@ module GroupsHelper
}
end
- def enabled_git_access_protocol_options_for_group(_)
+ def enabled_git_access_protocol_options_for_group
case ::Gitlab::CurrentSettings.enabled_git_access_protocol
when nil, ""
[[_("Both SSH and HTTP(S)"), "all"], [_("Only SSH"), "ssh"], [_("Only HTTP(S)"), "http"]]
diff --git a/app/helpers/work_items_helper.rb b/app/helpers/work_items_helper.rb
index d2e3d41377a..b7e9699dc12 100644
--- a/app/helpers/work_items_helper.rb
+++ b/app/helpers/work_items_helper.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
module WorkItemsHelper
- def work_items_index_data(resource_parent)
+ def work_items_show_data(resource_parent)
{
full_path: resource_parent.full_path,
issues_list_path:
diff --git a/app/models/application_setting.rb b/app/models/application_setting.rb
index 35d4722b711..490029ce0b5 100644
--- a/app/models/application_setting.rb
+++ b/app/models/application_setting.rb
@@ -240,7 +240,7 @@ class ApplicationSetting < MainClusterwide::ApplicationRecord
if: :auto_devops_enabled?
validates :enabled_git_access_protocol,
- inclusion: { in: ->(_) { enabled_git_access_protocol_values }, allow_blank: true }
+ inclusion: { in: %w[ssh http], allow_blank: true }
validates :domain_denylist,
presence: { message: 'Domain denylist cannot be empty if denylist is enabled.' },
@@ -898,10 +898,6 @@ class ApplicationSetting < MainClusterwide::ApplicationRecord
HUMANIZED_ATTRIBUTES[attribute.to_sym] || super
end
- def self.enabled_git_access_protocol_values
- %w[ssh http]
- end
-
def parsed_grafana_url
@parsed_grafana_url ||= Gitlab::Utils.parse_url(grafana_url)
end
diff --git a/app/models/namespace_setting.rb b/app/models/namespace_setting.rb
index e61e5a7f37e..95400beaf50 100644
--- a/app/models/namespace_setting.rb
+++ b/app/models/namespace_setting.rb
@@ -15,7 +15,7 @@ class NamespaceSetting < ApplicationRecord
belongs_to :namespace, inverse_of: :namespace_settings
enum jobs_to_be_done: { basics: 0, move_repository: 1, code_storage: 2, exploring: 3, ci: 4, other: 5 }, _suffix: true
- enum enabled_git_access_protocol: { all: 0, ssh: 1, http: 2, ssh_certificates: 3 }, _suffix: true
+ enum enabled_git_access_protocol: { all: 0, ssh: 1, http: 2 }, _suffix: true
attribute :default_branch_protection_defaults, default: -> { {} }
diff --git a/app/services/google_cloud_platform/artifact_registry/list_docker_images_service.rb b/app/services/google_cloud_platform/artifact_registry/list_docker_images_service.rb
index c9afa8609f9..1e227a2fcb6 100644
--- a/app/services/google_cloud_platform/artifact_registry/list_docker_images_service.rb
+++ b/app/services/google_cloud_platform/artifact_registry/list_docker_images_service.rb
@@ -16,7 +16,7 @@ module GoogleCloudPlatform
end
def client
- ::Integrations::GoogleCloudPlatform::ArtifactRegistry::Client.new(
+ ::GoogleCloudPlatform::ArtifactRegistry::Client.new(
project: project,
user: current_user,
gcp_project_id: gcp_project_id,
diff --git a/app/services/import/github_service.rb b/app/services/import/github_service.rb
index ffd26e2aaca..92a91740304 100644
--- a/app/services/import/github_service.rb
+++ b/app/services/import/github_service.rb
@@ -5,6 +5,7 @@ module Import
include ActiveSupport::NumberHelper
include Gitlab::Utils::StrongMemoize
+ MINIMUM_IMPORT_SCOPE = %w[repo].freeze
COLLAB_IMPORT_SCOPES = %w[admin:org read:org].freeze
attr_accessor :client
@@ -14,7 +15,7 @@ module Import
context_error = validate_context
return context_error if context_error
- scope_error = validate_collaborators_import_scope
+ scope_error = validate_scopes
return scope_error if scope_error
project = create_project(access_params, provider)
@@ -103,18 +104,22 @@ module Import
private
- def validate_collaborators_import_scope
- collaborators_import = params.dig(:optional_stages, :collaborators_import)
- # A value for `collaborators_import` may not be included in POST params
- # and the default value is `true`
- return unless collaborators_import == true || collaborators_import.nil?
-
+ def validate_scopes
# We need to call `#repo` to ensure the `#last_response` from the client has the headers we need.
repo
scopes = client.octokit.last_response.headers["x-oauth-scopes"]
scopes = scopes.split(',').map(&:strip)
- return if (scopes & COLLAB_IMPORT_SCOPES).any?
+ unless scopes.intersect?(MINIMUM_IMPORT_SCOPE + COLLAB_IMPORT_SCOPES)
+ return log_and_return_error('Invalid Scope', _('Your GitHub access token does not have the correct scope to import.'), :unprocessable_entity)
+ end
+
+ collaborators_import = params.dig(:optional_stages, :collaborators_import)
+ # A value for `collaborators_import` may not be included in POST params
+ # and the default value is `true`
+ return unless collaborators_import == true || collaborators_import.nil?
+
+ return if scopes.intersect?(COLLAB_IMPORT_SCOPES)
log_and_return_error('Invalid scope', _('Your GitHub access token does not have the correct scope to import collaborators.'), :unprocessable_entity)
end
diff --git a/app/views/groups/settings/_git_access_protocols.html.haml b/app/views/groups/settings/_git_access_protocols.html.haml
index c9cbe56e6ec..c6d32cae760 100644
--- a/app/views/groups/settings/_git_access_protocols.html.haml
+++ b/app/views/groups/settings/_git_access_protocols.html.haml
@@ -1,7 +1,7 @@
- if group.root?
.form-group
= f.label _('Enabled Git access protocols'), class: 'label-bold'
- = f.select :enabled_git_access_protocol, options_for_select(enabled_git_access_protocol_options_for_group(group), group.enabled_git_access_protocol), {}, class: 'form-control', disabled: !::Gitlab::CurrentSettings.enabled_git_access_protocol.blank?
+ = f.select :enabled_git_access_protocol, options_for_select(enabled_git_access_protocol_options_for_group, group.enabled_git_access_protocol), {}, class: 'form-control', disabled: !::Gitlab::CurrentSettings.enabled_git_access_protocol.blank?
- if !::Gitlab::CurrentSettings.enabled_git_access_protocol.blank?
.form-text.text-muted
= _("This setting has been configured at the instance level and cannot be overridden per group")
diff --git a/app/views/groups/work_items/show.html.haml b/app/views/groups/work_items/show.html.haml
index 7def8b0d6e6..7363d8f977a 100644
--- a/app/views/groups/work_items/show.html.haml
+++ b/app/views/groups/work_items/show.html.haml
@@ -4,4 +4,4 @@
- @gfm_form = true
- @noteable_type = 'WorkItem'
-#js-work-items{ data: work_items_index_data(@group).merge(iid: request.params['iid']) }
+#js-work-items{ data: work_items_show_data(@group).merge(iid: request.params['iid']) }
diff --git a/app/views/projects/issues/_work_item_links.html.haml b/app/views/projects/issues/_work_item_links.html.haml
index bf23fdc761b..7a8f2163bf6 100644
--- a/app/views/projects/issues/_work_item_links.html.haml
+++ b/app/views/projects/issues/_work_item_links.html.haml
@@ -1,6 +1,6 @@
.js-work-item-links-root{ data: { issuable_id: @issue.id,
issuable_iid: @issue.iid,
full_path: @project.full_path,
- wi: work_items_index_data(@project),
+ wi: work_items_show_data(@project),
register_path: new_user_registration_path(redirect_to_referer: 'yes'),
sign_in_path: new_session_path(:user, redirect_to_referer: 'yes') } }
diff --git a/app/views/projects/work_items/show.html.haml b/app/views/projects/work_items/show.html.haml
index 7e0bddf1b5d..c69e42917f1 100644
--- a/app/views/projects/work_items/show.html.haml
+++ b/app/views/projects/work_items/show.html.haml
@@ -4,4 +4,4 @@
- @gfm_form = true
- @noteable_type = 'WorkItem'
-#js-work-items{ data: work_items_index_data(@project) }
+#js-work-items{ data: work_items_show_data(@project) }
diff --git a/app/workers/concerns/gitlab/bitbucket_import/stage_methods.rb b/app/workers/concerns/gitlab/bitbucket_import/stage_methods.rb
index 2885cc29532..51e2f5cff22 100644
--- a/app/workers/concerns/gitlab/bitbucket_import/stage_methods.rb
+++ b/app/workers/concerns/gitlab/bitbucket_import/stage_methods.rb
@@ -14,7 +14,7 @@ module Gitlab
data_consistency :always
- sidekiq_options dead: false, retry: 3
+ sidekiq_options dead: false, retry: 6
sidekiq_retries_exhausted do |msg, e|
Gitlab::Import::ImportFailureService.track(
diff --git a/app/workers/concerns/gitlab/bitbucket_server_import/stage_methods.rb b/app/workers/concerns/gitlab/bitbucket_server_import/stage_methods.rb
index db4e71051c0..cf5710e6108 100644
--- a/app/workers/concerns/gitlab/bitbucket_server_import/stage_methods.rb
+++ b/app/workers/concerns/gitlab/bitbucket_server_import/stage_methods.rb
@@ -14,7 +14,7 @@ module Gitlab
data_consistency :always
- sidekiq_options dead: false, retry: 3
+ sidekiq_options dead: false, retry: 6
sidekiq_retries_exhausted do |msg, e|
Gitlab::Import::ImportFailureService.track(
diff --git a/app/workers/concerns/gitlab/jira_import/import_worker.rb b/app/workers/concerns/gitlab/jira_import/import_worker.rb
index d18b9ff023b..c597e791cbe 100644
--- a/app/workers/concerns/gitlab/jira_import/import_worker.rb
+++ b/app/workers/concerns/gitlab/jira_import/import_worker.rb
@@ -8,9 +8,9 @@ module Gitlab
included do
include ApplicationWorker
- sidekiq_options retry: 3
include ProjectImportOptions
include Gitlab::JiraImport::QueueOptions
+ sidekiq_options retry: 6
end
def perform(project_id)
diff --git a/app/workers/gitlab/bitbucket_import/advance_stage_worker.rb b/app/workers/gitlab/bitbucket_import/advance_stage_worker.rb
index ed89f332652..8242c5c8e9a 100644
--- a/app/workers/gitlab/bitbucket_import/advance_stage_worker.rb
+++ b/app/workers/gitlab/bitbucket_import/advance_stage_worker.rb
@@ -12,10 +12,6 @@ module Gitlab
data_consistency :delayed
- sidekiq_options dead: false, retry: 3
-
- feature_category :importers
-
loggable_arguments 1, 2
# The known importer stages and their corresponding Sidekiq workers.
diff --git a/app/workers/gitlab/bitbucket_server_import/advance_stage_worker.rb b/app/workers/gitlab/bitbucket_server_import/advance_stage_worker.rb
index 1fc35725c9f..9ce3837e66f 100644
--- a/app/workers/gitlab/bitbucket_server_import/advance_stage_worker.rb
+++ b/app/workers/gitlab/bitbucket_server_import/advance_stage_worker.rb
@@ -12,10 +12,6 @@ module Gitlab
data_consistency :delayed
- sidekiq_options dead: false, retry: 3
-
- feature_category :importers
-
loggable_arguments 1, 2
# The known importer stages and their corresponding Sidekiq workers.
diff --git a/app/workers/gitlab/github_import/advance_stage_worker.rb b/app/workers/gitlab/github_import/advance_stage_worker.rb
index 8de9850298b..316035fd683 100644
--- a/app/workers/gitlab/github_import/advance_stage_worker.rb
+++ b/app/workers/gitlab/github_import/advance_stage_worker.rb
@@ -14,8 +14,6 @@ module Gitlab
include ::Gitlab::Import::AdvanceStage
loggable_arguments 1, 2
- sidekiq_options retry: 6, dead: false
- feature_category :importers
# The known importer stages and their corresponding Sidekiq workers.
#
diff --git a/app/workers/gitlab/import/advance_stage.rb b/app/workers/gitlab/import/advance_stage.rb
index 709957556d3..ccd5f906462 100644
--- a/app/workers/gitlab/import/advance_stage.rb
+++ b/app/workers/gitlab/import/advance_stage.rb
@@ -3,6 +3,8 @@
module Gitlab
module Import
module AdvanceStage
+ extend ActiveSupport::Concern
+
INTERVAL = 30.seconds.to_i
TIMEOUT_DURATION = 2.hours
@@ -12,6 +14,11 @@ module Gitlab
# continuing to the next waiter.
BLOCKING_WAIT_TIME = 5
+ included do
+ sidekiq_options dead: false, retry: 6
+ feature_category :importers
+ end
+
# project_id - The ID of the project being imported.
# waiters - A Hash mapping Gitlab::JobWaiter keys to the number of
# remaining jobs.
diff --git a/app/workers/gitlab/jira_import/advance_stage_worker.rb b/app/workers/gitlab/jira_import/advance_stage_worker.rb
index 9641b55a584..55285080d95 100644
--- a/app/workers/gitlab/jira_import/advance_stage_worker.rb
+++ b/app/workers/gitlab/jira_import/advance_stage_worker.rb
@@ -7,7 +7,6 @@ module Gitlab
data_consistency :always
- sidekiq_options retry: 3
include QueueOptions
include ::Gitlab::Import::AdvanceStage
diff --git a/app/workers/gitlab/jira_import/stage/start_import_worker.rb b/app/workers/gitlab/jira_import/stage/start_import_worker.rb
index 3f6ad66e278..ceeccf41dee 100644
--- a/app/workers/gitlab/jira_import/stage/start_import_worker.rb
+++ b/app/workers/gitlab/jira_import/stage/start_import_worker.rb
@@ -8,11 +8,12 @@ module Gitlab
data_consistency :always
- sidekiq_options retry: 3
include ProjectStartImport
include ProjectImportOptions
include Gitlab::JiraImport::QueueOptions
+ sidekiq_options retry: 6
+
attr_reader :project
def perform(project_id)
diff --git a/config/feature_flags/development/enforce_ssh_certificates.yml b/config/feature_flags/development/enforce_ssh_certificates.yml
deleted file mode 100644
index beaa6c02869..00000000000
--- a/config/feature_flags/development/enforce_ssh_certificates.yml
+++ /dev/null
@@ -1,8 +0,0 @@
----
-name: enforce_ssh_certificates
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/132653
-rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/426235
-milestone: '16.5'
-type: development
-group: group::source code
-default_enabled: false
diff --git a/config/feature_flags/development/lfs_check.yml b/config/feature_flags/development/lfs_check.yml
deleted file mode 100644
index 8e13d46a02f..00000000000
--- a/config/feature_flags/development/lfs_check.yml
+++ /dev/null
@@ -1,8 +0,0 @@
----
-name: lfs_check
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/27451
-rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/233550
-milestone: '11.11'
-type: development
-group: group::source code
-default_enabled: true
diff --git a/data/whats_new/202401180001_16_8.yml b/data/whats_new/202401180001_16_8.yml
index 694b082fed6..54ea99a54b1 100644
--- a/data/whats_new/202401180001_16_8.yml
+++ b/data/whats_new/202401180001_16_8.yml
@@ -1,34 +1,23 @@
-# This is a template for a "Whats New" release.
-# A release typically contains multiple entries of features that we'd like to highlight.
-#
-# Below is an example of what a single entry should look like, it's required attributes,
-# and what types we expect those attribute values to be. All attributes are required.
-#
-# For more information please refer to the handbook documentation here:
-# https://about.gitlab.com/handbook/marketing/blog/release-posts/index.html#create-mr-for-whats-new-entries
-#
-# Please delete this line and above before submitting your merge request.
-
-- name: GCP Secret Manager support # Match the release post entry
- description: | # Do not modify this line, instead modify the lines below.
+- name: GCP Secret Manager support
+ description: |
Secrets stored in GCP Secrets Manager can now be easily retrieved and used in CI/CD jobs. Our new integration simplifies the process of interacting with GCP Secrets Manager through GitLab CI/CD, helping you streamline your build and deploy processes! This is just one of the many ways [GitLab and Google Cloud are better together](https://about.gitlab.com/blog/2023/08/29/gitlab-google-partnership-s3c/)!
- stage: Verify # String value of the stage that the feature was created in. e.g., Growth
- self-managed: true # Boolean value (true or false)
- gitlab-com: true # Boolean value (true or false)
- available_in: [Premium, Ultimate] # Array of strings. The Array brackets are required here. e.g., [Free, Premium, Ultimate]
+ stage: Verify
+ self-managed: true
+ gitlab-com: true
+ available_in: [Premium, Ultimate]
documentation_link: https://docs.gitlab.com/ee/ci/secrets/gcp_secret_manager.html # This is the documentation URL, but can be a URL to a video if there is one
- image_url: https://about.gitlab.com/images/16_8/gcp_secrets_mgr.png # This should be a full URL, generally taken from the release post content. If a video, use the youtube thumbnail URL with the structure of https://img.youtube.com/vi/UNIQUEID/hqdefault.jpg
- published_at: 2024-01-18 # YYYY-MM-DD
- release: 16.8 # XX.Y
+ image_url: https://about.gitlab.com/images/16_8/gcp_secrets_mgr.png
+ published_at: 2024-01-18
+ release: 16.8
-- name: Enforce 2FA for GitLab administrators # Match the release post entry
- description: | # Do not modify this line, instead modify the lines below.
+- name: Enforce 2FA for GitLab administrators
+ description: |
You can now enforce whether GitLab administrators are required to use two-factor authentication (2FA) in their self-managed instance. It is good security practice to use 2FA for all accounts, especially for privileged accounts like administrators. If this setting is enforced, and an administrator does not already use 2FA, they must set 2FA up on their next sign-in.
- stage: Govern # String value of the stage that the feature was created in. e.g., Growth
- self-managed: true # Boolean value (true or false)
- gitlab-com: false # Boolean value (true or false)
- available_in: [Free, Premium, Ultimate] # Array of strings. The Array brackets are required here. e.g., [Free, Premium, Ultimate]
+ stage: Govern
+ self-managed: true
+ gitlab-com: false
+ available_in: [Free, Premium, Ultimate]
documentation_link: https://docs.gitlab.com/ee/security/two_factor_authentication.html#enforce-2fa-for-administrator-users # This is the documentation URL, but can be a URL to a video if there is one
- image_url: https://img.youtube.com/vi/fHleeXzoB6k/hqdefault.jpg # This should be a full URL, generally taken from the release post content. If a video, use the youtube thumbnail URL with the structure of https://img.youtube.com/vi/UNIQUEID/hqdefault.jpg
- published_at: 2024-01-18 # YYYY-MM-DD
- release: 16.8 # XX.Y
+ image_url: https://img.youtube.com/vi/fHleeXzoB6k/hqdefault.jpg
+ published_at: 2024-01-18
+ release: 16.8
diff --git a/doc/administration/settings/sign_up_restrictions.md b/doc/administration/settings/sign_up_restrictions.md
index 3ebb80c34ab..23aa3ee68de 100644
--- a/doc/administration/settings/sign_up_restrictions.md
+++ b/doc/administration/settings/sign_up_restrictions.md
@@ -83,6 +83,8 @@ by an administrator. Users can use their account only after they have been appro
If an administrator increases or removes the user cap, users pending approval are automatically approved.
+[View how to set up a user cap for groups](../../user/group/manage.md#user-cap-for-groups).
+
NOTE:
For instances that use LDAP or OmniAuth, when [administrator approval for new sign-ups](#require-administrator-approval-for-new-sign-ups)
is enabled or disabled, downtime might occur due to changes in the Rails configuration.
diff --git a/doc/api/graphql/reference/index.md b/doc/api/graphql/reference/index.md
index e8f95c5e5a3..1fa12bd1ee0 100644
--- a/doc/api/graphql/reference/index.md
+++ b/doc/api/graphql/reference/index.md
@@ -2683,6 +2683,28 @@ Input type: `CreateDiffNoteInput`
| <a id="mutationcreatediffnoteerrors"></a>`errors` | [`[String!]!`](#string) | Errors encountered during execution of the mutation. |
| <a id="mutationcreatediffnotenote"></a>`note` | [`Note`](#note) | Note after mutation. |
+### `Mutation.createDiscussion`
+
+Input type: `CreateDiscussionInput`
+
+#### Arguments
+
+| Name | Type | Description |
+| ---- | ---- | ----------- |
+| <a id="mutationcreatediscussionbody"></a>`body` | [`String!`](#string) | Content of the note. |
+| <a id="mutationcreatediscussionclientmutationid"></a>`clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. |
+| <a id="mutationcreatediscussionconfidential"></a>`confidential` **{warning-solid}** | [`Boolean`](#boolean) | **Deprecated:** This was renamed. Please use `internal`. Deprecated in 15.3. |
+| <a id="mutationcreatediscussioninternal"></a>`internal` | [`Boolean`](#boolean) | Internal flag for a note. Default is false. |
+| <a id="mutationcreatediscussionnoteableid"></a>`noteableId` | [`NoteableID!`](#noteableid) | Global ID of the resource to add a note to. |
+
+#### Fields
+
+| Name | Type | Description |
+| ---- | ---- | ----------- |
+| <a id="mutationcreatediscussionclientmutationid"></a>`clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. |
+| <a id="mutationcreatediscussionerrors"></a>`errors` | [`[String!]!`](#string) | Errors encountered during execution of the mutation. |
+| <a id="mutationcreatediscussionnote"></a>`note` | [`Note`](#note) | Note after mutation. |
+
### `Mutation.createEpic`
Input type: `CreateEpicInput`
diff --git a/doc/user/clusters/agent/gitops.md b/doc/user/clusters/agent/gitops.md
index df63d8ce7be..7a3ab01e991 100644
--- a/doc/user/clusters/agent/gitops.md
+++ b/doc/user/clusters/agent/gitops.md
@@ -87,7 +87,7 @@ unnecessary pulls from GitLab.
The agent for Kubernetes automatically detects Flux `GitRepository` objects that
reference GitLab projects in the instance the agent is connected to,
and configures a [`Receiver`](https://fluxcd.io/flux/components/notification/receiver/) for the instance.
-When the agent for Kubernetes detects a `git push`, the `Receiver` is triggered
+When the agent for Kubernetes detects a `git push` to a repository it has access to, the `Receiver` is triggered
and Flux reconciles the cluster with any changes to the repository.
To use immediate Git repository reconciliation, you must have a Kubernetes cluster that runs:
@@ -100,6 +100,11 @@ but it doesn't guarantee that every `git push` event is received. You should sti
[`GitRepository.spec.interval`](https://fluxcd.io/flux/components/source/gitrepositories/#interval)
to an acceptable duration.
+DISCLAIMER:
+The agent only has access to the agent configuration project and all public projects.
+The agent is not able to immediately reconcile any private projects, except the agent configuration project.
+Allowing the agent to access private projects is proposed in [issue 389393](https://gitlab.com/gitlab-org/gitlab/-/issues/389393).
+
### Custom webhook endpoints
When the agent for Kubernetes calls the `Receiver` webhook,
diff --git a/doc/user/index.md b/doc/user/index.md
index 80f480d9e26..dc75d801330 100644
--- a/doc/user/index.md
+++ b/doc/user/index.md
@@ -9,10 +9,12 @@ info: To determine the technical writer assigned to the Stage/Group associated w
Get to know the GitLab end-to-end workflow. Configure permissions,
organize your work, create and secure your application, and analyze its performance. Report on team productivity throughout the process.
+- [Learn Git](../topics/git/index.md)
- [Set up your organization](../topics/set_up_organization.md)
- [Organize work with projects](../user/project/organize_work_with_projects.md)
- [Plan and track work](../topics/plan_and_track.md)
-- [Build your application](../topics/build_your_application.md)
+- [Manage your code](../topics/manage_code.md)
+- [Use CI/CD to build your application](../topics/build_your_application.md)
- [Secure your application](../user/application_security/secure_your_application.md)
- [Deploy and release your application](../topics/release_your_application.md)
- [Monitor application performance](../operations/index.md)
diff --git a/doc/user/project/repository/code_suggestions/repository_xray.md b/doc/user/project/repository/code_suggestions/repository_xray.md
index d851ee94e34..465bfc8d16a 100644
--- a/doc/user/project/repository/code_suggestions/repository_xray.md
+++ b/doc/user/project/repository/code_suggestions/repository_xray.md
@@ -4,9 +4,11 @@ group: Code Creation
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://handbook.gitlab.com/handbook/product/ux/technical-writing/#assignments
---
-# Repository X-Ray **(PREMIUM)**
+# Repository X-Ray **(PREMIUM ALL)**
-Repository X-Ray enhances GitLab Duo Code Suggestions by providing additional context to improve the accuracy and relevance of code recommendations.
+> [Introduced](https://gitlab.com/groups/gitlab-org/-/epics/12060) in GitLab 16.7.
+
+Repository X-Ray enhances [GitLab Duo Code Suggestions](index.md) by providing additional context to improve the accuracy and relevance of code recommendations.
Repository X-Ray gives the code assistant more insight into the project's codebase and dependencies to generate better code suggestions. It does this by analyzing key project configuration files such as `Gemfile.lock`, `package.json`, and `go.mod` to build additional context.
diff --git a/gems/click_house-client/lib/click_house/client/formatter.rb b/gems/click_house-client/lib/click_house/client/formatter.rb
index a19c55e3e3d..501afe7689c 100644
--- a/gems/click_house-client/lib/click_house/client/formatter.rb
+++ b/gems/click_house-client/lib/click_house/client/formatter.rb
@@ -5,13 +5,18 @@ module ClickHouse
class Formatter
DEFAULT = ->(value) { value }
- TYPE_CASTERS = {
+ BASIC_TYPE_CASTERS = {
'UInt64' => ->(value) { Integer(value) },
"DateTime64(6, 'UTC')" => ->(value) { ActiveSupport::TimeZone['UTC'].parse(value) },
"IntervalSecond" => ->(value) { ActiveSupport::Duration.build(value.to_i) },
"IntervalMillisecond" => ->(value) { ActiveSupport::Duration.build(value.to_i / 1000.0) }
}.freeze
+ TYPE_CASTERS = BASIC_TYPE_CASTERS.merge(
+ BASIC_TYPE_CASTERS.transform_keys { |type| "Nullable(#{type})" }
+ .transform_values { |caster| ->(value) { value.nil? ? nil : caster.call(value) } }
+ )
+
def self.format(result)
name_type_mapping = result['meta'].each_with_object({}) do |column, hash|
hash[column['name']] = column['type']
diff --git a/gems/click_house-client/spec/click_house/client/formatter_spec.rb b/gems/click_house-client/spec/click_house/client/formatter_spec.rb
index ca57187b098..2389eba5bfa 100644
--- a/gems/click_house-client/spec/click_house/client/formatter_spec.rb
+++ b/gems/click_house-client/spec/click_house/client/formatter_spec.rb
@@ -7,6 +7,8 @@ RSpec.describe ClickHouse::Client::Formatter do
# this query here is just for documentation purposes, it generates the response below
_query = <<~SQL.squish
SELECT toUInt64(1) as uint64,
+ toNullable(toUInt64(2)) as nullable_uint64,
+ CAST(NULL AS Nullable(UInt64)) as nullable_uint64_null,
toDateTime64('2016-06-15 23:00:00', 6, 'UTC') as datetime64_6,
INTERVAL 1 second as interval_second,
INTERVAL 1 millisecond as interval_millisecond
@@ -21,6 +23,14 @@ RSpec.describe ClickHouse::Client::Formatter do
"type": "UInt64"
},
{
+ "name": "nullable_uint64",
+ "type": "Nullable(UInt64)"
+ },
+ {
+ "name": "nullable_uint64_null",
+ "type": "Nullable(UInt64)"
+ },
+ {
"name": "datetime64_6",
"type": "DateTime64(6, 'UTC')"
},
@@ -29,8 +39,8 @@ RSpec.describe ClickHouse::Client::Formatter do
"type": "IntervalSecond"
},
{
- "name": "interval_millisecond",
- "type": "IntervalMillisecond"
+ "name": "interval_millisecond",
+ "type": "IntervalMillisecond"
}
],
@@ -38,6 +48,8 @@ RSpec.describe ClickHouse::Client::Formatter do
[
{
"uint64": "1",
+ "nullable_uint64": "2",
+ "nullable_uint64_null": null,
"datetime64_6": "2016-06-15 23:00:00.000000",
"interval_second": "1",
"interval_millisecond": "1"
@@ -48,7 +60,7 @@ RSpec.describe ClickHouse::Client::Formatter do
"statistics":
{
- "elapsed": 0.002101,
+ "elapsed": 0.00168,
"rows_read": 1,
"bytes_read": 1
}
@@ -61,6 +73,8 @@ RSpec.describe ClickHouse::Client::Formatter do
expect(formatted_response).to(
eq(
[{ "uint64" => 1,
+ "nullable_uint64" => 2,
+ "nullable_uint64_null" => nil,
"datetime64_6" => ActiveSupport::TimeZone["UTC"].parse("2016-06-15 23:00:00"),
"interval_second" => 1.second,
"interval_millisecond" => 0.001.seconds }]
diff --git a/lib/gitlab/bitbucket_server_import/importers/pull_request_importer.rb b/lib/gitlab/bitbucket_server_import/importers/pull_request_importer.rb
index 99f4adbe317..8fd602c851c 100644
--- a/lib/gitlab/bitbucket_server_import/importers/pull_request_importer.rb
+++ b/lib/gitlab/bitbucket_server_import/importers/pull_request_importer.rb
@@ -10,7 +10,7 @@ module Gitlab
@project = project
@formatter = Gitlab::ImportFormatter.new
@user_finder = UserFinder.new(project)
- @mentions_converter = Gitlab::BitbucketServerImport::MentionsConverter.new(project.id)
+ @mentions_converter = Gitlab::Import::MentionsConverter.new('bitbucket_server', project.id)
# Object should behave as a object so we can remove object.is_a?(Hash) check
# This will be fixed in https://gitlab.com/gitlab-org/gitlab/-/issues/412328
diff --git a/lib/gitlab/bitbucket_server_import/importers/pull_request_notes_importer.rb b/lib/gitlab/bitbucket_server_import/importers/pull_request_notes_importer.rb
index 19e5cdcbdc2..4b7c5568dd6 100644
--- a/lib/gitlab/bitbucket_server_import/importers/pull_request_notes_importer.rb
+++ b/lib/gitlab/bitbucket_server_import/importers/pull_request_notes_importer.rb
@@ -11,7 +11,7 @@ module Gitlab
@project = project
@user_finder = UserFinder.new(project)
@formatter = Gitlab::ImportFormatter.new
- @mentions_converter = Gitlab::BitbucketServerImport::MentionsConverter.new(project.id)
+ @mentions_converter = Gitlab::Import::MentionsConverter.new('bitbucket_server', project.id)
@object = hash.with_indifferent_access
end
diff --git a/lib/gitlab/bitbucket_server_import/importers/users_importer.rb b/lib/gitlab/bitbucket_server_import/importers/users_importer.rb
index 156d89c2732..8b0b059b397 100644
--- a/lib/gitlab/bitbucket_server_import/importers/users_importer.rb
+++ b/lib/gitlab/bitbucket_server_import/importers/users_importer.rb
@@ -5,7 +5,7 @@ module Gitlab
module Importers
class UsersImporter
include Loggable
- include UserFromMention
+ include Gitlab::Import::UserFromMention
BATCH_SIZE = 100
@@ -46,7 +46,7 @@ module Gitlab
def cache_users(users)
users_hash = users.each_with_object({}) do |user, hash|
- cache_key = source_user_cache_key(project_id, user.username)
+ cache_key = source_user_cache_key('bitbucket_server', project_id, user.username)
hash[cache_key] = user.email
end
diff --git a/lib/gitlab/checks/lfs_check.rb b/lib/gitlab/checks/lfs_check.rb
index 1d1d24c8fcc..f2c4b28470d 100644
--- a/lib/gitlab/checks/lfs_check.rb
+++ b/lib/gitlab/checks/lfs_check.rb
@@ -7,10 +7,6 @@ module Gitlab
ERROR_MESSAGE = 'LFS objects are missing. Ensure LFS is properly set up or try a manual "git lfs push --all".'
def validate!
- # This feature flag is used for disabling integrity check on some envs
- # because these costy calculations may cause performance issues
- return unless Feature.enabled?(:lfs_check, project)
-
return unless project.lfs_enabled?
logger.log_timed(LOG_MESSAGE) do
diff --git a/lib/gitlab/bitbucket_server_import/mentions_converter.rb b/lib/gitlab/import/mentions_converter.rb
index 8b1eeb6e007..180a9f069e3 100644
--- a/lib/gitlab/bitbucket_server_import/mentions_converter.rb
+++ b/lib/gitlab/import/mentions_converter.rb
@@ -1,16 +1,17 @@
# frozen_string_literal: true
module Gitlab
- module BitbucketServerImport
+ module Import
class MentionsConverter
include UserFromMention
MENTIONS_REGEX = User.reference_pattern
MENTION_PLACEHOLDER = '~GITLAB_MENTION_PLACEHOLDER~'
- attr_reader :project_id
+ attr_reader :importer, :project_id
- def initialize(project_id)
+ def initialize(importer, project_id)
+ @importer = importer
@project_id = project_id
end
diff --git a/lib/gitlab/bitbucket_server_import/user_from_mention.rb b/lib/gitlab/import/user_from_mention.rb
index 907db245760..9e3489f91b4 100644
--- a/lib/gitlab/bitbucket_server_import/user_from_mention.rb
+++ b/lib/gitlab/import/user_from_mention.rb
@@ -1,9 +1,9 @@
# frozen_string_literal: true
module Gitlab
- module BitbucketServerImport
+ module Import
module UserFromMention
- SOURCE_USER_CACHE_KEY = 'bitbucket_server/project/%s/source/username/%s'
+ SOURCE_USER_CACHE_KEY = '%s/project/%s/source/username/%s'
def user_from_cache(mention)
cached_email = read(mention)
@@ -17,14 +17,14 @@ module Gitlab
::Gitlab::Cache::Import::Caching.write_multiple(hash, timeout: timeout)
end
- def source_user_cache_key(project_id, username)
- format(SOURCE_USER_CACHE_KEY, project_id, username)
+ def source_user_cache_key(importer, project_id, username)
+ format(SOURCE_USER_CACHE_KEY, importer, project_id, username)
end
private
def read(mention)
- ::Gitlab::Cache::Import::Caching.read(source_user_cache_key(project_id, mention))
+ ::Gitlab::Cache::Import::Caching.read(source_user_cache_key(importer, project_id, mention))
end
def find_user(email)
diff --git a/lib/gitlab/observability.rb b/lib/gitlab/observability.rb
index d42d10cd0f4..9dd6632aeeb 100644
--- a/lib/gitlab/observability.rb
+++ b/lib/gitlab/observability.rb
@@ -25,8 +25,8 @@ module Gitlab
def should_enable_observability_auth_scopes?(resource)
# Enable the needed oauth scopes if tracing is enabled.
if resource.is_a?(Group) || resource.is_a?(Project)
- return Feature.enabled?(:observability_tracing,
- resource.root_ancestor)
+ return Feature.enabled?(:observability_tracing, resource.root_ancestor) ||
+ Feature.enabled?(:observability_metrics, resource.root_ancestor)
end
false
diff --git a/lib/google_cloud_platform/artifact_registry/client.rb b/lib/google_cloud_platform/artifact_registry/client.rb
new file mode 100644
index 00000000000..f371a3ce9c7
--- /dev/null
+++ b/lib/google_cloud_platform/artifact_registry/client.rb
@@ -0,0 +1,57 @@
+# frozen_string_literal: true
+
+module GoogleCloudPlatform
+ module ArtifactRegistry
+ class Client < GoogleCloudPlatform::BaseClient
+ PAGE_SIZE = 10
+
+ def initialize(project:, user:, gcp_project_id:, gcp_location:, gcp_repository:, gcp_wlif:)
+ super(project: project, user: user)
+ @gcp_project_id = gcp_project_id
+ @gcp_location = gcp_location
+ @gcp_repository = gcp_repository
+ @gcp_wlif = gcp_wlif
+ end
+
+ def list_docker_images(page_token: nil)
+ url = list_docker_images_url
+ response = ::Gitlab::HTTP.get(
+ url,
+ headers: headers,
+ query: query_params(page_token: page_token),
+ format: :plain, # disable httparty json parsing
+ extra_allowed_uris: [URI(GLGO_BASE_URL)]
+ )
+
+ if response.success?
+ ::Gitlab::Json.parse(response.body, symbolize_keys: true)
+ else
+ {}
+ end
+ end
+
+ private
+
+ def list_docker_images_url
+ "#{GLGO_BASE_URL}/gcp/ar/" \
+ "projects/#{@gcp_project_id}/" \
+ "locations/#{@gcp_location}/" \
+ "repositories/#{@gcp_repository}/docker"
+ end
+
+ def query_params(page_token: nil)
+ {
+ page_token: page_token,
+ page_size: PAGE_SIZE
+ }.compact
+ end
+
+ def headers
+ jwt = encoded_jwt(wlif: @gcp_wlif)
+ {
+ 'Authorization' => "Bearer #{jwt}"
+ }
+ end
+ end
+ end
+end
diff --git a/lib/google_cloud_platform/base_client.rb b/lib/google_cloud_platform/base_client.rb
new file mode 100644
index 00000000000..a1a13e1e0e9
--- /dev/null
+++ b/lib/google_cloud_platform/base_client.rb
@@ -0,0 +1,30 @@
+# frozen_string_literal: true
+
+module GoogleCloudPlatform
+ class BaseClient
+ GLGO_BASE_URL = if Gitlab.staging?
+ 'https://glgo.staging.runway.gitlab.net'
+ else
+ 'https://glgo.runway.gitlab.net'
+ end
+
+ def initialize(project:, user:)
+ @project = project
+ @user = user
+ end
+
+ private
+
+ def encoded_jwt(wlif:)
+ jwt = ::GoogleCloudPlatform::Jwt.new(
+ project: @project,
+ user: @user,
+ claims: {
+ audience: GLGO_BASE_URL,
+ wlif: wlif
+ }
+ )
+ jwt.encoded
+ end
+ end
+end
diff --git a/lib/google_cloud_platform/jwt.rb b/lib/google_cloud_platform/jwt.rb
new file mode 100644
index 00000000000..128dd5ae6f1
--- /dev/null
+++ b/lib/google_cloud_platform/jwt.rb
@@ -0,0 +1,86 @@
+# frozen_string_literal: true
+
+module GoogleCloudPlatform
+ class Jwt < ::JSONWebToken::RSAToken
+ extend ::Gitlab::Utils::Override
+
+ JWT_OPTIONS_ERROR = 'This jwt needs jwt claims audience and wlif to be set.'
+
+ NoSigningKeyError = Class.new(StandardError)
+
+ def initialize(project:, user:, claims:)
+ super
+
+ raise ArgumentError, JWT_OPTIONS_ERROR if claims[:audience].blank? || claims[:wlif].blank?
+
+ @claims = claims
+ @project = project
+ @user = user
+ end
+
+ def encoded
+ @custom_payload.merge!(custom_claims)
+
+ super
+ end
+
+ private
+
+ override :subject
+ def subject
+ "project_#{@project.id}_user_#{@user.id}"
+ end
+
+ override :key_data
+ def key_data
+ @key_data ||= begin
+ # TODO Feels strange to use the CI signing key but do
+ # we have a different signing key?
+ key_data = Gitlab::CurrentSettings.ci_jwt_signing_key
+
+ raise NoSigningKeyError unless key_data
+
+ key_data
+ end
+ end
+
+ def custom_claims
+ {
+ namespace_id: namespace.id.to_s,
+ namespace_path: namespace.full_path,
+ root_namespace_path: root_namespace.full_path,
+ root_namespace_id: root_namespace.id.to_s,
+ project_id: @project.id.to_s,
+ project_path: @project.full_path,
+ user_id: @user&.id.to_s,
+ user_login: @user&.username,
+ user_email: @user&.email,
+ wlif: @claims[:wlif]
+ }
+ end
+
+ def namespace
+ @project.namespace
+ end
+
+ def root_namespace
+ @project.root_namespace
+ end
+
+ override :issuer
+ def issuer
+ Feature.enabled?(:oidc_issuer_url) ? Gitlab.config.gitlab.url : Settings.gitlab.base_url
+ end
+
+ override :audience
+ def audience
+ @claims[:audience]
+ end
+
+ override :kid
+ def kid
+ rsa_key = OpenSSL::PKey::RSA.new(key_data)
+ rsa_key.public_key.to_jwk[:kid]
+ end
+ end
+end
diff --git a/lib/integrations/google_cloud_platform/artifact_registry/client.rb b/lib/integrations/google_cloud_platform/artifact_registry/client.rb
deleted file mode 100644
index 32e09821814..00000000000
--- a/lib/integrations/google_cloud_platform/artifact_registry/client.rb
+++ /dev/null
@@ -1,59 +0,0 @@
-# frozen_string_literal: true
-
-module Integrations
- module GoogleCloudPlatform
- module ArtifactRegistry
- class Client < Integrations::GoogleCloudPlatform::BaseClient
- PAGE_SIZE = 10
-
- def initialize(project:, user:, gcp_project_id:, gcp_location:, gcp_repository:, gcp_wlif:)
- super(project: project, user: user)
- @gcp_project_id = gcp_project_id
- @gcp_location = gcp_location
- @gcp_repository = gcp_repository
- @gcp_wlif = gcp_wlif
- end
-
- def list_docker_images(page_token: nil)
- url = list_docker_images_url
- response = ::Gitlab::HTTP.get(
- url,
- headers: headers,
- query: query_params(page_token: page_token),
- format: :plain, # disable httparty json parsing
- extra_allowed_uris: [URI(GLGO_BASE_URL)]
- )
-
- if response.success?
- ::Gitlab::Json.parse(response.body, symbolize_keys: true)
- else
- {}
- end
- end
-
- private
-
- def list_docker_images_url
- "#{GLGO_BASE_URL}/gcp/ar/" \
- "projects/#{@gcp_project_id}/" \
- "locations/#{@gcp_location}/" \
- "repositories/#{@gcp_repository}/docker"
- end
-
- def query_params(page_token: nil)
- {
- page_token: page_token,
- page_size: PAGE_SIZE
- }.compact
- end
-
- def headers
- jwt = encoded_jwt(wlif: @gcp_wlif)
- {
- 'Authorization' => "Bearer #{jwt}"
- }
- end
- end
- end
- end
-end
diff --git a/lib/integrations/google_cloud_platform/base_client.rb b/lib/integrations/google_cloud_platform/base_client.rb
deleted file mode 100644
index 937454cda43..00000000000
--- a/lib/integrations/google_cloud_platform/base_client.rb
+++ /dev/null
@@ -1,32 +0,0 @@
-# frozen_string_literal: true
-
-module Integrations
- module GoogleCloudPlatform
- class BaseClient
- GLGO_BASE_URL = if Gitlab.staging?
- 'https://glgo.staging.runway.gitlab.net'
- else
- 'https://glgo.runway.gitlab.net'
- end
-
- def initialize(project:, user:)
- @project = project
- @user = user
- end
-
- private
-
- def encoded_jwt(wlif:)
- jwt = ::Integrations::GoogleCloudPlatform::Jwt.new(
- project: @project,
- user: @user,
- claims: {
- audience: GLGO_BASE_URL,
- wlif: wlif
- }
- )
- jwt.encoded
- end
- end
- end
-end
diff --git a/lib/integrations/google_cloud_platform/jwt.rb b/lib/integrations/google_cloud_platform/jwt.rb
deleted file mode 100644
index 26343a3a9db..00000000000
--- a/lib/integrations/google_cloud_platform/jwt.rb
+++ /dev/null
@@ -1,88 +0,0 @@
-# frozen_string_literal: true
-
-module Integrations
- module GoogleCloudPlatform
- class Jwt < ::JSONWebToken::RSAToken
- extend ::Gitlab::Utils::Override
-
- JWT_OPTIONS_ERROR = 'This jwt needs jwt claims audience and wlif to be set.'
-
- NoSigningKeyError = Class.new(StandardError)
-
- def initialize(project:, user:, claims:)
- super
-
- raise ArgumentError, JWT_OPTIONS_ERROR if claims[:audience].blank? || claims[:wlif].blank?
-
- @claims = claims
- @project = project
- @user = user
- end
-
- def encoded
- @custom_payload.merge!(custom_claims)
-
- super
- end
-
- private
-
- override :subject
- def subject
- "project_#{@project.id}_user_#{@user.id}"
- end
-
- override :key_data
- def key_data
- @key_data ||= begin
- # TODO Feels strange to use the CI signing key but do
- # we have a different signing key?
- key_data = Gitlab::CurrentSettings.ci_jwt_signing_key
-
- raise NoSigningKeyError unless key_data
-
- key_data
- end
- end
-
- def custom_claims
- {
- namespace_id: namespace.id.to_s,
- namespace_path: namespace.full_path,
- root_namespace_path: root_namespace.full_path,
- root_namespace_id: root_namespace.id.to_s,
- project_id: @project.id.to_s,
- project_path: @project.full_path,
- user_id: @user&.id.to_s,
- user_login: @user&.username,
- user_email: @user&.email,
- wlif: @claims[:wlif]
- }
- end
-
- def namespace
- @project.namespace
- end
-
- def root_namespace
- @project.root_namespace
- end
-
- override :issuer
- def issuer
- Feature.enabled?(:oidc_issuer_url) ? Gitlab.config.gitlab.url : Settings.gitlab.base_url
- end
-
- override :audience
- def audience
- @claims[:audience]
- end
-
- override :kid
- def kid
- rsa_key = OpenSSL::PKey::RSA.new(key_data)
- rsa_key.public_key.to_jwk[:kid]
- end
- end
- end
-end
diff --git a/locale/gitlab.pot b/locale/gitlab.pot
index 608b930f5c9..3090451b2ec 100644
--- a/locale/gitlab.pot
+++ b/locale/gitlab.pot
@@ -19579,6 +19579,9 @@ msgstr ""
msgid "Error fetching the dependency list. Please check your network connection and try again."
msgstr ""
+msgid "Error fetching the dependency list: %{errorDetails}"
+msgstr ""
+
msgid "Error loading branch data. Please try again."
msgstr ""
@@ -33913,9 +33916,6 @@ msgstr ""
msgid "Only SSH"
msgstr ""
-msgid "Only SSH Certificates"
-msgstr ""
-
msgid "Only accessible by %{membersPageLinkStart}project members%{membersPageLinkEnd}. Membership must be explicitly granted to each user."
msgstr ""
@@ -56952,6 +56952,9 @@ msgstr ""
msgid "Your GitHub access token does not have the correct scope to import collaborators."
msgstr ""
+msgid "Your GitHub access token does not have the correct scope to import."
+msgstr ""
+
msgid "Your GitLab account has been locked due to an excessive number of unsuccessful sign in attempts. You can wait for your account to automatically unlock in %{duration} or you can click the link below to unlock now."
msgstr ""
diff --git a/qa/qa/fixtures/files/one_b b/qa/qa/fixtures/files/one_b
deleted file mode 100644
index ddd224c7520..00000000000
--- a/qa/qa/fixtures/files/one_b
+++ /dev/null
Binary files differ
diff --git a/qa/qa/page/main/login.rb b/qa/qa/page/main/login.rb
index c7ad909e6de..27c5f59f381 100644
--- a/qa/qa/page/main/login.rb
+++ b/qa/qa/page/main/login.rb
@@ -44,7 +44,6 @@ module QA
element 'github-login-button'
element 'oidc-login-button'
element 'gitlab-oauth-login-button'
- element 'facebook-login-button'
end
view 'app/views/layouts/devise.html.haml' do
@@ -184,11 +183,6 @@ module QA
click_element 'github-login-button'
end
- def sign_in_with_facebook
- set_initial_password_if_present
- click_element 'facebook-login-button'
- end
-
def sign_in_with_saml
set_initial_password_if_present
click_element 'saml-login-button'
diff --git a/qa/qa/runtime/env.rb b/qa/qa/runtime/env.rb
index c62df7a8cde..cbd1c91a758 100644
--- a/qa/qa/runtime/env.rb
+++ b/qa/qa/runtime/env.rb
@@ -286,14 +286,6 @@ module QA
ENV['QA_GITHUB_PASSWORD']
end
- def facebook_username
- ENV['QA_FACEBOOK_USERNAME']
- end
-
- def facebook_password
- ENV['QA_FACEBOOK_PASSWORD']
- end
-
def forker?
!!(forker_username && forker_password)
end
diff --git a/qa/qa/specs/features/browser_ui/10_govern/login/oauth_login_with_facebook_spec.rb b/qa/qa/specs/features/browser_ui/10_govern/login/oauth_login_with_facebook_spec.rb
deleted file mode 100644
index 717c5d6d935..00000000000
--- a/qa/qa/specs/features/browser_ui/10_govern/login/oauth_login_with_facebook_spec.rb
+++ /dev/null
@@ -1,22 +0,0 @@
-# frozen_string_literal: true
-
-module QA
- RSpec.describe 'Govern', :orchestrated, :oauth, product_group: :authentication do
- describe 'OAuth' do
- it 'logs in with Facebook credentials',
- testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/417115',
- quarantine: {
- type: :waiting_on,
- issue: 'https://gitlab.com/gitlab-org/gitlab/-/issues/431392'
- } do
- Runtime::Browser.visit(:gitlab, Page::Main::Login)
-
- Page::Main::Login.perform(&:sign_in_with_facebook)
-
- Vendor::Facebook::Page::Login.perform(&:login)
-
- expect(page).to have_content('Welcome to GitLab')
- end
- end
- end
-end
diff --git a/qa/qa/vendor/facebook/page/login.rb b/qa/qa/vendor/facebook/page/login.rb
deleted file mode 100644
index 99e79d2e5a4..00000000000
--- a/qa/qa/vendor/facebook/page/login.rb
+++ /dev/null
@@ -1,23 +0,0 @@
-# frozen_string_literal: true
-
-module QA
- module Vendor
- module Facebook
- module Page
- class Login < Vendor::Page::Base
- def login
- fill_in 'email', with: QA::Runtime::Env.facebook_username
- fill_in 'pass', with: QA::Runtime::Env.facebook_password
- find('#loginbutton').click
-
- confirm_oauth_access
- end
-
- def confirm_oauth_access
- first('span', text: 'Continue as').click if has_css?('span', text: 'Continue as')
- end
- end
- end
- end
- end
-end
diff --git a/spec/frontend/authentication/password/components/password_input_spec.js b/spec/frontend/authentication/password/components/password_input_spec.js
index 62438e824cf..d31bfea224a 100644
--- a/spec/frontend/authentication/password/components/password_input_spec.js
+++ b/spec/frontend/authentication/password/components/password_input_spec.js
@@ -32,7 +32,6 @@ describe('PasswordInput', () => {
expect(findPasswordInput().attributes('autocomplete')).toBe(propsData.autocomplete);
expect(findPasswordInput().attributes('name')).toBe(propsData.name);
expect(findPasswordInput().attributes('minlength')).toBe(propsData.minimumPasswordLength);
- expect(findPasswordInput().attributes('data-qa-selector')).toBe(propsData.qaSelector);
expect(findPasswordInput().attributes('data-testid')).toBe(propsData.testid);
expect(findPasswordInput().attributes('title')).toBe(propsData.title);
});
diff --git a/spec/frontend/members/components/table/members_table_spec.js b/spec/frontend/members/components/table/members_table_spec.js
index c2400fbc142..9fcf1853ef5 100644
--- a/spec/frontend/members/components/table/members_table_spec.js
+++ b/spec/frontend/members/components/table/members_table_spec.js
@@ -45,8 +45,7 @@ describe('MembersTable', () => {
members: [],
tableFields: [],
tableAttrs: {
- table: { 'data-qa-selector': 'members_list' },
- tr: { 'data-qa-selector': 'member_row' },
+ tr: { 'data-testid': 'member-row' },
},
pagination,
...state,
@@ -274,16 +273,10 @@ describe('MembersTable', () => {
});
});
- it('adds QA selector to table', () => {
+ it('adds QA testid to table row', () => {
createComponent();
- expect(findTable().attributes('data-qa-selector')).toBe('members_list');
- });
-
- it('adds QA selector to table row', () => {
- createComponent();
-
- expect(findTable().find('tbody tr').attributes('data-qa-selector')).toBe('member_row');
+ expect(findTable().find('tbody tr').attributes('data-testid')).toBe('member-row');
});
describe('when required pagination data is provided', () => {
diff --git a/spec/frontend/members/index_spec.js b/spec/frontend/members/index_spec.js
index b1730cf3746..a48ed944292 100644
--- a/spec/frontend/members/index_spec.js
+++ b/spec/frontend/members/index_spec.js
@@ -13,7 +13,7 @@ describe('initMembersApp', () => {
vm = initMembersApp(el, {
[MEMBER_TYPES.user]: {
tableFields: ['account'],
- tableAttrs: { table: { 'data-qa-selector': 'members_list' } },
+ tableAttrs: { table: { 'data-testid': 'members-list' } },
tableSortableFields: ['account'],
requestFormatter: () => ({}),
filteredSearchBar: { show: false },
@@ -61,7 +61,7 @@ describe('initMembersApp', () => {
setup();
expect(vm.$store.state[MEMBER_TYPES.user].tableAttrs).toEqual({
- table: { 'data-qa-selector': 'members_list' },
+ table: { 'data-testid': 'members-list' },
});
});
diff --git a/spec/frontend/work_items/components/work_item_assignees_spec.js b/spec/frontend/work_items/components/work_item_assignees_spec.js
index 6c0042bdad7..b34eed21c60 100644
--- a/spec/frontend/work_items/components/work_item_assignees_spec.js
+++ b/spec/frontend/work_items/components/work_item_assignees_spec.js
@@ -14,9 +14,9 @@ import updateWorkItemMutation from '~/work_items/graphql/update_work_item.mutati
import WorkItemAssignees from '~/work_items/components/work_item_assignees.vue';
import {
i18n,
- TASK_TYPE_NAME,
- TRACKING_CATEGORY_SHOW,
DEFAULT_PAGE_SIZE_ASSIGNEES,
+ TRACKING_CATEGORY_SHOW,
+ WORK_ITEM_TYPE_VALUE_TASK,
} from '~/work_items/constants';
import {
projectMembersResponseWithCurrentUser,
@@ -97,7 +97,7 @@ describe('WorkItemAssignees component', () => {
fullPath: 'test-project-path',
workItemId,
allowsMultipleAssignees,
- workItemType: TASK_TYPE_NAME,
+ workItemType: WORK_ITEM_TYPE_VALUE_TASK,
canUpdate,
canInviteMembers,
},
diff --git a/spec/frontend/work_items/components/work_item_links/work_item_link_child_spec.js b/spec/frontend/work_items/components/work_item_links/work_item_link_child_spec.js
index 36af0c5b3c8..3c65a29e438 100644
--- a/spec/frontend/work_items/components/work_item_links/work_item_link_child_spec.js
+++ b/spec/frontend/work_items/components/work_item_links/work_item_link_child_spec.js
@@ -13,8 +13,8 @@ import WorkItemTreeChildren from '~/work_items/components/work_item_links/work_i
import WorkItemLinkChildContents from '~/work_items/components/shared/work_item_link_child_contents.vue';
import {
WIDGET_TYPE_HIERARCHY,
- TASK_TYPE_NAME,
WORK_ITEM_TYPE_VALUE_OBJECTIVE,
+ WORK_ITEM_TYPE_VALUE_TASK,
} from '~/work_items/constants';
import {
@@ -47,7 +47,7 @@ describe('WorkItemLinkChild', () => {
canUpdate = true,
issuableGid = WORK_ITEM_ID,
childItem = workItemTask,
- workItemType = TASK_TYPE_NAME,
+ workItemType = WORK_ITEM_TYPE_VALUE_TASK,
apolloProvider = null,
} = {}) => {
getWorkItemTreeQueryHandler = jest.fn().mockResolvedValue(workItemHierarchyTreeResponse);
diff --git a/spec/helpers/groups_helper_spec.rb b/spec/helpers/groups_helper_spec.rb
index 807898884a1..6c4595ce4bb 100644
--- a/spec/helpers/groups_helper_spec.rb
+++ b/spec/helpers/groups_helper_spec.rb
@@ -533,24 +533,22 @@ RSpec.describe GroupsHelper, feature_category: :groups_and_projects do
end
describe "#enabled_git_access_protocol_options_for_group" do
- let_it_be(:group) { create(:group) }
-
- subject { helper.enabled_git_access_protocol_options_for_group(group) }
+ subject { helper.enabled_git_access_protocol_options_for_group }
before do
- allow(::Gitlab::CurrentSettings).to receive(:enabled_git_access_protocol).and_return(instance_setting)
+ expect(::Gitlab::CurrentSettings).to receive(:enabled_git_access_protocol).and_return(instance_setting)
end
context "instance setting is nil" do
let(:instance_setting) { nil }
- it { is_expected.to include([_("Both SSH and HTTP(S)"), "all"], [_("Only SSH"), "ssh"], [_("Only HTTP(S)"), "http"]) }
+ it { is_expected.to contain_exactly([_("Both SSH and HTTP(S)"), "all"], [_("Only SSH"), "ssh"], [_("Only HTTP(S)"), "http"]) }
end
context "instance setting is blank" do
- let(:instance_setting) { '' }
+ let(:instance_setting) { nil }
- it { is_expected.to include([_("Both SSH and HTTP(S)"), "all"], [_("Only SSH"), "ssh"], [_("Only HTTP(S)"), "http"]) }
+ it { is_expected.to contain_exactly([_("Both SSH and HTTP(S)"), "all"], [_("Only SSH"), "ssh"], [_("Only HTTP(S)"), "http"]) }
end
context "instance setting is ssh" do
diff --git a/spec/helpers/work_items_helper_spec.rb b/spec/helpers/work_items_helper_spec.rb
index b790f21d412..59b8b13aea2 100644
--- a/spec/helpers/work_items_helper_spec.rb
+++ b/spec/helpers/work_items_helper_spec.rb
@@ -3,13 +3,13 @@
require "spec_helper"
RSpec.describe WorkItemsHelper, feature_category: :team_planning do
- describe '#work_items_index_data' do
- subject(:work_items_index_data) { helper.work_items_index_data(project) }
+ describe '#work_items_show_data' do
+ subject(:work_items_show_data) { helper.work_items_show_data(project) }
let_it_be(:project) { build(:project) }
it 'returns the expected data properties' do
- expect(work_items_index_data).to include(
+ expect(work_items_show_data).to include(
{
full_path: project.full_path,
issues_list_path: project_issues_path(project),
diff --git a/spec/lib/gitlab/auth_spec.rb b/spec/lib/gitlab/auth_spec.rb
index fd51ebbc8fa..3c87ac258b3 100644
--- a/spec/lib/gitlab/auth_spec.rb
+++ b/spec/lib/gitlab/auth_spec.rb
@@ -75,10 +75,12 @@ RSpec.describe Gitlab::Auth, :use_clean_rails_memory_store_caching, feature_cate
expect(subject.optional_scopes).to match_array %i[read_user read_api read_repository write_repository read_registry read_service_ping write_registry sudo admin_mode openid profile email read_observability write_observability create_runner k8s_proxy ai_features]
end
- context 'with observability_tracing feature flag' do
- context 'when disabled' do
+ context 'with observability feature flags' do
+ feature_flags = [:observability_tracing, :observability_metrics]
+
+ context 'when all disabled' do
before do
- stub_feature_flags(observability_tracing: false)
+ stub_feature_flags(feature_flags.index_with { false })
end
it 'contains for group all resource bot scopes without observability scopes' do
@@ -99,49 +101,55 @@ RSpec.describe Gitlab::Auth, :use_clean_rails_memory_store_caching, feature_cate
end
end
- context 'when enabled for specific root group' do
- let(:parent) { build_stubbed(:group) }
- let(:group) do
- build_stubbed(:group, parent: parent).tap { |g| g.namespace_settings = build_stubbed(:namespace_settings, namespace: g) }
- end
+ flag_states = [true, false].repeated_permutation(feature_flags.length)
+ flag_tests = flag_states.filter(&:any?).map { |flags| Hash[feature_flags.zip(flags)] }
- let(:project) { build_stubbed(:project, namespace: group) }
+ flag_tests.each do |flags|
+ context "with flags #{flags} enabled for specific root group" do
+ let(:parent) { build_stubbed(:group) }
+ let(:group) do
+ build_stubbed(:group, parent: parent).tap { |g| g.namespace_settings = build_stubbed(:namespace_settings, namespace: g) }
+ end
- before do
- stub_feature_flags(observability_tracing: parent)
- end
+ let(:project) { build_stubbed(:project, namespace: group) }
- it 'contains for group all resource bot scopes including observability scopes' do
- expect(subject.available_scopes_for(group)).to match_array %i[api read_api read_repository write_repository read_registry write_registry read_observability write_observability create_runner k8s_proxy ai_features]
- end
+ before do
+ flags.transform_values! { |v| v ? parent : false }
+ stub_feature_flags(flags)
+ end
- it 'contains for admin user all non-default scopes with ADMIN access and without observability scopes' do
- user = build_stubbed(:user, admin: true)
+ it 'contains for group all resource bot scopes including observability scopes' do
+ expect(subject.available_scopes_for(group)).to match_array %i[api read_api read_repository write_repository read_registry write_registry read_observability write_observability create_runner k8s_proxy ai_features]
+ end
- expect(subject.available_scopes_for(user)).to match_array %i[api read_user read_api read_repository write_repository read_registry write_registry read_service_ping sudo admin_mode create_runner k8s_proxy ai_features]
- end
+ it 'contains for admin user all non-default scopes with ADMIN access and without observability scopes' do
+ user = build_stubbed(:user, admin: true)
- it 'contains for project all resource bot scopes including observability scopes' do
- expect(subject.available_scopes_for(project)).to match_array %i[api read_api read_repository write_repository read_registry write_registry read_observability write_observability create_runner k8s_proxy ai_features]
- end
+ expect(subject.available_scopes_for(user)).to match_array %i[api read_user read_api read_repository write_repository read_registry write_registry read_service_ping sudo admin_mode create_runner k8s_proxy ai_features]
+ end
- it 'contains for other group all resource bot scopes without observability scopes' do
- other_parent = build_stubbed(:group)
- other_group = build_stubbed(:group, parent: other_parent).tap do |g|
- g.namespace_settings = build_stubbed(:namespace_settings, namespace: g)
+ it 'contains for project all resource bot scopes including observability scopes' do
+ expect(subject.available_scopes_for(project)).to match_array %i[api read_api read_repository write_repository read_registry write_registry read_observability write_observability create_runner k8s_proxy ai_features]
end
- expect(subject.available_scopes_for(other_group)).to match_array %i[api read_api read_repository write_repository read_registry write_registry create_runner k8s_proxy ai_features]
- end
+ it 'contains for other group all resource bot scopes without observability scopes' do
+ other_parent = build_stubbed(:group)
+ other_group = build_stubbed(:group, parent: other_parent).tap do |g|
+ g.namespace_settings = build_stubbed(:namespace_settings, namespace: g)
+ end
- it 'contains for other project all resource bot scopes without observability scopes' do
- other_parent = build_stubbed(:group)
- other_group = build_stubbed(:group, parent: other_parent).tap do |g|
- g.namespace_settings = build_stubbed(:namespace_settings, namespace: g)
+ expect(subject.available_scopes_for(other_group)).to match_array %i[api read_api read_repository write_repository read_registry write_registry create_runner k8s_proxy ai_features]
end
- other_project = build_stubbed(:project, namespace: other_group)
- expect(subject.available_scopes_for(other_project)).to match_array %i[api read_api read_repository write_repository read_registry write_registry create_runner k8s_proxy ai_features]
+ it 'contains for other project all resource bot scopes without observability scopes' do
+ other_parent = build_stubbed(:group)
+ other_group = build_stubbed(:group, parent: other_parent).tap do |g|
+ g.namespace_settings = build_stubbed(:namespace_settings, namespace: g)
+ end
+ other_project = build_stubbed(:project, namespace: other_group)
+
+ expect(subject.available_scopes_for(other_project)).to match_array %i[api read_api read_repository write_repository read_registry write_registry create_runner k8s_proxy ai_features]
+ end
end
end
end
diff --git a/spec/lib/gitlab/bitbucket_server_import/importers/pull_request_importer_spec.rb b/spec/lib/gitlab/bitbucket_server_import/importers/pull_request_importer_spec.rb
index eeb2f9c8000..bff25fb723f 100644
--- a/spec/lib/gitlab/bitbucket_server_import/importers/pull_request_importer_spec.rb
+++ b/spec/lib/gitlab/bitbucket_server_import/importers/pull_request_importer_spec.rb
@@ -18,7 +18,8 @@ RSpec.describe Gitlab::BitbucketServerImport::Importers::PullRequestImporter, fe
it 'imports the merge request correctly' do
expect_next(Gitlab::Import::MergeRequestCreator, project).to receive(:execute).and_call_original
expect_next(Gitlab::BitbucketServerImport::UserFinder, project).to receive(:author_id).and_call_original
- expect_next(Gitlab::BitbucketServerImport::MentionsConverter, project.id).to receive(:convert).and_call_original
+ expect_next(Gitlab::Import::MentionsConverter, 'bitbucket_server',
+ project.id).to receive(:convert).and_call_original
expect { importer.execute }.to change { MergeRequest.count }.by(1)
@@ -42,7 +43,7 @@ RSpec.describe Gitlab::BitbucketServerImport::Importers::PullRequestImporter, fe
end
it 'does not convert mentions' do
- expect_next(Gitlab::BitbucketServerImport::MentionsConverter, project.id).not_to receive(:convert)
+ expect_next(Gitlab::Import::MentionsConverter, 'bitbucket_server', project.id).not_to receive(:convert)
importer.execute
end
diff --git a/spec/lib/gitlab/bitbucket_server_import/importers/pull_request_notes_importer_spec.rb b/spec/lib/gitlab/bitbucket_server_import/importers/pull_request_notes_importer_spec.rb
index 7b662c1a2c7..31035d8844e 100644
--- a/spec/lib/gitlab/bitbucket_server_import/importers/pull_request_notes_importer_spec.rb
+++ b/spec/lib/gitlab/bitbucket_server_import/importers/pull_request_notes_importer_spec.rb
@@ -17,7 +17,7 @@ RSpec.describe Gitlab::BitbucketServerImport::Importers::PullRequestNotesImporte
let_it_be(:pull_request_data) { Gitlab::Json.parse(fixture_file('importers/bitbucket_server/pull_request.json')) }
let_it_be(:pull_request) { BitbucketServer::Representation::PullRequest.new(pull_request_data) }
let_it_be(:note_author) { create(:user, username: 'note_author', email: 'note_author@example.org') }
- let(:mentions_converter) { Gitlab::BitbucketServerImport::MentionsConverter.new(project) }
+ let(:mentions_converter) { Gitlab::Import::MentionsConverter.new('bitbucket_server', project) }
let!(:pull_request_author) do
create(:user, username: 'pull_request_author', email: 'pull_request_author@example.org')
@@ -81,7 +81,7 @@ RSpec.describe Gitlab::BitbucketServerImport::Importers::PullRequestNotesImporte
end
before do
- allow(Gitlab::BitbucketServerImport::MentionsConverter).to receive(:new).and_return(mentions_converter)
+ allow(Gitlab::Import::MentionsConverter).to receive(:new).and_return(mentions_converter)
end
subject(:importer) { described_class.new(project.reload, pull_request.to_hash) }
diff --git a/spec/lib/gitlab/checks/lfs_check_spec.rb b/spec/lib/gitlab/checks/lfs_check_spec.rb
index f00915bc1ec..ef27b30475f 100644
--- a/spec/lib/gitlab/checks/lfs_check_spec.rb
+++ b/spec/lib/gitlab/checks/lfs_check_spec.rb
@@ -31,18 +31,6 @@ RSpec.describe Gitlab::Checks::LfsCheck, feature_category: :source_code_manageme
allow(project).to receive(:lfs_enabled?).and_return(true)
end
- context 'with lfs_check feature disabled' do
- before do
- stub_feature_flags(lfs_check: false)
- end
-
- it 'skips integrity check' do
- expect_any_instance_of(Gitlab::Git::LfsChanges).not_to receive(:new_pointers)
-
- subject.validate!
- end
- end
-
context 'with deletion' do
shared_examples 'a skipped integrity check' do
it 'skips integrity check' do
diff --git a/spec/lib/gitlab/bitbucket_server_import/mentions_converter_spec.rb b/spec/lib/gitlab/import/mentions_converter_spec.rb
index 46800c924c9..122d7f227cc 100644
--- a/spec/lib/gitlab/bitbucket_server_import/mentions_converter_spec.rb
+++ b/spec/lib/gitlab/import/mentions_converter_spec.rb
@@ -2,12 +2,13 @@
require 'spec_helper'
-RSpec.describe Gitlab::BitbucketServerImport::MentionsConverter, :clean_gitlab_redis_cache, feature_category: :importers do
+RSpec.describe Gitlab::Import::MentionsConverter, :clean_gitlab_redis_cache, feature_category: :importers do
let(:project_id) { 12 }
+ let(:importer) { 'bitbucket_server' }
let(:text) { 'text without @ mentions' }
let(:source_user_cache_prefix) { "bitbucket_server/project/#{project_id}/source/username" }
- subject(:converted_text) { described_class.new(project_id).convert(text) }
+ subject(:converted_text) { described_class.new(importer, project_id).convert(text) }
describe '#convert' do
context 'when the text has no mentions' do
diff --git a/spec/lib/gitlab/bitbucket_server_import/user_from_mention_spec.rb b/spec/lib/gitlab/import/user_from_mention_spec.rb
index 73f9cde8322..0dcd7f92ee6 100644
--- a/spec/lib/gitlab/bitbucket_server_import/user_from_mention_spec.rb
+++ b/spec/lib/gitlab/import/user_from_mention_spec.rb
@@ -2,22 +2,24 @@
require 'spec_helper'
-RSpec.describe Gitlab::BitbucketServerImport::UserFromMention, :clean_gitlab_redis_cache, feature_category: :importers do
+RSpec.describe Gitlab::Import::UserFromMention, :clean_gitlab_redis_cache, feature_category: :importers do
let(:project_id) { 11 }
let(:username) { '@johndoe' }
let(:email) { 'john@gmail.com' }
let(:hash) { { key: 'value' } }
- let(:cache_key) { "bitbucket_server/project/#{project_id}/source/username/#{username}" }
+ let(:importer) { 'bitbucket_server' }
+ let(:cache_key) { "#{importer}/project/#{project_id}/source/username/#{username}" }
let(:example) do
Class.new do
- include Gitlab::BitbucketServerImport::UserFromMention
+ include Gitlab::Import::UserFromMention
- def initialize(project_id)
+ def initialize(importer, project_id)
+ @importer = importer
@project_id = project_id
end
- attr_reader :project_id
+ attr_reader :project_id, :importer
def foo(mention)
user_from_cache(mention)
@@ -29,7 +31,7 @@ RSpec.describe Gitlab::BitbucketServerImport::UserFromMention, :clean_gitlab_red
end
end
- subject(:example_class) { example.new(project_id) }
+ subject(:example_class) { example.new(importer, project_id) }
describe '#user_from_cache' do
it 'returns nil if the cache is empty' do
diff --git a/spec/lib/gitlab/observability_spec.rb b/spec/lib/gitlab/observability_spec.rb
index 7af2daea11c..221923ac12a 100644
--- a/spec/lib/gitlab/observability_spec.rb
+++ b/spec/lib/gitlab/observability_spec.rb
@@ -56,44 +56,35 @@ RSpec.describe Gitlab::Observability, feature_category: :error_tracking do
end
end
- before do
- stub_feature_flags(observability_tracing: parent)
- end
-
- describe 'when resource is group' do
- context 'if observability_tracing FF enabled' do
- it { is_expected.to be true }
- end
+ feature_flags = [:observability_tracing, :observability_metrics]
+ flag_states = [true, false].repeated_permutation(feature_flags.length)
+ flag_tests = flag_states.map { |flags| Hash[feature_flags.zip(flags)] }
- context 'if observability_tracing FF disabled' do
+ flag_tests.each do |flags|
+ context "with feature flag state #{flags}" do
before do
- stub_feature_flags(observability_tracing: false)
+ flags.transform_values! { |v| v ? parent : false }
+ stub_feature_flags(flags)
end
- it { is_expected.to be false }
- end
- end
+ let(:expected_enabled) { flags.values.any? }
- describe 'when resource is project' do
- let(:resource) { build_stubbed(:project, namespace: parent) }
+ describe 'when resource is group' do
+ it { is_expected.to be expected_enabled }
+ end
- context 'if observability_tracing FF enabled' do
- it { is_expected.to be true }
- end
+ describe 'when resource is project' do
+ let(:resource) { build_stubbed(:project, namespace: parent) }
- context 'if observability_tracing FF disabled' do
- before do
- stub_feature_flags(observability_tracing: false)
+ it { is_expected.to be expected_enabled }
end
- it { is_expected.to be false }
- end
- end
+ describe 'when resource is not a group or project' do
+ let(:resource) { build_stubbed(:user) }
- describe 'when resource is not a group or project' do
- let(:resource) { build_stubbed(:user) }
-
- it { is_expected.to be false }
+ it { is_expected.to be false }
+ end
+ end
end
end
end
diff --git a/spec/lib/gitlab/protocol_access_spec.rb b/spec/lib/gitlab/protocol_access_spec.rb
index cae14c3d7cf..e7e81b4b3e1 100644
--- a/spec/lib/gitlab/protocol_access_spec.rb
+++ b/spec/lib/gitlab/protocol_access_spec.rb
@@ -10,34 +10,25 @@ RSpec.describe Gitlab::ProtocolAccess, feature_category: :source_code_management
describe ".allowed?" do
where(:protocol, :project, :admin_setting, :namespace_setting, :expected_result) do
- "web" | nil | nil | nil | true
- "ssh" | nil | nil | nil | true
- "http" | nil | nil | nil | true
- "ssh_certificates" | nil | nil | nil | true
- "ssh" | nil | "" | nil | true
- "http" | nil | "" | nil | true
- "ssh_certificates" | nil | "" | nil | true
- "ssh" | nil | "ssh" | nil | true
- "http" | nil | "http" | nil | true
- "ssh_certificates" | nil | "ssh_certificates" | nil | true
- "ssh" | nil | "http" | nil | false
- "http" | nil | "ssh" | nil | false
- "ssh_certificates" | nil | "ssh" | nil | false
- "ssh" | ref(:p1) | nil | "all" | true
- "http" | ref(:p1) | nil | "all" | true
- "ssh_certificates" | ref(:p1) | nil | "all" | true
- "ssh" | ref(:p1) | nil | "ssh" | true
- "http" | ref(:p1) | nil | "http" | true
- "ssh_certificates" | ref(:p1) | nil | "ssh_certificates" | true
- "ssh" | ref(:p1) | nil | "http" | false
- "http" | ref(:p1) | nil | "ssh" | false
- "ssh_certificates" | ref(:p1) | nil | "ssh" | false
- "ssh" | ref(:p1) | "" | "all" | true
- "http" | ref(:p1) | "" | "all" | true
- "ssh_certificates" | ref(:p1) | "" | "all" | true
- "ssh" | ref(:p1) | "ssh" | "ssh" | true
- "http" | ref(:p1) | "http" | "http" | true
- "ssh_certificates" | ref(:p1) | "ssh_certificates" | "ssh_certificates" | true
+ "web" | nil | nil | nil | true
+ "ssh" | nil | nil | nil | true
+ "http" | nil | nil | nil | true
+ "ssh" | nil | "" | nil | true
+ "http" | nil | "" | nil | true
+ "ssh" | nil | "ssh" | nil | true
+ "http" | nil | "http" | nil | true
+ "ssh" | nil | "http" | nil | false
+ "http" | nil | "ssh" | nil | false
+ "ssh" | ref(:p1) | nil | "all" | true
+ "http" | ref(:p1) | nil | "all" | true
+ "ssh" | ref(:p1) | nil | "ssh" | true
+ "http" | ref(:p1) | nil | "http" | true
+ "ssh" | ref(:p1) | nil | "http" | false
+ "http" | ref(:p1) | nil | "ssh" | false
+ "ssh" | ref(:p1) | "" | "all" | true
+ "http" | ref(:p1) | "" | "all" | true
+ "ssh" | ref(:p1) | "ssh" | "ssh" | true
+ "http" | ref(:p1) | "http" | "http" | true
end
with_them do
diff --git a/spec/lib/integrations/google_cloud_platform/artifact_registry/client_spec.rb b/spec/lib/google_cloud_platform/artifact_registry/client_spec.rb
index a258518953a..09ddba7c091 100644
--- a/spec/lib/integrations/google_cloud_platform/artifact_registry/client_spec.rb
+++ b/spec/lib/google_cloud_platform/artifact_registry/client_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe Integrations::GoogleCloudPlatform::ArtifactRegistry::Client, feature_category: :container_registry do
+RSpec.describe GoogleCloudPlatform::ArtifactRegistry::Client, feature_category: :container_registry do
let_it_be(:project) { create(:project) }
let_it_be(:rsa_key) { OpenSSL::PKey::RSA.generate(3072) }
let_it_be(:rsa_key_data) { rsa_key.to_s }
diff --git a/spec/lib/integrations/google_cloud_platform/jwt_spec.rb b/spec/lib/google_cloud_platform/jwt_spec.rb
index 51707c26a3a..d41056a8606 100644
--- a/spec/lib/integrations/google_cloud_platform/jwt_spec.rb
+++ b/spec/lib/google_cloud_platform/jwt_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe Integrations::GoogleCloudPlatform::Jwt, feature_category: :shared do
+RSpec.describe GoogleCloudPlatform::Jwt, feature_category: :shared do
let_it_be(:project) { create(:project) }
let_it_be(:user) { create(:user) }
diff --git a/spec/models/namespace_setting_spec.rb b/spec/models/namespace_setting_spec.rb
index c7449e047b0..07ac3248c0a 100644
--- a/spec/models/namespace_setting_spec.rb
+++ b/spec/models/namespace_setting_spec.rb
@@ -12,7 +12,7 @@ RSpec.describe NamespaceSetting, feature_category: :groups_and_projects, type: :
end
it { is_expected.to define_enum_for(:jobs_to_be_done).with_values([:basics, :move_repository, :code_storage, :exploring, :ci, :other]).with_suffix }
- it { is_expected.to define_enum_for(:enabled_git_access_protocol).with_suffix }
+ it { is_expected.to define_enum_for(:enabled_git_access_protocol).with_values([:all, :ssh, :http]).with_suffix }
describe 'default values' do
subject(:setting) { described_class.new }
diff --git a/spec/requests/api/graphql/mutations/notes/create/discussion_spec.rb b/spec/requests/api/graphql/mutations/notes/create/discussion_spec.rb
new file mode 100644
index 00000000000..c7ed63c2560
--- /dev/null
+++ b/spec/requests/api/graphql/mutations/notes/create/discussion_spec.rb
@@ -0,0 +1,45 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe 'Adding an DiscussionNote', feature_category: :code_review_workflow do
+ include GraphqlHelpers
+
+ let_it_be(:current_user) { create(:user) }
+
+ let(:noteable) { create(:merge_request, source_project: project, target_project: project) }
+ let(:project) { create(:project, :repository) }
+ let(:diff_refs) { noteable.diff_refs }
+ let(:mutation) do
+ variables = {
+ noteable_id: GitlabSchema.id_from_object(noteable).to_s,
+ body: 'Body text'
+ }
+
+ graphql_mutation(:create_discussion, variables)
+ end
+
+ def mutation_response
+ graphql_mutation_response(:create_discussion)
+ end
+
+ it_behaves_like 'a Note mutation when the user does not have permission'
+
+ context 'when the user has permission' do
+ before do
+ project.add_developer(current_user)
+ end
+
+ it_behaves_like 'a Note mutation that creates a Note'
+
+ it_behaves_like 'a Note mutation when there are active record validation errors', model: DiscussionNote
+
+ it_behaves_like 'a Note mutation when there are rate limit validation errors'
+
+ it 'returns the discussion' do
+ post_graphql_mutation(mutation, current_user: current_user)
+
+ expect(mutation_response['note']['body']).to eq('Body text')
+ end
+ end
+end
diff --git a/spec/requests/api/graphql/mutations/work_items/create_spec.rb b/spec/requests/api/graphql/mutations/work_items/create_spec.rb
index 2c2cd5f2acc..78b93c3210b 100644
--- a/spec/requests/api/graphql/mutations/work_items/create_spec.rb
+++ b/spec/requests/api/graphql/mutations/work_items/create_spec.rb
@@ -281,18 +281,6 @@ RSpec.describe 'Create a work item', feature_category: :team_planning do
it_behaves_like 'creates work item'
- # This is a temporary measure just to ensure the internal id migration doesn't get conflicts
- # More info in https://gitlab.com/gitlab-org/gitlab/-/merge_requests/139367
- context 'when making the request in a production environment' do
- before do
- stub_rails_env('production')
- end
-
- it_behaves_like 'a mutation that returns top-level errors', errors: [
- 'Group level work items are disabled. Only project paths allowed in `namespacePath`.'
- ]
- end
-
context 'when the namespace_level_work_items feature flag is disabled' do
before do
stub_feature_flags(namespace_level_work_items: false)
diff --git a/spec/services/google_cloud_platform/artifact_registry/list_docker_images_service_spec.rb b/spec/services/google_cloud_platform/artifact_registry/list_docker_images_service_spec.rb
index f19cbaa21cd..d772634e682 100644
--- a/spec/services/google_cloud_platform/artifact_registry/list_docker_images_service_spec.rb
+++ b/spec/services/google_cloud_platform/artifact_registry/list_docker_images_service_spec.rb
@@ -26,10 +26,10 @@ RSpec.describe GoogleCloudPlatform::ArtifactRegistry::ListDockerImagesService, f
describe '#execute' do
let(:page_token) { nil }
let(:list_docker_images_response) { dummy_list_response }
- let(:client_double) { instance_double('::Integrations::GoogleCloudPlatform::ArtifactRegistry::Client') }
+ let(:client_double) { instance_double('::GoogleCloudPlatform::ArtifactRegistry::Client') }
before do
- allow(::Integrations::GoogleCloudPlatform::ArtifactRegistry::Client).to receive(:new)
+ allow(::GoogleCloudPlatform::ArtifactRegistry::Client).to receive(:new)
.with(
project: project,
user: user,
diff --git a/spec/services/import/github_service_spec.rb b/spec/services/import/github_service_spec.rb
index 6fe17a31f3e..949031b961a 100644
--- a/spec/services/import/github_service_spec.rb
+++ b/spec/services/import/github_service_spec.rb
@@ -202,7 +202,25 @@ RSpec.describe Import::GithubService, feature_category: :importers do
end
end
- context 'validates scopes when collaborator import is true' do
+ context 'validates minimum scope when collaborator import is false' do
+ let(:optional_stages) do
+ {
+ collaborators_import: false
+ }
+ end
+
+ let(:headers) do
+ {
+ 'x-oauth-scopes' => 'write:packages'
+ }
+ end
+
+ it 'returns error when scope is not adequate' do
+ expect(subject.execute(access_params, :github)).to include(minimum_scope_error)
+ end
+ end
+
+ context 'validates collaborator scopes when collaborator import is true' do
let(:optional_stages) do
{
collaborators_import: true
@@ -211,12 +229,12 @@ RSpec.describe Import::GithubService, feature_category: :importers do
let(:headers) do
{
- 'x-oauth-scopes' => 'read:user'
+ 'x-oauth-scopes' => 'repo, read:user'
}
end
it 'returns error when scope is not adequate' do
- expect(subject.execute(access_params, :github)).to include(scope_error)
+ expect(subject.execute(access_params, :github)).to include(collab_import_scope_error)
end
end
@@ -355,7 +373,15 @@ RSpec.describe Import::GithubService, feature_category: :importers do
}
end
- def scope_error
+ def minimum_scope_error
+ {
+ status: :error,
+ http_status: :unprocessable_entity,
+ message: 'Your GitHub access token does not have the correct scope to import.'
+ }
+ end
+
+ def collab_import_scope_error
{
status: :error,
http_status: :unprocessable_entity,
diff --git a/spec/workers/every_sidekiq_worker_spec.rb b/spec/workers/every_sidekiq_worker_spec.rb
index 4067bce8d8d..4918c4e0082 100644
--- a/spec/workers/every_sidekiq_worker_spec.rb
+++ b/spec/workers/every_sidekiq_worker_spec.rb
@@ -247,21 +247,21 @@ RSpec.describe 'Every Sidekiq worker', feature_category: :shared do
'Geo::VerificationStateBackfillWorker' => false,
'Geo::VerificationTimeoutWorker' => false,
'Geo::VerificationWorker' => 3,
- 'Gitlab::BitbucketImport::AdvanceStageWorker' => 3,
- 'Gitlab::BitbucketImport::Stage::FinishImportWorker' => 3,
- 'Gitlab::BitbucketImport::Stage::ImportIssuesWorker' => 3,
- 'Gitlab::BitbucketImport::Stage::ImportIssuesNotesWorker' => 3,
- 'Gitlab::BitbucketImport::Stage::ImportLfsObjectsWorker' => 3,
- 'Gitlab::BitbucketImport::Stage::ImportPullRequestsWorker' => 3,
- 'Gitlab::BitbucketImport::Stage::ImportPullRequestsNotesWorker' => 3,
- 'Gitlab::BitbucketImport::Stage::ImportRepositoryWorker' => 3,
- 'Gitlab::BitbucketServerImport::AdvanceStageWorker' => 3,
- 'Gitlab::BitbucketServerImport::Stage::FinishImportWorker' => 3,
- 'Gitlab::BitbucketServerImport::Stage::ImportLfsObjectsWorker' => 3,
- 'Gitlab::BitbucketServerImport::Stage::ImportNotesWorker' => 3,
- 'Gitlab::BitbucketServerImport::Stage::ImportPullRequestsWorker' => 3,
- 'Gitlab::BitbucketServerImport::Stage::ImportRepositoryWorker' => 3,
- 'Gitlab::BitbucketServerImport::Stage::ImportUsersWorker' => 3,
+ 'Gitlab::BitbucketImport::AdvanceStageWorker' => 6,
+ 'Gitlab::BitbucketImport::Stage::FinishImportWorker' => 6,
+ 'Gitlab::BitbucketImport::Stage::ImportIssuesWorker' => 6,
+ 'Gitlab::BitbucketImport::Stage::ImportIssuesNotesWorker' => 6,
+ 'Gitlab::BitbucketImport::Stage::ImportLfsObjectsWorker' => 6,
+ 'Gitlab::BitbucketImport::Stage::ImportPullRequestsWorker' => 6,
+ 'Gitlab::BitbucketImport::Stage::ImportPullRequestsNotesWorker' => 6,
+ 'Gitlab::BitbucketImport::Stage::ImportRepositoryWorker' => 6,
+ 'Gitlab::BitbucketServerImport::AdvanceStageWorker' => 6,
+ 'Gitlab::BitbucketServerImport::Stage::FinishImportWorker' => 6,
+ 'Gitlab::BitbucketServerImport::Stage::ImportLfsObjectsWorker' => 6,
+ 'Gitlab::BitbucketServerImport::Stage::ImportNotesWorker' => 6,
+ 'Gitlab::BitbucketServerImport::Stage::ImportPullRequestsWorker' => 6,
+ 'Gitlab::BitbucketServerImport::Stage::ImportRepositoryWorker' => 6,
+ 'Gitlab::BitbucketServerImport::Stage::ImportUsersWorker' => 6,
'Gitlab::GithubImport::AdvanceStageWorker' => 6,
'Gitlab::GithubImport::Attachments::ImportReleaseWorker' => 5,
'Gitlab::GithubImport::Attachments::ImportNoteWorker' => 5,
@@ -297,14 +297,14 @@ RSpec.describe 'Every Sidekiq worker', feature_category: :shared do
'Gitlab::GithubGistsImport::ImportGistWorker' => 5,
'Gitlab::GithubGistsImport::StartImportWorker' => 5,
'Gitlab::GithubGistsImport::FinishImportWorker' => 5,
- 'Gitlab::JiraImport::AdvanceStageWorker' => 5,
+ 'Gitlab::JiraImport::AdvanceStageWorker' => 6,
'Gitlab::JiraImport::ImportIssueWorker' => 5,
- 'Gitlab::JiraImport::Stage::FinishImportWorker' => 5,
- 'Gitlab::JiraImport::Stage::ImportAttachmentsWorker' => 5,
- 'Gitlab::JiraImport::Stage::ImportIssuesWorker' => 5,
- 'Gitlab::JiraImport::Stage::ImportLabelsWorker' => 5,
- 'Gitlab::JiraImport::Stage::ImportNotesWorker' => 5,
- 'Gitlab::JiraImport::Stage::StartImportWorker' => 5,
+ 'Gitlab::JiraImport::Stage::FinishImportWorker' => 6,
+ 'Gitlab::JiraImport::Stage::ImportAttachmentsWorker' => 6,
+ 'Gitlab::JiraImport::Stage::ImportIssuesWorker' => 6,
+ 'Gitlab::JiraImport::Stage::ImportLabelsWorker' => 6,
+ 'Gitlab::JiraImport::Stage::ImportNotesWorker' => 6,
+ 'Gitlab::JiraImport::Stage::StartImportWorker' => 6,
'GitlabPerformanceBarStatsWorker' => 3,
'GitlabSubscriptions::RefreshSeatsWorker' => 0,
'GitlabSubscriptions::AddOnPurchases::BulkRefreshUserAssignmentsWorker' => 0,