diff --git a/scripts/dev-lead-fix-issue.sh b/scripts/dev-lead-fix-issue.sh index 7cb0f75fb..f48655f44 100755 --- a/scripts/dev-lead-fix-issue.sh +++ b/scripts/dev-lead-fix-issue.sh @@ -456,13 +456,30 @@ ${lint_output} fi git push --set-upstream origin "$branch" - gh pr create \ + local pr_url + pr_url=$(gh pr create \ --repo "$REPO" \ --title "feat: implement issue #${ISSUE_NUMBER} — ${ISSUE_TITLE}" \ --body "Closes #${ISSUE_NUMBER} Implemented by dev-lead agent. Please review." \ - --head "$branch" + --head "$branch") + echo "$pr_url" + + # Mark the PR auto-rebase-eligible from creation (petry-projects/.github#711). + # The auto-rebase 'review-ready' gate (#465) only rebases PRs that are approved + # OR carry the ready label; without this, a dev-lead PR that falls behind before + # it is approved is skipped, drifts into a merge conflict, and cannot be approved + # (pr-review skips red/conflicting PRs) — a deadlock that rots the PR for weeks. + # Ensure the label exists first (idempotent; || true absorbs the "already exists" + # error) so a repo missing it does not break; guard everything so PR creation + # never fails on a labeling hiccup. + if [ -n "$pr_url" ]; then + gh label create "auto-rebase:ready" --repo "$REPO" \ + --description "Opts a non-draft PR into auto-rebase without an approval (auto-rebase ready_label)" \ + --color "0e8a16" >/dev/null 2>&1 || true + gh pr edit "$pr_url" --repo "$REPO" --add-label "auto-rebase:ready" >/dev/null 2>&1 || true + fi rm -f "$prompt_file" } diff --git a/tests/dev-lead/unit/test_fix_issue.bats b/tests/dev-lead/unit/test_fix_issue.bats index ced676ed8..285a8de77 100644 --- a/tests/dev-lead/unit/test_fix_issue.bats +++ b/tests/dev-lead/unit/test_fix_issue.bats @@ -718,3 +718,53 @@ GHEOF rm -f "$comment_sentinel" 2>/dev/null || true } + +@test "fix-issue: opened PR is labeled auto-rebase:ready (breaks #711 review-ready deadlock)" { + # Lint passes + cat > "$STUB_BIN_DIR/dev-lead-lint.sh" <<'LINTEOF' +#!/usr/bin/env bash +echo " [lint] all checks passed (stub)" +exit 0 +LINTEOF + chmod +x "$STUB_BIN_DIR/dev-lead-lint.sh" + + # Intentionally dirty working tree — exercises the commit path + cat > "$STUB_BIN_DIR/git" <<'GITEOF' +#!/usr/bin/env bash +case "$*" in + "status --porcelain") echo "M scripts/foo.sh" ;; + "rev-parse HEAD") echo "abc123" ;; + *) exit 0 ;; +esac +GITEOF + chmod +x "$STUB_BIN_DIR/git" + + # Record file lives in STUB_BIN_DIR (cleaned up by teardown); its path is baked + # into the gh stub below via the unquoted heredoc, so no export is needed. + LABEL_RECORD="$STUB_BIN_DIR/label_record" + + # gh stub: pr create returns a URL so the label path is exercised; record pr edit args + cat > "$STUB_BIN_DIR/gh" <> "$LABEL_RECORD"; exit 0 ;; + *"label create"*) exit 0 ;; + *"pulls?state=open"*) echo "0" ;; + *"api"*"repos/"*"issues/"*) echo '{"title":"Test","body":"body"}' ;; + *"api"*"users/"*) echo '{"id":12345}' ;; + *"issue comment"*) exit 0 ;; + *) echo "{}" ;; +esac +GHEOF + chmod +x "$STUB_BIN_DIR/gh" + + export DEV_LEAD_DRY_RUN="false" + export LINT_SCRIPT="$STUB_BIN_DIR/dev-lead-lint.sh" + + run bash "$FIX_ISSUE_SCRIPT" + + [ "$status" -eq 0 ] + # The opened PR must be made auto-rebase-eligible from creation. + grep -q "add-label auto-rebase:ready" "$LABEL_RECORD" +}