Notes on

For the past few months I’ve been using sourcehut’s platform to work on software an it has been quite an interesting experience. Nonetheless, one of the services I really enjoy using is the their build service called is a service on that allows you to submit “build manifests” for us to work on. –

The thing I don’t like on GitHub Actions is that it is kind of magical. For example, you don’t actually know what it is doing when you define that an action should only run when a specific path is modified. Not to even mention their custom actions which usually takes a non-trivial amount of TypeScript/JavaScript.

Contrary to this, is really explicit on its build manifest. You’re basically expected to write plain shell scripts for your builds.

Reducing resource usage

As I said previously, there’s no special syntax to work on specific paths, branches, pull requests and such. By default your task will run on every commit you push. In order to reduce our CI usage we can restrain our tasks to run on specific scenarios:

On path change

if ! $(git diff --quiet HEAD HEAD^ -- "<your-path>")
  # do something

On branch change

This tip was taken from issue #170.

- check-branch: |
   cd repo_name
   if [ "$(git rev-parse your-branch)" != "$(git rev-parse HEAD)" ]; then \
      complete-build; \

NixOS on

As I don’t like to write shell scripts I use Nix and this is my favorite feature of this service. supports NixOS by default1. This means that we can leverage Nix Flakes for truly declarative and reproducible builds there! Let’s consider a small example using Go to show you how easy it really is. A small flake.nix containing the following content should suffice our needs:

  inputs.nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable";

  outputs = { self, nixpkgs, ... }:
    let pkgs = import nixpkgs { system = "x86_64-linux"; };
      devShells."x86_64-linux".ci = with pkgs; mkShell {
        buildInputs = [ go golangci-lint ];

This definition is capable of giving us a shell containing Go and golangci-lint on $PATH.

Now let’s write the build manifest for our CI:

image: nixos/unstable
  - nixos.nixUnstable
  NIX_CONFIG: "experimental-features = nix-command flakes"
  - lint: |
      cd source
      nix develop .#ci -c golangci-lint run      
  - test: |
      cd source
      nix develop .#ci -c go test ./...      
  - build: |
      cd source
      nix develop .#ci -c go build      

And that’s it! We have our CI up and running with the guarantee of having our tools being the same on every run. No sudden updates or unexpected behavior.

Articles from blogs I follow around the net

Variations of the Range kata

In the languages I usually employ. The Range kata is succinct, bordering on the spartan in both description and requirements. To be honest, it's hardly the most inspiring kata available, and yet it may help showcase a few in…

via ploeh blog January 1, 2024

Some notes on NixOS

Hello! Over the holidays I decided it might be fun to run NixOS on one of my servers, as part of my continuing experiments with Nix. My motivation for this was that previously I was using Ansible to provision the server, but then I’d ad hoc installed a bunch…

via Julia Evans January 1, 2024

I found some of my first code! Annotating and reflecting on robotics code from 2009.

In high school, one of my teachers shattered my plans for my life, in the most beautiful way. Most of my life, I'd intended to become a math professional of some sort: a math teacher, when that was all I saw math for; an actuary, when I started to lear…

via blog January 1, 2024

Generated by openring