Skip to content

Commit f6d6c1a

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

1 file changed

Lines changed: 84 additions & 1 deletion

File tree

.github/workflows/ci.yaml

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

0 commit comments

Comments
 (0)