No description
  • Python 99.3%
  • Dockerfile 0.7%
Find a file
Zoa Hickenlooper e6fcadf46b Adopt forgejo-mcp as ops/verification tool (not a runtime component)
- .mcp.json: register forgejo-mcp as a Claude Code MCP server (token via
  ${FORGEJO_TOKEN} env expansion, no secret committed).
- tests/test_e2e_forgejo.py: live E2E verification via `forgejo-mcp --cli`,
  skip-gated on FORGEMIRROR_E2E + binary presence + token auth.
- Document rationale in README + design spec: keep MCP out of the sync hot
  path; earmark its workflow tools for the CI/CD subproject.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-09 14:05:33 -04:00
docs/superpowers/specs Adopt forgejo-mcp as ops/verification tool (not a runtime component) 2026-07-09 14:05:33 -04:00
src/forgemirror Initial forgemirror: GitHub->Forgejo migration + one-way mirror-out 2026-07-07 14:10:42 -04:00
tests Adopt forgejo-mcp as ops/verification tool (not a runtime component) 2026-07-09 14:05:33 -04:00
.dockerignore Initial forgemirror: GitHub->Forgejo migration + one-way mirror-out 2026-07-07 14:10:42 -04:00
.env.example Initial forgemirror: GitHub->Forgejo migration + one-way mirror-out 2026-07-07 14:10:42 -04:00
.gitignore Initial forgemirror: GitHub->Forgejo migration + one-way mirror-out 2026-07-07 14:10:42 -04:00
.mcp.json Adopt forgejo-mcp as ops/verification tool (not a runtime component) 2026-07-09 14:05:33 -04:00
docker-compose.yml Initial forgemirror: GitHub->Forgejo migration + one-way mirror-out 2026-07-07 14:10:42 -04:00
Dockerfile Initial forgemirror: GitHub->Forgejo migration + one-way mirror-out 2026-07-07 14:10:42 -04:00
project.md Initial forgemirror: GitHub->Forgejo migration + one-way mirror-out 2026-07-07 14:10:42 -04:00
pyproject.toml Initial forgemirror: GitHub->Forgejo migration + one-way mirror-out 2026-07-07 14:10:42 -04:00
README.md Adopt forgejo-mcp as ops/verification tool (not a runtime component) 2026-07-09 14:05:33 -04:00

forgemirror

One-way GitHub → Forgejo migration plus Forgejo → external mirroring. Forgejo is the source of truth; everything flows outward.

  • migrate — one-time full-content import (git + issues + PRs + comments + labels + milestones + releases + wiki) GitHub → Forgejo.
  • mirrors — native Forgejo push-mirror (git) Forgejo → GitHub, for original sources.
  • sync — Forgejo webhooks → GitHub REST for issues/PRs/comments/labels/milestones (per-repo opt-in).

See docs/ / the design spec for architecture and rationale.

Setup

  1. Copy .env.example.env and fill tokens (see Token scopes below).
  2. uv venv --python 3.11 .venv && uv pip install --python .venv -e ".[dev]"
  3. forgemirror --help

Token scopes

Forgejo token (Settings → Applications): write:repository, read:user, write:organization, write:issue.

GitHub token (fine-grained PAT):

  • migration (read): Contents read, Metadata read.
  • mirror + sync (write): Contents read/write, Issues read/write, Pull requests read/write, Administration read/write (for push-mirror setup), on both the user and the femboyisp org.

Running it (in order)

# 0. Verify credentials + scopes before touching anything.
forgemirror preflight

# 1. Preview, then run the one-time full-content migration (git + issues + PRs +
#    comments + labels + milestones + releases + wiki) for all 140 repos.
forgemirror migrate --dry-run
forgemirror migrate --no-dry-run

# 2. Set up native Forgejo->GitHub push mirrors for original sources only.
forgemirror setup-mirrors --dry-run
forgemirror setup-mirrors --no-dry-run

# 3. Opt specific repos into ongoing metadata sync (per-repo switch).
forgemirror enable femboyisp blackwall
forgemirror repos

# 4. Run the sync service (webhook receiver + hourly reconciliation poller).
forgemirror serve            # or: docker compose up -d forgemirror-sync

Wire up the Forgejo webhook

For each opted-in repo (or as an org-wide default webhook) in Forgejo → Settings → Webhooks → Add → Forgejo:

  • Target URL: http://<sync-host>:8080/webhook
  • HTTP method: POST, content type application/json
  • Secret: the same value as WEBHOOK_SECRET
  • Events: Issues, Issue Comment, Pull Request, Pull Request Comment, Labels, Milestones

The reconciliation poller (runs alongside serve) heals anything a webhook misses, so the system is correct even if a delivery is dropped or the service was down.

Docker

docker compose run --rm migrate preflight
docker compose run --rm migrate migrate --no-dry-run
docker compose run --rm migrate setup-mirrors --no-dry-run
docker compose run --rm migrate enable femboyisp blackwall
docker compose up -d forgemirror-sync

Tests

uv pip install --python .venv -e ".[dev]" && .venv/bin/python -m pytest -q

Live E2E verification (forgejo-mcp)

forgejo-mcp is used as an **operational

  • verification** tool — not a runtime dependency of the sync engine (see the design spec's "forgejo-mcp" note for the rationale). Its --cli mode gives JSON-in/JSON-out access to 60+ Forgejo tools, which tests/test_e2e_forgejo.py uses to assert post-migration state:
go install codeberg.org/goern/forgejo-mcp@latest    # -> ~/go/bin/forgejo-mcp
FORGEMIRROR_E2E=1 FORGEJO_TOKEN=... .venv/bin/python -m pytest tests/test_e2e_forgejo.py -q

The E2E test skips unless FORGEMIRROR_E2E=1, the binary is present, and the token authenticates. It's also registered as a Claude Code MCP server via .mcp.json (secret injected from $FORGEJO_TOKEN), so an assistant can inspect Forgejo directly. Its list_workflow_runs / get_workflow_run tools are earmarked for the CI/CD subproject (#3).

Non-goals

One-way only (no GitHub → Forgejo ongoing sync). No Projects/boards sync. CI/CD is a separate project.