010/011: relabel Decisions->Decision + add Status/Consequences. 013: add Status + Decision umbrella (existing Consequences untouched). No decision substance changed. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
3.8 KiB
ADR-010 — Forgejo integration and CI
Status
Accepted (2026-05-30)
Context
boma's git host, container registry, and (planned) CI all run on a self-hosted
Forgejo instance at forgejo.nyumbani.baobab.band (SSH on 7577, HTTPS on 443). Both
humans and AI/automation interact with it. This ADR sets the principles so the
instance does not become undocumented click-ops drift, and so its credentials are
held to the same standard as the rest of the repo's secrets.
What Forgejo provides here
- Git hosting —
origin(push/pull over SSH; key-based, not token). - Container registry — hosts the Molecule test image
(
forgejo.nyumbani.baobab.band/sjat/molecule-debian13); see ADR-008. - Actions CI — planned, not yet enabled (
has_actions: false); trunk-based pipeline per ADR-003 / ADR-008.
Decision
1. API tokens are managed secrets, least-privilege
A Forgejo API token (PAT) is a secret and follows ADR-002: stored in Vaultwarden
(item boma-forgejo-api), fetched via rbw get boma-forgejo-api (run rbw sync
first if it was just added), never written to a file or pasted into chat. Tokens
are least-privilege — scoped to their purpose, never admin.
Note what does not need a token: git push/pull (SSH key), and Terraform state (local — ADR-006). A token for CI / registry use needs only:
read:repositoryread:package,write:package(pull/push the Molecule image)
2. Declarative-first, not click-ops
Forgejo configuration lives in the repo where possible:
- Actions workflows in
.forgejo/workflows/(version-controlled). - Repo/instance settings are codified or documented; changing them ad-hoc via the API or UI is a documented exception, recorded when done — not the norm.
The point: the Forgejo instance must not become the kind of undocumented drift that
/review-repo exists to catch.
3. Automation boundary
Automation / AI may, via the API or CLI: read repo and CI state, manage the container registry, run and inspect CI. It must not, without explicit human direction: change instance/admin settings, delete repos or packages, or rotate credentials.
CI pipeline (planned)
Trunk-based, matching ADR-003 / ADR-008:
push to main → lint + Molecule → deploy staging → [manual gate] → deploy production
Runner: act_runner on ubongo (the control node — ADR-015), or a dedicated runner VM
later if CI load warrants a separate host. Actions is not yet enabled — see STATUS.md.
What was ruled out
| Option | Reason |
|---|---|
| Terraform Forgejo HTTP state backend | Forgejo's /raw/ API is read-only; state can't be written there. Local state instead (ADR-006). |
| Admin-scoped automation tokens | Unnecessary privilege; scope to read:repository + read/write:package. |
| Ad-hoc UI/API configuration as the norm | Becomes undocumented drift; codify or document instead. |
Consequences
- The planned CI pipeline (see "CI pipeline (planned)") is trunk-based per ADR-003 /
ADR-008 —
push to main → lint + Molecule → deploy staging → [manual gate] → deploy production— runningact_runneronubongo(or a dedicated runner VM later if CI load warrants); Actions is not yet enabled, so this remains future work tracked in STATUS.md. - Terraform state is not held in Forgejo: its
/raw/API is read-only and cannot be written, so local state is used instead (ADR-006) (see "What was ruled out"). - Automation tokens are scoped to
read:repository+read/write:packagerather than admin, accepting the limits that least-privilege imposes on what automation can do (see "What was ruled out"). - Instance/repo configuration must be codified or documented rather than changed
ad-hoc, to avoid the undocumented drift
/review-repoexists to catch (see "What was ruled out").