Commit 65ad11b4 authored by Robert Speicher's avatar Robert Speicher

Merge branch '21949-add-type-to-changelog' into 'master'

Let's start labeling our CHANGELOG entries

Closes #21949

See merge request !11579
parents 130c369a eb2b895a
...@@ -14,11 +14,26 @@ Options = Struct.new( ...@@ -14,11 +14,26 @@ Options = Struct.new(
:dry_run, :dry_run,
:force, :force,
:merge_request, :merge_request,
:title :title,
:type
) )
INVALID_TYPE = -1
class ChangelogOptionParser class ChangelogOptionParser
def self.parse(argv) 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('other', 'Other')
].freeze
TYPES_OFFSET = 1
class << self
def parse(argv)
options = Options.new options = Options.new
parser = OptionParser.new do |opts| parser = OptionParser.new do |opts|
...@@ -46,6 +61,10 @@ class ChangelogOptionParser ...@@ -46,6 +61,10 @@ class ChangelogOptionParser
options.author = git_user_name if value options.author = git_user_name if value
end 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 opts.on('-h', '--help', 'Print help message') do
$stdout.puts opts $stdout.puts opts
exit exit
...@@ -60,9 +79,43 @@ class ChangelogOptionParser ...@@ -60,9 +79,43 @@ class ChangelogOptionParser
options options
end end
def self.git_user_name 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 %x{git config user.name}.strip
end end
end
end end
class ChangelogEntry class ChangelogEntry
...@@ -72,8 +125,12 @@ class ChangelogEntry ...@@ -72,8 +125,12 @@ class ChangelogEntry
@options = options @options = options
assert_feature_branch! assert_feature_branch!
assert_new_file!
assert_title! 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 "\e[32mcreate\e[0m #{file_path}"
$stdout.puts contents $stdout.puts contents
...@@ -90,7 +147,8 @@ class ChangelogEntry ...@@ -90,7 +147,8 @@ class ChangelogEntry
yaml_content = YAML.dump( yaml_content = YAML.dump(
'title' => title, 'title' => title,
'merge_request' => options.merge_request, 'merge_request' => options.merge_request,
'author' => options.author 'author' => options.author,
'type' => options.type
) )
remove_trailing_whitespace(yaml_content) remove_trailing_whitespace(yaml_content)
end end
...@@ -129,6 +187,12 @@ class ChangelogEntry ...@@ -129,6 +187,12 @@ class ChangelogEntry
" to use the title from the previous commit." " to use the title from the previous commit."
end end
def assert_valid_type!
return unless options.type && options.type == INVALID_TYPE
fail_with 'Invalid category given!'
end
def title def title
if options.title.empty? if options.title.empty?
last_commit_subject last_commit_subject
......
---
title: Added type to CHANGELOG entries
merge_request:
author: Jacopo Beschi @jacopo-beschi
...@@ -15,11 +15,14 @@ following format: ...@@ -15,11 +15,14 @@ following format:
title: "Going through change[log]s" title: "Going through change[log]s"
merge_request: 1972 merge_request: 1972
author: Ozzy Osbourne author: Ozzy Osbourne
type: added
``` ```
The `merge_request` value is a reference to a merge request that adds this The `merge_request` value is a reference to a merge request that adds this
entry, and the `author` key is used to give attribution to community entry, and the `author` key is used to give attribution to community
contributors. **Both are optional**. contributors. **Both are optional**.
The `type` field maps the category of the change,
valid options are: added, fixed, changed, deprecated, removed, security, other. **Type field is mandatory**.
Community contributors and core team members are encouraged to add their name to Community contributors and core team members are encouraged to add their name to
the `author` field. GitLab team members **should not**. the `author` field. GitLab team members **should not**.
...@@ -94,6 +97,19 @@ Its simplest usage is to provide the value for `title`: ...@@ -94,6 +97,19 @@ Its simplest usage is to provide the value for `title`:
$ bin/changelog 'Hey DZ, I added a feature to GitLab!' $ bin/changelog 'Hey DZ, I added a feature to GitLab!'
``` ```
At this point the script would ask you to select the category of the change (mapped to the `type` field in the entry):
```text
>> Please specify the category of your change:
1. New feature
2. Bug fix
3. Feature change
4. New deprecation
5. Feature removal
6. Security fix
7. Other
```
The entry filename is based on the name of the current Git branch. If you run The entry filename is based on the name of the current Git branch. If you run
the command above on a branch called `feature/hey-dz`, it will generate a the command above on a branch called `feature/hey-dz`, it will generate a
`changelogs/unreleased/feature-hey-dz.yml` file. `changelogs/unreleased/feature-hey-dz.yml` file.
...@@ -106,6 +122,7 @@ create changelogs/unreleased/my-feature.yml ...@@ -106,6 +122,7 @@ create changelogs/unreleased/my-feature.yml
title: Hey DZ, I added a feature to GitLab! title: Hey DZ, I added a feature to GitLab!
merge_request: merge_request:
author: author:
type:
``` ```
If you're working on the GitLab EE repository, the entry will be added to If you're working on the GitLab EE repository, the entry will be added to
`changelogs/unreleased-ee/` instead. `changelogs/unreleased-ee/` instead.
...@@ -113,12 +130,13 @@ If you're working on the GitLab EE repository, the entry will be added to ...@@ -113,12 +130,13 @@ If you're working on the GitLab EE repository, the entry will be added to
#### Arguments #### Arguments
| Argument | Shorthand | Purpose | | Argument | Shorthand | Purpose |
| ----------------- | --------- | --------------------------------------------- | | ----------------- | --------- | ---------------------------------------------------------------------------------------------------------- |
| [`--amend`] | | Amend the previous commit | | [`--amend`] | | Amend the previous commit |
| [`--force`] | `-f` | Overwrite an existing entry | | [`--force`] | `-f` | Overwrite an existing entry |
| [`--merge-request`] | `-m` | Set merge request ID | | [`--merge-request`] | `-m` | Set merge request ID |
| [`--dry-run`] | `-n` | Don't actually write anything, just print | | [`--dry-run`] | `-n` | Don't actually write anything, just print |
| [`--git-username`] | `-u` | Use Git user.name configuration as the author | | [`--git-username`] | `-u` | Use Git user.name configuration as the author |
| [`--type`] | `-t` | The category of the change, valid options are: added, fixed, changed, deprecated, removed, security, other |
| [`--help`] | `-h` | Print help message | | [`--help`] | `-h` | Print help message |
[`--amend`]: #-amend [`--amend`]: #-amend
...@@ -126,6 +144,7 @@ If you're working on the GitLab EE repository, the entry will be added to ...@@ -126,6 +144,7 @@ If you're working on the GitLab EE repository, the entry will be added to
[`--merge-request`]: #-merge-request-or-m [`--merge-request`]: #-merge-request-or-m
[`--dry-run`]: #-dry-run-or-n [`--dry-run`]: #-dry-run-or-n
[`--git-username`]: #-git-username-or-u [`--git-username`]: #-git-username-or-u
[`--type`]: #-type-or-t
[`--help`]: #-help [`--help`]: #-help
##### `--amend` ##### `--amend`
...@@ -147,6 +166,7 @@ create changelogs/unreleased/feature-hey-dz.yml ...@@ -147,6 +166,7 @@ create changelogs/unreleased/feature-hey-dz.yml
title: Added an awesome new feature to GitLab title: Added an awesome new feature to GitLab
merge_request: merge_request:
author: author:
type:
``` ```
##### `--force` or `-f` ##### `--force` or `-f`
...@@ -164,6 +184,7 @@ create changelogs/unreleased/feature-hey-dz.yml ...@@ -164,6 +184,7 @@ create changelogs/unreleased/feature-hey-dz.yml
title: Hey DZ, I added a feature to GitLab! title: Hey DZ, I added a feature to GitLab!
merge_request: 1983 merge_request: 1983
author: author:
type:
``` ```
##### `--merge-request` or `-m` ##### `--merge-request` or `-m`
...@@ -178,6 +199,7 @@ create changelogs/unreleased/feature-hey-dz.yml ...@@ -178,6 +199,7 @@ create changelogs/unreleased/feature-hey-dz.yml
title: Hey DZ, I added a feature to GitLab! title: Hey DZ, I added a feature to GitLab!
merge_request: 1983 merge_request: 1983
author: author:
type:
``` ```
##### `--dry-run` or `-n` ##### `--dry-run` or `-n`
...@@ -192,6 +214,7 @@ create changelogs/unreleased/feature-hey-dz.yml ...@@ -192,6 +214,7 @@ create changelogs/unreleased/feature-hey-dz.yml
title: Added an awesome new feature to GitLab title: Added an awesome new feature to GitLab
merge_request: merge_request:
author: author:
type:
$ ls changelogs/unreleased/ $ ls changelogs/unreleased/
``` ```
...@@ -211,6 +234,21 @@ create changelogs/unreleased/feature-hey-dz.yml ...@@ -211,6 +234,21 @@ create changelogs/unreleased/feature-hey-dz.yml
title: Hey DZ, I added a feature to GitLab! title: Hey DZ, I added a feature to GitLab!
merge_request: merge_request:
author: Jane Doe author: Jane Doe
type:
```
##### `--type` or `-t`
Use the **`--type`** or **`-t`** argument to provide the `type` value:
```text
$ bin/changelog 'Hey DZ, I added a feature to GitLab!' -t added
create changelogs/unreleased/feature-hey-dz.yml
---
title: Hey DZ, I added a feature to GitLab!
merge_request:
author:
type: added
``` ```
### History and Reasoning ### History and Reasoning
......
...@@ -4,7 +4,8 @@ load File.expand_path('../../bin/changelog', __dir__) ...@@ -4,7 +4,8 @@ load File.expand_path('../../bin/changelog', __dir__)
describe 'bin/changelog' do describe 'bin/changelog' do
describe ChangelogOptionParser do describe ChangelogOptionParser do
it 'parses --ammend' do describe '.parse' do
it 'parses --amend' do
options = described_class.parse(%w[foo bar --amend]) options = described_class.parse(%w[foo bar --amend])
expect(options.amend).to eq true expect(options.amend).to eq true
...@@ -44,6 +45,14 @@ describe 'bin/changelog' do ...@@ -44,6 +45,14 @@ describe 'bin/changelog' do
end end
end end
it 'parses --type and -t' do
%w[--type -t].each do |flag|
options = described_class.parse(%W[foo #{flag} security])
expect(options.type).to eq 'security'
end
end
it 'parses -h' do it 'parses -h' do
expect do expect do
expect { described_class.parse(%w[foo -h bar]) }.to output.to_stdout expect { described_class.parse(%w[foo -h bar]) }.to output.to_stdout
...@@ -56,4 +65,29 @@ describe 'bin/changelog' do ...@@ -56,4 +65,29 @@ describe 'bin/changelog' do
expect(options.title).to eq 'foo bar baz' expect(options.title).to eq 'foo bar baz'
end end
end end
describe '.read_type' do
let(:type) { '1' }
it 'reads type from $stdin' do
expect($stdin).to receive(:getc).and_return(type)
expect do
expect(described_class.read_type).to eq('added')
end.to output.to_stdout
end
context 'invalid type given' do
let(:type) { '99' }
it 'shows error message and exits the program' do
allow($stdin).to receive(:getc).and_return(type)
expect do
expect do
expect{ described_class.read_type }.to raise_error(SystemExit)
end.to output("Invalid category index, please select an index between 1 and 7\n").to_stderr
end.to output.to_stdout
end
end
end
end
end end
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment