Add latest changes from gitlab-org/gitlab@master
This commit is contained in:
parent
bbc06065aa
commit
179b33c546
|
|
@ -335,10 +335,13 @@ bundle-size-review:
|
||||||
stage: test
|
stage: test
|
||||||
needs: ["compile-production-assets"]
|
needs: ["compile-production-assets"]
|
||||||
script:
|
script:
|
||||||
|
- source scripts/utils.sh
|
||||||
- mkdir -p bundle-size-review
|
- mkdir -p bundle-size-review
|
||||||
- cp webpack-report/index.html bundle-size-review/bundle-report.html
|
- 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
|
- 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:
|
artifacts:
|
||||||
when: always
|
when: always
|
||||||
name: bundle-size-review
|
name: bundle-size-review
|
||||||
|
|
|
||||||
12
Dangerfile
12
Dangerfile
|
|
@ -11,16 +11,8 @@ project_name = ee? ? 'gitlab' : 'gitlab-foss'
|
||||||
|
|
||||||
Gitlab::Dangerfiles.for_project(self, project_name) do |gitlab_dangerfiles|
|
Gitlab::Dangerfiles.for_project(self, project_name) do |gitlab_dangerfiles|
|
||||||
gitlab_dangerfiles.import_plugins
|
gitlab_dangerfiles.import_plugins
|
||||||
|
gitlab_dangerfiles.config.ci_only_rules = ProjectHelper::CI_ONLY_RULES
|
||||||
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
|
gitlab_dangerfiles.config.files_to_category = ProjectHelper::CATEGORIES
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
return if helper.release_automation?
|
gitlab_dangerfiles.import_dangerfiles(except: %w[simple_roulette])
|
||||||
|
|
||||||
project_helper.rule_names.each do |rule|
|
|
||||||
danger.import_dangerfile(path: File.join('danger', rule))
|
|
||||||
end
|
end
|
||||||
|
|
|
||||||
2
Gemfile
2
Gemfile
|
|
@ -403,7 +403,7 @@ group :development, :test do
|
||||||
end
|
end
|
||||||
|
|
||||||
group :development, :test, :danger do
|
group :development, :test, :danger do
|
||||||
gem 'gitlab-dangerfiles', '~> 2.11.0', require: false
|
gem 'gitlab-dangerfiles', '~> 3.0', require: false
|
||||||
end
|
end
|
||||||
|
|
||||||
group :development, :test, :coverage do
|
group :development, :test, :coverage do
|
||||||
|
|
|
||||||
|
|
@ -224,7 +224,7 @@ GEM
|
||||||
css_parser (1.7.0)
|
css_parser (1.7.0)
|
||||||
addressable
|
addressable
|
||||||
daemons (1.3.1)
|
daemons (1.3.1)
|
||||||
danger (8.4.5)
|
danger (8.5.0)
|
||||||
claide (~> 1.0)
|
claide (~> 1.0)
|
||||||
claide-plugins (>= 0.9.2)
|
claide-plugins (>= 0.9.2)
|
||||||
colored2 (~> 3.1)
|
colored2 (~> 3.1)
|
||||||
|
|
@ -463,9 +463,10 @@ GEM
|
||||||
terminal-table (~> 1.5, >= 1.5.1)
|
terminal-table (~> 1.5, >= 1.5.1)
|
||||||
gitlab-chronic (0.10.5)
|
gitlab-chronic (0.10.5)
|
||||||
numerizer (~> 0.2)
|
numerizer (~> 0.2)
|
||||||
gitlab-dangerfiles (2.11.0)
|
gitlab-dangerfiles (3.0.0)
|
||||||
danger (>= 8.4.5)
|
danger (>= 8.4.5)
|
||||||
danger-gitlab (>= 8.0.0)
|
danger-gitlab (>= 8.0.0)
|
||||||
|
rake
|
||||||
gitlab-experiment (0.7.0)
|
gitlab-experiment (0.7.0)
|
||||||
activesupport (>= 3.0)
|
activesupport (>= 3.0)
|
||||||
request_store (>= 1.0)
|
request_store (>= 1.0)
|
||||||
|
|
@ -1494,7 +1495,7 @@ DEPENDENCIES
|
||||||
gitaly (~> 14.9.0.pre.rc4)
|
gitaly (~> 14.9.0.pre.rc4)
|
||||||
github-markup (~> 1.7.0)
|
github-markup (~> 1.7.0)
|
||||||
gitlab-chronic (~> 0.10.5)
|
gitlab-chronic (~> 0.10.5)
|
||||||
gitlab-dangerfiles (~> 2.11.0)
|
gitlab-dangerfiles (~> 3.0)
|
||||||
gitlab-experiment (~> 0.7.0)
|
gitlab-experiment (~> 0.7.0)
|
||||||
gitlab-fog-azure-rm (~> 1.2.0)
|
gitlab-fog-azure-rm (~> 1.2.0)
|
||||||
gitlab-labkit (~> 0.22.0)
|
gitlab-labkit (~> 0.22.0)
|
||||||
|
|
|
||||||
3
Rakefile
3
Rakefile
|
|
@ -16,3 +16,6 @@ require File.expand_path('config/initializers/01_active_record_database_tasks_co
|
||||||
Gitlab::Application.load_tasks
|
Gitlab::Application.load_tasks
|
||||||
|
|
||||||
Knapsack.load_tasks if defined?(Knapsack)
|
Knapsack.load_tasks if defined?(Knapsack)
|
||||||
|
|
||||||
|
require 'gitlab-dangerfiles'
|
||||||
|
Gitlab::Dangerfiles.load_tasks
|
||||||
|
|
|
||||||
|
|
@ -37,9 +37,6 @@ class Oauth::AuthorizationsController < Doorkeeper::AuthorizationsController
|
||||||
|
|
||||||
# limit scopes when signing in with GitLab
|
# limit scopes when signing in with GitLab
|
||||||
def downgrade_scopes!
|
def downgrade_scopes!
|
||||||
return unless Feature.enabled?(:omniauth_login_minimal_scopes, current_user,
|
|
||||||
default_enabled: :yaml)
|
|
||||||
|
|
||||||
auth_type = params.delete('gl_auth_type')
|
auth_type = params.delete('gl_auth_type')
|
||||||
return unless auth_type == 'login'
|
return unless auth_type == 'login'
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -83,17 +83,9 @@ module WebpackHelper
|
||||||
end
|
end
|
||||||
|
|
||||||
def webpack_public_host
|
def webpack_public_host
|
||||||
# We do not proxy the webpack output in the 'test' environment,
|
# We proxy webpack output in 'test' and 'dev' environment, so we can just use asset_host
|
||||||
# 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, '/')
|
ActionController::Base.asset_host.try(:chomp, '/')
|
||||||
end
|
end
|
||||||
end
|
|
||||||
|
|
||||||
def webpack_public_path
|
def webpack_public_path
|
||||||
relative_path = Gitlab.config.gitlab.relative_url_root
|
relative_path = Gitlab.config.gitlab.relative_url_root
|
||||||
|
|
|
||||||
|
|
@ -16,10 +16,14 @@ class Suggestion < ApplicationRecord
|
||||||
note.latest_diff_file
|
note.latest_diff_file
|
||||||
end
|
end
|
||||||
|
|
||||||
def project
|
def source_project
|
||||||
noteable.source_project
|
noteable.source_project
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def target_project
|
||||||
|
noteable.target_project
|
||||||
|
end
|
||||||
|
|
||||||
def branch
|
def branch
|
||||||
noteable.source_branch
|
noteable.source_branch
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,10 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
class SuggestionPolicy < BasePolicy
|
class SuggestionPolicy < BasePolicy
|
||||||
delegate { @subject.project }
|
delegate { @subject.source_project }
|
||||||
|
|
||||||
condition(:can_push_to_branch) do
|
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
|
end
|
||||||
|
|
||||||
rule { can_push_to_branch }.enable :apply_suggestion
|
rule { can_push_to_branch }.enable :apply_suggestion
|
||||||
|
|
|
||||||
|
|
@ -54,7 +54,7 @@ module Suggestions
|
||||||
author_email: author&.email
|
author_email: author&.email
|
||||||
}
|
}
|
||||||
|
|
||||||
::Files::MultiService.new(suggestion_set.project, current_user, params)
|
::Files::MultiService.new(suggestion_set.source_project, current_user, params)
|
||||||
end
|
end
|
||||||
|
|
||||||
def commit_message
|
def commit_message
|
||||||
|
|
|
||||||
|
|
@ -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
|
|
||||||
|
|
@ -21,7 +21,7 @@ if app.config.public_file_server.enabled
|
||||||
|
|
||||||
# If webpack-dev-server is configured, proxy webpack's public directory
|
# If webpack-dev-server is configured, proxy webpack's public directory
|
||||||
# instead of looking for static assets
|
# 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(
|
app.config.middleware.insert_before(
|
||||||
Gitlab::Middleware::Static,
|
Gitlab::Middleware::Static,
|
||||||
Gitlab::Webpack::DevServerMiddleware,
|
Gitlab::Webpack::DevServerMiddleware,
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
# frozen_string_literal: true
|
# 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"
|
analysis_result = "./bundle-size-review/analysis.json"
|
||||||
markdown_result = "./bundle-size-review/comparison.md"
|
markdown_result = "./bundle-size-review/comparison.md"
|
||||||
|
|
@ -19,7 +19,7 @@ return unless helper.ci?
|
||||||
|
|
||||||
template_paths_to_review = helper.changes_by_category[:ci_template]
|
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 ' \
|
message 'This merge request adds or changes files that require a ' \
|
||||||
'review from the CI/CD Templates maintainers.'
|
'review from the CI/CD Templates maintainers.'
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -49,11 +49,11 @@ if geo_migration_created && !geo_db_schema_updated
|
||||||
end
|
end
|
||||||
|
|
||||||
return unless helper.ci?
|
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]
|
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 ' \
|
message 'This merge request adds or changes files that require a ' \
|
||||||
'review from the [Database team](https://gitlab.com/groups/gl-database/-/group_members).'
|
'review from the [Database team](https://gitlab.com/groups/gl-database/-/group_members).'
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -22,21 +22,21 @@ def check_feature_flag_yaml(feature_flag)
|
||||||
end
|
end
|
||||||
rescue Psych::Exception
|
rescue Psych::Exception
|
||||||
# YAML could not be parsed, fail the build.
|
# 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
|
rescue StandardError => e
|
||||||
warn "There was a problem trying to check the Feature Flag file. Exception: #{e.class.name} - #{e.message}"
|
warn "There was a problem trying to check the Feature Flag file. Exception: #{e.class.name} - #{e.message}"
|
||||||
end
|
end
|
||||||
|
|
||||||
def message_for_feature_flag_missing_group!(feature_flag:, mr_group_label:)
|
def message_for_feature_flag_missing_group!(feature_flag:, mr_group_label:)
|
||||||
if mr_group_label.nil?
|
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
|
else
|
||||||
mr_line = feature_flag.raw.lines.find_index("group:\n")
|
mr_line = feature_flag.raw.lines.find_index("group:\n")
|
||||||
|
|
||||||
if mr_line
|
if mr_line
|
||||||
markdown(format(SUGGEST_MR_COMMENT, group: mr_group_label), file: feature_flag.path, line: mr_line.succ)
|
markdown(format(SUGGEST_MR_COMMENT, group: mr_group_label), file: feature_flag.path, line: mr_line.succ)
|
||||||
else
|
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
|
end
|
||||||
end
|
end
|
||||||
|
|
@ -60,7 +60,7 @@ def message_for_feature_flag_with_group!(feature_flag:, mr_group_label:)
|
||||||
if mr_group_label.nil?
|
if mr_group_label.nil?
|
||||||
helper.labels_to_add << feature_flag.group
|
helper.labels_to_add << feature_flag.group
|
||||||
else
|
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
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -16,11 +16,11 @@ SPECIALIZATIONS = {
|
||||||
labels_to_add = helper.changes_by_category.each_with_object([]) do |(category, _changes), memo|
|
labels_to_add = helper.changes_by_category.each_with_object([]) do |(category, _changes), memo|
|
||||||
label = SPECIALIZATIONS[category]
|
label = SPECIALIZATIONS[category]
|
||||||
next unless label
|
next unless label
|
||||||
next if gitlab.mr_labels.include?(label)
|
next if helper.mr_labels.include?(label)
|
||||||
|
|
||||||
# Don't override already-set scoped labels.
|
# Don't override already-set scoped labels.
|
||||||
label_scope = label.split('::')[0...-1].join('::')
|
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
|
memo << label
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -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)
|
spec_changes = specs.changed_specs_files(ee: :exclude)
|
||||||
has_spec_changes = spec_changes.any?
|
has_spec_changes = spec_changes.any?
|
||||||
has_ee_spec_changes = specs.changed_specs_files(ee: :only).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
|
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
|
warn format(NO_NEW_SPEC_MESSAGE, labels: helper.labels_list(NO_SPECS_LABELS)), sticky: false
|
||||||
|
|
|
||||||
|
|
@ -14,12 +14,12 @@ end
|
||||||
|
|
||||||
has_milestone = !gitlab.mr_json["milestone"].nil?
|
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
|
warn "This merge request does not refer to an existing milestone.", sticky: false
|
||||||
end
|
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."
|
warn "Most of the time, merge requests should target `#{DEFAULT_BRANCH}`. Otherwise, please set the relevant `Pick into X.Y` label."
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
@ -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
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
4c329622299c76ca753381f1ccc0686714d07eeee8acfc834e576d5a5addaafc
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
7ca832e710026c0721ecdcd50b477073aeaf7cb795c50acd604897f85707b163
|
||||||
|
|
@ -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_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_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[]));
|
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[]));
|
||||||
|
|
|
||||||
|
|
@ -3236,6 +3236,10 @@ Input type: `iterationCreateInput`
|
||||||
|
|
||||||
### `Mutation.iterationDelete`
|
### `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`
|
Input type: `IterationDeleteInput`
|
||||||
|
|
||||||
#### Arguments
|
#### Arguments
|
||||||
|
|
|
||||||
|
|
@ -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**.
|
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))
|
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
|
## 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))
|
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
|
## dropdown list
|
||||||
|
|
||||||
Use **dropdown list** to refer to the UI element. Do not use **dropdown** without **list** after it.
|
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).
|
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
|
## 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).
|
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.
|
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
|
## 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))
|
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))
|
||||||
|
|
|
||||||
|
|
@ -117,10 +117,9 @@ signed in.
|
||||||
|
|
||||||
## Reduce access privileges on sign 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.
|
> - [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.
|
||||||
FLAG:
|
> - [Feature flag `omniauth_login_minimal_scopes`](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/83453) removed in GitLab 14.10
|
||||||
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.
|
|
||||||
|
|
||||||
If you use a GitLab instance for authentication, you can reduce access rights when an OAuth application is used for sign in.
|
If you use a GitLab instance for authentication, you can reduce access rights when an OAuth application is used for sign in.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -108,6 +108,8 @@ For example, to customize the commit message to output
|
||||||
**Addresses user_1's review**, set the custom text to
|
**Addresses user_1's review**, set the custom text to
|
||||||
`Addresses %{username}'s review`.
|
`Addresses %{username}'s review`.
|
||||||
|
|
||||||
|
For merge requests created from forks, GitLab uses the template defined in target project.
|
||||||
|
|
||||||
NOTE:
|
NOTE:
|
||||||
Custom commit messages for each applied suggestion is
|
Custom commit messages for each applied suggestion is
|
||||||
introduced by [#25381](https://gitlab.com/gitlab-org/gitlab/-/issues/25381).
|
introduced by [#25381](https://gitlab.com/gitlab-org/gitlab/-/issues/25381).
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ pre-push:
|
||||||
parallel: true
|
parallel: true
|
||||||
commands:
|
commands:
|
||||||
danger:
|
danger:
|
||||||
run: CI_PROJECT_DIR=. bundle exec danger dry_run
|
run: bundle exec rake danger_local
|
||||||
eslint:
|
eslint:
|
||||||
tags: frontend style
|
tags: frontend style
|
||||||
files: git diff --name-only --diff-filter=d $(git merge-base origin/master HEAD)..HEAD
|
files: git diff --name-only --diff-filter=d $(git merge-base origin/master HEAD)..HEAD
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
@ -13,7 +13,7 @@ module Gitlab
|
||||||
end
|
end
|
||||||
|
|
||||||
def message
|
def message
|
||||||
project = suggestion_set.project
|
project = suggestion_set.target_project
|
||||||
user_defined_message = @custom_message.presence || project.suggestion_commit_message.presence
|
user_defined_message = @custom_message.presence || project.suggestion_commit_message.presence
|
||||||
message = user_defined_message || DEFAULT_SUGGESTION_COMMIT_MESSAGE
|
message = user_defined_message || DEFAULT_SUGGESTION_COMMIT_MESSAGE
|
||||||
|
|
||||||
|
|
@ -37,8 +37,8 @@ module Gitlab
|
||||||
'branch_name' => ->(user, suggestion_set) { suggestion_set.branch },
|
'branch_name' => ->(user, suggestion_set) { suggestion_set.branch },
|
||||||
'files_count' => ->(user, suggestion_set) { suggestion_set.file_paths.length },
|
'files_count' => ->(user, suggestion_set) { suggestion_set.file_paths.length },
|
||||||
'file_paths' => ->(user, suggestion_set) { format_paths(suggestion_set.file_paths) },
|
'file_paths' => ->(user, suggestion_set) { format_paths(suggestion_set.file_paths) },
|
||||||
'project_name' => ->(user, suggestion_set) { suggestion_set.project.name },
|
'project_name' => ->(user, suggestion_set) { suggestion_set.target_project.name },
|
||||||
'project_path' => ->(user, suggestion_set) { suggestion_set.project.path },
|
'project_path' => ->(user, suggestion_set) { suggestion_set.target_project.path },
|
||||||
'user_full_name' => ->(user, suggestion_set) { user.name },
|
'user_full_name' => ->(user, suggestion_set) { user.name },
|
||||||
'username' => ->(user, suggestion_set) { user.username },
|
'username' => ->(user, suggestion_set) { user.username },
|
||||||
'suggestions_count' => ->(user, suggestion_set) { suggestion_set.suggestions.size }
|
'suggestions_count' => ->(user, suggestion_set) { suggestion_set.suggestions.size }
|
||||||
|
|
|
||||||
|
|
@ -9,8 +9,12 @@ module Gitlab
|
||||||
@suggestions = suggestions
|
@suggestions = suggestions
|
||||||
end
|
end
|
||||||
|
|
||||||
def project
|
def source_project
|
||||||
first_suggestion.project
|
first_suggestion.source_project
|
||||||
|
end
|
||||||
|
|
||||||
|
def target_project
|
||||||
|
first_suggestion.target_project
|
||||||
end
|
end
|
||||||
|
|
||||||
def branch
|
def branch
|
||||||
|
|
|
||||||
|
|
@ -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
|
|
||||||
|
|
@ -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
|
||||||
|
|
@ -3,7 +3,10 @@
|
||||||
require 'spec_helper'
|
require 'spec_helper'
|
||||||
|
|
||||||
RSpec.describe Gitlab::Suggestions::CommitMessage do
|
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,
|
position = Gitlab::Diff::Position.new(old_path: file_path,
|
||||||
new_path: file_path,
|
new_path: file_path,
|
||||||
old_line: nil,
|
old_line: nil,
|
||||||
|
|
@ -29,25 +32,45 @@ RSpec.describe Gitlab::Suggestions::CommitMessage do
|
||||||
create(:project, :repository, path: 'project-1', name: 'Project_1')
|
create(:project, :repository, path: 'project-1', name: 'Project_1')
|
||||||
end
|
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)
|
create(:merge_request, source_project: project, target_project: project)
|
||||||
end
|
end
|
||||||
|
|
||||||
let_it_be(:suggestion_set) do
|
let_it_be(:merge_request_from_fork) do
|
||||||
suggestion1 = create_suggestion('files/ruby/popen.rb', 9, '*** SUGGESTION 1 ***')
|
create(:merge_request, source_project: forked_project, target_project: project)
|
||||||
suggestion2 = create_suggestion('files/ruby/popen.rb', 13, '*** SUGGESTION 2 ***')
|
end
|
||||||
suggestion3 = create_suggestion('files/ruby/regex.rb', 22, '*** SUGGESTION 3 ***')
|
|
||||||
|
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])
|
Gitlab::Suggestions::SuggestionSet.new([suggestion1, suggestion2, suggestion3])
|
||||||
end
|
end
|
||||||
|
|
||||||
describe '#message' do
|
describe '#message' do
|
||||||
|
where(:suggestion_set) { [ref(:suggestion_set_same_project), ref(:suggestion_set_forked_project)] }
|
||||||
|
|
||||||
|
with_them do
|
||||||
before do
|
before do
|
||||||
# Updating the suggestion_commit_message on a project shared across specs
|
# Updating the suggestion_commit_message on a project shared across specs
|
||||||
# avoids recreating the repository for each spec.
|
# avoids recreating the repository for each spec.
|
||||||
project.update!(suggestion_commit_message: message)
|
project.update!(suggestion_commit_message: message)
|
||||||
|
forked_project.update!(suggestion_commit_message: fork_message)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
let(:fork_message) { nil }
|
||||||
|
|
||||||
context 'when a custom commit message is not specified' do
|
context 'when a custom commit message is not specified' do
|
||||||
let(:expected_message) { 'Apply 3 suggestion(s) to 2 file(s)' }
|
let(:expected_message) { 'Apply 3 suggestion(s) to 2 file(s)' }
|
||||||
|
|
||||||
|
|
@ -70,6 +93,17 @@ RSpec.describe Gitlab::Suggestions::CommitMessage do
|
||||||
.message).to eq(expected_message)
|
.message).to eq(expected_message)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
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 '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
|
context 'when a custom commit message is specified' do
|
||||||
|
|
@ -93,6 +127,17 @@ RSpec.describe Gitlab::Suggestions::CommitMessage do
|
||||||
.new(user, suggestion_set)
|
.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 ***')
|
.message).to eq('*** master 2 files/ruby/popen.rb, files/ruby/regex.rb Project_1 project-1 Test User test.user 3 ***')
|
||||||
end
|
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
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,9 @@
|
||||||
require 'spec_helper'
|
require 'spec_helper'
|
||||||
|
|
||||||
RSpec.describe Gitlab::Suggestions::SuggestionSet do
|
RSpec.describe Gitlab::Suggestions::SuggestionSet do
|
||||||
|
include ProjectForksHelper
|
||||||
|
using RSpec::Parameterized::TableSyntax
|
||||||
|
|
||||||
def create_suggestion(file_path, new_line, to_content)
|
def create_suggestion(file_path, new_line, to_content)
|
||||||
position = Gitlab::Diff::Position.new(old_path: file_path,
|
position = Gitlab::Diff::Position.new(old_path: file_path,
|
||||||
new_path: file_path,
|
new_path: file_path,
|
||||||
|
|
@ -24,30 +27,42 @@ RSpec.describe Gitlab::Suggestions::SuggestionSet do
|
||||||
let_it_be(:user) { create(:user) }
|
let_it_be(:user) { create(:user) }
|
||||||
|
|
||||||
let_it_be(:project) { create(:project, :repository) }
|
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)
|
create(:merge_request, source_project: project, target_project: project)
|
||||||
end
|
end
|
||||||
|
|
||||||
let_it_be(:suggestion) { create(:suggestion)}
|
let_it_be(:merge_request_from_fork) do
|
||||||
|
create(:merge_request, source_project: forked_project, target_project: project)
|
||||||
|
end
|
||||||
|
|
||||||
let_it_be(:suggestion2) do
|
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(:suggestion2) do
|
||||||
create_suggestion('files/ruby/popen.rb', 13, "*** SUGGESTION 2 ***")
|
create_suggestion('files/ruby/popen.rb', 13, "*** SUGGESTION 2 ***")
|
||||||
end
|
end
|
||||||
|
|
||||||
let_it_be(:suggestion3) do
|
let(:suggestion3) do
|
||||||
create_suggestion('files/ruby/regex.rb', 22, "*** SUGGESTION 3 ***")
|
create_suggestion('files/ruby/regex.rb', 22, "*** SUGGESTION 3 ***")
|
||||||
end
|
end
|
||||||
|
|
||||||
let_it_be(:unappliable_suggestion) { create(:suggestion, :unappliable) }
|
let(:unappliable_suggestion) { create(:suggestion, :unappliable) }
|
||||||
|
|
||||||
let(:suggestion_set) { described_class.new([suggestion]) }
|
let(:suggestion_set) { described_class.new([suggestion]) }
|
||||||
|
|
||||||
describe '#project' do
|
describe '#source_project' do
|
||||||
it 'returns the project associated with the suggestions' do
|
it 'returns the source project associated with the suggestions' do
|
||||||
expected_project = suggestion.project
|
expect(suggestion_set.source_project).to be(merge_request.source_project)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
expect(suggestion_set.project).to be(expected_project)
|
describe '#target_project' do
|
||||||
|
it 'returns the target project associated with the suggestions' do
|
||||||
|
expect(suggestion_set.target_project).to be(project)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
@ -107,3 +122,4 @@ RSpec.describe Gitlab::Suggestions::SuggestionSet do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
@ -276,40 +276,6 @@ RSpec.describe Tooling::Danger::ProjectHelper do
|
||||||
end
|
end
|
||||||
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
|
describe '#file_lines' do
|
||||||
let(:filename) { 'spec/foo_spec.rb' }
|
let(:filename) { 'spec/foo_spec.rb' }
|
||||||
let(:file_spy) { spy }
|
let(:file_spy) { spy }
|
||||||
|
|
|
||||||
|
|
@ -3,22 +3,6 @@
|
||||||
module Tooling
|
module Tooling
|
||||||
module Danger
|
module Danger
|
||||||
module ProjectHelper
|
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[
|
CI_ONLY_RULES ||= %w[
|
||||||
ce_ee_vue_templates
|
ce_ee_vue_templates
|
||||||
ci_templates
|
ci_templates
|
||||||
|
|
@ -31,8 +15,6 @@ module Tooling
|
||||||
z_metadata
|
z_metadata
|
||||||
].freeze
|
].freeze
|
||||||
|
|
||||||
MESSAGE_PREFIX = '==>'
|
|
||||||
|
|
||||||
# First-match win, so be sure to put more specific regex at the top...
|
# First-match win, so be sure to put more specific regex at the top...
|
||||||
CATEGORIES = {
|
CATEGORIES = {
|
||||||
[%r{usage_data\.rb}, %r{^(\+|-).*\s+(count|distinct_count|estimate_batch_distinct_count)\(.*\)(.*)$}] => [:database, :backend, :product_intelligence],
|
[%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
|
%r{\.js\z} => :frontend
|
||||||
}.freeze
|
}.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)
|
def file_lines(filename)
|
||||||
read_file(filename).lines(chomp: true)
|
read_file(filename).lines(chomp: true)
|
||||||
end
|
end
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue