diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index ed4654c..bd5b3fe 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -77,6 +77,40 @@ jobs: - name: Build run: cargo build --release + nix: + name: Nix Build + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v4 + + - name: Check for Nix-relevant changes + uses: dorny/paths-filter@v3 + id: filter + with: + filters: | + nix: + - 'flake.nix' + - 'flake.lock' + - 'Cargo.toml' + - 'Cargo.lock' + - 'src/**' + - 'tests/**' + + - name: Install Nix + if: steps.filter.outputs.nix == 'true' + uses: DeterminateSystems/determinate-nix-action@v3 + + - name: Setup Nix cache + if: steps.filter.outputs.nix == 'true' + uses: DeterminateSystems/magic-nix-cache-action@v8 + with: + use-flakehub: false + + - name: Check flake + if: steps.filter.outputs.nix == 'true' + run: nix flake check + # E2E tests run only on main branch with secrets e2e: name: E2E Tests diff --git a/.github/workflows/update-flake-lock.yml b/.github/workflows/update-flake-lock.yml new file mode 100644 index 0000000..30d493d --- /dev/null +++ b/.github/workflows/update-flake-lock.yml @@ -0,0 +1,22 @@ +name: Update flake.lock + +on: + workflow_dispatch: + schedule: + - cron: '0 0 1 * *' # Monthly on the 1st + +jobs: + update: + runs-on: ubuntu-latest + permissions: + contents: write + pull-requests: write + steps: + - uses: actions/checkout@v4 + - uses: DeterminateSystems/determinate-nix-action@v3 + - uses: DeterminateSystems/update-flake-lock@main + with: + pr-title: "nix: update flake.lock" + pr-labels: | + dependencies + nix diff --git a/.gitignore b/.gitignore index 2cda5b5..2f82f00 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,9 @@ /target .DS_Store +# Nix +result + # Generated npm platform packages /npm/darwin-arm64/ /npm/darwin-x64/ diff --git a/README.md b/README.md index 01cc1a6..ecdfc12 100644 --- a/README.md +++ b/README.md @@ -33,6 +33,33 @@ cargo install jj-ryu Binary name is `ryu`. +### Nix + +```sh +# Try it +nix run github:dmmulroy/jj-ryu + +# Install to profile +nix profile install github:dmmulroy/jj-ryu +``` + +Or add to your flake inputs: + +```nix +{ + inputs.jj-ryu.url = "github:dmmulroy/jj-ryu"; + + outputs = { self, nixpkgs, jj-ryu, ... }: { + nixosConfigurations.myhost = nixpkgs.lib.nixosSystem { + modules = [{ + nixpkgs.overlays = [ jj-ryu.overlays.default ]; + environment.systemPackages = [ pkgs.jj-ryu ]; + }]; + }; + }; +} +``` + ## Quick start ```sh diff --git a/flake.lock b/flake.lock new file mode 100644 index 0000000..29eae42 --- /dev/null +++ b/flake.lock @@ -0,0 +1,96 @@ +{ + "nodes": { + "flake-utils": { + "inputs": { + "systems": "systems" + }, + "locked": { + "lastModified": 1731533236, + "narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "11707dc2f618dd54ca8739b309ec4fc024de578b", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "nixpkgs": { + "locked": { + "lastModified": 1768395095, + "narHash": "sha256-ZhuYJbwbZT32QA95tSkXd9zXHcdZj90EzHpEXBMabaw=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "13868c071cc73a5e9f610c47d7bb08e5da64fdd5", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixpkgs-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs_2": { + "locked": { + "lastModified": 1744536153, + "narHash": "sha256-awS2zRgF4uTwrOKwwiJcByDzDOdo3Q1rPZbiHQg/N38=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "18dd725c29603f582cf1900e0d25f9f1063dbf11", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixpkgs-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "root": { + "inputs": { + "flake-utils": "flake-utils", + "nixpkgs": "nixpkgs", + "rust-overlay": "rust-overlay" + } + }, + "rust-overlay": { + "inputs": { + "nixpkgs": "nixpkgs_2" + }, + "locked": { + "lastModified": 1768531678, + "narHash": "sha256-tf4xEp5Zq8+Zce0WtU8b0VNMxhQtwes67sN2phnbkpk=", + "owner": "oxalica", + "repo": "rust-overlay", + "rev": "0a9de73f3c23206a2fce3c7656a42d3a3f07be9f", + "type": "github" + }, + "original": { + "owner": "oxalica", + "repo": "rust-overlay", + "type": "github" + } + }, + "systems": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/flake.nix b/flake.nix new file mode 100644 index 0000000..ad58448 --- /dev/null +++ b/flake.nix @@ -0,0 +1,100 @@ +{ + description = "jj-ryu - Stacked PRs CLI for Jujutsu"; + + inputs = { + nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable"; + rust-overlay.url = "github:oxalica/rust-overlay"; + flake-utils.url = "github:numtide/flake-utils"; + }; + + outputs = + { + self, + nixpkgs, + rust-overlay, + flake-utils, + }: + { + overlays.default = final: prev: { + jj-ryu = self.packages.${final.system}.ryu; + }; + } + // flake-utils.lib.eachDefaultSystem ( + system: + let + overlays = [ (import rust-overlay) ]; + pkgs = import nixpkgs { inherit system overlays; }; + lib = pkgs.lib; + + rust = pkgs.rust-bin.stable."1.89.0".default; + rustPlatform = pkgs.makeRustPlatform { + cargo = rust; + rustc = rust; + }; + + version = (builtins.fromTOML (builtins.readFile ./Cargo.toml)).package.version; + versionSuffix = if self ? rev then "-${builtins.substring 0 7 self.rev}" else "-dirty"; + + src = pkgs.lib.fileset.toSource { + root = ./.; + fileset = pkgs.lib.fileset.unions [ + ./Cargo.toml + ./Cargo.lock + ./src + ./tests + ]; + }; + + meta = with pkgs.lib; { + description = "Stacked PRs for Jujutsu with GitHub/GitLab support"; + homepage = "https://github.com/dmmulroy/jj-ryu"; + changelog = "https://github.com/dmmulroy/jj-ryu/releases/tag/v${version}"; + license = licenses.mit; + maintainers = [ ]; + mainProgram = "ryu"; + platforms = platforms.unix; + }; + + ryu = rustPlatform.buildRustPackage { + pname = "jj-ryu"; + version = "${version}${versionSuffix}"; + inherit src meta; + cargoLock = { + lockFile = ./Cargo.lock; + }; + nativeBuildInputs = [ + pkgs.pkg-config + pkgs.jujutsu + pkgs.git + ]; + buildInputs = lib.optionals pkgs.stdenv.isDarwin [ pkgs.libiconv ]; + doCheck = true; + }; + in + { + packages = { + default = ryu; + ryu = ryu; + }; + + apps.default = flake-utils.lib.mkApp { drv = ryu; }; + apps.ryu = flake-utils.lib.mkApp { drv = ryu; }; + + checks = { + ryu = ryu; + }; + + devShells.default = pkgs.mkShell { + inputsFrom = [ ryu ]; + packages = [ + rust + pkgs.pkg-config + pkgs.rust-analyzer + pkgs.cargo-watch + ]; + }; + + formatter = pkgs.nixfmt-rfc-style; + } + ); +}