gitlab-dangerfiles 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,37 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Danger
4
- # Common helper functions for our danger scripts. See Danger::Helper
5
- # for more details
6
- class SidekiqQueues < Danger::Plugin
7
- def changed_queue_files
8
- @changed_queue_files ||= git.modified_files.grep(%r{\A(ee/)?app/workers/all_queues\.yml})
9
- end
10
-
11
- def added_queue_names
12
- @added_queue_names ||= new_queues.keys - old_queues.keys
13
- end
14
-
15
- def changed_queue_names
16
- @changed_queue_names ||=
17
- (new_queues.values_at(*old_queues.keys) - old_queues.values)
18
- .compact.map { |queue| queue[:name] }
19
- end
20
-
21
- private
22
-
23
- def old_queues
24
- @old_queues ||= queues_for(gitlab.base_commit)
25
- end
26
-
27
- def new_queues
28
- @new_queues ||= queues_for(gitlab.head_commit)
29
- end
30
-
31
- def queues_for(branch)
32
- changed_queue_files
33
- .flat_map { |file| YAML.safe_load(`git show #{branch}:#{file}`, permitted_classes: [Symbol]) }
34
- .to_h { |queue| [queue[:name], queue] }
35
- end
36
- end
37
- end
@@ -1,38 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- analysis_result = "./bundle-size-review/analysis.json"
4
- markdown_result = "./bundle-size-review/comparison.md"
5
-
6
- # Executing the webpack-entry-point-analyser
7
- # We would like to do that in the CI file directly,
8
- # but unfortunately the head_commit SHA is not available
9
- # as a CI variable due to our merge into master simulation
10
- analyze_cmd = [
11
- "webpack-entry-point-analyser",
12
- "--from-file ./webpack-report/stats.json",
13
- "--json #{analysis_result}",
14
- " --sha #{gitlab&.head_commit}"
15
- ].join(" ")
16
-
17
- # execute analysis
18
- `#{analyze_cmd}`
19
-
20
- # We are executing the comparison by comparing the start_sha
21
- # to the current pipeline result. The start_sha is the commit
22
- # from master that was merged into for the merged pipeline.
23
- comparison_cmd = [
24
- "webpack-compare-reports",
25
- "--job #{ENV["CI_JOB_ID"]}",
26
- "--to-file #{analysis_result}",
27
- "--html ./bundle-size-review/comparison.html",
28
- "--markdown #{markdown_result}"
29
- ].join(" ")
30
-
31
- # execute comparison
32
- `#{comparison_cmd}`
33
-
34
- comment = `cat #{markdown_result}`
35
-
36
- markdown(<<~MARKDOWN)
37
- #{comment}
38
- MARKDOWN
@@ -1,56 +0,0 @@
1
- # frozen_string_literal: true
2
- require 'cgi'
3
-
4
- def get_vue_files_with_ce_and_ee_versions(files)
5
- files.select do |file|
6
- if file.end_with?('.vue')
7
- counterpart_path = if file.start_with?('ee/')
8
- file.delete_prefix('ee/')
9
- else
10
- "ee/#{file}"
11
- end
12
-
13
- escaped_path = CGI.escape(counterpart_path)
14
- api_endpoint = "https://gitlab.com/api/v4/projects/gitlab-org%2Fgitlab-ee/repository/files/#{escaped_path}?ref=master"
15
- response = HTTParty.get(api_endpoint) # rubocop:disable Gitlab/HTTParty
16
- response.code != 404
17
- else
18
- false
19
- end
20
- end
21
- end
22
-
23
- vue_candidates = get_vue_files_with_ce_and_ee_versions(helper.all_changed_files)
24
-
25
- return if vue_candidates.empty?
26
-
27
- message 'This merge request includes changes to Vue files that have both CE and EE versions.'
28
-
29
- markdown(<<~MARKDOWN)
30
- ## Vue `<template>` in CE and EE
31
-
32
- Some Vue files in CE have a counterpart in EE.
33
- (For example, `path/to/file.vue` and `ee/path/to/file.vue`.)
34
-
35
- When run in the context of CE, the `<template>` of the CE Vue file is used.
36
- When run in the context of EE, the `<template>` of the EE Vue file is used.
37
-
38
- It's easy to accidentally make a change to a CE `<template>` that _should_
39
- appear in both CE and EE without making the change in both places.
40
- When this happens, the change only takes effect in CE.
41
-
42
- The following Vue files were changed as part of this merge request that
43
- include both a CE and EE version of the file:
44
-
45
- * #{vue_candidates.map { |path| "`#{path}`" }.join("\n* ")}
46
-
47
- If you made a change to the `<template>` of any of these Vue files that
48
- should be visible in both CE and EE, please ensure you have made your
49
- change to both versions of the file.
50
-
51
- ### A better alternative
52
-
53
- An even _better_ alternative is to refactor this component to only use
54
- a single template for both CE and EE. More info on this approach here:
55
- https://docs.gitlab.com/ee/development/ee_features.html#template-tag
56
- MARKDOWN
@@ -1,90 +0,0 @@
1
- # frozen_string_literal: true
2
- # rubocop:disable Style/SignalException
3
-
4
- require 'yaml'
5
-
6
- SEE_DOC = "See the [changelog documentation](https://docs.gitlab.com/ee/development/changelog.html)."
7
- CREATE_CHANGELOG_MESSAGE = <<~MSG
8
- If you want to create a changelog entry for GitLab FOSS, run the following:
9
-
10
- ```
11
- bin/changelog -m %<mr_iid>s "%<mr_title>s"
12
- ```
13
-
14
- If you want to create a changelog entry for GitLab EE, run the following instead:
15
-
16
- ```
17
- bin/changelog --ee -m %<mr_iid>s "%<mr_title>s"
18
- ```
19
-
20
- If this merge request [doesn't need a CHANGELOG entry](https://docs.gitlab.com/ee/development/changelog.html#what-warrants-a-changelog-entry), feel free to ignore this message.
21
- MSG
22
-
23
- SUGGEST_MR_COMMENT = <<~SUGGEST_COMMENT
24
- ```suggestion
25
- merge_request: %<mr_iid>s
26
- ```
27
-
28
- #{SEE_DOC}
29
- SUGGEST_COMMENT
30
-
31
- def check_changelog_yaml(path)
32
- raw_file = File.read(path)
33
- yaml = YAML.safe_load(raw_file)
34
-
35
- fail "`title` should be set, in #{helper.html_link(path)}! #{SEE_DOC}" if yaml["title"].nil?
36
- fail "`type` should be set, in #{helper.html_link(path)}! #{SEE_DOC}" if yaml["type"].nil?
37
-
38
- return if helper.security_mr?
39
-
40
- cherry_pick_against_stable_branch = helper.cherry_pick_mr? && helper.stable_branch?
41
-
42
- if yaml["merge_request"].nil?
43
- mr_line = raw_file.lines.find_index("merge_request:\n")
44
-
45
- if mr_line
46
- markdown(format(SUGGEST_MR_COMMENT, mr_iid: gitlab.mr_json["iid"]), file: path, line: mr_line.succ)
47
- else
48
- message "Consider setting `merge_request` to #{gitlab.mr_json["iid"]} in #{helper.html_link(path)}. #{SEE_DOC}"
49
- end
50
- elsif yaml["merge_request"] != gitlab.mr_json["iid"] && !cherry_pick_against_stable_branch
51
- fail "Merge request ID was not set to #{gitlab.mr_json["iid"]}! #{SEE_DOC}"
52
- end
53
- rescue Psych::SyntaxError, Psych::DisallowedClass, Psych::BadAlias
54
- # YAML could not be parsed, fail the build.
55
- fail "#{helper.html_link(path)} isn't valid YAML! #{SEE_DOC}"
56
- rescue StandardError => e
57
- warn "There was a problem trying to check the Changelog. Exception: #{e.class.name} - #{e.message}"
58
- end
59
-
60
- def check_changelog_path(path)
61
- ee_changes = helper.all_ee_changes.dup
62
- ee_changes.delete(path)
63
-
64
- if ee_changes.any? && !changelog.ee_changelog?
65
- warn "This MR has a Changelog file outside `ee/`, but code changes in `ee/`. Consider moving the Changelog file into `ee/`."
66
- end
67
-
68
- if ee_changes.empty? && changelog.ee_changelog?
69
- warn "This MR has a Changelog file in `ee/`, but no code changes in `ee/`. Consider moving the Changelog file outside `ee/`."
70
- end
71
- end
72
-
73
- def sanitized_mr_title
74
- helper.sanitize_mr_title(gitlab.mr_json["title"])
75
- end
76
-
77
- if git.modified_files.include?("CHANGELOG.md")
78
- fail "**CHANGELOG.md was edited.** Please remove the additions and create a CHANGELOG entry.\n\n" +
79
- format(CREATE_CHANGELOG_MESSAGE, mr_iid: gitlab.mr_json["iid"], mr_title: sanitized_mr_title)
80
- end
81
-
82
- changelog_found = changelog.found
83
-
84
- if changelog_found
85
- check_changelog_yaml(changelog_found)
86
- check_changelog_path(changelog_found)
87
- elsif changelog.needed?
88
- message "**[CHANGELOG missing](https://docs.gitlab.com/ee/development/changelog.html)**:\n\n" +
89
- format(CREATE_CHANGELOG_MESSAGE, mr_iid: gitlab.mr_json["iid"], mr_title: sanitized_mr_title)
90
- end
@@ -1,17 +0,0 @@
1
- # FIXME: git.info_for_file raises the following error
2
- # /usr/local/bundle/gems/git-1.4.0/lib/git/lib.rb:956:in `command': (Danger::DSLError)
3
- # [!] Invalid `Dangerfile` file:
4
- # [!] Invalid `Dangerfile` file: git '--git-dir=/builds/gitlab-org/gitlab/.git' '--work-tree=/builds/gitlab-org/gitlab' cat-file '-t' '' 2>&1:fatal: Not a valid object name
5
- # This seems to be the same as https://github.com/danger/danger/issues/535.
6
-
7
- # locale_files_updated = git.modified_files.select { |path| path.start_with?('locale') }
8
- # locale_files_updated.each do |locale_file_updated|
9
- # git_stats = git.info_for_file(locale_file_updated)
10
- # message "Git stats for #{locale_file_updated}: #{git_stats[:insertions]} insertions, #{git_stats[:deletions]} insertions"
11
- # end
12
-
13
- if git.lines_of_code > 2_000
14
- warn "This merge request is definitely too big (more than #{git.lines_of_code} lines changed), please split it into multiple merge requests."
15
- elsif git.lines_of_code > 500
16
- warn "This merge request is quite big (more than #{git.lines_of_code} lines changed), please consider splitting it into multiple merge requests."
17
- end
@@ -1,135 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require_relative File.expand_path("../../danger/commit_linter", __dir__)
4
-
5
- COMMIT_MESSAGE_GUIDELINES = "https://docs.gitlab.com/ee/development/contributing/merge_request_workflow.html#commit-messages-guidelines"
6
- MORE_INFO = "For more information, take a look at our [Commit message guidelines](#{COMMIT_MESSAGE_GUIDELINES})."
7
- THE_DANGER_JOB_TEXT = "the `danger-review` job"
8
- MAX_COMMITS_COUNT = 10
9
- MAX_COMMITS_COUNT_EXCEEDED_MESSAGE = <<~MSG
10
- This merge request includes more than %<max_commits_count>d commits. Each commit should meet the following criteria:
11
-
12
- 1. Have a well-written commit message.
13
- 1. Has all tests passing when used on its own (e.g. when using git checkout SHA).
14
- 1. Can be reverted on its own without also requiring the revert of commit that came before it.
15
- 1. Is small enough that it can be reviewed in isolation in under 30 minutes or so.
16
-
17
- If this merge request contains commits that do not meet this criteria and/or contains intermediate work, please rebase these commits into a smaller number of commits or split this merge request into multiple smaller merge requests.
18
- MSG
19
-
20
- def fail_commit(commit, message, more_info: true)
21
- self.fail(build_message(commit, message, more_info: more_info))
22
- end
23
-
24
- def warn_commit(commit, message, more_info: true)
25
- self.warn(build_message(commit, message, more_info: more_info))
26
- end
27
-
28
- def build_message(commit, message, more_info: true)
29
- [message].tap do |full_message|
30
- full_message << ". #{MORE_INFO}" if more_info
31
- full_message.unshift("#{commit.sha}: ") if commit.sha
32
- end.join
33
- end
34
-
35
- def squash_mr?
36
- helper.ci? ? gitlab.mr_json['squash'] : false
37
- end
38
-
39
- def wip_mr?
40
- helper.ci? ? gitlab.mr_json['work_in_progress'] : false
41
- end
42
-
43
- def danger_job_link
44
- helper.ci? ? "[#{THE_DANGER_JOB_TEXT}](#{ENV['CI_JOB_URL']})" : THE_DANGER_JOB_TEXT
45
- end
46
-
47
- # Perform various checks against commits. We're not using
48
- # https://github.com/jonallured/danger-commit_lint because its output is not
49
- # very helpful, and it doesn't offer the means of ignoring merge commits.
50
- def lint_commit(commit)
51
- linter = Gitlab::Dangerfiles::CommitLinter.new(commit)
52
-
53
- # For now we'll ignore merge commits, as getting rid of those is a problem
54
- # separate from enforcing good commit messages.
55
- return linter if linter.merge?
56
-
57
- # We ignore revert commits as they are well structured by Git already
58
- return linter if linter.revert?
59
-
60
- # If MR is set to squash, we ignore fixup commits
61
- return linter if linter.fixup? && squash_mr?
62
-
63
- if linter.fixup?
64
- msg = "Squash or fixup commits must be squashed before merge, or enable squash merge option and re-run #{danger_job_link}."
65
- if wip_mr? || squash_mr?
66
- warn_commit(commit, msg, more_info: false)
67
- else
68
- fail_commit(commit, msg, more_info: false)
69
- end
70
-
71
- # Makes no sense to process other rules for fixup commits, they trigger just more noise
72
- return linter
73
- end
74
-
75
- # Fail if a suggestion commit is used and squash is not enabled
76
- if linter.suggestion?
77
- unless squash_mr?
78
- fail_commit(commit, "If you are applying suggestions, enable squash in the merge request and re-run #{danger_job_link}.", more_info: false)
79
- end
80
-
81
- return linter
82
- end
83
-
84
- linter.lint
85
- end
86
-
87
- def lint_mr_title(mr_title)
88
- commit = Struct.new(:message, :sha).new(mr_title)
89
-
90
- Gitlab::Dangerfiles::CommitLinter.new(commit).lint_subject("merge request title")
91
- end
92
-
93
- def count_non_fixup_commits(commit_linters)
94
- commit_linters.count { |commit_linter| !commit_linter.fixup? }
95
- end
96
-
97
- def lint_commits(commits)
98
- commit_linters = commits.map { |commit| lint_commit(commit) }
99
- failed_commit_linters = commit_linters.select { |commit_linter| commit_linter.failed? }
100
- warn_or_fail_commits(failed_commit_linters, default_to_fail: !squash_mr?)
101
-
102
- if count_non_fixup_commits(commit_linters) > MAX_COMMITS_COUNT
103
- self.warn(format(MAX_COMMITS_COUNT_EXCEEDED_MESSAGE, max_commits_count: MAX_COMMITS_COUNT))
104
- end
105
-
106
- if squash_mr?
107
- multi_line_commit_linter = commit_linters.detect { |commit_linter| !commit_linter.merge? && commit_linter.multi_line? }
108
-
109
- if multi_line_commit_linter && multi_line_commit_linter.failed?
110
- warn_or_fail_commits(multi_line_commit_linter)
111
- else
112
- title_linter = lint_mr_title(gitlab.mr_json['title'])
113
- if title_linter.failed?
114
- warn_or_fail_commits(title_linter)
115
- end
116
- end
117
- end
118
- end
119
-
120
- def warn_or_fail_commits(failed_linters, default_to_fail: true)
121
- level = default_to_fail ? :fail : :warn
122
-
123
- Array(failed_linters).each do |linter|
124
- linter.problems.each do |problem_key, problem_desc|
125
- case problem_key
126
- when :subject_above_warning
127
- warn_commit(linter.commit, problem_desc)
128
- else
129
- self.__send__("#{level}_commit", linter.commit, problem_desc) # rubocop:disable GitlabSecurity/PublicSend
130
- end
131
- end
132
- end
133
- end
134
-
135
- lint_commits(git.commits)
@@ -1,67 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- SCHEMA_NOT_UPDATED_MESSAGE_SHORT = <<~MSG
4
- New %<migrations>s added but %<schema>s wasn't updated.
5
- MSG
6
-
7
- SCHEMA_NOT_UPDATED_MESSAGE_FULL = <<~MSG
8
- **#{SCHEMA_NOT_UPDATED_MESSAGE_SHORT}**
9
-
10
- Usually, when adding new %<migrations>s, %<schema>s should be
11
- updated too (unless the migration isn't changing the DB schema
12
- and isn't the most recent one).
13
- MSG
14
-
15
- DB_MESSAGE = <<~MSG
16
- This merge request requires a database review. To make sure these
17
- changes are reviewed, take the following steps:
18
-
19
- 1. Ensure the merge request has ~database and ~"database::review pending" labels.
20
- If the merge request modifies database files, Danger will do this for you.
21
- 1. Prepare your MR for database review according to the
22
- [docs](https://docs.gitlab.com/ee/development/database_review.html#how-to-prepare-the-merge-request-for-a-database-review).
23
- 1. Assign and mention the database reviewer suggested by Reviewer Roulette.
24
- MSG
25
-
26
- DB_FILES_MESSAGE = <<~MSG
27
- The following files require a review from the Database team:
28
- MSG
29
-
30
- DATABASE_APPROVED_LABEL = 'database::approved'
31
-
32
- non_geo_db_schema_updated = !git.modified_files.grep(%r{\Adb/structure\.sql}).empty?
33
- geo_db_schema_updated = !git.modified_files.grep(%r{\Aee/db/geo/schema\.rb}).empty?
34
-
35
- non_geo_migration_created = !git.added_files.grep(%r{\A(db/(post_)?migrate)/}).empty?
36
- geo_migration_created = !git.added_files.grep(%r{\Aee/db/geo/(post_)?migrate/}).empty?
37
-
38
- format_str = helper.ci? ? SCHEMA_NOT_UPDATED_MESSAGE_FULL : SCHEMA_NOT_UPDATED_MESSAGE_SHORT
39
-
40
- if non_geo_migration_created && !non_geo_db_schema_updated
41
- warn format(format_str, migrations: 'migrations', schema: helper.html_link("db/structure.sql"))
42
- end
43
-
44
- if geo_migration_created && !geo_db_schema_updated
45
- warn format(format_str, migrations: 'Geo migrations', schema: helper.html_link("ee/db/geo/schema.rb"))
46
- end
47
-
48
- return unless helper.ci?
49
- return if gitlab.mr_labels.include?(DATABASE_APPROVED_LABEL)
50
-
51
- db_paths_to_review = helper.changes_by_category[:database]
52
-
53
- if gitlab.mr_labels.include?('database') || db_paths_to_review.any?
54
- message 'This merge request adds or changes files that require a ' \
55
- 'review from the [Database team](https://gitlab.com/groups/gl-database/-/group_members).'
56
-
57
- markdown(DB_MESSAGE)
58
- markdown(DB_FILES_MESSAGE + helper.markdown_list(db_paths_to_review)) if db_paths_to_review.any?
59
-
60
- database_labels = helper.missing_database_labels(gitlab.mr_labels)
61
-
62
- if database_labels.any?
63
- gitlab.api.update_merge_request(gitlab.mr_json['project_id'],
64
- gitlab.mr_json['iid'],
65
- labels: (gitlab.mr_labels + database_labels).join(','))
66
- end
67
- end