- Python 98.7%
- Shell 1.3%
| examples | ||
| src/forgejo_repo_tools | ||
| tests | ||
| .gitignore | ||
| install.sh | ||
| pyproject.toml | ||
| README.md | ||
forgejo-repo-tools
Safe command-line tools for making Forgejo the canonical Git server while optionally replicating public repositories to GitHub, Codeberg, GitLab.com and a configurable GitGud-compatible GitLab host.
The four command names are:
make-private-repo [name]
make-public-repo [name]
push-private
push-public
The preferred Forgejo SSH remote defaults to:
primegit:tarsow/REPOSITORY.git
That assumes this SSH config:
Host primegit
HostName git.primeforge.net
User git
Port 2223
IdentityFile ~/.ssh/id_ed25519
IdentitiesOnly yes
Install
From this repository:
./install.sh
Equivalent manual install:
uv tool install --reinstall .
mkdir -p ~/.config/forgejo-repo-tools
chmod 700 ~/.config/forgejo-repo-tools
cp examples/config.toml ~/.config/forgejo-repo-tools/config.toml
cp examples/secrets.toml.example ~/.config/forgejo-repo-tools/secrets.toml
chmod 600 ~/.config/forgejo-repo-tools/secrets.toml
Ensure ~/.local/bin is on PATH for Bash and Zsh.
Configuration
Edit:
~/.config/forgejo-repo-tools/config.toml
~/.config/forgejo-repo-tools/secrets.toml
The config directory must not be group/world accessible. The secrets file must be exactly 0600.
Use examples/config.toml as the non-secret config. Store tokens only in secrets.toml or environment variables:
FRT_FORGEJO_TOKEN
FRT_GITHUB_TOKEN
FRT_CODEBERG_TOKEN
FRT_GITLAB_TOKEN
FRT_GITGUD_TOKEN
Other overrides are available as FRT_<PROVIDER>_<KEY>, for example FRT_GITGUD_URL or FRT_GITHUB_ENABLED.
Command Behavior
make-private-repo [name]:
- Requires an existing Git repository with at least one commit.
- Creates or reuses a private Forgejo repository.
- Refuses if the Forgejo repository already exists as public.
- Sets
originto the configured Forgejo remote. - Preserves any previous
originasgithub,codeberg,gitlab,gitgud, ororigin-backup. - Pushes local branches with
git push --all originand tags withgit push --tags origin. - Verifies the final Forgejo repository is private and has no public push mirrors.
make-public-repo [name]:
- Performs the same local Git safety checks.
- Creates or reuses a public Forgejo repository.
- Creates empty public repositories on enabled providers.
- Configures Forgejo push mirrors to enabled providers.
- Registers Forgejo-generated mirror SSH public keys as write-enabled deploy keys when Forgejo exposes the key through its API.
- Pushes local branches and tags to Forgejo.
- Reports Forgejo and each provider separately. Replication is not globally transactional.
push-private:
- Derives the repository name from
origin. - Requires
originto exactly match the configured Forgejo remote template. - Verifies Forgejo says the repository is private.
- Refuses if any public push mirror exists.
- Pushes only to Forgejo.
push-public:
- Requires exact Forgejo
origin. - Verifies Forgejo says the repository is public.
- Verifies all enabled public push mirrors exist.
- Pushes local branches and tags to Forgejo.
- Triggers mirror sync when the live Forgejo OpenAPI advertises a sync endpoint; otherwise it reports that periodic sync will handle it.
Safety Decisions
The tools never run git add ., never create commits, never push private repositories to public providers, and never place API tokens in Git remote URLs.
Local pushes use --all and --tags, not git push --mirror. Forgejo server-side push mirrors may force-push depending on Forgejo’s own mirror implementation; Forgejo’s documentation warns that push mirrors can overwrite changes on the destination, so external repositories should be treated as replicas.
The tool checks Forgejo’s live OpenAPI document at:
https://git.primeforge.net/swagger.v1.json
and refuses to guess push-mirror API endpoints that are not advertised.
Token Scopes
Do not paste tokens into chat. Create them in each provider UI and store them locally in ~/.config/forgejo-repo-tools/secrets.toml.
Forgejo:
- Create at
Settings -> Applications -> Generate New Token. - Required:
read:repository,write:repository. - For organization owners, also grant organization access to the selected organization.
- Forgejo’s docs describe token scopes and repository/organization access: https://forgejo.org/docs/latest/user/token-scope/
GitHub:
- Fine-grained PAT: repository Administration read/write for the target owner, enough to create public repos and deploy keys.
- Classic PAT alternative:
public_repofor public repositories. - GitHub repository and deploy-key API docs: https://docs.github.com/en/rest/repos/repos and https://docs.github.com/en/rest/deploy-keys/deploy-keys
Codeberg:
- Codeberg is Forgejo-compatible.
- Required:
read:repository,write:repositoryfor the target owner.
GitLab.com:
- Personal access token with
apiis required for project creation and deploy-key management. write_repositoryalone is enough for Git writes but not enough for project/deploy-key API administration.- GitLab project and deploy-key API docs: https://docs.gitlab.com/api/projects/ and https://docs.gitlab.com/api/deploy_keys/
GitGud:
- Configure
gitgud.urlandgitgud.namespace. - The tool treats GitGud as GitLab API-compatible and verifies behavior through the configured API host.
- Use the minimum GitGud token scope equivalent to GitLab
apifor repository creation and deploy-key administration.
Provider Steps That May Need Manual Work
Forgejo can generate a distinct SSH key for each push mirror. When the push-mirror API response exposes the public key, this tool registers it as a write-enabled deploy key on the destination repository.
If Forgejo 15 on your instance does not expose that public key through the API, the tool reports a provider failure instead of pretending the mirror is complete. In that case:
- Open the Forgejo repository.
- Go to
Settings -> Repository -> Mirror Settings. - Copy the push mirror public key.
- Add it as a write-enabled deploy key on the destination provider.
- Rerun
make-public-repo; it will reuse existing repositories and mirrors.
Migration From the Old Sourced Bash Script
- Remove any
.bashrcor.zshrcline that sources the oldforgejo-repo-tools.sh. - Install this package with
./install.sh. - Put
~/.local/binon your shellPATH. - Move old shell variables into
~/.config/forgejo-repo-tools/config.tomlandsecrets.toml. - Run
make-private-repo --dry-runormake-public-repo --dry-runinside an existing repository before the first real run.
Existing Forgejo repositories and remotes are reused. If origin points somewhere else, the tool preserves it under a provider-specific backup name before setting Forgejo as canonical origin.
Development and Tests
Run:
PYTHONPATH=src python3 -m unittest discover -s tests
python3 -m compileall src tests
Provider APIs are mocked in tests. The tests create only temporary local Git repositories.
ShellCheck is not required because the implementation is Python. The installer is POSIX shell and intentionally small.
Architecture
cli.pymaps the four executable names to operations and handles exit codes.config.pyloads TOML config, enforces permissions and applies environment overrides.git.pyowns local Git checks, origin preservation and local pushes.forgejo.pyowns Forgejo repository and push-mirror API behavior, including live OpenAPI endpoint verification.providers.pyowns GitHub, Codeberg and GitLab-compatible provider APIs.operations.pycomposes the safety checks into the four command workflows.