yumeami/modules/nixos/services/ci/github-runner/default.nix
2026-06-30 15:02:05 -05:00

107 lines
3.1 KiB
Nix

{
config,
lib,
namespace,
pkgs,
...
}: let
inherit (lib) types mkEnableOption mkOption mkIf;
inherit (lib.${namespace}) getAttrByNamespace mkOptionsWithNamespace mkOpt mkRequiredOpt mkNullableOpt mkOptAttrset;
inherit (config.networking) hostName;
inherit (config.sops) secrets;
base = "${namespace}.services.ci.github-runner";
cfg = getAttrByNamespace config base;
nvdaCfg = getAttrByNamespace config "${namespace}.hardware.nvidia";
in {
options = with types;
mkOptionsWithNamespace base {
enable = mkEnableOption "Github self-hosted runner";
runners = mkOptAttrset (submodule {
options = {
instances = mkOpt int 1 "Number of instances of the runner to spawn for this configuration.";
tokenFile = mkNullableOpt path null "Path to the token file to utilize for authentication";
url = mkOpt str "" "URL of the repository for which to add the self-hosted runner";
};
}) [] "Definition of runners to enable to the device";
};
config = mkIf cfg.enable {
services.github-runners = let
inherit (config.users.users) github-runner;
inherit (lib) attrValues concatLists genList listToAttrs mapAttrs optional replicate;
inherit (builtins) stringLength concatStringsSep;
padIndex = idx: concatStringsSep "" (replicate (3 - stringLength (toString idx)) "0") + toString idx;
mkRunnerConfig = {
index,
name,
runner,
}: {
name = "${hostName}-${name}-${padIndex index}";
value = {
enable = true;
name = "${hostName}-${padIndex index}";
replace = true;
ephemeral = true;
tokenFile =
if runner.tokenFile == null
then secrets."github/runner".path
else runner.tokenFile;
url = runner.url;
nodeRuntimes = [
"node24"
];
extraPackages = with pkgs; let
gtar = pkgs.runCommandNoCC "gtar" {} ''
mkdir -p $out/bin
ln -s ${lib.getExe pkgs.gnutar} $out/bin/gtar
'';
in [
nix
cachix
awscli2
coreutils
docker
gh
gtar
jq
nodejs_24
openssl
unzip
which
];
extraLabels = ["nix"] ++ optional nvdaCfg.enable "gpu";
user = github-runner.name;
group = github-runner.group;
};
};
in
cfg.runners
|> mapAttrs (name: runner:
genList (idx: {
index = idx;
name = name;
runner = runner;
})
runner.instances)
|> attrValues
|> concatLists
|> map mkRunnerConfig
|> listToAttrs;
users = {
users.github-runner = {
isSystemUser = true;
group = "github-runner";
extraGroups = ["docker" "podman"];
};
groups.github-runner = {};
};
sops.secrets."github/runner" = {};
${namespace}.services.storage.impermanence.folders = ["/var/lib/github-runner"];
};
}