ci: always run the workflow on PRs, guard the heavy steps
CI / flake (pull_request) Successful in 3m24s
CI / flake (pull_request) Successful in 3m24s
This job is a required status check on main. The workflow was path-filtered to **.nix/flake.lock/ci.yaml, so a PR touching none of those (e.g. a .renovaterc.json-only change) skipped the workflow entirely, leaving the required check pending forever and making the PR unmergeable. Run the workflow on every PR so the check is always reported, but keep a 'detect' step that diffs the PR against its base and runs nix flake check and the per-host evals only when a .nix file, flake.lock, or this workflow changed. When nothing Nix-relevant changed the heavy steps skip and the job still passes, so the required check stays green-reportable without burning a full evaluation on unrelated changes. Checkout uses fetch-depth: 0 so the diff has the base history.
This commit is contained in:
@@ -2,18 +2,18 @@
|
|||||||
# plus an explicit per-host evaluation pass for granular output.
|
# plus an explicit per-host evaluation pass for granular output.
|
||||||
name: CI
|
name: CI
|
||||||
|
|
||||||
|
# Deliberately no `paths:` filter. This job is a required status check on main,
|
||||||
|
# and a path-filtered workflow is *skipped* (never runs) for PRs that touch no
|
||||||
|
# matching file -- which leaves the required check pending forever and blocks the
|
||||||
|
# merge (e.g. a .renovaterc.json-only change). So the workflow always runs and
|
||||||
|
# always reports. To avoid burning a full Nix evaluation on changes that can't
|
||||||
|
# affect it, the "detect" step below diffs the PR and the heavy steps run only
|
||||||
|
# when a .nix file, flake.lock, or this workflow changed; otherwise they skip and
|
||||||
|
# the job still passes. The required check is therefore always green-reportable.
|
||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
branches: [main]
|
branches: [main]
|
||||||
paths:
|
|
||||||
- "**.nix"
|
|
||||||
- "flake.lock"
|
|
||||||
- ".gitea/workflows/ci.yaml"
|
|
||||||
pull_request:
|
pull_request:
|
||||||
paths:
|
|
||||||
- "**.nix"
|
|
||||||
- "flake.lock"
|
|
||||||
- ".gitea/workflows/ci.yaml"
|
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
flake:
|
flake:
|
||||||
@@ -21,8 +21,39 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6
|
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6
|
||||||
|
with:
|
||||||
|
# Full history so the detect step can diff the PR against its base.
|
||||||
|
fetch-depth: 0
|
||||||
|
|
||||||
|
# Decide whether the Nix steps need to run. On a pull_request, diff the PR
|
||||||
|
# against its base and look for files that can affect the flake: any .nix,
|
||||||
|
# the lockfile, or this workflow. On any other event (push to main) always
|
||||||
|
# run. The job itself always succeeds, so the required status check is
|
||||||
|
# reported even when the heavy steps are skipped.
|
||||||
|
- name: Detect Nix-relevant changes
|
||||||
|
id: detect
|
||||||
|
run: |
|
||||||
|
set -euo pipefail
|
||||||
|
if [ "${{ github.event_name }}" != "pull_request" ]; then
|
||||||
|
echo "Event ${{ github.event_name }}: running full checks."
|
||||||
|
echo "run=true" >> "$GITHUB_OUTPUT"
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
base='${{ github.event.pull_request.base.sha }}'
|
||||||
|
head='${{ github.event.pull_request.head.sha }}'
|
||||||
|
changed=$(git diff --name-only "$base...$head")
|
||||||
|
echo "Changed files:"
|
||||||
|
echo "$changed"
|
||||||
|
if echo "$changed" | grep -Eq '(\.nix$|^flake\.lock$|^\.gitea/workflows/ci\.yaml$)'; then
|
||||||
|
echo "Nix-relevant changes found: running checks."
|
||||||
|
echo "run=true" >> "$GITHUB_OUTPUT"
|
||||||
|
else
|
||||||
|
echo "No Nix-relevant changes: skipping checks (job still passes)."
|
||||||
|
echo "run=false" >> "$GITHUB_OUTPUT"
|
||||||
|
fi
|
||||||
|
|
||||||
- name: Install Nix
|
- name: Install Nix
|
||||||
|
if: steps.detect.outputs.run == 'true'
|
||||||
uses: cachix/install-nix-action@8aa03977d8d733052d78f4e008a241fd1dbf36b3 # v31
|
uses: cachix/install-nix-action@8aa03977d8d733052d78f4e008a241fd1dbf36b3 # v31
|
||||||
with:
|
with:
|
||||||
extra_nix_config: |
|
extra_nix_config: |
|
||||||
@@ -34,6 +65,7 @@ jobs:
|
|||||||
# Runs every flake check: treefmt formatting, deadnix, statix, and the
|
# Runs every flake check: treefmt formatting, deadnix, statix, and the
|
||||||
# pre-commit hooks (so a --no-verify commit can't ship unlinted).
|
# pre-commit hooks (so a --no-verify commit can't ship unlinted).
|
||||||
- name: Flake check
|
- name: Flake check
|
||||||
|
if: steps.detect.outputs.run == 'true'
|
||||||
run: nix flake check --print-build-logs
|
run: nix flake check --print-build-logs
|
||||||
|
|
||||||
# Evaluate (not build) each host's toplevel so eval errors fail CI cheaply.
|
# Evaluate (not build) each host's toplevel so eval errors fail CI cheaply.
|
||||||
@@ -44,6 +76,7 @@ jobs:
|
|||||||
# nixos/darwinConfigurations) rather than hard-coded, so adding or removing
|
# nixos/darwinConfigurations) rather than hard-coded, so adding or removing
|
||||||
# a host needs no change to this workflow.
|
# a host needs no change to this workflow.
|
||||||
- name: Evaluate NixOS host configurations
|
- name: Evaluate NixOS host configurations
|
||||||
|
if: steps.detect.outputs.run == 'true'
|
||||||
run: |
|
run: |
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
hosts=$(nix eval --raw '.#nixosConfigurations' \
|
hosts=$(nix eval --raw '.#nixosConfigurations' \
|
||||||
@@ -56,6 +89,7 @@ jobs:
|
|||||||
done
|
done
|
||||||
|
|
||||||
- name: Evaluate Darwin host configurations
|
- name: Evaluate Darwin host configurations
|
||||||
|
if: steps.detect.outputs.run == 'true'
|
||||||
run: |
|
run: |
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
hosts=$(nix eval --raw '.#darwinConfigurations' \
|
hosts=$(nix eval --raw '.#darwinConfigurations' \
|
||||||
|
|||||||
Reference in New Issue
Block a user