docs(session): SESSION_005 — CI images to forge registry (repo-linked) + ci-bot; stale runner deregistered
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
110a199495
commit
66ea6ac377
1 changed files with 89 additions and 0 deletions
89
documentation/sessions/SESSION_2026-07-01_005.md
Normal file
89
documentation/sessions/SESSION_2026-07-01_005.md
Normal file
|
|
@ -0,0 +1,89 @@
|
|||
# Session 2026-07-01 #005 — CI images → forge container registry (repo-linked) + ci-bot
|
||||
|
||||
## What was done
|
||||
Delivered operator **ask #1** (HANDOVER task #1): the docker CI candidates now PUSH
|
||||
their built image to Forgejo's built-in **container registry**, **linked to their
|
||||
repo**. Stood up the **`ci-bot`** Tier-1 identity to do it, wired the reusable docker
|
||||
workflow, proved both candidates green + linked, pushed the backlog of local commits,
|
||||
and deregistered the stale `crunchy-runner`. Along the way, resolved four Forgejo-11
|
||||
behaviours the handover flagged as unknown.
|
||||
|
||||
## `ci-bot` — the CI / registry / git-push identity (NEW Tier-1 step: [`ci-bot/`](../../ci-bot/))
|
||||
As decided (operator, 2026-07-01): a dedicated **non-admin** service account, provisioned
|
||||
as a step **peer to `runners/`**, NOT in `bootstrap` (so CI never couples to Vault-unsealed).
|
||||
- User `ci-bot` (token-only, no password) in the `olsitec` org via a new non-admin team
|
||||
**`ci`** (id 2): `repo.code=write` + `repo.packages=write`, all repos. This is what grants
|
||||
git push + registry package write without platform-admin.
|
||||
- Two tokens: **`registry`** (`write:package`) and **`git-push`** (`write:repository`),
|
||||
kept root-600 at `/root/ci-bot-{registry,git-push}.token` on the forge VM.
|
||||
- Org Actions secrets **`FORGE_REGISTRY_USER=ci-bot`** + **`FORGE_REGISTRY_TOKEN`** — what CI
|
||||
reads for `docker login` (never Vault).
|
||||
- Codified as idempotent [`ci-bot/provision.sh`](../../ci-bot/provision.sh) (+ README): mints a
|
||||
short-lived platform-admin API token, does the user/team/token/secret work, revokes it on
|
||||
exit. `re-run == re-mint == source of truth`; Vault is optional backup only.
|
||||
- **git push as ci-bot** (the standing "push needs a token" gap): the `foundation-test` SSH key
|
||||
isn't a registered Forgejo key, so push over HTTPS with the git-push token as an
|
||||
**`Authorization: token` header** (`git -c http.extraHeader=…`). The basic-auth credential
|
||||
helper is REJECTED for token push; the header (same as the API) works.
|
||||
|
||||
## Registry push + repo-link — `reusable-docker-build.yml`
|
||||
`push: true` now: `docker login forge.olsitec.net` (org secrets) → build with the OCI source
|
||||
label → `docker push` → **link the package to its repo via the package API**. Verified end-to-end.
|
||||
- **token-service:ci** → repo `olsitec/token-service`; **seaspots-homepage:ci** → repo
|
||||
`olsitec/seaspots-homepage`. Both green; both listed at `/olsitec/-/packages?repo=<repo>` (200).
|
||||
- seaspots was linked **fresh** by the workflow's own link step (never pre-linked) — end-to-end proof.
|
||||
|
||||
### Four Forgejo-11 behaviours resolved (all now in `.forgejo/workflows/README.md`)
|
||||
1. **Secrets are NOT inherited by a called reusable workflow.** `${{ secrets.X }}` was empty
|
||||
inside `reusable-docker-build` (login failed `username is empty`) until the caller added
|
||||
**`secrets: inherit`**. (Answers the handover's open question — org-level secrets do NOT
|
||||
auto-inject into the callee.)
|
||||
2. **`@master` reusable refs are stale-parsed.** After pushing the updated reusable workflow,
|
||||
callers at `@master` kept running the OLD body (caller `with:` updated, steps didn't — no
|
||||
error). Fix: **pin the caller to the commit SHA**. (forgejo restart also clears it; SHA-pin is
|
||||
deterministic + better practice, and aligns with the "pin floating refs" hardening goal.)
|
||||
3. **buildx pushes an OCI index with provenance/sbom attestations** by default (Docker 29),
|
||||
which hides the source label AND creates junk `sha256:`-tagged package versions. Fix:
|
||||
**`docker build --provenance=false --sbom=false`** → one clean image manifest.
|
||||
4. **Forgejo 11 does NOT auto-link container packages from `org.opencontainers.image.source`**
|
||||
(verified: config label AND manifest annotation both leave `repo_id=0`, even on fresh package
|
||||
creation). Fix: the workflow **POSTs `…/packages/{owner}/container/{name}/-/link/{repo}`** as
|
||||
ci-bot (`write:package` suffices; 201=linked, 400=already-linked). The link **persists** across
|
||||
future pushes (Forgejo leaves `repo_id` untouched on version push). NB: there is **no
|
||||
`/{owner}/{repo}/packages` route** — the handover's URL was wrong; the real one is
|
||||
`/{owner}/-/packages?repo=<repo>`. Revisit auto-link on a Forgejo **v15** upgrade.
|
||||
|
||||
### Candidate wiring (final)
|
||||
Both `~/work/foundation-ci-candidates/{token-service,seaspots-homepage}` ci.yml:
|
||||
`runs-on: docker` (quirk 1) · `uses: …/reusable-docker-build.yml@110a199…` (SHA pin, quirk 5) ·
|
||||
`secrets: inherit` (quirk 4) · `image: forge.olsitec.net/olsitec/<repo>:ci` · `source-url` · `push: true`.
|
||||
Pushed to their forge repos (as ci-bot).
|
||||
|
||||
## Foundation repo — pushed (the backlog is cleared)
|
||||
The 14 previously-local commits + this session's commits are now on the forge master
|
||||
(`1bba311..110a199…`), pushed as ci-bot over HTTPS. New commits: `feat(ci-bot)`, the
|
||||
`reusable-docker-build` registry-push + single-manifest + auto-link + README quirks, and the
|
||||
`ci-bot` git-push doc fix.
|
||||
|
||||
## Stale `crunchy-runner` (id 2) — DEREGISTERED
|
||||
The offline `fenced` runner from the retired hand-built crunchy VM (last online 01:32) was
|
||||
removed (`action_runner` row delete; no admin runner-delete API exists in Forgejo 11). Runner
|
||||
inventory now clean: `foundation-runner` (docker), `foundation-runner-02`+`-03` (fenced HA
|
||||
pair), `foundation-runner-k8s-s57`. Two orphaned historical `action_task.runner_id=2` rows left
|
||||
(harmless).
|
||||
|
||||
## Hygiene
|
||||
Temp admin API token minted for provisioning was **revoked** (DB delete) at end; only ci-bot's
|
||||
`registry` + `git-push` tokens remain. Throwaway probe/test packages (`citest:probe`,
|
||||
`zz-linktest-*`) and the early junk `token-service:sha256:*` versions were deleted. Registry now
|
||||
holds exactly `token-service:ci` + `seaspots-homepage:ci`, both repo-linked.
|
||||
|
||||
## Still open
|
||||
- **Ask #2** — postgis/osm k8s toolchain runners (s57 done). Operator note: the runner scripts
|
||||
have a **pre-flight-only** mode — use it as the CI quality gate so test jobs don't run the full
|
||||
40–60 min pipeline. NEXT.
|
||||
- **DR/backlog (carried):** `runners`/`runners-k8s` stack state not backed up; T15; hardening
|
||||
(Forgejo v15 upgrade would drop quirks 1–2 and may add container auto-link → revisit the
|
||||
SHA-pin + explicit-link once upgraded).
|
||||
|
||||
## Operating mode: HIGH-RISK / INFRA (remote VMs, k3s, Docker, secrets).
|
||||
Loading…
Add table
Add a link
Reference in a new issue