Follow-up to #905: adds CLAUDE.md index entries (file map + reading path) for the new docs/ci.md. Also clarifies runner details in ci.md: - curl/jq use absolute nix store paths (no systemPackages needed) - .runner credential reuse: script writes dummy token on subsequent boots, runner ignores it when .runner file exists
3 KiB
3 KiB
hive-ci: Forgejo Actions Runner
The hive-ci module runs a Forgejo Actions runner in a hive-ci nixos-container, executing CI jobs from .forgejo/workflows/ci.yml (e.g., nix flake check on every PR).
Operator bootstrap
Set services.hyperhive.ci.enable = true in the host NixOS config. That's it — no manual token provisioning.
Requirements:
services.hyperhive.forge.enable = truemust also be set (the runner registers against hive-forge).- Optional: tune
services.hyperhive.ci.name(runner name in forge admin panel),concurrency(parallel job capacity),labels(workflow targeting).
Container design
- Shared host netns: container reaches hive-forge at
http://127.0.0.1:<httpPort>(same as hive-gateway). - Non-ephemeral: runner credentials persist across restarts (written to container's stateDir on first registration, reused thereafter).
- Sandbox fallback: nspawn containers can't create user-namespaces, so nix's sandboxing would always fail. Module sets
nix.settings.sandbox-fallback = truein the container — nix builds run unsandboxed (safe because the container is already isolated). Seedocs/gotchas.md.
Auto-registration flow
- On first container boot,
systemdruns theExecStartPrescript (fromhive-ci.nix:autoRegisterScript). - Script checks for existing runner credentials (
/var/lib/gitea-runner/hive/.runner):- If found: container was previously registered — write dummy token to satisfy module's path check, exit.
- If not found: first boot — proceed to registration.
- Script reads hive-c0re's admin token from
/run/hive-ci/core-token(bind-mounted from/var/lib/hyperhive/forge-core-token). - Calls
POST /api/v1/admin/runners/registration-tokenon the forge using${pkgs.curl}/bin/curland${pkgs.jq}/bin/jq(absolute nix store paths — the container doesn't need these in systemPackages). Retries for 30s in case forge is still starting. - Writes real token to
/run/hive-ci/runner-token. gitea-actions-runnerreads the token and registers itself, persisting credentials (.runnerfile) to stateDir.- On subsequent boots, runner reuses the
.runnercredentials — the preStart script detects the existing.runnerfile and writes a dummy token instead. The runner ignores the token file when.runneralready exists.
CI workflow
The single CI job is defined in .forgejo/workflows/ci.yml:
name: CI
on:
pull_request:
branches: ["**"]
jobs:
check:
name: nix flake check
runs-on: [hive-ci]
steps:
- uses: actions/checkout@v3
- name: check
run: nix flake check
This runs on every PR, executing all flake checks (treefmt, rustfmt, cargo test, cargo clippy, module evaluation). No --no-build: the checks' derivations are the canonical source of truth.
References
nix/modules/hive-ci.nix: runner configuration, auto-registration script, container setup..forgejo/workflows/ci.yml: workflow definition.docs/gotchas.md: nix sandboxing limitations in containers.