Skip to content

CI: build and smoke-test every container image a PR touches, with a size/boot summary #814

Closed as not planned

Description

@QuinnsCode

Problem

codeSplitter ships three images: sandbox/Dockerfile, deploy-sandbox/Dockerfile and deploy-sandbox/ci.Dockerfile. They're declared as container bindings in apps/codesplitter/rustybuns.config.ts. No CI job builds them. A broken apt-get, a bad base tag or a COPY of a moved file only shows up when the owner runs the live deploy and Alchemy/wrangler builds the image, which is the worst place to find it.

What good looks like

A PR that touches an image's Dockerfile, or anything in its build context, gets a containers check that builds that image and reports back clearly:

  • Builds only the images that changed. scripts/ci-apps.ts already plans per-app jobs, so add a containers output to it. It reads the container bindings from each app's rustybuns.config.ts (the Dockerfile path and its context folder) and lists the bindings whose context the diff touched, plus every binding when packages/cli/src/gen/ changes.

  • Uses the right architecture. It builds for linux/amd64, the platform Cloudflare Containers runs, on a standard runner, so the job stays within scripts/ci-guard.ts.

  • Is fast when nothing big moved. Layers are cached with BuildKit's GHA cache (type=gha, scoped per image), so a PR that only changes server.mjs rebuilds just the last layers.

  • Smoke-tests each image after building it. The job runs the image, waits for :8080 to answer, and fails if the server never comes up or exits. The images set CMD to node server.mjs, so a missing node or a syntax error fails here.

  • Writes a job summary. It adds a table to $GITHUB_STEP_SUMMARY, one row per image:

    Image Build Size Δ vs main Boot
    AGENT_SANDBOX (sandbox/Dockerfile) ✅ 1m12s 812 MB +4 MB 0.9s

    Size and Δ show image bloat (e.g. someone adds Rust to the check image) before it costs cold-start time. Main's sizes come from the GHA cache, or from a small JSON artifact the last main run uploaded.

  • Says which step failed. On failure, the summary names the failing Dockerfile line and shows the last 30 lines of build output, so nobody has to open the raw log.

  • Gives a clear "no images touched" result. When the PR didn't touch any image, the job finishes in seconds with a single line saying so.

Out of scope

  • Pushing images anywhere. Deploys still build their own.
  • Making containers a required check. That's a ruleset change, which is the owner's call. Propose it once the job is stable.

Acceptance

  • Breaking sandbox/Dockerfile (e.g. a typo in a package name) fails the PR with the bad line in the summary.
  • Changing only deploy-sandbox/server.mjs rebuilds both deploy-sandbox images (they share the context) and not sandbox/.
  • A PR that touches no image runs nothing heavy.
  • The job has a timeout and runs on standard runners (ci-guard.ts passes).

Activity

  1. QuinnsCode commented on Oct 12, 2026

    @QuinnsCode
    OwnerAuthor

    Folded into #818, which now holds this spec in full along with the other container and Docker work.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or requestgithub_actionsPull requests that update GitHub Actions code

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions