configure_trusted_publisher 0.1.6 → 0.1.7

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: 75930e6d2a3b492c60737125a7e4a96abf6f50339722b4d454e2641675c4d094
4
- data.tar.gz: 45b86dc2cea3ac44909fe36e93d4cedd98f8ec06abf6e7af4b0dbc33c2050f07
3
+ metadata.gz: 62e88e6f8fe2b2d276cb12750fa89c2197510a32c2c0f173f8d1fb0882c48195
4
+ data.tar.gz: 1aca9105419c282a2e007f9d0289425bfddbdca0508a008d9142fddb79aa7072
5
5
  SHA512:
6
- metadata.gz: abebcafcae7cd008644fa9e61837e4ea2d298f0ca409c827eed3bf3b90146d6498328d0c02a91f65c373317862962d7faec2a3bb1a524198d51b19119e576507
7
- data.tar.gz: a2d9ee000971206315bb8bbfea72c583eebcc5f4fe05273567dc4148a920367ccb553079d90a3e821f6700c79e18213dd693de8e584edb7d8441efc28cadd9da
6
+ metadata.gz: 593966c8a3b809875c88151be176f7e6c62feeb934f337cf1e54479668fd24dbc4e763fb3bb1eb579292b9f1b4e758fef4c9b9e3db8f59c9677446df9eca974a
7
+ data.tar.gz: 9ea13772ac9bd771cdf766cdfed92e906aaf05498744172a225c055d5e71a1fd5b2f598ba86e4c5700b78c3c3b42c4d61aab8c1b29b3c52325dd3c0f797032f5
data/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # ConfigureTrustedPublisher
2
2
 
