mr_bump 0.0.10 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +8 -8
- data/bin/mr_bump +125 -62
- data/defaults.yml +27 -0
- data/lib/mr_bump.rb +45 -40
- data/lib/mr_bump/change.rb +40 -0
- data/lib/mr_bump/config.rb +32 -8
- data/lib/mr_bump/git_api.rb +25 -0
- data/lib/mr_bump/git_config.rb +11 -4
- data/lib/mr_bump/slack.rb +4 -0
- data/lib/mr_bump/version.rb +4 -0
- data/spec/change_spec.rb +275 -0
- data/spec/config_spec.rb +24 -0
- data/spec/git_config_spec.rb +76 -0
- data/spec/mr_bump_spec.rb +238 -0
- data/spec/spec_helper.rb +8 -0
- metadata +87 -3
checksums.yaml
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
---
|
2
2
|
!binary "U0hBMQ==":
|
3
3
|
metadata.gz: !binary |-
|
4
|
-
|
4
|
+
YjZmNTY4ODM4MjMyNzFiNmE4MDY2MWVlOWJmN2YwODhlYzcwYmQwYg==
|
5
5
|
data.tar.gz: !binary |-
|
6
|
-
|
6
|
+
ZDZiNWQwYmJiNmJkMzMzZDYzNjZiMmQyNDJhZmQwZmM5Y2Q0ODRhMg==
|
7
7
|
SHA512:
|
8
8
|
metadata.gz: !binary |-
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
NGIzNTUwNDc2OTAzOTFhNWY4OGI5MWIyODczMTdkODliYTg2MmUxMWEwNzgx
|
10
|
+
YWE0Mzk1OTA3OWZhMDY5ZWEyZmI3MzIyYTYzMWVkZjdhYjc1NTMxMTE5ZjY3
|
11
|
+
NWU4M2U2ODY0OTMwNjExODRiOTFiZmIwYzkzNTRiNWM0YTJlYjA=
|
12
12
|
data.tar.gz: !binary |-
|
13
|
-
|
14
|
-
|
15
|
-
|
13
|
+
ODg4MzE1MzZmZGQzYjJiYTk0Y2IyMWJhNDVjODFkNWQyZmMzMDA2Zjg2MzFl
|
14
|
+
ZTlkZjczY2Y2M2JjMmUyYTgzOGFmOWQ3YTdkNjI5OTI2MTMwMDY4ZWI3OWIw
|
15
|
+
MTg5MWVlNWFkYzAyMjEzZmRmNDBiZGZmZWViZTQ3ZGZjMWM0ZTE=
|
data/bin/mr_bump
CHANGED
@@ -1,10 +1,45 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
|
-
#
|
2
|
+
# This Source Code Form is subject to the terms of the Mozilla Public
|
3
|
+
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
4
|
+
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
5
|
+
|
6
|
+
# Script to tag releases and update changelogs
|
7
|
+
require 'optparse'
|
8
|
+
|
3
9
|
require 'mr_bump'
|
10
|
+
require 'mr_bump/git_api'
|
11
|
+
|
12
|
+
def menu(text, valid_options, &block)
|
13
|
+
loop do
|
14
|
+
print text + ': '
|
15
|
+
choice = gets.chomp.upcase
|
16
|
+
if valid_options.include? choice
|
17
|
+
block.call(choice)
|
18
|
+
break
|
19
|
+
else
|
20
|
+
puts "I'm sorry Dave; I'm afraid I can't do that."
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
options = {
|
26
|
+
dryrun: false
|
27
|
+
}
|
28
|
+
OptionParser.new do |parser|
|
29
|
+
parser.on(
|
30
|
+
'-n', '--dry-run',
|
31
|
+
'Make no changes to git state (except to update remotes), and change some fatal errors to ' \
|
32
|
+
'warnings'
|
33
|
+
) do
|
34
|
+
options[:dryrun] = true
|
35
|
+
end
|
36
|
+
end.parse!
|
4
37
|
|
5
38
|
release = !MrBump.current_branch[/^release/].nil?
|
6
39
|
master = !MrBump.current_branch[/^master$/].nil?
|
7
40
|
|
41
|
+
changelog = "#{`git rev-parse --show-toplevel`.strip}/CHANGELOG.md"
|
42
|
+
|
8
43
|
unless release || master
|
9
44
|
puts 'Need to be on either release or master branch'
|
10
45
|
exit 1
|
@@ -16,102 +51,130 @@ unless master || MrBump.current_branch.to_s == "release/#{MrBump.current_uat_maj
|
|
16
51
|
exit 1
|
17
52
|
end
|
18
53
|
|
54
|
+
unless MrBump.config_file['github_api_token']
|
55
|
+
puts "Couldn't find a github API token in configuration files"
|
56
|
+
puts "Please obtain a github token by following the guide at\n" \
|
57
|
+
" https://help.github.com/articles/creating-an-access-token-for-command-line-use/\n" \
|
58
|
+
"and add it with the 'github_api_token:' option"
|
59
|
+
exit 1
|
60
|
+
end
|
61
|
+
|
62
|
+
puts 'Have you already closed your PR?'
|
63
|
+
|
64
|
+
github_client = MrBump::GitApi.new(MrBump.config_file['github_api_token'])
|
65
|
+
menu '[Y]es / [N]o', %w(Y N) do |choice|
|
66
|
+
if choice == 'N'
|
67
|
+
puts 'Here are the 10 most recent PRs in your repo:'
|
68
|
+
puts github_client.sorted_prs(MrBump.git_config.path)
|
69
|
+
loop do
|
70
|
+
print 'Enter the PR number to merge : '
|
71
|
+
pr_id = gets.chomp
|
72
|
+
if options[:dryrun]
|
73
|
+
puts "dryrun: Would merge ##{pr_id}"
|
74
|
+
else
|
75
|
+
github_client.merge_pr(MrBump.git_config.path, pr_id)
|
76
|
+
end
|
77
|
+
break
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
19
82
|
unless system('git remote update > /dev/null 2>&1')
|
20
83
|
puts 'Failed to update remotes. (Connectivity problems?)'
|
21
84
|
exit 1
|
22
85
|
end
|
23
86
|
|
24
87
|
unless `git rev-parse @` == `git rev-parse @{u}`
|
25
|
-
|
26
|
-
|
88
|
+
if options[:dryrun]
|
89
|
+
puts 'WARNING! Not up to date with origin! Please run git pull'
|
90
|
+
else
|
91
|
+
puts 'Not up to date with origin! Please run git pull'
|
92
|
+
exit 1
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
unless MrBump.all_tagged_versions.include? MrBump.current_uat_major
|
97
|
+
base_sha = `git merge_base release/#{MrBump.current_uat_major} develop`
|
98
|
+
|
99
|
+
puts "Missing tag for version #{MrBump.current_uat_major}. Suggesting commit #{base_sha[0...8]}"
|
100
|
+
puts "\t#{`git log --format="(%ci) %cn - %s" -n 1 #{base_sha}`}"
|
101
|
+
puts 'Would you like to tag this commit?'
|
102
|
+
menu '[Y]es / [N]o', %w(Y N) do |choice|
|
103
|
+
exit 1 if choice == 'N'
|
104
|
+
end
|
105
|
+
`git tag #{MrBump.current_uat_major} #{base_sha}`
|
27
106
|
end
|
28
107
|
|
29
|
-
unless File.file?(
|
30
|
-
puts "Couldn't find CHANGELOG.md
|
108
|
+
unless File.file?(changelog)
|
109
|
+
puts "Couldn't find CHANGELOG.md at '#{changelog}'."
|
31
110
|
exit 1
|
32
111
|
end
|
33
112
|
|
34
113
|
if release
|
35
114
|
last_release = MrBump.current_uat
|
36
|
-
|
37
|
-
changes = MrBump.change_log_items_for_range(last_release, "release/#{
|
115
|
+
uat_major = MrBump.current_uat_major
|
116
|
+
changes = MrBump.change_log_items_for_range(last_release, "release/#{uat_major}")
|
38
117
|
else
|
39
118
|
last_release = MrBump.current_master
|
40
119
|
changes = MrBump.change_log_items_for_range(last_release, 'master')
|
41
120
|
end
|
42
121
|
|
43
122
|
new_release = last_release.bump_patch
|
44
|
-
changes = changes.join(
|
45
|
-
md_changes = "# #{new_release}#{changes}\n\n"
|
123
|
+
changes = changes.join("\n")
|
124
|
+
md_changes = "# #{new_release}\n#{changes}\n\n"
|
46
125
|
|
47
126
|
puts 'Changelog additions'
|
48
127
|
puts '----------'
|
49
128
|
puts md_changes
|
50
129
|
puts '----------'
|
51
130
|
|
52
|
-
|
53
|
-
|
54
|
-
choice = gets.chomp.upcase
|
55
|
-
|
56
|
-
case choice
|
57
|
-
when 'A'
|
58
|
-
MrBump.file_prepend('CHANGELOG.md', md_changes)
|
59
|
-
break
|
60
|
-
when 'E'
|
61
|
-
MrBump.file_prepend('CHANGELOG.md', md_changes)
|
62
|
-
system 'nano CHANGELOG.md'
|
63
|
-
loop do
|
64
|
-
log = File.open('CHANGELOG.md', 'r').read
|
65
|
-
changes = log.split("\n\n").first.strip.split("\n").drop(1)
|
66
|
-
changes = changes.join("\n")
|
67
|
-
md_changes = "# #{new_release}\n#{changes}\n\n"
|
68
|
-
puts 'Modified Changelog additions'
|
69
|
-
puts '----------'
|
70
|
-
puts md_changes
|
71
|
-
puts '----------'
|
72
|
-
print '[A]ccept modified changes / [C]ancel Release : '
|
73
|
-
choice2 = gets.chomp.upcase
|
74
|
-
if choice2 == 'C'
|
75
|
-
exit 1
|
76
|
-
elsif choice2 == 'A'
|
77
|
-
break
|
78
|
-
else
|
79
|
-
puts "I'm sorry Dave; I'm afraid I can't do that."
|
80
|
-
end
|
81
|
-
end
|
82
|
-
break
|
83
|
-
when 'C'
|
131
|
+
menu '[A]ccept these changes / Manually [E]dit / [C]ancel Release', %w(A E C) do |choice|
|
132
|
+
if choice == 'C'
|
84
133
|
exit 1
|
85
|
-
|
86
|
-
|
134
|
+
elsif choice == 'E'
|
135
|
+
tempfile = Tempfile.new('CHANGELOG')
|
136
|
+
tempfile.write(changes)
|
137
|
+
tempfile.close
|
138
|
+
system "nano #{tempfile.path}"
|
139
|
+
changes = File.open(tempfile.path, 'r').read.rstrip
|
140
|
+
md_changes = "# #{new_release}\n#{changes}\n\n"
|
141
|
+
puts 'Modified Changelog additions'
|
142
|
+
puts '----------'
|
143
|
+
puts md_changes
|
144
|
+
puts '----------'
|
145
|
+
|
146
|
+
menu '[A]ccept modified changes / [C]ancel Release', %w(A C) do |cancel|
|
147
|
+
exit 1 if cancel == 'C'
|
148
|
+
end
|
87
149
|
end
|
88
|
-
end
|
89
150
|
|
90
|
-
|
91
|
-
|
92
|
-
`git push && git push --tags`
|
151
|
+
MrBump.file_prepend(changelog, md_changes) unless options[:dryrun]
|
152
|
+
end
|
93
153
|
|
94
|
-
|
154
|
+
if options[:dryrun]
|
155
|
+
puts "dry-run: `git commit -m 'Bump version to #{new_release}' -- #{changelog}`"
|
156
|
+
puts "dry-run: `git tag #{new_release}`"
|
157
|
+
puts 'dry-run: git push && git push --tags`'
|
158
|
+
else
|
159
|
+
`git commit -m 'Bump version to #{new_release}' -- #{changelog}`
|
160
|
+
`git tag #{new_release}`
|
161
|
+
`git push && git push --tags`
|
162
|
+
MrBump.slack_notifier(new_release, changes)
|
163
|
+
end
|
95
164
|
|
96
165
|
config_file = MrBump.config_file()
|
97
166
|
branch_type = release ? "release" : 'master'
|
98
167
|
bump_cmd_exists = config_file.key?('post_bump') &&
|
99
168
|
config_file['post_bump'].key?(branch_type)
|
100
169
|
if bump_cmd_exists
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
system post_command
|
110
|
-
break
|
111
|
-
when 'N'
|
112
|
-
break
|
113
|
-
else
|
114
|
-
puts "I'm sorry Dave; I'm afraid I can't do that."
|
170
|
+
puts 'Would you like to execute post bump commands? '
|
171
|
+
menu '[Y]es execute / [N]o Im done', %w(Y N) do |choice|
|
172
|
+
if choice == 'Y'
|
173
|
+
if options[:dryrun]
|
174
|
+
puts "dry-run: `#{config_file['post_bump'][branch_type]}`"
|
175
|
+
else
|
176
|
+
system(config_file['post_bump'][branch_type])
|
177
|
+
end
|
115
178
|
end
|
116
179
|
end
|
117
180
|
end
|
data/defaults.yml
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
# Slack integration
|
2
|
+
|
3
|
+
# Mr Bump can be configured to post a message to slack while bumping.
|
4
|
+
# To do so, a slack web hook is needed, as well as an icon and user name
|
5
|
+
# format for this configuration is below
|
6
|
+
#slack:
|
7
|
+
# webhook_url: "https://hooks.slack.com/services/some_custom_webhook"
|
8
|
+
# username: "Mr Bump"
|
9
|
+
# icon: "https://path_to_image.png"
|
10
|
+
|
11
|
+
# Post bump hooks
|
12
|
+
|
13
|
+
# Mr Bump can also run custom deploy or other commands after a bumping
|
14
|
+
#post_bump:
|
15
|
+
# release: "echo 'There has been a release on the release branch'"
|
16
|
+
# master: "echo 'There has been a release on the master branch'"
|
17
|
+
|
18
|
+
|
19
|
+
# Changelog template
|
20
|
+
# Your changelog can be customized by using a template. The template is in
|
21
|
+
# mustache format. The allowed parameters are
|
22
|
+
# - branch_type: Bugfix / Feature / Hotfix
|
23
|
+
# - dev_id: The development ID for this feature
|
24
|
+
# - comment_lines: Array of all lines in commit comment
|
25
|
+
# - first_commit_line: The first line of the commit comment
|
26
|
+
# - comment_body: The rest of the lines in the comment
|
27
|
+
markdown_template: " * {{branch_type}} - {{dev_id}} - {{first_comment_line}}{{#comment_body}}\n {{.}}{{/comment_body}}"
|
data/lib/mr_bump.rb
CHANGED
@@ -1,8 +1,12 @@
|
|
1
|
+
# This Source Code Form is subject to the terms of the Mozilla Public
|
2
|
+
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
3
|
+
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
4
|
+
|
1
5
|
require 'mr_bump/version'
|
2
6
|
require 'mr_bump/slack'
|
3
7
|
require 'mr_bump/config'
|
4
8
|
require 'mr_bump/git_config'
|
5
|
-
|
9
|
+
require 'mr_bump/change'
|
6
10
|
|
7
11
|
module MrBump
|
8
12
|
def self.current_branch
|
@@ -10,45 +14,42 @@ module MrBump
|
|
10
14
|
@current_branch.strip
|
11
15
|
end
|
12
16
|
|
17
|
+
def self.latest_release_from_list(branches)
|
18
|
+
prefix = 'origin/release[-/]'
|
19
|
+
regex = Regexp.new("^#{prefix}(\\d+\\.\\d+)\\.\\d+$")
|
20
|
+
branches.map do |branch|
|
21
|
+
matches = regex.match(branch)
|
22
|
+
MrBump::Version.new(matches[1]) if matches
|
23
|
+
end.compact.max
|
24
|
+
end
|
25
|
+
|
13
26
|
def self.current_uat_major
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
27
|
+
branches = `git branch -r`.each_line.map(&:strip)
|
28
|
+
latest_release_from_list(branches)
|
29
|
+
end
|
30
|
+
|
31
|
+
def self.all_tags
|
32
|
+
`git tag -l`.each_line.map(&:strip)
|
33
|
+
end
|
34
|
+
|
35
|
+
def self.all_tagged_versions
|
36
|
+
all_tags.map do |tag|
|
37
|
+
begin
|
38
|
+
MrBump::Version.new(tag)
|
39
|
+
rescue
|
40
|
+
nil
|
41
|
+
end
|
20
42
|
end.compact
|
21
|
-
vers.max
|
22
43
|
end
|
23
44
|
|
24
45
|
def self.current_uat
|
25
46
|
uat = current_uat_major
|
26
|
-
|
27
|
-
vers = vers.each_line.map do |branch|
|
28
|
-
MrBump::Version.new(branch) rescue nil
|
29
|
-
end.compact
|
30
|
-
vers.select { |ver| ver.major == uat.major && ver.minor == uat.minor }.max
|
47
|
+
all_tagged_versions.select { |ver| ver.major == uat.major && ver.minor == uat.minor }.max
|
31
48
|
end
|
32
49
|
|
33
50
|
def self.current_master
|
34
51
|
uat = current_uat_major
|
35
|
-
|
36
|
-
vers = vers.each_line.map do |branch|
|
37
|
-
MrBump::Version.new(branch) rescue nil
|
38
|
-
end.compact
|
39
|
-
vers.select { |ver| ver < uat }.max
|
40
|
-
end
|
41
|
-
|
42
|
-
def self.story_information(merge_str)
|
43
|
-
branch_fmt = '(?<fix_type>bugfix|feature|hotfix)/(?<dev_id>\w+[-_]?\d+)?'
|
44
|
-
merge_pr_fmt = "^Merge pull request #(?<pr_number>\\d+) from \\w+/#{branch_fmt}"
|
45
|
-
merge_manual_fmt = "^Merge branch '#{branch_fmt}'"
|
46
|
-
matches = Regexp.new(merge_pr_fmt + '|' + merge_manual_fmt).match(merge_str)
|
47
|
-
if matches
|
48
|
-
type = matches['fix_type'].capitalize
|
49
|
-
dev_id = (matches['dev_id'].nil? ? 'UNKNOWN' : matches['dev_id'])
|
50
|
-
"#{type} - #{dev_id} - "
|
51
|
-
end
|
52
|
+
all_tagged_versions.select { |ver| ver < uat }.max
|
52
53
|
end
|
53
54
|
|
54
55
|
def self.merge_logs(rev, head)
|
@@ -69,9 +70,10 @@ module MrBump
|
|
69
70
|
def self.change_log_items_for_range(rev, head)
|
70
71
|
chunked_log = merge_logs(rev, head).chunk { |change| change[/^Merge/].nil? }
|
71
72
|
chunked_log.each_slice(2).map do |merge_str, comment|
|
72
|
-
|
73
|
-
|
74
|
-
|
73
|
+
begin
|
74
|
+
MrBump::Change.new(config_file, merge_str[1][0], comment[1]).to_md
|
75
|
+
rescue ArgumentError => e
|
76
|
+
puts e
|
75
77
|
end
|
76
78
|
end.compact
|
77
79
|
end
|
@@ -85,16 +87,19 @@ module MrBump
|
|
85
87
|
File.open(file, 'w') do |fd|
|
86
88
|
fd.write(new_contents)
|
87
89
|
end
|
90
|
+
end
|
88
91
|
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
+
def self.config_file
|
93
|
+
@config_file ||= MrBump::Config.new.config
|
94
|
+
end
|
92
95
|
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
end
|
96
|
+
def self.slack_notifier(version, changelog)
|
97
|
+
if config_file.key? 'slack'
|
98
|
+
MrBump::Slack.new(git_config, config_file['slack']).bump(version, changelog)
|
97
99
|
end
|
100
|
+
end
|
98
101
|
|
102
|
+
def self.git_config
|
103
|
+
@git_config ||= MrBump::GitConfig.from_current_path
|
99
104
|
end
|
100
105
|
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
# This Source Code Form is subject to the terms of the Mozilla Public
|
2
|
+
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
3
|
+
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
4
|
+
|
5
|
+
require 'mustache'
|
6
|
+
|
7
|
+
module MrBump
|
8
|
+
# This class acts parses merge information from a commit message string
|
9
|
+
class Change
|
10
|
+
attr_reader :pr_number, :branch_type, :dev_id, :config, :comment_lines
|
11
|
+
|
12
|
+
BRANCH_FMT = '((?<branch_type>bugfix|feature|hotfix)/)?(?<dev_id>\w+[-_]?\d+)?[\\w\\-_]+'.freeze
|
13
|
+
MERGE_PR_FMT = "^Merge pull request #(?<pr_number>\\d+) from [\\w\\-_]+/#{BRANCH_FMT}".freeze
|
14
|
+
MERGE_MANUAL_FMT = "^Merge branch '#{BRANCH_FMT}'".freeze
|
15
|
+
MERGE_REGEX = Regexp.new(MERGE_PR_FMT + '|' + MERGE_MANUAL_FMT).freeze
|
16
|
+
|
17
|
+
def initialize(config, commit_msg, comment_lines)
|
18
|
+
matches = MERGE_REGEX.match(commit_msg)
|
19
|
+
raise ArgumentError, "Couldn't extract merge information from commit message " \
|
20
|
+
"'#{commit_msg}'" unless matches
|
21
|
+
@config = config
|
22
|
+
@branch_type = (matches['branch_type'] || 'Task').capitalize
|
23
|
+
@dev_id = matches['dev_id'] || 'UNKNOWN'
|
24
|
+
@pr_number = matches['pr_number'] || ''
|
25
|
+
@comment_lines = Array(comment_lines)
|
26
|
+
end
|
27
|
+
|
28
|
+
def first_comment_line
|
29
|
+
comment_lines.first
|
30
|
+
end
|
31
|
+
|
32
|
+
def comment_body
|
33
|
+
comment_lines[1..-1] if comment_lines.size > 1
|
34
|
+
end
|
35
|
+
|
36
|
+
def to_md
|
37
|
+
Mustache.render(config['markdown_template'], self)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
data/lib/mr_bump/config.rb
CHANGED
@@ -1,3 +1,7 @@
|
|
1
|
+
# This Source Code Form is subject to the terms of the Mozilla Public
|
2
|
+
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
3
|
+
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
4
|
+
|
1
5
|
require 'yaml'
|
2
6
|
|
3
7
|
module MrBump
|
@@ -6,20 +10,40 @@ module MrBump
|
|
6
10
|
attr_reader :config_file
|
7
11
|
|
8
12
|
def initialize(config_file = nil)
|
9
|
-
@config_file = config_file ||
|
13
|
+
@config_file = config_file || default_project_filename
|
10
14
|
end
|
11
15
|
|
12
|
-
def
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
16
|
+
def user_config_file
|
17
|
+
File.join(Dir.home, '.mr_bump.yml')
|
18
|
+
end
|
19
|
+
|
20
|
+
def default_project_filename
|
21
|
+
File.join('.mr_bump')
|
22
|
+
end
|
23
|
+
|
24
|
+
def default_config
|
25
|
+
@default_config = begin
|
26
|
+
defaults_yml = File.join(File.dirname(__FILE__), '..', '..', 'defaults.yml')
|
27
|
+
YAML.load_file(defaults_yml)
|
17
28
|
end
|
18
29
|
end
|
19
30
|
|
20
|
-
def
|
21
|
-
|
31
|
+
def user_config
|
32
|
+
@user_config = begin
|
33
|
+
loaded = YAML.load_file(user_config_file) if File.exist?(user_config_file)
|
34
|
+
loaded || {}
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def project_config
|
39
|
+
@project_config ||= begin
|
40
|
+
loaded = YAML.load_file(@config_file) if File.exist?(@config_file)
|
41
|
+
loaded || {}
|
42
|
+
end
|
22
43
|
end
|
23
44
|
|
45
|
+
def config
|
46
|
+
@config ||= default_config.merge(user_config).merge(project_config)
|
47
|
+
end
|
24
48
|
end
|
25
49
|
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# This Source Code Form is subject to the terms of the Mozilla Public
|
2
|
+
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
3
|
+
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
4
|
+
|
5
|
+
require 'octokit'
|
6
|
+
module MrBump
|
7
|
+
# This class makes calls to the github API
|
8
|
+
class GitApi
|
9
|
+
def initialize(token)
|
10
|
+
@client = Octokit::Client.new(access_token: token)
|
11
|
+
end
|
12
|
+
|
13
|
+
def prs(repo_url)
|
14
|
+
@prs ||= client.pull_requests(repo_url, state: 'open')
|
15
|
+
end
|
16
|
+
|
17
|
+
def sorted_prs(repo_url)
|
18
|
+
prs(repo_url).map { |x| '#' + x[:number].to_s + ' - ' + x[:title].to_s + "\n" }.first(10).join
|
19
|
+
end
|
20
|
+
|
21
|
+
def merge_pr(repo_url, pr_id)
|
22
|
+
client.merge_pull_request(repo_url, pr_id)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
data/lib/mr_bump/git_config.rb
CHANGED
@@ -1,16 +1,22 @@
|
|
1
|
+
# This Source Code Form is subject to the terms of the Mozilla Public
|
2
|
+
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
3
|
+
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
4
|
+
|
1
5
|
module MrBump
|
2
6
|
# This class gathers configuration infromation from git
|
3
7
|
class GitConfig
|
4
|
-
attr_reader :user, :username, :repo_url, :repo_name, :orgin
|
8
|
+
attr_reader :user, :username, :repo_url, :host, :path, :repo_name, :orgin
|
5
9
|
GITHUB_URL_REGEX = Regexp.new(
|
6
10
|
'(https?://((?<user>[\w_\-\d]+)@)?|git@)(?<domain>github.com)[:/](?<path>[\w_\-\d]+)/' \
|
7
11
|
'(?<repo_name>[\w_\-\d\.]+?)(\.git)?$'
|
8
12
|
).freeze
|
9
13
|
|
10
|
-
def initialize(origin, repo_name,
|
14
|
+
def initialize(origin, repo_name, repo_host, repo_path, username, user)
|
11
15
|
@origin = origin
|
12
16
|
@repo_name = repo_name
|
13
|
-
@repo_url =
|
17
|
+
@repo_url = repo_host + '/' + repo_path + '/'
|
18
|
+
@host = repo_host
|
19
|
+
@path = repo_path
|
14
20
|
@username = username
|
15
21
|
@user = user || `git config user.name`
|
16
22
|
end
|
@@ -22,7 +28,8 @@ module MrBump
|
|
22
28
|
GitConfig.new(
|
23
29
|
origin,
|
24
30
|
match['repo_name'],
|
25
|
-
"https://#{match['domain']}
|
31
|
+
"https://#{match['domain']}",
|
32
|
+
"#{match['path']}/#{match['repo_name']}",
|
26
33
|
match['user'],
|
27
34
|
user
|
28
35
|
)
|
data/lib/mr_bump/slack.rb
CHANGED
@@ -1,3 +1,7 @@
|
|
1
|
+
# This Source Code Form is subject to the terms of the Mozilla Public
|
2
|
+
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
3
|
+
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
4
|
+
|
1
5
|
require 'slack-notifier'
|
2
6
|
module MrBump
|
3
7
|
# This class uses a slack webhook to push notifications to slack
|
data/lib/mr_bump/version.rb
CHANGED
@@ -1,3 +1,7 @@
|
|
1
|
+
# This Source Code Form is subject to the terms of the Mozilla Public
|
2
|
+
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
3
|
+
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
4
|
+
|
1
5
|
module MrBump
|
2
6
|
# This class enables comparison and bumping of sementic versions and
|
3
7
|
# conversion to and from strings
|
data/spec/change_spec.rb
ADDED
@@ -0,0 +1,275 @@
|
|
1
|
+
# This Source Code Form is subject to the terms of the Mozilla Public
|
2
|
+
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
3
|
+
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
4
|
+
|
5
|
+
require 'mr_bump/change'
|
6
|
+
|
7
|
+
describe MrBump::Change do
|
8
|
+
let(:config) do
|
9
|
+
{
|
10
|
+
'markdown_template' => ' * {{branch_type}} - {{dev_id}} - {{first_comment_line}}' \
|
11
|
+
"{{#comment_body}}\n {{.}}{{/comment_body}}"
|
12
|
+
}
|
13
|
+
end
|
14
|
+
|
15
|
+
let(:change) { described_class.new(config, merge_str, ['Line 1', 'Line 2']) }
|
16
|
+
|
17
|
+
context 'when given a merge string in the default PR format for a feature' do
|
18
|
+
let(:merge_str) { 'Merge pull request #555 from AGithubUsername/feature/DEV-1_Stuff' }
|
19
|
+
|
20
|
+
it 'extracts the correct PR Number' do
|
21
|
+
expect(change.pr_number).to eq('555')
|
22
|
+
end
|
23
|
+
|
24
|
+
it 'extracts the correct branch type' do
|
25
|
+
expect(change.branch_type).to eq('Feature')
|
26
|
+
end
|
27
|
+
|
28
|
+
it 'extracts the correct dev ID' do
|
29
|
+
expect(change.dev_id).to eq('DEV-1')
|
30
|
+
end
|
31
|
+
|
32
|
+
it 'renders to markdown correctly' do
|
33
|
+
expect(change.to_md).to eq(" * Feature - DEV-1 - Line 1\n Line 2")
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
context 'when given a merge string in the default PR format for a feature' do
|
38
|
+
let(:merge_str) { 'Merge pull request #555 from AGithubUsername/feature/Stuff' }
|
39
|
+
|
40
|
+
it 'extracts the correct PR Number' do
|
41
|
+
expect(change.pr_number).to eq('555')
|
42
|
+
end
|
43
|
+
|
44
|
+
it 'extracts the correct branch type' do
|
45
|
+
expect(change.branch_type).to eq('Feature')
|
46
|
+
end
|
47
|
+
|
48
|
+
it 'defaults the dev ID to UNKNOWN' do
|
49
|
+
expect(change.dev_id).to eq('UNKNOWN')
|
50
|
+
end
|
51
|
+
|
52
|
+
it 'renders to markdown correctly' do
|
53
|
+
expect(change.to_md).to eq(" * Feature - UNKNOWN - Line 1\n Line 2")
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
context 'when given a merge string in the default PR format for a bugfix' do
|
58
|
+
let(:merge_str) { 'Merge pull request #555 from AGithubUsername/bugfix/DEV-1_Stuff' }
|
59
|
+
|
60
|
+
it 'extracts the correct PR Number' do
|
61
|
+
expect(change.pr_number).to eq('555')
|
62
|
+
end
|
63
|
+
|
64
|
+
it 'extracts the correct branch type' do
|
65
|
+
expect(change.branch_type).to eq('Bugfix')
|
66
|
+
end
|
67
|
+
|
68
|
+
it 'extracts the correct dev ID' do
|
69
|
+
expect(change.dev_id).to eq('DEV-1')
|
70
|
+
end
|
71
|
+
|
72
|
+
it 'renders to markdown correctly' do
|
73
|
+
expect(change.to_md).to eq(" * Bugfix - DEV-1 - Line 1\n Line 2")
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
context 'when given a merge string in the default PR format for a bugfix' do
|
78
|
+
let(:merge_str) { 'Merge pull request #555 from AGithubUsername/bugfix/Stuff' }
|
79
|
+
|
80
|
+
it 'extracts the correct PR Number' do
|
81
|
+
expect(change.pr_number).to eq('555')
|
82
|
+
end
|
83
|
+
|
84
|
+
it 'extracts the correct branch type' do
|
85
|
+
expect(change.branch_type).to eq('Bugfix')
|
86
|
+
end
|
87
|
+
|
88
|
+
it 'defaults the dev ID to UNKNOWN' do
|
89
|
+
expect(change.dev_id).to eq('UNKNOWN')
|
90
|
+
end
|
91
|
+
|
92
|
+
it 'renders to markdown correctly' do
|
93
|
+
expect(change.to_md).to eq(" * Bugfix - UNKNOWN - Line 1\n Line 2")
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
context 'when given a merge string in the default PR format for a hotfix' do
|
98
|
+
let(:merge_str) { 'Merge pull request #555 from AGithubUsername/hotfix/DEV-1_Stuff' }
|
99
|
+
|
100
|
+
it 'extracts the correct PR Number' do
|
101
|
+
expect(change.pr_number).to eq('555')
|
102
|
+
end
|
103
|
+
|
104
|
+
it 'extracts the correct branch type' do
|
105
|
+
expect(change.branch_type).to eq('Hotfix')
|
106
|
+
end
|
107
|
+
|
108
|
+
it 'extracts the correct dev ID' do
|
109
|
+
expect(change.dev_id).to eq('DEV-1')
|
110
|
+
end
|
111
|
+
|
112
|
+
it 'renders to markdown correctly' do
|
113
|
+
expect(change.to_md).to eq(" * Hotfix - DEV-1 - Line 1\n Line 2")
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
context 'when given a merge string in the default PR format for a hotfix' do
|
118
|
+
let(:merge_str) { 'Merge pull request #555 from AGithubUsername/hotfix/Stuff' }
|
119
|
+
|
120
|
+
it 'extracts the correct PR Number' do
|
121
|
+
expect(change.pr_number).to eq('555')
|
122
|
+
end
|
123
|
+
|
124
|
+
it 'extracts the correct branch type' do
|
125
|
+
expect(change.branch_type).to eq('Hotfix')
|
126
|
+
end
|
127
|
+
|
128
|
+
it 'defaults the dev ID to UNKNOWN' do
|
129
|
+
expect(change.dev_id).to eq('UNKNOWN')
|
130
|
+
end
|
131
|
+
|
132
|
+
it 'renders to markdown correctly' do
|
133
|
+
expect(change.to_md).to eq(" * Hotfix - UNKNOWN - Line 1\n Line 2")
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
context 'when given a merge string in the default manual format for a feature' do
|
138
|
+
let(:merge_str) { "Merge branch 'feature/DEV-1_Stuff'" }
|
139
|
+
|
140
|
+
it 'defaults PR Number to a blank string' do
|
141
|
+
expect(change.pr_number).to eq('')
|
142
|
+
end
|
143
|
+
|
144
|
+
it 'extracts the correct branch type' do
|
145
|
+
expect(change.branch_type).to eq('Feature')
|
146
|
+
end
|
147
|
+
|
148
|
+
it 'extracts the correct dev ID' do
|
149
|
+
expect(change.dev_id).to eq('DEV-1')
|
150
|
+
end
|
151
|
+
|
152
|
+
it 'renders to markdown correctly' do
|
153
|
+
expect(change.to_md).to eq(" * Feature - DEV-1 - Line 1\n Line 2")
|
154
|
+
end
|
155
|
+
end
|
156
|
+
|
157
|
+
context 'when given a merge string in the default PR format for a feature' do
|
158
|
+
let(:merge_str) { "Merge branch 'feature/Stuff'" }
|
159
|
+
|
160
|
+
it 'defaults PR Number to a blank string' do
|
161
|
+
expect(change.pr_number).to eq('')
|
162
|
+
end
|
163
|
+
|
164
|
+
it 'extracts the correct branch type' do
|
165
|
+
expect(change.branch_type).to eq('Feature')
|
166
|
+
end
|
167
|
+
|
168
|
+
it 'defaults the dev ID to UNKNOWN' do
|
169
|
+
expect(change.dev_id).to eq('UNKNOWN')
|
170
|
+
end
|
171
|
+
|
172
|
+
it 'renders to markdown correctly' do
|
173
|
+
expect(change.to_md).to eq(" * Feature - UNKNOWN - Line 1\n Line 2")
|
174
|
+
end
|
175
|
+
end
|
176
|
+
|
177
|
+
context 'when given a merge string in the default manual format for a bugfix' do
|
178
|
+
let(:merge_str) { "Merge branch 'bugfix/DEV-1_Stuff'" }
|
179
|
+
|
180
|
+
it 'defaults PR Number to a blank string' do
|
181
|
+
expect(change.pr_number).to eq('')
|
182
|
+
end
|
183
|
+
|
184
|
+
it 'extracts the correct branch type' do
|
185
|
+
expect(change.branch_type).to eq('Bugfix')
|
186
|
+
end
|
187
|
+
|
188
|
+
it 'extracts the correct dev ID' do
|
189
|
+
expect(change.dev_id).to eq('DEV-1')
|
190
|
+
end
|
191
|
+
|
192
|
+
it 'renders to markdown correctly' do
|
193
|
+
expect(change.to_md).to eq(" * Bugfix - DEV-1 - Line 1\n Line 2")
|
194
|
+
end
|
195
|
+
end
|
196
|
+
|
197
|
+
context 'when given a merge string in the default PR format for a bugfix' do
|
198
|
+
let(:merge_str) { "Merge branch 'bugfix/Stuff'" }
|
199
|
+
|
200
|
+
it 'defaults PR Number to a blank string' do
|
201
|
+
expect(change.pr_number).to eq('')
|
202
|
+
end
|
203
|
+
|
204
|
+
it 'extracts the correct branch type' do
|
205
|
+
expect(change.branch_type).to eq('Bugfix')
|
206
|
+
end
|
207
|
+
|
208
|
+
it 'defaults the dev ID to UNKNOWN' do
|
209
|
+
expect(change.dev_id).to eq('UNKNOWN')
|
210
|
+
end
|
211
|
+
|
212
|
+
it 'renders to markdown correctly' do
|
213
|
+
expect(change.to_md).to eq(" * Bugfix - UNKNOWN - Line 1\n Line 2")
|
214
|
+
end
|
215
|
+
end
|
216
|
+
|
217
|
+
context 'when given a merge string in the default manual format for a hotfix' do
|
218
|
+
let(:merge_str) { "Merge branch 'hotfix/DEV-1_Stuff'" }
|
219
|
+
|
220
|
+
it 'defaults PR Number to a blank string' do
|
221
|
+
expect(change.pr_number).to eq('')
|
222
|
+
end
|
223
|
+
|
224
|
+
it 'extracts the correct branch type' do
|
225
|
+
expect(change.branch_type).to eq('Hotfix')
|
226
|
+
end
|
227
|
+
|
228
|
+
it 'extracts the correct dev ID' do
|
229
|
+
expect(change.dev_id).to eq('DEV-1')
|
230
|
+
end
|
231
|
+
|
232
|
+
it 'renders to markdown correctly' do
|
233
|
+
expect(change.to_md).to eq(" * Hotfix - DEV-1 - Line 1\n Line 2")
|
234
|
+
end
|
235
|
+
end
|
236
|
+
|
237
|
+
context 'when given a merge string in the default PR format for a hotfix' do
|
238
|
+
let(:merge_str) { "Merge branch 'hotfix/Stuff'" }
|
239
|
+
|
240
|
+
it 'defaults PR Number to a blank string' do
|
241
|
+
expect(change.pr_number).to eq('')
|
242
|
+
end
|
243
|
+
|
244
|
+
it 'extracts the correct branch type' do
|
245
|
+
expect(change.branch_type).to eq('Hotfix')
|
246
|
+
end
|
247
|
+
|
248
|
+
it 'defaults the dev ID to UNKNOWN' do
|
249
|
+
expect(change.dev_id).to eq('UNKNOWN')
|
250
|
+
end
|
251
|
+
|
252
|
+
it 'renders to markdown correctly' do
|
253
|
+
expect(change.to_md).to eq(" * Hotfix - UNKNOWN - Line 1\n Line 2")
|
254
|
+
end
|
255
|
+
end
|
256
|
+
|
257
|
+
context 'when no merge type given' do
|
258
|
+
let(:merge_str) { 'Merge pull request #1224 from Xulaus/gem_bump' }
|
259
|
+
it 'extracts the correct PR Number' do
|
260
|
+
expect(change.pr_number).to eq('1224')
|
261
|
+
end
|
262
|
+
|
263
|
+
it 'defaults the branch type to "Task"' do
|
264
|
+
expect(change.branch_type).to eq('Task')
|
265
|
+
end
|
266
|
+
|
267
|
+
it 'defaults the dev ID to UNKNOWN' do
|
268
|
+
expect(change.dev_id).to eq('UNKNOWN')
|
269
|
+
end
|
270
|
+
|
271
|
+
it 'renders to markdown correctly' do
|
272
|
+
expect(change.to_md).to eq(" * Task - UNKNOWN - Line 1\n Line 2")
|
273
|
+
end
|
274
|
+
end
|
275
|
+
end
|
data/spec/config_spec.rb
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
# This Source Code Form is subject to the terms of the Mozilla Public
|
2
|
+
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
3
|
+
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
4
|
+
|
5
|
+
require 'mr_bump/config'
|
6
|
+
|
7
|
+
describe MrBump::Config do
|
8
|
+
context 'when given default, user and project level configuration' do
|
9
|
+
let(:default) { { 'a' => 'a', 'b' => 'a', 'c' => 'a' } }
|
10
|
+
let(:user_level) { { 'c' => 'b', 'b' => 'b' } }
|
11
|
+
let(:project_level) { { 'c' => 'c' } }
|
12
|
+
let(:expected_result) { { 'a' => 'a', 'b' => 'b', 'c' => 'c' } }
|
13
|
+
let(:config) do
|
14
|
+
config = described_class.new
|
15
|
+
allow(config).to receive(:default_config).and_return(default)
|
16
|
+
allow(config).to receive(:user_config).and_return(user_level)
|
17
|
+
allow(config).to receive(:project_config).and_return(project_level)
|
18
|
+
config.config
|
19
|
+
end
|
20
|
+
it 'correctly prefers more specific configuration' do
|
21
|
+
expect(config).to eq(expected_result)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,76 @@
|
|
1
|
+
# This Source Code Form is subject to the terms of the Mozilla Public
|
2
|
+
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
3
|
+
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
4
|
+
|
5
|
+
require 'mr_bump/git_config'
|
6
|
+
|
7
|
+
describe MrBump::GitConfig do
|
8
|
+
let(:config) { described_class.from_origin(origin, 'Someone') }
|
9
|
+
|
10
|
+
context 'Given https origin with no username' do
|
11
|
+
let(:origin) { 'https://github.com/xulaus/mr_bump' }
|
12
|
+
it 'correctly extracts the repository name' do
|
13
|
+
expect(config.repo_name).to eq('mr_bump')
|
14
|
+
end
|
15
|
+
|
16
|
+
it 'correctly constructs github url' do
|
17
|
+
expect(config.repo_url).to eq('https://github.com/xulaus/mr_bump/')
|
18
|
+
end
|
19
|
+
|
20
|
+
it "doesn't extract a username" do
|
21
|
+
expect(config.username.nil?)
|
22
|
+
end
|
23
|
+
|
24
|
+
it "extracts correct host" do
|
25
|
+
expect(config.host).to eq('https://github.com')
|
26
|
+
end
|
27
|
+
|
28
|
+
it "extracts the correct path" do
|
29
|
+
expect(config.path).to eq('xulaus/mr_bump')
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
context 'Given https origin with username' do
|
34
|
+
let(:origin) { 'https://xulaus@github.com/xulaus/mr_bump.git' }
|
35
|
+
it 'correctly extracts the repository name' do
|
36
|
+
expect(config.repo_name).to eq('mr_bump')
|
37
|
+
end
|
38
|
+
it 'correctly constructs github url' do
|
39
|
+
expect(config.repo_url).to eq('https://github.com/xulaus/mr_bump/')
|
40
|
+
end
|
41
|
+
|
42
|
+
it 'correctly extracts the username' do
|
43
|
+
expect(config.username).to eq('xulaus')
|
44
|
+
end
|
45
|
+
|
46
|
+
it "extracts correct host" do
|
47
|
+
expect(config.host).to eq('https://github.com')
|
48
|
+
end
|
49
|
+
|
50
|
+
it "extracts the correct path" do
|
51
|
+
expect(config.path).to eq('xulaus/mr_bump')
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
context 'Given git origin' do
|
56
|
+
let(:origin) { 'git@github.com:xulaus/mr_bump.git' }
|
57
|
+
it 'correctly extracts the repository name' do
|
58
|
+
expect(config.repo_name).to eq('mr_bump')
|
59
|
+
end
|
60
|
+
it 'correctly constructs github url' do
|
61
|
+
expect(config.repo_url).to eq('https://github.com/xulaus/mr_bump/')
|
62
|
+
end
|
63
|
+
|
64
|
+
it "doesn't extract a username" do
|
65
|
+
expect(config.username.nil?)
|
66
|
+
end
|
67
|
+
|
68
|
+
it "extracts correct host" do
|
69
|
+
expect(config.host).to eq('https://github.com')
|
70
|
+
end
|
71
|
+
|
72
|
+
it "extracts the correct path" do
|
73
|
+
expect(config.path).to eq('xulaus/mr_bump')
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
@@ -0,0 +1,238 @@
|
|
1
|
+
# This Source Code Form is subject to the terms of the Mozilla Public
|
2
|
+
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
3
|
+
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
4
|
+
|
5
|
+
require 'mr_bump/version'
|
6
|
+
require 'mr_bump'
|
7
|
+
|
8
|
+
describe MrBump do
|
9
|
+
describe '#all_tagged_versions' do
|
10
|
+
before(:each) { allow(MrBump).to receive(:all_tags).and_return(tag_list) }
|
11
|
+
|
12
|
+
context 'when given a mixed list of tags' do
|
13
|
+
let(:tag_list) do
|
14
|
+
[
|
15
|
+
'safbdhasgbd',
|
16
|
+
'',
|
17
|
+
'9.1.32',
|
18
|
+
'21.1',
|
19
|
+
'132',
|
20
|
+
'Not.A Version'
|
21
|
+
]
|
22
|
+
end
|
23
|
+
it 'parses into versions where possible' do
|
24
|
+
expect(MrBump.all_tagged_versions).to match_array(
|
25
|
+
[
|
26
|
+
MrBump::Version.new('9.1.32'),
|
27
|
+
MrBump::Version.new('21.1'),
|
28
|
+
MrBump::Version.new('132')
|
29
|
+
]
|
30
|
+
)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
describe '#current_uat' do
|
36
|
+
before(:each) do
|
37
|
+
allow(MrBump).to receive(:all_tags).and_return(tag_list)
|
38
|
+
allow(MrBump).to receive(:current_uat_major).and_return(MrBump::Version.new(next_version))
|
39
|
+
end
|
40
|
+
|
41
|
+
context 'when the next release is a minor bump' do
|
42
|
+
let(:next_version) { '1.2.0' }
|
43
|
+
let(:tag_list) do
|
44
|
+
[
|
45
|
+
'safbdhasgbd',
|
46
|
+
'',
|
47
|
+
'Not.A Version',
|
48
|
+
'1.2.3',
|
49
|
+
'1.2.2',
|
50
|
+
'1.1.1',
|
51
|
+
'1.1.9'
|
52
|
+
]
|
53
|
+
end
|
54
|
+
it 'returns the maximum tagged version with the same major and minor numbers' do
|
55
|
+
expect(MrBump.current_uat).to eq(MrBump::Version.new('1.2.3'))
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
context 'when the next release is a major bump' do
|
60
|
+
let(:next_version) { '2.0.0' }
|
61
|
+
let(:tag_list) do
|
62
|
+
[
|
63
|
+
'safbdhasgbd',
|
64
|
+
'',
|
65
|
+
'Not.A Version',
|
66
|
+
'1.2.3',
|
67
|
+
'1.2.2',
|
68
|
+
'1.1.1',
|
69
|
+
'1.0.9',
|
70
|
+
'2.0.0',
|
71
|
+
'2.0.1',
|
72
|
+
'2.0.9'
|
73
|
+
]
|
74
|
+
end
|
75
|
+
it 'returns the maximum tagged version with the same major and minor numbers' do
|
76
|
+
expect(MrBump.current_uat).to eq(MrBump::Version.new('2.0.9'))
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
describe '#current_master' do
|
82
|
+
before(:each) do
|
83
|
+
allow(MrBump).to receive(:all_tags).and_return(tag_list)
|
84
|
+
allow(MrBump).to receive(:current_uat_major).and_return(MrBump::Version.new(next_version))
|
85
|
+
end
|
86
|
+
|
87
|
+
context 'when the next release is a minor bump' do
|
88
|
+
let(:next_version) { '1.2.0' }
|
89
|
+
let(:tag_list) do
|
90
|
+
[
|
91
|
+
'safbdhasgbd',
|
92
|
+
'',
|
93
|
+
'Not.A Version',
|
94
|
+
'1.2.3',
|
95
|
+
'1.2.2',
|
96
|
+
'1.1.1',
|
97
|
+
'1.1.9'
|
98
|
+
]
|
99
|
+
end
|
100
|
+
it 'returns the maximum tagged version below the UAT version' do
|
101
|
+
expect(MrBump.current_master).to eq(MrBump::Version.new('1.1.9'))
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
context 'when the next release is a major bump' do
|
106
|
+
let(:next_version) { '2.0.0' }
|
107
|
+
let(:tag_list) do
|
108
|
+
[
|
109
|
+
'safbdhasgbd',
|
110
|
+
'',
|
111
|
+
'Not.A Version',
|
112
|
+
'1.2.3',
|
113
|
+
'1.2.2',
|
114
|
+
'1.1.1',
|
115
|
+
'1.0.9',
|
116
|
+
'2.0.0',
|
117
|
+
'2.0.1',
|
118
|
+
'2.0.9'
|
119
|
+
]
|
120
|
+
end
|
121
|
+
it 'returns the maximum tagged version below the UAT version' do
|
122
|
+
expect(MrBump.current_master).to eq(MrBump::Version.new('1.2.3'))
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
describe '#latest_release_from_list' do
|
128
|
+
context 'With many release branches and using slash separator' do
|
129
|
+
it 'extracts the highest version' do
|
130
|
+
branch_list = [
|
131
|
+
'origin/release/10.16.0',
|
132
|
+
'origin/release/10.15.9',
|
133
|
+
'origin/release/10.1.0',
|
134
|
+
'origin/release/10.15.0',
|
135
|
+
'origin/rse/10.16.0',
|
136
|
+
'origin/master',
|
137
|
+
''
|
138
|
+
]
|
139
|
+
expect(MrBump.latest_release_from_list(branch_list)).to eq(MrBump::Version.new('10.16.0'))
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
context 'With a single release branch and using slash separator' do
|
144
|
+
it 'extracts the version' do
|
145
|
+
branch_list = [
|
146
|
+
'origin/release/10.16.9',
|
147
|
+
'origin/rse/1.2.0',
|
148
|
+
'origin/master',
|
149
|
+
''
|
150
|
+
]
|
151
|
+
expect(MrBump.latest_release_from_list(branch_list)).to eq(MrBump::Version.new('10.16.0'))
|
152
|
+
end
|
153
|
+
end
|
154
|
+
|
155
|
+
context 'With many release branches and minor versions and using slash separator' do
|
156
|
+
it 'extracts the highest version with patch version set to 0' do
|
157
|
+
branch_list = [
|
158
|
+
'origin/release/10.16.0',
|
159
|
+
'origin/release/10.15.9',
|
160
|
+
'origin/release/10.1.0',
|
161
|
+
'origin/release/10.15.0',
|
162
|
+
'origin/release/10.16.9',
|
163
|
+
'origin/rse/10.16.0',
|
164
|
+
'origin/master',
|
165
|
+
''
|
166
|
+
]
|
167
|
+
expect(MrBump.latest_release_from_list(branch_list)).to eq(MrBump::Version.new('10.16.0'))
|
168
|
+
end
|
169
|
+
end
|
170
|
+
|
171
|
+
context 'With a single release branch with a patch number and using slash separator' do
|
172
|
+
it 'extracts the version with patch version set to 0' do
|
173
|
+
branch_list = [
|
174
|
+
'origin/release/10.16.9',
|
175
|
+
'origin/rse/1.2.0',
|
176
|
+
'origin/master',
|
177
|
+
''
|
178
|
+
]
|
179
|
+
expect(MrBump.latest_release_from_list(branch_list)).to eq(MrBump::Version.new('10.16.0'))
|
180
|
+
end
|
181
|
+
end
|
182
|
+
|
183
|
+
context 'With many release branches and using dash separator' do
|
184
|
+
it 'extracts the highest version' do
|
185
|
+
branch_list = [
|
186
|
+
'origin/release-10.16.0',
|
187
|
+
'origin/release-10.15.9',
|
188
|
+
'origin/release-10.1.0',
|
189
|
+
'origin/release-10.15.0',
|
190
|
+
'origin/rse-10.16.0',
|
191
|
+
'origin/master',
|
192
|
+
''
|
193
|
+
]
|
194
|
+
expect(MrBump.latest_release_from_list(branch_list)).to eq(MrBump::Version.new('10.16.0'))
|
195
|
+
end
|
196
|
+
end
|
197
|
+
|
198
|
+
context 'With a single release branch and using dash separator' do
|
199
|
+
it 'extracts the version' do
|
200
|
+
branch_list = [
|
201
|
+
'origin/release-10.16.9',
|
202
|
+
'origin/rse-1.2.0',
|
203
|
+
'origin/master',
|
204
|
+
''
|
205
|
+
]
|
206
|
+
expect(MrBump.latest_release_from_list(branch_list)).to eq(MrBump::Version.new('10.16.0'))
|
207
|
+
end
|
208
|
+
end
|
209
|
+
|
210
|
+
context 'With many release branches and minor versions and using dash separator' do
|
211
|
+
it 'extracts the highest version with patch version set to 0' do
|
212
|
+
branch_list = [
|
213
|
+
'origin/release-10.16.0',
|
214
|
+
'origin/release-10.15.9',
|
215
|
+
'origin/release-10.1.0',
|
216
|
+
'origin/release-10.15.0',
|
217
|
+
'origin/release-10.16.9',
|
218
|
+
'origin/rse-10.16.0',
|
219
|
+
'origin/master',
|
220
|
+
''
|
221
|
+
]
|
222
|
+
expect(MrBump.latest_release_from_list(branch_list)).to eq(MrBump::Version.new('10.16.0'))
|
223
|
+
end
|
224
|
+
end
|
225
|
+
|
226
|
+
context 'With a single release branch with a patch number and using dash separator' do
|
227
|
+
it 'extracts the version with patch version set to 0' do
|
228
|
+
branch_list = [
|
229
|
+
'origin/release-10.16.9',
|
230
|
+
'origin/rse-1.2.0',
|
231
|
+
'origin/master',
|
232
|
+
''
|
233
|
+
]
|
234
|
+
expect(MrBump.latest_release_from_list(branch_list)).to eq(MrBump::Version.new('10.16.0'))
|
235
|
+
end
|
236
|
+
end
|
237
|
+
end
|
238
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,8 @@
|
|
1
|
+
# This Source Code Form is subject to the terms of the Mozilla Public
|
2
|
+
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
3
|
+
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
4
|
+
|
5
|
+
require 'bundler/setup'
|
6
|
+
Bundler.setup
|
7
|
+
|
8
|
+
require 'mr_bump'
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: mr_bump
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 0.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Richard Fitzgerald
|
@@ -25,6 +25,76 @@ dependencies:
|
|
25
25
|
- - ~>
|
26
26
|
- !ruby/object:Gem::Version
|
27
27
|
version: '1.0'
|
28
|
+
- !ruby/object:Gem::Dependency
|
29
|
+
name: octokit
|
30
|
+
requirement: !ruby/object:Gem::Requirement
|
31
|
+
requirements:
|
32
|
+
- - ~>
|
33
|
+
- !ruby/object:Gem::Version
|
34
|
+
version: '4.0'
|
35
|
+
type: :runtime
|
36
|
+
prerelease: false
|
37
|
+
version_requirements: !ruby/object:Gem::Requirement
|
38
|
+
requirements:
|
39
|
+
- - ~>
|
40
|
+
- !ruby/object:Gem::Version
|
41
|
+
version: '4.0'
|
42
|
+
- !ruby/object:Gem::Dependency
|
43
|
+
name: mustache
|
44
|
+
requirement: !ruby/object:Gem::Requirement
|
45
|
+
requirements:
|
46
|
+
- - ~>
|
47
|
+
- !ruby/object:Gem::Version
|
48
|
+
version: 0.99.3
|
49
|
+
type: :runtime
|
50
|
+
prerelease: false
|
51
|
+
version_requirements: !ruby/object:Gem::Requirement
|
52
|
+
requirements:
|
53
|
+
- - ~>
|
54
|
+
- !ruby/object:Gem::Version
|
55
|
+
version: 0.99.3
|
56
|
+
- !ruby/object:Gem::Dependency
|
57
|
+
name: OptionParser
|
58
|
+
requirement: !ruby/object:Gem::Requirement
|
59
|
+
requirements:
|
60
|
+
- - ! '>='
|
61
|
+
- !ruby/object:Gem::Version
|
62
|
+
version: '0'
|
63
|
+
type: :runtime
|
64
|
+
prerelease: false
|
65
|
+
version_requirements: !ruby/object:Gem::Requirement
|
66
|
+
requirements:
|
67
|
+
- - ! '>='
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: '0'
|
70
|
+
- !ruby/object:Gem::Dependency
|
71
|
+
name: rspec
|
72
|
+
requirement: !ruby/object:Gem::Requirement
|
73
|
+
requirements:
|
74
|
+
- - ! '>='
|
75
|
+
- !ruby/object:Gem::Version
|
76
|
+
version: '0'
|
77
|
+
type: :development
|
78
|
+
prerelease: false
|
79
|
+
version_requirements: !ruby/object:Gem::Requirement
|
80
|
+
requirements:
|
81
|
+
- - ! '>='
|
82
|
+
- !ruby/object:Gem::Version
|
83
|
+
version: '0'
|
84
|
+
- !ruby/object:Gem::Dependency
|
85
|
+
name: pry
|
86
|
+
requirement: !ruby/object:Gem::Requirement
|
87
|
+
requirements:
|
88
|
+
- - ! '>='
|
89
|
+
- !ruby/object:Gem::Version
|
90
|
+
version: '0'
|
91
|
+
type: :development
|
92
|
+
prerelease: false
|
93
|
+
version_requirements: !ruby/object:Gem::Requirement
|
94
|
+
requirements:
|
95
|
+
- - ! '>='
|
96
|
+
- !ruby/object:Gem::Version
|
97
|
+
version: '0'
|
28
98
|
description: Bump versions
|
29
99
|
email: richard.fitzgerald36@gmail.com
|
30
100
|
executables:
|
@@ -33,13 +103,22 @@ extensions: []
|
|
33
103
|
extra_rdoc_files: []
|
34
104
|
files:
|
35
105
|
- bin/mr_bump
|
106
|
+
- defaults.yml
|
36
107
|
- lib/mr_bump.rb
|
108
|
+
- lib/mr_bump/change.rb
|
37
109
|
- lib/mr_bump/config.rb
|
110
|
+
- lib/mr_bump/git_api.rb
|
38
111
|
- lib/mr_bump/git_config.rb
|
39
112
|
- lib/mr_bump/slack.rb
|
40
113
|
- lib/mr_bump/version.rb
|
114
|
+
- spec/change_spec.rb
|
115
|
+
- spec/config_spec.rb
|
116
|
+
- spec/git_config_spec.rb
|
117
|
+
- spec/mr_bump_spec.rb
|
118
|
+
- spec/spec_helper.rb
|
41
119
|
homepage: https://github.com/xulaus/mr_bump
|
42
|
-
licenses:
|
120
|
+
licenses:
|
121
|
+
- MPL 2.0
|
43
122
|
metadata: {}
|
44
123
|
post_install_message:
|
45
124
|
rdoc_options: []
|
@@ -61,4 +140,9 @@ rubygems_version: 2.4.8
|
|
61
140
|
signing_key:
|
62
141
|
specification_version: 3
|
63
142
|
summary: BUMP!
|
64
|
-
test_files:
|
143
|
+
test_files:
|
144
|
+
- spec/change_spec.rb
|
145
|
+
- spec/config_spec.rb
|
146
|
+
- spec/git_config_spec.rb
|
147
|
+
- spec/mr_bump_spec.rb
|
148
|
+
- spec/spec_helper.rb
|