# quine-manifestDeclares where every Quine repo lives (this repo: forge.in.quineglobal.com/quine-global/quine-manifest) on GitHub and on Forgejo(forge.in.quineglobal.com), and a script that makes both match.| Bucket | GitHub org | Forgejo org | Notes ||----------|-------------------------|-------------------------|-------------------------------|| main | `quine-global` | `quine-global` | || labs | `quine-global-labs` | `quine-global-labs` | || boneyard | `quine-global-boneyard` | `quine-global-boneyard` | retired repos (not archived) |By default Forgejo is primary and push-mirrors to GitHub (`primary = "forgejo"`).With `primary = "github"`, Forgejo holds a pull mirror instead.## UseNeeds Python 3.11+ and a logged-in `gh`.```shpython3.14 quine-repos.py # plan: show drift, change nothingpython3.14 quine-repos.py --apply # make it sopython3.14 quine-repos.py --apply ncdu # only some repos```To move a repo, change its `bucket` and apply: it's transferred on both sides,and its push mirror is repointed.## Credentials- Forgejo admin token: `$FORGEJO_TOKEN` or `~/.config/forgejo/token`.- GitHub admin actions (transfer, archive) and imports: your `gh` login.- Push mirrors: each bucket's `mirror_token_file`, a GitHub fine-grained tokenwhose resource owner is that bucket's GitHub org (Contents + Workflowsread/write). Fine-grained tokens cover one org, so each bucket needs its own.The `main` token expires 2027-10-12.Every repo in a bucket org (on either host) must be listed in `manifest.toml`;the script exits with an error before doing anything if it finds one that isn't.Upstream mirrors (`upstream = …`) have Forgejo Actions off unless they say`actions = true`: they carry upstream's own CI, which would sit "waiting"forever for runners we don't have.## Renovate[Renovate](https://docs.renovatebot.com/) opens dependency update PRs on theforge (it runs on the forge VM: petersweb-infra's `nixos/renovate.nix` and`docs/RENOVATE.md`). For every repo it covers, `--apply` gives the forge's`renovate` account write access and adds the webhook that wakes it(`[renovate]` in `manifest.toml`). Renovate then finds the repo itself andopens a "Configure Renovate" PR adding a `renovate.json` that extends[`renovate/default.json`](renovate/default.json), the shared defaults: theschedule (Monday mornings), Forgejo workflows, and leaving our own forgeimages to their deploy workflows. Nothing else happens in a repo until thatPR is merged; put anything repo-specific in its own `renovate.json`.It covers our own repos in the main and labs buckets by default, not forks(`forked_from`: their dependencies come with upstream merges) or mirrors. Arepo's `renovate = true` or `false` overrides that. Turning it off is onlyreported: remove the collaborator and webhook by hand.## What it won't do- Delete repositories. A repo that's the wrong kind (a regular repo that shouldbe a pull mirror) is reported for you to fix by hand.- Create GitHub orgs (GitHub has no API for that).- Full imports that outlast nginx's 60 s proxy timeout leave the repo stuck"migrating" — use `import = "code"` for repos with big release assets.Don't click "Cancel migration" on a stuck repo: it deletes the repo.