feat: auto-attest docker images pushed in later steps#33
Draft
tooky wants to merge 1 commit into
Draft
Conversation
Opt-in via attest-docker-artifact: true. On Linux runners the action installs bash shims for docker/buildx/docker-buildx that shadow the real binaries on the PATH of subsequent steps. After a successful push (docker push, build --push, or --output type=registry/push=true) the shim runs `kosli attest artifact <ref> --artifact-type=oci` for each pushed tag, deriving --name from the image ref unless artifact-name is set. Attest failures warn by default (fail-on-attest-error to opt out); a real docker failure is never masked. The shim source is embedded as a JS string constant so ncc bundles it into dist/ on release. Unit tests execute the shim against stub docker/kosli binaries; a new integration job pushes to a local registry:2 with KOSLI_DRY_RUN. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Adds an opt-in
attest-docker-artifact: trueinput. When enabled (Linux runners only), the action installs bash shims fordocker,buildx, anddocker-buildxthat shadow the real binaries on thePATHof subsequent steps. Whenever a later step pushes an image —docker push,docker build --push,docker buildx build --push, standalonebuildx build --push, or the--output type=registry/push=truelong forms — the shim runsfor each pushed tag, after the push succeeds. No explicit attest step needed:
--nameis derived per image ref (strip digest → last/-segment → strip tag), so monorepos pushing several images each get their own artifact name;artifact-nameoverrides it for single-artifact repos.attest-flagsappends extra flags;fail-on-attest-error(default false) controls whether a failed attestation fails the push step. A real docker/buildx failure is never masked, and the shim writes only to stderr so$(docker push -q ...)captures stay clean.How
src/shim.js— the bash shim embedded as a JS string constant, sonccbundles it intodist/on release (a runtime-read.shasset would only break in released tags). Bash-3.2 compatible.src/wrapDocker.js— resolves the real binaries, writes the shim per program name into a fresh dir under$RUNNER_TEMP, passes config viaKOSLI_SHIM_*env vars (can't collide with the CLI'sKOSLI_<flag>binding), prepends the dir toPATH. Warns and no-ops rather than ever failing the CLI install.Testing
test/shim.test.jsexecutes the real shim against stubdocker/koslibinaries that record their argv — 26 cases covering all three invocation names, ref collection, dedupe, name derivation, and failure handling.test/wrapDocker.test.jsunit-tests the installer with injected deps.attest-dockerintegration job intest.yaml: pushes to a localregistry:2withKOSLI_DRY_RUN=trueand asserts the shim's marker lines fordocker push,docker buildx build --push, and a no-push build.Learnings from the first CI run (all green)
kosli attest artifact --artifact-type=ociunderKOSLI_DRY_RUNfingerprints an image from a plain-HTTPlocalhost:5000registry with no extra flags or config. The integration job needed zero debug cycles.kosli-shim:marker lines (not kosli's dry-run output) worked as intended — the integration test stays decoupled from CLI output format changes.spawnSynccalls block the worker thread, so the harness spawns the shim asynchronously; andnpm run build'sconvert-actionstep rewritesaction.ymltomain: dist/index.js, which must not be committed on main (dist/only lands on release tags).v1 limitations (documented in README)
--all-tagspush (warned + skipped), absolute-path invocations of docker (PATH shims can't intercept),buildx bake/docker compose push, attest-flags values containing spaces.🤖 Generated with Claude Code