git-pr-release 2.3.0 → 2.4.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 17e56434b26daa007a68481f6c125c523c3c2287ce04a3884aa1fd92b3e0f6a2
4
- data.tar.gz: 345da41250aa2f0d723c9cf4f7ee21ad275a41fb45ee217c5e69e4c365e62056
3
+ metadata.gz: 9e376b7fffae49f44aebc877ed835158b11fdcc74cb6ef59f9226b638c9e4d31
4
+ data.tar.gz: cb97fbbffc5be83f438384a02902ba05c6c12327d787d9df93d93f6b5c11c61c
5
5
  SHA512:
6
- metadata.gz: 62394388288ad25af3050f77b036e1c043865c618354f29e7ae00ddad95baf902cbf49b512c581fba3ea122694209de444689baaecf54b11e29bd3f5027dd07c
7
- data.tar.gz: d9aad0d322c38cd485d9f31366076789861d7b79980c68832318a209baa2ac068dbdd2d5f185a90682afcb3a644b8b8af09add2c114d41a0f38952c30181860e
6
+ metadata.gz: bd00f29dcbb0690b1a607ab34a110d51e8b44f25c0f51e834a99a8034062147277fe07d50ee12248494a37e10c1eb2196c3960a3bf7253072be988f3f9cce49b
7
+ data.tar.gz: b18a60610527e86b6ef83bb744d197460bd5e90f2ddc7e35ad8d6502ae633834b2f21a66b41f2f5f174d1ff27401c70743500bcfca715d3024631a8affe69637
@@ -0,0 +1,24 @@
1
+ name: Release new version to RubyGems.org
2
+
3
+ on:
4
+ workflow_dispatch:
5
+
6
+ jobs:
7
+ release:
8
+ runs-on: ubuntu-slim
9
+
10
+ permissions:
11
+ contents: write
12
+ id-token: write
13
+
14
+ steps:
15
+ - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
16
+ with:
17
+ persist-credentials: false
18
+
19
+ - uses: ruby/setup-ruby@ac793fdd38cc468a4dd57246fa9d0e868aba9085 # v1.270.0
20
+ with:
21
+ bundler-cache: true
22
+ ruby-version: ruby
23
+
24
+ - uses: rubygems/release-gem@1c162a739e8b4cb21a676e97b087e8268d8fc40b # v1.1.2
data/CHANGELOG.md CHANGED
@@ -1,5 +1,12 @@
1
1
  # git-pr-release
2
2
 
