NotGit.org / Push-Mirror Setup
Push-Mirror Setup Walkthrough
The exact Forgejo API calls WellSpr.ing used to restore the 32 WellBuilder repos across Railway, Codeberg, and GitHub. Given freely. Adapt as needed.
Prerequisites
- A running Forgejo instance (see formula Step 1)
- A Forgejo API token with
write:repositoryscope - A Codeberg account + personal access token (
reposcope) - A GitHub PAT with
reposcope (if configuring GitHub mirror) curlandjqinstalled locally
1. Configure Codeberg push-mirror (web UI)
In your Forgejo instance, navigate to the repository → Settings → Mirrors → Add Push Mirror. Set:
- Remote URL:
https://codeberg.org/yourorg/yourrepo.git - Username: your Codeberg username
- Password/Token: your Codeberg PAT
- Sync on commit: enabled
- Interval: 8h (or 1h for active projects)
2. Configure Codeberg push-mirror (API)
# Set your variables FORGEJO_URL=https://git.yourproject.org FORGEJO_TOKEN=your_forgejo_api_token FORGEJO_ORG=yourorg REPO=yourrepo CODEBERG_USER=yourusername CODEBERG_TOKEN=your_codeberg_pat # Add Codeberg push-mirror curl -sX POST "$FORGEJO_URL/api/v1/repos/$FORGEJO_ORG/$REPO/push_mirrors" -H "Authorization: token $FORGEJO_TOKEN" -H "Content-Type: application/json" -d "{ "remote_address": "https://codeberg.org/$FORGEJO_ORG/$REPO.git", "remote_username": "$CODEBERG_USER", "remote_password": "$CODEBERG_TOKEN", "sync_on_commit": true, "interval": "8h" }" | jq '.id,.remote_address,.sync_on_commit'
3. Configure GitHub push-mirror (API)
GITHUB_USER=yourgithubusername GITHUB_TOKEN=ghp_your_github_pat curl -sX POST "$FORGEJO_URL/api/v1/repos/$FORGEJO_ORG/$REPO/push_mirrors" -H "Authorization: token $FORGEJO_TOKEN" -H "Content-Type: application/json" -d "{ "remote_address": "https://github.com/$GITHUB_USER/$REPO.git", "remote_username": "$GITHUB_USER", "remote_password": "$GITHUB_TOKEN", "sync_on_commit": true, "interval": "8h" }" | jq '.id,.remote_address'
4. WellBuilder's bulk setup script
This is the exact script WellSpr.ing used to configure push-mirrors for all 32 WellBuilder MCP repos. Given freely. Replace the variables for your own use.
#!/usr/bin/env bash # WellBuilder 32-repo push-mirror setup # WellSpr.ing, April 2026. CC0 — public domain. Use freely. FORGEJO_URL="https://forgejo-production-ba79.up.railway.app" FORGEJO_TOKEN="$(cat /tmp/forgejo_api_token.txt)" ORG="WellBuilder" # All 32 area code repos AREA_CODES="202 206 212 213 214 215 253 303 305 312 313 360 404 407 408 415 425 503 509 510 512 541 602 612 617 619 650 702 713 718 801 971" for AC in $AREA_CODES; do REPO="mcp-$AC" echo "Configuring mirrors for $REPO..." # Codeberg mirror curl -sX POST "$FORGEJO_URL/api/v1/repos/$ORG/$REPO/push_mirrors" -H "Authorization: token $FORGEJO_TOKEN" -H "Content-Type: application/json" -d "{ "remote_address": "https://codeberg.org/$ORG/$REPO.git", "remote_username": "$CODEBERG_USER", "remote_password": "$CODEBERG_TOKEN", "sync_on_commit": true, "interval": "8h" }" | jq -r '.id // .message' sleep 0.5 # rate-limit — be a good API citizen done echo "Done. All $ORG repos now mirror to Codeberg."
5. Verify sync
# Make a test commit to your sovereign primary echo "mirror-test" >> .mirror-test && git add .mirror-test && git commit -m "test: verify push-mirror sync" && git push # Check Codeberg — should appear within seconds (sync_on_commit: true) # Check the push-mirror status via API curl -s "$FORGEJO_URL/api/v1/repos/$ORG/$REPO/push_mirrors" -H "Authorization: token $FORGEJO_TOKEN" | jq '.[].last_error' # null means no errors. Any non-null value = check your token scopes.
6. Failure modes and recovery
- 401 Unauthorized: Token expired or wrong scope. Codeberg needs
repo; GitHub needsrepo. Re-generate and update the mirror config. - Mirror shows "last_error: repository not found": The destination repo doesn't exist. Create it on Codeberg/GitHub first, then re-trigger.
- Push-mirror queued but not syncing: Trigger a manual sync via Forgejo web UI (Settings → Mirrors → Sync Now) or API:
POST /api/v1/repos/{org}/{repo}/push_mirrors/{mirrorId}/sync - Rate limited by GitHub: Increase the interval from
8hto24hif you have many repos. GitHub's API rate limits apply to the push-mirror's authenticated requests.
If GitHub suspends while mirrors are active: The Codeberg mirror continues syncing. Your sovereign primary is unaffected. Set the GitHub mirror to disabled via API (
PATCH /push_mirrors/{id} with "disabled": true) while the suspension resolves. Re-enable when restored.