mirror of
https://github.com/4gray/iptvnator.git
synced 2026-10-11 11:06:16 -08:00
Re-check the live PR state at the start of the cleanup job and again right before deleting the draft, so a PR that is reopened while the cleanup is queued or waiting keeps its rolling draft and its fresh reopened-run builds are not cancelled. Addresses Codex round-6 feedback on #1202. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
93 lines
4.3 KiB
YAML
93 lines
4.3 KiB
YAML
name: Cleanup PR Draft Release
|
|
|
|
on:
|
|
pull_request:
|
|
types: [closed]
|
|
|
|
# contents: write — delete the draft release; actions: write — cancel the
|
|
# closed PR's still-running build workflow before deleting.
|
|
permissions:
|
|
actions: write
|
|
contents: write
|
|
|
|
jobs:
|
|
delete-draft:
|
|
name: Delete PR draft release
|
|
# Fork PRs never get a draft (the release job skips them) and their
|
|
# GITHUB_TOKEN is read-only regardless of the permissions block, so
|
|
# there is nothing to cancel or delete.
|
|
if: github.event.pull_request.head.repo.full_name == github.repository
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
# A closed PR can be reopened while this job is still queued or
|
|
# waiting; a reopened PR's fresh build must not be cancelled and
|
|
# its draft must not be deleted. Check the live state up front
|
|
# (and again right before deleting below).
|
|
- name: Check PR is still closed
|
|
id: pr-state
|
|
env:
|
|
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
PR_NUMBER: ${{ github.event.pull_request.number }}
|
|
run: |
|
|
set -euo pipefail
|
|
echo "state=$(gh api "repos/${GITHUB_REPOSITORY}/pulls/${PR_NUMBER}" --jq '.state')" >> "${GITHUB_OUTPUT}"
|
|
|
|
# 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
|
|
if: steps.pr-state.outputs.state == 'closed'
|
|
env:
|
|
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
HEAD_BRANCH: ${{ github.event.pull_request.head.ref }}
|
|
run: |
|
|
set -euo pipefail
|
|
|
|
# --event pull_request: a manually dispatched build on the
|
|
# same branch is not this PR's work and must not be cancelled.
|
|
list_active_runs() {
|
|
gh run list --repo "${GITHUB_REPOSITORY}" \
|
|
--workflow 'Build and Make Electron App' \
|
|
--branch "${HEAD_BRANCH}" \
|
|
--event pull_request \
|
|
--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. The PR state
|
|
# is re-checked one last time right before deleting, in case the
|
|
# PR was reopened during the cancellation wait above.
|
|
- name: Delete draft release for closed PR
|
|
if: steps.pr-state.outputs.state == 'closed'
|
|
env:
|
|
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
PR_NUMBER: ${{ github.event.pull_request.number }}
|
|
run: |
|
|
set -euo pipefail
|
|
|
|
if [ "$(gh api "repos/${GITHUB_REPOSITORY}/pulls/${PR_NUMBER}" --jq '.state')" != "closed" ]; then
|
|
echo "PR #${PR_NUMBER} was reopened; keeping its draft."
|
|
exit 0
|
|
fi
|
|
|
|
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/{}"
|