name: CI
on:
push:
branches:
- main
pull_request:
workflow_dispatch:
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: ${{ github.ref_name != github.event.repository.default_branch }}
env:
CARGO_TERM_COLOR: always
permissions: {}
jobs:
set-matrix:
runs-on: ubuntu-latest
outputs:
rust: ${{ steps.set-values.outputs.rust }}
os: ${{ steps.set-values.outputs.os }}
steps:
- uses: actions/checkout@v6
- uses: dtolnay/rust-toolchain@v1
with:
toolchain: stable
- uses: Swatinem/rust-cache@v2
- name: Set matrix values
id: set-values
run: |
root_package_id="$(cargo metadata --format-version 1 | jq -cr '.resolve.root')"
root_package="$(cargo metadata --format-version 1 | jq -c --arg pkgid "${root_package_id}" '.packages[] | select(.id == $pkgid)')"
echo "${root_package}" | jq -c '{ root_package: .name }'
msrv="$(echo "${root_package}" | jq '.rust_version')"
rust="$(echo "[\"stable\", ${msrv}]" | jq -c)"
echo "rust=${rust}" >> "$GITHUB_OUTPUT"
os="$(echo '["ubuntu-latest", "macos-latest", "windows-latest"]' | jq -c)"
echo "os=${os}" >> "$GITHUB_OUTPUT"
jq -n --argjson rust "${rust}" --argjson os "${os}" '{ rust: $rust, os: $os }'
shell: bash
rustfmt:
name: Rustfmt
strategy:
fail-fast: true
matrix:
rust: [stable]
os: [ubuntu-latest]
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v6
- uses: dtolnay/rust-toolchain@v1
with:
toolchain: ${{ matrix.rust }}
components: rustfmt
- uses: taiki-e/install-action@v2
with:
tool: just
- run: just ci-rustfmt
shell: bash
check:
name: Check
needs: set-matrix
strategy:
fail-fast: true
matrix:
rust: ${{ fromJSON(needs.set-matrix.outputs.rust) }}
os: ${{ fromJSON(needs.set-matrix.outputs.os) }}
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v6
- uses: dtolnay/rust-toolchain@v1
with:
toolchain: ${{ matrix.rust }}
- uses: taiki-e/install-action@v2
with:
tool: just,cargo-hack
- uses: Swatinem/rust-cache@v2
- run: just ci-check
shell: bash
clippy:
name: Clippy
needs: set-matrix
strategy:
fail-fast: true
matrix:
rust: [stable]
os: ${{ fromJSON(needs.set-matrix.outputs.os) }}
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v6
- uses: dtolnay/rust-toolchain@v1
with:
toolchain: ${{ matrix.rust }}
components: clippy
- uses: taiki-e/install-action@v2
with:
tool: just,cargo-hack
- uses: Swatinem/rust-cache@v2
- run: just ci-clippy
shell: bash
rustdoc:
name: Rustdoc
needs: set-matrix
strategy:
fail-fast: true
matrix:
rust: [stable]
os: ${{ fromJSON(needs.set-matrix.outputs.os) }}
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v6
- uses: dtolnay/rust-toolchain@v1
with:
toolchain: ${{ matrix.rust }}
- uses: taiki-e/install-action@v2
with:
tool: just,cargo-hack
- uses: Swatinem/rust-cache@v2
- run: just ci-rustdoc
shell: bash
docs-rs:
name: Docs.rs
needs: set-matrix
strategy:
fail-fast: true
matrix:
rust: [nightly]
os: ${{ fromJSON(needs.set-matrix.outputs.os) }}
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v6
- uses: dtolnay/rust-toolchain@v1
with:
toolchain: ${{ matrix.rust }}
- uses: taiki-e/install-action@v2
with:
tool: just,cargo-hack,cargo-docs-rs
- uses: Swatinem/rust-cache@v2
- run: just ci-docs-rs
shell: bash
sync-rdme:
name: Sync Readme
needs: set-matrix
strategy:
fail-fast: true
matrix:
rust: [nightly]
os: ${{ fromJSON(needs.set-matrix.outputs.os) }}
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v6
- uses: dtolnay/rust-toolchain@v1
with:
toolchain: ${{ matrix.rust }}
- uses: taiki-e/install-action@v2
with:
tool: just,cargo-hack,cargo-sync-rdme
- uses: Swatinem/rust-cache@v2
- run: just ci-sync-rdme
shell: bash
machete:
name: Machete
needs: set-matrix
strategy:
fail-fast: true
matrix:
rust: [stable]
os: ${{ fromJSON(needs.set-matrix.outputs.os) }}
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v6
- uses: dtolnay/rust-toolchain@v1
with:
toolchain: ${{ matrix.rust }}
- uses: taiki-e/install-action@v2
with:
tool: just,cargo-machete
- uses: Swatinem/rust-cache@v2
- run: just ci-machete
shell: bash
test:
name: Test
needs: set-matrix
strategy:
fail-fast: true
matrix:
rust: ${{ fromJSON(needs.set-matrix.outputs.rust) }}
os: ${{ fromJSON(needs.set-matrix.outputs.os) }}
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v6
- uses: dtolnay/rust-toolchain@v1
with:
toolchain: ${{ matrix.rust }}
- uses: Swatinem/rust-cache@v2
- uses: taiki-e/install-action@v2
with:
tool: just,cargo-hack
- run: just ci-test
shell: bash
coverage:
name: Coverage (test)
needs: set-matrix
strategy:
fail-fast: true
matrix:
rust: [stable]
os: ${{ fromJSON(needs.set-matrix.outputs.os) }}
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v6
- uses: dtolnay/rust-toolchain@v1
with:
toolchain: ${{ matrix.rust }}
components: llvm-tools-preview
- uses: Swatinem/rust-cache@v2
- uses: taiki-e/install-action@v2
with:
tool: just,cargo-llvm-cov
- run: just ci-coverage
shell: bash
- uses: codecov/codecov-action@v6
with:
token: ${{ secrets.CODECOV_TOKEN }}
files: target/codecov.json
fail_ci_if_error: false
release-dry-run:
name: Release dry run
strategy:
fail-fast: true
matrix:
rust: [stable]
os: [ubuntu-latest]
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v6
- uses: dtolnay/rust-toolchain@v1
with:
toolchain: ${{ matrix.rust }}
- uses: Swatinem/rust-cache@v2
- uses: taiki-e/install-action@v2
with:
tool: cargo-release,just
- run: cargo release patch -vv --allow-branch '*'
shell: bash
actionlint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- uses: taiki-e/install-action@v2
with:
tool: just
- name: Install actionlint
run: bash <(curl -sSfL https://raw.githubusercontent.com/rhysd/actionlint/main/scripts/download-actionlint.bash) && sudo mv actionlint /usr/local/bin/
shell: bash
- run: just ci-actionlint
typos:
name: Typos
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- uses: taiki-e/install-action@v2
with:
tool: just,typos
- run: just ci-typos
markdownlint:
name: Markdownlint
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- uses: taiki-e/install-action@v2
with:
tool: just
- run: just ci-markdownlint
ci-complete:
needs:
- set-matrix
- rustfmt
- check
- clippy
- rustdoc
- docs-rs
- sync-rdme
- machete
- test
- coverage
- release-dry-run
- actionlint
- typos
- markdownlint
runs-on: ubuntu-latest
if: ${{ always() }}
steps:
- name: CI complete
run: |
if ${{ !contains(needs.*.result, 'failure') && !contains(needs.*.result, 'cancelled') }}; then
echo "CI succeeded"
else
echo "CI failed"
exit 1
fi
shell: bash