Carl Sagan once said, “If you wish to make an apple pie from scratch, you must first invent the universe.” In the world of software, creating a reproducible build environment is the universe you need to invent. This post will walk you through using Nix in tandem with Gitea Actions to make that universe a reality for your projects.

I am an enthusiastic user of Nix and am a maintainer of several packages. I appreciate the reproducibility of the binaries it offers across different systems and its rapid update cycle.

Gitea Actions is a CI/CD solution that can run your build and deployment tasks. Using Nix within Gitea Actions is as straightforward as adding a few lines to your workflow file. Here’s how:

name: nix

on:
  push:

jobs:
  lint-backend:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Install dependencies for Nix setup action
        run: |
          apt update -y
          apt install sudo -y                    
      - uses: cachix/install-nix-action@v27
        with:
          nix_path: nixpkgs=channel:nixos-unstable
      - name: Test running command with Nix
        run: nix-shell -p hello --run "hello"

This workflow will install Nix and then execute the hello command. Note that we need to install sudo, as it is a prerequisite for the cachix/install-nix-action and is not present in the default Gitea Actions runner image. If you’re using a custom runner that already has sudo installed, feel free to skip that step.

Regarding the Nix package channel, I prefer to live on the bleeding edge with nixpkgs=channel:nixos-unstable. However, you’re free to pin to a more stable channel if you wish. The cachix/install-nix-action Action does not have a channel configured by default, so you must specify one.

If you haven’t explored Nix yet, I highly recommend you do so. It’s a powerful tool for creating consistent and reproducible build environments.