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 }}
features: ${{ steps.set-values.outputs.features}}
steps:
- uses: actions/checkout@v3
- uses: actions-rs/toolchain@v1
with:
toolchain: stable
profile: minimal
override: true
- 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 "::set-output name=rust::${rust}"
os="$(echo '["ubuntu-latest", "macos-latest", "windows-latest"]' | jq -c)"
echo "::set-output name=os::${os}"
features="$(echo "${root_package}" | jq '.features | del(.default) | keys | map("--features " + . + " --no-default-features")')"
if [[ "$(echo "${features}" | jq 'length')" -gt "0" ]]; then
features="$(echo "${features}" | jq -c '. + ["--no-default-features", "--all-features"]')"
else
features='["--all-features"]'
fi
echo "::set-output name=features::${features}"
jq -n --argjson rust "${rust}" --argjson os "${os}" --argjson features "${features}" '{ rust: $rust, os: $os, features: $features }'
test:
name: Test
needs: set-matrix
strategy:
fail-fast: false
matrix:
rust: ${{ fromJSON(needs.set-matrix.outputs.rust) }}
os: ${{ fromJSON(needs.set-matrix.outputs.os) }}
features: ${{ fromJSON(needs.set-matrix.outputs.features) }}
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v3
- uses: actions-rs/toolchain@v1
with:
toolchain: ${{ matrix.rust }}
profile: minimal
override: true
- uses: Swatinem/rust-cache@v2
with:
key: ${{ matrix.features }}
- name: cargo test
run: cargo test --workspace --all-targets ${{ matrix.features }}
coverage:
name: Code coverage
needs: set-matrix
strategy:
fail-fast: false
matrix:
rust: [ stable ]
os: ${{ fromJSON(needs.set-matrix.outputs.os) }}
features: ${{ fromJSON(needs.set-matrix.outputs.features) }}
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v3
- uses: actions-rs/toolchain@v1
with:
toolchain: ${{ matrix.rust }}
profile: minimal
components: llvm-tools-preview
override: true
- uses: Swatinem/rust-cache@v2
with:
key: ${{ matrix.features }}
- name: Install cargo-llvm-cov
uses: taiki-e/install-action@cargo-llvm-cov
- name: Generate code coverage
run: cargo llvm-cov --workspace ${{ matrix.features }} --lcov --output-path lcov.info
- name: Upload coverage to Codecov
uses: codecov/codecov-action@v3
with:
files: lcov.info
fail_ci_if_error: true
build:
name: Build
needs: set-matrix
strategy:
fail-fast: false
matrix:
rust: ${{ fromJSON(needs.set-matrix.outputs.rust) }}
os: ${{ fromJSON(needs.set-matrix.outputs.os) }}
features: ${{ fromJSON(needs.set-matrix.outputs.features) }}
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v3
- uses: actions-rs/toolchain@v1
with:
toolchain: ${{ matrix.rust }}
profile: minimal
override: true
- uses: Swatinem/rust-cache@v2
with:
key: ${{ matrix.features }}
- name: cargo build
run: cargo build --workspace --all-targets ${{ matrix.features }}
rustfmt:
name: Rustfmt
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions-rs/toolchain@v1
with:
toolchain: stable
profile: minimal
components: rustfmt
override: true
- uses: Swatinem/rust-cache@v2
- name: cargo fmt
run: cargo fmt --all --check
clippy:
name: Clippy
needs: set-matrix
strategy:
fail-fast: false
matrix:
features: ${{ fromJSON(needs.set-matrix.outputs.features) }}
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions-rs/toolchain@v1
with:
toolchain: stable
profile: minimal
components: clippy
override: true
- uses: Swatinem/rust-cache@v2
with:
key: ${{ matrix.features }}
- name: Check workflow permissions
id: check_permissions
uses: scherermichael-oss/action-has-permission@1.0.6
with:
required-permission: write
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Run clippy action to produce annotations
uses: actions-rs/clippy-check@v1
if: ${{ steps.check_permissions.outputs.has-permission }}
with:
name: Clippy (stable) Results
token: ${{ secrets.GITHUB_TOKEN }}
args: --workspace --all-targets ${{ matrix.features }} -- -D warnings
- name: Run clippy manually without annotations
if: ${{ !steps.check_permissions.outputs.has-permission }}
run: cargo clippy --workspace --all-targets ${{ matrix.features }} -- -D warnings
rustdoc:
name: Docs
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions-rs/toolchain@v1
with:
toolchain: stable
profile: minimal
override: true
- uses: Swatinem/rust-cache@v2
- name: cargo doc
uses: actions-rs/cargo@v1
env:
RUSTDOCFLAGS: -D warnings
with:
command: doc
args: --no-deps --document-private-items --workspace --all-features --examples
publish-dry-run:
name: Publish dry run
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions-rs/toolchain@v1
with:
toolchain: stable
profile: minimal
override: true
- uses: Swatinem/rust-cache@v2
- uses: actions-rs/cargo@v1
with:
command: publish
args: --dry-run
actionlint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- 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