summaryrefslogtreecommitdiff
path: root/lib/rubygems/commands/push_command.rb
diff options
context:
space:
mode:
authorSamuel Giddins <[email protected]>2024-11-13 18:48:58 -0600
committergit <[email protected]>2024-11-20 19:32:49 +0000
commitb70c1bb1503df69716312ce5b0ad89e9be02d44b (patch)
tree8f11838139cf71bf81d4fb625a5dd63f0030c574 /lib/rubygems/commands/push_command.rb
parentb4969348bf16c9aaf8eaf78b230527955939d59c (diff)
[rubygems/rubygems] Add --attestation option to gem push
Signed-off-by: Samuel Giddins <[email protected]> https://github.com/rubygems/rubygems/commit/a5412d9a0e
Diffstat (limited to 'lib/rubygems/commands/push_command.rb')
-rw-r--r--lib/rubygems/commands/push_command.rb34
1 files changed, 29 insertions, 5 deletions
diff --git a/lib/rubygems/commands/push_command.rb b/lib/rubygems/commands/push_command.rb
index 591ddc3a80..726191377a 100644
--- a/lib/rubygems/commands/push_command.rb
+++ b/lib/rubygems/commands/push_command.rb
@@ -30,7 +30,7 @@ The push command will use ~/.gem/credentials to authenticate to a server, but yo
end
def initialize
- super "push", "Push a gem up to the gem server", host: host
+ super "push", "Push a gem up to the gem server", host: host, attestations: []
@user_defined_host = false
@@ -45,6 +45,11 @@ The push command will use ~/.gem/credentials to authenticate to a server, but yo
@user_defined_host = true
end
+ add_option("--attestation FILE",
+ "Push with sigstore attestations") do |value, options|
+ options[:attestations] << value
+ end
+
@host = nil
end
@@ -88,10 +93,18 @@ The push command will use ~/.gem/credentials to authenticate to a server, but yo
def send_push_request(name, args)
rubygems_api_request(*args, scope: get_push_scope) do |request|
- request.body = Gem.read_binary name
- request.add_field "Content-Length", request.body.size
- request.add_field "Content-Type", "application/octet-stream"
- request.add_field "Authorization", api_key
+ body = Gem.read_binary name
+ if options[:attestations].any?
+ request.set_form([
+ ["gem", body, { filename: name, content_type: "application/octet-stream" }],
+ get_attestations_part,
+ ], "multipart/form-data")
+ else
+ request.body = body
+ request.add_field "Content-Type", "application/octet-stream"
+ request.add_field "Content-Length", request.body.size
+ end
+ request.add_field "Authorization", api_key
end
end
@@ -107,4 +120,15 @@ The push command will use ~/.gem/credentials to authenticate to a server, but yo
def get_push_scope
:push_rubygem
end
+
+ def get_attestations_part
+ bundles = "[" + options[:attestations].map do |attestation|
+ Gem.read_binary(attestation)
+ end.join(",") + "]"
+ [
+ "attestations",
+ bundles,
+ { content_type: "application/json" },
+ ]
+ end
end