Skip to content

ci: cache Docker layers, add concurrency, parallelize smoke, pin bun#413

Merged
mgoldsborough merged 2 commits into
mainfrom
ci/build-cache-concurrency
Jun 10, 2026
Merged

ci: cache Docker layers, add concurrency, parallelize smoke, pin bun#413
mgoldsborough merged 2 commits into
mainfrom
ci/build-cache-concurrency

Conversation

@mgoldsborough

Copy link
Copy Markdown
Contributor

Speeds up CI without weakening the test gate. Measured baseline (run for `9495ea9`): three serial waves, ~3.2 min wall-clock to a pushed image, with the image build not even starting until ~93s in.

Changes

1. Docker layer caching (the big win)

Both images used raw `docker build` with no cross-run cache, rebuilding identical base layers (`apt-get install curl/git/nodejs`, `bun.sh/install`, `npm i -g @nimblebrain/mpak`) every run. Now built via `docker/build-push-action@v6` with `type=gha` cache (per-image `scope` so platform/web don't clobber each other; `mode=max` for multi-stage layers). Warm builds skip the unchanged base.

Expected: platform ~65s → ~20–30s, web ~28s → ~10s.

2. Concurrency

No `concurrency` existed — stale PR runs ran to completion. Now cancels superseded PR-branch runs. Never cancels a push to main: on push events `head_ref` is empty so the group falls back to the unique `run_id`, keeping every main commit's SHA-tagged image build intact.

3. Ordering (test gate unchanged)

`smoke` no longer chains behind `test-unit`/`test-integration`. `build-and-push` still `needs` all four test jobs including smoke — nothing builds until every test is green. Chaining smoke serially only pushed the build's start later without adding safety. Build now starts when the slowest test finishes (~54s) instead of after smoke runs in a second wave (~93s).

4. Pin bun, DRY

`bun-version: latest` (duplicated in 4 jobs) → single workflow-level `env.BUN_VERSION` pinned to `1.3.14` (what `latest` resolves to today). Deterministic, one place to bump.

Expected critical path

```
before: wave1 tests(~54) → wave2 smoke(~93) → wave3 build(~192) ~3.2 min
after: wave1 all tests(~54) → wave2 build, warm cache(~30–40) ~1.5 min
```

Notes

  • Native amd64 on GitHub runners (no QEMU), so the cache is the whole win.
  • `release.yml` has the same two hand-maintained build blocks and could take the same cache treatment — deferred (ties into deduplicating the two workflows).

Speeds up the CI pipeline without weakening the test gate.

- Docker layer cache: build the platform + web images via
  docker/build-push-action with type=gha cache (per-image scope). The
  base layers (apt deps, node, bun, mpak) are identical across commits
  and are now restored from cache instead of rebuilt cold every run.
- Concurrency: cancel superseded PR-branch runs; never cancel a push to
  main (each main commit must complete so its SHA-tagged image lands in
  ECR — group falls back to the unique run_id on push events).
- Ordering: smoke no longer chains behind unit+integration. build-and-push
  still gates on all four test jobs (incl. smoke), so nothing builds until
  every test is green — chaining smoke only delayed that gate. Build now
  starts as soon as the slowest test finishes, not after smoke runs serially.
- bun-version: pinned to a single workflow-level env var (BUN_VERSION)
  instead of `latest` duplicated across four jobs — deterministic and DRY.
@mgoldsborough mgoldsborough added the qa-reviewed QA review completed with no critical issues label Jun 10, 2026
@mgoldsborough mgoldsborough merged commit 16c3586 into main Jun 10, 2026
5 checks passed
@mgoldsborough mgoldsborough deleted the ci/build-cache-concurrency branch June 10, 2026 20:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

qa-reviewed QA review completed with no critical issues

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant