# Stolen from https://git.neet.dev/zuckerberg/nix-config/src/branch/master/common/server/gitea-actions-runner.nix { config, lib, pkgs, ... }: let cfg = config.sydnix.gitea-actions-runner; token-file = config.sops.secrets.gitea-actions-runner-token.path; in { options.sydnix.gitea-actions-runner = { enable = lib.mkEnableOption "Gitea actions runner"; instance-name = lib.mkOption { type = lib.types.str; default = config.networking.hostName; description = '' The name of the runner instance name. ''; }; user.name = lib.mkOption { type = lib.types.str; default = "gitea-actions-runner"; description = '' The name of the user gitea-actions-runner should run under. ''; }; user.uid = lib.mkOption { type = lib.types.int; default = 991; description = '' The UID of the user gitea-actions-runner should run under. This must be known at evaluation time so that the same UID can be used both on the host and in the container, allowing the container to access the host's nix-daemon. ''; }; group.name = lib.mkOption { type = lib.types.str; default = "gitea-actions-runner"; description = '' The name of the group gitea-actions-runner should run under. ''; }; group.gid = lib.mkOption { type = lib.types.int; default = 989; description = '' The GID of the group gitea-actions-runner should run under. This must be known at evaluation time so that the same GID can be used both on the host and in the container, allowing the container to access the host's nix-daemon. ''; }; }; config = lib.mkIf cfg.enable { sydnix.sops.secrets.gitea-actions-runner-token = {}; sydnix.impermanence.directories = [ "/var/lib/gitea-actions-runner" ]; containers."gitea-actions-runner" = { autoStart = true; ephemeral = true; bindMounts = { ${token-file} = { hostPath = token-file; isReadOnly = true; }; "/var/lib/gitea-actions-runner" = { hostPath = "/var/lib/gitea-actions-runner"; isReadOnly = false; }; }; config = { config, lib, pkgs, ... }: { system.stateVersion = "25.11"; services.gitea-actions-runner.instances.${cfg.instance-name} = { enable = true; name = cfg.instance-name; url = "https://git.deertopia.net/"; tokenFile = token-file; labels = [ "nixos:host" ]; hostPackages = with pkgs; [ bash coreutils curl gawk gitMinimal gnused nodejs wget nix ]; }; # Disable dynamic user so runner state persists via bind mount assertions = [{ assertion = config.systemd.services.gitea-actions-runner-sydpc.enable; message = '' Expected systemd service 'gitea-actions-runner-sydpc' is not enabled — the gitea-actions-runner NixOS module may have changed its naming scheme. ''; }]; systemd.services.gitea-actions-runner-sydpc.serviceConfig.DynamicUser = lib.mkForce false; users.users.${cfg.user.name} = { uid = cfg.user.uid; home = "/var/lib/gitea-actions-runner"; group = cfg.group.name; isSystemUser = true; createHome = true; }; users.groups.gitea-actions-runner.gid = cfg.group.gid; nix.settings.experimental-features = [ "nix-command" "flakes" ]; environment.systemPackages = with pkgs; [ git nodejs jq attic-client omnix ]; }; }; # Needs to be outside of the container because container uses's # the host's nix-daemon nix.settings.trusted-users = [ cfg.user.name ]; # Matching user on host — the container's gitea-actions-runner UID # must be recognized by the host's nix-daemon as trusted (shared # UID namespace) users.users.${cfg.user.name} = { uid = cfg.user.uid; home = "/var/lib/gitea-actions-runner"; group = cfg.group.name; isSystemUser = true; createHome = true; }; users.groups.${cfg.group.name}.gid = cfg.group.gid; }; }