You indeed need some kind of nix-aware runner (e.g. with a persistent /nix) if you want both the flexibility and performance...
With "it works so well", I mean:
* CI is cheap because namespace.so runners are faster & cheaper than GitHub Actions
* the UX is exactly the same as using vanilla GitHub Actions, namespace.so's runner is a drop-in replacement
* the CI starts up very fast because `/nix/store` is stored on namespace.so's "Cached Volumes" which are like virtual disks attached to the CI runner, so there is nothing to download to prime the cache, Nix can just start running immediately
* https://github.com/cachix/cachix-action uploads whatever Nix builds to Cachix in the background so from this point on if any of our devs pulls the latest code, they don't have to build any derivations locally, and lose time waiting, everything is pulled automatically from Cachix to their machines, they can get right to work. Or if I have to purge the Cache Volume for some reason, nothing needs to be rebuilt, just pulled from Cachix.
It's taken a few years to get this dialed in, but now that it works, it's sooo good!
(full disclosure: Determinate Systems employee)
Just need to figure out what the cache size limitations are..
I use Gitlab CI and with self hosted runners I can make sure the /nix/store is persistent across CI jobs and then my builds take ~5 seconds if no code has changed, 5 seconds of which is just nix build evaluating all my nix files and realising no work needs to be done.
I think the fact that there is no bidding process for agents is a mistake that we need to correct. It's a little used concept in distributed computing, but a powerful one when applicable, and I think the preconditions for a fast build, with all of the docker images and other bootstrapping pipelines is making that cost harder to ignore. We are de facto using heterogeneous networks of worker processes now, and it's starting to reach 8 Fallacies level.
You build a distributed queue for response time or throughput, and we are using the throughput model, more or less, while CI/CD is mostly about response time.
Is there an easier way to do it?
Also, wouldn't it be pretty similar performance-wise to caching the /nix path on a generic Nix image? I've tried that, but it has problems because the Nix path ends up being a few GB, so that ends up adding a long time to the build as well.
- A bare image with just Nix can pull the deps from a cache.
- A pre-built image contains the deps from the latest push to default branch and nothing else.
I do not maintain a separate repo for this. Part of my CI is building and caching the paths. And then CD is building and pushing the image, which the CI has verified as working. This requires using a mutable tag, but you could also have the CD process auto-update the tag if this is not an option.
You're correct that this doesn't save you from having to get the same amount of data to the same place, but the image repo can usually be cached more advantageously for whatever is pulling images, so it should be considerably faster overall.
I have the complication of android + Rust (com[compiling rust for android + SQLite require gimnastics: https://www.reddit.com/r/rust/comments/1872ftd/exist_a_solid...).
My ideal setup is to have my dev env be the CI env, to stop the chance that every so often things break (my CI breaks my delicate android incantions with some regularity).
One roadblock I haven't been able to overcome is integrating Nix in CI. In my case, I use CircleCI. I know there are Nix-centric CI platforms, but I've invested a lot into CircleCI and would like to stay.
The problem I hit is that if I switch from something like a sqlfluff Docker container to a Nix Docker container, my build job goes from 15s to 2m+ because now I have to download several gigs within the CI job and build my Nix environment from scratch.[1]
I tried Cachix, but the best I could get was bringing the job down to 55s (a roughly 3x performance penalty from an off-the-shelf Docker container).[2]
How does FlakeHub Cache's performance in CI compare to the default Nux cache or to Cachix?
[0] https://mtlynch.io/notes/nix-dev-environment/
[1] https://github.com/cachix/cachix/issues/579
[2] https://github.com/cachix/cachix/issues/579#issuecomment-175...