git-pr-release 1.1.0 → 1.6.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/CHANGELOG.md +39 -2
- data/README.md +9 -0
- data/git-pr-release.gemspec +3 -2
- data/lib/git/pr/release/cli.rb +130 -77
- data/lib/git/pr/release/pull_request.rb +1 -1
- data/lib/git/pr/release/util.rb +13 -22
- data/spec/git/pr/release/cli_spec.rb +487 -0
- data/spec/git/pr/release_spec.rb +4 -26
- data/spec/spec_helper.rb +10 -0
- metadata +23 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 54aeb2f71e8311efc9d48ea98c695496ddf9a9755d23aa822078484384b83329
|
4
|
+
data.tar.gz: ee8358c06dc99f8d15983c81f9725c50111af8697253fcc39c66bf2eef3099d7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 594733c2d859ec97b8573df6bfb805df8ad83ffde7e1f80afde7bdc889c1f73b1641f54d047657d58b9cea54c3a24375e56cac6088326fe24f28843be756bfda
|
7
|
+
data.tar.gz: '09f9266b8d49b75a8fc2981b524df7a8bfb3bffd100c258ac4d660a1fa6cf3906af51f4ad913ae7ba86a3c13f6b1ec27fb9ce7c59e4e7fde49e9f204544604c8'
|
data/CHANGELOG.md
CHANGED
@@ -1,14 +1,51 @@
|
|
1
1
|
# git-pr-release
|
2
2
|
|
3
|
+
## v1.6.0 (2021-05-15)
|
4
|
+
|
5
|
+
[full changelog](https://github.com/x-motemen/git-pr-release/compare/v1.5.0...v1.6.0)
|
6
|
+
|
7
|
+
* (#63) Sort merged_pull_request_numbers numerically by default (@yutailang0119)
|
8
|
+
|
9
|
+
## v1.5.0 (2021-04-02)
|
10
|
+
|
11
|
+
[full changelog](https://github.com/x-motemen/git-pr-release/compare/v1.4.0...v1.5.0)
|
12
|
+
|
13
|
+
* (#60, #61) Get issue number from GitHub API for squashed PR (@yuuan)
|
14
|
+
* (#58) Make stable test (@kachick)
|
15
|
+
* (#55) Suppress warning for ERB (@ohbarye)
|
16
|
+
* (#50) support `GIT_PR_RELEASE_MENTION` environment variable (@dabutvin)
|
17
|
+
* (#49) Transfer repository to x-motemen organization (@onk)
|
18
|
+
|
19
|
+
## v1.4.0 (2020-02-22)
|
20
|
+
|
21
|
+
[full changelog](https://github.com/x-motemen/git-pr-release/compare/v1.3.0...v1.4.0)
|
22
|
+
|
23
|
+
* (#48) List PR API needs head user or head organization and branch name (@sasasin)
|
24
|
+
|
25
|
+
## v1.3.0 (2020-02-19)
|
26
|
+
|
27
|
+
[full changelog](https://github.com/x-motemen/git-pr-release/compare/v1.2.0...v1.3.0)
|
28
|
+
|
29
|
+
* (#47) Fix Errno::ENOENT when finding the specified template (@onk)
|
30
|
+
* (#45) Fix "warning: instance variable @xxx not initialized" (@onk)
|
31
|
+
|
32
|
+
## v1.2.0 (2020-02-07)
|
33
|
+
|
34
|
+
[full changelog](https://github.com/x-motemen/git-pr-release/compare/v1.1.0...v1.2.0)
|
35
|
+
|
36
|
+
* (#44) Use API option when detecting existing release PR (@onk)
|
37
|
+
* (#41, #42) Refactor (@onk)
|
38
|
+
- Some local variables are removed. This will break if you have customized the template ERB.
|
39
|
+
|
3
40
|
## v1.1.0 (2020-01-02)
|
4
41
|
|
5
|
-
[full changelog](https://github.com/motemen/git-pr-release/compare/v1.0.1...v1.1.0)
|
42
|
+
[full changelog](https://github.com/x-motemen/git-pr-release/compare/v1.0.1...v1.1.0)
|
6
43
|
|
7
44
|
* (#38) Fetch changed files as many as possible (@shibayu36)
|
8
45
|
|
9
46
|
## v1.0.1 (2019-12-17)
|
10
47
|
|
11
|
-
[full changelog](https://github.com/motemen/git-pr-release/compare/v1.0.0...v1.0.1)
|
48
|
+
[full changelog](https://github.com/x-motemen/git-pr-release/compare/v1.0.0...v1.0.1)
|
12
49
|
|
13
50
|
* (#37) Fix NameError (@onk)
|
14
51
|
|
data/README.md
CHANGED
@@ -75,6 +75,15 @@ You can specify this value by `GIT_PR_RELEASE_LABELS` environment variable.
|
|
75
75
|
|
76
76
|
If not specified, any labels will not be added for PRs.
|
77
77
|
|
78
|
+
### `pr-release.mention`
|
79
|
+
|
80
|
+
The name that is listed next to each PR title.
|
81
|
+
Accepted values: `author`
|
82
|
+
|
83
|
+
You can specify this value by `GIT_PR_RELEASE_MENTION` environment variable.
|
84
|
+
|
85
|
+
If not specified, the mention will be the PR assignee
|
86
|
+
|
78
87
|
|
79
88
|
Errors and exit statuses
|
80
89
|
------------------------
|
data/git-pr-release.gemspec
CHANGED
@@ -4,12 +4,12 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
|
4
4
|
|
5
5
|
Gem::Specification.new do |spec|
|
6
6
|
spec.name = "git-pr-release"
|
7
|
-
spec.version = '1.
|
7
|
+
spec.version = '1.6.0'
|
8
8
|
spec.authors = ["motemen"]
|
9
9
|
spec.email = ["motemen@gmail.com"]
|
10
10
|
spec.summary = 'Creates a release pull request'
|
11
11
|
spec.description = 'git-pr-release creates a pull request which summarizes feature branches that are to be released into production'
|
12
|
-
spec.homepage = 'https://github.com/motemen/git-pr-release'
|
12
|
+
spec.homepage = 'https://github.com/x-motemen/git-pr-release'
|
13
13
|
|
14
14
|
spec.files = `git ls-files`.split($/)
|
15
15
|
spec.bindir = "exe"
|
@@ -24,6 +24,7 @@ Gem::Specification.new do |spec|
|
|
24
24
|
|
25
25
|
spec.add_development_dependency 'rspec'
|
26
26
|
spec.add_development_dependency 'timecop'
|
27
|
+
spec.add_development_dependency 'webmock'
|
27
28
|
|
28
29
|
spec.license = 'MIT'
|
29
30
|
end
|
data/lib/git/pr/release/cli.rb
CHANGED
@@ -6,20 +6,21 @@ module Git
|
|
6
6
|
module Release
|
7
7
|
class CLI
|
8
8
|
include Git::Pr::Release::Util
|
9
|
-
|
10
|
-
def self.start
|
11
|
-
host, repository, scheme = host_and_repository_and_scheme
|
9
|
+
attr_reader :repository, :production_branch, :staging_branch, :template_path, :labels
|
12
10
|
|
13
|
-
|
14
|
-
|
15
|
-
|
11
|
+
def self.start
|
12
|
+
result = self.new.start
|
13
|
+
exit result
|
14
|
+
end
|
16
15
|
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
16
|
+
def initialize
|
17
|
+
@dry_run = false
|
18
|
+
@json = false
|
19
|
+
@no_fetch = false
|
20
|
+
@squashed = false
|
21
|
+
end
|
22
22
|
|
23
|
+
def start
|
23
24
|
OptionParser.new do |opts|
|
24
25
|
opts.on('-n', '--dry-run', 'Do not create/update a PR. Just prints out') do |v|
|
25
26
|
@dry_run = v
|
@@ -30,31 +31,78 @@ module Git
|
|
30
31
|
opts.on('--no-fetch', 'Do not fetch from remote repo before determining target PRs (CI friendly)') do |v|
|
31
32
|
@no_fetch = v
|
32
33
|
end
|
34
|
+
opts.on('--squashed', 'Handle squash merged PRs') do |v|
|
35
|
+
@squashed = v
|
36
|
+
end
|
33
37
|
end.parse!
|
34
38
|
|
35
39
|
### Set up configuration
|
40
|
+
configure
|
41
|
+
|
42
|
+
### Fetch merged PRs
|
43
|
+
merged_prs = fetch_merged_prs
|
44
|
+
if merged_prs.empty?
|
45
|
+
say 'No pull requests to be released', :error
|
46
|
+
return 1
|
47
|
+
end
|
48
|
+
|
49
|
+
### Create a release PR
|
50
|
+
create_release_pr(merged_prs)
|
51
|
+
return 0
|
52
|
+
end
|
53
|
+
|
54
|
+
def client
|
55
|
+
@client ||= Octokit::Client.new :access_token => obtain_token!
|
56
|
+
end
|
36
57
|
|
37
|
-
|
38
|
-
|
58
|
+
def configure
|
59
|
+
host, @repository, scheme = host_and_repository_and_scheme
|
60
|
+
|
61
|
+
if host
|
62
|
+
# GitHub:Enterprise
|
63
|
+
OpenSSL::SSL.const_set :VERIFY_PEER, OpenSSL::SSL::VERIFY_NONE # XXX
|
64
|
+
|
65
|
+
Octokit.configure do |c|
|
66
|
+
c.api_endpoint = "#{scheme}://#{host}/api/v3"
|
67
|
+
c.web_endpoint = "#{scheme}://#{host}/"
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
@production_branch = ENV.fetch('GIT_PR_RELEASE_BRANCH_PRODUCTION') { git_config('branch.production') } || 'master'
|
72
|
+
@staging_branch = ENV.fetch('GIT_PR_RELEASE_BRANCH_STAGING') { git_config('branch.staging') } || 'staging'
|
73
|
+
@template_path = ENV.fetch('GIT_PR_RELEASE_TEMPLATE') { git_config('template') }
|
74
|
+
|
75
|
+
_labels = ENV.fetch('GIT_PR_RELEASE_LABELS') { git_config('labels') }
|
76
|
+
@labels = _labels && _labels.split(/\s*,\s*/) || []
|
39
77
|
|
40
78
|
say "Repository: #{repository}", :debug
|
41
79
|
say "Production branch: #{production_branch}", :debug
|
42
80
|
say "Staging branch: #{staging_branch}", :debug
|
81
|
+
say "Template path: #{template_path}", :debug
|
82
|
+
say "Labels #{labels}", :debug
|
83
|
+
end
|
43
84
|
|
44
|
-
|
45
|
-
|
85
|
+
def fetch_merged_prs
|
46
86
|
git :remote, 'update', 'origin' unless @no_fetch
|
47
87
|
|
48
|
-
|
88
|
+
merged_pull_request_numbers = @squashed ? fetch_merged_pr_numbers_from_github : fetch_merged_pr_numbers_from_git_remote
|
89
|
+
|
90
|
+
merged_prs = merged_pull_request_numbers.sort.map do |nr|
|
91
|
+
pr = client.pull_request repository, nr
|
92
|
+
say "To be released: ##{pr.number} #{pr.title}", :notice
|
93
|
+
pr
|
94
|
+
end
|
95
|
+
|
96
|
+
merged_prs
|
97
|
+
end
|
49
98
|
|
50
|
-
|
51
|
-
|
52
|
-
).map do |line|
|
99
|
+
def fetch_merged_pr_numbers_from_git_remote
|
100
|
+
merged_feature_head_sha1s = git(:log, '--merges', '--pretty=format:%P', "origin/#{production_branch}..origin/#{staging_branch}").map do |line|
|
53
101
|
main_sha1, feature_sha1 = line.chomp.split /\s+/
|
54
102
|
feature_sha1
|
55
103
|
end
|
56
104
|
|
57
|
-
|
105
|
+
git('ls-remote', 'origin', 'refs/pull/*/head').map do |line|
|
58
106
|
sha1, ref = line.chomp.split /\s+/
|
59
107
|
|
60
108
|
if merged_feature_head_sha1s.include? sha1
|
@@ -72,87 +120,92 @@ module Git
|
|
72
120
|
end
|
73
121
|
end
|
74
122
|
end.compact
|
123
|
+
end
|
75
124
|
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
pr = client.pull_request repository, nr
|
83
|
-
say "To be released: ##{pr.number} #{pr.title}", :notice
|
84
|
-
pr
|
85
|
-
end
|
125
|
+
def fetch_merged_pr_numbers_from_github
|
126
|
+
git(:log, '--pretty=format:%H', "origin/#{production_branch}..origin/#{staging_branch}").map(&:chomp).map do |sha1|
|
127
|
+
client.search_issues("repo:#{repository} is:pr is:closed #{sha1}")[:items].map(&:number)
|
128
|
+
sleep 1
|
129
|
+
end.flatten
|
130
|
+
end
|
86
131
|
|
87
|
-
|
132
|
+
def create_release_pr(merged_prs)
|
133
|
+
found_release_pr = detect_existing_release_pr
|
134
|
+
create_mode = found_release_pr.nil?
|
88
135
|
|
89
|
-
|
90
|
-
|
91
|
-
|
136
|
+
if create_mode
|
137
|
+
if @dry_run
|
138
|
+
release_pr = nil
|
139
|
+
changed_files = []
|
140
|
+
else
|
141
|
+
release_pr = prepare_release_pr
|
142
|
+
changed_files = pull_request_files(release_pr)
|
143
|
+
end
|
144
|
+
else
|
145
|
+
release_pr = found_release_pr
|
146
|
+
changed_files = pull_request_files(release_pr)
|
92
147
|
end
|
93
|
-
create_mode = found_release_pr.nil?
|
94
148
|
|
95
|
-
|
96
|
-
changed_files = pull_request_files(client, found_release_pr)
|
149
|
+
pr_title, pr_body = build_and_merge_pr_title_and_body(release_pr, merged_prs, changed_files)
|
97
150
|
|
98
151
|
if @dry_run
|
99
|
-
pr_title, new_body = build_pr_title_and_body found_release_pr, merged_prs, changed_files
|
100
|
-
pr_body = create_mode ? new_body : merge_pr_body(found_release_pr.body, new_body)
|
101
|
-
|
102
152
|
say 'Dry-run. Not updating PR', :info
|
103
153
|
say pr_title, :notice
|
104
154
|
say pr_body, :notice
|
105
|
-
dump_result_as_json(
|
106
|
-
|
155
|
+
dump_result_as_json( release_pr, merged_prs, changed_files ) if @json
|
156
|
+
return
|
107
157
|
end
|
108
158
|
|
109
|
-
pr_title, pr_body
|
110
|
-
release_pr = nil
|
159
|
+
update_release_pr(release_pr, pr_title, pr_body)
|
111
160
|
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
end
|
161
|
+
say "#{create_mode ? 'Created' : 'Updated'} pull request: #{release_pr.rels[:html].href}", :notice
|
162
|
+
dump_result_as_json( release_pr, merged_prs, changed_files ) if @json
|
163
|
+
end
|
164
|
+
|
165
|
+
def detect_existing_release_pr
|
166
|
+
say 'Searching for existing release pull requests...', :info
|
167
|
+
user=repository.split("/")[0]
|
168
|
+
client.pull_requests(repository, head: "#{user}:#{staging_branch}", base: production_branch).first
|
169
|
+
end
|
170
|
+
|
171
|
+
def prepare_release_pr
|
172
|
+
client.create_pull_request(
|
173
|
+
repository, production_branch, staging_branch, 'Preparing release pull request...', ''
|
174
|
+
)
|
175
|
+
end
|
128
176
|
|
177
|
+
def build_and_merge_pr_title_and_body(release_pr, merged_prs, changed_files)
|
178
|
+
# release_pr is nil when dry_run && create_mode
|
179
|
+
old_body = release_pr ? release_pr.body : ""
|
180
|
+
pr_title, new_body = build_pr_title_and_body(release_pr, merged_prs, changed_files, template_path)
|
181
|
+
|
182
|
+
[pr_title, merge_pr_body(old_body, new_body)]
|
183
|
+
end
|
184
|
+
|
185
|
+
def update_release_pr(release_pr, pr_title, pr_body)
|
129
186
|
say 'Pull request body:', :debug
|
130
187
|
say pr_body, :debug
|
131
188
|
|
132
|
-
|
189
|
+
client.update_pull_request(
|
133
190
|
repository, release_pr.number, :title => pr_title, :body => pr_body
|
134
191
|
)
|
135
192
|
|
136
|
-
unless
|
137
|
-
|
138
|
-
exit 3
|
139
|
-
end
|
140
|
-
|
141
|
-
labels = ENV.fetch('GIT_PR_RELEASE_LABELS') { git_config('labels') }
|
142
|
-
if not labels.nil? and not labels.empty?
|
143
|
-
labels = labels.split(/\s*,\s*/)
|
144
|
-
labeled_pull_request = client.add_labels_to_an_issue(
|
193
|
+
unless labels.empty?
|
194
|
+
client.add_labels_to_an_issue(
|
145
195
|
repository, release_pr.number, labels
|
146
196
|
)
|
147
|
-
|
148
|
-
unless labeled_pull_request
|
149
|
-
say 'Failed to add labels to a pull request', :error
|
150
|
-
exit 4
|
151
|
-
end
|
152
197
|
end
|
198
|
+
end
|
153
199
|
|
154
|
-
|
155
|
-
|
200
|
+
# Fetch PR files of specified pull_request
|
201
|
+
def pull_request_files(pull_request)
|
202
|
+
return [] if pull_request.nil?
|
203
|
+
|
204
|
+
# Fetch files as many as possible
|
205
|
+
client.auto_paginate = true
|
206
|
+
files = client.pull_request_files repository, pull_request.number
|
207
|
+
client.auto_paginate = false
|
208
|
+
return files
|
156
209
|
end
|
157
210
|
end
|
158
211
|
end
|
data/lib/git/pr/release/util.rb
CHANGED
@@ -83,18 +83,22 @@ Release <%= Time.now %>
|
|
83
83
|
<% end -%>
|
84
84
|
ERB
|
85
85
|
|
86
|
-
def build_pr_title_and_body(release_pr, merged_prs, changed_files)
|
86
|
+
def build_pr_title_and_body(release_pr, merged_prs, changed_files, template_path)
|
87
87
|
release_pull_request = target_pull_request = release_pr ? PullRequest.new(release_pr) : DummyPullRequest.new
|
88
88
|
merged_pull_requests = pull_requests = merged_prs.map { |pr| PullRequest.new(pr) }
|
89
89
|
|
90
|
-
template =
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
erb =
|
90
|
+
template = if template_path
|
91
|
+
template_fullpath = File.join(git('rev-parse', '--show-toplevel').first.chomp, template_path)
|
92
|
+
File.read(template_fullpath)
|
93
|
+
else
|
94
|
+
DEFAULT_PR_TEMPLATE
|
95
|
+
end
|
96
|
+
|
97
|
+
erb = if RUBY_VERSION >= '2.6'
|
98
|
+
ERB.new template, trim_mode: '-'
|
99
|
+
else
|
100
|
+
ERB.new template, nil, '-'
|
101
|
+
end
|
98
102
|
content = erb.result binding
|
99
103
|
content.split(/\n/, 2)
|
100
104
|
end
|
@@ -195,19 +199,6 @@ ERB
|
|
195
199
|
|
196
200
|
auth
|
197
201
|
end
|
198
|
-
|
199
|
-
# Fetch PR files of specified pull_request
|
200
|
-
def pull_request_files(client, pull_request)
|
201
|
-
return [] if pull_request.nil?
|
202
|
-
|
203
|
-
host, repository, scheme = host_and_repository_and_scheme
|
204
|
-
|
205
|
-
# Fetch files as many as possible
|
206
|
-
client.auto_paginate = true
|
207
|
-
files = client.pull_request_files repository, pull_request.number
|
208
|
-
client.auto_paginate = false
|
209
|
-
return files
|
210
|
-
end
|
211
202
|
end
|
212
203
|
end
|
213
204
|
end
|
@@ -0,0 +1,487 @@
|
|
1
|
+
RSpec.describe Git::Pr::Release::CLI do
|
2
|
+
let(:configured_cli) {
|
3
|
+
cli = Git::Pr::Release::CLI.new
|
4
|
+
allow(cli).to receive(:host_and_repository_and_scheme) {
|
5
|
+
[nil, "motemen/git-pr-release", "https"]
|
6
|
+
}
|
7
|
+
allow(cli).to receive(:git_config).with(anything) { nil }
|
8
|
+
cli.configure
|
9
|
+
cli
|
10
|
+
}
|
11
|
+
|
12
|
+
describe "#start" do
|
13
|
+
subject { @cli.start }
|
14
|
+
|
15
|
+
before {
|
16
|
+
@cli = Git::Pr::Release::CLI.new
|
17
|
+
|
18
|
+
allow(@cli).to receive(:configure)
|
19
|
+
allow(@cli).to receive(:fetch_merged_prs) { merged_prs }
|
20
|
+
allow(@cli).to receive(:create_release_pr)
|
21
|
+
}
|
22
|
+
|
23
|
+
context "When merged_prs is empty" do
|
24
|
+
let(:merged_prs) { [] }
|
25
|
+
it {
|
26
|
+
is_expected.to eq 1
|
27
|
+
expect(@cli).to have_received(:configure)
|
28
|
+
expect(@cli).to have_received(:fetch_merged_prs)
|
29
|
+
expect(@cli).not_to have_received(:create_release_pr)
|
30
|
+
}
|
31
|
+
end
|
32
|
+
|
33
|
+
context "When merged_prs exists" do
|
34
|
+
let(:merged_prs) {
|
35
|
+
agent = Sawyer::Agent.new("http://example.com/") do |conn|
|
36
|
+
conn.builder.handlers.delete(Faraday::Adapter::NetHttp)
|
37
|
+
conn.adapter(:test, Faraday::Adapter::Test::Stubs.new)
|
38
|
+
end
|
39
|
+
pr_3 = Sawyer::Resource.new(agent, YAML.load_file(file_fixture("pr_3.yml")))
|
40
|
+
pr_4 = Sawyer::Resource.new(agent, YAML.load_file(file_fixture("pr_4.yml")))
|
41
|
+
[pr_3, pr_4]
|
42
|
+
}
|
43
|
+
it {
|
44
|
+
is_expected.to eq 0
|
45
|
+
expect(@cli).to have_received(:configure)
|
46
|
+
expect(@cli).to have_received(:fetch_merged_prs)
|
47
|
+
expect(@cli).to have_received(:create_release_pr).with(merged_prs)
|
48
|
+
}
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
describe "#configure" do
|
53
|
+
subject { @cli.configure }
|
54
|
+
|
55
|
+
before {
|
56
|
+
@cli = Git::Pr::Release::CLI.new
|
57
|
+
|
58
|
+
allow(@cli).to receive(:git_config).with(anything) { nil }
|
59
|
+
}
|
60
|
+
|
61
|
+
context "When default" do
|
62
|
+
before {
|
63
|
+
allow(@cli).to receive(:host_and_repository_and_scheme) {
|
64
|
+
[nil, "motemen/git-pr-release", "https"]
|
65
|
+
}
|
66
|
+
}
|
67
|
+
|
68
|
+
it "configured as default" do
|
69
|
+
subject
|
70
|
+
|
71
|
+
expect(Octokit.api_endpoint).to eq "https://api.github.com/"
|
72
|
+
expect(Octokit.web_endpoint).to eq "https://github.com/"
|
73
|
+
|
74
|
+
expect(@cli.repository).to eq "motemen/git-pr-release"
|
75
|
+
expect(@cli.production_branch).to eq "master"
|
76
|
+
expect(@cli.staging_branch).to eq "staging"
|
77
|
+
expect(@cli.template_path).to eq nil
|
78
|
+
expect(@cli.labels).to eq []
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
context "When GitHub Enterprise Server" do
|
83
|
+
before {
|
84
|
+
allow(@cli).to receive(:host_and_repository_and_scheme) {
|
85
|
+
["example.com", "motemen/git-pr-release", "https"]
|
86
|
+
}
|
87
|
+
}
|
88
|
+
after {
|
89
|
+
Octokit.reset!
|
90
|
+
}
|
91
|
+
|
92
|
+
it "octokit is configured" do
|
93
|
+
subject
|
94
|
+
|
95
|
+
expect(Octokit.api_endpoint).to eq "https://example.com/api/v3/"
|
96
|
+
expect(Octokit.web_endpoint).to eq "https://example.com/"
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
describe "branches" do
|
101
|
+
context "When branches are set by ENV" do
|
102
|
+
around do |example|
|
103
|
+
original = ENV.to_hash
|
104
|
+
begin
|
105
|
+
ENV["GIT_PR_RELEASE_BRANCH_PRODUCTION"] = "prod"
|
106
|
+
ENV["GIT_PR_RELEASE_BRANCH_STAGING"] = "dev"
|
107
|
+
example.run
|
108
|
+
ensure
|
109
|
+
ENV.replace(original)
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
it "branches are configured" do
|
114
|
+
subject
|
115
|
+
|
116
|
+
expect(@cli.production_branch).to eq "prod"
|
117
|
+
expect(@cli.staging_branch).to eq "dev"
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
context "When branches are set by git_config" do
|
122
|
+
before {
|
123
|
+
allow(@cli).to receive(:git_config).with("branch.production") { "production" }
|
124
|
+
allow(@cli).to receive(:git_config).with("branch.staging") { "develop" }
|
125
|
+
}
|
126
|
+
|
127
|
+
it "branches are configured" do
|
128
|
+
subject
|
129
|
+
|
130
|
+
expect(@cli.production_branch).to eq "production"
|
131
|
+
expect(@cli.staging_branch).to eq "develop"
|
132
|
+
end
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
describe "labels" do
|
137
|
+
context "With ENV" do
|
138
|
+
around do |example|
|
139
|
+
original = ENV.to_hash
|
140
|
+
begin
|
141
|
+
ENV["GIT_PR_RELEASE_LABELS"] = env_labels
|
142
|
+
example.run
|
143
|
+
ensure
|
144
|
+
ENV.replace(original)
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
context "string" do
|
149
|
+
let(:env_labels) { "release" }
|
150
|
+
it "set labels" do
|
151
|
+
subject
|
152
|
+
expect(@cli.labels).to eq ["release"]
|
153
|
+
end
|
154
|
+
end
|
155
|
+
|
156
|
+
context "comma separated string" do
|
157
|
+
let(:env_labels) { "release,release2" }
|
158
|
+
it "set labels" do
|
159
|
+
subject
|
160
|
+
expect(@cli.labels).to eq ["release", "release2"]
|
161
|
+
end
|
162
|
+
end
|
163
|
+
|
164
|
+
context "empty string" do
|
165
|
+
let(:env_labels) { "" }
|
166
|
+
it "set labels as default" do
|
167
|
+
subject
|
168
|
+
expect(@cli.labels).to eq []
|
169
|
+
end
|
170
|
+
end
|
171
|
+
end
|
172
|
+
|
173
|
+
context "With git_config" do
|
174
|
+
before {
|
175
|
+
allow(@cli).to receive(:git_config).with("labels") { "release" }
|
176
|
+
}
|
177
|
+
|
178
|
+
it "set labels" do
|
179
|
+
subject
|
180
|
+
expect(@cli.labels).to eq ["release"]
|
181
|
+
end
|
182
|
+
end
|
183
|
+
end
|
184
|
+
end
|
185
|
+
|
186
|
+
describe "#fetch_merged_prs" do
|
187
|
+
subject { @cli.fetch_merged_prs }
|
188
|
+
|
189
|
+
before {
|
190
|
+
@cli = configured_cli
|
191
|
+
|
192
|
+
agent = Sawyer::Agent.new("http://example.com/") do |conn|
|
193
|
+
conn.builder.handlers.delete(Faraday::Adapter::NetHttp)
|
194
|
+
conn.adapter(:test, Faraday::Adapter::Test::Stubs.new)
|
195
|
+
end
|
196
|
+
|
197
|
+
expect(@cli).to receive(:git).with(:remote, "update", "origin") {
|
198
|
+
[]
|
199
|
+
}
|
200
|
+
|
201
|
+
expect(@cli).to receive(:git).with(:log, "--merges", "--pretty=format:%P", "origin/master..origin/staging") {
|
202
|
+
<<~GIT_LOG.each_line
|
203
|
+
ad694b9c2b868e8801f9209f0ad5dd5458c49854 42bd43b80c973c8f348df3521745201be05bf194
|
204
|
+
b620bead10831d2e4e15be392e0a435d3470a0ad 5c977a1827387ac7b7a85c7b827ee119165f1823
|
205
|
+
GIT_LOG
|
206
|
+
}
|
207
|
+
expect(@cli).to receive(:git).with("ls-remote", "origin", "refs/pull/*/head") {
|
208
|
+
<<~GIT_LS_REMOTE.each_line
|
209
|
+
bbcd2a04ef394e91be44c24e93e52fdbca944060 refs/pull/1/head
|
210
|
+
5c977a1827387ac7b7a85c7b827ee119165f1823 refs/pull/3/head
|
211
|
+
42bd43b80c973c8f348df3521745201be05bf194 refs/pull/4/head
|
212
|
+
GIT_LS_REMOTE
|
213
|
+
}
|
214
|
+
expect(@cli).to receive(:git).with("merge-base", "5c977a1827387ac7b7a85c7b827ee119165f1823", "origin/master") {
|
215
|
+
"b620bead10831d2e4e15be392e0a435d3470a0ad".each_line
|
216
|
+
}
|
217
|
+
expect(@cli).to receive(:git).with("merge-base", "42bd43b80c973c8f348df3521745201be05bf194", "origin/master") {
|
218
|
+
"b620bead10831d2e4e15be392e0a435d3470a0ad".each_line
|
219
|
+
}
|
220
|
+
|
221
|
+
client = double(Octokit::Client)
|
222
|
+
@pr_3 = Sawyer::Resource.new(agent, YAML.load_file(file_fixture("pr_3.yml")))
|
223
|
+
@pr_4 = Sawyer::Resource.new(agent, YAML.load_file(file_fixture("pr_4.yml")))
|
224
|
+
expect(client).to receive(:pull_request).with("motemen/git-pr-release", 3) { @pr_3 }
|
225
|
+
expect(client).to receive(:pull_request).with("motemen/git-pr-release", 4) { @pr_4 }
|
226
|
+
allow(@cli).to receive(:client).with(no_args) { client }
|
227
|
+
}
|
228
|
+
|
229
|
+
it { is_expected.to eq [@pr_3, @pr_4] }
|
230
|
+
end
|
231
|
+
|
232
|
+
describe "#create_release_pr" do
|
233
|
+
subject { @cli.create_release_pr(@merged_prs) }
|
234
|
+
|
235
|
+
before {
|
236
|
+
@cli = configured_cli
|
237
|
+
|
238
|
+
@agent = Sawyer::Agent.new("http://example.com/") do |conn|
|
239
|
+
conn.builder.handlers.delete(Faraday::Adapter::NetHttp)
|
240
|
+
conn.adapter(:test, Faraday::Adapter::Test::Stubs.new)
|
241
|
+
end
|
242
|
+
|
243
|
+
@merged_prs = [
|
244
|
+
Sawyer::Resource.new(@agent, YAML.load_file(file_fixture("pr_3.yml"))),
|
245
|
+
Sawyer::Resource.new(@agent, YAML.load_file(file_fixture("pr_4.yml"))),
|
246
|
+
]
|
247
|
+
|
248
|
+
allow(@cli).to receive(:detect_existing_release_pr) { existing_release_pr }
|
249
|
+
@pr_title = "Release 2020-01-04 16:51:09 +0900"
|
250
|
+
@pr_body = <<~BODY.chomp
|
251
|
+
- [ ] #3 Provides a creating release pull-request object for template @hakobe
|
252
|
+
- [ ] #4 use user who create PR if there is no assignee @motemen
|
253
|
+
BODY
|
254
|
+
allow(@cli).to receive(:build_and_merge_pr_title_and_body) {
|
255
|
+
[@pr_title, @pr_body]
|
256
|
+
}
|
257
|
+
allow(@cli).to receive(:update_release_pr)
|
258
|
+
@changed_files = [double(Sawyer::Resource)]
|
259
|
+
allow(@cli).to receive(:pull_request_files) { @changed_files }
|
260
|
+
}
|
261
|
+
|
262
|
+
context "When create_mode" do
|
263
|
+
before {
|
264
|
+
@created_pr = Sawyer::Resource.new(@agent, YAML.load_file(file_fixture("pr_1.yml")))
|
265
|
+
allow(@cli).to receive(:prepare_release_pr) { @created_pr }
|
266
|
+
}
|
267
|
+
|
268
|
+
let(:existing_release_pr) { nil }
|
269
|
+
|
270
|
+
it {
|
271
|
+
subject
|
272
|
+
|
273
|
+
expect(@cli).to have_received(:detect_existing_release_pr)
|
274
|
+
expect(@cli).to have_received(:prepare_release_pr)
|
275
|
+
expect(@cli).to have_received(:pull_request_files)
|
276
|
+
expect(@cli).to have_received(:build_and_merge_pr_title_and_body).with(@created_pr, @merged_prs, @changed_files)
|
277
|
+
expect(@cli).to have_received(:update_release_pr).with(@created_pr, @pr_title, @pr_body)
|
278
|
+
}
|
279
|
+
end
|
280
|
+
|
281
|
+
context "When not create_mode" do
|
282
|
+
before {
|
283
|
+
allow(@cli).to receive(:prepare_release_pr)
|
284
|
+
}
|
285
|
+
|
286
|
+
let(:existing_release_pr) { double(
|
287
|
+
number: 1023,
|
288
|
+
rels: { html: double(href: "https://github.com/motemen/git-pr-release/pull/1023") },
|
289
|
+
)}
|
290
|
+
|
291
|
+
it {
|
292
|
+
subject
|
293
|
+
|
294
|
+
expect(@cli).to have_received(:detect_existing_release_pr)
|
295
|
+
expect(@cli).to have_received(:pull_request_files).with(existing_release_pr)
|
296
|
+
expect(@cli).not_to have_received(:prepare_release_pr)
|
297
|
+
expect(@cli).to have_received(:build_and_merge_pr_title_and_body).with(existing_release_pr, @merged_prs, @changed_files)
|
298
|
+
expect(@cli).to have_received(:update_release_pr).with(existing_release_pr, @pr_title, @pr_body)
|
299
|
+
}
|
300
|
+
end
|
301
|
+
|
302
|
+
context "When dry_run with create_mode" do
|
303
|
+
before {
|
304
|
+
@created_pr = Sawyer::Resource.new(@agent, YAML.load_file(file_fixture("pr_1.yml")))
|
305
|
+
allow(@cli).to receive(:prepare_release_pr) { @created_pr }
|
306
|
+
|
307
|
+
@cli.instance_variable_set(:@dry_run, true)
|
308
|
+
}
|
309
|
+
|
310
|
+
let(:existing_release_pr) { nil }
|
311
|
+
|
312
|
+
it {
|
313
|
+
subject
|
314
|
+
|
315
|
+
expect(@cli).to have_received(:detect_existing_release_pr)
|
316
|
+
expect(@cli).not_to have_received(:prepare_release_pr)
|
317
|
+
expect(@cli).not_to have_received(:pull_request_files)
|
318
|
+
expect(@cli).to have_received(:build_and_merge_pr_title_and_body).with(nil, @merged_prs, [])
|
319
|
+
expect(@cli).not_to have_received(:update_release_pr).with(@created_pr, @pr_title, @pr_body)
|
320
|
+
}
|
321
|
+
end
|
322
|
+
end
|
323
|
+
|
324
|
+
describe "#prepare_release_pr" do
|
325
|
+
subject { @cli.prepare_release_pr }
|
326
|
+
|
327
|
+
before {
|
328
|
+
@cli = configured_cli
|
329
|
+
|
330
|
+
@client = double(Octokit::Client)
|
331
|
+
allow(@client).to receive(:create_pull_request)
|
332
|
+
allow(@cli).to receive(:client) { @client }
|
333
|
+
}
|
334
|
+
|
335
|
+
it {
|
336
|
+
subject
|
337
|
+
|
338
|
+
expect(@client).to have_received(:create_pull_request).with(
|
339
|
+
"motemen/git-pr-release",
|
340
|
+
"master",
|
341
|
+
"staging",
|
342
|
+
"Preparing release pull request...",
|
343
|
+
"", # empby body
|
344
|
+
)
|
345
|
+
}
|
346
|
+
end
|
347
|
+
|
348
|
+
describe "#build_and_merge_pr_title_and_body" do
|
349
|
+
subject { @cli.build_and_merge_pr_title_and_body(release_pr, @merged_prs, changed_files) }
|
350
|
+
|
351
|
+
before {
|
352
|
+
@cli = configured_cli
|
353
|
+
|
354
|
+
@merged_prs = [double(Sawyer::Resource)]
|
355
|
+
allow(@cli).to receive(:build_pr_title_and_body) { ["PR Title", "PR Body"] }
|
356
|
+
allow(@cli).to receive(:merge_pr_body) { "Merged Body" }
|
357
|
+
}
|
358
|
+
|
359
|
+
context "When release_pr exists" do
|
360
|
+
let(:release_pr) { double(body: "Old Body") }
|
361
|
+
let(:changed_files) { [double(Sawyer::Resource)] }
|
362
|
+
|
363
|
+
it {
|
364
|
+
is_expected.to eq ["PR Title", "Merged Body"]
|
365
|
+
|
366
|
+
expect(@cli).to have_received(:build_pr_title_and_body).with(release_pr, @merged_prs, changed_files, nil)
|
367
|
+
expect(@cli).to have_received(:merge_pr_body).with("Old Body", "PR Body")
|
368
|
+
}
|
369
|
+
end
|
370
|
+
|
371
|
+
context "When release_pr is nil" do
|
372
|
+
# = When dry_run with create_mode
|
373
|
+
let(:release_pr) { nil }
|
374
|
+
let(:changed_files) { [] }
|
375
|
+
|
376
|
+
it {
|
377
|
+
is_expected.to eq ["PR Title", "Merged Body"]
|
378
|
+
|
379
|
+
expect(@cli).to have_received(:build_pr_title_and_body).with(release_pr, @merged_prs, changed_files, nil)
|
380
|
+
expect(@cli).to have_received(:merge_pr_body).with("", "PR Body")
|
381
|
+
}
|
382
|
+
end
|
383
|
+
end
|
384
|
+
|
385
|
+
describe "#update_release_pr" do
|
386
|
+
subject { @cli.update_release_pr(@release_pr, "PR Title", "PR Body") }
|
387
|
+
|
388
|
+
before {
|
389
|
+
@cli = configured_cli
|
390
|
+
|
391
|
+
@release_pr = double(number: 1023)
|
392
|
+
|
393
|
+
@client = double(Octokit::Client)
|
394
|
+
allow(@client).to receive(:update_pull_request) { @release_pr }
|
395
|
+
allow(@client).to receive(:add_labels_to_an_issue)
|
396
|
+
allow(@cli).to receive(:client) { @client }
|
397
|
+
}
|
398
|
+
|
399
|
+
context "Without labels" do
|
400
|
+
it {
|
401
|
+
subject
|
402
|
+
|
403
|
+
expect(@client).to have_received(:update_pull_request).with(
|
404
|
+
"motemen/git-pr-release",
|
405
|
+
1023,
|
406
|
+
{
|
407
|
+
title: "PR Title",
|
408
|
+
body: "PR Body",
|
409
|
+
}
|
410
|
+
)
|
411
|
+
expect(@client).not_to have_received(:add_labels_to_an_issue)
|
412
|
+
}
|
413
|
+
end
|
414
|
+
|
415
|
+
context "With labels" do
|
416
|
+
before {
|
417
|
+
allow(@cli).to receive(:labels) { ["release"] }
|
418
|
+
}
|
419
|
+
it {
|
420
|
+
subject
|
421
|
+
|
422
|
+
expect(@client).to have_received(:update_pull_request).with(
|
423
|
+
"motemen/git-pr-release",
|
424
|
+
1023,
|
425
|
+
{
|
426
|
+
title: "PR Title",
|
427
|
+
body: "PR Body",
|
428
|
+
}
|
429
|
+
)
|
430
|
+
expect(@client).to have_received(:add_labels_to_an_issue).with(
|
431
|
+
"motemen/git-pr-release", 1023, ["release"]
|
432
|
+
)
|
433
|
+
}
|
434
|
+
end
|
435
|
+
end
|
436
|
+
|
437
|
+
describe "#detect_existing_release_pr" do
|
438
|
+
subject { @cli.detect_existing_release_pr }
|
439
|
+
|
440
|
+
before {
|
441
|
+
@cli = configured_cli
|
442
|
+
|
443
|
+
@client = double(Octokit::Client)
|
444
|
+
allow(@cli).to receive(:client).with(no_args) { @client }
|
445
|
+
}
|
446
|
+
|
447
|
+
context "When exists" do
|
448
|
+
before {
|
449
|
+
@release_pr = double(head: double(ref: "staging"), base: double(ref: "master"))
|
450
|
+
allow(@client).to receive(:pull_requests) { [@release_pr] }
|
451
|
+
}
|
452
|
+
|
453
|
+
it { is_expected.to eq @release_pr }
|
454
|
+
end
|
455
|
+
|
456
|
+
context "When not exists" do
|
457
|
+
before {
|
458
|
+
allow(@client).to receive(:pull_requests) { [] }
|
459
|
+
}
|
460
|
+
|
461
|
+
it { is_expected.to be_nil }
|
462
|
+
end
|
463
|
+
end
|
464
|
+
|
465
|
+
describe "#pull_request_files" do
|
466
|
+
subject { @cli.pull_request_files(@release_pr) }
|
467
|
+
|
468
|
+
before {
|
469
|
+
@cli = configured_cli
|
470
|
+
|
471
|
+
@release_pr = double(number: 1023)
|
472
|
+
@client = double(Octokit::Client)
|
473
|
+
@changed_files = [double(Sawyer::Resource)]
|
474
|
+
allow(@client).to receive(:pull_request_files) { @changed_files }
|
475
|
+
allow(@client).to receive(:auto_paginate=)
|
476
|
+
allow(@cli).to receive(:client) { @client }
|
477
|
+
}
|
478
|
+
|
479
|
+
it {
|
480
|
+
is_expected.to eq @changed_files
|
481
|
+
|
482
|
+
expect(@client).to have_received(:auto_paginate=).with(true)
|
483
|
+
expect(@client).to have_received(:pull_request_files).with("motemen/git-pr-release", 1023)
|
484
|
+
expect(@client).to have_received(:auto_paginate=).with(false)
|
485
|
+
}
|
486
|
+
end
|
487
|
+
end
|
data/spec/git/pr/release_spec.rb
CHANGED
@@ -19,9 +19,9 @@ RSpec.describe Git::Pr::Release do
|
|
19
19
|
end
|
20
20
|
|
21
21
|
describe "#build_pr_title_and_body" do
|
22
|
-
context "without
|
22
|
+
context "without template_path" do
|
23
23
|
it {
|
24
|
-
pr_title, new_body = build_pr_title_and_body(@release_pr, @merged_prs, @changed_files)
|
24
|
+
pr_title, new_body = build_pr_title_and_body(@release_pr, @merged_prs, @changed_files, nil)
|
25
25
|
expect(pr_title).to eq "Release 2019-02-20 22:58:35 +0900"
|
26
26
|
expect(new_body).to eq <<~MARKDOWN
|
27
27
|
- [ ] #3 Provides a creating release pull-request object for template @hakobe
|
@@ -30,37 +30,15 @@ RSpec.describe Git::Pr::Release do
|
|
30
30
|
}
|
31
31
|
end
|
32
32
|
|
33
|
-
context "with
|
34
|
-
before {
|
35
|
-
ENV["GIT_PR_RELEASE_TEMPLATE"] = "spec/fixtures/file/template_1.erb"
|
36
|
-
}
|
37
|
-
|
38
|
-
after {
|
39
|
-
ENV["GIT_PR_RELEASE_TEMPLATE"] = nil
|
40
|
-
}
|
41
|
-
|
33
|
+
context "with template_path" do
|
42
34
|
it {
|
43
|
-
pr_title, new_body = build_pr_title_and_body(@release_pr, @merged_prs, @changed_files)
|
35
|
+
pr_title, new_body = build_pr_title_and_body(@release_pr, @merged_prs, @changed_files, "spec/fixtures/file/template_1.erb")
|
44
36
|
expect(pr_title).to eq "a"
|
45
37
|
expect(new_body).to eq <<~MARKDOWN
|
46
38
|
b
|
47
39
|
MARKDOWN
|
48
40
|
}
|
49
41
|
end
|
50
|
-
|
51
|
-
context "with git_config template" do
|
52
|
-
before {
|
53
|
-
expect(self).to receive(:git_config).with("template") { "spec/fixtures/file/template_2.erb" }
|
54
|
-
}
|
55
|
-
|
56
|
-
it {
|
57
|
-
pr_title, new_body = build_pr_title_and_body(@release_pr, @merged_prs, @changed_files)
|
58
|
-
expect(pr_title).to eq "c"
|
59
|
-
expect(new_body).to eq <<~MARKDOWN
|
60
|
-
d
|
61
|
-
MARKDOWN
|
62
|
-
}
|
63
|
-
end
|
64
42
|
end
|
65
43
|
|
66
44
|
describe "#dump_result_as_json" do
|
data/spec/spec_helper.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
require "timecop"
|
2
2
|
require "yaml"
|
3
3
|
require "git/pr/release"
|
4
|
+
require "webmock/rspec"
|
4
5
|
|
5
6
|
RSpec.configure do |config|
|
6
7
|
config.expect_with :rspec do |expectations|
|
@@ -18,6 +19,15 @@ RSpec.configure do |config|
|
|
18
19
|
config.order = :random
|
19
20
|
Kernel.srand config.seed
|
20
21
|
|
22
|
+
config.around(:each) do |example|
|
23
|
+
begin
|
24
|
+
ENV['TZ'], old = 'Asia/Tokyo', ENV['TZ']
|
25
|
+
example.run
|
26
|
+
ensure
|
27
|
+
ENV['TZ'] = old
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
21
31
|
config.after do
|
22
32
|
Timecop.return
|
23
33
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: git-pr-release
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.6.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- motemen
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2021-05-14 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: octokit
|
@@ -94,6 +94,20 @@ dependencies:
|
|
94
94
|
- - ">="
|
95
95
|
- !ruby/object:Gem::Version
|
96
96
|
version: '0'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: webmock
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - ">="
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '0'
|
104
|
+
type: :development
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - ">="
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '0'
|
97
111
|
description: git-pr-release creates a pull request which summarizes feature branches
|
98
112
|
that are to be released into production
|
99
113
|
email:
|
@@ -124,15 +138,16 @@ files:
|
|
124
138
|
- spec/fixtures/file/pr_6.yml
|
125
139
|
- spec/fixtures/file/template_1.erb
|
126
140
|
- spec/fixtures/file/template_2.erb
|
141
|
+
- spec/git/pr/release/cli_spec.rb
|
127
142
|
- spec/git/pr/release_spec.rb
|
128
143
|
- spec/spec_helper.rb
|
129
144
|
- spec/support/capture_support.rb
|
130
145
|
- spec/support/file_fixture_support.rb
|
131
|
-
homepage: https://github.com/motemen/git-pr-release
|
146
|
+
homepage: https://github.com/x-motemen/git-pr-release
|
132
147
|
licenses:
|
133
148
|
- MIT
|
134
149
|
metadata: {}
|
135
|
-
post_install_message:
|
150
|
+
post_install_message:
|
136
151
|
rdoc_options: []
|
137
152
|
require_paths:
|
138
153
|
- lib
|
@@ -147,8 +162,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
147
162
|
- !ruby/object:Gem::Version
|
148
163
|
version: '0'
|
149
164
|
requirements: []
|
150
|
-
rubygems_version: 3.0.
|
151
|
-
signing_key:
|
165
|
+
rubygems_version: 3.3.0.dev
|
166
|
+
signing_key:
|
152
167
|
specification_version: 4
|
153
168
|
summary: Creates a release pull request
|
154
169
|
test_files:
|
@@ -159,6 +174,7 @@ test_files:
|
|
159
174
|
- spec/fixtures/file/pr_6.yml
|
160
175
|
- spec/fixtures/file/template_1.erb
|
161
176
|
- spec/fixtures/file/template_2.erb
|
177
|
+
- spec/git/pr/release/cli_spec.rb
|
162
178
|
- spec/git/pr/release_spec.rb
|
163
179
|
- spec/spec_helper.rb
|
164
180
|
- spec/support/capture_support.rb
|