Attest supported third-party tap bottles - #23769
Conversation
Extend bottle attestation verification beyond homebrew/core, add attesting publish workflows to brew tap-new by default with a --no-attestations opt-out, and update tests and documentation for the new third-party tap support.
|
Thanks for your pull request. This has been closed because it appears to be missing the pull request template, perhaps because this was written by an AI not a human. We require humans to read and fill in these templates. Please edit this pull request to fill in the current pull request template. This workflow will reopen this pull request automatically once the template is complete. Do not open a new pull request for this. |
|
Actually, I created it using `gh pr create' but I'll fill out the template. |
There was a problem hiding this comment.
Copilot review overview
🟡 Changes recommended
The generated publish workflow deletes its bottle directory before the new attestation step can access the artifacts.
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Review tier: Balanced
Findings: 1
New issues introduced by this change (2)
| Severity | Finding |
|---|---|
.github/workflows/tap-new-publish.yml — The attestation step cannot see the bottles: brew pr-pull creates them under a temporary… |
|
docs/Homebrew-Security-and-Supply-Chain.md — These two lines each contain two sentences, contrary to the docs convention requiring one sentence… |
What changed in this PR
Extends bottle attestation support to eligible third-party taps and enables attestations in newly generated tap workflows.
Changes:
- Resolves expected attestation repositories from formula taps.
- Adds third-party verification handling and tests.
- Generates attesting publish workflows with an opt-out flag.
| File | Description |
|---|---|
.github/workflows/tap-new-publish.yml |
Adds bottle attestation generation. |
Library/Homebrew/attestation.rb |
Resolves and verifies tap attestations. |
Library/Homebrew/dev-cmd/tap-new.rb |
Adds attestation workflow configuration. |
Library/Homebrew/dev-cmd/verify.rb |
Verifies third-party bottles. |
Library/Homebrew/env_config.rb |
Updates environment descriptions. |
Library/Homebrew/formula_installer.rb |
Enables third-party verification. |
Library/Homebrew/sorbet/rbi/dsl/homebrew/dev_cmd/tap_new.rbi |
Types the new option. |
Library/Homebrew/utils/attestation.rb |
Handles unsupported taps. |
Library/Homebrew/test/attestation_spec.rb |
Tests tap repository resolution. |
Library/Homebrew/test/dev-cmd/tap-new_spec.rb |
Tests workflow generation and opt-out. |
Library/Homebrew/test/dev-cmd/verify_spec.rb |
Tests third-party verification. |
Library/Homebrew/test/formula_installer_spec.rb |
Tests verification enqueueing. |
completions/bash/brew |
Adds Bash completion. |
completions/fish/brew.fish |
Adds fish completion. |
completions/zsh/_brew |
Adds zsh completion. |
docs/Homebrew-Security-and-Supply-Chain.md |
Documents third-party attestations. |
docs/Manpage.md |
Updates generated command documentation. |
manpages/brew.1 |
Updates generated manpage content. |
Files not reviewed (1)
- Library/Homebrew/sorbet/rbi/dsl/homebrew/dev_cmd/tap_new.rbi: File type not supported
💡 Add a code-review agent skill for context-aware, tailored reviews. Learn more in the docs.
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
MikeMcQuaid
left a comment
There was a problem hiding this comment.
Thanks @heaths; great work and looking good so far. A few questions and comments but we're pretty close already.
| # tap-new-attestations-start | ||
| attestations: write | ||
| # tap-new-attestations-end | ||
| checks: read | ||
| contents: write | ||
| # tap-new-attestations-start | ||
| id-token: write | ||
| # tap-new-attestations-end |
There was a problem hiding this comment.
A comment above the comment explaining this and grouping both of these into a single block would be preferable
| switch "--no-attestations", | ||
| description: "Do not include GitHub Artifact Attestations in generated workflows." |
There was a problem hiding this comment.
wondering when/why you'd want to do this. any downsides of just having them always enabled for everyone?
| Verify the build provenance of bottles using GitHub's attestation tools. | ||
| This is done by first fetching the given bottles and then verifying | ||
| their provenance. | ||
| their provenance for `homebrew/core` and supported third-party taps. |
There was a problem hiding this comment.
| their provenance for `homebrew/core` and supported third-party taps. | |
| their provenance for `homebrew/core` and third-party taps that provide attestations. |
| ATTESTATION_MAX_RETRIES = 5 | ||
|
|
||
| sig { params(bottle: Bottle).returns(T.nilable(Formula)) } | ||
| def self.formula_for_bottle(bottle) |
There was a problem hiding this comment.
please inline any new methods used only once


Extend bottle attestation verification beyond homebrew/core, add attesting publish workflows to brew tap-new by default with a --no-attestations opt-out, and update tests and documentation for the new third-party tap support.
This allows third-party taps to be verified if they also attest their bottles. Per a previous discussion, it sounded like verifying third-party taps wasn't supported only due to lack of request or contributions. I've been trying to attest all my binaries but need brew to verify bottles since binaries may be modified even on the host machine, I was told.
brew benchmarkresults.brewcommands to reproduce the bug?brew lgtm(style, typechecking and tests) locally?I did use gpt-5.4 to find relevant code initially but then read through the code to come up with a design and high-level plan, then again to write initial code, but everything was reviewed and code context around changes was considered. I also ran manual tests including rev'ing a formula in my tap after updating my workflow to include the attestation step (and required permissions) in the workflow template in this PR.
Test PR: heaths/homebrew-tap#29. I found an issue because the bottle tarballs were in a temp directory and not available to attest. Passing the
bottle_pathfrom thepull_bottlesstep fixes that, andbrew verify <formula>works: