Skip to content

Commit eeb34bb

Browse files
committed
Update PR sync documentation to use Docker-based workflow
1 parent c099808 commit eeb34bb

File tree

2 files changed

+184
-168
lines changed

2 files changed

+184
-168
lines changed

.cursor/rules/sync-prs.mdc

Lines changed: 184 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -4,82 +4,98 @@ description: Sync all open pull requests with origin/main to keep them up-to-dat
44

55
# Sync Open PRs with origin/main
66

7-
This rule provides a systematic approach to keeping all open pull requests synchronized with the main branch.
7+
This rule provides a systematic approach to keeping all open pull requests synchronized with the main branch using the Docker-based `just pr` command for isolated testing.
88

99
## Why Sync PRs?
1010

1111
- Prevents merge conflicts from accumulating
1212
- Ensures PRs are tested against the latest codebase
1313
- Makes reviews easier by reducing the delta between PR and main
1414
- Identifies integration issues early
15+
- Uses isolated Docker environments to avoid polluting local git state
1516

1617
## Prerequisites
1718

18-
1. Ensure local main is up-to-date:
19+
1. Docker installed and running
20+
2. GitHub CLI (`gh`) installed and authenticated:
1921
```bash
20-
git checkout main
21-
git pull origin main
22+
gh auth login
2223
```
2324

24-
2. Fetch all remote branches:
25+
3. Justfile command runner installed:
2526
```bash
26-
git fetch origin
27+
# On macOS
28+
brew install just
2729
```
2830

2931
## Process to Sync All Open PRs
3032

3133
### Step 1: Get List of Open PRs
3234

33-
Use GitHub API to list open PRs:
35+
Use GitHub CLI to list open PRs:
3436
```bash
35-
# Get current origin/main SHA
36-
git rev-parse origin/main
37-
38-
# List open PRs (requires gh CLI or use GitHub API tools)
39-
# This will show PR numbers, branches, and base commit
37+
gh pr list --json number,title,headRefName --limit 50
4038
```
4139

42-
### Step 2: Update Each PR Branch
40+
### Step 2: Update Each PR Using Docker
4341

44-
For each open PR branch:
42+
For each open PR, use the `just pr` command to sync in an isolated environment:
4543

4644
```bash
47-
# Checkout the PR branch
48-
git checkout <pr-branch-name>
49-
50-
# Merge origin/main
51-
git merge origin/main --no-edit
45+
# Sync a single PR with origin/main
46+
just sync-pr <PR_NUMBER>
5247

53-
# If successful, push
54-
git push origin <pr-branch-name>
48+
# Or manually run the sync commands
49+
just pr <PR_NUMBER> "git fetch origin main && git merge origin/main --no-edit && cargo fmt --all && cargo check && git push origin HEAD"
5550
```
5651

52+
The `just pr` command:
53+
- Builds a Docker container with the PR checked out
54+
- Runs commands inside that isolated environment
55+
- Automatically handles GitHub authentication
56+
- Keeps your local git state clean
57+
5758
### Step 3: Handle Merge Conflicts
5859

59-
When conflicts occur:
60+
When conflicts occur, you'll need to resolve them manually:
6061

61-
1. **Identify conflicting files**:
62+
1. **Checkout the PR branch locally**:
6263
```bash
64+
gh pr checkout <PR_NUMBER>
65+
```
66+
67+
2. **Identify conflicting files**:
68+
```bash
69+
git fetch origin main
70+
git merge origin/main --no-edit
6371
git status
6472
```
6573

