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

gitlab.com/gitlab-org/gitaly.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYorick Peterse <yorick@yorickpeterse.com>2021-05-18 18:07:56 +0300
committerYorick Peterse <yorick@yorickpeterse.com>2021-05-21 16:54:49 +0300
commitbe63f02ea121c07e0b4a55ee8fa37a418d41ceb5 (patch)
treed3a87d8390c41aaa3804b144839c956fe8f13801
parent98b62a8e6b2b87ad6fbfb70f706274ee91e953d8 (diff)
Update tooling for the new changelog workflow
Similar to https://gitlab.com/gitlab-org/gitlab/-/merge_requests/62012, this updates Gitaly's CI tooling for the new changelog workflow.
-rwxr-xr-x_support/changelog243
-rw-r--r--danger/changelog/Dangerfile141
2 files changed, 43 insertions, 341 deletions
diff --git a/_support/changelog b/_support/changelog
deleted file mode 100755
index 4abb9da2c..000000000
--- a/_support/changelog
+++ /dev/null
@@ -1,243 +0,0 @@
-#!/usr/bin/env ruby
-#
-# Generate a changelog entry file in the correct location.
-#
-# Automatically stages the file and amends the previous commit if the `--amend`
-# argument is used.
-#
-# Lifted from gitlab-org/gitlab-ce
-
-require 'optparse'
-require 'yaml'
-
-Options = Struct.new(
- :amend,
- :author,
- :dry_run,
- :force,
- :merge_request,
- :title,
- :type
-)
-INVALID_TYPE = -1
-
-class ChangelogOptionParser
- Type = Struct.new(:name, :description)
- TYPES = [
- Type.new('added', 'New feature'),
- Type.new('fixed', 'Bug fix'),
- Type.new('changed', 'Feature change'),
- Type.new('deprecated', 'New deprecation'),
- Type.new('removed', 'Feature removal'),
- Type.new('security', 'Security fix'),
- Type.new('performance', 'Performance improvement'),
- Type.new('other', 'Other')
- ].freeze
- TYPES_OFFSET = 1
-
- class << self
- def parse(argv)
- options = Options.new
-
- parser = OptionParser.new do |opts|
- opts.banner = "Usage: #{__FILE__} [options] [title]\n\n"
-
- # Note: We do not provide a shorthand for this in order to match the `git
- # commit` interface
- opts.on('--amend', 'Amend the previous commit') do |value|
- options.amend = value
- end
-
- opts.on('-f', '--force', 'Overwrite an existing entry') do |value|
- options.force = value
- end
-
- opts.on('-m', '--merge-request [integer]', Integer, 'Merge Request ID') do |value|
- options.merge_request = value
- end
-
- opts.on('-n', '--dry-run', "Don't actually write anything, just print") do |value|
- options.dry_run = value
- end
-
- opts.on('-u', '--git-username', 'Use Git user.name configuration as the author') do |value|
- options.author = git_user_name if value
- end
-
- opts.on('-t', '--type [string]', String, "The category of the change, valid options are: #{TYPES.map(&:name).join(', ')}") do |value|
- options.type = parse_type(value)
- end
-
- opts.on('-h', '--help', 'Print help message') do
- $stdout.puts opts
- exit
- end
- end
-
- parser.parse!(argv)
-
- # Title is everything that remains, but let's clean it up a bit
- options.title = argv.join(' ').strip.squeeze(' ').tr("\r\n", '')
-
- options
- end
-
- def read_type
- read_type_message
-
- type = TYPES[$stdin.getc.to_i - TYPES_OFFSET]
- assert_valid_type!(type)
-
- type.name
- end
-
- private
-
- def parse_type(name)
- type_found = TYPES.find do |type|
- type.name == name
- end
- type_found ? type_found.name : INVALID_TYPE
- end
-
- def read_type_message
- $stdout.puts "\n>> Please specify the index for the category of your change:"
- TYPES.each_with_index do |type, index|
- $stdout.puts "#{index + TYPES_OFFSET}. #{type.description}"
- end
- $stdout.print "\n?> "
- end
-
- def assert_valid_type!(type)
- unless type
- $stderr.puts "Invalid category index, please select an index between 1 and #{TYPES.length}"
- exit 1
- end
- end
-
- def git_user_name
- %x{git config user.name}.strip
- end
- end
-end
-
-class ChangelogEntry
- attr_reader :options
-
- def initialize(options)
- @options = options
-
- assert_feature_branch!
- assert_title!
- assert_new_file!
-
- # Read type from $stdin unless is already set
- options.type ||= ChangelogOptionParser.read_type
- assert_valid_type!
-
- $stdout.puts "\e[32mcreate\e[0m #{file_path}"
- $stdout.puts contents
-
- unless options.dry_run
- write
- amend_commit if options.amend
- end
- end
-
- private
-
- def contents
- yaml_content = YAML.dump(
- 'title' => title,
- 'merge_request' => options.merge_request,
- 'author' => options.author,
- 'type' => options.type
- )
- remove_trailing_whitespace(yaml_content)
- end
-
- def write
- File.write(file_path, contents)
- end
-
- def amend_commit
- %x{git add #{file_path}}
- exec("git commit --amend")
- end
-
- def fail_with(message)
- $stderr.puts "\e[31merror\e[0m #{message}"
- exit 1
- end
-
- def assert_feature_branch!
- return unless branch_name == 'master'
-
- fail_with "Create a branch first!"
- end
-
- def assert_new_file!
- return unless File.exist?(file_path)
- return if options.force
-
- fail_with "#{file_path} already exists! Use `--force` to overwrite."
- end
-
- def assert_title!
- return if options.title.length > 0 || options.amend
-
- fail_with "Provide a title for the changelog entry or use `--amend`" \
- " to use the title from the previous commit."
- end
-
- def assert_valid_type!
- return unless options.type && options.type == INVALID_TYPE
-
- fail_with 'Invalid category given!'
- end
-
- def title
- if options.title.empty?
- last_commit_subject
- else
- options.title
- end
- end
-
- def last_commit_subject
- %x{git log --format="%s" -1}.strip
- end
-
- def file_path
- File.join(
- unreleased_path,
- branch_name.gsub(/[^\w-]/, '-') << '.yml'
- )
- end
-
- def unreleased_path
- path = File.join('changelogs', 'unreleased')
- path = File.join('ee', path) if ee?
-
- path
- end
-
- def ee?
- @ee ||= File.exist?(File.expand_path('../CHANGELOG-EE.md', __dir__))
- end
-
- def branch_name
- @branch_name ||= %x{git symbolic-ref --short HEAD}.strip
- end
-
- def remove_trailing_whitespace(yaml_content)
- yaml_content.gsub(/ +$/, '')
- end
-end
-
-if $0 == __FILE__
- options = ChangelogOptionParser.parse(ARGV)
- ChangelogEntry.new(options)
-end
-
-# vim: ft=ruby
diff --git a/danger/changelog/Dangerfile b/danger/changelog/Dangerfile
index 1a7029768..56efe44de 100644
--- a/danger/changelog/Dangerfile
+++ b/danger/changelog/Dangerfile
@@ -1,33 +1,33 @@
-# frozen_string_literal: true
require 'yaml'
+def lint_commit(commit)
+ trailer = commit.message.match(/^Changelog:\s*(?<category>\w+)/)
+
+ return :missing if trailer.nil? || trailer[:category].nil?
+
+ category = trailer[:category]
+
+ return :valid if CATEGORIES.include?(category)
+
+ self.fail(
+ "Commit #{commit.sha} uses an invalid changelog category: #{category}"
+ )
+
+ :invalid
+end
+
+def presented_no_changelog_labels
+ NO_CHANGELOG_LABELS.map { |label| %(~"#{label}") }.join(', ')
+end
+
NO_CHANGELOG_LABELS = [
+ 'documentation',
'tooling',
'tooling::pipelines',
'tooling::workflow',
'ci-build',
- 'meta',
- 'documentation'
+ 'meta'
].freeze
-SEE_DOC = "See the [changelog documentation](https://docs.gitlab.com/ee/development/changelog.html)."
-CREATE_CHANGELOG_MESSAGE = <<~MSG
-You can create one with:
-
-```
-_support/changelog -m %<mr_iid>s "%<mr_title>s"
-```
-
-If your merge request doesn't warrant a CHANGELOG entry,
-consider adding any of the %<labels>s labels.
-MSG
-
-SUGGEST_MR_COMMENT = <<~SUGGEST_COMMENT
-```suggestion
-merge_request: %<mr_iid>s
-```
-
-#{SEE_DOC}
-SUGGEST_COMMENT
CATEGORIES = YAML
.load_file(File.expand_path('../../.gitlab/changelog_config.yml', __dir__))
@@ -35,102 +35,47 @@ CATEGORIES = YAML
.keys
.freeze
-def check_changelog_trailer(commit)
- trailer = commit.message.match(/^Changelog:\s*(?<category>.+)$/)
+SEE_DOC = "See [the documentation](https://docs.gitlab.com/ee/development/changelog.html).".freeze
- return :missing if trailer.nil? || trailer[:category].nil?
+CHANGELOG_MISSING = <<~MSG.freeze
+**[CHANGELOG missing](https://docs.gitlab.com/ee/development/changelog.html).**
- category = trailer[:category]
+To ceate a changelog, annotate one or more commits with the `Changelog` Git
+trailer. If you want to annotate the latest commit, you can do so using `git
+commit --amend`. If you want to annotate older or multiple commits, you need to
+do so using `git rebase -i`.
- return :valid if CATEGORIES.include?(category)
+When adding the trailer, you can use the following values:
- self.fail(
- "Commit #{commit.sha} uses an invalid changelog category: #{category}"
- )
+- #{CATEGORIES.join("\n- ")}
- :invalid
-end
+For example:
-def check_changelog(path)
- raw_file = File.read(path)
- yaml = YAML.safe_load(raw_file)
+```
+This is the subject of your commit.
- fail "`title` should be set, in #{gitlab.html_link(path)}! #{SEE_DOC}" if yaml["title"].nil?
- fail "`type` should be set, in #{gitlab.html_link(path)}! #{SEE_DOC}" if yaml["type"].nil?
+This would be the body of your commit containing some extra details.
- if yaml["merge_request"].nil?
- mr_line = raw_file.lines.find_index { |l| l.start_with?("merge_request:") }
+Changelog: added
+```
- if mr_line
- markdown(format(SUGGEST_MR_COMMENT, mr_iid: gitlab.mr_json["iid"]), file: path, line: mr_line.succ)
- else
- message "Consider setting `merge_request` to #{gitlab.mr_json["iid"]} in #{gitlab.html_link(path)}. #{SEE_DOC}"
- end
- elsif yaml["merge_request"] != gitlab.mr_json["iid"]
- fail "Merge request ID was not set to #{gitlab.mr_json["iid"]}! #{SEE_DOC}"
- end
-rescue Psych::SyntaxError, Psych::DisallowedClass, Psych::BadAlias
- # YAML could not be parsed, fail the build.
- fail "#{gitlab.html_link(path)} isn't valid YAML! #{SEE_DOC}"
-rescue StandardError => e
- warn "There was a problem trying to check the Changelog. Exception: #{e.name} - #{e.message}"
-end
+If your merge request doesn't warrant a CHANGELOG entry, consider adding any of
+the #{presented_no_changelog_labels} labels.
-def presented_no_changelog_labels
- NO_CHANGELOG_LABELS.map { |label| %Q(~\\"#{label}\\") }.join(', ')
-end
+#{SEE_DOC}
+MSG
changelog_needed = (gitlab.mr_labels & NO_CHANGELOG_LABELS).empty?
-changelog_found = git.added_files.find { |path| path =~ %r{\Achangelogs/unreleased/} }
-
-mr_title = gitlab.mr_json["title"].gsub(/^WIP: */, '')
-
-if git.modified_files.include?("CHANGELOG.md")
- fail "**CHANGELOG.md was edited.** Please remove the additions and create a CHANGELOG entry.\n\n" +
- format(CREATE_CHANGELOG_MESSAGE, mr_iid: gitlab.mr_json["iid"], mr_title: mr_title, labels: presented_no_changelog_labels)
-end
-
-if changelog_found
- check_changelog(changelog_found)
-elsif changelog_needed
- warn "**[CHANGELOG missing](https://docs.gitlab.com/ce/development/changelog.html).**\n\n" +
- format(CREATE_CHANGELOG_MESSAGE, mr_iid: gitlab.mr_json["iid"], mr_title: mr_title, labels: presented_no_changelog_labels)
-end
if changelog_needed
checked = 0
git.commits.each do |commit|
- case check_changelog_trailer(commit)
+ case lint_commit(commit)
when :valid, :invalid
checked += 1
end
end
- if checked == 0
- 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
- end
+ warn(CHANGELOG_MISSING) if checked.zero?
end
-
-# vim: ft=ruby