~ knotless Search/
↑↓ move↵ open⇧↵ all results

chadtmiller.com/knotless

git that lives in your Atmosphere account

knotless.dev
1 collaborator

knotless 0.13.0 Latest 2 packages, 1 image

1
10

A deploy keeps the runner unless its build changed

Merged
Merged chadtmiller.com asked to merge into main from chadtmiller.com/knotless:deploy/run-fingerprint

What changes

A deploy restarts knotless-run only when the runner it would start is a different build from the one running, or its settings changed. The image keeps a fingerprint of what the runner is made of, /etc/knotless-run.fingerprint: the knotless-run binary, the docker client and the installed packages (git and the libraries). deploy.sh up compares the running container's fingerprint with the new image's, in place of deploy/run-unchanged.sh's list of source paths, which is removed.

So the fingerprint holds still across commits, KNOTLESS_COMMIT is read as the binaries run (ENV, the image's last layer) rather than built in with option_env!, in knotless-run, knotless-serve, knotless-triage and knotless-agent.

Why

On 2026-11-03, 15 of the 29 pulls that landed restarted the runner, and restarts cancelled 44 checks (just queue-stats). Only about 6 of those pulls changed the runner. The rest restarted it for client-only files in crates/knotless/src (cli.rs, oauth.rs, status.rs), a release's Cargo.lock, or serve's Zoekt stage in the Dockerfile, which the path list counted as the runner's. Comparing the built binary is exact: it restarts the runner only when its bytes change. A runner left running keeps logging the commit it was built from, which is what it runs.

How it was checked

bash -n deploy/deploy.sh. The rest is left to CI, and to the first deploy after this lands. That deploy restarts the runner, as the old container keeps no fingerprint. The deploy log should then say run: its build, …, and settings are the same, not restarted for a pull that does not touch the runner.

Shortcomings

The deploy profile builds with 16 codegen units, and panic locations carry line numbers. So a change in crates/knotless that knotless-run links may still change its bytes, and restart it, even when the runner behaves the same. That is never worse than the old path list. The cost of a restart that does happen is the next pull's work: the old runner hands over to the new one instead of cancelling.

A release still restarts it, as CARGO_PKG_VERSION is built in.

Changeset: none

Approved

This replaces the source-path list with a build fingerprint. The image writes /etc/knotless-run.fingerprint (a hash of the knotless-run binary, the docker client and dpkg/status). deploy.sh up compares the running container's fingerprint with the one in knotless:current. KNOTLESS_COMMIT is now read with ENV at run time, in the last layer, so the binaries no longer change per commit.

I found nothing that must change. I checked these points:

  • knotless:current is tagged before the STATUS block runs, so the candidate read is the new image.
  • No other option_env!("KNOTLESS_COMMIT") or run-unchanged reference remains. runner-host/deploy.sh still passes the build arg, which the ARG still accepts.
  • Every failure to read a fingerprint falls back to a restart, as before.
  • The README and docs/design/runner.md are updated with the change.

One small thing: the fingerprint doesn't cover the knotless CLI or knotless-mcp binaries, so a runner step that depends on them could change without a restart. The runner doesn't appear to call them, so this is only a note.

Merged as 9e26f55