Mechanical reformat — no logic changes. 398 files changed, 19125 insertions(+), 16457 deletions(-). Prettier 3.8.4 with .prettierrc (singleQuote:true, semi:true, tabWidth:2, trailingComma:all, printWidth:100). Isolated per D-13-08 for reviewability.
51 lines
7.4 KiB
Markdown
51 lines
7.4 KiB
Markdown
# Phase 8: Gitea CI — Verification
|
|
|
|
**Status: PASSED**
|
|
**Verified:** 2026-06-11
|
|
**Evidence basis:** Gitea Actions run log + Gitea Packages API inspection by operator
|
|
|
|
---
|
|
|
|
## Phase Goal
|
|
|
|
Every PR to `main` runs a full regression that gates the merge — lint, typecheck, unit, API-integration against a MariaDB service container, and the Phase 7 mobile Playwright harness as a UI-regression step — and a merge to `main` builds and publishes the API Docker image. All on the existing self-hosted Gitea Actions runner.
|
|
|
|
## Six-Criteria Evidence Table
|
|
|
|
| # | Success Criterion | Status | Evidence |
|
|
| --- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
| 1 | PR triggers lint + typecheck + unit + API-integration vs MariaDB service container; failing run blocks merge | **PASSED** | Runs #11 and #12: `fast-checks` (191s, lint no-op + tsc both apps + PWA vitest) and `api` (238s, MariaDB cold start + drizzle-kit migrate + DB-backed integration tests) both green. Run blocking enforced by Gitea branch protection on `main`. |
|
|
| 2 | API integration tests connect to service-container MariaDB (DB_HOST=127.0.0.1) and pass reliably on cold first run | **PASSED** | Run #11 cold start: MariaDB readiness wait (mysql2 loop) completed before migrate; squashed migration baseline (commit c0f892c) eliminated false drizzle-kit destructive diff; all API integration tests passed on first attempt. |
|
|
| 3 | PR workflow brings up dev stack (API + PWA dev servers + MariaDB, DEV_AUTH_BYPASS=true) and runs Phase 7 mobile Playwright harness headlessly; harness failure blocks merge | **PASSED** | Run #11: `harness` job — 58 specs across iphone/WebKit + pixel/Chromium — all green in 1.6 min. Four CI-specific infrastructure fixes applied (API-reap timeout, ipv4first/127.0.0.1 DNS, dev-user seed, direct test:e2e call). No Phase 7 harness files modified. |
|
|
| 4 | Harness step waits for both API and PWA dev servers before launching Playwright (no startup-race flake) | **PASSED** | mysql2 readiness loop (DB) → `:3000/health` poll (API) → global-setup `:5173` poll (PWA) — three sequential readiness gates before Playwright launches. No flake observed on cold or warm runs. |
|
|
| 5 | Merge to `main` builds and pushes API Docker image under a sensible tag | **PASSED** | Run #14 (push of merge commit 98acff8): `docker build --target production -f apps/api/Dockerfile .` succeeded; both tags pushed — `familysync-api:latest` and `familysync-api:v1.1-98acff8` — same digest `sha256:ce724852…`; confirmed present in Gitea Packages API. |
|
|
| 6 | Registry credentials never appear in plaintext in the CI logs | **PASSED** | Log audit of run #14: PAT masked as `***` throughout (Gitea secret scrubber); `--password-stdin` used exclusively (token piped via stdin); no `-p`/`--password` argument form anywhere; `docker logout` ran in `always()` cleanup. REGISTRY*PAT naming used (GITEA* prefix excluded to avoid Gitea's silent secret-drop behavior). |
|
|
|
|
## Plans Delivering the Criteria
|
|
|
|
| Plan | Contribution |
|
|
| ----- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
| 08-01 | Runner probe — confirmed ubuntu-latest label, Docker executor (/.dockerenv), GITHUB_SHA availability, Playwright deps install cleanly |
|
|
| 08-02 | ci.yml: fast-checks job (lint, tsc, PWA vitest) + api job (MariaDB service, mysql2 readiness, drizzle-kit migrate, integration tests). Delivers criteria 1 + 2. |
|
|
| 08-03 | ci.yml: harness job (dev-stack bring-up, readiness waits, pnpm test:e2e). Delivers criteria 3 + 4. Four CI infrastructure fixes (no Phase 7 files modified). |
|
|
| 08-04 | ci.yml: publish job (docker login --password-stdin, build --target production from repo root, dual push :latest + :v1.1-<sha>, docker logout). Delivers criteria 5 + 6. |
|
|
|
|
## Key Fixes Applied During Phase 8 (CI-side only, no harness changes)
|
|
|
|
1. **squashed migration baseline** (commit c0f892c) — single `0000_baseline.sql` replaces the incremental migration history; eliminates the false drizzle-kit destructive diff that aborted the first cold CI run.
|
|
2. **API-reap + ipv4first** — `pkill -f "tsx watch"` reap guard + `--dns-result-order=ipv4first` flag ensures the API dev server binds on 127.0.0.1 (not ::1), matching the harness readiness poll.
|
|
3. **dev-user seed** — global-setup inserts the DEV_AUTH_BYPASS user (id=1) before Playwright launches, so the authed bypass session is valid on first spec.
|
|
4. **direct test:e2e** — `pnpm --filter @familysync/pwa test:e2e` called directly (not via Makefile) to avoid shell-expansion issues in the runner.
|
|
5. **REGISTRY_PAT naming** (commit 73eecf7) — Gitea runner silently drops secrets whose names begin with `GITEA_`; secret renamed from `GITEA_REGISTRY_PAT` to `REGISTRY_PAT`.
|
|
|
|
## Requirements Delivered
|
|
|
|
| REQ-ID | Description | Status |
|
|
| ------ | -------------------------------------------------------------------------------------- | ------------ |
|
|
| CI-01 | PR regression gates merge (lint + typecheck + unit + API-integration + mobile harness) | **Complete** |
|
|
| CI-02 | Push to main builds + publishes API Docker image | **Complete** |
|
|
|
|
## Phase 8 Outcome
|
|
|
|
Phase 8 is complete. The Gitea CI pipeline is fully operational on the self-hosted runner. Future merges to `main` will automatically run the full regression gate and publish a new image — no manual steps required.
|