configure_trusted_publisher 0.1.6 → 0.1.7

Sign up to get free protection for your applications and to get access to all the features.
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