Skip to content

Commit c35865b

Browse files
committed
Add an ABI check for the last tag of the previous release
The 3.18.0 ABI issue came up as we didn't have an ABI check to the last previous release. The supressions file needs to compare to the previous version is also used for the existing ABI check - will reduce false positives. This will fail ABI checks against libfuse-3.18.0, as some symbols in 3.18.0 were marked as the wrong version. Signed-off-by: Bernd Schubert <bernd@bsbernd.com> (cherry picked from commit fef7822)
1 parent 98f94e0 commit c35865b

4 files changed

Lines changed: 185 additions & 3 deletions

File tree

.github/workflows/abicheck.yml

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,8 @@ jobs:
5959
- name: Run abidiff
6060
run: abidiff
6161
--no-added-syms
62-
--headers-dir1 previous/include/
63-
--headers-dir2 current/include/
64-
previous/build/lib/libfuse3.so
62+
--suppressions current/.github/workflows/abidiff_suppressions.abignore
63+
--headers-dir1 previous/include/
64+
--headers-dir2 current/include/
65+
previous/build/lib/libfuse3.so
6566
current/build/lib/libfuse3.so
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
---
2+
name: 'libfuse ABI check against previous major release'
3+
4+
on:
5+
push:
6+
branches:
7+
- master
8+
- 'fuse-[0-9]+.[0-9]+*' # This will match branches like 3.17, 3.18, 4.0, etc.
9+
pull_request:
10+
branches:
11+
- master
12+
- 'fuse-[0-9]+.[0-9]+*'
13+
permissions:
14+
contents: read
15+
16+
jobs:
17+
abi:
18+
runs-on: '${{ matrix.os }}'
19+
strategy:
20+
matrix:
21+
os:
22+
- ubuntu-latest
23+
24+
steps:
25+
- name: Install dependencies (Ubuntu)
26+
if: runner.os == 'Linux'
27+
run: |
28+
sudo apt-get update
29+
sudo apt-get -y install abigail-tools clang gcc liburing-dev libnuma-dev
30+
31+
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
32+
with:
33+
path: current
34+
fetch-depth: 0 # Fetch all history and tags
35+
36+
- name: Determine previous major release tag
37+
id: prev_release
38+
run: |
39+
cd current
40+
chmod +x .github/workflows/find_previous_release_tag.sh
41+
PREV_TAG=$(.github/workflows/find_previous_release_tag.sh)
42+
echo "prev_tag=$PREV_TAG" >> $GITHUB_OUTPUT
43+
44+
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
45+
with:
46+
path: previous
47+
ref: ${{ steps.prev_release.outputs.prev_tag }}
48+
49+
- uses: actions/setup-python@e797f83bcb11b83ae66e0230d6156d7c80228e7c # v6.0.0
50+
with:
51+
python-version: '3.12'
52+
53+
- name: Build current
54+
working-directory: current
55+
run: |
56+
pip install -r requirements.txt
57+
meson setup build --buildtype=debug
58+
meson compile -C build
59+
60+
- name: Build previous
61+
working-directory: previous
62+
run: |
63+
echo "Previous release tag: ${{ steps.prev_release.outputs.prev_tag }}"
64+
echo "Commit-id of previous release: $(git show HEAD)"
65+
pip install -r requirements.txt
66+
meson setup build --buildtype=debug
67+
meson compile -C build
68+
69+
- name: Run abidiff
70+
run: abidiff
71+
--no-added-syms
72+
--suppressions current/.github/workflows/abidiff_suppressions.abignore
73+
--headers-dir1 previous/include/
74+
--headers-dir2 current/include/
75+
previous/build/lib/libfuse3.so
76+
current/build/lib/libfuse3.so
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
# Suppression file for abidiff false positives in libfuse
2+
# This file suppresses ABI changes that are actually compatible but flagged by abidiff
3+
4+
[suppress_type]
5+
# Suppress the fuse_conn_info reserved array transformation
6+
# This change is ABI-compatible: uint32_t[16] -> uint16_t request_timeout + uint16_t[31]
7+
# Both use exactly 64 bytes (16*4 = 32*2 = 64 bytes)
8+
name = fuse_conn_info
9+
# Suppress changes to the reserved field that are size/offset related
10+
change_kind = size-or-offset-change
11+
has_data_member_inserted_at = offset_in_bits(512)
12+
13+
[suppress_type]
14+
# Also suppress the general struct size change for fuse_conn_info
15+
# since the total size remains the same (128 bytes) by a static assertion
16+
# in the code
17+
name = fuse_conn_info
18+
change_kind = size-change
19+
20+
[suppress_type]
21+
# Suppress ALL changes to fuse_operations struct
22+
# These are backward compatible due to the op_size mechanism in fuse_main()
23+
# Applications pass sizeof(struct fuse_operations) at compile time,
24+
# and the library uses memcpy(&fs->op, op, op_size) to safely copy only
25+
# the fields the application knows about. New fields remain NULL.
26+
name = fuse_operations
27+
has_data_member_inserted_at = end
28+
has_size_change = yes
29+
30+
[suppress_type]
31+
# Suppress ALL changes to fuse_lowlevel_ops struct
32+
# These are backward compatible due to the op_size mechanism in fuse_session_new()
33+
# Same pattern as fuse_operations - op_size controls safe copying
34+
name = fuse_lowlevel_ops
35+
has_data_member_inserted_at = end
36+
has_size_change = yes
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
#!/bin/bash
2+
3+
set -e
4+
5+
# Script to find the previous major release tag for libfuse
6+
# Usage: ./find_previous_release_tag.sh
7+
8+
# Get current version from meson.build
9+
# Pattern matches: version : "3.18.0" or version: '3.18.0'
10+
VERSION_PATTERN="version\s*:\s*['\"]"
11+
VERSION_EXTRACT="s/.*version\s*:\s*['\"]([^'\"]+)['\"].*/\1/"
12+
13+
CURRENT_VERSION=$(grep -E "$VERSION_PATTERN" meson.build | \
14+
sed -E "$VERSION_EXTRACT")
15+
echo "Current version: $CURRENT_VERSION" >&2
16+
17+
# Extract major.minor version (e.g., 3.18 from 3.18.0)
18+
# Pattern captures first two numbers separated by dot
19+
MAJOR_MINOR_PATTERN='s/^([0-9]+\.[0-9]+).*/\1/'
20+
21+
CURRENT_MAJOR_MINOR=$(echo "$CURRENT_VERSION" | \
22+
sed -E "$MAJOR_MINOR_PATTERN")
23+
echo "Current major.minor: $CURRENT_MAJOR_MINOR" >&2
24+
25+
# Get all major.minor versions from tags, sort them, and find the one before
26+
# current
27+
# Pattern matches tags like: fuse-3.17.0, fuse-3.18.1, etc.
28+
FUSE_TAG_PATTERN="^fuse-[0-9]+\.[0-9]+"
29+
# Pattern extracts major.minor from version strings
30+
TAG_MAJOR_MINOR_PATTERN='s/^([0-9]+\.[0-9]+).*/\1/'
31+
32+
ALL_MAJOR_MINOR=$(git tag --list | \
33+
grep -E "$FUSE_TAG_PATTERN" | \
34+
sed 's/fuse-//' | \
35+
sed -E "$TAG_MAJOR_MINOR_PATTERN" | \
36+
sort -V -u)
37+
echo "All major.minor versions found:" >&2
38+
echo "$ALL_MAJOR_MINOR" >&2
39+
40+
# Find the previous major.minor version
41+
PREV_MAJOR_MINOR=$(echo "$ALL_MAJOR_MINOR" | \
42+
grep -B1 "^${CURRENT_MAJOR_MINOR}$" | \
43+
head -1)
44+
45+
if [ -z "$PREV_MAJOR_MINOR" ] || [ "$PREV_MAJOR_MINOR" = "$CURRENT_MAJOR_MINOR" ]; then
46+
echo "Error: No previous major.minor version found before $CURRENT_MAJOR_MINOR" >&2
47+
exit 1
48+
fi
49+
50+
echo "Previous major.minor: $PREV_MAJOR_MINOR" >&2
51+
52+
# Get the latest tag for the previous major.minor version
53+
# Pattern matches tags like: fuse-3.17.0, fuse-3.17.1, fuse-3.17.2, etc.
54+
PREV_TAG_PATTERN="^fuse-${PREV_MAJOR_MINOR}\.[0-9]+"
55+
56+
PREV_TAG=$(git tag --list | \
57+
grep -E "$PREV_TAG_PATTERN" | \
58+
sort -V | \
59+
tail -1)
60+
61+
if [ -z "$PREV_TAG" ]; then
62+
echo "Error: No previous major release tag found for version $PREV_MAJOR_MINOR" >&2
63+
exit 1
64+
fi
65+
66+
echo "Previous release tag: $PREV_TAG" >&2
67+
68+
# Output the tag to stdout (this is what the workflow will capture)
69+
echo "$PREV_TAG"

0 commit comments

Comments
 (0)