Merge branch 'staging' into release #338
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: CI | |
| env: | |
| # HDF5 version pinning. To move to a different patch on 1.12.x, bump | |
| # HDF5_VERSION and HDF5_CACHE_VERSION. To move to a different series | |
| # (e.g. 1.14.x), bump HDF5_SERIES + HDF5_VERSION + HDF5_CACHE_VERSION. | |
| # The release tarball URL follows the pattern: | |
| # https://support.hdfgroup.org/ftp/HDF5/releases/hdf5-${SERIES}/hdf5-${VERSION}/src/hdf5-${VERSION}.tar.gz | |
| HDF5_SERIES: "1.12" | |
| HDF5_VERSION: 1.12.3 | |
| HDF5_CACHE_VERSION: v5 | |
| CDASH_SUBMIT: ${{ (github.event_name == 'push' && github.ref_name == 'release') || (github.event_name == 'pull_request' && contains(github.event.pull_request.labels.*.name, 'cdash')) }} | |
| on: | |
| push: | |
| branches: [ release, staging ] | |
| pull_request: | |
| branches: [ release, staging ] | |
| workflow_dispatch: | |
| permissions: | |
| contents: write | |
| concurrency: | |
| group: ci-${{ github.ref }} | |
| cancel-in-progress: true | |
| jobs: | |
| build: | |
| name: ${{ matrix.os }} / ${{ matrix.compiler }} | |
| runs-on: ${{ matrix.os }} | |
| timeout-minutes: 45 | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| include: | |
| - os: ubuntu-22.04 | |
| compiler: gcc-13 | |
| compiler-version: 13 | |
| - os: ubuntu-22.04 | |
| compiler: clang-17 | |
| compiler-version: 17 | |
| - os: ubuntu-22.04 | |
| compiler: clang-18 | |
| compiler-version: 18 | |
| - os: ubuntu-22.04 | |
| compiler: clang-19 | |
| compiler-version: 19 | |
| - os: ubuntu-22.04 | |
| compiler: clang-20 | |
| compiler-version: 20 | |
| - os: ubuntu-24.04 | |
| compiler: gcc-13 | |
| compiler-version: 13 | |
| - os: ubuntu-24.04 | |
| compiler: gcc-14 | |
| compiler-version: 14 | |
| - os: ubuntu-24.04 | |
| compiler: clang-18 | |
| compiler-version: 18 | |
| - os: ubuntu-24.04 | |
| compiler: clang-19 | |
| compiler-version: 19 | |
| - os: ubuntu-24.04 | |
| compiler: clang-20 | |
| compiler-version: 20 | |
| - os: macos-15 | |
| compiler: apple-clang | |
| compiler-version: native | |
| - os: windows-latest | |
| compiler: msvc | |
| compiler-version: native | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v6 | |
| with: | |
| fetch-depth: 0 | |
| - name: Install system dependencies on Linux | |
| if: runner.os == 'Linux' | |
| shell: bash | |
| run: | | |
| set -euxo pipefail | |
| sudo apt-get update | |
| sudo apt-get install -y cmake ninja-build wget gnupg lsb-release software-properties-common libboost-dev | |
| # libhdf5-dev intentionally NOT installed — HDF5 is source-built | |
| # from a pinned version below for consistency across the matrix. | |
| - name: Setup compiler on Linux | |
| if: runner.os == 'Linux' | |
| shell: bash | |
| run: | | |
| set -euxo pipefail | |
| compiler="${{ matrix.compiler }}" | |
| version="${{ matrix.compiler-version }}" | |
| if [[ "$compiler" == clang-* ]]; then | |
| wget https://apt.llvm.org/llvm.sh | |
| chmod +x llvm.sh | |
| sudo ./llvm.sh "$version" all | |
| echo "CC=$(command -v clang-$version)" >> "$GITHUB_ENV" | |
| echo "CXX=$(command -v clang++-$version)" >> "$GITHUB_ENV" | |
| clang++-"$version" --version | |
| elif [[ "$compiler" == gcc-* ]]; then | |
| if ! command -v "gcc-$version" &>/dev/null; then | |
| sudo add-apt-repository ppa:ubuntu-toolchain-r/test -y | |
| for attempt in 1 2 3; do | |
| sudo apt-get update | |
| if apt-cache show "gcc-$version" >/dev/null 2>&1; then | |
| break | |
| fi | |
| if [[ $attempt -lt 3 ]]; then | |
| echo "Package gcc-$version not found after update (attempt $attempt), retrying in 30s..." | |
| sleep 30 | |
| else | |
| echo "Package gcc-$version not found in PPA after $attempt attempts" >&2 | |
| exit 1 | |
| fi | |
| done | |
| sudo apt-get install -y "gcc-$version" "g++-$version" | |
| fi | |
| echo "CC=$(command -v gcc-$version)" >> "$GITHUB_ENV" | |
| echo "CXX=$(command -v g++-$version)" >> "$GITHUB_ENV" | |
| g++-"$version" --version | |
| fi | |
| - name: Install system dependencies on macOS | |
| if: runner.os == 'macOS' | |
| shell: bash | |
| run: | | |
| set -euxo pipefail | |
| brew update | |
| brew install --quiet cmake ninja boost | |
| # hdf5 intentionally NOT installed via brew — built from source below. | |
| # Expose Boost.uBLAS headers (header-only) to downstream cmake configures. | |
| BOOST_PREFIX="$(brew --prefix boost)" | |
| echo "CMAKE_PREFIX_PATH=${BOOST_PREFIX}" >> "$GITHUB_ENV" | |
| echo "CPATH=${BOOST_PREFIX}/include:${CPATH:-}" >> "$GITHUB_ENV" | |
| # macOS uses apple-clang as the default compiler. | |
| echo "CC=clang" >> "$GITHUB_ENV" | |
| echo "CXX=clang++" >> "$GITHUB_ENV" | |
| clang++ --version | |
| - name: Install HDF5 from source (Linux/macOS, cached) | |
| if: runner.os != 'Windows' | |
| uses: ./.github/actions/install-hdf5 | |
| with: | |
| cache-key-suffix: -${{ matrix.os }}-${{ matrix.compiler }} | |
| - name: Build Windows zlib from source | |
| if: runner.os == 'Windows' | |
| shell: powershell | |
| run: | | |
| $ErrorActionPreference = "Stop" | |
| # Build zlib ourselves rather than relying on vcpkg. The vcpkg | |
| # `x64-windows` install was flaky: its ZLIBConfig.cmake referenced a | |
| # non-existent ZLIB-static.cmake, and even after sidestepping that the | |
| # linker intermittently failed to open the installed import lib. | |
| # Building from source takes ~30s, gives us a predictable layout, and | |
| # lets both HDF5 and h5cpp link against the same zlib. | |
| $zlib_version = "1.3.1" | |
| $zlib_archive = "$env:RUNNER_TEMP\zlib-$zlib_version.tar.gz" | |
| $zlib_source = "$env:RUNNER_TEMP\zlib-$zlib_version" | |
| $zlib_build = "$env:RUNNER_TEMP\zlib-build" | |
| $zlib_prefix = "$env:RUNNER_TEMP\zlib-install" | |
| Invoke-WebRequest ` | |
| -Uri "https://github.com/madler/zlib/archive/refs/tags/v$zlib_version.tar.gz" ` | |
| -OutFile $zlib_archive | |
| tar -xzf $zlib_archive -C $env:RUNNER_TEMP | |
| cmake -S $zlib_source -B $zlib_build ` | |
| -G "Visual Studio 17 2022" -A x64 ` | |
| -DCMAKE_INSTALL_PREFIX="$zlib_prefix" | |
| cmake --build $zlib_build --parallel --config Release | |
| cmake --install $zlib_build --config Release | |
| Get-ChildItem -Recurse "$zlib_prefix\lib","$zlib_prefix\include" | |
| - name: Restore HDF5 ${{ env.HDF5_VERSION }} cache | |
| if: runner.os == 'Windows' | |
| id: cache-hdf5 | |
| uses: actions/cache/restore@v5 | |
| with: | |
| path: ${{ runner.temp }}\hdf5-${{ env.HDF5_VERSION }}-install | |
| key: hdf5-${{ runner.os }}-${{ matrix.compiler }}-${{ env.HDF5_VERSION }}-${{ env.HDF5_CACHE_VERSION }} | |
| - name: Build HDF5 ${{ env.HDF5_VERSION }} from source (Windows) | |
| if: runner.os == 'Windows' && steps.cache-hdf5.outputs.cache-hit != 'true' | |
| shell: powershell | |
| run: | | |
| $ErrorActionPreference = "Stop" | |
| $hdf5_version = "${{ env.HDF5_VERSION }}" | |
| $hdf5_series = "${{ env.HDF5_SERIES }}" | |
| $hdf5_archive = "$env:RUNNER_TEMP\hdf5-$hdf5_version.tar.gz" | |
| $hdf5_source = "$env:RUNNER_TEMP\hdf5-$hdf5_version" | |
| $hdf5_build = "$env:RUNNER_TEMP\hdf5-$hdf5_version-build" | |
| $hdf5_prefix = "$env:RUNNER_TEMP\hdf5-$hdf5_version-install" | |
| Invoke-WebRequest ` | |
| -Uri "https://support.hdfgroup.org/ftp/HDF5/releases/hdf5-$hdf5_series/hdf5-$hdf5_version/src/hdf5-$hdf5_version.tar.gz" ` | |
| -OutFile $hdf5_archive | |
| tar -xzf $hdf5_archive -C $env:RUNNER_TEMP | |
| cmake -S $hdf5_source -B $hdf5_build ` | |
| -G "Visual Studio 17 2022" ` | |
| -A x64 ` | |
| -DCMAKE_INSTALL_PREFIX="$hdf5_prefix" ` | |
| -DHDF_CFG_NAME=Release ` | |
| -DBUILD_SHARED_LIBS=ON ` | |
| -DBUILD_TESTING=OFF ` | |
| -DHDF5_BUILD_TOOLS=OFF ` | |
| -DHDF5_BUILD_UTILS=OFF ` | |
| -DHDF5_BUILD_EXAMPLES=OFF ` | |
| -DHDF5_BUILD_CPP_LIB=OFF ` | |
| -DHDF5_BUILD_HL_LIB=OFF ` | |
| -DHDF5_BUILD_FORTRAN=OFF ` | |
| -DHDF5_ENABLE_DEPRECATED_SYMBOLS=OFF ` | |
| -DHDF5_ENABLE_Z_LIB_SUPPORT=ON ` | |
| -DHDF5_ENABLE_SZIP_SUPPORT=OFF ` | |
| -DZLIB_USE_EXTERNAL=OFF ` | |
| -DZLIB_INCLUDE_DIR="$env:RUNNER_TEMP/zlib-install/include" ` | |
| -DZLIB_LIBRARY="$env:RUNNER_TEMP/zlib-install/lib/zlib.lib" | |
| cmake --build $hdf5_build --parallel --config Release | |
| cmake --install $hdf5_build --config Release | |
| - name: Save HDF5 ${{ env.HDF5_VERSION }} cache | |
| if: runner.os == 'Windows' && steps.cache-hdf5.outputs.cache-hit != 'true' | |
| uses: actions/cache/save@v5 | |
| with: | |
| path: ${{ runner.temp }}\hdf5-${{ env.HDF5_VERSION }}-install | |
| key: ${{ steps.cache-hdf5.outputs.cache-primary-key }} | |
| - name: Export Windows HDF5 environment | |
| if: runner.os == 'Windows' | |
| shell: powershell | |
| run: | | |
| $ErrorActionPreference = "Stop" | |
| $hdf5_version = "${{ env.HDF5_VERSION }}" | |
| $hdf5_prefix = "$env:RUNNER_TEMP\hdf5-$hdf5_version-install" | |
| if (!(Test-Path "$hdf5_prefix")) { | |
| throw "HDF5 install prefix not found: $hdf5_prefix" | |
| } | |
| $hdf5_cmake_prefix = $hdf5_prefix -replace '\\','/' | |
| $zlib_cmake_prefix = "$env:RUNNER_TEMP\zlib-install" -replace '\\','/' | |
| "HDF5_ROOT=$hdf5_cmake_prefix" >> $env:GITHUB_ENV | |
| "CMAKE_PREFIX_PATH=$hdf5_cmake_prefix;$zlib_cmake_prefix" >> $env:GITHUB_ENV | |
| "$hdf5_prefix\bin" >> $env:GITHUB_PATH | |
| "$env:RUNNER_TEMP\zlib-install\bin" >> $env:GITHUB_PATH | |
| - name: Configure | |
| if: runner.os != 'Windows' | |
| shell: bash | |
| run: | | |
| set -euxo pipefail | |
| cmake_args=( | |
| -S . | |
| -B build | |
| -G Ninja | |
| -DCMAKE_C_COMPILER="$CC" | |
| -DCMAKE_CXX_COMPILER="$CXX" | |
| -DCMAKE_CXX_STANDARD=23 | |
| -DCMAKE_BUILD_TYPE=Release | |
| -DH5CPP_BUILD_TESTS=ON | |
| -DH5CPP_BUILD_EXAMPLES=ON | |
| ) | |
| if [[ -n "${HDF5_ROOT:-}" ]]; then | |
| cmake_args+=(-DHDF5_ROOT="$HDF5_ROOT") | |
| fi | |
| if [[ -n "${CMAKE_PREFIX_PATH:-}" ]]; then | |
| cmake_args+=(-DCMAKE_PREFIX_PATH="$CMAKE_PREFIX_PATH") | |
| fi | |
| if [[ -n "${HDF5_C_COMPILER_EXECUTABLE:-}" ]]; then | |
| cmake_args+=(-DHDF5_C_COMPILER_EXECUTABLE="$HDF5_C_COMPILER_EXECUTABLE") | |
| fi | |
| if [[ -n "${HDF5_CXX_COMPILER_EXECUTABLE:-}" ]]; then | |
| cmake_args+=(-DHDF5_CXX_COMPILER_EXECUTABLE="$HDF5_CXX_COMPILER_EXECUTABLE") | |
| fi | |
| # macOS: std::stop_token in Apple's libc++ requires deployment target >= 14.4. | |
| # The runner sets MACOSX_DEPLOYMENT_TARGET=14.0 in the environment; CMake reads | |
| # this with FORCE, overriding any CMakeLists.txt value, so we must override it | |
| # explicitly on the command line with a higher value. | |
| if [[ "$RUNNER_OS" == "macOS" ]]; then | |
| cmake_args+=(-DCMAKE_OSX_DEPLOYMENT_TARGET=14.4) | |
| fi | |
| cmake "${cmake_args[@]}" | |
| - name: Install Boost.uBLAS via vcpkg (Windows) | |
| if: runner.os == 'Windows' | |
| shell: powershell | |
| run: | | |
| # Boost.uBLAS is header-only; examples/attributes/attributes.cpp | |
| # consumes <boost/numeric/ublas/matrix.hpp>. Pre-installed vcpkg | |
| # on windows-latest has boost-ublas readily available. | |
| & "$env:VCPKG_INSTALLATION_ROOT\vcpkg.exe" install boost-ublas:x64-windows | |
| - name: Configure Windows | |
| if: runner.os == 'Windows' | |
| shell: powershell | |
| run: | | |
| # vcpkg deposits headers under | |
| # <vcpkg>/installed/x64-windows/include/boost/...; expose that path | |
| # to find_path() via CMAKE_PREFIX_PATH AND pre-seed the cache | |
| # variable directly so examples/CMakeLists.txt's | |
| # find_path(H5CPP_BOOST_CONFIG_INCLUDE_EX ...) succeeds regardless | |
| # of CMake's prefix-path search behaviour with the vcpkg toolchain. | |
| $vcpkg_prefix = "$env:VCPKG_INSTALLATION_ROOT\installed\x64-windows" -replace '\\','/' | |
| $vcpkg_include = "$vcpkg_prefix/include" | |
| $prefix_path = "$env:CMAKE_PREFIX_PATH;$vcpkg_prefix" | |
| if (-not (Test-Path "$vcpkg_include\boost\config.hpp")) { | |
| throw "vcpkg boost-ublas missing: $vcpkg_include\boost\config.hpp not present" | |
| } | |
| cmake -S . -B build ` | |
| -DCMAKE_TOOLCHAIN_FILE="$env:VCPKG_INSTALLATION_ROOT\scripts\buildsystems\vcpkg.cmake" ` | |
| -DHDF5_ROOT="$env:HDF5_ROOT" ` | |
| -DCMAKE_PREFIX_PATH="$prefix_path" ` | |
| -DH5CPP_BOOST_CONFIG_INCLUDE_EX="$vcpkg_include" ` | |
| -DCMAKE_CXX_STANDARD=23 ` | |
| -DCMAKE_BUILD_TYPE=Release ` | |
| -DH5CPP_BUILD_TESTS=ON ` | |
| -DH5CPP_BUILD_EXAMPLES=ON | |
| - name: Build | |
| run: cmake --build build --parallel --config Release | |
| - name: Test | |
| shell: bash | |
| run: | | |
| set -euxo pipefail | |
| if [ "$CDASH_SUBMIT" = "true" ]; then | |
| ctest -D Experimental --test-dir build -C Release --output-on-failure | |
| else | |
| ctest --test-dir build -C Release --output-on-failure | |
| fi | |
| env: | |
| CTEST_SITE: "github-actions" | |
| CTEST_BUILD_NAME: "${{ matrix.os }}-${{ matrix.compiler }}" | |
| - name: Record Badge Status | |
| if: always() | |
| shell: bash | |
| run: | | |
| set -euxo pipefail | |
| mkdir -p badge-status | |
| cat <<EOF > "badge-status/status-${{ matrix.os }}-${{ matrix.compiler }}.json" | |
| { | |
| "os": "${{ matrix.os }}", | |
| "compiler": "${{ matrix.compiler }}", | |
| "status": "${{ job.status }}" | |
| } | |
| EOF | |
| - name: Upload Status Artifact | |
| if: always() | |
| uses: actions/upload-artifact@v7 | |
| with: | |
| name: status-${{ matrix.os }}-${{ matrix.compiler }} | |
| path: badge-status/status-${{ matrix.os }}-${{ matrix.compiler }}.json | |
| asan: | |
| name: asan / ubuntu-24.04 / clang-20 | |
| runs-on: ubuntu-24.04 | |
| timeout-minutes: 45 | |
| concurrency: | |
| group: asan-${{ github.ref }} | |
| cancel-in-progress: true | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v6 | |
| with: | |
| fetch-depth: 0 | |
| - name: Install dependencies | |
| shell: bash | |
| run: | | |
| set -euxo pipefail | |
| sudo apt-get update | |
| sudo apt-get install -y cmake ninja-build wget gnupg lsb-release software-properties-common libboost-dev | |
| # libhdf5-dev intentionally NOT installed — source-built via the | |
| # ./.github/actions/install-hdf5 composite action below. | |
| wget https://apt.llvm.org/llvm.sh | |
| chmod +x llvm.sh | |
| sudo ./llvm.sh 20 all | |
| echo "CC=$(command -v clang-20)" >> "$GITHUB_ENV" | |
| echo "CXX=$(command -v clang++-20)" >> "$GITHUB_ENV" | |
| - name: Install HDF5 from source (cached) | |
| uses: ./.github/actions/install-hdf5 | |
| - name: Configure | |
| shell: bash | |
| run: | | |
| set -euxo pipefail | |
| cmake -S . -B build -G Ninja \ | |
| -DCMAKE_C_COMPILER="$CC" \ | |
| -DCMAKE_CXX_COMPILER="$CXX" \ | |
| -DCMAKE_CXX_STANDARD=17 \ | |
| -DCMAKE_BUILD_TYPE=Debug \ | |
| -DCMAKE_C_FLAGS="-fsanitize=address -fno-omit-frame-pointer -O1 -g" \ | |
| -DCMAKE_CXX_FLAGS="-fsanitize=address -fno-omit-frame-pointer -O1 -g" \ | |
| -DCMAKE_EXE_LINKER_FLAGS="-fsanitize=address" \ | |
| -DH5CPP_BUILD_TESTS=ON | |
| - name: Build | |
| shell: bash | |
| run: cmake --build build --parallel | |
| - name: Test | |
| shell: bash | |
| env: | |
| ASAN_OPTIONS: "detect_leaks=1:halt_on_error=1:abort_on_error=1:strict_string_checks=1" | |
| CTEST_SITE: "github-actions" | |
| CTEST_BUILD_NAME: "asan-ubuntu-24.04-clang-20" | |
| run: | | |
| if [ "$CDASH_SUBMIT" = "true" ]; then | |
| ctest -D Experimental --test-dir build --output-on-failure | |
| else | |
| ctest --test-dir build --output-on-failure | |
| fi | |
| - name: Record Badge Status | |
| if: always() | |
| shell: bash | |
| run: | | |
| set -euxo pipefail | |
| mkdir -p badge-status | |
| cat <<EOF > badge-status/status-asan.json | |
| { | |
| "os": "ubuntu-24.04", | |
| "compiler": "clang-20", | |
| "label": "ASan", | |
| "status": "${{ job.status }}" | |
| } | |
| EOF | |
| - name: Upload Status Artifact | |
| if: always() | |
| uses: actions/upload-artifact@v7 | |
| with: | |
| name: status-asan | |
| path: badge-status/status-asan.json | |
| ubsan: | |
| name: ubsan / ubuntu-24.04 / clang-20 | |
| runs-on: ubuntu-24.04 | |
| timeout-minutes: 45 | |
| concurrency: | |
| group: ubsan-${{ github.ref }} | |
| cancel-in-progress: true | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v6 | |
| with: | |
| fetch-depth: 0 | |
| - name: Install dependencies | |
| shell: bash | |
| run: | | |
| set -euxo pipefail | |
| sudo apt-get update | |
| sudo apt-get install -y cmake ninja-build wget gnupg lsb-release software-properties-common libboost-dev | |
| # libhdf5-dev intentionally NOT installed — source-built via the | |
| # ./.github/actions/install-hdf5 composite action below. | |
| wget https://apt.llvm.org/llvm.sh | |
| chmod +x llvm.sh | |
| sudo ./llvm.sh 20 all | |
| echo "CC=$(command -v clang-20)" >> "$GITHUB_ENV" | |
| echo "CXX=$(command -v clang++-20)" >> "$GITHUB_ENV" | |
| - name: Install HDF5 from source (cached) | |
| uses: ./.github/actions/install-hdf5 | |
| - name: Configure | |
| shell: bash | |
| run: | | |
| set -euxo pipefail | |
| cmake -S . -B build -G Ninja \ | |
| -DCMAKE_C_COMPILER="$CC" \ | |
| -DCMAKE_CXX_COMPILER="$CXX" \ | |
| -DCMAKE_CXX_STANDARD=17 \ | |
| -DCMAKE_BUILD_TYPE=Debug \ | |
| -DCMAKE_C_FLAGS="-fsanitize=undefined -fno-sanitize-recover=undefined -fno-omit-frame-pointer -O1 -g" \ | |
| -DCMAKE_CXX_FLAGS="-fsanitize=undefined -fno-sanitize-recover=undefined -fno-omit-frame-pointer -O1 -g" \ | |
| -DCMAKE_EXE_LINKER_FLAGS="-fsanitize=undefined" \ | |
| -DH5CPP_BUILD_TESTS=ON | |
| - name: Build | |
| shell: bash | |
| run: cmake --build build --parallel | |
| - name: Test | |
| shell: bash | |
| env: | |
| UBSAN_OPTIONS: "print_stacktrace=1:halt_on_error=1" | |
| CTEST_SITE: "github-actions" | |
| CTEST_BUILD_NAME: "ubsan-ubuntu-24.04-clang-20" | |
| run: | | |
| if [ "$CDASH_SUBMIT" = "true" ]; then | |
| ctest -D Experimental --test-dir build --output-on-failure | |
| else | |
| ctest --test-dir build --output-on-failure | |
| fi | |
| - name: Record Badge Status | |
| if: always() | |
| shell: bash | |
| run: | | |
| set -euxo pipefail | |
| mkdir -p badge-status | |
| cat <<EOF > badge-status/status-ubsan.json | |
| { | |
| "os": "ubuntu-24.04", | |
| "compiler": "clang-20", | |
| "label": "UBSan", | |
| "status": "${{ job.status }}" | |
| } | |
| EOF | |
| - name: Upload Status Artifact | |
| if: always() | |
| uses: actions/upload-artifact@v7 | |
| with: | |
| name: status-ubsan | |
| path: badge-status/status-ubsan.json | |
| tsan: | |
| name: tsan / ubuntu-24.04 / clang-20 | |
| runs-on: ubuntu-24.04 | |
| timeout-minutes: 45 | |
| concurrency: | |
| group: tsan-${{ github.ref }} | |
| cancel-in-progress: true | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v6 | |
| with: | |
| fetch-depth: 0 | |
| - name: Install dependencies | |
| shell: bash | |
| run: | | |
| set -euxo pipefail | |
| sudo apt-get update | |
| sudo apt-get install -y cmake ninja-build wget gnupg lsb-release software-properties-common libboost-dev | |
| # libhdf5-dev intentionally NOT installed — source-built via the | |
| # ./.github/actions/install-hdf5 composite action below. | |
| wget https://apt.llvm.org/llvm.sh | |
| chmod +x llvm.sh | |
| sudo ./llvm.sh 20 all | |
| echo "CC=$(command -v clang-20)" >> "$GITHUB_ENV" | |
| echo "CXX=$(command -v clang++-20)" >> "$GITHUB_ENV" | |
| - name: Install HDF5 from source (cached) | |
| uses: ./.github/actions/install-hdf5 | |
| - name: Configure | |
| shell: bash | |
| run: | | |
| set -euxo pipefail | |
| cmake -S . -B build -G Ninja \ | |
| -DCMAKE_C_COMPILER="$CC" \ | |
| -DCMAKE_CXX_COMPILER="$CXX" \ | |
| -DCMAKE_CXX_STANDARD=17 \ | |
| -DCMAKE_BUILD_TYPE=Debug \ | |
| -DCMAKE_C_FLAGS="-fsanitize=thread -fno-omit-frame-pointer -O1 -g" \ | |
| -DCMAKE_CXX_FLAGS="-fsanitize=thread -fno-omit-frame-pointer -O1 -g" \ | |
| -DCMAKE_EXE_LINKER_FLAGS="-fsanitize=thread" \ | |
| -DH5CPP_BUILD_TESTS=ON | |
| - name: Build | |
| shell: bash | |
| run: cmake --build build --parallel | |
| - name: Test | |
| shell: bash | |
| env: | |
| # halt_on_error=1: TSAN exits on the first data race so CI fails loud. | |
| # second_deadlock_stack=1: print full stack of the lock that completed | |
| # the cycle (default prints only one stack for the offending pair). | |
| TSAN_OPTIONS: "halt_on_error=1:second_deadlock_stack=1" | |
| CTEST_SITE: "github-actions" | |
| CTEST_BUILD_NAME: "tsan-ubuntu-24.04-clang-20" | |
| run: | | |
| if [ "$CDASH_SUBMIT" = "true" ]; then | |
| ctest -D Experimental --test-dir build --output-on-failure | |
| else | |
| ctest --test-dir build --output-on-failure | |
| fi | |
| - name: Record Badge Status | |
| if: always() | |
| shell: bash | |
| run: | | |
| set -euxo pipefail | |
| mkdir -p badge-status | |
| cat <<EOF > badge-status/status-tsan.json | |
| { | |
| "os": "ubuntu-24.04", | |
| "compiler": "clang-20", | |
| "label": "TSan", | |
| "status": "${{ job.status }}" | |
| } | |
| EOF | |
| - name: Upload Status Artifact | |
| if: always() | |
| uses: actions/upload-artifact@v7 | |
| with: | |
| name: status-tsan | |
| path: badge-status/status-tsan.json | |
| badge: | |
| name: Generate SVG Badges | |
| if: always() | |
| needs: [build, asan, ubsan, tsan] | |
| runs-on: ubuntu-24.04 | |
| steps: | |
| - name: Install badge tools | |
| shell: bash | |
| run: | | |
| set -euxo pipefail | |
| sudo apt-get update | |
| sudo apt-get install -y jq curl | |
| - name: Download all status artifacts | |
| uses: actions/download-artifact@v8 | |
| with: | |
| path: badge-status | |
| pattern: status-* | |
| merge-multiple: true | |
| - name: Generate SVG Badges | |
| shell: bash | |
| run: | | |
| set -euxo pipefail | |
| ref_name="${GITHUB_REF_NAME:-}" | |
| if [[ "$ref_name" == "staging" ]]; then | |
| badge_dir="badges-staging" | |
| else | |
| badge_dir="badges" | |
| fi | |
| mkdir -p "$badge_dir" | |
| na_badge="$badge_dir/na.svg" | |
| na_url="https://img.shields.io/badge/na-%E2%97%8B-gray.svg" | |
| if [[ ! -f "$na_badge" ]]; then | |
| echo "$na_url -> $na_badge" | |
| curl -fsSL "$na_url" -o "$na_badge" | |
| fi | |
| for status_file in badge-status/*.json; do | |
| os=$(jq -r '.os' "$status_file") | |
| compiler=$(jq -r '.compiler' "$status_file") | |
| status=$(jq -r '.status' "$status_file") | |
| custom_label=$(jq -r '.label // ""' "$status_file") | |
| prefix="unknown" | |
| symbol="%3F" | |
| color="lightgrey" | |
| case "$status" in | |
| success) | |
| prefix="ok" | |
| symbol="%E2%9C%94" | |
| color="green" | |
| ;; | |
| failure) | |
| prefix="failed" | |
| symbol="%E2%9C%98" | |
| color="red" | |
| ;; | |
| cancelled) | |
| prefix="cancelled" | |
| symbol="%E2%97%87" | |
| color="yellow" | |
| ;; | |
| skipped) | |
| prefix="na" | |
| symbol="%E2%97%8B" | |
| color="gray" | |
| ;; | |
| esac | |
| if [[ -n "$custom_label" ]]; then | |
| badge_name="${custom_label,,}" | |
| url="https://img.shields.io/badge/${custom_label}-${symbol}-${color}.svg" | |
| else | |
| badge_name="${os}-${compiler}" | |
| url="https://img.shields.io/badge/${prefix}-${symbol}-${color}.svg" | |
| fi | |
| badge="$badge_dir/${badge_name}.svg" | |
| echo "$url -> $badge" | |
| curl -fsSL "$url" -o "$badge" | |
| done | |
| - name: Upload badges artifact | |
| if: always() | |
| uses: actions/upload-artifact@v7 | |
| with: | |
| name: ${{ github.ref_name == 'staging' && 'badges-staging' || 'badges' }} | |
| path: ${{ github.ref_name == 'staging' && 'badges-staging' || 'badges' }} | |
| - name: Deploy badges to GitHub Pages | |
| if: github.event_name == 'push' | |
| uses: peaceiris/actions-gh-pages@v4 | |
| with: | |
| github_token: ${{ secrets.GITHUB_TOKEN }} | |
| publish_dir: ./${{ github.ref_name == 'staging' && 'badges-staging' || 'badges' }} | |
| destination_dir: ${{ github.ref_name == 'staging' && 'badges-staging' || 'badges' }} | |
| keep_files: true # prevents wiping the other branch's folder on every deploy | |
| coverage: | |
| name: coverage / ubuntu-24.04 / gcc-14 | |
| runs-on: ubuntu-24.04 | |
| timeout-minutes: 45 | |
| env: | |
| CC: gcc-14 | |
| CXX: g++-14 | |
| GCOV: gcov-14 | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v6 | |
| with: | |
| fetch-depth: 0 | |
| - name: Install dependencies | |
| shell: bash | |
| run: | | |
| set -euxo pipefail | |
| sudo apt-get update | |
| sudo apt-get install -y \ | |
| cmake \ | |
| ninja-build \ | |
| gcc-14 \ | |
| g++-14 \ | |
| lcov \ | |
| libboost-dev | |
| # libhdf5-dev intentionally NOT installed — source-built via the | |
| # ./.github/actions/install-hdf5 composite action below. | |
| - name: Install HDF5 from source (cached) | |
| uses: ./.github/actions/install-hdf5 | |
| - name: Clean and configure | |
| shell: bash | |
| run: | | |
| set -euxo pipefail | |
| rm -rf build coverage*.info | |
| cmake -S . -B build -G Ninja \ | |
| -DCMAKE_BUILD_TYPE=Debug \ | |
| -DCMAKE_CXX_STANDARD=20 \ | |
| -DCMAKE_C_COMPILER=gcc-14 \ | |
| -DCMAKE_CXX_COMPILER=g++-14 \ | |
| -DCMAKE_C_FLAGS="--coverage -fprofile-update=atomic -O0 -g" \ | |
| -DCMAKE_CXX_FLAGS="--coverage -fprofile-update=atomic -O0 -g" \ | |
| -DH5CPP_BUILD_TESTS=ON \ | |
| -DH5CPP_BUILD_EXAMPLES=ON | |
| - name: Build | |
| shell: bash | |
| run: | | |
| set -euxo pipefail | |
| cmake --build build --parallel | |
| - name: Test | |
| shell: bash | |
| env: | |
| CTEST_SITE: "github-actions" | |
| CTEST_BUILD_NAME: "coverage-ubuntu-24.04-gcc-14" | |
| run: | | |
| set -euxo pipefail | |
| if [ "$CDASH_SUBMIT" = "true" ]; then | |
| ctest -D Experimental --test-dir build --output-on-failure --parallel | |
| else | |
| ctest --test-dir build --output-on-failure --parallel | |
| fi | |
| - name: Capture coverage | |
| shell: bash | |
| run: | | |
| set -euxo pipefail | |
| lcov \ | |
| --gcov-tool /usr/bin/gcov-14 \ | |
| --rc geninfo_unexecuted_blocks=1 \ | |
| --ignore-errors mismatch,inconsistent \ | |
| --no-function-coverage \ | |
| --directory build \ | |
| --capture \ | |
| --output-file coverage.full.info | |
| lcov \ | |
| --gcov-tool /usr/bin/gcov-14 \ | |
| --remove coverage.full.info \ | |
| '/usr/*' \ | |
| '*/test/*' \ | |
| '*/thirdparty/*' \ | |
| '*/examples/*' \ | |
| --ignore-errors unused,mismatch,inconsistent \ | |
| --output-file coverage.info | |
| rm coverage.full.info | |
| lcov --gcov-tool /usr/bin/gcov-14 --list coverage.info | |
| - name: Upload coverage reports to Codecov | |
| uses: codecov/codecov-action@v6 | |
| with: | |
| files: ./coverage.info | |
| disable_search: true | |
| fail_ci_if_error: true | |
| disable_telem: true | |
| env: | |
| CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} |