From 6f25ff7ee727d8d4c472703c9a2dd5045290a5d8 Mon Sep 17 00:00:00 2001 From: iris Date: Mon, 1 Jun 2026 00:04:57 +0200 Subject: [PATCH] =?UTF-8?q?docs:=20add=20ci.md=20=E2=80=94=20hive-ci=20For?= =?UTF-8?q?gejo=20Actions=20runner=20guide?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CLAUDE.md | 2 ++ docs/ci.md | 81 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 83 insertions(+) create mode 100644 docs/ci.md diff --git a/CLAUDE.md b/CLAUDE.md index d1de27a8..da2cfdfd 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -325,6 +325,8 @@ docs/ swarm.md multi-hive swarm config: peer declaration, TLS trust (CA vs certFingerprint), bilateral setup, identity env vars, matrix federation pointer + ci.md hive-ci Forgejo Actions runner: options, container + shape, auto-registration flow, nix sandbox note ``` ## Reading paths diff --git a/docs/ci.md b/docs/ci.md new file mode 100644 index 00000000..6b92e07d --- /dev/null +++ b/docs/ci.md @@ -0,0 +1,81 @@ +# hive-ci — Forgejo Actions runner + +The `hive-ci` module adds a Forgejo Actions runner to the hive so +workflows in the hyperhive repo (and any operator-managed repos on +the hive forge) can run on the same host. Disabled by default. + +## Enabling + +```nix +services.hyperhive.forge.ci = { + enable = true; + name = "prod-hive"; # shows in Forgejo admin panel; default = hostname +}; +``` + +Requires `services.hyperhive.forge.enable = true` (the runner +registers against the hive-forge Forgejo instance). The module +asserts this at eval time. + +## Options + +| option | default | description | +|---|---|---| +| `forge.ci.enable` | `false` | opt-in; off by default | +| `forge.ci.name` | hostname | runner name in Forgejo admin panel | +| `forge.ci.concurrency` | `2` | maximum parallel jobs | +| `forge.ci.labels` | `["hive-ci:host"]` | runner labels (`:`) | +| `forge.ci.package` | `pkgs.gitea-actions-runner` | override the runner binary | + +The `host` scheme in labels means jobs run directly inside the +`hive-ci` container (no docker/podman). Workflow files target this +runner with: + +```yaml +runs-on: [hive-ci] +``` + +## Container shape + +`hive-ci` is an ephemeral-false nixos-container sharing the host +network namespace (`privateNetwork = false`) so it reaches the +hive-forge Forgejo instance at `localhost:` without +needing a routed address. + +Bind mounts: +- `/run/hive-ci/core-token` ← `coreTokenPath` (host's forge + admin token, read-only). Used only on first boot for registration. + +The container has `git` in `systemPackages`; everything else a +workflow needs (rust tools, nix, etc.) is either pulled in by the +workflow itself via `nix flake check` or is part of the base NixOS +closure. + +Nix sandboxing is disabled in the container (`sandbox-fallback = +true`) because nspawn containers can't create the user namespaces +that the Nix sandbox requires. See `docs/gotchas.md` for the +general nspawn sandbox note. + +## Auto-registration + +On first boot an `ExecStartPre` script (`hive-ci-autoregister`) runs +before the runner service: + +1. Reads the hive-c0re admin token from `/run/hive-ci/core-token`. +2. Calls `GET /api/v1/admin/runners/registration-token` on the forge + (retrying for up to 30 s while forge starts). +3. Writes the registration token to `/run/hive-ci/runner-token`. +4. The runner service picks it up and registers, writing credentials + to `/var/lib/gitea-runner/hive/.runner`. + +On subsequent boots the `.runner` credentials file already exists; +the script writes a dummy token and exits — the runner ignores it +and reuses its stored credentials. + +No manual token handling is needed. The whole flow is automatic on +`nixos-container start`. + +## Cross-references + +- `docs/forge.md` — hive-forge setup (prerequisite) +- `docs/gotchas.md` — nspawn sandbox-fallback note