Skip to content

Commit a1997d2

Browse files
committed
ci: add detect changes, to reduce build time for pull requests
1 parent c05a62c commit a1997d2

1 file changed

Lines changed: 89 additions & 2 deletions

File tree

.github/workflows/ci.yaml

Lines changed: 89 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -81,13 +81,100 @@ jobs:
8181
- name: Check flake
8282
run: nix -L flake check --no-build
8383

84+
detect-changes:
85+
name: Detect changed tests with nix-diff
86+
runs-on: ubuntu-24.04
87+
outputs:
88+
matrix: ${{ steps.generate-matrix.outputs.matrix }}
89+
steps:
90+
- uses: DeterminateSystems/nix-installer-action@c5a866b6ab867e88becbed4467b93592bce69f8a # v21
91+
- uses: DeterminateSystems/magic-nix-cache-action@565684385bcd71bad329742eefe8d12f2e765b39 # v13
92+
with:
93+
use-flakehub: false
94+
95+
- name: Set revision variables
96+
id: set-revs
97+
run: |
98+
if [[ "${{ github.event_name }}" == "pull_request" ]]; then
99+
echo "REV1=${{ github.base_ref }}" >> "$GITHUB_ENV"
100+
echo "REV2=${{ github.head_ref }}" >> "$GITHUB_ENV"
101+
echo "PR detected. Comparing base branch '${{ github.base_ref }}' with head '${{ github.head_ref }}'."
102+
else
103+
echo "REV1=${{ github.event.before }}" >> "$GITHUB_ENV"
104+
echo "REV2=${{ github.sha }}" >> "$GITHUB_ENV"
105+
echo "Push detected. Comparing from $REV1 to $REV2."
106+
fi
107+
108+
- name: Checkout Base Revision (REV1)
109+
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5
110+
with:
111+
ref: ${{ env.REV1 }}
112+
path: repo-rev1
113+
fetch-depth: 0
114+
115+
- name: Checkout Head Revision (REV2)
116+
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5
117+
with:
118+
ref: ${{ env.REV2 }}
119+
path: repo-rev2
120+
fetch-depth: 0
121+
122+
- name: Generate matrix for changed tests
123+
id: generate-matrix
124+
run: |
125+
set -euo pipefail
126+
127+
echo "Comparing checks between directories 'repo-rev1' and 'repo-rev2'..."
128+
129+
ALL_CHECKS=$(nix flake show --quiet --json ./repo-rev2# \
130+
2>/dev/null \
131+
| jq -r '.checks."x86_64-linux" | keys[]')
132+
133+
if [[ -z "$ALL_CHECKS" ]]; then
134+
echo "No checks found in flake at REV2. Exiting."
135+
echo "matrix=[]" >> "$GITHUB_OUTPUT"
136+
exit 0
137+
fi
138+
139+
CHANGED_CHECKS=()
140+
141+
for check in $ALL_CHECKS; do
142+
echo " - Checking: ${check}"
143+
144+
if ! nix flake show --json ./repo-rev1# 2>/dev/null \
145+
| jq -e '.checks."x86_64-linux"."'${check}'"' >/dev/null 2>&1; then
146+
echo " -> New check detected: ${check}"
147+
CHANGED_CHECKS+=("${check}")
148+
else
149+
path_old=$(nix eval --raw --quiet ./repo-rev1#checks.x86_64-linux.\"${check}\".config.driver)
150+
path_new=$(nix eval --raw --quiet ./repo-rev2#checks.x86_64-linux.\"${check}\".config.driver)
151+
152+
if ! diff_output=$(nix run nixpkgs#nix-diff -- "$path_old" "$path_new" 2>&1); then
153+
echo " -> Change detected for ${check}:"
154+
echo "${diff_output}" | sed 's/^/ /'
155+
echo "-----------------------------------------------------"
156+
CHANGED_CHECKS+=("${check}")
157+
fi
158+
fi
159+
done
160+
161+
if [ "${#CHANGED_CHECKS[@]}" -eq 0 ]; then
162+
FINAL_MATRIX='[]'
163+
else
164+
FINAL_MATRIX=$(printf '%s\n' "${CHANGED_CHECKS[@]}" | jq -Rcn '[inputs]')
165+
fi
166+
167+
echo "Final matrix for build/deploy jobs:"
168+
echo "$FINAL_MATRIX"
169+
echo "matrix=$FINAL_MATRIX" >> "$GITHUB_OUTPUT"
170+
84171
test:
85172
name: "nix build .#${{ matrix.name }}"
86-
needs: [ show, check ]
173+
needs: [ show, check, detect-changes ]
87174
runs-on: ubuntu-24.04
88175
strategy:
89176
matrix:
90-
name: ${{ fromJson(needs.show.outputs.matrix) }}
177+
name: ${{ github.event_name == 'pull_request' && fromJson(needs.detect-changes.outputs.matrix) || fromJson(needs.show.outputs.matrix) }}
91178
steps:
92179
- name: Maximize build space
93180
run: |

0 commit comments

Comments
 (0)