3
+ ## v2.4.0 (2025-12-16)
4
+
5
+ [full changelog](https://github.com/x-motemen/git-pr-release/compare/v2.3.0...v2.4.0)
6
+
7
+ * (#112) Add release workflow using trusted publishing (@ohbarye)
8
+ * (#110) Support `pr-release.assign-pr-author` and `pr-release.request-pr-author-review` options (@moznion)
9
+
3
10
  ## v2.3.0 (2025-12-15)
4
11
 
5
12
  [full changelog](https://github.com/x-motemen/git-pr-release/compare/v2.2.0...v2.3.0)
data/README.md CHANGED
@@ -96,6 +96,28 @@ You can specify this value by `GIT_PR_RELEASE_MENTION` environment variable.
96
96
 
97
97
  If not specified, the mention will be the PR assignee
98
98
 
99
+ ### `pr-release.assign-pr-author`
100
+
101
+ Whether to assign the related users of the merged pull requests to the release pull request.
102
+ Accepted values: `true` | `false`
103
+
104
+ You can specify this value by `GIT_PR_RELEASE_ASSIGN_PR_AUTHOR` environment variable.
105
+
106
+ If not specified, no assignees will be added.
107
+
108
+ Note: The user selection follows the same logic as `pr-release.mention`. If `mention` is set to `author`, the PR author will be assigned. Otherwise, the PR assignee will be used (falling back to the author if no assignee exists).
109
+
110
+ ### `pr-release.request-pr-author-review`
111
+
112
+ Whether to request review from the related users of the merged pull requests on the release pull request.
113
+ Accepted values: `true` | `false`
114
+
115
+ You can specify this value by `GIT_PR_RELEASE_REQUEST_PR_AUTHOR_REVIEW` environment variable.
116
+
117
+ If not specified, no review requests will be made.
118
+
119
+ Note: The user selection follows the same logic as `pr-release.mention`. If `mention` is set to `author`, the PR author will be requested for review. Otherwise, the PR assignee will be used (falling back to the author if no assignee exists).
120
+
99
121
  ### `pr-release.ssl-no-verify`
100
122
 
101
123
  Whether to verify SSL certificate or not.
@@ -4,7 +4,7 @@ $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 = '2.3.0'
7
+ spec.version = '2.4.0'
8
8
  spec.authors = ["motemen"]
9
9
  spec.email = ["motemen@gmail.com"]
10
10
  spec.summary = 'Creates a release pull request'
@@ -6,7 +6,7 @@ module Git
6
6
  module Release
7
7
  class CLI
8
8
  include Git::Pr::Release::Util
9
- attr_reader :repository, :production_branch, :staging_branch, :template_path, :labels
9
+ attr_reader :repository, :production_branch, :staging_branch, :template_path, :labels, :assign_pr_author, :request_pr_author_review
10
10
 
11
11
  def self.start
12
12
  result = self.new.start
@@ -82,11 +82,19 @@ module Git
82
82
  _labels = ENV.fetch('GIT_PR_RELEASE_LABELS') { git_config('labels') }
83
83
  @labels = _labels && _labels.split(/\s*,\s*/) || []
84
84
 
85
+ _assign_pr_author = ENV.fetch('GIT_PR_RELEASE_ASSIGN_PR_AUTHOR') { git_config('assign-pr-author') }
86
+ @assign_pr_author = %w[true 1].include?(_assign_pr_author)
87
+
88
+ _request_pr_author_review = ENV.fetch('GIT_PR_RELEASE_REQUEST_PR_AUTHOR_REVIEW') { git_config('request-pr-author-review') }
89
+ @request_pr_author_review = %w[true 1].include?(_request_pr_author_review)
90
+
85
91
  say "Repository: #{repository}", :debug
86
92
  say "Production branch: #{production_branch}", :debug
87
93
  say "Staging branch: #{staging_branch}", :debug
88
94
  say "Template path: #{template_path}", :debug
89
95
  say "Labels #{labels}", :debug
96
+ say "Assign PR author: #{assign_pr_author}", :debug
97
+ say "Request PR author review: #{request_pr_author_review}", :debug
90
98
  end
91
99
 
92
100
  def fetch_merged_prs
@@ -212,7 +220,7 @@ module Git
212
220
  return
213
221
  end
214
222
 
215
- update_release_pr(release_pr, pr_title, pr_body)
223
+ update_release_pr(release_pr, pr_title, pr_body, merged_prs)
216
224
 
217
225
  say "#{create_mode ? 'Created' : 'Updated'} pull request: #{release_pr.rels[:html].href}", :notice
218
226
  dump_result_as_json( release_pr, merged_prs, changed_files ) if @json
@@ -238,7 +246,7 @@ module Git
238
246
  [pr_title, merge_pr_body(old_body, new_body)]
239
247
  end
240
248
 
241
- def update_release_pr(release_pr, pr_title, pr_body)
249
+ def update_release_pr(release_pr, pr_title, pr_body, merged_prs)
242
250
  say 'Pull request body:', :debug
243
251
  say pr_body, :debug
244
252
 
@@ -251,6 +259,24 @@ module Git
251
259
  repository, release_pr.number, labels
252
260
  )
253
261
  end
262
+
263
+ if assign_pr_author
264
+ assignees = merged_prs.map { |pr| PullRequest.new(pr).target_user_login_names }.flatten.compact.uniq
265
+ unless assignees.empty?
266
+ client.add_assignees(
267
+ repository, release_pr.number, assignees
268
+ )
269
+ end
270
+ end
271
+
272
+ if request_pr_author_review
273
+ reviewers = merged_prs.map { |pr| PullRequest.new(pr).target_user_login_names }.flatten.compact.uniq
274
+ unless reviewers.empty?
275
+ client.request_pull_request_review(
276
+ repository, release_pr.number, reviewers:
277
+ )
278
+ end
279
+ end
254
280
  end
255
281
 
256
282
  # Fetch PR files of specified pull_request
@@ -27,22 +27,25 @@ module Git
27
27
  end
28
28
 
29
29
  def mention
30
- mention = case PullRequest.mention_type
31
- when 'author'
32
- pr.user ? "@#{pr.user.login}" : nil
33
- else
34
- if pr.assignees&.any? && pr.assignees.length > 1
35
- pr.assignees.map { |assignee| "@#{assignee.login}" }.join(" ")
36
- elsif pr.assignee
37
- "@#{pr.assignee.login}"
38
- elsif pr.user
39
- "@#{pr.user.login}"
40
- else
41
- nil
42
- end
43
- end
44
-
45
- mention ? " #{mention}" : ""
30
+ mention = target_user_login_names.map { |login_name| "@#{login_name}" }.join(" ")
31
+ mention.empty? ? "" : " #{mention}"
32
+ end
33
+
34
+ def target_user_login_names
35
+ case PullRequest.mention_type
36
+ when 'author'
37
+ pr.user ? [pr.user.login] : []
38
+ else
39
+ if pr.assignees&.any? && pr.assignees.length > 1
40
+ pr.assignees.map(&:login)
41
+ elsif pr.assignee
42
+ [pr.assignee.login]
43
+ elsif pr.user
44
+ [pr.user.login]
45
+ else
46
+ []
47
+ end
48
+ end
46
49
  end
47
50
 
48
51
  def self.mention_type
@@ -76,6 +76,8 @@ RSpec.describe Git::Pr::Release::CLI do
76
76
  expect(@cli.staging_branch).to eq "staging"
77
77
  expect(@cli.template_path).to eq nil
78
78
  expect(@cli.labels).to eq []
79
+ expect(@cli.assign_pr_author).to eq false
80
+ expect(@cli.request_pr_author_review).to eq false
79
81
  end
80
82
  end
81
83
 
@@ -181,6 +183,134 @@ RSpec.describe Git::Pr::Release::CLI do
181
183
  end
182
184
  end
183
185
  end
186
+
187
+ describe "assign_pr_author" do
188
+ context "With ENV set to true" do
189
+ around do |example|
190
+ original = ENV.to_hash
191
+ begin
192
+ ENV["GIT_PR_RELEASE_ASSIGN_PR_AUTHOR"] = "true"
193
+ example.run
194
+ ensure
195
+ ENV.replace(original)
196
+ end
197
+ end
198
+
199
+ it "enables assign_pr_author" do
200
+ subject
201
+ expect(@cli.assign_pr_author).to eq true
202
+ end
203
+ end
204
+
205
+ context "With ENV set to 1" do
206
+ around do |example|
207
+ original = ENV.to_hash
208
+ begin
209
+ ENV["GIT_PR_RELEASE_ASSIGN_PR_AUTHOR"] = "1"
210
+ example.run
211
+ ensure
212
+ ENV.replace(original)
213
+ end
214
+ end
215
+
216
+ it "enables assign_pr_author" do
217
+ subject
218
+ expect(@cli.assign_pr_author).to eq true
219
+ end
220
+ end
221
+
222
+ context "With ENV set to false" do
223
+ around do |example|
224
+ original = ENV.to_hash
225
+ begin
226
+ ENV["GIT_PR_RELEASE_ASSIGN_PR_AUTHOR"] = "false"
227
+ example.run
228
+ ensure
229
+ ENV.replace(original)
230
+ end
231
+ end
232
+
233
+ it "disables assign_pr_author" do
234
+ subject
235
+ expect(@cli.assign_pr_author).to eq false
236
+ end
237
+ end
238
+
239
+ context "With git_config" do
240
+ before {
241
+ allow(@cli).to receive(:git_config).with("assign-pr-author") { "true" }
242
+ }
243
+
244
+ it "enables assign_pr_author" do
245
+ subject
246
+ expect(@cli.assign_pr_author).to eq true
247
+ end
248
+ end
249
+ end
250
+
251
+ describe "request_pr_author_review" do
252
+ context "With ENV set to true" do
253
+ around do |example|
254
+ original = ENV.to_hash
255
+ begin
256
+ ENV["GIT_PR_RELEASE_REQUEST_PR_AUTHOR_REVIEW"] = "true"
257
+ example.run
258
+ ensure
259
+ ENV.replace(original)
260
+ end
261
+ end
262
+
263
+ it "enables request_pr_author_review" do
264
+ subject
265
+ expect(@cli.request_pr_author_review).to eq true
266
+ end
267
+ end
268
+
269
+ context "With ENV set to 1" do
270
+ around do |example|
271
+ original = ENV.to_hash
272
+ begin
273
+ ENV["GIT_PR_RELEASE_REQUEST_PR_AUTHOR_REVIEW"] = "1"
274
+ example.run
275
+ ensure
276
+ ENV.replace(original)
277
+ end
278
+ end
279
+
280
+ it "enables request_pr_author_review" do
281
+ subject
282
+ expect(@cli.request_pr_author_review).to eq true
283
+ end
284
+ end
285
+
286
+ context "With ENV set to false" do
287
+ around do |example|
288
+ original = ENV.to_hash
289
+ begin
290
+ ENV["GIT_PR_RELEASE_REQUEST_PR_AUTHOR_REVIEW"] = "false"
291
+ example.run
292
+ ensure
293
+ ENV.replace(original)
294
+ end
295
+ end
296
+
297
+ it "disables request_pr_author_review" do
298
+ subject
299
+ expect(@cli.request_pr_author_review).to eq false
300
+ end
301
+ end
302
+
303
+ context "With git_config" do
304
+ before {
305
+ allow(@cli).to receive(:git_config).with("request-pr-author-review") { "true" }
306
+ }
307
+
308
+ it "enables request_pr_author_review" do
309
+ subject
310
+ expect(@cli.request_pr_author_review).to eq true
311
+ end
312
+ end
313
+ end
184
314
  end
185
315
 
186
316
  describe "#fetch_merged_prs" do
@@ -275,7 +405,7 @@ RSpec.describe Git::Pr::Release::CLI do
275
405
  expect(@cli).to have_received(:prepare_release_pr)
276
406
  expect(@cli).to have_received(:pull_request_files)
277
407
  expect(@cli).to have_received(:build_and_merge_pr_title_and_body).with(@created_pr, @merged_prs, @changed_files)
278
- expect(@cli).to have_received(:update_release_pr).with(@created_pr, @pr_title, @pr_body)
408
+ expect(@cli).to have_received(:update_release_pr).with(@created_pr, @pr_title, @pr_body, @merged_prs)
279
409
  }
280
410
  end
281
411
 
@@ -296,7 +426,7 @@ RSpec.describe Git::Pr::Release::CLI do
296
426
  expect(@cli).to have_received(:pull_request_files).with(existing_release_pr)
297
427
  expect(@cli).not_to have_received(:prepare_release_pr)
298
428
  expect(@cli).to have_received(:build_and_merge_pr_title_and_body).with(existing_release_pr, @merged_prs, @changed_files)
299
- expect(@cli).to have_received(:update_release_pr).with(existing_release_pr, @pr_title, @pr_body)
429
+ expect(@cli).to have_received(:update_release_pr).with(existing_release_pr, @pr_title, @pr_body, @merged_prs)
300
430
  }
301
431
  end
302
432
 
@@ -317,7 +447,7 @@ RSpec.describe Git::Pr::Release::CLI do
317
447
  expect(@cli).not_to have_received(:prepare_release_pr)
318
448
  expect(@cli).not_to have_received(:pull_request_files)
319
449
  expect(@cli).to have_received(:build_and_merge_pr_title_and_body).with(nil, @merged_prs, [])
320
- expect(@cli).not_to have_received(:update_release_pr).with(@created_pr, @pr_title, @pr_body)
450
+ expect(@cli).not_to have_received(:update_release_pr).with(@created_pr, @pr_title, @pr_body, @merged_prs)
321
451
  }
