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
- 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.