Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'tooling/danger/changelog.rb')
-rw-r--r--tooling/danger/changelog.rb161
1 files changed, 45 insertions, 116 deletions
diff --git a/tooling/danger/changelog.rb b/tooling/danger/changelog.rb
index e11799b268d..c053d366199 100644
--- a/tooling/danger/changelog.rb
+++ b/tooling/danger/changelog.rb
@@ -13,66 +13,31 @@ module Tooling
'meta'
].freeze
NO_CHANGELOG_CATEGORIES = %i[docs none].freeze
- CHANGELOG_TRAILER_REGEX = /^Changelog:\s*(?<category>.+)$/.freeze
- CREATE_CHANGELOG_COMMAND = 'bin/changelog -m %<mr_iid>s "%<mr_title>s"'
- CREATE_EE_CHANGELOG_COMMAND = 'bin/changelog --ee -m %<mr_iid>s "%<mr_title>s"'
+ CHANGELOG_TRAILER_REGEX = /^(?<name>Changelog):\s*(?<category>.+)$/i.freeze
+ CHANGELOG_EE_TRAILER_REGEX = /^EE: true$/.freeze
CHANGELOG_MODIFIED_URL_TEXT = "**CHANGELOG.md was edited.** Please remove the additions and follow the [changelog guidelines](https://docs.gitlab.com/ee/development/changelog.html).\n\n"
CHANGELOG_MISSING_URL_TEXT = "**[CHANGELOG missing](https://docs.gitlab.com/ee/development/changelog.html)**:\n\n"
OPTIONAL_CHANGELOG_MESSAGE = {
local: "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.",
ci: <<~MSG
- If you want to create a changelog entry for GitLab FOSS, run the following:
+ If you want to create a changelog entry for GitLab FOSS, add the `Changelog` trailer to the commit message you want to add to the changelog.
- #{CREATE_CHANGELOG_COMMAND}
-
- If you want to create a changelog entry for GitLab EE, run the following instead:
-
- #{CREATE_EE_CHANGELOG_COMMAND}
+ If you want to create a changelog entry for GitLab EE, also [add the `EE: true` trailer](https://docs.gitlab.com/ee/development/changelog.html#gitlab-enterprise-changes) to your commit message.
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.
MSG
}.freeze
- CHANGELOG_NEW_WORKFLOW_MESSAGE = <<~MSG
- We are in the process of rolling out a new workflow for adding changelog entries. This new workflow uses Git commit subjects and Git trailers to generate changelogs. This new approach will soon replace the current YAML based approach.
-
- To ease the transition process, we recommend you start using both the old and new approach in parallel. This is not required at this time, but will make it easier to transition to the new approach in the future. To do so, pick the commit that should go in the changelog and add a `Changelog` trailer to it. For example:
-
- ```
- This is my commit's subject line
-
- This is the optional commit body.
-
- Changelog: added
- ```
-
- The value of the `Changelog` trailer should be one of the following: added, fixed, changed, deprecated, removed, security, performance, other.
-
- For more information, take a look at the following resources:
-
- - `https://gitlab.com/gitlab-com/gl-infra/delivery/-/issues/1564`
- - https://docs.gitlab.com/ee/api/repositories.html#generate-changelog-data
-
- If you'd like to see the new approach in action, take a look at the commits in [the Omnibus repository](https://gitlab.com/gitlab-org/omnibus-gitlab/-/commits/master).
- MSG
SEE_DOC = "See the [changelog documentation](https://docs.gitlab.com/ee/development/changelog.html)."
- SUGGEST_MR_COMMENT = <<~SUGGEST_COMMENT
- ```suggestion
- merge_request: %<mr_iid>s
- ```
-
- #{SEE_DOC}
- SUGGEST_COMMENT
REQUIRED_CHANGELOG_REASONS = {
+ db_changes: 'introduces a database migration',
feature_flag_removed: 'removes a feature flag'
}.freeze
REQUIRED_CHANGELOG_MESSAGE = {
local: "This merge request requires a changelog entry because it [%<reason>s](https://docs.gitlab.com/ee/development/changelog.html#what-warrants-a-changelog-entry).",
ci: <<~MSG
- To create a changelog entry, run the following:
-
- #{CREATE_CHANGELOG_COMMAND}
+ To create a changelog entry, add the `Changelog` trailer to one of your Git commit messages.
This merge request requires a changelog entry because it [%<reason>s](https://docs.gitlab.com/ee/development/changelog.html#what-warrants-a-changelog-entry).
MSG
@@ -131,7 +96,6 @@ module Tooling
end
if present?
- add_danger_messages(check_changelog_yaml)
add_danger_messages(check_changelog_path)
elsif required?
required_texts.each { |_, text| fail(text) } # rubocop:disable Lint/UnreachableLoop
@@ -139,23 +103,7 @@ module Tooling
message optional_text
end
- return unless helper.ci?
-
- if required? || optional?
- checked = 0
-
- git.commits.each do |commit|
- check_result = check_changelog_trailer(commit)
- next if check_result.nil?
-
- checked += 1
- add_danger_messages(check_result)
- end
-
- if checked == 0
- message CHANGELOG_NEW_WORKFLOW_MESSAGE
- end
- end
+ check_changelog_commit_categories
end
# rubocop:enable Style/SignalException
@@ -168,70 +116,42 @@ module Tooling
end
# rubocop:enable Style/SignalException
+ def check_changelog_commit_categories
+ changelog_commits.each do |commit|
+ add_danger_messages(check_changelog_trailer(commit))
+ end
+ end
+
def check_changelog_trailer(commit)
trailer = commit.message.match(CHANGELOG_TRAILER_REGEX)
-
- return if trailer.nil? || trailer[:category].nil?
-
+ name = trailer[:name]
category = trailer[:category]
+ unless name == 'Changelog'
+ return ChangelogCheckResult.error("The changelog trailer for commit #{commit.sha} must be `Changelog` (starting with a capital C), not `#{name}`")
+ end
+
return ChangelogCheckResult.empty if CATEGORIES.include?(category)
ChangelogCheckResult.error("Commit #{commit.sha} uses an invalid changelog category: #{category}")
end
- def check_changelog_yaml
- check_result = ChangelogCheckResult.empty
- return check_result unless present?
-
- raw_file = read_file(changelog_path)
- yaml = YAML.safe_load(raw_file)
- yaml_merge_request = yaml["merge_request"].to_s
-
- check_result.error("`title` should be set, in #{helper.html_link(changelog_path)}! #{SEE_DOC}") if yaml["title"].nil?
- check_result.error("`type` should be set, in #{helper.html_link(changelog_path)}! #{SEE_DOC}") if yaml["type"].nil?
-
- return check_result if helper.security_mr? || helper.mr_iid.empty?
-
- check_changelog_yaml_merge_request(raw_file: raw_file, yaml_merge_request: yaml_merge_request, check_result: check_result)
- rescue Psych::Exception
- # YAML could not be parsed, fail the build.
- ChangelogCheckResult.error("#{helper.html_link(changelog_path)} isn't valid YAML! #{SEE_DOC}")
- rescue StandardError => e
- ChangelogCheckResult.warning("There was a problem trying to check the Changelog. Exception: #{e.class.name} - #{e.message}")
- end
-
- def check_changelog_yaml_merge_request(raw_file:, yaml_merge_request:, check_result:)
- cherry_pick_against_stable_branch = helper.cherry_pick_mr? && helper.stable_branch?
-
- if yaml_merge_request.empty?
- mr_line = raw_file.lines.find_index { |line| line =~ /merge_request:\s*\n/ }
-
- if mr_line
- check_result.markdown(msg: format(SUGGEST_MR_COMMENT, mr_iid: helper.mr_iid), file: changelog_path, line: mr_line.succ)
- else
- check_result.message("Consider setting `merge_request` to #{helper.mr_iid} in #{helper.html_link(changelog_path)}. #{SEE_DOC}")
- end
- elsif yaml_merge_request != helper.mr_iid && !cherry_pick_against_stable_branch
- check_result.error("Merge request ID was not set to #{helper.mr_iid}! #{SEE_DOC}")
- end
-
- check_result
- end
-
def check_changelog_path
check_result = ChangelogCheckResult.empty
return check_result unless present?
ee_changes = project_helper.all_ee_changes.dup
- ee_changes.delete(changelog_path)
if ee_changes.any? && !ee_changelog? && !required?
- check_result.warning("This MR has a Changelog file outside `ee/`, but code changes in `ee/`. Consider moving the Changelog file into `ee/`.")
+ check_result.warning("This MR changes code in `ee/`, but its Changelog commit is missing the [`EE: true` trailer](https://docs.gitlab.com/ee/development/changelog.html#gitlab-enterprise-changes). Consider adding it to your Changelog commits.")
end
if ee_changes.empty? && ee_changelog?
- check_result.warning("This MR has a Changelog file in `ee/`, but no code changes in `ee/`. Consider moving the Changelog file outside `ee/`.")
+ check_result.warning("This MR has a Changelog commit for EE, but no code changes in `ee/`. Consider removing the `EE: true` trailer from your commits.")
+ end
+
+ if ee_changes.any? && ee_changelog? && required_reasons.include?(:db_changes)
+ check_result.warning("This MR has a Changelog commit with the `EE: true` trailer, but there are database changes which [requires](https://docs.gitlab.com/ee/development/changelog.html#what-warrants-a-changelog-entry) the Changelog commit to not have the `EE: true` trailer. Consider removing the `EE: true` trailer from your commits.")
end
check_result
@@ -239,6 +159,7 @@ module Tooling
def required_reasons
[].tap do |reasons|
+ reasons << :db_changes if project_helper.changes.added.has_category?(:migration)
reasons << :feature_flag_removed if project_helper.changes.deleted.has_category?(:feature_flag)
end
end
@@ -252,33 +173,45 @@ module Tooling
end
def present?
- !!changelog_path
+ valid_changelog_commits.any?
end
- def ee_changelog?
- changelog_path.start_with?('ee/')
+ def changelog_commits
+ git.commits.select do |commit|
+ commit.message.match?(CHANGELOG_TRAILER_REGEX)
+ end
+ end
+
+ def valid_changelog_commits
+ changelog_commits.select do |commit|
+ trailer = commit.message.match(CHANGELOG_TRAILER_REGEX)
+
+ CATEGORIES.include?(trailer[:category])
+ end
end
- def changelog_path
- @changelog_path ||= project_helper.changes.added.by_category(:changelog).files.first
+ def ee_changelog?
+ changelog_commits.any? do |commit|
+ commit.message.match?(CHANGELOG_EE_TRAILER_REGEX)
+ end
end
def modified_text
CHANGELOG_MODIFIED_URL_TEXT +
- (helper.ci? ? format(OPTIONAL_CHANGELOG_MESSAGE[:ci], mr_iid: helper.mr_iid, mr_title: sanitized_mr_title) : OPTIONAL_CHANGELOG_MESSAGE[:local])
+ (helper.ci? ? format(OPTIONAL_CHANGELOG_MESSAGE[:ci]) : OPTIONAL_CHANGELOG_MESSAGE[:local])
end
def required_texts
required_reasons.each_with_object({}) do |required_reason, memo|
memo[required_reason] =
CHANGELOG_MISSING_URL_TEXT +
- (helper.ci? ? format(REQUIRED_CHANGELOG_MESSAGE[:ci], reason: REQUIRED_CHANGELOG_REASONS.fetch(required_reason), mr_iid: helper.mr_iid, mr_title: sanitized_mr_title) : REQUIRED_CHANGELOG_MESSAGE[:local])
+ (helper.ci? ? format(REQUIRED_CHANGELOG_MESSAGE[:ci], reason: REQUIRED_CHANGELOG_REASONS.fetch(required_reason)) : REQUIRED_CHANGELOG_MESSAGE[:local])
end
end
def optional_text
CHANGELOG_MISSING_URL_TEXT +
- (helper.ci? ? format(OPTIONAL_CHANGELOG_MESSAGE[:ci], mr_iid: helper.mr_iid, mr_title: sanitized_mr_title) : OPTIONAL_CHANGELOG_MESSAGE[:local])
+ (helper.ci? ? format(OPTIONAL_CHANGELOG_MESSAGE[:ci]) : OPTIONAL_CHANGELOG_MESSAGE[:local])
end
private
@@ -287,10 +220,6 @@ module Tooling
File.read(path)
end
- def sanitized_mr_title
- Gitlab::Dangerfiles::TitleLinting.sanitize_mr_title(helper.mr_title)
- end
-
def categories_need_changelog?
(project_helper.changes.categories - NO_CHANGELOG_CATEGORIES).any?
end