Add Fortran ABI check and auto-detect the release baseline (#6550)

* Add Fortran ABI compatibility check to abi-report workflow

Mirrors the existing C/HL/C++ abi-dumper + abi-compliance-checker
steps for libhdf5_fortran.so, plus a supplementary nm-based exported
symbol diff since gfortran's mangled names don't encode argument
lists and DWARF-based diffing has not been validated against
Fortran-specific constructs (array descriptors, derived types).

* Auto-detect ABI reference release instead of hardcoding it

file_ref was pinned to '2.0.0' in both daily-build.yml and release.yml
and had gone stale across two releases (2.1.0, 2.1.1) without being
bumped, silently comparing against a two-versions-old baseline. Have
abi-report.yml query the GitHub API for the latest published
HDFGroup/hdf5 release when file_ref isn't explicitly given, so callers
no longer need to remember to update a pinned tag after every release.
Verified the resolution command returns 2.1.1 against the live API.

Also documents the expected false-positive pattern in the new Fortran
ABI check: abi-dumper misreads gfortran's DWARF encoding of
assumed-shape array descriptors as fixed array bounds, producing bulk
Low-severity noise on the KIND/RANK-generated H5_gen.F90 procedures
that isn't a real interface change.
This commit is contained in:
Scot Breitenfeld
2026-07-27 08:28:18 -05:00
committed by GitHub
parent 3340ba53d3
commit aa9df72cc2
3 changed files with 59 additions and 10 deletions
+55 -6
View File
@@ -19,9 +19,10 @@ on:
required: true
type: string
file_ref:
description: "The reference name for the release binary"
required: true
description: "The reference release tag to compare against. Leave empty to auto-detect the latest published HDFGroup/hdf5 release."
required: false
type: string
default: ''
permissions:
contents: read
@@ -38,12 +39,27 @@ jobs:
sudo apt install -q -y abi-compliance-checker abi-dumper
sudo apt install -q -y japi-compliance-checker
- name: Resolve reference release tag
id: resolve-file-ref
run: |
if [[ -n "${{ inputs.file_ref }}" ]]; then
REF="${{ inputs.file_ref }}"
else
REF=$(curl -fsSL https://api.github.com/repos/HDFGroup/hdf5/releases/latest | sed -n 's/.*"tag_name": *"\([^"]*\)".*/\1/p')
if [[ -z "$REF" ]]; then
echo "::error::Could not auto-detect the latest HDFGroup/hdf5 release tag"
exit 1
fi
fi
echo "Using reference release: $REF"
echo "FILE_REF=$REF" >> $GITHUB_OUTPUT
- name: Convert hdf5 reference name (Linux)
id: convert-hdf5lib-refname
run: |
FILE_DOTS=$(echo "${{ inputs.file_ref }}" | sed -r "s/([0-9]+)\.([0-9]+)\.([0-9]+)\.([0-9]+).*/\1\.\2\.\3-\4/")
FILE_DOTS=$(echo "${{ steps.resolve-file-ref.outputs.FILE_REF }}" | sed -r "s/([0-9]+)\.([0-9]+)\.([0-9]+)\.([0-9]+).*/\1\.\2\.\3-\4/")
echo "HDF5R_DOTS=$FILE_DOTS" >> $GITHUB_OUTPUT
FILE_DOTSMAIN=$(echo "${{ inputs.file_ref }}" | sed -r "s/([0-9]+)\.([0-9]+)\.([0-9]+).*/\1\.\2\.\3/")
FILE_DOTSMAIN=$(echo "${{ steps.resolve-file-ref.outputs.FILE_REF }}" | sed -r "s/([0-9]+)\.([0-9]+)\.([0-9]+).*/\1\.\2\.\3/")
echo "HDF5R_DOTSMAIN=$FILE_DOTSMAIN" >> $GITHUB_OUTPUT
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
@@ -84,7 +100,7 @@ jobs:
run: |
mkdir "${{ github.workspace }}/hdf5R"
cd "${{ github.workspace }}/hdf5R"
wget -q https://github.com/HDFGroup/hdf5/releases/download/${{ inputs.file_ref }}/hdf5-${{ steps.convert-hdf5lib-refname.outputs.HDF5R_DOTS }}-ubuntu-2404_gcc.tar.gz
wget -q https://github.com/HDFGroup/hdf5/releases/download/${{ steps.resolve-file-ref.outputs.FILE_REF }}/hdf5-${{ steps.convert-hdf5lib-refname.outputs.HDF5R_DOTS }}-ubuntu-2404_gcc.tar.gz
tar zxf hdf5-${{ steps.convert-hdf5lib-refname.outputs.HDF5R_DOTS }}-ubuntu-2404_gcc.tar.gz
- name: List files for the space (Linux)
@@ -94,7 +110,7 @@ jobs:
- name: Uncompress hdf5 reference binary (Linux)
run: |
cd "${{ github.workspace }}/hdf5R"
tar -zxvf ${{ github.workspace }}/hdf5R/hdf5/HDF5-${{ inputs.file_ref }}-Linux.tar.gz --strip-components 1
tar -zxvf ${{ github.workspace }}/hdf5R/hdf5/HDF5-${{ steps.resolve-file-ref.outputs.FILE_REF }}-Linux.tar.gz --strip-components 1
- name: List files for the HDFR space (Linux)
run: |
@@ -147,6 +163,35 @@ jobs:
abi-compliance-checker -l ${{ inputs.file_base }}_hl_cpp -old ABI-6.dump -new ABI-7.dump
continue-on-error: true
# NOTE ON READING THE FORTRAN REPORT: expect a large number of "Low" severity
# "Problems with Symbols" findings on the generic KIND/RANK-generated buffer
# procedures in H5_gen.F90 (h5aread_*, h5awrite_*, h5dread_*, h5dwrite_*), e.g.
# "Type of Nth parameter buf has been changed from integer(kind=K)[X] to
# integer(kind=K)[Y]". These are false positives: abi-dumper misreads gfortran's
# DWARF encoding of assumed-shape array descriptors as if the bound were a fixed
# compile-time array size, so the reported X/Y values are debug-info noise, not a
# real interface change. Real signal shows up in Added/Removed Symbols and in
# Medium/High severity findings (e.g. a module-level data size actually changing) -
# focus review there and disregard bulk Low-severity Symbol findings from H5_gen.F90.
- name: Run fortran ABI report
run: |
abi-dumper ${{ steps.set-hdf5lib-refname.outputs.HDF5R_ROOT }}/lib/libhdf5_fortran.so -o ABI-8.dump
abi-dumper ${{ steps.set-hdf5lib-name.outputs.HDF5_ROOT }}/lib/libhdf5_fortran.so -o ABI-9.dump
abi-compliance-checker -l ${{ inputs.file_base }}_fortran -old ABI-8.dump -new ABI-9.dump
continue-on-error: true
- name: Run fortran exported symbol diff
run: |
# gfortran mangled names don't encode argument lists, so abi-compliance-checker
# (DWARF-based) is the primary signal above; this is a cheap supplementary check
# that still catches added/removed exported symbols even if debug info is stripped.
nm -D --defined-only ${{ steps.set-hdf5lib-refname.outputs.HDF5R_ROOT }}/lib/libhdf5_fortran.so | awk '{print $3}' | sort > old_fortran_syms.txt
nm -D --defined-only ${{ steps.set-hdf5lib-name.outputs.HDF5_ROOT }}/lib/libhdf5_fortran.so | awk '{print $3}' | sort > new_fortran_syms.txt
diff -u old_fortran_syms.txt new_fortran_syms.txt > ${{ inputs.file_base }}-hdf5_fortran_symbol_diff.txt || true
echo "=== Fortran exported symbol diff (reference vs new) ==="
cat ${{ inputs.file_base }}-hdf5_fortran_symbol_diff.txt
continue-on-error: true
- name: Copy ABI reports
run: |
cp compat_reports/jarhdf5-/${{ steps.convert-hdf5lib-refname.outputs.HDF5R_DOTSMAIN }}_to_${{ steps.set-hdf5lib-name.outputs.HDF5_VERS }}/compat_report.html ${{ inputs.file_base }}-java_compat_report.html
@@ -158,6 +203,8 @@ jobs:
cp compat_reports/${{ inputs.file_base }}_cpp/X_to_Y/compat_report.html ${{ inputs.file_base }}-hdf5_cpp_compat_report.html
ls -l compat_reports/${{ inputs.file_base }}_hl_cpp/X_to_Y
cp compat_reports/${{ inputs.file_base }}_hl_cpp/X_to_Y/compat_report.html ${{ inputs.file_base }}-hdf5_hl_cpp_compat_report.html
ls -l compat_reports/${{ inputs.file_base }}_fortran/X_to_Y
cp compat_reports/${{ inputs.file_base }}_fortran/X_to_Y/compat_report.html ${{ inputs.file_base }}-hdf5_fortran_compat_report.html
continue-on-error: true
- name: List files for the report spaces (Linux)
@@ -173,6 +220,8 @@ jobs:
cp ${{ inputs.file_base }}-hdf5_compat_report.html ${{ runner.workspace }}/buildabi/hdf5
cp ${{ inputs.file_base }}-hdf5_hl_compat_report.html ${{ runner.workspace }}/buildabi/hdf5
cp ${{ inputs.file_base }}-hdf5_cpp_compat_report.html ${{ runner.workspace }}/buildabi/hdf5
cp ${{ inputs.file_base }}-hdf5_fortran_compat_report.html ${{ runner.workspace }}/buildabi/hdf5
cp ${{ inputs.file_base }}-hdf5_fortran_symbol_diff.txt ${{ runner.workspace }}/buildabi/hdf5
cp ${{ inputs.file_base }}-java_compat_report.html ${{ runner.workspace }}/buildabi/hdf5
cd "${{ runner.workspace }}/buildabi"
tar -zcvf ${{ inputs.file_base }}.html.abi.reports.tar.gz hdf5
+2 -2
View File
@@ -161,8 +161,8 @@ jobs:
needs: [get-old-names, call-workflow-tarball, call-workflow-ctest]
uses: ./.github/workflows/abi-report.yml
with:
# previous release version
file_ref: '2.0.0'
# file_ref intentionally omitted: abi-report.yml auto-detects the latest
# published HDFGroup/hdf5 release when it isn't given one
file_base: ${{ needs.call-workflow-tarball.outputs.file_base }}
use_tag: snapshot
use_environ: snapshots
+2 -2
View File
@@ -82,8 +82,8 @@ jobs:
needs: [log-the-inputs, call-workflow-tarball, call-workflow-ctest]
uses: ./.github/workflows/abi-report.yml
with:
# previous release version
file_ref: '2.0.0'
# file_ref intentionally omitted: abi-report.yml auto-detects the latest
# published HDFGroup/hdf5 release when it isn't given one
file_base: ${{ needs.call-workflow-tarball.outputs.file_base }}
use_tag: ${{ needs.log-the-inputs.outputs.rel_tag }}
use_environ: release