Skip to content

How and Why to Ditch GitHub

How much of your code do you feel like entrusting to Microsoft? How about American data centers? Here's an easy way to jump ship and maintain operations.

T
Mar 31, 20258 min read

t's just possible that you, a sentient being with active sensory input, have cause for concern about the security of data hosted both in the United States and by Microsoft. GitHub has been ubiquitous and indispensable for technologists. But maybe it's time to reconsider that status.

<!--more-->

Don't feel like reading? Skip to the cheat sheet for the full procedure.

Look, I really like using GitHub. If you're a developer, or someone who interacts with a lot of open source projects, GitHub has been The Place To Be™ for years now. It's even an assumed component of a resume for many jobs in tech. I personally have hundreds of starred repositories on my GitHub account, and my projects have benefited from its ubiquity and ease of use.

H O W E V E R...

GitHub is not the only Git hosting service in town. In fact, there are a bunch of other towns, and GitHub's neighborhood is getting shady as hell. Between Microsoft's seeming inability to keep nation state actors out of its business, the US government's questionable choices around cybersecurity, and GitHub's use of everyone's code to train its language models, I felt it was time to seek greener pastures for my code.

You ever have something that you know in your bones is the right thing to do, but it seems unreasonably onerous? Moving off GitHub has felt that way for me for quite some time. While you can't always choose an ethical option in a culture of consumption, this one felt important enough to try. My technical efforts contributing to a technology I vehemently oppose did not sit well with me.

So I finally made the leap. And you know what? It wasn't that hard. Forgejo and Codeberg

I moved all my code to Codeberg. I had heard positive things about it on Mastodon, and had even created an account there previously to interact with some projects.The interface seemed rather GitHub-y, but that didn't mean it had the capacity to replace GitHub for my purposes. So I read the docs.

Codeberg is the flagship instance of Forgejo (pronounced "for-JAY-o"), an open source Git repository. There are others, like Gitea, but I'll tell you what makes Forgejo/Codeberg special: Codeberg e.V., a German non-profit that maintains the project. I'm particularly impressed by the transparency and openness of the organization, as described in their bylaws.

There's an irony in this American turning to a German organization for some kind of freedom in this chapter of history. I'll leave you to tease that out.

You can self-host Forgejo, and there are other public instances. But since Codeberg is a turn-key option, and has all the data protections of the EU to boot, it seemed like a reasonable exit strategy from GitHub. Here's how I did it.

Migration

You'd think the first step is to make a Codeberg account, and that's definitely the _second_ step. But to make your transition as easy as possible, I recommend you start at your GitHub account—specifically, your personal access tokens—and create a new one for Codeberg. This new "classic" token (because it needs access to all your repositories) requires all repo permissions. Save the token once created in someplace secure. I recommend a password manager.

_Now_ go make sure you have a Codeberg account. Once logged in, click on the "+" button by your profile picture, and click "New migration."

Or just go right there. As you can see, there are a bunch of migration options. We're focusing on GitHub, but if you have repositories on GitLab or other services, Codeberg/Forgejo will help you migrate those repos too.

Time to fill in a form! Add the URL of your source repo, and your access token (for private repos or if you want the issues, pull requests. etc.). Make sure to check the "Make repository private" box for any private repos—we don't want to accidentally disclose sensitive code/data. And then migrate! Codeberg also has organizations, if some of your repos are owned by orgs rather than individuals. You can make those before migration and use them as target owners.

Migrations can take a few minutes to complete, but I've never had one fail. I was quite impressed with the smoothness of this process.

This process can take a while if you have a repository problem like me. My first instinct when solving a technical problem often involves git init. It is absolutely possible to combine GitHub and Forgejo REST APIs to script an automated migration process, but I leave that as an exercise for the reader. In truth, I found the manual review both an enjoyable walk down memory lane, and an opportunity to delete/archive repositories I no longer needed. It felt a bit like digital spring cleaning.

Speaking of archiving: do it. Mark your GitHub repository as archived (unless you feel comfortable deleting it altogether). Before I did,I added a final commit to the repo's README.md that communicates the move.

In case you're unfamiliar, the "archive" option is at the bottom of a repo's settings, in the "Danger Zone."

Insert Kenny Loggins joke here.

