Onboarding / registration steps
The manifests these steps reference (runner Deployment, ArgoCD
AppProject/Application) exist undermanifests/and are live on con-prod. Allkubectl/argocdexamples use an explicit--kubeconfig <path>(no aliases) for the audit trail.
1. Codeberg — enroll the forgejo-runner (connection model, no register)
Verified on con-prod (runner v12.12.0). forgejo-runner register is deprecated on
Codeberg and fails ("registration token not found",
forgejo/forgejo#4890); the offline
create-runner-file --secret needs server-admin we don't have. The working path is the
v12 connection model: Codeberg's Create new runner gives a uuid + token that you
declare directly in the daemon config (server.connections). No register, no .runner.
Model: ONE org-scope runner. A single organization-scope connection serves every Conduction repo that has Actions enabled — one token, no per-repo enrollment. The repo allowlist is simply "which repos have Actions on". The connection token is long-lived (only dies if the runner is deleted/rotated), so no routine re-enrollment.
One-time enrollment (org admin):
- Codeberg → organization Conduction → Settings → Actions → Runners → Create new runner (org admin rights required). Copy the UUID and token from that screen (they are a pair — use both from the same screen).
- Put them into the runner config (
server.connections, one entry) and store it as the SOPS-encrypted Secretforgejo-runner-conn(keyconfig.yml) — seemanifests/components/runner-secrets/. The config holds the token, so it is a Secret, never a ConfigMap, committed only SOPS+age-encrypted. It is not a Codeberg Actions secret. - The daemon runs
forgejo-runner daemon --config /config/config.yml; it declares the connection and polls.runner.capacitysets simultaneous jobs (host backend → jobs share the runner pod; size pod + quota accordingly).
Adding a repo (the allowlist): just enable Actions on the repo — repo Settings →
Units/Overview → tick Actions, then add .forgejo/workflows/*.yaml with a Talos label.
No new runner, no token, no config change. A repo without Actions enabled cannot use the
runner (default-deny by repo).
Which label? (con-ci vs con-ci-oci)
Talos serves only its own labels — generic docker/ubuntu-latest are NOT served, so a
job on those just sits queued forever. Pick:
| Job | Label |
|---|---|
| lint / Semgrep / Trivy (host tools), kubectl/ops, the Nextcloud sign step | con-ci (host) |
any job with a container: image or services:; Hydra personas; building OCI images (podman build) |
con-ci-oci (container) |
Heuristic (revised 2026-07-04): plain host job → con-ci; anything involving container
images — running AND building — → con-ci-oci.
Guardrail so devs don't sit queued
scripts/check-forgejo-runs-on.sh validates workflow labels (run it, or wire it as a
pre-commit hook). It fails on unsupported labels and on container:/services: jobs that
aren't con-ci-oci. In a consuming repo's .pre-commit-config.yaml:
- repo: https://codeberg.org/Conduction/talos
rev: <tag-or-sha>
hooks:
- id: forgejo-runs-on
(Requires yq on the dev machine. Run manually: scripts/check-forgejo-runs-on.sh path/to/wf.yml.)
Quick manual bring-up (no SOPS, e.g. a smoke runner): create the Secret straight from a
local config — kubectl --kubeconfig <path> -n con-ci create secret generic
forgejo-runner-conn --from-file=config.yml=./config.yml — and apply the runner Deployment.
Rotation. Delete the runner in the Codeberg UI, Create new runner (org) again, update the Secret, re-sync. (Per-repo cryptographic isolation or an auto-enrollment operator — declarative repo list + registration-token API + self-heal — is deferred to Change-2.)
2. ArgoCD — bootstrap the Application (one-time, then GitOps takes over)
House style (observed in cluster-infra/argo/): AppProject under argo/projects/,
Application under argo/applications/, multiSource (chart/overlay + $values from the
Codeberg repo), app.kubernetes.io/part-of label, a finalizer, and
syncPolicy.automated with prune + selfHeal.
Steps (operator, once):
- Register this repo as an ArgoCD source if not already trusted. Conduction's other
Codeberg repos (e.g.
cluster-infra) are already registered, so prefer reusing the existing repo-creds Secret/pattern over adding a new credential:
argocd repo add https://codeberg.org/Conduction/talos.git --username
- Apply the
AppProject(RBAC guardrails scoped to the CI namespace):
kubectl --kubeconfig
- Apply the
Application:
kubectl --kubeconfig
- ArgoCD reconciles automatically (
selfHeal+prune). Verify:
argocd app get talos
Rollback. Delete the Application → prune removes the managed resources and the CI
namespace drains (see the gitops-delivery spec).
Prerequisites still open (carried from design.md)
- Confirm con-prod's CNI before the apply phase (vanilla NetworkPolicy assumed; no Cilium
toFQDNsconfirmed). The egress-proxy approach was chosen precisely so enrollment does not depend on CNI FQDN support.