diff --git a/.gitea/workflows/ci.yml b/.gitea/workflows/ci.yml index f1e2d4c..4da5bad 100644 --- a/.gitea/workflows/ci.yml +++ b/.gitea/workflows/ci.yml @@ -41,9 +41,29 @@ jobs: - name: Install bun run: npm i -g bun@1.4.2 + # Job-level dep cache via the runner's built-in cache server. continue-on-error on + # both steps: an unreachable/broken cache server must never break the run. + - name: Restore deps cache + uses: actions/cache@v4 + continue-on-error: true + with: + path: | + node_modules + $HOME/.bun/install/cache + key: ${{ runner.os }}-deps-bun-${{ hashFiles('bun.lock') }} + - name: Install dependencies run: bun install --frozen-lockfile + - name: Save deps cache + uses: actions/cache@v4 + continue-on-error: true + with: + path: | + node_modules + $HOME/.bun/install/cache + key: ${{ runner.os }}-deps-bun-${{ hashFiles('bun.lock') }} + - name: Build run: npm run build @@ -65,7 +85,9 @@ jobs: - name: E2E (isolated stack in dind) env: PW_REMOTE_BROWSER: "0" - E2E_DEPLOY_CMD: docker compose -f docker-compose.ci.yml -p flight-ci up -d --build + # Build separately with plain progress so BuildKit step output is visible in the + # job log (auto progress hides it), then start without rebuilding. + E2E_DEPLOY_CMD: "docker compose -f docker-compose.ci.yml -p flight-ci build --progress=plain && docker compose -f docker-compose.ci.yml -p flight-ci up -d" E2E_COMPOSE_ARGS: "-f docker-compose.ci.yml -p flight-ci" run: npx playwright test diff --git a/CHANGELOG.md b/CHANGELOG.md index c024be3..339c2e5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ - **Playwright config made CI-aware, backward-compatible** (`playwright.config.ts`): new optional env vars — `PW_REMOTE_BROWSER=0` (local chromium instead of the shared remote server at 192.168.1.4:3000), `E2E_DEPLOY_CMD` (runs as webServer + readiness wait; unset = current local behavior with no auto-deploy); `E2E_BASE_URL` already existed. `e2e/state.spec.ts` reads `E2E_COMPOSE_ARGS` for its mid-run `docker compose restart flight` (default empty → unchanged locally) - **@playwright/test pinned as devDependency** (`1.63.0`, matching the shared remote browser server image and the global install) so CI is self-contained; still excluded from the runtime image via .dockerignore (comment updated), prod-deps stage unaffected - `AGENTS.md`: "Change process" + "E2E tests" rewritten for the PR workflow — feature branch off master → commits with CHANGELOG entry + version bump → PR to master → CI (build→unit→e2e) green → merge → tag on master → manual production deploy via `docker compose up -d --build`; no direct pushes to master, CI never deploys +- **CI build reliability + caching** (after first dind runs): the e2e image is now built with `--progress=plain` before `up -d` so BuildKit step output lands in job logs instead of being hidden by auto progress; Dockerfile bun installs use a BuildKit cache mount (`/root/.bun/install/cache`) that persists on the runner's shared daemon, and CI restores/saves node_modules + the bun cache via actions/cache around dependency install (both steps `continue-on-error` — safe while the runner's cache server is being fixed) - Verified: unit suite 234 green locally; e2e not run locally by design (would deploy to production) — first real pass happens in the PR's CI run ## v0.12.2 — 2026-09-18 14:06 diff --git a/Dockerfile b/Dockerfile index 41b62cc..37ffb69 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,17 +1,17 @@ # Multi-stage build: bun for installs (fast), node for build + runtime. -# No BuildKit type=cache mounts: they don't persist across builds on this daemon -# (Docker 29 + containerd image store), and bun install is fast enough (~3s cold) -# that cross-build tarball caching isn't worth the complexity. +# The bun install steps use a BuildKit cache mount (/root/.bun/install/cache, both stages +# run as root) so the package cache persists across builds on daemons that keep named +# caches — notably the CI runner's shared dind daemon; where it doesn't persist it costs nothing. FROM oven/bun:1.4.2-alpine AS deps WORKDIR /app COPY package.json bun.lock ./ -RUN bun install --frozen-lockfile +RUN --mount=type=cache,target=/root/.bun/install/cache bun install --frozen-lockfile # Production dependencies only — devDeps (typescript, vitest, @types) are build-time only. FROM oven/bun:1.4.2-alpine AS prod-deps WORKDIR /app COPY package.json bun.lock ./ -RUN bun install --production --frozen-lockfile +RUN --mount=type=cache,target=/root/.bun/install/cache bun install --production --frozen-lockfile FROM node:22-alpine AS build WORKDIR /app