Skip to content

Add fallback lookup for shell files without domain-ID suffix #337

Add fallback lookup for shell files without domain-ID suffix

Add fallback lookup for shell files without domain-ID suffix #337

Workflow file for this run

# =============================================================================
# ABI/API Compatibility Check Workflow
# =============================================================================
# Ensures that PR changes don't break binary compatibility for existing apps
# by comparing shared library ABIs between PR and development branch versions
name: ABI/API Compatibility Check
on:
pull_request:
branches: [development, main]
# Cross-compilation environment for AArch64 (ARM64) architecture
env:
CC: aarch64-linux-gnu-gcc
CXX: aarch64-linux-gnu-g++
AS: aarch64-linux-gnu-as
LD: aarch64-linux-gnu-ld
RANLIB: aarch64-linux-gnu-ranlib
STRIP: aarch64-linux-gnu-strip
# -fno-eliminate-unused-debug-types prevents GCC from optimizing away debug info
# that abi-dumper needs to extract complete type information from shared libraries
CFLAGS: "-g -Og -fno-eliminate-unused-debug-types"
CXXFLAGS: "-g -Og -fno-eliminate-unused-debug-types"
jobs:
abi:
runs-on: ubuntu-latest
steps:
# -------------------------------------------------------------------------
# Setup Phase: Prepare environment and install dependencies
# -------------------------------------------------------------------------
- name: Checkout PR (new)
uses: actions/checkout@v6
with:
# fetch-depth: 0 required for git worktree to access development branch
# without full history, worktree creation will fail
fetch-depth: 0
- name: Configure APT for amd64 + arm64 (ports) and update
shell: bash
run: |
set -euxo pipefail
# Detect Ubuntu codename
CODENAME="$(. /etc/os-release; echo "${VERSION_CODENAME}")"
: "${CODENAME:?Failed to read VERSION_CODENAME from /etc/os-release}"
echo "Detected Ubuntu codename: ${CODENAME}"
# 1) Enable ARM64 multiarch
sudo dpkg --add-architecture arm64
# 2) Overwrite main sources to be amd64-only (archive + security)
sudo tee /etc/apt/sources.list > /dev/null <<EOF
deb [arch=amd64] http://archive.ubuntu.com/ubuntu ${CODENAME} main restricted universe multiverse
deb [arch=amd64] http://archive.ubuntu.com/ubuntu ${CODENAME}-updates main restricted universe multiverse
deb [arch=amd64] http://archive.ubuntu.com/ubuntu ${CODENAME}-backports main restricted universe multiverse
deb [arch=amd64] http://security.ubuntu.com/ubuntu ${CODENAME}-security main restricted universe multiverse
EOF
# 3) Add Ubuntu Ports for arm64 only
sudo tee /etc/apt/sources.list.d/arm64-ports.list > /dev/null <<EOF
deb [arch=arm64] http://ports.ubuntu.com/ubuntu-ports ${CODENAME} main restricted universe multiverse
deb [arch=arm64] http://ports.ubuntu.com/ubuntu-ports ${CODENAME}-updates main restricted universe multiverse
deb [arch=arm64] http://ports.ubuntu.com/ubuntu-ports ${CODENAME}-backports main restricted universe multiverse
deb [arch=arm64] http://ports.ubuntu.com/ubuntu-ports ${CODENAME}-security main restricted universe multiverse
EOF
# 4) Remove deb822 sources that may still request arm64 from security.ubuntu.com
sudo rm -f /etc/apt/sources.list.d/ubuntu.sources || true
# 5) Clean and update indices (amd64 from archive/security; arm64 from ports)
sudo apt-get clean
sudo apt-get update
- name: Install ABI tools & build dependencies (incl. ARM64 libyaml)
shell: bash
run: |
set -euxo pipefail
sudo apt-get install -y \
abi-compliance-checker abi-dumper elfutils \
automake autoconf libtool pkg-config \
gcc-aarch64-linux-gnu g++-aarch64-linux-gnu binutils-aarch64-linux-gnu \
libyaml-dev \
libyaml-0-2:arm64 libyaml-dev:arm64 \
libbsd-dev:arm64
# Sanity checks
abi-compliance-checker -version
abi-dumper -version
# ARM64 pkg-config file for yaml must exist
ls -l /usr/include/yaml.h
ls -l /usr/lib/aarch64-linux-gnu/pkgconfig/yaml-0.1.pc
# -------------------------------------------------------------------------
# Build Phase: Compile both PR and baseline versions
# -------------------------------------------------------------------------
- name: Build PR (AArch64, with debug info)
shell: bash
env:
PKG_CONFIG_PATH: /usr/lib/aarch64-linux-gnu/pkgconfig
run: |
./gitcompile --host=aarch64-linux-gnu
ls -l src/.libs || true
- name: Prepare baseline worktree (development)
run: |
git fetch origin development:refs/remotes/origin/development
git worktree add ../baseline origin/development
- name: Build baseline (AArch64, with debug info)
working-directory: ../baseline
shell: bash
env:
PKG_CONFIG_PATH: /usr/lib/aarch64-linux-gnu/pkgconfig
run: |
./gitcompile --host=aarch64-linux-gnu
ls -l src/.libs || true
# -------------------------------------------------------------------------
# Analysis Phase: Compare ABI compatibility between versions
# -------------------------------------------------------------------------
- name: Run ABI compatibility check
shell: bash
run: |
# Setup directory structure for analysis artifacts
mkdir -p abi/{dumps,reports,headers-{baseline,pr}}
# Headers define the public API surface - abi-dumper uses these to filter
# which symbols are considered "public" vs internal implementation details
cp ../baseline/inc/{remote,rpcmem}.h abi/headers-baseline/
cp inc/{remote,rpcmem}.h abi/headers-pr/
# These are the user-facing shared libraries - internal/test libraries excluded
# to focus ABI checking on what external applications actually link against
LIBS=(libadsprpc.so libcdsprpc.so libsdsprpc.so)
FAIL=0
# Process each library for ABI compatibility
for lib in "${LIBS[@]}"; do
base_lib="../baseline/src/.libs/$lib"
pr_lib="src/.libs/$lib"
# Extract the base name of a shared library file, excluding its .so* version suffix
name="${lib%%.so*}"
if [[ -f "$base_lib" && -f "$pr_lib" ]]; then
echo "::group::Processing $lib"
# Generate ABI dumps for both versions
abi-dumper "$base_lib" -o "abi/dumps/${name}.base.dump" -lver base -public-headers "abi/headers-baseline" || FAIL=1
abi-dumper "$pr_lib" -o "abi/dumps/${name}.pr.dump" -lver pr -public-headers "abi/headers-pr" || FAIL=1
# Compare ABIs and generate compatibility report
abi-compliance-checker -l "$name" -old "abi/dumps/${name}.base.dump" -new "abi/dumps/${name}.pr.dump" -report-path "abi/reports/${name}.html" || FAIL=1
echo "::endgroup::"
else
echo "Skipping $lib (missing files)"
fi
done
# Fail the job only after processing all libraries to get complete picture
[[ $FAIL -eq 0 ]] || { echo "ABI check failed"; exit 1; }
# -------------------------------------------------------------------------
# Reporting Phase: Upload analysis results for review
# -------------------------------------------------------------------------
- name: Upload ABI reports
# if: always() ensures reports are uploaded even when ABI check fails
# - critical for debugging what specific ABI changes caused the failure
if: always()
uses: actions/upload-artifact@v7
with:
name: abi-compat-reports
path: abi/reports