From 9efc78a4e464abedfd27350d77adf26fddd25226 Mon Sep 17 00:00:00 2001 From: Antoine du Hamel Date: Fri, 10 Jul 2026 09:37:01 +0200 Subject: [PATCH 1/3] tools: add workflow to compare Nix changes If a change breaks e.g. the benchmark workflow, it might be not obvious to detect as we typically do not run any benchmark when bumping the nixpkgs pin. The added workflows will verify that all derivations can be built on all platforms, and report the list of changes. Signed-off-by: Antoine du Hamel --- .github/workflows/linters.yml | 20 ---- .github/workflows/nix-changes-comment.yml | 94 +++++++++++++++ .github/workflows/nix-changes.yml | 140 ++++++++++++++++++++++ 3 files changed, 234 insertions(+), 20 deletions(-) create mode 100644 .github/workflows/nix-changes-comment.yml create mode 100644 .github/workflows/nix-changes.yml diff --git a/.github/workflows/linters.yml b/.github/workflows/linters.yml index 4e0fdab245e1f9..a7641a3c04d73d 100644 --- a/.github/workflows/linters.yml +++ b/.github/workflows/linters.yml @@ -132,26 +132,6 @@ jobs: NODE=$(command -v node) make lint-md env: NODE_RELEASED_VERSIONS: ${{ steps.get-released-versions.outputs.NODE_RELEASED_VERSIONS }} - lint-nix: - if: github.event.pull_request.draft == false - runs-on: ubuntu-slim - steps: - - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 - with: - persist-credentials: false - sparse-checkout: '*.nix' - sparse-checkout-cone-mode: false - - uses: cachix/install-nix-action@8aa03977d8d733052d78f4e008a241fd1dbf36b3 # v31.10.6 - - name: Lint Nix files - run: | - nix-shell -I nixpkgs=./tools/nix/pkgs.nix -p 'nixfmt-tree' --run ' - treefmt --quiet --ci - ' && EXIT_CODE="$?" || EXIT_CODE="$?" - if [ "$EXIT_CODE" != "0" ] - then - git --no-pager diff || true - exit "$EXIT_CODE" - fi lint-py: if: github.event.pull_request.draft == false diff --git a/.github/workflows/nix-changes-comment.yml b/.github/workflows/nix-changes-comment.yml new file mode 100644 index 00000000000000..953b919b1fe3a7 --- /dev/null +++ b/.github/workflows/nix-changes-comment.yml @@ -0,0 +1,94 @@ +# This action requires the following secrets to be set on the repository: +# GH_USER_TOKEN: GitHub user token, to be used by ncu and to push changes +name: Comment on PR on Nix changes + +on: + workflow_run: + workflows: [Nix files edited] + types: [completed] + +permissions: {} + +jobs: + aggregate-results: + if: ${{ github.event.workflow_run.conclusion == 'success' }} + name: Aggregate results + runs-on: ubuntu-slim + permissions: + pull-requests: write + steps: + - name: Download artefacts + uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 + with: + run-id: ${{ github.event.workflow_run.id }} + # Using privileged token to be able to download file from a different workflow + github-token: ${{ secrets.GH_USER_TOKEN }} + + - name: Fetch PR data + id: pr-data + run: | + mv requisites-*/* . + ls + echo "NUMBER=$(grep -E '^[0-9]+$' pr_number.txt || true)" >> "$GITHUB_OUTPUT" + + - name: Aggregate results + if: ${{ steps.pr-data.outputs.NUMBER }} + run: | + set -x + > requisites-before.list + > requisites-after.list + TABLE=$( + echo '| Platform | Number of requisites | Proportion of new derivations |' + echo '| :-: | -: | -: |' + TOTAL_BEFORE=0 + TOTAL_AFTER=0 + TOTAL_CHANGED=0 + QUOTE='`' + for PLATFORM in x86_64-linux aarch64-linux x86_64-darwin aarch64-darwin; do + BEFORE=$(wc -l < "requisites-${PLATFORM}-before.list") + TOTAL_BEFORE=$(($TOTAL_BEFORE + $BEFORE)) + AFTER=$(wc -l < "requisites-${PLATFORM}-after.list") + TOTAL_AFTER=$(($TOTAL_AFTER + $AFTER)) + DIFF="_no changes_" + [ "$BEFORE" = "$AFTER" ] || DIFF="**$([ "$AFTER" < "$BEFORE" ] || echo '+')$(($AFTER - $BEFORE))**" + CHANGED=$(git diff --no-index "requisites-${PLATFORM}-before.list" "requisites-${PLATFORM}-after.list" | grep -c '^+[^+]') + TOTAL_CHANGED=$(($TOTAL_CHANGED + $CHANGED)) + PERCENT=100 + [ "$CHANGED" = "$AFTER" ] || { + PERMILLE=$((1000 * $CHANGED / $AFTER)) + PERCENT="$((PERMILLE / 10)).$((PERMILLE % 10))" + } + echo "| ${QUOTE}${PLATFORM}${QUOTE} | $BEFORE -> $AFTER => $DIFF | $CHANGED / $AFTER = $PERCENT% |" + awk '{ print $0 " ('"$PLATFORM"')" }' "requisites-${PLATFORM}-before.list" >> requisites-before.list + awk '{ print $0 " ('"$PLATFORM"')" }' "requisites-${PLATFORM}-after.list" >> requisites-after.list + done + + DIFF="_no changes_" + [ "$TOTAL_BEFORE" = "$TOTAL_AFTER" ] || DIFF="**$([ "$TOTAL_AFTER" < "$TOTAL_BEFORE" ] || echo '+')$(($TOTAL_AFTER - $TOTAL_BEFORE))**" + PERCENT=100 + [ "$TOTAL_CHANGED" = "$TOTAL_AFTER" ] || { + PERMILLE=$((1000 * $TOTAL_CHANGED / $TOTAL_AFTER)) + PERCENT="$((PERMILLE / 10)).$((PERMILLE % 10))" + } + echo "| **Total** | $TOTAL_BEFORE -> $TOTAL_AFTER => $DIFF | $TOTAL_CHANGED / $TOTAL_AFTER = $PERCENT% |" + ) + sort -k1.45 requisites-before.list > requisites-before.sort + sort -k1.45 requisites-after.list > requisites-after.sort + if git diff -U0 --no-color --no-index requisites-before.sort requisites-after.sort > requisites.diff; then + echo 'No changes detected.' + else + { + echo "$TABLE" + echo + echo '
Changelog' + echo + echo '```diff' + tail -n +5 requisites.diff + echo '```' + echo + echo '
' + } | gh pr comment -R "$GITHUB_REPOSITORY" "$PR_NUMBER" -F - + fi + env: + GH_TOKEN: ${{ github.token }} + PR_NUMBER: ${{ steps.pr-data.outputs.NUMBER }} diff --git a/.github/workflows/nix-changes.yml b/.github/workflows/nix-changes.yml new file mode 100644 index 00000000000000..ddf19260359027 --- /dev/null +++ b/.github/workflows/nix-changes.yml @@ -0,0 +1,140 @@ +# This action uses the following secrets: +# CACHIX_AUTH_TOKEN: Write access to nodejs.cachix.org – without it, the cache is read-only. +name: Nix files edited + +on: + push: + branches: + - main + - canary + - v[0-9]+.x-staging + - v[0-9]+.x + paths: + - '**.nix' + - .github/workflows/nix-changes.yml + pull_request: + paths: + - '**.nix' + - .github/workflows/nix-changes.yml + types: [opened, synchronize, reopened, ready_for_review] + +concurrency: + group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} + cancel-in-progress: true + +permissions: + contents: read + +jobs: + diff: + if: github.event.pull_request.draft == false + strategy: + fail-fast: false + matrix: + include: + - runner: ubuntu-24.04 + system: x86_64-linux + - runner: ubuntu-24.04-arm + system: aarch64-linux + - runner: macos-15-intel + system: x86_64-darwin + - runner: macos-latest + system: aarch64-darwin + name: '${{ matrix.system }}: dependencies diff' + runs-on: ${{ matrix.runner }} + steps: + - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + with: + fetch-depth: 2 + persist-credentials: false + sparse-checkout: '*.nix' + sparse-checkout-cone-mode: false + + - uses: cachix/install-nix-action@8aa03977d8d733052d78f4e008a241fd1dbf36b3 # v31.10.6 + with: + extra_nix_config: sandbox = true + + - uses: cachix/cachix-action@5f2d7c5294214f71b873db4b969586b980625e71 # v17 + with: + authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} + name: nodejs + + - name: Compute requisites after change + shell: bash # See https://docs.github.com/en/actions/writing-workflows/workflow-syntax-for-github-actions#exit-codes-and-error-action-preference, we want the pipefail option. + run: | + nix-store --query --references "$( + nix-instantiate -I "nixpkgs=./tools/nix/pkgs.nix" shell.nix \ + --arg devTools " + (import ./tools/nix/devTools.nix {}) + ++ builtins.attrValues ( + { inherit (import {}) nixfmt-tree sccache; } + // import ./tools/nix/openssl-matrix.nix {} + )")" \ + | xargs nix-store --realise \ + | xargs nix-store --query --requisites \ + | sort -k1.45 \ + > requisites-${{ matrix.system }}-after.list + + - name: Compute requisites before change + shell: bash # See https://docs.github.com/en/actions/writing-workflows/workflow-syntax-for-github-actions#exit-codes-and-error-action-preference, we want the pipefail option. + run: | + git reset HEAD^ --hard + nix-store --query --references "$( + nix-instantiate -I "nixpkgs=./tools/nix/pkgs.nix" shell.nix \ + --arg devTools " + (import ./tools/nix/devTools.nix {}) + ++ builtins.attrValues ( + { inherit (import {}) nixfmt-tree sccache; } + // import ./tools/nix/openssl-matrix.nix {} + )")" \ + | xargs nix-store --realise \ + | xargs nix-store --query --requisites \ + | sort -k1.45 \ + > requisites-${{ matrix.system }}-before.list + + - name: Output diff + run: | + { + if diff_output="$(git diff -U0 --no-color --no-index requisites-${{ matrix.system }}-before.list requisites-${{ matrix.system }}-after.list)"; then + echo 'No changes detected.' + else + echo '```diff' + echo "$diff_output" | tail -n +5 + echo '```' + fi + } >> "$GITHUB_STEP_SUMMARY" + + - name: Store PR number + if: ${{ github.event.pull_request && matrix.system == 'x86_64-linux' }} + run: echo "${{ github.event.pull_request.number }}" > pr_number.txt + + - name: Upload requisites lists + if: ${{ github.event.pull_request }} + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 + with: + name: requisites-${{ matrix.system }} + path: | + pr_number.* + requisites-${{ matrix.system }}-before.list + requisites-${{ matrix.system }}-after.list + + lint-nix: + if: github.event.pull_request.draft == false + runs-on: ubuntu-slim + steps: + - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + with: + persist-credentials: false + sparse-checkout: '*.nix' + sparse-checkout-cone-mode: false + - uses: cachix/install-nix-action@8aa03977d8d733052d78f4e008a241fd1dbf36b3 # v31.10.6 + - name: Lint Nix files + run: | + nix-shell -I nixpkgs=./tools/nix/pkgs.nix -p 'nixfmt-tree' --run ' + treefmt --quiet --ci + ' && EXIT_CODE="$?" || EXIT_CODE="$?" + if [ "$EXIT_CODE" != "0" ] + then + git --no-pager diff || true + exit "$EXIT_CODE" + fi From f2d506555577e52372aab66f0709e7157dc0a84a Mon Sep 17 00:00:00 2001 From: Antoine du Hamel Date: Sat, 11 Jul 2026 11:41:29 +0200 Subject: [PATCH 2/3] fixup! tools: add workflow to compare Nix changes Do not attempt to add comment on non-PR runs, i.e. when pushing to `main`. --- .github/workflows/nix-changes-comment.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/nix-changes-comment.yml b/.github/workflows/nix-changes-comment.yml index 953b919b1fe3a7..df051cca494352 100644 --- a/.github/workflows/nix-changes-comment.yml +++ b/.github/workflows/nix-changes-comment.yml @@ -11,7 +11,7 @@ permissions: {} jobs: aggregate-results: - if: ${{ github.event.workflow_run.conclusion == 'success' }} + if: ${{ github.event.workflow_run.conclusion == 'success' && github.event.workflow_run.event == 'pull_request' }} name: Aggregate results runs-on: ubuntu-slim permissions: From b37ded93991a9293c8901e10866bfff457834dd1 Mon Sep 17 00:00:00 2001 From: Antoine du Hamel Date: Sat, 11 Jul 2026 13:55:51 +0200 Subject: [PATCH 3/3] fixup! tools: add workflow to compare Nix changes --- .github/workflows/nix-changes-comment.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/nix-changes-comment.yml b/.github/workflows/nix-changes-comment.yml index df051cca494352..db96ff4a09caea 100644 --- a/.github/workflows/nix-changes-comment.yml +++ b/.github/workflows/nix-changes-comment.yml @@ -29,6 +29,10 @@ jobs: run: | mv requisites-*/* . ls + if grep -nvHE '^/nix/store/[0-9a-df-np-sv-z]{32}-[A-Za-z0-9?=._+-]+$' requisites-*.list; then + echo 'Unexpected line format in requisites list; refusing to process.' >&2 + exit 1 + fi echo "NUMBER=$(grep -E '^[0-9]+$' pr_number.txt || true)" >> "$GITHUB_OUTPUT" - name: Aggregate results