66-
2. **Resolve conflicts manually**:
74+
3. **Resolve conflicts manually**:
6775
- Read both versions carefully
6876
- Understand the intent of each change
6977
- Combine changes intelligently (don't just pick one side)
7078
- Remove conflict markers (`<<<<<<<`, `=======`, `>>>>>>>`)
7179

72-
3. **Key principles for conflict resolution**:
80+
4. **Key principles for conflict resolution**:
7381
- Preserve new functionality from main
7482
- Keep PR-specific changes
7583
- Ensure constants/config changes are consistent
7684
- Test that the resolution compiles
7785

78-
4. **Complete the merge**:
86+
5. **Complete the merge and test**:
7987
```bash
8088
git add <resolved-files>
8189
git commit --no-edit
82-
git push origin <pr-branch-name>
90+
cargo fmt --all
91+
cargo check
92+
git push origin HEAD
93+
```
94+
95+
6. **Verify using Docker**:
96+
```bash
97+
# Test the resolved PR in isolated environment
98+
just pr <PR_NUMBER> "cargo test"
8399
```
84100

85101
## Common Conflict Scenarios
@@ -118,82 +134,156 @@ When both branches add imports:
118134

119135
```bash
120136
#!/bin/bash
121-
# sync-all-prs.sh - Sync all open PRs with origin/main
137+
# sync-all-prs - Sync all open PRs with origin/main using Docker
122138

123139
set -e
124140

125-
# Fetch latest
126-
git fetch origin
141+
echo "Fetching open PRs..."
142+
143+
# Get list of open PR numbers
144+
PR_NUMBERS=$(gh pr list --json number --jq '.[].number')
127145

128-
# Get main SHA
129-
MAIN_SHA=$(git rev-parse origin/main)
146+
if [ -z "$PR_NUMBERS" ]; then
147+
echo "No open PRs found"
148+
exit 0
149+
fi
150+
151+
# Get main SHA for reference
152+
MAIN_SHA=$(git rev-parse origin/main 2>/dev/null || echo "unknown")
130153
echo "Syncing PRs to main: $MAIN_SHA"
154+
echo ""
131155

132-
# List of PR branches (populate from GitHub API)
133-
PR_BRANCHES=(
134-
"copilot/fix-branch-1"
135-
"copilot/fix-branch-2"
136-
# ... add more branches
137-
)
156+
# Track results
157+
SUCCESS=()
158+
CONFLICTS=()
138159

139-
for branch in "${PR_BRANCHES[@]}"; do
140-
echo "=== Syncing $branch ==="
160+
for pr_num in $PR_NUMBERS; do
161+
echo "=== Syncing PR #$pr_num ==="
141162

142-
# Checkout and merge
143-
git checkout "$branch" || git checkout -b "$branch" "origin/$branch"
163+
# Get PR title for better output
164+
PR_TITLE=$(gh pr view "$pr_num" --json title --jq '.title')
165+
echo "Title: $PR_TITLE"
144166

145-
if git merge origin/main --no-edit; then
146-
echo "✓ Merged successfully"
147-
git push origin "$branch"
167+
# Attempt sync using Docker-isolated environment
168+
if just sync-pr "$pr_num"; then
169+
echo "✓ PR #$pr_num merged successfully"
170+
SUCCESS+=("$pr_num")
148171
else
149-
echo "✗ Merge conflict - manual resolution needed"
150-
echo " Conflicting files:"
151-
git status --short | grep "^UU"
152-
echo " Resolve conflicts then run:"
153-
echo " git add <files> && git commit --no-edit && git push origin $branch"
154-
exit 1
172+
echo "✗ PR #$pr_num has conflicts - manual resolution needed"
173+
echo " Resolve with:"
174+
echo " gh pr checkout $pr_num"
175+
echo " git merge origin/main --no-edit"
176+
echo " # ... resolve conflicts ..."
177+
echo " git push origin HEAD"
178+
CONFLICTS+=("$pr_num")
155179
fi
180+
echo ""
181+
done
182+
183+
# Summary
184+
echo "========================================"
185+
echo "Sync Summary"
186+
echo "========================================"
187+
echo "Successful: ${#SUCCESS[@]} PRs"
188+
for pr in "${SUCCESS[@]}"; do
189+
echo " ✓ #$pr"
156190
done
157191

158-
# Return to main
159-
git checkout main
160-
echo "All PRs synced!"
192+
if [ ${#CONFLICTS[@]} -gt 0 ]; then
193+
echo ""
194+
echo "Conflicts: ${#CONFLICTS[@]} PRs"
195+
for pr in "${CONFLICTS[@]}"; do
196+
echo " ✗ #$pr"
197+
done
198+
exit 1
199+
fi
200+
201+
echo ""
202+
echo "All PRs synced successfully!"
161203
```
162204

205+
This script uses the existing `just sync-pr` command from the Justfile, which runs the merge in an isolated Docker container.
206+
163207
## Best Practices
164208

165209
1. **Sync regularly**: Update PRs weekly or after significant main branch changes
166-
2. **Test after sync**: Run tests to ensure the merge didn't break anything
210+
2. **Use Docker for testing**: The `just pr` command provides isolation and consistency
167211
3. **Review conflicts carefully**: Don't blindly accept one side
168212
4. **Document complex resolutions**: Add comments explaining non-obvious merge decisions
169-
5. **Clean up**: Return to main branch when done
170-
6. **Verify builds**: Run `cargo check` or `cargo build` after resolving conflicts
213+
5. **Test in isolation**: After resolving conflicts locally, verify with `just pr <NUM> "cargo test"`
214+
6. **Verify builds**: Always run `cargo check` and `cargo fmt` after resolving conflicts
215+
216+
## Using the `just pr` Command
217+
218+
The `just pr` command is a powerful tool for working with PRs in isolation:
219+
220+
```bash
221+
# Run any command in the PR's Docker environment
222+
just pr <PR_NUMBER> "<command>"
223+
224+
# Examples:
225+
just pr 42 "cargo build"
226+
just pr 42 "cargo test"
227+
just pr 42 "cargo clippy"
228+
just pr 42 "git log --oneline -5"
229+
230+
# Sync a PR (combines fetch, merge, format, check, and push)
231+
just sync-pr 42
232+
```
233+
234+
### Benefits of Docker-based PR Testing:
235+
- **Isolation**: No impact on your local git state
236+
- **Consistency**: Same environment for all PRs
237+
- **Authentication**: Automatically uses your GitHub token
238+
- **Clean slate**: Each command runs in a fresh container
171239

172240
## Troubleshooting
173241

174-
### "Your local changes would be overwritten"
242+
### Docker build fails
175243
```bash
176-
# Stash or commit your changes first
177-
git stash
178-
# or
179-
git commit -am "WIP: save current work"
244+
# Clean up Docker cache and rebuild
245+
docker system prune -f
246+
docker build -t git-ai .
247+
```
248+
249+
### GitHub authentication issues
250+
```bash
251+
# Re-authenticate with GitHub CLI
252+
gh auth logout
253+
gh auth login
254+
255+
# Verify token works
256+
gh auth status
180257
```
181258

182259
### "Branch is up to date" but GitHub shows behind
183260
```bash
184-
# Force fetch to update remote tracking
185-
git fetch origin --force
261+
# The PR container always fetches fresh from origin
262+
# Just run sync-pr again
263+
just sync-pr <PR_NUMBER>
186264
```
187265

188266
### Accidentally pushed broken code
189267
```bash
190-
# Fix the issue, then amend and force push (be careful!)
268+
# Checkout the PR locally, fix, and push
269+
gh pr checkout <PR_NUMBER>
270+
# ... make fixes ...
191271
git commit --amend --no-edit
192-
git push origin <branch> --force-with-lease
272+
git push origin HEAD --force-with-lease
273+
274+
# Then verify with Docker
275+
just pr <PR_NUMBER> "cargo test"
276+
```
277+
278+
### Script not executable
279+
```bash
280+
chmod +x scripts/sync-all-prs
193281
```
194282

195283
## Related Files
196284

285+
- [Justfile](mdc:Justfile) - Contains the `pr` and `sync-pr` commands
286+
- [Dockerfile](mdc:Dockerfile) - Docker configuration for PR testing
197287
- [src/config.rs](mdc:src/config.rs) - Often contains constants that conflict
198288
- [src/model.rs](mdc:src/model.rs) - Model definitions that may conflict
199289
- [Cargo.toml](mdc:Cargo.toml) - Dependency version conflicts
@@ -202,8 +292,33 @@ git push origin <branch> --force-with-lease
202292

203293
After syncing each PR:
204294
- [ ] No merge conflict markers remain in code
205-
- [ ] Code compiles: `cargo check`
206-
- [ ] No new clippy warnings: `cargo clippy`
207-
- [ ] Tests pass: `cargo test`
295+
- [ ] Code compiles: `just pr <NUM> "cargo check"`
296+
- [ ] No new clippy warnings: `just pr <NUM> "cargo clippy"`
297+
- [ ] Tests pass: `just pr <NUM> "cargo test"`
298+
- [ ] Code is formatted: `just pr <NUM> "cargo fmt --all -- --check"`
208299
- [ ] PR branch is pushed to origin
209300
- [ ] GitHub shows PR is up-to-date with base branch
301+
302+
## Quick Reference
303+
304+
```bash
305+
# List open PRs
306+
gh pr list
307+
308+
# Sync a single PR
309+
just sync-pr <PR_NUMBER>
310+
311+
# Sync all PRs
312+
just sync-prs
313+
# or
314+
./scripts/sync-all-prs
315+
316+
# Test a PR without syncing
317+
just pr <PR_NUMBER> "cargo test"
318+
319+
# Manually resolve conflicts
320+
gh pr checkout <PR_NUMBER>
321+
git merge origin/main --no-edit
322+
# ... resolve conflicts ...
323+
git push origin HEAD
324+
```

0 commit comments

Comments
 (0)