Now let's talk about auth. We all agree that SSH keys are the proper way to authenticate to GitHub, right? Right??

Great. Codeberg supports this, but there is a minor gotcha I ran into: for SSH key verification and signing, Codeberg/Forgejo requires either RSA 4096 or ed25519 keys. RSA 2048 keys are insufficient, so if that's what you've been using, you'll need to generate a new SSH key. You don't have to replace the old key; worry not. But you should make sure that the new key is added to ssh-agent. GitHub has excellent documentation on the process. Add the SSH keys to Codeberg in your user settings, and verify them with the provided instructions. You can now use SSH for auth and signing.

To finalize the migration, you'll want to update your local clones to point to Codeberg. Rather than manually changing the ref in .git/config for the origin remote, I find it best to add a new remote for Codeberg.

Now, git push will send to Codeberg by default.

That's it! You've successfully migrated your repos. Not too hard, right? Let's get into the slightly more complicated parts. Actions

Codeberg/Forgejo support Actions...kinda. While you can enable Actions for a repo, you need to bring your own runner. Maybe that's not such a bad thing. As we'll discuss later, this process forced me to interrogate whether I even _needed_ Actions for my use case (turns out: no). But I did create my own runner in my homelab, following the Forgejo documentation.

One note on the runner setup: do not mess with the default labels unless you know what you're doing. Those labels determine not only where something runs, but how. Leave them alone unless you love troubleshooting.

If your repo has actions form GitHub, there's a good chance they'll work out of the box. The base "Forgejo Actions" are literally just clones of GitHub Actions. For the rest, I suspect there will be some refactoring involved. But there are opportunities for improvement there as well.

Pages

If Codeberg/Forgejo did not support static site hosting, this migration would have been much more difficult for me. In fact, I'd probably still be on GitHub, if I'm being honest. Even so, the Codeberg Pages service has some significant differences and sticking points to bear in mind.

First, Codeberg Pages requires a repo that has index.html _at the root_. That's what it's serving. This differs from both GitHub Pages deployment options. The "classic" GH Pages scheme uses a dedicated branch and folder, inside of which your web content could be deployed. This is useful for static site generators like Jekyll, which take source Markdown files and templates, and return a fully built HTML site. The published content and source are in the same place, although isolated to a dedicated branch to minimize cruft. The newer GitHub Pages method eliminates the branch entirely, relying instead on Actions to deploy an artifact to an "environment." In this model, your repo's source never needs to contain the built site; GitHub handles all that behind the scenes. A few (dozen) lines of YAML, and you're golden.

I quite enjoyed using the Actions -> Environments deployment pipeline for my static sites. It felt smooth—after a couple hours of fighting with YAML and other people's Actions, anyway.

So after a few false starts, I think I've arrived at the "best" way to do Codeberg Pages—for me, anyway. This is the process by which you are currently reading this blog post!

Side note before continuing: I use Zola as my static site generator, but that's just details. Whatever you choose will likely map on to this approach.

How I Do Codeberg Pages

Reading through the documentation, the first thing you need to internalize is that A Codeberg Pages site must have the web content at the repo root. If there isn't an index.html there, nothing's happening. So if you use a static site generator like me to build your site, we're already in a bit of a pickle. Your repo root is all your source config/Markdown/templates, not the built site. The docs state you have three ways to present your content as a Codeberg Page:

1. A dedicated repo called pages, which will be the "default" repo for your account 2. A pages branch of a repo, with the web content at the root 3. A dedicated repo, again with the web content at the root

Let's discount option 1, since it is fairly limiting for no good reason. The docs are less clear that option 3 requires that the default branch be named pages, but it is the case. Option 2 is, in my opinion, much messier. Even though only a single repo is required, the diffs between a main and pages branch for a SSG will be huge, and that problem is never going away. Think through it:

- On main, write your Markdown content. Commit the changes to history. Push to Codeberg. - Switch to pages. Run the SSG to build the content. Here comes the awful part. - Delete the site source from pages, then copy the entire build directory to the root. Commit changes. Push to pages. - Do this every t

Did you enjoy this article?

Recommend it — Standard Reader surfaces well-loved writing to more readers across the network.

Across the AtmosphereDiscussions