name: CI
permissions:
contents: read
on:
pull_request:
branches:
- main
push:
branches:
- main
tags:
- v*
workflow_dispatch:
concurrency:
group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
cancel-in-progress: true
jobs:
single-commit:
name: Enforce single commit
runs-on: ubuntu-latest
steps:
- name: Enforce exactly one commit for a PR
if: github.event_name == 'pull_request'
run: |
COUNT="${{ github.event.pull_request.commits }}"
echo "PR contains $COUNT commit(s)"
if [ "$COUNT" -ne 1 ]; then
echo "::error::PRs must contain exactly one commit. Squash locally (git rebase -i) and force-push."
exit 1
fi
toolchain:
name: Setup Rust toolchain
runs-on: ubuntu-latest
needs: single-commit
outputs:
stable: ${{ steps.set_toolchain.outputs.stable }}
nightly: ${{ steps.set_toolchain.outputs.nightly }}
steps:
- name: Checkout repository
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0
- name: Output toolchain
id: set_toolchain
run: |
stable=$(grep channel rust-toolchain.toml | sed -r 's/channel = "(.*)"/\1/')
echo "stable=$stable" | tee -a "$GITHUB_OUTPUT"
nightly=$(rustc --version | grep -oE '[0-9]{4}-[0-9]{2}-[0-9]{2}' | sed 's/^/nightly-/')
echo "nightly=$nightly" | tee -a "$GITHUB_OUTPUT"
fmt-check:
name: Check Code Format
runs-on: ubuntu-latest
needs: toolchain
steps:
- name: Checkout repository
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0
- name: Install Rust
uses: dtolnay/rust-toolchain@fa04a1451ff1842e2626ccb99004d0195b455a88 with:
toolchain: ${{ needs.toolchain.outputs.nightly }}
components: rustfmt
- name: Install just
uses: taiki-e/install-action@c7eb1735f09259a5035e8e5d44b1406b1cddc0fb with:
tool: just
- name: Setup Rust cache
uses: Swatinem/rust-cache@c19371144df3bb44fab255c43d04cbc2ab54d1c4
- name: just fmt-check
run: |
just fmt-check
lint:
name: Lint Code
runs-on: ubuntu-latest
needs: toolchain
steps:
- name: Checkout repository
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0
- name: Install Rust
uses: dtolnay/rust-toolchain@fa04a1451ff1842e2626ccb99004d0195b455a88 with:
toolchain: ${{ needs.toolchain.outputs.stable }}
components: clippy
- name: Install just
uses: taiki-e/install-action@c7eb1735f09259a5035e8e5d44b1406b1cddc0fb with:
tool: just
- name: Setup Rust cache
uses: Swatinem/rust-cache@c19371144df3bb44fab255c43d04cbc2ab54d1c4
- name: just lint
run: |
rustup override set ${{ needs.toolchain.outputs.stable }}
just lint
test:
name: Run Tests
runs-on: ubuntu-latest
needs: toolchain
steps:
- name: Checkout repository
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0
- name: Install Rust
uses: dtolnay/rust-toolchain@fa04a1451ff1842e2626ccb99004d0195b455a88 with:
toolchain: ${{ needs.toolchain.outputs.stable }}
- name: Install just
uses: taiki-e/install-action@c7eb1735f09259a5035e8e5d44b1406b1cddc0fb with:
tool: just
- name: Setup Rust cache
uses: Swatinem/rust-cache@c19371144df3bb44fab255c43d04cbc2ab54d1c4
- name: just test
run: |
rustup override set ${{ needs.toolchain.outputs.stable }}
just test
doc:
name: Create Documentation
runs-on: ubuntu-latest
needs: toolchain
steps:
- name: Checkout repository
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0
- name: Install Rust
uses: dtolnay/rust-toolchain@fa04a1451ff1842e2626ccb99004d0195b455a88 with:
toolchain: ${{ needs.toolchain.outputs.stable }}
components: rust-docs
- name: Install just
uses: taiki-e/install-action@c7eb1735f09259a5035e8e5d44b1406b1cddc0fb with:
tool: just
- name: Setup Rust cache
uses: Swatinem/rust-cache@c19371144df3bb44fab255c43d04cbc2ab54d1c4
- name: just doc
run: |
rustup override set ${{ needs.toolchain.outputs.stable }}
just doc