From 175ed1e87cbc8d2208e4080bb1a51af18a70f97d Mon Sep 17 00:00:00 2001 From: "privilegedescalation-engineer[bot]" <269729446+privilegedescalation-engineer[bot]@users.noreply.github.com> Date: Wed, 15 Apr 2026 01:56:28 +0000 Subject: [PATCH] fix(plugin-release): handle clean-status PR merge gracefully (#77) * fix(plugin-release): handle clean-status PR merge gracefully - Check MERGED state before attempting merge (early exit) - Use mergeableState-based strategy: blocked=auto, others=direct squash - Remove invalid 'pending' mergeable_state value (was dead code) - Document 'unknown' state fallback behavior Rebase of PR #77 to resolve conflicts with main (PR #76) * fix(plugin-release): fix return syntax and handle unknown mergeableState - Replace invalid 'return 0 || true' with 'exit 0' for proper step exit - Add explicit handling for 'unknown' mergeableState with retry logic - QA feedback: PRI-1049 --------- Co-authored-by: Hugh Hackman Co-authored-by: privilegedescalation-ceo[bot] <269721483+privilegedescalation-ceo[bot]@users.noreply.github.com> --- .github/workflows/plugin-release.yaml | 31 +++++++++++++++++++++------ 1 file changed, 25 insertions(+), 6 deletions(-) diff --git a/.github/workflows/plugin-release.yaml b/.github/workflows/plugin-release.yaml index 9aac349..b81a1bb 100644 --- a/.github/workflows/plugin-release.yaml +++ b/.github/workflows/plugin-release.yaml @@ -304,15 +304,34 @@ jobs: else echo "::notice::PR for release/v${VERSION} already exists — skipping creation." fi - # Try auto-merge first (works on repos with required status checks pending). - # Fall back to direct squash merge on repos without required status checks - # (auto-merge is rejected when there are no pending required checks to wait for). - # If PR is already merged, skip entirely to avoid "branch not found" errors. + # Check if PR is already merged first (skip if so). PR_STATE=$(gh pr view "release/v${VERSION}" --json state --jq '.state' 2>/dev/null || echo "unknown") if [ "$PR_STATE" = "MERGED" ]; then echo "PR release/v${VERSION} is already merged. Skipping merge step." - elif ! gh pr merge "release/v${VERSION}" --auto --squash --delete-branch 2>&1; then - echo "Auto-merge not available (no pending required status checks or other constraint). Falling back to direct squash merge." + exit 0 + fi + # Use auto-merge only when there are pending status checks to wait for. + # Valid mergeableState values from GitHub REST API: + # behind, blocked, clean, dirty, draft, has_hooks, unknown, unstable + # Note: "pending" is NOT a valid mergeable_state value — it was dead code. + MERGE_STATE=$(gh pr view "release/v${VERSION}" --json mergeableState --jq '.mergeableState') + if [ "$MERGE_STATE" = "blocked" ]; then + echo "PR is $MERGE_STATE — enabling auto-merge." + gh pr merge "release/v${VERSION}" --auto --squash --delete-branch + elif [ "$MERGE_STATE" = "unknown" ]; then + # GitHub is still computing mergeability. Retry once after a brief wait. + echo "PR is $MERGE_STATE — GitHub is computing mergeability. Retrying in 5s." + sleep 5 + MERGE_STATE=$(gh pr view "release/v${VERSION}" --json mergeableState --jq '.mergeableState') + if [ "$MERGE_STATE" = "blocked" ]; then + echo "PR is now $MERGE_STATE — enabling auto-merge." + gh pr merge "release/v${VERSION}" --auto --squash --delete-branch + else + echo "PR is still $MERGE_STATE after retry — merging directly." + gh pr merge "release/v${VERSION}" --squash --delete-branch + fi + else + echo "PR is $MERGE_STATE — merging directly." gh pr merge "release/v${VERSION}" --squash --delete-branch fi env: