tasks/rubygems_patch.rb in oidc-test-trusted_publisher-0.8.12 vs tasks/rubygems_patch.rb in oidc-test-trusted_publisher-0.8.13
- old
+ new
@@ -1,18 +1,46 @@
# frozen_string_literal: true
+return unless defined?(Gem)
+
require "rubygems/commands/push_command"
Gem::Commands::PushCommand.prepend(Module.new do
def send_push_request(name, args)
- return super unless ENV["gem_attestation_path"]
+ return super if options[:attestations]&.any? || @host != "https://rubygems.org"
- rubygems_api_request(*args, scope: get_push_scope) do |request|
- request.set_form([
- ["gem", Gem.read_binary(name), { filename: name, content_type: "application/octet-stream" }],
- ["attestations", "[#{Gem.read_binary(ENV["gem_attestation_path"])}]",
- { content_type: "application/json" }]
- ], "multipart/form-data")
- request.add_field "Authorization", api_key
+ begin
+ send_push_request_with_attestation(name, args)
+ rescue StandardError => e
+ alert_warning "Failed to push with attestation, retrying without attestation.\n#{e.full_message}"
+ super
end
+ end
+
+ def send_push_request_with_attestation(name, args)
+ attestation = attest!(name)
+ if options[:attestations]
+ options[:attestations] << attestation
+ send_push_request(name, args)
+ else
+ rubygems_api_request(*args, scope: get_push_scope) do |request|
+ request.set_form([
+ ["gem", Gem.read_binary(name), { filename: name, content_type: "application/octet-stream" }],
+ ["attestations", "[#{Gem.read_binary(attestation)}]", { content_type: "application/json" }]
+ ], "multipart/form-data")
+ request.add_field "Authorization", api_key
+ end
+ end
+ end
+
+ def attest!(name)
+ require "open3"
+ bundle = "#{name}.sigstore.json"
+ out, st = Open3.capture2e(
+ Gem.ruby, "-S", "gem", "exec",
+ "sigstore-cli:0.2.1", "sign", name, "--bundle", bundle
+ )
+ raise Gem::Exception, "Failed to sign gem:\n\n#{out}" unless st.success?
+
+ bundle
end
end)