322
452
  end
323
453
 
@@ -343,7 +473,7 @@ RSpec.describe Git::Pr::Release::CLI do
343
473
  subject
344
474
 
345
475
  expect(@cli).not_to have_received(:build_and_merge_pr_title_and_body)
346
- expect(@cli).to have_received(:update_release_pr).with(existing_release_pr, @new_pr_title, @new_pr_body)
476
+ expect(@cli).to have_received(:update_release_pr).with(existing_release_pr, @new_pr_title, @new_pr_body, @merged_prs)
347
477
  }
348
478
  end
349
479
  end
@@ -410,20 +540,32 @@ RSpec.describe Git::Pr::Release::CLI do
410
540
  end
411
541
 
412
542
  describe "#update_release_pr" do
413
- subject { @cli.update_release_pr(@release_pr, "PR Title", "PR Body") }
543
+ subject { @cli.update_release_pr(@release_pr, "PR Title", "PR Body", @merged_prs) }
414
544
 
415
545
  before {
416
546
  @cli = configured_cli
417
547
 
418
548
  @release_pr = double(number: 1023)
419
549
 
550
+ @agent = Sawyer::Agent.new("http://example.com/") do |conn|
551
+ conn.builder.handlers.delete(Faraday::Adapter::NetHttp)
552
+ conn.adapter(:test, Faraday::Adapter::Test::Stubs.new)
553
+ end
554
+ @merged_prs = [
555
+ Sawyer::Resource.new(@agent, load_yaml("pr_3.yml")),
556
+ Sawyer::Resource.new(@agent, load_yaml("pr_4.yml")),
557
+ Sawyer::Resource.new(@agent, load_yaml("pr_6.yml")),
558
+ ]
559
+
420
560
  @client = double(Octokit::Client)
421
561
  allow(@client).to receive(:update_pull_request) { @release_pr }
422
562
  allow(@client).to receive(:add_labels_to_an_issue)
563
+ allow(@client).to receive(:add_assignees)
564
+ allow(@client).to receive(:request_pull_request_review)
423
565
  allow(@cli).to receive(:client) { @client }
424
566
  }
