Skip to content

Add a script to check for breaking C ABI changes #2

Add a script to check for breaking C ABI changes

Add a script to check for breaking C ABI changes #2

Workflow file for this run

name: C ABI Compatibility Check
on:
workflow_dispatch: # Allow manual trigger for bootstrap
workflow_call:
pull_request:
paths:
- 'c/include/**'
- 'ci/check_c_abi.py'
- '.github/workflows/check-c-abi.yaml'
push:
branches:
- main
paths:
- 'c/include/**'
- 'ci/check_c_abi.py'
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
# Extract and store baseline ABI from main branch
update-baseline:
if: github.event_name == 'workflow_dispatch' || (github.event_name == 'push' && github.ref == 'refs/heads/main')
runs-on: ubuntu-latest
concurrency:
group: abi-baseline-update
cancel-in-progress: false # Queue updates, don't skip
steps:
- name: Checkout main branch
uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.11'
- name: Install system dependencies
run: |
sudo apt-get update
sudo apt-get install -y \
libclang-dev \
clang \
cmake \
ninja-build
- name: Install Python dependencies
run: |
pip install --upgrade pip
pip install msgspec libclang termcolor
- name: Build C++ project to get dependencies (dlpack)
run: |
mkdir -p cpp/build
cd cpp/build
cmake .. \
-GNinja \
-DCMAKE_BUILD_TYPE=Debug \
-DBUILD_TESTS=OFF \
-DBUILD_EXAMPLES=OFF
echo "Build directory created and dependencies fetched"
- name: Extract ABI from main branch
run: |
mkdir -p baseline
python ci/check_c_abi.py extract \
--header_path c/include \
--include_file cuvs/core/all.h \
--output_file baseline/c_abi.json.gz
echo "ABI extracted from main branch (commit: ${{ github.sha }})"
- name: Store commit-specific baseline
uses: actions/upload-artifact@v4
with:
name: c-abi-baseline-${{ github.sha }}
path: baseline/c_abi.json.gz
retention-days: 90 # Keep for 3 months
- name: Store main baseline (latest, never expires)
uses: actions/upload-artifact@v4
with:
name: c-abi-baseline-main
path: baseline/c_abi.json.gz
retention-days: 0 # Never expire
# Check PRs for breaking ABI changes
check-pr:
if: github.event_name == 'pull_request' || github.event_name == 'workflow_call'
runs-on: ubuntu-latest
steps:
- name: Checkout PR branch
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.11'
- name: Install system dependencies
run: |
sudo apt-get update
sudo apt-get install -y \
libclang-dev \
clang \
cmake \
ninja-build
- name: Install Python dependencies
run: |
pip install --upgrade pip
pip install msgspec libclang termcolor
- name: Build C++ project to get dependencies (dlpack)
run: |
mkdir -p cpp/build
cd cpp/build
cmake .. \
-GNinja \
-DCMAKE_BUILD_TYPE=Debug \
-DBUILD_TESTS=OFF \
-DBUILD_EXAMPLES=OFF
echo "Build directory created and dependencies fetched"
- name: Find merge base commit
id: merge-base
run: |
git fetch origin main
MERGE_BASE=$(git merge-base HEAD origin/main)
echo "merge_base_sha=${MERGE_BASE}" >> $GITHUB_OUTPUT
echo "Merge base commit: ${MERGE_BASE}"
- name: Try to download baseline for merge-base commit (most accurate)
id: download-merge-base
continue-on-error: true
uses: dawidd6/action-download-artifact@v3
with:
name: c-abi-baseline-${{ steps.merge-base.outputs.merge_base_sha }}
workflow: check-c-abi.yaml
commit: ${{ steps.merge-base.outputs.merge_base_sha }}
path: baseline/
- name: Try to download latest main baseline (fallback 1)
id: download-main
if: steps.download-merge-base.outcome == 'failure'
continue-on-error: true
uses: dawidd6/action-download-artifact@v3
with:
name: c-abi-baseline-main
workflow: check-c-abi.yaml
branch: main
path: baseline/
- name: Extract baseline ABI from main branch (fallback 2)
if: steps.download-merge-base.outcome == 'failure' && steps.download-main.outcome == 'failure'
run: |
echo "⚠️ No baseline artifacts found, extracting from main branch..."
echo "This is slower but ensures we always have a baseline for comparison."
git worktree add ../cuvs-main main
mkdir -p ../cuvs-main/cpp/build
cd ../cuvs-main/cpp/build
cmake .. \
-GNinja \
-DCMAKE_BUILD_TYPE=Debug \
-DBUILD_TESTS=OFF \
-DBUILD_EXAMPLES=OFF
cd ../../..
mkdir -p baseline
python ci/check_c_abi.py extract \
--header_path ../cuvs-main/c/include \
--include_file cuvs/core/all.h \
--output_file baseline/c_abi.json.gz
echo "✓ Baseline ABI extracted from main branch"
- name: Report baseline source
run: |
if [ "${{ steps.download-merge-base.outcome }}" == "success" ]; then
echo "✓ Using baseline from merge-base commit: ${{ steps.merge-base.outputs.merge_base_sha }}"
elif [ "${{ steps.download-main.outcome }}" == "success" ]; then
echo "✓ Using latest main baseline (merge-base baseline not yet available)"
else
echo "✓ Using freshly extracted baseline from main branch"
fi
- name: Analyze current branch for ABI breaking changes
run: |
python ci/check_c_abi.py analyze \
--abi_file baseline/c_abi.json.gz \
--header_path c/include \
--include_file cuvs/core/all.h
- name: Comment on PR with results
if: failure() && github.event_name == 'pull_request'
uses: actions/github-script@v7
with:
script: |
github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: `## ⚠️ C ABI Breaking Changes Detected
This PR introduces breaking changes to the C ABI. Please review the changes carefully.

Check failure on line 205 in .github/workflows/check-c-abi.yaml

View workflow run for this annotation

GitHub Actions / .github/workflows/check-c-abi.yaml

Invalid workflow file

You have an error in your yaml syntax on line 205
Breaking ABI changes are only allowed in major releases. If this is intentional for a major release,
the baseline ABI will need to be updated after merge.
See the job logs for details on what specific changes were detected.
### What are breaking ABI changes?
Breaking ABI changes include:
- Removing functions from the public API
- Changing function signatures (parameters or return types)
- Removing struct members or changing their types
- Removing or changing enum values
### Next steps
1. Review the changes flagged in the CI logs
2. If these changes are unintentional, update your PR to maintain ABI compatibility
3. If these changes are required, ensure:
- This is part of a major version release
- The changes are documented in the changelog
- Migration guide is provided for users
For more information, see the [C ABI documentation](../docs/source/c_developer_guide.md).
`
});