Containers: release runner with docker access + restore runtime image smoke tests #26

Closed
opened 2026-04-17 16:32:04 +00:00 by claude-desktop · 0 comments
Collaborator

User story

As an operator, I want the release pipeline to actually exercise the
published image end-to-end — verifying that bun, git, forgejo-mcp
and claude all run inside it, and that no credential files ship with
it — so that a bad image cannot be tagged and pushed unnoticed.

Follow-up to #18 / PR #23: the PR CI for the Dockerfile had to be
downgraded to a daemonless static audit because this repo's
forgejo-runner (v12.8.2) strips --privileged from service containers
and does not bind-mount /var/run/docker.sock into job containers. That
is the right trade-off for PR runs (no broad docker privileges just to
check a pull request) but it leaves release.yml without the runtime
checks the original story called for.

Acceptance criteria

Runner

  • A dedicated forgejo-runner instance (or label) with docker access.
    Option A: bind-mount /var/run/docker.sock via container.options
    in the runner config.yml. Option B: run a privileged DinD
    service successfully by patching forgejo-runner to pass through
    options:. Option A is simpler; Option B is more isolated.
  • The runner is labelled so only release.yml jobs can pick it up
    (e.g. runs-on: [docker, release]). PR CI must NOT land on it.
  • Runner deployment documented in README.md or a dedicated
    docs/runner-setup.md.

release.yml — runtime verification after push

  • After docker/build-push-action@v6 pushes, pull the
    just-published image by digest and run:
    • bun --version
    • git --version
    • forgejo-mcp --help
    • claude --version
      Fail the release if any command exits non-zero.
  • Run the credential-file check against the published image:
    assert /home/claude/.claude.json, /home/claude/.credentials.json,
    /home/claude/.config/claude-hooks, /root/.claude.json,
    /root/.credentials.json do not exist. Fail the release if any
    found.
  • If any runtime check fails after the push, the release must be
    rolled back (delete the tag from the registry or leave a clear
    "do not use" marker on the release notes). Pick one and document.

PR CI

  • The static dockerfile job in qa.yml stays as-is. It already
    catches hadolint issues and credential-leak patterns in the
    Dockerfile source without needing a daemon.

Tests

  • Smoke-run the release pipeline against a test tag (e.g. v0.0.0-rc1)
    end-to-end before cutting the first real release.

Out of scope

  • Replacing forgejo-runner with a different action runner.
  • Rootless buildah or kaniko alternatives — revisit only if Option A
    (socket mount) proves unworkable.
  • Multi-platform smoke testing (running linux/arm64 image on amd64
    runner needs QEMU emulation; defer until demand exists).

References

  • Parent tracking issue: #17
  • PR that introduced the Dockerfile: #23 (commit a0863b4 documents the
    PR-time / release-time split)
  • forgejo-runner issue: options:-passthrough on service containers
    (v12.8.2 behaviour)

Dependencies

  • Blocked by: PR #23 landing (the Dockerfile itself)
  • Blocks: none — this is a hardening step, the containerisation
    milestone can progress without it in place
  • Branch off: main
  • Full graph: #17
## User story As an **operator**, I want the release pipeline to actually exercise the published image end-to-end — verifying that `bun`, `git`, `forgejo-mcp` and `claude` all run inside it, and that no credential files ship with it — so that a bad image cannot be tagged and pushed unnoticed. Follow-up to #18 / PR #23: the PR CI for the Dockerfile had to be downgraded to a daemonless static audit because this repo's forgejo-runner (v12.8.2) strips `--privileged` from service containers and does not bind-mount `/var/run/docker.sock` into job containers. That is the right trade-off for PR runs (no broad docker privileges just to check a pull request) but it leaves release.yml without the runtime checks the original story called for. ## Acceptance criteria ### Runner - [ ] A dedicated forgejo-runner instance (or label) with docker access. Option A: bind-mount `/var/run/docker.sock` via `container.options` in the runner `config.yml`. Option B: run a privileged DinD service successfully by patching forgejo-runner to pass through `options:`. Option A is simpler; Option B is more isolated. - [ ] The runner is labelled so only `release.yml` jobs can pick it up (e.g. `runs-on: [docker, release]`). PR CI must NOT land on it. - [ ] Runner deployment documented in `README.md` or a dedicated `docs/runner-setup.md`. ### release.yml — runtime verification after push - [ ] After `docker/build-push-action@v6` pushes, pull the just-published image by digest and run: - `bun --version` - `git --version` - `forgejo-mcp --help` - `claude --version` Fail the release if any command exits non-zero. - [ ] Run the credential-file check against the published image: assert `/home/claude/.claude.json`, `/home/claude/.credentials.json`, `/home/claude/.config/claude-hooks`, `/root/.claude.json`, `/root/.credentials.json` do not exist. Fail the release if any found. - [ ] If any runtime check fails after the push, the release must be rolled back (delete the tag from the registry or leave a clear "do not use" marker on the release notes). Pick one and document. ### PR CI - [ ] The static `dockerfile` job in `qa.yml` stays as-is. It already catches hadolint issues and credential-leak patterns in the Dockerfile source without needing a daemon. ### Tests - [ ] Smoke-run the release pipeline against a test tag (e.g. `v0.0.0-rc1`) end-to-end before cutting the first real release. ## Out of scope - Replacing forgejo-runner with a different action runner. - Rootless buildah or kaniko alternatives — revisit only if Option A (socket mount) proves unworkable. - Multi-platform smoke testing (running linux/arm64 image on amd64 runner needs QEMU emulation; defer until demand exists). ## References - Parent tracking issue: #17 - PR that introduced the Dockerfile: #23 (commit `a0863b4` documents the PR-time / release-time split) - forgejo-runner issue: options:-passthrough on service containers (v12.8.2 behaviour) ## Dependencies - **Blocked by:** PR #23 landing (the Dockerfile itself) - **Blocks:** none — this is a hardening step, the containerisation milestone can progress without it in place - **Branch off:** `main` - **Full graph:** #17
Sign in to join this conversation.
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
charles/claude-hooks#26
No description provided.