commit b4f88de7833767692412af68072064cf5dbdbbb0
parent ed64fca8cc2f1b2bd3e7415525ec8be4d597d139
Author: triesap <tyson@radroots.org>
Date: Thu, 12 Mar 2026 23:10:09 +0000
ci: harden nix workflows and supply chain
- pin every third-party workflow action to a full commit sha and add explicit least-privilege permissions for the nix cache lanes
- add a dedicated linux and macos nix flake check workflow and lint github workflow yaml through the flake checks with actionlint
- replace the hand-rolled flake lock updater with determinate systems update-flake-lock and expand nix-managed push filters for the sync and coverage lanes
- document workflow linting in the nix command surface and record public binary cache provisioning as the deferred infrastructure follow-up
Diffstat:
9 files changed, 127 insertions(+), 45 deletions(-)
diff --git a/.github/workflows/nix-flake-ci.yml b/.github/workflows/nix-flake-ci.yml
@@ -0,0 +1,37 @@
+name: nix-flake-ci
+
+on:
+ workflow_dispatch:
+ pull_request:
+ push:
+ branches:
+ - master
+
+permissions:
+ contents: read
+ id-token: write
+
+jobs:
+ flake-check:
+ strategy:
+ fail-fast: false
+ matrix:
+ runner:
+ - ubuntu-latest
+ - macos-latest
+ runs-on: ${{ matrix.runner }}
+ steps:
+ - name: checkout
+ uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
+
+ - name: install nix
+ uses: cachix/install-nix-action@1ca7d21a94afc7c957383a2d217460d980de4934
+ with:
+ extra_nix_config: |
+ experimental-features = nix-command flakes
+
+ - name: prime nix cache
+ uses: DeterminateSystems/magic-nix-cache-action@565684385bcd71bad329742eefe8d12f2e765b39
+
+ - name: run flake check
+ run: nix flake check
diff --git a/.github/workflows/publish-crates.yml b/.github/workflows/publish-crates.yml
@@ -18,6 +18,7 @@ on:
permissions:
contents: read
+ id-token: write
concurrency:
group: publish-crates
@@ -28,16 +29,16 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: checkout
- uses: actions/checkout@v4
+ uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
- name: install nix
- uses: cachix/install-nix-action@v31
+ uses: cachix/install-nix-action@1ca7d21a94afc7c957383a2d217460d980de4934
with:
extra_nix_config: |
experimental-features = nix-command flakes
- name: prime nix cache
- uses: DeterminateSystems/magic-nix-cache-action@main
+ uses: DeterminateSystems/magic-nix-cache-action@565684385bcd71bad329742eefe8d12f2e765b39
- name: verify workspace
run: nix run .#check
diff --git a/.github/workflows/release-preflight.yml b/.github/workflows/release-preflight.yml
@@ -3,21 +3,25 @@ name: release-preflight
on:
workflow_dispatch:
+permissions:
+ contents: read
+ id-token: write
+
jobs:
preflight:
runs-on: ubuntu-latest
steps:
- name: checkout
- uses: actions/checkout@v4
+ uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
- name: install nix
- uses: cachix/install-nix-action@v31
+ uses: cachix/install-nix-action@1ca7d21a94afc7c957383a2d217460d980de4934
with:
extra_nix_config: |
experimental-features = nix-command flakes
- name: prime nix cache
- uses: DeterminateSystems/magic-nix-cache-action@main
+ uses: DeterminateSystems/magic-nix-cache-action@565684385bcd71bad329742eefe8d12f2e765b39
- name: run repo guards
run: nix run .#guards
@@ -26,7 +30,7 @@ jobs:
run: nix run .#release-preflight
- name: upload release preflight artifacts
- uses: actions/upload-artifact@v4
+ uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02
with:
name: release-preflight
path: |
diff --git a/.github/workflows/sdk-contract-ci.yml b/.github/workflows/sdk-contract-ci.yml
@@ -6,27 +6,31 @@ on:
branches:
- master
+permissions:
+ contents: read
+ id-token: write
+
jobs:
contract:
runs-on: ubuntu-latest
steps:
- name: checkout
- uses: actions/checkout@v4
+ uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
- name: install nix
- uses: cachix/install-nix-action@v31
+ uses: cachix/install-nix-action@1ca7d21a94afc7c957383a2d217460d980de4934
with:
extra_nix_config: |
experimental-features = nix-command flakes
- name: prime nix cache
- uses: DeterminateSystems/magic-nix-cache-action@main
+ uses: DeterminateSystems/magic-nix-cache-action@565684385bcd71bad329742eefe8d12f2e765b39
- name: run contract lane
run: nix run .#contract
- name: upload export manifest
- uses: actions/upload-artifact@v4
+ uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02
with:
name: sdk-export-manifest
path: target/sdk-export-ci/ts/export-manifest.json
diff --git a/.github/workflows/sdk-core-sync-pr.yml b/.github/workflows/sdk-core-sync-pr.yml
@@ -6,6 +6,11 @@ on:
branches:
- master
paths:
+ - "flake.nix"
+ - "flake.lock"
+ - "treefmt.nix"
+ - "nix/**"
+ - "rust-toolchain.toml"
- "crates/core/**"
- "crates/types/**"
- "crates/events/**"
@@ -16,21 +21,25 @@ on:
- "contract/**"
- ".github/workflows/sdk-core-sync-pr.yml"
+permissions:
+ contents: read
+ id-token: write
+
jobs:
sync-models:
runs-on: ubuntu-latest
steps:
- name: checkout
- uses: actions/checkout@v4
+ uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
- name: install nix
- uses: cachix/install-nix-action@v31
+ uses: cachix/install-nix-action@1ca7d21a94afc7c957383a2d217460d980de4934
with:
extra_nix_config: |
experimental-features = nix-command flakes
- name: prime nix cache
- uses: DeterminateSystems/magic-nix-cache-action@main
+ uses: DeterminateSystems/magic-nix-cache-action@565684385bcd71bad329742eefe8d12f2e765b39
- name: run repo guards
run: nix run .#guards
@@ -67,14 +76,14 @@ jobs:
- name: upload sdk export artifact
if: steps.sync_token.outputs.configured == 'true'
- uses: actions/upload-artifact@v4
+ uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02
with:
name: sdk-export-ts-bundle
path: ${{ runner.temp }}/sdk-export/ts
- name: checkout sdk-typescript
if: steps.sync_token.outputs.configured == 'true'
- uses: actions/checkout@v4
+ uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
with:
repository: radrootslabs/sdk-typescript
ref: master
@@ -100,7 +109,7 @@ jobs:
- name: setup bun
if: steps.sync_token.outputs.configured == 'true'
- uses: oven-sh/setup-bun@v2
+ uses: oven-sh/setup-bun@ecf28ddc73e819eb6fa29df6b34ef8921c743461
with:
bun-version: 1.3.9
@@ -115,7 +124,7 @@ jobs:
- name: create pull request
if: steps.sync_token.outputs.configured == 'true'
- uses: peter-evans/create-pull-request@v7
+ uses: peter-evans/create-pull-request@271a8d0340265f705b14b6d32b9829c1cb33d45e
with:
token: ${{ secrets.RADROOTS_SDK_SYNC_TOKEN }}
path: sdk-typescript
diff --git a/.github/workflows/sdk-coverage-ci.yml b/.github/workflows/sdk-coverage-ci.yml
@@ -6,31 +6,40 @@ on:
branches:
- master
paths:
+ - "flake.nix"
+ - "flake.lock"
+ - "treefmt.nix"
+ - "nix/**"
+ - "rust-toolchain.toml"
- ".github/workflows/sdk-coverage-ci.yml"
- "crates/xtask/**"
- "crates/**"
+permissions:
+ contents: read
+ id-token: write
+
jobs:
coverage-report:
runs-on: ubuntu-latest
steps:
- name: checkout
- uses: actions/checkout@v4
+ uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
- name: install nix
- uses: cachix/install-nix-action@v31
+ uses: cachix/install-nix-action@1ca7d21a94afc7c957383a2d217460d980de4934
with:
extra_nix_config: |
experimental-features = nix-command flakes
- name: prime nix cache
- uses: DeterminateSystems/magic-nix-cache-action@main
+ uses: DeterminateSystems/magic-nix-cache-action@565684385bcd71bad329742eefe8d12f2e765b39
- name: run sdk coverage report set
run: nix run .#coverage-report
- name: upload sdk coverage reports
- uses: actions/upload-artifact@v4
+ uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02
with:
name: sdk-coverage-reports
path: |
diff --git a/.github/workflows/update-flake-lock.yml b/.github/workflows/update-flake-lock.yml
@@ -7,6 +7,8 @@ on:
permissions:
contents: write
+ id-token: write
+ issues: write
pull-requests: write
jobs:
@@ -14,27 +16,17 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: checkout
- uses: actions/checkout@v4
+ uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
- - name: install nix
- uses: cachix/install-nix-action@v31
- with:
- extra_nix_config: |
- experimental-features = nix-command flakes
-
- - name: prime nix cache
- uses: DeterminateSystems/magic-nix-cache-action@main
+ - name: install determinate nix
+ uses: DeterminateSystems/determinate-nix-action@131015bad844610e5e6300f8a143bf625d3e74f4
- name: update flake lock
- run: nix flake update
-
- - name: create pull request
- uses: peter-evans/create-pull-request@v7
+ uses: DeterminateSystems/update-flake-lock@834c491b2ece4de0bbd00d85214bb5e83b4da5c6
with:
branch: ci/update-flake-lock
- commit-message: "ci: update flake lock"
- title: "ci: update flake lock"
- body: |
- - refresh pinned flake inputs
- - update flake.lock with the latest upstream revisions
- - generated by the scheduled lock maintenance workflow
+ commit-msg: "ci: update flake lock"
+ pr-title: "ci: update flake lock"
+ pr-labels: |
+ dependencies
+ automated
diff --git a/docs/nix.md b/docs/nix.md
@@ -95,6 +95,7 @@ nix run .#publish-crates -- --dry-run
- Nix, shell, and TOML formatting through `treefmt`
- Rust formatting through `cargo fmt --check`
+- GitHub Actions workflow validation through `actionlint`
- pure cargo check/test derivations for the contract crate set
- repo guards that can run without cargo registry network access
@@ -120,3 +121,7 @@ nix run .#release-preflight
- Flakes only see tracked files when the source is treated as a git checkout. If Nix appears to miss a new file, `git add` it first.
- Do not put secrets in `flake.nix`.
- `publish-crates.sh` reads `CARGO_REGISTRY_TOKEN` or `CRATES_IO_TOKEN` from your runtime environment.
+
+## Deferred Infrastructure
+
+Public binary-cache support is intentionally deferred until repository infrastructure is ready to own it. The next infrastructure-backed follow-up is to provision a public cache, publish its trust key in `flake.nix`, and wire CI to write to it.
diff --git a/nix/checks.nix b/nix/checks.nix
@@ -1,22 +1,43 @@
{ common, pkgs }:
let
cargoFmt = common.craneLib.cargoFmt common.commonCraneArgs;
- cargoCheck = common.craneLib.cargoCheck (
+ cargoCheck = common.craneLib.mkCargoDerivation (
common.commonCraneArgs
// {
inherit (common) cargoArtifacts;
- cargoExtraArgs = common.sdkContractCargoArgs;
+ pname = "radroots-cargo-check";
+ doCheck = false;
+ buildPhaseCargoCommand = ''
+ cargo check ${common.sdkContractCargoArgs}
+ '';
+ installPhaseCommand = "mkdir -p $out";
}
);
- cargoTest = common.craneLib.cargoTest (
+ cargoTest = common.craneLib.mkCargoDerivation (
common.commonCraneArgs
// {
inherit (common) cargoArtifacts;
- cargoExtraArgs = common.sdkContractCargoArgs;
+ pname = "radroots-cargo-test";
+ doCheck = false;
+ buildPhaseCargoCommand = ''
+ cargo test ${common.sdkContractCargoArgs}
+ '';
+ installPhaseCommand = "mkdir -p $out";
}
);
+ actionlint = common.mkRepoCheck {
+ name = "actionlint";
+ runtimeInputs = [
+ pkgs.actionlint
+ pkgs.shellcheck
+ ];
+ command = ''
+ actionlint
+ '';
+ };
in
{
+ actionlint = actionlint;
cargo-fmt = cargoFmt;
cargo-check = cargoCheck;
cargo-test = cargoTest;