Skip to content

Ensure changes to your code don't break ABI (via a GitHub action!)

Notifications You must be signed in to change notification settings

buildsi/libabigail-action

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

9 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Libabigail Action

Libabigail is "The ABI Generic Analysis and Instrumentation Library" and it's a tool to help you make sure that your library does not break ABI, or the application binary interface. How can you do this?

  • For every pull request, check the abidiff against the latest main branch
  • Also have the option to check the PR against the release
  • Require a version bump if there are ABI breaks

For the libabigail base we use ghcr.io/buildsi/libabigail and you can request a new release of the Dockerfile if it's available for libabigail.

Usage

We recommend a workflow that triggers on pull request and (in parallel) builds:

  • the pull request commit (default checkout without parameters)
  • the latest release
  • the latest version on your main branch

And then you can use the action to save your library or binary from each build, and run abidiff. Depending on your use case for the run, you can also set a variable to indicate if the test should be allowed to fail. Here is an example.

Example

Let's say we have the repository buildsi/build-abi-test-mathclient. We have two releases, 1.0 andn 2.0 (on the main branch) and version 2.0 has an ABI break. For the purposes of the example, let's pretend version 2.0 isn't released and we are opening a PR against the current main (still with version 1.0) and we want to ensure that no ABI is broken. We would want to:

  • Do a build of the main branch
  • Do a build of our pull request
  • Do a build of the last release (1.0)

And for all of these cases, we'd want to run abidiff to ensure there are no breaks! Note that since we are going to be saving our binaries (or libraries in this case) as artifacts and then loading them in the same job, we are artificially renaming them. If you've set the SONAME this shouldn't be an issue. Our workflow might look like the following:

name: Run Libabigail
on: [pull_request]

jobs:
  build-release:
    runs-on: ubuntu-latest
    steps:
    - name: Build Previous Release
      uses: actions/checkout@v3
      with:
        ref: 1.0.0
    - name: Build Release Binary and Rename
      run: make && cp libmath.so libmath.1.so
    - name: Upload results
      uses: actions/upload-artifact@v2-preview
      with:
        name: libmath.1.so
        path: libmath.1.so

  build-pull-request:
    runs-on: ubuntu-latest
    steps:
    - name: Build Pull Request
      uses: actions/checkout@v3
    - name: Build Binary and Rename
      run: make && cp libmath.so libmath.dev.so
    - name: Upload results
      uses: actions/upload-artifact@v2-preview
      with:
        name: libmath.dev.so
        path: libmath.dev.so

  build-main:
    runs-on: ubuntu-latest
    steps:
    - name: Build Main
      uses: actions/checkout@v3
      with:
        ref: main
    - name: Build Binary
      run: make && cp libmath.main.so libmath.main.so
    - name: Upload results
      uses: actions/upload-artifact@v2-preview
      with:
        name: libmath.main.so
        path: libmath.main.so

  libabigail:
    runs-on: ubuntu-latest
    needs: [build-release, build-main, build-pull-request]
    steps:
    - name: Download Previous Release
      uses: actions/download-artifact@v2
      with:
        name: libmath.1.so

    - name: Download Latest Main (or PR)
      uses: actions/download-artifact@v2
      with:
        name: libmath.main.so

    - name: Download Pull Request Build
      uses: actions/download-artifact@v2
      with:
        name: libmath.dev.so

    - name: Show Files
      run: ls

    - name: Checkout Libabigail Action
      uses: actions/checkout@v3

    # You can add allow_fail: true if you expect a failure
    - name: Compare Main to Pull Request
      uses: buildsi/libabigail-action@main
      with: 
        abidiff: libmath.main.so libmath.dev.so
        abidw: "--abidiff libmath.dev.so"

    # You can add allow_fail: true if you expect a failure
    - name: Compare Release to Pull Request
      uses: buildsi/libabigail-action@main
      id: release-to-pr
      with: 
        abidiff: libmath.1.so libmath.dev.so

    - name: Example to show output
      env:
        retval: ${{ steps.release-to-pr.outputs.retval }}
      run: echo "The return code was ${retval}, do something custom here"

There are other checks you can do that we might recommend, such as looking at the return code of the run, and allowing it to fail only if the soname is changed. We set an output to help with that! If you'd like further help setting this up or example please let us know. There are additional examples in examples (including the one above!)