nix: Add nightly build job with cachix (#27014)

Julia Ryan created

I'll be using this to `nix run github:zed-industries/zed/nightly` and
get an up-to-date and cached nightly build.

It'll also serve as a way to warn me when the nix build is broken,
rather than having to wait for users to report it.

Eventually and depending on the build time of the nix builds, we may
want to consider putting a nix build in CI (#17458) to prevent
breakages, but for now a best-effort nightly build that doesn't block
the job if it fails is a good start.

Resolve #19937

Release Notes:

- N/A

Change summary

.github/workflows/release_nightly.yml | 52 +++++++++++++++++++++++++++++
flake.nix                             |  9 +++++
nix/build.nix                         | 16 +++++---
nix/shell.nix                         |  2 +
4 files changed, 72 insertions(+), 7 deletions(-)

Detailed changes

.github/workflows/release_nightly.yml 🔗

@@ -170,6 +170,58 @@ jobs:
       - name: Upload Zed Nightly
         run: script/upload-nightly linux-targz
 
+  bundle-nix:
+    timeout-minutes: 60
+    name: (${{ matrix.system.os }}) Nix Build
+    continue-on-error: true
+    strategy:
+      fail-fast: false
+      matrix:
+        system:
+          - os: x86 Linux
+            runner: buildjet-16vcpu-ubuntu-2204
+            install_nix: true
+          - os: arm Mac
+            # TODO: once other macs are provisioned for nix, remove that constraint from the runner
+            runner: [macOS, ARM64, nix]
+            install_nix: false
+          - os: arm Linux
+            runner: buildjet-16vcpu-ubuntu-2204-arm
+            install_nix: true
+    if: github.repository_owner == 'zed-industries'
+    runs-on: ${{ matrix.system.runner }}
+    needs: tests
+    env:
+      ZED_CLIENT_CHECKSUM_SEED: ${{ secrets.ZED_CLIENT_CHECKSUM_SEED }}
+      ZED_CLOUD_PROVIDER_ADDITIONAL_MODELS_JSON: ${{ secrets.ZED_CLOUD_PROVIDER_ADDITIONAL_MODELS_JSON }}
+      GIT_LFS_SKIP_SMUDGE: 1 # breaks the livekit rust sdk examples which we don't actually depend on
+    steps:
+      - name: Checkout repo
+        uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
+        with:
+          clean: false
+
+      # on our macs we manually install nix. for some reason the cachix action is running
+      # under a non-login /bin/bash shell which doesn't source the proper script to add the
+      # nix profile to PATH, so we manually add them here
+      - name: Set path
+        if: ${{ ! matrix.system.install_nix }}
+        run: |
+          echo "/nix/var/nix/profiles/default/bin" >> $GITHUB_PATH
+          echo "/Users/administrator/.nix-profile/bin" >> $GITHUB_PATH
+
+      - uses: cachix/install-nix-action@02a151ada4993995686f9ed4f1be7cfbb229e56f # v31
+        if: ${{ matrix.system.install_nix }}
+        with:
+          github_access_token: ${{ secrets.GITHUB_TOKEN }}
+
+      - uses: cachix/cachix-action@0fc020193b5a1fa3ac4575aa3a7d3aa6a35435ad # v16
+        with:
+          name: zed-industries
+          authToken: "${{ secrets.CACHIX_AUTH_TOKEN }}"
+      - run: nix build
+      - run: nix-collect-garbage -d
+
   update-nightly-tag:
     name: Update nightly tag
     if: github.repository_owner == 'zed-industries'

flake.nix 🔗

@@ -63,4 +63,13 @@
         default = nixpkgs.lib.composeManyExtensions (builtins.attrValues overlays);
       };
     };
+
+  nixConfig = {
+    extra-substituters = [
+      "https://zed-industries.cachix.org"
+    ];
+    extra-trusted-public-keys = [
+      "zed-industries.cachix.org-1:QW3RoXK0Lm4ycmU5/3bmYRd3MLf4RbTGPqRulGlX5W0="
+    ];
+  };
 }

nix/build.nix 🔗

@@ -38,6 +38,7 @@
   nodejs_22,
 
   withGLES ? false,
+  profile ? "release",
 }:
 
 assert withGLES -> stdenv.hostPlatform.isLinux;
@@ -153,6 +154,9 @@ let
           ]
         }";
         LK_CUSTOM_WEBRTC = livekit-libwebrtc;
+        CARGO_PROFILE = profile;
+        # need to handle some profiles specially https://github.com/rust-lang/cargo/issues/11053
+        TARGET_DIR = "target/" + (if profile == "dev" then "debug" else profile);
       };
 
       # prevent nix from removing the "unused" wayland/gpu-lib rpaths
@@ -228,13 +232,13 @@ craneLib.buildPackage (
           pushd crates/zed
           sed -i "s/package.metadata.bundle-nightly/package.metadata.bundle/" Cargo.toml
           export CARGO_BUNDLE_SKIP_BUILD=true
-          app_path="$(cargo bundle --release | xargs)"
+          app_path="$(cargo bundle --profile $CARGO_PROFILE | xargs)"
           popd
 
           mkdir -p $out/Applications $out/bin
           # Zed expects git next to its own binary
           ln -s ${git}/bin/git "$app_path/Contents/MacOS/git"
-          mv target/release/cli "$app_path/Contents/MacOS/cli"
+          mv $TARGET_DIR/cli "$app_path/Contents/MacOS/cli"
           mv "$app_path" $out/Applications/
 
           # Physical location of the CLI must be inside the app bundle as this is used
@@ -244,21 +248,19 @@ craneLib.buildPackage (
           runHook postInstall
         ''
       else
-        # TODO: icons should probably be named "zed-nightly". fix bundle-linux first
         ''
           runHook preInstall
 
           mkdir -p $out/bin $out/libexec
-          cp target/release/zed $out/libexec/zed-editor
-          cp target/release/cli $out/bin/zed
+          cp $TARGET_DIR/zed $out/libexec/zed-editor
+          cp $TARGET_DIR/cli $out/bin/zed
 
           install -D "crates/zed/resources/app-icon-nightly@2x.png" \
             "$out/share/icons/hicolor/1024x1024@2x/apps/zed.png"
           install -D crates/zed/resources/app-icon-nightly.png \
             $out/share/icons/hicolor/512x512/apps/zed.png
 
-          # extracted from ../script/bundle-linux (envsubst) and
-          # ../script/install.sh (final desktop file name)
+          # TODO: icons should probably be named "zed-nightly"
           (
             export DO_STARTUP_NOTIFY="true"
             export APP_CLI="zed"

nix/shell.nix 🔗

@@ -49,6 +49,8 @@ mkShell' {
     (removeAttrs baseEnvs [
       "LK_CUSTOM_WEBRTC" # download the staticlib during the build as usual
       "ZED_UPDATE_EXPLANATION" # allow auto-updates
+      "CARGO_PROFILE" # let you specify the profile
+      "TARGET_DIR"
     ])
     // {
       # note: different than `$FONTCONFIG_FILE` in `build.nix` – this refers to relative paths