If you’ve been around the hacker-news-sphere during the last year you must have heard of SourceHut (also known as sr.ht). A new no frills open source alternative to GitHub and GitLab. Sourcehut’s offering is split into a growing list of separate services, including git and mercurial hosting, ticket tracking, and even wiki hosting.

One of Sourcehut’s strongest offerings is its build system, https://builds.sr.ht/. Despite its spartan appearance, SourceHut’s CI offering has many features that put it a step above competing CI services, such as GitLab’s or Travis’.

For instance, in addition to the usual Linux distro images running on x86 architecture, Sourcehut supports a large number of operating systems and architecture combos. They range all the way from Linux on x86 to FreeBSD running on PowerPC. This eclectic selection has made it the service of choice for many open source projects that wish to build on many operating systems and architectures.

Let’s take a look at how dispatching a build to SourceHut looks like,

Dispatching Jobs Manually

The fastest way to get started with builds.sr.ht is to dispatch a build manually. After you’ve made an account, simply click on the Submit Manifest button on the main builds.sr.ht page and start typing your build manifest into the textbox.SourceHut’s manifest format shouldn’t be too hard to understand if you’re familiar with similar services. Here’s an example manifest, used to run ledgeroni’s test suite,

image: debian/testing
  - build-essential
  - libssl-dev 
  - zlib1g-dev
  - libbz2-dev
  - libreadline-dev 
  - libsqlite3-dev
  - wget
  - llvm
  - libncurses5-dev
  - libncursesw5-dev
  - xz-utils 
  - tk-dev
  - libffi-dev
  - liblzma-dev
  - https://github.com/rafacastillol/ledgeroni.git
  - setup: |
      curl -L https://raw.githubusercontent.com/pyenv/pyenv-installer/master/bin/pyenv-installer | bash
      export PATH="/home/build/.pyenv/bin:$PATH"
      eval "$(pyenv init -)"
      eval "$(pyenv virtualenv-init -)"
      pyenv install 3.7.5
      pyenv local 3.7.5
      cd ledgeroni
      pip install pytest
      pip install .
  - test: |
      export PATH="/home/build/.pyenv/bin:$PATH"
      eval "$(pyenv init -)"
      eval "$(pyenv virtualenv-init -)"
      cd ledgeroni
      pyenv local 3.7.5

Manifest files are written in yaml format. You can specify what image to use for the virtual machine and specify some dependencies that should be installed, business as usual. Specify where to get your sources from, since the build isn’t tied to a source control repository, and finally include a list of tasks to be run sequentially. These are simple shell scripts, nothing fancy. We can now submit our build and watch our tests run peacefully.

Dissecting a Failing Build

I mean, that’s in an ideal world, but the build actually fails! Looking at the logs, we can trace the cause down to forgetting to include curl in our dependency list. Anyone following from home can click the edit and resubmit button, make the edit, and watch it go!

Before that we can use another of SourceHut’s features to make sure this was the issue. If you run the failing manifest, you’ll see a message like this at the top,

When a build fails, SourceHut will actually keep the virtual machine around for a while and allow us to ssh into it to investigate the failure in search of a possible fix. Copying and running the ssh command provided, we can immediately connect to the VM, install Curl, and re-run our failing commands.

Being able to ssh into the machine when a build fails is the sort of feature that sets SourceHut apart from the competition, and makes it a first class experience in terms of developer ergonomics.

Automatically Dispatching Builds

If you’ve used CI before, you’re probably used to builds triggering when you upload new changes to a repository. You may have noticed these features are suspiciously missing from builds.sr.ht. If you host your code on SourceHut, builds happen automatically if you include a build.yml in your code repository. Yet that doesn’t mean that you’re left stranded if you happen to use a different code hosting service.

dispatch.sr.ht is the SourceHut service responsible for this kind of automation. It currently supports integration with GitHub and GitLab, but it’s possible other services will be added in the future.

Setting up dispatch.sr.ht to work with GitHub is a simple process, similar to the way you’d set up CI on a similar service such as Travis. At dispatch.sr.ht, click the configure new task button. After that, on the next page pick the GitHub Commits option. You’ll have to authorize your GitHub account to interact with SourceHut. After this simply select the repo you want to set up. Once you’ve done this, SourceHut will run any build.yml file checked into your repo every time you commit to GitHub.

By using dispatch.sr.ht transitioning into the SourceHut ecosystem can be gradual and relatively painless. One should keep in mind that the service is still in alpha status, so there are still many rough edges (patches are welcome!). Still, it’s definitely a name to keep in mind if you want to experiment with different ways of developing software beyond the standard GitHub model.

If you have any questions send me a message to [email protected].