2022-07-21 01:19:33 +02:00
name : 'cargo-semver-checks'
2022-07-21 01:34:12 +02:00
description : 'Ensure the public API in your Rust crate follows semantic versioning'
2022-07-21 01:19:33 +02:00
inputs :
crate-name :
description : 'The crate whose API to check for semver'
required : false
default : ''
2022-08-07 18:23:51 +02:00
crate-target :
description : 'By default, check the library target of the crate. If you' d like to check a different target (e.g. a binary target), set this to `--bin <NAME>`'
required : false
default : '--lib'
2022-07-21 01:19:33 +02:00
version-tag-prefix :
description : 'The prefix to use for the git tag for a version; the default "v" creates tags like "v1.0.0"'
required : false
default : 'v'
runs :
using : "composite"
steps :
- name : Install rust
uses : actions-rs/toolchain@v1
with :
toolchain : nightly
profile : minimal
2022-07-21 01:41:14 +02:00
- name : Build rustdoc and check it
2022-07-21 01:57:47 +02:00
shell : bash
2022-07-21 01:41:14 +02:00
run : |
2022-07-21 02:08:54 +02:00
set -euxo pipefail
2022-07-21 01:41:14 +02:00
# Colorize output, since GitHub Actions terminals support color.
export CARGO_TERM_COLOR=always
2022-07-21 01:19:33 +02:00
2022-07-21 01:41:14 +02:00
# Record the current git sha, so we can come back to it after generating the baseline.
export CURRENT_GIT_SHA="$(git rev-parse HEAD)"
2022-07-21 01:19:33 +02:00
2022-08-07 18:23:51 +02:00
# We add `--all-features` to semver-check every part of the crate.
# In principle, semver can be broken by moving public API code into a feature.
# Checking this requires rebuilding rustdoc multiple times with different sets of features,
# which can get expensive and is therefore left to individual maintainers' discretion.
#
# We add `--document-private-items` because for some reason, rustdoc seems to not always
# generate all implemented trait information without it:
# https://github.com/obi1kenobi/cargo-semver-check/issues/32
export RUSTDOC_EARLY_FLAGS="${{ inputs.crate-target }} --all-features"
export RUSTDOC_LATE_FLAGS="--document-private-items -Zunstable-options --output-format json"
2022-07-21 01:41:14 +02:00
export PACKAGE_NAME="${{ inputs.crate-name }}"
if [[ "$PACKAGE_NAME" == '' ]]; then
2022-07-21 02:08:54 +02:00
export PACKAGE_NAME="$("$GITHUB_ACTION_PATH/find_workspace_crates.sh")"
2022-08-07 18:23:51 +02:00
else
# cargo rustdoc uses the exact package name, not the "underscores" version.
export RUSTDOC_EARLY_FLAGS="--package $PACKAGE_NAME $RUSTDOC_EARLY_FLAGS"
2022-07-21 01:41:14 +02:00
fi
2022-07-21 02:14:39 +02:00
export PACKAGE_NAME_WITH_UNDERSCORES="$(echo "$PACKAGE_NAME" | tr '-' '_')"
2022-07-21 01:19:33 +02:00
2022-07-21 01:41:14 +02:00
# Switch to the tag for the correct baseline version,
# then build rustdoc JSON.
#
# We *do not* want to record and reuse the target directory path
# across different git commits, since it may be at a different location
# in different commits.
2022-08-02 20:41:19 +02:00
export COMPARISON_TAG="${{ inputs.version-tag-prefix }}$("$GITHUB_ACTION_PATH/find_comparison_version.sh" "$PACKAGE_NAME")"
2022-08-02 21:17:03 +02:00
git fetch --depth=1 origin "+refs/tags/$COMPARISON_TAG:refs/tags/$COMPARISON_TAG"
2022-08-02 21:12:33 +02:00
git checkout "$COMPARISON_TAG"
2022-08-07 18:23:51 +02:00
cargo +nightly rustdoc $RUSTDOC_EARLY_FLAGS -- $RUSTDOC_LATE_FLAGS
2022-07-21 01:41:14 +02:00
mv "$(cargo metadata --format-version 1 | jq -r .target_directory)/doc/$PACKAGE_NAME_WITH_UNDERSCORES.json" /tmp/baseline.json
2022-07-21 01:19:33 +02:00
2022-07-21 01:41:14 +02:00
# Return to the original git sha.
git checkout "$CURRENT_GIT_SHA"
2022-07-21 01:19:33 +02:00
2022-07-21 01:41:14 +02:00
# Build rustdoc JSON for the current version, and move it to /tmp/
# so it doesn't get overwritten by the baseline build.
2022-08-07 18:23:51 +02:00
cargo +nightly rustdoc $RUSTDOC_EARLY_FLAGS -- $RUSTDOC_LATE_FLAGS
2022-07-21 01:41:14 +02:00
mv "$(cargo metadata --format-version 1 | jq -r .target_directory)/doc/$PACKAGE_NAME_WITH_UNDERSCORES.json" /tmp/current.json
2022-07-21 01:19:33 +02:00
2022-07-21 01:41:14 +02:00
# Check for semver violations.
cargo install cargo-semver-checks
cargo semver-checks check-release --current /tmp/current.json --baseline /tmp/baseline.json