Skip to content

Releases: rhalbersma/cpp-ci

v0.15.0 — a big-endian leg: s390x under QEMU

Choose a tag to compare

@rhalbersma rhalbersma released this 21 Oct 08:02
d2d6607

Every target the ladders build is little-endian, so a byte copy that assumes the low byte comes first, or a test that counts on it, passes everywhere and fails only on a big-endian machine. This release adds one leg that runs on one.

  • A big-endian leg, s390x.yml (#79): builds a caller with the s390x cross GCC from the ubuntu-26.04 runner image's own archive (GCC 15 by default, the stable rung), and runs its tests under qemu-s390x. One release rather than a ladder, as emscripten.yml: what is under test is the byte order. Emulation is several times slower than native, so a caller dispatches it from its nightly canary, not from pull requests. Inputs: gcc_version, build_types (Debug by default), vcpkg_features, cxx_flags, scan_for_modules, debug_flags, cmake_args and build_memory_mib.
  • An s390x triplet and toolchain (#78): vcpkg-overlay gains s390x-linux-gcc, which builds a caller's dependencies with the same cross GCC and emulator, and the workflow chainloads the same toolchain for the caller's own configure. vcpkg's community s390x-linux triplet alone would build with the host compiler.
  • s390x rather than powerpc64 because it is a current platform: IBM sells it, and Ubuntu, RHEL and SLES all ship for it.

No existing workflow's inputs changed, and none became required. A caller repins by moving its uses: lines to this commit:

uses: rhalbersma/cpp-ci/.github/workflows/<workflow>.yml@d2d660725227972f5ac9bdd65efda9d485fb30b7 # v0.15.0

and adds the leg with a workflow_dispatch-only stub that its canary dispatches:

uses: rhalbersma/cpp-ci/.github/workflows/s390x.yml@d2d660725227972f5ac9bdd65efda9d485fb30b7 # v0.15.0

Full changes: #78 and #79. Refs #63.

v0.14.0 — pinned vcpkg, shared clang-tidy and gcovr actions, builds sized by memory

Choose a tag to compare

@rhalbersma rhalbersma released this 20 Oct 08:05
2a7b357

The ladders resolve the same dependencies on every runner image, the clang-tidy and coverage gates run through actions a local run can share, and the heavy builds are sized by memory.

  • vcpkg at a pinned commit (#70, #71): a new vcpkg-setup action checks out microsoft/vcpkg at bf19794383e8, which serves Boost 1.92, and every leg that installs dependencies runs it first. Port versions no longer move when the runner image does.
  • A caller's vcpkg ports on the dependency installs' prefix path (#69): a dependency_repos entry that find_package()s a port of its own configures.
  • A clang-tidy action (#72, #73): clang-tidy.yml's four passes live in .github/actions/clang-tidy/clang-tidy.sh, which a local run can call. Every pass runs, and the header pass checks every header, so one round reports every finding.
  • A gcovr action (#74, #75): the coverage gate's exclusions live in .github/actions/gcovr/gcovr.sh, run with the same arguments as before. It takes an optional SEARCH_PATHS for a local build directory; CI leaves it empty.
  • A project's own _ASSERT macro is excluded from coverage (#65), as assert( is: an upper-case name ending in _ASSERT, at the start of the line.
  • GCC installs fail loudly (#67, #68): the PPA's update and install are retried until g++-N has an install candidate, the install names that exact version, and the step fails unless g++-N is on PATH. During a Launchpad brownout, apt-get install g++-15 had installed clang-15 and exited 0.
  • Builds sized by memory (#66, #76): sanitizers.yml, gcc.yml, clang.yml and clang-libc++.yml take build_memory_mib, 4096 by default, and run as many jobs as MemAvailable holds at that budget, between one and one per CPU. On a 16 GB hosted runner that is three, where three 5 GiB units had shut runners down mid-Build.

No input a caller passes changed, and none became required. A caller repins by moving its uses: lines to this commit:

uses: rhalbersma/cpp-ci/.github/workflows/<workflow>.yml@2a7b3577168d22d62a9119b1913c6e0122e78994 # v0.14.0

Full changes: #65 to #76.

v0.13.0 - a 32-bit MSVC leg

Choose a tag to compare

@rhalbersma rhalbersma released this 14 Oct 08:10
170191b

visual-studio.yml takes an arch input, x64 (the default) or x86.

  • arch: x86 configures with -A Win32 against vcpkg's built-in x86-windows
    triplet, the x64-hosted tools cross-compiling. That leg is where MSVC's
    32-bit ABI meets the code: an ILP32 size_t with 8-byte alignment for
    64-bit members, and the STL's portable 128-bit integer class rather than
    the x64 intrinsics. vcpkg_triplet is ignored there, as gcc.yml ignores it
    for x86-linux-gcc.
  • A "Require a known target" step rejects anything but x64 or x86.
  • The vcpkg cache key carries the arch, so an x86 caller and an x64 caller
    of the same cache_prefix don't evict each other's archives. An existing
    caller's key gains "-x64", so its first run after repinning restores cold.
  • A caller passing nothing configures, installs and builds exactly as before.

The README's 32-bit table gains the MSVC x86 row and its stub. Its new
Future directions section records the open design issues: declared support
instead of dropped rungs, ladder freshness, a test for coverage.yml, drift
between callers, and the shared build and documentation.

Callers add one job:

msvc_x86:
uses: rhalbersma/cpp-ci/.github/workflows/visual-studio.yml@ # v0.13.0
with:
arch: x86
tiers: qualification
build_types: Debug

Full changes: #61, #62.

v0.12.0 — i686 and wasm32 legs: gcc.yml arch x86, and emscripten.yml

Choose a tag to compare

@rhalbersma rhalbersma released this 13 Oct 06:23
1c32e51

Two 32-bit targets, for the code that takes size_t to be 64 bits, alignof(std::int64_t) to be 8, or __int128 to exist. Every leg before this one builds for a 64-bit target, where none of that shows. The two targets fail differently, so each catches what the other cannot (#57, #58).

Target Workflow size_t alignof(std::int64_t) in a class __int128 Tests run under
i686 gcc.yml with arch: x86 unsigned int 4 no the runner, natively
wasm32 emscripten.yml unsigned long 8 yes node

gcc.yml takes arch

arch: x86 does four things:

  • adds -m32;
  • installs the GCC's multilib through install-gcc's new multilib input;
  • builds the dependencies from the new x86-linux-gcc overlay triplet;
  • ignores vcpkg_triplet, since the leg has its own triplet.

The trunk snapshot has no 32-bit runtime, so an i686 ladder names released rungs only. The default, x64, builds exactly as before.

emscripten.yml is new

It takes one Emscripten release, emsdk_version (default 6.0.12), rather than a ladder, and builds Debug by default. Its dependencies come from wasm32-emscripten-eh, vcpkg's community triplet with exceptions compiled in, and node from the emsdk runs the tests. It accepts the same vcpkg_features, cxx_flags, scan_for_modules, debug_flags and cmake_args as the other ladders, plus linker_flags, whose default turns on memory growth, an 8 MB stack and EXIT_RUNTIME. Its gate is <job> / all.

To add both legs

  i686:
    uses: rhalbersma/cpp-ci/.github/workflows/gcc.yml@<sha> # v0.12.0
    with:
      arch: x86
      tiers: stable
      build_types: Debug

  wasm32:
    uses: rhalbersma/cpp-ci/.github/workflows/emscripten.yml@<sha> # v0.12.0

No existing check names change

The ladders resolve as in v0.11.1. gcc.yml's vcpkg cache key now carries the arch, so the first run after the bump rebuilds the dependencies once. The internal actions are repinned to #57's commit. Both legs ran green on xstd-ints (rhalbersma/xstd-ints#284) and xstd-misc (rhalbersma/xstd-misc#39) before this tag.

v0.11.1 — codeql-action 4.38.2 and codecov-action 7.1.1

Choose a tag to compare

@rhalbersma rhalbersma released this 03 Oct 13:47
5e70b2d

Dependabot's action updates (#55):

Action From To
github/codeql-action (init, analyze, upload-sarif) 4.37.9 4.38.2
codecov/codecov-action 7.0.0 7.1.1

The internal actions are repinned from 3a0d191 to v0.11.0's commit. Their
content is unchanged, so the move is only a record.

No inputs or check names change

The ladders resolve exactly as in v0.11.0, and no required check needs renaming.

v0.11.0 — CMake's module scan off and -g1 Debug info by default, as inputs

Choose a tag to compare

@rhalbersma rhalbersma released this 03 Oct 13:03
b5161ff

Two new workflow_call inputs set how much a build writes rather than what it
checks. Both default to the lean side, so a caller gets them by bumping its pin,
and one repository can opt back to test the other setting (#56).

Input Default Passed as Taken by
scan_for_modules false -DCMAKE_CXX_SCAN_FOR_MODULES every workflow that configures and builds
debug_flags -g1 -DCMAKE_CXX_FLAGS_DEBUG; empty passes nothing gcc, clang, clang-libc++, apple-clang, mingw, sanitizers, coverage, codeql

Both are passed ahead of cmake_args, so a -D there still wins.

Why

CMake 3.28 and later scans every translation unit of a C++20 target for the
modules it imports. For a project that imports none, that is a preprocessor pass
per unit, and a fully preprocessed copy of each left in the build tree.

-g1 keeps the line tables and function names that a symbolized sanitizer
backtrace reads. It drops the variable and type information that only a
debugger uses, and no job here attaches one.

Measured on xstd-bits, 8 test targets, GCC 16 Debug with ASan and UBSan:

Variant Build tree Objects Executables Scan files
scan on, -g (v0.10.3) 499 MB 265 MB 202 MB 55 MB
scan off, -g 448 MB 265 MB 202 MB 0
scan off, -g1 (v0.11.0) 391 MB 230 MB 178 MB 0

Across that library's full 153 test units, the scan alone accounted for about
740 MB per build directory.

What else changed

  • sanitizers.yml and coverage.yml no longer hard-code -g. CMake places
    CMAKE_CXX_FLAGS_DEBUG after CMAKE_CXX_FLAGS, so -g1 overrode that -g
    anyway. gcov reads .gcno and .gcda, not DWARF.
  • clang-tidy.yml keeps the module scan fixed off, with no input. It
    configures without building, so a scan would leave module-map references
    in the compile database that are never written.
  • visual-studio.yml and msvc-analyze.yml take scan_for_modules only.
    MSVC's debug options are /Zi-style.
  • consumption.yml takes scan_for_modules only. It builds no Debug
    configuration.

To opt back

with:
  scan_for_modules: true   # scan every translation unit for module imports
  debug_flags: ""          # CMake's own -g

No check names change

The ladders resolve exactly as in v0.10.3, and no required check needs
renaming. The full xstd-bits matrix passed against this commit before the
merge (rhalbersma/xstd-bits#320).

v0.10.3 — A 403 from the runner's Microsoft apt source no longer fails an install

Choose a tag to compare

@rhalbersma rhalbersma released this 24 Sep 20:28
480aa17

A required leg failed before configuring anything: install-clang died in its
second apt-get update, on a source nothing here installs from.

Err:6 https://packages.microsoft.com/ubuntu/24.04/prod noble InRelease
  403  Forbidden [IP: 13.107.246.66 443]
Hit:7 https://apt.llvm.org/noble llvm-toolchain-noble InRelease
E: The repository 'https://packages.microsoft.com/ubuntu/24.04/prod noble InRelease' is no longer signed.

The Ubuntu runner image preinstalls packages.microsoft.com as an apt source.
The LLVM repository answered, and the Microsoft one had served its index six
seconds earlier in the same job, so the 403 was transient. Two things turned it
into a red check anyway:

  • Acquire::Retries, which apt-retry sets, retries a 5xx but not a 4xx.
  • A single source failing its index fails the whole apt-get update.

The fix is in apt-retry, the step every Linux job already runs once before
its installs. It now also removes any /etc/apt/sources.list.d/ file naming
packages.microsoft.com, in either the one-line .list or the deb822
.sources format, and prints what it removed. It is a no-op when there are
none. Every internal action reference is repinned to it (#53, #54).

What is affected

Workflow Affected
clang.yml, clang-libc++.yml, gcc.yml yes
sanitizers.yml, coverage.yml, clang-tidy.yml yes
clang-format.yml, codeql.yml, consumption.yml yes
visual-studio.yml, mingw.yml, msvc-analyze.yml no — Windows, no apt
apple-clang.yml no — macOS, no apt
actionlint.yml, scorecard.yml no — no apt install

No inputs or check names change

Between v0.10.2 and v0.10.3 the only action that changed is apt-retry, and
toolchains.json is untouched. Every ladder resolves exactly as it did, and no
required check needs renaming.

Upgrading

Repin, nothing else:

uses: rhalbersma/cpp-ci/.github/workflows/clang.yml@480aa17d38efd5c1641b861e9e1a0c6df053a451 # v0.10.3

v0.10.2 — A single cmake argument stays an argument

Choose a tag to compare

@rhalbersma rhalbersma released this 19 Sep 16:13
29fdd66

A caller passing exactly one -D argument through cmake_args to a
PowerShell leg had it delivered to cmake one character at a time. cmake
answered Unknown argument -, then Ignoring extra path for the last
character, and configured nothing.

$extra = $env:EXTRA_CMAKE -split '\s+' | Where-Object { $_ }

A PowerShell pipeline yielding one object assigns that object rather than a
one-element array, so $extra was a [string] — and splatting a string
enumerates it. At two or more arguments the split already yields an Object[]
and @extra is what it looks like, which is why this went unseen for so long:
no caller had passed exactly one.

The fix is @( ) around the pipeline, at all three sites — mingw.yml, and
both configure steps in visual-studio.yml (the regular one and the preview
toolset's).

What is affected

Workflow Affected
visual-studio.yml yes — both configure steps
mingw.yml yes
msvc-analyze.yml no — reads its arguments with bash's read -ra
every Unix leg no — bash throughout

Checked against pwsh 7.4.6 at every arity, before and after:

none  before Object[] ->                 after Object[] ->
one   before String   -> '-' 'D' 'X' ... after Object[] -> '-DXSTD_BITS_CXX_STANDARD=26'
two   before Object[] -> '-DA=1' '-DB=2' after Object[] -> '-DA=1' '-DB=2'

Empty and two-or-more are byte for byte what they were. Only the one-argument
case changes, and it changes from broken to correct.

No inputs or check names change

.github/actions/ and toolchains.json are untouched since v0.10.1, so every
ladder resolves exactly as it did and no required check needs renaming.

Upgrading

Repin, nothing else:

uses: rhalbersma/cpp-ci/.github/workflows/visual-studio.yml@29fdd6605bf237863ad39c3919c2cf389cfb6d38 # v0.10.2
uses: rhalbersma/cpp-ci/.github/workflows/mingw.yml@29fdd6605bf237863ad39c3919c2cf389cfb6d38 # v0.10.2

v0.10.1 — clang-tidy stops scanning for modules it never builds

Choose a tag to compare

@rhalbersma rhalbersma released this 16 Sep 12:16
18949f8

A one-line fix for the single regression in v0.10.0, found by the first caller
to repin (xstd-ints#249).

Ninja plus a C++20-or-later target turns CMake's module scanner on, and the
scanner appends a response file — @<target>.dir/<source>.o.modmap — to every
compile command it writes into the database. The build step creates those
files, and clang-tidy.yml has no build step: it configures, then replays
compile_commands.json. So clang-tidy ran commands naming files nobody had
written, and all 44 translation units failed alike:

error: no such file or directory:
'@test/CMakeFiles/header.xstd.ints.bit.dir/.../xstd.ints.bit.cpp.o.modmap'
[clang-diagnostic-error]

CMAKE_CXX_SCAN_FOR_MODULES=OFF on that job's configure line drops the flag.
Nothing is lost: clang-tidy analyses sources rather than built module
interfaces, so the scan had no reader there. Every leg that builds what it
configures — the seven ladders, coverage, sanitizers, codeql and
consumption — keeps scanning and is untouched.

Upgrading from v0.10.0: repin, nothing else. Everything but the three
clang-tidy legs was already green under Ninja on xstd-ints' full ladder.

v0.10.0 — The Unix legs build with Ninja

Choose a tag to compare

@rhalbersma rhalbersma released this 16 Sep 11:14
95dead5

Nine workflows configured with no -G and got Unix Makefiles, which cost twice
over: cmake --build shells out to make with no -j, so those legs compiled
on one core of the runner's four, and Makefiles cannot scan C++20 module
dependencies at all.

They now take a generator input, defaulting to Ninja — gcc, clang,
clang-libc++, apple-clang, coverage, sanitizers, clang-tidy, codeql
and consumption, the last across all five of its configure sites. Nothing is
installed: ubuntu-24.04, macos-15 and macos-26 all ship Ninja 1.13.2. A caller
needing the platform default writes generator: Unix Makefiles; mingw.yml and
the two Visual Studio legs already named their own and are unchanged.

Also since v0.9.0:

  • vcpkg_features lets a caller name the manifest features its tests need,
    instead of pushing them into default-features and charging every consumer
    for them (#45).
  • The internal pins name a commit the history can serve. A repin made on a
    branch is stale the moment it squash-merges, which had left main and every
    PR red on 58 bad pins (#47).
  • The README claims Active rather than WIP, and says what this CI is
    indifferent to — the shape of the library, the test framework — rather than
    defending it (#46, #48, #49).

Upgrading: repin and nothing else, unless your project depends on the
generator. The build directory is CMake's own, so a caller that cached one
across the change wants a clean configure.