# Setting Up an Organization

Complete workflow: create organization, configure teams with permissions, add members, create repositories, set up labels, webhooks, and secrets.

## 1. Create Organization

```bash
ORG=$(curl -s -X POST "${FORGEJO_URL}/api/v1/orgs" \
  -H "Authorization: token ${FORGEJO_PAT}" \
  -H "Content-Type: application/json" \
  -d '{
    "username": "{org}",
    "full_name": "My Organization",
    "description": "Building great software together",
    "website": "https://{org}.example.com",
    "location": "Remote",
    "visibility": "public"
  }')
echo "Created org: $(echo "$ORG" | jq -r '.username')"
```

Visibility options:
- `public` — visible to everyone
- `limited` — visible to logged-in users
- `private` — visible only to members

## 2. Create Teams with Different Permissions

```bash
ORG_NAME="{org}"

# Maintainers — full admin access
MAINTAINERS=$(curl -s -X POST "${FORGEJO_URL}/api/v1/orgs/${ORG_NAME}/teams" \
  -H "Authorization: token ${FORGEJO_PAT}" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "{team_name}",
    "description": "Core maintainers with full repository access",
    "permission": "admin",
    "includes_all_repositories": true,
    "can_create_org_repo": true,
    "units": ["repo.code", "repo.issues", "repo.pulls", "repo.releases", "repo.wiki", "repo.projects", "repo.packages"]
  }')
MAINTAINERS_ID=$(echo "$MAINTAINERS" | jq -r '.id')
echo "Created 'maintainers' team (ID: ${MAINTAINERS_ID})"

# Developers — write access
DEVELOPERS=$(curl -s -X POST "${FORGEJO_URL}/api/v1/orgs/${ORG_NAME}/teams" \
  -H "Authorization: token ${FORGEJO_PAT}" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "{team_name}",
    "description": "Developers with write access to assigned repos",
    "permission": "write",
    "includes_all_repositories": false,
    "can_create_org_repo": false,
    "units": ["repo.code", "repo.issues", "repo.pulls", "repo.releases"]
  }')
DEVELOPERS_ID=$(echo "$DEVELOPERS" | jq -r '.id')
echo "Created 'developers' team (ID: ${DEVELOPERS_ID})"

# QA — read access + issue write
QA=$(curl -s -X POST "${FORGEJO_URL}/api/v1/orgs/${ORG_NAME}/teams" \
  -H "Authorization: token ${FORGEJO_PAT}" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "qa",
    "description": "QA team with read access and issue management",
    "permission": "read",
    "includes_all_repositories": true,
    "can_create_org_repo": false,
    "units": ["repo.code", "repo.issues"]
  }')
QA_ID=$(echo "$QA" | jq -r '.id')
echo "Created 'qa' team (ID: ${QA_ID})"

# CI Bots — write access for automated workflows
BOTS=$(curl -s -X POST "${FORGEJO_URL}/api/v1/orgs/${ORG_NAME}/teams" \
  -H "Authorization: token ${FORGEJO_PAT}" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "{team_name}",
    "description": "Service accounts for CI/CD",
    "permission": "write",
    "includes_all_repositories": true,
    "can_create_org_repo": false,
    "units": ["repo.code", "repo.releases", "repo.packages"]
  }')
BOTS_ID=$(echo "$BOTS" | jq -r '.id')
echo "Created 'bots' team (ID: ${BOTS_ID})"
```

Permission levels:
- `read` — view only
- `write` — push commits, manage issues/PRs
- `admin` — full control including settings

Unit types: `repo.code`, `repo.issues`, `repo.pulls`, `repo.releases`, `repo.wiki`, `repo.projects`, `repo.packages`, `repo.ext_wiki`, `repo.ext_issues`.

## 3. Add Members to Teams

```bash
# Add users to maintainers
curl -s -X PUT "${FORGEJO_URL}/api/v1/teams/${MAINTAINERS_ID}/members/{username}" \
  -H "Authorization: token ${FORGEJO_PAT}"
curl -s -X PUT "${FORGEJO_URL}/api/v1/teams/${MAINTAINERS_ID}/members/{username}" \
  -H "Authorization: token ${FORGEJO_PAT}"

# Add users to developers
for user in {user1} {user2} {user3}; do
  curl -s -X PUT "${FORGEJO_URL}/api/v1/teams/${DEVELOPERS_ID}/members/${user}" \
    -H "Authorization: token ${FORGEJO_PAT}"
  echo "Added ${user} to developers"
done

# Add users to QA
curl -s -X PUT "${FORGEJO_URL}/api/v1/teams/${QA_ID}/members/{username}" \
  -H "Authorization: token ${FORGEJO_PAT}"

# Add bot account
curl -s -X PUT "${FORGEJO_URL}/api/v1/teams/${BOTS_ID}/members/{username}" \
  -H "Authorization: token ${FORGEJO_PAT}"

# Verify team membership
curl -s "${FORGEJO_URL}/api/v1/teams/${DEVELOPERS_ID}/members" \
  -H "Authorization: token ${FORGEJO_PAT}" | jq '.[].login'
```

