Pr
You are creating a pull request for the current changes and shepherding it through CI and review.
# Create PR and iterate until CI passes
You are creating a pull request for the current changes and shepherding it through CI and review.
**Important:** Other agents may be working in this same repo. You may see changes you didn't make — that's normal. Include everything in the branch; don't try to split out "your" changes.
## Step 1: Deterministic preflight (single command)
Run one script to do the repetitive setup/check work with clear output:
```bash
uv run python scripts/pr_preflight.py --base origin/main
This script deterministically does all of the following:
- Prints branch/HEAD, working tree status, diff stat, and commit list vs
main - Fetches latest
origin/main - Runs merge-conflict preflight including merge simulation against
origin/main - Suggests
RECOMMENDED_BASE=<branch>for PR creation - Runs local tests (CI-equivalent unit test command)
If preflight fails, fix issues and rerun before continuing.
Step 2: Branch and commit
If you're on main, create a new branch:
git checkout -b pr/$(date +%Y%m%d-%H%M%S)-$(git log -1 --format=%s | tr ' ' '-' | tr '[:upper:]' '[:lower:]' | cut -c1-40)
If you're already on a feature branch, stay on it.
Stage and commit all changes with a clear message summarizing the work:
git add -A
git commit -m "descriptive commit message"
If there are already commits on the branch, you can squash them:
git reset --soft $(git merge-base HEAD main)
git commit -m "descriptive commit message"
Step 3: Choose base branch
Use RECOMMENDED_BASE from preflight script output. If preflight defaulted to main, use main.
Step 4: Push and create PR
git push --force-with-lease -u origin HEAD
Resolve issue metadata from _agenttree/issues/*/issue.yaml by exact branch match.
Only fall back to parsing digits from the branch name if no match is found:
CURRENT_BRANCH=$(git branch --show-current)
read -r ISSUE_NUM ISSUE_TITLE <<EOF
$(uv run python - <<'PY'
from pathlib import Path
import yaml
import subprocess
branch = subprocess.check_output(
["git", "branch", "--show-current"],
text=True,
).strip()
issues_dir = Path("_agenttree/issues")
for issue_yaml in sorted(issues_dir.glob("*/issue.yaml")):
try:
data = yaml.safe_load(issue_yaml.read_text()) or {}
except Exception:
continue
if data.get("branch") == branch:
issue_id = data.get("id")
title = (data.get("title") or "").strip()
if issue_id:
print(f"{issue_id} {title}")
break
else:
print("")
PY
)
EOF
if [ -z "$ISSUE_NUM" ]; then
ISSUE_NUM=$(echo "$CURRENT_BRANCH" | grep -oE '[0-9]+' | head -1)
echo "WARN: Could not map branch to _agenttree issue metadata; falling back to branch digits ($ISSUE_NUM)."
fi
Create the PR using gh with the base you determined. PR titles MUST use the [Issue X] prefix format:
gh pr create --base <base-branch> --title "[Issue $ISSUE_NUM] $DESCRIPTION" --body "## Summary
- bullet points of what changed
## Test plan
- [ ] CI passes
- [ ] Tests pass"
For example: [Issue 42] Add user authentication flow
If a PR already exists for this branch, skip creation:
gh pr view HEAD 2>/dev/null && echo "PR already exists" || gh pr create ...
Step 5: Wait for CI and iterate
Now enter a check-fix loop. Repeat until CI is green and no unaddressed review comments:
5a. Wait for CI to start
sleep 30
5b. Check CI/review status (single command)
uv run python scripts/pr_ci_status.py --watch
5c. If CI fails
Read failing run logs with:
gh run view <run-id> --log-failed
Fix the issue, commit, and push:
uv run python scripts/pr_preflight.py --base origin/main --skip-tests
git add -A
git commit -m "fix: address CI failure - <what you fixed>"
git push
Go back to 5a.
5d. Check for review feedback
gh pr view HEAD --comments
gh api repos/{owner}/{repo}/pulls/{number}/reviews --jq '.[] | "\(.state): \(.body)"'
If there are requested changes:
- Read the feedback carefully
- Make the fixes
- Commit and push
- Go back to 5a
5e. All green
When CI passes and there are no unaddressed review comments, report success:
- Print the PR URL
- Summarize the final state (CI status, number of iterations)
Guidelines
- Don't give up after one CI failure. Read the logs, fix the issue, push again. Most CI failures are fixable.
- Keep commits clean. Each fix should have a descriptive message.
- Don't force-push after review. Once reviewers have commented, use regular pushes so they can see incremental changes.
- If stuck after 5 iterations, stop and ask for help rather than spinning forever.
- Run tests locally first if the project has a test command (
uv run pytest,npm test, etc.) — it's faster than waiting for CI.
Maintain Pr?
Let people know it's listed here — add the badge (live metrics, light/dark aware) or a plain link to your README or docs.
[Pr on getagentictools](https://getagentictools.com/loops/davefowler-create-pr-and-iterate-until-ci-passes?ref=badge)