Skip to content

How this website is built

Pipeline status

This is the source code for the new Montreal Mesh website, currently hosted at https://lora.reseaulibre.ca and backed by Codeberg at https://codeberg.org/anarcat/lora-reseaulibre-ca/.

This README file documents the git repository and how to make changes to the site. The actual site contents are in the docs/ directory of the git repository or on lora.reseaulibre.ca.

Contributing

If you want to participate here, agree with the Code of Conduct (Contributor Covenant 3.0 Code), and edit the files in the docs/ directory which should bring you into a pull request workflow.

💡 Tip

That can be done through the web interface directly, even though the linked documentation above doesn't make that obvious. The documentation seems to favor a local, git-based workflow which is more complicated, but also supported.

Once the request is approved, your changes will go live. Changes take a "few minuets" to show up, see this troubleshooting section otherwise.

The site was originally built on mkdocs-material but eventually switched to Zensical, then back to mkdocs-material to get the blog working. See their authoring guide for more information.

Translations

Translations used to be made with the mkdocs-static-i18n plugin. That approach has been abandoned because it conflicts with the blog plugin (see upstream issues on both projects). We have therefore adopted a "two-site" approach where each language is its own site.

This is done by having the translation in separate branches. Concretely, we only translate to "French" right now, which lives in the fr branch. The way this works is by merging the main branch into the fr branch whenever we update the main branch. This is a clunky, manual process, but given we don't have many translations, it feels like a good deal.

What this implies is that updates to existing pages will necessarily result in conflicts in the translation. That's a feature: one needs to know when a section needs an update.

Note that the translation branch has a copy of all the files here, even though a lot of those are superfluous (like the .woodpecker.yaml file). The mkdocs.yml is relevant, however, and differs between the two because the site_url needs the fr suffix.

Translating pages

  1. First pull the repository to have all branches up to date:

    git pull
    
  2. Switch to the translation branch:

    git switch fr
    
  3. Update it with the main branch:

    git merge main
    

    If this is an update on an existing page, this will result in a merge conflict. Don't panic.

  4. Translate a given page:

    $EDITOR docs/foo.md
    

    If this is an existing page, you will need to resolve the merge conflict. See the Codeberg merge conflict instructions for a tutorial. When the conflict is resolved, you mark the file as resolved with:

    git add docs/foo.md
    
  5. Commit the result and push:

    git commit -m'translate page foo'
    git push
    

The last step will require you to setup a remote to your own fork if you don't have access to the repository.

The checklinks job uses the Lychee link checker to check the site for dead links.

Checks sometimes fail because of transient errors like:

[ERROR] https://lora.reseaulibre.ca/fr/blog/archive/2026/ | Network error: HTTP/2 protocol error. Server may not support HTTP/2 properly (error sending request for url (https://lora.reseaulibre.ca/fr/blog/archive/2026/)): HTTP/2 protocol error. Server may not support HTTP/2 properly

Rerunning the pipeline fixes this issue. I assume this is a problem internal to Codeberg pages, but I haven't debugged the issue any further.

Links truly being mismatched by Lychee can be added to the .lycheeignore file.

Spell checking

Good old Aspell is used to check spelling in English and French.

To fix false positives found by Aspell, install the aspell package and run the command recommended by CI, which should be something like:

aspell --mode=markdown --lang=fr --home-dir=. --personal=aspell.fr.pws --encoding=utf-8 foo.md

... where foo.md is the file with a problem. It will run a text interface that will allow you to correct or accept the words.

Alternatively, you can add the word to the list in aspell.fr.pws following the peculiar file format. Essentially, you need to add the word on its own line and increment the line count on the first line.

Finally, if you use backquotes around a word, it will get excluded by the parser, which can be useful to bypass certain words marked as failures. This is particularly useful for project names that won't get reused or can't be added because they have a separator not recognized by Aspell. For example, Meshtastic is in our dictionary so it doesn't need to be quoted, but not grebedoc.dev, which does need back quotes.

(Astute readers will notice that backquotes itself needs back quotes, as it's an incorrect spelling, according to Aspell. Capitals matter as well: aspell is a typo, but not Aspell, of course.)

CI build workflow details

This section explains how the site is built. You don't need to read this unless you want to debug the continuous integration (CI) process or website build.

The way this is setup is rather convoluted because we need to have a custom domain and this is still not yet well supported by the new "git pages" and "actions" in Codeberg. So, essentially, it works like this:

  1. on push, Codeberg somehow notifies https://ci.codeberg.org which is Woodpecker CI instance
  2. woodpecker pulls the git repository, builds the site, and commits the result to the pages branch
  3. woodpecker pushes the branch back to Codeberg
  4. code berg fires off a webhook to publish the site to git pages

First setup

To set this up, I had to first follow the manual pushing guide:

  1. build the site on the main branch
  2. create an "orphan" pages branch (git switch --orphan pages) for the site
  3. add and commit the site directory, but to the root of the repository
  4. setup a webhook to the legacy v2 pages on push
  5. push the pages branch

At this point, anarcat.codeberg.page/lora-reseaulibre-ca is online. Next up was to setup the custom domain:

  1. add a CNAME for lora.reseaulibre.ca at my registrar, pointing at lora-reseaulibre-ca.anarcat.codeberg.page.
  2. add lora.reseaulibre.ca to the .domains file in the git repository, on the main branch
  3. push the main branch

At this point lora.reseaulibre.ca is online. The next step was to use Codeberg CI to build and publish the site automatically:

  1. enroll into Codeberg CI, see issue 1570
  2. login to https://ci.codeberg.org
  3. add the project to Woodpecker
  4. create an access token for Woodpecker in Codeberg
  5. add the access token to a codeberg_token variable in the Woodpecker project
  6. create a new mail variable with some dummy email on my domain in the woodpecker project
  7. push a trivial change to a markdown file

At this point, changes to the repository automatically rebuild and publish the changes.

Alternatives

We should probably hook this onto Forgejo Actions and the git-pages action, instead, but the guide for that explicitly says it does not work for custom domains.

There was a one day downtime on Codeberg on 2026-03-04 that cause the site to go down almost entirely. If this happens again, we can consider hosting the static site somewhere else. I was recommended statichost.eu (see this guide) or grebedoc.dev ("Codeberg" backwards). This might be difficult to deploy while the site is down, unless another Git hosting platform is used.

We also use the cache branch to carry around the Lychee cache. This could be fixed if Woodpecker supported caches or with a Forgejo "cache" action or artifacts.

Matrix commit bot

A bot was setup to send messages for new commits on the #reseaulibre:matrix.org Matrix room whenever there is a push. This was done using the built-in Codeberg Matrix integration.

This was done instead of setting up a dedicated bot like Maubot with its numerous plugins like a RSS plugin, or a webhook plugin. There is also a dedicated RSS bridge.