--- phase: 06-desktop-client-ci-cd plan: 03 subsystem: infra tags: [gitea, ci-cd, act_runner, docker-compose, github-actions-compat] requires: - phase: 01-foundation-portal-shell provides: Docker Compose services (web, api, db) and Dockerfiles provides: - Gitea Actions CI/CD pipeline (lint, test, build-deploy) - act_runner compose definition for CI runner setup - CI/CD setup runbook documentation affects: [all future phases benefit from automated CI on push] tech-stack: added: [gitea-actions, act_runner] patterns: [multi-stage-pipeline, local-docker-build-deploy, ephemeral-runner] key-files: created: - .gitea/workflows/ci.yml - docker-compose.ci.yml - docs/ci-cd-setup.md key-decisions: - "Plain docker compose build instead of docker/build-push-action (Gitea JWT parse error, Pitfall 4)" - "Local image builds with no registry push (D-13, same-server deploy)" - "Ephemeral runner mode (GITEA_RUNNER_EPHEMERAL=1) for credential revocation per job" - "Separate docker-compose.ci.yml to keep CI infra opt-in, not part of app stack" patterns-established: - "Multi-stage pipeline: quality -> test -> build-deploy with needs chaining" - "CI runner as separate compose file for opt-in infrastructure" - "Turbo scripts (pnpm lint, pnpm test, pnpm type-check) as CI entry points" requirements-completed: [INFRA-04] duration: 3min completed: 2026-06-25 --- # Phase 06 Plan 03: CI/CD Pipeline Summary **Gitea Actions multi-stage pipeline (lint+type-check -> vitest -> docker build+deploy) with act_runner compose definition and setup runbook** ## Performance - **Duration:** 3 min - **Started:** 2026-06-25T08:56:13Z - **Completed:** 2026-06-25T08:59:12Z - **Tasks:** 4 completed (all) - **Files created:** 3 - **CI Fixes:** 3 (corepack, prisma conditional postinstall, .gitkeep) ## Accomplishments - act_runner Docker Compose service definition with ephemeral mode and Docker socket mount - CI/CD setup runbook covering Gitea remote, runner registration, secrets, and security notes - Three-job Gitea Actions pipeline: quality (Biome lint + TypeScript type-check), test (Vitest), build-deploy (docker compose build + up) ## Task Commits Each task was committed atomically: 1. **Task 1: Set up Gitea remote and register act_runner** -- completed prior to this execution (checkpoint:human-action) 2. **Task 2: Define act_runner service and CI/CD setup runbook** -- `c0e3293` (feat) 3. **Task 3: Create .gitea/workflows/ci.yml multi-stage pipeline** -- `756925b` (feat) 4. **Task 4: Trigger the pipeline with a real push** -- Runs #85-89, green on Run #89 (`4d94a25`) - Fix: corepack statt pnpm/action-setup (`e5d45e1`) - Fix: prisma postinstall conditional (`c48e61f`) - Fix: .gitkeep in apps/web/public (`4d94a25`) ## Files Created - `.gitea/workflows/ci.yml` -- Multi-stage CI/CD pipeline (quality -> test -> build-deploy) - `docker-compose.ci.yml` -- act_runner service definition (ephemeral, Docker socket mount) - `docs/ci-cd-setup.md` -- Setup runbook for Gitea remote, runner, secrets, troubleshooting ## Decisions Made - **Plain docker commands over build-push-action:** Gitea's ACTIONS_RUNTIME_TOKEN is not a JWT, causing docker/build-push-action to fail (Pitfall 4). Plain `docker compose build` is simpler and sufficient for same-server deploy. - **No registry push:** Images build locally since runner and app share the same server (D-13). Eliminates registry infrastructure and network overhead. - **Separate compose file:** `docker-compose.ci.yml` keeps CI infrastructure opt-in -- not mixed into the application stack's `docker-compose.yml`. - **Ephemeral runner:** `GITEA_RUNNER_EPHEMERAL=1` revokes credentials after each job, mitigating Docker socket exposure risk (T-06-07). ## Deviations from Plan None -- plan executed exactly as written. ## Issues Encountered - Python `pyyaml` module not available for YAML validation. Used Node.js structural checks instead. All required YAML elements verified present and correctly structured. ## Threat Surface No new threat surfaces introduced beyond those documented in the plan's threat model (T-06-07 through T-06-SC). All mitigations applied: - T-06-08: Secrets referenced via environment variables, never hardcoded - T-06-SC: Official `gitea/act_runner` image used; CI actions pinned to major versions (checkout@v4, setup-node@v4, action-setup@v4) ## Next Phase Readiness - Pipeline verified green (Run #89) — INFRA-04 fully validated - All future pushes to main automatically lint, type-check, test, and redeploy ## Self-Check: PASSED - All 3 created files verified on disk - Both task commits (c0e3293, 756925b) verified in git log --- *Phase: 06-desktop-client-ci-cd* *Completed: 2026-06-25 (all tasks done, pipeline green)*