diff --git a/nixos/github-runner.nix b/nixos/github-runner.nix index 18aadb4..e22420d 100644 --- a/nixos/github-runner.nix +++ b/nixos/github-runner.nix @@ -2,17 +2,15 @@ Limitations - A runner can run only one job at a time: https://github.com/orgs/community/discussions/26769 - - This makes sharing an org-wide runner less useful. + - This makes sharing an org-wide runner less useful, unless we create multiple runners. TODOs - [x] Run runners in containers - [ ] macOS runners: https://github.com/LnL7/nix-darwin/issues/582 - - [ ] Support github orgs + - [x] Support github orgs - [ ] Unbreak cachix? https://github.com/cachix/cachix-action/issues/169 - [x] Or switch to nix-serve or attic - - [ ] Document PAC token - - For user accounts, create a legacy PAC token with 'repo' scope. New-style could also work. */ top@{ pkgs, lib, config, ... }: @@ -23,35 +21,47 @@ in options = { # TODO: Make this general enough to support organizations and other users. services.personal-github-runners = lib.mkOption { - default = { }; - type = types.submodule { + description = '' + Attrset of runners. + + The key is either org name or the repo path. + ''; + default = { + "srid/emanote" = { }; + "srid/haskell-flake" = { }; + "srid/nixos-config" = { }; + "srid/ema" = { }; + }; + type = types.lazyAttrsOf (types.submodule ({ config, name, ... }: { options = { owner = lib.mkOption { type = types.str; - default = "srid"; + default = lib.head (lib.splitString "/" config.githubPath); }; - repositories = lib.mkOption { - type = types.listOf types.str; - description = '' - My repositories configured to use self-hosted runners - - *Before* adding an entry, make sure the token exists in - secrets.json (use the `gh` command above to create this token - from CLI) - ''; - default = [ - "emanote" - "haskell-flake" - "nixos-config" - "ema" - ]; - }; - sopsPrefix = lib.mkOption { + url = lib.mkOption { type = types.str; - default = "gh-selfhosted-tokens"; + description = ''Github URL for this runner''; + default = "https://github.com/${config.githubPath}"; + }; + githubPath = lib.mkOption { + type = types.str; + default = name; + description = '' + The path after https://github.com in the URL for this runner + + By default, it uses the attr key. If you are running multiple + runners per org or per repo, you may want to explicitly specify + the githubPath to disambiguate. + ''; + }; + tokenSecretPath = lib.mkOption { + type = types.str; + # By default, we expect personal access token (not runner registeration token) + # Thus, it is bucket by the owner. + default = "gh-selfhosted-tokens/${config.owner}"; readOnly = true; description = '' - sops-nix parent key path containing the tokens + sops-nix key path containing the token for this runner. ''; }; nixosConfig = lib.mkOption { @@ -81,7 +91,7 @@ in }; }; }; - }; + })); }; }; config = @@ -98,7 +108,11 @@ in }; in userModule // { - sops.secrets."${cfg.sopsPrefix}/${cfg.owner}".mode = "0440"; + sops.secrets = + lib.flip lib.mapAttrs' cfg (name: cfg: + lib.nameValuePair cfg.tokenSecretPath { + mode = "0440"; + }); nix.settings = { trusted-users = [ user ]; @@ -106,15 +120,13 @@ in }; containers = - lib.listToAttrs (builtins.map - (name: + lib.flip lib.mapAttrs' cfg + (name: cfg: let - tokenFile = top.config.sops.secrets."${cfg.sopsPrefix}/${cfg.owner}".path; - githubPath = "${cfg.owner}/${name}"; - url = "https://github.com/${githubPath}"; - githubPathLegal = lib.replaceStrings [ "/" ] [ "-" ] githubPath; + tokenFile = top.config.sops.secrets."${cfg.tokenSecretPath}".path; + nameLegal = lib.replaceStrings [ "/" ] [ "-" ] name; in - lib.nameValuePair ''github-runner-${githubPathLegal}'' { + lib.nameValuePair ''github-runner-${nameLegal}'' { autoStart = true; bindMounts."${tokenFile}" = { hostPath = tokenFile; @@ -127,13 +139,12 @@ in cfg.nixosConfig ]; nix.settings.trusted-users = [ user ]; # for cachix - services.github-runners."${githubPathLegal}" = cfg.runnerConfig // { + services.github-runners."${nameLegal}" = cfg.runnerConfig // { enable = true; - inherit user url tokenFile; + inherit user tokenFile; + inherit (cfg) url; }; }; - }) - cfg.repositories); - + }); }; }