- Switch ci.yml + deploy.yml env bindings from ${{ vars.* }} to
${{ secrets.* }}. Gitea lets you put non-sensitive Actions values in
either tab, and the secrets tab was used in practice — workflow was
reading the wrong context and getting empty strings.
- Broaden the "no TODO markers ship" guard to accept both TODO: and
legacy TBD: prefixes, matching the imprint/privacy page markers that
were recently renamed.
- Document the secret-vs-variable choice in OPERATOR-CHECKLIST so the
next operator doesn't get tripped up by the same thing.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- .gitea/workflows/ci.yml: builds, tests, lints, and runs Lighthouse on
every push and PR to main. Runs on arm64 self-hosted Gitea runner.
- .gitea/workflows/deploy.yml: deploys to Hetzner on push to main or
manual workflow_dispatch from Gitea UI. No Lighthouse (that's CI's
job). Keeps the TBD-marker guard as a last-line safety check.
Both workflows live on the same concurrency group so no two deploys
race. On main push, CI and deploy run in parallel; CI is independent
and non-blocking for the deploy step.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>