- Rust 98.9%
- Dockerfile 1.1%
| .github/workflows | ||
| src | ||
| .dockerignore | ||
| .gitignore | ||
| Cargo.lock | ||
| Cargo.toml | ||
| Dockerfile | ||
| LICENSE.md | ||
| README.md | ||
| rustfmt.toml | ||
nerhegeb
A service that continuously mirrors your GitHub account to Forgejo, but keeping GitHub as the source of truth. For those who desire to move away from GitHub but can't.
nerhegeb is a service that automatically mirrors repositories from your GitHub account to a Forgejo instance. This is in a one-way fashion, as GitHub is kept as the source of truth. It also synchronizes changes of metadata like visibility after a repository is already mirrored. This can be used to automatically back up all your repositories to your own forge.
Currently nerhegeb supports the following:
- Automatic mirroring of public and private repositories
- Control mirroring on a per-repo basis by adding the
nerhegebtopic - Synchronizing metadata if changed after mirror creation
You can of course configure what repository types are mirrored, and how the topic impacts them. It will also cease touching repositories which are not (or no longer) a mirror on your Forgejo instance.
To see nerhegeb in action, check out my account on my personal git forge which uses nerhegeb to mirror this here GitHub account.
deployment
Deployment is currently only supported via docker. A docker image is available at ghcr.io/virtcode/nerhegeb:main for both x86_64 and arm64. An example docker compose service could look like the following.
services:
nerhegeb:
image: ghcr.io/virtcode/nerhegeb:main
restart: unless-stopped
environment:
# forgejo authentication
FORGEJO_URL: https://my-forge-domain.tld
FORGEJO_TOKEN: my-forgejo-token
FORGEJO_COOKIE: i_like_gitea=my-forgejo-cookie # optional, see below
# github authentication
GITHUB_TOKEN: github_pat_my-github-token
# other configuration
# SEE_BELOW: for more options
For more information about what scopes the tokens mentioned here require, see below. When first setting up nerhegeb, you can also first perform a dry run for testing your configuration and avoid unintended mirroring.
authentication
As nerhegeb automatically creates mirrors, it needs access to both your source GitHub account and your destination Forgejo account. Which account to mirror from/to is automatically determined from the token, so it is important that the following tokens are generated on the correct accounts. It is recommended to choose long expiration dates, as nerhegeb will cease working if one of the tokens expires.
github
To access the GitHub API, nerhegeb uses a personal access token (PAT). Ideally you should generate a fine-grained access token in your account settings to properly minimize required permissions. To work correctly, nerhegeb requires the following:
- Choose the account you want to mirror as the resource owner
- Select
All repositoriesunder repository access - Add the
Contentsscope as a read-only permission
You can now provide this token in the GITHUB_TOKEN environment variable.
Note that nerhegeb is going to use this token to check for new repositories, but also given to Frogejo to access the repository to mirror it. So the admin of your Forgejo instance may see this token at some point. This is why it is important that it is kept read-only.
forgejo
To mirror to Forgejo, nerhegeb also requires API access to your Forgejo account. Head to User Settings > Applications on your Forgejo instance and generate a token with the following:
- Select
All (public, private, and limited)under repository access - Set the
repositorypermission to read and write - Set the
userpermission to read
You can now provide this token in the FORGEJO_TOKEN environment variable.
Important
If you are planning to use nerhegeb to mirror private repositories you currently need to provide additional authentication. At the moment, Forgejo looses specified credentials after creating a mirror, which prevents mirrors of private repositories from syncing in the future. This is tracked at forgejo#9503 and forgejo#9629.
The issue is that updating mirror credentials is currently not exposed over the API, so nerhegeb has to set them again after mirror creation using the web interface, which requires cookie authentication. This is not ideal as a cookie to your account is very powerful but the only option at the moment.
To retrieve the cookie, open the developer tools in your browser and go to a request going to your Forgejo instance in the network tab. Copy the part starting with
i_like_(without the semicolon) from theCookierequest headers. Then provide it to nerhegeb using theFORGEJO_COOKIEenvironment variable.Note that this cookie will expire depending on how the instance is configured, so nerhegeb might cease working properly at some point. But luckily this should be a temporary workaround until it is fixed.
configuration
You can configure nerhegeb using environment variables. Below are available options together with their default values. Empty variables have no default are required if not stated otherwise.
To test your configuration without changes to your Forgejo account, you can enable the DRY_RUN environment variable. This will read the state from your Forgejo instance at startup once and then evolve and modify that state locally as long as the application runs. For more info what nerhegeb is actually doing, you can also enable debug logs with RUST_LOG=nerhegeb=debug.
# cron string when to check and synchronize repositories
# needs to be a cron string INCLUDING a seconds term
# the timezone used is always UTC
SCHEDULE="0 0 3 * * * *"
# immediately sync once when the container starts
IMMEDIATE=false
# performs a dry run, not doing any modification on forgejo
# will read current state of forgejo once at startup but only modify it locally
DRY_RUN=false
# url to reach the GitHub api at
GITHUB_URL="https://api.github.com/"
# personal access token to access the api
GITHUB_TOKEN=
# url of the Forgejo instance to mirror at
FORGEJO_URL=
# api token to access the api
FORGEJO_TOKEN=
# cookie to access the web interface (optional)
# see above for why/when this is required
FORGEJO_COOKIE=
# syncing interval set for new mirrors
SETTING_INTERVAL="8h0m0s"
# enable mirroring of public repositories
MIRROR_PUBLIC=true
# enable mirroring of private repositories
MIRROR_PRIVATE=true
# enable mirroring of forks
MIRROR_FORKS=false
# what to do with repositories with the `nerhegeb` topic, one of
# - `and` only mirror enabled repositories that have the topic
# - `or` mirror enabled repositories and also those with the topic
# - `not` don't mirror any repositories with the topic
# - `ignore` don't care, ignore the topic
MIRROR_TOPIC=or
# whether to synchronize metadata information to mirrors
# metadata is still copied over when the mirror is created
# currently includes description, topics and website
SYNC_METADATA=true
# how to sync the visibility status
# - `total` ensure the visibility matches the one on github
# - `weaken` only weaken visibility (i.e. sync when repo is made public)
# - `none` never sync visibility after creating the mirror
SYNC_VISIBILITY=total
# log level sent to the console
RUST_LOG=nerhegeb=info
development
To work on nerhegeb locally, check out this repository. You can build the project using cargo as usual with cargo build. The release docker image is built for your architecture with
docker build . -t nerhegeb
license
This project is licensed under the GPLv3 License. Have a look at the LICENSE.md file for more information.