gitlab-dangerfiles 2.0.0 → 2.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 +4 -4
- data/.gitignore +1 -0
- data/.gitlab-ci.yml +36 -1
- data/README.md +11 -0
- data/lib/danger/plugins/helper.rb +10 -1
- data/lib/danger/rules/commit_messages/Dangerfile +139 -0
- data/lib/gitlab/dangerfiles/commit_linter.rb +6 -2
- data/lib/gitlab/dangerfiles/config.rb +6 -0
- data/lib/gitlab/dangerfiles/title_linting.rb +2 -0
- data/lib/gitlab/dangerfiles/version.rb +1 -1
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 30a4d627f19b9baece5e677425892f5ede2b883db11c57ae4178956975dcdb69
|
4
|
+
data.tar.gz: dfb9f139593171a0ddf7b075993ebe9419c0b32a33a391c5b7dfa4814871f553
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 504abc1a266560c6277dd9cb329b35894e2cdc958703403bdd88e3b2a7ad883860ed56be1bb14bf48529d0207b61f69a896260e4ab87cd0e251b373bcb902b18
|
7
|
+
data.tar.gz: ba5ff6ef20d7571c70a6bc4b130b5b54a89881c3757bf2b4c6949be6e7c441ba9deca33b13753be8428f0877663d24410a05a9aa3e45bac8fc2f5ff9e5a6aeae
|
data/.gitignore
CHANGED
data/.gitlab-ci.yml
CHANGED
@@ -11,7 +11,7 @@ workflow:
|
|
11
11
|
# For tags, create a pipeline.
|
12
12
|
- if: '$CI_COMMIT_TAG'
|
13
13
|
|
14
|
-
default:
|
14
|
+
.default:
|
15
15
|
image: ruby:2.7
|
16
16
|
tags:
|
17
17
|
- gitlab-org
|
@@ -29,15 +29,50 @@ default:
|
|
29
29
|
policy: pull
|
30
30
|
|
31
31
|
test:rspec:
|
32
|
+
extends: .default
|
32
33
|
stage: test
|
33
34
|
script:
|
34
35
|
- bundle exec rspec
|
35
36
|
|
36
37
|
test:rufo:
|
38
|
+
extends: .default
|
37
39
|
stage: test
|
38
40
|
script:
|
39
41
|
- bundle exec rufo --check .
|
40
42
|
|
41
43
|
include:
|
44
|
+
- template: Security/Dependency-Scanning.gitlab-ci.yml
|
45
|
+
- template: Security/License-Scanning.gitlab-ci.yml
|
46
|
+
- template: Security/SAST.gitlab-ci.yml
|
47
|
+
- template: Security/Secret-Detection.gitlab-ci.yml
|
42
48
|
- project: 'gitlab-org/quality/pipeline-common'
|
43
49
|
file: '/ci/gem-release.yml'
|
50
|
+
|
51
|
+
# run security jobs on MRs
|
52
|
+
# see: https://gitlab.com/gitlab-org/gitlab/-/issues/218444#note_478761991
|
53
|
+
|
54
|
+
brakeman-sast:
|
55
|
+
rules:
|
56
|
+
- if: '$CI_MERGE_REQUEST_IID'
|
57
|
+
- if: '$CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH'
|
58
|
+
|
59
|
+
gemnasium-dependency_scanning:
|
60
|
+
rules:
|
61
|
+
- if: '$CI_MERGE_REQUEST_IID'
|
62
|
+
- if: '$CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH'
|
63
|
+
|
64
|
+
bundler-audit-dependency_scanning:
|
65
|
+
rules:
|
66
|
+
- if: '$CI_MERGE_REQUEST_IID'
|
67
|
+
- if: '$CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH'
|
68
|
+
|
69
|
+
license_scanning:
|
70
|
+
rules:
|
71
|
+
- if: '$CI_MERGE_REQUEST_IID'
|
72
|
+
- if: '$CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH'
|
73
|
+
|
74
|
+
secret_detection:
|
75
|
+
rules:
|
76
|
+
- if: '$CI_MERGE_REQUEST_IID'
|
77
|
+
- if: '$CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH'
|
78
|
+
|
data/README.md
CHANGED
@@ -64,6 +64,17 @@ Danger rules are located under `lib/danger/rules`.
|
|
64
64
|
`:high` is the lines changed threshold which triggers an error, and
|
65
65
|
`:medium` is the lines changed threshold which triggers a warning.
|
66
66
|
|
67
|
+
#### `commit_messages`
|
68
|
+
|
69
|
+
##### Available configurations
|
70
|
+
|
71
|
+
- `max_commits_count`: The maximum number of allowed non-squashed/non-fixup commits for a given MR.
|
72
|
+
A warning is triggered if the MR has more commits.
|
73
|
+
|
74
|
+
## Documentation
|
75
|
+
|
76
|
+
Latest documentation can be found at <https://www.rubydoc.info/gems/gitlab-dangerfiles>.
|
77
|
+
|
67
78
|
## Development
|
68
79
|
|
69
80
|
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
@@ -283,9 +283,18 @@ module Danger
|
|
283
283
|
gitlab_helper.mr_json["target_branch"]
|
284
284
|
end
|
285
285
|
|
286
|
+
# @return [Boolean] +true+ when not in the CI context, and whether the MR is set to be squashed otherwise.
|
287
|
+
def squash_mr?
|
288
|
+
return true unless ci?
|
289
|
+
|
290
|
+
gitlab.mr_json["squash"]
|
291
|
+
end
|
292
|
+
|
286
293
|
# @return [Boolean] whether a MR is a Draft or not.
|
287
294
|
def draft_mr?
|
288
|
-
|
295
|
+
return false unless ci?
|
296
|
+
|
297
|
+
gitlab.mr_json["work_in_progress"]
|
289
298
|
end
|
290
299
|
|
291
300
|
# @return [Boolean] whether a MR is opened in the security mirror or not.
|
@@ -0,0 +1,139 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "../../../gitlab/dangerfiles/commit_linter"
|
4
|
+
require_relative "../../../gitlab/dangerfiles/merge_request_linter"
|
5
|
+
|
6
|
+
COMMIT_MESSAGE_GUIDELINES = "https://docs.gitlab.com/ee/development/contributing/merge_request_workflow.html#commit-messages-guidelines"
|
7
|
+
MORE_INFO = "For more information, take a look at our [Commit message guidelines](#{COMMIT_MESSAGE_GUIDELINES})."
|
8
|
+
THE_DANGER_JOB_TEXT = "the `%<job_name>` job"
|
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
|
+
max_commits_count = helper.config.max_commits_count
|
21
|
+
|
22
|
+
def fail_commit(commit, message, more_info: true)
|
23
|
+
self.fail(build_message(commit, message, more_info: more_info))
|
24
|
+
end
|
25
|
+
|
26
|
+
def warn_commit(commit, message, more_info: true)
|
27
|
+
self.warn(build_message(commit, message, more_info: more_info))
|
28
|
+
end
|
29
|
+
|
30
|
+
def build_message(commit, message, more_info: true)
|
31
|
+
[message].tap do |full_message|
|
32
|
+
full_message << ". #{MORE_INFO}" if more_info
|
33
|
+
full_message.unshift("#{commit.sha}: ") if commit.sha
|
34
|
+
end.join
|
35
|
+
end
|
36
|
+
|
37
|
+
def danger_job_link
|
38
|
+
helper.ci? ? "[#{format(THE_DANGER_JOB_TEXT, job_name: ENV["CI_JOB_NAME"])}](#{ENV['CI_JOB_URL']})" : THE_DANGER_JOB_TEXT
|
39
|
+
end
|
40
|
+
|
41
|
+
# Perform various checks against commits. We're not using
|
42
|
+
# https://github.com/jonallured/danger-commit_lint because its output is not
|
43
|
+
# very helpful, and it doesn't offer the means of ignoring merge commits.
|
44
|
+
def lint_commit(commit)
|
45
|
+
linter = Gitlab::Dangerfiles::CommitLinter.new(commit)
|
46
|
+
|
47
|
+
# For now we'll ignore merge commits, as getting rid of those is a problem
|
48
|
+
# separate from enforcing good commit messages.
|
49
|
+
return linter if linter.merge?
|
50
|
+
|
51
|
+
# We ignore revert commits as they are well structured by Git already
|
52
|
+
return linter if linter.revert?
|
53
|
+
|
54
|
+
# If MR is set to squash, we ignore fixup commits
|
55
|
+
return linter if linter.fixup? && helper.squash_mr?
|
56
|
+
|
57
|
+
if linter.fixup?
|
58
|
+
msg = "Squash or fixup commits must be squashed before merge, or enable squash merge option and re-run #{danger_job_link}."
|
59
|
+
if helper.draft_mr? || helper.squash_mr?
|
60
|
+
warn_commit(commit, msg, more_info: false)
|
61
|
+
else
|
62
|
+
fail_commit(commit, msg, more_info: false)
|
63
|
+
end
|
64
|
+
|
65
|
+
# Makes no sense to process other rules for fixup commits, they trigger just more noise
|
66
|
+
return linter
|
67
|
+
end
|
68
|
+
|
69
|
+
# Fail if a suggestion commit is used and squash is not enabled
|
70
|
+
if linter.suggestion?
|
71
|
+
unless helper.squash_mr?
|
72
|
+
fail_commit(commit, "If you are applying suggestions, enable squash in the merge request and re-run #{danger_job_link}.", more_info: false)
|
73
|
+
end
|
74
|
+
|
75
|
+
return linter
|
76
|
+
end
|
77
|
+
|
78
|
+
linter.lint
|
79
|
+
end
|
80
|
+
|
81
|
+
def lint_mr_title(mr_title)
|
82
|
+
commit = Struct.new(:message, :sha).new(mr_title)
|
83
|
+
|
84
|
+
Gitlab::Dangerfiles::MergeRequestLinter.new(commit).lint
|
85
|
+
end
|
86
|
+
|
87
|
+
def count_non_fixup_commits(commit_linters)
|
88
|
+
commit_linters.count { |commit_linter| !commit_linter.fixup? }
|
89
|
+
end
|
90
|
+
|
91
|
+
def lint_commits(commits)
|
92
|
+
commit_linters = commits.map { |commit| lint_commit(commit) }
|
93
|
+
|
94
|
+
if helper.squash_mr?
|
95
|
+
multi_line_commit_linter = commit_linters.detect { |commit_linter| !commit_linter.merge? && commit_linter.multi_line? }
|
96
|
+
|
97
|
+
if multi_line_commit_linter && multi_line_commit_linter.failed?
|
98
|
+
warn_or_fail_commits(multi_line_commit_linter)
|
99
|
+
commit_linters.delete(multi_line_commit_linter) # Don't show an error (here) and a warning (below)
|
100
|
+
elsif helper.ci? # We don't have access to the MR title locally
|
101
|
+
title_linter = lint_mr_title(gitlab.mr_json['title'])
|
102
|
+
if title_linter.failed?
|
103
|
+
warn_or_fail_commits(title_linter)
|
104
|
+
end
|
105
|
+
end
|
106
|
+
else
|
107
|
+
if count_non_fixup_commits(commit_linters) > max_commits_count
|
108
|
+
self.warn(format(MAX_COMMITS_COUNT_EXCEEDED_MESSAGE, max_commits_count: max_commits_count))
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
failed_commit_linters = commit_linters.select { |commit_linter| commit_linter.failed? }
|
113
|
+
warn_or_fail_commits(failed_commit_linters, default_to_fail: !helper.squash_mr?)
|
114
|
+
end
|
115
|
+
|
116
|
+
def warn_or_fail_commits(failed_linters, default_to_fail: true)
|
117
|
+
level = default_to_fail ? :fail : :warn
|
118
|
+
|
119
|
+
Array(failed_linters).each do |linter|
|
120
|
+
linter.problems.each do |problem_key, problem_desc|
|
121
|
+
case problem_key
|
122
|
+
when :subject_too_short, :subject_above_warning, :details_too_many_changes, :details_line_too_long
|
123
|
+
warn_commit(linter.commit, problem_desc)
|
124
|
+
else
|
125
|
+
self.__send__("#{level}_commit", linter.commit, problem_desc) # rubocop:disable GitlabSecurity/PublicSend
|
126
|
+
end
|
127
|
+
end
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
# As part of https://gitlab.com/groups/gitlab-org/-/epics/4826 we are
|
132
|
+
# vendoring workhorse commits from the stand-alone gitlab-workhorse
|
133
|
+
# repo. There is no point in linting commits that we want to vendor as
|
134
|
+
# is.
|
135
|
+
def workhorse_changes?
|
136
|
+
git.diff.any? { |file| file.path.start_with?('workhorse/') }
|
137
|
+
end
|
138
|
+
|
139
|
+
lint_commits(git.commits) unless workhorse_changes?
|
@@ -8,7 +8,10 @@ module Gitlab
|
|
8
8
|
class CommitLinter < BaseLinter
|
9
9
|
MAX_CHANGED_FILES_IN_COMMIT = 3
|
10
10
|
MAX_CHANGED_LINES_IN_COMMIT = 30
|
11
|
-
|
11
|
+
# Issue, MR, Epic
|
12
|
+
SHORT_REFERENCE_REGEX = %r{([\w\-\/]+)?(?<!`)(#|!|&)\d+(?<!`)}.freeze
|
13
|
+
# Milestone
|
14
|
+
MS_SHORT_REFERENCE_REGEX = %r{([\w\-\/]+)?(?<!`)%"?\d{1,3}\.\d{1,3}"?(?<!`)}.freeze
|
12
15
|
|
13
16
|
def self.problems_mapping
|
14
17
|
super.merge(
|
@@ -139,7 +142,8 @@ module Gitlab
|
|
139
142
|
end
|
140
143
|
|
141
144
|
def message_contains_short_reference?
|
142
|
-
commit.message.match?(SHORT_REFERENCE_REGEX)
|
145
|
+
commit.message.match?(SHORT_REFERENCE_REGEX) ||
|
146
|
+
commit.message.match?(MS_SHORT_REFERENCE_REGEX)
|
143
147
|
end
|
144
148
|
|
145
149
|
def emoji_checker
|
@@ -7,10 +7,16 @@ module Gitlab
|
|
7
7
|
# @return [{ high: Integer, medium: Integer }] a hash of the form +{ high: 42, medium: 12 }+ where +:high+ is the lines changed threshold which triggers an error, and +:medium+ is the lines changed threshold which triggers a warning. Also, see +DEFAULT_CHANGES_SIZE_THRESHOLDS+ for the format of the hash.
|
8
8
|
attr_accessor :code_size_thresholds
|
9
9
|
|
10
|
+
# @!attribute max_commits_count
|
11
|
+
# @return [Integer] the maximum number of allowed non-squashed/non-fixup commits for a given MR. A warning is triggered if the MR has more commits.
|
12
|
+
attr_accessor :max_commits_count
|
13
|
+
|
10
14
|
DEFAULT_CHANGES_SIZE_THRESHOLDS = { high: 2_000, medium: 500 }.freeze
|
15
|
+
DEFAULT_COMMIT_MESSAGES_MAX_COMMITS_COUNT = 10
|
11
16
|
|
12
17
|
def initialize
|
13
18
|
@code_size_thresholds = DEFAULT_CHANGES_SIZE_THRESHOLDS
|
19
|
+
@max_commits_count = DEFAULT_COMMIT_MESSAGES_MAX_COMMITS_COUNT
|
14
20
|
end
|
15
21
|
end
|
16
22
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: gitlab-dangerfiles
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- GitLab
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-
|
11
|
+
date: 2021-06-11 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: danger-gitlab
|
@@ -134,6 +134,7 @@ files:
|
|
134
134
|
- lib/danger/plugins/helper.rb
|
135
135
|
- lib/danger/plugins/roulette.rb
|
136
136
|
- lib/danger/rules/changes_size/Dangerfile
|
137
|
+
- lib/danger/rules/commit_messages/Dangerfile
|
137
138
|
- lib/gitlab-dangerfiles.rb
|
138
139
|
- lib/gitlab/Dangerfile
|
139
140
|
- lib/gitlab/dangerfiles.rb
|