To provide more clarity about our journey, let’s begin with a few assumptions:
- Any industrial Haskell project will have private packages not found in
hackage
.
- Such a project might also utilize forked packages with patches, which, for various reasons, haven’t been upstreamed.
- The project wouldn’t prefer using an outdated GHC version.
- The development team use macOS (arm64).
Given these conditions, building Haskell projects with Nix became a time-intensive task for us.
Our initial inclination was towards haskell.nix
. However, our preliminary attempt using it was halted due to our reliance on private GitHub packages, which haskell.nix
didn’t support back then. We also encountered challenges integrating flakes with Haskell.nix
. When we revisited the idea of utilizing Nix for our Haskell projects this year, we did get haskell.nix
to work. Yet, we opted against full adoption. The complexity of the solution meant that delving into the code and troubleshooting issues wasn’t straightforward. We didn’t aspire to become haskell.nix
specialists, but it seemed almost mandatory for serious utilization. The last thing we wanted was to get stuck updating a package and then grapple with haskell.nix
for days.
Our subsequent effort involved directly using the haskellPackages
tooling in Nix. While this approach was somewhat successful, it lacked scalability, especially when juggling multiple projects and our numerous private packages.
Ultimately, we settled on crafting our package set, leveraging both haskell-flake and flake-parts
. This allowed all our Haskell projects and packages to access the package set. We also incorporated caching through cachix
and established a CI runner in cirus labs
for aarch64-darwin
. This ensured local builds were manageable. While our current setup operates efficiently, my initial message aimed to underscore the challenges of the setup process and the ongoing cost of maintaining it.