Compare commits
30 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| e50d5f73bf | |||
| 25431d2798 | |||
| b92f66560d | |||
| ddfca32d6f | |||
| da36cb69b1 | |||
| 1406b8b52c | |||
| 197bf2b2a5 | |||
| 452d9c7008 | |||
| 033f039e5c | |||
| 468e81bb99 | |||
| b164ca3241 | |||
| 055e848f13 | |||
| d41fccdd9e | |||
| ab6bcb2d5a | |||
| 0d82cb015a | |||
| 2a2ecc1e15 | |||
| 9e19e84fa9 | |||
| dc8972520c | |||
| 7ad5c49547 | |||
| 17a448a97b | |||
| 45cb2f89ca | |||
| 47dc48605c | |||
| 4b8e190ea5 | |||
| 8c320971f9 | |||
| 7b943f9a7e | |||
| 40e4bc1e80 | |||
| 9d5faf48ab | |||
| f92f10828b | |||
| 1025a55627 | |||
| 5adb94fc48 |
+29
-100
@@ -11,9 +11,9 @@ jobs:
|
||||
runs-on: ubuntu-22.04
|
||||
needs:
|
||||
- check-dist-up-to-date
|
||||
- install-nix-linux
|
||||
- install-nix-macos
|
||||
- install-nix
|
||||
- install-with-non-default-source-inputs
|
||||
- install-no-id-token
|
||||
# NOTE(cole-h): GitHub treats "skipped" as "OK" for the purposes of required checks on branch
|
||||
# protection, so we take advantage of this fact and fail if any of the dependent actions failed,
|
||||
# or "skip" (which is a success for GHA's purposes) if none of them did.
|
||||
@@ -44,14 +44,21 @@ jobs:
|
||||
- name: Ensure no staged changes
|
||||
run: git diff --exit-code
|
||||
|
||||
install-nix-linux:
|
||||
name: Run test suite for Linux systems
|
||||
install-nix:
|
||||
name: "Test: ${{ matrix.runner }}${{ matrix.determinate && ' with determinate' || '' }}"
|
||||
strategy:
|
||||
matrix:
|
||||
runner:
|
||||
- ubuntu-latest
|
||||
- nscloud-ubuntu-22.04-amd64-4x16
|
||||
- namespace-profile-default-arm64
|
||||
# - macos-12-large # determinate-nixd is broken on macos-12
|
||||
- macos-13-large
|
||||
- macos-14-large
|
||||
- macos-14-xlarge # arm64
|
||||
determinate:
|
||||
- true
|
||||
- false
|
||||
runs-on: ${{ matrix.runner }}
|
||||
permissions:
|
||||
contents: read
|
||||
@@ -65,6 +72,7 @@ jobs:
|
||||
log-directives: nix_installer=trace
|
||||
backtrace: full
|
||||
_internal-strict-mode: true
|
||||
determinate: ${{ matrix.determinate }}
|
||||
- name: echo $PATH
|
||||
run: echo $PATH
|
||||
|
||||
@@ -82,91 +90,6 @@ jobs:
|
||||
nix store gc
|
||||
nix run nixpkgs#hello
|
||||
|
||||
- name: Test bash
|
||||
run: nix-instantiate -E 'builtins.currentTime' --eval
|
||||
if: success() || failure()
|
||||
shell: bash --login {0}
|
||||
- name: Test sh
|
||||
run: nix-instantiate -E 'builtins.currentTime' --eval
|
||||
if: success() || failure()
|
||||
shell: sh -l {0}
|
||||
- name: Install Nix again (noop)
|
||||
uses: ./
|
||||
with:
|
||||
logger: pretty
|
||||
log-directives: nix_installer=trace
|
||||
backtrace: full
|
||||
_internal-strict-mode: true
|
||||
- name: Test `nix` with `$GITHUB_PATH`
|
||||
if: success() || failure()
|
||||
run: |
|
||||
nix run nixpkgs#hello
|
||||
nix profile install nixpkgs#hello
|
||||
hello
|
||||
nix store gc
|
||||
nix run nixpkgs#hello
|
||||
- name: Reinstall Nix
|
||||
uses: ./
|
||||
with:
|
||||
logger: pretty
|
||||
log-directives: nix_installer=trace
|
||||
backtrace: full
|
||||
reinstall: true
|
||||
extra-conf: |
|
||||
use-sqlite-wal = true
|
||||
_internal-strict-mode: true
|
||||
- name: Test `nix` with `$GITHUB_PATH`
|
||||
if: success() || failure()
|
||||
run: |
|
||||
nix run nixpkgs#hello
|
||||
nix profile install nixpkgs#hello
|
||||
hello
|
||||
nix store gc
|
||||
nix run nixpkgs#hello
|
||||
- name: Verify the generated nix.conf
|
||||
run: |
|
||||
cat -n /etc/nix/nix.conf
|
||||
grep -E "^trusted-users = .*$USER" /etc/nix/nix.conf
|
||||
grep -E "^use-sqlite-wal = true" /etc/nix/nix.conf
|
||||
- name: Breakpoint if tests failed
|
||||
if: failure()
|
||||
uses: namespacelabs/breakpoint-action@v0
|
||||
with:
|
||||
duration: 5m
|
||||
authorized-users: grahamc
|
||||
|
||||
install-nix-macos:
|
||||
name: Run test suite for macOS systems
|
||||
strategy:
|
||||
matrix:
|
||||
runner:
|
||||
# x86_64-darwin
|
||||
- macos-12
|
||||
# aarch64-darwin
|
||||
- macos-latest-xlarge
|
||||
runs-on: ${{ matrix.runner }}
|
||||
permissions:
|
||||
contents: read
|
||||
id-token: write
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Install Nix
|
||||
uses: ./
|
||||
with:
|
||||
logger: pretty
|
||||
log-directives: nix_installer=trace
|
||||
backtrace: full
|
||||
_internal-strict-mode: true
|
||||
- name: echo $PATH
|
||||
run: echo $PATH
|
||||
- name: Test `nix` with `$GITHUB_PATH`
|
||||
if: success() || failure()
|
||||
run: |
|
||||
nix run nixpkgs#hello
|
||||
nix profile install nixpkgs#hello
|
||||
hello
|
||||
nix store gc
|
||||
nix run nixpkgs#hello
|
||||
- name: Test bash
|
||||
run: nix-instantiate -E 'builtins.currentTime' --eval
|
||||
if: success() || failure()
|
||||
@@ -176,9 +99,8 @@ jobs:
|
||||
if: success() || failure()
|
||||
shell: sh -l {0}
|
||||
- name: Test zsh
|
||||
run: nix-instantiate -E 'builtins.currentTime' --eval
|
||||
run: if (zsh --help > /dev/null); then zsh --login --interactive -c "nix-instantiate -E 'builtins.currentTime' --eval"; fi
|
||||
if: success() || failure()
|
||||
shell: zsh --login --interactive {0}
|
||||
- name: Install Nix again (noop)
|
||||
uses: ./
|
||||
with:
|
||||
@@ -186,6 +108,7 @@ jobs:
|
||||
log-directives: nix_installer=trace
|
||||
backtrace: full
|
||||
_internal-strict-mode: true
|
||||
determinate: ${{ matrix.determinate }}
|
||||
- name: Test `nix` with `$GITHUB_PATH`
|
||||
if: success() || failure()
|
||||
run: |
|
||||
@@ -204,6 +127,7 @@ jobs:
|
||||
extra-conf: |
|
||||
use-sqlite-wal = true
|
||||
_internal-strict-mode: true
|
||||
determinate: ${{ matrix.determinate }}
|
||||
- name: Test `nix` with `$GITHUB_PATH`
|
||||
if: success() || failure()
|
||||
run: |
|
||||
@@ -214,15 +138,10 @@ jobs:
|
||||
nix run nixpkgs#hello
|
||||
- name: Verify the generated nix.conf
|
||||
run: |
|
||||
cat /etc/nix/nix.conf
|
||||
grep -E "^trusted-users = .*$USER" /etc/nix/nix.conf
|
||||
grep -E "^use-sqlite-wal = true" /etc/nix/nix.conf
|
||||
- name: Breakpoint if tests failed
|
||||
if: failure()
|
||||
uses: namespacelabs/breakpoint-action@v0
|
||||
with:
|
||||
duration: 5m
|
||||
authorized-users: grahamc
|
||||
nix config show
|
||||
cat -n /etc/nix/nix.conf
|
||||
nix config show | grep -E "^trusted-users = .*$USER"
|
||||
nix config show | grep -E "^use-sqlite-wal = true"
|
||||
|
||||
install-with-non-default-source-inputs:
|
||||
name: Install Nix using non-default source-${{ matrix.inputs.key }}
|
||||
@@ -248,3 +167,13 @@ jobs:
|
||||
_internal-strict-mode: true
|
||||
- name: Ensure that the expected Nix version ${{ matrix.inputs.nix-version }} is installed via alternative source-${{ matrix.inputs.key }}
|
||||
run: .github/verify-version.sh ${{ matrix.inputs.nix-version }}
|
||||
|
||||
install-no-id-token:
|
||||
name: Install Nix without an ID token
|
||||
runs-on: ubuntu-22.04
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: ./
|
||||
with:
|
||||
_internal-strict-mode: true
|
||||
determinate: true
|
||||
|
||||
@@ -34,7 +34,7 @@ jobs:
|
||||
|
||||
### With FlakeHub
|
||||
|
||||
To fetch private flakes from FlakeHub, update the `permissions` block and pass `flakehub: true`:
|
||||
To fetch private flakes from FlakeHub and Nix builds from FlakeHub Cache, update the `permissions` block and pass `determinate: true`:
|
||||
|
||||
```yaml
|
||||
on:
|
||||
@@ -53,7 +53,7 @@ jobs:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: DeterminateSystems/nix-installer-action@main
|
||||
with:
|
||||
flakehub: true
|
||||
determinate: true
|
||||
- run: nix build .
|
||||
```
|
||||
|
||||
@@ -85,9 +85,10 @@ Differing from the upstream [Nix](https://github.com/NixOS/nix) installer script
|
||||
| Parameter | Description | Type | Default |
|
||||
| :---------------------- | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :----------------------------------------- | :------------------------------------------------------------- |
|
||||
| `backtrace` | The setting for [`RUST_BACKTRACE`][backtrace] | string | |
|
||||
| `determinate` | Whether to install [Determinate Nix](https://determinate.systems/enterprise) and log in to FlakeHub for private Flakes and binary caches. | Boolean | `false` |
|
||||
| `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 | |
|
||||
| `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` |
|
||||
| `flakehub` | Deprecated. Implies `determinate`. | Boolean | `false` |
|
||||
| `force-docker-shim` | Force the use of Docker as a process supervisor. This setting is automatically enabled when necessary. | 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-server-url` | The URL for the GitHub server, to use with the `github-token` token. Defaults to the current GitHub server, supporting GitHub Enterprise Server automatically. Only change this value if the provided `github-token` is for a different GitHub server than the current server. | string | `${{ github.server }}` |
|
||||
@@ -110,7 +111,7 @@ Differing from the upstream [Nix](https://github.com/NixOS/nix) installer script
|
||||
| `source-pr` | The pull request of `nix-installer` to use (conflicts with `source-tag`, `source-revision`, and `source-branch`) | integer | |
|
||||
| `source-revision` | The revision of `nix-installer` to use (conflicts with `source-tag`, `source-branch`, and `source-pr`) | string | |
|
||||
| `source-tag` | The tag of `nix-installer` to use (conflicts with `source-revision`, `source-branch`, `source-pr`) | string | |
|
||||
| `source-url` | A URL pointing to a `nix-installer.sh` script | URL | `https://install.determinate.systems/nix` |
|
||||
| `source-url` | A URL pointing to the `nix-installer` binary | URL | n/a (calculated) |
|
||||
| `nix-package-url` | The Nix package URL | URL | |
|
||||
| `planner` | The installation [planner] to use | enum (`linux` or `macos`) | |
|
||||
| `reinstall` | Force a reinstall if an existing installation is detected (consider backing up `/nix/store`) | Boolean | `false` |
|
||||
|
||||
+8
-1
@@ -7,6 +7,10 @@ inputs:
|
||||
backtrace:
|
||||
description: The setting for `RUST_BACKTRACE` (see https://doc.rust-lang.org/std/backtrace/index.html#environment-variables)
|
||||
required: false
|
||||
determinate:
|
||||
description: |
|
||||
Whether to install [Determinate Nix](https://determinate.systems/enterprise) and log in to FlakeHub for private Flakes and binary caches.
|
||||
default: false
|
||||
extra-args:
|
||||
description: Extra args to pass to the planner (prefer using structured `with:` arguments unless using a custom planner!)
|
||||
required: false
|
||||
@@ -14,7 +18,7 @@ inputs:
|
||||
description: Extra configuration lines for `/etc/nix/nix.conf` (includes `access-tokens` with `secrets.GITHUB_TOKEN` automatically if `github-token` is set)
|
||||
required: false
|
||||
flakehub:
|
||||
description: Automatically log in to your [FlakeHub](https://flakehub.com) account, for accessing private flakes.
|
||||
description: Deprecated. Implies `determinate`.
|
||||
required: false
|
||||
default: false
|
||||
force-docker-shim:
|
||||
@@ -30,6 +34,9 @@ inputs:
|
||||
init:
|
||||
description: "The init system to configure, requires `planner: linux-multi` (allowing the choice between `none` or `systemd`)"
|
||||
required: false
|
||||
job-status:
|
||||
description: The overall status of the job. Set automatically, for aggregate analysis of Nix stability.
|
||||
default: ${{ job.status }}
|
||||
kvm:
|
||||
description: Automatically configure the GitHub Actions Runner for NixOS test supports, if the host supports it.
|
||||
required: false
|
||||
|
||||
+7866
-3643
File diff suppressed because one or more lines are too long
+5
-4
@@ -29,21 +29,22 @@
|
||||
"@actions/exec": "^1.1.1",
|
||||
"@actions/github": "^5.1.1",
|
||||
"detsys-ts": "github:DeterminateSystems/detsys-ts",
|
||||
"got": "^14.3.0",
|
||||
"string-argv": "^0.3.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@trivago/prettier-plugin-sort-imports": "^4.3.0",
|
||||
"@types/node": "^20.12.13",
|
||||
"@types/node": "^20.14.0",
|
||||
"@types/uuid": "^9.0.8",
|
||||
"@typescript-eslint/eslint-plugin": "^7.11.0",
|
||||
"@typescript-eslint/eslint-plugin": "^7.12.0",
|
||||
"@vercel/ncc": "^0.38.1",
|
||||
"eslint": "^8.57.0",
|
||||
"eslint-import-resolver-typescript": "^3.6.1",
|
||||
"eslint-plugin-github": "^4.10.2",
|
||||
"eslint-plugin-import": "^2.29.1",
|
||||
"eslint-plugin-prettier": "^5.1.3",
|
||||
"prettier": "^3.2.5",
|
||||
"tsup": "^8.0.2",
|
||||
"prettier": "^3.3.0",
|
||||
"tsup": "^8.1.0",
|
||||
"typescript": "^5.4.5"
|
||||
}
|
||||
}
|
||||
|
||||
Generated
+463
-177
File diff suppressed because it is too large
Load Diff
+188
-127
@@ -1,14 +1,14 @@
|
||||
import * as actionsCore from "@actions/core";
|
||||
import * as github from "@actions/github";
|
||||
import * as actionsExec from "@actions/exec";
|
||||
import { access, writeFile, readFile } from "node:fs/promises";
|
||||
import { access, readFile } from "node:fs/promises";
|
||||
import { join } from "node:path";
|
||||
import fs from "node:fs";
|
||||
import { userInfo } from "node:os";
|
||||
import stringArgv from "string-argv";
|
||||
import * as path from "path";
|
||||
import { DetSysAction, inputs, platform } from "detsys-ts";
|
||||
import { DetSysAction, inputs, platform, stringifyError } from "detsys-ts";
|
||||
import { randomUUID } from "node:crypto";
|
||||
import got from "got";
|
||||
|
||||
// Nix installation events
|
||||
const EVENT_INSTALL_NIX_FAILURE = "install_nix_failure";
|
||||
@@ -25,34 +25,32 @@ const EVENT_START_DOCKER_SHIM = "start_docker_shim";
|
||||
const EVENT_LOGIN_TO_FLAKEHUB = "login_to_flakehub";
|
||||
|
||||
// Other events
|
||||
const EVENT_CONCLUDE_WORKFLOW = "conclude_workflow";
|
||||
const EVENT_CONCLUDE_JOB = "conclude_job";
|
||||
|
||||
// Facts
|
||||
const FACT_DETERMINATE_NIX = "determinate_nix";
|
||||
const FACT_HAS_DOCKER = "has_docker";
|
||||
const FACT_HAS_SYSTEMD = "has_systemd";
|
||||
const FACT_IN_ACT = "in_act";
|
||||
const FACT_IN_NAMESPACE_SO = "in_namespace_so";
|
||||
const FACT_NIX_INSTALLER_PLANNER = "nix_installer_planner";
|
||||
|
||||
type WorkflowConclusion =
|
||||
| "success"
|
||||
| "failure"
|
||||
| "cancelled"
|
||||
| "unavailable"
|
||||
| "no-jobs";
|
||||
// Flags
|
||||
const FLAG_DETERMINATE = "--determinate";
|
||||
|
||||
class NixInstallerAction extends DetSysAction {
|
||||
determinate: boolean;
|
||||
platform: string;
|
||||
nixPackageUrl: string | null;
|
||||
backtrace: string | null;
|
||||
extraArgs: string | null;
|
||||
extraConf: string[] | null;
|
||||
flakehub: boolean;
|
||||
kvm: boolean;
|
||||
githubServerUrl: string | null;
|
||||
githubToken: string | null;
|
||||
forceDockerShim: boolean;
|
||||
init: string | null;
|
||||
jobConclusion: string | null;
|
||||
localRoot: string | null;
|
||||
logDirectives: string | null;
|
||||
logger: string | null;
|
||||
@@ -83,17 +81,19 @@ class NixInstallerAction extends DetSysAction {
|
||||
diagnosticsSuffix: "diagnostic",
|
||||
});
|
||||
|
||||
this.determinate =
|
||||
inputs.getBool("determinate") || inputs.getBool("flakehub");
|
||||
this.platform = platform.getNixPlatform(platform.getArchOs());
|
||||
this.nixPackageUrl = inputs.getStringOrNull("nix-package-url");
|
||||
this.backtrace = inputs.getStringOrNull("backtrace");
|
||||
this.extraArgs = inputs.getStringOrNull("extra-args");
|
||||
this.extraConf = inputs.getMultilineStringOrNull("extra-conf");
|
||||
this.flakehub = inputs.getBool("flakehub");
|
||||
this.kvm = inputs.getBool("kvm");
|
||||
this.forceDockerShim = inputs.getBool("force-docker-shim");
|
||||
this.githubToken = inputs.getStringOrNull("github-token");
|
||||
this.githubServerUrl = inputs.getStringOrNull("github-server-url");
|
||||
this.init = inputs.getStringOrNull("init");
|
||||
this.jobConclusion = inputs.getStringOrNull("job-status");
|
||||
this.localRoot = inputs.getStringOrNull("local-root");
|
||||
this.logDirectives = inputs.getStringOrNull("log-directives");
|
||||
this.logger = inputs.getStringOrNull("logger");
|
||||
@@ -117,6 +117,7 @@ class NixInstallerAction extends DetSysAction {
|
||||
}
|
||||
|
||||
async main(): Promise<void> {
|
||||
await this.scienceDebugFly();
|
||||
await this.detectAndForceDockerShim();
|
||||
await this.install();
|
||||
}
|
||||
@@ -145,6 +146,44 @@ class NixInstallerAction extends DetSysAction {
|
||||
);
|
||||
}
|
||||
|
||||
async scienceDebugFly(): Promise<void> {
|
||||
try {
|
||||
const feat = this.getFeature("debug-probe-urls");
|
||||
if (feat === undefined || feat.payload === undefined) {
|
||||
return;
|
||||
}
|
||||
|
||||
const { timeoutMs, url }: { timeoutMs: number; url: string } = JSON.parse(
|
||||
feat.payload,
|
||||
);
|
||||
try {
|
||||
const resp = await got.get(url, {
|
||||
timeout: {
|
||||
request: timeoutMs,
|
||||
},
|
||||
});
|
||||
|
||||
this.recordEvent("debug-probe-urls:response", {
|
||||
debug_probe_urls_ip: resp.ip, // eslint-disable-line camelcase
|
||||
debug_probe_urls_ok: resp.ok, // eslint-disable-line camelcase
|
||||
debug_probe_urls_status_code: resp.statusCode, // eslint-disable-line camelcase
|
||||
debug_probe_urls_body: resp.body, // eslint-disable-line camelcase
|
||||
// eslint-disable-next-line camelcase
|
||||
debug_probe_urls_elapsed:
|
||||
(resp.timings.end ?? 0) - resp.timings.start,
|
||||
});
|
||||
} catch (e: unknown) {
|
||||
this.recordEvent("debug-probe-urls:exception", {
|
||||
debug_probe_urls_exception: stringifyError(e), // eslint-disable-line camelcase
|
||||
});
|
||||
}
|
||||
} catch (err: unknown) {
|
||||
this.recordEvent("debug-probe-urls:error", {
|
||||
exception: stringifyError(err),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Detect if we're in a GHA runner which is Linux, doesn't have Systemd, and does have Docker.
|
||||
// This is a common case in self-hosted runners, providers like [Namespace](https://namespace.so/),
|
||||
// and especially GitHub Enterprise Server.
|
||||
@@ -479,15 +518,6 @@ class NixInstallerAction extends DetSysAction {
|
||||
}
|
||||
extraConf += "\n";
|
||||
}
|
||||
if (this.flakehub) {
|
||||
try {
|
||||
const flakeHubNetrcFile = await this.flakehubLogin();
|
||||
extraConf += `netrc-file = ${flakeHubNetrcFile}`;
|
||||
extraConf += "\n";
|
||||
} catch (e) {
|
||||
actionsCore.warning(`Failed to set up FlakeHub: ${e}`);
|
||||
}
|
||||
}
|
||||
if (this.extraConf !== null && this.extraConf.length !== 0) {
|
||||
extraConf += this.extraConf.join("\n");
|
||||
extraConf += "\n";
|
||||
@@ -513,13 +543,9 @@ class NixInstallerAction extends DetSysAction {
|
||||
return executionEnv;
|
||||
}
|
||||
|
||||
private async executeInstall(binaryPath: string): Promise<number> {
|
||||
const executionEnv = await this.executionEnvironment();
|
||||
actionsCore.debug(
|
||||
`Execution environment: ${JSON.stringify(executionEnv, null, 4)}`,
|
||||
);
|
||||
|
||||
private get installerArgs(): string[] {
|
||||
const args = ["install"];
|
||||
|
||||
if (this.planner) {
|
||||
this.addFact(FACT_NIX_INSTALLER_PLANNER, this.planner);
|
||||
args.push(this.planner);
|
||||
@@ -530,11 +556,36 @@ class NixInstallerAction extends DetSysAction {
|
||||
|
||||
if (this.extraArgs) {
|
||||
const extraArgs = stringArgv(this.extraArgs);
|
||||
args.concat(extraArgs);
|
||||
args.push(...extraArgs);
|
||||
}
|
||||
|
||||
if (this.determinate) {
|
||||
this.addFact(FACT_DETERMINATE_NIX, true);
|
||||
|
||||
actionsCore.info(
|
||||
`Installing Determinate Nix using the ${FLAG_DETERMINATE} flag`,
|
||||
);
|
||||
|
||||
if (!this.extraArgs) {
|
||||
args.push(FLAG_DETERMINATE);
|
||||
}
|
||||
|
||||
if (this.extraArgs && !this.extraArgs.includes(FLAG_DETERMINATE)) {
|
||||
args.push(FLAG_DETERMINATE);
|
||||
}
|
||||
}
|
||||
|
||||
return args;
|
||||
}
|
||||
|
||||
private async executeInstall(binaryPath: string): Promise<number> {
|
||||
const executionEnv = await this.executionEnvironment();
|
||||
actionsCore.debug(
|
||||
`Execution environment: ${JSON.stringify(executionEnv, null, 4)}`,
|
||||
);
|
||||
|
||||
this.recordEvent(EVENT_INSTALL_NIX_START);
|
||||
const exitCode = await actionsExec.exec(binaryPath, args, {
|
||||
const exitCode = await actionsExec.exec(binaryPath, this.installerArgs, {
|
||||
env: {
|
||||
...executionEnv,
|
||||
...process.env, // To get $PATH, etc
|
||||
@@ -563,8 +614,13 @@ class NixInstallerAction extends DetSysAction {
|
||||
);
|
||||
await this.executeUninstall();
|
||||
} else {
|
||||
// We're already installed, and not reinstalling, just set GITHUB_PATH and finish early
|
||||
// We're already installed, and not reinstalling, just log in to FlakeHub, set GITHUB_PATH and finish early
|
||||
await this.setGithubPath();
|
||||
|
||||
if (this.determinate) {
|
||||
await this.flakehubLogin();
|
||||
}
|
||||
|
||||
actionsCore.info("Nix was already installed, using existing install");
|
||||
return;
|
||||
}
|
||||
@@ -583,7 +639,6 @@ class NixInstallerAction extends DetSysAction {
|
||||
}
|
||||
}
|
||||
|
||||
// Normal just doing of the install
|
||||
actionsCore.startGroup("Installing Nix");
|
||||
const binaryPath = await this.fetchBinary();
|
||||
await this.executeInstall(binaryPath);
|
||||
@@ -592,7 +647,12 @@ class NixInstallerAction extends DetSysAction {
|
||||
if (this.forceDockerShim) {
|
||||
await this.spawnDockerShim();
|
||||
}
|
||||
|
||||
await this.setGithubPath();
|
||||
|
||||
if (this.determinate) {
|
||||
await this.flakehubLogin();
|
||||
}
|
||||
}
|
||||
|
||||
async spawnDockerShim(): Promise<void> {
|
||||
@@ -648,6 +708,67 @@ class NixInstallerAction extends DetSysAction {
|
||||
|
||||
{
|
||||
actionsCore.debug("Starting the Nix daemon through Docker...");
|
||||
|
||||
const candidateDirectories = [
|
||||
{
|
||||
dir: "/bin",
|
||||
readOnly: true,
|
||||
},
|
||||
{
|
||||
dir: "/etc",
|
||||
readOnly: true,
|
||||
},
|
||||
{
|
||||
dir: "/home",
|
||||
readOnly: true,
|
||||
},
|
||||
{
|
||||
dir: "/lib",
|
||||
readOnly: true,
|
||||
},
|
||||
{
|
||||
dir: "/lib64",
|
||||
readOnly: true,
|
||||
},
|
||||
{
|
||||
dir: "/tmp",
|
||||
readOnly: false,
|
||||
},
|
||||
{
|
||||
dir: "/usr",
|
||||
readOnly: true,
|
||||
},
|
||||
{
|
||||
dir: "/nix",
|
||||
readOnly: false,
|
||||
},
|
||||
];
|
||||
|
||||
const mountArguments = [];
|
||||
|
||||
for (const { dir, readOnly } of candidateDirectories) {
|
||||
try {
|
||||
await access(dir);
|
||||
actionsCore.debug(`Will mount ${dir} in the docker shim.`);
|
||||
mountArguments.push("--mount");
|
||||
mountArguments.push(
|
||||
`type=bind,src=${dir},dst=${dir}${readOnly ? ",readonly" : ""}`,
|
||||
);
|
||||
} catch {
|
||||
actionsCore.debug(
|
||||
`Not mounting ${dir} in the docker shim: it doesn't appear to exist.`,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const plausibleDeterminateOptions = [];
|
||||
const plausibleDeterminateArguments = [];
|
||||
if (this.determinate) {
|
||||
plausibleDeterminateOptions.push("--entrypoint");
|
||||
plausibleDeterminateOptions.push("/usr/local/bin/determinate-nixd");
|
||||
plausibleDeterminateArguments.push("daemon");
|
||||
}
|
||||
|
||||
this.recordEvent(EVENT_START_DOCKER_SHIM);
|
||||
const exitCode = await actionsExec.exec(
|
||||
"docker",
|
||||
@@ -659,25 +780,16 @@ class NixInstallerAction extends DetSysAction {
|
||||
"--network=host",
|
||||
"--userns=host",
|
||||
"--pid=host",
|
||||
"--mount",
|
||||
"type=bind,src=/bin,dst=/bin,readonly",
|
||||
"--mount",
|
||||
"type=bind,src=/lib,dst=/lib,readonly",
|
||||
"--mount",
|
||||
"type=bind,src=/home,dst=/home,readonly",
|
||||
"--mount",
|
||||
"type=bind,src=/tmp,dst=/tmp",
|
||||
"--mount",
|
||||
"type=bind,src=/nix,dst=/nix",
|
||||
"--mount",
|
||||
"type=bind,src=/etc,dst=/etc,readonly",
|
||||
"--restart",
|
||||
"always",
|
||||
"--init",
|
||||
"--name",
|
||||
`determinate-nix-shim-${this.getUniqueId()}-${randomUUID()}`,
|
||||
"determinate-nix-shim:latest",
|
||||
],
|
||||
]
|
||||
.concat(plausibleDeterminateOptions)
|
||||
.concat(mountArguments)
|
||||
.concat(["determinate-nix-shim:latest"])
|
||||
.concat(plausibleDeterminateArguments),
|
||||
{
|
||||
silent: true,
|
||||
listeners: {
|
||||
@@ -752,13 +864,19 @@ class NixInstallerAction extends DetSysAction {
|
||||
async setGithubPath(): Promise<void> {
|
||||
// Interim versions of the `nix-installer` crate may have already manipulated `$GITHUB_PATH`, as root even! Accessing that will be an error.
|
||||
try {
|
||||
const nixVarNixProfilePath = "/nix/var/nix/profiles/default/bin";
|
||||
const homeNixProfilePath = `${process.env["HOME"]}/.nix-profile/bin`;
|
||||
actionsCore.addPath(nixVarNixProfilePath);
|
||||
actionsCore.addPath(homeNixProfilePath);
|
||||
actionsCore.info(
|
||||
`Added \`${nixVarNixProfilePath}\` and \`${homeNixProfilePath}\` to \`$GITHUB_PATH\``,
|
||||
);
|
||||
const paths = [];
|
||||
|
||||
if (this.determinate) {
|
||||
paths.push("/usr/local/bin");
|
||||
}
|
||||
|
||||
paths.push("/nix/var/nix/profiles/default/bin");
|
||||
paths.push(`${process.env["HOME"]}/.nix-profile/bin`);
|
||||
|
||||
for (const p of paths) {
|
||||
actionsCore.addPath(p);
|
||||
actionsCore.debug(`Added \`${p}\` to \`$GITHUB_PATH\``);
|
||||
}
|
||||
} catch {
|
||||
actionsCore.info(
|
||||
"Skipping setting $GITHUB_PATH in action, the `nix-installer` crate seems to have done this already. From `nix-installer` version 0.11.0 and up, this step is done in the action. Prior to 0.11.0, this was only done in the `nix-installer` binary.",
|
||||
@@ -766,31 +884,23 @@ class NixInstallerAction extends DetSysAction {
|
||||
}
|
||||
}
|
||||
|
||||
async flakehubLogin(): Promise<string> {
|
||||
this.recordEvent(EVENT_LOGIN_TO_FLAKEHUB);
|
||||
const netrcPath = `${process.env["RUNNER_TEMP"]}/determinate-nix-installer-netrc`;
|
||||
|
||||
const jwt = await actionsCore.getIDToken("api.flakehub.com");
|
||||
|
||||
await writeFile(
|
||||
netrcPath,
|
||||
[
|
||||
`machine api.flakehub.com login flakehub password ${jwt}`,
|
||||
`machine flakehub.com login flakehub password ${jwt}`,
|
||||
].join("\n"),
|
||||
);
|
||||
|
||||
actionsCore.info("Logging in to FlakeHub.");
|
||||
|
||||
// the join followed by a match on ^... looks silly, but extra_config
|
||||
// could contain multi-line values
|
||||
if (this.extraConf?.join("\n").match(/^netrc-file/m)) {
|
||||
actionsCore.warning(
|
||||
"Logging in to FlakeHub conflicts with the Nix option `netrc-file`.",
|
||||
);
|
||||
async flakehubLogin(): Promise<void> {
|
||||
if (
|
||||
process.env["ACTIONS_ID_TOKEN_REQUEST_URL"] &&
|
||||
process.env["ACTIONS_ID_TOKEN_REQUEST_TOKEN"]
|
||||
) {
|
||||
actionsCore.startGroup("Logging in to FlakeHub");
|
||||
this.recordEvent(EVENT_LOGIN_TO_FLAKEHUB);
|
||||
try {
|
||||
await actionsExec.exec(`determinate-nixd`, ["login", "github-action"]);
|
||||
} catch (e: unknown) {
|
||||
actionsCore.warning(`FlakeHub Login failure: ${stringifyError(e)}`);
|
||||
this.recordEvent("flakehub-login:failure", {
|
||||
exception: stringifyError(e),
|
||||
});
|
||||
}
|
||||
actionsCore.endGroup();
|
||||
}
|
||||
|
||||
return netrcPath;
|
||||
}
|
||||
|
||||
async executeUninstall(): Promise<number> {
|
||||
@@ -932,63 +1042,14 @@ class NixInstallerAction extends DetSysAction {
|
||||
|
||||
async reportOverall(): Promise<void> {
|
||||
try {
|
||||
this.recordEvent(EVENT_CONCLUDE_WORKFLOW, {
|
||||
conclusion: await this.getWorkflowConclusion(),
|
||||
this.recordEvent(EVENT_CONCLUDE_JOB, {
|
||||
conclusion: this.jobConclusion ?? "unknown",
|
||||
});
|
||||
} catch (e) {
|
||||
actionsCore.debug(`Error submitting post-run diagnostics report: ${e}`);
|
||||
}
|
||||
}
|
||||
|
||||
private async getWorkflowConclusion(): Promise<
|
||||
undefined | WorkflowConclusion
|
||||
> {
|
||||
if (this.githubToken == null) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
try {
|
||||
const octokit = github.getOctokit(this.githubToken);
|
||||
const jobs = await octokit.paginate(
|
||||
octokit.rest.actions.listJobsForWorkflowRun,
|
||||
{
|
||||
owner: github.context.repo.owner,
|
||||
repo: github.context.repo.repo,
|
||||
/* eslint-disable camelcase */
|
||||
run_id: github.context.runId,
|
||||
},
|
||||
);
|
||||
|
||||
actionsCore.debug(`awaited jobs: ${jobs}`);
|
||||
const job = jobs
|
||||
.filter((candidate) => candidate.name === github.context.job)
|
||||
.at(0);
|
||||
if (job === undefined) {
|
||||
return "no-jobs";
|
||||
}
|
||||
|
||||
const outcomes = (job.steps ?? []).map((j) => j.conclusion ?? "unknown");
|
||||
|
||||
// Possible values: success, failure, cancelled, or skipped
|
||||
// from: https://docs.github.com/en/actions/learn-github-actions/contexts
|
||||
|
||||
if (outcomes.includes("failure")) {
|
||||
// Any failures fails the job
|
||||
return "failure";
|
||||
}
|
||||
if (outcomes.includes("cancelled")) {
|
||||
// Any cancellations cancels the job
|
||||
return "cancelled";
|
||||
}
|
||||
|
||||
// Assume success if no jobs failed or were canceled
|
||||
return "success";
|
||||
} catch (e) {
|
||||
actionsCore.debug(`Error determining final disposition: ${e}`);
|
||||
return "unavailable";
|
||||
}
|
||||
}
|
||||
|
||||
private get defaultPlanner(): string {
|
||||
if (this.isMacOS) {
|
||||
return "macos";
|
||||
|
||||
Reference in New Issue
Block a user