@@ -98,13 +98,46 @@ jobs:
9898 - name : Resolve wip branch for this chain
9999 id : wip
100100 env :
101+ GH_TOKEN : ${{ secrets.GITHUB_TOKEN }}
101102 INHERITED_WIP : ${{ inputs.wip_branch }}
102103 run : |
103104 set -euo pipefail
104105 if [ -n "$INHERITED_WIP" ]; then
106+ echo "Inheriting wip from chain: $INHERITED_WIP"
105107 echo "wip_branch=$INHERITED_WIP" >> "$GITHUB_OUTPUT"
108+ exit 0
109+ fi
110+ # No inherited wip -> this run is starting a chain. Before
111+ # creating a fresh wip, look for an orphan wip on remote.
112+ # An orphan exists when a prior chain was interrupted (e.g.
113+ # cancelled by GitHub's concurrency "queue length 1" rule)
114+ # before its wip reached the flush threshold. The chain-alive
115+ # gate (in the pick step) ensures we never adopt a wip that
116+ # belongs to a still-running chain.
117+ orphan=""
118+ while read -r _sha ref; do
119+ [ -z "$ref" ] && continue
120+ name="${ref#refs/heads/}"
121+ chain_id="${name#module-cleanup-wip-}"
122+ # Skip wips whose chain is still alive.
123+ if [ -n "$chain_id" ] && [ "$chain_id" != "manual" ]; then
124+ status=$(gh run view "$chain_id" --repo "$GITHUB_REPOSITORY" \
125+ --json status --jq .status 2>/dev/null || echo "")
126+ if [ "$status" = "queued" ] || [ "$status" = "in_progress" ]; then
127+ continue
128+ fi
129+ fi
130+ orphan="$name"
131+ echo "Adopting orphan wip: $orphan"
132+ break
133+ done < <(git ls-remote --heads origin 'module-cleanup-wip-*' || true)
134+
135+ if [ -n "$orphan" ]; then
136+ echo "wip_branch=$orphan" >> "$GITHUB_OUTPUT"
106137 else
107- echo "wip_branch=module-cleanup-wip-${GITHUB_RUN_ID}" >> "$GITHUB_OUTPUT"
138+ fresh="module-cleanup-wip-${GITHUB_RUN_ID}"
139+ echo "Starting fresh wip: $fresh"
140+ echo "wip_branch=$fresh" >> "$GITHUB_OUTPUT"
108141 fi
109142 - name : Pick next module
110143 id : pick
0 commit comments