Skip to content

Commit cf4729b

Browse files
authored
feat: add automatic API breaking change detection (#46)
* feat: add automatic API breaking change detection with cargo-semver-checks Implement automatic detection of breaking changes in public APIs using cargo-semver-checks instead of relying on manual labels or keywords. Changes: - Add cargo-semver-checks installation to auto-label workflow - Check CLI and SDK crates for API breaking changes - Automatically apply semantic:major label when API changes detected - Update PR comment to show API breaking change analysis - Works with existing release-on-breaking-change workflow Detection now works by analyzing actual API changes: - Removed public functions - Changed function signatures - Removed/renamed struct fields - Changed trait bounds - And more... This eliminates the need for manual "breaking change" annotations and ensures releases are triggered based on actual code changes. Example: PR #44 removed CLI arguments and command structures - this would now be automatically detected and labeled as breaking. * fix(workflow): use baseline-rev for semver checks on unpublished crates This fixes the cargo-semver-checks integration to work with unpublished crates by comparing against the PR base branch using --baseline-rev. Changes: - Add explicit fetch of base branch for comparison - Update semver-checks to use --baseline-rev origin/${{ github.base_ref }} - Remove CLI checking (binary-only, no public API to check) - Focus only on SDK/core library which has a public API - Update PR comments to clarify only SDK is checked This resolves the errors: - "core not found in registry (crates.io)" - now uses git baseline - "no library targets selected" for CLI - now skipped with explanation
1 parent c8ba8f7 commit cf4729b

File tree

1 file changed

+73
-2
lines changed

1 file changed

+73
-2
lines changed

.github/workflows/auto-label-semantic.yml

Lines changed: 73 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,59 @@ jobs:
1818
with:
1919
fetch-depth: 0
2020

21+
- name: Setup Rust
22+
uses: dtolnay/rust-toolchain@stable
23+
24+
- name: Install cargo-semver-checks
25+
run: |
26+
cargo install cargo-semver-checks --locked
27+
28+
- name: Fetch base branch for comparison
29+
run: |
30+
git fetch origin ${{ github.base_ref }}
31+
32+
- name: Check for API breaking changes
33+
id: semver-check
34+
continue-on-error: true
35+
run: |
36+
echo "Checking for API breaking changes in SDK..."
37+
38+
HAS_BREAKING=false
39+
40+
# Note: CLI crate is skipped - it's binary-only with no public library API
41+
# Only check core/SDK crate which has a public library API
42+
43+
if [ -d "core" ]; then
44+
echo "Checking core/SDK crate for API breaking changes..."
45+
echo "Comparing current code against base branch: ${{ github.base_ref }}"
46+
47+
cd core
48+
49+
# Use --baseline-rev to compare against base branch (works for unpublished crates)
50+
if ! cargo semver-checks check-release \
51+
--baseline-rev origin/${{ github.base_ref }} \
52+
2>&1 | tee /tmp/core-semver.log; then
53+
echo "⚠️ API breaking changes detected in SDK"
54+
HAS_BREAKING=true
55+
else
56+
echo "✓ No API breaking changes detected in SDK"
57+
fi
58+
59+
cd ..
60+
fi
61+
62+
echo "has_breaking=$HAS_BREAKING" >> $GITHUB_OUTPUT
63+
64+
# Save logs for comment
65+
if [ "$HAS_BREAKING" = "true" ]; then
66+
echo "SEMVER_BREAKING=true" >> $GITHUB_ENV
67+
cp /tmp/core-semver.log /tmp/semver-report.log 2>/dev/null || true
68+
fi
69+
2170
- name: Analyze commits and apply label
2271
uses: actions/github-script@v7
72+
env:
73+
SEMVER_BREAKING: ${{ steps.semver-check.outputs.has_breaking }}
2374
with:
2475
github-token: ${{ secrets.GITHUB_TOKEN }}
2576
script: |
@@ -102,6 +153,21 @@ jobs:
102153
}
103154
}
104155
156+
// Check for API breaking changes detected by cargo-semver-checks
157+
const semverBreaking = process.env.SEMVER_BREAKING === 'true';
158+
if (semverBreaking) {
159+
console.log('⚠️ API breaking changes detected by cargo-semver-checks');
160+
hasMajor = true;
161+
analyzedCommits.push({
162+
sha: 'semver',
163+
type: 'API',
164+
scope: '',
165+
breaking: true,
166+
impact: 'MAJOR',
167+
message: 'Breaking API changes detected by cargo-semver-checks'
168+
});
169+
}
170+
105171
// Determine highest semantic level
106172
let semanticLevel = null;
107173
if (hasMajor) {
@@ -147,16 +213,21 @@ jobs:
147213
? `**${semanticLevel.toUpperCase()}** version bump`
148214
: 'No version bump required';
149215
216+
const apiBreakingNote = semverBreaking
217+
? '\n\n⚠️ **API Breaking Changes Detected**\n\nThe `cargo-semver-checks` tool detected breaking changes in the SDK public API. This will trigger a MAJOR version bump (or MINOR in alpha v0.x.x).\n\n**Note:** Only the SDK/core library is checked for API breaking changes. The CLI is binary-only and has no public library API to check.\n'
218+
: '';
219+
150220
const commentBody = `## 🤖 Semantic Version Analysis
151221
152222
**Result:** ${versionBumpText}
153-
223+
${apiBreakingNote}
154224
### Commit Analysis
155225
156226
${table}
157227
158228
### Summary
159-
- Breaking changes (🔴 MAJOR): ${hasMajor ? '✓' : '✗'}
229+
- SDK API breaking changes (🔴 MAJOR): ${semverBreaking ? '✓ Detected by cargo-semver-checks' : '✗'}
230+
- Conventional breaking changes (🔴 MAJOR): ${hasMajor && !semverBreaking ? '✓' : '✗'}
160231
- New features (🟡 MINOR): ${hasMinor ? '✓' : '✗'}
161232
- Bug fixes (🟢 PATCH): ${hasPatch ? '✓' : '✗'}
162233

0 commit comments

Comments
 (0)