Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
---
bump: patch
---

CI now exercises a fully hermetic Nix build and the entire test suite on both
Linux and Darwin for pull requests into master. The workspace test suite runs
inside the Nix sandbox via a new flake check rather than an impure development
shell, and the package builds on darwin with the modern apple-sdk pattern so the
clipboard integration links correctly. This underpins nixpkgs support on macOS.
57 changes: 42 additions & 15 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -37,21 +37,6 @@ jobs:
- name: Run clippy
run: nix develop --command cargo clippy --all-targets --all-features -- -D warnings

test:
name: Test
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- uses: cachix/install-nix-action@v27
with:
github_access_token: ${{ secrets.GITHUB_TOKEN }}
extra_nix_config: |
experimental-features = nix-command flakes

- name: Run tests
run: nix develop --command cargo test --all-features --workspace

test-windows:
name: Test (Windows)
runs-on: windows-latest
Expand All @@ -65,6 +50,48 @@ jobs:
- name: Run tests
run: cargo test --all-features --workspace

hermetic:
name: Hermetic Build & Test (${{ matrix.system }})
if: github.base_ref == 'master'
strategy:
fail-fast: false
matrix:
include:
- os: ubuntu-latest
system: x86_64-linux
- os: macos-latest
system: aarch64-darwin
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v4

- uses: cachix/install-nix-action@v27
with:
github_access_token: ${{ secrets.GITHUB_TOKEN }}
extra_nix_config: |
experimental-features = nix-command flakes

# Persist /nix/store across runs so crane's cargoArtifacts and the package closure
# are restored instead of recompiled on each PR.
- uses: nix-community/cache-nix-action@v7
with:
primary-key: nix-${{ runner.os }}-${{ hashFiles('flake.lock', '**/Cargo.lock') }}
restore-prefixes-first-match: nix-${{ runner.os }}-
gc-max-store-size-linux: 5G
gc-max-store-size-macos: 5G
purge: true
purge-prefixes: nix-${{ runner.os }}-
purge-created: 0
purge-primary-key: never

# Build the release artifact the way nixpkgs would, inside the sandbox.
- name: Build package hermetically
run: nix build .#default -L

# Build the workspace and run the full test suite inside the sandbox.
- name: Run test suite hermetically
run: nix build .#checks.${{ matrix.system }}.tests -L

build:
name: Build
runs-on: ubuntu-latest
Expand Down
12 changes: 8 additions & 4 deletions default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,14 @@ rustPlatform.buildRustPackage {
cargoLock.lockFile = ./Cargo.lock;

nativeBuildInputs = [ pkgs.pkg-config ];
buildInputs = lib.optionals (pkgs.stdenv.isLinux && withTui) [
pkgs.wayland
pkgs.xorg.libxcb
];
buildInputs =
lib.optionals (pkgs.stdenv.isLinux && withTui) [
pkgs.wayland
pkgs.xorg.libxcb
]
++ lib.optionals (pkgs.stdenv.isDarwin && withTui) [
pkgs.apple-sdk
];

cargoBuildFlags = [ "--package" "kanban-cli" ]
++ lib.optionals (!withTui) [ "--no-default-features" ];
Expand Down
16 changes: 16 additions & 0 deletions flake.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

41 changes: 41 additions & 0 deletions flake.nix
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,15 @@
nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable";
rust-overlay.url = "github:oxalica/rust-overlay";
flake-utils.url = "github:numtide/flake-utils";
crane.url = "github:ipetkov/crane";
};

outputs = {
self,
nixpkgs,
rust-overlay,
flake-utils,
crane,
...
}:
flake-utils.lib.eachDefaultSystem (
Expand All @@ -18,11 +20,48 @@
pkgs = import nixpkgs {
inherit system overlays;
};
lib = pkgs.lib;

rustToolchain = pkgs.rust-bin.stable.latest.default.override {
extensions = ["rust-src" "rust-analyzer" "clippy" "rustfmt"];
};

# crane drives the fast, incremental per-PR test check. Dependencies are
# compiled once into cargoArtifacts (keyed on Cargo.lock) and reused, so
# CI only recompiles the first-party crates on each change. The released
# package stays on rustPlatform (default.nix) for nixpkgs parity.
craneLib = (crane.mkLib pkgs).overrideToolchain rustToolchain;

# kanban-persistence-sqlite pulls schema.sql in via include_str!, so keep
# .sql files that crane's default source cleaner would otherwise strip.
sqlFilter = path: _type: builtins.match ".*\\.sql$" path != null;
srcFilter = path: type:
(sqlFilter path type) || (craneLib.filterCargoSources path type);
craneSrc = lib.cleanSourceWith {
src = self;
filter = srcFilter;
name = "source";
};

commonArgs = {
src = craneSrc;
strictDeps = true;
pname = "kanban-workspace";
version = (lib.importTOML ./Cargo.toml).workspace.package.version;
cargoExtraArgs = "--workspace --all-features";
nativeBuildInputs = [pkgs.pkg-config];
buildInputs =
lib.optionals pkgs.stdenv.isLinux [pkgs.wayland pkgs.xorg.libxcb]
++ lib.optionals pkgs.stdenv.isDarwin [pkgs.apple-sdk];
};

cargoArtifacts = craneLib.buildDepsOnly commonArgs;

workspaceTests = craneLib.cargoTest (commonArgs
// {
inherit cargoArtifacts;
});

changeset = pkgs.writeShellApplication {
name = "changeset";
runtimeInputs = with pkgs; [coreutils];
Expand Down Expand Up @@ -74,6 +113,8 @@

devShells.demo = import ./demo/shell.nix { inherit pkgs kanban; };

checks.tests = workspaceTests;

packages = let
kanban-cli = pkgs.callPackage ./default.nix { src = self; gitRev = self.rev or null; withTui = false; };
in {
Expand Down
Loading