7 options.services.github-runners = lib.mkOption {
9 Multiple GitHub Runners.
14 url = "https://github.com/owner/repo";
16 tokenFile = "/secrets/token1";
21 url = "https://github.com/owner/repo";
23 tokenFile = "/secrets/token2";
27 type = lib.types.attrsOf (
32 enable = lib.mkOption {
36 Whether to enable GitHub Actions runner.
38 Note: GitHub recommends using self-hosted runners with private repositories only. Learn more here:
39 [About self-hosted runners](https://docs.github.com/en/actions/hosting-your-own-runners/about-self-hosted-runners).
41 type = lib.types.bool;
47 Repository to add the runner to.
49 Changing this option triggers a new runner registration.
51 IMPORTANT: If your token is org-wide (not per repository), you need to
52 provide a github org link, not a single repository, so do it like this
53 `https://github.com/nixos`, not like this
54 `https://github.com/nixos/nixpkgs`.
55 Otherwise, you are going to get a `404 NotFound`
56 from `POST https://api.github.com/actions/runner-registration`
57 in the configure script.
59 example = "https://github.com/nixos/nixpkgs";
62 tokenFile = lib.mkOption {
63 type = lib.types.path;
65 The full path to a file which contains either
67 * a fine-grained personal access token (PAT),
69 * or a runner registration token
71 Changing this option or the `tokenFile`’s content triggers a new runner registration.
73 We suggest using the fine-grained PATs. A runner registration token is valid
74 only for 1 hour after creation, so the next time the runner configuration changes
75 this will give you hard-to-debug HTTP 404 errors in the configure step.
77 The file should contain exactly one line with the token without any newline.
78 (Use `echo -n '…token…' > …token file…` to make sure no newlines sneak in.)
80 If the file contains a PAT, the service creates a new registration token
82 If a registration token is given, it can be used to re-register a runner of the same
83 name but is time-limited as noted above.
85 For fine-grained PATs:
87 Give it "Read and Write access to organization/repository self hosted runners",
88 depending on whether it is organization wide or per-repository. You might have to
89 experiment a little, fine-grained PATs are a `beta` Github feature and still subject
90 to change; nonetheless they are the best option at the moment.
94 Make sure the PAT has a scope of `admin:org` for organization-wide registrations
95 or a scope of `repo` for a single repository.
97 For runner registration tokens:
99 Nothing special needs to be done, but updating will break after one hour,
100 so these are not recommended.
102 example = "/run/secrets/github-runner/nixos.token";
105 name = lib.mkOption {
106 type = lib.types.nullOr lib.types.str;
108 Name of the runner to configure. If null, defaults to the hostname.
110 Changing this option triggers a new runner registration.
116 runnerGroup = lib.mkOption {
117 type = lib.types.nullOr lib.types.str;
119 Name of the runner group to add this runner to (defaults to the default runner group).
121 Changing this option triggers a new runner registration.
126 extraLabels = lib.mkOption {
127 type = lib.types.listOf lib.types.str;
129 Extra labels in addition to the default (unless disabled through the `noDefaultLabels` option).
131 Changing this option triggers a new runner registration.
133 example = lib.literalExpression ''[ "nixos" ]'';
137 noDefaultLabels = lib.mkOption {
138 type = lib.types.bool;
140 Disables adding the default labels. Also see the `extraLabels` option.
142 Changing this option triggers a new runner registration.
147 replace = lib.mkOption {
148 type = lib.types.bool;
150 Replace any existing runner with the same name.
152 Without this flag, registering a new runner with the same name fails.
157 extraPackages = lib.mkOption {
158 type = lib.types.listOf lib.types.package;
160 Extra packages to add to `PATH` of the service to make them available to workflows.
165 extraEnvironment = lib.mkOption {
166 type = lib.types.attrs;
168 Extra environment variables to set for the runner, as an attrset.
171 GIT_CONFIG = "/path/to/git/config";
176 serviceOverrides = lib.mkOption {
177 type = lib.types.attrs;
179 Modify the systemd service. Can be used to, e.g., adjust the sandboxing options.
180 See {manpage}`systemd.exec(5)` for more options.
184 RestrictAddressFamilies = [ "AF_PACKET" ];
189 package = lib.mkPackageOption pkgs "github-runner" { };
191 ephemeral = lib.mkOption {
192 type = lib.types.bool;
194 If enabled, causes the following behavior:
196 - Passes the `--ephemeral` flag to the runner configuration script
197 - De-registers and stops the runner with GitHub after it has processed one job
198 - On stop, systemd wipes the runtime directory (this always happens, even without using the ephemeral option)
199 - Restarts the service after its successful exit
200 - On start, wipes the state directory and configures a new runner
202 You should only enable this option if `tokenFile` points to a file which contains a
203 personal access token (PAT). If you're using the option with a registration token, restarting the
204 service will fail as soon as the registration token expired.
206 Changing this option triggers a new runner registration.
211 user = lib.mkOption {
212 type = lib.types.nullOr lib.types.str;
214 User under which to run the service.
216 If this option and the `group` option is set to `null`,
217 the service runs as a dynamically allocated user.
219 Also see the `group` option for an overview on the effects of the `user` and `group` settings.
222 defaultText = lib.literalExpression "username";
225 group = lib.mkOption {
226 type = lib.types.nullOr lib.types.str;
228 Group under which to run the service.
230 The effect of this option depends on the value of the `user` option:
232 - `group == null` and `user == null`:
233 The service runs with a dynamically allocated user and group.
234 - `group == null` and `user != null`:
235 The service runs as the given user and its default group.
236 - `group != null` and `user == null`:
237 This configuration is invalid. In this case, the service would use the given group
238 but run as root implicitly. If this is really what you want, set `user = "root"` explicitly.
241 defaultText = lib.literalExpression "groupname";
244 workDir = lib.mkOption {
245 type = with lib.types; nullOr str;
247 Working directory, available as `$GITHUB_WORKSPACE` during workflow runs
248 and used as a default for [repository checkouts](https://github.com/actions/checkout).
249 The service cleans this directory on every service start.
251 A value of `null` will default to the systemd `RuntimeDirectory`.
253 Changing this option triggers a new runner registration.
258 nodeRuntimes = lib.mkOption {
259 type = with lib.types; nonEmptyListOf (enum [ "node20" ]);
260 default = [ "node20" ];
262 List of Node.js runtimes the runner should support.