## 4. Create Repositories

```bash
# Create main project repo
curl -s -X POST "${FORGEJO_URL}/api/v1/orgs/${ORG_NAME}/repos" \
  -H "Authorization: token ${FORGEJO_PAT}" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "{repo}",
    "description": "Backend API service",
    "private": false,
    "auto_init": true,
    "default_branch": "{branch}",
    "gitignore": "{gitignore_template}",
    "license": "MIT"
  }'

# Create frontend repo
curl -s -X POST "${FORGEJO_URL}/api/v1/orgs/${ORG_NAME}/repos" \
  -H "Authorization: token ${FORGEJO_PAT}" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "{repo}",
    "description": "Frontend web application",
    "private": false,
    "auto_init": true,
    "default_branch": "{branch}",
    "gitignore": "{gitignore_template}",
    "license": "MIT"
  }'

# Create infrastructure repo (private)
curl -s -X POST "${FORGEJO_URL}/api/v1/orgs/${ORG_NAME}/repos" \
  -H "Authorization: token ${FORGEJO_PAT}" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "{repo}",
    "description": "Infrastructure as code and deployment configs",
    "private": true,
    "auto_init": true,
    "default_branch": "{branch}"
  }'

# Add repos to the developers team (if not includes_all_repositories)
curl -s -X PUT "${FORGEJO_URL}/api/v1/teams/${DEVELOPERS_ID}/repos/${ORG_NAME}/{repo}" \
  -H "Authorization: token ${FORGEJO_PAT}"
curl -s -X PUT "${FORGEJO_URL}/api/v1/teams/${DEVELOPERS_ID}/repos/${ORG_NAME}/{repo}" \
  -H "Authorization: token ${FORGEJO_PAT}"
# Note: infrastructure NOT added to developers — only maintainers have access
```

## 5. Set Up Org-Level Labels

Forgejo labels are per-repository. Create a consistent label set across repos:

```bash
# Define standard labels
LABELS='[
  {"name": "type/bug", "color": "#d73a4a", "description": "Something is broken"},
  {"name": "type/feature", "color": "#0075ca", "description": "New feature request"},
  {"name": "type/enhancement", "color": "#a2eeef", "description": "Improvement to existing feature"},
  {"name": "type/docs", "color": "#0075ca", "description": "Documentation changes"},
  {"name": "type/chore", "color": "#e4e669", "description": "Maintenance and housekeeping"},
  {"name": "priority/critical", "color": "#b60205", "description": "Must be fixed immediately"},
  {"name": "priority/high", "color": "#d93f0b", "description": "Important, fix soon"},
  {"name": "priority/medium", "color": "#fbca04", "description": "Normal priority"},
  {"name": "priority/low", "color": "#0e8a16", "description": "Nice to have"},
  {"name": "state/in-progress", "color": "#7057ff", "description": "Currently being worked on"},
  {"name": "state/review", "color": "#008672", "description": "Ready for review"},
  {"name": "state/blocked", "color": "#b60205", "description": "Blocked by dependency"}
]'

# Apply labels to each repo
for REPO in {repo1} {repo2} {repo3}; do
  echo "Setting up labels for ${REPO}..."
  echo "$LABELS" | jq -c '.[]' | while read -r label; do
    curl -s -X POST "${FORGEJO_URL}/api/v1/repos/${ORG_NAME}/${REPO}/labels" \
      -H "Authorization: token ${FORGEJO_PAT}" \
      -H "Content-Type: application/json" \
      -d "$label" > /dev/null
  done
  echo "  Done."
done
```

## 6. Configure Org-Level Webhooks

Organization webhooks fire for events across all org repositories:

