style(13-03): apply Prettier formatting across repo
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.
This commit is contained in:
@@ -3,32 +3,32 @@ phase: 08-gitea-ci
|
||||
plan: 04
|
||||
type: execute
|
||||
wave: 4
|
||||
depends_on: ["08-03"]
|
||||
depends_on: ['08-03']
|
||||
files_modified:
|
||||
- .gitea/workflows/ci.yml
|
||||
autonomous: false
|
||||
requirements: [CI-02]
|
||||
user_setup:
|
||||
- service: gitea-registry-pat
|
||||
why: "Publish job authenticates to the Gitea container registry; created in Plan 01"
|
||||
why: 'Publish job authenticates to the Gitea container registry; created in Plan 01'
|
||||
env_vars:
|
||||
- name: GITEA_REGISTRY_PAT
|
||||
source: "Repo secret created in Plan 01 (write:package scope)"
|
||||
source: 'Repo secret created in Plan 01 (write:package scope)'
|
||||
must_haves:
|
||||
truths:
|
||||
- "A merge (push) to main triggers a publish job that builds the API Docker production image and pushes it to the Gitea container registry"
|
||||
- "The image is pushed under two tags: :latest and :<milestone>-<shortsha> (e.g. v1.1-<7charsha>)"
|
||||
- "Registry authentication uses docker login --password-stdin with the PAT piped from a repo secret — the token never appears in plaintext in the CI log"
|
||||
- "The publish job runs only on push to main, never on pull_request, and never carries DEV_AUTH_BYPASS"
|
||||
- 'A merge (push) to main triggers a publish job that builds the API Docker production image and pushes it to the Gitea container registry'
|
||||
- 'The image is pushed under two tags: :latest and :<milestone>-<shortsha> (e.g. v1.1-<7charsha>)'
|
||||
- 'Registry authentication uses docker login --password-stdin with the PAT piped from a repo secret — the token never appears in plaintext in the CI log'
|
||||
- 'The publish job runs only on push to main, never on pull_request, and never carries DEV_AUTH_BYPASS'
|
||||
artifacts:
|
||||
- path: ".gitea/workflows/ci.yml"
|
||||
provides: "push-to-main publish job (CI-02)"
|
||||
contains: "docker push"
|
||||
- path: '.gitea/workflows/ci.yml'
|
||||
provides: 'push-to-main publish job (CI-02)'
|
||||
contains: 'docker push'
|
||||
key_links:
|
||||
- from: ".gitea/workflows/ci.yml (publish job)"
|
||||
to: "git.bergerhouse.net registry"
|
||||
via: "docker login --password-stdin + docker build --target production + docker push"
|
||||
pattern: "--password-stdin"
|
||||
- from: '.gitea/workflows/ci.yml (publish job)'
|
||||
to: 'git.bergerhouse.net registry'
|
||||
via: 'docker login --password-stdin + docker build --target production + docker push'
|
||||
pattern: '--password-stdin'
|
||||
---
|
||||
|
||||
<objective>
|
||||
@@ -55,18 +55,20 @@ Output: a `publish` job in ci.yml gated on `push → main`.
|
||||
</context>
|
||||
|
||||
<artifacts_this_phase_produces>
|
||||
|
||||
- `.gitea/workflows/ci.yml` (EXTENDED — adds the publish job; closes the phase)
|
||||
</artifacts_this_phase_produces>
|
||||
</artifacts_this_phase_produces>
|
||||
|
||||
<interface_context>
|
||||
Confirmed facts (do not re-derive):
|
||||
|
||||
- Git remote: `https://git.bergerhouse.net/luckberg/familysync.git` → registry host `git.bergerhouse.net`, owner `luckberg`. Image: `git.bergerhouse.net/luckberg/familysync-api` (08-RESEARCH §Registry Details).
|
||||
- Dockerfile is multi-stage with a `production` target that builds API + PWA and serves both on :3000. It MUST be built from the REPO ROOT with `-f apps/api/Dockerfile .` (the Dockerfile header and 08-RESEARCH §Dockerfile Build Context say so — building from apps/api/ fails because it copies the root workspace manifest + lockfile).
|
||||
- Milestone = `v1.1` (PROJECT.md "Current Milestone"). Per D-04, expose it as the workflow-level `env.MILESTONE` (already added in Plan 02) rather than hardcoding inline; update at milestone boundaries.
|
||||
- Short SHA = `${GITHUB_SHA:0:7}` (CONFIRMED available in Gitea Actions; 08-RESEARCH). If 08-01-SUMMARY found GITHUB_SHA unavailable, fall back to `git rev-parse --short=7 HEAD`.
|
||||
- Registry auth: PAT with write:package in repo secret `GITEA_REGISTRY_PAT` (created Plan 01). `GITHUB_TOKEN`/`GITEA_TOKEN` CANNOT push packages (08-RESEARCH; Gitea forum) — must use the PAT. Username = `luckberg`.
|
||||
- Pitfall 13: NEVER `docker login -p $TOKEN` (token leaks to the log / process list). ALWAYS `echo "$PAT" | docker login git.bergerhouse.net -u luckberg --password-stdin`.
|
||||
</interface_context>
|
||||
</interface_context>
|
||||
|
||||
<tasks>
|
||||
|
||||
@@ -97,6 +99,7 @@ Confirmed facts (do not re-derive):
|
||||
5. Final `if: always()` step: `docker logout git.bergerhouse.net || true` to drop the stored credential from the runner after push.
|
||||
|
||||
Use `docker/login-action`/`docker/build-push-action` ONLY if 08-01-SUMMARY confirmed they resolve AND you prefer them; the shell `docker login --password-stdin` + `docker build`/`docker push` form is the safer first iteration (08-RESEARCH §Pattern 6 note) and is the recommended path.
|
||||
|
||||
</action>
|
||||
<verify>
|
||||
<automated>grep -q "github.event_name == 'push'" .gitea/workflows/ci.yml && grep -q "refs/heads/main" .gitea/workflows/ci.yml && grep -q -- "--password-stdin" .gitea/workflows/ci.yml && ! grep -E "docker login.*(-p |--password )[^-]" .gitea/workflows/ci.yml && grep -q "docker build --target production" .gitea/workflows/ci.yml && grep -q "familysync-api:latest" .gitea/workflows/ci.yml && grep -q 'familysync-api:${MILESTONE}' .gitea/workflows/ci.yml && grep -q "docker push" .gitea/workflows/ci.yml && ! grep -qi "DEV_AUTH_BYPASS" <(awk '/publish:/,0' .gitea/workflows/ci.yml) && echo PUBLISH_OK</automated>
|
||||
@@ -120,20 +123,22 @@ Confirmed facts (do not re-derive):
|
||||
</tasks>
|
||||
|
||||
<threat_model>
|
||||
|
||||
## Trust Boundaries
|
||||
|
||||
| Boundary | Description |
|
||||
|----------|-------------|
|
||||
| Boundary | Description |
|
||||
| -------------------------- | ----------------------------------------------------------------------- |
|
||||
| Repo secret → docker login | PAT crosses into the job; the single highest-value secret in this phase |
|
||||
| publish job → registry | Authenticated push to the package registry |
|
||||
| publish job → registry | Authenticated push to the package registry |
|
||||
|
||||
## STRIDE Threat Register
|
||||
|
||||
| Threat ID | Category | Component | Disposition | Mitigation Plan |
|
||||
|-----------|----------|-----------|-------------|-----------------|
|
||||
| T-08-PAT | Information Disclosure | GITEA_REGISTRY_PAT in publish job | mitigate | `docker login --password-stdin` exclusively — token piped via stdin, never an `-p`/`--password` argument (Pitfall 13). Token referenced only as `${{ secrets.GITEA_REGISTRY_PAT }}` (Gitea masks registered secrets in logs); never echoed elsewhere; `docker logout` after push. Grep gate forbids `-p`/`--password` forms. Checkpoint requires a line-by-line log audit (ROADMAP criterion 6). This is the load-bearing mitigation for the phase. |
|
||||
| T-08-09 | Spoofing | DEV_AUTH_BYPASS bleed into publish | mitigate | Publish job never sets DEV_AUTH_BYPASS (grep gate scoped to the publish: block); the bypass is confined to the harness job (Plan 03). |
|
||||
| T-08-10 | Tampering | wrong build context | mitigate | Build from repo root with `-f apps/api/Dockerfile .` (Dockerfile requires root context for the workspace manifest + lockfile); building from apps/api/ would fail or produce a broken image. |
|
||||
| Threat ID | Category | Component | Disposition | Mitigation Plan |
|
||||
| --------- | ---------------------- | ---------------------------------- | ----------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| T-08-PAT | Information Disclosure | GITEA_REGISTRY_PAT in publish job | mitigate | `docker login --password-stdin` exclusively — token piped via stdin, never an `-p`/`--password` argument (Pitfall 13). Token referenced only as `${{ secrets.GITEA_REGISTRY_PAT }}` (Gitea masks registered secrets in logs); never echoed elsewhere; `docker logout` after push. Grep gate forbids `-p`/`--password` forms. Checkpoint requires a line-by-line log audit (ROADMAP criterion 6). This is the load-bearing mitigation for the phase. |
|
||||
| T-08-09 | Spoofing | DEV_AUTH_BYPASS bleed into publish | mitigate | Publish job never sets DEV_AUTH_BYPASS (grep gate scoped to the publish: block); the bypass is confined to the harness job (Plan 03). |
|
||||
| T-08-10 | Tampering | wrong build context | mitigate | Build from repo root with `-f apps/api/Dockerfile .` (Dockerfile requires root context for the workspace manifest + lockfile); building from apps/api/ would fail or produce a broken image. |
|
||||
|
||||
</threat_model>
|
||||
|
||||
<verification>
|
||||
@@ -142,10 +147,11 @@ Confirmed facts (do not re-derive):
|
||||
</verification>
|
||||
|
||||
<success_criteria>
|
||||
|
||||
- CI-02: on merge to main, the API production image is built and pushed to the Gitea registry under :latest + :v1.1-<shortsha> (ROADMAP criterion 5; D-04).
|
||||
- Registry credentials never appear in plaintext in the CI logs (ROADMAP criterion 6; Pitfall 13) — the load-bearing security outcome of the phase.
|
||||
- Publish runs only on push to main; DEV_AUTH_BYPASS never bleeds into it.
|
||||
</success_criteria>
|
||||
</success_criteria>
|
||||
|
||||
<output>
|
||||
Create `.planning/phases/08-gitea-ci/08-04-SUMMARY.md` when done. Record: the final image name + both tags pushed, confirmation the log audit found no plaintext PAT, and whether the shell or docker/* action form was used.
|
||||
|
||||
Reference in New Issue
Block a user