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:repository scope
  • A Codeberg account + personal access token (repo scope)
  • A GitHub PAT with repo scope (if configuring GitHub mirror)
  • curl and jq installed 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 needs repo. 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 8h to 24h if 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.

← Back to Formula  Submit an Incident