Cargo check before get the metadata #18
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
name: Build & Tests | |
on: | |
pull_request: | |
push: | |
branches: | |
- main | |
- v0.6.x | |
permissions: read-all | |
env: | |
CARGO_TERM_COLOR: always | |
RUSTFLAGS: -Dwarnings | |
RUSTDOCFLAGS: -Dwarnings | |
# `ZC_NIGHTLY_XXX` are flags that we add to `XXX` only on the nightly | |
# toolchain. | |
ZC_NIGHTLY_RUSTFLAGS: -Zrandomize-layout | |
ZC_NIGHTLY_MIRIFLAGS: "-Zmiri-symbolic-alignment-check -Zmiri-strict-provenance -Zmiri-backtrace=full" | |
jobs: | |
build_test: | |
runs-on: ubuntu-latest | |
strategy: | |
# By default, this is set to `true`, which means that a single CI job | |
# failure will cause all outstanding jobs to be canceled. This slows down | |
# development because it means that errors need to be encountered and | |
# fixed one at a time. | |
fail-fast: false | |
matrix: | |
# See `INTERNAL.md` for an explanation of these pinned toolchain | |
# versions. | |
toolchain: [ "msrv", "stable", "nightly" ] | |
target: [ | |
"i686-unknown-linux-gnu", | |
"x86_64-unknown-linux-gnu", | |
"arm-unknown-linux-gnueabi", | |
"aarch64-unknown-linux-gnu", | |
"powerpc-unknown-linux-gnu", | |
"powerpc64-unknown-linux-gnu", | |
"riscv64gc-unknown-linux-gnu", | |
"mips-unknown-linux-gnu", | |
"mips64-unknown-linux-gnuabi64", | |
"s390x-unknown-linux-gnu", | |
"wasm32-wasi" | |
] | |
features: [ "--no-default-features", "", "--features __internal_use_only_features_that_work_on_stable", "--all-features" ] | |
crate: [ "zerocopy", "zerocopy-derive" ] | |
exclude: | |
# Exclude any combination which uses a non-nightly toolchain but | |
# enables nightly features. | |
- toolchain: "msrv" | |
features: "--all-features" | |
- toolchain: "stable" | |
features: "--all-features" | |
# Exclude any combination for the zerocopy-derive crate which | |
# uses zerocopy features. | |
- crate: "zerocopy-derive" | |
features: "--no-default-features" | |
- crate: "zerocopy-derive" | |
features: "--features __internal_use_only_features_that_work_on_stable" | |
- crate: "zerocopy-derive" | |
features: "--all-features" | |
name: Build & Test (crate:${{ matrix.crate }}, toolchain:${{ matrix.toolchain }}, target:${{ matrix.target }}, features:${{ matrix.features }}) | |
steps: | |
- uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3.6.0 | |
# We use toolchain descriptors ("msrv", "stable", and "nightly") in the | |
# matrix. This step converts the current descriptor to a particular | |
# toolchain version by looking up the corresponding key in `Cargo.toml`. It | |
# sets the `ZC_TOOLCHAIN` environment variable for future steps to use. | |
# | |
# Note that all metadata is stored in zerocopy's `Cargo.toml` (the one at | |
# the repository root). zerocopy-derive is tested with the same versions, | |
# and we have another CI job (see below) that makes sure that the | |
# `package.rust_version` key in zerocopy-derive's `Cargo.toml` is the same | |
# as the one in zerocopy's `Cargo.toml`. This key indicates the crate's | |
# MSRV, and if this check weren't present, it would be possible for | |
# zerocopy-derive to be published with an earlier MSRV than the one we test | |
# for in CI - and thus potentially an MSRV that zerocopy-derive isn't | |
# actually compatible with. | |
- name: Set toolchain version | |
run: | | |
set -e | |
cargo check | |
function pkg-meta { | |
cargo metadata --format-version 1 | jq -r ".packages[] | select(.name == \"zerocopy\").$1" | |
} | |
case ${{ matrix.toolchain }} in | |
msrv) | |
ZC_TOOLCHAIN="$(pkg-meta rust_version)" | |
;; | |
stable) | |
ZC_TOOLCHAIN="$(pkg-meta 'metadata.ci."pinned-stable"')" | |
;; | |
nightly) | |
ZC_TOOLCHAIN="$(pkg-meta 'metadata.ci."pinned-nightly"')" | |
;; | |
*) | |
echo 'Unrecognized toolchain: ${{ matrix.toolchain }}' | tee -a $GITHUB_STEP_SUMMARY >&2 | |
exit 1 | |
;; | |
esac | |
echo "Found that the '${{ matrix.toolchain }}' toolchain is $ZC_TOOLCHAIN" | tee -a $GITHUB_STEP_SUMMARY | |
echo "ZC_TOOLCHAIN=$ZC_TOOLCHAIN" >> $GITHUB_ENV | |
- name: Configure environment variables | |
run: | | |
set -e | |
if [[ '${{ matrix.toolchain }}' == 'nightly' ]]; then | |
RUSTFLAGS="$RUSTFLAGS $ZC_NIGHTLY_RUSTFLAGS" | |
MIRIFLAGS="$MIRIFLAGS $ZC_NIGHTLY_MIRIFLAGS" | |
echo "Using nightly toolchain; setting RUSTFLAGS='$RUSTFLAGS' and MIRIFLAGS='$MIRIFLAGS'" | tee -a $GITHUB_STEP_SUMMARY | |
echo "RUSTFLAGS=$RUSTFLAGS" >> $GITHUB_ENV | |
echo "MIRIFLAGS=$MIRIFLAGS" >> $GITHUB_ENV | |
else | |
echo "Using non-nightly toolchain; not modifying RUSTFLAGS='$RUSTFLAGS' or MIRIFLAGS='$MIRIFLAGS'" | tee -a $GITHUB_STEP_SUMMARY | |
fi | |
- name: Install Rust with toolchain ${{ env.ZC_TOOLCHAIN }} and target ${{ matrix.target }} | |
uses: dtolnay/rust-toolchain@00b49be78f40fba4e87296b2ead62868750bdd83 # stable | |
with: | |
toolchain: ${{ env.ZC_TOOLCHAIN }} | |
targets: ${{ matrix.target }} | |
# Only nightly has a working Miri, so we skip installing on all other | |
# toolchains. This expression is effectively a ternary expression - | |
# see [1] for details. | |
# | |
# [1] | |
# https://github.com/actions/runner/issues/409#issuecomment-752775072 | |
components: clippy ${{ matrix.toolchain == 'nightly' && ', miri' || '' }} | |
- name: Rust Cache | |
uses: Swatinem/rust-cache@e207df5d269b42b69c8bc5101da26f7d31feddb4 # v2.6.2 | |
with: | |
key: "${{ matrix.target }}" | |
- name: Check | |
run: cargo +${{ env.ZC_TOOLCHAIN }} check --package ${{ matrix.crate }} --target ${{ matrix.target }} ${{ matrix.features }} --verbose | |
- name: Build | |
run: cargo +${{ env.ZC_TOOLCHAIN }} build --package ${{ matrix.crate }} --target ${{ matrix.target }} ${{ matrix.features }} --verbose | |
# When building tests for the i686 target, we need certain libraries which | |
# are not installed by default; `gcc-multilib` includes these libraries. | |
- name: Install gcc-multilib | |
# Per [1]: | |
# | |
# Note: Always run `sudo apt-get update` before installing a package. In | |
# case the `apt` index is stale, this command fetches and re-indexes any | |
# available packages, which helps prevent package installation failures. | |
# | |
# [1] https://docs.github.com/en/actions/using-github-hosted-runners/customizing-github-hosted-runners | |
run: | | |
sudo apt-get update | |
sudo apt-get install gcc-multilib | |
if: contains(matrix.target, 'i686') | |
- name: Run tests | |
run: cargo +${{ env.ZC_TOOLCHAIN }} test --package ${{ matrix.crate }} --target ${{ matrix.target }} ${{ matrix.features }} --verbose | |
# Only run tests when targetting x86 (32- or 64-bit) - we're executing on | |
# x86_64, so we can't run tests for any non-x86 target. | |
# | |
# TODO(https://github.com/dtolnay/trybuild/issues/184#issuecomment-1269097742): | |
# Run compile tests when building for other targets. | |
if: contains(matrix.target, 'x86_64') || contains(matrix.target, 'i686') | |
- name: Run tests under Miri | |
# Skip the `ui` test since it invokes the compiler, which we can't do from | |
# Miri (and wouldn't want to do anyway). | |
run: cargo +${{ env.ZC_TOOLCHAIN }} miri test --package ${{ matrix.crate }} --target ${{ matrix.target }} ${{ matrix.features }} -- --skip ui | |
# Only nightly has a working Miri, so we skip installing on all other | |
# toolchains. | |
# | |
# TODO(#22): Re-enable testing on riscv64gc-unknown-linux-gnu and/or | |
# wasm32-wasi once those work. | |
if: matrix.toolchain == 'nightly' && matrix.target != 'riscv64gc-unknown-linux-gnu' && matrix.target != 'wasm32-wasi' | |
- name: Run doc tests | |
# We explicitly pass `--doc` here because doc tests are disabled by | |
# default in zerocopy's `Cargo.toml`. This is because some doc examples | |
# make use of derives, and so would fail without the `derive` feature | |
# enabled. We skip this step for `zerocopy` when the `derive` feature is | |
# omitted for that reason. | |
run: cargo +${{ env.ZC_TOOLCHAIN }} test --doc --package ${{ matrix.crate }} --target ${{ matrix.target }} ${{ matrix.features }} --verbose | |
# Only run tests when targetting x86 (32- or 64-bit) - we're executing on | |
# x86_64, so we can't run tests for any non-x86 target. | |
# | |
# TODO(https://github.com/dtolnay/trybuild/issues/184#issuecomment-1269097742): | |
# Run compile tests when building for other targets. | |
if: ${{ (contains(matrix.target, 'x86_64') || contains(matrix.target, 'i686')) && !(matrix.crate == 'zerocopy' && !contains(matrix.features, 'derive')) }} | |
- name: Clippy check | |
run: cargo +${{ env.ZC_TOOLCHAIN }} clippy --package ${{ matrix.crate }} --target ${{ matrix.target }} ${{ matrix.features }} --tests --verbose | |
- name: Cargo doc | |
run: cargo +${{ env.ZC_TOOLCHAIN }} doc --package ${{ matrix.crate }} ${{ matrix.features }} | |
# When the `alloc` feature is disabled, `cargo doc` fails because we link | |
# to `alloc::vec::Vec` in a doc comment, and the `alloc` crate is not in | |
# scope without the `alloc` feature. This isn't a big deal because we care | |
# primarily about `cargo doc` working for `docs.rs`, which enables the | |
# `alloc` feature. | |
if: matrix.features != '' && matrix.features != '--no-default-features' | |
check_fmt: | |
runs-on: ubuntu-latest | |
name: Check Rust formatting | |
steps: | |
- uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3.6.0 | |
- name: Check Rust formatting | |
run: | | |
set -e | |
cargo fmt --check -p zerocopy | |
cargo fmt --check -p zerocopy-derive | |
shopt -s globstar | |
rustfmt --check tests/**/*.rs | |
rustfmt --check zerocopy-derive/tests/**/*.rs | |
check_readme: | |
runs-on: ubuntu-latest | |
name: Check README.md | |
steps: | |
- uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3.6.0 | |
# Cache the `cargo-readme` installation. | |
- name: Rust Cache | |
uses: Swatinem/rust-cache@e207df5d269b42b69c8bc5101da26f7d31feddb4 # v2.6.2 | |
- name: Check README.md | |
run: | | |
set -e | |
cargo install cargo-readme --version 3.2.0 | |
diff <(./generate-readme.sh) README.md | |
exit $? | |
check_msrv: | |
runs-on: ubuntu-latest | |
name: Check MSRVs match | |
steps: | |
- uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3.6.0 | |
# Make sure that the MSRV in zerocopy's and zerocopy-derive's `Cargo.toml` | |
# files are the same. | |
- name: Check MSRVs match | |
run: | | |
set -e | |
# Usage: msrv <crate-name> | |
function msrv { | |
cargo metadata --format-version 1 | jq -r ".packages[] | select(.name == \"$1\").rust_version" | |
} | |
ver_zerocopy=$(msrv zerocopy) | |
ver_zerocopy_derive=$(msrv zerocopy-derive) | |
if [[ "$ver_zerocopy" == "$ver_zerocopy_derive" ]]; then | |
echo "Same MSRV ($ver_zerocopy) found for zerocopy and zerocopy-derive." | tee -a $GITHUB_STEP_SUMMARY | |
exit 0 | |
else | |
echo "Different MSRVs found for zerocopy ($ver_zerocopy) and zerocopy-derive ($ver_zerocopy_derive)." \ | |
| tee -a $GITHUB_STEP_SUMMARY >&2 | |
exit 1 | |
fi | |
check_versions: | |
runs-on: ubuntu-latest | |
name: Check crate versions match | |
steps: | |
- uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3.6.0 | |
# Make sure that both crates are at the same version, and that zerocopy | |
# depends exactly upon the current version of zerocopy-derive. See | |
# `INTERNAL.md` for an explanation of why we do this. | |
- name: Check crate versions match | |
run: | | |
set -e | |
# Usage: version <crate-name> | |
function version { | |
cargo metadata --format-version 1 | jq -r ".packages[] | select(.name == \"$1\").version" | |
} | |
ver_zerocopy=$(version zerocopy) | |
ver_zerocopy_derive=$(version zerocopy-derive) | |
# The non-dev dependency version (`.kind == null` filters out the dev | |
# dependency). | |
zerocopy_derive_dep_ver=$(cargo metadata --format-version 1 \ | |
| jq -r ".packages[] | select(.name == \"zerocopy\").dependencies[] | select((.name == \"zerocopy-derive\") and .kind == null).req") | |
# The dev dependency version (`.kind == \"dev\"` selects only the dev | |
# dependency). | |
zerocopy_derive_dev_dep_ver=$(cargo metadata --format-version 1 \ | |
| jq -r ".packages[] | select(.name == \"zerocopy\").dependencies[] | select((.name == \"zerocopy-derive\") and .kind == \"dev\").req") | |
if [[ "$ver_zerocopy" == "$ver_zerocopy_derive" ]]; then | |
echo "Same crate version ($ver_zerocopy) found for zerocopy and zerocopy-derive." | tee -a $GITHUB_STEP_SUMMARY | |
else | |
echo "Different crate versions found for zerocopy ($ver_zerocopy) and zerocopy-derive ($ver_zerocopy_derive)." \ | |
| tee -a $GITHUB_STEP_SUMMARY >&2 | |
exit 1 | |
fi | |
# Note the leading `=` sign - the dependency needs to be an exact one. | |
if [[ "=$ver_zerocopy_derive" == "$zerocopy_derive_dep_ver" ]]; then | |
echo "zerocopy depends upon same version of zerocopy-derive in-tree ($zerocopy_derive_dep_ver)." | tee -a $GITHUB_STEP_SUMMARY | |
else | |
echo "zerocopy depends upon different version of zerocopy-derive ($zerocopy_derive_dep_ver) than the one in-tree ($ver_zerocopy_derive)." \ | |
| tee -a $GITHUB_STEP_SUMMARY >&2 | |
exit 1 | |
fi | |
if [[ "=$ver_zerocopy_derive" == "$zerocopy_derive_dev_dep_ver" ]]; then | |
echo "In dev mode, zerocopy depends upon same version of zerocopy-derive in-tree ($zerocopy_derive_dev_dep_ver)." | tee -a $GITHUB_STEP_SUMMARY | |
else | |
echo "In dev mode, zerocopy depends upon different version of zerocopy-derive ($zerocopy_derive_dev_dep_ver) than the one in-tree ($ver_zerocopy_derive)." \ | |
| tee -a $GITHUB_STEP_SUMMARY >&2 | |
exit 1 | |
fi |