diff --git a/.github/workflows/nix-vendor-hash.yml b/.github/workflows/nix-vendor-hash.yml new file mode 100644 index 00000000..5535d43f --- /dev/null +++ b/.github/workflows/nix-vendor-hash.yml @@ -0,0 +1,54 @@ +name: Nix Vendor Hash + +# Keep flake.nix's buildGoModule vendorHash in sync after dependency-bearing +# changes land on main. Only the go-modules fixed-output derivation is built +# (no compile), so this is cheap. Pushes a fixup commit on drift. +on: + push: + branches: [main] + paths: + - "go.mod" + - "go.sum" + - "go.work" + - "go.work.sum" + - "flake.nix" + - "flake.lock" + - "Makefile" + - "scripts/update-nix-vendor-hash.sh" + - ".github/workflows/nix-vendor-hash.yml" + workflow_dispatch: + +concurrency: + group: nix-vendor-hash-${{ github.ref }} + cancel-in-progress: true + +permissions: + contents: write + +jobs: + update: + name: update vendorHash + runs-on: ubuntu-latest + timeout-minutes: 15 + steps: + - name: Checkout repository + uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + + - name: Install Nix + uses: DeterminateSystems/nix-installer-action@33c9ab3ef95cd57c164d9d6eb1f9a46338538d41 # main + + - name: Update vendorHash + run: make nix-vendor-hash + + - name: Commit updated vendorHash + run: | + set -euo pipefail + if git diff --quiet -- flake.nix; then + echo "vendorHash already current" + exit 0 + fi + git config user.name "github-actions[bot]" + git config user.email "41898282+github-actions[bot]@users.noreply.github.com" + git add flake.nix + git commit -m "chore(nix): update vendorHash" + git push origin "HEAD:${GITHUB_REF_NAME}" diff --git a/Makefile b/Makefile index c2fa13e2..9bf51d6c 100644 --- a/Makefile +++ b/Makefile @@ -139,3 +139,8 @@ container-smoke: build clean: rm -f strike $(COVER_PROFILE) rm -rf web/dist web/node_modules + +# Recompute flake.nix vendorHash after go.mod/go.sum changes (CI also does this). +.PHONY: nix-vendor-hash +nix-vendor-hash: + ./scripts/update-nix-vendor-hash.sh diff --git a/flake.nix b/flake.nix index 7de0258f..9d07cda0 100644 --- a/flake.nix +++ b/flake.nix @@ -18,12 +18,16 @@ src = self; proxyVendor = true; - vendorHash = "sha256-ax5mSaryrwb+vSoqm6+Brl6RnA/2WZm+z+eEdxubhtQ="; + vendorHash = "sha256-kEJmV3MQt8k5KuXBjYoUy7+ZZrD3aTljpBziaRndJcU="; subPackages = [ "cmd/strike" ]; preBuild = '' go generate ./internal/frontend/tui/app ''; + # eval tests write under $HOME; the sandbox HOME (/homeless-shelter) is unwritable + preCheck = '' + export HOME="$(mktemp -d)" + ''; ldflags = [ "-s" "-w" diff --git a/scripts/update-nix-vendor-hash.sh b/scripts/update-nix-vendor-hash.sh new file mode 100755 index 00000000..da92aff7 --- /dev/null +++ b/scripts/update-nix-vendor-hash.sh @@ -0,0 +1,52 @@ +#!/usr/bin/env bash +# Recompute flake.nix's buildGoModule vendorHash after go.mod/go.sum change. +# Only realises the go-modules fixed-output derivation (.#default.goModules), +# never compiles strike, so it's cheap. Prints the old -> new hash on change. +set -euo pipefail + +repo_root="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" +flake="${repo_root}/flake.nix" + +current_hash="$( + sed -nE 's/^[[:space:]]*vendorHash = "([^"]+)";[[:space:]]*$/\1/p' "${flake}" | head -n1 +)" + +if [[ -z "${current_hash}" ]]; then + echo "could not find quoted vendorHash in ${flake}" >&2 + exit 1 +fi + +restore_current_hash() { + # NOTE: | delimiter because vendor hashes are base64 and may contain /, + # which would terminate an s/// substitution early. + perl -0pi -e "s|vendorHash = nixpkgs\\.lib\\.fakeHash;|vendorHash = \"${current_hash}\";|" "${flake}" +} + +perl -0pi -e 's/vendorHash = "[^"]+";/vendorHash = nixpkgs.lib.fakeHash;/' "${flake}" +trap restore_current_hash EXIT + +set +e +build_output="$(cd "${repo_root}" && nix build .#default.goModules --no-link 2>&1)" +build_status=$? +set -e + +new_hash="$( + printf '%s\n' "${build_output}" | + sed -nE 's/^[[:space:]]*got:[[:space:]]*(sha256-[A-Za-z0-9+/=]+)[[:space:]]*$/\1/p' | + tail -n1 +)" + +if [[ -z "${new_hash}" ]]; then + printf '%s\n' "${build_output}" >&2 + echo "nix did not report a replacement vendorHash" >&2 + exit "${build_status}" +fi + +trap - EXIT +perl -0pi -e "s|vendorHash = nixpkgs\\.lib\\.fakeHash;|vendorHash = \"${new_hash}\";|" "${flake}" + +if [[ "${new_hash}" == "${current_hash}" ]]; then + echo "vendorHash already current: ${current_hash}" +else + echo "updated vendorHash: ${current_hash} -> ${new_hash}" +fi