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,29 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- docs_paths_to_review = helper.changes_by_category[:docs]
4
-
5
- return if docs_paths_to_review.empty?
6
-
7
- message 'This merge request adds or changes files that require a review ' \
8
- 'from the Technical Writing team.'
9
-
10
- return unless helper.ci?
11
-
12
- markdown(<<~MARKDOWN)
13
- ## Documentation review
14
-
15
- The following files require a review from a technical writer:
16
-
17
- * #{docs_paths_to_review.map { |path| "`#{path}`" }.join("\n* ")}
18
-
19
- The review does not need to block merging this merge request. See the:
20
-
21
- - [Technical Writers assignments](https://about.gitlab.com/handbook/engineering/technical-writing/#designated-technical-writers) for the appropriate technical writer for this review.
22
- - [Documentation workflows](https://docs.gitlab.com/ee/development/documentation/workflow.html) for information on when to assign a merge request for review.
23
- MARKDOWN
24
-
25
- unless gitlab.mr_labels.include?('documentation')
26
- gitlab.api.update_merge_request(gitlab.mr_json['project_id'],
27
- gitlab.mr_json['iid'],
28
- labels: (gitlab.mr_labels + ['documentation']).join(','))
29
- end
@@ -1,29 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- return unless helper.all_changed_files.include?('yarn.lock')
4
-
5
- duplicate = `node_modules/.bin/yarn-deduplicate --list --strategy fewer yarn.lock`
6
- .split(/$/)
7
- .map(&:strip)
8
- .reject(&:empty?)
9
-
10
- return if duplicate.empty?
11
-
12
- warn 'This merge request has introduced duplicated yarn dependencies.'
13
-
14
- if helper.ci?
15
- markdown(<<~MARKDOWN)
16
- ## Duplicate yarn dependencies
17
-
18
- The following dependencies should be de-duplicated:
19
-
20
- * #{duplicate.map { |path| "`#{path}`" }.join("\n* ")}
21
-
22
- Please run the following command and commit the changes to `yarn.lock`:
23
-
24
- ```
25
- node_modules/.bin/yarn-deduplicate --strategy fewer yarn.lock \\
26
- && yarn install
27
- ```
28
- MARKDOWN
29
- end
@@ -1,31 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- def get_eslint_files(files)
4
- files.select do |file|
5
- file.end_with?('.js', '.vue') &&
6
- File.read(file).include?('/* eslint-disable')
7
- end
8
- end
9
-
10
- eslint_candidates = get_eslint_files(helper.all_changed_files)
11
-
12
- return if eslint_candidates.empty?
13
-
14
- warn 'This merge request changed files with disabled eslint rules. Please consider fixing them.'
15
-
16
- if helper.ci?
17
- markdown(<<~MARKDOWN)
18
- ## Disabled eslint rules
19
-
20
- The following files have disabled `eslint` rules. Please consider fixing them:
21
-
22
- * #{eslint_candidates.map { |path| "`#{path}`" }.join("\n* ")}
23
-
24
- Run the following command for more details
25
-
26
- ```
27
- node_modules/.bin/eslint --report-unused-disable-directives --no-inline-config \\
28
- #{eslint_candidates.map { |path| " '#{path}'" }.join(" \\\n")}
29
- ```
30
- MARKDOWN
31
- end
@@ -1,28 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- FILE_EXTENSION = ".rb"
4
- MAGIC_COMMENT = "# frozen_string_literal: true"
5
-
6
- def get_files_with_no_magic_comment(files)
7
- files.select do |file|
8
- file.end_with?(FILE_EXTENSION) &&
9
- !File.open(file, &:gets)&.start_with?(MAGIC_COMMENT)
10
- end
11
- end
12
-
13
- files_to_fix = get_files_with_no_magic_comment(git.added_files)
14
-
15
- if files_to_fix.any?
16
- warn 'This merge request adds files that do not enforce frozen string literal. ' \
17
- 'See https://gitlab.com/gitlab-org/gitlab-foss/issues/47424 for more information.'
18
-
19
- if helper.ci?
20
- markdown(<<~MARKDOWN)
21
- ## Enable Frozen String Literal
22
-
23
- The following files should have `#{MAGIC_COMMENT}` on the first line:
24
-
25
- * #{files_to_fix.map { |path| "`#{path}`" }.join("\n* ")}
26
- MARKDOWN
27
- end
28
- end
@@ -1,51 +0,0 @@
1
- # frozen_string_literal: true
2
- # rubocop:disable Style/SignalException
3
-
4
- def get_karma_files(files)
5
- files.select do |file|
6
- file.start_with?('ee/spec/javascripts', 'spec/javascripts') &&
7
- file.end_with?('_spec.js') &&
8
- !file.end_with?('browser_spec.js')
9
- end
10
- end
11
-
12
- new_karma_files = get_karma_files(git.added_files.to_a)
13
-
14
- unless new_karma_files.empty?
15
-
16
- if helper.ci?
17
- markdown(<<~MARKDOWN)
18
- ## New karma spec file
19
-
20
- New frontend specs ([except `browser_specs`](https://gitlab.com/gitlab-org/gitlab/blob/3b6fe2f1077eedb0b8aff02a7350234f0b7dc4f9/spec/javascripts/lib/utils/browser_spec.js#L2)) should be
21
- [written in jest](https://docs.gitlab.com/ee/development/testing_guide/frontend_testing.html#jest).
22
-
23
- You have created the following tests, please migrate them over to jest:
24
-
25
- * #{new_karma_files.map { |path| "`#{path}`" }.join("\n* ")}
26
- MARKDOWN
27
- end
28
-
29
- fail "You have created a new karma spec file"
30
-
31
- end
32
-
33
- changed_karma_files = get_karma_files(helper.all_changed_files) - new_karma_files
34
-
35
- return if changed_karma_files.empty?
36
-
37
- warn 'You have edited karma spec files. Please consider migrating them to jest.'
38
-
39
- if helper.ci?
40
- markdown(<<~MARKDOWN)
41
- ## Edited karma files
42
-
43
- You have edited the following karma spec files. Please consider migrating them to jest:
44
-
45
- * #{changed_karma_files.map { |path| "`#{path}`" }.join("\n* ")}
46
-
47
- In order to align with our Iteration value, migration can also be done as a follow-up.
48
-
49
- For more information: [Jestodus epic](https://gitlab.com/groups/gitlab-org/-/epics/895)
50
- MARKDOWN
51
- end
@@ -1,50 +0,0 @@
1
- # rubocop:disable Style/SignalException
2
-
3
- THROUGHPUT_LABELS = [
4
- 'Community contribution',
5
- 'security',
6
- 'bug',
7
- 'backstage', # To be removed by https://gitlab.com/gitlab-org/gitlab/-/issues/222360.
8
- 'feature',
9
- 'feature::addition',
10
- 'feature::maintenance',
11
- 'tooling',
12
- 'tooling::pipelines',
13
- 'tooling::workflow',
14
- 'documentation'
15
- ].freeze
16
-
17
- if gitlab.mr_body.size < 5
18
- fail "Please provide a proper merge request description."
19
- end
20
-
21
- if gitlab.mr_labels.empty?
22
- fail "Please add labels to this merge request."
23
- end
24
-
25
- if (THROUGHPUT_LABELS & gitlab.mr_labels).empty?
26
- warn 'Please add a [throughput label](https://about.gitlab.com/handbook/engineering/management/throughput/#implementation) to this merge request.'
27
- end
28
-
29
- unless gitlab.mr_json["assignee"]
30
- warn "This merge request does not have any assignee yet. Setting an assignee clarifies who needs to take action on the merge request at any given time."
31
- end
32
-
33
- has_milestone = !gitlab.mr_json["milestone"].nil?
34
-
35
- unless has_milestone
36
- warn "This merge request does not refer to an existing milestone.", sticky: false
37
- end
38
-
39
- has_pick_into_stable_label = gitlab.mr_labels.find { |label| label.start_with?('Pick into') }
40
-
41
- if gitlab.branch_for_base != "master" && !has_pick_into_stable_label && !helper.security_mr?
42
- warn "Most of the time, merge requests should target `master`. Otherwise, please set the relevant `Pick into X.Y` label."
43
- end
44
-
45
- if gitlab.mr_json['title'].length > 72
46
- warn 'The title of this merge request is longer than 72 characters and ' \
47
- 'would violate our commit message rules when using the Squash on Merge ' \
48
- 'feature. Please consider adjusting the title, or rebase the ' \
49
- "commits manually and don't use Squash on Merge."
50
- end
@@ -1,55 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "fileutils"
4
- require "open3"
5
-
6
- module Gitlab
7
- module Dangerfiles
8
- class Popen
9
- Result = Struct.new(:cmd, :stdout, :stderr, :status, :duration)
10
-
11
- # Returns [stdout + stderr, status]
12
- def popen(cmd, path = nil, vars = {}, &block)
13
- result = popen_with_detail(cmd, path, vars, &block)
14
-
15
- ["#{result.stdout}#{result.stderr}", result.status&.exitstatus]
16
- end
17
-
18
- # Returns Result
19
- def popen_with_detail(cmd, path = nil, vars = {})
20
- unless cmd.is_a?(Array)
21
- raise "System commands must be given as an array of strings"
22
- end
23
-
24
- path ||= Dir.pwd
25
- vars["PWD"] = path
26
- options = { chdir: path }
27
-
28
- unless File.directory?(path)
29
- FileUtils.mkdir_p(path)
30
- end
31
-
32
- cmd_stdout = ""
33
- cmd_stderr = ""
34
- cmd_status = nil
35
- start = Time.now
36
-
37
- Open3.popen3(vars, *cmd, options) do |stdin, stdout, stderr, wait_thr|
38
- # stderr and stdout pipes can block if stderr/stdout aren't drained: https://bugs.ruby-lang.org/issues/9082
39
- # Mimic what Ruby does with capture3: https://github.com/ruby/ruby/blob/1ec544695fa02d714180ef9c34e755027b6a2103/lib/open3.rb#L257-L273
40
- out_reader = Thread.new { stdout.read }
41
- err_reader = Thread.new { stderr.read }
42
-
43
- yield(stdin) if block_given?
44
- stdin.close
45
-
46
- cmd_stdout = out_reader.value
47
- cmd_stderr = err_reader.value
48
- cmd_status = wait_thr.value
49
- end
50
-
51
- Result.new(cmd, cmd_stdout, cmd_stderr, cmd_status, Time.now - start)
52
- end
53
- end
54
- end
55
- end
@@ -1,41 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- def get_prettier_files(files)
4
- files.select do |file|
5
- file.end_with?('.js', '.scss', '.vue')
6
- end
7
- end
8
-
9
- prettier_candidates = get_prettier_files(helper.all_changed_files)
10
-
11
- return if prettier_candidates.empty?
12
-
13
- unpretty = `node_modules/prettier/bin-prettier.js --list-different #{prettier_candidates.join(" ")}`
14
- .split(/$/)
15
- .map(&:strip)
16
- .reject(&:empty?)
17
-
18
- return if unpretty.empty?
19
-
20
- warn 'This merge request changed frontend files without pretty printing them.'
21
-
22
- if helper.ci?
23
- markdown(<<~MARKDOWN)
24
- ## Pretty print Frontend files
25
-
26
- The following files should have been pretty printed with `prettier`:
27
-
28
- * #{unpretty.map { |path| "`#{path}`" }.join("\n* ")}
29
-
30
- Please run
31
-
32
- ```
33
- node_modules/.bin/prettier --write \\
34
- #{unpretty.map { |path| " '#{path}'" }.join(" \\\n")}
35
- ```
36
-
37
- Also consider auto-formatting [on-save].
38
-
39
- [on-save]: https://docs.gitlab.com/ee/development/fe_guide/tooling.html#formatting-with-prettier
40
- MARKDOWN
41
- end
@@ -1,97 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'digest/md5'
4
-
5
- MESSAGE = <<MARKDOWN
6
- ## Reviewer roulette
7
-
8
- Changes that require review have been detected! A merge request is normally
9
- reviewed by both a reviewer and a maintainer in its primary category (e.g.
10
- ~frontend or ~backend), and by a maintainer in all other categories.
11
- MARKDOWN
12
-
13
- CATEGORY_TABLE_HEADER = <<MARKDOWN
14
-
15
- To spread load more evenly across eligible reviewers, Danger has picked a candidate for each
16
- review slot, based on their timezone. Feel free to
17
- [override these selections](https://about.gitlab.com/handbook/engineering/projects/#gitlab)
18
- if you think someone else would be better-suited, or the chosen person is unavailable.
19
-
20
- To read more on how to use the reviewer roulette, please take a look at the
21
- [Engineering workflow](https://about.gitlab.com/handbook/engineering/workflow/#basics)
22
- and [code review guidelines](https://docs.gitlab.com/ee/development/code_review.html).
23
- Please consider assigning a reviewer or maintainer who is a
24
- [domain expert](https://about.gitlab.com/handbook/engineering/projects/#gitlab) in the area of the merge request.
25
-
26
- Once you've decided who will review this merge request, mention them as you
27
- normally would! Danger does not automatically notify them for you.
28
-
29
- | Category | Reviewer | Maintainer |
30
- | -------- | -------- | ---------- |
31
- MARKDOWN
32
-
33
- UNKNOWN_FILES_MESSAGE = <<MARKDOWN
34
-
35
- These files couldn't be categorised, so Danger was unable to suggest a reviewer.
36
- Please consider creating a merge request to
37
- [add support](https://gitlab.com/gitlab-org/gitlab-dangerfiles/blob/master/lib/danger/helper.rb)
38
- for them.
39
- MARKDOWN
40
-
41
- OPTIONAL_REVIEW_TEMPLATE = "%{role} review is optional for %{category}".freeze
42
- NOT_AVAILABLE_TEMPLATE = 'No %{role} available'.freeze
43
- TIMEZONE_EXPERIMENT = true
44
-
45
- def mr_author
46
- roulette.team.find { |person| person.username == gitlab.mr_author }
47
- end
48
-
49
- def note_for_category_role(spin, role)
50
- if spin.optional_role == role
51
- return OPTIONAL_REVIEW_TEMPLATE % { role: role.capitalize, category: helper.label_for_category(spin.category) }
52
- end
53
-
54
- spin.public_send(role)&.markdown_name(timezone_experiment: TIMEZONE_EXPERIMENT, author: mr_author) || NOT_AVAILABLE_TEMPLATE % { role: role } # rubocop:disable GitlabSecurity/PublicSend
55
- end
56
-
57
- def markdown_row_for_spin(spin)
58
- reviewer_note = note_for_category_role(spin, :reviewer)
59
- maintainer_note = note_for_category_role(spin, :maintainer)
60
-
61
- "| #{helper.label_for_category(spin.category)} | #{reviewer_note} | #{maintainer_note} |"
62
- end
63
-
64
- changes = helper.changes_by_category
65
-
66
- # Ignore any files that are known but uncategorized. Prompt for any unknown files
67
- changes.delete(:none)
68
- # To reinstate roulette for documentation, remove this line.
69
- changes.delete(:docs)
70
- categories = changes.keys - [:unknown]
71
-
72
- # Ensure to spin for database reviewer/maintainer when ~database is applied (e.g. to review SQL queries)
73
- categories << :database if gitlab.mr_labels.include?('database') && !categories.include?(:database)
74
-
75
- if changes.any?
76
- project = helper.project_name
77
- branch_name = gitlab.mr_json['source_branch']
78
-
79
- markdown(MESSAGE)
80
-
81
- roulette_spins = roulette.spin(project, categories, branch_name, timezone_experiment: TIMEZONE_EXPERIMENT)
82
- rows = roulette_spins.map do |spin|
83
- # MR includes QA changes, but also other changes, and author isn't an SET
84
- if spin.category == :qa && categories.size > 1 && !mr_author.reviewer?(project, spin.category, [])
85
- spin.optional_role = :maintainer
86
- end
87
-
88
- spin.optional_role = :maintainer if spin.category == :test
89
-
90
- markdown_row_for_spin(spin)
91
- end
92
-
93
- markdown(CATEGORY_TABLE_HEADER + rows.join("\n")) unless rows.empty?
94
-
95
- unknown = changes.fetch(:unknown, [])
96
- markdown(UNKNOWN_FILES_MESSAGE + helper.markdown_list(unknown)) unless unknown.empty?
97
- end
@@ -1,27 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- SCALABILITY_REVIEW_MESSAGE = <<~MSG
4
- ## Sidekiq queue changes
5
-
6
- This merge request contains changes to Sidekiq queues. Please follow the [documentation on changing a queue's urgency](https://docs.gitlab.com/ee/development/sidekiq_style_guide.html#changing-a-queues-urgency).
7
- MSG
8
-
9
- ADDED_QUEUES_MESSAGE = <<~MSG
10
- These queues were added:
11
- MSG
12
-
13
- CHANGED_QUEUES_MESSAGE = <<~MSG
14
- These queues had their attributes changed:
15
- MSG
16
-
17
- if sidekiq_queues.added_queue_names.any? || sidekiq_queues.changed_queue_names.any?
18
- markdown(SCALABILITY_REVIEW_MESSAGE)
19
-
20
- if sidekiq_queues.added_queue_names.any?
21
- markdown(ADDED_QUEUES_MESSAGE + helper.markdown_list(sidekiq_queues.added_queue_names))
22
- end
23
-
24
- if sidekiq_queues.changed_queue_names.any?
25
- markdown(CHANGED_QUEUES_MESSAGE + helper.markdown_list(sidekiq_queues.changed_queue_names))
26
- end
27
- end