diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index d196b38..0d44e63 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -38,14 +38,6 @@ jobs: - name: Install dependencies run: bun install --frozen-lockfile - - name: Verify Nix lockfile is up to date - run: | - bun run nix:update-lock - if ! git diff --exit-code nix/bun.lock.nix; then - echo "::error::Nix lockfile is out of date. Please run 'bun run nix:update-lock' and commit the changes to nix/bun.lock.nix." - exit 1 - fi - - name: Format check run: bun run format:check diff --git a/.github/workflows/nix.yml b/.github/workflows/nix.yml new file mode 100644 index 0000000..c7975a6 --- /dev/null +++ b/.github/workflows/nix.yml @@ -0,0 +1,59 @@ +name: Nix + +on: + pull_request: + paths-ignore: + - "**/*.md" + - "docs/**" + - "assets/**" + - "LICENSE" + push: + branches: + - main + paths-ignore: + - "**/*.md" + - "docs/**" + - "assets/**" + - "LICENSE" + +concurrency: + group: nix-${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +jobs: + package: + name: Package + runs-on: ubuntu-latest + steps: + - name: Check out repository + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + + - name: Install Nix + uses: cachix/install-nix-action@8aa03977d8d733052d78f4e008a241fd1dbf36b3 # v31.10.6 + with: + extra_nix_config: | + extra-trusted-substituters = https://nix-community.cachix.org + extra-trusted-public-keys = nix-community.cachix.org-1:mB9FSh9qf2dCimDSUo8Zy7bkq5CX+/rkCWyvRCYg3Fs= + + - name: Verify Nix dependency lockfile + run: | + nix run .#update-bun-lock + if ! git diff --exit-code nix/bun.lock.nix; then + echo "::error::Nix lockfile is out of date. Please run 'bun run nix:update-lock' and commit the changes to nix/bun.lock.nix." + exit 1 + fi + + - name: Check flake outputs + run: nix flake check --print-build-logs + + - name: Evaluate all supported systems + run: nix flake check --all-systems --no-build + + - name: Build Hunk package + run: nix build .#default --print-build-logs + + - name: Smoke test Nix package + run: | + ./result/bin/hunk --version + skill_path="$(./result/bin/hunk skill path)" + test -f "$skill_path" diff --git a/.github/workflows/pr-ci.yml b/.github/workflows/pr-ci.yml index 6c1723f..6fd8968 100644 --- a/.github/workflows/pr-ci.yml +++ b/.github/workflows/pr-ci.yml @@ -81,14 +81,6 @@ jobs: - name: Install dependencies run: bun install --frozen-lockfile - - name: Verify Nix lockfile is up to date - run: | - bun run nix:update-lock - if ! git diff --exit-code nix/bun.lock.nix; then - echo "::error::Nix lockfile is out of date. Please run 'bun run nix:update-lock' and commit the changes to nix/bun.lock.nix." - exit 1 - fi - - name: Format check run: bun run format:check diff --git a/CHANGELOG.md b/CHANGELOG.md index 06c7e17..1dfc532 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,7 @@ All notable user-visible changes to Hunk are documented in this file. ### Added - Added Windows x64 prebuilt artifact publishing to the release workflow. +- Added Nix flake app outputs for `nix run` and a named `hunk` package output. ### Changed diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index f57cf96..f8d2186 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -87,6 +87,24 @@ bun run check:prebuilt-pack bun run publish:prebuilt:npm -- --dry-run ``` +## Updating dependencies + +After changing JavaScript or Bun dependencies, regenerate the Nix dependency lockfile so CI stays green: + +```bash +bun install +bun run nix:update-lock +git add bun.lock nix/bun.lock.nix package.json +``` + +The `nix:update-lock` script requires a one-time [Nix install](https://nixos.org/download/): + +```bash +curl -L https://nixos.org/nix/install | sh +``` + +If you don't have Nix installed, CI will catch the drift and a maintainer can push the regenerated lockfile as a follow-up commit. + ## Validation expectations - Rendering changes: run `bun run typecheck`, `bun test`, `bun run test:tty-smoke`, and do one real TTY smoke run on an actual diff. diff --git a/bun.lock b/bun.lock index 5af2ced..bf714d9 100644 --- a/bun.lock +++ b/bun.lock @@ -18,7 +18,7 @@ "@hunk/session-broker-node": "workspace:*", "@opentui/core": "^0.1.88", "@opentui/react": "^0.1.88", - "@types/bun": "latest", + "@types/bun": "1.3.10", "@types/react": "^19.2.14", "@types/ws": "^8.18.1", "lint-staged": "^16.4.0", diff --git a/flake.nix b/flake.nix index f6b0150..a77a3ed 100644 --- a/flake.nix +++ b/flake.nix @@ -27,28 +27,48 @@ "aarch64-darwin" ]; forAllSystems = lib.genAttrs supportedSystems; - in { - packages = forAllSystems ( + perSystem = forAllSystems ( system: let pkgs = import nixpkgs { inherit system; }; - in { - default = pkgs.callPackage ./nix/package.nix { + hunk = pkgs.callPackage ./nix/package.nix { bun2nix = bun2nix.packages.${system}.default; }; - } - ); - - devShells = forAllSystems ( - system: let - pkgs = import nixpkgs { - inherit system; - }; + updateBunLock = pkgs.writeShellScriptBin "hunk-update-bun-lock" '' + set -euo pipefail + ${bun2nix.packages.${system}.default}/bin/bun2nix -o nix/bun.lock.nix -c ../ "$@" + if [ -s nix/bun.lock.nix ] && [ "$(${pkgs.coreutils}/bin/tail -c 1 nix/bun.lock.nix)" != "" ]; then + printf '\n' >> nix/bun.lock.nix + fi + ''; in { - default = pkgs.callPackage ./nix/devShell.nix {}; + packages = { + inherit hunk; + default = hunk; + }; + apps = { + default = { + type = "app"; + program = "${hunk}/bin/hunk"; + meta.description = "Run Hunk"; + }; + update-bun-lock = { + type = "app"; + program = "${updateBunLock}/bin/hunk-update-bun-lock"; + meta.description = "Regenerate nix/bun.lock.nix with the flake-pinned bun2nix"; + }; + }; + devShells = { + default = pkgs.callPackage ./nix/devShell.nix {}; + }; } ); + systemOutput = name: lib.mapAttrs (_: value: value.${name}) perSystem; + in { + packages = systemOutput "packages"; + apps = systemOutput "apps"; + devShells = systemOutput "devShells"; homeManagerModules = { hunk = import ./nix/home-manager.nix; diff --git a/nix/README.md b/nix/README.md index d0a9a40..19fde85 100644 --- a/nix/README.md +++ b/nix/README.md @@ -22,7 +22,7 @@ Nix users can install Hunk from source instead of using npm. ```nix { environment.systemPackages = [ - inputs.hunk.packages.${pkgs.stdenv.hostPlatform.system}.default + inputs.hunk.packages.${pkgs.stdenv.hostPlatform.system}.hunk ]; } ``` @@ -32,7 +32,7 @@ Or in Home Manager `home.packages`: ```nix { home.packages = [ - inputs.hunk.packages.${pkgs.stdenv.hostPlatform.system}.default + inputs.hunk.packages.${pkgs.stdenv.hostPlatform.system}.hunk ]; } ``` @@ -63,6 +63,14 @@ Hunk provides a Home Manager module to manage both the package and its configura `enableGitIntegration` writes to Home Manager's Git configuration, so it requires Home Manager's Git module to be enabled with `programs.git.enable = true;`. +## Running from a flake + +Run Hunk directly with Nix: + +```bash +nix run github:modem-dev/hunk -- --help +``` + ## Updating Hunk Flake users update Hunk by updating their own pinned `flake.lock` input: @@ -73,8 +81,13 @@ nix flake lock --update-input hunk ## Building using Nix -Simply run `nix build .#packages.{YOUR_SYSTEM}.default` where YOUR_SYSTEM is one of `x86_64-linux`, `x86_64-darwin`, `aarch64-linux` or `aarch64-darwin`. The resulting -Hunk binary will be `./result/bin/hunk`. +Run `nix build` to build the default package for the current system. The resulting Hunk binary will be `./result/bin/hunk`. + +You can also build the named package explicitly: + +```bash +nix build .#hunk +``` ## Maintainer dependency updates @@ -83,3 +96,5 @@ When JavaScript or Bun dependencies change, regenerate the Nix dependency lockfi ```bash bun run nix:update-lock ``` + +This script requires Nix and runs the flake-pinned `bun2nix` version from `flake.lock`. diff --git a/package.json b/package.json index 4f85de5..825ae3f 100644 --- a/package.json +++ b/package.json @@ -71,7 +71,7 @@ "bench:highlight-prefetch": "bun run benchmarks/highlight-prefetch.ts", "bench:large-stream": "bun run benchmarks/large-stream.ts", "bench:large-stream-profile": "bun run benchmarks/large-stream-profile.ts", - "nix:update-lock": "bunx bun2nix -o nix/bun.lock.nix -c ../" + "nix:update-lock": "nix run .#update-bun-lock" }, "dependencies": { "@pierre/diffs": "^1.1.19", @@ -87,7 +87,7 @@ "@hunk/session-broker-node": "workspace:*", "@opentui/core": "^0.1.88", "@opentui/react": "^0.1.88", - "@types/bun": "latest", + "@types/bun": "1.3.10", "@types/react": "^19.2.14", "@types/ws": "^8.18.1", "lint-staged": "^16.4.0",