For many reasons, I want to mirror my public GitHub projects on other collaboration platforms. This short article describes my difficulties with it and a working solution.


Illustration by John Tenniel


For a year, I used the GitHub->GitLab pull mirroring. It could copy the code, tags, and discussions in issues and pull requests, which was nice. But some time ago, I noticed that my GitLab branches fall behind the origin. I signed in to GitLab and saw this annoying banner:

GitLab banner

GitLab pull mirroring disappeared from some of my repositories. Enabling it again with Free Tier is not possible anymore.


Buying GitLab Premium Tier is not possible for anyone from Russia. Even a free trial is not allowed. So I started to look at other mirroring solutions:

  • Running a self-hosted GitLab or Forgejo server couldn't suit me well, because I didn't want to host my open-source projects on an isolated server.

  • I checked Chinese Gitee and didn't like its limited support for English localization.

  • I looked at the Radicle p2p network for software development. But its "powerful blockchain-based functionalities" looked too radical to me.

  • Then I looked at Codeberg. It's driven by a non-profit organization promoting FOSS ideas. I like them much more than Microsoft. But in March 2020, they disabled mirroring due to a lack of resources. They say: "Mirror repos: easily created, consuming resources forever." :(

  • I also checked SourceHut (thanks to paulmairo for the idea). It doesn't suit me well because:
    1. It provides only paid services.
    2. Its workflow looks incompatible with GitHub: Sourcehut uses plain-text email for reporting bugs, creating tickets, and submitting patches.

  • I checked Salsa (thanks to Mic_92 for the idea). It's a collaborative development server for Debian based on the GitLab software. At first, I registered an account. Several days later, Salsa administrator enabled it and I managed to copy one of my projects from GitHub to Salsa. But it turned out that the pull mirroring feature at Salsa is disabled, similarly to gitlab.com. I asked about it on the Salsa issue tracker but didn't get any reply.

  • Then I created the mirrors for my GitHub projects at GitFlic, a small proof-of-concept collaboration platform. But it doesn't have CI and can't copy the information from GitHub issues and pull requests. Obviously, not a final solution. GitFlic mirroring

To sum up, I didn't find any popular code collaboration platform that could provide full-featured mirrors for my GitHub projects. So I decided to look at this task from another angle: how can I manually back up the info from the GitHub issues and pull requests?

My first idea was to turn the discussions into a part of the code. Shortly, I found a nice project gh2md, which can help with it. gh2md grabs the information from GitHub issues and pull requests and turns it into a Markdown document.

Under the hood, it uses GraphQL API provided by GitHub, so I had to generate a GitHub personal access token with public access. See the GitHub documentation for more info.

GitHub access token

Now my projects contain the issues.md file with a backup of issues/PRs. It's possible to use gh2md in GitHub Actions and update issues.md automatically. But for now, I refrain from giving write repository access to the GitHub Actions workers.

For a moment, I thought about a GitHub Actions script generating a pull request with the updates of issues.md. Shortly, I realized that it was not a clever idea: this new PR would make the CI script update issues.md once again and generate another PR :) That can be called a GitHub Actions spammer.

Another option is to keep GitHub issues in the git storage of the project: the git-bug tracker can do the job (thanks to Sergey Bronnikov for the link):

git-bug

Anyway, after committing the Markdown backup of GitHub issues and PRs, I decided to create clone repositories at Codeberg and then do a git push both to GitHub and Codeberg. GitHub->Codeberg migration of my projects worked well. It copied all the info from the origin. So Codeberg would be the ideal solution for me if it had a pull mirroring featureā€¦ Alas!

But what to do with out-of-date issues/PRs at Codeberg? Deleting and recreating projects manually would be a dirty hack, and I didn't like it.

Codeberg mirroring

I looked through repo settings and found a workaround: Codeberg provides options for using an external issue tracker! I set the URL format and numbering for the external issues, disabled the Codeberg pull requests, and now have the correct links to GitHub issues and PRs from Codeberg repositories.

Codeberg repo settings

Now it is a more or less working solution. If something goes wrong with GitHub, I will enable the internal issue tracker and pull requests at Codeberg.

Codeberg mirroring 2

That's all. Maybe this story will be useful to somebody.