Use baseline choosing logic of cargo-semver-checks

This commit is contained in:
Mieszko Grodzicki 2023-01-03 19:21:46 +01:00 committed by Predrag Gruevski
parent 1227c17749
commit 1b587be276
2 changed files with 1 additions and 96 deletions

View file

@ -32,20 +32,6 @@ runs:
# Colorize output, since GitHub Actions terminals support color.
export CARGO_TERM_COLOR=always
# Record the current git sha, so we can come back to it after generating the baseline.
export CURRENT_GIT_SHA="$(git rev-parse HEAD)"
# 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"
export PACKAGE_NAME="${{ inputs.crate-name }}"
if [[ "$PACKAGE_NAME" == '' ]]; then
export PACKAGE_NAME="$("$GITHUB_ACTION_PATH/find_workspace_crates.sh")"
@ -53,28 +39,7 @@ runs:
# cargo rustdoc uses the exact package name, not the "underscores" version.
export RUSTDOC_EARLY_FLAGS="--package $PACKAGE_NAME $RUSTDOC_EARLY_FLAGS"
fi
export PACKAGE_NAME_WITH_UNDERSCORES="$(echo "$PACKAGE_NAME" | tr '-' '_')"
# 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.
export COMPARISON_TAG="${{ inputs.version-tag-prefix }}$("$GITHUB_ACTION_PATH/find_comparison_version.sh" "$PACKAGE_NAME")"
git fetch --depth=1 origin "+refs/tags/$COMPARISON_TAG:refs/tags/$COMPARISON_TAG"
git checkout "$COMPARISON_TAG"
RUSTC_BOOTSTRAP=1 cargo rustdoc $RUSTDOC_EARLY_FLAGS -- $RUSTDOC_LATE_FLAGS
mv "$(cargo metadata --format-version 1 | jq -r .target_directory)/doc/$PACKAGE_NAME_WITH_UNDERSCORES.json" /tmp/baseline.json
# Return to the original git sha.
git checkout "$CURRENT_GIT_SHA"
# Build rustdoc JSON for the current version, and move it to /tmp/
# so it doesn't get overwritten by the baseline build.
RUSTC_BOOTSTRAP=1 cargo rustdoc $RUSTDOC_EARLY_FLAGS -- $RUSTDOC_LATE_FLAGS
mv "$(cargo metadata --format-version 1 | jq -r .target_directory)/doc/$PACKAGE_NAME_WITH_UNDERSCORES.json" /tmp/current.json
# Check for semver violations.
cargo install cargo-semver-checks --locked
cargo semver-checks check-release --current /tmp/current.json --baseline /tmp/baseline.json
cargo semver-checks check-release --package "$PACKAGE_NAME"

View file

@ -1,60 +0,0 @@
#!/usr/bin/env bash
# Script requirements:
# - curl
# - jq
# - sort with `-V` flag, available in `coreutils-7`
# On macOS this may require `brew install coreutils`.
# Fail on first error, on undefined variables, and on failures in pipelines.
set -euo pipefail
# Go to the repo root directory.
cd "$(git rev-parse --show-toplevel)"
# The first argument should be the name of a crate.
CRATE_NAME="$1"
CURRENT_VERSION="$( \
cargo metadata --format-version 1 | \
jq --arg crate_name "$CRATE_NAME" --exit-status -r \
'.packages[] | select(.name == $crate_name) | .version' \
)" || (echo >&2 "No crate named $CRATE_NAME found in workspace."; exit 1)
echo >&2 "Crate $CRATE_NAME current version: $CURRENT_VERSION"
# The leading whitespace is important! With it, we know that every version is both
# preceded by and followed by whitespace. We use this fact to avoid matching
# on substrings of versions.
EXISTING_VERSIONS="
$( \
curl 2>/dev/null "https://crates.io/api/v1/crates/$CRATE_NAME" | \
jq --exit-status -r .versions[].num \
)"
echo >&2 -e "Versions on crates.io:$EXISTING_VERSIONS\n"
# Use version sort (sort -V) to get all versions in ascending order, then use grep to:
# - grab the first line that matches the current version (--max-count=1)
# - only match full lines (--line-regexp)
# - get one line of leading context (-B 1) i.e. the immediately-smaller version, if one exists
# - explicitly opt out of trailing context lines (-A 0)
# Finally, use `head` to output only the first of the up-to-two lines output.
# Now, either:
# - two lines were output, and we grabbed the immediately-smaller version, or
# - one line was output with only our version, because there was no immediately-smaller version,
# and we grabbed that one. We sort this out with the subsequent conditional.
OUTPUT="$( \
echo -e "$CURRENT_VERSION$EXISTING_VERSIONS" | \
sort -V | \
grep -B 1 -A 0 --line-regexp --max-count=1 "$CURRENT_VERSION" | \
head -n 1 \
)"
if [[ "$OUTPUT" == "$CURRENT_VERSION" ]]; then
echo >&2 "There is no suitable comparison version."
echo >&2 \
"The current version $CURRENT_VERSION is smaller than any version published on crates.io"
exit 1
fi
echo "Comparison version: $OUTPUT" >&2
echo "$OUTPUT"