Skip to content

COMP: Widen CI coverage across platforms, linkage, and configurations - #77

Merged
hjmjohnson merged 3 commits into
masterfrom
ci/widen-coverage
Sep 21, 2026
Merged

hjmjohnson merged 3 commits into
masterfrom
ci/widen-coverage

Conversation

@hjmjohnson

Copy link
Copy Markdown
Member

Widens CI across the axes that change what is compiled, and fixes the Build and Test workflow, which has never run on this repository.

build.yml triggers on branch main; this repository's branch is master. Its last 40 runs on master are 40 of 40 CMake on multiple platforms and zero Build and Test. Valgrind, AddressSanitizer, UndefinedBehaviorSanitizer, scan-build, gcov coverage, and the only shared-library configuration have all been unexercised. Two lines fix it. (It appeared to work on #57 and #59 only because a pull_request event takes the workflow from the PR's merge ref, and #57 edits the trigger — so it ran against itself.)

Per-PR matrix goes 8 -> 16 jobs. Verified on Ubuntu 24.04 with GCC 13.3.0, the compiler the Linux runners use:

Configuration Result
shared, Release, FSLSTYLE=OFF 345/345 — install_linking passed
static, Debug, FSLSTYLE=ON 344/344, no assertion aborts
minimal (znzlib + niftilib) configures and builds
CMake 3.28.3 344/344
Why these axes, and why the macOS gcc legs are gone

shared — BUILD_SHARED_LIBS gates TEST_INSTALL, so the ON legs are the first ever to run install_linking. The install and export path (install_nifti_target, the generated NIFTIConfig.cmake, and the find_package(NIFTI ... CONFIG REQUIRED) in real_easy/stand_alone_app/) has not been covered by any pull request until now. Measured: TEST_INSTALL:BOOL=ON with shared libraries and an empty package prefix, which is exactly what the comment at CMakeLists.txt:118 documents.

fslstyle — -DFSLSTYLE is not additive. It forces FSLSTYLE_NAME_CONFLICTS, FSLSTYLE_PIGZ_SUPPORT, and FSLSTYLE_REJECT_COMPLEX on (CMakeLists.txt:63-67), which become the global definitions -DFSLSTYLE -DPIGZ -DREJECT_COMPLEX (:69-77) and therefore reach niftilib/nifti1_io.c and nifti2/nifti2_io.c, not only fsliolib. At nifti1_io.c:5569 one of them sits on an #else that changes the pixdim[0] value written to disk. Neither setting subsumes the other, so both are real configurations. This replaces the previous default/all axis, which conflated the behaviour defines with the optional libraries; the libraries are additive and are now simply always built.

build_type — one static Debug leg. Debug is what makes assert() live, and the library has eight live assert() sites (nifti1_io.c 2112/2122/2132, nifti2_io.c 2781/2791/2801, fslio.c:2055, afni_xml_io.c:525). Nothing had ever built this project with CMAKE_BUILD_TYPE=Debug. None of them fire on the current suite.

macOS gcc legs dropped — /usr/bin/gcc on the macOS runners reports AppleClang, so those two jobs duplicated the macos clang legs exactly. Removing them pays for part of the new coverage.

The three new jobs

minimal builds znzlib and niftilib alone, with applications off. That is what a downstream project vendoring only the core reader selects, and nothing else in the matrix proves the tree still configures that way. It registers no tests, hence --no-tests=ignore; the value is that it configures and builds.

oldest-cmake runs on ubuntu-24.04 against the distro CMake 3.28.3 and guards cmake_minimum_required. PR #30 was a hard configure failure on exactly that version, invisible to every runner because they all carry CMake >= 3.30. Confirmed green against the real 3.28.3 binary.

exported-symbols diffs the dynamic symbol set against cmake/exported_symbols_linux.txt via cmake/collect_exported_symbols.sh. An intended ABI change updates the baseline in the same commit, which puts it in front of a reviewer instead of letting it land silently.

What the symbol baseline turned up

448 symbols across six libraries — 137 libnifti2, 104 libniftiio, 89 libnifticdf, 79 libfslio, 31 libcifti, 8 libznz. 448 is the number several open linkage changes assert in their descriptions; nothing could check it until now.

100 symbol names are exported by more than one library. libniftiio.so and libnifti2.so both define nifti_fileexists, nifti_findhdrname, nifti_add_extension, nifti_copy_nim_info, disp_nifti_1_header, and 95 others. Under ELF an application linking both resolves to whichever comes first by link order. This job holds the situation steady; it does not fix it, and the duplication deserves its own look.

SOVERSION is applied inconsistently. libniftiio, libnifti2, libnifticdf, and libznz carry versioned sonames; libcifti and libfslio are plain .so. Packagers and ldconfig treat the two groups differently. Noted, not addressed here.

How this was tested, and what is still uncovered

Tested on a native Ubuntu 24.04 host with GCC 13.3.0 — the same compiler version the Linux runners report — rather than through act, whose runner image omits cmake. Each job's commands were run directly. act itself validated checkout, matrix expansion, and step sequencing.

