gitlab-dangerfiles 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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