# Complete PR Review Cycle

Full lifecycle of a pull request: create branch, open PR, request reviewers, submit review with inline comments, address feedback, approve, merge, and clean up.

## 1. Create a Branch

```bash
curl -s -X POST "${FORGEJO_URL}/api/v1/repos/{owner}/{repo}/branches" \
  -H "Authorization: token ${FORGEJO_PAT}" \
  -H "Content-Type: application/json" \
  -d '{
    "new_branch_name": "{new_branch}",
    "old_branch_name": "{base_branch}"
  }'
```

## 2. Make Changes on the Branch

Create or update files on the new branch:

```bash
# Create a new file
curl -s -X POST "${FORGEJO_URL}/api/v1/repos/{owner}/{repo}/contents/path/to/file.txt" \
  -H "Authorization: token ${FORGEJO_PAT}" \
  -H "Content-Type: application/json" \
  -d '{
    "content": "'$(echo -n "file contents here" | base64)'",
    "message": "Add new file",
    "branch": "{branch}"
  }'

# Update an existing file (requires current SHA)
FILE_INFO=$(curl -s "${FORGEJO_URL}/api/v1/repos/{owner}/{repo}/contents/path/to/existing.txt?ref={branch}" \
  -H "Authorization: token ${FORGEJO_PAT}")
FILE_SHA=$(echo "$FILE_INFO" | jq -r '.sha')

curl -s -X PUT "${FORGEJO_URL}/api/v1/repos/{owner}/{repo}/contents/path/to/existing.txt" \
  -H "Authorization: token ${FORGEJO_PAT}" \
  -H "Content-Type: application/json" \
  -d '{
    "content": "'$(echo -n "updated contents" | base64)'",
    "message": "Update existing file",
    "branch": "{branch}",
    "sha": "'"${FILE_SHA}"'"
  }'
```

## 3. Create the Pull Request

```bash
PR=$(curl -s -X POST "${FORGEJO_URL}/api/v1/repos/{owner}/{repo}/pulls" \
  -H "Authorization: token ${FORGEJO_PAT}" \
  -H "Content-Type: application/json" \
  -d '{
    "title": "feat: add new feature",
    "body": "## Summary\n\nDescription of changes\n\nCloses #42",
    "head": "{head_branch}",
    "base": "{base_branch}",
    "labels": [1, 5],
    "milestone": 3
  }')
PR_INDEX=$(echo "$PR" | jq -r '.number')
echo "Created PR #${PR_INDEX}"
```

## 4. Request Reviewers

```bash
curl -s -X POST "${FORGEJO_URL}/api/v1/repos/{owner}/{repo}/pulls/${PR_INDEX}/requested_reviewers" \
  -H "Authorization: token ${FORGEJO_PAT}" \
  -H "Content-Type: application/json" \
  -d '{
    "reviewers": ["{reviewer1}", "{reviewer2}"],
    "team_reviewers": ["backend-team"]
  }'
```

## 5. Check CI Status

Poll commit statuses until all checks complete:

```bash
HEAD_SHA=$(echo "$PR" | jq -r '.head.sha')

# Get combined status
STATUS=$(curl -s "${FORGEJO_URL}/api/v1/repos/{owner}/{repo}/commits/${HEAD_SHA}/status" \
  -H "Authorization: token ${FORGEJO_PAT}")
echo "Combined state: $(echo "$STATUS" | jq -r '.state')"
# Possible states: pending, success, failure, error

# Get individual statuses
curl -s "${FORGEJO_URL}/api/v1/repos/{owner}/{repo}/commits/${HEAD_SHA}/statuses" \
  -H "Authorization: token ${FORGEJO_PAT}" | jq '.[] | {context, state, target_url}'
```

Poll until complete:

```bash
while true; do
  STATE=$(curl -s "${FORGEJO_URL}/api/v1/repos/{owner}/{repo}/commits/${HEAD_SHA}/status" \
    -H "Authorization: token ${FORGEJO_PAT}" | jq -r '.state')
  echo "CI status: $STATE"
  [ "$STATE" = "success" ] || [ "$STATE" = "failure" ] || [ "$STATE" = "error" ] && break
  sleep 30
done
```

## 6. Submit a Review with Inline Comments

```bash
curl -s -X POST "${FORGEJO_URL}/api/v1/repos/{owner}/{repo}/pulls/${PR_INDEX}/reviews" \
  -H "Authorization: token ${FORGEJO_PAT}" \
  -H "Content-Type: application/json" \
  -d '{
    "event": "REQUEST_CHANGES",
    "body": "A few things to address before we can merge.",
    "comments": [
      {
        "path": "path/to/file.txt",
        "body": "This should handle the error case — what happens if the input is null?",
        "new_position": 15
      },
      {
        "path": "path/to/file.txt",
        "body": "Consider extracting this into a helper function for reusability.",
        "new_position": 42
      }
    ]
  }'
```

