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>2022-03-01 18:22:06 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2022-03-01 18:22:06 +0300
commit2ccb5c91c82c780c905ee77da144f17825610487 (patch)
tree92fd3f6a2638474bc0725714a31da365fd80a301
parentfbc7e1f503da80d993b970a74637a1edf53f7ab6 (diff)
Add latest changes from gitlab-org/gitlab@master
-rw-r--r--.gitlab/ci/reports.gitlab-ci.yml5
-rw-r--r--app/assets/javascripts/deploy_tokens/components/revoke_button.vue6
-rw-r--r--app/assets/javascripts/deploy_tokens/init_revoke_button.js3
-rw-r--r--app/assets/javascripts/integrations/edit/components/jira_issues_fields.vue6
-rw-r--r--app/assets/javascripts/integrations/edit/components/jira_trigger_fields.vue2
-rw-r--r--app/assets/javascripts/invite_members/components/invite_modal_base.vue2
-rw-r--r--app/assets/javascripts/issues/show/components/header_actions.vue12
-rw-r--r--app/assets/javascripts/merge_conflicts/merge_conflict_resolver_app.vue7
-rw-r--r--app/assets/javascripts/pipeline_editor/pipeline_editor_app.vue25
-rw-r--r--app/assets/javascripts/runner/admin_runner_edit/admin_runner_edit_app.vue4
-rw-r--r--app/assets/javascripts/runner/admin_runner_show/admin_runner_show_app.vue4
-rw-r--r--app/assets/javascripts/runner/admin_runners/admin_runners_app.vue8
-rw-r--r--app/assets/javascripts/runner/components/registration/registration_token_reset_dropdown_item.vue2
-rw-r--r--app/assets/javascripts/runner/components/runner_delete_button.vue2
-rw-r--r--app/assets/javascripts/runner/components/runner_jobs.vue4
-rw-r--r--app/assets/javascripts/runner/components/runner_pause_button.vue2
-rw-r--r--app/assets/javascripts/runner/components/runner_projects.vue4
-rw-r--r--app/assets/javascripts/runner/components/runner_update_form.vue2
-rw-r--r--app/assets/javascripts/runner/graphql/details/runner.query.graphql (renamed from app/assets/javascripts/runner/graphql/get_runner.query.graphql)3
-rw-r--r--app/assets/javascripts/runner/graphql/details/runner_details.fragment.graphql (renamed from app/assets/javascripts/runner/graphql/runner_details.fragment.graphql)0
-rw-r--r--app/assets/javascripts/runner/graphql/details/runner_details_shared.fragment.graphql (renamed from app/assets/javascripts/runner/graphql/runner_details_shared.fragment.graphql)3
-rw-r--r--app/assets/javascripts/runner/graphql/details/runner_jobs.query.graphql (renamed from app/assets/javascripts/runner/graphql/get_runner_jobs.query.graphql)0
-rw-r--r--app/assets/javascripts/runner/graphql/details/runner_projects.query.graphql (renamed from app/assets/javascripts/runner/graphql/get_runner_projects.query.graphql)0
-rw-r--r--app/assets/javascripts/runner/graphql/details/runner_update.mutation.graphql (renamed from app/assets/javascripts/runner/graphql/runner_update.mutation.graphql)2
-rw-r--r--app/assets/javascripts/runner/graphql/list/admin_runners.query.graphql (renamed from app/assets/javascripts/runner/graphql/get_runners.query.graphql)4
-rw-r--r--app/assets/javascripts/runner/graphql/list/admin_runners_count.query.graphql (renamed from app/assets/javascripts/runner/graphql/get_runners_count.query.graphql)0
-rw-r--r--app/assets/javascripts/runner/graphql/list/group_runners.query.graphql (renamed from app/assets/javascripts/runner/graphql/get_group_runners.query.graphql)5
-rw-r--r--app/assets/javascripts/runner/graphql/list/group_runners_count.query.graphql (renamed from app/assets/javascripts/runner/graphql/get_group_runners_count.query.graphql)0
-rw-r--r--app/assets/javascripts/runner/graphql/list/list_item.fragment.graphql (renamed from app/assets/javascripts/runner/graphql/runner_node.fragment.graphql)2
-rw-r--r--app/assets/javascripts/runner/graphql/list/runners_registration_token_reset.mutation.graphql (renamed from app/assets/javascripts/runner/graphql/runners_registration_token_reset.mutation.graphql)0
-rw-r--r--app/assets/javascripts/runner/graphql/shared/runner_delete.mutation.graphql (renamed from app/assets/javascripts/runner/graphql/runner_delete.mutation.graphql)0
-rw-r--r--app/assets/javascripts/runner/graphql/shared/runner_toggle_active.mutation.graphql (renamed from app/assets/javascripts/runner/graphql/runner_toggle_active.mutation.graphql)0
-rw-r--r--app/assets/javascripts/runner/group_runners/group_runners_app.vue8
-rw-r--r--app/controllers/projects/cluster_agents_controller.rb4
-rw-r--r--app/experiments/application_experiment.rb14
-rw-r--r--app/helpers/deploy_tokens_helper.rb7
-rw-r--r--app/models/integrations/jira.rb4
-rw-r--r--app/models/namespace/traversal_hierarchy.rb7
-rw-r--r--app/models/namespaces/traversal/linear.rb9
-rw-r--r--app/views/admin/application_settings/_eks.html.haml8
-rw-r--r--app/views/admin/application_settings/_sourcegraph.html.haml6
-rw-r--r--app/views/groups/group_members/index.html.haml2
-rw-r--r--app/views/projects/project_members/index.html.haml2
-rw-r--r--app/views/shared/deploy_tokens/_table.html.haml2
-rw-r--r--config/feature_flags/development/cluster_vulnerabilities.yml8
-rw-r--r--config/feature_flags/development/for_no_key_update_lock.yml8
-rw-r--r--config/feature_flags/development/sync_traversal_ids_before_commit.yml8
-rw-r--r--doc/development/experiment_guide/gitlab_experiment.md2
-rw-r--r--doc/integration/jira/configure.md2
-rw-r--r--doc/user/application_security/vulnerabilities/index.md2
-rw-r--r--doc/user/clusters/agent/vulnerabilities.md2
-rw-r--r--doc/user/markdown.md72
-rw-r--r--doc/user/search/index.md9
-rw-r--r--doc/user/snippets.md6
-rw-r--r--locale/gitlab.pot55
-rwxr-xr-xscripts/ingest-reports-to-siem38
-rw-r--r--spec/experiments/application_experiment_spec.rb60
-rw-r--r--spec/features/incidents/user_views_incident_spec.rb6
-rw-r--r--spec/frontend/deploy_tokens/components/revoke_button_spec.js5
-rw-r--r--spec/frontend/fixtures/runner.rb48
-rw-r--r--spec/frontend/issues/show/components/header_actions_spec.js45
-rw-r--r--spec/frontend/merge_conflicts/components/merge_conflict_resolver_app_spec.js33
-rw-r--r--spec/frontend/pipeline_editor/pipeline_editor_app_spec.js86
-rw-r--r--spec/frontend/runner/admin_runner_edit/admin_runner_edit_app_spec.js4
-rw-r--r--spec/frontend/runner/admin_runner_show/admin_runner_show_app_spec.js4
-rw-r--r--spec/frontend/runner/admin_runners/admin_runners_app_spec.js8
-rw-r--r--spec/frontend/runner/components/registration/registration_token_reset_dropdown_item_spec.js2
-rw-r--r--spec/frontend/runner/components/runner_delete_button_spec.js2
-rw-r--r--spec/frontend/runner/components/runner_jobs_spec.js4
-rw-r--r--spec/frontend/runner/components/runner_pause_button_spec.js2
-rw-r--r--spec/frontend/runner/components/runner_projects_spec.js4
-rw-r--r--spec/frontend/runner/components/runner_update_form_spec.js2
-rw-r--r--spec/frontend/runner/group_runners/group_runners_app_spec.js4
-rw-r--r--spec/frontend/runner/mock_data.js24
-rw-r--r--spec/helpers/deploy_tokens_helper_spec.rb20
-rw-r--r--spec/lib/gitlab/database/rename_reserved_paths_migration/v1/rename_projects_spec.rb2
-rw-r--r--spec/models/group_spec.rb20
-rw-r--r--spec/models/namespace/traversal_hierarchy_spec.rb15
-rw-r--r--spec/models/namespace_spec.rb12
-rw-r--r--spec/models/project_spec.rb12
-rw-r--r--spec/services/groups/create_service_spec.rb20
-rw-r--r--spec/services/projects/create_service_spec.rb12
-rw-r--r--spec/simplecov_env.rb1
-rw-r--r--spec/support/shared_examples/row_lock_shared_examples.rb4
-rw-r--r--spec/views/admin/application_settings/_eks.html.haml_spec.rb4
-rw-r--r--spec/views/layouts/_published_experiments.html.haml_spec.rb32
86 files changed, 462 insertions, 439 deletions
diff --git a/.gitlab/ci/reports.gitlab-ci.yml b/.gitlab/ci/reports.gitlab-ci.yml
index b9d2e31191a..d040abfe902 100644
--- a/.gitlab/ci/reports.gitlab-ci.yml
+++ b/.gitlab/ci/reports.gitlab-ci.yml
@@ -121,6 +121,11 @@ yarn-audit-dependency_scanning:
- cd .. && tar -I "gzip --best" -cf gitlab.tgz gitlab/
script:
- DEBUG=* node /usr/src/app/cli.js analyze --format gitlab --manager ${PACKAGE_MANAGER} gitlab.tgz | tee ${CI_PROJECT_DIR}/gl-dependency-scanning-report.json
+ after_script:
+ - mkdir ~/.aws
+ - '[[ -z "${AWS_SIEM_REPORT_INGESTION_CREDENTIALS_FILE}" ]] || mv "${AWS_SIEM_REPORT_INGESTION_CREDENTIALS_FILE}" ~/.aws/credentials'
+ - npm install --no-save --ignore-scripts @aws-sdk/client-s3@3.49.0
+ - scripts/ingest-reports-to-siem
artifacts:
paths:
- gl-dependency-scanning-report.json
diff --git a/app/assets/javascripts/deploy_tokens/components/revoke_button.vue b/app/assets/javascripts/deploy_tokens/components/revoke_button.vue
index fdf8b7796bf..7879357a042 100644
--- a/app/assets/javascripts/deploy_tokens/components/revoke_button.vue
+++ b/app/assets/javascripts/deploy_tokens/components/revoke_button.vue
@@ -17,9 +17,6 @@ export default {
revokePath: {
default: '',
},
- buttonClass: {
- default: '',
- },
},
computed: {
modalId() {
@@ -38,10 +35,9 @@ export default {
<div>
<gl-button
v-gl-modal="modalId"
- :class="buttonClass"
category="primary"
variant="danger"
- class="float-right"
+ class="gl-float-right"
data-testid="revoke-button"
>{{ s__('DeployTokens|Revoke') }}</gl-button
>
diff --git a/app/assets/javascripts/deploy_tokens/init_revoke_button.js b/app/assets/javascripts/deploy_tokens/init_revoke_button.js
index 20187150a60..bc3f3c9ddf4 100644
--- a/app/assets/javascripts/deploy_tokens/init_revoke_button.js
+++ b/app/assets/javascripts/deploy_tokens/init_revoke_button.js
@@ -9,14 +9,13 @@ export default () => {
}
return containers.forEach((el) => {
- const { token, revokePath, buttonClass } = el.dataset;
+ const { token, revokePath } = el.dataset;
return new Vue({
el,
provide: {
token: JSON.parse(token),
revokePath,
- buttonClass,
},
render(h) {
return h(RevokeButton);
diff --git a/app/assets/javascripts/integrations/edit/components/jira_issues_fields.vue b/app/assets/javascripts/integrations/edit/components/jira_issues_fields.vue
index 7f2f7620a86..198cabfad81 100644
--- a/app/assets/javascripts/integrations/edit/components/jira_issues_fields.vue
+++ b/app/assets/javascripts/integrations/edit/components/jira_issues_fields.vue
@@ -83,17 +83,17 @@ export default {
i18n: {
sectionTitle: s__('JiraService|View Jira issues in GitLab'),
sectionDescription: s__(
- 'JiraService|Work on Jira issues without leaving GitLab. Adds a Jira menu to access your list of Jira issues and view any issue as read-only.',
+ 'JiraService|Work on Jira issues without leaving GitLab. Add a Jira menu to access a read-only list of your Jira issues.',
),
enableCheckboxLabel: s__('JiraService|Enable Jira issues'),
enableCheckboxHelp: s__(
- 'JiraService|Warning: All GitLab users that have access to this GitLab project are able to view all issues from the Jira project specified below.',
+ 'JiraService|Warning: All GitLab users with access to this GitLab project can view all issues from the Jira project you select.',
),
projectKeyLabel: s__('JiraService|Jira project key'),
projectKeyPlaceholder: s__('JiraService|For example, AB'),
requiredFieldFeedback: __('This field is required.'),
issueTrackerConflictWarning: s__(
- 'JiraService|Displaying Jira issues while leaving the GitLab issue functionality enabled might be confusing. Consider %{linkStart}disabling GitLab issues%{linkEnd} if they won’t otherwise be used.',
+ 'JiraService|Displaying Jira issues while leaving GitLab issues also enabled might be confusing. Consider %{linkStart}disabling GitLab issues%{linkEnd} if they won’t otherwise be used.',
),
},
};
diff --git a/app/assets/javascripts/integrations/edit/components/jira_trigger_fields.vue b/app/assets/javascripts/integrations/edit/components/jira_trigger_fields.vue
index df5946b814a..bb8d630fb0e 100644
--- a/app/assets/javascripts/integrations/edit/components/jira_trigger_fields.vue
+++ b/app/assets/javascripts/integrations/edit/components/jira_trigger_fields.vue
@@ -138,7 +138,7 @@ export default {
label-for="service[trigger]"
:description="
s__(
- 'Integrations|When you mention a Jira issue in a commit or merge request, GitLab creates a remote link and comment (if enabled).',
+ 'JiraService|When a Jira issue is mentioned in a commit or merge request, a remote link and comment (if enabled) will be created.',
)
"
>
diff --git a/app/assets/javascripts/invite_members/components/invite_modal_base.vue b/app/assets/javascripts/invite_members/components/invite_modal_base.vue
index fc00f5b9343..e92433e0ccf 100644
--- a/app/assets/javascripts/invite_members/components/invite_modal_base.vue
+++ b/app/assets/javascripts/invite_members/components/invite_modal_base.vue
@@ -264,7 +264,7 @@ export default {
<gl-button
:disabled="submitDisabled"
:loading="isLoading"
- variant="success"
+ variant="confirm"
data-qa-selector="invite_button"
data-testid="invite-button"
@click="submit"
diff --git a/app/assets/javascripts/issues/show/components/header_actions.vue b/app/assets/javascripts/issues/show/components/header_actions.vue
index 8ba08472ea0..78ec5071b59 100644
--- a/app/assets/javascripts/issues/show/components/header_actions.vue
+++ b/app/assets/javascripts/issues/show/components/header_actions.vue
@@ -135,6 +135,14 @@ export default {
const canReopen = this.isClosed && this.canReopenIssue;
return canClose || canReopen;
},
+ hasDesktopDropdown() {
+ return (
+ this.canCreateIssue || this.canPromoteToEpic || !this.isIssueAuthor || this.canReportSpam
+ );
+ },
+ hasMobileDropdown() {
+ return this.hasDesktopDropdown || this.showToggleIssueStateButton;
+ },
},
created() {
eventHub.$on('toggle.issuable.state', this.toggleIssueState);
@@ -223,10 +231,12 @@ export default {
<template>
<div class="detail-page-header-actions gl-display-flex">
<gl-dropdown
+ v-if="hasMobileDropdown"
class="gl-sm-display-none! w-100"
block
:text="dropdownText"
data-qa-selector="issue_actions_dropdown"
+ data-testid="mobile-dropdown"
:loading="isToggleStateButtonLoading"
>
<gl-dropdown-item
@@ -276,11 +286,13 @@ export default {
</gl-button>
<gl-dropdown
+ v-if="hasDesktopDropdown"
class="gl-display-none gl-sm-display-inline-flex! gl-ml-3"
icon="ellipsis_v"
category="tertiary"
:text="dropdownText"
:text-sr-only="true"
+ data-testid="desktop-dropdown"
no-caret
right
>
diff --git a/app/assets/javascripts/merge_conflicts/merge_conflict_resolver_app.vue b/app/assets/javascripts/merge_conflicts/merge_conflict_resolver_app.vue
index 5fcc778a714..fdcb99351a7 100644
--- a/app/assets/javascripts/merge_conflicts/merge_conflict_resolver_app.vue
+++ b/app/assets/javascripts/merge_conflicts/merge_conflict_resolver_app.vue
@@ -1,5 +1,5 @@
<script>
-import { GlSprintf, GlButton, GlButtonGroup } from '@gitlab/ui';
+import { GlSprintf, GlButton, GlButtonGroup, GlLoadingIcon } from '@gitlab/ui';
import { mapGetters, mapState, mapActions } from 'vuex';
import { __ } from '~/locale';
import FileIcon from '~/vue_shared/components/file_icon.vue';
@@ -23,6 +23,7 @@ export default {
GlButton,
GlButtonGroup,
GlSprintf,
+ GlLoadingIcon,
FileIcon,
DiffFileEditor,
InlineConflictLines,
@@ -72,9 +73,7 @@ export default {
</script>
<template>
<div id="conflicts">
- <div v-if="isLoading" class="loading">
- <div class="spinner spinner-md"></div>
- </div>
+ <gl-loading-icon v-if="isLoading" size="md" data-testid="loading-spinner" />
<div v-if="hasError" class="nothing-here-block">
{{ conflictsData.errorMessage }}
</div>
diff --git a/app/assets/javascripts/pipeline_editor/pipeline_editor_app.vue b/app/assets/javascripts/pipeline_editor/pipeline_editor_app.vue
index 1da50c55a68..a5436ca63cb 100644
--- a/app/assets/javascripts/pipeline_editor/pipeline_editor_app.vue
+++ b/app/assets/javascripts/pipeline_editor/pipeline_editor_app.vue
@@ -69,9 +69,10 @@ export default {
// If it's a brand new file, we don't want to fetch the content.
// Then when the user commits the first time, the query would run
// to get the initial file content, but we already have it in `lastCommitedContent`
- // so we skip the loading altogether.
- skip({ isNewCiConfigFile, lastCommittedContent }) {
- return isNewCiConfigFile || lastCommittedContent;
+ // so we skip the loading altogether. We also wait for the currentBranch
+ // to have been fetched
+ skip() {
+ return this.shouldSkipBlobContentQuery;
},
variables() {
return {
@@ -128,8 +129,8 @@ export default {
},
ciConfigData: {
query: getCiConfigData,
- skip({ currentCiFileContent }) {
- return !currentCiFileContent;
+ skip() {
+ return this.shouldSkipCiConfigQuery;
},
variables() {
return {
@@ -174,6 +175,9 @@ export default {
},
commitSha: {
query: getLatestCommitShaQuery,
+ skip({ currentBranch }) {
+ return !currentBranch;
+ },
variables() {
return {
projectPath: this.projectFullPath,
@@ -181,7 +185,7 @@ export default {
};
},
update(data) {
- const latestCommitSha = data.project?.repository?.tree?.lastCommit?.sha;
+ const latestCommitSha = data?.project?.repository?.tree?.lastCommit?.sha;
if (this.isFetchingCommitSha && latestCommitSha === this.commitSha) {
this.$apollo.queries.commitSha.startPolling(COMMIT_SHA_POLL_INTERVAL);
@@ -192,6 +196,9 @@ export default {
this.$apollo.queries.commitSha.stopPolling();
return latestCommitSha;
},
+ error() {
+ this.reportFailure(LOAD_FAILURE_UNKNOWN);
+ },
},
currentBranch: {
query: getCurrentBranch,
@@ -234,6 +241,12 @@ export default {
isEmpty() {
return this.currentCiFileContent === '';
},
+ shouldSkipBlobContentQuery() {
+ return this.isNewCiConfigFile || this.lastCommittedContent || !this.currentBranch;
+ },
+ shouldSkipCiConfigQuery() {
+ return !this.currentCiFileContent || !this.commitSha;
+ },
},
i18n: {
resetModal: {
diff --git a/app/assets/javascripts/runner/admin_runner_edit/admin_runner_edit_app.vue b/app/assets/javascripts/runner/admin_runner_edit/admin_runner_edit_app.vue
index 4d2ca9b0c58..c2db3b9facd 100644
--- a/app/assets/javascripts/runner/admin_runner_edit/admin_runner_edit_app.vue
+++ b/app/assets/javascripts/runner/admin_runner_edit/admin_runner_edit_app.vue
@@ -5,7 +5,7 @@ import { convertToGraphQLId } from '~/graphql_shared/utils';
import RunnerHeader from '../components/runner_header.vue';
import RunnerUpdateForm from '../components/runner_update_form.vue';
import { I18N_FETCH_ERROR } from '../constants';
-import getRunnerQuery from '../graphql/get_runner.query.graphql';
+import runnerQuery from '../graphql/details/runner.query.graphql';
import { captureException } from '../sentry_utils';
export default {
@@ -27,7 +27,7 @@ export default {
},
apollo: {
runner: {
- query: getRunnerQuery,
+ query: runnerQuery,
variables() {
return {
id: convertToGraphQLId(TYPE_CI_RUNNER, this.runnerId),
diff --git a/app/assets/javascripts/runner/admin_runner_show/admin_runner_show_app.vue b/app/assets/javascripts/runner/admin_runner_show/admin_runner_show_app.vue
index 2795ddbbbcb..86ad912f017 100644
--- a/app/assets/javascripts/runner/admin_runner_show/admin_runner_show_app.vue
+++ b/app/assets/javascripts/runner/admin_runner_show/admin_runner_show_app.vue
@@ -8,7 +8,7 @@ import RunnerPauseButton from '../components/runner_pause_button.vue';
import RunnerHeader from '../components/runner_header.vue';
import RunnerDetails from '../components/runner_details.vue';
import { I18N_FETCH_ERROR } from '../constants';
-import getRunnerQuery from '../graphql/get_runner.query.graphql';
+import runnerQuery from '../graphql/details/runner.query.graphql';
import { captureException } from '../sentry_utils';
export default {
@@ -35,7 +35,7 @@ export default {
},
apollo: {
runner: {
- query: getRunnerQuery,
+ query: runnerQuery,
variables() {
return {
id: convertToGraphQLId(TYPE_CI_RUNNER, this.runnerId),
diff --git a/app/assets/javascripts/runner/admin_runners/admin_runners_app.vue b/app/assets/javascripts/runner/admin_runners/admin_runners_app.vue
index 3ce9a890b37..5e487ee5c52 100644
--- a/app/assets/javascripts/runner/admin_runners/admin_runners_app.vue
+++ b/app/assets/javascripts/runner/admin_runners/admin_runners_app.vue
@@ -26,8 +26,8 @@ import {
STATUS_STALE,
I18N_FETCH_ERROR,
} from '../constants';
-import getRunnersQuery from '../graphql/get_runners.query.graphql';
-import getRunnersCountQuery from '../graphql/get_runners_count.query.graphql';
+import runnersAdminQuery from '../graphql/list/admin_runners.query.graphql';
+import runnersAdminCountQuery from '../graphql/list/admin_runners_count.query.graphql';
import {
fromUrlQueryToSearch,
fromSearchToUrl,
@@ -36,7 +36,7 @@ import {
import { captureException } from '../sentry_utils';
const runnersCountSmartQuery = {
- query: getRunnersCountQuery,
+ query: runnersAdminCountQuery,
fetchPolicy: fetchPolicies.CACHE_AND_NETWORK,
update(data) {
return data?.runners?.count;
@@ -77,7 +77,7 @@ export default {
},
apollo: {
runners: {
- query: getRunnersQuery,
+ query: runnersAdminQuery,
// Runners can be updated by users directly in this list.
// A "cache and network" policy prevents outdated filtered
// results.
diff --git a/app/assets/javascripts/runner/components/registration/registration_token_reset_dropdown_item.vue b/app/assets/javascripts/runner/components/registration/registration_token_reset_dropdown_item.vue
index e65d30afee1..1234054c660 100644
--- a/app/assets/javascripts/runner/components/registration/registration_token_reset_dropdown_item.vue
+++ b/app/assets/javascripts/runner/components/registration/registration_token_reset_dropdown_item.vue
@@ -4,7 +4,7 @@ import { createAlert } from '~/flash';
import { TYPE_GROUP, TYPE_PROJECT } from '~/graphql_shared/constants';
import { convertToGraphQLId } from '~/graphql_shared/utils';
import { __, s__ } from '~/locale';
-import runnersRegistrationTokenResetMutation from '~/runner/graphql/runners_registration_token_reset.mutation.graphql';
+import runnersRegistrationTokenResetMutation from '~/runner/graphql/list/runners_registration_token_reset.mutation.graphql';
import { captureException } from '~/runner/sentry_utils';
import { INSTANCE_TYPE, GROUP_TYPE, PROJECT_TYPE } from '../../constants';
diff --git a/app/assets/javascripts/runner/components/runner_delete_button.vue b/app/assets/javascripts/runner/components/runner_delete_button.vue
index 4a508c64214..cf71a4705ca 100644
--- a/app/assets/javascripts/runner/components/runner_delete_button.vue
+++ b/app/assets/javascripts/runner/components/runner_delete_button.vue
@@ -1,6 +1,6 @@
<script>
import { GlButton, GlModalDirective, GlTooltipDirective } from '@gitlab/ui';
-import runnerDeleteMutation from '~/runner/graphql/runner_delete.mutation.graphql';
+import runnerDeleteMutation from '~/runner/graphql/shared/runner_delete.mutation.graphql';
import { createAlert } from '~/flash';
import { s__, sprintf } from '~/locale';
import { captureException } from '~/runner/sentry_utils';
diff --git a/app/assets/javascripts/runner/components/runner_jobs.vue b/app/assets/javascripts/runner/components/runner_jobs.vue
index f9804ed815a..eb77babcc57 100644
--- a/app/assets/javascripts/runner/components/runner_jobs.vue
+++ b/app/assets/javascripts/runner/components/runner_jobs.vue
@@ -1,7 +1,7 @@
<script>
import { GlSkeletonLoading } from '@gitlab/ui';
import { createAlert } from '~/flash';
-import getRunnerJobsQuery from '../graphql/get_runner_jobs.query.graphql';
+import runnerJobsQuery from '../graphql/details/runner_jobs.query.graphql';
import { I18N_FETCH_ERROR, I18N_NO_JOBS_FOUND, RUNNER_DETAILS_JOBS_PAGE_SIZE } from '../constants';
import { captureException } from '../sentry_utils';
import { getPaginationVariables } from '../utils';
@@ -34,7 +34,7 @@ export default {
},
apollo: {
jobs: {
- query: getRunnerJobsQuery,
+ query: runnerJobsQuery,
variables() {
return this.variables;
},
diff --git a/app/assets/javascripts/runner/components/runner_pause_button.vue b/app/assets/javascripts/runner/components/runner_pause_button.vue
index 3ea2006d17a..a1901c55e61 100644
--- a/app/assets/javascripts/runner/components/runner_pause_button.vue
+++ b/app/assets/javascripts/runner/components/runner_pause_button.vue
@@ -1,6 +1,6 @@
<script>
import { GlButton, GlTooltipDirective } from '@gitlab/ui';
-import runnerToggleActiveMutation from '~/runner/graphql/runner_toggle_active.mutation.graphql';
+import runnerToggleActiveMutation from '~/runner/graphql/shared/runner_toggle_active.mutation.graphql';
import { createAlert } from '~/flash';
import { captureException } from '~/runner/sentry_utils';
import { I18N_PAUSE, I18N_RESUME } from '../constants';
diff --git a/app/assets/javascripts/runner/components/runner_projects.vue b/app/assets/javascripts/runner/components/runner_projects.vue
index 2040b39e948..f8ec29b8a24 100644
--- a/app/assets/javascripts/runner/components/runner_projects.vue
+++ b/app/assets/javascripts/runner/components/runner_projects.vue
@@ -2,7 +2,7 @@
import { GlSkeletonLoading } from '@gitlab/ui';
import { sprintf, formatNumber } from '~/locale';
import { createAlert } from '~/flash';
-import getRunnerProjectsQuery from '../graphql/get_runner_projects.query.graphql';
+import runnerProjectsQuery from '../graphql/details/runner_projects.query.graphql';
import {
I18N_ASSIGNED_PROJECTS,
I18N_NONE,
@@ -41,7 +41,7 @@ export default {
},
apollo: {
projects: {
- query: getRunnerProjectsQuery,
+ query: runnerProjectsQuery,
variables() {
return this.variables;
},
diff --git a/app/assets/javascripts/runner/components/runner_update_form.vue b/app/assets/javascripts/runner/components/runner_update_form.vue
index abff3e59407..e44450a2a8d 100644
--- a/app/assets/javascripts/runner/components/runner_update_form.vue
+++ b/app/assets/javascripts/runner/components/runner_update_form.vue
@@ -15,7 +15,7 @@ import { createAlert, VARIANT_SUCCESS } from '~/flash';
import { __ } from '~/locale';
import { captureException } from '~/runner/sentry_utils';
import { ACCESS_LEVEL_NOT_PROTECTED, ACCESS_LEVEL_REF_PROTECTED, PROJECT_TYPE } from '../constants';
-import runnerUpdateMutation from '../graphql/runner_update.mutation.graphql';
+import runnerUpdateMutation from '../graphql/details/runner_update.mutation.graphql';
export default {
name: 'RunnerUpdateForm',
diff --git a/app/assets/javascripts/runner/graphql/get_runner.query.graphql b/app/assets/javascripts/runner/graphql/details/runner.query.graphql
index f6ce8281c64..4792a186160 100644
--- a/app/assets/javascripts/runner/graphql/get_runner.query.graphql
+++ b/app/assets/javascripts/runner/graphql/details/runner.query.graphql
@@ -1,10 +1,9 @@
-#import "ee_else_ce/runner/graphql/runner_details.fragment.graphql"
+#import "ee_else_ce/runner/graphql/details/runner_details.fragment.graphql"
query getRunner($id: CiRunnerID!) {
# We have an id in deeply nested fragment
# eslint-disable-next-line @graphql-eslint/require-id-when-available
runner(id: $id) {
- __typename
...RunnerDetails
}
}
diff --git a/app/assets/javascripts/runner/graphql/runner_details.fragment.graphql b/app/assets/javascripts/runner/graphql/details/runner_details.fragment.graphql
index 2449ee0fc0f..2449ee0fc0f 100644
--- a/app/assets/javascripts/runner/graphql/runner_details.fragment.graphql
+++ b/app/assets/javascripts/runner/graphql/details/runner_details.fragment.graphql
diff --git a/app/assets/javascripts/runner/graphql/runner_details_shared.fragment.graphql b/app/assets/javascripts/runner/graphql/details/runner_details_shared.fragment.graphql
index 74760bbaa07..d8c67728fac 100644
--- a/app/assets/javascripts/runner/graphql/runner_details_shared.fragment.graphql
+++ b/app/assets/javascripts/runner/graphql/details/runner_details_shared.fragment.graphql
@@ -1,4 +1,5 @@
fragment RunnerDetailsShared on CiRunner {
+ __typename
id
runnerType
active
@@ -22,7 +23,7 @@ fragment RunnerDetailsShared on CiRunner {
groups {
# Only a single group can be loaded here, while projects
# are loaded separately using the query with pagination
- # parameters `get_runner_projects.query.graphql`.
+ # parameters `runner_projects.query.graphql`.
nodes {
id
avatarUrl
diff --git a/app/assets/javascripts/runner/graphql/get_runner_jobs.query.graphql b/app/assets/javascripts/runner/graphql/details/runner_jobs.query.graphql
index 2b1decd3ddd..2b1decd3ddd 100644
--- a/app/assets/javascripts/runner/graphql/get_runner_jobs.query.graphql
+++ b/app/assets/javascripts/runner/graphql/details/runner_jobs.query.graphql
diff --git a/app/assets/javascripts/runner/graphql/get_runner_projects.query.graphql b/app/assets/javascripts/runner/graphql/details/runner_projects.query.graphql
index f97237b8267..f97237b8267 100644
--- a/app/assets/javascripts/runner/graphql/get_runner_projects.query.graphql
+++ b/app/assets/javascripts/runner/graphql/details/runner_projects.query.graphql
diff --git a/app/assets/javascripts/runner/graphql/runner_update.mutation.graphql b/app/assets/javascripts/runner/graphql/details/runner_update.mutation.graphql
index 8d1b75828be..e4bf51e2c30 100644
--- a/app/assets/javascripts/runner/graphql/runner_update.mutation.graphql
+++ b/app/assets/javascripts/runner/graphql/details/runner_update.mutation.graphql
@@ -1,4 +1,4 @@
-#import "ee_else_ce/runner/graphql/runner_details.fragment.graphql"
+#import "ee_else_ce/runner/graphql/details/runner_details.fragment.graphql"
# Mutation for updates from the runner form, loads
# attributes shown in the runner details.
diff --git a/app/assets/javascripts/runner/graphql/get_runners.query.graphql b/app/assets/javascripts/runner/graphql/list/admin_runners.query.graphql
index ed03a8c34ae..8df4c2fc65c 100644
--- a/app/assets/javascripts/runner/graphql/get_runners.query.graphql
+++ b/app/assets/javascripts/runner/graphql/list/admin_runners.query.graphql
@@ -1,4 +1,4 @@
-#import "~/runner/graphql/runner_node.fragment.graphql"
+#import "~/runner/graphql/list/list_item.fragment.graphql"
#import "~/graphql_shared/fragments/pageInfo.fragment.graphql"
query getRunners(
@@ -24,7 +24,7 @@ query getRunners(
sort: $sort
) {
nodes {
- ...RunnerNode
+ ...ListItem
adminUrl
editAdminUrl
}
diff --git a/app/assets/javascripts/runner/graphql/get_runners_count.query.graphql b/app/assets/javascripts/runner/graphql/list/admin_runners_count.query.graphql
index 181a4495cae..181a4495cae 100644
--- a/app/assets/javascripts/runner/graphql/get_runners_count.query.graphql
+++ b/app/assets/javascripts/runner/graphql/list/admin_runners_count.query.graphql
diff --git a/app/assets/javascripts/runner/graphql/get_group_runners.query.graphql b/app/assets/javascripts/runner/graphql/list/group_runners.query.graphql
index f9c7b89fc01..b517f5e89a8 100644
--- a/app/assets/javascripts/runner/graphql/get_group_runners.query.graphql
+++ b/app/assets/javascripts/runner/graphql/list/group_runners.query.graphql
@@ -1,4 +1,4 @@
-#import "~/runner/graphql/runner_node.fragment.graphql"
+#import "~/runner/graphql/list/list_item.fragment.graphql"
#import "~/graphql_shared/fragments/pageInfo.fragment.graphql"
query getGroupRunners(
@@ -29,8 +29,7 @@ query getGroupRunners(
webUrl
editUrl
node {
- __typename
- ...RunnerNode
+ ...ListItem
}
}
pageInfo {
diff --git a/app/assets/javascripts/runner/graphql/get_group_runners_count.query.graphql b/app/assets/javascripts/runner/graphql/list/group_runners_count.query.graphql
index 554eb09e372..554eb09e372 100644
--- a/app/assets/javascripts/runner/graphql/get_group_runners_count.query.graphql
+++ b/app/assets/javascripts/runner/graphql/list/group_runners_count.query.graphql
diff --git a/app/assets/javascripts/runner/graphql/runner_node.fragment.graphql b/app/assets/javascripts/runner/graphql/list/list_item.fragment.graphql
index fbdef817f2f..620c18c5bc0 100644
--- a/app/assets/javascripts/runner/graphql/runner_node.fragment.graphql
+++ b/app/assets/javascripts/runner/graphql/list/list_item.fragment.graphql
@@ -1,4 +1,4 @@
-fragment RunnerNode on CiRunner {
+fragment ListItem on CiRunner {
__typename
id
description
diff --git a/app/assets/javascripts/runner/graphql/runners_registration_token_reset.mutation.graphql b/app/assets/javascripts/runner/graphql/list/runners_registration_token_reset.mutation.graphql
index 9c2797732ad..9c2797732ad 100644
--- a/app/assets/javascripts/runner/graphql/runners_registration_token_reset.mutation.graphql
+++ b/app/assets/javascripts/runner/graphql/list/runners_registration_token_reset.mutation.graphql
diff --git a/app/assets/javascripts/runner/graphql/runner_delete.mutation.graphql b/app/assets/javascripts/runner/graphql/shared/runner_delete.mutation.graphql
index d580ea2785e..d580ea2785e 100644
--- a/app/assets/javascripts/runner/graphql/runner_delete.mutation.graphql
+++ b/app/assets/javascripts/runner/graphql/shared/runner_delete.mutation.graphql
diff --git a/app/assets/javascripts/runner/graphql/runner_toggle_active.mutation.graphql b/app/assets/javascripts/runner/graphql/shared/runner_toggle_active.mutation.graphql
index 9b15570dbc0..9b15570dbc0 100644
--- a/app/assets/javascripts/runner/graphql/runner_toggle_active.mutation.graphql
+++ b/app/assets/javascripts/runner/graphql/shared/runner_toggle_active.mutation.graphql
diff --git a/app/assets/javascripts/runner/group_runners/group_runners_app.vue b/app/assets/javascripts/runner/group_runners/group_runners_app.vue
index ba33ead6f46..f6b631bd216 100644
--- a/app/assets/javascripts/runner/group_runners/group_runners_app.vue
+++ b/app/assets/javascripts/runner/group_runners/group_runners_app.vue
@@ -24,8 +24,8 @@ import {
STATUS_OFFLINE,
STATUS_STALE,
} from '../constants';
-import getGroupRunnersQuery from '../graphql/get_group_runners.query.graphql';
-import getGroupRunnersCountQuery from '../graphql/get_group_runners_count.query.graphql';
+import groupRunnersQuery from '../graphql/list/group_runners.query.graphql';
+import groupRunnersCountQuery from '../graphql/list/group_runners_count.query.graphql';
import {
fromUrlQueryToSearch,
fromSearchToUrl,
@@ -34,7 +34,7 @@ import {
import { captureException } from '../sentry_utils';
const runnersCountSmartQuery = {
- query: getGroupRunnersCountQuery,
+ query: groupRunnersCountQuery,
fetchPolicy: fetchPolicies.CACHE_AND_NETWORK,
update(data) {
return data?.group?.runners?.count;
@@ -84,7 +84,7 @@ export default {
},
apollo: {
runners: {
- query: getGroupRunnersQuery,
+ query: groupRunnersQuery,
// Runners can be updated by users directly in this list.
// A "cache and network" policy prevents outdated filtered
// results.
diff --git a/app/controllers/projects/cluster_agents_controller.rb b/app/controllers/projects/cluster_agents_controller.rb
index 84bb01ee266..282b9ef1fb7 100644
--- a/app/controllers/projects/cluster_agents_controller.rb
+++ b/app/controllers/projects/cluster_agents_controller.rb
@@ -3,10 +3,6 @@
class Projects::ClusterAgentsController < Projects::ApplicationController
before_action :authorize_can_read_cluster_agent!
- before_action do
- push_frontend_feature_flag(:cluster_vulnerabilities, project, default_enabled: :yaml)
- end
-
feature_category :kubernetes_management
def show
diff --git a/app/experiments/application_experiment.rb b/app/experiments/application_experiment.rb
index 15c7f3389c4..f74e7fe3b1d 100644
--- a/app/experiments/application_experiment.rb
+++ b/app/experiments/application_experiment.rb
@@ -3,20 +3,6 @@
class ApplicationExperiment < Gitlab::Experiment
control { nil } # provide a default control for anonymous experiments
- def publish(_result = nil)
- super
-
- publish_to_client
- end
-
- def publish_to_client
- return unless should_track?
-
- Gon.push({ experiment: { name => signature } }, true)
- rescue NoMethodError
- # means we're not in the request cycle, and can't add to Gon. Log a warning maybe?
- end
-
def publish_to_database
ActiveSupport::Deprecation.warn('publish_to_database is deprecated and should not be used for reporting anymore')
diff --git a/app/helpers/deploy_tokens_helper.rb b/app/helpers/deploy_tokens_helper.rb
index d6fbe0b6b45..560d2fcd29f 100644
--- a/app/helpers/deploy_tokens_helper.rb
+++ b/app/helpers/deploy_tokens_helper.rb
@@ -16,4 +16,11 @@ module DeployTokensHelper
Gitlab.config.packages.enabled &&
can?(current_user, :read_package, group_or_project)
end
+
+ def deploy_token_revoke_button_data(token:, group_or_project:)
+ {
+ token: token.to_json(only: [:id, :name]),
+ revoke_path: revoke_deploy_token_path(group_or_project, token)
+ }
+ end
end
diff --git a/app/models/integrations/jira.rb b/app/models/integrations/jira.rb
index 8266d113492..8fc0a3461f7 100644
--- a/app/models/integrations/jira.rb
+++ b/app/models/integrations/jira.rb
@@ -111,8 +111,8 @@ module Integrations
end
def help
- jira_doc_link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: help_page_url('integration/jira/index.html') }
- s_("JiraService|You must configure Jira before enabling this integration. For more details, read the %{jira_doc_link_start}Jira integration documentation%{link_end}.") % { jira_doc_link_start: jira_doc_link_start, link_end: '</a>'.html_safe }
+ jira_doc_link_start = '<a href="%{url}">'.html_safe % { url: help_page_url('integration/jira/index.html') }
+ s_("JiraService|You must configure Jira before enabling this integration. %{jira_doc_link_start}Learn more.%{link_end}") % { jira_doc_link_start: jira_doc_link_start, link_end: '</a>'.html_safe }
end
def title
diff --git a/app/models/namespace/traversal_hierarchy.rb b/app/models/namespace/traversal_hierarchy.rb
index 93193cc2022..d2de85b5dd4 100644
--- a/app/models/namespace/traversal_hierarchy.rb
+++ b/app/models/namespace/traversal_hierarchy.rb
@@ -40,12 +40,7 @@ class Namespace
SQL
Namespace.transaction do
- if Feature.enabled?(:for_no_key_update_lock, default_enabled: :yaml)
- @root.lock!("FOR NO KEY UPDATE")
- else
- @root.lock!
- end
-
+ @root.lock!("FOR NO KEY UPDATE")
Namespace.connection.exec_query(sql)
end
rescue ActiveRecord::Deadlocked
diff --git a/app/models/namespaces/traversal/linear.rb b/app/models/namespaces/traversal/linear.rb
index 99a5b8cb063..1963745cf4d 100644
--- a/app/models/namespaces/traversal/linear.rb
+++ b/app/models/namespaces/traversal/linear.rb
@@ -44,22 +44,15 @@ module Namespaces
included do
before_update :lock_both_roots, if: -> { sync_traversal_ids? && parent_id_changed? }
after_update :sync_traversal_ids, if: -> { sync_traversal_ids? && saved_change_to_parent_id? }
- # sync traversal_ids on namespace create, which can happen quite early within a transaction, thus keeping the lock on root namespace record
- # for a relatively long time, e.g. creating the project namespace when a project is being created.
- after_create :sync_traversal_ids, if: -> { sync_traversal_ids? && !sync_traversal_ids_before_commit? }
# This uses rails internal before_commit API to sync traversal_ids on namespace create, right before transaction is committed.
# This helps reduce the time during which the root namespace record is locked to ensure updated traversal_ids are valid
- before_commit :sync_traversal_ids, on: [:create], if: -> { sync_traversal_ids? && sync_traversal_ids_before_commit? }
+ before_commit :sync_traversal_ids, on: [:create], if: -> { sync_traversal_ids? }
end
def sync_traversal_ids?
Feature.enabled?(:sync_traversal_ids, root_ancestor, default_enabled: :yaml)
end
- def sync_traversal_ids_before_commit?
- Feature.enabled?(:sync_traversal_ids_before_commit, root_ancestor, default_enabled: :yaml)
- end
-
def use_traversal_ids?
return false unless Feature.enabled?(:use_traversal_ids, default_enabled: :yaml)
diff --git a/app/views/admin/application_settings/_eks.html.haml b/app/views/admin/application_settings/_eks.html.haml
index c83e28d7f0b..d9c0a01beb0 100644
--- a/app/views/admin/application_settings/_eks.html.haml
+++ b/app/views/admin/application_settings/_eks.html.haml
@@ -22,15 +22,15 @@
= f.label :eks_account_id, _('Account ID'), class: 'label-bold'
= f.text_field :eks_account_id, class: 'form-control gl-form-input'
.form-group
- = f.label :eks_access_key_id, _('Access key ID'), class: 'label-bold'
+ = f.label :eks_access_key_id, _('AWS access key ID (Optional)'), class: 'label-bold'
= f.text_field :eks_access_key_id, class: 'form-control gl-form-input'
.form-text.text-muted
- = _('AWS Access Key. Only required if not using role instance credentials')
+ = _('Only required if not using role instance credentials.')
.form-group
- = f.label :eks_secret_access_key, _('Secret access key'), class: 'label-bold'
+ = f.label :eks_secret_access_key, _('AWS secret access key (Optional)'), class: 'label-bold'
= f.password_field :eks_secret_access_key, autocomplete: 'off', class: 'form-control gl-form-input'
.form-text.text-muted
- = _('AWS Secret Access Key. Only required if not using role instance credentials')
+ = _('Only required if not using role instance credentials.')
= f.submit _('Save changes'), class: "gl-button btn btn-confirm"
diff --git a/app/views/admin/application_settings/_sourcegraph.html.haml b/app/views/admin/application_settings/_sourcegraph.html.haml
index b92cf7b156a..65b2a95bcc1 100644
--- a/app/views/admin/application_settings/_sourcegraph.html.haml
+++ b/app/views/admin/application_settings/_sourcegraph.html.haml
@@ -12,7 +12,7 @@
- link_end = "#{sprite_icon('external-link', size: 12, css_class: 'ml-1 vertical-align-center')}</a>".html_safe
= s_('SourcegraphAdmin|Enable code intelligence powered by %{link_start}Sourcegraph%{link_end} on your GitLab instance\'s code views and merge requests.').html_safe % { link_start: link_start, link_end: link_end }
%span
- = link_to s_('SourcegraphAdmin|More information'), help_page_path('integration/sourcegraph.md'), target: '_blank', rel: 'noopener noreferrer'
+ = link_to s_('SourcegraphAdmin|Learn more.'), help_page_path('integration/sourcegraph.md'), target: '_blank', rel: 'noopener noreferrer'
.settings-content
@@ -29,10 +29,10 @@
= f.check_box :sourcegraph_public_only, class: 'form-check-input'
= f.label :sourcegraph_public_only, s_('SourcegraphAdmin|Block on private and internal projects'), class: 'form-check-label'
.form-text.text-muted
- = s_('SourcegraphAdmin|If checked, only public projects will have code intelligence and communicate with Sourcegraph.')
+ = s_('SourcegraphAdmin|Only public projects have code intelligence enabled and communicate with Sourcegraph.')
.form-group
= f.label :sourcegraph_url, s_('SourcegraphAdmin|Sourcegraph URL'), class: 'label-bold'
- = f.text_field :sourcegraph_url, class: 'form-control gl-form-input', placeholder: s_('SourcegraphAdmin|e.g. https://sourcegraph.example.com')
+ = f.text_field :sourcegraph_url, class: 'form-control gl-form-input', placeholder: s_('SourcegraphAdmin|https://sourcegraph.example.com')
.form-text.text-muted
= s_('SourcegraphAdmin|Configure the URL to a Sourcegraph instance which can read your GitLab projects.')
= f.submit s_('SourcegraphAdmin|Save changes'), class: 'gl-button btn btn-confirm'
diff --git a/app/views/groups/group_members/index.html.haml b/app/views/groups/group_members/index.html.haml
index d1f56a50907..dce1754a66d 100644
--- a/app/views/groups/group_members/index.html.haml
+++ b/app/views/groups/group_members/index.html.haml
@@ -15,7 +15,7 @@
.gl-w-half.gl-xs-w-full
.gl-display-flex.gl-flex-wrap.gl-justify-content-end.gl-mb-3
.js-invite-group-trigger{ data: { classes: 'gl-mt-3 gl-sm-w-auto gl-w-full', display_text: _('Invite a group') } }
- .js-invite-members-trigger{ data: { variant: 'success',
+ .js-invite-members-trigger{ data: { variant: 'confirm',
classes: 'gl-mt-3 gl-sm-w-auto gl-w-full gl-sm-ml-3',
trigger_source: 'group-members-page',
display_text: _('Invite members') } }
diff --git a/app/views/projects/project_members/index.html.haml b/app/views/projects/project_members/index.html.haml
index 220e44679cd..ef83c512e8d 100644
--- a/app/views/projects/project_members/index.html.haml
+++ b/app/views/projects/project_members/index.html.haml
@@ -23,7 +23,7 @@
.js-invite-group-trigger{ data: { classes: 'gl-mt-3 gl-sm-w-auto gl-w-full gl-sm-ml-3', display_text: _('Invite a group') } }
= render 'projects/invite_groups_modal', project: @project
- if can_admin_project_member?(@project)
- .js-invite-members-trigger{ data: { variant: 'success',
+ .js-invite-members-trigger{ data: { variant: 'confirm',
classes: 'gl-mt-3 gl-sm-w-auto gl-w-full gl-sm-ml-3',
trigger_source: 'project-members-page',
display_text: _('Invite members') } }
diff --git a/app/views/shared/deploy_tokens/_table.html.haml b/app/views/shared/deploy_tokens/_table.html.haml
index db9c646b694..a7bf3bfb81e 100644
--- a/app/views/shared/deploy_tokens/_table.html.haml
+++ b/app/views/shared/deploy_tokens/_table.html.haml
@@ -25,7 +25,7 @@
%span.token-never-expires-label= _('Never')
%td= token.scopes.present? ? token.scopes.join(', ') : _('no scopes selected')
%td
- .js-deploy-token-revoke-button{ data: { button_class: 'float-right', token: token.to_json, revoke_path: revoke_deploy_token_path(group_or_project, token) } }
+ .js-deploy-token-revoke-button{ data: deploy_token_revoke_button_data(token: token, group_or_project: group_or_project) }
- else
.settings-message.text-center
diff --git a/config/feature_flags/development/cluster_vulnerabilities.yml b/config/feature_flags/development/cluster_vulnerabilities.yml
deleted file mode 100644
index 9d7f3228d66..00000000000
--- a/config/feature_flags/development/cluster_vulnerabilities.yml
+++ /dev/null
@@ -1,8 +0,0 @@
----
-name: cluster_vulnerabilities
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/73321
-rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/343917
-milestone: '14.5'
-type: development
-group: group::container security
-default_enabled: true
diff --git a/config/feature_flags/development/for_no_key_update_lock.yml b/config/feature_flags/development/for_no_key_update_lock.yml
deleted file mode 100644
index a4ff426e876..00000000000
--- a/config/feature_flags/development/for_no_key_update_lock.yml
+++ /dev/null
@@ -1,8 +0,0 @@
----
-name: for_no_key_update_lock
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/81239
-rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/353619
-milestone: '14.9'
-type: development
-group: group::workspaces
-default_enabled: false
diff --git a/config/feature_flags/development/sync_traversal_ids_before_commit.yml b/config/feature_flags/development/sync_traversal_ids_before_commit.yml
deleted file mode 100644
index f8f1e854fa5..00000000000
--- a/config/feature_flags/development/sync_traversal_ids_before_commit.yml
+++ /dev/null
@@ -1,8 +0,0 @@
----
-name: sync_traversal_ids_before_commit
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/79964
-rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/352499
-group: group::workspace
-type: development
-default_enabled: false
-milestone: '14.8'
diff --git a/doc/development/experiment_guide/gitlab_experiment.md b/doc/development/experiment_guide/gitlab_experiment.md
index 5359a6f21a3..78e1f84d701 100644
--- a/doc/development/experiment_guide/gitlab_experiment.md
+++ b/doc/development/experiment_guide/gitlab_experiment.md
@@ -317,7 +317,7 @@ of tracking an event in Ruby would be:
experiment(:pill_color, actor: current_user).track(:clicked)
```
-When you run an experiment with any of the examples so far, an `:assigned` event
+When you run an experiment with any of the examples so far, an `:assignment` event
is tracked automatically by default. All events that are tracked from an
experiment have a special
[experiment context](https://gitlab.com/gitlab-org/iglu/-/blob/master/public/schemas/com.gitlab/gitlab_experiment/jsonschema/1-0-3)
diff --git a/doc/integration/jira/configure.md b/doc/integration/jira/configure.md
index 979d8a52fb8..2033ddbad6f 100644
--- a/doc/integration/jira/configure.md
+++ b/doc/integration/jira/configure.md
@@ -50,7 +50,7 @@ To configure your project:
If you enable Jira issues with this setting, all users with access to this GitLab project
can view all issues from the specified Jira project.
-1. To enable [issue creation for vulnerabilities](../../user/application_security/vulnerabilities/index.md#create-a-jira-issue-for-a-vulnerability), select **Enable Jira issues creation from vulnerabilities**.
+1. To enable [issue creation for vulnerabilities](../../user/application_security/vulnerabilities/index.md#create-a-jira-issue-for-a-vulnerability), select **Enable Jira issue creation from vulnerabilities**.
1. Select the **Jira issue type**. If the dropdown is empty, select refresh (**{retry}**) and try again.
1. To verify the Jira connection is working, select **Test settings**.
1. Select **Save changes**.
diff --git a/doc/user/application_security/vulnerabilities/index.md b/doc/user/application_security/vulnerabilities/index.md
index 7b39002bac3..db8b3fe8126 100644
--- a/doc/user/application_security/vulnerabilities/index.md
+++ b/doc/user/application_security/vulnerabilities/index.md
@@ -80,7 +80,7 @@ The issue is then opened so you can take further action.
Prerequisites:
- [Enable Jira integration](../../../integration/jira/index.md).
- The **Enable Jira issues creation from vulnerabilities** option must be selected as part of the configuration.
+ The **Enable Jira issue creation from vulnerabilities** option must be selected as part of the configuration.
- Each user must have a personal Jira user account with permission to create issues in the target project.
To create a Jira issue for a vulnerability:
diff --git a/doc/user/clusters/agent/vulnerabilities.md b/doc/user/clusters/agent/vulnerabilities.md
index ef3fd800220..41a80f43467 100644
--- a/doc/user/clusters/agent/vulnerabilities.md
+++ b/doc/user/clusters/agent/vulnerabilities.md
@@ -6,7 +6,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
# Container vulnerability scanning **(ULTIMATE)**
-> [Introduced](https://gitlab.com/groups/gitlab-org/-/epics/6346) in GitLab 14.8 [with a flag](../../../administration/feature_flags.md) named `cluster_vulnerabilities`. Enabled by default.
+> [Introduced](https://gitlab.com/groups/gitlab-org/-/epics/6346) in GitLab 14.8.
To view cluster vulnerabilities, you can view the [vulnerability report](../../application_security/vulnerabilities/index.md).
You can also configure your agent so the vulnerabilities are displayed with other agent information in GitLab.
diff --git a/doc/user/markdown.md b/doc/user/markdown.md
index a16f8fd39b1..fa739843e3b 100644
--- a/doc/user/markdown.md
+++ b/doc/user/markdown.md
@@ -67,15 +67,15 @@ Features not found in standard Markdown:
Features [extended from standard Markdown](#features-extended-from-standard-markdown):
-| Standard Markdown | Extended Markdown in GitLab |
-| ------------------------------------- | ------------------------- |
-| [blockquotes](#blockquotes) | [multi-line blockquotes](#multiline-blockquote) |
-| [code blocks](#code-spans-and-blocks) | [colored code and syntax highlighting](#colored-code-and-syntax-highlighting) |
-| [emphasis](#emphasis) | [multiple underscores in words](#multiple-underscores-in-words-and-mid-word-emphasis)
-| [headers](#headers) | [linkable Header IDs](#header-ids-and-links) |
-| [images](#images) | [embedded videos](#videos) and [audio](#audio) |
-| [line breaks](#line-breaks) | [more line break control](#newlines) |
-| [links](#links) | [automatically linking URLs](#url-auto-linking) |
+| Standard Markdown | Extended Markdown in GitLab |
+|---------------------------------------|---------------------------------------------------------------------------------------|
+| [blockquotes](#blockquotes) | [multi-line blockquotes](#multiline-blockquote) |
+| [code blocks](#code-spans-and-blocks) | [colored code and syntax highlighting](#colored-code-and-syntax-highlighting) |
+| [emphasis](#emphasis) | [multiple underscores in words](#multiple-underscores-in-words-and-mid-word-emphasis) |
+| [headers](#headers) | [linkable Header IDs](#header-ids-and-links) |
+| [images](#images) | [embedded videos](#videos) and [audio](#audio) |
+| [line breaks](#line-breaks) | [more line break control](#newlines) |
+| [links](#links) | [automatically linking URLs](#url-auto-linking) |
## Features not found in standard Markdown
@@ -262,7 +262,7 @@ The following delimiters are supported:
---
title: About Front Matter
example:
- language: yaml
+ language: yaml
---
```
@@ -515,31 +515,31 @@ version to reference other projects from the same namespace.
GitLab Flavored Markdown recognizes the following:
-| references | input | cross-project reference | shortcut inside same namespace |
-| :--------------------------------------------------- | :---------------------------- | :----------------------------------------- | :------------------------------- |
-| specific user | `@user_name` | | |
-| specific group | `@group_name` | | |
-| entire team | `@all` | | |
-| project | `namespace/project>` | | |
-| issue | ``#123`` | `namespace/project#123` | `project#123` |
-| merge request | `!123` | `namespace/project!123` | `project!123` |
-| snippet | `$123` | `namespace/project$123` | `project$123` |
-| [epic](group/epics/index.md) | `&123` | `group1/subgroup&123` | |
-| vulnerability **(ULTIMATE)** <sup>1</sup> | `[vulnerability:123]` | `[vulnerability:namespace/project/123]` | `[vulnerability:project/123]` |
-| feature flag | `[feature_flag:123]` | `[feature_flag:namespace/project/123]` | `[feature_flag:project/123]` |
-| label by ID | `~123` | `namespace/project~123` | `project~123` |
-| one-word label by name | `~bug` | `namespace/project~bug` | `project~bug` |
-| multi-word label by name | `~"feature request"` | `namespace/project~"feature request"` | `project~"feature request"` |
-| scoped label by name | `~"priority::high"` | `namespace/project~"priority::high"` | `project~"priority::high"` |
-| project milestone by ID | `%123` | `namespace/project%123` | `project%123` |
-| one-word milestone by name | `%v1.23` | `namespace/project%v1.23` | `project%v1.23` |
-| multi-word milestone by name | `%"release candidate"` | `namespace/project%"release candidate"` | `project%"release candidate"` |
-| specific commit | `9ba12248` | `namespace/project@9ba12248` | `project@9ba12248` |
-| commit range comparison | `9ba12248...b19a04f5` | `namespace/project@9ba12248...b19a04f5` | `project@9ba12248...b19a04f5` |
-| repository file references | `[README](doc/README.md)` | | |
-| repository file line references | `[README](doc/README.md#L13)` | | |
-| [alert](../operations/incident_management/alerts.md) | `^alert#123` | `namespace/project^alert#123` | `project^alert#123` |
-| contact | `[contact:test@example.com]` | | |
+| references | input | cross-project reference | shortcut inside same namespace |
+|:----------------------------------------------------------------------------|:------------------------------|:----------------------------------------|:-------------------------------|
+| specific user | `@user_name` | | |
+| specific group | `@group_name` | | |
+| entire team | `@all` | | |
+| project | `namespace/project>` | | |
+| issue | ``#123`` | `namespace/project#123` | `project#123` |
+| merge request | `!123` | `namespace/project!123` | `project!123` |
+| snippet | `$123` | `namespace/project$123` | `project$123` |
+| [epic](group/epics/index.md) | `&123` | `group1/subgroup&123` | |
+| [vulnerability](application_security/vulnerabilities/index.md) <sup>1</sup> | `[vulnerability:123]` | `[vulnerability:namespace/project/123]` | `[vulnerability:project/123]` |
+| feature flag | `[feature_flag:123]` | `[feature_flag:namespace/project/123]` | `[feature_flag:project/123]` |
+| label by ID | `~123` | `namespace/project~123` | `project~123` |
+| one-word label by name | `~bug` | `namespace/project~bug` | `project~bug` |
+| multi-word label by name | `~"feature request"` | `namespace/project~"feature request"` | `project~"feature request"` |
+| scoped label by name | `~"priority::high"` | `namespace/project~"priority::high"` | `project~"priority::high"` |
+| project milestone by ID | `%123` | `namespace/project%123` | `project%123` |
+| one-word milestone by name | `%v1.23` | `namespace/project%v1.23` | `project%v1.23` |
+| multi-word milestone by name | `%"release candidate"` | `namespace/project%"release candidate"` | `project%"release candidate"` |
+| specific commit | `9ba12248` | `namespace/project@9ba12248` | `project@9ba12248` |
+| commit range comparison | `9ba12248...b19a04f5` | `namespace/project@9ba12248...b19a04f5` | `project@9ba12248...b19a04f5` |
+| repository file references | `[README](doc/README.md)` | | |
+| repository file line references | `[README](doc/README.md#L13)` | | |
+| [alert](../operations/incident_management/alerts.md) | `^alert#123` | `namespace/project^alert#123` | `project^alert#123` |
+| contact | `[contact:test@example.com]` | | |
1. [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/222483) in GitLab 13.7.
@@ -1486,7 +1486,7 @@ but they do not render properly on `docs.gitlab.com`:
#### Copy from spreadsheet and paste in Markdown
-[Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/27205) in GitLab 12.7.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/27205) in GitLab 12.7.
If you're working in spreadsheet software (for example, Microsoft Excel, Google
Sheets, or Apple Numbers), GitLab creates a Markdown table when you copy-and-paste
diff --git a/doc/user/search/index.md b/doc/user/search/index.md
index f96ca746474..e57f9260f2c 100644
--- a/doc/user/search/index.md
+++ b/doc/user/search/index.md
@@ -34,7 +34,8 @@ in the search field in the upper right corner:
> - Filtering by epics was [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/195704) in GitLab 12.9.
> - Filtering by child epics was [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/9029) in GitLab 13.0.
-> - Filtering by iterations was [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/118742) in GitLab 13.6. Moved from GitLab Ultimate to Premium in 13.9.
+> - Filtering by iterations was [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/118742) in GitLab 13.6.
+> - Filtering by iterations was moved from GitLab Ultimate to GitLab Premium in 13.9.
> - Filtering by type was [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/322755) in GitLab 13.10 [with a flag](../../administration/feature_flags.md) named `vue_issues_list`. Disabled by default.
Follow these steps to filter the **Issues** and **Merge requests** list pages in projects and
@@ -127,14 +128,14 @@ the dropdown list) **Approved-By** and select the user.
![Filter MRs by approved by](img/filter_approved_by_merge_requests_v14_6.png)
-### Filtering merge requests by reviewer **(FREE)**
+### Filtering merge requests by reviewer
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/47605) in GitLab 13.7.
To filter review requested merge requests for a specific individual, you can type (or select from
the dropdown list) **Reviewer** and select the user.
-### Filtering merge requests by environment or deployment date **(FREE)**
+### Filtering merge requests by environment or deployment date
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/44041) in GitLab 13.6.
@@ -307,7 +308,7 @@ GitLab instance.
## Search settings
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/292941) in GitLab 13.8 [with a flag](../../administration/feature_flags.md) named `search_settings_in_page`. Disabled by default.
-> - [Added to Group, Administrator, and User settings](https://gitlab.com/groups/gitlab-org/-/epics/4842) in GitLab 13.9.
+> - [Added](https://gitlab.com/groups/gitlab-org/-/epics/4842) to Group, Administrator, and User settings in GitLab 13.9.
> - [Feature flag `search_settings_in_page` removed](https://gitlab.com/gitlab-org/gitlab/-/issues/294025) in GitLab 13.11.
> - [Generally available](https://gitlab.com/gitlab-org/gitlab/-/issues/294025) in GitLab 13.11.
diff --git a/doc/user/snippets.md b/doc/user/snippets.md
index fc6ae11c724..1750e2c8d10 100644
--- a/doc/user/snippets.md
+++ b/doc/user/snippets.md
@@ -37,8 +37,7 @@ You can create snippets in multiple ways, depending on whether you want to creat
**New snippet**, or:
- *If you're on a project's page,* select the plus icon (**{plus-square-o}**)
in the top navigation bar, and then select **New snippet** from the
- **GitLab** (GitLab SaaS) or **Your Instance** (self-managed) section
- of the same dropdown list.
+ **GitLab** section of the same dropdown list.
- *For all other pages,* select the plus icon (**{plus-square-o}**)
in the top navigation bar, then select **New snippet** from the dropdown list.
- If you installed the [GitLab Workflow VS Code extension](project/repository/vscode.md),
@@ -153,8 +152,7 @@ To delete a file from your snippet through the GitLab UI:
1. Go to your snippet in the GitLab UI.
1. Select **Edit** in the top right corner.
-1. Select **Delete file** alongside the filename of each file
-you wish to delete.
+1. Select **Delete file** alongside the filename of each file you wish to delete.
1. Select **Save changes**.
## Clone snippets
diff --git a/locale/gitlab.pot b/locale/gitlab.pot
index a2c12665fb0..7c7e919fa88 100644
--- a/locale/gitlab.pot
+++ b/locale/gitlab.pot
@@ -1773,13 +1773,13 @@ msgstr ""
msgid "AWS Access Key"
msgstr ""
-msgid "AWS Access Key. Only required if not using role instance credentials"
+msgid "AWS Secret Access Key"
msgstr ""
-msgid "AWS Secret Access Key"
+msgid "AWS access key ID (Optional)"
msgstr ""
-msgid "AWS Secret Access Key. Only required if not using role instance credentials"
+msgid "AWS secret access key (Optional)"
msgstr ""
msgid "AWS service error: %{error}"
@@ -1839,9 +1839,6 @@ msgstr ""
msgid "Access granted"
msgstr ""
-msgid "Access key ID"
-msgstr ""
-
msgid "Access requests"
msgstr ""
@@ -19864,9 +19861,6 @@ msgstr ""
msgid "Integrations|Use default settings"
msgstr ""
-msgid "Integrations|When you mention a Jira issue in a commit or merge request, GitLab creates a remote link and comment (if enabled)."
-msgstr ""
-
msgid "Integrations|You can now close this window and return to the GitLab for Jira application."
msgstr ""
@@ -20830,13 +20824,13 @@ msgstr ""
msgid "JiraService|Define the type of Jira issue to create from a vulnerability."
msgstr ""
-msgid "JiraService|Displaying Jira issues while leaving the GitLab issue functionality enabled might be confusing. Consider %{linkStart}disabling GitLab issues%{linkEnd} if they won’t otherwise be used."
+msgid "JiraService|Displaying Jira issues while leaving GitLab issues also enabled might be confusing. Consider %{linkStart}disabling GitLab issues%{linkEnd} if they won’t otherwise be used."
msgstr ""
-msgid "JiraService|Enable Jira issues"
+msgid "JiraService|Enable Jira issue creation from vulnerabilities"
msgstr ""
-msgid "JiraService|Enable Jira issues creation from vulnerabilities"
+msgid "JiraService|Enable Jira issues"
msgstr ""
msgid "JiraService|Enable Jira transitions"
@@ -20953,16 +20947,19 @@ msgstr ""
msgid "JiraService|View Jira issues in GitLab"
msgstr ""
-msgid "JiraService|Warning: All GitLab users that have access to this GitLab project are able to view all issues from the Jira project specified below."
+msgid "JiraService|Warning: All GitLab users with access to this GitLab project can view all issues from the Jira project you select."
msgstr ""
msgid "JiraService|Web URL"
msgstr ""
-msgid "JiraService|Work on Jira issues without leaving GitLab. Adds a Jira menu to access your list of Jira issues and view any issue as read-only."
+msgid "JiraService|When a Jira issue is mentioned in a commit or merge request, a remote link and comment (if enabled) will be created."
+msgstr ""
+
+msgid "JiraService|Work on Jira issues without leaving GitLab. Add a Jira menu to access a read-only list of your Jira issues."
msgstr ""
-msgid "JiraService|You must configure Jira before enabling this integration. For more details, read the %{jira_doc_link_start}Jira integration documentation%{link_end}."
+msgid "JiraService|You must configure Jira before enabling this integration. %{jira_doc_link_start}Learn more.%{link_end}"
msgstr ""
msgid "Job"
@@ -25611,6 +25608,9 @@ msgstr ""
msgid "Only reCAPTCHA v2 is supported:"
msgstr ""
+msgid "Only required if not using role instance credentials."
+msgstr ""
+
msgid "Only use lowercase letters, numbers, and underscores."
msgstr ""
@@ -32290,9 +32290,6 @@ msgstr ""
msgid "Secret Detection"
msgstr ""
-msgid "Secret access key"
-msgstr ""
-
msgid "Secret token"
msgstr ""
@@ -32491,9 +32488,6 @@ msgstr ""
msgid "SecurityOrchestration|.yaml preview"
msgstr ""
-msgid "SecurityOrchestration|Action"
-msgstr ""
-
msgid "SecurityOrchestration|Actions"
msgstr ""
@@ -32536,9 +32530,6 @@ msgstr ""
msgid "SecurityOrchestration|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
msgstr ""
-msgid "SecurityOrchestration|Executes a %{scanType} scan"
-msgstr ""
-
msgid "SecurityOrchestration|If you are using Auto DevOps, your %{monospacedStart}auto-deploy-values.yaml%{monospacedEnd} file will not be updated if you change a policy in this section. Auto DevOps users should make changes by following the %{linkStart}Container Network Policy documentation%{linkEnd}."
msgstr ""
@@ -32554,6 +32545,9 @@ msgstr ""
msgid "SecurityOrchestration|New policy"
msgstr ""
+msgid "SecurityOrchestration|No actions defined - policy will not run."
+msgstr ""
+
msgid "SecurityOrchestration|No description"
msgstr ""
@@ -32596,10 +32590,13 @@ msgstr ""
msgid "SecurityOrchestration|Require %{approvals} %{plural} from %{approvers} if any of the following occur:"
msgstr ""
-msgid "SecurityOrchestration|Rule"
+msgid "SecurityOrchestration|Rules"
+msgstr ""
+
+msgid "SecurityOrchestration|Runs %{actions} and %{lastAction} scans"
msgstr ""
-msgid "SecurityOrchestration|Rules"
+msgid "SecurityOrchestration|Runs a %{action} scan"
msgstr ""
msgid "SecurityOrchestration|Scan Execution"
@@ -34688,10 +34685,10 @@ msgstr ""
msgid "SourcegraphAdmin|Enable code intelligence powered by %{link_start}Sourcegraph%{link_end} on your GitLab instance's code views and merge requests."
msgstr ""
-msgid "SourcegraphAdmin|If checked, only public projects will have code intelligence and communicate with Sourcegraph."
+msgid "SourcegraphAdmin|Learn more."
msgstr ""
-msgid "SourcegraphAdmin|More information"
+msgid "SourcegraphAdmin|Only public projects have code intelligence enabled and communicate with Sourcegraph."
msgstr ""
msgid "SourcegraphAdmin|Save changes"
@@ -34700,7 +34697,7 @@ msgstr ""
msgid "SourcegraphAdmin|Sourcegraph URL"
msgstr ""
-msgid "SourcegraphAdmin|e.g. https://sourcegraph.example.com"
+msgid "SourcegraphAdmin|https://sourcegraph.example.com"
msgstr ""
msgid "SourcegraphPreferences|This feature is experimental and currently limited to certain projects."
diff --git a/scripts/ingest-reports-to-siem b/scripts/ingest-reports-to-siem
new file mode 100755
index 00000000000..5f5397fcd72
--- /dev/null
+++ b/scripts/ingest-reports-to-siem
@@ -0,0 +1,38 @@
+#!/usr/bin/env node
+
+const { S3Client, PutObjectCommand } = require('@aws-sdk/client-s3')
+const { fromIni } = require('@aws-sdk/credential-provider-ini')
+const path = require('path')
+const fs = require('fs')
+const crypto = require('crypto')
+
+function getMD5HashFromFile(data) {
+ const hash = crypto.createHash('md5').update(data).digest('base64')
+ return hash
+}
+
+(async function () {
+ const s3Client = new S3Client({
+ region: 'us-east-2',
+ credentials: fromIni({ profile: 'gl-logs-for-panther' }),
+ })
+ try {
+ const file = 'gl-dependency-scanning-report.json'
+ const data = fs.readFileSync(file)
+ const responseData = await s3Client.send(
+ new PutObjectCommand({
+ Bucket: 'gl-logs-for-panther-test',
+ Key: path.join('package_hunter_test', path.basename(file)),
+ Body: data,
+ ContentMD5: getMD5HashFromFile(data),
+ }),
+ )
+ console.log('Successfully uploaded %s', file)
+ } catch (err) {
+ if (err.name === 'CredentialsProviderError' || err.name === 'AuthorizationHeaderMalformed')
+ console.log('Could not upload the report. Are AWS credentials configured in ~/.aws/credentials?')
+ else
+ console.log('Unexpected error during upload.')
+ process.exit(1)
+ }
+})()
diff --git a/spec/experiments/application_experiment_spec.rb b/spec/experiments/application_experiment_spec.rb
index f3bd9eafbc3..f0a993bd03b 100644
--- a/spec/experiments/application_experiment_spec.rb
+++ b/spec/experiments/application_experiment_spec.rb
@@ -28,61 +28,23 @@ RSpec.describe ApplicationExperiment, :experiment do
end
describe "#publish" do
- let(:should_track) { true }
-
- before do
- allow(application_experiment).to receive(:should_track?).and_return(should_track)
- end
-
it "tracks the assignment", :snowplow do
- application_experiment.publish
-
- expect_snowplow_event(
- category: 'namespaced/stub',
- action: 'assignment',
- context: [{ schema: anything, data: anything }]
- )
- end
-
- it "publishes to the client" do
- expect(application_experiment).to receive(:publish_to_client)
+ expect(application_experiment).to receive(:track).with(:assignment)
application_experiment.publish
end
- context 'when we should not track' do
- let(:should_track) { false }
-
- it 'does not track an event to Snowplow', :snowplow do
- application_experiment.publish
-
- expect_no_snowplow_event
- end
- end
-
- describe "#publish_to_client" do
- it "adds the data into Gon" do
- signature = { key: '86208ac54ca798e11f127e8b23ec396a', variant: 'control' }
- expect(Gon).to receive(:push).with({ experiment: { 'namespaced/stub' => hash_including(signature) } }, true)
-
- application_experiment.publish_to_client
- end
-
- it "handles when Gon raises exceptions (like when it can't be pushed into)" do
- expect(Gon).to receive(:push).and_raise(NoMethodError)
-
- expect { application_experiment.publish_to_client }.not_to raise_error
- end
-
- context 'when we should not track' do
- let(:should_track) { false }
-
- it 'returns early' do
- expect(Gon).not_to receive(:push)
+ it "adds to the published experiments" do
+ # These are surfaced in the client layer by rendering them in the
+ # _published_experiments.html.haml partial.
+ application_experiment.publish
- application_experiment.publish_to_client
- end
- end
+ expect(ApplicationExperiment.published_experiments['namespaced/stub']).to include(
+ experiment: 'namespaced/stub',
+ excluded: false,
+ key: anything,
+ variant: 'control'
+ )
end
describe '#publish_to_database' do
diff --git a/spec/features/incidents/user_views_incident_spec.rb b/spec/features/incidents/user_views_incident_spec.rb
index fe54f7708c9..e0261ad4d0b 100644
--- a/spec/features/incidents/user_views_incident_spec.rb
+++ b/spec/features/incidents/user_views_incident_spec.rb
@@ -40,10 +40,8 @@ RSpec.describe "User views incident" do
visit(project_issues_incident_path(project, incident))
end
- it 'does not show the incident action', :js, :aggregate_failures do
- click_button 'Incident actions'
-
- expect(page).not_to have_link('New incident')
+ it 'does not show the incident actions', :js, :aggregate_failures do
+ expect(page).not_to have_button('Incident actions')
end
end
end
diff --git a/spec/frontend/deploy_tokens/components/revoke_button_spec.js b/spec/frontend/deploy_tokens/components/revoke_button_spec.js
index e70dfe4d2e6..fa2a7d9b155 100644
--- a/spec/frontend/deploy_tokens/components/revoke_button_spec.js
+++ b/spec/frontend/deploy_tokens/components/revoke_button_spec.js
@@ -70,11 +70,6 @@ describe('RevokeButton', () => {
expect(findRevokeButton().exists()).toBe(true);
});
- it('passes the buttonClass to the button', () => {
- wrapper = createComponent({ buttonClass: 'my-revoke-button' });
- expect(findRevokeButton().classes()).toContain('my-revoke-button');
- });
-
it('opens the modal', () => {
findRevokeButton().trigger('click');
expect(glModalDirective).toHaveBeenCalledWith(wrapper.vm.modalId);
diff --git a/spec/frontend/fixtures/runner.rb b/spec/frontend/fixtures/runner.rb
index cdb4c3fd8ba..25049ee4722 100644
--- a/spec/frontend/fixtures/runner.rb
+++ b/spec/frontend/fixtures/runner.rb
@@ -33,19 +33,19 @@ RSpec.describe 'Runner (JavaScript fixtures)' do
end
describe GraphQL::Query, type: :request do
- get_runners_query_name = 'get_runners.query.graphql'
+ admin_runners_query = 'list/admin_runners.query.graphql'
let_it_be(:query) do
- get_graphql_query_as_string("#{query_path}#{get_runners_query_name}")
+ get_graphql_query_as_string("#{query_path}#{admin_runners_query}")
end
- it "#{fixtures_path}#{get_runners_query_name}.json" do
+ it "#{fixtures_path}#{admin_runners_query}.json" do
post_graphql(query, current_user: admin, variables: {})
expect_graphql_errors_to_be_empty
end
- it "#{fixtures_path}#{get_runners_query_name}.paginated.json" do
+ it "#{fixtures_path}#{admin_runners_query}.paginated.json" do
post_graphql(query, current_user: admin, variables: { first: 2 })
expect_graphql_errors_to_be_empty
@@ -53,13 +53,13 @@ RSpec.describe 'Runner (JavaScript fixtures)' do
end
describe GraphQL::Query, type: :request do
- get_runners_count_query_name = 'get_runners_count.query.graphql'
+ admin_runners_count_query = 'list/admin_runners_count.query.graphql'
let_it_be(:query) do
- get_graphql_query_as_string("#{query_path}#{get_runners_count_query_name}")
+ get_graphql_query_as_string("#{query_path}#{admin_runners_count_query}")
end
- it "#{fixtures_path}#{get_runners_count_query_name}.json" do
+ it "#{fixtures_path}#{admin_runners_count_query}.json" do
post_graphql(query, current_user: admin, variables: {})
expect_graphql_errors_to_be_empty
@@ -67,13 +67,13 @@ RSpec.describe 'Runner (JavaScript fixtures)' do
end
describe GraphQL::Query, type: :request do
- get_runner_query_name = 'get_runner.query.graphql'
+ runner_query = 'details/runner.query.graphql'
let_it_be(:query) do
- get_graphql_query_as_string("#{query_path}#{get_runner_query_name}")
+ get_graphql_query_as_string("#{query_path}#{runner_query}")
end
- it "#{fixtures_path}#{get_runner_query_name}.json" do
+ it "#{fixtures_path}#{runner_query}.json" do
post_graphql(query, current_user: admin, variables: {
id: instance_runner.to_global_id.to_s
})
@@ -81,7 +81,7 @@ RSpec.describe 'Runner (JavaScript fixtures)' do
expect_graphql_errors_to_be_empty
end
- it "#{fixtures_path}#{get_runner_query_name}.with_group.json" do
+ it "#{fixtures_path}#{runner_query}.with_group.json" do
post_graphql(query, current_user: admin, variables: {
id: group_runner.to_global_id.to_s
})
@@ -91,13 +91,13 @@ RSpec.describe 'Runner (JavaScript fixtures)' do
end
describe GraphQL::Query, type: :request do
- get_runner_projects_query_name = 'get_runner_projects.query.graphql'
+ runner_projects_query = 'details/runner_projects.query.graphql'
let_it_be(:query) do
- get_graphql_query_as_string("#{query_path}#{get_runner_projects_query_name}")
+ get_graphql_query_as_string("#{query_path}#{runner_projects_query}")
end
- it "#{fixtures_path}#{get_runner_projects_query_name}.json" do
+ it "#{fixtures_path}#{runner_projects_query}.json" do
post_graphql(query, current_user: admin, variables: {
id: project_runner.to_global_id.to_s
})
@@ -107,13 +107,13 @@ RSpec.describe 'Runner (JavaScript fixtures)' do
end
describe GraphQL::Query, type: :request do
- get_runner_jobs_query_name = 'get_runner_jobs.query.graphql'
+ runner_jobs_query = 'details/runner_jobs.query.graphql'
let_it_be(:query) do
- get_graphql_query_as_string("#{query_path}#{get_runner_jobs_query_name}")
+ get_graphql_query_as_string("#{query_path}#{runner_jobs_query}")
end
- it "#{fixtures_path}#{get_runner_jobs_query_name}.json" do
+ it "#{fixtures_path}#{runner_jobs_query}.json" do
post_graphql(query, current_user: admin, variables: {
id: instance_runner.to_global_id.to_s
})
@@ -131,13 +131,13 @@ RSpec.describe 'Runner (JavaScript fixtures)' do
end
describe GraphQL::Query, type: :request do
- get_group_runners_query_name = 'get_group_runners.query.graphql'
+ group_runners_query = 'list/group_runners.query.graphql'
let_it_be(:query) do
- get_graphql_query_as_string("#{query_path}#{get_group_runners_query_name}")
+ get_graphql_query_as_string("#{query_path}#{group_runners_query}")
end
- it "#{fixtures_path}#{get_group_runners_query_name}.json" do
+ it "#{fixtures_path}#{group_runners_query}.json" do
post_graphql(query, current_user: group_owner, variables: {
groupFullPath: group.full_path
})
@@ -145,7 +145,7 @@ RSpec.describe 'Runner (JavaScript fixtures)' do
expect_graphql_errors_to_be_empty
end
- it "#{fixtures_path}#{get_group_runners_query_name}.paginated.json" do
+ it "#{fixtures_path}#{group_runners_query}.paginated.json" do
post_graphql(query, current_user: group_owner, variables: {
groupFullPath: group.full_path,
first: 1
@@ -156,13 +156,13 @@ RSpec.describe 'Runner (JavaScript fixtures)' do
end
describe GraphQL::Query, type: :request do
- get_group_runners_count_query_name = 'get_group_runners_count.query.graphql'
+ group_runners_count_query = 'list/group_runners_count.query.graphql'
let_it_be(:query) do
- get_graphql_query_as_string("#{query_path}#{get_group_runners_count_query_name}")
+ get_graphql_query_as_string("#{query_path}#{group_runners_count_query}")
end
- it "#{fixtures_path}#{get_group_runners_count_query_name}.json" do
+ it "#{fixtures_path}#{group_runners_count_query}.json" do
post_graphql(query, current_user: group_owner, variables: {
groupFullPath: group.full_path
})
diff --git a/spec/frontend/issues/show/components/header_actions_spec.js b/spec/frontend/issues/show/components/header_actions_spec.js
index 4a557a60b94..6640025a652 100644
--- a/spec/frontend/issues/show/components/header_actions_spec.js
+++ b/spec/frontend/issues/show/components/header_actions_spec.js
@@ -1,5 +1,5 @@
-import { GlButton, GlDropdown, GlDropdownItem, GlLink, GlModal } from '@gitlab/ui';
import Vue, { nextTick } from 'vue';
+import { GlButton, GlDropdownItem, GlLink, GlModal } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
import Vuex from 'vuex';
import { mockTracking } from 'helpers/tracking_helper';
@@ -65,12 +65,17 @@ describe('HeaderActions component', () => {
},
};
- const findToggleIssueStateButton = () => wrapper.findComponent(GlButton);
- const findDropdownAt = (index) => wrapper.findAllComponents(GlDropdown).at(index);
- const findMobileDropdownItems = () => findDropdownAt(0).findAllComponents(GlDropdownItem);
- const findDesktopDropdownItems = () => findDropdownAt(1).findAllComponents(GlDropdownItem);
- const findModal = () => wrapper.findComponent(GlModal);
- const findModalLinkAt = (index) => findModal().findAllComponents(GlLink).at(index);
+ const findToggleIssueStateButton = () => wrapper.find(GlButton);
+
+ const findDropdownBy = (dataTestId) => wrapper.find(`[data-testid="${dataTestId}"]`);
+ const findMobileDropdown = () => findDropdownBy('mobile-dropdown');
+ const findDesktopDropdown = () => findDropdownBy('desktop-dropdown');
+ const findMobileDropdownItems = () => findMobileDropdown().findAll(GlDropdownItem);
+ const findDesktopDropdownItems = () => findDesktopDropdown().findAll(GlDropdownItem);
+
+ const findModal = () => wrapper.find(GlModal);
+
+ const findModalLinkAt = (index) => findModal().findAll(GlLink).at(index);
const mountComponent = ({
props = {},
@@ -161,10 +166,10 @@ describe('HeaderActions component', () => {
});
describe.each`
- description | isCloseIssueItemVisible | findDropdownItems
- ${'mobile dropdown'} | ${true} | ${findMobileDropdownItems}
- ${'desktop dropdown'} | ${false} | ${findDesktopDropdownItems}
- `('$description', ({ isCloseIssueItemVisible, findDropdownItems }) => {
+ description | isCloseIssueItemVisible | findDropdownItems | findDropdown
+ ${'mobile dropdown'} | ${true} | ${findMobileDropdownItems} | ${findMobileDropdown}
+ ${'desktop dropdown'} | ${false} | ${findDesktopDropdownItems} | ${findDesktopDropdown}
+ `('$description', ({ isCloseIssueItemVisible, findDropdownItems, findDropdown }) => {
describe.each`
description | itemText | isItemVisible | canUpdateIssue | canCreateIssue | isIssueAuthor | canReportSpam | canPromoteToEpic | canDestroyIssue
${`when user can update ${issueType}`} | ${`Close ${issueType}`} | ${isCloseIssueItemVisible} | ${true} | ${true} | ${true} | ${true} | ${true} | ${true}
@@ -214,6 +219,24 @@ describe('HeaderActions component', () => {
});
},
);
+
+ describe(`when user can update but not create ${issueType}`, () => {
+ beforeEach(() => {
+ wrapper = mountComponent({
+ props: {
+ canUpdateIssue: true,
+ canCreateIssue: false,
+ isIssueAuthor: true,
+ issueType,
+ canReportSpam: false,
+ canPromoteToEpic: false,
+ },
+ });
+ });
+ it(`${isCloseIssueItemVisible ? 'shows' : 'hides'} the dropdown button`, () => {
+ expect(findDropdown().exists()).toBe(isCloseIssueItemVisible);
+ });
+ });
});
});
diff --git a/spec/frontend/merge_conflicts/components/merge_conflict_resolver_app_spec.js b/spec/frontend/merge_conflicts/components/merge_conflict_resolver_app_spec.js
index 750fff9b0aa..55e666609bd 100644
--- a/spec/frontend/merge_conflicts/components/merge_conflict_resolver_app_spec.js
+++ b/spec/frontend/merge_conflicts/components/merge_conflict_resolver_app_spec.js
@@ -1,7 +1,7 @@
import { GlSprintf } from '@gitlab/ui';
-import { shallowMount } from '@vue/test-utils';
import Vue, { nextTick } from 'vue';
import Vuex from 'vuex';
+import { shallowMountExtended, extendedWrapper } from 'helpers/vue_test_utils_helper';
import InlineConflictLines from '~/merge_conflicts/components/inline_conflict_lines.vue';
import ParallelConflictLines from '~/merge_conflicts/components/parallel_conflict_lines.vue';
import component from '~/merge_conflicts/merge_conflict_resolver_app.vue';
@@ -18,7 +18,7 @@ describe('Merge Conflict Resolver App', () => {
const decoratedMockFiles = decorateFiles(conflictsMock.files);
const mountComponent = () => {
- wrapper = shallowMount(component, {
+ wrapper = shallowMountExtended(component, {
store,
stubs: { GlSprintf },
provide() {
@@ -41,15 +41,17 @@ describe('Merge Conflict Resolver App', () => {
wrapper.destroy();
});
- const findConflictsCount = () => wrapper.find('[data-testid="conflicts-count"]');
- const findFiles = () => wrapper.findAll('[data-testid="files"]');
- const findFileHeader = (w = wrapper) => w.find('[data-testid="file-name"]');
- const findFileInteractiveButton = (w = wrapper) => w.find('[data-testid="interactive-button"]');
- const findFileInlineButton = (w = wrapper) => w.find('[data-testid="inline-button"]');
- const findSideBySideButton = () => wrapper.find('[data-testid="side-by-side"]');
+ const findLoadingSpinner = () => wrapper.findByTestId('loading-spinner');
+ const findConflictsCount = () => wrapper.findByTestId('conflicts-count');
+ const findFiles = () => wrapper.findAllByTestId('files');
+ const findFileHeader = (w = wrapper) => extendedWrapper(w).findByTestId('file-name');
+ const findFileInteractiveButton = (w = wrapper) =>
+ extendedWrapper(w).findByTestId('interactive-button');
+ const findFileInlineButton = (w = wrapper) => extendedWrapper(w).findByTestId('inline-button');
+ const findSideBySideButton = () => wrapper.findByTestId('side-by-side');
const findInlineConflictLines = (w = wrapper) => w.find(InlineConflictLines);
const findParallelConflictLines = (w = wrapper) => w.find(ParallelConflictLines);
- const findCommitMessageTextarea = () => wrapper.find('[data-testid="commit-message"]');
+ const findCommitMessageTextarea = () => wrapper.findByTestId('commit-message');
it('shows the amount of conflicts', () => {
mountComponent();
@@ -60,6 +62,19 @@ describe('Merge Conflict Resolver App', () => {
expect(title.text().trim()).toBe('Showing 3 conflicts between test-conflicts and main');
});
+ it('shows a loading spinner while loading', () => {
+ store.commit('SET_LOADING_STATE', true);
+ mountComponent();
+
+ expect(findLoadingSpinner().exists()).toBe(true);
+ });
+
+ it('does not show a loading spinner once loaded', () => {
+ mountComponent();
+
+ expect(findLoadingSpinner().exists()).toBe(false);
+ });
+
describe('files', () => {
it('shows one file area for each file', () => {
mountComponent();
diff --git a/spec/frontend/pipeline_editor/pipeline_editor_app_spec.js b/spec/frontend/pipeline_editor/pipeline_editor_app_spec.js
index 0a2c03b7850..0ce6cc3f2d4 100644
--- a/spec/frontend/pipeline_editor/pipeline_editor_app_spec.js
+++ b/spec/frontend/pipeline_editor/pipeline_editor_app_spec.js
@@ -18,12 +18,15 @@ import {
COMMIT_SUCCESS,
COMMIT_SUCCESS_WITH_REDIRECT,
COMMIT_FAILURE,
+ EDITOR_APP_STATUS_LOADING,
} from '~/pipeline_editor/constants';
import getBlobContent from '~/pipeline_editor/graphql/queries/blob_content.query.graphql';
import getCiConfigData from '~/pipeline_editor/graphql/queries/ci_config.query.graphql';
import getTemplate from '~/pipeline_editor/graphql/queries/get_starter_template.query.graphql';
import getLatestCommitShaQuery from '~/pipeline_editor/graphql/queries/latest_commit_sha.query.graphql';
import getPipelineQuery from '~/pipeline_editor/graphql/queries/pipeline.query.graphql';
+import getCurrentBranch from '~/pipeline_editor/graphql/queries/client/current_branch.query.graphql';
+import getAppStatus from '~/pipeline_editor/graphql/queries/client/app_status.query.graphql';
import PipelineEditorApp from '~/pipeline_editor/pipeline_editor_app.vue';
import PipelineEditorHome from '~/pipeline_editor/pipeline_editor_home.vue';
@@ -84,9 +87,6 @@ describe('Pipeline editor app component', () => {
initialCiFileContent: {
loading: blobLoading,
},
- ciConfigData: {
- loading: false,
- },
},
},
},
@@ -94,7 +94,11 @@ describe('Pipeline editor app component', () => {
});
};
- const createComponentWithApollo = async ({ provide = {}, stubs = {} } = {}) => {
+ const createComponentWithApollo = async ({
+ provide = {},
+ stubs = {},
+ withUndefinedBranch = false,
+ } = {}) => {
const handlers = [
[getBlobContent, mockBlobContentData],
[getCiConfigData, mockCiConfigData],
@@ -105,6 +109,31 @@ describe('Pipeline editor app component', () => {
mockApollo = createMockApollo(handlers, resolvers);
+ if (!withUndefinedBranch) {
+ mockApollo.clients.defaultClient.cache.writeQuery({
+ query: getCurrentBranch,
+ data: {
+ workBranches: {
+ __typename: 'BranchList',
+ current: {
+ __typename: 'WorkBranch',
+ name: mockDefaultBranch,
+ },
+ },
+ },
+ });
+ }
+
+ mockApollo.clients.defaultClient.cache.writeQuery({
+ query: getAppStatus,
+ data: {
+ app: {
+ __typename: 'AppData',
+ status: EDITOR_APP_STATUS_LOADING,
+ },
+ },
+ });
+
const options = {
localVue,
mocks: {},
@@ -145,6 +174,55 @@ describe('Pipeline editor app component', () => {
});
});
+ describe('skipping queries', () => {
+ describe('when branchName is undefined', () => {
+ beforeEach(async () => {
+ await createComponentWithApollo({ withUndefinedBranch: true });
+ });
+
+ it('does not calls getBlobContent', () => {
+ expect(mockBlobContentData).not.toHaveBeenCalled();
+ });
+ });
+
+ describe('when branchName is defined', () => {
+ beforeEach(async () => {
+ await createComponentWithApollo();
+ });
+
+ it('calls getBlobContent', () => {
+ expect(mockBlobContentData).toHaveBeenCalled();
+ });
+ });
+
+ describe('when commit sha is undefined', () => {
+ beforeEach(async () => {
+ mockLatestCommitShaQuery.mockResolvedValue(undefined);
+ await createComponentWithApollo();
+ });
+
+ it('calls getBlobContent', () => {
+ expect(mockBlobContentData).toHaveBeenCalled();
+ });
+
+ it('does not call ciConfigData', () => {
+ expect(mockCiConfigData).not.toHaveBeenCalled();
+ });
+ });
+
+ describe('when commit sha is defined', () => {
+ beforeEach(async () => {
+ mockBlobContentData.mockResolvedValue(mockBlobContentQueryResponse);
+ mockLatestCommitShaQuery.mockResolvedValue(mockCommitShaResults);
+ await createComponentWithApollo();
+ });
+
+ it('calls ciConfigData', () => {
+ expect(mockCiConfigData).toHaveBeenCalled();
+ });
+ });
+ });
+
describe('when queries are called', () => {
beforeEach(() => {
mockBlobContentData.mockResolvedValue(mockBlobContentQueryResponse);
diff --git a/spec/frontend/runner/admin_runner_edit/admin_runner_edit_app_spec.js b/spec/frontend/runner/admin_runner_edit/admin_runner_edit_app_spec.js
index ff6a632a4f8..d121c6be218 100644
--- a/spec/frontend/runner/admin_runner_edit/admin_runner_edit_app_spec.js
+++ b/spec/frontend/runner/admin_runner_edit/admin_runner_edit_app_spec.js
@@ -7,7 +7,7 @@ import { createAlert } from '~/flash';
import { getIdFromGraphQLId } from '~/graphql_shared/utils';
import RunnerHeader from '~/runner/components/runner_header.vue';
-import getRunnerQuery from '~/runner/graphql/get_runner.query.graphql';
+import runnerQuery from '~/runner/graphql/details/runner.query.graphql';
import AdminRunnerEditApp from '~//runner/admin_runner_edit/admin_runner_edit_app.vue';
import { captureException } from '~/runner/sentry_utils';
@@ -29,7 +29,7 @@ describe('AdminRunnerEditApp', () => {
const createComponentWithApollo = ({ props = {}, mountFn = shallowMount } = {}) => {
wrapper = mountFn(AdminRunnerEditApp, {
- apolloProvider: createMockApollo([[getRunnerQuery, mockRunnerQuery]]),
+ apolloProvider: createMockApollo([[runnerQuery, mockRunnerQuery]]),
propsData: {
runnerId: mockRunnerId,
...props,
diff --git a/spec/frontend/runner/admin_runner_show/admin_runner_show_app_spec.js b/spec/frontend/runner/admin_runner_show/admin_runner_show_app_spec.js
index 4b651961112..f994ff24c21 100644
--- a/spec/frontend/runner/admin_runner_show/admin_runner_show_app_spec.js
+++ b/spec/frontend/runner/admin_runner_show/admin_runner_show_app_spec.js
@@ -9,7 +9,7 @@ import { getIdFromGraphQLId } from '~/graphql_shared/utils';
import RunnerHeader from '~/runner/components/runner_header.vue';
import RunnerPauseButton from '~/runner/components/runner_pause_button.vue';
import RunnerEditButton from '~/runner/components/runner_edit_button.vue';
-import getRunnerQuery from '~/runner/graphql/get_runner.query.graphql';
+import runnerQuery from '~/runner/graphql/details/runner.query.graphql';
import AdminRunnerShowApp from '~/runner/admin_runner_show/admin_runner_show_app.vue';
import { captureException } from '~/runner/sentry_utils';
@@ -42,7 +42,7 @@ describe('AdminRunnerShowApp', () => {
const createComponent = ({ props = {}, mountFn = shallowMount } = {}) => {
wrapper = mountFn(AdminRunnerShowApp, {
- apolloProvider: createMockApollo([[getRunnerQuery, mockRunnerQuery]]),
+ apolloProvider: createMockApollo([[runnerQuery, mockRunnerQuery]]),
propsData: {
runnerId: mockRunnerId,
...props,
diff --git a/spec/frontend/runner/admin_runners/admin_runners_app_spec.js b/spec/frontend/runner/admin_runners/admin_runners_app_spec.js
index 2251f26d0c6..fe7d920800d 100644
--- a/spec/frontend/runner/admin_runners/admin_runners_app_spec.js
+++ b/spec/frontend/runner/admin_runners/admin_runners_app_spec.js
@@ -35,8 +35,8 @@ import {
STATUS_ACTIVE,
RUNNER_PAGE_SIZE,
} from '~/runner/constants';
-import getRunnersQuery from '~/runner/graphql/get_runners.query.graphql';
-import getRunnersCountQuery from '~/runner/graphql/get_runners_count.query.graphql';
+import adminRunnersQuery from '~/runner/graphql/list/admin_runners.query.graphql';
+import adminRunnersCountQuery from '~/runner/graphql/list/admin_runners_count.query.graphql';
import { captureException } from '~/runner/sentry_utils';
import FilteredSearch from '~/vue_shared/components/filtered_search_bar/filtered_search_bar_root.vue';
@@ -71,8 +71,8 @@ describe('AdminRunnersApp', () => {
const createComponent = ({ props = {}, mountFn = shallowMountExtended } = {}) => {
const handlers = [
- [getRunnersQuery, mockRunnersQuery],
- [getRunnersCountQuery, mockRunnersCountQuery],
+ [adminRunnersQuery, mockRunnersQuery],
+ [adminRunnersCountQuery, mockRunnersCountQuery],
];
wrapper = mountFn(AdminRunnersApp, {
diff --git a/spec/frontend/runner/components/registration/registration_token_reset_dropdown_item_spec.js b/spec/frontend/runner/components/registration/registration_token_reset_dropdown_item_spec.js
index d2deb49a5f7..2510aaf0334 100644
--- a/spec/frontend/runner/components/registration/registration_token_reset_dropdown_item_spec.js
+++ b/spec/frontend/runner/components/registration/registration_token_reset_dropdown_item_spec.js
@@ -8,7 +8,7 @@ import waitForPromises from 'helpers/wait_for_promises';
import { createAlert } from '~/flash';
import RegistrationTokenResetDropdownItem from '~/runner/components/registration/registration_token_reset_dropdown_item.vue';
import { INSTANCE_TYPE, GROUP_TYPE, PROJECT_TYPE } from '~/runner/constants';
-import runnersRegistrationTokenResetMutation from '~/runner/graphql/runners_registration_token_reset.mutation.graphql';
+import runnersRegistrationTokenResetMutation from '~/runner/graphql/list/runners_registration_token_reset.mutation.graphql';
import { captureException } from '~/runner/sentry_utils';
import { createMockDirective, getBinding } from 'helpers/vue_mock_directive';
diff --git a/spec/frontend/runner/components/runner_delete_button_spec.js b/spec/frontend/runner/components/runner_delete_button_spec.js
index 8479fa35dd2..5fa2d033dcc 100644
--- a/spec/frontend/runner/components/runner_delete_button_spec.js
+++ b/spec/frontend/runner/components/runner_delete_button_spec.js
@@ -4,7 +4,7 @@ import VueApollo from 'vue-apollo';
import createMockApollo from 'helpers/mock_apollo_helper';
import { createMockDirective, getBinding } from 'helpers/vue_mock_directive';
import { shallowMountExtended, mountExtended } from 'helpers/vue_test_utils_helper';
-import runnerDeleteMutation from '~/runner/graphql/runner_delete.mutation.graphql';
+import runnerDeleteMutation from '~/runner/graphql/shared/runner_delete.mutation.graphql';
import waitForPromises from 'helpers/wait_for_promises';
import { captureException } from '~/runner/sentry_utils';
import { getIdFromGraphQLId } from '~/graphql_shared/utils';
diff --git a/spec/frontend/runner/components/runner_jobs_spec.js b/spec/frontend/runner/components/runner_jobs_spec.js
index 97339056370..9abb2861005 100644
--- a/spec/frontend/runner/components/runner_jobs_spec.js
+++ b/spec/frontend/runner/components/runner_jobs_spec.js
@@ -11,7 +11,7 @@ import RunnerPagination from '~/runner/components/runner_pagination.vue';
import { captureException } from '~/runner/sentry_utils';
import { I18N_NO_JOBS_FOUND, RUNNER_DETAILS_JOBS_PAGE_SIZE } from '~/runner/constants';
-import getRunnerJobsQuery from '~/runner/graphql/get_runner_jobs.query.graphql';
+import runnerJobsQuery from '~/runner/graphql/details/runner_jobs.query.graphql';
import { runnerData, runnerJobsData } from '../mock_data';
@@ -34,7 +34,7 @@ describe('RunnerJobs', () => {
const createComponent = ({ mountFn = shallowMountExtended } = {}) => {
wrapper = mountFn(RunnerJobs, {
- apolloProvider: createMockApollo([[getRunnerJobsQuery, mockRunnerJobsQuery]]),
+ apolloProvider: createMockApollo([[runnerJobsQuery, mockRunnerJobsQuery]]),
propsData: {
runner: mockRunner,
},
diff --git a/spec/frontend/runner/components/runner_pause_button_spec.js b/spec/frontend/runner/components/runner_pause_button_spec.js
index 278f3dec2ee..c69bae05e45 100644
--- a/spec/frontend/runner/components/runner_pause_button_spec.js
+++ b/spec/frontend/runner/components/runner_pause_button_spec.js
@@ -4,7 +4,7 @@ import VueApollo from 'vue-apollo';
import createMockApollo from 'helpers/mock_apollo_helper';
import { createMockDirective, getBinding } from 'helpers/vue_mock_directive';
import { shallowMountExtended, mountExtended } from 'helpers/vue_test_utils_helper';
-import runnerToggleActiveMutation from '~/runner/graphql/runner_toggle_active.mutation.graphql';
+import runnerToggleActiveMutation from '~/runner/graphql/shared/runner_toggle_active.mutation.graphql';
import waitForPromises from 'helpers/wait_for_promises';
import { captureException } from '~/runner/sentry_utils';
import { createAlert } from '~/flash';
diff --git a/spec/frontend/runner/components/runner_projects_spec.js b/spec/frontend/runner/components/runner_projects_spec.js
index 68a2130d6d9..96de8d11bca 100644
--- a/spec/frontend/runner/components/runner_projects_spec.js
+++ b/spec/frontend/runner/components/runner_projects_spec.js
@@ -16,7 +16,7 @@ import RunnerAssignedItem from '~/runner/components/runner_assigned_item.vue';
import RunnerPagination from '~/runner/components/runner_pagination.vue';
import { captureException } from '~/runner/sentry_utils';
-import getRunnerProjectsQuery from '~/runner/graphql/get_runner_projects.query.graphql';
+import runnerProjectsQuery from '~/runner/graphql/details/runner_projects.query.graphql';
import { runnerData, runnerProjectsData } from '../mock_data';
@@ -40,7 +40,7 @@ describe('RunnerProjects', () => {
const createComponent = ({ mountFn = shallowMountExtended } = {}) => {
wrapper = mountFn(RunnerProjects, {
- apolloProvider: createMockApollo([[getRunnerProjectsQuery, mockRunnerProjectsQuery]]),
+ apolloProvider: createMockApollo([[runnerProjectsQuery, mockRunnerProjectsQuery]]),
propsData: {
runner: mockRunner,
},
diff --git a/spec/frontend/runner/components/runner_update_form_spec.js b/spec/frontend/runner/components/runner_update_form_spec.js
index 8b76be396ef..b071791e39f 100644
--- a/spec/frontend/runner/components/runner_update_form_spec.js
+++ b/spec/frontend/runner/components/runner_update_form_spec.js
@@ -13,7 +13,7 @@ import {
ACCESS_LEVEL_REF_PROTECTED,
ACCESS_LEVEL_NOT_PROTECTED,
} from '~/runner/constants';
-import runnerUpdateMutation from '~/runner/graphql/runner_update.mutation.graphql';
+import runnerUpdateMutation from '~/runner/graphql/details/runner_update.mutation.graphql';
import { captureException } from '~/runner/sentry_utils';
import { runnerData } from '../mock_data';
diff --git a/spec/frontend/runner/group_runners/group_runners_app_spec.js b/spec/frontend/runner/group_runners/group_runners_app_spec.js
index 4f373516abb..857db7663ec 100644
--- a/spec/frontend/runner/group_runners/group_runners_app_spec.js
+++ b/spec/frontend/runner/group_runners/group_runners_app_spec.js
@@ -32,8 +32,8 @@ import {
RUNNER_PAGE_SIZE,
I18N_EDIT,
} from '~/runner/constants';
-import getGroupRunnersQuery from '~/runner/graphql/get_group_runners.query.graphql';
-import getGroupRunnersCountQuery from '~/runner/graphql/get_group_runners_count.query.graphql';
+import getGroupRunnersQuery from '~/runner/graphql/list/group_runners.query.graphql';
+import getGroupRunnersCountQuery from '~/runner/graphql/list/group_runners_count.query.graphql';
import GroupRunnersApp from '~/runner/group_runners/group_runners_app.vue';
import { captureException } from '~/runner/sentry_utils';
import FilteredSearch from '~/vue_shared/components/filtered_search_bar/filtered_search_bar_root.vue';
diff --git a/spec/frontend/runner/mock_data.js b/spec/frontend/runner/mock_data.js
index d80caa47752..49c25039719 100644
--- a/spec/frontend/runner/mock_data.js
+++ b/spec/frontend/runner/mock_data.js
@@ -1,18 +1,18 @@
// Fixtures generated by: spec/frontend/fixtures/runner.rb
-// Admin queries
-import runnersData from 'test_fixtures/graphql/runner/get_runners.query.graphql.json';
-import runnersCountData from 'test_fixtures/graphql/runner/get_runners_count.query.graphql.json';
-import runnersDataPaginated from 'test_fixtures/graphql/runner/get_runners.query.graphql.paginated.json';
-import runnerData from 'test_fixtures/graphql/runner/get_runner.query.graphql.json';
-import runnerWithGroupData from 'test_fixtures/graphql/runner/get_runner.query.graphql.with_group.json';
-import runnerProjectsData from 'test_fixtures/graphql/runner/get_runner_projects.query.graphql.json';
-import runnerJobsData from 'test_fixtures/graphql/runner/get_runner_jobs.query.graphql.json';
+// List queries
+import runnersData from 'test_fixtures/graphql/runner/list/admin_runners.query.graphql.json';
+import runnersDataPaginated from 'test_fixtures/graphql/runner/list/admin_runners.query.graphql.paginated.json';
+import runnersCountData from 'test_fixtures/graphql/runner/list/admin_runners_count.query.graphql.json';
+import groupRunnersData from 'test_fixtures/graphql/runner/list/group_runners.query.graphql.json';
+import groupRunnersDataPaginated from 'test_fixtures/graphql/runner/list/group_runners.query.graphql.paginated.json';
+import groupRunnersCountData from 'test_fixtures/graphql/runner/list/group_runners_count.query.graphql.json';
-// Group queries
-import groupRunnersData from 'test_fixtures/graphql/runner/get_group_runners.query.graphql.json';
-import groupRunnersCountData from 'test_fixtures/graphql/runner/get_group_runners_count.query.graphql.json';
-import groupRunnersDataPaginated from 'test_fixtures/graphql/runner/get_group_runners.query.graphql.paginated.json';
+// Details queries
+import runnerData from 'test_fixtures/graphql/runner/details/runner.query.graphql.json';
+import runnerWithGroupData from 'test_fixtures/graphql/runner/details/runner.query.graphql.with_group.json';
+import runnerProjectsData from 'test_fixtures/graphql/runner/details/runner_projects.query.graphql.json';
+import runnerJobsData from 'test_fixtures/graphql/runner/details/runner_jobs.query.graphql.json';
export {
runnersData,
diff --git a/spec/helpers/deploy_tokens_helper_spec.rb b/spec/helpers/deploy_tokens_helper_spec.rb
new file mode 100644
index 00000000000..e5dd5ff79a2
--- /dev/null
+++ b/spec/helpers/deploy_tokens_helper_spec.rb
@@ -0,0 +1,20 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe DeployTokensHelper do
+ describe '#deploy_token_revoke_button_data' do
+ let_it_be(:token) { build(:deploy_token) }
+ let_it_be(:project) { build(:project) }
+ let_it_be(:revoke_deploy_token_path) { '/foobar/baz/-/deploy_tokens/1/revoke' }
+
+ it 'returns expected hash' do
+ expect(helper).to receive(:revoke_deploy_token_path).with(project, token).and_return(revoke_deploy_token_path)
+
+ expect(helper.deploy_token_revoke_button_data(token: token, group_or_project: project)).to match({
+ token: token.to_json(only: [:id, :name]),
+ revoke_path: revoke_deploy_token_path
+ })
+ end
+ end
+end
diff --git a/spec/lib/gitlab/database/rename_reserved_paths_migration/v1/rename_projects_spec.rb b/spec/lib/gitlab/database/rename_reserved_paths_migration/v1/rename_projects_spec.rb
index 3799fe3c316..50071e3e22b 100644
--- a/spec/lib/gitlab/database/rename_reserved_paths_migration/v1/rename_projects_spec.rb
+++ b/spec/lib/gitlab/database/rename_reserved_paths_migration/v1/rename_projects_spec.rb
@@ -49,7 +49,7 @@ RSpec.describe Gitlab::Database::RenameReservedPathsMigration::V1::RenameProject
it 'invalidates the markdown cache of related projects' do
expect(subject).to receive(:remove_cached_html_for_projects)
- .with(projects.map(&:id))
+ .with(a_collection_containing_exactly(*projects.map(&:id)))
subject.rename_projects
end
diff --git a/spec/models/group_spec.rb b/spec/models/group_spec.rb
index 5f8d75d1f59..297b11bd72a 100644
--- a/spec/models/group_spec.rb
+++ b/spec/models/group_spec.rb
@@ -390,26 +390,8 @@ RSpec.describe Group do
let!(:old_parent) { create(:group, parent: root) }
let!(:new_parent) { create(:group, parent: root) }
- context 'with FOR UPDATE lock' do
- before do
- stub_feature_flags(for_no_key_update_lock: false)
- subject
- reload_models(old_parent, new_parent, group)
- end
-
- it 'updates traversal_ids' do
- expect(group.traversal_ids).to eq [root.id, new_parent.id, group.id]
- end
-
- it_behaves_like 'hierarchy with traversal_ids'
- it_behaves_like 'locked row', 'FOR UPDATE' do
- let(:row) { root }
- end
- end
-
context 'with FOR NO KEY UPDATE lock' do
before do
- stub_feature_flags(for_no_key_update_lock: true)
subject
reload_models(old_parent, new_parent, group)
end
@@ -419,7 +401,7 @@ RSpec.describe Group do
end
it_behaves_like 'hierarchy with traversal_ids'
- it_behaves_like 'locked row', 'FOR NO KEY UPDATE' do
+ it_behaves_like 'locked row' do
let(:row) { root }
end
end
diff --git a/spec/models/namespace/traversal_hierarchy_spec.rb b/spec/models/namespace/traversal_hierarchy_spec.rb
index eeea071d326..51932ab943c 100644
--- a/spec/models/namespace/traversal_hierarchy_spec.rb
+++ b/spec/models/namespace/traversal_hierarchy_spec.rb
@@ -68,24 +68,11 @@ RSpec.describe Namespace::TraversalHierarchy, type: :model do
end
end
- it_behaves_like 'locked row', 'FOR UPDATE' do
+ it_behaves_like 'locked row' do
let(:recorded_queries) { ActiveRecord::QueryRecorder.new }
let(:row) { root }
before do
- stub_feature_flags(for_no_key_update_lock: false)
-
- recorded_queries.record { subject }
- end
- end
-
- it_behaves_like 'locked row', 'FOR NO KEY UPDATE' do
- let(:recorded_queries) { ActiveRecord::QueryRecorder.new }
- let(:row) { root }
-
- before do
- stub_feature_flags(for_no_key_update_lock: true)
-
recorded_queries.record { subject }
end
end
diff --git a/spec/models/namespace_spec.rb b/spec/models/namespace_spec.rb
index 1728d4fc3f3..ebd153f6f10 100644
--- a/spec/models/namespace_spec.rb
+++ b/spec/models/namespace_spec.rb
@@ -436,17 +436,7 @@ RSpec.describe Namespace do
it { expect(namespace.traversal_ids).to eq [namespace.id] }
end
- context 'with before_commit callback' do
- it_behaves_like 'default traversal_ids'
- end
-
- context 'with after_create callback' do
- before do
- stub_feature_flags(sync_traversal_ids_before_commit: false)
- end
-
- it_behaves_like 'default traversal_ids'
- end
+ it_behaves_like 'default traversal_ids'
end
describe "after_commit :expire_child_caches" do
diff --git a/spec/models/project_spec.rb b/spec/models/project_spec.rb
index 139223e4245..6516b5f777e 100644
--- a/spec/models/project_spec.rb
+++ b/spec/models/project_spec.rb
@@ -262,17 +262,7 @@ RSpec.describe Project, factory_default: :keep do
end
end
- context 'sync-ing traversal_ids in before_commit callback' do
- it_behaves_like 'creates project namespace'
- end
-
- context 'sync-ing traversal_ids in after_create callback' do
- before do
- stub_feature_flags(sync_traversal_ids_before_commit: false)
- end
-
- it_behaves_like 'creates project namespace'
- end
+ it_behaves_like 'creates project namespace'
end
end
diff --git a/spec/services/groups/create_service_spec.rb b/spec/services/groups/create_service_spec.rb
index 7ec523a1f2b..819569d6e67 100644
--- a/spec/services/groups/create_service_spec.rb
+++ b/spec/services/groups/create_service_spec.rb
@@ -85,14 +85,6 @@ RSpec.describe Groups::CreateService, '#execute' do
context 'with before_commit callback' do
it_behaves_like 'has sync-ed traversal_ids'
end
-
- context 'with after_create callback' do
- before do
- stub_feature_flags(sync_traversal_ids_before_commit: false)
- end
-
- it_behaves_like 'has sync-ed traversal_ids'
- end
end
context 'when user can not create a group' do
@@ -119,17 +111,7 @@ RSpec.describe Groups::CreateService, '#execute' do
expect { subject }.not_to change(OnboardingProgress, :count).from(0)
end
- context 'with before_commit callback' do
- it_behaves_like 'has sync-ed traversal_ids'
- end
-
- context 'with after_create callback' do
- before do
- stub_feature_flags(sync_traversal_ids_before_commit: false)
- end
-
- it_behaves_like 'has sync-ed traversal_ids'
- end
+ it_behaves_like 'has sync-ed traversal_ids'
end
context 'as guest' do
diff --git a/spec/services/projects/create_service_spec.rb b/spec/services/projects/create_service_spec.rb
index 0d4974a7a86..377acdd14cd 100644
--- a/spec/services/projects/create_service_spec.rb
+++ b/spec/services/projects/create_service_spec.rb
@@ -225,17 +225,7 @@ RSpec.describe Projects::CreateService, '#execute' do
expect(project.project_namespace).to be_in_sync_with_project(project)
end
- context 'with before_commit callback' do
- it_behaves_like 'has sync-ed traversal_ids'
- end
-
- context 'with after_create callback' do
- before do
- stub_feature_flags(sync_traversal_ids_before_commit: false)
- end
-
- it_behaves_like 'has sync-ed traversal_ids'
- end
+ it_behaves_like 'has sync-ed traversal_ids'
end
context 'group sharing', :sidekiq_inline do
diff --git a/spec/simplecov_env.rb b/spec/simplecov_env.rb
index da4a0e8da80..be2ff396bc4 100644
--- a/spec/simplecov_env.rb
+++ b/spec/simplecov_env.rb
@@ -49,6 +49,7 @@ module SimpleCovEnv
def configure_profile
SimpleCov.configure do
+ enable_coverage :branch
load_profile 'test_frameworks'
track_files '{app,config/initializers,config/initializers_before_autoloader,db/post_migrate,haml_lint,lib,rubocop,tooling}/**/*.rb'
diff --git a/spec/support/shared_examples/row_lock_shared_examples.rb b/spec/support/shared_examples/row_lock_shared_examples.rb
index e7eec88ec42..24fb2d41bdf 100644
--- a/spec/support/shared_examples/row_lock_shared_examples.rb
+++ b/spec/support/shared_examples/row_lock_shared_examples.rb
@@ -4,10 +4,10 @@
# Ensure a transaction also occurred.
# Be careful! This form of spec is not foolproof, but better than nothing.
-RSpec.shared_examples 'locked row' do |lock_type|
+RSpec.shared_examples 'locked row' do
it "has locked row" do
table_name = row.class.table_name
- ids_regex = /SELECT.*FROM.*#{table_name}.*"#{table_name}"."id" = #{row.id}.+#{lock_type}/m
+ ids_regex = /SELECT.*FROM.*#{table_name}.*"#{table_name}"."id" = #{row.id}.+FOR NO KEY UPDATE/m
expect(recorded_queries.log).to include a_string_matching 'SAVEPOINT'
expect(recorded_queries.log).to include a_string_matching ids_regex
diff --git a/spec/views/admin/application_settings/_eks.html.haml_spec.rb b/spec/views/admin/application_settings/_eks.html.haml_spec.rb
index e407970c7a4..d16cbc7b299 100644
--- a/spec/views/admin/application_settings/_eks.html.haml_spec.rb
+++ b/spec/views/admin/application_settings/_eks.html.haml_spec.rb
@@ -16,8 +16,8 @@ RSpec.describe 'admin/application_settings/_eks' do
shared_examples 'EKS secret access key input' do
it 'renders an empty password field' do
render
- expect(rendered).to have_field('Secret access key', type: 'password')
- expect(page.find_field('Secret access key').value).to be_blank
+ expect(rendered).to have_field('AWS secret access key (Optional)', type: 'password')
+ expect(page.find_field('AWS secret access key (Optional)').value).to be_blank
end
end
diff --git a/spec/views/layouts/_published_experiments.html.haml_spec.rb b/spec/views/layouts/_published_experiments.html.haml_spec.rb
index d1ade8ddd6e..84894554bd9 100644
--- a/spec/views/layouts/_published_experiments.html.haml_spec.rb
+++ b/spec/views/layouts/_published_experiments.html.haml_spec.rb
@@ -4,22 +4,20 @@ require 'spec_helper'
RSpec.describe 'layouts/_published_experiments', :experiment do
before do
- stub_const('TestControlExperiment', ApplicationExperiment)
- stub_const('TestCandidateExperiment', ApplicationExperiment)
- stub_const('TestExcludedExperiment', ApplicationExperiment)
+ # Stub each experiment to be enabled, otherwise tracking does not happen.
+ stub_experiments(
+ test_control: :control,
+ test_excluded: true,
+ test_published_only: :control,
+ test_candidate: :candidate,
+ test_variant: :variant_name
+ )
- TestControlExperiment.new('test_control').tap do |e|
- e.variant(:control)
- e.publish
- end
- TestCandidateExperiment.new('test_candidate').tap do |e|
- e.variant(:candidate)
- e.publish
- end
- TestExcludedExperiment.new('test_excluded').tap do |e|
- e.exclude!
- e.publish
- end
+ experiment(:test_control) { }
+ experiment(:test_excluded) { |e| e.exclude! }
+ experiment(:test_candidate) { |e| e.candidate { } }
+ experiment(:test_variant) { |e| e.variant(:variant_name) { } }
+ experiment(:test_published_only).publish
render
end
@@ -29,7 +27,9 @@ RSpec.describe 'layouts/_published_experiments', :experiment do
expect(output).to include('gl.experiments = {')
expect(output).to match(/"test_control":\{[^}]*"variant":"control"/)
- expect(output).to match(/"test_candidate":\{[^}]*"variant":"candidate"/)
expect(output).not_to include('"test_excluded"')
+ expect(output).to match(/"test_candidate":\{[^}]*"variant":"candidate"/)
+ expect(output).to match(/"test_variant":\{[^}]*"variant":"variant_name"/)
+ expect(output).to match(/"test_published_only":\{[^}]*"variant":"control"/)
end
end