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>2021-09-16 15:09:35 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2021-09-16 15:09:35 +0300
commit4c16d4ff4f92987f609e9853da5900a51f0ad1be (patch)
tree3ebc97c31f90db2f9c8fe4e5c5f33a502d68363d
parent3b85f5e4a123538b14eb052ae0efb9d7dbcd4e9b (diff)
Add latest changes from gitlab-org/gitlab@master
-rw-r--r--.rubocop.yml2
-rw-r--r--Gemfile2
-rw-r--r--Gemfile.lock4
-rw-r--r--app/assets/javascripts/boards/components/board_settings_sidebar.vue31
-rw-r--r--app/assets/javascripts/clusters_list/components/clusters.vue2
-rw-r--r--app/assets/javascripts/packages_and_registries/settings/project/components/registry_settings_app.vue2
-rw-r--r--app/assets/javascripts/vue_shared/components/notes/system_note.vue5
-rw-r--r--app/assets/javascripts/vue_shared/components/settings/settings_block.stories.js26
-rw-r--r--app/assets/javascripts/vue_shared/components/settings/settings_block.vue69
-rw-r--r--app/models/ci/pending_build.rb7
-rw-r--r--app/models/clusters/agent.rb3
-rw-r--r--app/models/clusters/agents/project_authorization.rb14
-rw-r--r--app/models/namespace.rb6
-rw-r--r--app/models/namespaces/project_namespace.rb2
-rw-r--r--app/services/ci/queue/build_queue_service.rb10
-rw-r--r--app/services/ci/queue/pending_builds_strategy.rb2
-rw-r--r--app/services/clusters/agents/refresh_authorization_service.rb71
-rwxr-xr-xbin/pngquant64
-rw-r--r--config/events/20210915205037_alert_integrations_view_alert_integrations_list.yml21
-rw-r--r--config/events/20210915205038_default_click_button.yml21
-rw-r--r--config/events/20210915205039_default_copy_keyboard_shortcut.yml21
-rw-r--r--config/events/20210915205040_default_generic.yml21
-rw-r--r--config/events/20210915205041_default_generic.yml21
-rw-r--r--config/events/20210915205050_code_quality_walkthrough_commit_ci_file_dismissed.yml21
-rw-r--r--config/events/20210915205051_code_quality_walkthrough_commit_ci_file_displayed.yml21
-rw-r--r--config/events/20210915205052_code_quality_walkthrough_commit_created.yml21
-rw-r--r--config/events/20210915205053_code_quality_walkthrough_cta_clicked.yml21
-rw-r--r--config/events/20210915205054_code_quality_walkthrough_failed_pipeline_displayed.yml21
-rw-r--r--config/events/20210915205055_code_quality_walkthrough_failed_pipeline_view_logs.yml21
-rw-r--r--config/events/20210915205056_code_quality_walkthrough_running_pipeline_dismissed.yml21
-rw-r--r--config/events/20210915205057_code_quality_walkthrough_running_pipeline_displayed.yml21
-rw-r--r--config/events/20210915205058_code_quality_walkthrough_success_pipeline_displayed.yml21
-rw-r--r--config/events/20210915205059_code_quality_walkthrough_success_pipeline_view_logs.yml21
-rw-r--r--config/events/20210915205100_default_execute_toolbar_control.yml21
-rw-r--r--config/events/20210915205101_default_execute_keyboard_shortcut.yml21
-rw-r--r--config/events/20210915205102_default_execute_input_rule.yml21
-rw-r--r--config/events/20210915205103_default_execute_bubble_menu_control.yml21
-rw-r--r--config/events/20210915205107_default_click_link.yml21
-rw-r--r--config/events/20210915205108_default_type_search_query.yml21
-rw-r--r--config/events/20210915205109_default_invite_members_banner_button_clicked.yml21
-rw-r--r--config/events/20210915205110_default_invite_members_banner_dismissed.yml21
-rw-r--r--config/events/20210915205111_default_change_discussion_sort_direction.yml21
-rw-r--r--config/events/20210915205112_packages_delete_package.yml21
-rw-r--r--config/events/20210915205113_packages_request_delete_package_file.yml21
-rw-r--r--config/events/20210915205114_packages_delete_package_file.yml21
-rw-r--r--config/events/20210915205115_packages_pull_package.yml21
-rw-r--r--config/events/20210915205116_packages_cancel_delete_package.yml21
-rw-r--r--config/events/20210915205117_packages_cancel_delete_package_file.yml21
-rw-r--r--config/events/20210915205118_default_copy_composer_registry_include_command.yml21
-rw-r--r--config/events/20210915205119_default_copy_composer_package_include_command.yml21
-rw-r--r--config/events/20210915205125_default_copy_gradle_install_command.yml21
-rw-r--r--config/events/20210915205126_default_copy_gradle_add_to_source_command.yml21
-rw-r--r--config/events/20210915205127_default_copy_kotlin_install_command.yml21
-rw-r--r--config/events/20210915205128_default_copy_kotlin_add_to_source_command.yml21
-rw-r--r--config/events/20210915205140_default_reset_form.yml21
-rw-r--r--config/events/20210915205141_default_submit_form.yml21
-rw-r--r--config/events/20210915205142_default_click_dismiss.yml21
-rw-r--r--config/events/20210915205143_default_show_home_page_banner.yml21
-rw-r--r--config/events/20210915205145_default_content_editor_loaded.yml21
-rw-r--r--config/events/20210915205146_default_saved_using_content_editor.yml21
-rw-r--r--config/events/20210915205147_default_browse_templates.yml21
-rw-r--r--config/events/20210915205148_default_template_clicked.yml21
-rw-r--r--config/events/20210915205149_default_dismiss_banner.yml21
-rw-r--r--config/events/20210915205150_default_click_button.yml21
-rw-r--r--config/events/20210915205151_default_click_dropdown.yml21
-rw-r--r--config/events/20210915205152_default_click_copy_login.yml21
-rw-r--r--config/events/20210915205153_default_click_copy_build.yml21
-rw-r--r--config/events/20210915205154_default_click_copy_push.yml21
-rw-r--r--config/events/20210915205155_default_click_button.yml21
-rw-r--r--config/events/20210915205156_default_confirm_delete.yml21
-rw-r--r--config/events/20210915205157_default_cancel_delete.yml21
-rw-r--r--config/events/20210915205158_default_click_button.yml21
-rw-r--r--config/events/20210915205159_default_confirm_delete.yml21
-rw-r--r--config/events/20210915205200_default_cancel_delete.yml21
-rw-r--r--config/events/20210915205202_default_generic.yml21
-rw-r--r--config/events/20210915205203_default_click_tab.yml21
-rw-r--r--config/events/20210915205204_default_click_whats_new_drawer.yml21
-rw-r--r--config/events/20210915205207_default_click_dropdown.yml21
-rw-r--r--config/feature_flags/development/ci_pending_builds_project_runners_decoupling.yml8
-rw-r--r--config/metrics/settings/20210915152326_service_ping_features_enabled.yml23
-rw-r--r--data/deprecations/14-3-repository-push-audit-events.yml4
-rw-r--r--data/deprecations/deprecation_omniauth-kerberos_gem.yml6
-rw-r--r--db/migrate/20210913010411_create_agent_project_authorizations.rb14
-rw-r--r--db/migrate/20210913010432_add_agent_project_authorizations_foreign_keys.rb20
-rw-r--r--db/schema_migrations/202109130104111
-rw-r--r--db/schema_migrations/202109130104321
-rw-r--r--db/structure.sql31
-rw-r--r--doc/administration/gitaly/praefect.md2
-rw-r--r--doc/administration/operations/puma.md2
-rw-r--r--doc/administration/redis/troubleshooting.md2
-rw-r--r--doc/administration/reference_architectures/troubleshooting.md2
-rw-r--r--doc/api/graphql/reference/index.md15
-rw-r--r--doc/ci/environments/index.md2
-rw-r--r--doc/development/database/pagination_guidelines.md2
-rw-r--r--doc/development/documentation/styleguide/index.md21
-rw-r--r--doc/development/experiment_guide/experimentation.md2
-rw-r--r--doc/development/fe_guide/graphql.md6
-rw-r--r--doc/development/import_project.md2
-rw-r--r--doc/development/internal_api.md2
-rw-r--r--doc/development/multi_version_compatibility.md2
-rw-r--r--doc/development/service_ping/metrics_dictionary.md2
-rw-r--r--doc/development/transient/prevention-patterns.md2
-rw-r--r--doc/install/aws/index.md2
-rw-r--r--doc/integration/recaptcha.md2
-rw-r--r--doc/operations/error_tracking.md2
-rw-r--r--doc/topics/autodevops/customize.md2
-rw-r--r--doc/update/deprecations.md14
-rw-r--r--doc/update/plan_your_upgrade.md2
-rw-r--r--doc/user/application_security/dast/index.md15
-rw-r--r--doc/user/application_security/dependency_scanning/index.md2
-rw-r--r--doc/user/application_security/policies/index.md2
-rw-r--r--doc/user/gitlab_com/index.md2
-rw-r--r--doc/user/group/saml_sso/index.md2
-rw-r--r--doc/user/group/value_stream_analytics/index.md3
-rw-r--r--doc/user/profile/notifications.md2
-rw-r--r--doc/user/project/clusters/add_eks_clusters.md2
-rw-r--r--doc/user/project/clusters/add_gke_clusters.md2
-rw-r--r--doc/user/project/clusters/add_remove_clusters.md2
-rw-r--r--doc/user/project/deploy_tokens/index.md2
-rw-r--r--doc/user/project/settings/index.md2
-rw-r--r--lib/gitlab/usage/metrics/instrumentations/service_ping_features_metric.rb15
-rw-r--r--lib/gitlab/usage_data.rb3
-rw-r--r--lib/tasks/pngquant.rake55
-rw-r--r--locale/gitlab.pot45
-rw-r--r--qa/qa/page/group/menu.rb17
-rw-r--r--qa/qa/page/group/settings/group_deploy_tokens.rb68
-rw-r--r--qa/qa/page/group/settings/repository.rb23
-rw-r--r--qa/qa/resource/group_deploy_token.rb51
-rw-r--r--qa/qa/specs/features/browser_ui/5_package/nuget_repository_spec.rb256
-rw-r--r--qa/qa/support/formatters/test_stats_formatter.rb1
-rw-r--r--qa/spec/support/formatters/test_stats_formatter_spec.rb3
-rw-r--r--rubocop/cop/sidekiq_load_balancing/worker_data_consistency.rb65
-rw-r--r--rubocop/cop/sidekiq_load_balancing/worker_data_consistency_with_deduplication.rb154
-rw-r--r--rubocop/cop/worker_data_consistency.rb63
-rw-r--r--spec/factories/ci/pending_builds.rb1
-rw-r--r--spec/factories/clusters/agents/project_authorizations.rb10
-rw-r--r--spec/frontend/boards/components/board_settings_sidebar_spec.js6
-rw-r--r--spec/frontend/vue_shared/components/settings/__snapshots__/settings_block_spec.js.snap12
-rw-r--r--spec/frontend/vue_shared/components/settings/settings_block_spec.js56
-rw-r--r--spec/lib/gitlab/usage/metrics/instrumentations/service_ping_features_metric_spec.rb20
-rw-r--r--spec/lib/gitlab/usage_data_spec.rb4
-rw-r--r--spec/models/ci/pending_build_spec.rb41
-rw-r--r--spec/models/clusters/agent_spec.rb2
-rw-r--r--spec/models/clusters/agents/project_authorization_spec.rb10
-rw-r--r--spec/models/namespace_spec.rb6
-rw-r--r--spec/models/namespaces/project_namespace_spec.rb4
-rw-r--r--spec/requests/api/internal/kubernetes_spec.rb4
-rw-r--r--spec/rubocop/cop/sidekiq_load_balancing/worker_data_consistency_spec.rb (renamed from spec/rubocop/cop/worker_data_consistency_spec.rb)4
-rw-r--r--spec/rubocop/cop/sidekiq_load_balancing/worker_data_consistency_with_deduplication_spec.rb166
-rw-r--r--spec/services/ci/register_job_service_spec.rb14
-rw-r--r--spec/services/clusters/agents/refresh_authorization_service_spec.rb108
151 files changed, 2730 insertions, 375 deletions
diff --git a/.rubocop.yml b/.rubocop.yml
index cc1b9258e1b..141ba874b21 100644
--- a/.rubocop.yml
+++ b/.rubocop.yml
@@ -40,7 +40,7 @@ AllCops:
- 'db/ci_migrate/*.rb' # since the `db/ci_migrate` is a symlinked to `db/migrate`
# Use absolute path to avoid orphan directories with changed workspace root.
CacheRootDirectory: <%= Dir.getwd %>/tmp
- MaxFilesInCache: 25000
+ MaxFilesInCache: 30000
Cop/AvoidKeywordArgumentsInSidekiqWorkers:
Enabled: true
diff --git a/Gemfile b/Gemfile
index c71ac209ecf..19f77c1ee82 100644
--- a/Gemfile
+++ b/Gemfile
@@ -522,7 +522,7 @@ gem 'lockbox', '~> 0.6.2'
gem 'valid_email', '~> 0.1'
# JSON
-gem 'json', '~> 2.3.0'
+gem 'json', '~> 2.5.1'
gem 'json_schemer', '~> 0.2.18'
gem 'oj', '~> 3.10.6'
gem 'multi_json', '~> 1.14.1'
diff --git a/Gemfile.lock b/Gemfile.lock
index 87f78455ee0..007694e6c28 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -657,7 +657,7 @@ GEM
character_set (~> 1.4)
regexp_parser (~> 2.1)
regexp_property_values (~> 1.0)
- json (2.3.0)
+ json (2.5.1)
json-jwt (1.13.0)
activesupport (>= 4.2)
aes_key_wrap
@@ -1509,7 +1509,7 @@ DEPENDENCIES
ipaddress (~> 0.8.3)
jira-ruby (~> 2.1.4)
js_regex (~> 3.7)
- json (~> 2.3.0)
+ json (~> 2.5.1)
json_schemer (~> 0.2.18)
jwt (~> 2.1.0)
kaminari (~> 1.0)
diff --git a/app/assets/javascripts/boards/components/board_settings_sidebar.vue b/app/assets/javascripts/boards/components/board_settings_sidebar.vue
index cfcdd470cf4..6b7c08d05a5 100644
--- a/app/assets/javascripts/boards/components/board_settings_sidebar.vue
+++ b/app/assets/javascripts/boards/components/board_settings_sidebar.vue
@@ -36,7 +36,7 @@ export default {
return this.glFeatures.wipLimits && !this.isEpicBoard;
},
activeList() {
- return this.boardLists[this.activeId];
+ return this.boardLists[this.activeId] || {};
},
activeListLabel() {
return this.activeList.label;
@@ -81,9 +81,26 @@ export default {
v-bind="$attrs"
class="js-board-settings-sidebar gl-absolute"
:open="isSidebarOpen"
+ variant="sidebar"
@close="unsetActiveId"
>
- <template #title>{{ $options.listSettingsText }}</template>
+ <template #title>
+ <h2 class="gl-my-0 gl-font-size-h2 gl-line-height-24">
+ {{ $options.listSettingsText }}
+ </h2>
+ </template>
+ <template #header>
+ <div v-if="canAdminList && activeList.id" class="gl-mt-3">
+ <gl-button
+ variant="danger"
+ category="secondary"
+ size="small"
+ data-testid="remove-list"
+ @click.stop="deleteBoard"
+ >{{ __('Remove list') }}
+ </gl-button>
+ </div>
+ </template>
<template v-if="isSidebarOpen">
<div v-if="boardListType === ListType.label">
<label class="js-list-label gl-display-block">{{ listTypeTitle }}</label>
@@ -103,16 +120,6 @@ export default {
v-if="isWipLimitsOn"
:max-issue-count="activeList.maxIssueCount"
/>
- <div v-if="canAdminList && !activeList.preset && activeList.id" class="gl-mt-4">
- <gl-button
- variant="danger"
- category="secondary"
- icon="remove"
- data-testid="remove-list"
- @click.stop="deleteBoard"
- >{{ __('Remove list') }}
- </gl-button>
- </div>
</template>
</gl-drawer>
</mounting-portal>
diff --git a/app/assets/javascripts/clusters_list/components/clusters.vue b/app/assets/javascripts/clusters_list/components/clusters.vue
index 8f81d967126..0d1534d20e0 100644
--- a/app/assets/javascripts/clusters_list/components/clusters.vue
+++ b/app/assets/javascripts/clusters_list/components/clusters.vue
@@ -205,6 +205,8 @@ export default {
:items="clusters"
:fields="fields"
stacked="md"
+ head-variant="white"
+ thead-class="gl-border-b-solid gl-border-b-1 gl-border-b-gray-100"
class="qa-clusters-table"
data-testid="cluster_list_table"
>
diff --git a/app/assets/javascripts/packages_and_registries/settings/project/components/registry_settings_app.vue b/app/assets/javascripts/packages_and_registries/settings/project/components/registry_settings_app.vue
index 6da2e3a47e8..bf286c84d5f 100644
--- a/app/assets/javascripts/packages_and_registries/settings/project/components/registry_settings_app.vue
+++ b/app/assets/javascripts/packages_and_registries/settings/project/components/registry_settings_app.vue
@@ -88,7 +88,7 @@ export default {
<template>
<section data-testid="registry-settings-app">
<cleanup-policy-enabled-alert v-if="showCleanupPolicyOnAlert" :project-path="projectPath" />
- <settings-block default-expanded>
+ <settings-block :collapsible="false">
<template #title> {{ __('Clean up image tags') }}</template>
<template #description>
<span data-testid="description">
diff --git a/app/assets/javascripts/vue_shared/components/notes/system_note.vue b/app/assets/javascripts/vue_shared/components/notes/system_note.vue
index d62a346355a..755e6f1f224 100644
--- a/app/assets/javascripts/vue_shared/components/notes/system_note.vue
+++ b/app/assets/javascripts/vue_shared/components/notes/system_note.vue
@@ -95,6 +95,9 @@ export default {
methods: {
...mapActions(['fetchDescriptionVersion', 'softDeleteDescriptionVersion']),
},
+ safeHtmlConfig: {
+ ADD_TAGS: ['use'], // to support icon SVGs
+ },
};
</script>
@@ -104,7 +107,7 @@ export default {
:class="{ target: isTargetNote, 'pr-0': shouldShowDescriptionVersion }"
class="note system-note note-wrapper"
>
- <div class="timeline-icon" v-html="iconHtml /* eslint-disable-line vue/no-v-html */"></div>
+ <div v-safe-html:[$options.safeHtmlConfig]="iconHtml" class="timeline-icon"></div>
<div class="timeline-content">
<div class="note-header">
<note-header :author="note.author" :created-at="note.created_at" :note-id="note.id">
diff --git a/app/assets/javascripts/vue_shared/components/settings/settings_block.stories.js b/app/assets/javascripts/vue_shared/components/settings/settings_block.stories.js
new file mode 100644
index 00000000000..5242743ad30
--- /dev/null
+++ b/app/assets/javascripts/vue_shared/components/settings/settings_block.stories.js
@@ -0,0 +1,26 @@
+import SettingsBlock from './settings_block.vue';
+
+export default {
+ component: SettingsBlock,
+ title: 'vue_shared/components/settings/settings_block',
+};
+
+const Template = (args, { argTypes }) => ({
+ components: { SettingsBlock },
+ props: Object.keys(argTypes),
+ template: `
+ <settings-block v-bind="$props">
+ <template #title>Settings section title</template>
+ <template #description>Settings section description</template>
+ <template #default>
+ <p>Content</p>
+ <p>More content</p>
+ <p>Content</p>
+ <p>More content...</p>
+ <p>Content</p>
+ </template>
+ </settings-block>
+ `,
+});
+
+export const Default = Template.bind({});
diff --git a/app/assets/javascripts/vue_shared/components/settings/settings_block.vue b/app/assets/javascripts/vue_shared/components/settings/settings_block.vue
index e8f517f40a6..e75fedbb1d7 100644
--- a/app/assets/javascripts/vue_shared/components/settings/settings_block.vue
+++ b/app/assets/javascripts/vue_shared/components/settings/settings_block.vue
@@ -1,5 +1,7 @@
<script>
import { GlButton } from '@gitlab/ui';
+import { uniqueId } from 'lodash';
+
import { __ } from '~/locale';
export default {
@@ -15,50 +17,99 @@ export default {
default: false,
required: false,
},
+ collapsible: {
+ type: Boolean,
+ default: true,
+ required: false,
+ },
},
data() {
return {
- sectionExpanded: false,
+ // Non-collapsible sections should always be expanded.
+ // For collapsible sections, fall back to defaultExpanded.
+ sectionExpanded: !this.collapsible || this.defaultExpanded,
};
},
computed: {
- expanded() {
- return this.defaultExpanded || this.sectionExpanded;
- },
toggleText() {
- return this.expanded ? __('Collapse') : __('Expand');
+ const { collapseText, expandText } = this.$options.i18n;
+ return this.sectionExpanded ? collapseText : expandText;
+ },
+ settingsContentId() {
+ return uniqueId('settings_content_');
+ },
+ settingsLabelId() {
+ return uniqueId('settings_label_');
+ },
+ toggleButtonAriaLabel() {
+ const { collapseAriaLabel, expandAriaLabel } = this.$options.i18n;
+ return this.sectionExpanded ? collapseAriaLabel : expandAriaLabel;
+ },
+ ariaExpanded() {
+ return String(this.sectionExpanded);
},
},
methods: {
toggleSectionExpanded() {
this.sectionExpanded = !this.sectionExpanded;
+
+ if (this.sectionExpanded) {
+ this.$refs.settingsContent.focus();
+ }
},
},
+ i18n: {
+ collapseText: __('Collapse'),
+ expandText: __('Expand'),
+ collapseAriaLabel: __('Collapse settings section'),
+ expandAriaLabel: __('Expand settings section'),
+ },
};
</script>
<template>
- <section class="settings" :class="{ 'no-animate': !slideAnimated, expanded }">
+ <section class="settings" :class="{ 'no-animate': !slideAnimated, expanded: sectionExpanded }">
<div class="settings-header">
<h4>
<span
+ v-if="collapsible"
+ :id="settingsLabelId"
role="button"
tabindex="0"
class="gl-cursor-pointer"
- data-testid="section-title"
+ :aria-controls="settingsContentId"
+ :aria-expanded="ariaExpanded"
+ data-testid="section-title-button"
@click="toggleSectionExpanded"
+ @keydown.enter.space="toggleSectionExpanded"
>
<slot name="title"></slot>
</span>
+ <template v-else>
+ <slot name="title"></slot>
+ </template>
</h4>
- <gl-button @click="toggleSectionExpanded">
+ <gl-button
+ v-if="collapsible"
+ :aria-controls="settingsContentId"
+ :aria-expanded="ariaExpanded"
+ :aria-label="toggleButtonAriaLabel"
+ @click="toggleSectionExpanded"
+ >
{{ toggleText }}
</gl-button>
<p>
<slot name="description"></slot>
</p>
</div>
- <div class="settings-content">
+ <div
+ :id="settingsContentId"
+ ref="settingsContent"
+ :aria-labelledby="settingsLabelId"
+ tabindex="-1"
+ role="region"
+ class="settings-content"
+ >
<slot></slot>
</div>
</section>
diff --git a/app/models/ci/pending_build.rb b/app/models/ci/pending_build.rb
index db50022d2c8..ccad6290fac 100644
--- a/app/models/ci/pending_build.rb
+++ b/app/models/ci/pending_build.rb
@@ -13,6 +13,13 @@ module Ci
scope :ref_protected, -> { where(protected: true) }
scope :queued_before, ->(time) { where(arel_table[:created_at].lt(time)) }
scope :with_instance_runners, -> { where(instance_runners_enabled: true) }
+ scope :for_tags, ->(tag_ids) do
+ if tag_ids.present?
+ where('ci_pending_builds.tag_ids <@ ARRAY[?]::int[]', Array.wrap(tag_ids))
+ else
+ where("ci_pending_builds.tag_ids = '{}'")
+ end
+ end
class << self
def upsert_from_build!(build)
diff --git a/app/models/clusters/agent.rb b/app/models/clusters/agent.rb
index 8c19a691144..cf6d95fc6df 100644
--- a/app/models/clusters/agent.rb
+++ b/app/models/clusters/agent.rb
@@ -13,6 +13,9 @@ module Clusters
has_many :group_authorizations, class_name: 'Clusters::Agents::GroupAuthorization'
has_many :authorized_groups, class_name: '::Group', through: :group_authorizations, source: :group
+ has_many :project_authorizations, class_name: 'Clusters::Agents::ProjectAuthorization'
+ has_many :authorized_projects, class_name: '::Project', through: :project_authorizations, source: :project
+
scope :ordered_by_name, -> { order(:name) }
scope :with_name, -> (name) { where(name: name) }
diff --git a/app/models/clusters/agents/project_authorization.rb b/app/models/clusters/agents/project_authorization.rb
new file mode 100644
index 00000000000..1c71a0a432a
--- /dev/null
+++ b/app/models/clusters/agents/project_authorization.rb
@@ -0,0 +1,14 @@
+# frozen_string_literal: true
+
+module Clusters
+ module Agents
+ class ProjectAuthorization < ApplicationRecord
+ self.table_name = 'agent_project_authorizations'
+
+ belongs_to :agent, class_name: 'Clusters::Agent', optional: false
+ belongs_to :project, class_name: '::Project', optional: false
+
+ validates :config, json_schema: { filename: 'cluster_agent_authorization_configuration' }
+ end
+ end
+end
diff --git a/app/models/namespace.rb b/app/models/namespace.rb
index ded317c205c..53375b72e69 100644
--- a/app/models/namespace.rb
+++ b/app/models/namespace.rb
@@ -57,7 +57,7 @@ class Namespace < ApplicationRecord
has_one :admin_note, inverse_of: :namespace
accepts_nested_attributes_for :admin_note, update_only: true
- validates :owner, presence: true, if: ->(n) { n.type.nil? }
+ validates :owner, presence: true, if: ->(n) { n.owner_required? }
validates :name,
presence: true,
length: { maximum: 255 }
@@ -266,6 +266,10 @@ class Namespace < ApplicationRecord
type.nil? || type == Namespaces::UserNamespace.sti_name || !(group? || project?)
end
+ def owner_required?
+ user?
+ end
+
def find_fork_of(project)
return unless project.fork_network
diff --git a/app/models/namespaces/project_namespace.rb b/app/models/namespaces/project_namespace.rb
index 22ec550dee2..d1806c1c088 100644
--- a/app/models/namespaces/project_namespace.rb
+++ b/app/models/namespaces/project_namespace.rb
@@ -4,6 +4,8 @@ module Namespaces
class ProjectNamespace < Namespace
has_one :project, foreign_key: :project_namespace_id, inverse_of: :project_namespace
+ validates :project, presence: true
+
def self.sti_name
'Project'
end
diff --git a/app/services/ci/queue/build_queue_service.rb b/app/services/ci/queue/build_queue_service.rb
index 9c11c4e1be1..3276c427923 100644
--- a/app/services/ci/queue/build_queue_service.rb
+++ b/app/services/ci/queue/build_queue_service.rb
@@ -47,7 +47,7 @@ module Ci
def builds_for_project_runner
relation = new_builds
- .where(project: runner.projects.without_deleted.with_builds_enabled)
+ .where(project: runner_projects_relation)
order(relation)
end
@@ -87,6 +87,14 @@ module Ci
end
end
end
+
+ def runner_projects_relation
+ if ::Feature.enabled?(:ci_pending_builds_project_runners_decoupling, runner, default_enabled: :yaml)
+ runner.runner_projects.select(:project_id)
+ else
+ runner.projects.without_deleted.with_builds_enabled
+ end
+ end
end
end
end
diff --git a/app/services/ci/queue/pending_builds_strategy.rb b/app/services/ci/queue/pending_builds_strategy.rb
index 9bfcac23fc8..7a913e47df4 100644
--- a/app/services/ci/queue/pending_builds_strategy.rb
+++ b/app/services/ci/queue/pending_builds_strategy.rb
@@ -24,7 +24,7 @@ module Ci
def builds_matching_tag_ids(relation, ids)
if ::Feature.enabled?(:ci_queueing_denormalize_tags_information, runner, default_enabled: :yaml)
- relation.where('tag_ids <@ ARRAY[?]::int[]', runner.tags_ids)
+ relation.for_tags(runner.tags_ids)
else
relation.merge(CommitStatus.matches_tag_ids(ids, table: 'ci_pending_builds', column: 'build_id'))
end
diff --git a/app/services/clusters/agents/refresh_authorization_service.rb b/app/services/clusters/agents/refresh_authorization_service.rb
index 0da012da861..a9e3340dbf5 100644
--- a/app/services/clusters/agents/refresh_authorization_service.rb
+++ b/app/services/clusters/agents/refresh_authorization_service.rb
@@ -5,9 +5,10 @@ module Clusters
class RefreshAuthorizationService
include Gitlab::Utils::StrongMemoize
- AUTHORIZED_GROUP_LIMIT = 100
+ AUTHORIZED_ENTITY_LIMIT = 100
delegate :project, to: :agent, private: true
+ delegate :root_ancestor, to: :project, private: true
def initialize(agent, config:)
@agent = agent
@@ -15,6 +16,30 @@ module Clusters
end
def execute
+ refresh_projects!
+ refresh_groups!
+
+ true
+ end
+
+ private
+
+ attr_reader :agent, :config
+
+ def refresh_projects!
+ if allowed_project_configurations.present?
+ project_ids = allowed_project_configurations.map { |config| config.fetch(:project_id) }
+
+ agent.with_lock do
+ agent.project_authorizations.upsert_all(allowed_project_configurations, unique_by: [:agent_id, :project_id])
+ agent.project_authorizations.where.not(project_id: project_ids).delete_all # rubocop: disable CodeReuse/ActiveRecord
+ end
+ else
+ agent.project_authorizations.delete_all(:delete_all)
+ end
+ end
+
+ def refresh_groups!
if allowed_group_configurations.present?
group_ids = allowed_group_configurations.map { |config| config.fetch(:group_id) }
@@ -25,35 +50,57 @@ module Clusters
else
agent.group_authorizations.delete_all(:delete_all)
end
-
- true
end
- private
+ def allowed_project_configurations
+ strong_memoize(:allowed_project_configurations) do
+ project_entries = extract_config_entries(entity: 'projects')
- attr_reader :agent, :config
+ if project_entries
+ allowed_projects.where_full_path_in(project_entries.keys).map do |project|
+ { project_id: project.id, config: project_entries[project.full_path] }
+ end
+ end
+ end
+ end
def allowed_group_configurations
strong_memoize(:allowed_group_configurations) do
- group_entries = config.dig('ci_access', 'groups')&.first(AUTHORIZED_GROUP_LIMIT)
+ group_entries = extract_config_entries(entity: 'groups')
if group_entries
- groups_by_path = group_entries.index_by { |config| config.delete('id') }
-
- allowed_groups.where_full_path_in(groups_by_path.keys).map do |group|
- { group_id: group.id, config: groups_by_path[group.full_path] }
+ allowed_groups.where_full_path_in(group_entries.keys).map do |group|
+ { group_id: group.id, config: group_entries[group.full_path] }
end
end
end
end
+ def extract_config_entries(entity:)
+ config.dig('ci_access', entity)
+ &.first(AUTHORIZED_ENTITY_LIMIT)
+ &.index_by { |config| config.delete('id') }
+ end
+
+ def allowed_projects
+ if group_root_ancestor?
+ root_ancestor.all_projects
+ else
+ ::Project.none
+ end
+ end
+
def allowed_groups
- if project.root_ancestor.group?
- project.root_ancestor.self_and_descendants
+ if group_root_ancestor?
+ root_ancestor.self_and_descendants
else
::Group.none
end
end
+
+ def group_root_ancestor?
+ root_ancestor.group?
+ end
end
end
end
diff --git a/bin/pngquant b/bin/pngquant
new file mode 100755
index 00000000000..8434e9d3ec9
--- /dev/null
+++ b/bin/pngquant
@@ -0,0 +1,64 @@
+#!/usr/bin/env ruby
+# frozen_string_literal: true
+
+require 'rails'
+require 'png_quantizator'
+require 'parallel'
+require 'rainbow/ext/string'
+require_relative '../tooling/lib/tooling/images'
+
+return if Rails.env.production?
+
+def usage
+ puts <<~EOF
+ Usage: #{$0} [compress|lint] [PATH..]
+
+ compress Compress all documentation PNG images using pngquant.
+ lint Checks that all documentation PNG images have been compressed with pngquant.
+
+ PATH One or more files or directories. If empty, `doc/**/*.png` is used.
+
+ EOF
+end
+
+command = ARGV.shift
+paths = ARGV.presence || ['doc']
+
+files = paths.flat_map do |path|
+ File.directory?(path) ? Dir.glob(File.join(path, '/**/*.png')) : path
+end
+
+case command
+when 'compress'
+ puts "Compressing #{files.size} PNG files"
+
+ Parallel.each(files) do |file|
+ was_uncompressed, savings = Tooling::Image.compress_image(file)
+
+ if was_uncompressed
+ puts "#{file} was reduced by #{savings} bytes"
+ end
+ end
+when 'lint'
+ puts "Checking #{files.size} PNG files"
+
+ uncompressed_files = Parallel.map(files) do |file|
+ is_uncompressed, _ = Tooling::Image.compress_image(file, true)
+ if is_uncompressed
+ puts "Uncompressed file detected: ".color(:red) + file
+ file
+ end
+ end.compact
+
+ if uncompressed_files.empty?
+ puts "All documentation images are optimally compressed!".color(:green)
+ else
+ warn(
+ "The #{uncompressed_files.size} image(s) above have not been optimally compressed using pngquant.".color(:red),
+ 'Please run "bin/pngquant compress" and commit the result.'
+ )
+ abort
+ end
+else
+ usage
+end
diff --git a/config/events/20210915205037_alert_integrations_view_alert_integrations_list.yml b/config/events/20210915205037_alert_integrations_view_alert_integrations_list.yml
new file mode 100644
index 00000000000..505cdf4c288
--- /dev/null
+++ b/config/events/20210915205037_alert_integrations_view_alert_integrations_list.yml
@@ -0,0 +1,21 @@
+description: "Show alert integrations list"
+category: "`Alert Integrations`"
+action: view_alert_integrations_list
+label_description: ""
+property_description: ""
+value_description: ""
+extra_properties:
+identifiers:
+product_section: ops
+product_stage: monitor
+product_group: group::monitor
+product_category:
+milestone: "13.5"
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/44549
+distributions:
+- ce
+- ee
+tiers:
+- free
+- premium
+- ultimate
diff --git a/config/events/20210915205038_default_click_button.yml b/config/events/20210915205038_default_click_button.yml
new file mode 100644
index 00000000000..d6fadb735d1
--- /dev/null
+++ b/config/events/20210915205038_default_click_button.yml
@@ -0,0 +1,21 @@
+description: "Click 2FA codes related buttons: copy, download, print..."
+category: default
+action: click_button
+label_description: "Action button name"
+property_description: ""
+value_description: ""
+extra_properties:
+identifiers:
+product_section: dev
+product_stage: manage
+product_group: group::compliance
+product_category:
+milestone: "13.7"
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/49510
+distributions:
+- ce
+- ee
+tiers:
+- free
+- premium
+- ultimate
diff --git a/config/events/20210915205039_default_copy_keyboard_shortcut.yml b/config/events/20210915205039_default_copy_keyboard_shortcut.yml
new file mode 100644
index 00000000000..c1f792de52e
--- /dev/null
+++ b/config/events/20210915205039_default_copy_keyboard_shortcut.yml
@@ -0,0 +1,21 @@
+description: "Copy 2FA codes with keyboard shortcut"
+category: default
+action: copy_keyboard_shortcut
+label_description: "Action button name"
+property_description: ""
+value_description: ""
+extra_properties:
+identifiers:
+product_section: dev
+product_stage: manage
+product_group: group::compliance
+product_category:
+milestone: "13.7"
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/49510
+distributions:
+- ce
+- ee
+tiers:
+- free
+- premium
+- ultimate
diff --git a/config/events/20210915205040_default_generic.yml b/config/events/20210915205040_default_generic.yml
new file mode 100644
index 00000000000..2c8a4d3ef4c
--- /dev/null
+++ b/config/events/20210915205040_default_generic.yml
@@ -0,0 +1,21 @@
+description: "Show a congratulation on first pipeline"
+category: default
+action: generic
+label_description: "`congratulate_first_pipeline`"
+property_description: "`[admin | maintainer | developer | owner]`"
+value_description: ""
+extra_properties:
+identifiers:
+product_section: growth
+product_stage: growth
+product_group: group::expansion
+product_category:
+milestone: "12.10"
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/28378
+distributions:
+- ce
+- ee
+tiers:
+- free
+- premium
+- ultimate
diff --git a/config/events/20210915205041_default_generic.yml b/config/events/20210915205041_default_generic.yml
new file mode 100644
index 00000000000..7d4f5efe3ba
--- /dev/null
+++ b/config/events/20210915205041_default_generic.yml
@@ -0,0 +1,21 @@
+description: "Show GitLab CI suggestion popover"
+category: default
+action: generic
+label_description: "`suggest_commit_first_project_gitlab_ci_yml`"
+property_description: "`[admin | maintainer | developer | owner]`"
+value_description: ""
+extra_properties:
+identifiers:
+product_section: growth
+product_stage: growth
+product_group: group::expansion
+product_category:
+milestone: "12.9"
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/26605
+distributions:
+- ce
+- ee
+tiers:
+- free
+- premium
+- ultimate
diff --git a/config/events/20210915205050_code_quality_walkthrough_commit_ci_file_dismissed.yml b/config/events/20210915205050_code_quality_walkthrough_commit_ci_file_dismissed.yml
new file mode 100644
index 00000000000..7ce1a3d9b76
--- /dev/null
+++ b/config/events/20210915205050_code_quality_walkthrough_commit_ci_file_dismissed.yml
@@ -0,0 +1,21 @@
+description: "Commit CI file dismissed"
+category: "`code_quality_walkthrough`"
+action: commit_ci_file_dismissed
+label_description: ""
+property_description: ""
+value_description: ""
+extra_properties:
+identifiers:
+product_section: growth
+product_stage: growth
+product_group: group::activation
+product_category:
+milestone: "13.12"
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/58900
+distributions:
+- ce
+- ee
+tiers:
+- free
+- premium
+- ultimate
diff --git a/config/events/20210915205051_code_quality_walkthrough_commit_ci_file_displayed.yml b/config/events/20210915205051_code_quality_walkthrough_commit_ci_file_displayed.yml
new file mode 100644
index 00000000000..4fbece2fef8
--- /dev/null
+++ b/config/events/20210915205051_code_quality_walkthrough_commit_ci_file_displayed.yml
@@ -0,0 +1,21 @@
+description: "Commit CI file displayed"
+category: "`code_quality_walkthrough`"
+action: commit_ci_file_displayed
+label_description: ""
+property_description: ""
+value_description: ""
+extra_properties:
+identifiers:
+product_section: growth
+product_stage: growth
+product_group: group::activation
+product_category:
+milestone: "13.12"
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/58900
+distributions:
+- ce
+- ee
+tiers:
+- free
+- premium
+- ultimate
diff --git a/config/events/20210915205052_code_quality_walkthrough_commit_created.yml b/config/events/20210915205052_code_quality_walkthrough_commit_created.yml
new file mode 100644
index 00000000000..5e8d8a1250a
--- /dev/null
+++ b/config/events/20210915205052_code_quality_walkthrough_commit_created.yml
@@ -0,0 +1,21 @@
+description: "Commit created"
+category: "`code_quality_walkthrough`"
+action: commit_created
+label_description: ""
+property_description: ""
+value_description: ""
+extra_properties:
+identifiers:
+product_section: growth
+product_stage: growth
+product_group: group::activation
+product_category:
+milestone: "13.12"
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/58900
+distributions:
+- ce
+- ee
+tiers:
+- free
+- premium
+- ultimate
diff --git a/config/events/20210915205053_code_quality_walkthrough_cta_clicked.yml b/config/events/20210915205053_code_quality_walkthrough_cta_clicked.yml
new file mode 100644
index 00000000000..684bb681045
--- /dev/null
+++ b/config/events/20210915205053_code_quality_walkthrough_cta_clicked.yml
@@ -0,0 +1,21 @@
+description: "Click empty state CTA"
+category: "`code_quality_walkthrough`"
+action: cta_clicked
+label_description: ""
+property_description: ""
+value_description: ""
+extra_properties:
+identifiers:
+product_section: growth
+product_stage: growth
+product_group: group::activation
+product_category:
+milestone: "13.12"
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/58900
+distributions:
+- ce
+- ee
+tiers:
+- free
+- premium
+- ultimate
diff --git a/config/events/20210915205054_code_quality_walkthrough_failed_pipeline_displayed.yml b/config/events/20210915205054_code_quality_walkthrough_failed_pipeline_displayed.yml
new file mode 100644
index 00000000000..517da8eac13
--- /dev/null
+++ b/config/events/20210915205054_code_quality_walkthrough_failed_pipeline_displayed.yml
@@ -0,0 +1,21 @@
+description: "Show failed pipeline"
+category: "`code_quality_walkthrough`"
+action: failed_pipeline_displayed
+label_description: ""
+property_description: ""
+value_description: ""
+extra_properties:
+identifiers:
+product_section: growth
+product_stage: growth
+product_group: group::activation
+product_category:
+milestone: "13.12"
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/58900
+distributions:
+- ce
+- ee
+tiers:
+- free
+- premium
+- ultimate
diff --git a/config/events/20210915205055_code_quality_walkthrough_failed_pipeline_view_logs.yml b/config/events/20210915205055_code_quality_walkthrough_failed_pipeline_view_logs.yml
new file mode 100644
index 00000000000..adb4400f288
--- /dev/null
+++ b/config/events/20210915205055_code_quality_walkthrough_failed_pipeline_view_logs.yml
@@ -0,0 +1,21 @@
+description: "Show failed pipeline logs"
+category: "`code_quality_walkthrough`"
+action: failed_pipeline_view_logs
+label_description: ""
+property_description: ""
+value_description: ""
+extra_properties:
+identifiers:
+product_section: growth
+product_stage: growth
+product_group: group::activation
+product_category:
+milestone: "13.12"
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/58900
+distributions:
+- ce
+- ee
+tiers:
+- free
+- premium
+- ultimate
diff --git a/config/events/20210915205056_code_quality_walkthrough_running_pipeline_dismissed.yml b/config/events/20210915205056_code_quality_walkthrough_running_pipeline_dismissed.yml
new file mode 100644
index 00000000000..7fcff9644f4
--- /dev/null
+++ b/config/events/20210915205056_code_quality_walkthrough_running_pipeline_dismissed.yml
@@ -0,0 +1,21 @@
+description: "Dismiss running pipeline"
+category: "`code_quality_walkthrough`"
+action: running_pipeline_dismissed
+label_description: ""
+property_description: ""
+value_description: ""
+extra_properties:
+identifiers:
+product_section: growth
+product_stage: growth
+product_group: group::activation
+product_category:
+milestone: "13.12"
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/58900
+distributions:
+- ce
+- ee
+tiers:
+- free
+- premium
+- ultimate
diff --git a/config/events/20210915205057_code_quality_walkthrough_running_pipeline_displayed.yml b/config/events/20210915205057_code_quality_walkthrough_running_pipeline_displayed.yml
new file mode 100644
index 00000000000..b7faa132d8b
--- /dev/null
+++ b/config/events/20210915205057_code_quality_walkthrough_running_pipeline_displayed.yml
@@ -0,0 +1,21 @@
+description: "Show running pipeline"
+category: "`code_quality_walkthrough`"
+action: running_pipeline_displayed
+label_description: ""
+property_description: ""
+value_description: ""
+extra_properties:
+identifiers:
+product_section: growth
+product_stage: growth
+product_group: group::activation
+product_category:
+milestone: "13.12"
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/58900
+distributions:
+- ce
+- ee
+tiers:
+- free
+- premium
+- ultimate
diff --git a/config/events/20210915205058_code_quality_walkthrough_success_pipeline_displayed.yml b/config/events/20210915205058_code_quality_walkthrough_success_pipeline_displayed.yml
new file mode 100644
index 00000000000..d5909cdab89
--- /dev/null
+++ b/config/events/20210915205058_code_quality_walkthrough_success_pipeline_displayed.yml
@@ -0,0 +1,21 @@
+description: "Show succeeded pipeline"
+category: "`code_quality_walkthrough`"
+action: success_pipeline_displayed
+label_description: ""
+property_description: ""
+value_description: ""
+extra_properties:
+identifiers:
+product_section: growth
+product_stage: growth
+product_group: group::activation
+product_category:
+milestone: "13.12"
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/58900
+distributions:
+- ce
+- ee
+tiers:
+- free
+- premium
+- ultimate
diff --git a/config/events/20210915205059_code_quality_walkthrough_success_pipeline_view_logs.yml b/config/events/20210915205059_code_quality_walkthrough_success_pipeline_view_logs.yml
new file mode 100644
index 00000000000..253bf3c3577
--- /dev/null
+++ b/config/events/20210915205059_code_quality_walkthrough_success_pipeline_view_logs.yml
@@ -0,0 +1,21 @@
+description: "Show succeeded pipeline logs"
+category: "`code_quality_walkthrough`"
+action: success_pipeline_view_logs
+label_description: ""
+property_description: ""
+value_description: ""
+extra_properties:
+identifiers:
+product_section: growth
+product_stage: growth
+product_group: group::activation
+product_category:
+milestone: "13.12"
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/58900
+distributions:
+- ce
+- ee
+tiers:
+- free
+- premium
+- ultimate
diff --git a/config/events/20210915205100_default_execute_toolbar_control.yml b/config/events/20210915205100_default_execute_toolbar_control.yml
new file mode 100644
index 00000000000..8a9ea7fd068
--- /dev/null
+++ b/config/events/20210915205100_default_execute_toolbar_control.yml
@@ -0,0 +1,21 @@
+description: "Execute toolbar control"
+category: default
+action: execute_toolbar_control
+label_description: "`content_editor`"
+property_description: "Content type"
+value_description: "Context data: [heading] 3, [heading] 2"
+extra_properties:
+identifiers:
+product_section: dev
+product_stage: create
+product_group: group::editor
+product_category:
+milestone: "13.12"
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/61065
+distributions:
+- ce
+- ee
+tiers:
+- free
+- premium
+- ultimate
diff --git a/config/events/20210915205101_default_execute_keyboard_shortcut.yml b/config/events/20210915205101_default_execute_keyboard_shortcut.yml
new file mode 100644
index 00000000000..2cd59d96ce7
--- /dev/null
+++ b/config/events/20210915205101_default_execute_keyboard_shortcut.yml
@@ -0,0 +1,21 @@
+description: "Execute keyboard shortcut"
+category: default
+action: execute_keyboard_shortcut
+label_description: "`content_editor`"
+property_description: ""
+value_description: ""
+extra_properties:
+identifiers:
+product_section: dev
+product_stage: create
+product_group: group::editor
+product_category:
+milestone: "14.0"
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/61248
+distributions:
+- ce
+- ee
+tiers:
+- free
+- premium
+- ultimate
diff --git a/config/events/20210915205102_default_execute_input_rule.yml b/config/events/20210915205102_default_execute_input_rule.yml
new file mode 100644
index 00000000000..4d0e518d07b
--- /dev/null
+++ b/config/events/20210915205102_default_execute_input_rule.yml
@@ -0,0 +1,21 @@
+description: "Execute input rule"
+category: default
+action: execute_input_rule
+label_description: "`content_editor`"
+property_description: ""
+value_description: ""
+extra_properties:
+identifiers:
+product_section: dev
+product_stage: create
+product_group: group::editor
+product_category:
+milestone: "14.0"
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/61248
+distributions:
+- ce
+- ee
+tiers:
+- free
+- premium
+- ultimate
diff --git a/config/events/20210915205103_default_execute_bubble_menu_control.yml b/config/events/20210915205103_default_execute_bubble_menu_control.yml
new file mode 100644
index 00000000000..03f4cd7e289
--- /dev/null
+++ b/config/events/20210915205103_default_execute_bubble_menu_control.yml
@@ -0,0 +1,21 @@
+description: "Execute bubble menu control"
+category: default
+action: execute_bubble_menu_control
+label_description: "`content_editor`"
+property_description: ""
+value_description: ""
+extra_properties:
+identifiers:
+product_section: dev
+product_stage: create
+product_group: group::editor
+product_category:
+milestone: "14.2"
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/67363
+distributions:
+- ce
+- ee
+tiers:
+- free
+- premium
+- ultimate
diff --git a/config/events/20210915205107_default_click_link.yml b/config/events/20210915205107_default_click_link.yml
new file mode 100644
index 00000000000..cb9d3a3dffa
--- /dev/null
+++ b/config/events/20210915205107_default_click_link.yml
@@ -0,0 +1,21 @@
+description: "Open frequent items dropdown"
+category: default
+action: click_link
+label_description: "`[dropdown_type]_dropdown_frequent_items_list_item`"
+property_description: ""
+value_description: ""
+extra_properties:
+identifiers:
+product_section: dev
+product_stage: create
+product_group: group::editor
+product_category:
+milestone: "13.7"
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/47589
+distributions:
+- ce
+- ee
+tiers:
+- free
+- premium
+- ultimate
diff --git a/config/events/20210915205108_default_type_search_query.yml b/config/events/20210915205108_default_type_search_query.yml
new file mode 100644
index 00000000000..274613bd201
--- /dev/null
+++ b/config/events/20210915205108_default_type_search_query.yml
@@ -0,0 +1,21 @@
+description: "Type search query"
+category: default
+action: type_search_query
+label_description: "`[dropdown_type]_dropdown_frequent_items_search_input`"
+property_description: ""
+value_description: ""
+extra_properties:
+identifiers:
+product_section: dev
+product_stage: create
+product_group: group::editor
+product_category:
+milestone: "13.7"
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/47589
+distributions:
+- ce
+- ee
+tiers:
+- free
+- premium
+- ultimate
diff --git a/config/events/20210915205109_default_invite_members_banner_button_clicked.yml b/config/events/20210915205109_default_invite_members_banner_button_clicked.yml
new file mode 100644
index 00000000000..adbea725085
--- /dev/null
+++ b/config/events/20210915205109_default_invite_members_banner_button_clicked.yml
@@ -0,0 +1,21 @@
+description: "Click invite members banner"
+category: default
+action: invite_members_banner_button_clicked
+label_description: "`invite_members_banner`"
+property_description: ""
+value_description: ""
+extra_properties:
+identifiers:
+product_section: growth
+product_stage: growth
+product_group: group::expansion
+product_category:
+milestone: "13.4"
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/41774
+distributions:
+- ce
+- ee
+tiers:
+- free
+- premium
+- ultimate
diff --git a/config/events/20210915205110_default_invite_members_banner_dismissed.yml b/config/events/20210915205110_default_invite_members_banner_dismissed.yml
new file mode 100644
index 00000000000..2041df2f058
--- /dev/null
+++ b/config/events/20210915205110_default_invite_members_banner_dismissed.yml
@@ -0,0 +1,21 @@
+description: "Dismiss invite members banner"
+category: default
+action: invite_members_banner_dismissed
+label_description: "`invite_members_banner`"
+property_description: ""
+value_description: ""
+extra_properties:
+identifiers:
+product_section: growth
+product_stage: growth
+product_group: group::expansion
+product_category:
+milestone: "13.4"
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/41774
+distributions:
+- ce
+- ee
+tiers:
+- free
+- premium
+- ultimate
diff --git a/config/events/20210915205111_default_change_discussion_sort_direction.yml b/config/events/20210915205111_default_change_discussion_sort_direction.yml
new file mode 100644
index 00000000000..cb6e31910d3
--- /dev/null
+++ b/config/events/20210915205111_default_change_discussion_sort_direction.yml
@@ -0,0 +1,21 @@
+description: "Change discussion sort direction"
+category: default
+action: change_discussion_sort_direction
+label_description: ""
+property_description: "`[asc | desc]`"
+value_description: ""
+extra_properties:
+identifiers:
+product_section: dev
+product_stage: plan
+product_group: group::product_planning
+product_category:
+milestone: "12.10"
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/28717
+distributions:
+- ce
+- ee
+tiers:
+- free
+- premium
+- ultimate
diff --git a/config/events/20210915205112_packages_delete_package.yml b/config/events/20210915205112_packages_delete_package.yml
new file mode 100644
index 00000000000..568a800a8e6
--- /dev/null
+++ b/config/events/20210915205112_packages_delete_package.yml
@@ -0,0 +1,21 @@
+description: "Delete package"
+category: "`UI:[MavenPackages | NpmPackages | ConanPackages | undefined]`"
+action: delete_package
+label_description: ""
+property_description: ""
+value_description: ""
+extra_properties:
+identifiers:
+product_section: dev
+product_stage: create
+product_group: group::ecosystem
+product_category:
+milestone: "13.4"
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/41668
+distributions:
+- ce
+- ee
+tiers:
+- free
+- premium
+- ultimate
diff --git a/config/events/20210915205113_packages_request_delete_package_file.yml b/config/events/20210915205113_packages_request_delete_package_file.yml
new file mode 100644
index 00000000000..6c0def2db07
--- /dev/null
+++ b/config/events/20210915205113_packages_request_delete_package_file.yml
@@ -0,0 +1,21 @@
+description: "Request deletion of items from the package file list"
+category: "`UI:[MavenPackages | NpmPackages | ConanPackages | undefined]`"
+action: request_delete_package_file
+label_description: ""
+property_description: ""
+value_description: ""
+extra_properties:
+identifiers:
+product_section: ops
+product_stage: package
+product_group: group::package
+product_category:
+milestone: "14.0"
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/62179
+distributions:
+- ce
+- ee
+tiers:
+- free
+- premium
+- ultimate
diff --git a/config/events/20210915205114_packages_delete_package_file.yml b/config/events/20210915205114_packages_delete_package_file.yml
new file mode 100644
index 00000000000..97d38b12b26
--- /dev/null
+++ b/config/events/20210915205114_packages_delete_package_file.yml
@@ -0,0 +1,21 @@
+description: "Delete items from the package file list"
+category: "`UI:[MavenPackages | NpmPackages | ConanPackages | undefined]`"
+action: delete_package_file
+label_description: ""
+property_description: ""
+value_description: ""
+extra_properties:
+identifiers:
+product_section: ops
+product_stage: package
+product_group: group::package
+product_category:
+milestone: "14.0"
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/62179
+distributions:
+- ce
+- ee
+tiers:
+- free
+- premium
+- ultimate
diff --git a/config/events/20210915205115_packages_pull_package.yml b/config/events/20210915205115_packages_pull_package.yml
new file mode 100644
index 00000000000..a45ad6cf945
--- /dev/null
+++ b/config/events/20210915205115_packages_pull_package.yml
@@ -0,0 +1,21 @@
+description: "Download package"
+category: "`UI:[MavenPackages | NpmPackages | ConanPackages | undefined]`"
+action: pull_package
+label_description: ""
+property_description: ""
+value_description: ""
+extra_properties:
+identifiers:
+product_section: ops
+product_stage: package
+product_group: group::package
+product_category:
+milestone: "13.7"
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/48451
+distributions:
+- ce
+- ee
+tiers:
+- free
+- premium
+- ultimate
diff --git a/config/events/20210915205116_packages_cancel_delete_package.yml b/config/events/20210915205116_packages_cancel_delete_package.yml
new file mode 100644
index 00000000000..ca9f90e5df4
--- /dev/null
+++ b/config/events/20210915205116_packages_cancel_delete_package.yml
@@ -0,0 +1,21 @@
+description: "Cancel package deletion"
+category: "`UI:[MavenPackages | NpmPackages | ConanPackages | undefined]`"
+action: cancel_delete_package
+label_description: ""
+property_description: ""
+value_description: ""
+extra_properties:
+identifiers:
+product_section: ops
+product_stage: package
+product_group: group::package
+product_category:
+milestone: "14.0"
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/62179
+distributions:
+- ce
+- ee
+tiers:
+- free
+- premium
+- ultimate
diff --git a/config/events/20210915205117_packages_cancel_delete_package_file.yml b/config/events/20210915205117_packages_cancel_delete_package_file.yml
new file mode 100644
index 00000000000..9985af6bf58
--- /dev/null
+++ b/config/events/20210915205117_packages_cancel_delete_package_file.yml
@@ -0,0 +1,21 @@
+description: "Cancel deletion of items from the package file list"
+category: "`UI:[MavenPackages | NpmPackages | ConanPackages | undefined]`"
+action: cancel_delete_package_file
+label_description: ""
+property_description: ""
+value_description: ""
+extra_properties:
+identifiers:
+product_section: ops
+product_stage: package
+product_group: group::package
+product_category:
+milestone: "14.0"
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/62179
+distributions:
+- ce
+- ee
+tiers:
+- free
+- premium
+- ultimate
diff --git a/config/events/20210915205118_default_copy_composer_registry_include_command.yml b/config/events/20210915205118_default_copy_composer_registry_include_command.yml
new file mode 100644
index 00000000000..31714aacf50
--- /dev/null
+++ b/config/events/20210915205118_default_copy_composer_registry_include_command.yml
@@ -0,0 +1,21 @@
+description: "Copy Composer registry include command"
+category: default
+action: copy_composer_registry_include_command
+label_description: "`code_instruction`"
+property_description: ""
+value_description: ""
+extra_properties:
+identifiers:
+product_section: ops
+product_stage: package
+product_group: group::package
+product_category:
+milestone: "13.3"
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/38779
+distributions:
+- ce
+- ee
+tiers:
+- free
+- premium
+- ultimate
diff --git a/config/events/20210915205119_default_copy_composer_package_include_command.yml b/config/events/20210915205119_default_copy_composer_package_include_command.yml
new file mode 100644
index 00000000000..e2a923c0c3a
--- /dev/null
+++ b/config/events/20210915205119_default_copy_composer_package_include_command.yml
@@ -0,0 +1,21 @@
+description: "Copy Composer package include command"
+category: default
+action: copy_composer_package_include_command
+label_description: "`code_instruction`"
+property_description: ""
+value_description: ""
+extra_properties:
+identifiers:
+product_section: ops
+product_stage: package
+product_group: group::package
+product_category:
+milestone: "13.3"
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/38779
+distributions:
+- ce
+- ee
+tiers:
+- free
+- premium
+- ultimate
diff --git a/config/events/20210915205125_default_copy_gradle_install_command.yml b/config/events/20210915205125_default_copy_gradle_install_command.yml
new file mode 100644
index 00000000000..5b016d38fbd
--- /dev/null
+++ b/config/events/20210915205125_default_copy_gradle_install_command.yml
@@ -0,0 +1,21 @@
+description: "Copy Gradle install command"
+category: default
+action: copy_gradle_install_command
+label_description: "`code_instruction`"
+property_description: ""
+value_description: ""
+extra_properties:
+identifiers:
+product_section: ops
+product_stage: package
+product_group: group::package
+product_category:
+milestone: "13.10"
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/55738
+distributions:
+- ce
+- ee
+tiers:
+- free
+- premium
+- ultimate
diff --git a/config/events/20210915205126_default_copy_gradle_add_to_source_command.yml b/config/events/20210915205126_default_copy_gradle_add_to_source_command.yml
new file mode 100644
index 00000000000..fa7c58eb2ef
--- /dev/null
+++ b/config/events/20210915205126_default_copy_gradle_add_to_source_command.yml
@@ -0,0 +1,21 @@
+description: "Copy Gradle add to source command"
+category: default
+action: copy_gradle_add_to_source_command
+label_description: "`code_instruction`"
+property_description: ""
+value_description: ""
+extra_properties:
+identifiers:
+product_section: ops
+product_stage: package
+product_group: group::package
+product_category:
+milestone: "13.10"
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/55738
+distributions:
+- ce
+- ee
+tiers:
+- free
+- premium
+- ultimate
diff --git a/config/events/20210915205127_default_copy_kotlin_install_command.yml b/config/events/20210915205127_default_copy_kotlin_install_command.yml
new file mode 100644
index 00000000000..187a500ba03
--- /dev/null
+++ b/config/events/20210915205127_default_copy_kotlin_install_command.yml
@@ -0,0 +1,21 @@
+description: "Copy Kotlin install command"
+category: default
+action: copy_kotlin_install_command
+label_description: "`code_instruction`"
+property_description: ""
+value_description: ""
+extra_properties:
+identifiers:
+product_section: ops
+product_stage: package
+product_group: group::package
+product_category:
+milestone: "13.12"
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/60097
+distributions:
+- ce
+- ee
+tiers:
+- free
+- premium
+- ultimate
diff --git a/config/events/20210915205128_default_copy_kotlin_add_to_source_command.yml b/config/events/20210915205128_default_copy_kotlin_add_to_source_command.yml
new file mode 100644
index 00000000000..d848afec43f
--- /dev/null
+++ b/config/events/20210915205128_default_copy_kotlin_add_to_source_command.yml
@@ -0,0 +1,21 @@
+description: "Copy Kotlin add to source command"
+category: default
+action: copy_kotlin_add_to_source_command
+label_description: "`code_instruction`"
+property_description: ""
+value_description: ""
+extra_properties:
+identifiers:
+product_section: ops
+product_stage: package
+product_group: group::package
+product_category:
+milestone: "13.12"
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/60097
+distributions:
+- ce
+- ee
+tiers:
+- free
+- premium
+- ultimate
diff --git a/config/events/20210915205140_default_reset_form.yml b/config/events/20210915205140_default_reset_form.yml
new file mode 100644
index 00000000000..c6a57c45971
--- /dev/null
+++ b/config/events/20210915205140_default_reset_form.yml
@@ -0,0 +1,21 @@
+description: "Reset Docker form"
+category: default
+action: reset_form
+label_description: "`docker_container_retention_and_expiration_policies`"
+property_description: ""
+value_description: ""
+extra_properties:
+identifiers:
+product_section: ops
+product_stage: package
+product_group: group::package
+product_category:
+milestone: "12.8"
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/23844
+distributions:
+- ce
+- ee
+tiers:
+- free
+- premium
+- ultimate
diff --git a/config/events/20210915205141_default_submit_form.yml b/config/events/20210915205141_default_submit_form.yml
new file mode 100644
index 00000000000..2e822fe5242
--- /dev/null
+++ b/config/events/20210915205141_default_submit_form.yml
@@ -0,0 +1,21 @@
+description: "Submit Docker form"
+category: default
+action: submit_form
+label_description: "`docker_container_retention_and_expiration_policies`"
+property_description: ""
+value_description: ""
+extra_properties:
+identifiers:
+product_section: ops
+product_stage: package
+product_group: group::package
+product_category:
+milestone: "12.8"
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/23844
+distributions:
+- ce
+- ee
+tiers:
+- free
+- premium
+- ultimate
diff --git a/config/events/20210915205142_default_click_dismiss.yml b/config/events/20210915205142_default_click_dismiss.yml
new file mode 100644
index 00000000000..73605ad7878
--- /dev/null
+++ b/config/events/20210915205142_default_click_dismiss.yml
@@ -0,0 +1,21 @@
+description: "Dismiss home page banner"
+category: default
+action: click_dismiss
+label_description: ""
+property_description: ""
+value_description: ""
+extra_properties:
+identifiers:
+product_section: growth
+product_stage: growth
+product_group: group::expansion
+product_category:
+milestone: "13.4"
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/39752
+distributions:
+- ce
+- ee
+tiers:
+- free
+- premium
+- ultimate
diff --git a/config/events/20210915205143_default_show_home_page_banner.yml b/config/events/20210915205143_default_show_home_page_banner.yml
new file mode 100644
index 00000000000..b33e51205a3
--- /dev/null
+++ b/config/events/20210915205143_default_show_home_page_banner.yml
@@ -0,0 +1,21 @@
+description: "Show home page banner"
+category: default
+action: show_home_page_banner
+label_description: ""
+property_description: ""
+value_description: ""
+extra_properties:
+identifiers:
+product_section: growth
+product_stage: growth
+product_group: group::expansion
+product_category:
+milestone: "13.4"
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/39752
+distributions:
+- ce
+- ee
+tiers:
+- free
+- premium
+- ultimate
diff --git a/config/events/20210915205145_default_content_editor_loaded.yml b/config/events/20210915205145_default_content_editor_loaded.yml
new file mode 100644
index 00000000000..fd223e5368d
--- /dev/null
+++ b/config/events/20210915205145_default_content_editor_loaded.yml
@@ -0,0 +1,21 @@
+description: "Wiki content editor loaded"
+category: default
+action: content_editor_loaded
+label_description: "`wiki_content_editor`"
+property_description: ""
+value_description: ""
+extra_properties:
+identifiers:
+product_section: dev
+product_stage: create
+product_group: group::editor
+product_category:
+milestone: "14.0"
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/62919
+distributions:
+- ce
+- ee
+tiers:
+- free
+- premium
+- ultimate
diff --git a/config/events/20210915205146_default_saved_using_content_editor.yml b/config/events/20210915205146_default_saved_using_content_editor.yml
new file mode 100644
index 00000000000..805ed60a992
--- /dev/null
+++ b/config/events/20210915205146_default_saved_using_content_editor.yml
@@ -0,0 +1,21 @@
+description: "Wiki saved using content editor"
+category: default
+action: saved_using_content_editor
+label_description: "`wiki_content_editor`"
+property_description: ""
+value_description: ""
+extra_properties:
+identifiers:
+product_section: dev
+product_stage: create
+product_group: group::editor
+product_category:
+milestone: "14.0"
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/62919
+distributions:
+- ce
+- ee
+tiers:
+- free
+- premium
+- ultimate
diff --git a/config/events/20210915205147_default_browse_templates.yml b/config/events/20210915205147_default_browse_templates.yml
new file mode 100644
index 00000000000..e7ae4423bc1
--- /dev/null
+++ b/config/events/20210915205147_default_browse_templates.yml
@@ -0,0 +1,21 @@
+description: "Browse Pipeline editor templates"
+category: default
+action: browse_templates
+label_description: "`pipeline_editor`"
+property_description: ""
+value_description: ""
+extra_properties:
+identifiers:
+product_section: ops
+product_stage: verify
+product_group: group::pipeline_authoring
+product_category:
+milestone: "14.1"
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/64349
+distributions:
+- ce
+- ee
+tiers:
+- free
+- premium
+- ultimate
diff --git a/config/events/20210915205148_default_template_clicked.yml b/config/events/20210915205148_default_template_clicked.yml
new file mode 100644
index 00000000000..277190af855
--- /dev/null
+++ b/config/events/20210915205148_default_template_clicked.yml
@@ -0,0 +1,21 @@
+description: "Click pipeline empty state template"
+category: default
+action: template_clicked
+label_description: "Template name or \"Getting-Started\""
+property_description: ""
+value_description: ""
+extra_properties:
+identifiers:
+product_section: growth
+product_stage: growth
+product_group: group::activation
+product_category:
+milestone: "13.11"
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/58808
+distributions:
+- ce
+- ee
+tiers:
+- free
+- premium
+- ultimate
diff --git a/config/events/20210915205149_default_dismiss_banner.yml b/config/events/20210915205149_default_dismiss_banner.yml
new file mode 100644
index 00000000000..7eb23fca354
--- /dev/null
+++ b/config/events/20210915205149_default_dismiss_banner.yml
@@ -0,0 +1,21 @@
+description: "Dismiss Terraform banner"
+category: default
+action: dismiss_banner
+label_description: "`terraform_banner`"
+property_description: ""
+value_description: ""
+extra_properties:
+identifiers:
+product_section: ops
+product_stage: configure
+product_group: group::configure
+product_category:
+milestone: "14.3"
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/68467
+distributions:
+- ce
+- ee
+tiers:
+- free
+- premium
+- ultimate
diff --git a/config/events/20210915205150_default_click_button.yml b/config/events/20210915205150_default_click_button.yml
new file mode 100644
index 00000000000..356117f6cb6
--- /dev/null
+++ b/config/events/20210915205150_default_click_button.yml
@@ -0,0 +1,21 @@
+description: "Click Terraform banner button"
+category: default
+action: click_button
+label_description: "`terraform_banner`"
+property_description: ""
+value_description: ""
+extra_properties:
+identifiers:
+product_section: ops
+product_stage: configure
+product_group: group::configure
+product_category:
+milestone: "14.3"
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/68467
+distributions:
+- ce
+- ee
+tiers:
+- free
+- premium
+- ultimate
diff --git a/config/events/20210915205151_default_click_dropdown.yml b/config/events/20210915205151_default_click_dropdown.yml
new file mode 100644
index 00000000000..61c04baab8d
--- /dev/null
+++ b/config/events/20210915205151_default_click_dropdown.yml
@@ -0,0 +1,21 @@
+description: "Click quickstart dropdown"
+category: default
+action: click_dropdown
+label_description: "`quickstart_dropdown`"
+property_description: ""
+value_description: ""
+extra_properties:
+identifiers:
+product_section: ops
+product_stage: package
+product_group: group::package
+product_category:
+milestone: "12.10"
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/27990
+distributions:
+- ce
+- ee
+tiers:
+- free
+- premium
+- ultimate
diff --git a/config/events/20210915205152_default_click_copy_login.yml b/config/events/20210915205152_default_click_copy_login.yml
new file mode 100644
index 00000000000..05283da858d
--- /dev/null
+++ b/config/events/20210915205152_default_click_copy_login.yml
@@ -0,0 +1,21 @@
+description: "Copy quickstart dropdown login"
+category: default
+action: click_copy_login
+label_description: "`quickstart_dropdown`"
+property_description: ""
+value_description: ""
+extra_properties:
+identifiers:
+product_section: ops
+product_stage: package
+product_group: group::package
+product_category:
+milestone: "12.10"
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/27990
+distributions:
+- ce
+- ee
+tiers:
+- free
+- premium
+- ultimate
diff --git a/config/events/20210915205153_default_click_copy_build.yml b/config/events/20210915205153_default_click_copy_build.yml
new file mode 100644
index 00000000000..86ee97b4b3a
--- /dev/null
+++ b/config/events/20210915205153_default_click_copy_build.yml
@@ -0,0 +1,21 @@
+description: "Copy quickstart dropdown build"
+category: default
+action: click_copy_build
+label_description: "`quickstart_dropdown`"
+property_description: ""
+value_description: ""
+extra_properties:
+identifiers:
+product_section: ops
+product_stage: package
+product_group: group::package
+product_category:
+milestone: "12.10"
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/27990
+distributions:
+- ce
+- ee
+tiers:
+- free
+- premium
+- ultimate
diff --git a/config/events/20210915205154_default_click_copy_push.yml b/config/events/20210915205154_default_click_copy_push.yml
new file mode 100644
index 00000000000..87de403e7de
--- /dev/null
+++ b/config/events/20210915205154_default_click_copy_push.yml
@@ -0,0 +1,21 @@
+description: "Copy quickstart dropdown push"
+category: default
+action: click_copy_push
+label_description: "`quickstart_dropdown`"
+property_description: ""
+value_description: ""
+extra_properties:
+identifiers:
+product_section: ops
+product_stage: package
+product_group: group::package
+product_category:
+milestone: "12.10"
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/27990
+distributions:
+- ce
+- ee
+tiers:
+- free
+- premium
+- ultimate
diff --git a/config/events/20210915205155_default_click_button.yml b/config/events/20210915205155_default_click_button.yml
new file mode 100644
index 00000000000..42fa0c97066
--- /dev/null
+++ b/config/events/20210915205155_default_click_button.yml
@@ -0,0 +1,21 @@
+description: "Click registry tag delete button"
+category: default
+action: click_button
+label_description: "`[bulk_registry_tag_delete | registry_tag_delete]`"
+property_description: ""
+value_description: ""
+extra_properties:
+identifiers:
+product_section: ops
+product_stage: package
+product_group: group::package
+product_category:
+milestone: "12.8"
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/23154
+distributions:
+- ce
+- ee
+tiers:
+- free
+- premium
+- ultimate
diff --git a/config/events/20210915205156_default_confirm_delete.yml b/config/events/20210915205156_default_confirm_delete.yml
new file mode 100644
index 00000000000..cc9481592ae
--- /dev/null
+++ b/config/events/20210915205156_default_confirm_delete.yml
@@ -0,0 +1,21 @@
+description: "Confirm registry tag deletion"
+category: default
+action: confirm_delete
+label_description: "`[bulk_registry_tag_delete | registry_tag_delete]`"
+property_description: ""
+value_description: ""
+extra_properties:
+identifiers:
+product_section: ops
+product_stage: package
+product_group: group::package
+product_category:
+milestone: "12.8"
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/23154
+distributions:
+- ce
+- ee
+tiers:
+- free
+- premium
+- ultimate
diff --git a/config/events/20210915205157_default_cancel_delete.yml b/config/events/20210915205157_default_cancel_delete.yml
new file mode 100644
index 00000000000..425fe8089d3
--- /dev/null
+++ b/config/events/20210915205157_default_cancel_delete.yml
@@ -0,0 +1,21 @@
+description: "Cancel registry tag deletion"
+category: default
+action: cancel_delete
+label_description: "`[bulk_registry_tag_delete | registry_tag_delete]`"
+property_description: ""
+value_description: ""
+extra_properties:
+identifiers:
+product_section: ops
+product_stage: package
+product_group: group::package
+product_category:
+milestone: "12.8"
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/23154
+distributions:
+- ce
+- ee
+tiers:
+- free
+- premium
+- ultimate
diff --git a/config/events/20210915205158_default_click_button.yml b/config/events/20210915205158_default_click_button.yml
new file mode 100644
index 00000000000..56329982262
--- /dev/null
+++ b/config/events/20210915205158_default_click_button.yml
@@ -0,0 +1,21 @@
+description: "Click registry repository delete button"
+category: default
+action: click_button
+label_description: "`registry_repository_delete`"
+property_description: ""
+value_description: ""
+extra_properties:
+identifiers:
+product_section: ops
+product_stage: package
+product_group: group::package
+product_category:
+milestone: "12.8"
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/23154
+distributions:
+- ce
+- ee
+tiers:
+- free
+- premium
+- ultimate
diff --git a/config/events/20210915205159_default_confirm_delete.yml b/config/events/20210915205159_default_confirm_delete.yml
new file mode 100644
index 00000000000..1939df91927
--- /dev/null
+++ b/config/events/20210915205159_default_confirm_delete.yml
@@ -0,0 +1,21 @@
+description: "Confirm registry repository deletion"
+category: default
+action: confirm_delete
+label_description: "`registry_repository_delete`"
+property_description: ""
+value_description: ""
+extra_properties:
+identifiers:
+product_section: ops
+product_stage: package
+product_group: group::package
+product_category:
+milestone: "12.8"
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/23154
+distributions:
+- ce
+- ee
+tiers:
+- free
+- premium
+- ultimate
diff --git a/config/events/20210915205200_default_cancel_delete.yml b/config/events/20210915205200_default_cancel_delete.yml
new file mode 100644
index 00000000000..99623717a84
--- /dev/null
+++ b/config/events/20210915205200_default_cancel_delete.yml
@@ -0,0 +1,21 @@
+description: "Cancel registry repository deletion"
+category: default
+action: cancel_delete
+label_description: "`registry_repository_delete`"
+property_description: ""
+value_description: ""
+extra_properties:
+identifiers:
+product_section: ops
+product_stage: package
+product_group: group::package
+product_category:
+milestone: "12.8"
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/23154
+distributions:
+- ce
+- ee
+tiers:
+- free
+- premium
+- ultimate
diff --git a/config/events/20210915205202_default_generic.yml b/config/events/20210915205202_default_generic.yml
new file mode 100644
index 00000000000..3e6169f1c68
--- /dev/null
+++ b/config/events/20210915205202_default_generic.yml
@@ -0,0 +1,21 @@
+description: "Show Pipeline suggestion on new MRs"
+category: default
+action: generic
+label_description: "`no_pipeline_noticed`"
+property_description: "`[admin | maintainer | developer | owner]`"
+value_description: ""
+extra_properties:
+identifiers:
+product_section: growth
+product_stage: growth
+product_group: group::expansion
+product_category:
+milestone: "13.12"
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/35069
+distributions:
+- ce
+- ee
+tiers:
+- free
+- premium
+- ultimate
diff --git a/config/events/20210915205203_default_click_tab.yml b/config/events/20210915205203_default_click_tab.yml
new file mode 100644
index 00000000000..e61ce545f7b
--- /dev/null
+++ b/config/events/20210915205203_default_click_tab.yml
@@ -0,0 +1,21 @@
+description: "Click tab on new namespace welcoming component"
+category: default
+action: click_tab
+label_description: "Panel name"
+property_description: ""
+value_description: ""
+extra_properties:
+identifiers:
+product_section: dev
+product_stage: manage
+product_group: group::import
+product_category:
+milestone: "13.12"
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/59452
+distributions:
+- ce
+- ee
+tiers:
+- free
+- premium
+- ultimate
diff --git a/config/events/20210915205204_default_click_whats_new_drawer.yml b/config/events/20210915205204_default_click_whats_new_drawer.yml
new file mode 100644
index 00000000000..8a994510fc7
--- /dev/null
+++ b/config/events/20210915205204_default_click_whats_new_drawer.yml
@@ -0,0 +1,21 @@
+description: "Show \"What's new\" drawer"
+category: default
+action: click_whats_new_drawer
+label_description: "`namespace_id`"
+property_description: "ID of namespace"
+value_description: ""
+extra_properties:
+identifiers:
+product_section: growth
+product_stage: growth
+product_group: group::adoption
+product_category:
+milestone: "13.5"
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/42653
+distributions:
+- ce
+- ee
+tiers:
+- free
+- premium
+- ultimate
diff --git a/config/events/20210915205207_default_click_dropdown.yml b/config/events/20210915205207_default_click_dropdown.yml
new file mode 100644
index 00000000000..d4d63e1bd2b
--- /dev/null
+++ b/config/events/20210915205207_default_click_dropdown.yml
@@ -0,0 +1,21 @@
+description: "Click Epic's board switcher"
+category: default
+action: click_dropdown
+label_description: "`board_switcher`"
+property_description: ""
+value_description: ""
+extra_properties:
+identifiers:
+product_section: dev
+product_stage: plan
+product_group: group::product_planning
+product_category:
+milestone: "14.0"
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/63765
+distributions:
+- ce
+- ee
+tiers:
+- free
+- premium
+- ultimate
diff --git a/config/feature_flags/development/ci_pending_builds_project_runners_decoupling.yml b/config/feature_flags/development/ci_pending_builds_project_runners_decoupling.yml
new file mode 100644
index 00000000000..82acc907507
--- /dev/null
+++ b/config/feature_flags/development/ci_pending_builds_project_runners_decoupling.yml
@@ -0,0 +1,8 @@
+---
+name: ci_pending_builds_project_runners_decoupling
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/70415
+rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/341005
+milestone: '14.4'
+type: development
+group: group::pipeline execution
+default_enabled: false
diff --git a/config/metrics/settings/20210915152326_service_ping_features_enabled.yml b/config/metrics/settings/20210915152326_service_ping_features_enabled.yml
new file mode 100644
index 00000000000..41101f0ff9d
--- /dev/null
+++ b/config/metrics/settings/20210915152326_service_ping_features_enabled.yml
@@ -0,0 +1,23 @@
+---
+key_path: settings.service_ping_features_enabled
+name: "service_ping_features_enabled"
+description: Whether Service Ping features are enabled
+product_section: growth
+product_stage: growth
+product_group: group::product intelligence
+product_category: collection
+value_type: boolean
+status: active
+milestone: "14.3"
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/70332
+time_frame: none
+data_source: database
+instrumentation_class: ServicePingFeaturesMetric
+data_category: optional
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
diff --git a/data/deprecations/14-3-repository-push-audit-events.yml b/data/deprecations/14-3-repository-push-audit-events.yml
index 9f9f9809663..6fafd7ba6db 100644
--- a/data/deprecations/14-3-repository-push-audit-events.yml
+++ b/data/deprecations/14-3-repository-push-audit-events.yml
@@ -2,7 +2,7 @@
announcement_milestone: "14.3" # The milestone when this feature was first announced as deprecated.
removal_milestone: "15.0" # the milestone when this feature is planned to be removed
body: | # Do not modify this line, instead modify the lines below.
- Audit events for [repository events](../administration/audit_events.md#repository-push) are now deprecated and will be removed in GitLab 15.0.
+ Audit events for [repository events](https://docs.gitlab.com/ee/administration/audit_events.html#repository-push) are now deprecated and will be removed in GitLab 15.0.
These events have always been disabled by default and had to be manually enabled with a
feature flag. Enabling them can cause too many events to be generated which can
@@ -10,5 +10,5 @@
stage: Manage
tiers: Premium
issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/337993
- documentation_url: ../administration/audit_events.md
+ documentation_url: https://docs.gitlab.com/ee/administration/audit_events.html#repository-push
announcement_date: 2021-09-02 # https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69024
diff --git a/data/deprecations/deprecation_omniauth-kerberos_gem.yml b/data/deprecations/deprecation_omniauth-kerberos_gem.yml
index 9abaa343812..f7068552ff9 100644
--- a/data/deprecations/deprecation_omniauth-kerberos_gem.yml
+++ b/data/deprecations/deprecation_omniauth-kerberos_gem.yml
@@ -4,12 +4,12 @@
body: | # Do not modify this line, instead modify the lines below.
The `omniauth-kerberos` gem will be removed in our next major release, GitLab 15.0.
- This gem has not been maintained and has very little usage. We therefore plan to remove support for this authentication method and recommend using the Kerberos [SPNEGO](https://en.wikipedia.org/wiki/SPNEGO) integration instead. You can follow the [upgrade instructions](../integration/kerberos.md#upgrading-from-password-based-to-ticket-based-kerberos-sign-ins) to upgrade from the `omniauth-kerberos` integration to the supported one.
+ This gem has not been maintained and has very little usage. We therefore plan to remove support for this authentication method and recommend using the Kerberos [SPNEGO](https://en.wikipedia.org/wiki/SPNEGO) integration instead. You can follow the [upgrade instructions](https://docs.gitlab.com/ee/integration/kerberos.html#upgrading-from-password-based-to-ticket-based-kerberos-sign-ins) to upgrade from the `omniauth-kerberos` integration to the supported one.
Note that we are not deprecating the Kerberos SPNEGO integration, only the old password-based Kerberos integration.
stage: Manage
- tiers: [Premium, Ultimate]
+ tiers: [Premium, Ultimate]
issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/337384
- documentation_url: ../integration/kerberos.md#upgrading-from-password-based-to-ticket-based-kerberos-sign-ins
+ documentation_url: https://docs.gitlab.com/ee/integration/kerberos.html#upgrading-from-password-based-to-ticket-based-kerberos-sign-ins
announcement_date: 2021-22-09
diff --git a/db/migrate/20210913010411_create_agent_project_authorizations.rb b/db/migrate/20210913010411_create_agent_project_authorizations.rb
new file mode 100644
index 00000000000..02b6ac677e0
--- /dev/null
+++ b/db/migrate/20210913010411_create_agent_project_authorizations.rb
@@ -0,0 +1,14 @@
+# frozen_string_literal: true
+
+class CreateAgentProjectAuthorizations < Gitlab::Database::Migration[1.0]
+ def change
+ create_table :agent_project_authorizations do |t|
+ t.bigint :project_id, null: false
+ t.bigint :agent_id, null: false
+ t.jsonb :config, null: false
+
+ t.index :project_id
+ t.index [:agent_id, :project_id], unique: true
+ end
+ end
+end
diff --git a/db/migrate/20210913010432_add_agent_project_authorizations_foreign_keys.rb b/db/migrate/20210913010432_add_agent_project_authorizations_foreign_keys.rb
new file mode 100644
index 00000000000..545fc125950
--- /dev/null
+++ b/db/migrate/20210913010432_add_agent_project_authorizations_foreign_keys.rb
@@ -0,0 +1,20 @@
+# frozen_string_literal: true
+
+class AddAgentProjectAuthorizationsForeignKeys < Gitlab::Database::Migration[1.0]
+ disable_ddl_transaction!
+
+ def up
+ add_concurrent_foreign_key :agent_project_authorizations, :projects, column: :project_id
+ add_concurrent_foreign_key :agent_project_authorizations, :cluster_agents, column: :agent_id
+ end
+
+ def down
+ with_lock_retries do
+ remove_foreign_key_if_exists :agent_project_authorizations, column: :project_id
+ end
+
+ with_lock_retries do
+ remove_foreign_key_if_exists :agent_project_authorizations, column: :agent_id
+ end
+ end
+end
diff --git a/db/schema_migrations/20210913010411 b/db/schema_migrations/20210913010411
new file mode 100644
index 00000000000..8ae59414604
--- /dev/null
+++ b/db/schema_migrations/20210913010411
@@ -0,0 +1 @@
+71d51d1ac74f5c559bf41b23e5677af7228ba824da835afbe0f2299695912c19 \ No newline at end of file
diff --git a/db/schema_migrations/20210913010432 b/db/schema_migrations/20210913010432
new file mode 100644
index 00000000000..db2f53a8d06
--- /dev/null
+++ b/db/schema_migrations/20210913010432
@@ -0,0 +1 @@
+172e77890657dd82c6ce770c286894731f6ef7fbcffb4b4fc97e0a41d132b8e8 \ No newline at end of file
diff --git a/db/structure.sql b/db/structure.sql
index 6ccb49396d0..bfc2abf08f5 100644
--- a/db/structure.sql
+++ b/db/structure.sql
@@ -9652,6 +9652,22 @@ CREATE SEQUENCE agent_group_authorizations_id_seq
ALTER SEQUENCE agent_group_authorizations_id_seq OWNED BY agent_group_authorizations.id;
+CREATE TABLE agent_project_authorizations (
+ id bigint NOT NULL,
+ project_id bigint NOT NULL,
+ agent_id bigint NOT NULL,
+ config jsonb NOT NULL
+);
+
+CREATE SEQUENCE agent_project_authorizations_id_seq
+ START WITH 1
+ INCREMENT BY 1
+ NO MINVALUE
+ NO MAXVALUE
+ CACHE 1;
+
+ALTER SEQUENCE agent_project_authorizations_id_seq OWNED BY agent_project_authorizations.id;
+
CREATE TABLE alert_management_alert_assignees (
id bigint NOT NULL,
user_id bigint NOT NULL,
@@ -20862,6 +20878,8 @@ ALTER TABLE ONLY abuse_reports ALTER COLUMN id SET DEFAULT nextval('abuse_report
ALTER TABLE ONLY agent_group_authorizations ALTER COLUMN id SET DEFAULT nextval('agent_group_authorizations_id_seq'::regclass);
+ALTER TABLE ONLY agent_project_authorizations ALTER COLUMN id SET DEFAULT nextval('agent_project_authorizations_id_seq'::regclass);
+
ALTER TABLE ONLY alert_management_alert_assignees ALTER COLUMN id SET DEFAULT nextval('alert_management_alert_assignees_id_seq'::regclass);
ALTER TABLE ONLY alert_management_alert_user_mentions ALTER COLUMN id SET DEFAULT nextval('alert_management_alert_user_mentions_id_seq'::regclass);
@@ -22195,6 +22213,9 @@ ALTER TABLE ONLY abuse_reports
ALTER TABLE ONLY agent_group_authorizations
ADD CONSTRAINT agent_group_authorizations_pkey PRIMARY KEY (id);
+ALTER TABLE ONLY agent_project_authorizations
+ ADD CONSTRAINT agent_project_authorizations_pkey PRIMARY KEY (id);
+
ALTER TABLE ONLY alert_management_alert_assignees
ADD CONSTRAINT alert_management_alert_assignees_pkey PRIMARY KEY (id);
@@ -24141,6 +24162,10 @@ CREATE UNIQUE INDEX index_agent_group_authorizations_on_agent_id_and_group_id ON
CREATE INDEX index_agent_group_authorizations_on_group_id ON agent_group_authorizations USING btree (group_id);
+CREATE UNIQUE INDEX index_agent_project_authorizations_on_agent_id_and_project_id ON agent_project_authorizations USING btree (agent_id, project_id);
+
+CREATE INDEX index_agent_project_authorizations_on_project_id ON agent_project_authorizations USING btree (project_id);
+
CREATE INDEX index_alert_assignees_on_alert_id ON alert_management_alert_assignees USING btree (alert_id);
CREATE UNIQUE INDEX index_alert_assignees_on_user_id_and_alert_id ON alert_management_alert_assignees USING btree (user_id, alert_id);
@@ -27423,6 +27448,9 @@ ALTER TABLE ONLY analytics_devops_adoption_segments
ALTER TABLE ONLY user_details
ADD CONSTRAINT fk_190e4fcc88 FOREIGN KEY (provisioned_by_group_id) REFERENCES namespaces(id) ON DELETE SET NULL;
+ALTER TABLE ONLY agent_project_authorizations
+ ADD CONSTRAINT fk_1d30bb4987 FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE;
+
ALTER TABLE ONLY vulnerabilities
ADD CONSTRAINT fk_1d37cddf91 FOREIGN KEY (epic_id) REFERENCES epics(id) ON DELETE SET NULL;
@@ -27906,6 +27934,9 @@ ALTER TABLE ONLY external_status_checks_protected_branches
ALTER TABLE ONLY issue_assignees
ADD CONSTRAINT fk_b7d881734a FOREIGN KEY (issue_id) REFERENCES issues(id) ON DELETE CASCADE;
+ALTER TABLE ONLY agent_project_authorizations
+ ADD CONSTRAINT fk_b7fe9b4777 FOREIGN KEY (agent_id) REFERENCES cluster_agents(id) ON DELETE CASCADE;
+
ALTER TABLE ONLY ci_trigger_requests
ADD CONSTRAINT fk_b8ec8b7245 FOREIGN KEY (trigger_id) REFERENCES ci_triggers(id) ON DELETE CASCADE;
diff --git a/doc/administration/gitaly/praefect.md b/doc/administration/gitaly/praefect.md
index d58bb1e88b5..eb666f1caf4 100644
--- a/doc/administration/gitaly/praefect.md
+++ b/doc/administration/gitaly/praefect.md
@@ -275,7 +275,7 @@ you need to prepare PostgreSQL server with [setup instruction](#manual-database-
```ruby
pgbouncer['databases'] = {
- # Other database configuation including gitlabhq_production
+ # Other database configuration including gitlabhq_production
...
praefect_production: {
diff --git a/doc/administration/operations/puma.md b/doc/administration/operations/puma.md
index faffb727a34..775761d655d 100644
--- a/doc/administration/operations/puma.md
+++ b/doc/administration/operations/puma.md
@@ -70,7 +70,7 @@ restarting the workers. `per_worker_max_memory_mb` should be set to a
higher value if the worker killer is replacing workers too often.
Worker count is calculated based on CPU cores, so a small GitLab deployment
-wih 4-8 workers may experience performance issues if workers are being restarted
+with 4-8 workers may experience performance issues if workers are being restarted
frequently, once or more per minute. This is too often.
A higher value of `1200` or more would be beneficial if the server has free memory.
diff --git a/doc/administration/redis/troubleshooting.md b/doc/administration/redis/troubleshooting.md
index 0c1046ca22d..6ab3d55e06a 100644
--- a/doc/administration/redis/troubleshooting.md
+++ b/doc/administration/redis/troubleshooting.md
@@ -73,7 +73,7 @@ there may be something wrong with your configuration files or it can be related
to [this issue](https://github.com/redis/redis-rb/issues/531).
You must make sure you are defining the same value in `redis['master_name']`
-and `redis['master_pasword']` as you defined for your sentinel node.
+and `redis['master_password']` as you defined for your sentinel node.
The way the Redis connector `redis-rb` works with sentinel is a bit
non-intuitive. We try to hide the complexity in omnibus, but it still requires
diff --git a/doc/administration/reference_architectures/troubleshooting.md b/doc/administration/reference_architectures/troubleshooting.md
index 61d9dfea2a2..aabf4809b4a 100644
--- a/doc/administration/reference_architectures/troubleshooting.md
+++ b/doc/administration/reference_architectures/troubleshooting.md
@@ -158,7 +158,7 @@ there may be something wrong with your configuration files or it can be related
to [this issue](https://github.com/redis/redis-rb/issues/531).
You must make sure you are defining the same value in `redis['master_name']`
-and `redis['master_pasword']` as you defined for your sentinel node.
+and `redis['master_password']` as you defined for your sentinel node.
The way the Redis connector `redis-rb` works with sentinel is a bit
non-intuitive. We try to hide the complexity in omnibus, but it still requires
diff --git a/doc/api/graphql/reference/index.md b/doc/api/graphql/reference/index.md
index ba045bc3cf7..af5fb66a2e6 100644
--- a/doc/api/graphql/reference/index.md
+++ b/doc/api/graphql/reference/index.md
@@ -7637,6 +7637,19 @@ Configuration details for an Agent.
| ---- | ---- | ----------- |
| <a id="agentconfigurationagentname"></a>`agentName` | [`String`](#string) | Name of the agent. |
+### `AgentMetadata`
+
+Information about a connected Agent.
+
+#### Fields
+
+| Name | Type | Description |
+| ---- | ---- | ----------- |
+| <a id="agentmetadatacommit"></a>`commit` | [`String`](#string) | Agent version commit. |
+| <a id="agentmetadatapodname"></a>`podName` | [`String`](#string) | Name of the pod running the Agent. |
+| <a id="agentmetadatapodnamespace"></a>`podNamespace` | [`String`](#string) | Namespace of the pod running the Agent. |
+| <a id="agentmetadataversion"></a>`version` | [`String`](#string) | Agent version tag. |
+
### `AlertManagementAlert`
Describes an alert from the project's Alert Management.
@@ -8551,7 +8564,7 @@ Connection details for an Agent.
| ---- | ---- | ----------- |
| <a id="connectedagentconnectedat"></a>`connectedAt` | [`Time`](#time) | When the connection was established. |
| <a id="connectedagentconnectionid"></a>`connectionId` | [`BigInt`](#bigint) | ID of the connection. |
-| <a id="connectedagentmetadata"></a>`metadata` | [`JSON`](#json) | Information about the Agent. |
+| <a id="connectedagentmetadata"></a>`metadata` | [`AgentMetadata`](#agentmetadata) | Information about the Agent. |
### `ContainerExpirationPolicy`
diff --git a/doc/ci/environments/index.md b/doc/ci/environments/index.md
index 363006ec7b6..6bac004fcdf 100644
--- a/doc/ci/environments/index.md
+++ b/doc/ci/environments/index.md
@@ -730,7 +730,7 @@ the `review/feature-1` spec takes precedence over `review/*` and `*` specs.
### Rename an environment
-> Renaming environments through the UI was [removed](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/68550) in GitLab 14.3. Renaming environments through the API was deprected and [will be removed](https://gitlab.com/gitlab-org/gitlab/-/issues/338897) in GitLab 15.0.
+> Renaming environments through the UI was [removed](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/68550) in GitLab 14.3. Renaming environments through the API was deprecated and [will be removed](https://gitlab.com/gitlab-org/gitlab/-/issues/338897) in GitLab 15.0.
Renaming an environment through the UI is not possible.
Instead, you need to delete the old environment and create a new one:
diff --git a/doc/development/database/pagination_guidelines.md b/doc/development/database/pagination_guidelines.md
index b7209b4ca30..3a772b10a6d 100644
--- a/doc/development/database/pagination_guidelines.md
+++ b/doc/development/database/pagination_guidelines.md
@@ -302,7 +302,7 @@ LIMIT 20
##### Tooling
-A generic keyset pagination library is available within the GitLab project which can most of the cases easly replace the existing, kaminari based pagination with significant performance improvements when dealing with large datasets.
+A generic keyset pagination library is available within the GitLab project which can most of the cases easily replace the existing, kaminari based pagination with significant performance improvements when dealing with large datasets.
Example:
diff --git a/doc/development/documentation/styleguide/index.md b/doc/development/documentation/styleguide/index.md
index a1c2bcdbdd7..ea1cf0ebf0c 100644
--- a/doc/development/documentation/styleguide/index.md
+++ b/doc/development/documentation/styleguide/index.md
@@ -1148,7 +1148,7 @@ known tool is [`pngquant`](https://pngquant.org/), which is cross-platform and
open source. Install it by visiting the official website and following the
instructions for your OS.
-GitLab has a [Rake task](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/tasks/pngquant.rake)
+GitLab has a [Ruby script](https://gitlab.com/gitlab-org/gitlab/-/blob/master/bin/pngquant)
that you can use to automate the process. In the root directory of your local
copy of `https://gitlab.com/gitlab-org/gitlab`, run in a terminal:
@@ -1156,19 +1156,26 @@ copy of `https://gitlab.com/gitlab-org/gitlab`, run in a terminal:
been compressed:
```shell
- bundle exec rake pngquant:lint
+ bin/pngquant lint
```
- Compress all documentation PNG images using `pngquant`:
```shell
- bundle exec rake pngquant:compress
+ bin/pngquant compress
```
-The only caveat is that the task runs on all images under `doc/`, not only the
-ones you might have included in a merge request. In that case, you can run the
-compress task and only commit the images that are relevant to your merge
-request.
+- Compress specific files:
+
+ ```shell
+ bin/pngquant compress doc/user/img/award_emoji_select.png doc/user/img/markdown_logo.png
+ ```
+
+- Compress all PNG files in a specific directory:
+
+ ```shell
+ bin/pngquant compress doc/user/img
+ ```
## Videos
diff --git a/doc/development/experiment_guide/experimentation.md b/doc/development/experiment_guide/experimentation.md
index ee0f63342f1..b242646c549 100644
--- a/doc/development/experiment_guide/experimentation.md
+++ b/doc/development/experiment_guide/experimentation.md
@@ -106,7 +106,7 @@ class SomeWorker
# Since we cannot access cookies in a worker, we need to bucket models
# based on a unique, unchanging attribute instead.
- # It is therefore necessery to always provide the same subject.
+ # It is therefore necessary to always provide the same subject.
if Gitlab::Experimentation.in_experiment_group?(:experiment_key, subject: user)
# execute experimental code
else
diff --git a/doc/development/fe_guide/graphql.md b/doc/development/fe_guide/graphql.md
index 54f8ffefdc9..0229aa0123a 100644
--- a/doc/development/fe_guide/graphql.md
+++ b/doc/development/fe_guide/graphql.md
@@ -458,7 +458,7 @@ export default {
};
```
-Note that, even if the directive evalutes to `false`, the guarded entity is sent to the backend and
+Note that, even if the directive evaluates to `false`, the guarded entity is sent to the backend and
matched against the GraphQL schema. So this approach requires that the feature-flagged entity
exists in the schema, even if the feature flag is disabled. When the feature flag is turned off, it
is recommended that the resolver returns `null` at the very least.
@@ -484,7 +484,7 @@ export default {
This approach is not recommended as it results in bigger merge requests and requires maintaining
two similar queries for as long as the feature flag exists. This can be used in cases where the new
GraphQL entities are not yet part of the schema, or if they are feature-flagged at the schema level
-(`new_entitiy: :feature_flag`).
+(`new_entity: :feature_flag`).
### Manually triggering queries
@@ -1340,7 +1340,7 @@ describe('when query times out', () => {
expect(getAlert().exists()).toBe(false);
expect(getGraph().exists()).toBe(true);
- /* fails again, alert retuns but data persists */
+ /* fails again, alert returns but data persists */
await advanceApolloTimers();
expect(getAlert().exists()).toBe(true);
expect(getGraph().exists()).toBe(true);
diff --git a/doc/development/import_project.md b/doc/development/import_project.md
index 69e5873cd87..d021126c8eb 100644
--- a/doc/development/import_project.md
+++ b/doc/development/import_project.md
@@ -195,7 +195,7 @@ You can use this snippet: `https://gitlab.com/gitlab-org/gitlab/snippets/1924954
You can execute the script from the `gdk/gitlab` directory like this:
```shell
-bundle exec rails r /path_to_sript/script.rb project_name /path_to_extracted_project request_store_enabled
+bundle exec rails r /path_to_script/script.rb project_name /path_to_extracted_project request_store_enabled
```
## Troubleshooting
diff --git a/doc/development/internal_api.md b/doc/development/internal_api.md
index 564c1928138..660d8c60ba8 100644
--- a/doc/development/internal_api.md
+++ b/doc/development/internal_api.md
@@ -510,7 +510,7 @@ create a single vulnerability.
| Attribute | Type | Required | Description |
|:----------------|:-------|:---------|:------------|
| `vulnerability` | Hash | yes | Vulnerability data matching the security report schema [`vulnerability` field](https://gitlab.com/gitlab-org/security-products/security-report-schemas/-/blob/master/src/security-report-format.json). |
-| `scanner` | Hash | yes | Scanner data matching the security report schmea [`scanner` field](https://gitlab.com/gitlab-org/security-products/security-report-schemas/-/blob/master/src/security-report-format.json). |
+| `scanner` | Hash | yes | Scanner data matching the security report schema [`scanner` field](https://gitlab.com/gitlab-org/security-products/security-report-schemas/-/blob/master/src/security-report-format.json). |
```plaintext
PUT internal/kubernetes/modules/starboard_vulnerability
diff --git a/doc/development/multi_version_compatibility.md b/doc/development/multi_version_compatibility.md
index af14fb73672..f834f4f4ee3 100644
--- a/doc/development/multi_version_compatibility.md
+++ b/doc/development/multi_version_compatibility.md
@@ -201,7 +201,7 @@ gantt
section Database
Schema A :done, schemaA, 00:00 , 1h
Schema B :crit, schemaB, after migr, 58m
- Schema C. : schmeaC, after postmigr, 1h
+ Schema C. : schemaC, after postmigr, 1h
section Machine A
Version N :done, mavn, 00:00 , 75m
diff --git a/doc/development/service_ping/metrics_dictionary.md b/doc/development/service_ping/metrics_dictionary.md
index 341f2a875d3..7c2bf41794d 100644
--- a/doc/development/service_ping/metrics_dictionary.md
+++ b/doc/development/service_ping/metrics_dictionary.md
@@ -41,7 +41,7 @@ Each metric is defined in a separate YAML file consisting of a number of fields:
| `instrumentation_class` | no | `string`; [the class that implements the metric](metrics_instrumentation.md). |
| `distribution` | yes | `array`; may be set to one of `ce, ee` or `ee`. The [distribution](https://about.gitlab.com/handbook/marketing/strategic-marketing/tiers/#definitions) where the tracked feature is available. |
| `performance_indicator_type` | no | `array`; may be set to one of [`gmau`, `smau`, `paid_gmau`, or `umau`](https://about.gitlab.com/handbook/business-technology/data-team/data-catalog/xmau-analysis/). |
-| `tier` | yes | `array`; may contain one or a combination of `free`, `premium` or `ultimate`. The [tier]( https://about.gitlab.com/handbook/marketing/strategic-marketing/tiers/) where the tracked feature is available. |
+| `tier` | yes | `array`; may contain one or a combination of `free`, `premium` or `ultimate`. The [tier]( https://about.gitlab.com/handbook/marketing/strategic-marketing/tiers/) where the tracked feature is available. This should be verbose and contain all tiers where a metric is available. |
| `milestone` | no | The milestone when the metric is introduced. |
| `milestone_removed` | no | The milestone when the metric is removed. |
| `introduced_by_url` | no | The URL to the Merge Request that introduced the metric. |
diff --git a/doc/development/transient/prevention-patterns.md b/doc/development/transient/prevention-patterns.md
index 472b5756805..c517a6bcd54 100644
--- a/doc/development/transient/prevention-patterns.md
+++ b/doc/development/transient/prevention-patterns.md
@@ -97,7 +97,7 @@ by the server-side endpoint satisfies the API contract.
#### Related reading
[Debug it!](https://pragprog.com/titles/pbdp/debug-it/) explores techniques to diagnose
-and fix non-determinstic bugs and write software that is easier to debug.
+and fix non-deterministic bugs and write software that is easier to debug.
## Backend
diff --git a/doc/install/aws/index.md b/doc/install/aws/index.md
index d11a77332bb..342b6962628 100644
--- a/doc/install/aws/index.md
+++ b/doc/install/aws/index.md
@@ -43,7 +43,7 @@ GitLab implementation patterns build upon [GitLab Reference Architectures](../..
Testing-backed architectural qualification is a fundamental concept behind implementation patterns:
-- Implementation patterns maintain GitLab Reference Architecture compliance and provide [GitLab Performance Tool](https://gitlab.com/gitlab-org/quality/performance) (gpt) reports to demonstrate adherance to them.
+- Implementation patterns maintain GitLab Reference Architecture compliance and provide [GitLab Performance Tool](https://gitlab.com/gitlab-org/quality/performance) (gpt) reports to demonstrate adherence to them.
- Implementation patterns may be qualified by and/or contributed to by the technology vendor. For instance, an implementation pattern for AWS may be officially reviewed by AWS.
- Implementation patterns may specify and test Cloud Platform PaaS services for suitability for GitLab. This testing can be coordinated and help qualify these technologies for Reference Architectures. For instance, qualifying compatibility with and availability of runtime versions of top level PaaS such as those for PostgreSQL and Redis.
- Implementation patterns can provided qualified testing for platform limitations, for example, ensuring Gitaly Cluster can work correctly on specific Cloud Platform availability zone latency and throughput characteristics or qualifying what levels of available platform partner local disk performance is workable for Gitaly server to operate with integrity.
diff --git a/doc/integration/recaptcha.md b/doc/integration/recaptcha.md
index ed4c3b4f21e..fd5170d615f 100644
--- a/doc/integration/recaptcha.md
+++ b/doc/integration/recaptcha.md
@@ -24,7 +24,7 @@ To use reCAPTCHA, first you must create a site and private key.
1. To enable reCAPTCHA for logins via password, select the **Enable reCAPTCHA for login** checkbox.
1. Save the configuration.
1. Change the first line of the `#execute` method in `app/services/spam/spam_verdict_service.rb`
- to `return CONDITONAL_ALLOW` so that the spam check short-circuits and triggers the response to
+ to `return CONDITIONAL_ALLOW` so that the spam check short-circuits and triggers the response to
return `recaptcha_html`.
NOTE:
diff --git a/doc/operations/error_tracking.md b/doc/operations/error_tracking.md
index 9d344384f64..7c258be13b4 100644
--- a/doc/operations/error_tracking.md
+++ b/doc/operations/error_tracking.md
@@ -50,7 +50,7 @@ You may also want to enable Sentry's GitLab integration by following the steps i
### Enable GitLab Runner
To configure GitLab Runner with Sentry, you must add the value for `sentry_dsn` to your GitLab
-Runner's `config.toml` configuration file, as referenced in [GitLab Runner Advanced Configuraton](https://docs.gitlab.com/runner/configuration/advanced-configuration.html).
+Runner's `config.toml` configuration file, as referenced in [GitLab Runner Advanced Configuration](https://docs.gitlab.com/runner/configuration/advanced-configuration.html).
While setting up Sentry, select **Go** if you're asked for the project type.
If you see the following error in your GitLab Runner logs, then you should specify the deprecated
diff --git a/doc/topics/autodevops/customize.md b/doc/topics/autodevops/customize.md
index 1d66ad35024..f8b63f5b41a 100644
--- a/doc/topics/autodevops/customize.md
+++ b/doc/topics/autodevops/customize.md
@@ -464,7 +464,7 @@ The following table lists variables used to disable jobs.
| `license_scanning` | `LICENSE_MANAGEMENT_DISABLED` | [From GitLab 12.8](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/22773) | If the variable is present, the job isn't created. |
| `load_performance` | `LOAD_PERFORMANCE_DISABLED` | From GitLab 13.2 | If the variable is present, the job isn't created. |
| `nodejs-scan-sast` | `SAST_DISABLED` | | If the variable is present, the job isn't created. |
-| `performance` | `PERFORMANCE_DISABLED` | GitLab 11.0 to GitLab 13.12 | Browser performance. If the variable is present, the job isn't created. Replaced by `browser_peformance`. |
+| `performance` | `PERFORMANCE_DISABLED` | GitLab 11.0 to GitLab 13.12 | Browser performance. If the variable is present, the job isn't created. Replaced by `browser_performance`. |
| `browser_performance` | `BROWSER_PERFORMANCE_DISABLED` | From GitLab 14.0 | Browser performance. If the variable is present, the job isn't created. Replaces `performance`. |
| `phpcs-security-audit-sast` | `SAST_DISABLED` | | If the variable is present, the job isn't created. |
| `pmd-apex-sast` | `SAST_DISABLED` | | If the variable is present, the job isn't created. |
diff --git a/doc/update/deprecations.md b/doc/update/deprecations.md
index 9eef831afa4..fd738f43501 100644
--- a/doc/update/deprecations.md
+++ b/doc/update/deprecations.md
@@ -41,3 +41,17 @@ The `omniauth-kerberos` gem will be removed in our next major release, GitLab 15
This gem has not been maintained and has very little usage. We therefore plan to remove support for this authentication method and recommend using the Kerberos [SPNEGO](https://en.wikipedia.org/wiki/SPNEGO) integration instead. You can follow the [upgrade instructions](../integration/kerberos.md#upgrading-from-password-based-to-ticket-based-kerberos-sign-ins) to upgrade from the `omniauth-kerberos` integration to the supported one.
Note that we are not deprecating the Kerberos SPNEGO integration, only the old password-based Kerberos integration.
+
+### GitLab Serverless
+
+[GitLab Serverless](../user/project/clusters/serverless/index.md) is a feature set to support Knative-based serverless development with automatic deployments and monitoring.
+
+We decided to remove the GitLab Serverless features as they never really resonated with our users. Besides, given the continuous development of Kubernetes and Knative, our current implementations do not even work with recent versions.
+
+## 14.4
+
+### Rename Task Runner pod to Toolbox
+
+The Task Runner pod is used to execute periodic housekeeping tasks within the GitLab application and is often confused with the GitLab Runner. Thus, [Task Runner will be renamed to Toolbox](https://gitlab.com/groups/gitlab-org/charts/-/epics/25).
+
+This will result in the rename of the sub-chart: `gitlab/task-runner` to `gitlab/toolbox`. Resulting pods will be named along the lines of `{{ .Release.Name }}-toolbox`, which will often be `gitlab-toolbox`. They will be locatable with the label `app=toolbox`.
diff --git a/doc/update/plan_your_upgrade.md b/doc/update/plan_your_upgrade.md
index e10819c08eb..7aca83071fc 100644
--- a/doc/update/plan_your_upgrade.md
+++ b/doc/update/plan_your_upgrade.md
@@ -88,7 +88,7 @@ To restore your GitLab backup:
- Before restoring, make sure to read about the
[prerequisites](../raketasks/backup_restore.md#restore-gitlab), most importantly,
- the versions of the backed up and the new GitLab istance must be the same.
+ the versions of the backed up and the new GitLab instance must be the same.
- [Restore GitLab](../raketasks/backup_restore.md#restore-gitlab).
Make sure to follow the instructions based on your installation method.
Confirm that the [secrets and configuration files](../raketasks/backup_restore.md#storing-configuration-files) are also restored.
diff --git a/doc/user/application_security/dast/index.md b/doc/user/application_security/dast/index.md
index 631cdf026c2..0d60701b030 100644
--- a/doc/user/application_security/dast/index.md
+++ b/doc/user/application_security/dast/index.md
@@ -556,6 +556,9 @@ By default, several rules are disabled because they either take a long time to
run or frequently generate false positives. The complete list of disabled rules
can be found in [exclude_rules.yml](https://gitlab.com/gitlab-org/security-products/dast/-/blob/main/src/config/exclude_rules.yml).
+The lists for `DAST_EXCLUDE_RULES` and `DAST_ONLY_INCLUDE_RULES` **must** be enclosed in double
+quotes (`"`), otherwise they are interpreted as numeric values.
+
### Hide sensitive information
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/36332) in GitLab 13.1.
@@ -744,7 +747,7 @@ dast:
when: always
```
-### Available CI/CD variables
+## Available CI/CD variables
These CI/CD variables are specific to DAST. They can be used to customize the behavior of DAST to your requirements.
@@ -764,7 +767,7 @@ These CI/CD variables are specific to DAST. They can be used to customize the be
| `DAST_AUTO_UPDATE_ADDONS` | boolean | ZAP add-ons are pinned to specific versions in the DAST Docker image. Set to `true` to download the latest versions when the scan starts. Default: `false`. |
| `DAST_BROWSER_PATH_TO_LOGIN_FORM` <sup>1,2</sup> | selector | Comma-separated list of selectors that will be clicked on prior to attempting to enter `DAST_USERNAME` and `DAST_PASSWORD` into the login form. Example: `"css:.navigation-menu,css:.login-menu-item"`. [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/326633) in GitLab 14.1. |
| `DAST_DEBUG` <sup>1</sup> | boolean | Enable debug message output. Default: `false`. [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/12652) in GitLab 13.1. |
-| `DAST_EXCLUDE_RULES` | string | Set to a comma-separated list of Vulnerability Rule IDs to exclude them from running during the scan. Rule IDs are numbers and can be found from the DAST log or on the [ZAP project](https://www.zaproxy.org/docs/alerts/). For example, `HTTP Parameter Override` has a rule ID of `10026`. Cannot be used when `DAST_ONLY_INCLUDE_RULES` is set. **Note:** In earlier versions of GitLab the excluded rules were executed but vulnerabilities they generated were suppressed. [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/118641) in GitLab 12.10. |
+| `DAST_EXCLUDE_RULES` | string | Set to a comma-separated list of Vulnerability Rule IDs to exclude them from running during the scan. The whole list **must** be enclosed in double quotes (`"`). Rule IDs are numbers and can be found from the DAST log or on the [ZAP project](https://www.zaproxy.org/docs/alerts/). For example, `HTTP Parameter Override` has a rule ID of `10026`. Cannot be used when `DAST_ONLY_INCLUDE_RULES` is set. **Note:** In earlier versions of GitLab the excluded rules were executed but vulnerabilities they generated were suppressed. [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/118641) in GitLab 12.10. |
| `DAST_EXCLUDE_URLS` <sup>1,2</sup> | URLs | The URLs to skip during the authenticated scan; comma-separated. Regular expression syntax can be used to match multiple URLs. For example, `.*` matches an arbitrary character sequence. Not supported for API scans. Example, `http://example.com/sign-out`. |
| `DAST_FIRST_SUBMIT_FIELD` <sup>2</sup> | string | The `id` or `name` of the element that when clicked submits the username form of a multi-page login process. For example, `css:button[type='user-submit']`. [Introduced](https://gitlab.com/gitlab-org/gitlab-ee/issues/9894) in GitLab 12.4. |
| `DAST_FULL_SCAN_DOMAIN_VALIDATION_REQUIRED` | boolean | **{warning}** **[Removed](https://gitlab.com/gitlab-org/gitlab/-/issues/293595)** in GitLab 14.0. Set to `true` to require domain validation when running DAST full scans. Not supported for API scans. Default: `false` |
@@ -774,7 +777,7 @@ These CI/CD variables are specific to DAST. They can be used to customize the be
| `DAST_MARKDOWN_REPORT` | string | The filename of the Markdown report written at the end of a scan. [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/12652) in GitLab 13.1. |
| `DAST_MASK_HTTP_HEADERS` | string | Comma-separated list of request and response headers to be masked (GitLab 13.1). Must contain **all** headers to be masked. Refer to [list of headers that are masked by default](#hide-sensitive-information). |
| `DAST_MAX_URLS_PER_VULNERABILITY` | number | The maximum number of URLs reported for a single vulnerability. `DAST_MAX_URLS_PER_VULNERABILITY` is set to `50` by default. To list all the URLs set to `0`. [Introduced](https://gitlab.com/gitlab-org/security-products/dast/-/merge_requests/433) in GitLab 13.12. |
-| `DAST_ONLY_INCLUDE_RULES` | string | Set to a comma-separated list of Vulnerability Rule IDs to configure the scan to run only them. Rule IDs are numbers and can be found from the DAST log or on the [ZAP project](https://www.zaproxy.org/docs/alerts/). Cannot be used when `DAST_EXCLUDE_RULES` is set. [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/250651) in GitLab 13.12. |
+| `DAST_ONLY_INCLUDE_RULES` | string | Set to a comma-separated list of Vulnerability Rule IDs to configure the scan to run only them. The whole list **must** be enclosed in double quotes (`"`). Rule IDs are numbers and can be found from the DAST log or on the [ZAP project](https://www.zaproxy.org/docs/alerts/). Cannot be used when `DAST_EXCLUDE_RULES` is set. [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/250651) in GitLab 13.12. |
| `DAST_PASSWORD` <sup>1,2</sup> | string | The password to authenticate to in the website. Example: `P@55w0rd!` |
| `DAST_PASSWORD_FIELD` <sup>1,2</sup> | string | The selector of password field at the sign-in HTML form. Example: `id:password` |
| `DAST_PATHS` | string | Set to a comma-separated list of URLs for DAST to scan. For example, `/page1.html,/category1/page3.html,/page2.html`. [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/214120) in GitLab 13.4. |
@@ -797,7 +800,7 @@ These CI/CD variables are specific to DAST. They can be used to customize the be
1. Available to an on-demand DAST scan.
1. Used for authentication.
-#### Selectors
+### Selectors
Selectors are used by CI/CD variables to specify the location of an element displayed on a page in a browser.
Selectors have the format `type`:`search string`. The crawler will search for the selector using the search string based on the type.
@@ -810,7 +813,7 @@ Selectors have the format `type`:`search string`. The crawler will search for th
| `xpath` | `xpath://input[@id="my-button"]/a` | Searches for a HTML element with the provided XPath. Note that XPath searches are expected to be less performant than other searches. |
| None provided | `a.click-me` | Defaults to searching using a CSS selector. |
-##### Find selectors with Google Chrome
+#### Find selectors with Google Chrome
Chrome DevTools element selector tool is an effective way to find a selector.
@@ -826,7 +829,7 @@ Chrome DevTools element selector tool is an effective way to find a selector.
In this example, the `id="user_login"` appears to be a good candidate. You can use this as a selector as the DAST username field by setting
`DAST_USERNAME_FIELD: "id:user_login"`.
-##### Choose the right selector
+#### Choose the right selector
Judicious choice of selector leads to a scan that is resilient to the application changing.
diff --git a/doc/user/application_security/dependency_scanning/index.md b/doc/user/application_security/dependency_scanning/index.md
index e6372d56cdf..d903ce58982 100644
--- a/doc/user/application_security/dependency_scanning/index.md
+++ b/doc/user/application_security/dependency_scanning/index.md
@@ -295,7 +295,7 @@ variation of this file (for example, `requirements.pip` or `requires.txt`).
#### Java and Scala
We only execute one build in the directory where a build file has been detected, such as `build.sbt` or `build.gradle`.
-Please note, we support the following types of Java project stuctures:
+Please note, we support the following types of Java project structures:
- [multi-project sbt builds](https://www.scala-sbt.org/1.x/docs/Multi-Project.html)
- [multi-project gradle builds](https://docs.gradle.org/current/userguide/intro_multi_project_builds.html)
diff --git a/doc/user/application_security/policies/index.md b/doc/user/application_security/policies/index.md
index ba863e8e744..bd143d8608a 100644
--- a/doc/user/application_security/policies/index.md
+++ b/doc/user/application_security/policies/index.md
@@ -396,7 +396,7 @@ In this example:
and `Site Profile D`.
- Secret detection and container scanning scans run for every pipeline executed on the `main` branch.
- Cluster Image Scanning scan runs every 24h. The scan runs on the `production-cluster` cluster and fetches vulnerabilities
- from the container with the name `database` configured for deployment with the name `production-application` in the `production-namepsace` namespace.
+ from the container with the name `database` configured for deployment with the name `production-application` in the `production-namespace` namespace.
## Roadmap
diff --git a/doc/user/gitlab_com/index.md b/doc/user/gitlab_com/index.md
index dc409c972fc..3379460cccc 100644
--- a/doc/user/gitlab_com/index.md
+++ b/doc/user/gitlab_com/index.md
@@ -14,7 +14,7 @@ This page contains information about the settings that are used on GitLab.com, a
GitLab.com has the following requirements for passwords on new accounts and password changes:
- Minimum character length 8 characters.
-- Maximum character lenght 128 characters.
+- Maximum character length 128 characters.
- All characters are accepted. For example, `~`, `!`, `@`, `#`, `$`, `%`, `^`, `&`, `*`, `()`,
`[]`, `_`, `+`, `=`, and `-`.
diff --git a/doc/user/group/saml_sso/index.md b/doc/user/group/saml_sso/index.md
index b7b31e89f3b..8f6b3e7244a 100644
--- a/doc/user/group/saml_sso/index.md
+++ b/doc/user/group/saml_sso/index.md
@@ -337,7 +337,7 @@ Ensure your SAML identity provider sends an attribute statement named `Groups` o
NOTE:
To inspect the SAML response, you can use one of these [SAML debugging tools](#saml-debugging-tools).
-Also note that the value for `Groups` or `groups` in the SAML reponse can be either the group name or
+Also note that the value for `Groups` or `groups` in the SAML response can be either the group name or
the group ID depending what the IdP sends to GitLab.
When SAML SSO is enabled for the top-level group, `Maintainer` and `Owner` level users
diff --git a/doc/user/group/value_stream_analytics/index.md b/doc/user/group/value_stream_analytics/index.md
index ec0f18f70d2..68ae5e0df2d 100644
--- a/doc/user/group/value_stream_analytics/index.md
+++ b/doc/user/group/value_stream_analytics/index.md
@@ -79,6 +79,9 @@ Data is shown for workflow items created during the selected date range. To filt
## How metrics are measured
+> DORA API-based deployment metrics [moved](https://gitlab.com/gitlab-org/gitlab/-/issues/337256)
+> to Premium in GitLab 14.3 for group-level Value Stream Analytics.
+
The "Time" metrics near the top of the page are measured as follows:
- **Lead time**: median time from issue created to issue closed.
diff --git a/doc/user/profile/notifications.md b/doc/user/profile/notifications.md
index ffb1db062b8..aaa311a4097 100644
--- a/doc/user/profile/notifications.md
+++ b/doc/user/profile/notifications.md
@@ -262,7 +262,7 @@ If the title or description of an issue or merge request is
changed, notifications are sent to any **new** mentions by `@username` as
if they had been mentioned in the original text.
-BNy default, you don't receive notifications for issues, merge requests, or epics created
+By default, you don't receive notifications for issues, merge requests, or epics created
by yourself. You only receive notifications when somebody else comments or adds changes to the ones
that you've created or mentions you, or when an issue is due soon.
To always receive notifications on your own issues and so on, you must turn on
diff --git a/doc/user/project/clusters/add_eks_clusters.md b/doc/user/project/clusters/add_eks_clusters.md
index e92a6d6a162..f7dd24fcfad 100644
--- a/doc/user/project/clusters/add_eks_clusters.md
+++ b/doc/user/project/clusters/add_eks_clusters.md
@@ -10,7 +10,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
> - [Deprecated](https://gitlab.com/gitlab-org/gitlab/-/issues/327908) in GitLab 14.0.
WARNING:
-Use [Infrastrucure as Code](../../infrastructure/index.md) to create new clusters. The method described in this document is deprecated as of GitLab 14.0.
+Use [Infrastructure as Code](../../infrastructure/index.md) to create new clusters. The method described in this document is deprecated as of GitLab 14.0.
Through GitLab, you can create new clusters and add existing clusters hosted on Amazon Elastic
Kubernetes Service (EKS).
diff --git a/doc/user/project/clusters/add_gke_clusters.md b/doc/user/project/clusters/add_gke_clusters.md
index a6c7a37c385..78d4bce737d 100644
--- a/doc/user/project/clusters/add_gke_clusters.md
+++ b/doc/user/project/clusters/add_gke_clusters.md
@@ -9,7 +9,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
> - [Deprecated](https://gitlab.com/groups/gitlab-org/-/epics/6049) in GitLab 14.0.
WARNING:
-Use [Infrastrucure as Code](../../infrastructure/index.md) to create new clusters. The method described in this document is deprecated as of GitLab 14.0.
+Use [Infrastructure as Code](../../infrastructure/index.md) to create new clusters. The method described in this document is deprecated as of GitLab 14.0.
Through GitLab, you can create new clusters and add existing clusters hosted on Amazon Elastic
Kubernetes Service (EKS).
diff --git a/doc/user/project/clusters/add_remove_clusters.md b/doc/user/project/clusters/add_remove_clusters.md
index 0484121db62..4f2bc5526e0 100644
--- a/doc/user/project/clusters/add_remove_clusters.md
+++ b/doc/user/project/clusters/add_remove_clusters.md
@@ -53,7 +53,7 @@ supports connecting existing clusters using the certificate-based connection met
As of GitLab 14.0, use the [GitLab Kubernetes Agent](../../clusters/agent/index.md)
to connect your cluster to GitLab.
-Alternativelly, you can [add an existing cluster](add_existing_cluster.md)
+Alternatively, you can [add an existing cluster](add_existing_cluster.md)
through the certificate-based method, but we don't recommend using this method for [security implications](../../infrastructure/clusters/connect/index.md#security-implications-for-clusters-connected-with-certificates).
## Configure your cluster
diff --git a/doc/user/project/deploy_tokens/index.md b/doc/user/project/deploy_tokens/index.md
index 70363b67c88..1798aa0c1c6 100644
--- a/doc/user/project/deploy_tokens/index.md
+++ b/doc/user/project/deploy_tokens/index.md
@@ -181,7 +181,7 @@ To pull images from the Dependency Proxy, you must:
1. Create a group deploy token with both `read_registry` and `write_registry` scopes.
1. Take note of your `username` and `token`.
-1. Follow the Depenency Proxy [authentication instructions](../../packages/dependency_proxy/index.md).
+1. Follow the Dependency Proxy [authentication instructions](../../packages/dependency_proxy/index.md).
### GitLab deploy token
diff --git a/doc/user/project/settings/index.md b/doc/user/project/settings/index.md
index edfa12b9843..8b159a75451 100644
--- a/doc/user/project/settings/index.md
+++ b/doc/user/project/settings/index.md
@@ -179,7 +179,7 @@ cannot change them:
- Explicitly set the container image file to run the job in. This ensures that your script
steps execute in the correct environment.
- Explicitly set any relevant GitLab pre-defined [job keywords](../../../ci/yaml/index.md#job-keywords).
- This ensures that your job uses the settings you intend and that they are not overriden by
+ This ensures that your job uses the settings you intend and that they are not overridden by
project-level pipelines.
### Sharing and permissions
diff --git a/lib/gitlab/usage/metrics/instrumentations/service_ping_features_metric.rb b/lib/gitlab/usage/metrics/instrumentations/service_ping_features_metric.rb
new file mode 100644
index 00000000000..dcf528c8136
--- /dev/null
+++ b/lib/gitlab/usage/metrics/instrumentations/service_ping_features_metric.rb
@@ -0,0 +1,15 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module Usage
+ module Metrics
+ module Instrumentations
+ class ServicePingFeaturesMetric < GenericMetric
+ value do
+ Gitlab::CurrentSettings.usage_ping_features_enabled
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/usage_data.rb b/lib/gitlab/usage_data.rb
index 9a091e8819c..854242031be 100644
--- a/lib/gitlab/usage_data.rb
+++ b/lib/gitlab/usage_data.rb
@@ -259,7 +259,8 @@ module Gitlab
smtp_encrypted_secrets_enabled: alt_usage_data(fallback: nil) { Gitlab::Email::SmtpConfig.encrypted_secrets.active? },
operating_system: alt_usage_data(fallback: nil) { operating_system },
gitaly_apdex: alt_usage_data { gitaly_apdex },
- collected_data_categories: add_metric('CollectedDataCategoriesMetric', time_frame: 'none')
+ collected_data_categories: add_metric('CollectedDataCategoriesMetric', time_frame: 'none'),
+ service_ping_features_enabled: add_metric('ServicePingFeaturesMetric', time_frame: 'none')
}
}
end
diff --git a/lib/tasks/pngquant.rake b/lib/tasks/pngquant.rake
deleted file mode 100644
index 45c0288cadf..00000000000
--- a/lib/tasks/pngquant.rake
+++ /dev/null
@@ -1,55 +0,0 @@
-# frozen_string_literal: true
-
-return if Rails.env.production?
-
-require 'png_quantizator'
-require 'parallel'
-require_relative '../../tooling/lib/tooling/images'
-
-# The amount of variance (in bytes) allowed in
-# file size when testing for compression size
-
-namespace :pngquant do
- # Returns an array of all images eligible for compression
- def doc_images
- Dir.glob('doc/**/*.png', File::FNM_CASEFOLD)
- end
-
- desc 'GitLab | Pngquant | Compress all documentation PNG images using pngquant'
- task :compress do
- files = doc_images
- puts "Compressing #{files.size} PNG files in doc/**"
-
- Parallel.each(files) do |file|
- was_uncompressed, savings = Tooling::Image.compress_image(file)
-
- if was_uncompressed
- puts "#{file} was reduced by #{savings} bytes"
- end
- end
- end
-
- desc 'GitLab | Pngquant | Checks that all documentation PNG images have been compressed with pngquant'
- task :lint do
- files = doc_images
- puts "Checking #{files.size} PNG files in doc/**"
-
- uncompressed_files = Parallel.map(files) do |file|
- is_uncompressed, _ = Tooling::Image.compress_image(file, true)
- if is_uncompressed
- puts "Uncompressed file detected: ".color(:red) + file
- file
- end
- end.compact
-
- if uncompressed_files.empty?
- puts "All documentation images are optimally compressed!".color(:green)
- else
- warn(
- "The #{uncompressed_files.size} image(s) above have not been optimally compressed using pngquant.".color(:red),
- 'Please run "bin/rake pngquant:compress" and commit the result.'
- )
- abort
- end
- end
-end
diff --git a/locale/gitlab.pot b/locale/gitlab.pot
index 702e1d2c9d5..146d6d03480 100644
--- a/locale/gitlab.pot
+++ b/locale/gitlab.pot
@@ -6225,6 +6225,9 @@ msgstr ""
msgid "Cancelling Preview"
msgstr ""
+msgid "Cannot assign a confidential epic to a non-confidential issue. Make the issue confidential and try again"
+msgstr ""
+
msgid "Cannot be assigned to other projects."
msgstr ""
@@ -6276,9 +6279,6 @@ msgstr ""
msgid "Cannot refer to a group %{timebox_type} by an internal id!"
msgstr ""
-msgid "Cannot set confidential epic for a non-confidential issue"
-msgstr ""
-
msgid "Cannot show preview. For previews on sketch files, they must have the file format introduced by Sketch version 43 and above."
msgstr ""
@@ -7174,6 +7174,12 @@ msgstr ""
msgid "ClusterAgents|Access tokens"
msgstr ""
+msgid "ClusterAgents|Agent might not be connected to GitLab"
+msgstr ""
+
+msgid "ClusterAgents|Agent never connected to GitLab"
+msgstr ""
+
msgid "ClusterAgents|Alternative installation methods"
msgstr ""
@@ -7189,6 +7195,12 @@ msgstr ""
msgid "ClusterAgents|Configuration"
msgstr ""
+msgid "ClusterAgents|Connected"
+msgstr ""
+
+msgid "ClusterAgents|Connection status"
+msgstr ""
+
msgid "ClusterAgents|Copy token"
msgstr ""
@@ -7207,6 +7219,9 @@ msgstr ""
msgid "ClusterAgents|For alternative installation methods %{linkStart}go to the documentation%{linkEnd}."
msgstr ""
+msgid "ClusterAgents|For more troubleshooting information go to"
+msgstr ""
+
msgid "ClusterAgents|Go to the repository"
msgstr ""
@@ -7222,18 +7237,33 @@ msgstr ""
msgid "ClusterAgents|Integrate with the GitLab Agent"
msgstr ""
+msgid "ClusterAgents|Last connected %{timeAgo}."
+msgstr ""
+
+msgid "ClusterAgents|Last contact"
+msgstr ""
+
msgid "ClusterAgents|Last used"
msgstr ""
msgid "ClusterAgents|Learn how to create an agent access token"
msgstr ""
+msgid "ClusterAgents|Make sure you are using a valid token."
+msgstr ""
+
msgid "ClusterAgents|Name"
msgstr ""
msgid "ClusterAgents|Never"
msgstr ""
+msgid "ClusterAgents|Never connected"
+msgstr ""
+
+msgid "ClusterAgents|Not connected"
+msgstr ""
+
msgid "ClusterAgents|Read more about getting started"
msgstr ""
@@ -7255,6 +7285,9 @@ msgstr ""
msgid "ClusterAgents|Select which Agent you want to install"
msgstr ""
+msgid "ClusterAgents|The Agent has not been connected in a long time. There might be a connectivity issue. Last contact was %{timeAgo}."
+msgstr ""
+
msgid "ClusterAgents|The GitLab Agent also requires %{linkStart}enabling the Agent Server%{linkEnd}"
msgstr ""
@@ -8140,6 +8173,9 @@ msgstr ""
msgid "Collapse replies"
msgstr ""
+msgid "Collapse settings section"
+msgstr ""
+
msgid "Collapse sidebar"
msgstr ""
@@ -13686,6 +13722,9 @@ msgstr ""
msgid "Expand pipeline"
msgstr ""
+msgid "Expand settings section"
+msgstr ""
+
msgid "Expand sidebar"
msgstr ""
diff --git a/qa/qa/page/group/menu.rb b/qa/qa/page/group/menu.rb
index c997598e25a..be877e56713 100644
--- a/qa/qa/page/group/menu.rb
+++ b/qa/qa/page/group/menu.rb
@@ -68,8 +68,25 @@ module QA
end
end
+ def go_to_repository_settings
+ hover_group_settings do
+ within_submenu do
+ click_element(:sidebar_menu_item_link, menu_item: 'Repository')
+ end
+ end
+ end
+
private
+ def hover_settings
+ within_sidebar do
+ scroll_to_element(:sidebar_menu_link, menu_item: 'Settings')
+ find_element(:sidebar_menu_link, menu_item: 'Settings').hover
+
+ yield
+ end
+ end
+
def hover_issues
within_sidebar do
scroll_to_element(:sidebar_menu_link, menu_item: 'Issues')
diff --git a/qa/qa/page/group/settings/group_deploy_tokens.rb b/qa/qa/page/group/settings/group_deploy_tokens.rb
new file mode 100644
index 00000000000..65ee3fc72eb
--- /dev/null
+++ b/qa/qa/page/group/settings/group_deploy_tokens.rb
@@ -0,0 +1,68 @@
+# frozen_string_literal: true
+
+module QA
+ module Page
+ module Group
+ module Settings
+ class GroupDeployTokens < Page::Base
+ view 'app/views/shared/deploy_tokens/_form.html.haml' do
+ element :deploy_token_name_field
+ element :deploy_token_expires_at_field
+ element :deploy_token_read_repository_checkbox
+ element :deploy_token_read_package_registry_checkbox
+ element :deploy_token_read_registry_checkbox
+ element :deploy_token_write_package_registry_checkbox
+ element :create_deploy_token_button
+ end
+
+ view 'app/views/shared/deploy_tokens/_new_deploy_token.html.haml' do
+ element :created_deploy_token_container
+ element :deploy_token_user_field
+ element :deploy_token_field
+ end
+
+ def fill_token_name(name)
+ fill_element(:deploy_token_name_field, name)
+ end
+
+ def fill_token_expires_at(expires_at)
+ fill_element(:deploy_token_expires_at_field, expires_at.to_s + "\n")
+ end
+
+ def fill_scopes(read_repository: false, read_registry: false, read_package_registry: false, write_package_registry: false )
+ check_element(:deploy_token_read_repository_checkbox) if read_repository
+ check_element(:deploy_token_read_package_registry_checkbox) if read_package_registry
+ check_element(:deploy_token_read_registry_checkbox) if read_registry
+ check_element(:deploy_token_write_package_registry_checkbox) if write_package_registry
+ end
+
+ def add_token
+ click_element(:create_deploy_token_button)
+ end
+
+ def token_username
+ within_new_project_deploy_token do
+ find_element(:deploy_token_user_field).value
+ end
+ end
+
+ def token_password
+ within_new_project_deploy_token do
+ find_element(:deploy_token_field).value
+ end
+ end
+
+ private
+
+ def within_new_project_deploy_token
+ has_element?(:created_deploy_token_container, wait: QA::Support::Repeater::DEFAULT_MAX_WAIT_TIME)
+
+ within_element(:created_deploy_token_container) do
+ yield
+ end
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/qa/qa/page/group/settings/repository.rb b/qa/qa/page/group/settings/repository.rb
new file mode 100644
index 00000000000..2cc80ef26c6
--- /dev/null
+++ b/qa/qa/page/group/settings/repository.rb
@@ -0,0 +1,23 @@
+# frozen_string_literal: true
+
+module QA
+ module Page
+ module Group
+ module Settings
+ class Repository < Page::Base
+ include QA::Page::Settings::Common
+
+ view 'app/views/shared/deploy_tokens/_index.html.haml' do
+ element :deploy_tokens_settings_content
+ end
+
+ def expand_deploy_tokens(&block)
+ expand_content(:deploy_tokens_settings_content) do
+ Settings::GroupDeployTokens.perform(&block)
+ end
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/qa/qa/resource/group_deploy_token.rb b/qa/qa/resource/group_deploy_token.rb
new file mode 100644
index 00000000000..410a7e6253f
--- /dev/null
+++ b/qa/qa/resource/group_deploy_token.rb
@@ -0,0 +1,51 @@
+# frozen_string_literal: true
+
+module QA
+ module Resource
+ class GroupDeployToken < Base
+ attr_accessor :name, :expires_at
+
+ attribute :username do
+ Page::Group::Settings::Repository.perform do |repository_page|
+ repository_page.expand_deploy_tokens(&:token_username)
+ end
+ end
+
+ attribute :password do
+ Page::Group::Settings::Repository.perform do |repository_page|
+ repository_page.expand_deploy_tokens(&:token_password)
+ end
+ end
+
+ attribute :group do
+ Group.fabricate! do |resource|
+ resource.name = 'group-with-deploy-token'
+ resource.description = 'group for adding deploy token test'
+ end
+ end
+
+ attribute :project do
+ Project.fabricate! do |resource|
+ resource.name = 'project-to-deploy'
+ resource.description = 'project for adding deploy token test'
+ end
+ end
+
+ def fabricate!
+ group.visit!
+
+ Page::Group::Menu.perform(&:go_to_repository_settings)
+
+ Page::Group::Settings::Repository.perform do |setting|
+ setting.expand_deploy_tokens do |page|
+ page.fill_token_name(name)
+ page.fill_token_expires_at(expires_at)
+ page.fill_scopes(read_repository: true, read_package_registry: true, write_package_registry: true)
+
+ page.add_token
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/qa/qa/specs/features/browser_ui/5_package/nuget_repository_spec.rb b/qa/qa/specs/features/browser_ui/5_package/nuget_repository_spec.rb
index 85807b4fc6d..8a6752ed817 100644
--- a/qa/qa/specs/features/browser_ui/5_package/nuget_repository_spec.rb
+++ b/qa/qa/specs/features/browser_ui/5_package/nuget_repository_spec.rb
@@ -3,6 +3,7 @@
module QA
RSpec.describe 'Package', :orchestrated, :packages, :object_storage do
describe 'NuGet Repository' do
+ using RSpec::Parameterized::TableSyntax
include Runtime::Fixtures
let(:project) do
Resource::Project.fabricate_via_api! do |project|
@@ -11,6 +12,21 @@ module QA
end
end
+ let(:personal_access_token) do
+ unless Page::Main::Menu.perform(&:signed_in?)
+ Flow::Login.sign_in
+ end
+
+ Resource::PersonalAccessToken.fabricate!
+ end
+
+ let(:group_deploy_token) do
+ Resource::GroupDeployToken.fabricate_via_browser_ui! do |deploy_token|
+ deploy_token.name = 'nuget-group-deploy-token'
+ deploy_token.group = project.group
+ end
+ end
+
let(:package) do
Resource::Package.init do |package|
package.name = "dotnetcore-#{SecureRandom.hex(8)}"
@@ -40,123 +56,153 @@ module QA
package.remove_via_api!
end
- it 'publishes a nuget package at the project level, installs and deletes it at the group level', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/quality/test_cases/1641' do
- Flow::Login.sign_in
-
- Resource::Repository::Commit.fabricate_via_api! do |commit|
- commit.project = project
- commit.commit_message = 'Add .gitlab-ci.yml'
- commit.update_files(
- [
- {
- file_path: '.gitlab-ci.yml',
- content: <<~YAML
- image: mcr.microsoft.com/dotnet/sdk:5.0
-
- stages:
- - deploy
-
- deploy:
- stage: deploy
- script:
- - dotnet restore -p:Configuration=Release
- - dotnet build -c Release
- - dotnet pack -c Release -p:PackageID=#{package.name}
- - dotnet nuget add source "$CI_SERVER_URL/api/v4/projects/$CI_PROJECT_ID/packages/nuget/index.json" --name gitlab --username gitlab-ci-token --password $CI_JOB_TOKEN --store-password-in-clear-text
- - dotnet nuget push "bin/Release/*.nupkg" --source gitlab
- only:
- - "#{project.default_branch}"
- tags:
- - "runner-for-#{project.group.name}"
- YAML
- }
- ]
- )
- end
-
- project.visit!
- Flow::Pipeline.visit_latest_pipeline
+ where(:authentication_token_type, :token_name) do
+ :personal_access_token | 'Personal Access Token'
+ :ci_job_token | 'CI Job Token'
+ :group_deploy_token | 'Deploy Token'
+ end
- Page::Project::Pipeline::Show.perform do |pipeline|
- pipeline.click_job('deploy')
+ with_them do
+ let(:auth_token_password) do
+ case authentication_token_type
+ when :personal_access_token
+ "\"#{personal_access_token.token}\""
+ when :ci_job_token
+ '${CI_JOB_TOKEN}'
+ when :group_deploy_token
+ "\"#{group_deploy_token.password}\""
+ end
end
- Page::Project::Job::Show.perform do |job|
- expect(job).to be_successful(timeout: 800)
+ let(:auth_token_username) do
+ case authentication_token_type
+ when :personal_access_token
+ "\"#{personal_access_token.user.username}\""
+ when :ci_job_token
+ 'gitlab-ci-token'
+ when :group_deploy_token
+ "\"#{group_deploy_token.username}\""
+ end
end
- another_project.visit!
-
- Resource::Repository::Commit.fabricate_via_api! do |commit|
- commit.project = another_project
- commit.commit_message = 'Add new csproj file'
- commit.add_files(
- [
- {
- file_path: 'otherdotnet.csproj',
- content: <<~EOF
- <Project Sdk="Microsoft.NET.Sdk">
-
- <PropertyGroup>
- <OutputType>Exe</OutputType>
- <TargetFramework>net5.0</TargetFramework>
- </PropertyGroup>
-
- </Project>
- EOF
- }
- ]
- )
- commit.update_files(
- [
- {
- file_path: '.gitlab-ci.yml',
- content: <<~YAML
+ it "publishes a nuget package at the project level, installs and deletes it at the group level using a #{params[:token_name]}", testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/1073' do
+ Flow::Login.sign_in
+
+ Resource::Repository::Commit.fabricate_via_api! do |commit|
+ commit.project = project
+ commit.commit_message = 'Add .gitlab-ci.yml'
+ commit.update_files(
+ [
+ {
+ file_path: '.gitlab-ci.yml',
+ content: <<~YAML
image: mcr.microsoft.com/dotnet/sdk:5.0
stages:
- - install
+ - deploy
- install:
- stage: install
+ deploy:
+ stage: deploy
script:
- - dotnet nuget locals all --clear
- - dotnet nuget add source "$CI_SERVER_URL/api/v4/groups/#{another_project.group.id}/-/packages/nuget/index.json" --name gitlab --username gitlab-ci-token --password $CI_JOB_TOKEN --store-password-in-clear-text
- - "dotnet add otherdotnet.csproj package #{package.name} --version 1.0.0"
- only:
- - "#{another_project.default_branch}"
+ - dotnet restore -p:Configuration=Release
+ - dotnet build -c Release
+ - dotnet pack -c Release -p:PackageID=#{package.name}
+ - dotnet nuget add source "$CI_SERVER_URL/api/v4/projects/$CI_PROJECT_ID/packages/nuget/index.json" --name gitlab --username #{auth_token_username} --password #{auth_token_password} --store-password-in-clear-text
+ - dotnet nuget push "bin/Release/*.nupkg" --source gitlab
+ rules:
+ - if: '$CI_COMMIT_BRANCH == "#{project.default_branch}"'
tags:
- "runner-for-#{project.group.name}"
- YAML
- }
- ]
- )
- end
-
- Flow::Pipeline.visit_latest_pipeline
-
- Page::Project::Pipeline::Show.perform do |pipeline|
- pipeline.click_job('install')
- end
-
- Page::Project::Job::Show.perform do |job|
- expect(job).to be_successful(timeout: 800)
- end
-
- project.group.visit!
-
- Page::Group::Menu.perform(&:go_to_group_packages)
-
- Page::Project::Packages::Index.perform do |index|
- expect(index).to have_package(package.name)
- index.click_package(package.name)
- end
-
- Page::Project::Packages::Show.perform(&:click_delete)
-
- Page::Project::Packages::Index.perform do |index|
- expect(index).to have_content("Package deleted successfully")
- expect(index).not_to have_package(package.name)
+ YAML
+ }
+ ]
+ )
+ end
+
+ project.visit!
+ Flow::Pipeline.visit_latest_pipeline
+
+ Page::Project::Pipeline::Show.perform do |pipeline|
+ pipeline.click_job('deploy')
+ end
+
+ Page::Project::Job::Show.perform do |job|
+ expect(job).to be_successful(timeout: 800)
+ end
+
+ another_project.visit!
+
+ Resource::Repository::Commit.fabricate_via_api! do |commit|
+ commit.project = another_project
+ commit.commit_message = 'Add new csproj file'
+ commit.add_files(
+ [
+ {
+ file_path: 'otherdotnet.csproj',
+ content: <<~EOF
+ <Project Sdk="Microsoft.NET.Sdk">
+
+ <PropertyGroup>
+ <OutputType>Exe</OutputType>
+ <TargetFramework>net5.0</TargetFramework>
+ </PropertyGroup>
+
+ </Project>
+ EOF
+ }
+ ]
+ )
+ commit.update_files(
+ [
+ {
+ file_path: '.gitlab-ci.yml',
+ content: <<~YAML
+ image: mcr.microsoft.com/dotnet/sdk:5.0
+
+ stages:
+ - install
+
+ install:
+ stage: install
+ script:
+ - dotnet nuget locals all --clear
+ - dotnet nuget add source "$CI_SERVER_URL/api/v4/groups/#{another_project.group.id}/-/packages/nuget/index.json" --name gitlab --username #{auth_token_username} --password #{auth_token_password} --store-password-in-clear-text
+ - "dotnet add otherdotnet.csproj package #{package.name} --version 1.0.0"
+ only:
+ - "#{another_project.default_branch}"
+ tags:
+ - "runner-for-#{project.group.name}"
+ YAML
+ }
+ ]
+ )
+ end
+
+ Flow::Pipeline.visit_latest_pipeline
+
+ Page::Project::Pipeline::Show.perform do |pipeline|
+ pipeline.click_job('install')
+ end
+
+ Page::Project::Job::Show.perform do |job|
+ expect(job).to be_successful(timeout: 800)
+ end
+
+ project.group.visit!
+
+ Page::Group::Menu.perform(&:go_to_group_packages)
+
+ Page::Project::Packages::Index.perform do |index|
+ expect(index).to have_package(package.name)
+ index.click_package(package.name)
+ end
+
+ Page::Project::Packages::Show.perform(&:click_delete)
+
+ Page::Project::Packages::Index.perform do |index|
+ expect(index).to have_content('Package deleted successfully')
+ expect(index).not_to have_package(package.name)
+ end
end
end
end
diff --git a/qa/qa/support/formatters/test_stats_formatter.rb b/qa/qa/support/formatters/test_stats_formatter.rb
index 098796fe0b9..0f76a924b10 100644
--- a/qa/qa/support/formatters/test_stats_formatter.rb
+++ b/qa/qa/support/formatters/test_stats_formatter.rb
@@ -76,6 +76,7 @@ module QA
run_time: (example.execution_result.run_time * 1000).round,
retry_attempts: example.metadata[:retry_attempts] || 0,
job_url: QA::Runtime::Env.ci_job_url,
+ pipeline_url: env('CI_PIPELINE_URL'),
pipeline_id: env('CI_PIPELINE_ID')
}
}
diff --git a/qa/spec/support/formatters/test_stats_formatter_spec.rb b/qa/spec/support/formatters/test_stats_formatter_spec.rb
index 41f8af4b0d0..fec7ec1c7c0 100644
--- a/qa/spec/support/formatters/test_stats_formatter_spec.rb
+++ b/qa/spec/support/formatters/test_stats_formatter_spec.rb
@@ -11,6 +11,7 @@ describe QA::Support::Formatters::TestStatsFormatter do
let(:ci_timestamp) { "2021-02-23T20:58:41Z" }
let(:ci_job_name) { "test-job 1/5" }
let(:ci_job_url) { "url" }
+ let(:ci_pipeline_url) { "url" }
let(:ci_pipeline_id) { "123" }
let(:run_type) { 'staging-full' }
let(:reliable) { 'false' }
@@ -47,6 +48,7 @@ describe QA::Support::Formatters::TestStatsFormatter do
run_time: 0,
retry_attempts: 0,
job_url: ci_job_url,
+ pipeline_url: ci_pipeline_url,
pipeline_id: ci_pipeline_id
}
}
@@ -103,6 +105,7 @@ describe QA::Support::Formatters::TestStatsFormatter do
stub_env('CI_PIPELINE_CREATED_AT', ci_timestamp)
stub_env('CI_JOB_URL', ci_job_url)
stub_env('CI_JOB_NAME', ci_job_name)
+ stub_env('CI_PIPELINE_URL', ci_pipeline_url)
stub_env('CI_PIPELINE_ID', ci_pipeline_id)
stub_env('CI_MERGE_REQUEST_IID', nil)
stub_env('TOP_UPSTREAM_MERGE_REQUEST_IID', nil)
diff --git a/rubocop/cop/sidekiq_load_balancing/worker_data_consistency.rb b/rubocop/cop/sidekiq_load_balancing/worker_data_consistency.rb
new file mode 100644
index 00000000000..7a2e7ee00b4
--- /dev/null
+++ b/rubocop/cop/sidekiq_load_balancing/worker_data_consistency.rb
@@ -0,0 +1,65 @@
+# frozen_string_literal: true
+
+require_relative '../../code_reuse_helpers'
+
+module RuboCop
+ module Cop
+ module SidekiqLoadBalancing
+ # This cop checks for a call to `data_consistency` to exist in Sidekiq workers.
+ #
+ # @example
+ #
+ # # bad
+ # class BadWorker
+ # def perform
+ # end
+ # end
+ #
+ # # good
+ # class GoodWorker
+ # data_consistency :delayed
+ #
+ # def perform
+ # end
+ # end
+ #
+ class WorkerDataConsistency < RuboCop::Cop::Cop
+ include CodeReuseHelpers
+
+ HELP_LINK = 'https://docs.gitlab.com/ee/development/sidekiq_style_guide.html#job-data-consistency-strategies'
+
+ MSG = <<~MSG
+ Should define data_consistency expectation.
+
+ It is encouraged for workers to use database replicas as much as possible by declaring
+ data_consistency to use the :delayed or :sticky modes. Mode :always will result in the
+ worker always hitting the primary database node for both reads and writes, which limits
+ scalability.
+
+ Some guidelines:
+
+ 1. If your worker mostly writes or reads its own writes, use mode :always. TRY TO AVOID THIS.
+ 2. If your worker performs mostly reads and can tolerate small delays, use mode :delayed.
+ 3. If your worker performs mostly reads but cannot tolerate any delays, use mode :sticky.
+
+ See #{HELP_LINK} for a more detailed explanation of these settings.
+ MSG
+
+ def_node_search :application_worker?, <<~PATTERN
+ `(send nil? :include (const nil? :ApplicationWorker))
+ PATTERN
+
+ def_node_search :data_consistency_defined?, <<~PATTERN
+ `(send nil? :data_consistency ...)
+ PATTERN
+
+ def on_class(node)
+ return unless in_worker?(node) && application_worker?(node)
+ return if data_consistency_defined?(node)
+
+ add_offense(node, location: :expression)
+ end
+ end
+ end
+ end
+end
diff --git a/rubocop/cop/sidekiq_load_balancing/worker_data_consistency_with_deduplication.rb b/rubocop/cop/sidekiq_load_balancing/worker_data_consistency_with_deduplication.rb
new file mode 100644
index 00000000000..e8b4b513a23
--- /dev/null
+++ b/rubocop/cop/sidekiq_load_balancing/worker_data_consistency_with_deduplication.rb
@@ -0,0 +1,154 @@
+# frozen_string_literal: true
+
+require_relative '../../code_reuse_helpers'
+
+module RuboCop
+ module Cop
+ module SidekiqLoadBalancing
+ # This cop checks for including_scheduled: true option in idempotent Sidekiq workers that utilize load balancing capabilities.
+ #
+ # @example
+ #
+ # # bad
+ # class BadWorker
+ # include ApplicationWorker
+ #
+ # data_consistency :delayed
+ # idempotent!
+ #
+ # def perform
+ # end
+ # end
+ #
+ # # bad
+ # class BadWorker
+ # include ApplicationWorker
+ #
+ # data_consistency :delayed
+ #
+ # deduplicate :until_executing
+ # idempotent!
+ #
+ # def perform
+ # end
+ # end
+ #
+ # # good
+ # class GoodWorker
+ # include ApplicationWorker
+ #
+ # data_consistency :delayed
+ #
+ # deduplicate :until_executing, including_scheduled: true
+ # idempotent!
+ #
+ # def perform
+ # end
+ # end
+ #
+ class WorkerDataConsistencyWithDeduplication < RuboCop::Cop::Base
+ include CodeReuseHelpers
+ extend AutoCorrector
+
+ HELP_LINK = 'https://docs.gitlab.com/ee/development/sidekiq_style_guide.html#scheduling-jobs-in-the-future'
+ REPLACEMENT = ', including_scheduled: true'
+ DEFAULT_STRATEGY = ':until_executing'
+
+ MSG = <<~MSG
+ Workers that declare either `:sticky` or `:delayed` data consistency become eligible for database load-balancing.
+ In both cases, jobs are enqueued with a short delay.
+
+ If you do want to deduplicate jobs that utilize load-balancing, you need to specify including_scheduled: true
+ argument when defining deduplication strategy.
+
+ See #{HELP_LINK} for a more detailed explanation of these settings.
+ MSG
+
+ def_node_search :application_worker?, <<~PATTERN
+ `(send nil? :include (const nil? :ApplicationWorker))
+ PATTERN
+
+ def_node_search :idempotent_worker?, <<~PATTERN
+ `(send nil? :idempotent!)
+ PATTERN
+
+ def_node_search :data_consistency_defined?, <<~PATTERN
+ `(send nil? :data_consistency (sym {:sticky :delayed }))
+ PATTERN
+
+ def_node_matcher :including_scheduled?, <<~PATTERN
+ `(hash <(pair (sym :including_scheduled) (%1)) ...>)
+ PATTERN
+
+ def_node_matcher :deduplicate_strategy?, <<~PATTERN
+ `(send nil? :deduplicate (sym $_) $(...)?)
+ PATTERN
+
+ def on_class(node)
+ return unless in_worker?(node)
+ return unless application_worker?(node)
+ return unless idempotent_worker?(node)
+ return unless data_consistency_defined?(node)
+
+ @strategy, options = deduplicate_strategy?(node)
+ including_scheduled = false
+ if options
+ @deduplicate_options = options[0]
+ including_scheduled = including_scheduled?(@deduplicate_options, :true) # rubocop:disable Lint/BooleanSymbol
+ end
+
+ @offense = !(including_scheduled || @strategy == :none)
+ end
+
+ def on_send(node)
+ return unless offense
+
+ if node.children[1] == :deduplicate
+ add_offense(node.loc.expression) do |corrector|
+ autocorrect_deduplicate_strategy(node, corrector)
+ end
+ elsif node.children[1] == :idempotent! && !strategy
+ add_offense(node.loc.expression) do |corrector|
+ autocorrect_missing_deduplicate_strategy(node, corrector)
+ end
+ end
+ end
+
+ private
+
+ attr_reader :offense, :deduplicate_options, :strategy
+
+ def autocorrect_deduplicate_with_options(corrector)
+ if including_scheduled?(deduplicate_options, :false) # rubocop:disable Lint/BooleanSymbol
+ replacement = deduplicate_options.source.sub("including_scheduled: false", "including_scheduled: true")
+ corrector.replace(deduplicate_options.loc.expression, replacement)
+ else
+ corrector.insert_after(deduplicate_options.loc.expression, REPLACEMENT)
+ end
+ end
+
+ def autocorrect_deduplicate_without_options(node, corrector)
+ corrector.insert_after(node.loc.expression, REPLACEMENT)
+ end
+
+ def autocorrect_missing_deduplicate_strategy(node, corrector)
+ indent_found = node.source_range.source_line =~ /^( +)/
+ # Get indentation size
+ whitespaces = Regexp.last_match(1).size if indent_found
+ replacement = "deduplicate #{DEFAULT_STRATEGY}#{REPLACEMENT}\n"
+ # Add indentation in the end since we are inserting a whole line before idempotent!
+ replacement += ' ' * whitespaces.to_i
+ corrector.insert_before(node.source_range, replacement)
+ end
+
+ def autocorrect_deduplicate_strategy(node, corrector)
+ if deduplicate_options
+ autocorrect_deduplicate_with_options(corrector)
+ else
+ autocorrect_deduplicate_without_options(node, corrector)
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/rubocop/cop/worker_data_consistency.rb b/rubocop/cop/worker_data_consistency.rb
deleted file mode 100644
index e9047750f3e..00000000000
--- a/rubocop/cop/worker_data_consistency.rb
+++ /dev/null
@@ -1,63 +0,0 @@
-# frozen_string_literal: true
-
-require_relative '../code_reuse_helpers'
-
-module RuboCop
- module Cop
- # This cop checks for a call to `data_consistency` to exist in Sidekiq workers.
- #
- # @example
- #
- # # bad
- # class BadWorker
- # def perform
- # end
- # end
- #
- # # good
- # class GoodWorker
- # data_consistency :delayed
- #
- # def perform
- # end
- # end
- #
- class WorkerDataConsistency < RuboCop::Cop::Cop
- include CodeReuseHelpers
-
- HELP_LINK = 'https://docs.gitlab.com/ee/development/sidekiq_style_guide.html#job-data-consistency-strategies'
-
- MSG = <<~MSG
- Should define data_consistency expectation.
-
- It is encouraged for workers to use database replicas as much as possible by declaring
- data_consistency to use the :delayed or :sticky modes. Mode :always will result in the
- worker always hitting the primary database node for both reads and writes, which limits
- scalability.
-
- Some guidelines:
-
- 1. If your worker mostly writes or reads its own writes, use mode :always. TRY TO AVOID THIS.
- 2. If your worker performs mostly reads and can tolerate small delays, use mode :delayed.
- 3. If your worker performs mostly reads but cannot tolerate any delays, use mode :sticky.
-
- See #{HELP_LINK} for a more detailed explanation of these settings.
- MSG
-
- def_node_search :application_worker?, <<~PATTERN
- `(send nil? :include (const nil? :ApplicationWorker))
- PATTERN
-
- def_node_search :data_consistency_defined?, <<~PATTERN
- `(send nil? :data_consistency ...)
- PATTERN
-
- def on_class(node)
- return unless in_worker?(node) && application_worker?(node)
- return if data_consistency_defined?(node)
-
- add_offense(node, location: :expression)
- end
- end
- end
-end
diff --git a/spec/factories/ci/pending_builds.rb b/spec/factories/ci/pending_builds.rb
index fbd76e07d8e..31e42e1bc9e 100644
--- a/spec/factories/ci/pending_builds.rb
+++ b/spec/factories/ci/pending_builds.rb
@@ -8,5 +8,6 @@ FactoryBot.define do
instance_runners_enabled { true }
namespace { project.namespace }
minutes_exceeded { false }
+ tag_ids { build.tags_ids }
end
end
diff --git a/spec/factories/clusters/agents/project_authorizations.rb b/spec/factories/clusters/agents/project_authorizations.rb
new file mode 100644
index 00000000000..176ecc3b517
--- /dev/null
+++ b/spec/factories/clusters/agents/project_authorizations.rb
@@ -0,0 +1,10 @@
+# frozen_string_literal: true
+
+FactoryBot.define do
+ factory :agent_project_authorization, class: 'Clusters::Agents::ProjectAuthorization' do
+ association :agent, factory: :cluster_agent
+ project
+
+ config { { default_namespace: 'production' } }
+ end
+end
diff --git a/spec/frontend/boards/components/board_settings_sidebar_spec.js b/spec/frontend/boards/components/board_settings_sidebar_spec.js
index 642ffecff2d..46dd109ffb1 100644
--- a/spec/frontend/boards/components/board_settings_sidebar_spec.js
+++ b/spec/frontend/boards/components/board_settings_sidebar_spec.js
@@ -3,6 +3,7 @@ import { shallowMount } from '@vue/test-utils';
import { MountingPortal } from 'portal-vue';
import Vue from 'vue';
import Vuex from 'vuex';
+import { stubComponent } from 'helpers/stub_component';
import { extendedWrapper } from 'helpers/vue_test_utils_helper';
import BoardSettingsSidebar from '~/boards/components/board_settings_sidebar.vue';
import { inactiveId, LIST } from '~/boards/constants';
@@ -45,6 +46,11 @@ describe('BoardSettingsSidebar', () => {
canAdminList,
scopedLabelsAvailable: false,
},
+ stubs: {
+ GlDrawer: stubComponent(GlDrawer, {
+ template: '<div><slot name="header"></slot><slot></slot></div>',
+ }),
+ },
}),
);
};
diff --git a/spec/frontend/vue_shared/components/settings/__snapshots__/settings_block_spec.js.snap b/spec/frontend/vue_shared/components/settings/__snapshots__/settings_block_spec.js.snap
index 0cf756bd106..165caea2751 100644
--- a/spec/frontend/vue_shared/components/settings/__snapshots__/settings_block_spec.js.snap
+++ b/spec/frontend/vue_shared/components/settings/__snapshots__/settings_block_spec.js.snap
@@ -9,8 +9,11 @@ exports[`Settings Block renders the correct markup 1`] = `
>
<h4>
<span
+ aria-controls="settings_content_3"
+ aria-expanded="false"
class="gl-cursor-pointer"
- data-testid="section-title"
+ data-testid="section-title-button"
+ id="settings_label_2"
role="button"
tabindex="0"
>
@@ -21,6 +24,9 @@ exports[`Settings Block renders the correct markup 1`] = `
</h4>
<gl-button-stub
+ aria-controls="settings_content_3"
+ aria-expanded="false"
+ aria-label="Expand settings section"
buttontextclasses=""
category="primary"
icon=""
@@ -40,7 +46,11 @@ exports[`Settings Block renders the correct markup 1`] = `
</div>
<div
+ aria-labelledby="settings_label_2"
class="settings-content"
+ id="settings_content_3"
+ role="region"
+ tabindex="-1"
>
<div
data-testid="default-slot"
diff --git a/spec/frontend/vue_shared/components/settings/settings_block_spec.js b/spec/frontend/vue_shared/components/settings/settings_block_spec.js
index 4189455d6c3..528dfd89690 100644
--- a/spec/frontend/vue_shared/components/settings/settings_block_spec.js
+++ b/spec/frontend/vue_shared/components/settings/settings_block_spec.js
@@ -1,12 +1,12 @@
import { GlButton } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
-import component from '~/vue_shared/components/settings/settings_block.vue';
+import SettingsBlock from '~/vue_shared/components/settings/settings_block.vue';
describe('Settings Block', () => {
let wrapper;
const mountComponent = (propsData) => {
- wrapper = shallowMount(component, {
+ wrapper = shallowMount(SettingsBlock, {
propsData,
slots: {
title: '<div data-testid="title-slot"></div>',
@@ -24,7 +24,19 @@ describe('Settings Block', () => {
const findTitleSlot = () => wrapper.find('[data-testid="title-slot"]');
const findDescriptionSlot = () => wrapper.find('[data-testid="description-slot"]');
const findExpandButton = () => wrapper.findComponent(GlButton);
- const findSectionTitle = () => wrapper.find('[data-testid="section-title"]');
+ const findSectionTitleButton = () => wrapper.find('[data-testid="section-title-button"]');
+
+ const expectExpandedState = ({ expanded = true } = {}) => {
+ const settingsExpandButton = findExpandButton();
+
+ expect(wrapper.classes('expanded')).toBe(expanded);
+ expect(settingsExpandButton.text()).toBe(
+ expanded ? SettingsBlock.i18n.collapseText : SettingsBlock.i18n.expandText,
+ );
+ expect(settingsExpandButton.attributes('aria-label')).toBe(
+ expanded ? SettingsBlock.i18n.collapseAriaLabel : SettingsBlock.i18n.expandAriaLabel,
+ );
+ };
it('renders the correct markup', () => {
mountComponent();
@@ -75,45 +87,41 @@ describe('Settings Block', () => {
it('is collapsed by default', () => {
mountComponent();
- expect(wrapper.classes('expanded')).toBe(false);
+ expectExpandedState({ expanded: false });
});
it('adds expanded class when the expand button is clicked', async () => {
mountComponent();
- expect(wrapper.classes('expanded')).toBe(false);
- expect(findExpandButton().text()).toBe('Expand');
-
await findExpandButton().vm.$emit('click');
- expect(wrapper.classes('expanded')).toBe(true);
- expect(findExpandButton().text()).toBe('Collapse');
+ expectExpandedState({ expanded: true });
});
it('adds expanded class when the section title is clicked', async () => {
mountComponent();
- expect(wrapper.classes('expanded')).toBe(false);
- expect(findExpandButton().text()).toBe('Expand');
+ await findSectionTitleButton().trigger('click');
- await findSectionTitle().trigger('click');
-
- expect(wrapper.classes('expanded')).toBe(true);
- expect(findExpandButton().text()).toBe('Collapse');
+ expectExpandedState({ expanded: true });
});
- it('is expanded when `defaultExpanded` is true no matter what', async () => {
- mountComponent({ defaultExpanded: true });
-
- expect(wrapper.classes('expanded')).toBe(true);
+ describe('when `collapsible` is `false`', () => {
+ beforeEach(() => {
+ mountComponent({ collapsible: false });
+ });
- await findExpandButton().vm.$emit('click');
+ it('does not render clickable section title', () => {
+ expect(findSectionTitleButton().exists()).toBe(false);
+ });
- expect(wrapper.classes('expanded')).toBe(true);
-
- await findExpandButton().vm.$emit('click');
+ it('contains expanded class', () => {
+ expect(wrapper.classes('expanded')).toBe(true);
+ });
- expect(wrapper.classes('expanded')).toBe(true);
+ it('does not render expand toggle button', () => {
+ expect(findExpandButton().exists()).toBe(false);
+ });
});
});
});
diff --git a/spec/lib/gitlab/usage/metrics/instrumentations/service_ping_features_metric_spec.rb b/spec/lib/gitlab/usage/metrics/instrumentations/service_ping_features_metric_spec.rb
new file mode 100644
index 00000000000..40e9b962878
--- /dev/null
+++ b/spec/lib/gitlab/usage/metrics/instrumentations/service_ping_features_metric_spec.rb
@@ -0,0 +1,20 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Gitlab::Usage::Metrics::Instrumentations::ServicePingFeaturesMetric do
+ using RSpec::Parameterized::TableSyntax
+
+ where(:usage_ping_features_enabled, :expected_value) do
+ true | true
+ false | false
+ end
+
+ with_them do
+ before do
+ stub_application_setting(usage_ping_features_enabled: usage_ping_features_enabled)
+ end
+
+ it_behaves_like 'a correct instrumented metric value', { time_frame: 'none' }
+ end
+end
diff --git a/spec/lib/gitlab/usage_data_spec.rb b/spec/lib/gitlab/usage_data_spec.rb
index d96cd8a2db4..a70b68a181f 100644
--- a/spec/lib/gitlab/usage_data_spec.rb
+++ b/spec/lib/gitlab/usage_data_spec.rb
@@ -1089,6 +1089,10 @@ RSpec.describe Gitlab::UsageData, :aggregate_failures do
expect(subject[:settings][:collected_data_categories]).to eq(expected_value)
end
+
+ it 'gathers service_ping_features_enabled' do
+ expect(subject[:settings][:service_ping_features_enabled]).to eq(Gitlab::CurrentSettings.usage_ping_features_enabled)
+ end
end
end
diff --git a/spec/models/ci/pending_build_spec.rb b/spec/models/ci/pending_build_spec.rb
index 3486db5d752..ad711f5622f 100644
--- a/spec/models/ci/pending_build_spec.rb
+++ b/spec/models/ci/pending_build_spec.rb
@@ -34,6 +34,47 @@ RSpec.describe Ci::PendingBuild do
end
end
end
+
+ describe '.for_tags' do
+ subject(:pending_builds) { described_class.for_tags(tag_ids) }
+
+ let_it_be(:pending_build_with_tags) { create(:ci_pending_build, tag_ids: [1, 2]) }
+ let_it_be(:pending_build_without_tags) { create(:ci_pending_build) }
+
+ context 'when tag_ids match pending builds' do
+ let(:tag_ids) { [1, 2] }
+
+ it 'returns matching pending builds' do
+ expect(pending_builds).to contain_exactly(pending_build_with_tags, pending_build_without_tags)
+ end
+ end
+
+ context 'when tag_ids does not match pending builds' do
+ let(:tag_ids) { [non_existing_record_id] }
+
+ it 'returns matching pending builds without tags' do
+ expect(pending_builds).to contain_exactly(pending_build_without_tags)
+ end
+ end
+
+ context 'when tag_ids is not provided' do
+ context 'with a nil value' do
+ let(:tag_ids) { nil }
+
+ it 'returns matching pending builds without tags' do
+ expect(pending_builds).to contain_exactly(pending_build_without_tags)
+ end
+ end
+
+ context 'with an empty array' do
+ let(:tag_ids) { [] }
+
+ it 'returns matching pending builds without tags' do
+ expect(pending_builds).to contain_exactly(pending_build_without_tags)
+ end
+ end
+ end
+ end
end
describe '.upsert_from_build!' do
diff --git a/spec/models/clusters/agent_spec.rb b/spec/models/clusters/agent_spec.rb
index c8fc09565a9..f9df84e8ff4 100644
--- a/spec/models/clusters/agent_spec.rb
+++ b/spec/models/clusters/agent_spec.rb
@@ -11,6 +11,8 @@ RSpec.describe Clusters::Agent do
it { is_expected.to have_many(:last_used_agent_tokens).class_name('Clusters::AgentToken') }
it { is_expected.to have_many(:group_authorizations).class_name('Clusters::Agents::GroupAuthorization') }
it { is_expected.to have_many(:authorized_groups).through(:group_authorizations) }
+ it { is_expected.to have_many(:project_authorizations).class_name('Clusters::Agents::ProjectAuthorization') }
+ it { is_expected.to have_many(:authorized_projects).through(:project_authorizations).class_name('::Project') }
it { is_expected.to validate_presence_of(:name) }
it { is_expected.to validate_length_of(:name).is_at_most(63) }
diff --git a/spec/models/clusters/agents/project_authorization_spec.rb b/spec/models/clusters/agents/project_authorization_spec.rb
new file mode 100644
index 00000000000..134c70739ac
--- /dev/null
+++ b/spec/models/clusters/agents/project_authorization_spec.rb
@@ -0,0 +1,10 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Clusters::Agents::ProjectAuthorization do
+ it { is_expected.to belong_to(:agent).class_name('Clusters::Agent').required }
+ it { is_expected.to belong_to(:project).class_name('Project').required }
+
+ it { expect(described_class).to validate_jsonb_schema(['config']) }
+end
diff --git a/spec/models/namespace_spec.rb b/spec/models/namespace_spec.rb
index f6019cece23..9744d58abb9 100644
--- a/spec/models/namespace_spec.rb
+++ b/spec/models/namespace_spec.rb
@@ -344,6 +344,12 @@ RSpec.describe Namespace do
end
end
+ describe '#owner_required?' do
+ specify { expect(build(:project_namespace).owner_required?).to be_falsey }
+ specify { expect(build(:group).owner_required?).to be_falsey }
+ specify { expect(build(:namespace).owner_required?).to be_truthy }
+ end
+
describe '#visibility_level_field' do
it { expect(namespace.visibility_level_field).to eq(:visibility_level) }
end
diff --git a/spec/models/namespaces/project_namespace_spec.rb b/spec/models/namespaces/project_namespace_spec.rb
index 11bdca54b70..f38e8aa85d0 100644
--- a/spec/models/namespaces/project_namespace_spec.rb
+++ b/spec/models/namespaces/project_namespace_spec.rb
@@ -7,6 +7,10 @@ RSpec.describe Namespaces::ProjectNamespace, type: :model do
it { is_expected.to have_one(:project).with_foreign_key(:project_namespace_id).inverse_of(:project_namespace) }
end
+ describe 'validations' do
+ it { is_expected.not_to validate_presence_of :owner }
+ end
+
context 'when deleting project namespace' do
# using delete rather than destroy due to `delete` skipping AR hooks/callbacks
# so it's ensured to work at the DB level. Uses ON DELETE CASCADE on foreign key
diff --git a/spec/requests/api/internal/kubernetes_spec.rb b/spec/requests/api/internal/kubernetes_spec.rb
index 14d5b8d4744..24422f7b0dd 100644
--- a/spec/requests/api/internal/kubernetes_spec.rb
+++ b/spec/requests/api/internal/kubernetes_spec.rb
@@ -106,6 +106,9 @@ RSpec.describe API::Internal::Kubernetes do
ci_access: {
groups: [
{ id: group.full_path, default_namespace: 'production' }
+ ],
+ projects: [
+ { id: project.full_path, default_namespace: 'staging' }
]
}
}
@@ -119,6 +122,7 @@ RSpec.describe API::Internal::Kubernetes do
expect(response).to have_gitlab_http_status(:no_content)
expect(agent.authorized_groups).to contain_exactly(group)
+ expect(agent.authorized_projects).to contain_exactly(project)
end
end
diff --git a/spec/rubocop/cop/worker_data_consistency_spec.rb b/spec/rubocop/cop/sidekiq_load_balancing/worker_data_consistency_spec.rb
index 5fa42bf2b87..cf8d0d1b66f 100644
--- a/spec/rubocop/cop/worker_data_consistency_spec.rb
+++ b/spec/rubocop/cop/sidekiq_load_balancing/worker_data_consistency_spec.rb
@@ -1,9 +1,9 @@
# frozen_string_literal: true
require 'fast_spec_helper'
-require_relative '../../../rubocop/cop/worker_data_consistency'
+require_relative '../../../../rubocop/cop/sidekiq_load_balancing/worker_data_consistency'
-RSpec.describe RuboCop::Cop::WorkerDataConsistency do
+RSpec.describe RuboCop::Cop::SidekiqLoadBalancing::WorkerDataConsistency do
subject(:cop) { described_class.new }
before do
diff --git a/spec/rubocop/cop/sidekiq_load_balancing/worker_data_consistency_with_deduplication_spec.rb b/spec/rubocop/cop/sidekiq_load_balancing/worker_data_consistency_with_deduplication_spec.rb
new file mode 100644
index 00000000000..6e7212b1002
--- /dev/null
+++ b/spec/rubocop/cop/sidekiq_load_balancing/worker_data_consistency_with_deduplication_spec.rb
@@ -0,0 +1,166 @@
+# frozen_string_literal: true
+
+require 'fast_spec_helper'
+require 'rspec-parameterized'
+require_relative '../../../../rubocop/cop/sidekiq_load_balancing/worker_data_consistency_with_deduplication'
+
+RSpec.describe RuboCop::Cop::SidekiqLoadBalancing::WorkerDataConsistencyWithDeduplication do
+ using RSpec::Parameterized::TableSyntax
+
+ subject(:cop) { described_class.new }
+
+ before do
+ allow(cop)
+ .to receive(:in_worker?)
+ .and_return(true)
+ end
+
+ where(:data_consistency) { %i[delayed sticky] }
+
+ with_them do
+ let(:strategy) { described_class::DEFAULT_STRATEGY }
+ let(:corrected) do
+ <<~CORRECTED
+ class SomeWorker
+ include ApplicationWorker
+
+ data_consistency :#{data_consistency}
+
+ deduplicate #{strategy}, including_scheduled: true
+ idempotent!
+ end
+ CORRECTED
+ end
+
+ context 'when deduplication strategy is not explicitly set' do
+ it 'registers an offense and corrects using default strategy' do
+ expect_offense(<<~CODE)
+ class SomeWorker
+ include ApplicationWorker
+
+ data_consistency :#{data_consistency}
+
+ idempotent!
+ ^^^^^^^^^^^ Workers that declare either `:sticky` or `:delayed` data consistency [...]
+ end
+ CODE
+
+ expect_correction(corrected)
+ end
+
+ context 'when identation is different' do
+ let(:corrected) do
+ <<~CORRECTED
+ class SomeWorker
+ include ApplicationWorker
+
+ data_consistency :#{data_consistency}
+
+ deduplicate #{strategy}, including_scheduled: true
+ idempotent!
+ end
+ CORRECTED
+ end
+
+ it 'registers an offense and corrects with correct identation' do
+ expect_offense(<<~CODE)
+ class SomeWorker
+ include ApplicationWorker
+
+ data_consistency :#{data_consistency}
+
+ idempotent!
+ ^^^^^^^^^^^ Workers that declare either `:sticky` or `:delayed` data consistency [...]
+ end
+ CODE
+
+ expect_correction(corrected)
+ end
+ end
+ end
+
+ context 'when deduplication strategy does not include including_scheduling option' do
+ let(:strategy) { ':until_executed' }
+
+ it 'registers an offense and corrects' do
+ expect_offense(<<~CODE)
+ class SomeWorker
+ include ApplicationWorker
+
+ data_consistency :#{data_consistency}
+
+ deduplicate :until_executed
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^ Workers that declare either `:sticky` or `:delayed` data consistency [...]
+ idempotent!
+ end
+ CODE
+
+ expect_correction(corrected)
+ end
+ end
+
+ context 'when deduplication strategy has including_scheduling option disabled' do
+ let(:strategy) { ':until_executed' }
+
+ it 'registers an offense and corrects' do
+ expect_offense(<<~CODE)
+ class SomeWorker
+ include ApplicationWorker
+
+ data_consistency :#{data_consistency}
+
+ deduplicate :until_executed, including_scheduled: false
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Workers that declare either `:sticky` or `:delayed` data consistency [...]
+ idempotent!
+ end
+ CODE
+
+ expect_correction(corrected)
+ end
+ end
+
+ context "when deduplication strategy is :none" do
+ it 'does not register an offense' do
+ expect_no_offenses(<<~CODE)
+ class SomeWorker
+ include ApplicationWorker
+
+ data_consistency :always
+
+ deduplicate :none
+ idempotent!
+ end
+ CODE
+ end
+ end
+
+ context "when deduplication strategy has including_scheduling option enabled" do
+ it 'does not register an offense' do
+ expect_no_offenses(<<~CODE)
+ class SomeWorker
+ include ApplicationWorker
+
+ data_consistency :always
+
+ deduplicate :until_executing, including_scheduled: true
+ idempotent!
+ end
+ CODE
+ end
+ end
+ end
+
+ context "data_consistency: :always" do
+ it 'does not register an offense' do
+ expect_no_offenses(<<~CODE)
+ class SomeWorker
+ include ApplicationWorker
+
+ data_consistency :always
+
+ idempotent!
+ end
+ CODE
+ end
+ end
+end
diff --git a/spec/services/ci/register_job_service_spec.rb b/spec/services/ci/register_job_service_spec.rb
index b4e2429d5e3..a8820f5f2c7 100644
--- a/spec/services/ci/register_job_service_spec.rb
+++ b/spec/services/ci/register_job_service_spec.rb
@@ -40,12 +40,16 @@ module Ci
context 'runner follow tag list' do
it "picks build with the same tag" do
pending_job.update!(tag_list: ["linux"])
+ pending_job.reload
+ pending_job.create_queuing_entry!
specific_runner.update!(tag_list: ["linux"])
expect(execute(specific_runner)).to eq(pending_job)
end
it "does not pick build with different tag" do
pending_job.update!(tag_list: ["linux"])
+ pending_job.reload
+ pending_job.create_queuing_entry!
specific_runner.update!(tag_list: ["win32"])
expect(execute(specific_runner)).to be_falsey
end
@@ -56,6 +60,8 @@ module Ci
it "does not pick build with tag" do
pending_job.update!(tag_list: ["linux"])
+ pending_job.reload
+ pending_job.create_queuing_entry!
expect(execute(specific_runner)).to be_falsey
end
@@ -81,6 +87,10 @@ module Ci
end
context 'for specific runner' do
+ before do
+ stub_feature_flags(ci_pending_builds_project_runners_decoupling: false)
+ end
+
it 'does not pick a build' do
expect(execute(specific_runner)).to be_nil
end
@@ -236,6 +246,10 @@ module Ci
end
context 'and uses project runner' do
+ before do
+ stub_feature_flags(ci_pending_builds_project_runners_decoupling: false)
+ end
+
let(:build) { execute(specific_runner) }
it { expect(build).to be_nil }
diff --git a/spec/services/clusters/agents/refresh_authorization_service_spec.rb b/spec/services/clusters/agents/refresh_authorization_service_spec.rb
index 8a887b347bb..77ba81ea9c0 100644
--- a/spec/services/clusters/agents/refresh_authorization_service_spec.rb
+++ b/spec/services/clusters/agents/refresh_authorization_service_spec.rb
@@ -5,10 +5,15 @@ require 'spec_helper'
RSpec.describe Clusters::Agents::RefreshAuthorizationService do
describe '#execute' do
let_it_be(:root_ancestor) { create(:group) }
+
let_it_be(:removed_group) { create(:group, parent: root_ancestor) }
let_it_be(:modified_group) { create(:group, parent: root_ancestor) }
let_it_be(:added_group) { create(:group, parent: root_ancestor) }
+ let_it_be(:removed_project) { create(:project, namespace: root_ancestor) }
+ let_it_be(:modified_project) { create(:project, namespace: root_ancestor) }
+ let_it_be(:added_project) { create(:project, namespace: root_ancestor) }
+
let(:project) { create(:project, namespace: root_ancestor) }
let(:agent) { create(:cluster_agent, project: project) }
@@ -18,6 +23,10 @@ RSpec.describe Clusters::Agents::RefreshAuthorizationService do
groups: [
{ id: added_group.full_path, default_namespace: 'default' },
{ id: modified_group.full_path, default_namespace: 'new-namespace' }
+ ],
+ projects: [
+ { id: added_project.full_path, default_namespace: 'default' },
+ { id: modified_project.full_path, default_namespace: 'new-namespace' }
]
}
}.deep_stringify_keys
@@ -30,54 +39,93 @@ RSpec.describe Clusters::Agents::RefreshAuthorizationService do
agent.group_authorizations.create!(group: removed_group, config: default_config)
agent.group_authorizations.create!(group: modified_group, config: default_config)
+
+ agent.project_authorizations.create!(project: removed_project, config: default_config)
+ agent.project_authorizations.create!(project: modified_project, config: default_config)
end
- it 'refreshes authorizations for the agent' do
- expect(subject).to be_truthy
- expect(agent.authorized_groups).to contain_exactly(added_group, modified_group)
+ shared_examples 'removing authorization' do
+ context 'config contains no groups' do
+ let(:config) { {} }
- added_authorization = agent.group_authorizations.find_by(group: added_group)
- expect(added_authorization.config).to eq({ 'default_namespace' => 'default' })
+ it 'removes all authorizations' do
+ expect(subject).to be_truthy
+ expect(authorizations).to be_empty
+ end
+ end
- modified_authorization = agent.group_authorizations.find_by(group: modified_group)
- expect(modified_authorization.config).to eq({ 'default_namespace' => 'new-namespace' })
- end
+ context 'config contains groups outside of the configuration project hierarchy' do
+ let(:project) { create(:project, namespace: create(:group)) }
- context 'config contains no groups' do
- let(:config) { {} }
+ it 'removes all authorizations' do
+ expect(subject).to be_truthy
+ expect(authorizations).to be_empty
+ end
+ end
- it 'removes all authorizations' do
- expect(subject).to be_truthy
- expect(agent.authorized_groups).to be_empty
+ context 'configuration project does not belong to a group' do
+ let(:project) { create(:project) }
+
+ it 'removes all authorizations' do
+ expect(subject).to be_truthy
+ expect(authorizations).to be_empty
+ end
end
end
- context 'config contains groups outside of the configuration project hierarchy' do
- let(:project) { create(:project, namespace: create(:group)) }
-
- it 'removes all authorizations' do
+ describe 'group authorization' do
+ it 'refreshes authorizations for the agent' do
expect(subject).to be_truthy
- expect(agent.authorized_groups).to be_empty
+ expect(agent.authorized_groups).to contain_exactly(added_group, modified_group)
+
+ added_authorization = agent.group_authorizations.find_by(group: added_group)
+ expect(added_authorization.config).to eq({ 'default_namespace' => 'default' })
+
+ modified_authorization = agent.group_authorizations.find_by(group: modified_group)
+ expect(modified_authorization.config).to eq({ 'default_namespace' => 'new-namespace' })
end
- end
- context 'configuration project does not belong to a group' do
- let(:project) { create(:project) }
+ context 'config contains too many groups' do
+ before do
+ stub_const("#{described_class}::AUTHORIZED_ENTITY_LIMIT", 1)
+ end
- it 'removes all authorizations' do
- expect(subject).to be_truthy
- expect(agent.authorized_groups).to be_empty
+ it 'authorizes groups up to the limit' do
+ expect(subject).to be_truthy
+ expect(agent.authorized_groups).to contain_exactly(added_group)
+ end
end
- end
- context 'config contains too many groups' do
- before do
- stub_const("#{described_class}::AUTHORIZED_GROUP_LIMIT", 1)
+ include_examples 'removing authorization' do
+ let(:authorizations) { agent.authorized_groups }
end
+ end
- it 'authorizes groups up to the limit' do
+ describe 'project authorization' do
+ it 'refreshes authorizations for the agent' do
expect(subject).to be_truthy
- expect(agent.authorized_groups).to contain_exactly(added_group)
+ expect(agent.authorized_projects).to contain_exactly(added_project, modified_project)
+
+ added_authorization = agent.project_authorizations.find_by(project: added_project)
+ expect(added_authorization.config).to eq({ 'default_namespace' => 'default' })
+
+ modified_authorization = agent.project_authorizations.find_by(project: modified_project)
+ expect(modified_authorization.config).to eq({ 'default_namespace' => 'new-namespace' })
+ end
+
+ context 'config contains too many projects' do
+ before do
+ stub_const("#{described_class}::AUTHORIZED_ENTITY_LIMIT", 1)
+ end
+
+ it 'authorizes projects up to the limit' do
+ expect(subject).to be_truthy
+ expect(agent.authorized_projects).to contain_exactly(added_project)
+ end
+ end
+
+ include_examples 'removing authorization' do
+ let(:authorizations) { agent.authorized_projects }
end
end
end