For some irrelevant reasons, I decided to move my website (and my library) to be hosted on Codeberg. So, I am going to write a little bit about how I did the migration.

First, I created an account on Codeberg. There are tons of useful tutorials and documentations on the web that explain how to migrate repositories from GitHub to Codeberg. It’s important to note that on GitHub, you usually have to name your repository in a specific way to make GitHub Pages work. In Codeberg, you technically can do the same (with the pages repository name), but I found it easier to configure everything with a general repository name. So, I recommend you to name your website’s repository whatever (mine is named website).

The way Codeberg Pages works is a bit more bare-bones than GitHub Pages. Here, you have to create a standard html, css, and js structure, and there is no easy shortcut for Hugo websites. So, what we usually do is build the Hugo website (by default under the public/ folder) and then we save the built website on a separate branch of the repository. Finally, we deploy this second branch and leave the main branch for the source code.

To this end, you must configure your Codeberg Actions. These are .yml files that are under .forgejo/workflows. Before writing anything, one must enable Actions under Repository Settings > Units > Overview > Actions and checking the box that read “Enable integrated CI/CD pipelines with Forgejo Actions”. Below you can check a sample action definition that publishes the website. Please read it carefully.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
---
name: Deploy Hugo site to Pages

on:
  push:
    branches:
      - main
  workflow_dispatch:

jobs:
  build:
    runs-on: codeberg-medium
    container:
      image: catthehacker/ubuntu:act-latest

    env:
      BASE_URL: https://github.com/gohugoio/hugo/releases/download
      HUGO_VERSION: 0.152.2
      CUSTOM_DOMAIN: example.com

    steps:
      - name: Checkout
        uses: https://code.forgejo.org/actions/checkout@v4
        with:
          submodules: recursive
          fetch-depth: 0

      - name: Install Hugo and System Dependencies
        run: |
          wget -O hugo.deb ${BASE_URL}/v${HUGO_VERSION}/hugo_extended_${HUGO_VERSION}_linux-amd64.deb
          dpkg -i hugo.deb

      - name: Build with Hugo
        env:
          HUGO_ENVIRONMENT: production
          HUGO_ENV: production
        run: |
          hugo --gc --minify --baseURL "https://${CUSTOM_DOMAIN}/"
      - name: Upload generated files
        uses: https://code.forgejo.org/actions/upload-artifact@v3
        with:
          name: Generated files
          path: public/

  deploy:
    needs: [build]
    runs-on: codeberg-tiny-lazy

    env:
      PUBLISH_BRANCH: pages
      CUSTOM_DOMAIN: example.com

    steps:
      - name: Clone the repository
        uses: https://code.forgejo.org/actions/checkout@v4
        with:
          submodules: recursive
          fetch-depth: 0
      - name: Checkout the target branch and clean it up
        run: |
          git checkout ${PUBLISH_BRANCH} || git switch --orphan pages && \
          rm -Rfv $(ls -A | egrep -v '^(\.git|LICENSE)$')
      - name: Download generated files
        uses: https://code.forgejo.org/actions/download-artifact@v3
        with:
          name: Generated files
      - name: Publish the website
        run: |
          printf "%s\nwww.%s" "${CUSTOM_DOMAIN}" "${CUSTOM_DOMAIN}" > .domains
          cat .domains

          git config user.email codeberg-ci && \
          git config user.name "Codeberg CI" && \
          git add . && \
          git commit --allow-empty --message "Codeberg build for ${GITHUB_SHA}" && \
          git push origin $PUBLISH_BRANCH

Please, notice that we must have the .domains file both in the main branch in in the branch that is going to be published. This file basically specifies which custom domains serve this website. It should look like the following.

1
2
example.com
www.example.com

Once you have the action configured, you must now setup your DNS Settings. This heavily depends on your registrar, but Codeberg’s documentations are really good. Just be sure to remove the A and CNAME records from GitHub and remember to set the TXT record with all information: branch.repository.username.codeberg.page.

After everything, your website should work. Let me know if I forgot any crucial step.