Skip to content

CI: Extend msvc pipeline runs #1382

CI: Extend msvc pipeline runs

CI: Extend msvc pipeline runs #1382

Workflow file for this run

# Copyright Dominic (DNKpp) Koepke 2024 - 2025.
# Distributed under the Boost Software License, Version 1.0.
# (See accompanying file LICENSE_1_0.txt or copy at
# https://www.boost.org/LICENSE_1_0.txt)
name: build & test
on:
push:
branches: [ main, development ]
paths-ignore:
- 'README.md'
- 'docs/**'
pull_request:
branches: [ main, development ]
paths-ignore:
- 'README.md'
- 'docs/**'
env:
CTEST_OPTIONS: --output-on-failure --schedule-random --no-tests=error --parallel
jobs:
############
#
# Defines the compiler configurations for the other jobs.
#
#####
generate-base-matrix:
runs-on: ubuntu-latest
outputs:
architectures: ${{ steps.output-options.outputs.architectures }}
build_modes: ${{ steps.output-options.outputs.build_modes }}
cxx_versions: ${{ steps.output-options.outputs.cxx_versions }}
steps:
# enables debug-mode, c++20 and 64bit for all cases
- name: Enable base matrix
shell: bash
run: |
echo "ARCHITECTURES=\"64bit\"" >> $GITHUB_ENV
echo "BUILD_MODES=\"Debug\"" >> $GITHUB_ENV
echo "CXX_VERSIONS=20" >> $GITHUB_ENV
# if it's a PR from development or the main branch in general, add release-mode, c++23 and 32bit
- name: Enable extended matrix
if: ${{
(github.event_name == 'pull_request' && github.head_ref == 'development')
|| github.ref_name == 'main'
}}
shell: bash
run: |
echo "ARCHITECTURES=$(echo ${ARCHITECTURES}, \"32bit\")" >> $GITHUB_ENV
echo "BUILD_MODES=$(echo ${BUILD_MODES}, \"Release\")" >> $GITHUB_ENV
echo "CXX_VERSIONS=$(echo ${CXX_VERSIONS}, 23)" >> $GITHUB_ENV
- name: Output architectures, build-modes and c++-versions
id: output-options
shell: bash
run: |
echo "architectures=$(echo [ ${ARCHITECTURES} ])" >> "$GITHUB_OUTPUT"
echo "build_modes=$(echo [ ${BUILD_MODES} ])" >> "$GITHUB_OUTPUT"
echo "cxx_versions=$(echo [ ${CXX_VERSIONS} ])" >> "$GITHUB_OUTPUT"
build-and-test:
needs: generate-base-matrix
runs-on: ${{ matrix.config.os }}
container: ${{ matrix.config.container.image }}
name: |
${{ matrix.config.prefix }}
${{ matrix.config.compiler.name }}-${{ matrix.config.compiler.version }}
${{ matrix.config.suffix }}
(C++${{ matrix.cxx_standard }}, ${{ matrix.build_mode }}, ${{ matrix.architecture }})
strategy:
fail-fast: false
matrix:
architecture: ${{ fromJSON(needs.generate-base-matrix.outputs.architectures) }}
build_mode: ${{ fromJSON(needs.generate-base-matrix.outputs.build_modes) }}
cxx_standard: ${{ fromJSON(needs.generate-base-matrix.outputs.cxx_versions) }}
config:
# clang
- prefix: "Ubuntu"
os: "ubuntu-latest"
container:
image: "ghcr.io/dnkpp/clang:21"
compiler:
name: "clang"
version: "21"
asan: true
cxx20_modules: true
- prefix: "Ubuntu"
suffix: "/libc++"
os: "ubuntu-latest"
container:
image: "ghcr.io/dnkpp/clang:21"
compiler:
name: "clang"
version: "21"
only_cpptrace: true
libcxx: true
cxx20_modules: false
- prefix: "Ubuntu"
suffix: "/libc++"
os: "ubuntu-latest"
container:
image: "ghcr.io/dnkpp/clang:20"
compiler:
name: "clang"
version: "20"
only_cpptrace: true
libcxx: true
cxx20_modules: false
- prefix: "Ubuntu"
os: "ubuntu-latest"
container:
image: "ghcr.io/dnkpp/clang:20"
compiler:
name: "clang"
version: "20"
cxx20_modules: true
- prefix: "Ubuntu"
suffix: "/libc++"
os: "ubuntu-latest"
container:
image: "ghcr.io/dnkpp/clang:19"
compiler:
name: "clang"
version: "19"
only_cpptrace: true
libcxx: true
cxx20_modules: false
- prefix: "Ubuntu"
os: "ubuntu-latest"
container:
image: "ghcr.io/dnkpp/clang:19"
compiler:
name: "clang"
version: "19"
cxx20_modules: true
- prefix: "Ubuntu"
suffix: "/libc++"
os: "ubuntu-latest"
container:
image: "ghcr.io/dnkpp/clang:18"
compiler:
name: "clang"
version: "18"
only_cpptrace: true
libcxx: true
cxx20_modules: false
- prefix: "Ubuntu"
os: "ubuntu-latest"
container:
image: "ghcr.io/dnkpp/clang:18"
compiler:
name: "clang"
version: "18"
cxx20_modules: true
- prefix: "Ubuntu"
suffix: "/libc++"
os: "ubuntu-latest"
container:
image: "ghcr.io/dnkpp/clang:17"
compiler:
name: "clang"
version: "17"
libcxx: true
only_cpptrace: true
cxx20_modules: false
- prefix: "Ubuntu"
os: "ubuntu-latest"
container:
image: "ghcr.io/dnkpp/clang:17"
compiler:
name: "clang"
version: "17"
cxx20_modules: true
- prefix: "Ubuntu"
suffix: "/libc++"
os: "ubuntu-latest"
container:
image: "ghcr.io/dnkpp/clang:16"
compiler:
name: "clang"
version: "16"
only_fmt: true
only_cpptrace: true
libcxx: true
- prefix: "Ubuntu"
os: "ubuntu-latest"
container:
image: "ghcr.io/dnkpp/clang:16"
compiler:
name: "clang"
version: "16"
only_fmt: true
only_cpptrace: true
# gcc
- prefix: "Ubuntu"
os: "ubuntu-latest"
container:
image: "ghcr.io/dnkpp/gcc:15"
compiler:
name: "gcc"
version: "15"
asan: true
cxx20_modules: false # in theory, it should work but in practice it does not.
- prefix: "Ubuntu"
os: "ubuntu-latest"
container:
image: "ghcr.io/dnkpp/gcc:14"
compiler:
name: "gcc"
version: "14"
- prefix: "Ubuntu"
os: "ubuntu-latest"
container:
image: "ghcr.io/dnkpp/gcc:13"
compiler:
name: "gcc"
version: "13"
- prefix: "Ubuntu"
os: "ubuntu-latest"
container:
image: "ghcr.io/dnkpp/gcc:12"
compiler:
name: "gcc"
version: "12"
only_fmt: true
only_cpptrace: true
- prefix: "Ubuntu"
os: "ubuntu-latest"
container:
image: "ghcr.io/dnkpp/gcc:11"
compiler:
name: "gcc"
version: "11"
only_fmt: true
only_cpptrace: true
- prefix: "Ubuntu"
os: "ubuntu-latest"
container:
image: "ghcr.io/dnkpp/gcc:10"
compiler:
name: "gcc"
version: "10"
only_fmt: true
only_cpptrace: true
compat_source_loc: true
# This is the latest debian-11 (aka `bullseye`) version
# and the absolute minimum version mimic++ ensures compatibility with.
- prefix: "Debian-11"
os: "ubuntu-latest"
container:
image: "ghcr.io/dnkpp/debian:bullseye-slim"
compiler:
name: "gcc"
version: "10.2"
only_fmt: true
only_cpptrace: true
compat_source_loc: true
# msvc
- prefix: "Windows 2022"
os: "windows-2022"
compiler:
name: "msvc"
version: "v143"
toolset: "14.38"
toolset_component: "Microsoft.VisualStudio.Component.VC.14.38.17.8.x86.x64"
cmake_generator: "Visual Studio 17 2022"
cxx20_modules: false
- prefix: "Windows 2022"
os: "windows-2022"
compiler:
name: "msvc"
version: "v143"
toolset: "14.40"
toolset_component: "Microsoft.VisualStudio.Component.VC.14.40.17.10.x86.x64"
cmake_generator: "Visual Studio 17 2022"
cxx20_modules: false
- prefix: "Windows 2022"
suffix: "/Gv"
os: "windows-2022"
compiler:
name: "msvc"
version: "v143"
cmake_generator: "Visual Studio 17 2022"
default_call_convention: "vectorcall"
cxx20_modules: false
# AppleClang
# The specified AppleClang version is just an assumption, which will be verified during the setup step.
- prefix: "macOS"
os: "macos-15"
xcode: "16.2"
compiler:
name: "AppleClang"
version: "16"
only_cpptrace: true
- prefix: "macOS"
os: "macos-15"
xcode: "16.4"
compiler:
name: "AppleClang"
version: "17"
only_cpptrace: true
exclude:
# Honestly, we do not get much insight from testing Release modes of different c++-versions.
- build_mode: "Release"
cxx_standard: 23
# gcc-10 doesn't know C++-23
- cxx_standard: 23
config:
compiler:
name: "gcc"
version: "10"
- cxx_standard: 23
config:
compiler:
name: "gcc"
version: "10.2"
# It seems macOS doesn't support 32bit builds.
- architecture: "32bit"
config:
prefix: "macOS"
steps:
- name: Checkout code
uses: actions/checkout@v6
- name: Setup base cmake options
shell: bash
# sets up common options, used by all cmake configure steps.
# explicitly disable all optional features here
run: |
echo "CMAKE_BASE_OPTIONS=$(echo ${CMAKE_BASE_OPTIONS} \
--log-level=DEBUG \
-D CMAKE_VERBOSE_MAKEFILE=YES \
-D MIMICPP_FORCED_CXX_STANDARD="${{ matrix.cxx_standard }}" \
-D MIMICPP_ENABLE_UNIT_TESTS=ON \
-D MIMICPP_ENABLE_PACKAGE_TEST=ON \
-D MIMICPP_ENABLE_ADAPTER_TESTS=OFF \
-D MIMICPP_ENABLE_STACKTRACE_TESTS=OFF \
-D MIMICPP_CONFIG_EXPERIMENTAL_PRETTY_TYPES=OFF \
-D MIMICPP_CONFIG_EXPERIMENTAL_CATCH2_MATCHER_INTEGRATION=OFF \
-D MIMICPP_CONFIG_EXPERIMENTAL_UNICODE_STR_MATCHER=OFF \
-D MIMICPP_ENABLE_UNICODE_STR_MATCHER_TESTS=OFF \
-D MIMICPP_CONFIG_EXPERIMENTAL_STACKTRACE=OFF \
-D MIMICPP_ENABLE_STACKTRACE_TESTS=OFF \
)" >> $GITHUB_ENV
- name: Setup compatibility source-location option
if: ${{ matrix.config.compat_source_loc }}
shell: bash
run: |
echo "CMAKE_BASE_OPTIONS=$(echo ${CMAKE_BASE_OPTIONS} -DMIMICPP_TESTING_ENABLE_COMPAT_SOURCE_LOCATION=ON)" >> $GITHUB_ENV
# Enable C++20 modules, but consume the dependencies in the traditional way.
# This way, we can test modules and header-only targets in one go.
- name: Setup C++20 modules related options
if: ${{ matrix.config.cxx20_modules == true }}
shell: bash
run: |
echo "CMAKE_BASE_OPTIONS=$(echo ${CMAKE_BASE_OPTIONS} \
-D MIMICPP_CONFIG_EXPERIMENTAL_ENABLE_CXX20_MODULES__UNPORTABLE__=ON \
-D MIMICPP_CONFIG_IMPORT_FMT=OFF \
-D MIMICPP_CONFIG_EXPERIMENTAL_IMPORT_CPPTRACE=OFF \
)" >> $GITHUB_ENV
- name: Setup macOS
if: startsWith(matrix.config.os, 'macOS')
shell: bash
run: |
ls /Applications | grep Xcode
sudo xcode-select -s "/Applications/Xcode_${{ matrix.config.xcode }}.app/Contents/Developer"
clang --version
clang --version | grep -q "Apple clang version ${{ matrix.config.compiler.version }}." || {
echo "ERROR: Expected AppleClang ${{ matrix.config.compiler.version }}.x, but got something else."
exit 1
}
echo "CMAKE_BASE_OPTIONS=$(echo ${CMAKE_BASE_OPTIONS} -DCMAKE_BUILD_TYPE=${{ matrix.build_mode }})" >> $GITHUB_ENV
- name: Setup linux
if: startsWith(matrix.config.os, 'ubuntu-')
shell: bash
run: |
echo "CMAKE_BASE_OPTIONS=$(echo ${CMAKE_BASE_OPTIONS} -DCMAKE_BUILD_TYPE=${{ matrix.build_mode }})" >> $GITHUB_ENV
- name: Gather msvc settings
if: ${{ matrix.config.compiler.name == 'msvc' }}
shell: bash
run: |
# translate architecture to appropriate platform config
if [[ "${{ matrix.architecture }}" == "64bit" ]]; then
PLATFORM="x64"
elif [[ "${{ matrix.architecture }}" == "32bit" ]]; then
PLATFORM="x86"
fi
#echo "CMAKE_BASE_OPTIONS=$(echo ${CMAKE_BASE_OPTIONS} \
# -G\"${{ matrix.config.cmake_generator }}\" \
# -T\"${{ matrix.config.compiler.version }}\" \
# -A\"${PLATFORM}\" \
# )" >> $GITHUB_ENV
echo "CMAKE_BASE_OPTIONS=$(echo ${CMAKE_BASE_OPTIONS} \
-G\"${{ matrix.config.cmake_generator }}\" \
-T\"version=${{ matrix.config.compiler.toolset }}\" \
)" >> $GITHUB_ENV
echo "CMAKE_BUILD_EXTRA=$(echo ${CMAKE_BUILD_EXTRA} --config ${{ matrix.build_mode }})" >> $GITHUB_ENV
- name: Setup msvc
id: setup-msvc
if: ${{ matrix.config.compiler.name == 'msvc' && matrix.config.compiler.toolset_component != '' }}
shell: powershell
run: |
Invoke-WebRequest `
-Uri https://aka.ms/vs/17/release/vs_BuildTools.exe `
-OutFile vs_BuildTools.exe
Start-Process vs_BuildTools.exe `
-ArgumentList '--quiet --wait --norestart --add ${{ matrix.config.compiler.toolset_component }}' `
-NoNewWindow -Wait
$vs_install = & vswhere.exe -products * -latest -property installationPath
echo "VS install path: $vs_install"
Get-ChildItem -Path "$vs_install\VC\Tools\MSVC" -Directory
- name: Setup alternative default call-convention for msvc
if: ${{ matrix.config.compiler.name == 'msvc' && matrix.config.default_call_convention != '' }}
shell: bash
run: |
# translate default_call_convention to appropriate option
if [[ "${{ matrix.config.default_call_convention }}" == 'vectorcall' ]]; then
CALL_CONVENTION="/Gv"
else
echo "Invalid call-convention: ${{ matrix.config.default_call_convention }}"
exit 1
fi
# Do NOT remove the double /, as this will cause trouble during cmake configuration (it somehow expands to C:/Program Files/Git/Gv ???!)
echo "CXXFLAGS=$(echo ${CXXFLAGS} /${CALL_CONVENTION})" >> $GITHUB_ENV
- name: Clang libc++ setup
if: ${{ matrix.config.compiler.name == 'clang' && matrix.config.libcxx == true }}
shell: bash
run: |
echo "CXXFLAGS=$(echo ${CXXFLAGS} -stdlib=libc++)" >> $GITHUB_ENV
echo "LDFLAGS=$(echo ${LDFLAGS} -lc++abi)" >> $GITHUB_ENV
- name: Setup 32bit on Linux
if: ${{ matrix.architecture == '32bit' && matrix.config.prefix == 'Linux' }}
shell: bash
run: |
echo "CXXFLAGS=$(echo ${CXXFLAGS} -m32)" >> $GITHUB_ENV
echo "CFLAGS=$(echo ${CFLAGS} -m32)" >> $GITHUB_ENV
echo "LDFLAGS=$(echo ${LDFLAGS} -m32)" >> $GITHUB_ENV
- name: Setup 32bit libc++ on Linux
if: ${{
matrix.architecture == '32bit'
&& matrix.config.prefix == 'Linux'
&& matrix.config.libcxx == true
}}
shell: bash
# remove 64bit binaries and install 32bit versions.
# I don't know, how to install them side by side.
run: |
apt-get remove -y \
libc++-${{ matrix.config.compiler.version }}-dev \
libc++abi-${{ matrix.config.compiler.version }}-dev
apt-get autoremove -y
dpkg --add-architecture i386
apt-get update -y
apt-get install -y \
libc++-${{ matrix.config.compiler.version }}-dev:i386 \
libc++abi-${{ matrix.config.compiler.version }}-dev:i386
- name: Enable Address and Undefined Sanitizer
if: ${{ matrix.config.asan && matrix.build_mode == 'Debug' }}
shell: bash
run: |
# ASan has some serious trouble with libc++ exception mechanism
# see: https://github.com/llvm/llvm-project/issues/59432
#if [[ "${{ matrix.config.libcxx }}" ]]; then
# echo "ASAN_OPTIONS=$(echo ${ASAN_OPTIONS}:alloc_dealloc_mismatch=0)" >> $GITHUB_ENV
#fi
echo "CMAKE_BASE_OPTIONS=$(echo ${CMAKE_BASE_OPTIONS} -DSANITIZE_ADDRESS=YES -DSANITIZE_UNDEFINED=YES)" >> $GITHUB_ENV
#################################
# Without optional features
- name: Configure Basic Framework
id: config-basic
if: ${{ matrix.config.only_fmt != true }}
shell: bash
run: |
cmake \
-S . \
-B build \
${{ env.CMAKE_BASE_OPTIONS }}
- name: Build Basic Framework
if: ${{ steps.config-basic.outcome == 'success' }}
shell: bash
run: |
cmake --build build \
-j5 \
${{ env.CMAKE_BUILD_EXTRA }}
- name: Run Basic Framework tests
if: ${{ steps.config-basic.outcome == 'success' }}
shell: bash
run: |
ctest --test-dir build \
${{ env.CTEST_OPTIONS }} \
-C ${{ matrix.build_mode }}
#
#################################
#################################
# Feature: fmt formatting-backend
- name: Configure with fmt formatting-backend
shell: bash
run: |
cmake \
-S . \
-B build \
${{ env.CMAKE_BASE_OPTIONS }} \
-D MIMICPP_CONFIG_USE_FMT=YES
- name: Build with fmt formatting-backend
shell: bash
run: |
cmake --build build \
-j5 \
${{ env.CMAKE_BUILD_EXTRA }}
- name: Run tests with fmt formatting-backend
shell: bash
run: |
ctest --test-dir build \
${{ env.CTEST_OPTIONS }} \
-C ${{ matrix.build_mode }}
#
#################################
#################################
# Feature: experimental pretty type-printing
- name: Configure with experimental pretty type-printing
shell: bash
run: |
cmake \
-S . \
-B build \
${{ env.CMAKE_BASE_OPTIONS }} \
-D MIMICPP_CONFIG_USE_FMT=YES \
-D MIMICPP_CONFIG_EXPERIMENTAL_PRETTY_TYPES=YES
- name: Build with experimental pretty type-printing
shell: bash
run: |
cmake --build build \
-j5 \
${{ env.CMAKE_BUILD_EXTRA }}
- name: Run tests with experimental pretty type-printing
shell: bash
run: |
ctest --test-dir build \
${{ env.CTEST_OPTIONS }} \
-C ${{ matrix.build_mode }}
#
#################################
#################################
# Feature: experimental stacktrace
- name: Select stacktrace backend
id: config-stacktrace-backend-test
if: ${{ matrix.build_mode == 'Debug' }}
shell: bash
run: |
BACKEND=cpptrace
if [[ "${{ matrix.cxx_standard }}" == "23" && "${{ matrix.config.only_cpptrace }}" != "true" ]]; then
BACKEND=c++23
fi
echo "SELECTED_STACKTRACE_BACKEND=$(echo ${BACKEND})" >> $GITHUB_ENV
- name: Configure with experimental stacktrace
if: ${{ steps.config-stacktrace-backend-test.outcome == 'success' }}
shell: bash
run: |
cmake \
-S . \
-B build \
${{ env.CMAKE_BASE_OPTIONS }} \
-D MIMICPP_CONFIG_USE_FMT=YES \
-D MIMICPP_CONFIG_EXPERIMENTAL_PRETTY_TYPES=YES \
-D MIMICPP_CONFIG_EXPERIMENTAL_STACKTRACE=${SELECTED_STACKTRACE_BACKEND}
- name: Build with experimental stacktrace
if: ${{ steps.config-stacktrace-backend-test.outcome == 'success' }}
shell: bash
run: |
cmake --build build \
-j5 \
${{ env.CMAKE_BUILD_EXTRA }}
- name: Run tests with experimental stacktrace
if: ${{ steps.config-stacktrace-backend-test.outcome == 'success' }}
shell: bash
run: |
ctest --test-dir build \
${{ env.CTEST_OPTIONS }} \
-C ${{ matrix.build_mode }}
#
#################################
#################################
# Adapter Tests
# Workflow is skipped, when an alternative default call-convention is applied, because not all of these
# framework supports it.
- name: Configure adapter tests
id: config-adapter-test
if: ${{ matrix.config.default_call_convention == '' }}
shell: bash
run: |
cmake \
-S . \
-B build \
${{ env.CMAKE_BASE_OPTIONS }} \
-D MIMICPP_CONFIG_USE_FMT=YES \
-D MIMICPP_BUILD_EXAMPLES=OFF \
-D MIMICPP_ENABLE_UNIT_TESTS=OFF \
-D MIMICPP_ENABLE_ADAPTER_TESTS=YES \
-D MIMICPP_CONFIG_EXPERIMENTAL_CATCH2_MATCHER_INTEGRATION=YES
- name: Build adapter tests
if: ${{ steps.config-adapter-test.outcome == 'success' }}
shell: bash
run: |
cmake --build build \
-j5 \
${{ env.CMAKE_BUILD_EXTRA }}
- name: Run adapter tests
if: ${{ steps.config-adapter-test.outcome == 'success' }}
shell: bash
run: |
ctest --test-dir build/test/adapter-tests \
${{ env.CTEST_OPTIONS }} \
-C ${{ matrix.build_mode }}
#
#################################
#################################
# Stacktrace Tests
# Workflow is skipped, when an alternative default call-convention is applied, because not all of these
# framework supports it.
- name: Configure stacktrace tests
id: config-stacktrace-test
if: ${{ matrix.config.default_call_convention == '' }}
shell: bash
run: |
cmake \
-S . \
-B build \
${{ env.CMAKE_BASE_OPTIONS }} \
-D MIMICPP_CONFIG_USE_FMT=YES \
-D MIMICPP_BUILD_EXAMPLES=OFF \
-D MIMICPP_ENABLE_UNIT_TESTS=OFF \
-D MIMICPP_ENABLE_STACKTRACE_TESTS=YES
- name: Build stacktrace tests
if: ${{ steps.config-stacktrace-test.outcome == 'success' }}
shell: bash
run: |
cmake --build build \
-j5 \
${{ env.CMAKE_BUILD_EXTRA }}
- name: Run stacktrace tests
if: ${{ steps.config-stacktrace-test.outcome == 'success' }}
shell: bash
run: |
ctest --test-dir build/test/stacktrace-tests \
${{ env.CTEST_OPTIONS }} \
-C ${{ matrix.build_mode }}
#
#################################
#################################
# Feature: Unicode string-matchers
- name: Configure with unicode string-matchers
shell: bash
run: |
cmake \
-S . \
-B build \
${{ env.CMAKE_BASE_OPTIONS }} \
-D MIMICPP_CONFIG_USE_FMT=YES \
-D MIMICPP_BUILD_EXAMPLES=OFF \
-D MIMICPP_ENABLE_UNIT_TESTS=OFF \
-D MIMICPP_CONFIG_EXPERIMENTAL_UNICODE_STR_MATCHER=YES \
-D MIMICPP_ENABLE_UNICODE_STR_MATCHER_TESTS=YES
- name: Build with unicode string-matchers
shell: bash
run: |
cmake --build build \
-j5 \
${{ env.CMAKE_BUILD_EXTRA }}
- name: Run tests with unicode string-matchers
shell: bash
run: |
ctest --test-dir build/test/unicode-str-matcher-tests \
${{ env.CTEST_OPTIONS }} \
-C ${{ matrix.build_mode }}
#
#################################