The infrastructure

Git workflow

Describes my workflow and how the git setup works, mainly used for the infra repo, but also used in some other repos.

Remotes and branches

First, set up the git branches and remotes correctly, the main branch tracks ben/infra:main:

$ git branch --unset-upstream main
$ git remote add origin ben
$ git fetch ben main
$ git branch --set-upstream-to=ben/main main

And the b branch tracks b/infra:b:

$ git remote add origin
$ git fetch origin b
$ git branch --set-upstream-to=origin/b b

Now the .git/config file should have the following remote and branch config sections:

[remote "origin"]
        url =
        fetch = +refs/heads/*:refs/remotes/b/*
[remote "ben"]
        url =
        fetch = +refs/heads/*:refs/remotes/ben/*
[branch "main"]
        remote = ben
        merge = refs/heads/main
[branch "b"]
        remote = origin
        merge = refs/heads/b

Making pull requests to main

When ready, work is moved from the local b branch to the public main branch:

  1. Commit your work on your local b branch

  2. Make PR from b/infra:b to b/infra:main.

  3. Merge it as a squash commit

  4. Now b/infra:main has the squashed commit from your PR, and your b/infra:b branch has the original commits.

    This ends up being the only commit published on ben/infra:main (and on the mirror).


    The b/infra repo doesn't have main set as its default branch, so to see the changes there in the web UI, you need to select the main branch.

  5. Now the b/infra:main branch has the commit that we want to publish on ben/infra:main (and the mirror), but it isn't there yet. this part is easy, just push to the main branch to ben/infra:main branch (the branch protection rules allow this):

    $ git push ben main

This doesn't have to happen right away, but it helps keeping things tidy. Update your local clone, and the b branch:

  1. First, pull the squash commit down to your main branch from b/infra:main.

    $ git checkout main
    $ git pull origin main
  2. Then rebase your b branch, replacing the original commits with the squash commit in main:

    $ git checkout b
    $ git rebase main
  3. Then you need to force push that to the remote to keep it in sync

    $ git push origin b --force

    NOTE: This could probably be improved, somehow. Re-using the branch might be the wrong approach.

  4. Now its a good idea to go and compare the ben/infra:main and b/infra:main branches (and the mirror), they should be the same and have the same commits.

The website

mdBook on /docs

The /docs pages are written with mdBook1. In order to build them, Rust and cargo will need to be installed first.

Install mdbook and the plugins needed2:

$ cargo install mdbook
$ cargo install mdbook-linkcheck \
                mdbook-toc \
                mdbook-admonish \

And build the HTML pages:

$ mdbook clean
$ mdbook build

The fonts and .css files for the mdbook-katex plugin (renders expressions) are served locally3 rather than served from a CDN. In book.toml:

no-css = true
after = ["links"]

To download or update the files:

$ cargo install mdbook_katex_css_download
$ cd docs/
$ mdbook_katex_css_download

To get a dev server:

$ mdbook serve

The dev server defaults to listening on localhost:3000.

Rest API on /api

Matrix federation tester

The "official" one has a swanky web UI: But it's not so nice to hammer that one with automated checks, and it's also nice to get a report from the point of view of our own server.

$ curl -s "" | jq ".FederationOK"

The full output has a lot more details.

Matrix server

Using the API to deactivate a user is the correct way4 remove a user from Synapse:

$ curl -X POST --data '{}' \

It's also possible to do this from synapse-admin.

Deactivating a user will still leave it in the database, and visible in synapse-admin, so this is not sufficient to permanently remove appservices users that were created by a Matrix bridge for example.