From 06254caaffee6720c7797bad356f9347ea6fd636 Mon Sep 17 00:00:00 2001 From: Kamron Batman <3953314+kamronbatman@users.noreply.github.com> Date: Fri, 7 Aug 2026 14:30:00 -0700 Subject: [PATCH] ci: stop installing libicu-dev, and prove the -dev packages are unnecessary The dnf job already installed runtime packages only, with a comment explaining that installing -dev would mask what the binding packages probe for. The apt job then installed libicu-dev, which does exactly that: it ships the unversioned libicuuc.so symlink, so every probe succeeded on the first attempt and the versioned-SONAME fallback this PR depends on was never exercised. libicu-dev was there because ICU's runtime package carries the ABI version in its name and has no stable alias. Matching by pattern is version-independent without the headers or the symlink, verified to resolve exactly one package on jammy (70), bookworm (72), noble (74) and trixie (76). Add an assertion that the unversioned symlinks are absent. Without it the suite silently stops testing anything the moment a base image starts shipping one. Verified against all eight matrix distributions: none ship them, and the step fails as intended when a symlink is planted. Also add tzdata to the dnf job to match apt, now that it is a checked prerequisite. --- .github/workflows/build-test.yml | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build-test.yml b/.github/workflows/build-test.yml index 359efdcfc..eb74c39a4 100644 --- a/.github/workflows/build-test.yml +++ b/.github/workflows/build-test.yml @@ -128,11 +128,32 @@ jobs: # unversioned .so symlink and mask the very thing the binding packages now probe for, so a # regression in versioned-SONAME resolution would sail through CI. - name: Install Prerequisites using dnf - run: dnf makecache --refresh && dnf install -y findutils libicu libdeflate libargon2 + run: dnf makecache --refresh && dnf install -y findutils libicu libdeflate libargon2 tzdata if: ${{ matrix.packageManager == 'dnf' }} + # ICU's runtime package carries the ABI version in its name (libicu70 on jammy, libicu76 on + # trixie) and has no stable alias, so match it by pattern. libicu-dev was the old way to stay + # version-independent, but it drags in the unversioned symlink and defeats the check below. - name: Install Prerequisites using apt - run: apt-get update -y && apt-get install -y curl libicu-dev libdeflate0 libargon2-1 tzdata + run: apt-get update -y && apt-get install -y curl '^libicu[0-9]+$' libdeflate0 libargon2-1 tzdata if: ${{ matrix.packageManager == 'apt' }} + # Versioned-SONAME resolution is only under test while the unversioned symlink is absent. If a + # base image or a package ever starts shipping it, every probe would succeed on the first try + # and a regression in the fallback would sail through CI, so fail loudly instead of silently + # testing nothing. + - name: Assert the unversioned .so symlinks are absent + run: | + found="" + for lib in libicuuc libicui18n libdeflate libargon2; do + hit=$(ls /usr/lib/*/"$lib".so /usr/lib64/"$lib".so 2>/dev/null || true) + if [ -n "$hit" ]; then + found="$found $hit" + fi + done + if [ -n "$found" ]; then + echo "::error::Unversioned symlinks present, so CI is no longer exercising versioned SONAME resolution:$found" + exit 1 + fi + echo "No unversioned symlinks present; versioned SONAME resolution is under test." - uses: actions/checkout@v7 with: fetch-depth: 0 # avoid shallow clone so nbgv can do its work.