I have taken some time to migrate all my code from GitHub to Codeberg, and I thought I could do a little write-up of the process here. For those who don’t know what I am talking about: These are code forges (yes, I know that GitHub refuses to call itself a forge because it is so ~special~), a place where you can develop and share code, applications and software. When developing stuff, it is common to use some sort of version control to keep track of changes you do in your code. When collaborating on stuff, it is nice to have a centralized platform to keep track of stuff. Like a fancy and complex Google Docs for code if you will. Anyways, enough of my not-so-good explanation of a code forge. You either know very well what it is, or you can check out the links above.
Why?
So on to why I am migrating. GitHub is owned by Microsoft, a company which I despise and who manage to turn everything they touches into shit (or it’s killed). I don’t own any devices running Windows, and it was a requirement to not use Windows when starting my new job. GitHub feels like it is becoming more and more like a social media platform every day. Getting stars on repositories are the name of the game. For me, the enshittification of the platform is noticeable. They are currently surfing on the network effect. Because it is the place to be, everyone is there and because everyone is there, it is the place to be. The network effect is a really hard thing to shake (why else would anyone still be using Facebook?). They are starting to lock more and more stuff behind login screens, shoving in AI everywhere (which is going great) and tracking users. I started on GitHub because my university required me to use it. Then I was on GitHub because “you need to have GitHub when you are job searching”. And when I got a job, I was there just because everyone was there.
Codeberg on the other hand is a German non-profit running a modified version of Forgejo, a free open source forge that you can self host. It’s been a while since I first heard about Forgejo. I am a fan of self hosting, and considered for some time to host my own forge. However, it is a lot of work to host and maintain. Especially since my ISP runs a CG-NAT and refuses to open any ports. That makes it even more of a hassle. I also enjoy the community part of a forge. So when I discovered Codeberg, a community- and open source-focused platform that hosts Forgejo for me, it was a no-brainer. Not to mention that the platform is democratic and ran by its users! I have been meaning to move for a while now, but these kind of things are a chore.
How?
Migrating my stuff was pretty easy. I found some scripts to automate the process. I only had about ten repositories I wanted to move over, so I ended up doing it manually. The migration was as simple as creating an access token on GitHub, pasting in the url for my repository and the token, then check some boxes. EZ PZ. Then I added a notice on all my GitHub repositories that I had migrated to Codeberg. Lastly, I archived my GitHub repositories.
The biggest job was migrating this page. It was running on GitHub Pages, a free hosting service for static sites. I had a CI/CD pipeline with GitHub Actions, that built and deployed my site whenever I pushed something to the main branch. So whenever I wrote something, I just pushed it to GitHub and everything was automatically deployed to the site. I also have my custom domain which I set DNS records for in Cloudflare, so my GitHub Page uses my own domain.
Codeberg also offers their own Pages for static sites. The docs made it seem easy enough. They even have a builtin CI/CD tool called Woodpecker as an alternative to GitHub Actions. So I set out to replicate the setup I had on GitHub. I am not going to lie, it was a bit of work to get it right. Mostly because the documentation was a bit lacking.
First I had to fill out a form to request access to Codeberg’s CI. I just had to link to the repository where I wanted to use the CI, how much resources I expected to use and optionally some other info. I think I sent the request early evening and it was approved the same night. Lightning speed! Next step was to create a .woodpecker.yaml file for the deployment job. Luckily, there was a pre-made template for Hugo sites like mine. I copy/pasted the template and deleted the files from my GitHub Actions pipeline. The template contained two secrets: Mail and a Codeberg token. So I generated a token for the pipeline. But where to put those secrets? That wasn’t very obvious to me.
So after some more reading, I figured out that in the repo settings there was a hidden menu under “Actions” called “Secrets”. So that had to be it, right? Wrong. I tried to push some changes to see if the pipeline would run. In GitHub there is a tab in the repository where you can see the pipeline. I figured that Codeberg would have the same, and that maybe the tab would show up when I had setup the pipeline. It would not. So where was the pipeline located? Back to the docs for more reading. I went to the Woodpecker documentation to see if I could figure it out. Woodpecker mentioned Woodpecker CLI, Woodpecker Server and Woodpecker Agent. I installed them thinking that would be it. Wrong. Those are used if you are hosting your own CI/CD, which I was not. Finally, after reading the CI docs one more time, I saw that Codebergs CI was located at ci.codeberg.org. I don’t know how I missed that. I got lost in the documentation I guess.
I logged in to the Codeberg CI and chose my repo. There I found the menu for secrets. I added mail and token. To setup a Codeberg Page at the main subdomain (username.codeberg.page), the first step in the docs was to have a repo called “pages”. I renamed the repository to pages and tried to push some changes to see if the site would be deployed. It would not. I was met with a 404 page. So back to the docs I went. Then after scouring through documentation, it was mentioned that you can have a repo page if you have a branch named “pages”. So I branched master to create a pages branch. Pushed some changes, waited for a bit and checked my domain. And we were up! Finally!
Next step was pointing my domain to jrgn9.codeberg.page. So I logged in to Cloudflare to setup the DNS. I removed the entries from GitHub and logged into GitHub to remove my custom domain there. Back to the Codeberg docs to check what I needed for DNS. I have my mail setup with my domain, so simply using CNAME/Alias was not an option. A/AAAA record it is. Four entries: A, AAAA, CNAME and TXT. Seemed pretty straight forward. I also knew that I had to turn off proxy in Cloudflare, because that was a fuckup I had done before. Added the entries, turned of the proxy cloud and ensured it was grey. Then waited for a while to ensure that the DNS records were propogated. Checked out my domain. 404. Fuck. It was starting to get late, so I figured I could take a look the next day.
The next day I eagerly went to my domain. Fingers crossed! Still 404. Fuck me. Back to the docs I guess. The troubleshooting mentioned the grey cloud in Cloudflare, but nothing more. No help from the docs, so I started searching the web. Reading the issue tracker on Codeberg. Then finally under a somewhat related issue a user mentioned that the “pages” branch needed to be the main branch. This was not mentioned anywhere in the documentation. I still had “main” as my main branch. Went to the repository settings and set “pages” as the main branch. Went to the domain to check. I did not have very high hopes, but lo and behold! The page was up! What a relief! I think the documentation needs some overhauling. I might send a pull request sometime if I have the time.
The future
Now I’m mostly done with the migration. My profile page is still a bit fucked, because I just moved the one I had on GitHub. It needs an update anyway. Then my plan is to do a full rewrite of Cheater at some point. I want to try using Bashly as a framework, and I want to clean up the code a bit. I will still keep my GitHub account. As mentioned, “everyone” is on GitHub. So to keep up with projects I am interested in, I still need to have it. I might also just keep using GitHub to host trash that I have in private repositories. I don’t mind wasting their resources. I am also considering setting up a mirror of Cheater on GitHub for visibility reasons. I have also considered doing the same for this page. To have the GitHub Page running as a backup and setting up some DNS rules that forwards my domain in case Codeberg Pages goes down. Time will see. I’m just happy to finally move my stuff over, and I am looking forward to embrace Codeberg. Who knows, maybe I find something I can contribute with too.