How hosting sites works on Codeberg
I won’t write about custom domains here.
Aside from that, there are 2 options that might intrest you in the docs.
{username}.codeberg.page
{username}.codeberg.page/{reponame}/
The former will point to index.html
on the default branch of your pages
repository.
The latter will point to index.html
on pages
branch in the reponame
repository.
So if your website doesn’t require building you can just put the appropriate files on the appropriate branch and be done with it.
Pre-requisites
Unlike on other git hosting sites, on codeberg you are not authorised to use the CI the moment you create an account. You must first fill in the form to be onboarded.
Branches setup
Because for {username}.codeberg.page
index.html
must be on the default branch and I do not want to have the code generating the website on the same branch as the generated code, my branch setup consists on 2 branches main
, and pages
— pages
being the default branch.
You can change the default branch at https://codeberg.org/{username}/{repo}/settings/branches.
You can of course have the branches named however you want and even keep the code on the default branch.
Manual steps
To enable CI for the repository you’ll need to go to https://ci.codeberg.org/repos, and click + Add repository.
In order to allow for pushing to our git repository from the CI we’ll need a token.
You can create it at https://codeberg.org/user/settings/applications, give it at least read and write premissions for repository.
Now you need to put it somewhere where CI can read it. Go to https://ci.codeberg.org/repos, coose your repo, go to secrets, click Add secret, put the token as value and give it some name e.g. GIT_TOKEN. Make it available at least for the push events.
Code setup
I took a lot of “inspiration” from Jan Wildeboer’s blog post about Woodpecker CI for Jekyll.
However, my blog is built on fuwari, so I needed to adjust the build step and image.
On the code
branch I created .woodpecker/deploy.yaml
:
when:
- event: push
branch: main
steps:
- name: build
image: node
environment:
GIT_TOKEN:
from_secret: GIT_TOKEN
commands:
- wget -qO- https://get.pnpm.io/install.sh | ENV="$HOME/.shrc" SHELL="$(which sh)" sh -
- export PNPM_HOME="/root/.local/share/pnpm"
- export PATH="$PNPM_HOME:$PATH"
- pnpm install
- pnpm build
- git config --global user.email "artur.mostowski@protonmail.com"
- git config --global user.name "Woodpecker CI"
- git clone -b pages https://codeberg.org/Vulwsztyn/pages.git _site
- cd _site
- git remote set-url origin https://$${GIT_TOKEN}@codeberg.org/Vulwsztyn/pages.git
- cd ..
- cp -r dist/* _site
- cd _site
- git add --all
- git commit -m "CI Build done at $( env TZ=Europe/Berlin date +"%Y-%m-%d %X %z %Z" )"
- git push
Code explanation
Let’s break it down 🤸🏻♂️.
when:
- event: push
branch: main
I want this Ci job to run upon push to the main
branch.
steps:
- name: build
image: node
You can name it however you want and I need node
to build fuwari
.
environment:
GIT_TOKEN: // environmental variable name
from_secret: GIT_TOKEN // secret name
I used the same name, but the comments should explain the syntax. This allows the job to use the secret we set up earlier.
- wget -qO- https://get.pnpm.io/install.sh | ENV="$HOME/.shrc" SHELL="$(which sh)" sh -
The job runs in sh
and I need wanted to use pnpm, so I took the 1st command from their website. After installation pnpm tells you:
Created /root/.shrc
Next configuration changes were made:
export PNPM_HOME="/root/.local/share/pnpm"
case ":$PATH:" in
*":$PNPM_HOME:"*) ;;
*) export PATH="$PNPM_HOME:$PATH" ;;
esac
To start using pnpm, run:
source /root/.shrc
I, however, was not able to run source /root/.shrc
so I set PNPM_HOME
and add it to PATH
manually in the next 2 steps:
- export PNPM_HOME="/root/.local/share/pnpm"
- export PATH="$PNPM_HOME:$PATH"
- pnpm install
- pnpm build
Straightforward enough. Install dependencies and build the static page. fuwari
builds into dist
dir.
- git config --global user.email "artur.mostowski@protonmail.com"
- git config --global user.name "Woodpecker CI"
Sets git credentials for the commit that will be created.
- git clone -b pages https://codeberg.org/Vulwsztyn/pages.git _site
- cd _site
- git remote set-url origin https://$${GIT_TOKEN}@codeberg.org/Vulwsztyn/pages.git
- cd ..
Clones the same repository the job runs in into _site
dir, but only its pages
branch. Then sets the url to one prepended with the token, which will allow for pushing without username nor password.
- cp -r dist/* _site
- cd _site
- git add --all
- git commit -m "CI Build done at $( env TZ=Europe/Berlin date +"%Y-%m-%d %X %z %Z" )"
- git push
Copies everything from dist into _site
, creates a commit message (yours can be anything and doesn’t need the timestamp), and pushes it.
Code changes for any other tempalte
While most of these instructions are universal-ish, depending on the blog/webpage tempalte you are using, you might need different languages and libraries present on the docker image on which the job is running, and different set of build instructions.
Jan Wildeboer uses Jekyll, so he cannot Hyde uses image: jekyll/jekyll
and his build instructions are:
- bundle install
- bundle exec jekyll build
I’m certain that with these 2 examples you will be able to adjust the image and build instructions to whichever template you use.
You can always take a look at the examples.
Skip CI when not needed
Since Codeberg’s resources are so scarce, and they are a non-profit, and not a start-up, it might be nice of us not to run the CI when we do not need it, or when running it wouldn’t result it any difference in the page — e.g. when refactoring the code. to achieve this add [CI SKIP]
in the commit message.