# Complex Workflows (Cookbook)

Multi-step workflows that require multiple API calls in sequence. Each recipe is a complete, end-to-end guide with working `curl` commands.

All examples use:
- `${FORGEJO_URL}` — base URL of your Forgejo instance
- `${FORGEJO_PAT}` — personal access token for authentication

## Recipes

| Recipe | Description |
|--------|-------------|
| [PR Review Cycle](pr-review-cycle.md) | Full PR lifecycle: create branch, open PR, request review, submit review with inline comments, address feedback, approve, merge, clean up |
| [Issue Lifecycle](issue-lifecycle.md) | Create issue with labels/milestone, assign, comment, update state, link to PR, close, verify timeline |
| [CI Status Check](ci-status-check.md) | Check if a PR passes all CI quality gates: get commit status, find failing jobs, access logs, check branch protection |
| [Release Workflow](release-workflow.md) | Verify PRs merged, create tag, create release with changelog, upload assets, close milestone |
| [Branch Protection Setup](branch-protection-setup.md) | Configure production-ready branch protection: required approvals, status checks, merge whitelist, push restrictions |
| [Org Setup](org-setup.md) | Create organization, teams with permissions, add members, create repos, set up labels, webhooks, secrets |
| [Fork & Contribute](fork-contribute.md) | External contributor flow: fork, branch, make changes, create cross-repo PR, sync fork with upstream |
| [Server-Side Rebase](server-side-rebase.md) | Rebase a PR without cloning: check if behind, detect conflicts, update branch via API, handle failures |
| [Automerge Workflow](automerge-workflow.md) | Enable automerge on a PR, monitor CI, cancel if needed, verify merge after CI passes |

## Common Patterns

### Error Handling

Always check HTTP status codes. Forgejo returns:
- `200` / `201` — success
- `403` — insufficient permissions
- `404` — resource not found
- `409` — conflict (e.g., branch already exists, merge conflict)
- `422` — validation error

```bash
response=$(curl -s -w "\n%{http_code}" "${FORGEJO_URL}/api/v1/..." \
  -H "Authorization: token ${FORGEJO_PAT}")
body=$(echo "$response" | head -n -1)
status=$(echo "$response" | tail -n 1)

if [ "$status" -ge 400 ]; then
  echo "Error ($status): $(echo "$body" | jq -r '.message // .error // .')"
  exit 1
fi
```

### Pagination

List endpoints return paginated results. Use `page` and `limit` query parameters:

```bash
page=1
while true; do
  results=$(curl -s "${FORGEJO_URL}/api/v1/repos/{owner}/{repo}/issues?state=open&page=${page}&limit=50" \
    -H "Authorization: token ${FORGEJO_PAT}")
  count=$(echo "$results" | jq length)
  [ "$count" -eq 0 ] && break
  echo "$results" | jq -r '.[].title'
  page=$((page + 1))
done
```

### JSON Parsing with jq

All examples assume `jq` is available. Common patterns:

```bash
# Extract single field
echo "$response" | jq -r '.id'

# Extract from array
echo "$response" | jq -r '.[].name'

# Filter array
echo "$response" | jq '[.[] | select(.state == "open")]'
```