```bash
# Create org-level webhook for Slack/Mattermost notifications
curl -s -X POST "${FORGEJO_URL}/api/v1/orgs/${ORG_NAME}/hooks" \
  -H "Authorization: token ${FORGEJO_PAT}" \
  -H "Content-Type: application/json" \
  -d '{
    "type": "forgejo",
    "config": {
      "url": "https://hooks.example.com/org-events",
      "content_type": "json",
      "secret": "{webhook_secret}"
    },
    "events": ["push", "pull_request", "issues", "release", "repository"],
    "active": true
  }'

# List org webhooks
curl -s "${FORGEJO_URL}/api/v1/orgs/${ORG_NAME}/hooks" \
  -H "Authorization: token ${FORGEJO_PAT}" | jq '.[] | {id, type, url: .config.url, events, active}'
```

## 7. Set Up Org-Level Secrets and Variables

Secrets and variables for Forgejo Actions (CI/CD):

```bash
# Create an org-level secret (for Actions workflows)
curl -s -X PUT "${FORGEJO_URL}/api/v1/orgs/${ORG_NAME}/actions/secrets/{secret_name}" \
  -H "Authorization: token ${FORGEJO_PAT}" \
  -H "Content-Type: application/json" \
  -d '{"data": "{secret_value}"}'

curl -s -X PUT "${FORGEJO_URL}/api/v1/orgs/${ORG_NAME}/actions/secrets/{secret_name}" \
  -H "Authorization: token ${FORGEJO_PAT}" \
  -H "Content-Type: application/json" \
  -d '{"data": "{secret_value}"}'

# Create org-level variables
curl -s -X POST "${FORGEJO_URL}/api/v1/orgs/${ORG_NAME}/actions/variables/{variable_name}" \
  -H "Authorization: token ${FORGEJO_PAT}" \
  -H "Content-Type: application/json" \
  -d '{"value": "{variable_value}"}'

curl -s -X POST "${FORGEJO_URL}/api/v1/orgs/${ORG_NAME}/actions/variables/{variable_name}" \
  -H "Authorization: token ${FORGEJO_PAT}" \
  -H "Content-Type: application/json" \
  -d '{"value": "{variable_value}"}'

# List org secrets (names only — values are never exposed)
curl -s "${FORGEJO_URL}/api/v1/orgs/${ORG_NAME}/actions/secrets" \
  -H "Authorization: token ${FORGEJO_PAT}" | jq '.[].name'

# List org variables
curl -s "${FORGEJO_URL}/api/v1/orgs/${ORG_NAME}/actions/variables" \
  -H "Authorization: token ${FORGEJO_PAT}" | jq '.[] | {name, data: .value}'
```

## Complete Setup Script

```bash
#!/bin/bash
set -euo pipefail

ORG_NAME="{org}"

echo "=== Creating organization: ${ORG_NAME} ==="

# 1. Create org
curl -s -X POST "${FORGEJO_URL}/api/v1/orgs" \
  -H "Authorization: token ${FORGEJO_PAT}" \
  -H "Content-Type: application/json" \
  -d '{
    "username": "'"${ORG_NAME}"'",
    "full_name": "My Organization",
    "description": "Building great software",
    "visibility": "public"
  }' | jq -r '.username'

# 2. Create teams
for TEAM_DEF in \
  '{"name":"maintainers","permission":"admin","includes_all_repositories":true,"can_create_org_repo":true}' \
  '{"name":"developers","permission":"write","includes_all_repositories":false,"can_create_org_repo":false}' \
  '{"name":"qa","permission":"read","includes_all_repositories":true,"can_create_org_repo":false}'; do
  TEAM_NAME=$(echo "$TEAM_DEF" | jq -r '.name')
  RESULT=$(curl -s -X POST "${FORGEJO_URL}/api/v1/orgs/${ORG_NAME}/teams" \
    -H "Authorization: token ${FORGEJO_PAT}" \
    -H "Content-Type: application/json" \
    -d "$TEAM_DEF")
  echo "Created team '${TEAM_NAME}' (ID: $(echo "$RESULT" | jq -r '.id'))"
done

# 3. Create repos
for REPO_DEF in \
  '{"name":"backend","description":"Backend API","auto_init":true,"default_branch":"master"}' \
  '{"name":"frontend","description":"Frontend app","auto_init":true,"default_branch":"master"}'; do
  REPO_NAME=$(echo "$REPO_DEF" | jq -r '.name')
  curl -s -X POST "${FORGEJO_URL}/api/v1/orgs/${ORG_NAME}/repos" \
    -H "Authorization: token ${FORGEJO_PAT}" \
    -H "Content-Type: application/json" \
    -d "$REPO_DEF" > /dev/null
  echo "Created repo '${REPO_NAME}'"
done

echo "=== Organization setup complete ==="
```
