Building with Nix

Jolt can use the Nix package manager to provision build environments with tools and dependencies for tasks to use. A list of required packages can be listed directly in the task class.

The example task below provisions three versions of the Go programming language and uses them to build three different versions of the same program for comparison.

# go.jolt

from jolt import influence
from jolt import Task


@influence.files("main.go")
class App(Task):
    def run(self, deps, tools):
        self.builddir = tools.builddir()

        for version in ["1_19", "1_20", "1_21"]:
            with tools.nixpkgs(packages=[f"go_{version}"], path=["nixpkgs=channel:nixos-23.11"]):
                tools.run("go build -o {builddir}/app.v{} main.go", version)

    def publish(self, artifact, tools):
        with tools.cwd(self.builddir):
            artifact.collect("app.*")

It is important to specify a Nix channel to use. The channel is a collection of Nix packages and is used to resolve package names to package paths and to fetch the packages from a binary cache. Without a channel, the Nix package manager may not be able to find the packages or the environment may not be deterministically reproducible.

It is also possible to create a Nix derivation in a separate file and use it in the task class:

# env.nix

let
  nixpkgs = fetchTarball "https://github.com/NixOS/nixpkgs/tarball/nixos-23.11";
  pkgs = import nixpkgs {};
in

pkgs.mkShell {
  packages = [
    pkgs.go
  ];
}

The derivation file is pointed to by the nixfile attribute:

# derivation.jolt

from jolt import influence
from jolt import Task


@influence.files("env.nix")
@influence.files("main.go")
class DerivationApp(Task):
    name = "app/derivation"

    def run(self, deps, tools):
        self.builddir = tools.builddir()

        # Build the go app using a Nix shell derivation
        with tools.nixpkgs(nixfile="env.nix"):
            tools.run("go build -o {builddir}/app.bin main.go")

    def publish(self, artifact, tools):
        with tools.cwd(self.builddir):
            artifact.collect("app.bin")

The Nix package manager is not available on Windows (except in WSL).