Releases: FootprintAI/containarium-run
Release list
v1.4.0 — forward cloud creds into box env + lease-TTL leak fix
Forward cloud credentials into the box env (#39, closes #19)
Box-CI roles that run inside the box and drive the cloud REST API now get credentials. The always-needed trio CONTAINARIUM_SERVER / CONTAINARIUM_TOKEN / CONTAINARIUM_ORG (org from the existing org-id input) is forwarded into the box's setup/test command env, plus a new optional multiline env: input (KEY=VALUE per line) for extras like a second org's CONTAINARIUM_TOKEN_PEER / CONTAINARIUM_ORG_PEER.
Done securely: secrets are written to a mode-0600 file (umask 077), scp'd over the existing channel, and chmod 600 on the box — never on the ssh argv (which would leak into the box process list and Action logs). Every value is ::add-mask::'d, the file is sourced before the command runs, and it's stripped on the keep-on-failure debug path so a debugger can't inherit the CI token.
Unblocks arming the Containarium-cloud actuation verifier (#192) and the Layer-4 per-org network-isolation sentry (#191) — the two remaining MVP verification gates.
Consumer usage
- uses: FootprintAI/containarium-run@v1.4.0
with:
server: ${{ secrets.CONTAINARIUM_SERVER }}
token: ${{ secrets.CONTAINARIUM_TOKEN }}
org-id: ${{ vars.CONTAINARIUM_ORG }}
env: |
CONTAINARIUM_TOKEN_PEER=${{ secrets.CONTAINARIUM_TOKEN_PEER }}
CONTAINARIUM_ORG_PEER=${{ vars.CONTAINARIUM_ORG_PEER }}Lease TTL + heartbeat — no box ever leaks (#37, Containarium#526)
Every box is now born with a short birth TTL (default 20m) stamped right after create, renewed by a background heartbeat while the job runs, so a CANCELLED job or a runner that dies mid-run can no longer leak a box — it self-reaps within one window. Success still deletes immediately; failure still keeps for the debug window.
Full changelog: v1.3.0...v1.4.0
v1.0.0 — first public release
First public release of containarium-run — the GitHub Action for running CI in a Containarium box.
What you get
- Spawns a fresh Containarium container per job — real Linux, your code goes in via rsync, your tests run there, the box is torn down on success.
- Failure-debug surface: when a job fails with `keep-on-failure: true` (default), the box stays alive for an hour and a comment is posted on the PR with an SSH command + an `agent-box` MCP URL. Hand the URL to Claude Code / Cursor / any MCP-aware agent and they can read the `containarium://ci-context` resource (PR + commit + failing test + log tail) before they connect — so the agent doesn't waste its first turn asking "what am I looking at?".
- Three-field `containarium.yml` in your repo: `image`, `setup`, `test`. Plus an optional `serve:` block for PR-preview-environment use.
Tiered setup (pick yours)
| Tier | Setup | Where your code runs |
|---|---|---|
| 0 — Evaluator | This Action + a token from cloud.containarium.dev | Code → GHA-hosted runner → cloud → Containarium box |
| 1 — Self-host | This Action + your own Containarium daemon | Code → GHA-hosted (orchestration only) → your boxes |
| 2 — Enterprise | Tier 1 + audit log + SSO | Nothing crosses to FootprintAI |
| 3 — Air-gapped | Tier 2 + offline install bundle | Fully contained in your VPC |
See https://containarium.dev/security for the full data-residency breakdown.
Pin to this release
```yaml
- uses: FootprintAI/containarium-run@v1
with:
server: https://cloud.containarium.dev
token: ${{ secrets.CONTAINARIUM_TOKEN }}
```
What's in v1
- Action scaffold with full `action.yml` contract (inputs, outputs, branding)
- `ci-context.json` writer that drops PR + commit + failing-test context into `/workspace/.containarium/` inside the box, for the agent-box MCP resource to surface
- Default `server` set to `https://cloud.containarium.dev\` (was previously a placeholder that didn't resolve)
What's next
- v0.1: cache-key implementation (warm volumes across runs)
- v0.1: sticky PR comments (edit existing instead of post new)
- v1.1: composite → JS Action when complexity warrants
Companion projects
- FootprintAI/containarium — the OSS daemon + CLI + agent-box (Tier 1+ self-host path)
- cloud.containarium.dev — the hosted control plane (Tier 0)
- hacks/runner/ — alternative: run CI workloads on Containarium-hosted self-hosted runners (zero GHA-hosted minutes)
v1.2.0 — per-role box sizing (box-cpu/box-memory/box-disk)
Highlights
Per-role box sizing (#33). Adds box-cpu / box-memory / box-disk
action inputs (defaults unchanged: 4 / 4GB / 50GB), plus a
resources: block in containarium.yml that overrides them per role.
Resolution order: resources: in the job config wins, else the action
inputs, else the defaults. Lets memory-heavy jobs (e.g. go test -race ./...)
get a larger box instead of OOM-killing in the default 4GB one.
This is v1.1.1 + #33 — no other changes. Existing consumers that set no
resources: block and pass no box-* inputs behave exactly as v1.1.1.
Inherited from v1.1.1
- create + delete via
curlHTTP/1.1, not the CLI (FootprintAI/Containarium#422) - SSH by the cloud-assigned identity (
cld-<id>), not the box name - source push via tar-over-ssh into
~/work - debug boxes self-reap via a 1h auto-delete TTL on
keep-on-failure - idempotent create + job-unique box name; retry on transient edge failures
🤖 Generated with Claude Code
v1.1.1 — auto-delete kept-alive debug boxes + accumulated CI fixes
Highlights
Debug boxes now self-reap. On a failed CI run with keep-on-failure, the box is kept alive for debugging but now also gets a 1h auto-delete TTL (SetContainerTTL → daemon ttlsweeper), so it cleans itself up instead of leaking until someone deletes it by hand. Best-effort: a server predating the TTL handler returns 501 and the step warns rather than failing the build.
@v1 now ships the accumulated fixes. The floating v1 tag was still pointing at v1.1.0 and missing everything merged since. This release moves v1 → v1.1.1, finally delivering to @v1 consumers:
- create + delete via
curlHTTP/1.1, not the CLI (FootprintAI/Containarium#422) - SSH by the cloud-assigned identity (
cld-<id>), not the box name - source push via
containarium sync/ tar-over-ssh into~/work - idempotent create + job-unique box name; retry on transient edge failures
- curl exit-code surfacing + empty-server guard
Known gap
Cancelled jobs (neither success nor failure) still skip both teardown and the failure-path TTL — tracked for a follow-up (always() reaper or create-time TTL). See STATUS.md.
Not included: per-role box sizing (box-cpu/box-memory/box-disk, #33) — that's a feature, landing in a future v1.2.0.
🤖 Generated with Claude Code
v1.1.0 — self-hosted-runner fixes + dashboard debug-box reporting
Six fixes for failures observed against self-hosted runners during the 2026-05-24/25 cloud-CI dogfood (see STATUS.md and #14 for the full chain), plus one additive feature.
Fixes
- CLI version subcommand (#8) —
containarium --versionwas unsupported; the action now uses theversionsubcommand. FixesError: unknown flag: --version. - gh→curl fallback for PR comments (#9) — self-hosted runners often lack the
ghCLI; the failure-debug PR comment now falls back to a curl POST. Fixesgh: command not found. - PyYAML parser instead of yq (#10) —
yqisn't preinstalled on self-hosted runners; switched topython3+ PyYAML. Includes edge-case handling (missingimage, scalarsetup/test, missingserveblock). - Per-run SSH keypair (#11) —
containarium createrequires--ssh-key. The action now mints a fresh ed25519 keypair under\$RUNNER_TEMPper run; subsequent ssh/scp/rsync use the privkey directly. - Box-name truncation (#12) — jump-server validator caps usernames at 32 chars. Switched box-name template from
ci-<repo>-<run-id>-<attempt>toci-<run-id>-<attempt>(GITHUB_RUN_ID is globally unique).
Features
- Debug-box info to cloud dashboard (#16) — new optional input `org-id`. When set, the runner POSTs debug-box endpoint info (SSH host/port/user, MCP URL, keep-alive deadline) to the cloud's `ReportCIJobRuntime` endpoint after a test failure, so the `/ci/runs/` FailureDebugSurface panel renders real connection info instead of the "Coming soon" stub. Backward-compatible: default empty → no behavior change.
Internal
- Self-test workflow to catch `action.yml` load failures before consumers do (#6, #7).
- STATUS.md records the 2026-05-24/25 cloud-CI silence chain (#14).
Upgrading
The floating `v1` tag has been moved to v1.1.0. Repos pinning to `@v1.0.1` should bump to `@v1.1.0` (or `@v1` if they accept moving aliases) to pick up these fixes.
v1.0.1 — action.yml load-time fix
Single-commit patch release fixing two action.yml parse errors that blocked the action from loading at all (downstream CI runs failed with Failed to load action.yml).
What's fixed
cache-keyinput description no longer contains a${{ hashFiles('go.sum') }}example. GHA evaluates${{ }}expressions in input descriptions at action-load time andhashFiles()is workflow-only. Now describes the recommended caller usage in plain prose.Expose portstep name is now quoted and rephrased to avoid an unquoted:inside parentheses that was tripping GHA's YAML parser.
Pinning
@v1(moving) — gets this fix automatically; recommended for most users@v1.0.1— pin to exactly this release if you want immutability@v1.0.0— still broken; no reason to stay pinned here, please bump
Upgrade path
If you saw any of these errors:
Unrecognized function: 'hashFiles'
Mapping values are not allowed in this context
Failed to load FootprintAI/containarium-run/main/action.yml
Bumping the pin to @v1 (or @v1.0.1) resolves them with no other workflow changes needed.
PR: #5