name: Semver
on:
pull_request:
branches: [main]
push:
tags:
- 'v*'
env:
CARGO_TERM_COLOR: always
jobs:
changes:
name: Detect Changes
runs-on: ubuntu-latest
outputs:
rust: ${{ steps.filter.outputs.rust }}
should_run: ${{ github.event_name == 'push' || steps.filter.outputs.rust == 'true' }}
steps:
- uses: actions/checkout@v7
- uses: dorny/paths-filter@v4
id: filter
if: github.event_name == 'pull_request'
with:
filters: |
rust:
- 'src/**'
- 'Cargo.toml'
- 'Cargo.lock'
- 'CHANGELOG.md'
semver-check:
name: API Compatibility
needs: changes
if: needs.changes.outputs.should_run == 'true'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
with:
fetch-depth: 0
- uses: dtolnay/rust-toolchain@stable
- name: Install cargo-semver-checks
run: cargo install cargo-semver-checks --locked
- name: Check semver compatibility
run: |
# Get the latest tag for comparison
LATEST_TAG=$(git describe --tags --abbrev=0 2>/dev/null || echo "")
if [ -z "$LATEST_TAG" ]; then
echo "No previous tags found, skipping semver check"
echo "## Semver Check" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "No previous release found. Skipping API compatibility check." >> $GITHUB_STEP_SUMMARY
exit 0
fi
echo "Checking API compatibility against $LATEST_TAG"
echo "## Semver Check" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "Comparing against: **$LATEST_TAG**" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
if cargo semver-checks check-release --baseline-rev "$LATEST_TAG"; then
echo "API is compatible" >> $GITHUB_STEP_SUMMARY
else
echo "::warning::API breaking changes detected"
echo "API breaking changes detected. Ensure version bump is appropriate." >> $GITHUB_STEP_SUMMARY
fi
changelog-check:
name: Changelog Updated
needs: changes
if: github.event_name == 'pull_request' && needs.changes.outputs.rust == 'true'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
with:
fetch-depth: 0
- name: Check CHANGELOG.md updated
run: |
if git diff --name-only origin/main...HEAD | grep -q "CHANGELOG.md"; then
echo "CHANGELOG.md has been updated"
else
echo "::warning::CHANGELOG.md has not been updated in this PR"
fi
semver-result:
name: Semver Result
needs: [changes, semver-check, changelog-check]
if: always()
runs-on: ubuntu-latest
steps:
- name: Check results
run: |
if [[ "${{ needs.changes.outputs.should_run }}" != "true" ]]; then
echo "No relevant changes detected, skipping semver checks"
exit 0
fi
if [[ "${{ needs.semver-check.result }}" == "failure" || \
"${{ needs.changelog-check.result }}" == "failure" ]]; then
echo "Semver check failed"
exit 1
fi
echo "Semver checks passed"