Compare commits
61 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| aa0e540080 | |||
| b6e4494ddc | |||
| fcf915473a | |||
| 36fb5b1a60 | |||
| c2a30cb3a8 | |||
| 3e4b225f86 | |||
| 4a754ab0c1 | |||
| 92148bb48b | |||
| 27719816fa | |||
| d8e7e8f433 | |||
| b66b36319c | |||
| 316ffaba87 | |||
| 430608d219 | |||
| efb202a03d | |||
| db0a13c605 | |||
| b38ad18dfd | |||
| 490cfee336 | |||
| f329e312da | |||
| a144448e6c | |||
| ef8a148080 | |||
| e02dcf858c | |||
| 9a59e15a74 | |||
| d96bc962e6 | |||
| 874a9842e1 | |||
| 1ae25535ec | |||
| d9137d7b28 | |||
| 95f009f8cb | |||
| 86cbc893b3 | |||
| 500e7f9345 | |||
| a4f499a84c | |||
| c39689c63e | |||
| 58e64ed13a | |||
| 1e3c5df315 | |||
| 4e167d57bb | |||
| ab0a9732c6 | |||
| e4fb5e65d8 | |||
| c786b79f19 | |||
| fcca85ded7 | |||
| 69b69b2791 | |||
| 4f7e5a32d2 | |||
| c5a866b6ab | |||
| 89b1f59ae9 | |||
| 86a5f59de1 | |||
| 64a1e1d1cb | |||
| 2fd3724578 | |||
| 45a18a6995 | |||
| d3ddf0223c | |||
| 786fff0690 | |||
| f161ab07ed | |||
| 61ce7897f4 | |||
| 44f3801e21 | |||
| cb6d4e86fa | |||
| e686131f84 | |||
| 2c3a2981f1 | |||
| 18b667a294 | |||
| 428f3c64a3 | |||
| 90bb610b90 | |||
| c723f3a885 | |||
| 41e0dcf215 | |||
| e455bc9d67 | |||
| b336b210d0 |
@@ -0,0 +1,74 @@
|
||||
{
|
||||
"plugins": ["@typescript-eslint"],
|
||||
"extends": ["plugin:github/recommended"],
|
||||
"parser": "@typescript-eslint/parser",
|
||||
"parserOptions": {
|
||||
"ecmaVersion": 9,
|
||||
"sourceType": "module",
|
||||
"project": "./tsconfig.json"
|
||||
},
|
||||
"settings": {
|
||||
"import/resolver": {
|
||||
"typescript": {}
|
||||
}
|
||||
},
|
||||
"rules": {
|
||||
"i18n-text/no-en": "off",
|
||||
"eslint-comments/no-use": "off",
|
||||
"import/no-namespace": "off",
|
||||
"no-unused-vars": "off",
|
||||
"@typescript-eslint/no-unused-vars": [
|
||||
"error",
|
||||
{
|
||||
"argsIgnorePattern": "^_"
|
||||
}
|
||||
],
|
||||
"@typescript-eslint/explicit-member-accessibility": [
|
||||
"error",
|
||||
{
|
||||
"accessibility": "no-public"
|
||||
}
|
||||
],
|
||||
"@typescript-eslint/no-base-to-string": "error",
|
||||
"@typescript-eslint/no-require-imports": "error",
|
||||
"@typescript-eslint/array-type": "error",
|
||||
"@typescript-eslint/await-thenable": "error",
|
||||
"@typescript-eslint/ban-ts-comment": "error",
|
||||
"camelcase": "error",
|
||||
"@typescript-eslint/consistent-type-assertions": "error",
|
||||
"@typescript-eslint/explicit-function-return-type": [
|
||||
"error",
|
||||
{
|
||||
"allowExpressions": true
|
||||
}
|
||||
],
|
||||
"@typescript-eslint/func-call-spacing": ["error", "never"],
|
||||
"@typescript-eslint/no-array-constructor": "error",
|
||||
"@typescript-eslint/no-empty-interface": "error",
|
||||
"@typescript-eslint/no-explicit-any": "error",
|
||||
"@typescript-eslint/no-floating-promises": "error",
|
||||
"@typescript-eslint/no-extraneous-class": "error",
|
||||
"@typescript-eslint/no-for-in-array": "error",
|
||||
"@typescript-eslint/no-inferrable-types": "error",
|
||||
"@typescript-eslint/no-misused-new": "error",
|
||||
"@typescript-eslint/no-namespace": "error",
|
||||
"@typescript-eslint/no-non-null-assertion": "warn",
|
||||
"@typescript-eslint/no-unnecessary-qualifier": "error",
|
||||
"@typescript-eslint/no-unnecessary-type-assertion": "error",
|
||||
"@typescript-eslint/no-useless-constructor": "error",
|
||||
"@typescript-eslint/no-var-requires": "error",
|
||||
"@typescript-eslint/prefer-for-of": "warn",
|
||||
"@typescript-eslint/prefer-function-type": "warn",
|
||||
"@typescript-eslint/prefer-includes": "error",
|
||||
"@typescript-eslint/prefer-string-starts-ends-with": "error",
|
||||
"@typescript-eslint/promise-function-async": "error",
|
||||
"@typescript-eslint/require-array-sort-compare": "error",
|
||||
"@typescript-eslint/restrict-plus-operands": "error",
|
||||
"@typescript-eslint/type-annotation-spacing": "error",
|
||||
"@typescript-eslint/unbound-method": "error"
|
||||
},
|
||||
"env": {
|
||||
"node": true,
|
||||
"es6": true
|
||||
}
|
||||
}
|
||||
@@ -7,9 +7,8 @@ EXPECTED_VERSION="${1}"
|
||||
|
||||
INSTALLED_NIX_VERSION_OUTPUT=$(nix --version)
|
||||
INSTALLED_NIX_VERSION=$(echo "${INSTALLED_NIX_VERSION_OUTPUT}" | awk '{print $NF}')
|
||||
EXPECTED_OUTPUT="nix (Nix) ${EXPECTED_VERSION}"
|
||||
|
||||
if [ "${INSTALLED_NIX_VERSION_OUTPUT}" != "${EXPECTED_OUTPUT}" ]; then
|
||||
if [ "${INSTALLED_NIX_VERSION}" != "${EXPECTED_VERSION}" ]; then
|
||||
echo "Nix version ${INSTALLED_NIX_VERSION} didn't match expected version ${EXPECTED_VERSION}"
|
||||
exit 1
|
||||
else
|
||||
|
||||
+24
-32
@@ -26,48 +26,44 @@ jobs:
|
||||
name: Check the dist/ folder is up to date
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@v6
|
||||
- uses: DeterminateSystems/nix-installer-action@main
|
||||
- uses: DeterminateSystems/flakehub-cache-action@main
|
||||
- name: pnpm install
|
||||
run: nix develop --command pnpm install
|
||||
- name: Check formatting
|
||||
run: nix develop --command pnpm run check-fmt
|
||||
- name: Link
|
||||
run: nix develop --command pnpm run lint
|
||||
- name: Test
|
||||
run: nix develop --command pnpm run test
|
||||
- name: npm install
|
||||
run: nix develop --command npm ci
|
||||
- name: prettier format
|
||||
run: nix develop --command npm run check-fmt
|
||||
- name: ESLint
|
||||
run: nix develop --command npm run lint
|
||||
- name: tsup build
|
||||
run: nix develop --command pnpm run build
|
||||
run: nix develop --command npm run build
|
||||
- name: ncc package
|
||||
run: nix develop --command pnpm run package
|
||||
run: nix develop --command npm run package
|
||||
- name: Git status
|
||||
run: git status --porcelain=v1
|
||||
- name: Ensure no staged changes
|
||||
run: git diff --exit-code
|
||||
|
||||
install-nix:
|
||||
name: "Test: ${{ matrix.runner }}${{ matrix.determinate && ' with determinate' || '' }}"
|
||||
name: "Test: ${{ matrix.system.nix-system }} on ${{ matrix.system.runner }}${{ matrix.determinate && ' with determinate' || '' }}"
|
||||
strategy:
|
||||
fail-fast: false
|
||||
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
|
||||
system:
|
||||
- {
|
||||
nix-system: x86_64-linux,
|
||||
runner: nscloud-ubuntu-22.04-amd64-4x16,
|
||||
}
|
||||
- { nix-system: aarch64-darwin, runner: macos-latest }
|
||||
determinate:
|
||||
- true
|
||||
- false
|
||||
runs-on: ${{ matrix.runner }}
|
||||
runs-on: ${{ matrix.system.runner }}
|
||||
permissions:
|
||||
contents: read
|
||||
id-token: write
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@v6
|
||||
- name: Install Nix
|
||||
uses: ./
|
||||
with:
|
||||
@@ -80,7 +76,7 @@ jobs:
|
||||
run: echo $PATH
|
||||
|
||||
- name: Render the devshell
|
||||
if: success() || failure()
|
||||
if: (success() || failure())
|
||||
run: |
|
||||
nix develop --command date
|
||||
|
||||
@@ -152,17 +148,13 @@ jobs:
|
||||
strategy:
|
||||
matrix:
|
||||
inputs:
|
||||
# https://github.com/DeterminateSystems/nix-installer/blob/v0.18.0
|
||||
# https://github.com/DeterminateSystems/nix-installer/blob/v3.11.3
|
||||
- key: url
|
||||
value: https://github.com/DeterminateSystems/nix-installer/releases/download/v0.18.0/nix-installer-x86_64-linux
|
||||
nix-version: "2.21.2"
|
||||
# https://github.com/DeterminateSystems/nix-installer/tree/7011c077ec491da410fbc39f68676b0908b9ce7e
|
||||
- key: revision
|
||||
value: 7011c077ec491da410fbc39f68676b0908b9ce7e
|
||||
nix-version: "2.19.2"
|
||||
value: https://github.com/DeterminateSystems/nix-installer/releases/download/v3.11.3/nix-installer-x86_64-linux
|
||||
nix-version: "2.31.2" # 3.11.3 is based on 2.31.2
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@v6
|
||||
- name: Install with alternative source-${{ matrix.inputs.key }}
|
||||
uses: ./
|
||||
with:
|
||||
@@ -175,7 +167,7 @@ jobs:
|
||||
name: Install Nix without an ID token
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@v6
|
||||
- uses: ./
|
||||
with:
|
||||
_internal-strict-mode: true
|
||||
|
||||
@@ -53,6 +53,9 @@ typings/
|
||||
# Optional npm cache directory
|
||||
.npm
|
||||
|
||||
# Optional eslint cache
|
||||
.eslintcache
|
||||
|
||||
# Optional REPL history
|
||||
.node_repl_history
|
||||
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
.direnv/
|
||||
dist/
|
||||
lib/
|
||||
node_modules/
|
||||
package-lock.json
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
{}
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
# Submitting Pull Requests
|
||||
|
||||
Run `pnpm install` to install necessary JS tools.
|
||||
Run `npm ci` to install necessary JS tools.
|
||||
|
||||
This action is based off https://github.com/actions/javascript-action. As part of your contributing flow you **must** run `npm run all` before we can merge.
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
# The Determinate Nix Installer Action
|
||||
|
||||
Based on the [Determinate Nix Installer](https://github.com/DeterminateSystems/nix-installer), responsible for over tens of thousands of Nix installs daily.
|
||||
The fast, friendly, and reliable GitHub Action to install Nix with Flakes.
|
||||
The fast, friendly, and reliable GitHub Action to install [Determinate Nix][det-nix] with [flakes].
|
||||
The Determinate Nix Installer Action is based on [Determinate Nix Installer][installer], which is responsible for tens of thousands of installs daily.
|
||||
|
||||
## Supports
|
||||
|
||||
- ✅ **Accelerated KVM** on open source projects and larger runners. See [GitHub's announcement](https://github.blog/changelog/2023-02-23-hardware-accelerated-android-virtualization-on-actions-windows-and-linux-larger-hosted-runners/) for more info.
|
||||
- ✅ Linux, x86_64, aarch64, and i686
|
||||
- ✅ macOS, x86_64 and aarch64
|
||||
- ✅ WSL2, x86_64 and aarch64
|
||||
- ✅ Linux (x86_64 and aarch64)
|
||||
- ✅ macOS (aarch64)
|
||||
- ✅ Windows Subsystem for Linux (WSL) (x86_64 and aarch64)
|
||||
- ✅ Containers
|
||||
- ✅ Valve's SteamOS
|
||||
- ✅ GitHub Enterprise Server
|
||||
@@ -27,14 +27,18 @@ jobs:
|
||||
name: Build
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@v6
|
||||
- uses: DeterminateSystems/nix-installer-action@main
|
||||
- run: nix build .
|
||||
```
|
||||
|
||||
> [!NOTE]
|
||||
> This Action installs [Determinate Nix][det-nix] by default.
|
||||
> You can, however, use it to install [upstream Nix](#installing-upstream-nix) until **January 1, 2026**.
|
||||
|
||||
### With FlakeHub
|
||||
|
||||
To fetch private flakes from FlakeHub and Nix builds from FlakeHub Cache, update the `permissions` block and use [`determinate-nix-action`][determinate-nix-action]:
|
||||
To fetch private flakes from FlakeHub and Nix builds from FlakeHub Cache, update the `permissions` block and use [`determinate-nix-action`][determinate-nix-action] instead of this Action:
|
||||
|
||||
```yaml
|
||||
on:
|
||||
@@ -50,7 +54,7 @@ jobs:
|
||||
id-token: "write"
|
||||
contents: "read"
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@v6
|
||||
- uses: DeterminateSystems/determinate-nix-action@v3
|
||||
- run: nix build .
|
||||
```
|
||||
@@ -59,8 +63,8 @@ See [`.github/workflows/ci.yml`](.github/workflows/ci.yml) for a full example.
|
||||
|
||||
### Pinning the version
|
||||
|
||||
This GitHub Action uses the most recent version of the Determinate Nix Installer, even when the Action itself is pinned.
|
||||
If you wish to pin your CI workflows to a specific version, use the [`determinate-nix-action`][determinate-nix-action].
|
||||
This GitHub Action uses the most recent version of Determinate Nix Installer, even when the Action itself is pinned.
|
||||
If you wish to pin your CI workflows to a specific Determinate Nix version, use the [`determinate-nix-action`][determinate-nix-action].
|
||||
That Action is updated and tagged for every Determinate release.
|
||||
|
||||
The `DeterminateSystems/determinate-nix-action@v3.5.2` reference, for example, always installs Determinate Nix v3.5.2.
|
||||
@@ -84,8 +88,8 @@ Differing from the upstream [Nix](https://github.com/NixOS/nix) installer script
|
||||
- the `nix-command` and `flakes` features are enabled
|
||||
- `bash-prompt-prefix` is set
|
||||
- `auto-optimise-store` is set to `true` (On Linux only)
|
||||
* `extra-nix-path` is set to `nixpkgs=flake:nixpkgs`
|
||||
* `max-jobs` is set to `auto`
|
||||
- `extra-nix-path` is set to `nixpkgs=flake:nixpkgs`
|
||||
- `max-jobs` is set to `auto`
|
||||
- KVM is enabled by default.
|
||||
- an installation receipt (for uninstalling) is stored at `/nix/receipt.json` as well as a copy of the install binary at `/nix/nix-installer`
|
||||
- `nix-channel --update` is not run, `~/.nix-channels` is not provisioned
|
||||
@@ -96,7 +100,7 @@ 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` |
|
||||
| `determinate` | Whether to install [Determinate Nix](https://determinate.systems/enterprise) and log in to FlakeHub for private Flakes and binary caches. | Boolean | `true` |
|
||||
| `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` | Deprecated. Implies `determinate`. | Boolean | `false` |
|
||||
@@ -128,15 +132,32 @@ Differing from the upstream [Nix](https://github.com/NixOS/nix) installer script
|
||||
| `reinstall` | Force a reinstall if an existing installation is detected (consider backing up `/nix/store`) | Boolean | `false` |
|
||||
| `start-daemon` | If the daemon should be started, requires `planner: linux-multi` | Boolean | `false` |
|
||||
| `trust-runner-user` | Whether to make the runner user trusted by the Nix daemon | Boolean | `true` |
|
||||
| `summarize` | Whether to add a build summary and timeline chart to the GitHub job summary | Boolean | `true` |
|
||||
| `diagnostic-endpoint` | Diagnostic endpoint url where the installer sends install [diagnostic reports](https://github.com/DeterminateSystems/nix-installer#diagnostics) to, to disable set this to an empty string | string | `https://install.determinate.systems/nix-installer/diagnostic` |
|
||||
| `proxy` | The proxy to use (if any), valid proxy bases are `https://$URL`, `http://$URL` and `socks5://$URL` | string | |
|
||||
| `ssl-cert-file` | An SSL cert to use (if any), used for fetching Nix and sets `NIX_SSL_CERT_FILE` for Nix | string | |
|
||||
|
||||
## Installing upstream Nix
|
||||
|
||||
Although Determinate Nix is the default, you can also use this Action to install [upstream Nix][upstream].
|
||||
Make sure to set `determinate: false` in the Action's configuration:
|
||||
|
||||
```yaml
|
||||
- uses: DeterminateSystems/nix-installer-action@main
|
||||
with:
|
||||
determinate: false
|
||||
```
|
||||
|
||||
This option will be available until **January 1, 2026**, at which point installing upstream Nix using this Action will no longer be possible.
|
||||
|
||||
[apfs]: https://en.wikipedia.org/wiki/Apple_File_System
|
||||
[backtrace]: https://doc.rust-lang.org/std/backtrace/index.html#environment-variables
|
||||
[dependabot-actions]: https://github.com/DeterminateSystems/determinate-nix-action?tab=readme-ov-file#-automate-updates-with-dependabot
|
||||
[det-nix]: https://docs.determinate.systems/determinate-nix
|
||||
[determinate-nix-action]: https://github.com/DeterminateSystems/determinate-nix-action
|
||||
[github token]: https://docs.github.com/en/actions/security-guides/automatic-token-authentication
|
||||
[installer]: https://github.com/DeterminateSystems/nix-installer
|
||||
[planner]: https://github.com/determinateSystems/nix-installer#usage
|
||||
[profile]: https://nixos.org/manual/nix/stable/package-management/profiles
|
||||
[tracing directives]: https://docs.rs/tracing-subscriber/latest/tracing_subscriber/filter/struct.EnvFilter.html#directives
|
||||
[upstream]: https://github.com/NixOS/nix
|
||||
|
||||
+5
-2
@@ -10,7 +10,7 @@ inputs:
|
||||
determinate:
|
||||
description: |
|
||||
Whether to install [Determinate Nix](https://determinate.systems/enterprise) and log in to FlakeHub for private Flakes and binary caches.
|
||||
default: false
|
||||
default: true
|
||||
extra-args:
|
||||
description: Extra args to pass to the planner (prefer using structured `with:` arguments unless using a custom planner!)
|
||||
required: false
|
||||
@@ -126,6 +126,9 @@ inputs:
|
||||
trust-runner-user:
|
||||
description: Whether to make the runner user trusted by the Nix daemon
|
||||
default: true
|
||||
summarize:
|
||||
description: Whether to add a build summary and timeline chart to the GitHub job summary
|
||||
default: true
|
||||
nix-installer-branch:
|
||||
description: (deprecated) The branch of `nix-installer` to use (conflicts with `nix-installer-tag`, `nix-installer-revision`, `nix-installer-pr`)
|
||||
required: false
|
||||
@@ -147,6 +150,6 @@ inputs:
|
||||
default: false
|
||||
|
||||
runs:
|
||||
using: "node20"
|
||||
using: "node24"
|
||||
main: "dist/index.js"
|
||||
post: "dist/index.js"
|
||||
|
||||
-148
@@ -1,148 +0,0 @@
|
||||
{
|
||||
"$schema": "https://biomejs.dev/schemas/1.9.4/schema.json",
|
||||
"vcs": { "enabled": true, "clientKind": "git", "useIgnoreFile": true },
|
||||
"files": {
|
||||
"ignoreUnknown": false,
|
||||
"ignore": ["dist"]
|
||||
},
|
||||
"formatter": {
|
||||
"enabled": true,
|
||||
"useEditorconfig": true,
|
||||
"formatWithErrors": false,
|
||||
"indentStyle": "space",
|
||||
"indentWidth": 2,
|
||||
"lineEnding": "lf",
|
||||
"lineWidth": 80,
|
||||
"attributePosition": "auto",
|
||||
"bracketSpacing": true
|
||||
},
|
||||
"organizeImports": { "enabled": true },
|
||||
"linter": {
|
||||
"enabled": true,
|
||||
"rules": {
|
||||
"recommended": false,
|
||||
"complexity": {
|
||||
"noExtraBooleanCast": "error",
|
||||
"noMultipleSpacesInRegularExpressionLiterals": "error",
|
||||
"noStaticOnlyClass": "error",
|
||||
"noUselessConstructor": "error",
|
||||
"noUselessStringConcat": "error",
|
||||
"noUselessTypeConstraint": "error"
|
||||
},
|
||||
"correctness": {
|
||||
"noConstAssign": "error",
|
||||
"noConstantCondition": "error",
|
||||
"noEmptyCharacterClassInRegex": "error",
|
||||
"noEmptyPattern": "error",
|
||||
"noGlobalObjectCalls": "error",
|
||||
"noInnerDeclarations": "error",
|
||||
"noInvalidConstructorSuper": "error",
|
||||
"noNewSymbol": "error",
|
||||
"noSelfAssign": "error",
|
||||
"noSwitchDeclarations": "error",
|
||||
"noUndeclaredVariables": "error",
|
||||
"noUnreachable": "error",
|
||||
"noUnreachableSuper": "error",
|
||||
"noUnsafeFinally": "error",
|
||||
"noUnusedLabels": "error",
|
||||
"noUnusedVariables": "error",
|
||||
"useArrayLiterals": "off",
|
||||
"useIsNan": "error",
|
||||
"useYield": "error"
|
||||
},
|
||||
"style": {
|
||||
"noArguments": "error",
|
||||
"noCommaOperator": "error",
|
||||
"noInferrableTypes": "error",
|
||||
"noNamespace": "error",
|
||||
"noNonNullAssertion": "warn",
|
||||
"noVar": "error",
|
||||
"useAsConstAssertion": "error",
|
||||
"useConsistentArrayType": "error",
|
||||
"useConst": "error",
|
||||
"useForOf": "warn",
|
||||
"useShorthandFunctionType": "warn",
|
||||
"useSingleVarDeclarator": "error",
|
||||
"useTemplate": "error"
|
||||
},
|
||||
"suspicious": {
|
||||
"noCatchAssign": "error",
|
||||
"noClassAssign": "error",
|
||||
"noCompareNegZero": "error",
|
||||
"noConsole": "error",
|
||||
"noControlCharactersInRegex": "error",
|
||||
"noDebugger": "error",
|
||||
"noDoubleEquals": "error",
|
||||
"noDuplicateCase": "error",
|
||||
"noDuplicateClassMembers": "error",
|
||||
"noDuplicateObjectKeys": "error",
|
||||
"noDuplicateParameters": "error",
|
||||
"noEmptyBlockStatements": "error",
|
||||
"noExplicitAny": "error",
|
||||
"noExtraNonNullAssertion": "error",
|
||||
"noFallthroughSwitchClause": "error",
|
||||
"noFunctionAssign": "error",
|
||||
"noGlobalAssign": "error",
|
||||
"noMisleadingInstantiator": "error",
|
||||
"noRedeclare": "error",
|
||||
"noSparseArray": "error",
|
||||
"noUnsafeDeclarationMerging": "error",
|
||||
"noUnsafeNegation": "error",
|
||||
"useNamespaceKeyword": "error",
|
||||
"useValidTypeof": "error"
|
||||
}
|
||||
}
|
||||
},
|
||||
"javascript": {
|
||||
"formatter": {
|
||||
"jsxQuoteStyle": "double",
|
||||
"quoteProperties": "asNeeded",
|
||||
"trailingCommas": "all",
|
||||
"semicolons": "always",
|
||||
"arrowParentheses": "always",
|
||||
"bracketSameLine": false,
|
||||
"quoteStyle": "double",
|
||||
"attributePosition": "auto",
|
||||
"bracketSpacing": true
|
||||
},
|
||||
"globals": ["exports"]
|
||||
},
|
||||
"overrides": [
|
||||
{
|
||||
"include": ["**/*.ts", "**/*.tsx", "**/*.mts", "**/*.cts"],
|
||||
"linter": {
|
||||
"rules": {
|
||||
"complexity": { "noWith": "off" },
|
||||
"correctness": {
|
||||
"noConstAssign": "off",
|
||||
"noGlobalObjectCalls": "off",
|
||||
"noInvalidBuiltinInstantiation": "off",
|
||||
"noInvalidConstructorSuper": "off",
|
||||
"noNewSymbol": "off",
|
||||
"noSetterReturn": "off",
|
||||
"noUndeclaredVariables": "off",
|
||||
"noUnreachable": "off",
|
||||
"noUnreachableSuper": "off"
|
||||
},
|
||||
"style": {
|
||||
"noArguments": "error",
|
||||
"noVar": "error",
|
||||
"useConst": "error",
|
||||
"useNamingConvention": "error"
|
||||
},
|
||||
"suspicious": {
|
||||
"noClassAssign": "off",
|
||||
"noDuplicateClassMembers": "off",
|
||||
"noDuplicateObjectKeys": "off",
|
||||
"noDuplicateParameters": "off",
|
||||
"noFunctionAssign": "off",
|
||||
"noImportAssign": "off",
|
||||
"noRedeclare": "off",
|
||||
"noUnsafeNegation": "off",
|
||||
"useGetterReturn": "off"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
+90329
-77221
File diff suppressed because one or more lines are too long
Generated
+5
-20
@@ -1,27 +1,13 @@
|
||||
{
|
||||
"nodes": {
|
||||
"flake-schemas": {
|
||||
"locked": {
|
||||
"lastModified": 1721999734,
|
||||
"narHash": "sha256-G5CxYeJVm4lcEtaO87LKzOsVnWeTcHGKbKxNamNWgOw=",
|
||||
"rev": "0a5c42297d870156d9c57d8f99e476b738dcd982",
|
||||
"revCount": 75,
|
||||
"type": "tarball",
|
||||
"url": "https://api.flakehub.com/f/pinned/DeterminateSystems/flake-schemas/0.1.5/0190ef2f-61e0-794b-ba14-e82f225e55e6/source.tar.gz"
|
||||
},
|
||||
"original": {
|
||||
"type": "tarball",
|
||||
"url": "https://flakehub.com/f/DeterminateSystems/flake-schemas/0.1"
|
||||
}
|
||||
},
|
||||
"nixpkgs": {
|
||||
"locked": {
|
||||
"lastModified": 1748460289,
|
||||
"narHash": "sha256-7doLyJBzCllvqX4gszYtmZUToxKvMUrg45EUWaUYmBg=",
|
||||
"rev": "96ec055edbe5ee227f28cdbc3f1ddf1df5965102",
|
||||
"revCount": 807377,
|
||||
"lastModified": 1777954456,
|
||||
"narHash": "sha256-hGdgeU2Nk87RAuZyYjyDjFL6LK7dAZN5RE9+hrDTkDU=",
|
||||
"rev": "549bd84d6279f9852cae6225e372cc67fb91a4c1",
|
||||
"revCount": 992384,
|
||||
"type": "tarball",
|
||||
"url": "https://api.flakehub.com/f/pinned/NixOS/nixpkgs/0.1.807377%2Brev-96ec055edbe5ee227f28cdbc3f1ddf1df5965102/01972133-94d2-786e-bfeb-34136c7f0b07/source.tar.gz"
|
||||
"url": "https://api.flakehub.com/f/pinned/NixOS/nixpkgs/0.1.992384%2Brev-549bd84d6279f9852cae6225e372cc67fb91a4c1/019df915-70b5-73a2-a5a4-63c620b45d9f/source.tar.gz"
|
||||
},
|
||||
"original": {
|
||||
"type": "tarball",
|
||||
@@ -30,7 +16,6 @@
|
||||
},
|
||||
"root": {
|
||||
"inputs": {
|
||||
"flake-schemas": "flake-schemas",
|
||||
"nixpkgs": "nixpkgs"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,30 +2,44 @@
|
||||
{
|
||||
description = "Development environment for the Nix Installer action for GitHub.";
|
||||
|
||||
inputs = {
|
||||
flake-schemas.url = "https://flakehub.com/f/DeterminateSystems/flake-schemas/0.1";
|
||||
nixpkgs.url = "https://flakehub.com/f/NixOS/nixpkgs/0.1";
|
||||
};
|
||||
inputs.nixpkgs.url = "https://flakehub.com/f/NixOS/nixpkgs/0.1";
|
||||
|
||||
outputs = { self, flake-schemas, nixpkgs }:
|
||||
outputs =
|
||||
{ self, ... }@inputs:
|
||||
let
|
||||
supportedSystems = [ "x86_64-linux" "aarch64-darwin" "aarch64-linux" "x86_64-darwin" ];
|
||||
forEachSupportedSystem = f: nixpkgs.lib.genAttrs supportedSystems (system: f {
|
||||
pkgs = import nixpkgs { inherit system; };
|
||||
});
|
||||
supportedSystems = [
|
||||
"x86_64-linux"
|
||||
"aarch64-darwin"
|
||||
];
|
||||
forEachSupportedSystem =
|
||||
f:
|
||||
inputs.nixpkgs.lib.genAttrs supportedSystems (
|
||||
system:
|
||||
f {
|
||||
inherit system;
|
||||
pkgs = import inputs.nixpkgs { inherit system; };
|
||||
}
|
||||
);
|
||||
in
|
||||
{
|
||||
schemas = flake-schemas.schemas;
|
||||
devShells = forEachSupportedSystem (
|
||||
{ pkgs, system }:
|
||||
{
|
||||
default = pkgs.mkShell {
|
||||
packages = with pkgs; [
|
||||
nodejs_latest
|
||||
self.formatter.${system}
|
||||
|
||||
devShells = forEachSupportedSystem ({ pkgs }: {
|
||||
default = pkgs.mkShell {
|
||||
packages = with pkgs; [
|
||||
nodejs_latest
|
||||
nodePackages_latest.pnpm
|
||||
biome
|
||||
nixpkgs-fmt
|
||||
];
|
||||
};
|
||||
});
|
||||
# Keep people from accidentally running pnpm
|
||||
(writeScriptBin "pnpm" ''
|
||||
echo "pnpm is no longer used in this repo; use npm instead"
|
||||
exit 1
|
||||
'')
|
||||
];
|
||||
};
|
||||
}
|
||||
);
|
||||
|
||||
formatter = forEachSupportedSystem ({ pkgs, ... }: pkgs.nixfmt);
|
||||
};
|
||||
}
|
||||
|
||||
Generated
+8097
File diff suppressed because it is too large
Load Diff
+21
-13
@@ -7,12 +7,12 @@
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"build": "tsup",
|
||||
"format": "biome format --write",
|
||||
"check-fmt": "biome format",
|
||||
"lint": "biome lint",
|
||||
"format": "prettier --write .",
|
||||
"check-fmt": "prettier --check .",
|
||||
"lint": "eslint src/**/*.ts",
|
||||
"package": "ncc build",
|
||||
"test": "vitest --watch false",
|
||||
"all": "pnpm run test && pnpm run format && pnpm run lint && pnpm run test && pnpm run build && pnpm run package"
|
||||
"all": "npm run test && npm run format && npm run lint && npm run build && npm run package"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
@@ -26,19 +26,27 @@
|
||||
},
|
||||
"homepage": "https://github.com/DeterminateSystems/nix-installer-action#readme",
|
||||
"dependencies": {
|
||||
"@actions/core": "^1.11.1",
|
||||
"@actions/exec": "^1.1.1",
|
||||
"@actions/github": "^6.0.1",
|
||||
"@actions/core": "^3.0.0",
|
||||
"@actions/exec": "^3.0.0",
|
||||
"@actions/github": "^9.0.0",
|
||||
"detsys-ts": "github:DeterminateSystems/detsys-ts",
|
||||
"got": "^14.4.7",
|
||||
"got": "^14.6.6",
|
||||
"string-argv": "^0.3.2",
|
||||
"vitest": "^3.2.0"
|
||||
"vitest": "^3.2.4"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^20.17.57",
|
||||
"@trivago/prettier-plugin-sort-imports": "^4.3.0",
|
||||
"@types/node": "^20.19.37",
|
||||
"@types/uuid": "^9.0.8",
|
||||
"@vercel/ncc": "^0.38.3",
|
||||
"tsup": "^8.5.0",
|
||||
"typescript": "^5.8.3"
|
||||
"@typescript-eslint/eslint-plugin": "^7.18.0",
|
||||
"@vercel/ncc": "^0.38.4",
|
||||
"eslint": "^8.57.1",
|
||||
"eslint-import-resolver-typescript": "^3.10.1",
|
||||
"eslint-plugin-github": "^4.10.2",
|
||||
"eslint-plugin-import": "^2.32.0",
|
||||
"eslint-plugin-prettier": "^5.5.5",
|
||||
"prettier": "^3.8.1",
|
||||
"tsup": "^8.5.1",
|
||||
"typescript": "^5.9.3"
|
||||
}
|
||||
}
|
||||
|
||||
Generated
-2559
File diff suppressed because it is too large
Load Diff
+2
-2
@@ -1,8 +1,8 @@
|
||||
import { parseEvents, getRecentEvents } from "./events.js";
|
||||
import { expect, test } from "vitest";
|
||||
import { getRecentEvents, parseEvents } from "./events.js";
|
||||
|
||||
// Handy test for locally making sure you can fetch recent events:
|
||||
// biome-ignore lint/correctness/noConstantCondition: testing
|
||||
// eslint-disable-next-line no-constant-condition
|
||||
if (false) {
|
||||
test("Parsing existing events", async () => {
|
||||
expect(await getRecentEvents(new Date(Date.now() - 1000000))).toStrictEqual(
|
||||
|
||||
+2
-2
@@ -1,6 +1,6 @@
|
||||
import got from "got";
|
||||
|
||||
export interface Event {
|
||||
export interface DEvent {
|
||||
v: string;
|
||||
c: string;
|
||||
drv: string;
|
||||
@@ -11,7 +11,7 @@ export interface Event {
|
||||
}
|
||||
|
||||
export interface ParsedEventsResult {
|
||||
readonly events: Event[];
|
||||
readonly events: DEvent[];
|
||||
readonly hasMismatches: boolean;
|
||||
}
|
||||
|
||||
|
||||
+10
-14
@@ -5,6 +5,8 @@ import {
|
||||
summarizeFailures,
|
||||
} from "./failuresummary.js";
|
||||
|
||||
/* eslint-disable @typescript-eslint/no-non-null-assertion */
|
||||
|
||||
test("Select for failure events", () => {
|
||||
const events = [
|
||||
{
|
||||
@@ -97,12 +99,10 @@ test("Summarize Failures", async () => {
|
||||
}
|
||||
};
|
||||
|
||||
// biome-ignore lint/style/noNonNullAssertion: testing
|
||||
const summary: FailureSummary = (await summarizeFailures(events, logMaker))!;
|
||||
|
||||
expect(
|
||||
summary.markdownLines.join("\n"),
|
||||
).toStrictEqual(`### Build error review :boom:
|
||||
expect(summary.markdownLines.join("\n"))
|
||||
.toStrictEqual(`### Build error review :boom:
|
||||
> [!NOTE]
|
||||
> 2 builds failed
|
||||
<details><summary>Failure log: <code>/nix/store/rz9hrpay90sjrid5hx3x8v606ji679xa-<strong>dep-1</strong>.drv</code></summary>
|
||||
@@ -150,9 +150,8 @@ test("Summarize Failures", async () => {
|
||||
</details>
|
||||
`);
|
||||
|
||||
expect(
|
||||
summary.logLines.join("\n"),
|
||||
).toStrictEqual(`\u001b[38;2;255;0;0mBuild logs from 2 failures
|
||||
expect(summary.logLines.join("\n"))
|
||||
.toStrictEqual(`\u001b[38;2;255;0;0mBuild logs from 2 failures
|
||||
The following build logs are also available in the Markdown summary:
|
||||
::group::Failed build: /nix/store/rz9hrpay90sjrid5hx3x8v606ji679xa-dep-1.drv
|
||||
/nix/store/rz9hrpay90sjrid5hx3x8v606ji679xa-dep-1.drv
|
||||
@@ -229,16 +228,14 @@ test("Omit some logs if there are too many", async () => {
|
||||
return `${drv}\n`.repeat(5).trimEnd();
|
||||
};
|
||||
|
||||
// biome-ignore lint/style/noNonNullAssertion: testing
|
||||
const summary: FailureSummary = (await summarizeFailures(
|
||||
events,
|
||||
logMaker,
|
||||
500,
|
||||
))!;
|
||||
|
||||
expect(
|
||||
summary.markdownLines.join("\n"),
|
||||
).toStrictEqual(`### Build error review :boom:
|
||||
expect(summary.markdownLines.join("\n"))
|
||||
.toStrictEqual(`### Build error review :boom:
|
||||
> [!NOTE]
|
||||
> 2 builds failed
|
||||
<details><summary>Failure log: <code>/nix/store/rz9hrpay90sjrid5hx3x8v606ji679xa-<strong>dep-1</strong>.drv</code></summary>
|
||||
@@ -257,9 +254,8 @@ test("Omit some logs if there are too many", async () => {
|
||||
> The full logs are available in the post-run phase of the Nix Installer Action.
|
||||
> * \`/nix/store/rz9hrpay90sjrid5hx3x8v606ji679xa-dep-3.drv\``);
|
||||
|
||||
expect(
|
||||
summary.logLines.join("\n"),
|
||||
).toStrictEqual(`\u001b[38;2;255;0;0mBuild logs from 2 failures
|
||||
expect(summary.logLines.join("\n"))
|
||||
.toStrictEqual(`\u001b[38;2;255;0;0mBuild logs from 2 failures
|
||||
The following build logs are also available in the Markdown summary:
|
||||
::group::Failed build: /nix/store/rz9hrpay90sjrid5hx3x8v606ji679xa-dep-1.drv
|
||||
/nix/store/rz9hrpay90sjrid5hx3x8v606ji679xa-dep-1.drv
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
import { stripVTControlCharacters } from "node:util";
|
||||
import { getExecOutput } from "@actions/exec";
|
||||
import { Event } from "./events.js";
|
||||
import { DEvent } from "./events.js";
|
||||
import { stripVTControlCharacters } from "node:util";
|
||||
|
||||
// CI summaries have a max length of "1024k" which I assume to be 1048576 bytes.
|
||||
// Generously, the mermaid doc is about 50,000 bytes.
|
||||
// Rounding it all down a bit further for wiggle room, that leaves lots of log space.
|
||||
const defaultMaxSummaryLength = 995_000;
|
||||
|
||||
export function getBuildFailures(events: Event[]): Event[] {
|
||||
return events.filter((event: Event): Boolean => {
|
||||
export function getBuildFailures(events: DEvent[]): DEvent[] {
|
||||
return events.filter((event: DEvent): Boolean => {
|
||||
return event.c === "BuildFailureResponseEventV1";
|
||||
});
|
||||
}
|
||||
@@ -19,7 +19,7 @@ export interface FailureSummary {
|
||||
}
|
||||
|
||||
export async function summarizeFailures(
|
||||
events: Event[],
|
||||
events: DEvent[],
|
||||
getLog: (drv: string) => Promise<string | undefined> = getLogFromNix,
|
||||
maxLength: number = defaultMaxSummaryLength,
|
||||
): Promise<FailureSummary | undefined> {
|
||||
|
||||
+121
-67
@@ -1,31 +1,34 @@
|
||||
import { SpawnOptions, spawn } from "node:child_process";
|
||||
import fs, { mkdirSync, openSync } from "node:fs";
|
||||
import { access, readFile, stat, writeFile } from "node:fs/promises";
|
||||
import { userInfo } from "node:os";
|
||||
import { join } from "node:path";
|
||||
import { setTimeout } from "node:timers/promises";
|
||||
import * as path from "path";
|
||||
import * as actionsCore from "@actions/core";
|
||||
import * as actionsExec from "@actions/exec";
|
||||
import * as github from "@actions/github";
|
||||
import { access, readFile, stat, writeFile } from "node:fs/promises";
|
||||
import { join } from "node:path";
|
||||
import fs, { mkdirSync, openSync } from "node:fs";
|
||||
import { userInfo } from "node:os";
|
||||
import stringArgv from "string-argv";
|
||||
import * as path from "path";
|
||||
import { DetSysAction, inputs, platform, stringifyError } from "detsys-ts";
|
||||
import got from "got";
|
||||
import stringArgv from "string-argv";
|
||||
import { annotateMismatches } from "./annotate.js";
|
||||
import { getRecentEvents } from "./events.js";
|
||||
import { summarizeFailures } from "./failuresummary.js";
|
||||
import { setTimeout } from "node:timers/promises";
|
||||
import { getFixHashes } from "./fixHashes.js";
|
||||
import { annotateMismatches } from "./annotate.js";
|
||||
import { DEvent, getRecentEvents } from "./events.js";
|
||||
import { makeMermaidReport } from "./mermaid.js";
|
||||
import { summarizeFailures } from "./failuresummary.js";
|
||||
import { SpawnOptions, spawn } from "node:child_process";
|
||||
|
||||
// Nix installation events
|
||||
const EVENT_INSTALL_NIX_FAILURE = "install_nix_failure";
|
||||
const EVENT_INSTALL_NIX_START = "install_nix_start";
|
||||
const EVENT_INSTALL_NIX_SUCCESS = "install_nix_start";
|
||||
const EVENT_INSTALL_NIX_SUCCESS = "install_nix_success";
|
||||
const EVENT_SETUP_KVM = "setup_kvm";
|
||||
const EVENT_UNINSTALL_NIX = "uninstall";
|
||||
|
||||
// FlakeHub events
|
||||
const EVENT_LOGIN_TO_FLAKEHUB = "login_to_flakehub";
|
||||
const EVENT_LOGIN_START = "flakehub-login:start";
|
||||
const EVENT_LOGIN_FAILURE = "flakehub-login:failure";
|
||||
const EVENT_LOGIN_SUCCESS = "flakehub-login:success";
|
||||
const EVENT_LOGIN_END = "flakehub-login:end";
|
||||
|
||||
// Other events
|
||||
const EVENT_CONCLUDE_JOB = "conclude_job";
|
||||
@@ -45,6 +48,7 @@ const FACT_SENT_SIGTERM = "sent_sigterm";
|
||||
|
||||
// Flags
|
||||
const FLAG_DETERMINATE = "--determinate";
|
||||
const FLAG_PREFER_UPSTREAM_NIX = "--prefer-upstream-nix";
|
||||
|
||||
// Pre/post state keys
|
||||
const STATE_DAEMONDIR = "DNI_DAEMONDIR";
|
||||
@@ -84,8 +88,23 @@ class NixInstallerAction extends DetSysAction {
|
||||
startDaemon: boolean;
|
||||
trustRunnerUser: boolean;
|
||||
runnerOs: string | undefined;
|
||||
summarize: boolean;
|
||||
|
||||
constructor() {
|
||||
if (platform.getArchOs() === "X64-macOS") {
|
||||
// Holy guacamole this is ugly
|
||||
actionsCore.error(
|
||||
"Determinate Nix Installer no longer supports macOS on Intel. Please migrate to Apple Silicon, and use Nix's built-in Rosetta support to build for Intel. See: https://github.com/DeterminateSystems/nix-src/issues/224",
|
||||
);
|
||||
const sourceTag = inputs.getStringOrUndefined("source-tag");
|
||||
if (sourceTag === undefined) {
|
||||
actionsCore.notice(
|
||||
"Pinning the installer tag to v3.12.2 (the last version to support Intel Macs) as a temporary fallback.",
|
||||
);
|
||||
process.env["INPUT_SOURCE-TAG"] = "v3.12.2";
|
||||
}
|
||||
}
|
||||
|
||||
super({
|
||||
name: "nix-installer",
|
||||
fetchStyle: "nix-style",
|
||||
@@ -134,30 +153,33 @@ class NixInstallerAction extends DetSysAction {
|
||||
this.reinstall = inputs.getBool("reinstall");
|
||||
this.startDaemon = inputs.getBool("start-daemon");
|
||||
this.trustRunnerUser = inputs.getBool("trust-runner-user");
|
||||
this.summarize = inputs.getBool("summarize");
|
||||
this.runnerOs = process.env["RUNNER_OS"];
|
||||
}
|
||||
|
||||
async main(): Promise<void> {
|
||||
actionsCore.saveState(STATE_START_DATETIME, new Date().toISOString());
|
||||
await this.scienceDebugFly();
|
||||
await this.detectAndForceNoSystemd();
|
||||
await this.install();
|
||||
actionsCore.saveState(STATE_START_DATETIME, new Date().toISOString());
|
||||
}
|
||||
|
||||
async post(): Promise<void> {
|
||||
await this.annotateMismatches();
|
||||
try {
|
||||
await this.summarizeExecution();
|
||||
} catch (err: unknown) {
|
||||
this.recordEvent("summarize-execution:error", {
|
||||
exception: stringifyError(err),
|
||||
});
|
||||
if (this.summarize) {
|
||||
try {
|
||||
await this.summarizeExecution();
|
||||
} catch (err: unknown) {
|
||||
this.recordEvent("summarize-execution:error", {
|
||||
exception: stringifyError(err),
|
||||
});
|
||||
}
|
||||
}
|
||||
await this.cleanupNoSystemd();
|
||||
await this.reportOverall();
|
||||
}
|
||||
|
||||
private get isMacOs(): boolean {
|
||||
private get isMacOS(): boolean {
|
||||
return this.runnerOs === "macOS";
|
||||
}
|
||||
|
||||
@@ -194,22 +216,17 @@ class NixInstallerAction extends DetSysAction {
|
||||
});
|
||||
|
||||
this.recordEvent("debug-probe-urls:response", {
|
||||
// biome-ignore lint/style/useNamingConvention: Posthog JSON
|
||||
debug_probe_urls_ip: resp.ip,
|
||||
// biome-ignore lint/style/useNamingConvention: Posthog JSON
|
||||
debug_probe_urls_ok: resp.ok,
|
||||
// biome-ignore lint/style/useNamingConvention: Posthog JSON
|
||||
debug_probe_urls_status_code: resp.statusCode,
|
||||
// biome-ignore lint/style/useNamingConvention: Posthog JSON
|
||||
debug_probe_urls_body: resp.body,
|
||||
// biome-ignore lint/style/useNamingConvention: Posthog JSON
|
||||
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", {
|
||||
// biome-ignore lint/style/useNamingConvention: Posthog JSON
|
||||
debug_probe_urls_exception: stringifyError(e),
|
||||
debug_probe_urls_exception: stringifyError(e), // eslint-disable-line camelcase
|
||||
});
|
||||
}
|
||||
} catch (err: unknown) {
|
||||
@@ -287,7 +304,7 @@ class NixInstallerAction extends DetSysAction {
|
||||
}
|
||||
|
||||
if (this.nixBuildUserBase !== null) {
|
||||
executionEnv.NIX_INSTALLER_NIX_BUILD_USER_ID_BASE = `${this.nixBuildUserCount}`;
|
||||
executionEnv.NIX_INSTALLER_NIX_BUILD_USER_ID_BASE = `${this.nixBuildUserBase}`;
|
||||
}
|
||||
|
||||
if (this.nixPackageUrl !== null) {
|
||||
@@ -307,14 +324,14 @@ class NixInstallerAction extends DetSysAction {
|
||||
|
||||
// TODO: Error if the user uses these on not-MacOS
|
||||
if (this.macEncrypt !== null) {
|
||||
if (!this.isMacOs) {
|
||||
if (!this.isMacOS) {
|
||||
throw new Error("`mac-encrypt` while `$RUNNER_OS` was not `macOS`");
|
||||
}
|
||||
executionEnv.NIX_INSTALLER_ENCRYPT = this.macEncrypt;
|
||||
}
|
||||
|
||||
if (this.macCaseSensitive !== null) {
|
||||
if (!this.isMacOs) {
|
||||
if (!this.isMacOS) {
|
||||
throw new Error(
|
||||
"`mac-case-sensitive` while `$RUNNER_OS` was not `macOS`",
|
||||
);
|
||||
@@ -323,7 +340,7 @@ class NixInstallerAction extends DetSysAction {
|
||||
}
|
||||
|
||||
if (this.macVolumeLabel !== null) {
|
||||
if (!this.isMacOs) {
|
||||
if (!this.isMacOS) {
|
||||
throw new Error(
|
||||
"`mac-volume-label` while `$RUNNER_OS` was not `macOS`",
|
||||
);
|
||||
@@ -332,7 +349,7 @@ class NixInstallerAction extends DetSysAction {
|
||||
}
|
||||
|
||||
if (this.macRootDisk !== null) {
|
||||
if (!this.isMacOs) {
|
||||
if (!this.isMacOS) {
|
||||
throw new Error("`mac-root-disk` while `$RUNNER_OS` was not `macOS`");
|
||||
}
|
||||
executionEnv.NIX_INSTALLER_ROOT_DISK = this.macRootDisk;
|
||||
@@ -348,7 +365,7 @@ class NixInstallerAction extends DetSysAction {
|
||||
|
||||
// TODO: Error if the user uses these on MacOS
|
||||
if (this.init !== null) {
|
||||
if (this.isMacOs) {
|
||||
if (this.isMacOS) {
|
||||
throw new Error(
|
||||
"`init` is not a valid option when `$RUNNER_OS` is `macOS`",
|
||||
);
|
||||
@@ -379,6 +396,7 @@ class NixInstallerAction extends DetSysAction {
|
||||
}
|
||||
extraConf += "\n";
|
||||
}
|
||||
extraConf += `build-provenance-tags = ${JSON.stringify(this.getBuildProvenanceTags())}\n`;
|
||||
if (this.extraConf !== null && this.extraConf.length !== 0) {
|
||||
extraConf += this.extraConf.join("\n");
|
||||
extraConf += "\n";
|
||||
@@ -404,6 +422,26 @@ class NixInstallerAction extends DetSysAction {
|
||||
return executionEnv;
|
||||
}
|
||||
|
||||
getBuildProvenanceTags(): Record<string, string> {
|
||||
const mapping = {
|
||||
GITHUB_WORKFLOW_REF: "github_workflow_ref",
|
||||
GITHUB_WORKFLOW_SHA: "github_workflow_sha",
|
||||
GITHUB_SHA: "github_sha",
|
||||
GITHUB_RUN_ATTEMPT: "github_run_attempt",
|
||||
GITHUB_RUN_ID: "github_run_id",
|
||||
GITHUB_RUN_NUMBER: "github_run_number",
|
||||
GITHUB_JOB: "github_job",
|
||||
GITHUB_REF: "github_ref",
|
||||
GITHUB_REPOSITORY: "github_repository",
|
||||
GITHUB_SERVER_URL: "github_server_url",
|
||||
};
|
||||
|
||||
const tags = Object.entries(mapping)
|
||||
.map(([sourceKey, targetKey]) => [targetKey, process.env[sourceKey]])
|
||||
.filter(([_, value]) => value !== undefined);
|
||||
return { ...Object.fromEntries(tags), builder: "github-actions" };
|
||||
}
|
||||
|
||||
private get installerArgs(): string[] {
|
||||
const args = ["install"];
|
||||
|
||||
@@ -434,6 +472,8 @@ class NixInstallerAction extends DetSysAction {
|
||||
if (this.extraArgs && !this.extraArgs.includes(FLAG_DETERMINATE)) {
|
||||
args.push(FLAG_DETERMINATE);
|
||||
}
|
||||
} else {
|
||||
args.push(FLAG_PREFER_UPSTREAM_NIX);
|
||||
}
|
||||
|
||||
return args;
|
||||
@@ -601,6 +641,7 @@ class NixInstallerAction extends DetSysAction {
|
||||
await stat(socketPath);
|
||||
return true;
|
||||
} catch (error: unknown) {
|
||||
// eslint-disable-next-line no-undef
|
||||
if ((error as NodeJS.ErrnoException).code === "ENOENT") {
|
||||
actionsCore.debug(`Socket '${socketPath}' does not exist yet`);
|
||||
return false;
|
||||
@@ -620,6 +661,8 @@ class NixInstallerAction extends DetSysAction {
|
||||
const startDate = new Date(actionsCore.getState(STATE_START_DATETIME));
|
||||
const { events, hasMismatches } = await getRecentEvents(startDate);
|
||||
|
||||
await this.reportPassFailCount(events);
|
||||
|
||||
const mermaidSummary = makeMermaidReport(events);
|
||||
const failureSummary = await summarizeFailures(events);
|
||||
|
||||
@@ -670,6 +713,29 @@ class NixInstallerAction extends DetSysAction {
|
||||
}
|
||||
}
|
||||
|
||||
async reportPassFailCount(events: DEvent[]): Promise<void> {
|
||||
let built = 0;
|
||||
let failed = 0;
|
||||
let unknown = 0;
|
||||
|
||||
for (const event of events) {
|
||||
switch (event.c) {
|
||||
case "BuiltPathResponseEventV1":
|
||||
built++;
|
||||
break;
|
||||
case "BuildFailureResponseEventV1":
|
||||
failed++;
|
||||
break;
|
||||
default:
|
||||
unknown++;
|
||||
}
|
||||
}
|
||||
|
||||
this.addFact("nix_builds_succeeded", built);
|
||||
this.addFact("nix_builds_failed", failed);
|
||||
this.addFact("nix_builds_unknown_event", unknown);
|
||||
}
|
||||
|
||||
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 {
|
||||
@@ -694,6 +760,8 @@ class NixInstallerAction extends DetSysAction {
|
||||
}
|
||||
|
||||
async flakehubLogin(): Promise<void> {
|
||||
this.recordEvent(EVENT_LOGIN_START);
|
||||
|
||||
const canLogin =
|
||||
process.env["ACTIONS_ID_TOKEN_REQUEST_URL"] &&
|
||||
process.env["ACTIONS_ID_TOKEN_REQUEST_TOKEN"];
|
||||
@@ -704,14 +772,20 @@ class NixInstallerAction extends DetSysAction {
|
||||
const head = pr?.head?.repo?.full_name;
|
||||
|
||||
if (pr && base !== head) {
|
||||
this.recordEvent(EVENT_LOGIN_FAILURE, { reason: "fork" });
|
||||
this.recordEvent(EVENT_LOGIN_END);
|
||||
|
||||
actionsCore.info(
|
||||
`Not logging in to FlakeHub: GitHub Actions does not allow OIDC authentication from forked repositories ("${head}" is not the same repository as "${base}").`,
|
||||
`FlakeHub is disabled because this is a fork. GitHub Actions does not allow OIDC authentication from forked repositories ("${head}" is not from the same repository as "${base}").`,
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
this.recordEvent(EVENT_LOGIN_FAILURE, { reason: "not-configured" });
|
||||
this.recordEvent(EVENT_LOGIN_END);
|
||||
|
||||
actionsCore.info(
|
||||
`Not logging in to FlakeHub: GitHub Actions has not provided OIDC token endpoints; please make sure that \`id-token: write\` and \`contents: read\` are set for this step's (or job's) permissions.`,
|
||||
"FlakeHub is disabled because the workflow is misconfigured. Please make sure that `id-token: write` and `contents: read` are set for this step's (or job's) permissions so that GitHub Actions provides OIDC token endpoints.",
|
||||
);
|
||||
actionsCore.info(
|
||||
`For more information, see https://docs.determinate.systems/guides/github-actions/#nix-installer-action`,
|
||||
@@ -720,15 +794,18 @@ class NixInstallerAction extends DetSysAction {
|
||||
}
|
||||
|
||||
actionsCore.startGroup("Logging in to FlakeHub");
|
||||
this.recordEvent(EVENT_LOGIN_TO_FLAKEHUB);
|
||||
try {
|
||||
await actionsExec.exec(`determinate-nixd`, ["login", "github-action"]);
|
||||
this.recordEvent(EVENT_LOGIN_SUCCESS);
|
||||
} catch (e: unknown) {
|
||||
actionsCore.warning(`FlakeHub Login failure: ${stringifyError(e)}`);
|
||||
this.recordEvent("flakehub-login:failure", {
|
||||
this.recordEvent(EVENT_LOGIN_FAILURE, {
|
||||
reason: "failed",
|
||||
exception: stringifyError(e),
|
||||
});
|
||||
}
|
||||
|
||||
this.recordEvent(EVENT_LOGIN_END);
|
||||
actionsCore.endGroup();
|
||||
}
|
||||
|
||||
@@ -739,7 +816,6 @@ class NixInstallerAction extends DetSysAction {
|
||||
["uninstall"],
|
||||
{
|
||||
env: {
|
||||
// biome-ignore lint/style/useNamingConvention: environment variable
|
||||
NIX_INSTALLER_NO_CONFIRM: "true",
|
||||
...process.env, // To get $PATH, etc
|
||||
},
|
||||
@@ -955,7 +1031,7 @@ class NixInstallerAction extends DetSysAction {
|
||||
}
|
||||
|
||||
private get defaultPlanner(): string {
|
||||
if (this.isMacOs) {
|
||||
if (this.isMacOS) {
|
||||
return "macos";
|
||||
} else if (this.isLinux) {
|
||||
return "linux";
|
||||
@@ -1001,51 +1077,29 @@ class NixInstallerAction extends DetSysAction {
|
||||
}
|
||||
}
|
||||
|
||||
// All env vars are strings, no fanciness here.
|
||||
type ExecuteEnvironment = {
|
||||
// biome-ignore lint/style/useNamingConvention: environment variable
|
||||
// All env vars are strings, no fanciness here.
|
||||
RUST_BACKTRACE?: string;
|
||||
// biome-ignore lint/style/useNamingConvention: environment variable
|
||||
NIX_INSTALLER_MODIFY_PROFILE?: string;
|
||||
// biome-ignore lint/style/useNamingConvention: environment variable
|
||||
NIX_INSTALLER_NIX_BUILD_GROUP_NAME?: string;
|
||||
// biome-ignore lint/style/useNamingConvention: environment variable
|
||||
NIX_INSTALLER_NIX_BUILD_GROUP_ID?: string;
|
||||
// biome-ignore lint/style/useNamingConvention: environment variable
|
||||
NIX_INSTALLER_NIX_BUILD_USER_PREFIX?: string;
|
||||
// biome-ignore lint/style/useNamingConvention: environment variable
|
||||
NIX_INSTALLER_NIX_BUILD_USER_COUNT?: string;
|
||||
// biome-ignore lint/style/useNamingConvention: environment variable
|
||||
NIX_INSTALLER_NIX_BUILD_USER_ID_BASE?: string;
|
||||
// biome-ignore lint/style/useNamingConvention: environment variable
|
||||
NIX_INSTALLER_NIX_PACKAGE_URL?: string;
|
||||
// biome-ignore lint/style/useNamingConvention: environment variable
|
||||
NIX_INSTALLER_PROXY?: string;
|
||||
// biome-ignore lint/style/useNamingConvention: environment variable
|
||||
NIX_INSTALLER_SSL_CERT_FILE?: string;
|
||||
// biome-ignore lint/style/useNamingConvention: environment variable
|
||||
NIX_INSTALLER_DIAGNOSTIC_ENDPOINT?: string;
|
||||
// biome-ignore lint/style/useNamingConvention: environment variable
|
||||
NIX_INSTALLER_DIAGNOSTIC_ATTRIBUTION?: string;
|
||||
// biome-ignore lint/style/useNamingConvention: environment variable
|
||||
NIX_INSTALLER_ENCRYPT?: string;
|
||||
// biome-ignore lint/style/useNamingConvention: environment variable
|
||||
NIX_INSTALLER_CASE_SENSITIVE?: string;
|
||||
// biome-ignore lint/style/useNamingConvention: environment variable
|
||||
NIX_INSTALLER_VOLUME_LABEL?: string;
|
||||
// biome-ignore lint/style/useNamingConvention: environment variable
|
||||
NIX_INSTALLER_ROOT_DISK?: string;
|
||||
// biome-ignore lint/style/useNamingConvention: environment variable
|
||||
NIX_INSTALLER_INIT?: string;
|
||||
// biome-ignore lint/style/useNamingConvention: environment variable
|
||||
NIX_INSTALLER_START_DAEMON?: string;
|
||||
// biome-ignore lint/style/useNamingConvention: environment variable
|
||||
NIX_INSTALLER_NO_CONFIRM?: string;
|
||||
// biome-ignore lint/style/useNamingConvention: environment variable
|
||||
NIX_INSTALLER_EXTRA_CONF?: string;
|
||||
// biome-ignore lint/style/useNamingConvention: environment variable
|
||||
NIX_INSTALLER_LOG_DIRECTIVES?: string;
|
||||
// biome-ignore lint/style/useNamingConvention: environment variable
|
||||
NIX_INSTALLER_LOGGER?: string;
|
||||
};
|
||||
|
||||
|
||||
+6
-24
@@ -1,9 +1,11 @@
|
||||
import { mermaidify, makeMermaidReport } from "./mermaid.js";
|
||||
import { DEvent, parseEvents } from "./events.js";
|
||||
import { expect, test } from "vitest";
|
||||
import { Event, parseEvents } from "./events.js";
|
||||
import { makeMermaidReport, mermaidify } from "./mermaid.js";
|
||||
|
||||
function generateEvents(count: number): Event[] {
|
||||
const events: Event[] = [];
|
||||
/* eslint-disable @typescript-eslint/no-non-null-assertion */
|
||||
|
||||
function generateEvents(count: number): DEvent[] {
|
||||
const events: DEvent[] = [];
|
||||
|
||||
for (let i = 0; i < count; i++) {
|
||||
events.push({
|
||||
@@ -27,21 +29,16 @@ test("Empty event list returns no report", () => {
|
||||
});
|
||||
|
||||
test("Create a very large report doc and make sure it is small enough", () => {
|
||||
// biome-ignore lint/style/noNonNullAssertion: testing
|
||||
const report = makeMermaidReport(generateEvents(2500))!;
|
||||
|
||||
// Assert the `.drv` suffix was pruned (1 reference = the NOTE at the end)
|
||||
// biome-ignore lint/style/noNonNullAssertion: testing
|
||||
expect(report.match(/\.drv/g)!.length).equals(1);
|
||||
|
||||
// Assert the `/nix/store` prefix was pruned (1 reference = the NOTE at the end)
|
||||
// biome-ignore lint/style/noNonNullAssertion: testing
|
||||
expect(report.match(/\/nix\/store\//g)!.length).equals(1);
|
||||
|
||||
// Assert that some events were pruned
|
||||
// biome-ignore lint/style/noNonNullAssertion: testing
|
||||
expect(report.match(/dep-/g)!.length).lessThan(2500);
|
||||
// biome-ignore lint/style/noNonNullAssertion: testing
|
||||
expect(report.match(/dep-/g)!.length).greaterThan(1500);
|
||||
|
||||
expect(report).toContain("suffix, and builds that took less than ");
|
||||
@@ -52,19 +49,15 @@ test("Create a very large report doc and make sure it is small enough", () => {
|
||||
|
||||
test("Create a medium large report doc and make sure it is small enough", () => {
|
||||
const eventCount = 675;
|
||||
// biome-ignore lint/style/noNonNullAssertion: testing
|
||||
const report = makeMermaidReport(generateEvents(eventCount))!;
|
||||
|
||||
// Assert the `.drv` suffix was pruned (1 reference = the NOTE at the end)
|
||||
// biome-ignore lint/style/noNonNullAssertion: testing
|
||||
expect(report.match(/\.drv/g)!.length).equals(1);
|
||||
|
||||
// Assert the `/nix/store` prefix was pruned (1 reference = the NOTE at the end)
|
||||
// biome-ignore lint/style/noNonNullAssertion: testing
|
||||
expect(report.match(/\/nix\/store\//g)!.length).equals(1);
|
||||
|
||||
// Assert that no lines were pruned
|
||||
// biome-ignore lint/style/noNonNullAssertion: testing
|
||||
expect(report.match(/dep-/g)!.length).toStrictEqual(eventCount);
|
||||
|
||||
expect(report).toContain(
|
||||
@@ -76,15 +69,12 @@ test("Create a medium large report doc and make sure it is small enough", () =>
|
||||
});
|
||||
|
||||
test("Create a small report doc and make sure it isn't pruned", () => {
|
||||
// biome-ignore lint/style/noNonNullAssertion: testing
|
||||
const report = makeMermaidReport(generateEvents(100))!;
|
||||
|
||||
// Assert 100 events have the `.drv` suffix, ie: were not pruned
|
||||
// biome-ignore lint/style/noNonNullAssertion: testing
|
||||
expect(report.match(/\.drv/g)!.length).equals(100);
|
||||
|
||||
// Assert 100 events have the `.drv` suffix, ie: were not pruned
|
||||
// biome-ignore lint/style/noNonNullAssertion: testing
|
||||
expect(report.match(/\/nix\/store\//g)!.length).equals(100);
|
||||
|
||||
expect(report.length).lessThan(50000);
|
||||
@@ -93,13 +83,9 @@ test("Create a small report doc and make sure it isn't pruned", () => {
|
||||
test("Generate a really big report and shrink it", () => {
|
||||
const events = generateEvents(1000);
|
||||
|
||||
// biome-ignore lint/style/noNonNullAssertion: testing
|
||||
const originalLength = mermaidify(events, -1)!.length;
|
||||
// biome-ignore lint/style/noNonNullAssertion: testing
|
||||
const limitedLengthZero = mermaidify(events, 0)!.length;
|
||||
// biome-ignore lint/style/noNonNullAssertion: testing
|
||||
const limitedLengthOne = mermaidify(events, 1)!.length;
|
||||
// biome-ignore lint/style/noNonNullAssertion: testing
|
||||
const limitedLengthTwo = mermaidify(events, 2)!.length;
|
||||
|
||||
expect(originalLength).greaterThan(limitedLengthZero);
|
||||
@@ -187,13 +173,9 @@ hash-mismatch-md5-base16 (4s):crit, 3, 4s
|
||||
test("Generate a really big report and shrink it", () => {
|
||||
const events = generateEvents(1000);
|
||||
|
||||
// biome-ignore lint/style/noNonNullAssertion: testing
|
||||
const originalLength = mermaidify(events, -1)!.length;
|
||||
// biome-ignore lint/style/noNonNullAssertion: testing
|
||||
const limitedLengthZero = mermaidify(events, 0)!.length;
|
||||
// biome-ignore lint/style/noNonNullAssertion: testing
|
||||
const limitedLengthOne = mermaidify(events, 1)!.length;
|
||||
// biome-ignore lint/style/noNonNullAssertion: testing
|
||||
const limitedLengthTwo = mermaidify(events, 2)!.length;
|
||||
|
||||
expect(originalLength).greaterThan(limitedLengthZero);
|
||||
|
||||
+3
-3
@@ -1,7 +1,7 @@
|
||||
import { Event } from "./events.js";
|
||||
import { DEvent } from "./events.js";
|
||||
import { truncateDerivation } from "./util.js";
|
||||
|
||||
export function makeMermaidReport(events: Event[]): string | undefined {
|
||||
export function makeMermaidReport(events: DEvent[]): string | undefined {
|
||||
// # 50k is the max: https://github.com/mermaid-js/mermaid/blob/c269dc822c528e1afbde34e18a1cad03d972d4fe/src/defaultConfig.js#L55
|
||||
const maxLength = 49900;
|
||||
let mermaid = "";
|
||||
@@ -42,7 +42,7 @@ export function makeMermaidReport(events: Event[]): string | undefined {
|
||||
}
|
||||
|
||||
export function mermaidify(
|
||||
allEvents: Event[],
|
||||
allEvents: DEvent[],
|
||||
pruneLevel: number,
|
||||
): string | undefined {
|
||||
const events = allEvents
|
||||
|
||||
+1
-1
@@ -5,7 +5,7 @@ export default defineConfig({
|
||||
name,
|
||||
entry: ["src/index.ts"],
|
||||
format: ["esm"],
|
||||
target: "node20",
|
||||
target: "node24",
|
||||
bundle: true,
|
||||
splitting: false,
|
||||
clean: true,
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
export default {
|
||||
test: {
|
||||
exclude: ["**/node_modules/**", "**/.direnv/**"],
|
||||
},
|
||||
};
|
||||
Reference in New Issue
Block a user