fix: stuck PRs priority + STATE.md in first commit + 405 bug in dev-poll
1. PRIORITY 1.5 in dev-poll: scan ALL open PRs for REQUEST_CHANGES or CI failure before picking new backlog issues. Stuck PRs get fixed first to avoid complex rebases piling up. 2. STATE.md written in worktree before claude starts (included in first commit, not a separate push that dismisses stale approvals). 3. Removed HTTP 405 from merge success check in dev-poll.sh (was fixed in dev-agent.sh but not here — 2 occurrences).
This commit is contained in:
parent
793dafdb8a
commit
0f979fd6c9
2 changed files with 81 additions and 29 deletions
|
|
@ -545,6 +545,10 @@ else
|
|||
cd "$WORKTREE"
|
||||
git checkout -B "$BRANCH" origin/master 2>/dev/null
|
||||
git submodule update --init --recursive 2>/dev/null || true
|
||||
|
||||
# Write STATE.md entry — will be included in the first commit
|
||||
write_state_entry "in-progress"
|
||||
|
||||
# Symlink lib node_modules from main repo (submodule init doesn't run npm install)
|
||||
for lib_dir in "$REPO_ROOT"/onchain/lib/*/; do
|
||||
lib_name=$(basename "$lib_dir")
|
||||
|
|
@ -856,45 +860,32 @@ fi
|
|||
# =============================================================================
|
||||
# STATE.MD APPEND
|
||||
# =============================================================================
|
||||
# After each merge, append one line to STATE.md describing what now exists.
|
||||
# Format: - [YYYY-MM-DD] what is now true about harb (#PR)
|
||||
# The planner will collapse this into a compact snapshot later.
|
||||
append_state_log() {
|
||||
local state_file="${REPO_ROOT}/STATE.md"
|
||||
# Write STATE.md entry in the worktree BEFORE implementation starts.
|
||||
# This ensures the STATE.md update is part of the first commit, not a separate
|
||||
# push that would dismiss stale approvals.
|
||||
# Format: - [YYYY-MM-DD] <in-progress|done> description (#ISSUE)
|
||||
write_state_entry() {
|
||||
local status_word="${1:-in-progress}" # "in-progress" or "done"
|
||||
local target="${WORKTREE:-$REPO_ROOT}"
|
||||
local state_file="${target}/STATE.md"
|
||||
local today
|
||||
today=$(date -u +%Y-%m-%d)
|
||||
|
||||
# Derive a "what now exists" description from the issue title.
|
||||
# Strip prefixes (feat:/fix:/refactor:) to get the essence.
|
||||
local description
|
||||
description=$(echo "$ISSUE_TITLE" | sed 's/^feat:\s*//i;s/^fix:\s*//i;s/^refactor:\s*//i')
|
||||
|
||||
local line="- [${today}] ${description} (#${PR_NUMBER})"
|
||||
|
||||
# Create file with header if it doesn't exist
|
||||
if [ ! -f "$state_file" ]; then
|
||||
echo "# STATE.md — What harb currently is and does" > "$state_file"
|
||||
echo "" >> "$state_file"
|
||||
fi
|
||||
|
||||
echo "$line" >> "$state_file"
|
||||
|
||||
# Append to STATE.md on the PR branch, push before merge
|
||||
local worktree="${WORKTREE:-}"
|
||||
local target="${worktree:-$REPO_ROOT}"
|
||||
local state_file="${target}/STATE.md"
|
||||
local line="- [${today}] [${status_word}] ${description} (#${ISSUE})"
|
||||
|
||||
if [ ! -f "$state_file" ]; then
|
||||
printf '# STATE.md — What harb currently is and does\n\n' > "$state_file"
|
||||
fi
|
||||
echo "$line" >> "$state_file"
|
||||
log "STATE.md: ${line}"
|
||||
}
|
||||
|
||||
cd "$target"
|
||||
git add STATE.md 2>/dev/null || true
|
||||
git diff --cached --quiet && return 0
|
||||
git commit -m "state: ${description} (#${PR_NUMBER})" --no-verify 2>/dev/null || true
|
||||
git push origin "${BRANCH}" 2>/dev/null || log "STATE.md push failed — will be missing from this merge"
|
||||
log "STATE.md updated: ${line}"
|
||||
# Alias for backward compat
|
||||
append_state_log() {
|
||||
write_state_entry "done"
|
||||
}
|
||||
|
||||
# MERGE HELPER
|
||||
|
|
@ -948,6 +939,10 @@ do_merge() {
|
|||
if [ "$http_code" = "200" ] || [ "$http_code" = "204" ]; then
|
||||
log "PR #${PR_NUMBER} merged!"
|
||||
|
||||
# Update STATE.md on master (pull merged changes first)
|
||||
(cd "$REPO_ROOT" && git checkout master 2>/dev/null && git pull --ff-only origin master 2>/dev/null) || true
|
||||
append_state_log || log "WARNING: STATE.md update failed (non-fatal)"
|
||||
|
||||
curl -sf -X DELETE \
|
||||
-H "Authorization: token ${CODEBERG_TOKEN}" \
|
||||
"${API}/branches/${BRANCH}" >/dev/null 2>&1 || true
|
||||
|
|
|
|||
|
|
@ -150,7 +150,7 @@ if [ "$ORPHAN_COUNT" -gt 0 ]; then
|
|||
"${API}/pulls/${HAS_PR}/merge" \
|
||||
-d '{"Do":"merge","delete_branch_after_merge":true}')
|
||||
|
||||
if [ "$MERGE_CODE" = "200" ] || [ "$MERGE_CODE" = "204" ] || [ "$MERGE_CODE" = "405" ]; then
|
||||
if [ "$MERGE_CODE" = "200" ] || [ "$MERGE_CODE" = "204" ] ; then
|
||||
log "PR #${HAS_PR} merged! Closing #${ISSUE_NUM}"
|
||||
curl -sf -X PATCH -H "Authorization: token ${CODEBERG_TOKEN}" \
|
||||
-H "Content-Type: application/json" \
|
||||
|
|
@ -186,6 +186,63 @@ if [ "$ORPHAN_COUNT" -gt 0 ]; then
|
|||
fi
|
||||
fi
|
||||
|
||||
# =============================================================================
|
||||
# PRIORITY 1.5: any open PR with REQUEST_CHANGES or CI failure (stuck PRs)
|
||||
# =============================================================================
|
||||
log "checking for stuck PRs"
|
||||
OPEN_PRS=$(curl -sf -H "Authorization: token ${CODEBERG_TOKEN}" \
|
||||
"${API}/pulls?state=open&limit=20")
|
||||
|
||||
for i in $(seq 0 $(($(echo "$OPEN_PRS" | jq 'length') - 1))); do
|
||||
PR_NUM=$(echo "$OPEN_PRS" | jq -r ".[$i].number")
|
||||
PR_BRANCH=$(echo "$OPEN_PRS" | jq -r ".[$i].head.ref")
|
||||
PR_SHA=$(echo "$OPEN_PRS" | jq -r ".[$i].head.sha")
|
||||
|
||||
# Extract issue number from branch name (fix/issue-NNN)
|
||||
STUCK_ISSUE=$(echo "$PR_BRANCH" | grep -oP '(?<=fix/issue-)\d+' || true)
|
||||
[ -z "$STUCK_ISSUE" ] && continue
|
||||
|
||||
CI_STATE=$(curl -sf -H "Authorization: token ${CODEBERG_TOKEN}" \
|
||||
"${API}/commits/${PR_SHA}/status" | jq -r '.state // "unknown"') || true
|
||||
HAS_CHANGES=$(curl -sf -H "Authorization: token ${CODEBERG_TOKEN}" \
|
||||
"${API}/pulls/${PR_NUM}/reviews" | \
|
||||
jq -r '[.[] | select(.state == "REQUEST_CHANGES") | select(.stale == false)] | length') || true
|
||||
HAS_APPROVE=$(curl -sf -H "Authorization: token ${CODEBERG_TOKEN}" \
|
||||
"${API}/pulls/${PR_NUM}/reviews" | \
|
||||
jq -r '[.[] | select(.state == "APPROVED") | select(.stale == false)] | length') || true
|
||||
|
||||
# Try merge if approved + CI green
|
||||
if [ "$CI_STATE" = "success" ] && [ "${HAS_APPROVE:-0}" -gt 0 ]; then
|
||||
log "PR #${PR_NUM} (issue #${STUCK_ISSUE}) approved + CI green → merging"
|
||||
MERGE_CODE=$(curl -s -o /dev/null -w "%{http_code}" -X POST \
|
||||
-H "Authorization: token ${CODEBERG_TOKEN}" \
|
||||
-H "Content-Type: application/json" \
|
||||
"${API}/pulls/${PR_NUM}/merge" \
|
||||
-d '{"Do":"merge","delete_branch_after_merge":true}')
|
||||
if [ "$MERGE_CODE" = "200" ] || [ "$MERGE_CODE" = "204" ]; then
|
||||
log "PR #${PR_NUM} merged! Closing #${STUCK_ISSUE}"
|
||||
curl -sf -X PATCH -H "Authorization: token ${CODEBERG_TOKEN}" \
|
||||
-H "Content-Type: application/json" \
|
||||
"${API}/issues/${STUCK_ISSUE}" -d '{"state":"closed"}' >/dev/null 2>&1 || true
|
||||
openclaw system event --text "✅ PR #${PR_NUM} merged! Issue #${STUCK_ISSUE} done." --mode now 2>/dev/null || true
|
||||
fi
|
||||
continue
|
||||
fi
|
||||
|
||||
# Stuck: REQUEST_CHANGES or CI failure → spawn agent
|
||||
if [ "$CI_STATE" = "success" ] && [ "${HAS_CHANGES:-0}" -gt 0 ]; then
|
||||
log "PR #${PR_NUM} (issue #${STUCK_ISSUE}) has REQUEST_CHANGES — fixing first"
|
||||
nohup "${SCRIPT_DIR}/dev-agent.sh" "$STUCK_ISSUE" >> "$LOGFILE" 2>&1 &
|
||||
log "started dev-agent PID $! for stuck PR #${PR_NUM}"
|
||||
exit 0
|
||||
elif [ "$CI_STATE" = "failure" ] || [ "$CI_STATE" = "error" ]; then
|
||||
log "PR #${PR_NUM} (issue #${STUCK_ISSUE}) CI failed — fixing first"
|
||||
nohup "${SCRIPT_DIR}/dev-agent.sh" "$STUCK_ISSUE" >> "$LOGFILE" 2>&1 &
|
||||
log "started dev-agent PID $! for stuck PR #${PR_NUM}"
|
||||
exit 0
|
||||
fi
|
||||
done
|
||||
|
||||
# =============================================================================
|
||||
# PRIORITY 2: find ready backlog issues (pull system)
|
||||
# =============================================================================
|
||||
|
|
@ -236,7 +293,7 @@ for i in $(seq 0 $((BACKLOG_COUNT - 1))); do
|
|||
-H "Content-Type: application/json" \
|
||||
"${API}/pulls/${EXISTING_PR}/merge" \
|
||||
-d '{"Do":"merge","delete_branch_after_merge":true}')
|
||||
if [ "$MERGE_CODE" = "200" ] || [ "$MERGE_CODE" = "204" ] || [ "$MERGE_CODE" = "405" ]; then
|
||||
if [ "$MERGE_CODE" = "200" ] || [ "$MERGE_CODE" = "204" ] ; then
|
||||
log "PR #${EXISTING_PR} merged! Closing #${ISSUE_NUM}"
|
||||
curl -sf -X PATCH -H "Authorization: token ${CODEBERG_TOKEN}" \
|
||||
-H "Content-Type: application/json" \
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue