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

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2022-03-16 18:07:32 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2022-03-16 18:07:32 +0300
commitdb19df23733c768c564534a09de2e6718097ec95 (patch)
treef148eb0723f20a2442e0274089d567e1810ee8d2
parentd2199d74936cd5cb9f45f569f723a5370ae5013e (diff)
Add latest changes from gitlab-org/gitlab@master
-rw-r--r--.gitlab/issue_templates/Refactoring.md5
-rw-r--r--.gitlab/merge_request_templates/Pipeline Configuration.md2
-rw-r--r--Gemfile2
-rw-r--r--Gemfile.lock6
-rw-r--r--app/assets/javascripts/editor/schema/ci.json55
-rw-r--r--app/assets/javascripts/runner/components/runner_pause_button.vue13
-rw-r--r--app/assets/javascripts/runner/components/runner_paused_badge.vue12
-rw-r--r--app/assets/javascripts/runner/constants.js7
-rw-r--r--app/models/application_setting.rb12
-rw-r--r--app/models/integrations/zentao.rb1
-rw-r--r--app/services/concerns/members/bulk_create_users.rb13
-rw-r--r--app/views/groups/runners/_runner.html.haml6
-rw-r--r--app/views/projects/commits/_commits.html.haml9
-rw-r--r--app/views/projects/runners/_runner.html.haml4
-rw-r--r--danger/specialization_labels/Dangerfile1
-rw-r--r--danger/specs/Dangerfile5
-rw-r--r--doc/administration/object_storage.md1
-rw-r--r--doc/administration/pages/index.md1
-rw-r--r--doc/api/index.md3
-rw-r--r--doc/ci/environments/deployment_approvals.md2
-rw-r--r--doc/development/contributing/issue_workflow.md16
-rw-r--r--doc/development/documentation/testing.md3
-rw-r--r--doc/development/licensed_feature_availability.md9
-rw-r--r--doc/development/service_ping/metrics_dictionary.md2
-rw-r--r--lib/gitlab/current_settings.rb2
-rw-r--r--lib/security/ci_configuration/base_build_action.rb2
-rw-r--r--locale/gitlab.pot8
-rw-r--r--spec/frontend/runner/components/runner_pause_button_spec.js22
-rw-r--r--spec/lib/gitlab/current_settings_spec.rb15
-rw-r--r--spec/lib/security/ci_configuration/sast_iac_build_action_spec.rb120
-rw-r--r--spec/support/shared_examples/models/member_shared_examples.rb45
-rw-r--r--spec/tooling/danger/datateam_spec.rb8
-rw-r--r--workhorse/internal/upload/destination/destination.go3
-rw-r--r--workhorse/internal/upload/destination/filestore/filestore.go1
-rw-r--r--workhorse/internal/upload/destination/objectstore/doc.go3
35 files changed, 242 insertions, 177 deletions
diff --git a/.gitlab/issue_templates/Refactoring.md b/.gitlab/issue_templates/Refactoring.md
index df18dcf7656..453ae743237 100644
--- a/.gitlab/issue_templates/Refactoring.md
+++ b/.gitlab/issue_templates/Refactoring.md
@@ -42,8 +42,9 @@ please list them here.
Please select the appropriate label from the following:
~"feature::addition"
~"type::maintenance"
- ~"tooling::pipelines"
- ~"tooling::workflow"
+ ~"maintenance::refactor"
+ ~"maintenance::pipelines"
+ ~"maintenance::workflow"
-->
/label ~"type::maintenance"
diff --git a/.gitlab/merge_request_templates/Pipeline Configuration.md b/.gitlab/merge_request_templates/Pipeline Configuration.md
index a0b8d1cb8e4..336988d8bdf 100644
--- a/.gitlab/merge_request_templates/Pipeline Configuration.md
+++ b/.gitlab/merge_request_templates/Pipeline Configuration.md
@@ -35,4 +35,4 @@ This will help keep track of expected cost increases to the [GitLab project aver
- [ ] Consider communicating these changes to the broader team following the [communication guideline for pipeline changes](https://about.gitlab.com/handbook/engineering/quality/engineering-productivity/#pipeline-changes)
-/label ~"type::tooling" ~"tooling::pipelines" ~"Engineering Productivity"
+/label ~"maintenance::pipelines" ~"Engineering Productivity"
diff --git a/Gemfile b/Gemfile
index b37923973ea..ed18ae38318 100644
--- a/Gemfile
+++ b/Gemfile
@@ -403,7 +403,7 @@ group :development, :test do
end
group :development, :test, :danger do
- gem 'gitlab-dangerfiles', '~> 2.10.2', require: false
+ gem 'gitlab-dangerfiles', '~> 2.11.0', require: false
end
group :development, :test, :coverage do
diff --git a/Gemfile.lock b/Gemfile.lock
index a8a01945085..2b0057d353d 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -463,8 +463,8 @@ GEM
terminal-table (~> 1.5, >= 1.5.1)
gitlab-chronic (0.10.5)
numerizer (~> 0.2)
- gitlab-dangerfiles (2.10.2)
- danger (>= 8.3.1)
+ gitlab-dangerfiles (2.11.0)
+ danger (>= 8.4.5)
danger-gitlab (>= 8.0.0)
gitlab-experiment (0.7.0)
activesupport (>= 3.0)
@@ -1494,7 +1494,7 @@ DEPENDENCIES
gitaly (~> 14.9.0.pre.rc4)
github-markup (~> 1.7.0)
gitlab-chronic (~> 0.10.5)
- gitlab-dangerfiles (~> 2.10.2)
+ gitlab-dangerfiles (~> 2.11.0)
gitlab-experiment (~> 0.7.0)
gitlab-fog-azure-rm (~> 1.2.0)
gitlab-labkit (~> 0.22.0)
diff --git a/app/assets/javascripts/editor/schema/ci.json b/app/assets/javascripts/editor/schema/ci.json
index 4d9fe6ff851..84220d59205 100644
--- a/app/assets/javascripts/editor/schema/ci.json
+++ b/app/assets/javascripts/editor/schema/ci.json
@@ -423,37 +423,34 @@
"description": "Defines secrets to be injected as environment variables",
"additionalProperties": {
"type": "object",
- "additionalProperties": {
- "type": "object",
- "description": "Environment variable name",
- "properties": {
- "vault": {
- "oneOf": [
- {
- "type": "string",
- "description": "The secret to be fetched from Vault (e.g. 'production/db/password@ops' translates to secret 'ops/data/production/db', field `password`)"
- },
- {
- "type": "object",
- "properties": {
- "engine": {
- "type": "object",
- "properties": {
- "name": { "type": "string" },
- "path": { "type": "string" }
- },
- "required": ["name", "path"]
+ "description": "Environment variable name",
+ "properties": {
+ "vault": {
+ "oneOf": [
+ {
+ "type": "string",
+ "description": "The secret to be fetched from Vault (e.g. 'production/db/password@ops' translates to secret 'ops/data/production/db', field `password`)"
+ },
+ {
+ "type": "object",
+ "properties": {
+ "engine": {
+ "type": "object",
+ "properties": {
+ "name": { "type": "string" },
+ "path": { "type": "string" }
},
- "path": { "type": "string" },
- "field": { "type": "string" }
+ "required": ["name", "path"]
},
- "required": ["engine", "path", "field"]
- }
- ]
- }
- },
- "required": ["vault"]
- }
+ "path": { "type": "string" },
+ "field": { "type": "string" }
+ },
+ "required": ["engine", "path", "field"]
+ }
+ ]
+ }
+ },
+ "required": ["vault"]
}
},
"before_script": {
diff --git a/app/assets/javascripts/runner/components/runner_pause_button.vue b/app/assets/javascripts/runner/components/runner_pause_button.vue
index a1901c55e61..c88634bfbd9 100644
--- a/app/assets/javascripts/runner/components/runner_pause_button.vue
+++ b/app/assets/javascripts/runner/components/runner_pause_button.vue
@@ -3,7 +3,7 @@ import { GlButton, GlTooltipDirective } from '@gitlab/ui';
import runnerToggleActiveMutation from '~/runner/graphql/shared/runner_toggle_active.mutation.graphql';
import { createAlert } from '~/flash';
import { captureException } from '~/runner/sentry_utils';
-import { I18N_PAUSE, I18N_RESUME } from '../constants';
+import { I18N_PAUSE, I18N_PAUSE_TOOLTIP, I18N_RESUME, I18N_RESUME_TOOLTIP } from '../constants';
export default {
name: 'RunnerPauseButton',
@@ -52,11 +52,10 @@ export default {
return null;
},
tooltip() {
- // Only show tooltip when compact.
- // Also prevent a "sticky" tooltip: If this button is
- // disabled, mouseout listeners don't run leaving the tooltip stuck
- if (this.compact && !this.updating) {
- return this.label;
+ // Prevent a "sticky" tooltip: If this button is disabled,
+ // mouseout listeners don't run leaving the tooltip stuck
+ if (!this.updating) {
+ return this.isActive ? I18N_PAUSE_TOOLTIP : I18N_RESUME_TOOLTIP;
}
return '';
},
@@ -102,7 +101,7 @@ export default {
<template>
<gl-button
- v-gl-tooltip.hover.viewport="tooltip"
+ v-gl-tooltip="tooltip"
v-bind="$attrs"
:aria-label="ariaLabel"
:icon="icon"
diff --git a/app/assets/javascripts/runner/components/runner_paused_badge.vue b/app/assets/javascripts/runner/components/runner_paused_badge.vue
index d1e6fa05e4d..27618290ce6 100644
--- a/app/assets/javascripts/runner/components/runner_paused_badge.vue
+++ b/app/assets/javascripts/runner/components/runner_paused_badge.vue
@@ -1,6 +1,6 @@
<script>
import { GlBadge, GlTooltipDirective } from '@gitlab/ui';
-import { I18N_PAUSED_RUNNER_DESCRIPTION } from '../constants';
+import { I18N_PAUSED_DESCRIPTION } from '../constants';
export default {
components: {
@@ -9,17 +9,11 @@ export default {
directives: {
GlTooltip: GlTooltipDirective,
},
- i18n: {
- I18N_PAUSED_RUNNER_DESCRIPTION,
- },
+ I18N_PAUSED_DESCRIPTION,
};
</script>
<template>
- <gl-badge
- v-gl-tooltip="$options.i18n.I18N_PAUSED_RUNNER_DESCRIPTION"
- variant="danger"
- v-bind="$attrs"
- >
+ <gl-badge v-gl-tooltip="$options.I18N_PAUSED_DESCRIPTION" variant="danger" v-bind="$attrs">
{{ s__('Runners|paused') }}
</gl-badge>
</template>
diff --git a/app/assets/javascripts/runner/constants.js b/app/assets/javascripts/runner/constants.js
index 7ac19210fb1..bd5be2175ad 100644
--- a/app/assets/javascripts/runner/constants.js
+++ b/app/assets/javascripts/runner/constants.js
@@ -37,13 +37,18 @@ export const I18N_STALE_RUNNER_DESCRIPTION = s__(
// Actions
export const I18N_EDIT = __('Edit');
+
export const I18N_PAUSE = __('Pause');
+export const I18N_PAUSE_TOOLTIP = s__('Runners|Pause from accepting jobs');
+export const I18N_PAUSED_DESCRIPTION = s__('Runners|Not accepting jobs');
+
export const I18N_RESUME = __('Resume');
+export const I18N_RESUME_TOOLTIP = s__('Runners|Resume accepting jobs');
+
export const I18N_DELETE_RUNNER = s__('Runners|Delete runner');
export const I18N_DELETED_TOAST = s__('Runners|Runner %{name} was deleted');
export const I18N_LOCKED_RUNNER_DESCRIPTION = s__('Runners|You cannot assign to other projects');
-export const I18N_PAUSED_RUNNER_DESCRIPTION = s__('Runners|Not available to run jobs');
// Runner details
diff --git a/app/models/application_setting.rb b/app/models/application_setting.rb
index 3453518fea8..c7aad7ff861 100644
--- a/app/models/application_setting.rb
+++ b/app/models/application_setting.rb
@@ -657,7 +657,17 @@ class ApplicationSetting < ApplicationRecord
users_count >= INSTANCE_REVIEW_MIN_USERS
end
+ Recursion = Class.new(RuntimeError)
+
def self.create_from_defaults
+ # this is posssible if calls to create the record depend on application
+ # settings themselves. This was seen in the case of a feature flag called by
+ # `transaction` that ended up requiring application settings to determine metrics behavior.
+ # If something like that happens, we break the loop here, and let the caller decide how to manage it.
+ raise Recursion if Thread.current[:application_setting_create_from_defaults]
+
+ Thread.current[:application_setting_create_from_defaults] = true
+
check_schema!
transaction(requires_new: true) do # rubocop:disable Performance/ActiveRecordSubtransactions
@@ -666,6 +676,8 @@ class ApplicationSetting < ApplicationRecord
rescue ActiveRecord::RecordNotUnique
# We already have an ApplicationSetting record, so just return it.
current_without_cache
+ ensure
+ Thread.current[:application_setting_create_from_defaults] = nil
end
def self.find_or_create_without_cache
diff --git a/app/models/integrations/zentao.rb b/app/models/integrations/zentao.rb
index 0d437d335e9..c33df465fde 100644
--- a/app/models/integrations/zentao.rb
+++ b/app/models/integrations/zentao.rb
@@ -11,7 +11,6 @@ module Integrations
validates :api_token, presence: true, if: :activated?
validates :zentao_product_xid, presence: true, if: :activated?
- # License Level: EEP_FEATURES
def self.issues_license_available?(project)
project&.licensed_feature_available?(:zentao_issues_integration)
end
diff --git a/app/services/concerns/members/bulk_create_users.rb b/app/services/concerns/members/bulk_create_users.rb
index 9cfef96311e..3f8971dde74 100644
--- a/app/services/concerns/members/bulk_create_users.rb
+++ b/app/services/concerns/members/bulk_create_users.rb
@@ -47,16 +47,15 @@ module Members
end
end
- if user_ids.present?
- # we should handle the idea of existing members where users are passed as users - https://gitlab.com/gitlab-org/gitlab/-/issues/352617
- # the below will automatically discard invalid user_ids
- users.concat(User.id_in(user_ids))
+ # the below will automatically discard invalid user_ids
+ users.concat(User.id_in(user_ids)) if user_ids.present?
+ users.uniq! # de-duplicate just in case as there is no controlling if user records and ids are sent multiple times
+
+ if users.present?
# helps not have to perform another query per user id to see if the member exists later on when fetching
- existing_members = source.members_and_requesters.where(user_id: user_ids).index_by(&:user_id) # rubocop:disable CodeReuse/ActiveRecord
+ existing_members = source.members_and_requesters.where(user_id: users).index_by(&:user_id) # rubocop:disable CodeReuse/ActiveRecord
end
- users.uniq! # de-duplicate just in case as there is no controlling if user records and ids are sent multiple times
-
[emails, users, existing_members]
end
end
diff --git a/app/views/groups/runners/_runner.html.haml b/app/views/groups/runners/_runner.html.haml
index 3297d3c473f..b2d8b9668e7 100644
--- a/app/views/groups/runners/_runner.html.haml
+++ b/app/views/groups/runners/_runner.html.haml
@@ -9,7 +9,7 @@
- if runner.locked?
= gl_badge_tag s_('Runners|locked'), variant: :warning, size: :sm
- unless runner.active?
- = gl_badge_tag s_('Runners|paused'), variant: :danger, size: :sm
+ = gl_badge_tag s_('Runners|paused'), { variant: :danger, size: :sm }, { title: s_('Runners|Not accepting jobs'), data: { toggle: 'tooltip', container: 'body' } }
.table-section.section-30
.table-mobile-header{ role: 'rowheader' }= s_('Runners|Runner')
@@ -64,10 +64,10 @@
= sprite_icon('pencil', css_class: 'gl-icon')
.btn-group
- if runner.active?
- = link_to pause_group_runner_path(@group, runner), method: :post, class: 'gl-button btn btn-default btn-icon has-tooltip', title: _('Pause'), ref: 'tooltip', aria: { label: _('Pause') }, data: { placement: 'top', container: 'body', confirm: _('Are you sure?') } do
+ = link_to pause_group_runner_path(@group, runner), method: :post, class: 'gl-button btn btn-default btn-icon', title: s_('Runners|Pause from accepting jobs'), ref: 'tooltip', aria: { label: _('Pause') }, data: { toggle: 'tooltip', container: 'body', confirm: _('Are you sure?') } do
= sprite_icon('pause', css_class: 'gl-icon')
- else
- = link_to resume_group_runner_path(@group, runner), method: :post, class: 'gl-button btn btn-default btn-icon has-tooltip', title: _('Resume'), ref: 'tooltip', aria: { label: _('Resume') }, data: { placement: 'top', container: 'body'} do
+ = link_to resume_group_runner_path(@group, runner), method: :post, class: 'gl-button btn btn-default btn-icon', title: s_('Runners|Resume accepting jobs'), ref: 'tooltip', aria: { label: _('Resume') }, data: { toggle: 'tooltip', container: 'body'} do
= sprite_icon('play', css_class: 'gl-icon')
- if runner.belongs_to_more_than_one_project?
- delete_runner_tooltip = _('Multi-project Runners cannot be removed')
diff --git a/app/views/projects/commits/_commits.html.haml b/app/views/projects/commits/_commits.html.haml
index 4837f829568..02b5fe00ad0 100644
--- a/app/views/projects/commits/_commits.html.haml
+++ b/app/views/projects/commits/_commits.html.haml
@@ -34,10 +34,11 @@
= render partial: 'projects/commits/commit', collection: context_commits, locals: { project: project, ref: ref, merge_request: merge_request }
- if hidden > 0
- %li.gl-alert.gl-alert-warning
- .gl-alert-container
- = sprite_icon('warning', size: 16, css_class: 'gl-icon gl-alert-icon gl-alert-icon-no-title')
- .gl-alert-content
+ %li
+ = render 'shared/global_alert',
+ variant: :warning,
+ dismissible: false do
+ .gl-alert-body
= n_('%s additional commit has been omitted to prevent performance issues.', '%s additional commits have been omitted to prevent performance issues.', hidden) % number_with_delimiter(hidden)
- if can_update_merge_request && context_commits&.empty?
diff --git a/app/views/projects/runners/_runner.html.haml b/app/views/projects/runners/_runner.html.haml
index 28e5618f8b0..5eaf6c9d22b 100644
--- a/app/views/projects/runners/_runner.html.haml
+++ b/app/views/projects/runners/_runner.html.haml
@@ -16,10 +16,10 @@
= link_to edit_project_runner_path(@project, runner), class: 'btn gl-button btn-icon', title: _('Edit'), aria: { label: _('Edit') }, data: { testid: 'edit-runner-link', toggle: 'tooltip', placement: 'top', container: 'body' } do
= sprite_icon('pencil')
- if runner.active?
- = link_to pause_project_runner_path(@project, runner), method: :post, class: 'btn gl-button btn-icon', title: _('Pause'), aria: { label: _('Pause') }, data: { toggle: 'tooltip', placement: 'top', container: 'body', confirm: _("Are you sure?") } do
+ = link_to pause_project_runner_path(@project, runner), method: :post, class: 'btn gl-button btn-icon', title: s_('Runners|Pause from accepting jobs'), aria: { label: _('Pause') }, data: { toggle: 'tooltip', container: 'body', confirm: _("Are you sure?") } do
= sprite_icon('pause')
- else
- = link_to resume_project_runner_path(@project, runner), method: :post, class: 'btn gl-button btn-icon', title: _('Resume'), aria: { label: _('Resume') }, data: { toggle: 'tooltip', placement: 'top', container: 'body' } do
+ = link_to resume_project_runner_path(@project, runner), method: :post, class: 'btn gl-button btn-icon', title: s_('Runners|Resume accepting jobs'), aria: { label: _('Resume') }, data: { toggle: 'tooltip', container: 'body' } do
= sprite_icon('play')
- if runner.belongs_to_one_project?
= link_to _('Remove runner'), project_runner_path(@project, runner), data: { confirm: _("Are you sure?") }, method: :delete, class: 'btn gl-button btn-danger'
diff --git a/danger/specialization_labels/Dangerfile b/danger/specialization_labels/Dangerfile
index b3520e7af7e..f161c470f36 100644
--- a/danger/specialization_labels/Dangerfile
+++ b/danger/specialization_labels/Dangerfile
@@ -9,7 +9,6 @@ SPECIALIZATIONS = {
ux: 'UX',
docs: 'documentation',
qa: 'QA',
- tooling: 'type::tooling',
ci_template: 'ci::templates',
feature_flag: 'feature flag'
}.freeze
diff --git a/danger/specs/Dangerfile b/danger/specs/Dangerfile
index c4f609f5806..8ef046f7bc1 100644
--- a/danger/specs/Dangerfile
+++ b/danger/specs/Dangerfile
@@ -1,9 +1,8 @@
# frozen_string_literal: true
NO_SPECS_LABELS = [
- 'type::tooling',
- 'tooling::pipelines',
- 'tooling::workflow',
+ 'maintenance::pipelines',
+ 'maintenance::workflow',
'documentation',
'QA'
].freeze
diff --git a/doc/administration/object_storage.md b/doc/administration/object_storage.md
index c303dc1fd19..8ea4ad9019e 100644
--- a/doc/administration/object_storage.md
+++ b/doc/administration/object_storage.md
@@ -598,6 +598,7 @@ See the following additional guides:
1. Configure [database lookup of SSH keys](operations/fast_ssh_key_lookup.md)
to eliminate the need for a shared `authorized_keys` file.
1. [Prevent local disk usage for job logs](job_logs.md#prevent-local-disk-usage).
+1. [Disable Pages local storage](pages/index.md#disable-pages-local-storage).
## Warnings, limitations, and known issues
diff --git a/doc/administration/pages/index.md b/doc/administration/pages/index.md
index f000824711f..be1ec290c95 100644
--- a/doc/administration/pages/index.md
+++ b/doc/administration/pages/index.md
@@ -547,6 +547,7 @@ archive. You can modify the cache behavior by changing the following configurati
| `zip_cache_cleanup` | The interval at which archives are cleaned from memory if they have already expired. Default is 30s. |
| `zip_cache_refresh` | The time interval in which an archive is extended in memory if accessed before `zip_cache_expiration`. This works together with `zip_cache_expiration` to determine if an archive is extended in memory. See the [example below](#zip-cache-refresh-example) for important details. Default is 30s. |
| `zip_open_timeout` | The maximum time allowed to open a ZIP archive. Increase this time for big archives or slow network connections, as doing so may affect the latency of serving Pages. Default is 30s. |
+| `zip_http_client_timeout` | The maximum time for the ZIP HTTP client. Default is 30m. |
#### ZIP cache refresh example
diff --git a/doc/api/index.md b/doc/api/index.md
index 40b3fd4e22a..6cdf64a01af 100644
--- a/doc/api/index.md
+++ b/doc/api/index.md
@@ -8,9 +8,6 @@ info: To determine the technical writer assigned to the Stage/Group associated w
Use the GitLab APIs to automate GitLab.
-NOTE:
-We've launched our first API user survey! Do you use GitLab APIs? How can we improve? [Contribute your feedback today](https://gitlab.fra1.qualtrics.com/jfe/form/SV_cD9wcDYMcVDruSy) and make sure your voice is heard!
-
## REST API
A REST API is available in GitLab.
diff --git a/doc/ci/environments/deployment_approvals.md b/doc/ci/environments/deployment_approvals.md
index 12090443e61..e42cde031ad 100644
--- a/doc/ci/environments/deployment_approvals.md
+++ b/doc/ci/environments/deployment_approvals.md
@@ -11,7 +11,7 @@ description: Require approvals prior to deploying to a Protected Environment
> - [Feature flag removed](https://gitlab.com/gitlab-org/gitlab/-/issues/347342) in GitLab 14.8.
WARNING:
-This feature is in an [Alpha](../../policy/alpha-beta-support.md#alpha-features) stage and subject to change without prior notice.
+This feature is in a [Beta](../../policy/alpha-beta-support.md#beta-features) stage and subject to change without prior notice.
It may be useful to require additional approvals before deploying to certain protected environments (for example, production). This pre-deployment approval requirement is useful to accommodate testing, security, or compliance processes that must happen before each deployment.
diff --git a/doc/development/contributing/issue_workflow.md b/doc/development/contributing/issue_workflow.md
index ad8403d242c..4db686b9b1e 100644
--- a/doc/development/contributing/issue_workflow.md
+++ b/doc/development/contributing/issue_workflow.md
@@ -45,7 +45,7 @@ scheduling into milestones. Labeling is a task for everyone. (For some projects,
Most issues will have labels for at least one of the following:
-- Type. For example: `~"type::feature"`, `~"type::bug"`, or `~"type::tooling"`.
+- Type. For example: `~"type::feature"`, `~"type::bug"`, or `~"type::maintenance"`.
- Stage. For example: `~"devops::plan"` or `~"devops::create"`.
- Group. For example: `~"group::source code"`, `~"group::knowledge"`, or `~"group::editor"`.
- Category. For example: `~"Category:Code Analytics"`, `~"Category:DevOps Reports"`, or `~"Category:Templates"`.
@@ -72,19 +72,7 @@ labels, you can _always_ add the type, stage, group, and often the category/feat
Type labels are very important. They define what kind of issue this is. Every
issue should have one and only one.
-The current type labels are:
-
-- `~"type::feature"`
- - `~"feature::addition"`
- - `~"feature::enhancement"`
-- `~"type::maintenance"`
-- `~"type::bug"`
-- `~"type::tooling"`
- - `~"tooling::pipelines"`
- - `~"tooling::workflow"`
-- `~"support request"`
-- `~meta`
-- `~documentation`
+The current type labels are [available in the handbook](https://about.gitlab.com/handbook/engineering/metrics/#work-type-classification)
A number of type labels have a priority assigned to them, which automatically
makes them float to the top, depending on their importance.
diff --git a/doc/development/documentation/testing.md b/doc/development/documentation/testing.md
index a8745b974b9..2c97b5e2aff 100644
--- a/doc/development/documentation/testing.md
+++ b/doc/development/documentation/testing.md
@@ -313,6 +313,9 @@ To configure Vale in your editor, install one of the following as appropriate:
- Visual Studio Code [`errata-ai.vale-server` extension](https://marketplace.visualstudio.com/items?itemName=errata-ai.vale-server).
You can configure the plugin to [display only a subset of alerts](#show-subset-of-vale-alerts).
- Vim [ALE plugin](https://github.com/dense-analysis/ale).
+- Jetbrains IDEs - No plugin exists, but
+ [this issue comment](https://github.com/errata-ai/vale-server/issues/39#issuecomment-751714451)
+ contains tips for configuring an external tool.
- Emacs [Flycheck extension](https://github.com/flycheck/flycheck).
This requires some configuration:
diff --git a/doc/development/licensed_feature_availability.md b/doc/development/licensed_feature_availability.md
index 629d0027ffe..0de3f94cf70 100644
--- a/doc/development/licensed_feature_availability.md
+++ b/doc/development/licensed_feature_availability.md
@@ -17,9 +17,8 @@ feature such as [Related issues](../user/project/issues/related_issues.md) or
[Service Desk](../user/project/service_desk.md),
it should be restricted on namespace scope.
-1. Add the feature symbol on `EES_FEATURES`, `EEP_FEATURES`, or `EEU_FEATURES` constants in
- `ee/app/models/license.rb`. Note that the prefix `EES` signifies Starter, `EEP` signifies
- Premium, and `EEU` signifies Ultimate.
+1. Add the feature symbol on `STARTER_FEATURES`, `PREMIUM_FEATURES`, or `ULTIMATE_FEATURES` constants in
+ `ee/app/models/gitlab_subscriptions/features.rb`.
1. Check using:
```ruby
@@ -33,8 +32,8 @@ However, for features such as [Geo](../administration/geo/index.md) and
to only a subset of projects or namespaces, the check is made directly in
the instance license.
-1. Add the feature symbol on `EES_FEATURES`, `EEP_FEATURES` or `EEU_FEATURES` constants in
- `ee/app/models/license.rb`.
+1. Add the feature symbol to `STARTER_FEATURES`, `PREMIUM_FEATURES` or `ULTIMATE_FEATURES` constants in
+ `ee/app/models/gitlab_subscriptions/features.rb`.
1. Add the same feature symbol to `GLOBAL_FEATURES`.
1. Check using:
diff --git a/doc/development/service_ping/metrics_dictionary.md b/doc/development/service_ping/metrics_dictionary.md
index 588453be002..6884844da3f 100644
--- a/doc/development/service_ping/metrics_dictionary.md
+++ b/doc/development/service_ping/metrics_dictionary.md
@@ -49,7 +49,7 @@ Each metric is defined in a separate YAML file consisting of a number of fields:
| `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 and when it's available to self-managed instances with the official GitLab release. |
| `milestone_removed` | no | The milestone when the metric is removed. |
-| `introduced_by_url` | no | The URL to the merge request that introduced the metric. |
+| `introduced_by_url` | no | The URL to the merge request that introduced the metric to be available for self-managed instances. |
| `repair_issue_url` | no | The URL of the issue that was created to repair a metric with a `broken` status. |
| `options` | no | `object`: options information needed to calculate the metric value. |
| `skip_validation` | no | This should **not** be set. [Used for imported metrics until we review, update and make them valid](https://gitlab.com/groups/gitlab-org/-/epics/5425). |
diff --git a/lib/gitlab/current_settings.rb b/lib/gitlab/current_settings.rb
index 0d6767ad564..8ef4977177a 100644
--- a/lib/gitlab/current_settings.rb
+++ b/lib/gitlab/current_settings.rb
@@ -70,6 +70,8 @@ module Gitlab
else
::ApplicationSetting.create_from_defaults
end
+ rescue ::ApplicationSetting::Recursion
+ in_memory_application_settings
end
def fake_application_settings(attributes = {})
diff --git a/lib/security/ci_configuration/base_build_action.rb b/lib/security/ci_configuration/base_build_action.rb
index 9c2670144e3..8f0765a35c2 100644
--- a/lib/security/ci_configuration/base_build_action.rb
+++ b/lib/security/ci_configuration/base_build_action.rb
@@ -6,7 +6,7 @@ module Security
def initialize(auto_devops_enabled, existing_gitlab_ci_content, ci_config_path = ::Ci::Pipeline::DEFAULT_CONFIG_PATH)
@auto_devops_enabled = auto_devops_enabled
@existing_gitlab_ci_content = existing_gitlab_ci_content || {}
- @ci_config_path = ci_config_path || ::Ci::Pipeline::DEFAULT_CONFIG_PATH
+ @ci_config_path = ci_config_path.presence || ::Ci::Pipeline::DEFAULT_CONFIG_PATH
end
def generate
diff --git a/locale/gitlab.pot b/locale/gitlab.pot
index 989c38161be..d1e24d7ea43 100644
--- a/locale/gitlab.pot
+++ b/locale/gitlab.pot
@@ -31912,7 +31912,7 @@ msgstr ""
msgid "Runners|No recent contact from this runner; last contact was %{timeAgo}"
msgstr ""
-msgid "Runners|Not available to run jobs"
+msgid "Runners|Not accepting jobs"
msgstr ""
msgid "Runners|Offline"
@@ -31927,6 +31927,9 @@ msgstr ""
msgid "Runners|Online runners"
msgstr ""
+msgid "Runners|Pause from accepting jobs"
+msgstr ""
+
msgid "Runners|Paused"
msgstr ""
@@ -31963,6 +31966,9 @@ msgstr ""
msgid "Runners|Reset token"
msgstr ""
+msgid "Runners|Resume accepting jobs"
+msgstr ""
+
msgid "Runners|Revision"
msgstr ""
diff --git a/spec/frontend/runner/components/runner_pause_button_spec.js b/spec/frontend/runner/components/runner_pause_button_spec.js
index c69bae05e45..3d9df03977e 100644
--- a/spec/frontend/runner/components/runner_pause_button_spec.js
+++ b/spec/frontend/runner/components/runner_pause_button_spec.js
@@ -8,6 +8,12 @@ import runnerToggleActiveMutation from '~/runner/graphql/shared/runner_toggle_ac
import waitForPromises from 'helpers/wait_for_promises';
import { captureException } from '~/runner/sentry_utils';
import { createAlert } from '~/flash';
+import {
+ I18N_PAUSE,
+ I18N_PAUSE_TOOLTIP,
+ I18N_RESUME,
+ I18N_RESUME_TOOLTIP,
+} from '~/runner/constants';
import RunnerPauseButton from '~/runner/components/runner_pause_button.vue';
import { runnersData } from '../mock_data';
@@ -74,10 +80,10 @@ describe('RunnerPauseButton', () => {
describe('Pause/Resume action', () => {
describe.each`
- runnerState | icon | content | isActive | newActiveValue
- ${'paused'} | ${'play'} | ${'Resume'} | ${false} | ${true}
- ${'active'} | ${'pause'} | ${'Pause'} | ${true} | ${false}
- `('When the runner is $runnerState', ({ icon, content, isActive, newActiveValue }) => {
+ runnerState | icon | content | tooltip | isActive | newActiveValue
+ ${'paused'} | ${'play'} | ${I18N_RESUME} | ${I18N_RESUME_TOOLTIP} | ${false} | ${true}
+ ${'active'} | ${'pause'} | ${I18N_PAUSE} | ${I18N_PAUSE_TOOLTIP} | ${true} | ${false}
+ `('When the runner is $runnerState', ({ icon, content, tooltip, isActive, newActiveValue }) => {
beforeEach(() => {
createComponent({
props: {
@@ -91,7 +97,11 @@ describe('RunnerPauseButton', () => {
it(`Displays a ${icon} button`, () => {
expect(findBtn().props('loading')).toBe(false);
expect(findBtn().props('icon')).toBe(icon);
+ });
+
+ it('Displays button content', () => {
expect(findBtn().text()).toBe(content);
+ expect(getTooltip()).toBe(tooltip);
});
it('Does not display redundant text for screen readers', () => {
@@ -218,8 +228,8 @@ describe('RunnerPauseButton', () => {
});
it('Display correctly for screen readers', () => {
- expect(findBtn().attributes('aria-label')).toBe('Pause');
- expect(getTooltip()).toBe('Pause');
+ expect(findBtn().attributes('aria-label')).toBe(I18N_PAUSE);
+ expect(getTooltip()).toBe(I18N_PAUSE_TOOLTIP);
});
describe('Immediately after the button is clicked', () => {
diff --git a/spec/lib/gitlab/current_settings_spec.rb b/spec/lib/gitlab/current_settings_spec.rb
index 73540a9b0f3..fda3b07eb82 100644
--- a/spec/lib/gitlab/current_settings_spec.rb
+++ b/spec/lib/gitlab/current_settings_spec.rb
@@ -179,6 +179,21 @@ RSpec.describe Gitlab::CurrentSettings do
expect(settings).to have_attributes(settings_from_defaults)
end
+ context 'when we hit a recursive loop' do
+ before do
+ expect(ApplicationSetting).to receive(:create_from_defaults) do
+ raise ApplicationSetting::Recursion
+ end
+ end
+
+ it 'recovers and returns in-memory settings' do
+ settings = described_class.current_application_settings
+
+ expect(settings).to be_a(ApplicationSetting)
+ expect(settings).not_to be_persisted
+ end
+ end
+
context 'when ApplicationSettings does not have a primary key' do
before do
allow(ApplicationSetting.connection).to receive(:primary_key).with('application_settings').and_return(nil)
diff --git a/spec/lib/security/ci_configuration/sast_iac_build_action_spec.rb b/spec/lib/security/ci_configuration/sast_iac_build_action_spec.rb
index 4c459058368..7b2a0d22918 100644
--- a/spec/lib/security/ci_configuration/sast_iac_build_action_spec.rb
+++ b/spec/lib/security/ci_configuration/sast_iac_build_action_spec.rb
@@ -7,12 +7,13 @@ RSpec.describe Security::CiConfiguration::SastIacBuildAction do
let(:params) { {} }
- context 'with existing .gitlab-ci.yml' do
- let(:auto_devops_enabled) { false }
+ shared_examples 'existing .gitlab-ci.yml tests' do
+ context 'with existing .gitlab-ci.yml' do
+ let(:auto_devops_enabled) { false }
- context 'sast iac has not been included' do
- let(:expected_yml) do
- <<-CI_YML.strip_heredoc
+ context 'sast iac has not been included' do
+ let(:expected_yml) do
+ <<-CI_YML.strip_heredoc
# You can override the included template(s) by including variable overrides
# SAST customization: https://docs.gitlab.com/ee/user/application_security/sast/#customizing-the-sast-settings
# Secret Detection customization: https://docs.gitlab.com/ee/user/application_security/secret_detection/#customizing-settings
@@ -28,39 +29,39 @@ RSpec.describe Security::CiConfiguration::SastIacBuildAction do
include:
- template: existing.yml
- template: Security/SAST-IaC.latest.gitlab-ci.yml
- CI_YML
- end
-
- context 'template includes are an array' do
- let(:gitlab_ci_content) do
- { "stages" => %w(test security),
- "variables" => { "RANDOM" => "make sure this persists" },
- "include" => [{ "template" => "existing.yml" }] }
+ CI_YML
end
- it 'generates the correct YML' do
- expect(result[:action]).to eq('update')
- expect(result[:content]).to eq(expected_yml)
- end
- end
-
- context 'template include is not an array' do
- let(:gitlab_ci_content) do
- { "stages" => %w(test security),
- "variables" => { "RANDOM" => "make sure this persists" },
- "include" => { "template" => "existing.yml" } }
+ context 'template includes are an array' do
+ let(:gitlab_ci_content) do
+ { "stages" => %w(test security),
+ "variables" => { "RANDOM" => "make sure this persists" },
+ "include" => [{ "template" => "existing.yml" }] }
+ end
+
+ it 'generates the correct YML' do
+ expect(result[:action]).to eq('update')
+ expect(result[:content]).to eq(expected_yml)
+ end
end
- it 'generates the correct YML' do
- expect(result[:action]).to eq('update')
- expect(result[:content]).to eq(expected_yml)
+ context 'template include is not an array' do
+ let(:gitlab_ci_content) do
+ { "stages" => %w(test security),
+ "variables" => { "RANDOM" => "make sure this persists" },
+ "include" => { "template" => "existing.yml" } }
+ end
+
+ it 'generates the correct YML' do
+ expect(result[:action]).to eq('update')
+ expect(result[:content]).to eq(expected_yml)
+ end
end
end
- end
- context 'secret_detection has been included' do
- let(:expected_yml) do
- <<-CI_YML.strip_heredoc
+ context 'secret_detection has been included' do
+ let(:expected_yml) do
+ <<-CI_YML.strip_heredoc
# You can override the included template(s) by including variable overrides
# SAST customization: https://docs.gitlab.com/ee/user/application_security/sast/#customizing-the-sast-settings
# Secret Detection customization: https://docs.gitlab.com/ee/user/application_security/secret_detection/#customizing-settings
@@ -74,37 +75,50 @@ RSpec.describe Security::CiConfiguration::SastIacBuildAction do
RANDOM: make sure this persists
include:
- template: Security/SAST-IaC.latest.gitlab-ci.yml
- CI_YML
- end
-
- context 'secret_detection template include are an array' do
- let(:gitlab_ci_content) do
- { "stages" => %w(test),
- "variables" => { "RANDOM" => "make sure this persists" },
- "include" => [{ "template" => "Security/SAST-IaC.latest.gitlab-ci.yml" }] }
+ CI_YML
end
- it 'generates the correct YML' do
- expect(result[:action]).to eq('update')
- expect(result[:content]).to eq(expected_yml)
- end
- end
-
- context 'secret_detection template include is not an array' do
- let(:gitlab_ci_content) do
- { "stages" => %w(test),
- "variables" => { "RANDOM" => "make sure this persists" },
- "include" => { "template" => "Security/SAST-IaC.latest.gitlab-ci.yml" } }
+ context 'secret_detection template include are an array' do
+ let(:gitlab_ci_content) do
+ { "stages" => %w(test),
+ "variables" => { "RANDOM" => "make sure this persists" },
+ "include" => [{ "template" => "Security/SAST-IaC.latest.gitlab-ci.yml" }] }
+ end
+
+ it 'generates the correct YML' do
+ expect(result[:action]).to eq('update')
+ expect(result[:content]).to eq(expected_yml)
+ end
end
- it 'generates the correct YML' do
- expect(result[:action]).to eq('update')
- expect(result[:content]).to eq(expected_yml)
+ context 'secret_detection template include is not an array' do
+ let(:gitlab_ci_content) do
+ { "stages" => %w(test),
+ "variables" => { "RANDOM" => "make sure this persists" },
+ "include" => { "template" => "Security/SAST-IaC.latest.gitlab-ci.yml" } }
+ end
+
+ it 'generates the correct YML' do
+ expect(result[:action]).to eq('update')
+ expect(result[:content]).to eq(expected_yml)
+ end
end
end
end
end
+ context 'with existing .gitlab-ci.yml and when the ci config file configuration was not set' do
+ subject(:result) { described_class.new(auto_devops_enabled, gitlab_ci_content).generate }
+
+ it_behaves_like 'existing .gitlab-ci.yml tests'
+ end
+
+ context 'with existing .gitlab-ci.yml and when the ci config file configuration was deleted' do
+ subject(:result) { described_class.new(auto_devops_enabled, gitlab_ci_content, ci_config_path: '').generate }
+
+ it_behaves_like 'existing .gitlab-ci.yml tests'
+ end
+
context 'with no .gitlab-ci.yml' do
let(:gitlab_ci_content) { nil }
diff --git a/spec/support/shared_examples/models/member_shared_examples.rb b/spec/support/shared_examples/models/member_shared_examples.rb
index f7e09cfca62..17026f085bb 100644
--- a/spec/support/shared_examples/models/member_shared_examples.rb
+++ b/spec/support/shared_examples/models/member_shared_examples.rb
@@ -371,8 +371,7 @@ RSpec.shared_examples_for "bulk member creation" do
it 'returns a Member objects' do
members = described_class.add_users(source, [user1, user2], :maintainer)
- expect(members).to be_a Array
- expect(members.size).to eq(2)
+ expect(members.map(&:user)).to contain_exactly(user1, user2)
expect(members).to all(be_a(member_type))
expect(members).to all(be_persisted)
end
@@ -394,20 +393,18 @@ RSpec.shared_examples_for "bulk member creation" do
end
context 'with de-duplication' do
- it 'with the same user by id and user' do
+ it 'has the same user by id and user' do
members = described_class.add_users(source, [user1.id, user1, user1.id, user2, user2.id, user2], :maintainer)
- expect(members).to be_a Array
- expect(members.size).to eq(2)
+ expect(members.map(&:user)).to contain_exactly(user1, user2)
expect(members).to all(be_a(member_type))
expect(members).to all(be_persisted)
end
- it 'with the same user sent more than once' do
+ it 'has the same user sent more than once' do
members = described_class.add_users(source, [user1, user1], :maintainer)
- expect(members).to be_a Array
- expect(members.size).to eq(1)
+ expect(members.map(&:user)).to contain_exactly(user1)
expect(members).to all(be_a(member_type))
expect(members).to all(be_persisted)
end
@@ -418,15 +415,35 @@ RSpec.shared_examples_for "bulk member creation" do
source.add_user(user1, :developer)
end
- it 'supports existing users as expected' do
+ it 'has the same user sent more than once with the member already existing' do
+ expect do
+ members = described_class.add_users(source, [user1, user1, user2], :maintainer)
+ expect(members.map(&:user)).to contain_exactly(user1, user2)
+ expect(members).to all(be_a(member_type))
+ expect(members).to all(be_persisted)
+ end.to change { Member.count }.by(1)
+ end
+
+ it 'supports existing users as expected with user_ids passed' do
user3 = create(:user)
- members = described_class.add_users(source, [user1.id, user2, user3.id], :maintainer)
+ expect do
+ members = described_class.add_users(source, [user1.id, user2, user3.id], :maintainer)
+ expect(members.map(&:user)).to contain_exactly(user1, user2, user3)
+ expect(members).to all(be_a(member_type))
+ expect(members).to all(be_persisted)
+ end.to change { Member.count }.by(2)
+ end
+
+ it 'supports existing users as expected without user ids passed' do
+ user3 = create(:user)
- expect(members).to be_a Array
- expect(members.size).to eq(3)
- expect(members).to all(be_a(member_type))
- expect(members).to all(be_persisted)
+ expect do
+ members = described_class.add_users(source, [user1, user2, user3], :maintainer)
+ expect(members.map(&:user)).to contain_exactly(user1, user2, user3)
+ expect(members).to all(be_a(member_type))
+ expect(members).to all(be_persisted)
+ end.to change { Member.count }.by(2)
end
end
diff --git a/spec/tooling/danger/datateam_spec.rb b/spec/tooling/danger/datateam_spec.rb
index 3bcef3ac886..e6698dd8970 100644
--- a/spec/tooling/danger/datateam_spec.rb
+++ b/spec/tooling/danger/datateam_spec.rb
@@ -62,28 +62,28 @@ RSpec.describe Tooling::Danger::Datateam do
'with metric file changes and no performance indicator changes and other label' => {
modified_files: %w(config/metrics/20210216182127_user_secret_detection_jobs.yml),
changed_lines: ['-product_stage: growth'],
- mr_labels: ['type::tooling'],
+ mr_labels: ['type::maintenance'],
impacted: false,
impacted_files: []
},
'with performance indicator changes and other label' => {
modified_files: %w(config/metrics/20210216182127_user_secret_detection_jobs.yml app/models/user.rb),
changed_lines: ['+-gmau'],
- mr_labels: ['type::tooling'],
+ mr_labels: ['type::maintenance'],
impacted: true,
impacted_files: %w(config/metrics/20210216182127_user_secret_detection_jobs.yml)
},
'with performance indicator changes, Data Warehouse::Impact Check and other label' => {
modified_files: %w(config/metrics/20210216182127_user_secret_detection_jobs.yml app/models/user.rb),
changed_lines: ['+-gmau'],
- mr_labels: ['type::tooling', 'Data Warehouse::Impact Check'],
+ mr_labels: ['type::maintenance', 'Data Warehouse::Impact Check'],
impacted: false,
impacted_files: %w(config/metrics/20210216182127_user_secret_detection_jobs.yml)
},
'with performance indicator changes and other labels' => {
modified_files: %w(config/metrics/20210216182127_user_secret_detection_jobs.yml app/models/user.rb),
changed_lines: ['+-gmau'],
- mr_labels: ['type::tooling', 'Data Warehouse::Impacted'],
+ mr_labels: ['type::maintenance', 'Data Warehouse::Impacted'],
impacted: false,
impacted_files: %w(config/metrics/20210216182127_user_secret_detection_jobs.yml)
}
diff --git a/workhorse/internal/upload/destination/destination.go b/workhorse/internal/upload/destination/destination.go
index df0d67aea30..7a030e59a64 100644
--- a/workhorse/internal/upload/destination/destination.go
+++ b/workhorse/internal/upload/destination/destination.go
@@ -1,3 +1,6 @@
+// The destination package handles uploading to a specific destination (delegates
+// to filestore or objectstore packages) based on options from the pre-authorization
+// API and finalizing the upload.
package destination
import (
diff --git a/workhorse/internal/upload/destination/filestore/filestore.go b/workhorse/internal/upload/destination/filestore/filestore.go
index f593cc30aeb..2d88874bf25 100644
--- a/workhorse/internal/upload/destination/filestore/filestore.go
+++ b/workhorse/internal/upload/destination/filestore/filestore.go
@@ -1,3 +1,4 @@
+// The filestore package has a consumer specific to uploading to local disk storage.
package filestore
import (
diff --git a/workhorse/internal/upload/destination/objectstore/doc.go b/workhorse/internal/upload/destination/objectstore/doc.go
new file mode 100644
index 00000000000..00f98f230ec
--- /dev/null
+++ b/workhorse/internal/upload/destination/objectstore/doc.go
@@ -0,0 +1,3 @@
+// The objectstore package consists of a number of consumers specific to uploading
+// to object storage providers that are S3 compatible (e.g. AWS S3, GCP, Azure).
+package objectstore