Review event types:
- `APPROVED` — approve the PR
- `REQUEST_CHANGES` — request changes
- `COMMENT` — general comment without approval/rejection

## 7. Address Review Feedback

Push fixes to the same branch:

```bash
# Get current file content and SHA
FILE_INFO=$(curl -s "${FORGEJO_URL}/api/v1/repos/{owner}/{repo}/contents/path/to/file.txt?ref={branch}" \
  -H "Authorization: token ${FORGEJO_PAT}")
FILE_SHA=$(echo "$FILE_INFO" | jq -r '.sha')

# Update the file with fixes
curl -s -X PUT "${FORGEJO_URL}/api/v1/repos/{owner}/{repo}/contents/path/to/file.txt" \
  -H "Authorization: token ${FORGEJO_PAT}" \
  -H "Content-Type: application/json" \
  -d '{
    "content": "'$(echo -n "fixed contents with error handling" | base64)'",
    "message": "fix: address review feedback",
    "branch": "{branch}",
    "sha": "'"${FILE_SHA}"'"
  }'
```

## 8. Re-request Review

After addressing feedback, dismiss stale reviews and re-request:

```bash
# List existing reviews
REVIEWS=$(curl -s "${FORGEJO_URL}/api/v1/repos/{owner}/{repo}/pulls/${PR_INDEX}/reviews" \
  -H "Authorization: token ${FORGEJO_PAT}")

# Dismiss a stale review (by review ID)
REVIEW_ID=$(echo "$REVIEWS" | jq -r '.[0].id')
curl -s -X POST "${FORGEJO_URL}/api/v1/repos/{owner}/{repo}/pulls/${PR_INDEX}/reviews/${REVIEW_ID}/dismissals" \
  -H "Authorization: token ${FORGEJO_PAT}" \
  -H "Content-Type: application/json" \
  -d '{"message": "Feedback addressed in latest commits"}'

# Re-request review
curl -s -X POST "${FORGEJO_URL}/api/v1/repos/{owner}/{repo}/pulls/${PR_INDEX}/requested_reviewers" \
  -H "Authorization: token ${FORGEJO_PAT}" \
  -H "Content-Type: application/json" \
  -d '{"reviewers": ["{reviewer}"]}'
```

## 9. Approve the PR

```bash
curl -s -X POST "${FORGEJO_URL}/api/v1/repos/{owner}/{repo}/pulls/${PR_INDEX}/reviews" \
  -H "Authorization: token ${FORGEJO_PAT}" \
  -H "Content-Type: application/json" \
  -d '{
    "event": "APPROVED",
    "body": "LGTM! Great work."
  }'
```

## 10. Merge the PR

```bash
curl -s -X POST "${FORGEJO_URL}/api/v1/repos/{owner}/{repo}/pulls/${PR_INDEX}/merge" \
  -H "Authorization: token ${FORGEJO_PAT}" \
  -H "Content-Type: application/json" \
  -d '{
    "Do": "squash",
    "MergeTitleField": "feat: add new feature (#'"${PR_INDEX}"')",
    "MergeMessageField": "Description of the squashed changes",
    "delete_branch_after_merge": true
  }'
```

Merge strategies (`Do` field):
- `merge` — merge commit
- `rebase` — rebase and fast-forward
- `rebase-merge` — rebase and create merge commit
- `squash` — squash all commits into one
- `manually-merged` — mark as manually merged (set `merge_commit_id`)

## 11. Clean Up Branch (if not auto-deleted)

```bash
curl -s -X DELETE "${FORGEJO_URL}/api/v1/repos/{owner}/{repo}/branches/{branch}" \
  -H "Authorization: token ${FORGEJO_PAT}"
```

## 12. Verify Merge

```bash
# Check PR state
curl -s "${FORGEJO_URL}/api/v1/repos/{owner}/{repo}/pulls/${PR_INDEX}" \
  -H "Authorization: token ${FORGEJO_PAT}" | jq '{state, merged, merged_by: .merged_by.login}'

# Check that linked issue was closed
curl -s "${FORGEJO_URL}/api/v1/repos/{owner}/{repo}/issues/{index}" \
  -H "Authorization: token ${FORGEJO_PAT}" | jq '{state, title}'
```
