name: CI
on:
push:
branches:
- main
pull_request:
env:
CARGO_TERM_COLOR: always
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@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
set-workspace:
runs-on: ubuntu-latest
outputs:
workspaces: ${{ steps.set-workspace.outputs.workspaces }}
steps:
- uses: actions/checkout@v6
- uses: dtolnay/rust-toolchain@stable
- uses: Swatinem/rust-cache@v2
- name: Set workspace paths
id: set-workspace
run: |
value="$(cargo xtask exec --all-workspaces -- pwd | sed "s@^$(pwd)@.@" | sed 's/$/ -> target/')"
echo "${value}"
value="${value//$'\n'/'%0A'}"
echo "workspaces=${value}" >> "${GITHUB_OUTPUT}"
shell: bash
test:
name: Test
needs: [set-matrix, set-workspace]
strategy:
fail-fast: false
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
with:
workspaces: ${{ needs.set-workspace.outputs.workspaces }}
- run: cargo xtask test --exhaustive
shell: bash
integration_test:
name: Integration test
needs: [set-matrix, set-workspace]
strategy:
fail-fast: false
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 }}
components: rustfmt,clippy
- uses: Swatinem/rust-cache@v2
with:
workspaces: ${{ needs.set-workspace.outputs.workspaces }}
- uses: taiki-e/install-action@v2
with:
tool: cargo-udeps,cargo-sync-rdme
- run: rustup toolchain add nightly --profile minimal
shell: bash
- run: cargo xtask xtask-test
shell: bash
coverage_test:
name: Coverage (test)
needs: [set-matrix, set-workspace]
strategy:
fail-fast: false
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
with:
workspaces: ${{ needs.set-workspace.outputs.workspaces }}
- name: Install cargo-llvm-cov
uses: taiki-e/install-action@v2
with:
tool: cargo-llvm-cov
- run: rustup toolchain add nightly --profile minimal --component llvm-tools-preview
shell: bash
- name: Generate code coverage
run: |
cargo llvm-cov --workspace --all-targets --all-features --lcov --output-path lcov-test.info
cargo +nightly llvm-cov --doctests --workspace --all-features --lcov --output-path lcov-doctest.info
cargo llvm-cov run -p xtask --lcov --output-path lcov-exec.info -- exec --all-workspaces --exclude-current-workspace -- cargo llvm-cov --workspace --lcov --output-path lcov-test.info
shell: bash
- name: Upload coverage to Codecov
uses: codecov/codecov-action@v5
with:
token: ${{ secrets.CODECOV_TOKEN }}
files: |
**/lcov-*.info
fail_ci_if_error: false
coverage_integration_test:
name: Coverage (integration test)
needs: [set-matrix, set-workspace]
strategy:
fail-fast: false
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 }}
components: llvm-tools-preview,rustfmt,clippy
- uses: Swatinem/rust-cache@v2
with:
workspaces: ${{ needs.set-workspace.outputs.workspaces }}
- uses: taiki-e/install-action@v2
with:
tool: cargo-udeps,cargo-sync-rdme,cargo-llvm-cov
- name: Generate code coverage
run: cargo llvm-cov run -p xtask --lcov --output-path lcov-xtask.info -- xtask-test --cargo-llvm-cov
shell: bash
- name: Upload coverage to Codecov
uses: codecov/codecov-action@v5
with:
token: ${{ secrets.CODECOV_TOKEN }}
files: |
**/lcov-*.info
fail_ci_if_error: false
build:
name: Build
needs: [set-matrix, set-workspace]
strategy:
fail-fast: false
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
with:
workspaces: ${{ needs.set-workspace.outputs.workspaces }}
- name: cargo xtask build
run: cargo xtask build --exhaustive -- --all-targets
shell: bash
lint:
name: Lint
needs: [set-matrix, set-workspace]
strategy:
fail-fast: false
matrix:
os: ${{ fromJSON(needs.set-matrix.outputs.os) }}
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v6
- uses: dtolnay/rust-toolchain@stable
with:
components: rustfmt,clippy
- uses: Swatinem/rust-cache@v2
with:
workspaces: ${{ needs.set-workspace.outputs.workspaces }}
- uses: taiki-e/install-action@v2
with:
tool: cargo-udeps,cargo-sync-rdme
- run: rustup toolchain add nightly --profile minimal
shell: bash
- run: cargo xtask lint --exhaustive
shell: bash
release-dry-run:
name: Release dry run
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- uses: dtolnay/rust-toolchain@stable
- uses: Swatinem/rust-cache@v2
- uses: taiki-e/install-action@v2
with:
tool: cargo-udeps,cargo-sync-rdme,cargo-release
- run: rustup toolchain add nightly --profile minimal
shell: bash
- run: cargo release patch -vv --allow-branch '*'
shell: bash
actionlint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- name: Check workflow files
run: |
bash <(curl https://raw.githubusercontent.com/rhysd/actionlint/main/scripts/download-actionlint.bash)
echo "::add-matcher::.github/actionlint-matcher.json"
./actionlint -color
shell: bash