{ config, lib, pkgs, homeyConfig, ... }: # Gitea Actions Runner — executes CI/CD jobs triggered by Gitea Actions. # # Uses the NixOS native services.gitea-actions-runner module (act runner). # Jobs run directly on the host ("host" executor) — no container isolation. # This is appropriate for a trusted home server and avoids the overhead of # nested containers on a Pi 4. # # The service uses DynamicUser=true so there is no persistent system user. # Job step PATH is controlled by hostPackages (not the service PATH). # nix is not in the NixOS module's default hostPackages and must be added. # # Setup (one-time): # 1. In Gitea: Site Administration → Actions → Runners → Create Runner Token # 2. Store the token in sops with KEY=VALUE format: # gitea/runner_token: "TOKEN=" # 3. Enable homey.giteaRunner in the host config and deploy. # # After first start the runner registers itself and stores credentials in # /var/lib/gitea-runner//.runner — the token file is only needed for # (re-)registration. # # Secrets consumed from sops: # gitea/runner_token (must contain: TOKEN=) let cfg = config.homey.giteaRunner; domain = homeyConfig.domain; in { options.homey.giteaRunner = { enable = lib.mkEnableOption "Gitea Actions runner"; name = lib.mkOption { type = lib.types.str; default = config.networking.hostName; description = "Runner name as shown in Gitea's runner list."; }; labels = lib.mkOption { type = lib.types.listOf lib.types.str; default = [ "native:host" "ubuntu-latest:host" "debian-latest:host" "nix:host" ]; description = '' Labels advertised to Gitea. The "host" executor runs jobs directly on this machine. Workflow files targeting any of these labels will be picked up by this runner. ''; }; }; config = lib.mkIf cfg.enable { # The NixOS module reads tokenFile as a systemd EnvironmentFile (root reads # it before DynamicUser privilege drop), so owner=root / mode=0400 is correct. # The file must contain: TOKEN= sops.secrets."gitea/runner_token" = { owner = "root"; mode = "0400"; }; services.gitea-actions-runner.instances.${cfg.name} = { enable = true; url = "https://git.${domain}"; tokenFile = config.sops.secrets."gitea/runner_token".path; name = cfg.name; labels = cfg.labels; # hostPackages controls the PATH available to job steps (host executor). # nix is not in the default list so must be added explicitly. hostPackages = with pkgs; [ bash coreutils curl gawk gitMinimal gnused nodejs wget nix ]; }; }; }