= Guix inside sourcehut builds.sr.ht CI :nixos: https://man.sr.ht/builds.sr.ht/compatibility.md#nixos :guix: https://guix.gnu.org/ :binary-inst: https://guix.gnu.org/manual/en/guix.html#Binary-Installation :shell-inst: https://git.savannah.gnu.org/cgit/guix.git/plain/etc/guix-install.sh After the release of the {nixos}[NixOS images in builds.sr.ht] and much usage of it, I also started looking at {guix}[Guix] and wondered if I could get it on the awesome builds.sr.ht service. The Guix manual section on the {binary-inst}[binary installation] is very thorough, and even a {shell-inst}[shell installer script] is provided, but it is built towards someone installing Guix on their personal computer, and relies heavily on interactive input. I developed the following set of scripts that I have been using for some time to run Guix tasks inside builds.sr.ht jobs. First, `install-guix.sh`: [source,shell] ---- #!/usr/bin/env bash set -x set -Eeuo pipefail VERSION='1.0.1' SYSTEM='x86_64-linux' BINARY="guix-binary-${VERSION}.${SYSTEM}.tar.xz" cd /tmp wget "https://ftp.gnu.org/gnu/guix/${BINARY}" tar -xf "${BINARY}" sudo mv var/guix /var/ sudo mv gnu / sudo mkdir -p ~root/.config/guix sudo ln -fs /var/guix/profiles/per-user/root/current-guix ~root/.config/guix/current GUIX_PROFILE="$(echo ~root)/.config/guix/current" source "${GUIX_PROFILE}/etc/profile" groupadd --system guixbuild for i in $(seq -w 1 10); do useradd -g guixbuild \ -G guixbuild \ -d /var/empty \ -s "$(command -v nologin)" \ -c "Guix build user ${i}" --system \ "guixbuilder${i}"; done mkdir -p /usr/local/bin cd /usr/local/bin ln -s /var/guix/profiles/per-user/root/current-guix/bin/guix . ln -s /var/guix/profiles/per-user/root/current-guix/bin/guix-daemon . guix archive --authorize < ~root/.config/guix/current/share/guix/ci.guix.gnu.org.pub ---- Almost all of it is taken directly from the {binary-inst}[binary installation] section from the manual, with the interactive bits stripped out: after downloading and extracting the Guix tarball, we create some symlinks, add guixbuild users and authorize the `ci.guix.gnu.org.pub` signing key. After installing Guix, we perform a `guix pull` to update Guix inside `start-guix.sh`: [source,shell] ---- #!/usr/bin/env bash set -x set -Eeuo pipefail sudo guix-daemon --build-users-group=guixbuild & guix pull guix package -u guix --version ---- Then we can put it all together in a sample `.build.yml` configuration file I'm using myself: [source,yaml] ---- image: debian/stable packages: - wget sources: - https://git.sr.ht/~euandreh/songbooks tasks: - install-guix: | cd ./songbooks/ ./scripts/install-guix.sh ./scripts/start-guix.sh echo 'sudo guix-daemon --build-users-group=guixbuild &' >> ~/.buildenv echo 'export PATH="${HOME}/.config/guix/current/bin${PATH:+:}$PATH"' >> ~/.buildenv - tests: | cd ./songbooks/ guix environment -m build-aux/guix.scm -- make check - docs: | cd ./songbooks/ guix environment -m build-aux/guix.scm -- make publish-dist ---- We have to add the `guix-daemon` to `~/.buildenv` so it can be started on every following task run. Also, since we used `wget` inside `install-guix.sh`, we had to add it to the images package list. After the `install-guix` task, you can use Guix to build and test your project, or run any `guix environment --ad-hoc my-package -- my script` :) == Improvements :repository: https://git.sr.ht/~sircmpwn/builds.sr.ht When I originally created this code I had a reason why to have both a `sudo` call for `sudo ./scripts/install-guix.sh` and `sudo` usages inside `install-guix.sh` itself. I couldn't figure out why (it feels like my past self was a bit smarter 😬), but it feels ugly now. If it is truly required I could add an explanation for it, or remove this entirely in favor of a more elegant solution. I could also contribute the Guix image upstream to builds.sr.ht, but there wasn't any build or smoke tests in the original {repository}[repository], so I wasn't inclined to make something that just ``works on my machine'' or add a maintainence burden to the author. I didn't look at it again recently, though.