API Breaking Change Detection¶
This document describes the API breaking change detection system integrated into the CI pipeline.
Overview¶
The API breaking change detection system automatically detects and reports breaking changes in the OpenAPI specification between a PR branch and the main branch. This prevents unintentional breaking changes from being merged without review and approval.
How It Works¶
CI Workflow¶
The api-compatibility.yml workflow runs on all PRs that modify:
backend/api/**backend/models/**backend/main.py
The workflow:
- Generates OpenAPI spec from the main branch
- Generates OpenAPI spec from the PR branch
- Compares the specs using
oasdiffto detect breaking changes - Posts a comment on the PR with details of any breaking changes
- Blocks the PR if breaking changes are detected (unless approved)
- Allows the PR to proceed if the
breaking-change-approvedlabel is added
Breaking Changes Detected¶
The system detects the following breaking changes:
Endpoint Changes¶
- ❌ Removed endpoints: Entire API paths removed
- ❌ Removed HTTP methods: Specific methods removed from an endpoint
Parameter Changes¶
- ❌ Removed required parameters: Required parameters removed
- ⚠️ Removed optional parameters: Optional parameters removed (potentially breaking)
- ❌ Parameter made required: Optional parameter changed to required
- ❌ Parameter type changed: Parameter data type changed
Request Body Changes¶
- ❌ Request body removed: Required request body removed
- ❌ Request body made required: Optional request body changed to required
- ❌ Content type removed: Supported content type removed
Response Changes¶
- ❌ Success response removed: 2xx response removed
- ❌ Response content type removed: Supported response content type removed
Usage¶
For Developers¶
When Your PR Triggers Breaking Change Detection¶
If your PR introduces breaking changes, the workflow will:
- Post a comment on the PR with details of all breaking changes
- Fail the CI check (blocking merge)
- Require approval via the
breaking-change-approvedlabel
Example PR comment:
## 🚨 Breaking API Changes Detected
❌ **Not Approved**: Add the `breaking-change-approved` label to merge despite breaking changes.
### Breaking Changes
- **Method Removed**: `POST /api/users`
- HTTP method POST was removed
- **Parameter Made Required**: `GET /api/users`
- Parameter 'limit' is now required
- Location: query
### Required Actions
1. **Review** all breaking changes above
2. **Update** frontend API clients if needed
3. **Update** API documentation
4. **Consider** API versioning for major changes
5. **Add label** `breaking-change-approved` to proceed with merge
Approving Breaking Changes¶
To approve a PR with breaking changes:
- Review the breaking changes thoroughly
- Ensure all necessary updates are made:
- Frontend API clients updated
- API documentation updated
- Changelog updated
- Migration guide provided (if needed)
- Add the
breaking-change-approvedlabel to the PR - CI will re-run and allow the PR to proceed
For Reviewers¶
When reviewing a PR with breaking changes:
- Verify intentionality: Are the breaking changes intentional or accidental?
- Check completeness: Are all necessary updates included in the PR?
- Consider versioning: Should this use API versioning instead?
- Approve the label: Add
breaking-change-approvedonly if all requirements are met
Local Testing¶
You can run breaking change detection locally before pushing:
Using the Shell Script (Recommended)¶
# Compare against main branch
./scripts/check-api-compatibility.sh
# Compare against a specific branch or commit
./scripts/check-api-compatibility.sh origin/develop
./scripts/check-api-compatibility.sh HEAD~5
Using the Python Script¶
# Generate specs
uv run python scripts/generate-openapi.py
# Compare specs (assuming you have base spec from main)
uv run python scripts/check-api-breaking-changes.py \
--base openapi-main.json \
--current docs/openapi.json
# Different output formats
uv run python scripts/check-api-breaking-changes.py \
--base openapi-main.json \
--current docs/openapi.json \
--format markdown
uv run python scripts/check-api-breaking-changes.py \
--base openapi-main.json \
--current docs/openapi.json \
--format json
Scripts¶
check-api-compatibility.sh¶
Bash script that:
- Installs
oasdiffif needed - Generates OpenAPI specs from both branches
- Compares them using
oasdiff - Reports breaking changes and full diff
Location: scripts/check-api-compatibility.sh
Usage:
Exit codes:
0: No breaking changes1: Breaking changes detected
check-api-breaking-changes.py¶
Python script that:
- Parses OpenAPI specifications
- Implements custom breaking change detection logic
- Supports multiple output formats (text, markdown, JSON)
- Provides detailed categorization of changes
Location: scripts/check-api-breaking-changes.py
Usage:
Options:
--base: Base OpenAPI spec (e.g., from main branch)--current: Current OpenAPI spec (e.g., from PR branch)--format: Output format (text,markdown,json)--verbose: Enable verbose output--allow-potentially-breaking: Don't fail on potentially breaking changes
Exit codes:
0: No breaking changes1: Breaking changes detected2: Error (invalid files, parsing failure, etc.)
Architecture¶
Workflow Flow¶
PR Created/Updated
↓
Workflow Triggered
↓
Generate Main Spec ────────┐
↓ │
Generate PR Spec │
↓ │
Compare Specs ←────────────┘
↓
Breaking Changes? ──→ No ──→ ✅ Pass
↓
Yes
↓
Post PR Comment
↓
Has 'breaking-change-approved' label? ──→ Yes ──→ ✅ Pass
↓
No
↓
❌ Fail (Block PR)
Change Detection Logic¶
The Python script (check-api-breaking-changes.py) implements:
- Path comparison: Detect removed endpoints
- Method comparison: Detect removed HTTP methods
- Parameter comparison: Detect parameter changes (type, required status, removal)
- Request body comparison: Detect request body changes
- Response comparison: Detect response schema changes
- Severity classification: Categorize changes as breaking or potentially breaking
Testing¶
Unit Tests¶
The breaking change detection logic is tested in:
backend/tests/unit/test_check_api_breaking_changes.py
Run tests:
Test Cases¶
The test suite covers:
- ✅ No breaking changes
- ✅ Removed endpoints
- ✅ Removed HTTP methods
- ✅ Parameter made required
- ✅ Parameter type changed
- ✅ Removed required parameters
- ✅ Request body removed
- ✅ Multiple breaking changes
- ✅ Markdown output format
- ✅ JSON output format
- ✅ Invalid spec handling
Best Practices¶
For API Developers¶
- Run locally first: Check for breaking changes before pushing
- Document intentional breaks: If a breaking change is necessary, document it thoroughly
- Consider alternatives:
- Can you add a new endpoint instead of modifying an existing one?
- Can you support both old and new parameters during a transition period?
- Should you introduce API versioning?
- Update clients: Ensure all API clients are updated before merging
- Communication: Inform stakeholders about breaking changes
For Reviewers¶
- Verify necessity: Are the breaking changes truly necessary?
- Check completeness: Are all updates included?
- Require documentation: Ensure breaking changes are documented
- Consider impact: Who will be affected by these changes?
- Approve thoughtfully: Only add the approval label when confident
For Maintainers¶
- Monitor failures: Review any breaking changes merged to main
- Track trends: Are breaking changes becoming too frequent?
- Enforce standards: Ensure the approval process is followed
- Update tooling: Keep
oasdiffand detection scripts updated
Troubleshooting¶
False Positives¶
If the detection reports a breaking change that isn't actually breaking:
- Review the change: Understand why it's flagged
- Check the spec: Ensure the OpenAPI spec is accurate
- Update detection logic: If needed, improve the detection script
- Document exception: Add to known limitations
Missing Detections¶
If a breaking change isn't detected:
- Report the issue: Create a Linear issue with details
- Add test case: Add a test for the missed case
- Update detection logic: Improve the script to catch it
- Run tests: Verify the fix works
Workflow Failures¶
If the workflow fails unexpectedly:
- Check logs: Review the GitHub Actions logs
- Verify specs: Ensure both specs were generated correctly
- Check oasdiff: Ensure
oasdiffinstalled successfully - Retry: Sometimes transient failures occur
Integration with Other Systems¶
Linear¶
On main branch failures, the workflow:
- Creates a Linear issue with details
- Links to the failing workflow run
- Avoids duplicate issues
GitHub¶
The workflow:
- Posts detailed comments on PRs
- Uses GitHub Actions artifacts to store specs
- Integrates with required status checks
CI/CD¶
The breaking change check:
- Runs alongside other API checks
- Must pass for PR to be mergeable
- Can be overridden with approval label
Future Enhancements¶
Potential improvements:
- Semantic versioning: Automatically suggest version bumps based on changes
- Migration guides: Auto-generate migration guides for breaking changes
- Client SDKs: Auto-update client SDK versions when breaking changes are approved
- Deprecation tracking: Track deprecated endpoints and warn before removal
- Change impact analysis: Estimate how many clients will be affected
- Notification system: Alert teams when breaking changes are introduced