11name : Eval
22
3- on : pull_request_target
3+ on :
4+ pull_request_target :
5+ push :
6+ # Keep this synced with ci/request-reviews/dev-branches.txt
7+ branches :
8+ - master
9+ - staging
10+ - release-*
11+ - staging-*
12+ - haskell-updates
13+ - python-updates
414
515permissions :
616 contents : read
1121 runs-on : ubuntu-latest
1222 outputs :
1323 mergedSha : ${{ steps.merged.outputs.mergedSha }}
24+ baseSha : ${{ steps.baseSha.outputs.baseSha }}
1425 systems : ${{ steps.systems.outputs.systems }}
1526 steps :
1627 # Important: Because of `pull_request_target`, this doesn't check out the PR,
@@ -24,23 +35,39 @@ jobs:
2435 id : merged
2536 env :
2637 GH_TOKEN : ${{ github.token }}
38+ GH_EVENT : ${{ github.event_name }}
2739 run : |
28- if mergedSha=$(base/ci/get-merge-commit.sh ${{ github.repository }} ${{ github.event.number }}); then
29- echo "Checking the merge commit $mergedSha"
30- echo "mergedSha=$mergedSha" >> "$GITHUB_OUTPUT"
31- else
32- # Skipping so that no notifications are sent
33- echo "Skipping the rest..."
34- fi
40+ case "$GH_EVENT" in
41+ push)
42+ echo "mergedSha=${{ github.sha }}" >> "$GITHUB_OUTPUT"
43+ ;;
44+ pull_request_target)
45+ if mergedSha=$(base/ci/get-merge-commit.sh ${{ github.repository }} ${{ github.event.number }}); then
46+ echo "Checking the merge commit $mergedSha"
47+ echo "mergedSha=$mergedSha" >> "$GITHUB_OUTPUT"
48+ else
49+ # Skipping so that no notifications are sent
50+ echo "Skipping the rest..."
51+ fi
52+ ;;
53+ esac
3554 rm -rf base
3655 - name : Check out the PR at the test merge commit
3756 uses : actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
3857 # Add this to _all_ subsequent steps to skip them
3958 if : steps.merged.outputs.mergedSha
4059 with :
4160 ref : ${{ steps.merged.outputs.mergedSha }}
61+ fetch-depth : 2
4262 path : nixpkgs
4363
64+ - name : Determine base commit
65+ if : github.event_name == 'pull_request_target' && steps.merged.outputs.mergedSha
66+ id : baseSha
67+ run : |
68+ baseSha=$(git -C nixpkgs rev-parse HEAD^1)
69+ echo "baseSha=$baseSha" >> "$GITHUB_OUTPUT"
70+
4471 - name : Install Nix
4572 uses : cachix/install-nix-action@08dcb3a5e62fa31e2da3d490afc4176ef55ecd72 # v30
4673 if : steps.merged.outputs.mergedSha
@@ -105,6 +132,8 @@ jobs:
105132 name : Process
106133 runs-on : ubuntu-latest
107134 needs : [ outpaths, attrs ]
135+ outputs :
136+ baseRunId : ${{ steps.baseRunId.outputs.baseRunId }}
108137 steps :
109138 - name : Download output paths and eval stats for all systems
110139 uses : actions/download-artifact@fa0a91b85d4f404e444e00e005971372dc801d16 # v4.1.8
@@ -124,18 +153,93 @@ jobs:
124153 - name : Combine all output paths and eval stats
125154 run : |
126155 nix-build nixpkgs/ci -A eval.combine \
127- --arg resultsDir ./intermediate
156+ --arg resultsDir ./intermediate \
157+ -o prResult
128158
129159 - name : Upload the combined results
130160 uses : actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3
131161 with :
132162 name : result
133- path : result /*
163+ path : prResult /*
134164
165+ - name : Get base run id
166+ if : needs.attrs.outputs.baseSha
167+ id : baseRunId
168+ run : |
169+ # Get the latest eval.yml workflow run for the PR's base commit
170+ if ! run=$(gh api --method GET /repos/"$REPOSITORY"/actions/workflows/eval.yml/runs \
171+ -f head_sha="$BASE_SHA" \
172+ --jq '.workflow_runs | sort_by(.run_started_at) | .[-1]') \
173+ || [[ -z "$run" ]]; then
174+ echo "Could not find an eval.yml workflow run for $BASE_SHA, cannot make comparison"
175+ exit 0
176+ fi
177+ echo "Comparing against $(jq .html_url <<< "$run")"
178+ runId=$(jq .id <<< "$run")
179+ conclusion=$(jq -r .conclusion <<< "$run")
180+
181+ while [[ "$conclusion" == null ]]; do
182+ echo "Workflow not done, waiting 10 seconds before checking again"
183+ sleep 10
184+ conclusion=$(gh api /repos/"$REPOSITORY"/actions/runs/"$runId" --jq '.conclusion')
185+ done
186+
187+ if [[ "$conclusion" != "success" ]]; then
188+ echo "Workflow was not successful, cannot make comparison"
189+ exit 0
190+ fi
135191
136- # TODO: Run this workflow also on `push` (on at least the main development branches)
137- # Then add an extra step here that waits for the base branch (not the merge base, because that could be very different)
138- # to have completed the eval, then use
139- # gh api --method GET /repos/NixOS/nixpkgs/actions/workflows/eval.yml/runs -f head_sha=<BASE>
140- # and follow it to the artifact results, where you can then download the outpaths.json from the base branch
141- # That can then be used to compare the number of changed paths, get evaluation stats and ping appropriate reviewers
192+ echo "baseRunId=$runId" >> "$GITHUB_OUTPUT"
193+ env :
194+ REPOSITORY : ${{ github.repository }}
195+ BASE_SHA : ${{ needs.attrs.outputs.baseSha }}
196+ GH_TOKEN : ${{ github.token }}
197+
198+ - uses : actions/download-artifact@v4
199+ if : steps.baseRunId.outputs.baseRunId
200+ with :
201+ name : result
202+ path : baseResult
203+ github-token : ${{ github.token }}
204+ run-id : ${{ steps.baseRunId.outputs.baseRunId }}
205+
206+ - name : Compare against the base branch
207+ if : steps.baseRunId.outputs.baseRunId
208+ run : |
209+ nix-build nixpkgs/ci -A eval.compare \
210+ --arg beforeResultDir ./baseResult \
211+ --arg afterResultDir ./prResult \
212+ -o comparison
213+
214+ # TODO: Request reviews from maintainers for packages whose files are modified in the PR
215+
216+ - name : Upload the combined results
217+ if : steps.baseRunId.outputs.baseRunId
218+ uses : actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3
219+ with :
220+ name : comparison
221+ path : comparison/*
222+
223+ # Separate job to have a very tightly scoped PR write token
224+ tag :
225+ name : Tag
226+ runs-on : ubuntu-latest
227+ needs : process
228+ if : needs.process.outputs.baseRunId
229+ permissions :
230+ pull-requests : write
231+ steps :
232+ - name : Download process result
233+ uses : actions/download-artifact@fa0a91b85d4f404e444e00e005971372dc801d16 # v4.1.8
234+ with :
235+ name : comparison
236+ path : comparison
237+
238+ - name : Tagging pull request
239+ run : |
240+ gh api \
241+ --method POST \
242+ /repos/${{ github.repository }}/issues/${{ github.event.number }}/labels \
243+ --input <(jq -c '{ labels: .labels }' comparison/changed-paths.json)
244+ env :
245+ GH_TOKEN : ${{ github.token }}
0 commit comments