mirror of
https://github.com/DeterminateSystems/nix-installer-action.git
synced 2024-12-23 05:22:21 +01:00
Support private flakes on FlakeHub (#38)
Use the GitHub Actions-issued JWT to authenticate with FlakeHub. The repository will be granted its due permissions on FlakeHub, and be able to pull the user's private flakes.
This commit is contained in:
parent
d654f7b93a
commit
07ebb8d274
6 changed files with 194 additions and 107 deletions
28
README.md
28
README.md
|
@ -15,13 +15,38 @@ jobs:
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v3
|
||||||
- name: Install Nix
|
- name: Install Nix
|
||||||
uses: DeterminateSystems/nix-installer-action@v4
|
uses: DeterminateSystems/nix-installer-action@main
|
||||||
- name: Run `nix build`
|
- name: Run `nix build`
|
||||||
run: nix build .
|
run: nix build .
|
||||||
```
|
```
|
||||||
|
|
||||||
See [`.github/workflows/ci.yml`](.github/workflows/ci.yml) for a full example.
|
See [`.github/workflows/ci.yml`](.github/workflows/ci.yml) for a full example.
|
||||||
|
|
||||||
|
To use private flakes from FlakeHub, use a configuration like this:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
on:
|
||||||
|
pull_request:
|
||||||
|
push:
|
||||||
|
branches: [main]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
lints:
|
||||||
|
name: Build
|
||||||
|
runs-on: ubuntu-22.04
|
||||||
|
permissions:
|
||||||
|
id-token: "write"
|
||||||
|
contents: "read"
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v3
|
||||||
|
- name: Install Nix
|
||||||
|
uses: DeterminateSystems/nix-installer-action@main
|
||||||
|
with:
|
||||||
|
flakehub: true
|
||||||
|
- name: Run `nix build`
|
||||||
|
run: nix build .
|
||||||
|
```
|
||||||
|
|
||||||
## Configuration
|
## Configuration
|
||||||
|
|
||||||
| Parameter | Description | Type | Default |
|
| Parameter | Description | Type | Default |
|
||||||
|
@ -29,6 +54,7 @@ See [`.github/workflows/ci.yml`](.github/workflows/ci.yml) for a full example.
|
||||||
| `backtrace` | The setting for [`RUST_BACKTRACE`][backtrace] | string | |
|
| `backtrace` | The setting for [`RUST_BACKTRACE`][backtrace] | string | |
|
||||||
| `extra-args` | Extra arguments to pass to the planner (prefer using structured `with:` arguments unless using a custom [planner]!) | string | |
|
| `extra-args` | Extra arguments to pass to the planner (prefer using structured `with:` arguments unless using a custom [planner]!) | string | |
|
||||||
| `extra-conf` | Extra configuration lines for `/etc/nix/nix.conf` (includes `access-tokens` with `secrets.GITHUB_TOKEN` automatically if `github-token` is set) | string | |
|
| `extra-conf` | Extra configuration lines for `/etc/nix/nix.conf` (includes `access-tokens` with `secrets.GITHUB_TOKEN` automatically if `github-token` is set) | string | |
|
||||||
|
| `flakehub` | Log in to FlakeHub to pull private flakes using the GitHub Actions [JSON Web Token](https://jwt.io) (JWT), which is bound to the `api.flakehub.com` audience. | Boolean | `false` |
|
||||||
| `github-token` | A [GitHub token] for making authenticated requests (which have a higher rate-limit quota than unauthenticated requests) | string | `${{ github.token }}` |
|
| `github-token` | A [GitHub token] for making authenticated requests (which have a higher rate-limit quota than unauthenticated requests) | string | `${{ github.token }}` |
|
||||||
| `init` | The init system to configure (requires `planner: linux-multi`) | enum (`none` or `systemd`) | |
|
| `init` | The init system to configure (requires `planner: linux-multi`) | enum (`none` or `systemd`) | |
|
||||||
| `local-root` | A local `nix-installer` binary root. Overrides the `nix-installer-url` setting (a `nix-installer.sh` should exist, binaries should be named `nix-installer-$ARCH`, eg. `nix-installer-x86_64-linux`). | Boolean | `false` |
|
| `local-root` | A local `nix-installer` binary root. Overrides the `nix-installer-url` setting (a `nix-installer.sh` should exist, binaries should be named `nix-installer-$ARCH`, eg. `nix-installer-x86_64-linux`). | Boolean | `false` |
|
||||||
|
|
|
@ -13,6 +13,10 @@ inputs:
|
||||||
extra-conf:
|
extra-conf:
|
||||||
description: Extra configuration lines for `/etc/nix/nix.conf` (includes `access-tokens` with `secrets.GITHUB_TOKEN` automatically if `github-token` is set)
|
description: Extra configuration lines for `/etc/nix/nix.conf` (includes `access-tokens` with `secrets.GITHUB_TOKEN` automatically if `github-token` is set)
|
||||||
required: false
|
required: false
|
||||||
|
flakehub:
|
||||||
|
description: Automatically log in to your [FlakeHub](https://flakehub.com) account, for accessing private flakes.
|
||||||
|
required: false
|
||||||
|
default: false
|
||||||
github-token:
|
github-token:
|
||||||
description: A GitHub token for making authenticated requests (which have a higher rate-limit quota than unauthenticated requests)
|
description: A GitHub token for making authenticated requests (which have a higher rate-limit quota than unauthenticated requests)
|
||||||
default: ${{ github.token }}
|
default: ${{ github.token }}
|
||||||
|
|
27
dist/index.js
vendored
27
dist/index.js
vendored
|
@ -61,6 +61,7 @@ class NixInstallerAction {
|
||||||
this.backtrace = action_input_string_or_null("backtrace");
|
this.backtrace = action_input_string_or_null("backtrace");
|
||||||
this.extra_args = action_input_string_or_null("extra-args");
|
this.extra_args = action_input_string_or_null("extra-args");
|
||||||
this.extra_conf = action_input_multiline_string_or_null("extra-conf");
|
this.extra_conf = action_input_multiline_string_or_null("extra-conf");
|
||||||
|
this.flakehub = action_input_bool("flakehub");
|
||||||
this.github_token = action_input_string_or_null("github-token");
|
this.github_token = action_input_string_or_null("github-token");
|
||||||
this.init = action_input_string_or_null("init");
|
this.init = action_input_string_or_null("init");
|
||||||
this.local_root = action_input_string_or_null("local-root");
|
this.local_root = action_input_string_or_null("local-root");
|
||||||
|
@ -87,6 +88,7 @@ class NixInstallerAction {
|
||||||
this.nix_installer_url = resolve_nix_installer_url(this.platform, this.correlation);
|
this.nix_installer_url = resolve_nix_installer_url(this.platform, this.correlation);
|
||||||
}
|
}
|
||||||
executionEnvironment() {
|
executionEnvironment() {
|
||||||
|
return __awaiter(this, void 0, void 0, function* () {
|
||||||
const execution_env = {};
|
const execution_env = {};
|
||||||
execution_env.NIX_INSTALLER_NO_CONFIRM = "true";
|
execution_env.NIX_INSTALLER_NO_CONFIRM = "true";
|
||||||
execution_env.NIX_INSTALLER_DIAGNOSTIC_ATTRIBUTION = this.correlation;
|
execution_env.NIX_INSTALLER_DIAGNOSTIC_ATTRIBUTION = this.correlation;
|
||||||
|
@ -186,6 +188,10 @@ class NixInstallerAction {
|
||||||
extra_conf += `trusted-users = root ${process.env.USER}`;
|
extra_conf += `trusted-users = root ${process.env.USER}`;
|
||||||
extra_conf += "\n";
|
extra_conf += "\n";
|
||||||
}
|
}
|
||||||
|
if (this.flakehub) {
|
||||||
|
extra_conf += `netrc-file = ${yield this.flakehub_login()}`;
|
||||||
|
extra_conf += "\n";
|
||||||
|
}
|
||||||
if (this.extra_conf !== null && this.extra_conf.length !== 0) {
|
if (this.extra_conf !== null && this.extra_conf.length !== 0) {
|
||||||
extra_conf += this.extra_conf.join("\n");
|
extra_conf += this.extra_conf.join("\n");
|
||||||
extra_conf += "\n";
|
extra_conf += "\n";
|
||||||
|
@ -196,10 +202,11 @@ class NixInstallerAction {
|
||||||
execution_env.NIX_INSTALLER_INIT = "none";
|
execution_env.NIX_INSTALLER_INIT = "none";
|
||||||
}
|
}
|
||||||
return execution_env;
|
return execution_env;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
execute_install(binary_path) {
|
execute_install(binary_path) {
|
||||||
return __awaiter(this, void 0, void 0, function* () {
|
return __awaiter(this, void 0, void 0, function* () {
|
||||||
const execution_env = this.executionEnvironment();
|
const execution_env = yield this.executionEnvironment();
|
||||||
actions_core.info(`Execution environment: ${JSON.stringify(execution_env, null, 4)}`);
|
actions_core.info(`Execution environment: ${JSON.stringify(execution_env, null, 4)}`);
|
||||||
const args = ["install"];
|
const args = ["install"];
|
||||||
if (this.planner) {
|
if (this.planner) {
|
||||||
|
@ -276,6 +283,24 @@ class NixInstallerAction {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
flakehub_login() {
|
||||||
|
var _a;
|
||||||
|
return __awaiter(this, void 0, void 0, function* () {
|
||||||
|
const netrc_path = `${process.env["RUNNER_TEMP"]}/determinate-nix-installer-netrc`;
|
||||||
|
const jwt = yield actions_core.getIDToken("api.flakehub.com");
|
||||||
|
yield (0, promises_1.writeFile)(netrc_path, [
|
||||||
|
`machine api.flakehub.com login flakehub password ${jwt}`,
|
||||||
|
`machine flakehub.com login flakehub password ${jwt}`,
|
||||||
|
].join("\n"));
|
||||||
|
actions_core.info("Logging in to FlakeHub.");
|
||||||
|
// the join followed by a match on ^... looks silly, but extra_config
|
||||||
|
// could contain multi-line values
|
||||||
|
if ((_a = this.extra_conf) === null || _a === void 0 ? void 0 : _a.join("\n").match(/^netrc-file/m)) {
|
||||||
|
actions_core.warning("Logging in to FlakeHub conflicts with the Nix option `netrc-file`.");
|
||||||
|
}
|
||||||
|
return netrc_path;
|
||||||
|
});
|
||||||
|
}
|
||||||
execute_uninstall() {
|
execute_uninstall() {
|
||||||
return __awaiter(this, void 0, void 0, function* () {
|
return __awaiter(this, void 0, void 0, function* () {
|
||||||
const spawned = (0, node_child_process_1.spawn)(`/nix/nix-installer`, ["uninstall"], {
|
const spawned = (0, node_child_process_1.spawn)(`/nix/nix-installer`, ["uninstall"], {
|
||||||
|
|
2
dist/index.js.map
vendored
2
dist/index.js.map
vendored
File diff suppressed because one or more lines are too long
38
src/main.ts
38
src/main.ts
|
@ -1,6 +1,6 @@
|
||||||
import * as actions_core from "@actions/core";
|
import * as actions_core from "@actions/core";
|
||||||
import * as github from "@actions/github";
|
import * as github from "@actions/github";
|
||||||
import { mkdtemp, chmod, access } from "node:fs/promises";
|
import { mkdtemp, chmod, access, writeFile } from "node:fs/promises";
|
||||||
import { spawn } from "node:child_process";
|
import { spawn } from "node:child_process";
|
||||||
import { randomUUID } from "node:crypto";
|
import { randomUUID } from "node:crypto";
|
||||||
import { join } from "node:path";
|
import { join } from "node:path";
|
||||||
|
@ -17,6 +17,7 @@ class NixInstallerAction {
|
||||||
backtrace: string | null;
|
backtrace: string | null;
|
||||||
extra_args: string | null;
|
extra_args: string | null;
|
||||||
extra_conf: string[] | null;
|
extra_conf: string[] | null;
|
||||||
|
flakehub: boolean;
|
||||||
github_token: string | null;
|
github_token: string | null;
|
||||||
// TODO: linux_init
|
// TODO: linux_init
|
||||||
init: string | null;
|
init: string | null;
|
||||||
|
@ -54,6 +55,7 @@ class NixInstallerAction {
|
||||||
this.backtrace = action_input_string_or_null("backtrace");
|
this.backtrace = action_input_string_or_null("backtrace");
|
||||||
this.extra_args = action_input_string_or_null("extra-args");
|
this.extra_args = action_input_string_or_null("extra-args");
|
||||||
this.extra_conf = action_input_multiline_string_or_null("extra-conf");
|
this.extra_conf = action_input_multiline_string_or_null("extra-conf");
|
||||||
|
this.flakehub = action_input_bool("flakehub");
|
||||||
this.github_token = action_input_string_or_null("github-token");
|
this.github_token = action_input_string_or_null("github-token");
|
||||||
this.init = action_input_string_or_null("init");
|
this.init = action_input_string_or_null("init");
|
||||||
this.local_root = action_input_string_or_null("local-root");
|
this.local_root = action_input_string_or_null("local-root");
|
||||||
|
@ -93,7 +95,7 @@ class NixInstallerAction {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
private executionEnvironment(): ExecuteEnvironment {
|
private async executionEnvironment(): Promise<ExecuteEnvironment> {
|
||||||
const execution_env: ExecuteEnvironment = {};
|
const execution_env: ExecuteEnvironment = {};
|
||||||
|
|
||||||
execution_env.NIX_INSTALLER_NO_CONFIRM = "true";
|
execution_env.NIX_INSTALLER_NO_CONFIRM = "true";
|
||||||
|
@ -217,6 +219,10 @@ class NixInstallerAction {
|
||||||
extra_conf += `trusted-users = root ${process.env.USER}`;
|
extra_conf += `trusted-users = root ${process.env.USER}`;
|
||||||
extra_conf += "\n";
|
extra_conf += "\n";
|
||||||
}
|
}
|
||||||
|
if (this.flakehub) {
|
||||||
|
extra_conf += `netrc-file = ${await this.flakehub_login()}`;
|
||||||
|
extra_conf += "\n";
|
||||||
|
}
|
||||||
if (this.extra_conf !== null && this.extra_conf.length !== 0) {
|
if (this.extra_conf !== null && this.extra_conf.length !== 0) {
|
||||||
extra_conf += this.extra_conf.join("\n");
|
extra_conf += this.extra_conf.join("\n");
|
||||||
extra_conf += "\n";
|
extra_conf += "\n";
|
||||||
|
@ -234,7 +240,7 @@ class NixInstallerAction {
|
||||||
}
|
}
|
||||||
|
|
||||||
private async execute_install(binary_path: string): Promise<number> {
|
private async execute_install(binary_path: string): Promise<number> {
|
||||||
const execution_env = this.executionEnvironment();
|
const execution_env = await this.executionEnvironment();
|
||||||
actions_core.info(
|
actions_core.info(
|
||||||
`Execution environment: ${JSON.stringify(execution_env, null, 4)}`,
|
`Execution environment: ${JSON.stringify(execution_env, null, 4)}`,
|
||||||
);
|
);
|
||||||
|
@ -326,6 +332,32 @@ class NixInstallerAction {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async flakehub_login(): Promise<string> {
|
||||||
|
const netrc_path = `${process.env["RUNNER_TEMP"]}/determinate-nix-installer-netrc`;
|
||||||
|
|
||||||
|
const jwt = await actions_core.getIDToken("api.flakehub.com");
|
||||||
|
|
||||||
|
await writeFile(
|
||||||
|
netrc_path,
|
||||||
|
[
|
||||||
|
`machine api.flakehub.com login flakehub password ${jwt}`,
|
||||||
|
`machine flakehub.com login flakehub password ${jwt}`,
|
||||||
|
].join("\n"),
|
||||||
|
);
|
||||||
|
|
||||||
|
actions_core.info("Logging in to FlakeHub.");
|
||||||
|
|
||||||
|
// the join followed by a match on ^... looks silly, but extra_config
|
||||||
|
// could contain multi-line values
|
||||||
|
if (this.extra_conf?.join("\n").match(/^netrc-file/m)) {
|
||||||
|
actions_core.warning(
|
||||||
|
"Logging in to FlakeHub conflicts with the Nix option `netrc-file`.",
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return netrc_path;
|
||||||
|
}
|
||||||
|
|
||||||
async execute_uninstall(): Promise<number> {
|
async execute_uninstall(): Promise<number> {
|
||||||
const spawned = spawn(`/nix/nix-installer`, ["uninstall"], {
|
const spawned = spawn(`/nix/nix-installer`, ["uninstall"], {
|
||||||
env: {
|
env: {
|
||||||
|
|
Loading…
Reference in a new issue