425
567
 
426
- context "Without labels" do
568
+ context "Without labels and without assign_pr_author" do
427
569
  it {
428
570
  subject
429
571
 
@@ -436,6 +578,8 @@ RSpec.describe Git::Pr::Release::CLI do
436
578
  }
437
579
  )
438
580
  expect(@client).not_to have_received(:add_labels_to_an_issue)
581
+ expect(@client).not_to have_received(:add_assignees)
582
+ expect(@client).not_to have_received(:request_pull_request_review)
439
583
  }
440
584
  end
441
585
 
@@ -457,6 +601,58 @@ RSpec.describe Git::Pr::Release::CLI do
457
601
  expect(@client).to have_received(:add_labels_to_an_issue).with(
458
602
  "motemen/git-pr-release", 1023, ["release"]
459
603
  )
604
+ expect(@client).not_to have_received(:add_assignees)
605
+ expect(@client).not_to have_received(:request_pull_request_review)
606
+ }
607
+ end
608
+
609
+ context "With assign_pr_author enabled" do
610
+ before {
611
+ allow(@cli).to receive(:assign_pr_author) { true }
612
+ }
613
+
614
+ it {
615
+ subject
616
+
617
+ expect(@client).to have_received(:update_pull_request).with(
618
+ "motemen/git-pr-release",
619
+ 1023,
620
+ {
621
+ title: "PR Title",
622
+ body: "PR Body",
623
+ }
624
+ )
625
+ # Both pr_3.yml and pr_4.yml have hakobe as the author, so only one unique assignee
626
+ # And the author of pr_6.yml is ninjinkun.
627
+ expect(@client).to have_received(:add_assignees).with(
628
+ "motemen/git-pr-release", 1023, ["hakobe", "ninjinkun"]
629
+ )
630
+ expect(@client).not_to have_received(:request_pull_request_review)
631
+ }
632
+ end
633
+
634
+ context "With request_pr_author_review enabled" do
635
+ before {
636
+ allow(@cli).to receive(:request_pr_author_review) { true }
637
+ }
638
+
639
+ it {
640
+ subject
641
+
642
+ expect(@client).to have_received(:update_pull_request).with(
643
+ "motemen/git-pr-release",
644
+ 1023,
645
+ {
646
+ title: "PR Title",
647
+ body: "PR Body",
648
+ }
649
+ )
650
+ expect(@client).not_to have_received(:add_assignees)
651
+ # Both pr_3.yml and pr_4.yml have hakobe as the author
652
+ # And the author of pr_6.yml is ninjinkun.
653
+ expect(@client).to have_received(:request_pull_request_review).with(
654
+ "motemen/git-pr-release", 1023, reviewers: ["hakobe", "ninjinkun"]
655
+ )
460
656
  }
461
657
  end
462
658
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: git-pr-release
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.3.0
4
+ version: 2.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - motemen
@@ -130,6 +130,7 @@ executables:
130
130
  extensions: []
131
131
  extra_rdoc_files: []
132
132
  files:
133
+ - ".github/workflows/release.yml"
133
134
  - ".github/workflows/test.yml"
134
135
  - ".gitignore"
135
136
  - ".rspec"