gitlab-dangerfiles 0.1.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.
- checksums.yaml +7 -0
- data/.gitignore +14 -0
- data/.gitlab-ci.yml +43 -0
- data/.gitlab/merge_request_templates/Release.md +35 -0
- data/CODE_OF_CONDUCT.md +74 -0
- data/Gemfile +7 -0
- data/Guardfile +70 -0
- data/LICENSE.txt +21 -0
- data/README.md +43 -0
- data/Rakefile +6 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/fixtures/emojis/aliases.json +542 -0
- data/fixtures/emojis/digests.json +12553 -0
- data/gitlab-dangerfiles.gemspec +38 -0
- data/lib/danger/changelog.rb +39 -0
- data/lib/danger/helper.rb +260 -0
- data/lib/danger/roulette.rb +135 -0
- data/lib/danger/sidekiq_queues.rb +37 -0
- data/lib/gitlab-dangerfiles.rb +1 -0
- data/lib/gitlab/Dangerfile +1 -0
- data/lib/gitlab/dangerfiles.rb +40 -0
- data/lib/gitlab/dangerfiles/bundle_size/Dangerfile +38 -0
- data/lib/gitlab/dangerfiles/ce_ee_vue_templates/Dangerfile +56 -0
- data/lib/gitlab/dangerfiles/changelog/Dangerfile +90 -0
- data/lib/gitlab/dangerfiles/changes_size/Dangerfile +17 -0
- data/lib/gitlab/dangerfiles/commit_linter.rb +226 -0
- data/lib/gitlab/dangerfiles/commit_messages/Dangerfile +135 -0
- data/lib/gitlab/dangerfiles/database/Dangerfile +67 -0
- data/lib/gitlab/dangerfiles/documentation/Dangerfile +29 -0
- data/lib/gitlab/dangerfiles/duplicate_yarn_dependencies/Dangerfile +29 -0
- data/lib/gitlab/dangerfiles/emoji_checker.rb +45 -0
- data/lib/gitlab/dangerfiles/eslint/Dangerfile +31 -0
- data/lib/gitlab/dangerfiles/frozen_string/Dangerfile +28 -0
- data/lib/gitlab/dangerfiles/karma/Dangerfile +51 -0
- data/lib/gitlab/dangerfiles/metadata/Dangerfile +50 -0
- data/lib/gitlab/dangerfiles/popen.rb +55 -0
- data/lib/gitlab/dangerfiles/prettier/Dangerfile +41 -0
- data/lib/gitlab/dangerfiles/roulette/Dangerfile +97 -0
- data/lib/gitlab/dangerfiles/sidekiq_queues/Dangerfile +27 -0
- data/lib/gitlab/dangerfiles/specs/Dangerfile +42 -0
- data/lib/gitlab/dangerfiles/tasks.rb +19 -0
- data/lib/gitlab/dangerfiles/teammate.rb +106 -0
- data/lib/gitlab/dangerfiles/telemetry/Dangerfile +32 -0
- data/lib/gitlab/dangerfiles/utility_css/Dangerfile +51 -0
- data/lib/gitlab/dangerfiles/version.rb +5 -0
- metadata +191 -0
@@ -0,0 +1,55 @@
|
|
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
|
@@ -0,0 +1,41 @@
|
|
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
|
@@ -0,0 +1,97 @@
|
|
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
|
@@ -0,0 +1,27 @@
|
|
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
|
@@ -0,0 +1,42 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
NO_SPECS_LABELS = [
|
4
|
+
'backstage', # To be removed by https://gitlab.com/gitlab-org/gitlab/-/issues/222360.
|
5
|
+
'tooling',
|
6
|
+
'tooling::pipelines',
|
7
|
+
'tooling::workflow',
|
8
|
+
'documentation',
|
9
|
+
'QA'
|
10
|
+
].freeze
|
11
|
+
NO_NEW_SPEC_MESSAGE = <<~MSG
|
12
|
+
You've made some app changes, but didn't add any tests.
|
13
|
+
That's OK as long as you're refactoring existing code,
|
14
|
+
but please consider adding any of the %<labels>s labels.
|
15
|
+
MSG
|
16
|
+
EE_CHANGE_WITH_FOSS_SPEC_CHANGE_MESSAGE = <<~MSG
|
17
|
+
You've made some EE-specific changes, but only made changes to FOSS tests.
|
18
|
+
This could be a sign that you're testing an EE-specific behavior in a FOSS test.
|
19
|
+
|
20
|
+
Please make sure the spec files pass in AS-IF-FOSS mode either:
|
21
|
+
|
22
|
+
1. Locally with `FOSS_ONLY=1 bin/rspec -- %<spec_files>s`.
|
23
|
+
1. In the MR pipeline by verifying that the `rspec foss-impact` job has passed.
|
24
|
+
1. In the MR pipelines by including `RUN AS-IF-FOSS` in the MR title (you can do it with the ``/title %<mr_title>s [RUN AS-IF-FOSS]`` quick action) and start a new MR pipeline.
|
25
|
+
|
26
|
+
MSG
|
27
|
+
|
28
|
+
has_app_changes = helper.all_changed_files.grep(%r{\A(app|lib|db/(geo/)?(post_)?migrate)/}).any?
|
29
|
+
has_ee_app_changes = helper.all_changed_files.grep(%r{\Aee/(app|lib|db/(geo/)?(post_)?migrate)/}).any?
|
30
|
+
spec_changes = helper.all_changed_files.grep(%r{\Aspec/})
|
31
|
+
has_spec_changes = spec_changes.any?
|
32
|
+
has_ee_spec_changes = helper.all_changed_files.grep(%r{\Aee/spec/}).any?
|
33
|
+
new_specs_needed = (gitlab.mr_labels & NO_SPECS_LABELS).empty?
|
34
|
+
|
35
|
+
if (has_app_changes || has_ee_app_changes) && !(has_spec_changes || has_ee_spec_changes) && new_specs_needed
|
36
|
+
warn format(NO_NEW_SPEC_MESSAGE, labels: helper.labels_list(NO_SPECS_LABELS)), sticky: false
|
37
|
+
end
|
38
|
+
|
39
|
+
# The only changes outside `ee/` are in `spec/`
|
40
|
+
if has_ee_app_changes && has_spec_changes && !(has_app_changes || has_ee_spec_changes)
|
41
|
+
warn format(EE_CHANGE_WITH_FOSS_SPEC_CHANGE_MESSAGE, spec_files: spec_changes.join(" "), mr_title: gitlab.mr_json['title']), sticky: false
|
42
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
desc "Run local Danger rules"
|
4
|
+
task :danger_local do
|
5
|
+
require "gitlab/dangerfiles"
|
6
|
+
require "popen/danger/popen"
|
7
|
+
|
8
|
+
puts("#{Gitlab::Dangerfiles.local_warning_message}\n")
|
9
|
+
|
10
|
+
# _status will _always_ be 0, regardless of failure or success :(
|
11
|
+
output, _status = Gitlab::Dangerfiles::Popen.popen(%w{danger dry_run})
|
12
|
+
|
13
|
+
if output.empty?
|
14
|
+
puts(Gitlab::Dangerfiles.success_message)
|
15
|
+
else
|
16
|
+
puts(output)
|
17
|
+
exit(1)
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,106 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Gitlab
|
4
|
+
module Dangerfiles
|
5
|
+
class Teammate
|
6
|
+
attr_reader :username, :name, :role, :projects, :available, :tz_offset_hours
|
7
|
+
|
8
|
+
# The options data are produced by https://gitlab.com/gitlab-org/gitlab-roulette/-/blob/master/lib/team_member.rb
|
9
|
+
def initialize(options = {})
|
10
|
+
@username = options["username"]
|
11
|
+
@name = options["name"]
|
12
|
+
@markdown_name = options["markdown_name"]
|
13
|
+
@role = options["role"]
|
14
|
+
@projects = options["projects"]
|
15
|
+
@available = options["available"]
|
16
|
+
@tz_offset_hours = options["tz_offset_hours"]
|
17
|
+
end
|
18
|
+
|
19
|
+
def in_project?(name)
|
20
|
+
projects&.has_key?(name)
|
21
|
+
end
|
22
|
+
|
23
|
+
# Traintainers also count as reviewers
|
24
|
+
def reviewer?(project, category, labels)
|
25
|
+
has_capability?(project, category, :reviewer, labels) ||
|
26
|
+
traintainer?(project, category, labels)
|
27
|
+
end
|
28
|
+
|
29
|
+
def traintainer?(project, category, labels)
|
30
|
+
has_capability?(project, category, :trainee_maintainer, labels)
|
31
|
+
end
|
32
|
+
|
33
|
+
def maintainer?(project, category, labels)
|
34
|
+
has_capability?(project, category, :maintainer, labels)
|
35
|
+
end
|
36
|
+
|
37
|
+
def markdown_name(timezone_experiment: false, author: nil)
|
38
|
+
return @markdown_name unless timezone_experiment
|
39
|
+
|
40
|
+
"#{@markdown_name} (#{utc_offset_text(author)})"
|
41
|
+
end
|
42
|
+
|
43
|
+
def local_hour
|
44
|
+
(Time.now.utc + tz_offset_hours * 3600).hour
|
45
|
+
end
|
46
|
+
|
47
|
+
protected
|
48
|
+
|
49
|
+
def floored_offset_hours
|
50
|
+
floored_offset = tz_offset_hours.floor(0)
|
51
|
+
|
52
|
+
floored_offset == tz_offset_hours ? floored_offset : tz_offset_hours
|
53
|
+
end
|
54
|
+
|
55
|
+
private
|
56
|
+
|
57
|
+
def utc_offset_text(author = nil)
|
58
|
+
offset_text = if floored_offset_hours >= 0
|
59
|
+
"UTC+#{floored_offset_hours}"
|
60
|
+
else
|
61
|
+
"UTC#{floored_offset_hours}"
|
62
|
+
end
|
63
|
+
|
64
|
+
return offset_text unless author
|
65
|
+
|
66
|
+
"#{offset_text}, #{offset_diff_compared_to_author(author)}"
|
67
|
+
end
|
68
|
+
|
69
|
+
def offset_diff_compared_to_author(author)
|
70
|
+
diff = floored_offset_hours - author.floored_offset_hours
|
71
|
+
return "same timezone as `@#{author.username}`" if diff.zero?
|
72
|
+
|
73
|
+
ahead_or_behind = diff < 0 ? "behind" : "ahead"
|
74
|
+
pluralized_hours = pluralize(diff.abs, "hour", "hours")
|
75
|
+
|
76
|
+
"#{pluralized_hours} #{ahead_or_behind} `@#{author.username}`"
|
77
|
+
end
|
78
|
+
|
79
|
+
def has_capability?(project, category, kind, labels)
|
80
|
+
case category
|
81
|
+
when :test
|
82
|
+
area = role[/Software Engineer in Test(?:.*?, (\w+))/, 1]
|
83
|
+
|
84
|
+
area && labels.any?("devops::#{area.downcase}") if kind == :reviewer
|
85
|
+
when :engineering_productivity
|
86
|
+
return false unless role[/Engineering Productivity/]
|
87
|
+
return true if kind == :reviewer
|
88
|
+
|
89
|
+
capabilities(project).include?("#{kind} backend")
|
90
|
+
else
|
91
|
+
capabilities(project).include?("#{kind} #{category}")
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
def capabilities(project)
|
96
|
+
Array(projects.fetch(project, []))
|
97
|
+
end
|
98
|
+
|
99
|
+
def pluralize(count, singular, plural)
|
100
|
+
word = count == 1 || count.to_s =~ /^1(\.0+)?$/ ? singular : plural
|
101
|
+
|
102
|
+
"#{count || 0} #{word}"
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
TELEMETRY_CHANGED_FILES_MESSAGE = <<~MSG
|
4
|
+
For the following files, a review from the [Data team and Telemetry team](https://gitlab.com/groups/gitlab-org/growth/telemetry/engineers/-/group_members?with_inherited_permissions=exclude) is recommended
|
5
|
+
Please check the ~telemetry [guide](https://docs.gitlab.com/ee/development/telemetry/usage_ping.html) and reach out to @gitlab-org/growth/telemetry/engineers group for a review.
|
6
|
+
|
7
|
+
%<changed_files>s
|
8
|
+
|
9
|
+
MSG
|
10
|
+
|
11
|
+
tracking_files = [
|
12
|
+
'lib/gitlab/tracking.rb',
|
13
|
+
'spec/lib/gitlab/tracking_spec.rb',
|
14
|
+
'app/helpers/tracking_helper.rb',
|
15
|
+
'spec/helpers/tracking_helper_spec.rb',
|
16
|
+
'app/assets/javascripts/tracking.js',
|
17
|
+
'spec/frontend/tracking_spec.js'
|
18
|
+
]
|
19
|
+
|
20
|
+
usage_data_changed_files = git.modified_files.grep(%r{usage_data})
|
21
|
+
snowplow_events_changed_files = git.modified_files & tracking_files
|
22
|
+
|
23
|
+
changed_files = (usage_data_changed_files + snowplow_events_changed_files)
|
24
|
+
|
25
|
+
if changed_files.any?
|
26
|
+
warn format(TELEMETRY_CHANGED_FILES_MESSAGE, changed_files: helper.markdown_list(changed_files))
|
27
|
+
|
28
|
+
telemetry_labels = ['telemetry']
|
29
|
+
telemetry_labels << 'telemetry::review pending' unless helper.mr_has_labels?('telemetry::reviewed')
|
30
|
+
|
31
|
+
markdown(helper.prepare_labels_for_mr(telemetry_labels))
|
32
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
common = 'app/assets/stylesheets/framework/common.scss'
|
4
|
+
utilities = 'app/assets/stylesheets/utilities.scss'
|
5
|
+
|
6
|
+
def get_css_files(files, common_filepath, utilities_filepath)
|
7
|
+
files.select do |file|
|
8
|
+
file.include?(common_filepath) ||
|
9
|
+
file.include?(utilities_filepath)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
changed_util_files = get_css_files(helper.all_changed_files.to_a, common, utilities)
|
14
|
+
|
15
|
+
unless changed_util_files.empty?
|
16
|
+
|
17
|
+
markdown(<<~MARKDOWN)
|
18
|
+
## Changes to utility SCSS files
|
19
|
+
MARKDOWN
|
20
|
+
|
21
|
+
if changed_util_files.include?(common)
|
22
|
+
|
23
|
+
markdown(<<~MARKDOWN)
|
24
|
+
### Addition to `#{common}`
|
25
|
+
|
26
|
+
You have added a new rule to `#{common}`. Are you sure you need this rule?
|
27
|
+
|
28
|
+
If it is a component class shared across items, could it be added to the component as a utility class or to the component's stylesheet? If not, you can ignore this warning.
|
29
|
+
|
30
|
+
If it is a new utility class, is there another class that shares the same values in either this file or in `#{utilities}`? If not, please add it to `#{utilities}`, following the [Gitlab UI naming style](https://unpkg.com/browse/@gitlab/ui/src/scss/utilities.scss).
|
31
|
+
|
32
|
+
MARKDOWN
|
33
|
+
|
34
|
+
end
|
35
|
+
|
36
|
+
if changed_util_files.include?(utilities)
|
37
|
+
markdown(<<~MARKDOWN)
|
38
|
+
### Addition to `#{utilities}`
|
39
|
+
|
40
|
+
You have added a new rule to `#{utilities}`. Are you sure you need this rule?
|
41
|
+
|
42
|
+
If it is a component class shared across items, could it be added to the component as a utility class or to the component's stylesheet? If not, consider adding it to `#{common}`
|
43
|
+
|
44
|
+
If it is a new utility class, is there another class that shares the same values in either this file or in `#{utilities}`? If not, please be sure this addition follows the [Gitlab UI naming style](https://unpkg.com/browse/@gitlab/ui/src/scss/utilities.scss) so it may be removed when these rules are included. See [Include gitlab-ui utility-class library](https://gitlab.com/gitlab-org/gitlab/issues/36857) for more about this project.
|
45
|
+
|
46
|
+
MARKDOWN
|
47
|
+
end
|
48
|
+
|
49
|
+
warn "This merge request adds a new rule to #{common} or #{utilities}."
|
50
|
+
|
51
|
+
end
|