Files
iptvnator/.github/workflows/cleanup-pr-draft.yml
T
4grayandClaude Fable 5 4d793485a7 ci(release): close review-bot race windows in draft release flow
- Move concurrency from workflow level to job level: cancelling a whole
  run could interrupt action-gh-release mid-asset-replacement and leave
  the rolling draft incomplete. Build slots still cancel superseded PR
  work (matrix-aware groups); the release job gets its own serializing,
  never-cancelling group.
- Re-check the live PR state in the release job right before touching
  the draft, so a build that outlives its PR cannot recreate the draft
  after cleanup deleted it.
- In the cleanup workflow, cancel still-running builds of the closed PR
  (dead work anyway) and wait for them to settle before deleting.
- Emit an explicit empty `body=` output for tag builds instead of a
  blank-line heredoc.

Addresses Codex and Greptile review feedback on #1202.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-18 16:21:32 +02:00

61 lines
2.5 KiB
YAML

name: Cleanup PR Draft Release
on:
pull_request:
types: [closed]
permissions:
contents: write
jobs:
delete-draft:
name: Delete PR draft release
runs-on: ubuntu-latest
steps:
# A build for this PR may still be running and would recreate the
# rolling draft after we delete it. Cancel those runs (dead work
# for a closed PR anyway) and wait for them to wind down. The
# release job additionally re-checks the live PR state, so this
# wait is defense in depth, not the only guard.
- name: Cancel in-progress builds for the closed PR
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
HEAD_BRANCH: ${{ github.event.pull_request.head.ref }}
run: |
set -euo pipefail
list_active_runs() {
gh run list --repo "${GITHUB_REPOSITORY}" \
--workflow 'Build and Make Electron App' \
--branch "${HEAD_BRANCH}" \
--json databaseId,status \
--jq '.[] | select(.status == "queued" or .status == "in_progress" or .status == "waiting" or .status == "requested" or .status == "pending") | .databaseId'
}
for run_id in $(list_active_runs); do
echo "Cancelling run ${run_id}"
gh run cancel "${run_id}" --repo "${GITHUB_REPOSITORY}" || true
done
# Cancellation is asynchronous; poll until the runs settle.
for _ in $(seq 1 18); do
if [ -z "$(list_active_runs)" ]; then
break
fi
sleep 10
done
# Draft releases have no real git tag, so a lookup via
# releases/tags/<tag> returns 404. List releases and match the
# draft by its stored tag_name (test-pr-<n>) instead.
- name: Delete draft release for closed PR
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
PR_NUMBER: ${{ github.event.pull_request.number }}
run: |
set -euo pipefail
gh api "repos/${GITHUB_REPOSITORY}/releases?per_page=100" --paginate \
--jq ".[] | select(.draft and .tag_name == \"test-pr-${PR_NUMBER}\") | .id" |
xargs -r -n1 -I{} gh api -X DELETE "repos/${GITHUB_REPOSITORY}/releases/{}"