name: ci
on:
push:
branches: [ main ]
pull_request:
branches: [ main ]
workflow_dispatch:
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
env:
CARGO_TERM_COLOR: always
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
jobs:
lint:
runs-on: ubuntu-24.04
steps:
- name: ๐ Checkout code
uses: actions/checkout@v6
- name: ๐ฐ Cache
uses: Swatinem/rust-cache@v2
- name: Install lychee
uses: baptiste0928/cargo-install@v3
with:
crate: lychee
version: "=0.23.0"
- name: ๐ Pre-commit hooks
uses: pre-commit/action@v3.0.1
test:
strategy:
fail-fast: false
matrix:
include:
- os: ubuntu-24.04
name: linux
- os: macos-15
name: macos
- os: windows-2022
name: windows
name: test (${{ matrix.name }})
runs-on: ${{ matrix.os }}
steps:
- name: ๐ Checkout code
uses: actions/checkout@v6
- name: Install cargo-insta
uses: baptiste0928/cargo-install@v3
with:
crate: cargo-insta
version: "=1.46.3"
- name: Install cargo-nextest
uses: baptiste0928/cargo-install@v3
with:
crate: cargo-nextest
version: "=0.9.132"
- name: ๐ฐ Cache
uses: Swatinem/rust-cache@v2
- name: Install shells (zsh, fish) - Ubuntu
if: runner.os == 'Linux'
uses: awalsh128/cache-apt-pkgs-action@latest
with:
packages: zsh fish
version: 1.0
- name: Install shells (fish) - macOS
if: runner.os == 'macOS'
run: |
brew install fish
# bash and zsh are pre-installed on macOS
- name: Install nushell
if: runner.os != 'Windows'
uses: hustcer/setup-nu@v3
with:
version: '*'
- name: Install shells - Windows
if: runner.os == 'Windows'
run: |
# Git Bash is pre-installed on GitHub Actions Windows runners
# Fish, zsh, and nushell are not commonly available on native Windows (require WSL/MSYS2)
# CI will test with bash only on Windows (tests skip unavailable shells)
echo "Using Git Bash for Windows tests"
shell: pwsh
- name: Install uv
uses: astral-sh/setup-uv@v8.0.0
with:
cache-dependency-glob: ".pre-commit-config.yaml"
- name: Install pre-commit
run: uv tool install pre-commit
- name: Install lychee
if: runner.os != 'Windows'
uses: baptiste0928/cargo-install@v3
with:
crate: lychee
version: "=0.23.0"
- name: Install wt
uses: baptiste0928/cargo-install@v3
with:
crate: worktrunk
version: "=0.32.0"
- name: ๐งช Pre-merge hooks
run: wt hook pre-merge --yes
- name: ๐ Upload test timing
if: always()
uses: actions/upload-artifact@v7
with:
name: junit-${{ matrix.name }}
path: target/nextest/default/junit.xml
- name: ๐ Upload test results to Codecov
if: ${{ !cancelled() && github.repository_owner == 'max-sixty' }}
uses: codecov/codecov-action@v6.0.0
with:
token: ${{ secrets.CODECOV_TOKEN }}
files: target/nextest/default/junit.xml
report_type: test_results
changes:
runs-on: ubuntu-24.04
permissions:
contents: read
pull-requests: read
outputs:
cargo: ${{ steps.filter.outputs.cargo }}
docs: ${{ steps.filter.outputs.docs }}
steps:
- name: ๐ Checkout code
uses: actions/checkout@v6
- uses: dorny/paths-filter@v4
id: filter
with:
filters: |
cargo:
- 'Cargo.toml'
- 'Cargo.lock'
- 'rust-toolchain.toml'
- '.github/workflows/ci.yaml'
docs:
- 'docs/**'
- 'src/cli/mod.rs'
msrv:
runs-on: ubuntu-24.04
needs: changes
if: needs.changes.outputs.cargo == 'true' || github.event_name == 'workflow_dispatch'
steps:
- name: ๐ Checkout code
uses: actions/checkout@v6
- name: ๐ฐ Cache
uses: Swatinem/rust-cache@v2
- uses: baptiste0928/cargo-install@v3
with:
crate: cargo-msrv
version: "=0.19.2"
- name: Verify minimum rust version
run: cargo msrv verify
check-unused-dependencies:
runs-on: ubuntu-24.04
needs: changes
if: needs.changes.outputs.cargo == 'true' || github.event_name == 'workflow_dispatch'
steps:
- name: ๐ Checkout code
uses: actions/checkout@v6
- run: rustup override set nightly-2026-03-01
- name: ๐ฐ Cache
uses: Swatinem/rust-cache@v2
- uses: baptiste0928/cargo-install@v3
with:
crate: cargo-udeps
version: "=0.1.60"
- uses: clechasseur/rs-cargo@v5.0.3
with:
command: udeps
args: --all-targets
check-docs:
runs-on: ubuntu-24.04
needs: changes
if: needs.changes.outputs.docs == 'true' || github.event_name == 'workflow_dispatch'
steps:
- name: ๐ Checkout code
uses: actions/checkout@v6
- name: Setup Zola
uses: taiki-e/install-action@v2.74.0
with:
tool: zola@0.22.1
- name: ๐ท๏ธ Build docs
run: zola build
working-directory: docs
benchmarks:
runs-on: ubuntu-24.04
needs: changes
if: needs.changes.outputs.cargo == 'true' || github.event_name == 'workflow_dispatch'
steps:
- name: ๐ Checkout code
uses: actions/checkout@v6
- name: ๐ฐ Cache
uses: Swatinem/rust-cache@v2
- name: Install shells (zsh, fish)
uses: awalsh128/cache-apt-pkgs-action@latest
with:
packages: zsh fish
version: 1.0
- name: Install nushell
uses: hustcer/setup-nu@v3
with:
version: '*'
- name: ๐ฐ Rust repo cache
uses: actions/cache@v5
with:
path: target/bench-repos
key: bench-repos-rust-${{ runner.os }}
- name: ๐ Run benchmarks
run: cargo bench
code-coverage:
runs-on: ubuntu-24.04
steps:
- name: ๐ Checkout code
uses: actions/checkout@v6
- uses: baptiste0928/cargo-install@v3
with:
crate: cargo-llvm-cov
version: "=0.8.5"
- name: ๐ฐ Cache
uses: Swatinem/rust-cache@v2
with:
save-if: ${{ github.ref == 'refs/heads/main' }}
- name: Install shells (zsh, fish)
uses: awalsh128/cache-apt-pkgs-action@latest
with:
packages: zsh fish
version: 1.0
- name: Install nushell
uses: hustcer/setup-nu@v3
with:
version: '*'
- run: cargo llvm-cov clean --workspace
- name: ๐ Generate coverage report
env:
NEXTEST_NO_INPUT_HANDLER: 1
run: cargo llvm-cov --features shell-integration-tests --cobertura --output-path=cobertura.xml
- name: Upload code coverage results
uses: actions/upload-artifact@v7
with:
name: code-coverage-report
path: cobertura.xml
- name: Upload to codecov.io
if: github.repository_owner == 'max-sixty'
uses: codecov/codecov-action@v6.0.0
with:
files: cobertura.xml
fail_ci_if_error: true
token: ${{ secrets.CODECOV_TOKEN }}