Skip to content

Add abidiff CI #516

@markcmiller86

Description

@markcmiller86

Add CI to check for ABI diffs in the committed code. Maybe allow them to main but not to any RC branch.

In many ways, this would involve make the same changes on an RC branch and a main branch differently, especially if they involve changes in public structure members. On the RC, allow only changes to the end of a struct whereas on main, they could be re-ordered to their proper positions. OTOH, the struct size would still change and having an array of them (well, no Silo client should have an array of public structs. They should have only arrays of pointers to public structs).

name: ABI check

on:
  pull_request:

jobs:
  abidiff:
    runs-on: ubuntu-latest
    steps:
      - name: Install libabigail tools
        run: |
          sudo apt-get update
          sudo apt-get install -y abigail-tools

      # Checkout BASE (the branch the PR targets)
      - name: Checkout base
        uses: actions/checkout@v4
        with:
          ref: ${{ github.base_ref }}
          path: base

      # Checkout PR HEAD
      - name: Checkout PR
        uses: actions/checkout@v4
        with:
          ref: ${{ github.sha }}
          path: pr

      - name: Build base (produce shared libs with DWARF)
        run: |
          set -euxo pipefail
          mkdir -p base/build
          cd base/build
          cmake .. \
            -DCMAKE_BUILD_TYPE=RelWithDebInfo \
            -DBUILD_SHARED_LIBS=ON
          cmake --build . -j2

      - name: Build PR (produce shared libs with DWARF)
        run: |
          set -euxo pipefail
          mkdir -p pr/build
          cd pr/build
          cmake .. \
            -DCMAKE_BUILD_TYPE=RelWithDebInfo \
            -DBUILD_SHARED_LIBS=ON
          cmake --build . -j2

      - name: Run abidiff
        run: |
          set -euxo pipefail

          # Point these at the actual .so you care about
          OLD_SO="base/build/path/to/libmylib.so"
          NEW_SO="pr/build/path/to/libmylib.so"

          # Produce a human-readable report regardless of pass/fail
          abidiff "$OLD_SO" "$NEW_SO" > abidiff-report.txt || true

          # Now re-run and use the exit status to fail on ABI change.
          # abidiff exit is a bitfield; nonzero may mean "ABI change" or "error".
          # We'll treat any ABI change as failure; keep report as artifact.
          set +e
          abidiff "$OLD_SO" "$NEW_SO" > /dev/null
          RC=$?
          set -e

          # Bit 4 (value 4) indicates ABI change (ABIDIFF_ABI_CHANGE).
          # See abidiff return values.
          if (( (RC & 4) != 0 )); then
            echo "ABI change detected."
            exit 1
          fi

          # If it wasn't an ABI change but still nonzero, it's an abidiff/tool error.
          if (( RC != 0 )); then
            echo "abidiff returned nonzero ($RC) but not ABI_CHANGE; treating as error."
            exit 2
          fi

      - name: Upload abidiff report
        uses: actions/upload-artifact@v4
        with:
          name: abidiff-report
          path: abidiff-report.txt

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions