git-attest 1.0.0

Verify a signed attestation that a test suite already passed on this exact tree, so CI can skip it
git-attest-1.0.0 is not a library.
Visit the last successful build: git-attest-1.7.0

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:

ssh-keygen -t ed25519 -N '' -C "$(git config user.email)" -f ~/.ssh/amont-attest
git config --global amont.attest true

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

cargo install git-attest
git-attest covered                     # names, or nothing
git-attest explain                     # ...and why

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:

make check                                  # both implementations
./tests/conformance.sh ./verify.sh
./tests/conformance.sh "target/release/git-attest covered"

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.