Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

4-2: Codeberg Pages

The MDBook tool that we’re using can generate websites for any platform, but since we’re on Codeberg anyhow, we can take advantage of Codeberg Pages. This feature lets you host static websites directly from a Codeberg Repo. There are technically two ways to use this feature.

There are 2 ways to use Codeberg Pages: the webhooks method and the legacy method. As of this writing, the legacy method is the only way to use a custom domain. Either way though, we’ll need to create a new branch of our repo for our published data.

Branch Setup

In your local copy of your creating-with-git fork, make a new branch for our Pages deployment.

git switch -c pages

What comes next is going to feel very uncomfortable. We’re going to delete everything tracked by Git. That’s because the structure of the pages branch will be fundamentally different from main. So we start with a clean slate.

Warning

Make sure you enter these commands exactly as written here! I don’t want you to accidentally destroy data somewhere else on your system!

Inside the repo folder, run:

rm -rf ./*
rm .*
git add -A
git commit -m "Clean repo for pages"

Then, as we’ve done before, push this new branch to Codeberg.

git push -u origin pages

Scary I know, but we’re about to see all our stuff again. Let’s switch back to the main branch.

git switch -

There, see? All our stuff is back.

Submodule Setup

It’s time to introduce a brand new Git concept: Submodules. Repos can have subordinate repos as ad-hoc dependencies. This is extremely valuable when you have an overarching project that uses code from multiple smaller projects. Instead of manually updating each one, Git can keep the submodules up to date.

We’re going use this feature to make updating the pages branch really easy. Since pages no longer has our source material, we’re going to simply copy the built book data from our build folder to the pages submodule, which will look like just another folder in our repo. To accomplish this, we add the pages branch of this repo as a submodule in main. It’s a little wacky, but trust me: it makes this process incredibly simple.

You may have noticed that the repo you forked has a pages folder in it. And in fact, if you look at that folder on Codeberg, it looks kind of strange. There appears to be a specific commit next to its listing. This folder is a submodule. However, in your version of the repo, the folder is empty.

That’s because by default, Git does not initialize submodules when you clone a repository. You can pass --recurse-submodules to do so, but we didn’t want to in this case.

Now it’s time to use that folder though. I want you to understand what’s going on with submodules, because they can get a little tricky. First, look at the current entry in .gitmodules:

cat .gitmodules

This is the definition file for all defined submodules. You should see this:

[submodule "pages"]
        path = pages
        url = git@codeberg.org:The-Taggart-Institute/creating-with-git
        branch = pages 

Pretty clear, right? The submodule pulls from the TTI repo for this course, using the pages branch.

But…that’s not really what you want. You want to use your pages branch, not ours. So we need to modify that file. git submodule set-url will sort you out.

git submodule set-url pages git@codeberg.org:USERNAME/REPO

Obviously replace USERNAME and REPO with the appropriate values there. The .gitmodules entry will reflect the change.

But the pages folder is still empty. We need to initialize the submodule (tell Git to care about it), and then update it to match its remote. This is a two-command process.

git submodule init
git submodule update

You will see what looks like cloning behavior. The pages folder is still empty, but we’ll soon fix that. One last piece of housekeeping. When we ran git submodule update, the submodule was checked out to a new, detached HEAD. We need to set it to pages by moving into the directory and using git switch.

cd pages
git switch pages
cd ..

At this point, git status will tell you that .gitmodules has changed. Commit that change to clean the repo.

git commit -am "Update submodule URL"

Note

The submodule commands we just ran are because you cloned a repo with defined submodules. If you were doing this completely from scratch on your repo, you’d add a brand new submodule in main, like so:

git submodule add -b pages git@codeberg.org:USERNAME/REPO pages

Okay, that’s the submodule setup. Time to publish.

Publishing

Let’s build the site.

mdbook build

You’ll notice that there is book folder in your repo. That’s where your built site is! This folder has actually been there for a while now, since that’s where mdbook serve was generating our local site. But Git was ignoring it based on an entry in the repo’s .gitignore file.

With the site built, we can copy the contents from book to pages to populate our submodule/branch. We would then want to change into the pages directory, commit the changes, push, and come back out.

Every. Time.

So that’s what scripting is for. We’d want a publish.sh to handle this for us.

Make publish.sh in your repo. It will look like:

#!/usr/bin/env bash
PAGES_DIR=./pages
BOOK_DIR=./book
pubdate=$(date -Iseconds)
echo "[+] Building book for $pubdate"
mdbook build
cd $BOOK_DIR
cp -R ./* $PAGES_DIR
cd $PAGES_DIR
git add -A
git commit -m "Publish: $pubdate"
git push
cd ..
git commit -am "Update: $pubdate"
git push

Save this file. Then make it executable by running chmod +x publish.sh. Now of course we’ll add it:

git add publish.sh
git commit -m "Add publish script"

Let’s do a test run! Make some changes to your Markdown files, then run:

./publish.sh

If all goes well, your content should be pushed to Codeberg and in a minute or two, your site will be live at https://your-account-name.codeberg.page/your-repo-name.

Note

We’ve done the non-webhook version of this because it’s the most flexible. Additionally, if you want to use a custom domain, it’s the only option. Please see the Codeberg Documentation on adding a custom domain. It’s not too tricky; just a CNAME DNS record and a .domains file in the pages branch.

Believe it or not, that’s it! You’ve not only published your documentation, but you’ve finished this course! Well done! Now all that’s left is the Exhibition Of Mastery.