Try to improve nix caching (#48297)

Release Notes:

- N/A
This commit is contained in:
Conrad Irwin
2026-02-03 20:31:02 -07:00
committed by GitHub
parent 8bf3b4fece
commit 8b6bd20a6a
5 changed files with 108 additions and 5 deletions
+23
View File
@@ -387,6 +387,10 @@ jobs:
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
with:
clean: false
- name: steps::cache_nix_dependencies_namespace
uses: namespacelabs/nscloud-cache-action@v1
with:
cache: nix
- name: nix_build::build_nix::install_nix
uses: cachix/install-nix-action@02a151ada4993995686f9ed4f1be7cfbb229e56f
with:
@@ -417,10 +421,20 @@ jobs:
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
with:
clean: false
- name: steps::cache_nix_store_macos
uses: namespacelabs/nscloud-cache-action@v1
with:
path: ~/nix-cache
- name: nix_build::build_nix::install_nix
uses: cachix/install-nix-action@02a151ada4993995686f9ed4f1be7cfbb229e56f
with:
github_access_token: ${{ secrets.GITHUB_TOKEN }}
- name: nix_build::build_nix::configure_local_nix_cache
run: |
mkdir -p ~/nix-cache
echo "extra-substituters = file://$HOME/nix-cache?priority=10" | sudo tee -a /etc/nix/nix.conf
echo "require-sigs = false" | sudo tee -a /etc/nix/nix.conf
sudo launchctl kickstart -k system/org.nixos.nix-daemon
- name: nix_build::build_nix::cachix_action
uses: cachix/cachix-action@0fc020193b5a1fa3ac4575aa3a7d3aa6a35435ad
with:
@@ -429,6 +443,15 @@ jobs:
cachixArgs: -v
- name: nix_build::build_nix::build
run: nix build .#default -L --accept-flake-config
- name: nix_build::build_nix::export_to_local_nix_cache
if: always()
run: |
if [ -L result ]; then
echo "Copying build closure to local binary cache..."
nix copy --to "file://$HOME/nix-cache" ./result || echo "Warning: nix copy to local cache failed"
else
echo "No build result found, skipping cache export."
fi
timeout-minutes: 60
continue-on-error: true
update_nightly_tag:
+23
View File
@@ -478,6 +478,10 @@ jobs:
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
with:
clean: false
- name: steps::cache_nix_dependencies_namespace
uses: namespacelabs/nscloud-cache-action@v1
with:
cache: nix
- name: nix_build::build_nix::install_nix
uses: cachix/install-nix-action@02a151ada4993995686f9ed4f1be7cfbb229e56f
with:
@@ -508,10 +512,20 @@ jobs:
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
with:
clean: false
- name: steps::cache_nix_store_macos
uses: namespacelabs/nscloud-cache-action@v1
with:
path: ~/nix-cache
- name: nix_build::build_nix::install_nix
uses: cachix/install-nix-action@02a151ada4993995686f9ed4f1be7cfbb229e56f
with:
github_access_token: ${{ secrets.GITHUB_TOKEN }}
- name: nix_build::build_nix::configure_local_nix_cache
run: |
mkdir -p ~/nix-cache
echo "extra-substituters = file://$HOME/nix-cache?priority=10" | sudo tee -a /etc/nix/nix.conf
echo "require-sigs = false" | sudo tee -a /etc/nix/nix.conf
sudo launchctl kickstart -k system/org.nixos.nix-daemon
- name: nix_build::build_nix::cachix_action
uses: cachix/cachix-action@0fc020193b5a1fa3ac4575aa3a7d3aa6a35435ad
with:
@@ -521,6 +535,15 @@ jobs:
pushFilter: -zed-editor-[0-9.]*-nightly
- name: nix_build::build_nix::build
run: nix build .#debug -L --accept-flake-config
- name: nix_build::build_nix::export_to_local_nix_cache
if: always()
run: |
if [ -L result ]; then
echo "Copying build closure to local binary cache..."
nix copy --to "file://$HOME/nix-cache" ./result || echo "Warning: nix copy to local cache failed"
else
echo "No build result found, skipping cache export."
fi
timeout-minutes: 60
continue-on-error: true
check_postgres_and_protobuf_migrations:
+1 -1
View File
@@ -1,5 +1,5 @@
{
description = "High-performance, multiplayer code editor from the creators of Atom and Tree-sitter";
description = "Zed is a minimal code editor crafted for speed and collaboration with humans and AI.";
inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
+50 -4
View File
@@ -44,6 +44,32 @@ pub(crate) fn build_nix(
))
}
// After install-nix, register ~/nix-cache as a local binary cache
// substituter so nix pulls from it on demand during builds (no bulk
// import). Also restart the daemon so it picks up the new config.
pub fn configure_local_nix_cache() -> Step<Run> {
named::bash(indoc::indoc! {r#"
mkdir -p ~/nix-cache
echo "extra-substituters = file://$HOME/nix-cache?priority=10" | sudo tee -a /etc/nix/nix.conf
echo "require-sigs = false" | sudo tee -a /etc/nix/nix.conf
sudo launchctl kickstart -k system/org.nixos.nix-daemon
"#})
}
// Incrementally copy only new store paths from the build result's
// closure into the local binary cache for the next run.
pub fn export_to_local_nix_cache() -> Step<Run> {
named::bash(indoc::indoc! {r#"
if [ -L result ]; then
echo "Copying build closure to local binary cache..."
nix copy --to "file://$HOME/nix-cache" ./result || echo "Warning: nix copy to local cache failed"
else
echo "No build result found, skipping cache export."
fi
"#})
.if_condition(Expression::new("always()"))
}
let runner = match platform {
Platform::Windows => unimplemented!(),
Platform::Linux => runners::LINUX_X86_BUNDLER,
@@ -67,10 +93,30 @@ pub(crate) fn build_nix(
job = job.needs(deps.iter().map(|d| d.name.clone()).collect::<Vec<String>>());
}
job = job
.add_step(install_nix())
.add_step(cachix_action(cachix_filter))
.add_step(build(&flake_output));
// On Linux, `cache: nix` uses bind-mounts so the /nix store is available
// before install-nix-action runs — no extra steps needed.
//
// On macOS, `/nix` lives on a read-only root filesystem and the nscloud
// cache action cannot mount or symlink there. Instead we cache a
// user-writable directory (~/nix-cache) as a local binary cache and
// register it as a nix substituter. Nix then pulls paths from it on
// demand during builds (zero-copy at startup), and after building we
// incrementally copy new paths into the cache for the next run.
job = match platform {
Platform::Linux => job
.add_step(steps::cache_nix_dependencies_namespace())
.add_step(install_nix())
.add_step(cachix_action(cachix_filter))
.add_step(build(&flake_output)),
Platform::Mac => job
.add_step(steps::cache_nix_store_macos())
.add_step(install_nix())
.add_step(configure_local_nix_cache())
.add_step(cachix_action(cachix_filter))
.add_step(build(&flake_output))
.add_step(export_to_local_nix_cache()),
Platform::Windows => unimplemented!(),
};
NamedJob {
name: format!("build_nix_{platform}_{arch}"),
@@ -138,6 +138,17 @@ pub fn cache_rust_dependencies_namespace() -> Step<Use> {
.add_with(("path", "~/.rustup"))
}
pub fn cache_nix_dependencies_namespace() -> Step<Use> {
named::uses("namespacelabs", "nscloud-cache-action", "v1").add_with(("cache", "nix"))
}
pub fn cache_nix_store_macos() -> Step<Use> {
// On macOS, `/nix` is on a read-only root filesystem so nscloud's `cache: nix`
// cannot mount or symlink there. Instead we cache a user-writable directory and
// use nix-store --import/--export in separate steps to transfer store paths.
named::uses("namespacelabs", "nscloud-cache-action", "v1").add_with(("path", "~/nix-cache"))
}
pub fn setup_linux() -> Step<Run> {
named::bash("./script/linux")
}