Skip to content

Comments

Use Tempfile for auto-attestation bundles to avoid file conflicts and cleanup issues#9327

Merged
hsbt merged 3 commits intopush-with-attestationfrom
copilot/sub-pr-9325
Feb 10, 2026
Merged

Use Tempfile for auto-attestation bundles to avoid file conflicts and cleanup issues#9327
hsbt merged 3 commits intopush-with-attestationfrom
copilot/sub-pr-9325

Conversation

Copy link
Contributor

Copilot AI commented Feb 10, 2026

What was the end-user or developer problem that led to this PR?

The attest! method wrote attestation bundles to a deterministic path (#{name}.sigstore.json) next to the gem file, which could overwrite existing files and left artifacts behind after successful pushes.

What is your fix for the problem, implemented in this PR?

Changed attest! to use Tempfile for bundle creation instead of a fixed path:

  • Bundle now lives in OS-managed temp directory with unique name
  • Added begin...ensure block in send_push_request_with_attestation to unlink bundle after reading
  • Uses tempfile.close(false) to prevent premature deletion before sigstore-cli writes to it

User-provided attestations via --attestation flag remain unchanged and are not cleaned up.

Make sure the following tasks are checked


✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.

Copilot AI and others added 2 commits February 10, 2026 10:26
Co-authored-by: hsbt <12301+hsbt@users.noreply.github.com>
Co-authored-by: hsbt <12301+hsbt@users.noreply.github.com>
@hsbt hsbt marked this pull request as ready for review February 10, 2026 10:29
Copilot AI review requested due to automatic review settings February 10, 2026 10:29
Copilot AI changed the title [WIP] Address feedback on auto-attestation implementation Use Tempfile for auto-attestation bundles to avoid file conflicts and cleanup issues Feb 10, 2026
@hsbt hsbt merged commit 9f87b0f into push-with-attestation Feb 10, 2026
2 checks passed
Copilot AI requested a review from hsbt February 10, 2026 10:29
@hsbt hsbt deleted the copilot/sub-pr-9325 branch February 10, 2026 10:29
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR iterates on the push command’s auto-attestation flow by switching bundle generation to use a temporary file and ensuring cleanup occurs after the multipart request payload is constructed.

Changes:

  • Update Gem::Commands::PushCommand#attest! to create the sigstore bundle using Tempfile instead of a deterministic path.
  • Ensure the auto-generated bundle file is removed after it’s read into the multipart request payload.
  • Adjust the auto-attestation test to avoid reading the bundle after cleanup.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 3 comments.

File Description
lib/rubygems/commands/push_command.rb Uses Tempfile for bundle path creation and unlinks the auto-attestation bundle after reading it.
test/rubygems/test_gem_commands_push_command.rb Updates the auto-attestation test to assert multipart payload contents without rereading a cleaned-up file.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +125 to +129
begin
[Gem.read_binary(bundle_path)]
ensure
File.unlink(bundle_path) if bundle_path && File.exist?(bundle_path)
end
Copy link

Copilot AI Feb 10, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The ensure cleanup uses File.unlink(...) without rescuing errors. If unlink fails (Windows file locking, permissions, race between exist? and unlink), the push could error out even though the request was constructed successfully. Prefer a non-raising cleanup (FileUtils.rm_f) or rescue SystemCallError around the unlink so cleanup failure doesn’t break the command.

Copilot uses AI. Check for mistakes.
Comment on lines 130 to 137
@@ -133,7 +134,7 @@ def test_execute_attestation_auto
assert_equal Gem::Net::HTTP::Post, @fetcher.last_request.class
content_length = @fetcher.last_request["Content-Length"].to_i
assert_equal content_length, @fetcher.last_request.body.length
assert_attestation_multipart Gem.read_binary(attestation_path)
assert_attestation_multipart attestation_content
Copy link

Copilot AI Feb 10, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This test exercises the auto-attestation path but no longer asserts the key new behavior: that the generated bundle file is cleaned up after request construction. Add an assertion after @cmd.execute that the file at attestation_path no longer exists to prevent regressions in the cleanup logic.

Copilot uses AI. Check for mistakes.
Comment on lines +146 to +150
# Create a temporary file for the bundle
basename = File.basename(name, ".*")
tempfile = Tempfile.new([basename, ".sigstore.json"])
bundle = tempfile.path
tempfile.close(false) # Close but don't unlink - we need the file for sigstore-cli
Copy link

Copilot AI Feb 10, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

attest! creates a Tempfile but only returns its path. Since Tempfile registers a finalizer to unlink the file on GC, the bundle can be deleted between returning from attest! and Gem.read_binary(bundle_path), causing intermittent ENOENT and attestation fallback. Consider managing the tempfile lifetime across signing+reading (e.g., create/hold the Tempfile in send_push_request_with_attestation and only unlink after reading, or use an approach that disables Tempfile auto-unlink and ensures manual cleanup on both success and failure).

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants