#!/usr/bin/env bash # Mint a fresh Gitea Actions registration token and write it into the SOPS secret. # # The token value is NEVER printed. It goes from the Gitea API into `sops set` and # nowhere else. (It is briefly visible in this host's process list as a sops argument; # acceptable on a single-operator workstation, and far better than echoing it.) # # This ALONE may not bring the runner back -- see "IMPORTANT" at the end of the output. set -euo pipefail HOST=gitea.home.keithjackson.dev SECRET=apps/wave-1/gitea-actions-runner-secret.sops.yaml REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)" cd "$REPO_ROOT" [ -f "$SECRET" ] || { echo "not in the repo root, or $SECRET is missing" >&2; exit 1; } creds="$(printf 'protocol=https\nhost=%s\n\n' "$HOST" | git credential fill)" U="$(sed -n 's/^username=//p' <<<"$creds")" P="$(sed -n 's/^password=//p' <<<"$creds")" [ -n "$U" ] && [ -n "$P" ] || { echo "no stored git credential for $HOST" >&2; exit 1; } echo "==> minting an instance-level registration token as '${U}'" TOKEN="$(curl -sS --config <(printf 'user = "%s:%s"\n' "$U" "$P") \ "https://${HOST}/api/v1/admin/runners/registration-token" | jq -r '.token // empty')" [ -n "$TOKEN" ] || { echo "Gitea did not return a token" >&2; exit 1; } echo "==> got a ${#TOKEN}-character token (value not shown)" echo "==> writing it into ${SECRET} via sops" DEV_KUBECONFIG=/dev/null ./infra/devcontainer/dev.sh run \ sops set "$SECRET" '["stringData"]["token"]' "\"${TOKEN}\"" unset TOKEN echo "==> done. Verify the file is still encrypted (no plaintext token):" grep -q 'ENC\[' "$SECRET" && echo " OK - stringData is still SOPS-encrypted" \ || { echo " REFUSING TO CONTINUE: $SECRET is not encrypted" >&2; exit 1; } cat <<'NOTE' Next: commit this on a branch, open a PR, and merge it so Flux applies the new Secret. IMPORTANT -- a new token is usually NOT sufficient on its own. act_runner registers exactly ONCE and then persists its identity in /data/.runner on the act-runner-data PVC. If Gitea no longer has a matching runner row (DB restore, the row was deleted, the instance was rebuilt), the pod starts, sees .runner, SKIPS registration, and polls with an identity Gitea does not recognise -- so it never appears in the runner list, which is exactly the observed symptom (zero runners, pod running). So after the Secret lands, force a genuine re-registration by clearing that state: kubectl --context k3s-prod -n gitea-actions scale deploy/act-runner --replicas=0 kubectl --context k3s-prod -n gitea-actions delete pvc act-runner-data kubectl --context k3s-prod -n gitea-actions scale deploy/act-runner --replicas=1 (The PVC holds only runner registration state -- no build artifacts, nothing durable. Deleting it is the supported way to re-register. Flux recreates it from the manifest.) Then confirm it actually registered -- do not assume: curl -s -u '' https://gitea.home.keithjackson.dev/api/v1/admin/actions/runners | jq A runner must appear with status "online" and the labels ubuntu-latest / homelab. NOTE