configure_trusted_publisher 0.1.6 → 0.1.8

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: 9618ca80722f42567b997bfc7f392a9c2265bf8bfe504a1a6e2b1fcea797d266
4
+ data.tar.gz: c64f6c0ec0ddbd143483fc4663826edfafb9c84e6d9a8a82d70c66444ef04347
5
5
  SHA512:
6
- metadata.gz: abebcafcae7cd008644fa9e61837e4ea2d298f0ca409c827eed3bf3b90146d6498328d0c02a91f65c373317862962d7faec2a3bb1a524198d51b19119e576507
7
- data.tar.gz: a2d9ee000971206315bb8bbfea72c583eebcc5f4fe05273567dc4148a920367ccb553079d90a3e821f6700c79e18213dd693de8e584edb7d8441efc28cadd9da
6
+ metadata.gz: 0a1274ea1f7f908e57801322ecabfe9960d8e6a0a134ae1dd9c3b7238c4f89ec1e0911a86019c4d01e1ff7b99f68f37d2673dcf19dbd702e54b000f4d26b63a8
7
+ data.tar.gz: 3e49f2378150f87c043d7807031c84eba9b6bf45f402b486efc7ae45330332df4f3522019740a093e0c90b013d99db68adadd1bc7d4f9e1f47d682e80228a6e6
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,24 +154,35 @@ 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
+ environment = add_environment
158
+ write_release_action(repository, rubygem_name, environment:)
159
+
156
160
  gc = GemcutterUtilities.new(
157
161
  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 },
162
+ ask: lambda { |msg|
163
+ puts
164
+ ask msg.strip.chomp(":")
165
+ },
166
+ ask_for_password: lambda { |msg|
167
+ puts
168
+ ask_secret msg.strip.chomp(":")
169
+ },
170
+ terminate_interaction: lambda { |msg|
171
+ puts
172
+ exit msg
173
+ },
161
174
  otp: options[:otp]
162
175
  )
163
176
  gc.sign_in(scope: "configure_trusted_publishers") unless gc.api_key
164
177
 
165
- write_release_action(repository, rubygem_name)
166
-
167
178
  owner, name = github_repository
168
179
  config = {
169
180
  "trusted_publisher" => {
170
181
  "repository_name" => name,
171
182
  "repository_owner" => owner,
183
+ "environment" => environment,
172
184
  "workflow_filename" => "push_gem.yml"
173
- },
185
+ }.compact,
174
186
  "trusted_publisher_type" => "OIDC::TrustedPublisher::GitHubAction"
175
187
  }
176
188
 
@@ -235,13 +247,46 @@ module ConfigureTrustedPublisher
235
247
  raise "No GitHub repository found for #{gemspec.name}"
236
248
  end
237
249
 
250
+ def add_environment
251
+ puts
252
+ return unless ask_yes_or_no("Would you like to add a github environment to allow customizing " \
253
+ "prerequisites for the action?")
254
+
255
+ env_name = "rubygems.org"
256
+
257
+ owner, name = github_repository
258
+ puts "Adding GitHub environment to #{owner}/#{name} to protect the action"
259
+ if (env = Open3.capture2e("gh", "api", "repos/#{owner}/#{name}/environments").then do |output, status|
260
+ exit "Failed to list environments for #{owner}/#{name} using `gh api`:\n#{output}" unless status.success?
261
+
262
+ JSON.parse(output)["environments"].find { |e| e["name"] == env_name }
263
+ end)
264
+
265
+ puts
266
+ puts "Environment 'rubygems.org' already exists for #{owner}/#{name}:\n #{env['html_url']}"
267
+ else
268
+ Open3.capture2e("gh", "api", "--method", "PUT",
269
+ "repos/#{owner}/#{name}/environments/#{env_name}").then do |output, status|
270
+ unless status.success?
271
+ exit "Failed to create rubygems.org environment for #{owner}/#{name} using `gh api`:\n#{output}"
272
+ end
273
+
274
+ env = JSON.parse(output)
275
+ puts
276
+ puts "Created environment 'rubygems.org' for #{owner}/#{name}:\n #{env['html_url']}"
277
+ end
278
+ end
279
+
280
+ env_name
281
+ end
282
+
238
283
  attr_reader :gemspec_source
239
284
 
240
285
  def gemspec
241
286
  gemspec_source.specs.first
242
287
  end
243
288
 
244
- def write_release_action(repository, rubygem_name)
289
+ def write_release_action(repository, rubygem_name, environment: nil)
245
290
  tag = "Automatically when a new tag matching v* is pushed"
246
291
  manual = "Manually by running a GitHub Action"
247
292
  puts
@@ -252,103 +297,50 @@ module ConfigureTrustedPublisher
252
297
  ],
253
298
  default: "2"
254
299
  )
255
- case response
256
- when tag
257
- write_tag_action(repository)
258
- when manual
259
- write_manual_action(repository)
260
- end
261
- end
262
300
 
263
- def write_tag_action(repository)
264
301
  action_file = File.expand_path(".github/workflows/push_gem.yml", repository)
265
302
  return unless check_action(action_file)
266
303
 
267
304
  File.write(
268
305
  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
-
306
+ [
307
+ "name: Push Gem",
308
+ nil,
309
+ "on:",
310
+ " #{response == tag ? "push:\n tags:\n - 'v*'" : 'workflow_dispatch:'}",
311
+ nil,
312
+ "permissions:",
313
+ " contents: read",
314
+ nil,
315
+ "jobs:",
316
+ " push:",
317
+ " if: github.repository == '#{github_repository.join('/')}'",
318
+ " runs-on: ubuntu-latest",
319
+ if environment
320
+ "\n environment:\n name: #{environment}\n url: https://rubygems.org/gems/#{rubygem_name}\n"
321
+ end,
322
+ " permissions:",
323
+ " contents: write",
324
+ " id-token: write",
325
+ nil,
326
+ " steps:",
327
+ " # Set up",
328
+ " - name: Harden Runner",
329
+ " uses: step-security/harden-runner@a4aa98b93cab29d9b1101a6143fb8bce00e2eac4 # v2.7.1",
330
+ " with:",
331
+ " egress-policy: audit",
332
+ nil,
333
+ " - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4",
334
+ " - name: Set up Ruby",
335
+ " uses: ruby/setup-ruby@cacc9f1c0b3f4eb8a16a6bb0ed10897b43b9de49 # v1.176.0",
336
+ " with:",
337
+ " bundler-cache: true",
338
+ " ruby-version: ruby",
339
+ nil,
340
+ " # Release",
341
+ " - uses: rubygems/release-gem@612653d273a73bdae1df8453e090060bb4db5f31 # v1",
342
+ nil
343
+ ].join("\n")
352
344
  )
353
345
  puts "Created #{action_file}"
354
346
  end
@@ -357,9 +349,9 @@ module ConfigureTrustedPublisher
357
349
  return FileUtils.mkdir_p(File.dirname(action_file)) || true unless File.exist?(action_file)
358
350
 
359
351
  puts
360
- response = ask_multiple_choice(
361
- "#{action_file} already exists, overwrite?", { "y" => "Yes", "n" => "No" },
362
- default: "n"
352
+ response = ask_yes_or_no(
353
+ "#{action_file} already exists, overwrite?",
354
+ default: false
363
355
  )
364
356
  return if response == "No"
365
357
 
@@ -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.8"
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
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.8
5
5
  platform: ruby
6
6
  authors:
7
7
  - Samuel Giddins
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2024-05-08 00:00:00.000000000 Z
11
+ date: 2024-06-14 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler