diff --git a/CHANGELOG.md b/CHANGELOG.md
index 5b6894e4e41..362ebae3c91 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2,6 +2,14 @@
documentation](doc/development/changelog.md) for instructions on adding your own
entry.
+## 14.3.3 (2021-10-12)
+
+### Fixed (3 changes)
+
+- [Disable caching of MergeToRefService call in mergeability check](gitlab-org/gitlab@ea9f38fb3ce1f9b345ca699b5f9ae7b36726a56f) ([merge request](gitlab-org/gitlab!72179))
+- [Fix 2FA setup for users with no password](gitlab-org/gitlab@c6d5cdfc3fa1a1dc0a6686a8f189972c03403f7a) ([merge request](gitlab-org/gitlab!72179))
+- [Fix dependency proxy image prefix](gitlab-org/gitlab@deb9719db05e99dec787bd76c5e96408f92eb802) ([merge request](gitlab-org/gitlab!72179))
+
## 14.3.2 (2021-10-01)
### Fixed (1 change)
diff --git a/app/assets/javascripts/pipeline_editor/components/ui/pipeline_editor_empty_state.vue b/app/assets/javascripts/pipeline_editor/components/ui/pipeline_editor_empty_state.vue
index fbb66231f16..dcd08c9de8d 100644
--- a/app/assets/javascripts/pipeline_editor/components/ui/pipeline_editor_empty_state.vue
+++ b/app/assets/javascripts/pipeline_editor/components/ui/pipeline_editor_empty_state.vue
@@ -2,7 +2,6 @@
import { GlButton, GlSprintf } from '@gitlab/ui';
import { __ } from '~/locale';
import PipelineEditorFileNav from '~/pipeline_editor/components/file_nav/pipeline_editor_file_nav.vue';
-import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
export default {
components: {
@@ -17,17 +16,11 @@ export default {
),
btnText: __('Create new CI/CD pipeline'),
},
- mixins: [glFeatureFlagsMixin()],
inject: {
emptyStateIllustrationPath: {
default: '',
},
},
- computed: {
- showCTAButton() {
- return this.glFeatures.pipelineEditorEmptyStateAction;
- },
- },
methods: {
createEmptyConfigFile() {
this.$emit('createEmptyConfigFile');
@@ -48,12 +41,7 @@ export default {
-
+
{{ $options.i18n.btnText }}
diff --git a/app/controllers/profiles/passwords_controller.rb b/app/controllers/profiles/passwords_controller.rb
index c8c2dd1c7d6..5eb0f80ddc9 100644
--- a/app/controllers/profiles/passwords_controller.rb
+++ b/app/controllers/profiles/passwords_controller.rb
@@ -15,17 +15,11 @@ class Profiles::PasswordsController < Profiles::ApplicationController
end
def create
- unless @user.password_automatically_set || @user.valid_password?(user_params[:current_password])
+ unless @user.password_automatically_set || @user.valid_password?(user_params[:password])
redirect_to new_profile_password_path, alert: _('You must provide a valid current password')
return
end
- password_attributes = {
- password: user_params[:password],
- password_confirmation: user_params[:password_confirmation],
- password_automatically_set: false
- }
-
result = Users::UpdateService.new(current_user, password_attributes.merge(user: @user)).execute
if result[:status] == :success
@@ -41,12 +35,7 @@ class Profiles::PasswordsController < Profiles::ApplicationController
end
def update
- password_attributes = user_params.select do |key, value|
- %w(password password_confirmation).include?(key.to_s)
- end
- password_attributes[:password_automatically_set] = false
-
- unless @user.password_automatically_set || @user.valid_password?(user_params[:current_password])
+ unless @user.password_automatically_set || @user.valid_password?(user_params[:password])
handle_invalid_current_password_attempt!
redirect_to edit_profile_password_path, alert: _('You must provide a valid current password')
@@ -94,6 +83,14 @@ class Profiles::PasswordsController < Profiles::ApplicationController
end
def user_params
- params.require(:user).permit(:current_password, :password, :password_confirmation)
+ params.require(:user).permit(:password, :new_password, :password_confirmation)
+ end
+
+ def password_attributes
+ {
+ password: user_params[:new_password],
+ password_confirmation: user_params[:password_confirmation],
+ password_automatically_set: false
+ }
end
end
diff --git a/app/controllers/projects/ci/pipeline_editor_controller.rb b/app/controllers/projects/ci/pipeline_editor_controller.rb
index 550877548e1..953b9d83a66 100644
--- a/app/controllers/projects/ci/pipeline_editor_controller.rb
+++ b/app/controllers/projects/ci/pipeline_editor_controller.rb
@@ -3,7 +3,6 @@
class Projects::Ci::PipelineEditorController < Projects::ApplicationController
before_action :check_can_collaborate!
before_action do
- push_frontend_feature_flag(:pipeline_editor_empty_state_action, @project, default_enabled: :yaml)
push_frontend_feature_flag(:pipeline_editor_drawer, @project, default_enabled: :yaml)
push_frontend_feature_flag(:schema_linting, @project, default_enabled: :yaml)
end
diff --git a/app/models/ci/build.rb b/app/models/ci/build.rb
index 1e0ce5638bb..226289e4f62 100644
--- a/app/models/ci/build.rb
+++ b/app/models/ci/build.rb
@@ -309,8 +309,10 @@ module Ci
end
after_transition pending: :running do |build|
- Gitlab::Database.allow_cross_database_modification_within_transaction(url: 'https://gitlab.com/gitlab-org/gitlab/-/issues/338867') do
- build.deployment&.run
+ unless build.update_deployment_after_transaction_commit?
+ Gitlab::Database.allow_cross_database_modification_within_transaction(url: 'https://gitlab.com/gitlab-org/gitlab/-/issues/338867') do
+ build.deployment&.run
+ end
end
build.run_after_commit do
@@ -333,8 +335,10 @@ module Ci
end
after_transition any => [:success] do |build|
- Gitlab::Database.allow_cross_database_modification_within_transaction(url: 'https://gitlab.com/gitlab-org/gitlab/-/issues/338867') do
- build.deployment&.succeed
+ unless build.update_deployment_after_transaction_commit?
+ Gitlab::Database.allow_cross_database_modification_within_transaction(url: 'https://gitlab.com/gitlab-org/gitlab/-/issues/338867') do
+ build.deployment&.succeed
+ end
end
build.run_after_commit do
@@ -347,12 +351,14 @@ module Ci
next unless build.project
next unless build.deployment
- begin
- Gitlab::Database.allow_cross_database_modification_within_transaction(url: 'https://gitlab.com/gitlab-org/gitlab/-/issues/338867') do
- build.deployment.drop!
+ unless build.update_deployment_after_transaction_commit?
+ begin
+ Gitlab::Database.allow_cross_database_modification_within_transaction(url: 'https://gitlab.com/gitlab-org/gitlab/-/issues/338867') do
+ build.deployment.drop!
+ end
+ rescue StandardError => e
+ Gitlab::ErrorTracking.track_and_raise_for_dev_exception(e, build_id: build.id)
end
- rescue StandardError => e
- Gitlab::ErrorTracking.track_and_raise_for_dev_exception(e, build_id: build.id)
end
true
@@ -371,14 +377,29 @@ module Ci
end
after_transition any => [:skipped, :canceled] do |build, transition|
- Gitlab::Database.allow_cross_database_modification_within_transaction(url: 'https://gitlab.com/gitlab-org/gitlab/-/issues/338867') do
- if transition.to_name == :skipped
- build.deployment&.skip
- else
- build.deployment&.cancel
+ unless build.update_deployment_after_transaction_commit?
+ Gitlab::Database.allow_cross_database_modification_within_transaction(url: 'https://gitlab.com/gitlab-org/gitlab/-/issues/338867') do
+ if transition.to_name == :skipped
+ build.deployment&.skip
+ else
+ build.deployment&.cancel
+ end
end
end
end
+
+ # Synchronize Deployment Status
+ # Please note that the data integirty is not assured because we can't use
+ # a database transaction due to DB decomposition.
+ after_transition do |build, transition|
+ next if transition.loopback?
+ next unless build.project
+ next unless build.update_deployment_after_transaction_commit?
+
+ build.run_after_commit do
+ build.deployment&.sync_status_with(build)
+ end
+ end
end
def self.build_matchers(project)
@@ -1095,6 +1116,12 @@ module Ci
runner&.instance_type?
end
+ def update_deployment_after_transaction_commit?
+ strong_memoize(:update_deployment_after_transaction_commit) do
+ Feature.enabled?(:update_deployment_after_transaction_commit, project, default_enabled: :yaml)
+ end
+ end
+
protected
def run_status_commit_hooks!
diff --git a/app/models/deployment.rb b/app/models/deployment.rb
index 2925fc7cdd7..f91700f764b 100644
--- a/app/models/deployment.rb
+++ b/app/models/deployment.rb
@@ -10,6 +10,9 @@ class Deployment < ApplicationRecord
include FastDestroyAll
include IgnorableColumns
+ StatusUpdateError = Class.new(StandardError)
+ StatusSyncError = Class.new(StandardError)
+
belongs_to :project, required: true
belongs_to :environment, required: true
belongs_to :cluster, class_name: 'Clusters::Cluster', optional: true
@@ -312,20 +315,23 @@ class Deployment < ApplicationRecord
# Changes the status of a deployment and triggers the corresponding state
# machine events.
def update_status(status)
- case status
- when 'running'
- run
- when 'success'
- succeed
- when 'failed'
- drop
- when 'canceled'
- cancel
- when 'skipped'
- skip
- else
- raise ArgumentError, "The status #{status.inspect} is invalid"
- end
+ update_status!(status)
+ rescue StandardError => e
+ Gitlab::ErrorTracking.track_exception(
+ StatusUpdateError.new(e.message), deployment_id: self.id)
+
+ false
+ end
+
+ def sync_status_with(build)
+ return false unless ::Deployment.statuses.include?(build.status)
+
+ update_status!(build.status)
+ rescue StandardError => e
+ Gitlab::ErrorTracking.track_exception(
+ StatusSyncError.new(e.message), deployment_id: self.id, build_id: build.id)
+
+ false
end
def valid_sha
@@ -353,6 +359,23 @@ class Deployment < ApplicationRecord
private
+ def update_status!(status)
+ case status
+ when 'running'
+ run!
+ when 'success'
+ succeed!
+ when 'failed'
+ drop!
+ when 'canceled'
+ cancel!
+ when 'skipped'
+ skip!
+ else
+ raise ArgumentError, "The status #{status.inspect} is invalid"
+ end
+ end
+
def legacy_finished_at
self.created_at if success? && !read_attribute(:finished_at)
end
diff --git a/app/views/profiles/passwords/edit.html.haml b/app/views/profiles/passwords/edit.html.haml
index 2cc919fc70e..5d3e0720176 100644
--- a/app/views/profiles/passwords/edit.html.haml
+++ b/app/views/profiles/passwords/edit.html.haml
@@ -19,16 +19,16 @@
- unless @user.password_automatically_set?
.form-group
- = f.label :current_password, _('Current password'), class: 'label-bold'
- = f.password_field :current_password, required: true, class: 'form-control gl-form-input', data: { qa_selector: 'current_password_field' }
+ = f.label :password, _('Current password'), class: 'label-bold'
+ = f.password_field :password, required: true, autocomplete: 'current-password', class: 'form-control gl-form-input', data: { qa_selector: 'current_password_field' }
%p.form-text.text-muted
= _('You must provide your current password in order to change it.')
.form-group
- = f.label :password, _('New password'), class: 'label-bold'
- = f.password_field :password, required: true, class: 'form-control gl-form-input', data: { qa_selector: 'new_password_field' }
+ = f.label :new_password, _('New password'), class: 'label-bold'
+ = f.password_field :new_password, required: true, autocomplete: 'new-password', class: 'form-control gl-form-input', data: { qa_selector: 'new_password_field' }
.form-group
= f.label :password_confirmation, _('Password confirmation'), class: 'label-bold'
- = f.password_field :password_confirmation, required: true, class: 'form-control gl-form-input', data: { qa_selector: 'confirm_password_field' }
+ = f.password_field :password_confirmation, required: true, autocomplete: 'new-password', class: 'form-control gl-form-input', data: { qa_selector: 'confirm_password_field' }
.gl-mt-3.gl-mb-3
= f.submit _('Save password'), class: "gl-button btn btn-confirm gl-mr-3", data: { qa_selector: 'save_password_button' }
- unless @user.password_automatically_set?
diff --git a/app/views/profiles/passwords/new.html.haml b/app/views/profiles/passwords/new.html.haml
index 7780ffe0cb4..9154c94abb6 100644
--- a/app/views/profiles/passwords/new.html.haml
+++ b/app/views/profiles/passwords/new.html.haml
@@ -14,18 +14,18 @@
- unless @user.password_automatically_set?
.form-group.row
.col-sm-2.col-form-label
- = f.label :current_password, _('Current password')
+ = f.label :password, _('Current password')
.col-sm-10
- = f.password_field :current_password, required: true, class: 'form-control gl-form-input', data: { qa_selector: 'current_password_field' }
+ = f.password_field :password, required: true, autocomplete: 'current-password', class: 'form-control gl-form-input', data: { qa_selector: 'current_password_field' }
.form-group.row
.col-sm-2.col-form-label
- = f.label :password, _('New password')
+ = f.label :new_password, _('New password')
.col-sm-10
- = f.password_field :password, required: true, class: 'form-control gl-form-input', data: { qa_selector: 'new_password_field' }
+ = f.password_field :new_password, required: true, autocomplete: 'new-password', class: 'form-control gl-form-input', data: { qa_selector: 'new_password_field' }
.form-group.row
.col-sm-2.col-form-label
= f.label :password_confirmation, _('Password confirmation')
.col-sm-10
- = f.password_field :password_confirmation, required: true, class: 'form-control gl-form-input', data: { qa_selector: 'confirm_password_field' }
+ = f.password_field :password_confirmation, required: true, autocomplete: 'new-password', class: 'form-control gl-form-input', data: { qa_selector: 'confirm_password_field' }
.form-actions
= f.submit _('Set new password'), class: 'gl-button btn btn-confirm', data: { qa_selector: 'set_new_password_button' }
diff --git a/config/feature_flags/development/pipeline_editor_empty_state_action.yml b/config/feature_flags/development/update_deployment_after_transaction_commit.yml
similarity index 52%
rename from config/feature_flags/development/pipeline_editor_empty_state_action.yml
rename to config/feature_flags/development/update_deployment_after_transaction_commit.yml
index 870aeb14932..c07622fc9b4 100644
--- a/config/feature_flags/development/pipeline_editor_empty_state_action.yml
+++ b/config/feature_flags/development/update_deployment_after_transaction_commit.yml
@@ -1,8 +1,8 @@
---
-name: pipeline_editor_empty_state_action
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/55414
-rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/323229
-milestone: '13.10'
+name: update_deployment_after_transaction_commit
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/71450
+rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/342021
+milestone: '14.4'
type: development
-group: group::pipeline authoring
-default_enabled: true
+group: group::release
+default_enabled: false
diff --git a/db/migrate/20210929025600_add_phone_to_user_details.rb b/db/migrate/20210929025600_add_phone_to_user_details.rb
new file mode 100644
index 00000000000..9bcfd4ab7e3
--- /dev/null
+++ b/db/migrate/20210929025600_add_phone_to_user_details.rb
@@ -0,0 +1,15 @@
+# frozen_string_literal: true
+
+class AddPhoneToUserDetails < Gitlab::Database::Migration[1.0]
+ enable_lock_retries!
+
+ # rubocop:disable Migration/AddLimitToTextColumns
+ def up
+ add_column :user_details, :phone, :text, comment: 'JiHu-specific column'
+ end
+ # rubocop:enable Migration/AddLimitToTextColumns
+
+ def down
+ remove_column :user_details, :phone
+ end
+end
diff --git a/db/migrate/20210929030834_add_text_limit_to_user_details_phone.rb b/db/migrate/20210929030834_add_text_limit_to_user_details_phone.rb
new file mode 100644
index 00000000000..f250aad3253
--- /dev/null
+++ b/db/migrate/20210929030834_add_text_limit_to_user_details_phone.rb
@@ -0,0 +1,13 @@
+# frozen_string_literal: true
+
+class AddTextLimitToUserDetailsPhone < Gitlab::Database::Migration[1.0]
+ disable_ddl_transaction!
+
+ def up
+ add_text_limit :user_details, :phone, 32
+ end
+
+ def down
+ remove_text_limit :user_details, :phone
+ end
+end
diff --git a/db/migrate/20210929031049_add_unique_index_phone_on_user_details.rb b/db/migrate/20210929031049_add_unique_index_phone_on_user_details.rb
new file mode 100644
index 00000000000..e0cf7aa8a44
--- /dev/null
+++ b/db/migrate/20210929031049_add_unique_index_phone_on_user_details.rb
@@ -0,0 +1,15 @@
+# frozen_string_literal: true
+
+class AddUniqueIndexPhoneOnUserDetails < Gitlab::Database::Migration[1.0]
+ disable_ddl_transaction!
+
+ INDEX_NAME = 'index_user_details_on_phone'
+
+ def up
+ add_concurrent_index :user_details, :phone, unique: true, where: 'phone IS NOT NULL', name: INDEX_NAME, comment: 'JiHu-specific index'
+ end
+
+ def down
+ remove_concurrent_index_by_name :user_details, INDEX_NAME
+ end
+end
diff --git a/db/migrate/20210929032555_create_verification_codes.rb b/db/migrate/20210929032555_create_verification_codes.rb
new file mode 100644
index 00000000000..ad743641b9c
--- /dev/null
+++ b/db/migrate/20210929032555_create_verification_codes.rb
@@ -0,0 +1,36 @@
+# frozen_string_literal: true
+
+class CreateVerificationCodes < Gitlab::Database::Migration[1.0]
+ include Gitlab::Database::PartitioningMigrationHelpers::TableManagementHelpers
+
+ def up
+ constraint_visitor_id_code = check_constraint_name('verification_codes', 'visitor_id_code', 'max_length')
+ constraint_code = check_constraint_name('verification_codes', 'code', 'max_length')
+ constraint_phone = check_constraint_name('verification_codes', 'phone', 'max_length')
+
+ execute(<<~SQL)
+ CREATE TABLE verification_codes (
+ created_at timestamp with time zone NOT NULL DEFAULT NOW(),
+ visitor_id_code text,
+ code text,
+ phone text,
+ PRIMARY KEY (created_at, visitor_id_code, code, phone),
+ CONSTRAINT #{constraint_visitor_id_code} CHECK ((char_length(visitor_id_code) <= 64)),
+ CONSTRAINT #{constraint_code} CHECK ((char_length(code) <= 8)),
+ CONSTRAINT #{constraint_phone} CHECK ((char_length(phone) <= 32))
+ ) PARTITION BY RANGE (created_at);
+ COMMENT ON TABLE verification_codes IS 'JiHu-specific table';
+
+ CREATE UNIQUE INDEX index_verification_codes_on_phone_and_visitor_id_code ON verification_codes (visitor_id_code, phone, created_at);
+ COMMENT ON INDEX index_verification_codes_on_phone_and_visitor_id_code IS 'JiHu-specific index';
+ SQL
+
+ min_date = Date.today - 1.month
+ max_date = Date.today + 1.month
+ create_daterange_partitions('verification_codes', 'created_at', min_date, max_date)
+ end
+
+ def down
+ drop_table :verification_codes
+ end
+end
diff --git a/db/schema_migrations/20210929025600 b/db/schema_migrations/20210929025600
new file mode 100644
index 00000000000..fb00216afac
--- /dev/null
+++ b/db/schema_migrations/20210929025600
@@ -0,0 +1 @@
+c757a7e17433b8ddf15ae6304286fe3da69f820966455e7fbed7282286f5eb67
\ No newline at end of file
diff --git a/db/schema_migrations/20210929030834 b/db/schema_migrations/20210929030834
new file mode 100644
index 00000000000..a3dc19d0440
--- /dev/null
+++ b/db/schema_migrations/20210929030834
@@ -0,0 +1 @@
+b5302b3a2384bd7d0e639f00941efb490c3121a9332f1e73be620ab0f6f3e771
\ No newline at end of file
diff --git a/db/schema_migrations/20210929031049 b/db/schema_migrations/20210929031049
new file mode 100644
index 00000000000..19ba54b465a
--- /dev/null
+++ b/db/schema_migrations/20210929031049
@@ -0,0 +1 @@
+d3f588e4edded61f36acbf25fba39be17a2ac16f37e9114f2c5c257c47dc1308
\ No newline at end of file
diff --git a/db/schema_migrations/20210929032555 b/db/schema_migrations/20210929032555
new file mode 100644
index 00000000000..779e6a63fe2
--- /dev/null
+++ b/db/schema_migrations/20210929032555
@@ -0,0 +1 @@
+08593002910759482c58f9b31f251d589ab32b540d9614a2c677df11d32f7f26
\ No newline at end of file
diff --git a/db/structure.sql b/db/structure.sql
index 43927bdf4e7..9ecb7857d50 100644
--- a/db/structure.sql
+++ b/db/structure.sql
@@ -19851,12 +19851,16 @@ CREATE TABLE user_details (
pronouns text,
pronunciation text,
registration_objective smallint,
+ phone text,
CONSTRAINT check_245664af82 CHECK ((char_length(webauthn_xid) <= 100)),
+ CONSTRAINT check_a73b398c60 CHECK ((char_length(phone) <= 32)),
CONSTRAINT check_b132136b01 CHECK ((char_length(other_role) <= 100)),
CONSTRAINT check_eeeaf8d4f0 CHECK ((char_length(pronouns) <= 50)),
CONSTRAINT check_f932ed37db CHECK ((char_length(pronunciation) <= 255))
);
+COMMENT ON COLUMN user_details.phone IS 'JiHu-specific column';
+
CREATE SEQUENCE user_details_user_id_seq
START WITH 1
INCREMENT BY 1
@@ -20150,6 +20154,19 @@ CREATE SEQUENCE users_statistics_id_seq
ALTER SEQUENCE users_statistics_id_seq OWNED BY users_statistics.id;
+CREATE TABLE verification_codes (
+ created_at timestamp with time zone DEFAULT now() NOT NULL,
+ visitor_id_code text NOT NULL,
+ code text NOT NULL,
+ phone text NOT NULL,
+ CONSTRAINT check_9b84e6aaff CHECK ((char_length(code) <= 8)),
+ CONSTRAINT check_ccc542256b CHECK ((char_length(visitor_id_code) <= 64)),
+ CONSTRAINT check_f5684c195b CHECK ((char_length(phone) <= 32))
+)
+PARTITION BY RANGE (created_at);
+
+COMMENT ON TABLE verification_codes IS 'JiHu-specific table';
+
CREATE TABLE vulnerabilities (
id bigint NOT NULL,
milestone_id bigint,
@@ -23810,6 +23827,9 @@ ALTER TABLE ONLY users_star_projects
ALTER TABLE ONLY users_statistics
ADD CONSTRAINT users_statistics_pkey PRIMARY KEY (id);
+ALTER TABLE ONLY verification_codes
+ ADD CONSTRAINT verification_codes_pkey PRIMARY KEY (created_at, visitor_id_code, code, phone);
+
ALTER TABLE ONLY vulnerabilities
ADD CONSTRAINT vulnerabilities_pkey PRIMARY KEY (id);
@@ -26764,6 +26784,10 @@ CREATE INDEX index_user_custom_attributes_on_key_and_value ON user_custom_attrib
CREATE UNIQUE INDEX index_user_custom_attributes_on_user_id_and_key ON user_custom_attributes USING btree (user_id, key);
+CREATE UNIQUE INDEX index_user_details_on_phone ON user_details USING btree (phone) WHERE (phone IS NOT NULL);
+
+COMMENT ON INDEX index_user_details_on_phone IS 'JiHu-specific index';
+
CREATE INDEX index_user_details_on_provisioned_by_group_id ON user_details USING btree (provisioned_by_group_id);
CREATE UNIQUE INDEX index_user_details_on_user_id ON user_details USING btree (user_id);
@@ -26846,6 +26870,10 @@ CREATE INDEX index_users_star_projects_on_project_id ON users_star_projects USIN
CREATE UNIQUE INDEX index_users_star_projects_on_user_id_and_project_id ON users_star_projects USING btree (user_id, project_id);
+CREATE UNIQUE INDEX index_verification_codes_on_phone_and_visitor_id_code ON ONLY verification_codes USING btree (visitor_id_code, phone, created_at);
+
+COMMENT ON INDEX index_verification_codes_on_phone_and_visitor_id_code IS 'JiHu-specific index';
+
CREATE UNIQUE INDEX index_vuln_historical_statistics_on_project_id_and_date ON vulnerability_historical_statistics USING btree (project_id, date);
CREATE INDEX index_vulnerabilities_on_author_id ON vulnerabilities USING btree (author_id);
diff --git a/doc/ci/runners/build_cloud/windows_build_cloud.md b/doc/ci/runners/build_cloud/windows_build_cloud.md
index 5a1a3a4b58e..e01de723055 100644
--- a/doc/ci/runners/build_cloud/windows_build_cloud.md
+++ b/doc/ci/runners/build_cloud/windows_build_cloud.md
@@ -19,7 +19,7 @@ the Google Cloud Platform. This solution uses an
developed by GitLab for the [custom executor](https://docs.gitlab.com/runner/executors/custom.html).
Windows runners execute your CI/CD jobs on `n1-standard-2` instances with
2 vCPUs and 7.5 GB RAM. You can find a full list of available Windows packages in
-the [package documentation](https://gitlab.com/gitlab-org/ci-cd/shared-runners/images/gcp/windows-containers/blob/master/cookbooks/preinstalled-software/README.md).
+the [package documentation](https://gitlab.com/gitlab-org/ci-cd/shared-runners/images/gcp/windows-containers/blob/main/cookbooks/preinstalled-software/README.md).
We want to keep iterating to get Windows runners in a stable state and
[generally available](https://about.gitlab.com/handbook/product/gitlab-the-product/#generally-available-ga).
diff --git a/doc/development/documentation/testing.md b/doc/development/documentation/testing.md
index dfa2f3ed55a..13648a7c710 100644
--- a/doc/development/documentation/testing.md
+++ b/doc/development/documentation/testing.md
@@ -206,7 +206,6 @@ Vale returns three types of results: `suggestion`, `warning`, and `error`:
(after the Technical Writing team completes its cleanup). Warnings don't break CI. See a list of
[warning-level rules](https://gitlab.com/search?utf8=✓&snippets=false&scope=&repository_ref=master&search=path%3Adoc%2F.vale%2Fgitlab+Warning%3A&group_id=9970&project_id=278964).
- **Error**-level results are Style Guide violations, and should contain clear explanations
- about how to resolve the error. Errors break CI and are displayed in CI job output.
of how to resolve the error. Errors break CI and are displayed in CI job output. See a list of
[error-level rules](https://gitlab.com/search?utf8=✓&snippets=false&scope=&repository_ref=master&search=path%3Adoc%2F.vale%2Fgitlab+Error%3A&group_id=9970&project_id=278964).
diff --git a/doc/user/admin_area/settings/external_authorization.md b/doc/user/admin_area/settings/external_authorization.md
index 985f3c133d5..0531f30f0af 100644
--- a/doc/user/admin_area/settings/external_authorization.md
+++ b/doc/user/admin_area/settings/external_authorization.md
@@ -1,8 +1,7 @@
---
-stage: none
-group: unassigned
+stage: Manage
+group: Access
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
-type: reference
---
# External authorization control **(FREE SELF)**
diff --git a/doc/user/analytics/ci_cd_analytics.md b/doc/user/analytics/ci_cd_analytics.md
index 3c80e1f5f2a..4a42133c308 100644
--- a/doc/user/analytics/ci_cd_analytics.md
+++ b/doc/user/analytics/ci_cd_analytics.md
@@ -24,7 +24,7 @@ View pipeline duration history:
## DevOps Research and Assessment (DORA) key metrics **(ULTIMATE)**
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/275991) in GitLab 13.7.
-> - Added support for [lead time for changes](https://gitlab.com/gitlab-org/gitlab/-/issues/291746) in GitLab 13.10.
+> - [Added support](https://gitlab.com/gitlab-org/gitlab/-/issues/291746) for lead time for changes in GitLab 13.10.
Customer experience is a key metric. Users want to measure platform stability and other
post-deployment performance KPIs, and set targets for customer behavior, experience, and financial
@@ -56,7 +56,7 @@ The following table shows the supported metrics, at which level they are support
| `change_failure_rate` | Project/Group-level | To be supported | To be supported | |
| `time_to_restore_service` | Project/Group-level | To be supported | To be supported | |
-### Deployment frequency charts **(ULTIMATE)**
+### Deployment frequency charts
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/275991) in GitLab 13.8.
@@ -69,7 +69,7 @@ for its deployment information to appear on the graphs.
These charts are available for both groups and projects.
-### Lead time charts **(ULTIMATE)**
+### Lead time charts
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/250329) in GitLab 13.11.
diff --git a/doc/user/analytics/issue_analytics.md b/doc/user/analytics/issue_analytics.md
index 44b8c87ee27..af7307eab39 100644
--- a/doc/user/analytics/issue_analytics.md
+++ b/doc/user/analytics/issue_analytics.md
@@ -7,7 +7,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
# Issue Analytics **(PREMIUM)**
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/196561) in [GitLab Premium](https://about.gitlab.com/pricing/) 12.9.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/196561) in GitLab 12.9.
Issue Analytics is a bar graph which illustrates the number of issues created each month.
The default time span is 13 months, which includes the current month, and the 12 months
diff --git a/doc/user/analytics/merge_request_analytics.md b/doc/user/analytics/merge_request_analytics.md
index 44e4cd8b371..2ff15c00a3f 100644
--- a/doc/user/analytics/merge_request_analytics.md
+++ b/doc/user/analytics/merge_request_analytics.md
@@ -115,5 +115,5 @@ bookmark for those preferred settings in your browser.
The **Merge Request Analytics** feature can be accessed only:
-- On [Premium](https://about.gitlab.com/pricing/) and above.
+- On [GitLab Premium](https://about.gitlab.com/pricing/) and above.
- By users with [Reporter access](../permissions.md) and above.
diff --git a/doc/user/analytics/productivity_analytics.md b/doc/user/analytics/productivity_analytics.md
index 391ec5c04d9..dbe71d5f743 100644
--- a/doc/user/analytics/productivity_analytics.md
+++ b/doc/user/analytics/productivity_analytics.md
@@ -6,7 +6,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
# Productivity Analytics **(PREMIUM)**
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/12079) in [GitLab Premium](https://about.gitlab.com/pricing/) 12.3.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/12079) in GitLab 12.3.
Track development velocity with Productivity Analytics.
@@ -60,5 +60,5 @@ You can filter analytics based on a date range. To filter results:
The **Productivity Analytics** dashboard can be accessed only:
-- On the [Premium tier](https://about.gitlab.com/pricing/) and above.
+- On [GitLab Premium](https://about.gitlab.com/pricing/) and above.
- By users with [Reporter access](../permissions.md) and above.
diff --git a/doc/user/analytics/repository_analytics.md b/doc/user/analytics/repository_analytics.md
index 9016bf6393f..e8f8acf5661 100644
--- a/doc/user/analytics/repository_analytics.md
+++ b/doc/user/analytics/repository_analytics.md
@@ -4,7 +4,7 @@ group: Optimize
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
---
-# Repository Analytics
+# Repository Analytics **(FREE)**
Get high-level overview of the project's Git repository.
diff --git a/doc/user/application_security/coverage_fuzzing/index.md b/doc/user/application_security/coverage_fuzzing/index.md
index 303427d31e9..cdb2e7109bf 100644
--- a/doc/user/application_security/coverage_fuzzing/index.md
+++ b/doc/user/application_security/coverage_fuzzing/index.md
@@ -16,6 +16,18 @@ We recommend that you use fuzz testing in addition to the other security scanner
and your own test processes. If you're using [GitLab CI/CD](../../../ci/index.md),
you can run your coverage-guided fuzz tests as part your CI/CD workflow.
+## Coverage-guided fuzz testing process
+
+The fuzz testing process:
+
+1. Compiles the target application.
+1. Runs the instrumented application, using the `gitlab-cov-fuzz` tool.
+1. Parses and analyzes the exception information output by the fuzzer.
+1. Downloads the [corpus](../terminology/index.md#corpus) and crash events from previous pipelines.
+1. Outputs the parsed crash events and data to the `gl-coverage-fuzzing-report.json` file.
+
+The results of the coverage-guided fuzz testing are available in the CI/CD pipeline.
+
## Supported fuzzing engines and languages
GitLab supports these languages through the fuzzing engine listed for each. We currently provide a
diff --git a/doc/user/group/settings/img/import_panel_v14_1.png b/doc/user/group/settings/img/import_panel_v14_1.png
deleted file mode 100644
index 28417383b6c..00000000000
Binary files a/doc/user/group/settings/img/import_panel_v14_1.png and /dev/null differ
diff --git a/doc/user/group/settings/img/new_group_navigation_v13_1.png b/doc/user/group/settings/img/new_group_navigation_v13_1.png
deleted file mode 100644
index 307175727c7..00000000000
Binary files a/doc/user/group/settings/img/new_group_navigation_v13_1.png and /dev/null differ
diff --git a/doc/user/group/settings/import_export.md b/doc/user/group/settings/import_export.md
index 1d117480f6b..3f9d94f044e 100644
--- a/doc/user/group/settings/import_export.md
+++ b/doc/user/group/settings/import_export.md
@@ -4,6 +4,7 @@ stage: Manage
group: Import
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
---
+
# Group import/export **(FREE)**
> [Introduced](https://gitlab.com/groups/gitlab-org/-/epics/2888) in GitLab 13.0 as an experimental feature. May change in future releases.
@@ -23,9 +24,9 @@ Users with the [Owner role](../../permissions.md) for a group can enable
import and export for that group:
1. On the top bar, select **Menu > Admin**.
-1. On the left sidebar, select **Settings > General > Visibility and access controls**.
-1. Scroll to **Import sources**.
-1. Enable the desired **Import sources**.
+1. On the left sidebar, select **Settings > General**.
+1. Expand **Visibility and access controls**.
+1. In the **Import sources** section, select the checkboxes for the sources you want.
## Important Notes
@@ -72,16 +73,16 @@ in GitLab 14.6 and replaced by [GitLab Migration](../import/).
Users with the [Owner role](../../permissions.md) for a group can export the
contents of that group:
-1. On the top bar, select **Menu >** **Groups** and find your group.
-1. On the left sidebar, select **Settings**.
-1. Scroll to the **Advanced** section, and select **Export Group**.
+1. On the top bar, select **Menu > Groups** and find your group.
+1. On the left sidebar, select **Settings > General**.
+1. In the **Advanced** section, select **Export Group**.
1. After the export is generated, you should receive an email with a link to the [exported contents](#exported-contents)
in a compressed tar archive, with contents in NDJSON format.
1. Alternatively, you can download the export from the UI:
1. Return to your group's **Settings > General** page.
- 1. Scroll to the **Advanced** section, and select **Download export**.
- You can also generate a new file by clicking **Regenerate export**.
+ 1. In the **Advanced** section, select **Download export**.
+ You can also generate a new file by selecting **Regenerate export**.
NOTE:
The maximum import file size can be set by the Administrator, default is `0` (unlimited).
@@ -95,24 +96,18 @@ The Enterprise Edition retains some group data that isn't part of the Community
## Importing the group
-1. Navigate to the New Group page, either via the `+` button in the top navigation bar, or the **New subgroup** button
-on an existing group's page.
-
- ![Navigation paths to create a new group](img/new_group_navigation_v13_1.png)
-
-1. On the New Group page, select the **Import group**.
-
- ![Fill in group details](img/import_panel_v14_1.png)
+1. Create a new group:
+ - On the top bar, select **New** (**{plus}**) and then **New group**.
+ - On an existing group's page, select the **New subgroup** button.
+1. Select **Import group**.
1. Enter your group name.
-
1. Accept or modify the associated group URL.
-
-1. Click **Choose file**
-
+1. Select **Choose file**.
1. Select the file that you exported in the [Export a group](#export-a-group) section.
+1. To begin importing, select **Import group**.
-1. Click **Import group** to begin importing. Your newly imported group page appears after the operation completes.
+Your newly imported group page appears after the operation completes.
## Version history
diff --git a/doc/user/profile/img/notification_global_settings_v13_12.png b/doc/user/profile/img/notification_global_settings_v13_12.png
deleted file mode 100644
index 0998bb89778..00000000000
Binary files a/doc/user/profile/img/notification_global_settings_v13_12.png and /dev/null differ
diff --git a/doc/user/profile/notifications.md b/doc/user/profile/notifications.md
index aaa311a4097..6de09f5538f 100644
--- a/doc/user/profile/notifications.md
+++ b/doc/user/profile/notifications.md
@@ -13,56 +13,62 @@ You can receive updates about activity in issues, merge requests, epics, and des
For the tool that GitLab administrators can use to send messages to users, read
[Email from GitLab](../../tools/email.md).
-## Receive notifications
+## Who receives notifications
-You receive notifications for one of the following reasons:
+When notifications are enabled for an issue, merge request, or epic, GitLab notifies you of actions
+that happen there.
-- You participate in an issue, merge request, epic, or design. In this context, _participate_ means
- comment or edit.
+You might receive notifications for one of the following reasons:
+
+- You participate in an issue, merge request, epic, or design. You become a participant when you comment
+ or edit, or someone mentions you.
- You've [enabled notifications in an issue, merge request, or epic](#notifications-on-issues-merge-requests-and-epics).
-- You configured notifications at the [project](#project-notifications) and/or [group](#group-notifications) level.
-
-While notifications are enabled, you receive notification of actions occurring in that issue, merge request, or epic.
+- You've configured notifications for the [project](#change-level-of-project-notifications) or [group](#group-notifications).
NOTE:
Administrators can block notifications, preventing them from being sent.
-## Tune your notifications
+## Edit notification settings
Getting many notifications can be overwhelming. You can tune the notifications you receive.
For example, you might want to be notified about all activity in a specific project.
For other projects, you only want to be notified when you are mentioned by name.
-You can tune the notifications you receive by changing your notification settings:
-
-- [Global notification settings](#global-notification-settings)
-- [Notification scope](#notification-scope)
-- [Notification levels](#notification-levels)
-
-## Edit notification settings
-
These notification settings apply only to you. They do not affect the notifications received by
-anyone else in the same project or group.
+anyone else.
To edit your notification settings:
1. In the top-right corner, select your avatar.
1. Select **Preferences**.
1. On the left sidebar, select **Notifications**.
-1. Edit the desired notification settings. Edited settings are automatically saved and enabled.
+1. Edit the desired global, group, or project notification settings.
+ Edited settings are automatically saved.
-## Notification scope
+### Notification scope
-You can tune the scope of your notifications by selecting different notification levels for each project and group.
+You can tune the scope of your notifications by selecting different notification levels for each
+project and group.
Notification scope is applied from the broadest to most specific levels:
-- **Global (default)**: Your global, or _default_, notification level applies if you
+- Your **global**, or _default_, notification level applies if you
have not selected a notification level for the project or group in which the activity occurred.
-- **Group**: For each group, you can select a notification level. Your group setting
- overrides your default setting.
-- **Project**: For each project, you can select a notification level. Your project
- setting overrides the group setting.
+- Your **group** setting overrides your default setting.
+- Your **project** setting overrides the group setting.
+
+### Notification levels
+
+For each project and group you can select one of the following levels:
+
+| Level | Description |
+| ----------- | ----------------------------------------------------------- |
+| Global | Your global settings apply. |
+| Watch | Receive notifications for any activity. |
+| Participate | Receive notifications for threads you have participated in. |
+| On mention | Receive notifications when you are [mentioned](../project/issues/issue_data_and_actions.md#mentions) in a comment. |
+| Disabled | Receive no notifications. |
+| Custom | Receive notifications for selected events. |
### Global notification settings
@@ -72,19 +78,17 @@ different values for a project or a group.
- **Notification email**: the email address your notifications are sent to.
Defaults to your primary email address.
- **Receive product marketing emails**: select this checkbox to receive
- [periodic emails](#product-marketing-emails) about GitLab features.
+ [periodic emails](#opt-out-of-product-marketing-emails) about GitLab features.
- **Global notification level**: the default [notification level](#notification-levels)
which applies to all your notifications.
- **Receive notifications about your own activity**: select this checkbox to receive
notifications about your own activity. Not selected by default.
-![notification settings](img/notification_global_settings_v13_12.png)
-
### Group notifications
You can select a notification level and email address for each group.
-#### Group notification level
+#### Change level of group notifications
To select a notification level for a group, use either of these methods:
@@ -100,11 +104,12 @@ Or:
1. Select the notification dropdown, next to the bell icon (**{notifications}**).
1. Select the desired [notification level](#notification-levels).
-#### Group notification email address
+#### Change email address used for group notifications
-> Introduced in GitLab 12.0
+> Introduced in GitLab 12.0.
-You can select an email address to receive notifications for each group you belong to. This could be useful, for example, if you work freelance, and want to keep email about clients' projects separate.
+You can select an email address to receive notifications for each group you belong to.
+You can use group notifications, for example, if you work freelance, and want to keep email about clients' projects separate.
1. In the top-right corner, select your avatar.
1. Select **Preferences**.
@@ -112,9 +117,9 @@ You can select an email address to receive notifications for each group you belo
1. Locate the project in the **Groups** section.
1. Select the desired email address.
-### Project notifications
+### Change level of project notifications
-You can select a notification level for each project to help you closely monitor activity in select projects.
+To help you stay up to date, you can select a notification level for each project.
To select a notification level for a project, use either of these methods:
@@ -131,28 +136,20 @@ Or:
1. Select the desired [notification level](#notification-levels).
-To learn how to be notified when a new release is available, see [Notification for releases](https://www.youtube.com/watch?v=qyeNkGgqmH4).
+To learn how to be notified when a new release is available, watch [Notification for releases](https://www.youtube.com/watch?v=qyeNkGgqmH4).
-### Notification levels
-
-For each project and group you can select one of the following levels:
-
-| Level | Description |
-| ----------- | ----------------------------------------------------------- |
-| Global | Your global settings apply. |
-| Watch | Receive notifications for any activity. |
-| On mention | Receive notifications when [mentioned](../project/issues/issue_data_and_actions.md#mentions) in a comment. |
-| Participate | Receive notifications for threads you have participated in. |
-| Disabled | Turns off notifications. |
-| Custom | Receive notifications for custom selected events. |
-
-### Product marketing emails
+### Opt out of product marketing emails
You can receive emails that teach you about various GitLab features.
-This is enabled by default.
+These emails are enabled by default.
-To opt out, [edit your notification settings](#edit-notification-settings) and clear the
-**Receive product marketing emails** checkbox.
+To opt out:
+
+1. In the top-right corner, select your avatar.
+1. Select **Preferences**.
+1. On the left sidebar, select **Notifications**.
+1. Clear the **Receive product marketing emails** checkbox.
+ Edited settings are automatically saved and enabled.
Disabling these emails does not disable all emails.
Learn how to [opt out of all emails from GitLab](#opt-out-of-all-gitlab-emails).
@@ -175,108 +172,115 @@ Users are notified of the following events:
| Event | Sent to | Settings level |
|------------------------------|---------------------|------------------------------|
-| New release | Project members | Custom notification |
-| Project moved | Project members (1) | (1) not disabled |
+| New release | Project members | Custom notification. |
+| Project moved | Project members | Any other than disabled. |
| Email changed | User | Security email, always sent. |
-| Group access level changed | User | Sent when user group access level is changed |
+| Group access level changed | User | Sent when user group access level is changed. |
| New email added | User | Security email, always sent. |
| New SAML/SCIM user provisioned | User | Sent when a user is provisioned through SAML/SCIM. [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/276018) in GitLab 13.8 |
| New SSH key added | User | Security email, always sent. |
-| New user created | User | Sent on user creation, except for OmniAuth (LDAP)|
-| Password changed | User | Security email, always sent when user changes their own password |
-| Password changed by administrator | User | Security email, always sent when an administrator changes the password of another user |
-| Personal access tokens expiring soon | User | Security email, always sent. |
+| New user created | User | Sent on user creation, except for OmniAuth (LDAP). |
+| Password changed | User | Security email, always sent when user changes their own password. |
+| Password changed by administrator | User | Security email, always sent when an administrator changes the password of another user. |
+| Personal access tokens expiring soon | User | Security email, always sent. |
| Personal access tokens have expired | User | Security email, always sent. |
-| Project access level changed | User | Sent when user project access level is changed |
-| SSH key has expired | User | Security email, always sent. [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/322637) in GitLab 13.12 |
+| Project access level changed | User | Sent when user project access level is changed. |
+| SSH key has expired | User | Security email, always sent. _[Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/322637) in GitLab 13.12._ |
| Two-factor authentication disabled | User | Security email, always sent. |
-| User added to group | User | Sent when user is added to group |
-| User added to project | User | Sent when user is added to project |
+| User added to group | User | Sent when user is added to group. |
+| User added to project | User | Sent when user is added to project. |
## Notifications on issues, merge requests, and epics
+You also receive notifications for events happening on
+issues, merge requests, and epics.
+
+### Who receives notifications on issues, merge requests, and epics
+
+In issues, merge requests, and epics, for most events, the notification is sent to:
+
+- Participants:
+ - The author and assignee.
+ - Authors of comments.
+ - Anyone [mentioned](../project/issues/issue_data_and_actions.md#mentions) by username in the title
+ or description.
+ - Anyone mentioned by username in a comment if their notification level is "Participating" or higher.
+- Watchers: users with notification level "Watch".
+- Subscribers: anyone who manually subscribed to notifications.
+- Custom: users with notification level "Custom" who turned on notifications for a fitting type of events.
+
+NOTE:
+To minimize the number of notifications that do not require any action, in
+[GitLab 12.9 and later](https://gitlab.com/gitlab-org/gitlab/-/issues/616), eligible
+approvers are no longer notified for all the activities in their projects. To turn on such notifications, they have
+to change their user notification settings to **Watch** instead.
+
+### Edit notification settings for issues, merge requests, and epics
+
To enable notifications on a specific issue, merge request, or epic, you must turn on the
**Notifications** toggle in the right sidebar.
- To subscribe, **turn on** if you are not a participant in the discussion, but want to receive
notifications on each update.
+
+ When you turn notifications on in an epic, you aren't automatically subscribed to the issues linked
+ to the epic.
+
- To unsubscribe, **turn off** if you are receiving notifications for updates but no longer want to
- receive them, unsubscribe from it.
+ receive them.
-Turning this toggle off only unsubscribes you from updates related to this issue, merge request, or epic.
-Learn how to [opt out of all emails from GitLab](#opt-out-of-all-gitlab-emails).
+ Turning this toggle off only unsubscribes you from updates related to this issue, merge request, or epic.
+ Learn how to [opt out of all emails from GitLab](#opt-out-of-all-gitlab-emails).
-Turning notifications on in an epic doesn't automatically subscribe you to the issues linked
-to the epic.
-
-For most events, the notification is sent to:
-
-- Participants:
- - The author and assignee of the issue/merge request.
- - Authors of comments.
- - Anyone [mentioned](../project/issues/issue_data_and_actions.md#mentions) by username in the title
- or description of the issue, merge request or epic.
- - Anyone with notification level "Participating" or higher that is mentioned by their username in
- any of the comments on the issue, merge request, or epic.
-- Watchers: users with notification level "Watch".
-- Subscribers: anyone who manually subscribed to the issue, merge request, or epic.
-- Custom: Users with notification level "custom" who turned on notifications for any of the events in the following table.
-
-NOTE:
-To minimize the number of notifications that do not require any action, in
-[GitLab versions 12.9 and later](https://gitlab.com/gitlab-org/gitlab/-/issues/616), eligible
-approvers are no longer notified for all the activities in their projects. To receive them they have
-to change their user notification settings to **Watch** instead.
+### Notification events on issues, merge requests, and epics
The following table presents the events that generate notifications for issues, merge requests, and
epics:
| Event | Sent to |
|------------------------|---------|
-| Change milestone issue | Subscribers, participants mentioned, and Custom notification level with this event selected |
-| Change milestone merge request | Subscribers, participants mentioned, and Custom notification level with this event selected |
+| Change milestone issue | Subscribers, participants mentioned, and Custom notification level with this event selected. |
+| Change milestone merge request | Subscribers, participants mentioned, and Custom notification level with this event selected. |
| Close epic | |
| Close issue | |
| Close merge request | |
-| Due issue | Participants and Custom notification level with this event selected |
-| Failed pipeline | The author of the pipeline |
-| Fixed pipeline | The author of the pipeline. Enabled by default. [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/24309) in GitLab 13.1 |
+| Due issue | Participants and Custom notification level with this event selected. |
+| Failed pipeline | The author of the pipeline. |
+| Fixed pipeline | The author of the pipeline. Enabled by default. _[Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/24309) in GitLab 13.1._ |
| Merge merge request | |
-| Merge when pipeline succeeds | Author, Participants, Watchers, Subscribers, and Custom notification level with this event selected. Custom notification level is ignored for Author, Watchers and Subscribers. [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/211961) in GitLab 13.4 |
-| Merge request [marked as ready](../project/merge_requests/drafts.md) | Watchers and participants. [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/15332) in GitLab 13.10 |
-| New comment | Participants, Watchers, Subscribers, and Custom notification level with this event selected, plus anyone mentioned by `@username` in the comment, with notification level "Mention" or higher |
+| Merge when pipeline succeeds | Author, Participants, Watchers, Subscribers, and Custom notification level with this event selected. Custom notification level is ignored for Author, Watchers and Subscribers. _[Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/211961) in GitLab 13.4._ |
+| Merge request [marked as ready](../project/merge_requests/drafts.md) | Watchers and participants. _[Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/15332) in GitLab 13.10._ |
+| New comment | Participants, Watchers, Subscribers, and Custom notification level with this event selected. Also anyone mentioned by username in the comment, with notification level "Mention" or higher. |
| New epic | |
| New issue | |
| New merge request | |
-| Push to merge request | Participants and Custom notification level with this event selected |
-| Reassign issue | Participants, Watchers, Subscribers, and Custom notification level with this event selected, plus the old assignee |
-| Reassign merge request | Participants, Watchers, Subscribers, and Custom notification level with this event selected, plus the old assignee |
-| Remove milestone issue | Subscribers, participants mentioned, and Custom notification level with this event selected |
-| Remove milestone merge request | Subscribers, participants mentioned, and Custom notification level with this event selected |
+| Push to merge request | Participants and Custom notification level with this event selected. |
+| Reassign issue | Participants, Watchers, Subscribers, Custom notification level with this event selected, and the old assignee. |
+| Reassign merge request | Participants, Watchers, Subscribers, Custom notification level with this event selected, and the old assignee. |
+| Remove milestone issue | Subscribers, participants mentioned, and Custom notification level with this event selected. |
+| Remove milestone merge request | Subscribers, participants mentioned, and Custom notification level with this event selected. |
| Reopen epic | |
| Reopen issue | |
| Reopen merge request | |
-| Successful pipeline | The author of the pipeline, if they have the custom notification setting for successful pipelines set. If the pipeline failed previously, a `Fixed pipeline` message is sent for the first successful pipeline after the failure, then a `Successful pipeline` message for any further successful pipelines. |
+| Successful pipeline | The author of the pipeline, with Custom notification level for successful pipelines. If the pipeline failed previously, a "Fixed pipeline" message is sent for the first successful pipeline after the failure, and then a "Successful pipeline" message for any further successful pipelines. |
If the title or description of an issue or merge request is
-changed, notifications are sent to any **new** mentions by `@username` as
+changed, notifications are sent to any **new** mentions by username as
if they had been mentioned in the original text.
-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
-[notifications about your own activity](#global-notification-settings).
-
If an open merge request becomes unmergeable due to conflict, its author is notified about the cause.
If a user has also set the merge request to automatically merge when pipeline succeeds,
then that user is also notified.
+By default, you don't receive notifications for issues, merge requests, or epics created by yourself.
+To always receive notifications on your own issues, merge requests, and so on, turn on
+[notifications about your own activity](#global-notification-settings).
+
## Notifications on designs
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/217095) in GitLab 13.6.
-Email notifications are sent to the participants when comments are made on a design.
+Email notifications are sent to the participants when someone comments on a design.
The participants are:
@@ -288,7 +292,9 @@ The participants are:
If you no longer wish to receive any email notifications:
-1. [Go to the Notifications settings page.](#edit-notification-settings)
+1. In the top-right corner, select your avatar.
+1. Select **Preferences**.
+1. On the left sidebar, select **Notifications**.
1. Clear the **Receive product marketing emails** checkbox.
1. Set your **Global notification level** to **Disabled**.
1. Clear the **Receive notifications about your own activity** checkbox.
@@ -299,40 +305,43 @@ On self-managed installations, even after doing this, your instance administrato
[can still email you](../../tools/email.md).
To unsubscribe, select the unsubscribe link in one of these emails.
-## Filter email
+## Email headers you can use to filter email
-Notification email messages include GitLab-specific headers. You can filter the notification emails based on the content of these headers to better manage your notifications. For example, you could filter all emails for a specific project where you are being assigned either a merge request or issue.
+Notification email messages include GitLab-specific headers. To better manage your notifications,
+you can filter the notification emails based on the content of these headers.
+
+For example, you could filter all emails from a specific project where you are being assigned a
+a merge request or an issue.
The following table lists all GitLab-specific email headers:
| Header | Description |
|------------------------------------|-------------------------------------------------------------------------|
-| `X-GitLab-Group-Id` **(PREMIUM)** | The group's ID. Only present on notification emails for epics. |
-| `X-GitLab-Group-Path` **(PREMIUM)** | The group's path. Only present on notification emails for epics. |
-| `X-GitLab-Project` | The name of the project the notification belongs to. |
-| `X-GitLab-Project-Id` | The project's ID. |
-| `X-GitLab-Project-Path` | The project's path. |
+| `List-Id` | The path of the project in an RFC 2919 mailing list identifier. You can use it for email organization with filters. |
| `X-GitLab-(Resource)-ID` | The ID of the resource the notification is for. The resource, for example, can be `Issue`, `MergeRequest`, `Commit`, or another such resource. |
| `X-GitLab-Discussion-ID` | The ID of the thread the comment belongs to, in notification emails for comments. |
+| `X-GitLab-Group-Id` **(PREMIUM)** | The group's ID. Only present on notification emails for epics. |
+| `X-GitLab-Group-Path` **(PREMIUM)** | The group's path. Only present on notification emails for epics. |
+| [`X-GitLab-NotificationReason`](#x-gitlab-notificationreason) | The reason for the notification. This can be `mentioned`, `assigned`, or `own_activity`. |
| `X-GitLab-Pipeline-Id` | The ID of the pipeline the notification is for, in notification emails for pipelines. |
+| `X-GitLab-Project-Id` | The project's ID. |
+| `X-GitLab-Project-Path` | The project's path. |
+| `X-GitLab-Project` | The name of the project the notification belongs to. |
| `X-GitLab-Reply-Key` | A unique token to support reply by email. |
-| `X-GitLab-NotificationReason` | The reason for the notification. This can be `mentioned`, `assigned`, or `own_activity`. |
-| `List-Id` | The path of the project in an RFC 2919 mailing list identifier. This is useful for email organization with filters, for example. |
### X-GitLab-NotificationReason
-The `X-GitLab-NotificationReason` header contains the reason for the notification. The value is one of the following, in order of priority:
+The `X-GitLab-NotificationReason` header contains the reason for the notification.
+The value is one of the following, in order of priority:
- `own_activity`
- `assigned`
- `mentioned`
-The reason for the notification is also included in the footer of the notification email. For example an email with the
-reason `assigned` has this sentence in the footer:
+The reason for the notification is also included in the footer of the notification email.
+For example, an email with the reason `assigned` has this sentence in the footer:
-- `You are receiving this email because you have been assigned an item on .`
-
-Notification of other events is being considered for inclusion in the `X-GitLab-NotificationReason` header. For details, see this [related issue](https://gitlab.com/gitlab-org/gitlab/-/issues/20689).
+> You are receiving this email because you have been assigned an item on \.
For example, an alert notification email can have one of
[the alert's](../../operations/incident_management/alerts.md) statuses:
@@ -341,3 +350,6 @@ For example, an alert notification email can have one of
- `alert_acknowledged`
- `alert_resolved`
- `alert_ignored`
+
+Expanding the list of events included in the `X-GitLab-NotificationReason` header is tracked in
+[issue 20689](https://gitlab.com/gitlab-org/gitlab/-/issues/20689).
diff --git a/spec/features/profiles/password_spec.rb b/spec/features/profiles/password_spec.rb
index 893dd2c76e0..7059697354d 100644
--- a/spec/features/profiles/password_spec.rb
+++ b/spec/features/profiles/password_spec.rb
@@ -89,7 +89,7 @@ RSpec.describe 'Profile > Password' do
shared_examples 'user enters an incorrect current password' do
subject do
page.within '.update-password' do
- fill_in 'user_current_password', with: user_current_password
+ fill_in 'user_password', with: user_current_password
fill_passwords(new_password, new_password)
end
end
@@ -131,7 +131,7 @@ RSpec.describe 'Profile > Password' do
end
context 'when current password is incorrect' do
- let(:user_current_password) {'invalid' }
+ let(:user_current_password) { 'invalid' }
it_behaves_like 'user enters an incorrect current password'
end
@@ -139,7 +139,7 @@ RSpec.describe 'Profile > Password' do
context 'when the password reset is successful' do
subject do
page.within '.update-password' do
- fill_in "user_current_password", with: user.password
+ fill_in "user_password", with: user.password
fill_passwords(new_password, new_password)
end
end
@@ -169,8 +169,8 @@ RSpec.describe 'Profile > Password' do
expect(current_path).to eq new_profile_password_path
- fill_in :user_current_password, with: user.password
- fill_in :user_password, with: '12345678'
+ fill_in :user_password, with: user.password
+ fill_in :user_new_password, with: '12345678'
fill_in :user_password_confirmation, with: '12345678'
click_button 'Set new password'
diff --git a/spec/features/users/login_spec.rb b/spec/features/users/login_spec.rb
index d9c919dae3d..b4c041199bb 100644
--- a/spec/features/users/login_spec.rb
+++ b/spec/features/users/login_spec.rb
@@ -866,8 +866,8 @@ RSpec.describe 'Login', :clean_gitlab_redis_shared_state do
expect(current_path).to eq(new_profile_password_path)
- fill_in 'user_current_password', with: '12345678'
- fill_in 'user_password', with: 'new password'
+ fill_in 'user_password', with: '12345678'
+ fill_in 'user_new_password', with: 'new password'
fill_in 'user_password_confirmation', with: 'new password'
click_button 'Set new password'
diff --git a/spec/frontend/pipeline_editor/components/ui/pipeline_editor_empty_state_spec.js b/spec/frontend/pipeline_editor/components/ui/pipeline_editor_empty_state_spec.js
index b019bae886c..8e0a73b6e7c 100644
--- a/spec/frontend/pipeline_editor/components/ui/pipeline_editor_empty_state_spec.js
+++ b/spec/frontend/pipeline_editor/components/ui/pipeline_editor_empty_state_spec.js
@@ -6,9 +6,6 @@ import PipelineEditorEmptyState from '~/pipeline_editor/components/ui/pipeline_e
describe('Pipeline editor empty state', () => {
let wrapper;
const defaultProvide = {
- glFeatures: {
- pipelineEditorEmptyStateAction: false,
- },
emptyStateIllustrationPath: 'my/svg/path',
};
@@ -51,24 +48,6 @@ describe('Pipeline editor empty state', () => {
expect(findFileNav().exists()).toBe(true);
});
- describe('with feature flag off', () => {
- it('does not renders a CTA button', () => {
- expect(findConfirmButton().exists()).toBe(false);
- });
- });
- });
-
- describe('with feature flag on', () => {
- beforeEach(() => {
- createComponent({
- provide: {
- glFeatures: {
- pipelineEditorEmptyStateAction: true,
- },
- },
- });
- });
-
it('renders a CTA button', () => {
expect(findConfirmButton().exists()).toBe(true);
expect(findConfirmButton().text()).toBe(wrapper.vm.$options.i18n.btnText);
diff --git a/spec/frontend/pipeline_editor/pipeline_editor_app_spec.js b/spec/frontend/pipeline_editor/pipeline_editor_app_spec.js
index 393cad0546b..b6713319e69 100644
--- a/spec/frontend/pipeline_editor/pipeline_editor_app_spec.js
+++ b/spec/frontend/pipeline_editor/pipeline_editor_app_spec.js
@@ -22,7 +22,6 @@ import {
mockCiConfigPath,
mockCiConfigQueryResponse,
mockBlobContentQueryResponse,
- mockBlobContentQueryResponseEmptyCiFile,
mockBlobContentQueryResponseNoCiFile,
mockCiYml,
mockCommitSha,
@@ -43,9 +42,6 @@ const MockSourceEditor = {
const mockProvide = {
ciConfigPath: mockCiConfigPath,
defaultBranch: mockDefaultBranch,
- glFeatures: {
- pipelineEditorEmptyStateAction: false,
- },
projectFullPath: mockProjectFullPath,
};
@@ -221,37 +217,12 @@ describe('Pipeline editor app component', () => {
});
});
- describe('with an empty CI config file', () => {
- describe('with empty state feature flag on', () => {
- it('does not show the empty screen state', async () => {
- mockBlobContentData.mockResolvedValue(mockBlobContentQueryResponseEmptyCiFile);
-
- await createComponentWithApollo({
- provide: {
- glFeatures: {
- pipelineEditorEmptyStateAction: true,
- },
- },
- });
-
- expect(findEmptyState().exists()).toBe(false);
- expect(findTextEditor().exists()).toBe(true);
- });
- });
- });
-
- describe('when landing on the empty state with feature flag on', () => {
- it('user can click on CTA button and see an empty editor', async () => {
+ describe('with no CI config setup', () => {
+ it('user can click on CTA button to get started', async () => {
mockBlobContentData.mockResolvedValue(mockBlobContentQueryResponseNoCiFile);
mockLatestCommitShaQuery.mockResolvedValue(mockEmptyCommitShaResults);
- await createComponentWithApollo({
- provide: {
- glFeatures: {
- pipelineEditorEmptyStateAction: true,
- },
- },
- });
+ await createComponentWithApollo();
expect(findEmptyState().exists()).toBe(true);
expect(findTextEditor().exists()).toBe(false);
diff --git a/spec/models/ci/build_spec.rb b/spec/models/ci/build_spec.rb
index 9ba7d0ab359..2ebf75a1d8a 100644
--- a/spec/models/ci/build_spec.rb
+++ b/spec/models/ci/build_spec.rb
@@ -1290,7 +1290,7 @@ RSpec.describe Ci::Build do
end
end
- describe 'state transition as a deployable' do
+ shared_examples_for 'state transition as a deployable' do
subject { build.send(event) }
let!(:build) { create(:ci_build, :with_deployment, :start_review_app, project: project, pipeline: pipeline) }
@@ -1399,6 +1399,36 @@ RSpec.describe Ci::Build do
end
end
+ it_behaves_like 'state transition as a deployable' do
+ context 'when transits to running' do
+ let(:event) { :run! }
+
+ context 'when deployment is already running state' do
+ before do
+ build.deployment.success!
+ end
+
+ it 'does not change deployment status and tracks an error' do
+ expect(Gitlab::ErrorTracking)
+ .to receive(:track_exception).with(
+ instance_of(Deployment::StatusSyncError), deployment_id: deployment.id, build_id: build.id)
+
+ with_cross_database_modification_prevented do
+ expect { subject }.not_to change { deployment.reload.status }
+ end
+ end
+ end
+ end
+ end
+
+ context 'when update_deployment_after_transaction_commit feature flag is disabled' do
+ before do
+ stub_feature_flags(update_deployment_after_transaction_commit: false)
+ end
+
+ it_behaves_like 'state transition as a deployable'
+ end
+
describe '#on_stop' do
subject { build.on_stop }
@@ -3948,7 +3978,7 @@ RSpec.describe Ci::Build do
end
it 'can drop the build' do
- expect(Gitlab::ErrorTracking).to receive(:track_and_raise_for_dev_exception)
+ expect(Gitlab::ErrorTracking).to receive(:track_exception)
expect { build.drop! }.not_to raise_error
diff --git a/spec/models/deployment_spec.rb b/spec/models/deployment_spec.rb
index acccf2c39c4..f9a05fbb06f 100644
--- a/spec/models/deployment_spec.rb
+++ b/spec/models/deployment_spec.rb
@@ -765,7 +765,7 @@ RSpec.describe Deployment do
expect(Deployments::LinkMergeRequestWorker).to receive(:perform_async)
expect(Deployments::HooksWorker).to receive(:perform_async)
- deploy.update_status('success')
+ expect(deploy.update_status('success')).to eq(true)
end
it 'updates finished_at when transitioning to a finished status' do
@@ -775,6 +775,139 @@ RSpec.describe Deployment do
expect(deploy.read_attribute(:finished_at)).to eq(Time.current)
end
end
+
+ it 'tracks an exception if an invalid status transition is detected' do
+ expect(Gitlab::ErrorTracking)
+ .to receive(:track_exception)
+ .with(instance_of(described_class::StatusUpdateError), deployment_id: deploy.id)
+
+ expect(deploy.update_status('running')).to eq(false)
+ end
+
+ it 'tracks an exception if an invalid argument' do
+ expect(Gitlab::ErrorTracking)
+ .to receive(:track_exception)
+ .with(instance_of(described_class::StatusUpdateError), deployment_id: deploy.id)
+
+ expect(deploy.update_status('created')).to eq(false)
+ end
+ end
+
+ describe '#sync_status_with' do
+ subject { deployment.sync_status_with(ci_build) }
+
+ let_it_be(:project) { create(:project, :repository) }
+
+ let(:deployment) { create(:deployment, project: project, status: deployment_status) }
+ let(:ci_build) { create(:ci_build, project: project, status: build_status) }
+
+ shared_examples_for 'synchronizing deployment' do
+ it 'changes deployment status' do
+ expect(Gitlab::ErrorTracking).not_to receive(:track_exception)
+
+ is_expected.to eq(true)
+
+ expect(deployment.status).to eq(build_status.to_s)
+ expect(deployment.errors).to be_empty
+ end
+ end
+
+ shared_examples_for 'gracefully handling error' do
+ it 'tracks an exception' do
+ expect(Gitlab::ErrorTracking).to receive(:track_exception).with(
+ instance_of(described_class::StatusSyncError),
+ deployment_id: deployment.id,
+ build_id: ci_build.id)
+
+ is_expected.to eq(false)
+
+ expect(deployment.status).to eq(deployment_status.to_s)
+ expect(deployment.errors.full_messages).to include(error_message)
+ end
+ end
+
+ shared_examples_for 'ignoring build' do
+ it 'does not change deployment status' do
+ expect(Gitlab::ErrorTracking).not_to receive(:track_exception)
+
+ is_expected.to eq(false)
+
+ expect(deployment.status).to eq(deployment_status.to_s)
+ expect(deployment.errors).to be_empty
+ end
+ end
+
+ context 'with created deployment' do
+ let(:deployment_status) { :created }
+
+ context 'with running build' do
+ let(:build_status) { :running }
+
+ it_behaves_like 'synchronizing deployment'
+ end
+
+ context 'with finished build' do
+ let(:build_status) { :success }
+
+ it_behaves_like 'synchronizing deployment'
+ end
+
+ context 'with unrelated build' do
+ let(:build_status) { :waiting_for_resource }
+
+ it_behaves_like 'ignoring build'
+ end
+ end
+
+ context 'with running deployment' do
+ let(:deployment_status) { :running }
+
+ context 'with running build' do
+ let(:build_status) { :running }
+
+ it_behaves_like 'gracefully handling error' do
+ let(:error_message) { %Q{Status cannot transition via \"run\"} }
+ end
+ end
+
+ context 'with finished build' do
+ let(:build_status) { :success }
+
+ it_behaves_like 'synchronizing deployment'
+ end
+
+ context 'with unrelated build' do
+ let(:build_status) { :waiting_for_resource }
+
+ it_behaves_like 'ignoring build'
+ end
+ end
+
+ context 'with finished deployment' do
+ let(:deployment_status) { :success }
+
+ context 'with running build' do
+ let(:build_status) { :running }
+
+ it_behaves_like 'gracefully handling error' do
+ let(:error_message) { %Q{Status cannot transition via \"run\"} }
+ end
+ end
+
+ context 'with finished build' do
+ let(:build_status) { :success }
+
+ it_behaves_like 'gracefully handling error' do
+ let(:error_message) { %Q{Status cannot transition via \"succeed\"} }
+ end
+ end
+
+ context 'with unrelated build' do
+ let(:build_status) { :waiting_for_resource }
+
+ it_behaves_like 'ignoring build'
+ end
+ end
end
describe '#valid_sha' do
diff --git a/spec/requests/api/deployments_spec.rb b/spec/requests/api/deployments_spec.rb
index 38c96cd37af..69f7b54c277 100644
--- a/spec/requests/api/deployments_spec.rb
+++ b/spec/requests/api/deployments_spec.rb
@@ -376,6 +376,16 @@ RSpec.describe API::Deployments do
expect(json_response['status']).to eq('success')
end
+ it 'returns an error when an invalid status transition is detected' do
+ put(
+ api("/projects/#{project.id}/deployments/#{deploy.id}", user),
+ params: { status: 'running' }
+ )
+
+ expect(response).to have_gitlab_http_status(:bad_request)
+ expect(json_response['message']['status']).to include(%Q{cannot transition via \"run\"})
+ end
+
it 'links merge requests when the deployment status changes to success', :sidekiq_inline do
mr = create(
:merge_request,
diff --git a/spec/services/deployments/update_service_spec.rb b/spec/services/deployments/update_service_spec.rb
index 16b24d0dee8..d3840189ba4 100644
--- a/spec/services/deployments/update_service_spec.rb
+++ b/spec/services/deployments/update_service_spec.rb
@@ -34,9 +34,11 @@ RSpec.describe Deployments::UpdateService do
expect(deploy).to be_canceled
end
- it 'raises ArgumentError if the status is invalid' do
- expect { described_class.new(deploy, status: 'kittens').execute }
- .to raise_error(ArgumentError)
+ it 'does not change the state if the status is invalid' do
+ expect(described_class.new(deploy, status: 'kittens').execute)
+ .to be_falsy
+
+ expect(deploy).to be_created
end
it 'links merge requests when changing the status to success', :sidekiq_inline do