Moving from GitHub to Codeberg
Why I’m leaving GitHub
GitHub has been owned by Microsoft since 2018, but while I don’t otherwise like Microsoft or use their products, I didn’t really care. Mainly because I hardly used it. And also because it was before they sucked up all our data to train their AI without asking permission, and before they supported Trump.
More on why I’m leaving all GAFAM services here.
What I was using GitHub for
The years when I spent many hours on open source software (MoreUnit) are long gone now (I know, it’s kind of sad). Event at that time, I’ve been using Sourceforge a lot, and only then GitHub.
Even at work, I stopped using GitHub in 2021.
Today, apart from very occasional pull requests to propose a fix to an OSS project, I sometimes use GitHub to store gists to include in blog articles, and I keep old small projects on it. And I use GitHub Pages to host this blog. That is, I used to. I don’t use it anymore :-)
My needs
As you can see, my needs are pretty basic. I don’t even need GitHub Actions. And of course I can delete some of the projects I keep here, they aren’t of much interest.
So I need a solution to at least host my website (which doesn’t require a git platform), and to occasionally share open source software, even if it’s very simple and sporadic (an example).
And I don’t want to host it by myself.
Alternatives considered
GitLab
To be honest, if I just wanted to replace GitHub with an equivalent service and have a similar experience, I would choose the free plan from GitLab.com. I’ve been using a paid plan for years at work, so I’d feel right at home.
But I don’t particularly like how the product is evolving, or how features are being prioritized (I’ve blogged about the CI part in the past).
And I don’t think the company is ultimately better than anyone else. They’re just constantly trying to catch up to GitHub, whether it’s a good idea or not.
Bitbucket
I don’t know Bitbucket. But I’m sure its free plan would do the job.
That said, it’s made by the people who committed Jira, so… Atlassian also made Confluence and Bamboo, all products that I have used in the past. It’s generally - and understandably - enterprisey, and I’m not especially in love with them.
And again, I don’t think the company is ultimately better than anyone else.
Sourcehut
I find Sourcehut appealing. It’s all open source. They’re concerned with privacy and efficiency. No needless bells or whistles, but packed with features nonetheless. It has web hosting, and a CI platform if I need one. It also has an equivalent to GitHub Gists with https://paste.sr.ht/.
And it would require me to pay $2/month. I’m fine with it.
But it’s still beta, and subject to changes, and why there’s no real risk for me, I don’t want to come back to my setup every now and then because of it.
Sourceforge
Honestly, I haven’t looked into it. I opened their website and it looked like it did when I used it… in 2009. And even then I did not like their interface. So I don’t even know what they offer.
I could go on
There are many git-based platforms out there (and not just git-based), and that’s great! But I haven’t even tried to review all of them. The above selection was enough for me, along with Codeberg, which I will quickly introduce below.
My choice: Codeberg
Codeberg has similarities to Sourcehut, which I mentioned above. It is hosted in Europe, it cares about privacy. It’s open source and supports open source software. In fact, your code has to be open source to be hosted on Codeberg.
It looks like GitHub or GitLab, and features pull requests, an issue tracker, a wiki, etc. It offers very basic web hosting (more on that later). And I can apply for the CI part if I need to… but this is conditioned on the fact that my code is indeed open source, has a clear goal, and will make reasonable use of the CI resources (here are the criteria).
You don’t have to pay to use Codeberg, but it is supported by donations, so it’s best to make one from time to time.
Also, I find that the UI for repositories is similar enough to that of GitHub or GitLab that people won’t be surprised if they receive a link to a project hosted here.
Migrating GitHub repositories to Codeberg
First, you may want to delete the repositories you don’t care about. No need to migrate those, right? I’ve deleted most of mine.
Codeberg offers you to migrate your GitHub repositories automatically, including issues, pull requests, releases, wiki pages, etc. All it needs is an access token with the right permissions.
Just follow the steps documented here.
There is one drawback, however: you have to do it one at a time.
If, like me, you mainly have repositories with nothing else (issues, pull requests, etc.), you can try this script (documentation), which works very well. It will migrate all your repositories at once, or a selection of them.
Migrating Gists to Codeberg
As far as I can tell, Codeberg doesn’t provide a “paste” service or any equivalent to GitHub Gists.
I don’t really mind: a simple repository holding a collection of files can serve the same purpose.
And so I just downloaded all my gists using this tool (GitHub TakeOut), and pushed the result to Codeberg as a new repository:
git clone https://github.com/devarda/github-takeout.git
cd github-takeout
npm install
# firt, create an access token with the right permissions
export GITHUB_TOKEN=...
npm run download-all
mv downloaded-gists ../gists
cd ../gists
git init
git add .
git commit -m "Import gists from GitHub"
# create a repository on Codeberg, and push to it
Migrating a site from GitHub Pages to Codeberg Pages
The principle, simple as hell…
Like GitHub, Codeberg offers to publish:
- a site for your user or organization, from the main branch of a specific repository named
pages
(vsyour_name.github.com
), accessible atyour_name.codeberg.page
(vsyour_name.github.io
) - a site for any repository, from a dedicated orphan branch named
pages
(vsgh-pages
), accessible atyour_name.codeberg.page/your_repo
(vsyour_name.github.io/your_repo
).
Unlike GitHub, Codeberg only allows you to publish static files. There won’t be a “magic” Jekyll build for your site. But it’s easy enough to deal with, as I will explain. You can keep your Markdown :-)
Like GitHub, Codeberg Pages allows you to use a custom domain, by creating of a .domains
file at the root of your repository (vs a CNAME
file), and configuring the proper DNS record(s).
The whole procedure is very well summarized here.
… except when it isn’t
While I was able to create a site for my user using a “pages” repository, I was unable to create one for another repository.
Since I didn’t really need one, I moved on.
How to migrate your site
Disclaimer: I had availability problems with Codeberg Pages, as described later in this article. So you might want to take a look at the Codeberg Service Status page and decide if it’s OK for you before you decide to migrate.
Publication
- Create a
pages
repository on Codeberg, without a first commit. - Locally, pull your “GitHub user” repository (
your_name.github.com
). - If you relied on Jekyll, rename your branches, because the
main
one will have to contain the result of a local Jekyll build. Proceed as follows:- Install Jekyll (instructions). To my surprise, the latest version (v4.4.1 at the time of writing) worked perfectly to build my old site that relied on a very old version (1.x).
- From your
main
branch (ormaster
, or whatever), create a branch for the Jekyll sources of your site. I called minesources
:git switch --create sources
- Delete your previous
main
branch:git branch --delete --force main
- Recreate an orphan
main
branch:git switch --orphan main
- Switch back to your
sources
branch:git switch sources
- Add this script to it, and tune it if you like:
curl --location --remote-name https://codeberg.org/ndemengel/pages/raw/commit/b3e4373ba21884797a0ef7075c3adac444552aac/build-and-publish.sh chmod u+x build-and-publish.sh git add build-and-publish.sh git commit "Add build script"
- Every time you make a change and wants to rebuild your site, run the script:
./build-and-publish.sh
It will build the site, commit the result in the
main
branch, and push this branch to Codeberg.
One could tune it to also commit and push thesources
branch. Or, one could make it a pre-push hook, that would execute it every time thesources
is pushed.
- Now, wait for your site to be available on
your_name.codeberg.page
. You can do so by repeatedly running the following command and looking at the result:curl --include --silent https://your_name.codeberg.page | head -n 25
You should get a 200 status code, and then the content of your site:
$ curl --include --silent https://your_name.codeberg.page | head -n 25 HTTP/1.1 200 OK [..] <!DOCTYPE html> [..] <title>Your page title!</title>
Using a custom domain
- If you want to use a custom domain name, add a
.domains
file at the root of your main branch, containing your domain name (or multiple ones). For example, mine isn.gridem.fr
.
Commit, and push your main branch.
Note: if you use thebuild-and-publish.sh
script presented above, place the.domains
file in thesources
branch, and the script will copy it tomain
when run.
Again, wait for the changes to be visible, by running:curl --include --silent https://your_name.codeberg.page | head -n 25
You should get a redirection, with a 307 status code:
$ curl --include --silent https://your_name.codeberg.page | head -n 25 HTTP/2 307 [..] location: https://your.domain.name/ [..] <a href="https://your.domain.name/">Temporary Redirect</a>.
- It is now time to update your DNS record for
your.domain.name
, to make it an alias ofyour_name.codeberg.page
.
Since I use a subdomain, all I had to do was changing myCNAME
record forn.gridem.fr
fromndemengel.github.io
tondemengel.codeberg.page
.
If you use an apex domain, you will have to update (or create) both anALIAS
(orA
&AAAA
) record and aTXT
one, as described on https://codeberg.page/.
To observe your changes, you can use thedig
command, as follows:dig your.domain.name +nostats +nocomments
For a
CNAME
record, you want to see something like the following:$ dig autoconfig.gridem.fr +nostats +nocomments [..] your.domain.name. 60 IN CNAME your_name.codeberg.page.
Note: I advise you to use a short TTL (time to leave) for your DNS records at first, like 60 seconds, so that if you screw up, your fix will propagate fast enough.
But… Codeberg Pages availability
I decided to migrate last week when Codeberg was under constant DDOS attack. I don’t know if it was related, but the availability of the Codebase Pages was around 80% during that time.
As a result, my site was either super slow to load or simply unreachable.
Of course, I can’t blame them. Firstly, because Codeberg doesn’t owe me anything. And also because my thoughts were with them. These people had a tough time!
But I decided to temporarily publish my website on a very small space (10MB!) that I have at Infomaniak. At the time of writing, it is still there, and I will see if I have a new try with Codeberg Pages later.
But the sources are still in my pages
repository on Codeberg, and the website is still built and published the same way. Only, I now also copy the build result to Infomaniak.
In the process, I had to change my DNS configuration again (using an A
record this time), and tweak a good old .htaccess
file too, to expose the contents of a specific folder depending on the subdomain being queried :-)
I also had to update the certificate I use on Infomaniak for my domains (gridem.fr
and a few subdomains), to include the n
subdomain used by the website.
For some unknown reason, the new certificate took like forever to be live, and so I had to wait for it to be ready before applying my new DNS configuration. Otherwise browsers would complain about the certificate of my site.
In case you ever face the same problem, here is how I monitored the certificate exposed by Infomaniak, to detect when it finally included the new subdomain. This trick relies on the fact that I have a small (and admittedly useless) page already served by Infomaniak, on gridem.fr:
openssl s_client -showcerts -servername gridem.fr -connect gridem.fr:443 <<< "Q" \
| openssl x509 -text \
| grep -E -A2 '(Alternative|Validity)'
I just had to wait for the output to have new dates in the “Validity” section, and to see n.gridem.fr
in the “Subject Alternative Name” section.
That’s about it
The instructions in this article should be pretty similar for migrating to another service. I hope this experience helps someone!