Skip to content
Merged
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
2 changes: 2 additions & 0 deletions .cspell/words.txt
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ APFS
arboard
atuin
cachain
cachix
catppuccin
claudemd
Clawd
Expand All @@ -24,6 +25,7 @@ dedupe
deque
deserialize
desync
direnv
disambiguable
dtolnay
EACCES
Expand Down
27 changes: 27 additions & 0 deletions .github/actions/setup-nix/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
name: Setup Nix
description: Install Nix and configure the Cachix substituter

inputs:
cachix_name:
description: Cachix cache name (skips Cachix if not provided)
cachix_auth_token:
description: Cachix authentication token
cachix_skip_push:
description: Skip pushing to Cachix
default: 'false'

runs:
using: composite
steps:
- name: Install Nix
uses: cachix/install-nix-action@v31
with:
install_options: ${{ runner.os == 'Linux' && '--no-daemon' || '' }}

- name: Setup Cachix
if: ${{ inputs.cachix_name }}
uses: cachix/cachix-action@v17
with:
name: ${{ inputs.cachix_name }}
authToken: ${{ inputs.cachix_auth_token }}
skipPush: ${{ inputs.cachix_skip_push }}
95 changes: 71 additions & 24 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,50 +7,77 @@ on:
branches: [main]
workflow_dispatch:

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

env:
CACHIX_NAME: hakula
CARGO_TERM_COLOR: always

jobs:
flake-check:
name: Nix Flake Check
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v6

- name: Setup Nix
uses: ./.github/actions/setup-nix
with:
cachix_name: ${{ env.CACHIX_NAME }}
cachix_auth_token: ${{ secrets.CACHIX_AUTH_TOKEN }}
cachix_skip_push: ${{ !(github.ref == 'refs/heads/main' || github.actor == 'hakula139') }}

- name: Run flake check
run: nix flake check

rust-check:
name: Rust Check
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v6

- name: Set up Rust
uses: dtolnay/rust-toolchain@stable
- name: Setup Nix
uses: ./.github/actions/setup-nix
with:
components: rustfmt, clippy
cachix_name: ${{ env.CACHIX_NAME }}
cachix_auth_token: ${{ secrets.CACHIX_AUTH_TOKEN }}
cachix_skip_push: ${{ !(github.ref == 'refs/heads/main' || github.actor == 'hakula139') }}

- name: Cache dependencies
- name: Cache cargo target
uses: Swatinem/rust-cache@v2

- name: Format
run: cargo fmt --all --check
run: nix develop -c cargo fmt --all --check

- name: Clippy
run: cargo clippy --all-targets -- -D warnings
run: nix develop -c cargo clippy --all-targets -- -D warnings

- name: Test
run: cargo test
run: nix develop -c cargo test

coverage:
name: Coverage
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v6

- name: Set up Rust
uses: dtolnay/rust-toolchain@stable
- name: Setup Nix
uses: ./.github/actions/setup-nix
with:
cachix_name: ${{ env.CACHIX_NAME }}
cachix_auth_token: ${{ secrets.CACHIX_AUTH_TOKEN }}
cachix_skip_push: ${{ !(github.ref == 'refs/heads/main' || github.actor == 'hakula139') }}

- name: Cache dependencies
- name: Cache cargo target
uses: Swatinem/rust-cache@v2

- name: Install cargo-llvm-cov
uses: taiki-e/install-action@cargo-llvm-cov

- name: Generate coverage
run: cargo llvm-cov --ignore-filename-regex 'main\.rs' --lcov --output-path lcov.info
run: nix develop -c cargo llvm-cov --ignore-filename-regex 'main\.rs' --lcov --output-path lcov.info

- name: Upload to Codecov
uses: codecov/codecov-action@v6
Expand All @@ -59,25 +86,45 @@ jobs:
files: lcov.info

node-check:
name: Node Check
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v6

- name: Set up pnpm
uses: pnpm/action-setup@v5

- name: Set up Node.js
uses: actions/setup-node@v6
- name: Setup Nix
uses: ./.github/actions/setup-nix
with:
node-version: lts/*
cache: pnpm
cachix_name: ${{ env.CACHIX_NAME }}
cachix_auth_token: ${{ secrets.CACHIX_AUTH_TOKEN }}
cachix_skip_push: ${{ !(github.ref == 'refs/heads/main' || github.actor == 'hakula139') }}

- name: Install dependencies
run: pnpm install --frozen-lockfile
run: nix develop -c pnpm install --frozen-lockfile

- name: Lint Markdown
run: pnpm lint
run: nix develop -c pnpm lint

- name: Spell check
run: pnpm spellcheck
run: nix develop -c pnpm spellcheck

nix-build:
name: Nix Build (${{ matrix.os }})
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, macos-latest]
steps:
- name: Checkout
uses: actions/checkout@v6

- name: Setup Nix
uses: ./.github/actions/setup-nix
with:
cachix_name: ${{ env.CACHIX_NAME }}
cachix_auth_token: ${{ secrets.CACHIX_AUTH_TOKEN }}
cachix_skip_push: ${{ !(github.ref == 'refs/heads/main' || github.actor == 'hakula139') }}

- name: Build oxide-code
run: nix build .#oxide-code --print-build-logs
6 changes: 6 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,12 @@
/target/
/node_modules/

# Nix
.direnv/
.pre-commit-config.yaml
result
result-*

# cargo insta pending-review files
*.snap.new

Expand Down
2 changes: 2 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -293,6 +293,8 @@ pnpm spellcheck # Spell check

The `pnpm` checks gate the `node-check` CI job. `cspell` covers Rust sources too, so a new word in a doc comment fails the same way as one in `README.md`.

`nix develop` provisions the hook toolchain and installs a [pre-commit](https://pre-commit.com) hook (generated by [`git-hooks.nix`](https://github.com/cachix/git-hooks.nix)) that runs the compile-free subset of these checks at commit time: `rustfmt`, `nixfmt`, `markdownlint`, and `cspell`. `nix flake check` runs the same hooks. `clippy`, tests, and coverage stay out of the hook because their build cost would gate every commit.

### Mutation testing

Coverage reports whether a line ran. Mutation testing reports whether a mutation of that line would be caught. Run out-of-band before large-scope changes ship because a full run is slow:
Expand Down
8 changes: 5 additions & 3 deletions crates/oxide-code/src/file_tracker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1080,10 +1080,12 @@ mod tests {
];

let tracker = FileTracker::default();
let dropped = tracker.restore_verified(snaps);
let mut dropped = tracker.restore_verified(snaps);
dropped.sort();
let mut expected = vec![drifted_path, missing_path];
expected.sort();
assert_eq!(
dropped,
vec![missing_path, drifted_path],
dropped, expected,
"both the size-drifted and the missing snapshots must be reported",
);
assert!(tracker.lock().contains_key(&kept_path));
Expand Down
68 changes: 64 additions & 4 deletions flake.lock

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

Loading
Loading