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

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitlab/ci/package-and-test/main.gitlab-ci.yml4
-rw-r--r--.gitlab/ci/qa-common/rules.gitlab-ci.yml9
-rw-r--r--.gitlab/ci/qa-common/variables.gitlab-ci.yml1
-rw-r--r--app/assets/javascripts/ci/ci_variable_list/components/ci_variable_drawer.vue93
-rw-r--r--app/assets/javascripts/ci/ci_variable_list/components/ci_variable_settings.vue5
-rw-r--r--app/assets/javascripts/sidebar/components/assignees/sidebar_invite_members.vue2
-rw-r--r--app/assets/javascripts/super_sidebar/components/create_menu.vue2
-rw-r--r--app/assets/javascripts/work_items/components/work_item_assignees.vue2
-rw-r--r--app/helpers/nav/new_dropdown_helper.rb2
-rw-r--r--app/views/groups/group_members/index.html.haml2
-rw-r--r--app/views/projects/_invite_members_empty_project.html.haml2
-rw-r--r--app/views/projects/compare/index.html.haml2
-rw-r--r--app/views/projects/project_members/index.html.haml2
-rw-r--r--app/views/shared/issuable/_sidebar_assignees.html.haml2
-rw-r--r--app/views/shared/issuable/_sidebar_reviewers.html.haml2
-rw-r--r--config/feature_flags/development/explain_current_blob.yml8
-rw-r--r--config/feature_flags/development/push_ai_to_load_identified_issue_json.yml8
-rw-r--r--data/deprecations/16-3-CI-job-token-scope-update.yml28
-rw-r--r--doc/update/deprecations.md21
-rw-r--r--doc/user/project/integrations/webhook_events.md3
-rw-r--r--lib/gitlab/ci/templates/Jobs/DAST-Default-Branch-Deploy.gitlab-ci.yml2
-rw-r--r--lib/gitlab/ci/templates/Jobs/Deploy.gitlab-ci.yml2
-rw-r--r--lib/gitlab/ci/templates/Jobs/Deploy.latest.gitlab-ci.yml2
-rw-r--r--lib/gitlab/data_builder/deployment.rb2
-rw-r--r--locale/gitlab.pot9
-rw-r--r--qa/qa/specs/features/api/5_package/container_registry/saas/container_registry_spec.rb8
-rwxr-xr-xscripts/process_custom_semgrep_results.sh2
-rw-r--r--spec/features/groups/members/manage_members_spec.rb2
-rw-r--r--spec/features/projects/members/manage_members_spec.rb2
-rw-r--r--spec/frontend/ci/ci_variable_list/components/ci_variable_drawer_spec.js204
-rw-r--r--spec/frontend/ci/ci_variable_list/components/ci_variable_settings_spec.js15
-rw-r--r--spec/frontend/sidebar/components/assignees/sidebar_invite_members_spec.js2
-rw-r--r--spec/helpers/nav/new_dropdown_helper_spec.rb2
-rw-r--r--spec/lib/gitlab/data_builder/deployment_spec.rb9
-rw-r--r--spec/support/finder_collection_allowlist.yml1
-rw-r--r--spec/views/projects/empty.html.haml_spec.rb2
36 files changed, 405 insertions, 61 deletions
diff --git a/.gitlab/ci/package-and-test/main.gitlab-ci.yml b/.gitlab/ci/package-and-test/main.gitlab-ci.yml
index 9e11a6606f7..c616fe3de82 100644
--- a/.gitlab/ci/package-and-test/main.gitlab-ci.yml
+++ b/.gitlab/ci/package-and-test/main.gitlab-ci.yml
@@ -104,6 +104,7 @@ instance:
variables:
QA_SCENARIO: Test::Instance::Image
rules:
+ - !reference [.rules:test:smoke-for-omnibus-mr, rules]
- !reference [.rules:test:feature-flags-set, rules] # always run instance to validate ff change
- !reference [.rules:test:qa-parallel, rules]
- if: $QA_SUITES =~ /Test::Instance::All/
@@ -140,6 +141,7 @@ praefect:
QA_CAN_TEST_PRAEFECT: "true"
KNAPSACK_TEST_FILE_PATTERN: "qa/specs/features/**/3_create/**/*_spec.rb"
rules:
+ - !reference [.rules:test:smoke-for-omnibus-mr, rules]
- !reference [.rules:test:qa-parallel, rules]
- if: $QA_SUITES =~ /Test::Instance::All/
@@ -177,6 +179,7 @@ decomposition-single-db:
QA_SCENARIO: Test::Instance::Image
GITLAB_QA_OPTS: --omnibus-config decomposition_single_db $EXTRA_GITLAB_QA_OPTS
rules:
+ - !reference [.rules:test:smoke-for-omnibus-mr, rules]
- !reference [.rules:test:qa-parallel, rules]
- if: $QA_SUITES =~ /Test::Instance::All/
@@ -213,6 +216,7 @@ decomposition-multiple-db:
GITLAB_ALLOW_SEPARATE_CI_DATABASE: "true"
GITLAB_QA_OPTS: --omnibus-config decomposition_multiple_db $EXTRA_GITLAB_QA_OPTS
rules:
+ - !reference [.rules:test:smoke-for-omnibus-mr, rules]
- !reference [.rules:test:qa-parallel, rules]
- if: $QA_SUITES =~ /Test::Instance::All/
diff --git a/.gitlab/ci/qa-common/rules.gitlab-ci.yml b/.gitlab/ci/qa-common/rules.gitlab-ci.yml
index 7518f08398f..16440aa4cbc 100644
--- a/.gitlab/ci/qa-common/rules.gitlab-ci.yml
+++ b/.gitlab/ci/qa-common/rules.gitlab-ci.yml
@@ -155,6 +155,15 @@
- *default-branch
- *feature-flags-set-manual
+.rules:test:smoke-for-omnibus-mr:
+ rules:
+ - if: '$CI_PROJECT_NAME == "omnibus-gitlab" && $PIPELINE_TYPE =~ /TRIGGERED_(CE|EE)_PIPELINE/ && $QA_OMNIBUS_MR_TESTS == "only-smoke-reliable"'
+ variables:
+ QA_RSPEC_TAGS: "--tag smoke --tag reliable --tag ~orchestrated --tag ~skip_live_env"
+ - if: '$CI_PROJECT_NAME == "omnibus-gitlab" && $PIPELINE_TYPE =~ /TRIGGERED_(CE|EE)_PIPELINE/ && $QA_OMNIBUS_MR_TESTS == "except-smoke-reliable"'
+ variables:
+ QA_RSPEC_TAGS: "--tag ~smoke --tag ~reliable --tag ~orchestrated --tag ~skip_live_env --tag ~transient"
+
# ------------------------------------------
# Report
# ------------------------------------------
diff --git a/.gitlab/ci/qa-common/variables.gitlab-ci.yml b/.gitlab/ci/qa-common/variables.gitlab-ci.yml
index 9498df47ecc..a449d960cff 100644
--- a/.gitlab/ci/qa-common/variables.gitlab-ci.yml
+++ b/.gitlab/ci/qa-common/variables.gitlab-ci.yml
@@ -17,3 +17,4 @@ variables:
RSPEC_FAST_QUARANTINE_FILE: "fast_quarantine-gitlab.txt"
# This path is relative to /home/gitlab/qa/ in the QA container
RSPEC_FAST_QUARANTINE_PATH: "rspec/${RSPEC_FAST_QUARANTINE_FILE}"
+ QA_OMNIBUS_MR_TESTS: "only-smoke-reliable"
diff --git a/app/assets/javascripts/ci/ci_variable_list/components/ci_variable_drawer.vue b/app/assets/javascripts/ci/ci_variable_list/components/ci_variable_drawer.vue
index 0ce11da658c..3e084c45c31 100644
--- a/app/assets/javascripts/ci/ci_variable_list/components/ci_variable_drawer.vue
+++ b/app/assets/javascripts/ci/ci_variable_list/components/ci_variable_drawer.vue
@@ -5,6 +5,7 @@ import {
GlFormCheckbox,
GlFormCombobox,
GlFormGroup,
+ GlFormInput,
GlFormSelect,
GlFormTextarea,
GlIcon,
@@ -16,7 +17,9 @@ import { DRAWER_Z_INDEX } from '~/lib/utils/constants';
import { getContentWrapperHeight } from '~/lib/utils/dom_utils';
import { helpPagePath } from '~/helpers/help_page_helper';
import {
+ allEnvironments,
defaultVariableState,
+ EDIT_VARIABLE_ACTION,
ENVIRONMENT_SCOPE_LINK_TITLE,
EXPANDED_VARIABLES_NOTE,
FLAG_LINK_TITLE,
@@ -26,9 +29,11 @@ import {
import CiEnvironmentsDropdown from './ci_environments_dropdown.vue';
import { awsTokenList } from './ci_variable_autocomplete_tokens';
-const i18n = {
+export const i18n = {
addVariable: s__('CiVariables|Add Variable'),
cancel: __('Cancel'),
+ defaultScope: allEnvironments.text,
+ editVariable: s__('CiVariables|Edit Variable'),
environments: __('Environments'),
environmentScopeLinkTitle: ENVIRONMENT_SCOPE_LINK_TITLE,
expandedField: s__('CiVariables|Expand variable reference'),
@@ -57,26 +62,33 @@ export default {
GlFormCheckbox,
GlFormCombobox,
GlFormGroup,
+ GlFormInput,
GlFormSelect,
GlFormTextarea,
GlIcon,
GlLink,
GlSprintf,
},
- inject: ['environmentScopeLink'],
+ inject: ['environmentScopeLink', 'isProtectedByDefault'],
props: {
areEnvironmentsLoading: {
type: Boolean,
required: true,
},
+ areScopedVariablesAvailable: {
+ type: Boolean,
+ required: false,
+ default: false,
+ },
environments: {
type: Array,
required: false,
default: () => [],
},
- hasEnvScopeQuery: {
+ hideEnvironmentScope: {
type: Boolean,
- required: true,
+ required: false,
+ default: false,
},
mode: {
type: String,
@@ -85,22 +97,47 @@ export default {
return VARIABLE_ACTIONS.includes(val);
},
},
+ selectedVariable: {
+ type: Object,
+ required: false,
+ default: () => {},
+ },
},
data() {
return {
- key: defaultVariableState.key,
- variableType: defaultVariableState.variableType,
+ variable: { ...defaultVariableState, ...this.selectedVariable },
};
},
computed: {
getDrawerHeaderHeight() {
return getContentWrapperHeight();
},
+ isExpanded() {
+ return !this.variable.raw;
+ },
+ isEditing() {
+ return this.mode === EDIT_VARIABLE_ACTION;
+ },
+ modalActionText() {
+ return this.isEditing ? this.$options.i18n.editVariable : this.$options.i18n.addVariable;
+ },
+ },
+ mounted() {
+ if (this.isProtectedByDefault && !this.isEditing) {
+ this.variable = { ...this.variable, protected: true };
+ }
},
methods: {
close() {
this.$emit('close-form');
},
+ setRaw(expanded) {
+ this.variable = { ...this.variable, raw: !expanded };
+ },
+ submit() {
+ this.$emit(this.isEditing ? 'update-variable' : 'add-variable', this.variable);
+ this.close();
+ },
},
awsTokenList,
flagLink: helpPagePath('ci/variables/index', {
@@ -119,20 +156,25 @@ export default {
@close="close"
>
<template #title>
- <h2 class="gl-m-0">{{ $options.i18n.addVariable }}</h2>
+ <h2 class="gl-m-0">{{ modalActionText }}</h2>
</template>
<gl-form-group
:label="$options.i18n.type"
label-for="ci-variable-type"
- class="gl-border-none gl-mb-n5"
+ class="gl-border-none"
+ :class="{
+ 'gl-mb-n5': !hideEnvironmentScope,
+ 'gl-mb-n1': hideEnvironmentScope,
+ }"
>
<gl-form-select
id="ci-variable-type"
- v-model="variableType"
+ v-model="variable.variableType"
:options="$options.variableOptions"
/>
</gl-form-group>
<gl-form-group
+ v-if="!hideEnvironmentScope"
class="gl-border-none gl-mb-n5"
label-for="ci-variable-env"
data-testid="environment-scope"
@@ -154,11 +196,18 @@ export default {
</div>
</template>
<ci-environments-dropdown
+ v-if="areScopedVariablesAvailable"
class="gl-mb-5"
+ has-env-scope-query
:are-environments-loading="areEnvironmentsLoading"
:environments="environments"
- :has-env-scope-query="hasEnvScopeQuery"
- selected-environment-scope=""
+ :selected-environment-scope="variable.environmentScope"
+ />
+ <gl-form-input
+ v-else
+ :value="$options.i18n.defaultScope"
+ class="gl-w-full gl-mb-5"
+ readonly
/>
</gl-form-group>
<gl-form-group class="gl-border-none gl-mb-n8">
@@ -177,17 +226,21 @@ export default {
</gl-link>
</div>
</template>
- <gl-form-checkbox data-testid="ci-variable-protected-checkbox">
+ <gl-form-checkbox v-model="variable.protected" data-testid="ci-variable-protected-checkbox">
{{ $options.i18n.protectedField }}
<p class="gl-text-secondary">
{{ $options.i18n.protectedDescription }}
</p>
</gl-form-checkbox>
- <gl-form-checkbox data-testid="ci-variable-masked-checkbox">
+ <gl-form-checkbox v-model="variable.masked" data-testid="ci-variable-masked-checkbox">
{{ $options.i18n.maskedField }}
<p class="gl-text-secondary">{{ $options.i18n.maskedDescription }}</p>
</gl-form-checkbox>
- <gl-form-checkbox data-testid="ci-variable-expanded-checkbox">
+ <gl-form-checkbox
+ data-testid="ci-variable-expanded-checkbox"
+ :checked="isExpanded"
+ @change="setRaw"
+ >
{{ $options.i18n.expandedField }}
<p class="gl-text-secondary">
<gl-sprintf :message="$options.i18n.expandedDescription" class="gl-text-secondary">
@@ -199,7 +252,7 @@ export default {
</gl-form-checkbox>
</gl-form-group>
<gl-form-combobox
- v-model="key"
+ v-model="variable.key"
:token-list="$options.awsTokenList"
:label-text="$options.i18n.key"
class="gl-border-none gl-pb-0! gl-mb-n5"
@@ -222,11 +275,15 @@ export default {
/>
</gl-form-group>
<div class="gl-display-flex gl-justify-content-end">
- <gl-button category="primary" class="gl-mr-3" data-testid="cancel-button" @click="close"
+ <gl-button category="secondary" class="gl-mr-3" data-testid="cancel-button" @click="close"
>{{ $options.i18n.cancel }}
</gl-button>
- <gl-button category="primary" variant="confirm" data-testid="confirm-button"
- >{{ $options.i18n.addVariable }}
+ <gl-button
+ category="primary"
+ variant="confirm"
+ data-testid="ci-variable-confirm-btn"
+ @click="submit"
+ >{{ modalActionText }}
</gl-button>
</div>
</gl-drawer>
diff --git a/app/assets/javascripts/ci/ci_variable_list/components/ci_variable_settings.vue b/app/assets/javascripts/ci/ci_variable_list/components/ci_variable_settings.vue
index f4e1da9b34f..482f6da5617 100644
--- a/app/assets/javascripts/ci/ci_variable_list/components/ci_variable_settings.vue
+++ b/app/assets/javascripts/ci/ci_variable_list/components/ci_variable_settings.vue
@@ -139,7 +139,10 @@ export default {
<ci-variable-drawer
v-if="showDrawer"
:are-environments-loading="areEnvironmentsLoading"
- :has-env-scope-query="hasEnvScopeQuery"
+ :are-scoped-variables-available="areScopedVariablesAvailable"
+ :environments="environments"
+ :hide-environment-scope="hideEnvironmentScope"
+ :selected-variable="selectedVariable"
:mode="mode"
v-on="$listeners"
@close-form="closeForm"
diff --git a/app/assets/javascripts/sidebar/components/assignees/sidebar_invite_members.vue b/app/assets/javascripts/sidebar/components/assignees/sidebar_invite_members.vue
index b41d126be68..232cdcd2198 100644
--- a/app/assets/javascripts/sidebar/components/assignees/sidebar_invite_members.vue
+++ b/app/assets/javascripts/sidebar/components/assignees/sidebar_invite_members.vue
@@ -15,7 +15,7 @@ export default {
},
computed: {
triggerSource() {
- return `${this.issuableType}-assignee-dropdown`;
+ return `${this.issuableType}_assignee_dropdown`;
},
},
};
diff --git a/app/assets/javascripts/super_sidebar/components/create_menu.vue b/app/assets/javascripts/super_sidebar/components/create_menu.vue
index 3645606515f..7918f8c8840 100644
--- a/app/assets/javascripts/super_sidebar/components/create_menu.vue
+++ b/app/assets/javascripts/super_sidebar/components/create_menu.vue
@@ -83,7 +83,7 @@ export default {
<invite-members-trigger
v-if="isInvitedMembers(groupItem)"
:key="`${groupItem.text}-trigger`"
- trigger-source="top-nav"
+ trigger-source="top_nav"
:trigger-element="$options.TRIGGER_ELEMENT_DISCLOSURE_DROPDOWN"
/>
<gl-disclosure-dropdown-item v-else :key="groupItem.text" :item="groupItem" />
diff --git a/app/assets/javascripts/work_items/components/work_item_assignees.vue b/app/assets/javascripts/work_items/components/work_item_assignees.vue
index 4b4aa7f96ca..f9527884adc 100644
--- a/app/assets/javascripts/work_items/components/work_item_assignees.vue
+++ b/app/assets/javascripts/work_items/components/work_item_assignees.vue
@@ -388,7 +388,7 @@ export default {
:display-text="__('Invite members')"
trigger-element="side-nav"
icon="plus"
- trigger-source="work-item-assignees-dropdown"
+ trigger-source="work_item_assignees_dropdown"
classes="gl-display-block gl-text-body! gl-hover-text-decoration-none gl-pb-2"
/>
</gl-dropdown-item>
diff --git a/app/helpers/nav/new_dropdown_helper.rb b/app/helpers/nav/new_dropdown_helper.rb
index 306c4d8694e..5274ace3d8a 100644
--- a/app/helpers/nav/new_dropdown_helper.rb
+++ b/app/helpers/nav/new_dropdown_helper.rb
@@ -157,7 +157,7 @@ module Nav
partial: partial,
component: 'invite_members',
data: {
- trigger_source: 'top-nav',
+ trigger_source: 'top_nav',
trigger_element: 'text-emoji'
}
)
diff --git a/app/views/groups/group_members/index.html.haml b/app/views/groups/group_members/index.html.haml
index e5c66c2c432..fbfaaa49b39 100644
--- a/app/views/groups/group_members/index.html.haml
+++ b/app/views/groups/group_members/index.html.haml
@@ -15,7 +15,7 @@
= render_if_exists 'groups/group_members/create_service_account'
.js-invite-members-trigger{ data: { variant: 'confirm',
classes: 'gl-md-w-auto gl-w-full',
- trigger_source: 'group-members-page',
+ trigger_source: 'group_members_page',
display_text: _('Invite members') } }
= render 'groups/invite_groups_modal', group: @group, reload_page_on_submit: true
diff --git a/app/views/projects/_invite_members_empty_project.html.haml b/app/views/projects/_invite_members_empty_project.html.haml
index 18d06c7d0bb..d6cab06f773 100644
--- a/app/views/projects/_invite_members_empty_project.html.haml
+++ b/app/views/projects/_invite_members_empty_project.html.haml
@@ -6,4 +6,4 @@
.js-invite-members-trigger{ data: { variant: 'confirm',
classes: 'gl-mb-8 gl-xs-w-full',
display_text: s_('InviteMember|Invite members'),
- trigger_source: 'project-empty-page' } }
+ trigger_source: 'project_empty_page' } }
diff --git a/app/views/projects/compare/index.html.haml b/app/views/projects/compare/index.html.haml
index 4a29402bfe7..38633c9e5f1 100644
--- a/app/views/projects/compare/index.html.haml
+++ b/app/views/projects/compare/index.html.haml
@@ -1,6 +1,6 @@
- breadcrumb_title s_("CompareRevisions|Compare revisions")
-- page_title _("CompareRevisions|Compare revisions")
+- page_title s_("CompareRevisions|Compare revisions")
.prepend-top-20
#js-compare-selector{ data: project_compare_selector_data(@project, @merge_request, @compare_params) }
diff --git a/app/views/projects/project_members/index.html.haml b/app/views/projects/project_members/index.html.haml
index 6b6aaaad802..1f39bbe12a2 100644
--- a/app/views/projects/project_members/index.html.haml
+++ b/app/views/projects/project_members/index.html.haml
@@ -26,7 +26,7 @@
- if can_admin_project_member?(@project)
.js-invite-members-trigger{ data: { variant: 'confirm',
classes: 'gl-md-w-auto gl-w-full gl-md-ml-3 gl-md-mt-0 gl-mt-3',
- trigger_source: 'project-members-page',
+ trigger_source: 'project_members_page',
display_text: _('Invite members') } }
- else
- if project_can_be_shared?
diff --git a/app/views/shared/issuable/_sidebar_assignees.html.haml b/app/views/shared/issuable/_sidebar_assignees.html.haml
index a27bb506c87..0ffce0ac571 100644
--- a/app/views/shared/issuable/_sidebar_assignees.html.haml
+++ b/app/views/shared/issuable/_sidebar_assignees.html.haml
@@ -45,4 +45,4 @@
options: options,
wrapper_class: 'js-sidebar-assignee-dropdown',
track_label: 'edit_assignee',
- trigger_source: "#{issuable_type}-assignee-dropdown"
+ trigger_source: "#{issuable_type}_assignee_dropdown"
diff --git a/app/views/shared/issuable/_sidebar_reviewers.html.haml b/app/views/shared/issuable/_sidebar_reviewers.html.haml
index b360fac0a55..4b07d8d0850 100644
--- a/app/views/shared/issuable/_sidebar_reviewers.html.haml
+++ b/app/views/shared/issuable/_sidebar_reviewers.html.haml
@@ -42,4 +42,4 @@
options: options,
wrapper_class: 'js-sidebar-reviewer-dropdown',
track_label: 'edit_reviewer',
- trigger_source: "#{issuable_type}-reviewer-dropdown"
+ trigger_source: "#{issuable_type}_reviewer_dropdown"
diff --git a/config/feature_flags/development/explain_current_blob.yml b/config/feature_flags/development/explain_current_blob.yml
new file mode 100644
index 00000000000..e296748a3f7
--- /dev/null
+++ b/config/feature_flags/development/explain_current_blob.yml
@@ -0,0 +1,8 @@
+---
+name: explain_current_blob
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/128342/
+rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/420959
+milestone: '16.3'
+type: development
+group: group::ai framework
+default_enabled: false
diff --git a/config/feature_flags/development/push_ai_to_load_identified_issue_json.yml b/config/feature_flags/development/push_ai_to_load_identified_issue_json.yml
new file mode 100644
index 00000000000..265b561c760
--- /dev/null
+++ b/config/feature_flags/development/push_ai_to_load_identified_issue_json.yml
@@ -0,0 +1,8 @@
+---
+name: push_ai_to_load_identified_issue_json
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/128342
+rollout_issue_url:
+milestone: '16.3'
+type: development
+group: group::ai framework
+default_enabled: false
diff --git a/data/deprecations/16-3-CI-job-token-scope-update.yml b/data/deprecations/16-3-CI-job-token-scope-update.yml
new file mode 100644
index 00000000000..5867cedcc53
--- /dev/null
+++ b/data/deprecations/16-3-CI-job-token-scope-update.yml
@@ -0,0 +1,28 @@
+#
+# REQUIRED FIELDS
+#
+- title: "Job token allowlist covers public and internal projects" # (required) Clearly explain the change, or planned change. For example, "The `confidential` field for a `Note` is deprecated" or "CI/CD job names will be limited to 250 characters."
+ removal_milestone: "16.6" # (required) The milestone when this feature is planned to be removed
+ announcement_milestone: "16.3" # (required) The milestone when this feature was first announced as deprecated.
+ breaking_change: true # (required) Change to false if this is not a breaking change.
+ reporter: jocelynjane # (required) GitLab username of the person reporting the change
+ stage: Verify # (required) String value of the stage that the feature was created in. e.g., Growth
+ issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/420678 # (required) Link to the deprecation issue in GitLab
+ body: | # (required) Do not modify this line, instead modify the lines below.
+ Starting in 16.6, projects that are **public** or **internal** will no longer authorize job token requests from projects that are **not** on the project's allowlist when [**Limit access to this project**](https://docs.gitlab.com/ee/ci/jobs/ci_job_token.html#allow-access-to-your-project-with-a-job-token) is enabled.
+
+ If you have [public or internal](https://docs.gitlab.com/ee/user/public_access.html#change-project-visibility) projects with the **Limit access to this project** setting enabled, you must add any projects which make job token requests to your project's allowlist for continued authorization.
+#
+# OPTIONAL END OF SUPPORT FIELDS
+#
+# If an End of Support period applies, the announcement should be shared with GitLab Support
+# in the `#spt_managers` channel in Slack, and mention `@gitlab-com/support` in this MR.
+#
+ end_of_support_milestone: # (optional) Use "XX.YY" format. The milestone when support for this feature will end.
+ #
+ # OTHER OPTIONAL FIELDS
+ #
+ tiers: # (optional - may be required in the future) An array of tiers that the feature is available in currently. e.g., [Free, Silver, Gold, Core, Premium, Ultimate]
+ documentation_url: # (optional) This is a link to the current documentation page
+ image_url: # (optional) This is a link to a thumbnail image depicting the feature
+ video_url: # (optional) Use the youtube thumbnail URL with the structure of https://img.youtube.com/vi/UNIQUEID/hqdefault.jpg
diff --git a/doc/update/deprecations.md b/doc/update/deprecations.md
index a3a644d1d49..1138cc8d0dd 100644
--- a/doc/update/deprecations.md
+++ b/doc/update/deprecations.md
@@ -909,6 +909,27 @@ Previous work helped [align the vulnerabilities calls for pipeline security tabs
</div>
</div>
+<div class="milestone-wrapper" data-milestone="16.6">
+
+## GitLab 16.6
+
+<div class="deprecation breaking-change" data-milestone="16.6">
+
+### Job token allowlist covers public and internal projects
+
+<div class="deprecation-notes">
+- Announced in GitLab <span class="milestone">16.3</span>
+- Removal in GitLab <span class="milestone">16.6</span> ([breaking change](https://docs.gitlab.com/ee/update/terminology.html#breaking-change))
+- To discuss this change or learn more, see the [deprecation issue](https://gitlab.com/gitlab-org/gitlab/-/issues/420678).
+</div>
+
+Starting in 16.6, projects that are **public** or **internal** will no longer authorize job token requests from projects that are **not** on the project's allowlist when [**Limit access to this project**](https://docs.gitlab.com/ee/ci/jobs/ci_job_token.html#allow-access-to-your-project-with-a-job-token) is enabled.
+
+If you have [public or internal](https://docs.gitlab.com/ee/user/public_access.html#change-project-visibility) projects with the **Limit access to this project** setting enabled, you must add any projects which make job token requests to your project's allowlist for continued authorization.
+
+</div>
+</div>
+
<div class="milestone-wrapper" data-milestone="16.5">
## GitLab 16.5
diff --git a/doc/user/project/integrations/webhook_events.md b/doc/user/project/integrations/webhook_events.md
index c4dd8dcf812..8bb1c433af5 100644
--- a/doc/user/project/integrations/webhook_events.md
+++ b/doc/user/project/integrations/webhook_events.md
@@ -1521,7 +1521,8 @@ Deployment events are triggered when a deployment:
- Fails
- Is cancelled
-The `deployable_id` in the payload is the ID of the CI/CD job.
+The `deployable_id` and `deployable_url` in the payload represent a CI/CD job that executed the deployment.
+When the deployment event occurs by [API](../../../ci/environments/external_deployment_tools.md) or [`trigger` jobs](../../../ci/pipelines/downstream_pipelines.md), `deployable_url` is `null`.
Request header:
diff --git a/lib/gitlab/ci/templates/Jobs/DAST-Default-Branch-Deploy.gitlab-ci.yml b/lib/gitlab/ci/templates/Jobs/DAST-Default-Branch-Deploy.gitlab-ci.yml
index 7b2fb49b65e..c737da7a579 100644
--- a/lib/gitlab/ci/templates/Jobs/DAST-Default-Branch-Deploy.gitlab-ci.yml
+++ b/lib/gitlab/ci/templates/Jobs/DAST-Default-Branch-Deploy.gitlab-ci.yml
@@ -1,5 +1,5 @@
variables:
- DAST_AUTO_DEPLOY_IMAGE_VERSION: 'v2.53.0'
+ DAST_AUTO_DEPLOY_IMAGE_VERSION: 'v2.54.0'
.dast-auto-deploy:
image: "${CI_TEMPLATE_REGISTRY_HOST}/gitlab-org/cluster-integration/auto-deploy-image:${DAST_AUTO_DEPLOY_IMAGE_VERSION}"
diff --git a/lib/gitlab/ci/templates/Jobs/Deploy.gitlab-ci.yml b/lib/gitlab/ci/templates/Jobs/Deploy.gitlab-ci.yml
index 1e482ccca82..9b37d8774d9 100644
--- a/lib/gitlab/ci/templates/Jobs/Deploy.gitlab-ci.yml
+++ b/lib/gitlab/ci/templates/Jobs/Deploy.gitlab-ci.yml
@@ -1,5 +1,5 @@
variables:
- AUTO_DEPLOY_IMAGE_VERSION: 'v2.53.0'
+ AUTO_DEPLOY_IMAGE_VERSION: 'v2.54.0'
.auto-deploy:
image: "${CI_TEMPLATE_REGISTRY_HOST}/gitlab-org/cluster-integration/auto-deploy-image:${AUTO_DEPLOY_IMAGE_VERSION}"
diff --git a/lib/gitlab/ci/templates/Jobs/Deploy.latest.gitlab-ci.yml b/lib/gitlab/ci/templates/Jobs/Deploy.latest.gitlab-ci.yml
index 6eac691b293..54ce5f06ad0 100644
--- a/lib/gitlab/ci/templates/Jobs/Deploy.latest.gitlab-ci.yml
+++ b/lib/gitlab/ci/templates/Jobs/Deploy.latest.gitlab-ci.yml
@@ -1,5 +1,5 @@
variables:
- AUTO_DEPLOY_IMAGE_VERSION: 'v2.53.0'
+ AUTO_DEPLOY_IMAGE_VERSION: 'v2.54.0'
.auto-deploy:
image: "${CI_TEMPLATE_REGISTRY_HOST}/gitlab-org/cluster-integration/auto-deploy-image:${AUTO_DEPLOY_IMAGE_VERSION}"
diff --git a/lib/gitlab/data_builder/deployment.rb b/lib/gitlab/data_builder/deployment.rb
index b26f9a61ee1..915d606feb9 100644
--- a/lib/gitlab/data_builder/deployment.rb
+++ b/lib/gitlab/data_builder/deployment.rb
@@ -9,7 +9,7 @@ module Gitlab
def build(deployment, status, status_changed_at)
# Deployments will not have a deployable when created using the API.
deployable_url =
- if deployment.deployable
+ if deployment.deployable.instance_of?(::Ci::Build)
Gitlab::UrlBuilder.build(deployment.deployable)
end
diff --git a/locale/gitlab.pot b/locale/gitlab.pot
index 65dcb7bbfe0..b4b9e846699 100644
--- a/locale/gitlab.pot
+++ b/locale/gitlab.pot
@@ -1904,6 +1904,9 @@ msgstr ""
msgid "AI|Apply AI-generated description"
msgstr ""
+msgid "AI|Ask GitLab Duo"
+msgstr ""
+
msgid "AI|Ask a question"
msgstr ""
@@ -2015,9 +2018,6 @@ msgstr ""
msgid "AI|You are not allowed to copy any part of this output into issues, comments, GitLab source code, commit messages, merge requests or any other user interface in the %{gitlabOrg} or %{gitlabCom} groups."
msgstr ""
-msgid "AI|You can ask AI for more information."
-msgstr ""
-
msgid "AI|finding"
msgstr ""
@@ -10135,6 +10135,9 @@ msgstr ""
msgid "CiVariables|Do you want to delete the variable %{key}?"
msgstr ""
+msgid "CiVariables|Edit Variable"
+msgstr ""
+
msgid "CiVariables|Environments"
msgstr ""
diff --git a/qa/qa/specs/features/api/5_package/container_registry/saas/container_registry_spec.rb b/qa/qa/specs/features/api/5_package/container_registry/saas/container_registry_spec.rb
index d2b1cbd2c95..32100fbce32 100644
--- a/qa/qa/specs/features/api/5_package/container_registry/saas/container_registry_spec.rb
+++ b/qa/qa/specs/features/api/5_package/container_registry/saas/container_registry_spec.rb
@@ -57,11 +57,9 @@ module QA
- docker build -t $IMAGE_TAG .
- docker push $IMAGE_TAG
- docker pull $IMAGE_TAG
- tags:
- - "runner-for-#{project.name}"
test:
- image: dwdraju/alpine-curl-jq:latest
+ image: registry.gitlab.com/gitlab-ci-utils/curl-jq:latest
stage: test
script:
- 'id=$(curl --header "PRIVATE-TOKEN: #{masked_token}" "https://${CI_SERVER_HOST}/api/v4/projects/#{project.id}/registry/repositories" | jq ".[0].id")'
@@ -72,8 +70,6 @@ module QA
- if [ $status_code -ne 200 ]; then exit 1; fi;
- 'status_code=$(curl --head --output /dev/null --write-out "%{http_code}\n" --header "PRIVATE-TOKEN: #{masked_token}" "https://${CI_SERVER_HOST}/api/v4/projects/#{project.id}/registry/repositories/$id/tags/master")'
- if [ $status_code -ne 404 ]; then exit 1; fi;
- tags:
- - "runner-for-#{project.name}"
YAML
end
@@ -96,7 +92,7 @@ module QA
end
Support::Retrier.retry_until(
- max_duration: 10,
+ max_duration: 30,
sleep_interval: 1,
message: "Waiting for pipeline to start"
) do
diff --git a/scripts/process_custom_semgrep_results.sh b/scripts/process_custom_semgrep_results.sh
index 1fdd8e486f3..0eccef00973 100755
--- a/scripts/process_custom_semgrep_results.sh
+++ b/scripts/process_custom_semgrep_results.sh
@@ -22,7 +22,7 @@ jq -crM '.vulnerabilities |
echo "Resulting file:"
cat findings.txt
-EXISTING_COMMENT_ID=$(curl "https://gitlab.com/api/v4/projects/$CI_PROJECT_ID/merge_requests/$CI_MERGE_REQUEST_IID/notes" \
+EXISTING_COMMENT_ID=$(curl "https://gitlab.com/api/v4/projects/$CI_PROJECT_ID/merge_requests/$CI_MERGE_REQUEST_IID/notes?per_page=100" \
--header "Private-Token: $CUSTOM_SAST_RULES_BOT_PAT" |
jq -crM 'map( select( .author.id == (env.BOT_USER_ID | tonumber) ) | .id ) | first')
diff --git a/spec/features/groups/members/manage_members_spec.rb b/spec/features/groups/members/manage_members_spec.rb
index 138031ffaac..dd64ddcede5 100644
--- a/spec/features/groups/members/manage_members_spec.rb
+++ b/spec/features/groups/members/manage_members_spec.rb
@@ -85,7 +85,7 @@ RSpec.describe 'Groups > Members > Manage members', feature_category: :groups_an
end
end
- it_behaves_like 'inviting members', 'group-members-page' do
+ it_behaves_like 'inviting members', 'group_members_page' do
let_it_be(:entity) { group }
let_it_be(:members_page_path) { group_group_members_path(entity) }
let_it_be(:subentity) { create(:group, parent: group) }
diff --git a/spec/features/projects/members/manage_members_spec.rb b/spec/features/projects/members/manage_members_spec.rb
index 0e3ac5ff3ac..76b2a73e170 100644
--- a/spec/features/projects/members/manage_members_spec.rb
+++ b/spec/features/projects/members/manage_members_spec.rb
@@ -173,7 +173,7 @@ RSpec.describe 'Projects > Members > Manage members', :js, feature_category: :on
end
end
- it_behaves_like 'inviting members', 'project-members-page' do
+ it_behaves_like 'inviting members', 'project_members_page' do
let_it_be(:entity) { project }
let_it_be(:members_page_path) { project_project_members_path(entity) }
let_it_be(:subentity) { project }
diff --git a/spec/frontend/ci/ci_variable_list/components/ci_variable_drawer_spec.js b/spec/frontend/ci/ci_variable_list/components/ci_variable_drawer_spec.js
index 762c9611dac..cb839503931 100644
--- a/spec/frontend/ci/ci_variable_list/components/ci_variable_drawer_spec.js
+++ b/spec/frontend/ci/ci_variable_list/components/ci_variable_drawer_spec.js
@@ -1,42 +1,73 @@
-import { GlDrawer, GlFormSelect } from '@gitlab/ui';
+import { GlDrawer, GlFormInput, GlFormSelect } from '@gitlab/ui';
import { mountExtended, shallowMountExtended } from 'helpers/vue_test_utils_helper';
-import CiVariableDrawer from '~/ci/ci_variable_list/components/ci_variable_drawer.vue';
+import CiEnvironmentsDropdown from '~/ci/ci_variable_list/components/ci_environments_dropdown.vue';
+import CiVariableDrawer, { i18n } from '~/ci/ci_variable_list/components/ci_variable_drawer.vue';
import {
ADD_VARIABLE_ACTION,
+ EDIT_VARIABLE_ACTION,
variableOptions,
+ projectString,
variableTypes,
} from '~/ci/ci_variable_list/constants';
+import { mockVariablesWithScopes } from '../mocks';
describe('CI Variable Drawer', () => {
let wrapper;
+ const mockProjectVariable = mockVariablesWithScopes(projectString)[0];
+ const mockProjectVariableFileType = mockVariablesWithScopes(projectString)[1];
+ const mockEnvScope = 'staging';
+ const mockEnvironments = ['*', 'dev', 'staging', 'production'];
+
const defaultProps = {
areEnvironmentsLoading: false,
- hasEnvScopeQuery: true,
+ areScopedVariablesAvailable: true,
+ environments: mockEnvironments,
+ hideEnvironmentScope: false,
+ selectedVariable: {},
mode: ADD_VARIABLE_ACTION,
};
- const createComponent = ({ mountFn = shallowMountExtended, props = {} } = {}) => {
+ const defaultProvide = {
+ isProtectedByDefault: true,
+ environmentScopeLink: '/help/environments',
+ };
+
+ const createComponent = ({
+ mountFn = shallowMountExtended,
+ props = {},
+ provide = {},
+ stubs = {},
+ } = {}) => {
wrapper = mountFn(CiVariableDrawer, {
propsData: {
...defaultProps,
...props,
},
provide: {
- environmentScopeLink: '/help/environments',
+ ...defaultProvide,
+ ...provide,
},
+ stubs,
});
};
+ const findConfirmBtn = () => wrapper.findByTestId('ci-variable-confirm-btn');
+ const findDisabledEnvironmentScopeDropdown = () => wrapper.findComponent(GlFormInput);
const findDrawer = () => wrapper.findComponent(GlDrawer);
+ const findEnvironmentScopeDropdown = () => wrapper.findComponent(CiEnvironmentsDropdown);
+ const findExpandedCheckbox = () => wrapper.findByTestId('ci-variable-expanded-checkbox');
+ const findMaskedCheckbox = () => wrapper.findByTestId('ci-variable-masked-checkbox');
+ const findProtectedCheckbox = () => wrapper.findByTestId('ci-variable-protected-checkbox');
+ const findTitle = () => findDrawer().find('h2');
const findTypeDropdown = () => wrapper.findComponent(GlFormSelect);
describe('validations', () => {
- beforeEach(() => {
- createComponent({ mountFn: mountExtended });
- });
-
describe('type dropdown', () => {
+ beforeEach(() => {
+ createComponent({ mountFn: mountExtended });
+ });
+
it('adds each type option as a dropdown item', () => {
expect(findTypeDropdown().findAll('option')).toHaveLength(variableOptions.length);
@@ -50,20 +81,169 @@ describe('CI Variable Drawer', () => {
variableTypes.envType,
);
});
+
+ it('renders the selected variable type', () => {
+ createComponent({
+ mountFn: mountExtended,
+ props: {
+ areEnvironmentsLoading: true,
+ selectedVariable: mockProjectVariableFileType,
+ },
+ });
+
+ expect(findTypeDropdown().element.value).toBe(variableTypes.fileType);
+ });
+ });
+
+ describe('environment scope dropdown', () => {
+ it('passes correct props to the dropdown', () => {
+ createComponent({
+ props: {
+ areEnvironmentsLoading: true,
+ selectedVariable: { ...mockProjectVariable, environmentScope: mockEnvScope },
+ },
+ stubs: { CiEnvironmentsDropdown },
+ });
+
+ expect(findEnvironmentScopeDropdown().props()).toMatchObject({
+ areEnvironmentsLoading: true,
+ environments: mockEnvironments,
+ selectedEnvironmentScope: mockEnvScope,
+ });
+ });
+
+ it('hides environment scope dropdown when hideEnvironmentScope is true', () => {
+ createComponent({
+ props: { hideEnvironmentScope: true },
+ stubs: { CiEnvironmentsDropdown },
+ });
+
+ expect(findEnvironmentScopeDropdown().exists()).toBe(false);
+ });
+
+ it('disables the environment scope dropdown when areScopedVariablesAvailable is false', () => {
+ createComponent({
+ mountFn: mountExtended,
+ props: { areScopedVariablesAvailable: false },
+ });
+
+ expect(findEnvironmentScopeDropdown().exists()).toBe(false);
+ expect(findDisabledEnvironmentScopeDropdown().attributes('readonly')).toBe('readonly');
+ });
+ });
+
+ describe('protected flag', () => {
+ beforeEach(() => {
+ createComponent();
+ });
+
+ it('is true by default when isProtectedByDefault is true', () => {
+ expect(findProtectedCheckbox().attributes('checked')).toBeDefined();
+ });
+
+ it('is not checked when isProtectedByDefault is false', () => {
+ createComponent({ provide: { isProtectedByDefault: false } });
+
+ expect(findProtectedCheckbox().attributes('checked')).toBeUndefined();
+ });
+
+ it('inherits value of selected variable when editing', () => {
+ createComponent({
+ props: {
+ selectedVariable: mockProjectVariableFileType,
+ mode: EDIT_VARIABLE_ACTION,
+ },
+ });
+
+ expect(findProtectedCheckbox().attributes('checked')).toBeUndefined();
+ });
+ });
+
+ describe('masked flag', () => {
+ beforeEach(() => {
+ createComponent();
+ });
+
+ it('is false by default', () => {
+ expect(findMaskedCheckbox().attributes('checked')).toBeUndefined();
+ });
+
+ it('inherits value of selected variable when editing', () => {
+ createComponent({
+ props: {
+ selectedVariable: mockProjectVariableFileType,
+ mode: EDIT_VARIABLE_ACTION,
+ },
+ });
+
+ expect(findMaskedCheckbox().attributes('checked')).toBeDefined();
+ });
+ });
+
+ describe('expanded flag', () => {
+ beforeEach(() => {
+ createComponent();
+ });
+
+ it('is true by default when adding a variable', () => {
+ expect(findExpandedCheckbox().attributes('checked')).toBeDefined();
+ });
+
+ it('inherits value of selected variable when editing', () => {
+ createComponent({
+ props: {
+ selectedVariable: mockProjectVariableFileType,
+ mode: EDIT_VARIABLE_ACTION,
+ },
+ });
+
+ expect(findExpandedCheckbox().attributes('checked')).toBeUndefined();
+ });
+
+ it("sets the variable's raw value", async () => {
+ await findExpandedCheckbox().vm.$emit('change');
+ await findConfirmBtn().vm.$emit('click');
+
+ const sentRawValue = wrapper.emitted('add-variable')[0][0].raw;
+ expect(sentRawValue).toBe(!defaultProps.raw);
+ });
});
});
describe('drawer events', () => {
- beforeEach(() => {
+ it('emits `close-form` when closing the drawer', async () => {
createComponent();
- });
- it('emits `close-form` when closing the drawer', async () => {
expect(wrapper.emitted('close-form')).toBeUndefined();
await findDrawer().vm.$emit('close');
expect(wrapper.emitted('close-form')).toHaveLength(1);
});
+
+ describe('when adding a variable', () => {
+ beforeEach(() => {
+ createComponent({ stubs: { GlDrawer } });
+ });
+
+ it('title and confirm button renders the correct text', () => {
+ expect(findTitle().text()).toBe(i18n.addVariable);
+ expect(findConfirmBtn().text()).toBe(i18n.addVariable);
+ });
+ });
+
+ describe('when editing a variable', () => {
+ beforeEach(() => {
+ createComponent({
+ props: { mode: EDIT_VARIABLE_ACTION },
+ stubs: { GlDrawer },
+ });
+ });
+
+ it('title and confirm button renders the correct text', () => {
+ expect(findTitle().text()).toBe(i18n.editVariable);
+ expect(findConfirmBtn().text()).toBe(i18n.editVariable);
+ });
+ });
});
});
diff --git a/spec/frontend/ci/ci_variable_list/components/ci_variable_settings_spec.js b/spec/frontend/ci/ci_variable_list/components/ci_variable_settings_spec.js
index f5737c61eea..79dd638e2bd 100644
--- a/spec/frontend/ci/ci_variable_list/components/ci_variable_settings_spec.js
+++ b/spec/frontend/ci/ci_variable_list/components/ci_variable_settings_spec.js
@@ -77,6 +77,21 @@ describe('Ci variable table', () => {
selectedVariable: {},
});
});
+
+ it('passes props down correctly to the ci drawer', async () => {
+ createComponent({ featureFlags: { ciVariableDrawer: true } });
+
+ await findCiVariableTable().vm.$emit('set-selected-variable');
+
+ expect(findCiVariableDrawer().props()).toEqual({
+ areEnvironmentsLoading: defaultProps.areEnvironmentsLoading,
+ areScopedVariablesAvailable: defaultProps.areScopedVariablesAvailable,
+ environments: defaultProps.environments,
+ hideEnvironmentScope: defaultProps.hideEnvironmentScope,
+ mode: ADD_VARIABLE_ACTION,
+ selectedVariable: {},
+ });
+ });
});
describe.each`
diff --git a/spec/frontend/sidebar/components/assignees/sidebar_invite_members_spec.js b/spec/frontend/sidebar/components/assignees/sidebar_invite_members_spec.js
index 501048bf056..8c42e61548f 100644
--- a/spec/frontend/sidebar/components/assignees/sidebar_invite_members_spec.js
+++ b/spec/frontend/sidebar/components/assignees/sidebar_invite_members_spec.js
@@ -26,7 +26,7 @@ describe('Sidebar invite members component', () => {
});
it('has expected attributes on the trigger', () => {
- expect(findDirectInviteLink().props('triggerSource')).toBe('issue-assignee-dropdown');
+ expect(findDirectInviteLink().props('triggerSource')).toBe('issue_assignee_dropdown');
});
});
});
diff --git a/spec/helpers/nav/new_dropdown_helper_spec.rb b/spec/helpers/nav/new_dropdown_helper_spec.rb
index 26dadd3b4f1..db394739b60 100644
--- a/spec/helpers/nav/new_dropdown_helper_spec.rb
+++ b/spec/helpers/nav/new_dropdown_helper_spec.rb
@@ -37,7 +37,7 @@ RSpec.describe Nav::NewDropdownHelper, feature_category: :navigation do
partial: partial,
component: 'invite_members',
data: {
- trigger_source: 'top-nav',
+ trigger_source: 'top_nav',
trigger_element: 'text-emoji'
}
)
diff --git a/spec/lib/gitlab/data_builder/deployment_spec.rb b/spec/lib/gitlab/data_builder/deployment_spec.rb
index bbcfa1973ea..bf97f40e97f 100644
--- a/spec/lib/gitlab/data_builder/deployment_spec.rb
+++ b/spec/lib/gitlab/data_builder/deployment_spec.rb
@@ -50,6 +50,15 @@ RSpec.describe Gitlab::DataBuilder::Deployment, feature_category: :continuous_de
expect(data[:deployable_url]).to be_nil
end
+ it 'does not include the deployable URL when deployable is bridge' do
+ project = create(:project, :repository)
+ bridge = create(:ci_bridge, project: project)
+ deployment = create(:deployment, status: :failed, project: project, deployable: bridge)
+ data = described_class.build(deployment, 'failed', Time.current)
+
+ expect(data[:deployable_url]).to be_nil
+ end
+
context 'when commit does not exist in the repository' do
let_it_be(:project) { create(:project, :repository) }
let_it_be(:deployment) { create(:deployment, project: project) }
diff --git a/spec/support/finder_collection_allowlist.yml b/spec/support/finder_collection_allowlist.yml
index 5de8e8cdca2..e7dd9cea922 100644
--- a/spec/support/finder_collection_allowlist.yml
+++ b/spec/support/finder_collection_allowlist.yml
@@ -7,6 +7,7 @@
- Namespaces::FreeUserCap::UsersFinder # Reason: There is no need to have anything else besides the count
- Groups::EnvironmentScopesFinder # Reason: There is no need to have anything else besides the simple strucutre with the scope name
- Security::RelatedPipelinesFinder # Reason: There is no need to have anything else besides the IDs of pipelines
+- Llm::ExtraResourceFinder # Reason: The finder does not deal with DB-backend resource for now.
# Temporary excludes (aka TODOs)
# For example:
diff --git a/spec/views/projects/empty.html.haml_spec.rb b/spec/views/projects/empty.html.haml_spec.rb
index 2b19b364365..c478b446864 100644
--- a/spec/views/projects/empty.html.haml_spec.rb
+++ b/spec/views/projects/empty.html.haml_spec.rb
@@ -73,7 +73,7 @@ RSpec.describe 'projects/empty' do
expect(rendered).to have_content('Invite your team')
expect(rendered).to have_content('Add members to this project and start collaborating with your team.')
expect(rendered).to have_selector('.js-invite-members-trigger')
- expect(rendered).to have_selector('[data-trigger-source=project-empty-page]')
+ expect(rendered).to have_selector('[data-trigger-source=project_empty_page]')
end
context 'when user does not have permissions to invite members' do