3
- A small CLI to automate the process of configuring a trusted publisher for a gem.
3
+ A small CLI to automate the process of configuring a [trusted publisher](https://guides.rubygems.org/trusted-publishing/) for a gem and [automating gem releases](https://guides.rubygems.org/trusted-publishing/releasing-gems/) with GitHub Actions!.
4
4
 
5
5
  ## Usage
6
6
 
@@ -9,6 +9,7 @@ To configure a trusted publisher for a gem, run the following command:
9
9
  ```console
10
10
  $ gem exec configure_trusted_publisher rubygem
11
11
  Configuring trusted publisher for rubygem0 in /Users/segiddins/Development/github.com/rubygems/configure_trusted_publisher for rubygems/configure_trusted_publisher
12
+
12
13
  Enter your https://rubygems.org credentials.
13
14
  Don't have an account yet? Create one at https://rubygems.org/sign_up
14
15
  Username/email: : gem-author
@@ -9,6 +9,7 @@ require "bundler"
9
9
  require "json"
10
10
  require "open3"
11
11
  require "rubygems/gemcutter_utilities"
12
+ require "yaml"
12
13
 
13
14
  Gem.configuration.verbose = true
14
15
 
@@ -153,17 +154,26 @@ module ConfigureTrustedPublisher
153
154
  puts "Configuring trusted publisher for #{rubygem_name} in #{File.expand_path(repository)} for " \
154
155
  "#{github_repository.join('/')}"
155
156
 
157
+ write_release_action(repository, rubygem_name, environment: add_environment)
158
+
156
159
  gc = GemcutterUtilities.new(
157
160
  say: ->(msg) { puts msg },
158
- ask: ->(msg) { ask msg.chomp(":") },
159
- ask_for_password: ->(msg) { ask_secret msg.chomp(":") },
160
- terminate_interaction: ->(msg) { exit msg },
161
+ ask: lambda { |msg|
162
+ puts
163
+ ask msg.chomp(":")
164
+ },
165
+ ask_for_password: lambda { |msg|
166
+ puts
167
+ ask_secret msg.chomp(":")
168
+ },
169
+ terminate_interaction: lambda { |msg|
170
+ puts
171
+ exit msg
172
+ },
161
173
  otp: options[:otp]
162
174
  )
163
175
  gc.sign_in(scope: "configure_trusted_publishers") unless gc.api_key
164
176
 
165
- write_release_action(repository, rubygem_name)
166
-
167
177
  owner, name = github_repository
168
178
  config = {
169
179
  "trusted_publisher" => {
@@ -235,13 +245,46 @@ module ConfigureTrustedPublisher
235
245
  raise "No GitHub repository found for #{gemspec.name}"
236
246
  end
237
247
 
248
+ def add_environment
249
+ puts
250
+ return unless ask_yes_or_no("Would you like to add a github environment to allow customizing " \
251
+ "prerequisites for the action?")
252
+
253
+ env_name = "rubygems.org"
254
+
255
+ owner, name = github_repository
256
+ puts "Adding GitHub environment to #{owner}/#{name} to protect the action"
257
+ if (env = Open3.capture2e("gh", "api", "repos/#{owner}/#{name}/environments").then do |output, status|
258
+ exit "Failed to list environments for #{owner}/#{name} using `gh api`:\n#{output}" unless status.success?
259
+
260
+ JSON.parse(output)["environments"].find { |e| e["name"] == env_name }
261
+ end)
262
+
263
+ puts
264
+ puts "Environment 'rubygems.org' already exists for #{owner}/#{name}:\n #{env['html_url']}"
265
+ else
266
+ Open3.capture2e("gh", "api", "--method", "PUT",
267
+ "repos/#{owner}/#{name}/environments/#{env_name}").then do |output, status|
268
+ unless status.success?
269
+ exit "Failed to create rubygems.org environment for #{owner}/#{name} using `gh api`:\n#{output}"
270
+ end
271
+
272
+ env = JSON.parse(output)
273
+ puts
274
+ puts "Created environment 'rubygems.org' for #{owner}/#{name}:\n #{env['html_url']}"
275
+ end
276
+ end
277
+
278
+ env_name
279
+ end
280
+
238
281
  attr_reader :gemspec_source
239
282
 
240
283
  def gemspec
241
284
  gemspec_source.specs.first
242
285
  end
243
286
 
244
- def write_release_action(repository, rubygem_name)
287
+ def write_release_action(repository, rubygem_name, environment: nil)
245
288
  tag = "Automatically when a new tag matching v* is pushed"
246
289
  manual = "Manually by running a GitHub Action"
247
290
  puts
@@ -252,103 +295,50 @@ module ConfigureTrustedPublisher
252
295
  ],
253
296
  default: "2"
254
297
  )
255
- case response
256
- when tag
257
- write_tag_action(repository)
258
- when manual
259
- write_manual_action(repository)
260
- end
261
- end
262
298
 
263
- def write_tag_action(repository)
264
299
  action_file = File.expand_path(".github/workflows/push_gem.yml", repository)
265
300
  return unless check_action(action_file)
266
301
 
267
302
  File.write(
268
303
  action_file,
269
- <<~YAML
270
- name: Push Gem
271
-
272
- on:
273
- push:
274
- tags:
275
- - v*
276
-
277
- permissions:
278
- contents: read
279
-
280
- jobs:
281
- push:
282
- if: github.repository == '#{github_repository.join('/')}'
283
- runs-on: ubuntu-latest
284
-
285
- permissions:
286
- contents: write
287
- id-token: write
288
-
289
- steps:
290
- # Set up
291
- - name: Harden Runner
292
- uses: step-security/harden-runner@a4aa98b93cab29d9b1101a6143fb8bce00e2eac4 # v2.7.1
293
- with:
294
- egress-policy: audit
295
-
296
- - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4
297
- - name: Set up Ruby
298
- uses: ruby/setup-ruby@cacc9f1c0b3f4eb8a16a6bb0ed10897b43b9de49 # v1.176.0
299
- with:
300
- bundler-cache: true
301
- ruby-version: ruby
302
-
303
- # Release
304
- - uses: rubygems/release-gem@612653d273a73bdae1df8453e090060bb4db5f31 # v1
305
- YAML
306
- )
307
- puts "Created #{action_file}"
308
- end
309
-
310
- def write_manual_action(repository)
311
- action_file = File.expand_path(".github/workflows/push_gem.yml", repository)
312
- return unless check_action(action_file)
313
-
314
- File.write(
315
- action_file,
316
- <<~YAML
317
- name: Push Gem
318
-
319
- on:
320
- workflow_dispatch:
321
-
322
- permissions:
323
- contents: read
324
-
325
- jobs:
326
- push:
327
- if: github.repository == '#{github_repository.join('/')}'
328
- runs-on: ubuntu-latest
329
-
330
- permissions:
331
- contents: write
332
- id-token: write
333
-
334
- steps:
335
- # Set up
336
- - name: Harden Runner
337
- uses: step-security/harden-runner@a4aa98b93cab29d9b1101a6143fb8bce00e2eac4 # v2.7.1
338
- with:
339
- egress-policy: audit
340
-
341
- - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4
342
- - name: Set up Ruby
343
- uses: ruby/setup-ruby@cacc9f1c0b3f4eb8a16a6bb0ed10897b43b9de49 # v1.176.0
344
- with:
345
- bundler-cache: true
346
- ruby-version: ruby
347
-
348
- # Release
349
- - uses: rubygems/release-gem@612653d273a73bdae1df8453e090060bb4db5f31 # v1
350
- YAML
351
-
304
+ [
305
+ "name: Push Gem",
306
+ nil,
307
+ "on:",
308
+ " #{response == tag ? "push:\n tags:\n - 'v*'" : 'workflow_dispatch:'}",
309
+ nil,
310
+ "permissions:",
311
+ " contents: read",
312
+ nil,
313
+ "jobs:",
314
+ " push:",
315
+ " if: github.repository == '#{github_repository.join('/')}'",
316
+ " runs-on: ubuntu-latest",
317
+ if environment
318
+ "\n environment:\n name: #{environment}\n url: https://rubygems.org/gems/#{rubygem_name}\n"
319
+ end,
320
+ " permissions:",
321
+ " contents: write",
322
+ " id-token: write",
323
+ nil,
324
+ " steps:",
325
+ " # Set up",
326
+ " - name: Harden Runner",
327
+ " uses: step-security/harden-runner@a4aa98b93cab29d9b1101a6143fb8bce00e2eac4 # v2.7.1",
328
+ " with:",
329
+ " egress-policy: audit",
330
+ nil,
331
+ " - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4",
332
+ " - name: Set up Ruby",
333
+ " uses: ruby/setup-ruby@cacc9f1c0b3f4eb8a16a6bb0ed10897b43b9de49 # v1.176.0",
334
+ " with:",
335
+ " bundler-cache: true",
336
+ " ruby-version: ruby",
337
+ nil,
338
+ " # Release",
339
+ " - uses: rubygems/release-gem@612653d273a73bdae1df8453e090060bb4db5f31 # v1",
340
+ nil
341
+ ].join("\n")
352
342
  )
353
343
  puts "Created #{action_file}"
354
344
  end
@@ -357,9 +347,9 @@ module ConfigureTrustedPublisher
357
347
  return FileUtils.mkdir_p(File.dirname(action_file)) || true unless File.exist?(action_file)
358
348
 
359
349
  puts
360
- response = ask_multiple_choice(
361
- "#{action_file} already exists, overwrite?", { "y" => "Yes", "n" => "No" },
362
- default: "n"
350
+ response = ask_yes_or_no(
351
+ "#{action_file} already exists, overwrite?",
352
+ default: false
363
353
  )
364
354
  return if response == "No"
365
355
 
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ConfigureTrustedPublisher
4
- VERSION = "0.1.6"
4
+ VERSION = "0.1.7"
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: configure_trusted_publisher
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.6
4
+ version: 0.1.7
5
5
  platform: ruby
6
6
  authors:
7
7
  - Samuel Giddins