···99# lock: `nix flake update`, pushed as update/flake-lock with its own PR.
1010# 2. verify: for every open update/* PR, one after another (flake.lock
1111# first), rebase it onto the current master, build all machines with the
1212-# farm (farm.yml) on that commit and squash-merge the PR only if the run
1313-# succeeded. A commit that already has a finished farm run is not built
1414-# again, so a failing PR stays open until its branch or master changes.
1212+# farm (farm.yml) and run ci.yml on that commit, and squash-merge the PR
1313+# only if both succeeded (master's ruleset requires the ci check). A
1414+# commit that already has finished runs is not checked again, so a
1515+# failing PR stays open until its branch or master changes.
1516#
1617# One PR at a time because the farm has a fixed endpoint and runs in a single
1718# concurrency group, where GitHub keeps only one pending run.
···208209 git config user.name "github-actions[bot]"
209210 git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
210211211211- # Farm run for a head commit: "<id> <status> <conclusion>" or empty.
212212- # Cancelled runs don't count: a push to master replaced them.
213213- farm_run() {
214214- gh run list -R "$repo" -w farm.yml -b "$1" -e workflow_dispatch -L 20 \
212212+ # Dispatched run of a workflow for a head commit: "<id> <status>
213213+ # <conclusion>" or empty. Cancelled runs don't count: a push to
214214+ # master replaced them.
215215+ dispatched_run() {
216216+ gh run list -R "$repo" -w "$1" -b "$2" -e workflow_dispatch -L 20 \
215217 --json databaseId,headSha,status,conclusion \
216216- --jq "[.[] | select(.headSha == \"$2\" and .conclusion != \"cancelled\")][0] // empty
218218+ --jq "[.[] | select(.headSha == \"$3\" and .conclusion != \"cancelled\")][0] // empty
217219 | \"\(.databaseId) \(.status) \(.conclusion)\""
218220 }
219221220220- # Rebase a PR onto master, farm-build that commit and wait for the
221221- # result. Prints "<conclusion> <sha>"; conclusion is the farm run's,
222222- # or "conflict" / "nostart".
222222+ # Dispatch a workflow on a branch unless its head commit already
223223+ # has a run, wait for it and print its conclusion, or "nostart".
224224+ run_workflow() {
225225+ local workflow=$1 branch=$2 sha=$3 run id
226226+ run=$(dispatched_run "$workflow" "$branch" "$sha")
227227+ if [ -z "$run" ]; then
228228+ gh workflow run "$workflow" -R "$repo" --ref "$branch" >&2
229229+ for _ in $(seq 60); do
230230+ sleep 10
231231+ run=$(dispatched_run "$workflow" "$branch" "$sha")
232232+ [ -n "$run" ] && break
233233+ done
234234+ fi
235235+ id=${run%% *}
236236+ if [ -z "$id" ]; then
237237+ echo nostart
238238+ return
239239+ fi
240240+ echo "$workflow run $id on $sha" >&2
241241+ gh run watch "$id" -R "$repo" --interval 60 >/dev/null 2>&1 </dev/null || true
242242+ gh run view "$id" -R "$repo" --json conclusion --jq .conclusion
243243+ }
244244+245245+ # Rebase a PR branch onto master, farm-build that commit and run
246246+ # ci.yml on it. Prints "<conclusion> <sha>"; conclusion is the farm
247247+ # run's, then ci's as "ci-<conclusion>", or "conflict" / "nostart".
223248 verify_pr() {
224224- local pr=$1 branch=$2 sha run id
249249+ local branch=$1 sha conclusion
225250 git fetch -q origin master "$branch"
226251 git switch -q -C "$branch" "origin/$branch"
227252 if ! git rebase -q origin/master >&2; then
···233258 if [ "$sha" != "$(git rev-parse "origin/$branch")" ]; then
234259 git push -q --force-with-lease="$branch:origin/$branch" origin "$branch" >&2
235260 fi
236236- run=$(farm_run "$branch" "$sha")
237237- if [ -z "$run" ]; then
238238- gh workflow run farm.yml -R "$repo" --ref "$branch" >&2
239239- for _ in $(seq 60); do
240240- sleep 10
241241- run=$(farm_run "$branch" "$sha")
242242- [ -n "$run" ] && break
243243- done
261261+ conclusion=$(run_workflow farm.yml "$branch" "$sha")
262262+ if [ "$conclusion" = success ]; then
263263+ conclusion=$(run_workflow ci.yml "$branch" "$sha")
264264+ [ "$conclusion" = success ] || conclusion="ci-$conclusion"
244265 fi
245245- id=${run%% *}
246246- if [ -z "$id" ]; then
247247- echo "nostart $sha"
248248- return
249249- fi
250250- echo "#$pr: farm run $id on $sha" >&2
251251- gh run watch "$id" -R "$repo" --interval 60 >/dev/null 2>&1 </dev/null || true
252252- echo "$(gh run view "$id" -R "$repo" --json conclusion --jq .conclusion) $sha"
266266+ echo "$conclusion $sha"
253267 }
254268255269 # flake.lock first: every package PR is rebased onto the master it
···268282 # A push to master cancels a running verification; master has
269283 # moved then, so rebase and build again.
270284 for attempt in 1 2 3; do
271271- read -r conclusion sha < <(verify_pr "$pr" "$branch")
285285+ read -r conclusion sha < <(verify_pr "$branch")
272286 [ "$conclusion" = cancelled ] || break
273287 echo "#$pr: farm run cancelled by a push to master (attempt $attempt)"
274288 done