Rewrite reposyncer in Python and enforce repo settings #325

Merged
Doridian merged 2 commits from reposyncer-python into main 2026-10-09 14:14:37 -07:00
Owner

Rewrites reposyncer.sh as a tested Python package. It now also enforces repo settings and branch protection.

Changes

  • File sync works as before: managed workflows, renovate.json, and the .disable / .nosync opt-outs. The list of which file enables which pipeline now lives in reposyncer.json.
  • Merge settings from maid are applied everywhere: squash only, rebase-update allowed, delete branch after merge, squash as default merge style, merge as default update style.
  • Branch protection: main becomes the only rule on each repo. Its settings come from reposyncer.json exactly: push disabled, no merge whitelist, rule applies to admins, everything else at Forgejo defaults. All other rules are deleted.
  • Required checks are exactly the managed workflows (<workflow name> / * (pull_request)). A workflow only becomes required once it is on main and still in the generated baseline, so a reposyncer PR that adds, removes or renames a workflow is never blocked by its own check.
  • Dry-run prints every planned change and doesn't change anything. The old script deleted the stale sync branch even in dry-run.
  • Other changes:
    • Repo listing paginates past 100 repos.
    • Mirror and empty repos are skipped.
    • One repo failing doesn't stop the rest; the job fails at the end with a list of failed repos.
    • The token is kept out of git argv.
    • Added a --repo option to sync a single repo.
  • CI: new test job runs ruff and pytest, including end-to-end tests against a local bare git repo and a fake forge.

Before merging

The first live run will delete protection rules on other branches and remove any hand-added required checks on main in every synced org. Please review this PR's dry-run log for those changes. The live token also needs admin on every synced repo.

🤖 Generated with Claude Code

https://claude.ai/code/session_01Ez959LAFLSHBaLnc3KeAad

Rewrites `reposyncer.sh` as a tested Python package. It now also enforces repo settings and branch protection. ## Changes - **File sync** works as before: managed workflows, `renovate.json`, and the `.disable` / `.nosync` opt-outs. The list of which file enables which pipeline now lives in `reposyncer.json`. - **Merge settings** from maid are applied everywhere: squash only, rebase-update allowed, delete branch after merge, squash as default merge style, merge as default update style. - **Branch protection**: `main` becomes the only rule on each repo. Its settings come from `reposyncer.json` exactly: push disabled, no merge whitelist, rule applies to admins, everything else at Forgejo defaults. All other rules are deleted. - **Required checks** are exactly the managed workflows (`<workflow name> / * (pull_request)`). A workflow only becomes required once it is on `main` and still in the generated baseline, so a reposyncer PR that adds, removes or renames a workflow is never blocked by its own check. - **Dry-run** prints every planned change and doesn't change anything. The old script deleted the stale sync branch even in dry-run. - **Other changes**: - Repo listing paginates past 100 repos. - Mirror and empty repos are skipped. - One repo failing doesn't stop the rest; the job fails at the end with a list of failed repos. - The token is kept out of git argv. - Added a `--repo` option to sync a single repo. - **CI**: new `test` job runs `ruff` and `pytest`, including end-to-end tests against a local bare git repo and a fake forge. ## Before merging The first live run will delete protection rules on other branches and remove any hand-added required checks on `main` in every synced org. Please review this PR's dry-run log for those changes. The live token also needs admin on every synced repo. 🤖 Generated with [Claude Code](https://claude.com/claude-code) https://claude.ai/code/session_01Ez959LAFLSHBaLnc3KeAad
Rewrite reposyncer in Python and enforce repo settings
Some checks failed
Run reposyncer / test (pull_request) Successful in 12s
Run reposyncer / reposyncer (pull_request) Has been cancelled
NodeJS check / check-nodejs (pull_request) Has been cancelled
Run renovate / renovate (pull_request) Has been cancelled
baaec152e9
- Port reposyncer.sh to a tested Python package (run via uv)
- Enforce merge settings and an exact, single main branch protection
  rule from reposyncer.json
- Require every managed workflow as a status check once it is on main
- Dry-run now prints planned settings changes and never mutates anything

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Ez959LAFLSHBaLnc3KeAad
Ignore nix build results
All checks were successful
NodeJS check / check-nodejs (pull_request) Successful in 1m11s
Run reposyncer / test (pull_request) Successful in 10s
Run renovate / renovate (pull_request) Successful in 6m5s
Run reposyncer / reposyncer (pull_request) Successful in 17s
c8ff35d96b
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Ez959LAFLSHBaLnc3KeAad
Doridian deleted branch reposyncer-python 2026-10-09 14:14:37 -07:00
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
FoxDen/maid!325
No description provided.