From c3b44020f4c271ad518a2270a4cb52d1e294012c Mon Sep 17 00:00:00 2001 From: Chris Marchesi Date: Thu, 23 Nov 2023 21:41:55 -0800 Subject: [PATCH] nix: add GitHub Actions workflow This adds a nix workflow that does the following: * Checks to see if the Zig cache fixed derivation needs its hash updated. It does this by downloading a new cache, calculating the hash, and comparing it against what has already been set. If the hash is different, the workflow fails. * Runs a Nix build if the hash is OK, testing the build of packages.ghostty (using "nix build .") The cache workflow we use in the build job comes from: https://github.com/DeterminateSystems/magic-nix-cache-action/ Fixes #937. --- .github/workflows/nix.yml | 30 ++++++++++ README.md | 67 +++++++++++++++++++++++ nix/build-support/check-zig-cache-hash.sh | 60 ++++++++++++++++++++ nix/package.nix | 2 +- nix/zig_cache_hash.nix | 3 + 5 files changed, 161 insertions(+), 1 deletion(-) create mode 100644 .github/workflows/nix.yml create mode 100755 nix/build-support/check-zig-cache-hash.sh create mode 100644 nix/zig_cache_hash.nix diff --git a/.github/workflows/nix.yml b/.github/workflows/nix.yml new file mode 100644 index 000000000..3a7c263b8 --- /dev/null +++ b/.github/workflows/nix.yml @@ -0,0 +1,30 @@ +on: [push, pull_request] +name: Nix +jobs: + check-zig-cache-hash: + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@v4 + - name: Setup Nix + uses: cachix/install-nix-action@v23 + with: + nix_path: nixpkgs=channel:nixos-unstable + - name: Check Zig cache hash + run: nix develop -c ./nix/build-support/check-zig-cache-hash.sh + build: + needs: check-zig-cache-hash + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@v4 + - name: Setup Nix + uses: cachix/install-nix-action@v23 + with: + nix_path: nixpkgs=channel:nixos-unstable + - name: Setup Nix cache + uses: DeterminateSystems/magic-nix-cache-action@main + with: + diagnostic-endpoint: "" # disable telemetry + - name: Run build + run: nix build . diff --git a/README.md b/README.md index f029d80c2..5c9526736 100644 --- a/README.md +++ b/README.md @@ -469,3 +469,70 @@ prettier --write . ``` Make sure your Prettier version matches the version of in [devshell.nix](https://github.com/mitchellh/ghostty/blob/main/nix/devshell.nix). + +### Nix Package + +> [!WARNING] +> The Nix package currently depends on versions of LLVM and Zig that are +> currently not in cache.nixos.org and will be built from source. This can take +> a very long time, especially in situations where CPU is at a premium. Most +> people should follow the instructions in [Developing +> Ghostty](#developing-ghostty) instead. + +There is a functional Nix package that can be used in the `flake.nix` file +(`packages.ghostty`). It can be used in NixOS configurations and otherwise +built off of (however, please heed the above warning). + +Below is a sample on how to add it to a NixOS overlay: + +```nix +{ + inputs = { + nixpkgs.url = github:NixOS/nixpkgs/nixos-unstable; + + # NOTE: This will require your git SSH access to the repo + ghostty = { + url = git+ssh://git@github.com/mitchellh/ghostty; + inputs.nixpkgs.follows = "nixpkgs"; + }; + }; + + outputs = { nixpkgs, ghostty, ... }: { + nixosConfigurations.nixos = nixpkgs.lib.nixosSystem { + modules = [ + { + nixpkgs.overlays = [ + (final: prev: { + ghostty = ghostty.packages.${prev.system}.ghostty; + }) + ]; + } + + # Other modules here... + ]; + }; + }; +} +``` + +You can also test the build of the nix package at any time by running `nix build .` + +#### Updating the Zig Cache Fixed-Output Derivation Hash + +The Nix package depends on a [fixed-output +derivation](https://nixos.org/manual/nix/stable/language/advanced-attributes.html#adv-attr-outputHash) +that manages the Zig package cache. This allows the package to be built in the +Nix sandbox. + +Occasionally (usually when `build.zig.zon` is updated), the hash that +identifies the cache will need to be updated. There are jobs that monitor the +hash in CI, and builds will fail if it drifts. + +To update it, you can run the following in the repository root: + +``` +./nix/build-support/check-zig-cache-hash.sh --update +``` + +This will write out the `nix/zig_cache_hash.nix` file with the updated hash +that can then be committed and pushed to fix the builds. diff --git a/nix/build-support/check-zig-cache-hash.sh b/nix/build-support/check-zig-cache-hash.sh new file mode 100755 index 000000000..8c02e237b --- /dev/null +++ b/nix/build-support/check-zig-cache-hash.sh @@ -0,0 +1,60 @@ +#!/usr/bin/env bash + +# Nothing in this script should fail. +set -e + +CACHE_HASH_FILE="$(realpath "$(dirname "$0")/../zig_cache_hash.nix")" + +help() { + echo "" + echo "To fix, please (manually) re-run the script from the repository root," + echo "commit, and push the update:" + echo "" + echo " ./nix/build-support/check-zig-cache-hash.sh --update" + echo " git add nix/zig_cache_hash.nix" + echo " git commit -m \"nix: update Zig cache hash\"" + echo " git push" + echo "" +} + +if [ -f "${CACHE_HASH_FILE}" ]; then + OLD_CACHE_HASH="$(nix eval --raw --file "${CACHE_HASH_FILE}")" +elif [ "$1" != "--update" ]; then + echo -e "\nERROR: Zig cache hash file missing." + help + exit 1 +fi + +TMP_CACHE_DIR="$(mktemp --directory --suffix nix-zig-cache)" +# This is not 100% necessary in CI but is helpful when running locally to keep +# a local workstation clean. +trap 'rm -rf "${TMP_CACHE_DIR}"' EXIT + +# Run Zig and download the cache to the temporary directory. +zig build --fetch --global-cache-dir "${TMP_CACHE_DIR}" + +# Now, calculate the hash. +ZIG_CACHE_HASH="sha256-$(nix-hash --type sha256 --to-base64 "$(nix-hash --type sha256 "${TMP_CACHE_DIR}")")" + +if [ "${OLD_CACHE_HASH}" == "${ZIG_CACHE_HASH}" ]; then + echo -e "\nOK: Zig cache store hash unchanged." + exit 0 +elif [ "$1" != "--update" ]; then + echo -e "\nERROR: The Zig cache store hash has updated." + echo "" + echo " * Old hash: ${OLD_CACHE_HASH}" + echo " * New hash: ${ZIG_CACHE_HASH}" + help + exit 1 +else + echo -e "\nNew Zig cache store hash: ${ZIG_CACHE_HASH}" +fi + +# Write out the cache file +cat > "${CACHE_HASH_FILE}" <