summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2022-03-24 00:07:27 +0000
committerGitLab Bot <gitlab-bot@gitlab.com>2022-03-24 00:07:27 +0000
commit179b33c5465649ee5d020f70604f1b02473fc702 (patch)
treef2883044ea8126a7b5774ec2ff7750940a443246
parentbbc06065aa40c3d0d037bea16081f4f5c969053e (diff)
downloadgitlab-ce-179b33c5465649ee5d020f70604f1b02473fc702.tar.gz
Add latest changes from gitlab-org/gitlab@master
-rw-r--r--.gitlab/ci/frontend.gitlab-ci.yml5
-rw-r--r--Dangerfile14
-rw-r--r--Gemfile2
-rw-r--r--Gemfile.lock7
-rwxr-xr-xRakefile3
-rw-r--r--app/controllers/oauth/authorizations_controller.rb3
-rw-r--r--app/helpers/webpack_helper.rb12
-rw-r--r--app/models/suggestion.rb6
-rw-r--r--app/policies/suggestion_policy.rb4
-rw-r--r--app/services/suggestions/apply_service.rb2
-rw-r--r--config/feature_flags/development/omniauth_login_minimal_scopes.yml8
-rw-r--r--config/initializers/static_files.rb2
-rw-r--r--danger/Dangerfile-bundle_size (renamed from danger/bundle_size/Dangerfile)1
-rw-r--r--danger/ci_templates/Dangerfile2
-rw-r--r--danger/database/Dangerfile4
-rw-r--r--danger/feature_flag/Dangerfile8
-rw-r--r--danger/specialization_labels/Dangerfile4
-rw-r--r--danger/specs/Dangerfile2
-rw-r--r--danger/z_metadata/Dangerfile6
-rw-r--r--db/post_migrate/20220315171027_add_tmp_index_to_support_leaky_regex_cleanup.rb19
-rw-r--r--db/post_migrate/20220315171129_cleanup_draft_data_from_faulty_regex.rb42
-rw-r--r--db/schema_migrations/202203151710271
-rw-r--r--db/schema_migrations/202203151711291
-rw-r--r--db/structure.sql2
-rw-r--r--doc/api/graphql/reference/index.md4
-rw-r--r--doc/development/documentation/styleguide/word_list.md41
-rw-r--r--doc/integration/gitlab.md7
-rw-r--r--doc/user/project/merge_requests/reviews/suggestions.md2
-rw-r--r--lefthook.yml2
-rw-r--r--lib/gitlab/background_migration/cleanup_draft_data_from_faulty_regex.rb48
-rw-r--r--lib/gitlab/suggestions/commit_message.rb6
-rw-r--r--lib/gitlab/suggestions/suggestion_set.rb8
-rw-r--r--lib/tasks/gitlab_danger.rake19
-rw-r--r--spec/lib/gitlab/background_migration/cleanup_draft_data_from_faulty_regex_spec.rb54
-rw-r--r--spec/lib/gitlab/suggestions/commit_message_spec.rb131
-rw-r--r--spec/lib/gitlab/suggestions/suggestion_set_spec.rb116
-rw-r--r--spec/migrations/20220315171129_cleanup_draft_data_from_faulty_regex_spec.rb40
-rw-r--r--spec/tooling/danger/project_helper_spec.rb34
-rw-r--r--tooling/danger/project_helper.rb32
39 files changed, 460 insertions, 244 deletions
diff --git a/.gitlab/ci/frontend.gitlab-ci.yml b/.gitlab/ci/frontend.gitlab-ci.yml
index cb07384676d..5d4521b3f36 100644
--- a/.gitlab/ci/frontend.gitlab-ci.yml
+++ b/.gitlab/ci/frontend.gitlab-ci.yml
@@ -335,10 +335,13 @@ bundle-size-review:
stage: test
needs: ["compile-production-assets"]
script:
+ - source scripts/utils.sh
- mkdir -p bundle-size-review
- cp webpack-report/index.html bundle-size-review/bundle-report.html
- yarn global add https://gitlab.com/gitlab-org/frontend/playground/webpack-memory-metrics.git
- - danger --dangerfile=danger/bundle_size/Dangerfile --fail-on-errors=true --verbose --danger_id=bundle-size-review
+ - |
+ danger_id=$(echo -n ${DANGER_GITLAB_API_TOKEN} | md5sum | awk '{print $1}' | cut -c5-10)
+ run_timed_command "danger --dangerfile=danger/Dangerfile-bundle_size --fail-on-errors=true --verbose --danger_id=bundle-size-review-${danger_id}"
artifacts:
when: always
name: bundle-size-review
diff --git a/Dangerfile b/Dangerfile
index aaa1aae813b..280a73d432c 100644
--- a/Dangerfile
+++ b/Dangerfile
@@ -11,16 +11,8 @@ project_name = ee? ? 'gitlab' : 'gitlab-foss'
Gitlab::Dangerfiles.for_project(self, project_name) do |gitlab_dangerfiles|
gitlab_dangerfiles.import_plugins
+ gitlab_dangerfiles.config.ci_only_rules = ProjectHelper::CI_ONLY_RULES
+ gitlab_dangerfiles.config.files_to_category = ProjectHelper::CATEGORIES
- unless helper.release_automation?
- danger.import_plugin('danger/plugins/*.rb')
- gitlab_dangerfiles.import_dangerfiles(except: %w[simple_roulette])
- gitlab_dangerfiles.config.files_to_category = ProjectHelper::CATEGORIES
- end
-end
-
-return if helper.release_automation?
-
-project_helper.rule_names.each do |rule|
- danger.import_dangerfile(path: File.join('danger', rule))
+ gitlab_dangerfiles.import_dangerfiles(except: %w[simple_roulette])
end
diff --git a/Gemfile b/Gemfile
index ac5b5517f22..49a5e75d4e9 100644
--- a/Gemfile
+++ b/Gemfile
@@ -403,7 +403,7 @@ group :development, :test do
end
group :development, :test, :danger do
- gem 'gitlab-dangerfiles', '~> 2.11.0', require: false
+ gem 'gitlab-dangerfiles', '~> 3.0', require: false
end
group :development, :test, :coverage do
diff --git a/Gemfile.lock b/Gemfile.lock
index dbffdd3835c..6a981d37fe6 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -224,7 +224,7 @@ GEM
css_parser (1.7.0)
addressable
daemons (1.3.1)
- danger (8.4.5)
+ danger (8.5.0)
claide (~> 1.0)
claide-plugins (>= 0.9.2)
colored2 (~> 3.1)
@@ -463,9 +463,10 @@ GEM
terminal-table (~> 1.5, >= 1.5.1)
gitlab-chronic (0.10.5)
numerizer (~> 0.2)
- gitlab-dangerfiles (2.11.0)
+ gitlab-dangerfiles (3.0.0)
danger (>= 8.4.5)
danger-gitlab (>= 8.0.0)
+ rake
gitlab-experiment (0.7.0)
activesupport (>= 3.0)
request_store (>= 1.0)
@@ -1494,7 +1495,7 @@ DEPENDENCIES
gitaly (~> 14.9.0.pre.rc4)
github-markup (~> 1.7.0)
gitlab-chronic (~> 0.10.5)
- gitlab-dangerfiles (~> 2.11.0)
+ gitlab-dangerfiles (~> 3.0)
gitlab-experiment (~> 0.7.0)
gitlab-fog-azure-rm (~> 1.2.0)
gitlab-labkit (~> 0.22.0)
diff --git a/Rakefile b/Rakefile
index 9545516d2a9..9a651fda7a0 100755
--- a/Rakefile
+++ b/Rakefile
@@ -16,3 +16,6 @@ require File.expand_path('config/initializers/01_active_record_database_tasks_co
Gitlab::Application.load_tasks
Knapsack.load_tasks if defined?(Knapsack)
+
+require 'gitlab-dangerfiles'
+Gitlab::Dangerfiles.load_tasks
diff --git a/app/controllers/oauth/authorizations_controller.rb b/app/controllers/oauth/authorizations_controller.rb
index d1c409d071e..e13c240de25 100644
--- a/app/controllers/oauth/authorizations_controller.rb
+++ b/app/controllers/oauth/authorizations_controller.rb
@@ -37,9 +37,6 @@ class Oauth::AuthorizationsController < Doorkeeper::AuthorizationsController
# limit scopes when signing in with GitLab
def downgrade_scopes!
- return unless Feature.enabled?(:omniauth_login_minimal_scopes, current_user,
- default_enabled: :yaml)
-
auth_type = params.delete('gl_auth_type')
return unless auth_type == 'login'
diff --git a/app/helpers/webpack_helper.rb b/app/helpers/webpack_helper.rb
index 64900714327..ba3c232bec4 100644
--- a/app/helpers/webpack_helper.rb
+++ b/app/helpers/webpack_helper.rb
@@ -83,16 +83,8 @@ module WebpackHelper
end
def webpack_public_host
- # We do not proxy the webpack output in the 'test' environment,
- # so we must reference the webpack dev server directly.
- if Rails.env.test? && Gitlab.config.webpack.dev_server.enabled
- host = Gitlab.config.webpack.dev_server.host
- port = Gitlab.config.webpack.dev_server.port
- protocol = Gitlab.config.webpack.dev_server.https ? 'https' : 'http'
- "#{protocol}://#{host}:#{port}"
- else
- ActionController::Base.asset_host.try(:chomp, '/')
- end
+ # We proxy webpack output in 'test' and 'dev' environment, so we can just use asset_host
+ ActionController::Base.asset_host.try(:chomp, '/')
end
def webpack_public_path
diff --git a/app/models/suggestion.rb b/app/models/suggestion.rb
index f1ca5c23997..ca2ad8bf88c 100644
--- a/app/models/suggestion.rb
+++ b/app/models/suggestion.rb
@@ -16,10 +16,14 @@ class Suggestion < ApplicationRecord
note.latest_diff_file
end
- def project
+ def source_project
noteable.source_project
end
+ def target_project
+ noteable.target_project
+ end
+
def branch
noteable.source_branch
end
diff --git a/app/policies/suggestion_policy.rb b/app/policies/suggestion_policy.rb
index 4c84c8ba690..3c273dc6d39 100644
--- a/app/policies/suggestion_policy.rb
+++ b/app/policies/suggestion_policy.rb
@@ -1,10 +1,10 @@
# frozen_string_literal: true
class SuggestionPolicy < BasePolicy
- delegate { @subject.project }
+ delegate { @subject.source_project }
condition(:can_push_to_branch) do
- Gitlab::UserAccess.new(@user, container: @subject.project).can_push_to_branch?(@subject.branch)
+ Gitlab::UserAccess.new(@user, container: @subject.source_project).can_push_to_branch?(@subject.branch)
end
rule { can_push_to_branch }.enable :apply_suggestion
diff --git a/app/services/suggestions/apply_service.rb b/app/services/suggestions/apply_service.rb
index a0d26e08341..a20eb6b79c5 100644
--- a/app/services/suggestions/apply_service.rb
+++ b/app/services/suggestions/apply_service.rb
@@ -54,7 +54,7 @@ module Suggestions
author_email: author&.email
}
- ::Files::MultiService.new(suggestion_set.project, current_user, params)
+ ::Files::MultiService.new(suggestion_set.source_project, current_user, params)
end
def commit_message
diff --git a/config/feature_flags/development/omniauth_login_minimal_scopes.yml b/config/feature_flags/development/omniauth_login_minimal_scopes.yml
deleted file mode 100644
index b2ca3484a98..00000000000
--- a/config/feature_flags/development/omniauth_login_minimal_scopes.yml
+++ /dev/null
@@ -1,8 +0,0 @@
----
-name: omniauth_login_minimal_scopes
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/78556
-rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/351331
-milestone: '14.8'
-type: development
-group: 'group::authentication and authorization'
-default_enabled: false
diff --git a/config/initializers/static_files.rb b/config/initializers/static_files.rb
index 2879d48387d..a26d78f102b 100644
--- a/config/initializers/static_files.rb
+++ b/config/initializers/static_files.rb
@@ -21,7 +21,7 @@ if app.config.public_file_server.enabled
# If webpack-dev-server is configured, proxy webpack's public directory
# instead of looking for static assets
- if Gitlab.config.webpack.dev_server.enabled && Rails.env.development?
+ if Gitlab.config.webpack.dev_server.enabled && Gitlab.dev_or_test_env?
app.config.middleware.insert_before(
Gitlab::Middleware::Static,
Gitlab::Webpack::DevServerMiddleware,
diff --git a/danger/bundle_size/Dangerfile b/danger/Dangerfile-bundle_size
index b824edb5dab..23ab726096e 100644
--- a/danger/bundle_size/Dangerfile
+++ b/danger/Dangerfile-bundle_size
@@ -1,4 +1,5 @@
# frozen_string_literal: true
+# This file isn't named "Dangerfile" so that it's not imported by default since it's only meant to be run in the `bundle-size-review` job.
analysis_result = "./bundle-size-review/analysis.json"
markdown_result = "./bundle-size-review/comparison.md"
diff --git a/danger/ci_templates/Dangerfile b/danger/ci_templates/Dangerfile
index 3d57436ef94..ace9905e91d 100644
--- a/danger/ci_templates/Dangerfile
+++ b/danger/ci_templates/Dangerfile
@@ -19,7 +19,7 @@ return unless helper.ci?
template_paths_to_review = helper.changes_by_category[:ci_template]
-if gitlab.mr_labels.include?('ci::templates') || template_paths_to_review.any?
+if helper.mr_labels.include?('ci::templates') || template_paths_to_review.any?
message 'This merge request adds or changes files that require a ' \
'review from the CI/CD Templates maintainers.'
diff --git a/danger/database/Dangerfile b/danger/database/Dangerfile
index 0128f0fa195..f94184263ad 100644
--- a/danger/database/Dangerfile
+++ b/danger/database/Dangerfile
@@ -49,11 +49,11 @@ if geo_migration_created && !geo_db_schema_updated
end
return unless helper.ci?
-return if gitlab.mr_labels.include?(DATABASE_APPROVED_LABEL)
+return if helper.mr_labels.include?(DATABASE_APPROVED_LABEL)
db_paths_to_review = helper.changes_by_category[:database]
-if gitlab.mr_labels.include?('database') || db_paths_to_review.any?
+if helper.mr_labels.include?('database') || db_paths_to_review.any?
message 'This merge request adds or changes files that require a ' \
'review from the [Database team](https://gitlab.com/groups/gl-database/-/group_members).'
diff --git a/danger/feature_flag/Dangerfile b/danger/feature_flag/Dangerfile
index 5fe9d42a7a1..d5b907377aa 100644
--- a/danger/feature_flag/Dangerfile
+++ b/danger/feature_flag/Dangerfile
@@ -22,21 +22,21 @@ def check_feature_flag_yaml(feature_flag)
end
rescue Psych::Exception
# YAML could not be parsed, fail the build.
- fail "#{gitlab.html_link(feature_flag.path)} isn't valid YAML! #{SEE_DOC}"
+ fail "#{helper.html_link(feature_flag.path)} isn't valid YAML! #{SEE_DOC}"
rescue StandardError => e
warn "There was a problem trying to check the Feature Flag file. Exception: #{e.class.name} - #{e.message}"
end
def message_for_feature_flag_missing_group!(feature_flag:, mr_group_label:)
if mr_group_label.nil?
- warn "Consider setting `group` in #{gitlab.html_link(feature_flag.path)}. #{SEE_DOC}"
+ warn "Consider setting `group` in #{helper.html_link(feature_flag.path)}. #{SEE_DOC}"
else
mr_line = feature_flag.raw.lines.find_index("group:\n")
if mr_line
markdown(format(SUGGEST_MR_COMMENT, group: mr_group_label), file: feature_flag.path, line: mr_line.succ)
else
- warn %(Consider setting `group: "#{mr_group_label}"` in #{gitlab.html_link(feature_flag.path)}. #{SEE_DOC})
+ warn %(Consider setting `group: "#{mr_group_label}"` in #{helper.html_link(feature_flag.path)}. #{SEE_DOC})
end
end
end
@@ -60,7 +60,7 @@ def message_for_feature_flag_with_group!(feature_flag:, mr_group_label:)
if mr_group_label.nil?
helper.labels_to_add << feature_flag.group
else
- fail %(`group` is set to ~"#{feature_flag.group}" in #{gitlab.html_link(feature_flag.path)}, which does not match ~"#{mr_group_label}" set on the MR!)
+ fail %(`group` is set to ~"#{feature_flag.group}" in #{helper.html_link(feature_flag.path)}, which does not match ~"#{mr_group_label}" set on the MR!)
end
end
diff --git a/danger/specialization_labels/Dangerfile b/danger/specialization_labels/Dangerfile
index f161c470f36..615ceb8625d 100644
--- a/danger/specialization_labels/Dangerfile
+++ b/danger/specialization_labels/Dangerfile
@@ -16,11 +16,11 @@ SPECIALIZATIONS = {
labels_to_add = helper.changes_by_category.each_with_object([]) do |(category, _changes), memo|
label = SPECIALIZATIONS[category]
next unless label
- next if gitlab.mr_labels.include?(label)
+ next if helper.mr_labels.include?(label)
# Don't override already-set scoped labels.
label_scope = label.split('::')[0...-1].join('::')
- next if !label_scope.empty? && gitlab.mr_labels.any? { |mr_label| mr_label.start_with?(label_scope) }
+ next if !label_scope.empty? && helper.has_scoped_label_with_scope?(label_scope)
memo << label
end
diff --git a/danger/specs/Dangerfile b/danger/specs/Dangerfile
index 8ef046f7bc1..dc9809b20b5 100644
--- a/danger/specs/Dangerfile
+++ b/danger/specs/Dangerfile
@@ -37,7 +37,7 @@ has_ee_app_changes = all_changed_files.grep(%r{\Aee/(app|lib|db/(geo/)?(post_)?m
spec_changes = specs.changed_specs_files(ee: :exclude)
has_spec_changes = spec_changes.any?
has_ee_spec_changes = specs.changed_specs_files(ee: :only).any?
-new_specs_needed = (gitlab.mr_labels & NO_SPECS_LABELS).empty?
+new_specs_needed = (helper.mr_labels & NO_SPECS_LABELS).empty?
if (has_app_changes || has_ee_app_changes) && !(has_spec_changes || has_ee_spec_changes) && new_specs_needed
warn format(NO_NEW_SPEC_MESSAGE, labels: helper.labels_list(NO_SPECS_LABELS)), sticky: false
diff --git a/danger/z_metadata/Dangerfile b/danger/z_metadata/Dangerfile
index 546fdc8de5f..8aeb0c33a9c 100644
--- a/danger/z_metadata/Dangerfile
+++ b/danger/z_metadata/Dangerfile
@@ -14,12 +14,12 @@ end
has_milestone = !gitlab.mr_json["milestone"].nil?
-unless has_milestone || (helper.security_mr? && gitlab.branch_for_base == DEFAULT_BRANCH)
+unless has_milestone || (helper.security_mr? && helper.mr_target_branch == DEFAULT_BRANCH)
warn "This merge request does not refer to an existing milestone.", sticky: false
end
-has_pick_into_stable_label = gitlab.mr_labels.find { |label| label.start_with?('Pick into') }
+has_pick_into_stable_label = helper.mr_labels.find { |label| label.start_with?('Pick into') }
-if gitlab.branch_for_base != DEFAULT_BRANCH && !has_pick_into_stable_label && !helper.security_mr?
+if helper.mr_target_branch != DEFAULT_BRANCH && !has_pick_into_stable_label && !helper.security_mr?
warn "Most of the time, merge requests should target `#{DEFAULT_BRANCH}`. Otherwise, please set the relevant `Pick into X.Y` label."
end
diff --git a/db/post_migrate/20220315171027_add_tmp_index_to_support_leaky_regex_cleanup.rb b/db/post_migrate/20220315171027_add_tmp_index_to_support_leaky_regex_cleanup.rb
new file mode 100644
index 00000000000..6f4bd29337e
--- /dev/null
+++ b/db/post_migrate/20220315171027_add_tmp_index_to_support_leaky_regex_cleanup.rb
@@ -0,0 +1,19 @@
+# frozen_string_literal: true
+
+class AddTmpIndexToSupportLeakyRegexCleanup < Gitlab::Database::Migration[1.0]
+ INDEX_NAME = "tmp_index_merge_requests_draft_and_status_leaky_regex"
+ LEAKY_REGEXP_STR = "^\\[draft\\]|\\(draft\\)|draft:|draft|\\[WIP\\]|WIP:|WIP"
+ CORRECTED_REGEXP_STR = "^(\\[draft\\]|\\(draft\\)|draft:|draft|\\[WIP\\]|WIP:|WIP)"
+
+ disable_ddl_transaction!
+
+ def up
+ add_concurrent_index :merge_requests, :id,
+ where: "draft = true AND state_id = 1 AND ((title)::text ~* '#{LEAKY_REGEXP_STR}'::text) AND ((title)::text !~* '#{CORRECTED_REGEXP_STR}'::text)",
+ name: INDEX_NAME
+ end
+
+ def down
+ remove_concurrent_index_by_name :merge_requests, INDEX_NAME
+ end
+end
diff --git a/db/post_migrate/20220315171129_cleanup_draft_data_from_faulty_regex.rb b/db/post_migrate/20220315171129_cleanup_draft_data_from_faulty_regex.rb
new file mode 100644
index 00000000000..be81bf85f62
--- /dev/null
+++ b/db/post_migrate/20220315171129_cleanup_draft_data_from_faulty_regex.rb
@@ -0,0 +1,42 @@
+# frozen_string_literal: true
+
+class CleanupDraftDataFromFaultyRegex < Gitlab::Database::Migration[1.0]
+ MIGRATION = 'CleanupDraftDataFromFaultyRegex'
+ DELAY_INTERVAL = 5.minutes
+ BATCH_SIZE = 20
+
+ disable_ddl_transaction!
+
+ class MergeRequest < ActiveRecord::Base
+ LEAKY_REGEXP_STR = "^\\[draft\\]|\\(draft\\)|draft:|draft|\\[WIP\\]|WIP:|WIP"
+ CORRECTED_REGEXP_STR = "^(\\[draft\\]|\\(draft\\)|draft:|draft|\\[WIP\\]|WIP:|WIP)"
+
+ self.table_name = 'merge_requests'
+
+ include ::EachBatch
+
+ def self.eligible
+ where(state_id: 1)
+ .where(draft: true)
+ .where("title ~* ?", LEAKY_REGEXP_STR)
+ .where("title !~* ?", CORRECTED_REGEXP_STR)
+ end
+ end
+
+ def up
+ return unless Gitlab.com?
+
+ queue_background_migration_jobs_by_range_at_intervals(
+ MergeRequest.eligible,
+ MIGRATION,
+ DELAY_INTERVAL,
+ batch_size: BATCH_SIZE,
+ track_jobs: true
+ )
+ end
+
+ def down
+ # noop
+ #
+ end
+end
diff --git a/db/schema_migrations/20220315171027 b/db/schema_migrations/20220315171027
new file mode 100644
index 00000000000..7a4c65f3b7f
--- /dev/null
+++ b/db/schema_migrations/20220315171027
@@ -0,0 +1 @@
+4c329622299c76ca753381f1ccc0686714d07eeee8acfc834e576d5a5addaafc \ No newline at end of file
diff --git a/db/schema_migrations/20220315171129 b/db/schema_migrations/20220315171129
new file mode 100644
index 00000000000..1f558096664
--- /dev/null
+++ b/db/schema_migrations/20220315171129
@@ -0,0 +1 @@
+7ca832e710026c0721ecdcd50b477073aeaf7cb795c50acd604897f85707b163 \ No newline at end of file
diff --git a/db/structure.sql b/db/structure.sql
index 1e169489c1e..2b7a8e5a5ba 100644
--- a/db/structure.sql
+++ b/db/structure.sql
@@ -29617,6 +29617,8 @@ CREATE INDEX tmp_index_issues_on_issue_type_and_id ON issues USING btree (issue_
CREATE INDEX tmp_index_members_on_state ON members USING btree (state) WHERE (state = 2);
+CREATE INDEX tmp_index_merge_requests_draft_and_status_leaky_regex ON merge_requests USING btree (id) WHERE ((draft = true) AND (state_id = 1) AND ((title)::text ~* '^\[draft\]|\(draft\)|draft:|draft|\[WIP\]|WIP:|WIP'::text) AND ((title)::text !~* '^(\[draft\]|\(draft\)|draft:|draft|\[WIP\]|WIP:|WIP)'::text));
+
CREATE INDEX tmp_index_namespaces_empty_traversal_ids_with_child_namespaces ON namespaces USING btree (id) WHERE ((parent_id IS NOT NULL) AND (traversal_ids = '{}'::integer[]));
CREATE INDEX tmp_index_namespaces_empty_traversal_ids_with_root_namespaces ON namespaces USING btree (id) WHERE ((parent_id IS NULL) AND (traversal_ids = '{}'::integer[]));
diff --git a/doc/api/graphql/reference/index.md b/doc/api/graphql/reference/index.md
index 8bc87d37a48..df68a27673e 100644
--- a/doc/api/graphql/reference/index.md
+++ b/doc/api/graphql/reference/index.md
@@ -3236,6 +3236,10 @@ Input type: `iterationCreateInput`
### `Mutation.iterationDelete`
+WARNING:
+**Deprecated** in 14.10.
+Manual iteration management is deprecated. Only automatic iteration cadences will be supported in the future.
+
Input type: `IterationDeleteInput`
#### Arguments
diff --git a/doc/development/documentation/styleguide/word_list.md b/doc/development/documentation/styleguide/word_list.md
index 9954a3cc3e4..dcb9a5f7362 100644
--- a/doc/development/documentation/styleguide/word_list.md
+++ b/doc/development/documentation/styleguide/word_list.md
@@ -261,11 +261,17 @@ Do not use **Developer permissions**. A user who is assigned the Developer role
See [the Microsoft style guide](https://docs.microsoft.com/en-us/style-guide/a-z-word-list-term-collections/d/disable-disabled) for guidance on **disable**.
Use **inactive** or **off** instead. ([Vale](../testing.md#vale) rule: [`InclusionAbleism.yml`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/doc/.vale/gitlab/InclusionAbleism.yml))
-
## disallow
Use **prevent** instead of **disallow**. ([Vale](../testing.md#vale) rule: [`Substitutions.yml`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/doc/.vale/gitlab/Substitutions.yml))
+## downgrade
+
+To be more upbeat and precise, do not use **downgrade**. Focus instead on the action the user is taking.
+
+- For changing to earlier GitLab versions, use [**roll back**](#roll-back).
+- For changing to lower GitLab tiers, use **change the subscription tier**.
+
## dropdown list
Use **dropdown list** to refer to the UI element. Do not use **dropdown** without **list** after it.
@@ -748,6 +754,12 @@ Do not use **roles** and [**permissions**](#permissions) interchangeably. Each u
Roles are not the same as [**access levels**](#access-level).
+## roll back
+
+Use **roll back** for changing a GitLab version to an earlier one.
+
+Do not use **roll back** for licensing or subscriptions. Use **change the subscription tier** instead.
+
## runner, runners
Use lowercase for **runners**. These are the agents that run CI/CD jobs. See also [GitLab Runner](#gitlab-runner) and [this issue](https://gitlab.com/gitlab-org/gitlab/-/issues/233529).
@@ -934,6 +946,33 @@ Use [**2FA** and **two-factor authentication**](#2fa-two-factor-authentication)
Do not use **type** if you can avoid it. Use **enter** instead.
+## update
+
+Use **update** for installing a newer **patch** version of the software only. For example:
+
+- Update GitLab from 14.9 to 14.9.1.
+
+Do not use **update** for any other case. Instead, use **upgrade**.
+
+## upgrade
+
+Use **upgrade** for:
+
+- Choosing a higher subscription tier (Premium or Ultimate).
+- Installing a newer **major** (13.0, 14.0) or **minor** (13.8, 14.5) version of GitLab.
+
+For example:
+
+- Upgrade to GitLab Ultimate.
+- Upgrade GitLab from 14.0 to 14.1.
+- Upgrade GitLab from 14.0 to 15.0.
+
+Use caution with the phrase **Upgrade GitLab** without any other text.
+Ensure the surrounding text clarifies whether
+you're talking about the product version or the subscription tier.
+
+See also [downgrade](#downgrade) and [roll back](#roll-back).
+
## useful
Do not use **useful**. If the user doesn't find the process to be useful, we lose their trust. ([Vale](../testing.md#vale) rule: [`Simplicity.yml`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/doc/.vale/gitlab/Simplicity.yml))
diff --git a/doc/integration/gitlab.md b/doc/integration/gitlab.md
index 132006ab996..c79aeb8546d 100644
--- a/doc/integration/gitlab.md
+++ b/doc/integration/gitlab.md
@@ -117,10 +117,9 @@ signed in.
## Reduce access privileges on sign in
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/337663) in GitLab 14.8 [with a flag](../administration/feature_flags.md) named `omniauth_login_minimal_scopes`. Disabled by default.
-
-FLAG:
-On self-managed GitLab, by default this feature is not available. To make it available, ask an administrator to [enable the feature flag](../administration/feature_flags.md) named `omniauth_login_minimal_scopes`. On GitLab.com, this feature is not available.
+> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/337663) in GitLab 14.8 [with a flag](../administration/feature_flags.md) named `omniauth_login_minimal_scopes`. Disabled by default.
+> - [Enabled on GitLab.com](https://gitlab.com/gitlab-org/gitlab/-/issues/351331) in GitLab 14.9.
+> - [Feature flag `omniauth_login_minimal_scopes`](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/83453) removed in GitLab 14.10
If you use a GitLab instance for authentication, you can reduce access rights when an OAuth application is used for sign in.
diff --git a/doc/user/project/merge_requests/reviews/suggestions.md b/doc/user/project/merge_requests/reviews/suggestions.md
index 9868f2619ba..8e6794bcfa7 100644
--- a/doc/user/project/merge_requests/reviews/suggestions.md
+++ b/doc/user/project/merge_requests/reviews/suggestions.md
@@ -108,6 +108,8 @@ For example, to customize the commit message to output
**Addresses user_1's review**, set the custom text to
`Addresses %{username}'s review`.
+For merge requests created from forks, GitLab uses the template defined in target project.
+
NOTE:
Custom commit messages for each applied suggestion is
introduced by [#25381](https://gitlab.com/gitlab-org/gitlab/-/issues/25381).
diff --git a/lefthook.yml b/lefthook.yml
index b21db70a385..086e70fcbb9 100644
--- a/lefthook.yml
+++ b/lefthook.yml
@@ -2,7 +2,7 @@ pre-push:
parallel: true
commands:
danger:
- run: CI_PROJECT_DIR=. bundle exec danger dry_run
+ run: bundle exec rake danger_local
eslint:
tags: frontend style
files: git diff --name-only --diff-filter=d $(git merge-base origin/master HEAD)..HEAD
diff --git a/lib/gitlab/background_migration/cleanup_draft_data_from_faulty_regex.rb b/lib/gitlab/background_migration/cleanup_draft_data_from_faulty_regex.rb
new file mode 100644
index 00000000000..b703faf6a6c
--- /dev/null
+++ b/lib/gitlab/background_migration/cleanup_draft_data_from_faulty_regex.rb
@@ -0,0 +1,48 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module BackgroundMigration
+ # Cleanup draft column data inserted by a faulty regex
+ #
+ class CleanupDraftDataFromFaultyRegex
+ # Migration only version of MergeRequest table
+ ##
+ class MergeRequest < ActiveRecord::Base
+ LEAKY_REGEXP_STR = "^\\[draft\\]|\\(draft\\)|draft:|draft|\\[WIP\\]|WIP:|WIP"
+ CORRECTED_REGEXP_STR = "^(\\[draft\\]|\\(draft\\)|draft:|draft|\\[WIP\\]|WIP:|WIP)"
+
+ include EachBatch
+
+ self.table_name = 'merge_requests'
+
+ def self.eligible
+ where(state_id: 1)
+ .where(draft: true)
+ .where("title ~* ?", LEAKY_REGEXP_STR)
+ .where("title !~* ?", CORRECTED_REGEXP_STR)
+ end
+ end
+
+ def perform(start_id, end_id)
+ eligible_mrs = MergeRequest.eligible.where(id: start_id..end_id).pluck(:id)
+
+ return if eligible_mrs.empty?
+
+ eligible_mrs.each_slice(10) do |slice|
+ MergeRequest.where(id: slice).update_all(draft: false)
+ end
+
+ mark_job_as_succeeded(start_id, end_id)
+ end
+
+ private
+
+ def mark_job_as_succeeded(*arguments)
+ Gitlab::Database::BackgroundMigrationJob.mark_all_as_succeeded(
+ 'CleanupDraftDataFromFaultyRegex',
+ arguments
+ )
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/suggestions/commit_message.rb b/lib/gitlab/suggestions/commit_message.rb
index 5bca3efe6e1..fcf30cd6df9 100644
--- a/lib/gitlab/suggestions/commit_message.rb
+++ b/lib/gitlab/suggestions/commit_message.rb
@@ -13,7 +13,7 @@ module Gitlab
end
def message
- project = suggestion_set.project
+ project = suggestion_set.target_project
user_defined_message = @custom_message.presence || project.suggestion_commit_message.presence
message = user_defined_message || DEFAULT_SUGGESTION_COMMIT_MESSAGE
@@ -37,8 +37,8 @@ module Gitlab
'branch_name' => ->(user, suggestion_set) { suggestion_set.branch },
'files_count' => ->(user, suggestion_set) { suggestion_set.file_paths.length },
'file_paths' => ->(user, suggestion_set) { format_paths(suggestion_set.file_paths) },
- 'project_name' => ->(user, suggestion_set) { suggestion_set.project.name },
- 'project_path' => ->(user, suggestion_set) { suggestion_set.project.path },
+ 'project_name' => ->(user, suggestion_set) { suggestion_set.target_project.name },
+ 'project_path' => ->(user, suggestion_set) { suggestion_set.target_project.path },
'user_full_name' => ->(user, suggestion_set) { user.name },
'username' => ->(user, suggestion_set) { user.username },
'suggestions_count' => ->(user, suggestion_set) { suggestion_set.suggestions.size }
diff --git a/lib/gitlab/suggestions/suggestion_set.rb b/lib/gitlab/suggestions/suggestion_set.rb
index 53885cdbf19..21a5acf8afe 100644
--- a/lib/gitlab/suggestions/suggestion_set.rb
+++ b/lib/gitlab/suggestions/suggestion_set.rb
@@ -9,8 +9,12 @@ module Gitlab
@suggestions = suggestions
end
- def project
- first_suggestion.project
+ def source_project
+ first_suggestion.source_project
+ end
+
+ def target_project
+ first_suggestion.target_project
end
def branch
diff --git a/lib/tasks/gitlab_danger.rake b/lib/tasks/gitlab_danger.rake
deleted file mode 100644
index ff9464a588a..00000000000
--- a/lib/tasks/gitlab_danger.rake
+++ /dev/null
@@ -1,19 +0,0 @@
-# frozen_string_literal: true
-
-desc 'Run local Danger rules'
-task :danger_local do
- require_relative '../../tooling/danger/project_helper'
- require 'gitlab/popen'
-
- puts("#{Tooling::Danger::ProjectHelper.local_warning_message}\n")
-
- # _status will _always_ be 0, regardless of failure or success :(
- output, _status = Gitlab::Popen.popen(%w{danger dry_run})
-
- if output.empty?
- puts(Tooling::Danger::ProjectHelper.success_message)
- else
- puts(output)
- exit(1)
- end
-end
diff --git a/spec/lib/gitlab/background_migration/cleanup_draft_data_from_faulty_regex_spec.rb b/spec/lib/gitlab/background_migration/cleanup_draft_data_from_faulty_regex_spec.rb
new file mode 100644
index 00000000000..50489c26547
--- /dev/null
+++ b/spec/lib/gitlab/background_migration/cleanup_draft_data_from_faulty_regex_spec.rb
@@ -0,0 +1,54 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Gitlab::BackgroundMigration::CleanupDraftDataFromFaultyRegex do
+ let(:namespaces) { table(:namespaces) }
+ let(:projects) { table(:projects) }
+ let(:merge_requests) { table(:merge_requests) }
+
+ let(:group) { namespaces.create!(name: 'gitlab', path: 'gitlab') }
+ let(:project) { projects.create!(namespace_id: group.id) }
+
+ let(:draft_prefixes) { ["[Draft]", "(Draft)", "Draft:", "Draft", "[WIP]", "WIP:", "WIP"] }
+
+ def create_merge_request(params)
+ common_params = {
+ target_project_id: project.id,
+ target_branch: 'feature1',
+ source_branch: 'master'
+ }
+
+ merge_requests.create!(common_params.merge(params))
+ end
+
+ context "mr.draft == true, and title matches the leaky regex and not the corrected regex" do
+ let(:mr_ids) { merge_requests.all.collect(&:id) }
+
+ before do
+ draft_prefixes.each do |prefix|
+ (1..4).each do |n|
+ create_merge_request(
+ title: "#{prefix} This is a title",
+ draft: true,
+ state_id: 1
+ )
+ end
+ end
+
+ create_merge_request(title: "This has draft in the title", draft: true, state_id: 1)
+ end
+
+ it "updates all open draft merge request's draft field to true" do
+ expect { subject.perform(mr_ids.first, mr_ids.last) }
+ .to change { MergeRequest.where(draft: true).count }
+ .by(-1)
+ end
+
+ it "marks successful slices as completed" do
+ expect(subject).to receive(:mark_job_as_succeeded).with(mr_ids.first, mr_ids.last)
+
+ subject.perform(mr_ids.first, mr_ids.last)
+ end
+ end
+end
diff --git a/spec/lib/gitlab/suggestions/commit_message_spec.rb b/spec/lib/gitlab/suggestions/commit_message_spec.rb
index 965960f0c3e..dcadc206715 100644
--- a/spec/lib/gitlab/suggestions/commit_message_spec.rb
+++ b/spec/lib/gitlab/suggestions/commit_message_spec.rb
@@ -3,7 +3,10 @@
require 'spec_helper'
RSpec.describe Gitlab::Suggestions::CommitMessage do
- def create_suggestion(file_path, new_line, to_content)
+ include ProjectForksHelper
+ using RSpec::Parameterized::TableSyntax
+
+ def create_suggestion(merge_request, file_path, new_line, to_content)
position = Gitlab::Diff::Position.new(old_path: file_path,
new_path: file_path,
old_line: nil,
@@ -29,69 +32,111 @@ RSpec.describe Gitlab::Suggestions::CommitMessage do
create(:project, :repository, path: 'project-1', name: 'Project_1')
end
- let_it_be(:merge_request) do
+ let_it_be(:forked_project) { fork_project(project, nil, repository: true) }
+
+ let_it_be(:merge_request_same_project) do
create(:merge_request, source_project: project, target_project: project)
end
- let_it_be(:suggestion_set) do
- suggestion1 = create_suggestion('files/ruby/popen.rb', 9, '*** SUGGESTION 1 ***')
- suggestion2 = create_suggestion('files/ruby/popen.rb', 13, '*** SUGGESTION 2 ***')
- suggestion3 = create_suggestion('files/ruby/regex.rb', 22, '*** SUGGESTION 3 ***')
+ let_it_be(:merge_request_from_fork) do
+ create(:merge_request, source_project: forked_project, target_project: project)
+ end
+
+ let_it_be(:suggestion_set_same_project) do
+ suggestion1 = create_suggestion(merge_request_same_project, 'files/ruby/popen.rb', 9, '*** SUGGESTION 1 ***')
+ suggestion2 = create_suggestion(merge_request_same_project, 'files/ruby/popen.rb', 13, '*** SUGGESTION 2 ***')
+ suggestion3 = create_suggestion(merge_request_same_project, 'files/ruby/regex.rb', 22, '*** SUGGESTION 3 ***')
+
+ Gitlab::Suggestions::SuggestionSet.new([suggestion1, suggestion2, suggestion3])
+ end
+
+ let_it_be(:suggestion_set_forked_project) do
+ suggestion1 = create_suggestion(merge_request_from_fork, 'files/ruby/popen.rb', 9, '*** SUGGESTION 1 ***')
+ suggestion2 = create_suggestion(merge_request_from_fork, 'files/ruby/popen.rb', 13, '*** SUGGESTION 2 ***')
+ suggestion3 = create_suggestion(merge_request_from_fork, 'files/ruby/regex.rb', 22, '*** SUGGESTION 3 ***')
Gitlab::Suggestions::SuggestionSet.new([suggestion1, suggestion2, suggestion3])
end
describe '#message' do
- before do
- # Updating the suggestion_commit_message on a project shared across specs
- # avoids recreating the repository for each spec.
- project.update!(suggestion_commit_message: message)
- end
+ where(:suggestion_set) { [ref(:suggestion_set_same_project), ref(:suggestion_set_forked_project)] }
+
+ with_them do
+ before do
+ # Updating the suggestion_commit_message on a project shared across specs
+ # avoids recreating the repository for each spec.
+ project.update!(suggestion_commit_message: message)
+ forked_project.update!(suggestion_commit_message: fork_message)
+ end
+
+ let(:fork_message) { nil }
- context 'when a custom commit message is not specified' do
- let(:expected_message) { 'Apply 3 suggestion(s) to 2 file(s)' }
+ context 'when a custom commit message is not specified' do
+ let(:expected_message) { 'Apply 3 suggestion(s) to 2 file(s)' }
- context 'and is nil' do
- let(:message) { nil }
+ context 'and is nil' do
+ let(:message) { nil }
- it 'uses the default commit message' do
- expect(described_class
- .new(user, suggestion_set)
- .message).to eq(expected_message)
+ it 'uses the default commit message' do
+ expect(described_class
+ .new(user, suggestion_set)
+ .message).to eq(expected_message)
+ end
end
- end
- context 'and is an empty string' do
- let(:message) { '' }
+ context 'and is an empty string' do
+ let(:message) { '' }
- it 'uses the default commit message' do
- expect(described_class
- .new(user, suggestion_set)
- .message).to eq(expected_message)
+ it 'uses the default commit message' do
+ expect(described_class
+ .new(user, suggestion_set)
+ .message).to eq(expected_message)
+ end
end
- end
- end
- context 'when a custom commit message is specified' do
- let(:message) { "i'm a project message. a user's custom message takes precedence over me :(" }
- let(:custom_message) { "hello there! i'm a cool custom commit message." }
+ context 'when a custom commit message is specified for forked project' do
+ let(:message) { nil }
+ let(:fork_message) { "I'm a sad message that will not be used :(" }
- it 'shows the custom commit message' do
- expect(Gitlab::Suggestions::CommitMessage
- .new(user, suggestion_set, custom_message)
- .message).to eq(custom_message)
+ it 'uses the default commit message' do
+ expect(described_class
+ .new(user, suggestion_set)
+ .message).to eq(expected_message)
+ end
+ end
end
- end
- context 'is specified and includes all placeholders' do
- let(:message) do
- '*** %{branch_name} %{files_count} %{file_paths} %{project_name} %{project_path} %{user_full_name} %{username} %{suggestions_count} ***'
+ context 'when a custom commit message is specified' do
+ let(:message) { "i'm a project message. a user's custom message takes precedence over me :(" }
+ let(:custom_message) { "hello there! i'm a cool custom commit message." }
+
+ it 'shows the custom commit message' do
+ expect(Gitlab::Suggestions::CommitMessage
+ .new(user, suggestion_set, custom_message)
+ .message).to eq(custom_message)
+ end
end
- it 'generates a custom commit message' do
- expect(Gitlab::Suggestions::CommitMessage
- .new(user, suggestion_set)
- .message).to eq('*** master 2 files/ruby/popen.rb, files/ruby/regex.rb Project_1 project-1 Test User test.user 3 ***')
+ context 'is specified and includes all placeholders' do
+ let(:message) do
+ '*** %{branch_name} %{files_count} %{file_paths} %{project_name} %{project_path} %{user_full_name} %{username} %{suggestions_count} ***'
+ end
+
+ it 'generates a custom commit message' do
+ expect(Gitlab::Suggestions::CommitMessage
+ .new(user, suggestion_set)
+ .message).to eq('*** master 2 files/ruby/popen.rb, files/ruby/regex.rb Project_1 project-1 Test User test.user 3 ***')
+ end
+
+ context 'when a custom commit message is specified for forked project' do
+ let(:fork_message) { "I'm a sad message that will not be used :(" }
+
+ it 'uses the target project commit message' do
+ expect(Gitlab::Suggestions::CommitMessage
+ .new(user, suggestion_set)
+ .message).to eq('*** master 2 files/ruby/popen.rb, files/ruby/regex.rb Project_1 project-1 Test User test.user 3 ***')
+ end
+ end
end
end
end
diff --git a/spec/lib/gitlab/suggestions/suggestion_set_spec.rb b/spec/lib/gitlab/suggestions/suggestion_set_spec.rb
index 54d79a9d4ba..469646986e1 100644
--- a/spec/lib/gitlab/suggestions/suggestion_set_spec.rb
+++ b/spec/lib/gitlab/suggestions/suggestion_set_spec.rb
@@ -3,6 +3,9 @@
require 'spec_helper'
RSpec.describe Gitlab::Suggestions::SuggestionSet do
+ include ProjectForksHelper
+ using RSpec::Parameterized::TableSyntax
+
def create_suggestion(file_path, new_line, to_content)
position = Gitlab::Diff::Position.new(old_path: file_path,
new_path: file_path,
@@ -24,86 +27,99 @@ RSpec.describe Gitlab::Suggestions::SuggestionSet do
let_it_be(:user) { create(:user) }
let_it_be(:project) { create(:project, :repository) }
+ let_it_be(:forked_project) { fork_project(project, nil, repository: true) }
- let_it_be(:merge_request) do
+ let_it_be(:merge_request_same_project) do
create(:merge_request, source_project: project, target_project: project)
end
- let_it_be(:suggestion) { create(:suggestion)}
-
- let_it_be(:suggestion2) do
- create_suggestion('files/ruby/popen.rb', 13, "*** SUGGESTION 2 ***")
- end
-
- let_it_be(:suggestion3) do
- create_suggestion('files/ruby/regex.rb', 22, "*** SUGGESTION 3 ***")
+ let_it_be(:merge_request_from_fork) do
+ create(:merge_request, source_project: forked_project, target_project: project)
end
- let_it_be(:unappliable_suggestion) { create(:suggestion, :unappliable) }
+ where(:merge_request) { [ref(:merge_request_same_project), ref(:merge_request_from_fork)] }
+ with_them do
+ let(:note) { create(:diff_note_on_merge_request, project: project, noteable: merge_request) }
+ let(:suggestion) { create(:suggestion, note: note) }
- let(:suggestion_set) { described_class.new([suggestion]) }
-
- describe '#project' do
- it 'returns the project associated with the suggestions' do
- expected_project = suggestion.project
+ let(:suggestion2) do
+ create_suggestion('files/ruby/popen.rb', 13, "*** SUGGESTION 2 ***")
+ end
- expect(suggestion_set.project).to be(expected_project)
+ let(:suggestion3) do
+ create_suggestion('files/ruby/regex.rb', 22, "*** SUGGESTION 3 ***")
end
- end
- describe '#branch' do
- it 'returns the branch associated with the suggestions' do
- expected_branch = suggestion.branch
+ let(:unappliable_suggestion) { create(:suggestion, :unappliable) }
+
+ let(:suggestion_set) { described_class.new([suggestion]) }
- expect(suggestion_set.branch).to be(expected_branch)
+ describe '#source_project' do
+ it 'returns the source project associated with the suggestions' do
+ expect(suggestion_set.source_project).to be(merge_request.source_project)
+ end
end
- end
- describe '#valid?' do
- it 'returns true if no errors are found' do
- expect(suggestion_set.valid?).to be(true)
+ describe '#target_project' do
+ it 'returns the target project associated with the suggestions' do
+ expect(suggestion_set.target_project).to be(project)
+ end
end
- it 'returns false if an error is found' do
- suggestion_set = described_class.new([unappliable_suggestion])
+ describe '#branch' do
+ it 'returns the branch associated with the suggestions' do
+ expected_branch = suggestion.branch
- expect(suggestion_set.valid?).to be(false)
+ expect(suggestion_set.branch).to be(expected_branch)
+ end
end
- end
- describe '#error_message' do
- it 'returns an error message if an error is found' do
- suggestion_set = described_class.new([unappliable_suggestion])
+ describe '#valid?' do
+ it 'returns true if no errors are found' do
+ expect(suggestion_set.valid?).to be(true)
+ end
- expect(suggestion_set.error_message).to be_a(String)
+ it 'returns false if an error is found' do
+ suggestion_set = described_class.new([unappliable_suggestion])
+
+ expect(suggestion_set.valid?).to be(false)
+ end
end
- it 'returns nil if no errors are found' do
- expect(suggestion_set.error_message).to be(nil)
+ describe '#error_message' do
+ it 'returns an error message if an error is found' do
+ suggestion_set = described_class.new([unappliable_suggestion])
+
+ expect(suggestion_set.error_message).to be_a(String)
+ end
+
+ it 'returns nil if no errors are found' do
+ expect(suggestion_set.error_message).to be(nil)
+ end
end
- end
- describe '#actions' do
- it 'returns an array of hashes with proper key/value pairs' do
- first_action = suggestion_set.actions.first
+ describe '#actions' do
+ it 'returns an array of hashes with proper key/value pairs' do
+ first_action = suggestion_set.actions.first
- file_suggestion = suggestion_set.send(:suggestions_per_file).first
+ file_suggestion = suggestion_set.send(:suggestions_per_file).first
- expect(first_action[:action]).to be('update')
- expect(first_action[:file_path]).to eq(file_suggestion.file_path)
- expect(first_action[:content]).to eq(file_suggestion.new_content)
+ expect(first_action[:action]).to be('update')
+ expect(first_action[:file_path]).to eq(file_suggestion.file_path)
+ expect(first_action[:content]).to eq(file_suggestion.new_content)
+ end
end
- end
- describe '#file_paths' do
- it 'returns an array of unique file paths associated with the suggestions' do
- suggestion_set = described_class.new([suggestion, suggestion2, suggestion3])
+ describe '#file_paths' do
+ it 'returns an array of unique file paths associated with the suggestions' do
+ suggestion_set = described_class.new([suggestion, suggestion2, suggestion3])
- expected_paths = %w(files/ruby/popen.rb files/ruby/regex.rb)
+ expected_paths = %w(files/ruby/popen.rb files/ruby/regex.rb)
- actual_paths = suggestion_set.file_paths
+ actual_paths = suggestion_set.file_paths
- expect(actual_paths.sort).to eq(expected_paths)
+ expect(actual_paths.sort).to eq(expected_paths)
+ end
end
end
end
diff --git a/spec/migrations/20220315171129_cleanup_draft_data_from_faulty_regex_spec.rb b/spec/migrations/20220315171129_cleanup_draft_data_from_faulty_regex_spec.rb
new file mode 100644
index 00000000000..925f1e573be
--- /dev/null
+++ b/spec/migrations/20220315171129_cleanup_draft_data_from_faulty_regex_spec.rb
@@ -0,0 +1,40 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require_migration!
+
+RSpec.describe CleanupDraftDataFromFaultyRegex do
+ let(:merge_requests) { table(:merge_requests) }
+
+ let!(:namespace) { table(:namespaces).create!(name: 'namespace', path: 'namespace') }
+ let!(:project) { table(:projects).create!(namespace_id: namespace.id) }
+
+ let(:default_mr_values) do
+ {
+ target_project_id: project.id,
+ draft: true,
+ source_branch: 'master',
+ target_branch: 'feature'
+ }
+ end
+
+ let!(:known_good_1) { merge_requests.create!(default_mr_values.merge(title: "Draft: Test Title")) }
+ let!(:known_good_2) { merge_requests.create!(default_mr_values.merge(title: "WIP: Test Title")) }
+ let!(:known_bad_1) { merge_requests.create!(default_mr_values.merge(title: "Known bad title drafts")) }
+ let!(:known_bad_2) { merge_requests.create!(default_mr_values.merge(title: "Known bad title wip")) }
+
+ describe '#up' do
+ it 'schedules CleanupDraftDataFromFaultyRegex background jobs filtering for eligble MRs' do
+ stub_const("#{described_class}::BATCH_SIZE", 2)
+ allow(Gitlab).to receive(:com?).and_return(true)
+
+ freeze_time do
+ migrate!
+
+ expect(described_class::MIGRATION).to be_scheduled_delayed_migration(5.minutes, known_bad_1.id, known_bad_2.id)
+
+ expect(BackgroundMigrationWorker.jobs.size).to eq(1)
+ end
+ end
+ end
+end
diff --git a/spec/tooling/danger/project_helper_spec.rb b/spec/tooling/danger/project_helper_spec.rb
index 902e01e2cbd..b3fb592c2e3 100644
--- a/spec/tooling/danger/project_helper_spec.rb
+++ b/spec/tooling/danger/project_helper_spec.rb
@@ -276,40 +276,6 @@ RSpec.describe Tooling::Danger::ProjectHelper do
end
end
- describe '.local_warning_message' do
- it 'returns an informational message with rules that can run' do
- expect(described_class.local_warning_message).to eq('==> Only the following Danger rules can be run locally: ci_config, database, documentation, duplicate_yarn_dependencies, eslint, gitaly, pajamas, pipeline, prettier, product_intelligence, utility_css, vue_shared_documentation, datateam')
- end
- end
-
- describe '.success_message' do
- it 'returns an informational success message' do
- expect(described_class.success_message).to eq('==> No Danger rule violations!')
- end
- end
-
- describe '#rule_names' do
- context 'when running locally' do
- before do
- expect(fake_helper).to receive(:ci?).and_return(false)
- end
-
- it 'returns local only rules' do
- expect(project_helper.rule_names).to match_array(described_class::LOCAL_RULES)
- end
- end
-
- context 'when running under CI' do
- before do
- expect(fake_helper).to receive(:ci?).and_return(true)
- end
-
- it 'returns all rules' do
- expect(project_helper.rule_names).to eq(described_class::LOCAL_RULES | described_class::CI_ONLY_RULES)
- end
- end
- end
-
describe '#file_lines' do
let(:filename) { 'spec/foo_spec.rb' }
let(:file_spy) { spy }
diff --git a/tooling/danger/project_helper.rb b/tooling/danger/project_helper.rb
index 02002e1d1b2..fc87498f5d0 100644
--- a/tooling/danger/project_helper.rb
+++ b/tooling/danger/project_helper.rb
@@ -3,22 +3,6 @@
module Tooling
module Danger
module ProjectHelper
- LOCAL_RULES ||= %w[
- ci_config
- database
- documentation
- duplicate_yarn_dependencies
- eslint
- gitaly
- pajamas
- pipeline
- prettier
- product_intelligence
- utility_css
- vue_shared_documentation
- datateam
- ].freeze
-
CI_ONLY_RULES ||= %w[
ce_ee_vue_templates
ci_templates
@@ -31,8 +15,6 @@ module Tooling
z_metadata
].freeze
- MESSAGE_PREFIX = '==>'
-
# First-match win, so be sure to put more specific regex at the top...
CATEGORIES = {
[%r{usage_data\.rb}, %r{^(\+|-).*\s+(count|distinct_count|estimate_batch_distinct_count)\(.*\)(.*)$}] => [:database, :backend, :product_intelligence],
@@ -181,20 +163,6 @@ module Tooling
%r{\.js\z} => :frontend
}.freeze
- def local_warning_message
- "#{MESSAGE_PREFIX} Only the following Danger rules can be run locally: #{LOCAL_RULES.join(', ')}"
- end
- module_function :local_warning_message # rubocop:disable Style/AccessModifierDeclarations
-
- def success_message
- "#{MESSAGE_PREFIX} No Danger rule violations!"
- end
- module_function :success_message # rubocop:disable Style/AccessModifierDeclarations
-
- def rule_names
- helper.ci? ? LOCAL_RULES | CI_ONLY_RULES : LOCAL_RULES
- end
-
def file_lines(filename)
read_file(filename).lines(chomp: true)
end