attest
Your laptop already ran the tests. Stop paying CI to run them again.
When a pre-push hook runs your test suite, that result is thrown away the
moment the push succeeds — and CI runs the same suite again, on the same
content, for minutes you pay for. attest lets the hook sign what it
proved, and lets CI verify that signature and skip the work.
- uses: actions/checkout@v4
- id: attest
uses: fredericrous/attest@v1
- run: cargo test --workspace
if: ${{ !contains(fromJSON(steps.attest.outputs.gates), 'pre-push-cargo-test') }}
That is the whole integration. Nothing is skipped unless a signature by a key you committed to the repository covers the exact tree CI checked out, on the same platform the job is running.
Safety, stated plainly
Nothing here can make an untested tree skip CI. It can only cost a redundant
run. Every failure path — no note, no key, no ssh-keygen, a rebase, a
tampered payload, a signature from a stranger — reports "nothing covered", and
nothing covered means your tests run. The verifier always exits 0; it can never
fail your build.
The price of that is silence, so the action explains itself in the job log:
attest: attested on aarch64-macos, this leg is x86_64-linux
attest: no attestation found for tree 9f2a1c…
attest: covered by you@example.com: pre-push-cargo-test pre-push-clippy
Setup
Three steps, once.
1. Make a signing key and tell your hook runner to use it:
2. Commit the public half as .github/allowed_signers (or
.forgejo/allowed_signers), pinned to the namespace:
you@example.com namespaces="amont-attest" ssh-ed25519 AAAAC3Nza…
Use your real address, the one in the note's principal column. The action defaults to the first principal this file names, so there is nothing to keep in sync.
3. Add the step, as shown at the top.
Producing attestations
amont is the reference producer: with
amont.attest enabled it signs a note at pre-push naming the gates that
actually passed. Any tool can produce one — SPEC.md is the format,
and it is short.
What is in here
SPEC.md |
the amont-attest-v2 wire format |
action.yml |
the composite action, for GitHub and Forgejo |
verify.sh |
the verifier the action runs. git and ssh-keygen, nothing else |
src/ |
git-attest, the same contract as a binary |
tests/conformance.sh |
the fixtures both implementations must pass |
Forgejo
Same file, full-URL uses::
- uses: https://github.com/fredericrous/attest@v1
Other CI
git-attest explain is the answer to "why didn't it skip?", which is otherwise
unanswerable by design.
Zero dependencies
The verifier decides whether tests may be skipped, so it is a security
boundary, and everything it links is something you have to trust. It links
nothing. The hard parts — ed25519, the OpenSSH signature envelope — are handled
by ssh-keygen, which is already on every runner and audited by people who do
that for a living.
Contributing
tests/conformance.sh runs the fixtures against any implementation:
tests/legacy.sh is a negative control — the verifier this project
replaces, kept so the suite can prove it is not vacuous. Cases marked
(defect N) must fail against it. Please don't fix it.
MIT.