ctest --no-tests=ignore was confirmed to exit 0 under both CMake 3.28.3 and 4.2.1, since the default for "no tests found" has moved between releases.

Still not covered, and deliberately out of scope here: Windows and MSVC (no job exists anywhere, so the /W3 branch of the warning set compiles nowhere), 32-bit, and big-endian. Also worth a follow-up: the test-data FetchContent download dominates configure time and is now paid by 13 build jobs, so an actions/cache step keyed on the tarball hash would pay for itself quickly.

Run the Build and Test workflow on this repository's branch. Its
trigger named "main" while the branch is "master", so it had never
executed on master and did not execute on pull requests; valgrind,
AddressSanitizer, UndefinedBehaviorSanitizer, scan-build, gcov
coverage, and the only shared-library configuration were all
unexercised. Also move its macOS entry off the retired macos-11 image.

Restructure the per-PR matrix around the axes that change what is
compiled:

  shared     BUILD_SHARED_LIBS gates TEST_INSTALL, so the ON legs are
             the first to run install_linking and cover the install
             and export path.
  fslstyle   -DFSLSTYLE is not additive.  It rewrites behaviour in
             niftilib and nifti2 through global -DFSLSTYLE, -DPIGZ and
             -DREJECT_COMPLEX, and one site has an #else that changes
             the pixdim[0] value written to disk.  Neither value
             subsumes the other.
  build_type One static Debug leg, which is what makes assert() live.

Drop both macos gcc legs: /usr/bin/gcc there is a clang shim reporting
AppleClang, so they duplicated the macos clang legs exactly. The
optional libraries are built everywhere rather than forming an axis,
since they are additive.

Add three jobs. The minimal configuration builds znzlib and niftilib
alone, which is what a downstream project vendoring the core reader
selects and which nothing else configures. The oldest supported CMake
job guards cmake_minimum_required, invisible to runners that all carry
a recent CMake. The exported symbol baseline diffs the dynamic symbol
set against a committed file, so a change to the ABI has to be updated
in the same commit rather than landing unnoticed.

Verified on Ubuntu 24.04 with GCC 13.3.0, the compiler the Linux
runners use:

  shared, Release, FSLSTYLE=OFF   345/345, install_linking passed
  static, Debug,   FSLSTYLE=ON    344/344, no assertion aborts
  minimal                          configures and builds, no tests
  CMake 3.28.3                     344/344

The baseline holds 448 symbols across six libraries, which is the
figure the linkage changes have been asserting without a way to check
it.

The workflow steps were exercised by running them directly in the
runner container image rather than through act, whose image omits
cmake.
The dashboard script restates the CTestConfig.cmake settings because
CTest's delayed initialization does not pick them up, and the restated
copy had drifted from the original.

Submit over https rather than http. my.cdash.org serves plain http
without redirecting, so submissions were going unencrypted.

Use the 00:00:00 EST nightly start time that CTestConfig.cmake
declares, rather than 01:00:00 UTC. The two differ by four hours, so
nightly builds were filed under the wrong day on the dashboard.
The 2025 conversion to GitHub Actions replaced .travis.yml with two
workflows but left the dashboard script untouched, so it still
required a Travis environment. The workflow that drives it named the
wrong branch and never ran, which is why nothing surfaced the
mismatch.

Rename travis_dashboard.cmake to github_dashboard.cmake and take its
inputs from the runner that actually exists. CTEST_SITE now comes from
RUNNER_OS rather than the required TRAVIS_APP_HOST, whose absence
aborted the script before it configured anything, and the build name
carries RUNNER_OS in place of TRAVIS_OS_NAME.

Compare the branch name against its value rather than against the
literal string "ENV{BUILD_SOURCEBRANCHNAME}", so the Continuous and
Nightly models can be selected at all, and give the workflow a branch
name on push events as well as on pull requests.

Apply the same corrections to local_dashboard.cmake.
@hjmjohnson
hjmjohnson marked this pull request as ready for review September 21, 2026 18:54
@hjmjohnson
hjmjohnson merged commit 998e04e into master Sep 21, 2026
16 of 21 checks passed
@hjmjohnson
hjmjohnson deleted the ci/widen-coverage branch September 21, 2026 18:54
@hjmjohnson

Copy link
Copy Markdown
Member Author

The commit messages in this range were rewritten to remove trailers that do not belong in permanent history: Co-Authored-By: naming an AI tool, and Claude-Session: URLs that resolve for nobody. Only messages changed — the tree at the tip of master is byte-identical, and author, committer, and dates are preserved.

This PR's commits on the rewritten master:

  • 77b7418963 COMP: Widen CI coverage across platforms, linkage, and configurations
  • 063e83833f COMP: Submit dashboard results over https, at the documented start time
  • f578e03b8d COMP: Finish the migration from Travis to GitHub Actions

The SHA recorded above by GitHub is from the pre-rewrite history and no longer resolves.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant