Skip to content

util: add Tagged<T, "Name"> newtype helper; relax Quantity/Rational DecimalPlaces floor to 0 #235

util: add Tagged<T, "Name"> newtype helper; relax Quantity/Rational DecimalPlaces floor to 0

util: add Tagged<T, "Name"> newtype helper; relax Quantity/Rational DecimalPlaces floor to 0 #235

Workflow file for this run

name: CI
on:
push:
branches: [main, master]
pull_request:
# actions: write lets the sccache save step evict the previous entry under
# the same static key via `gh cache delete` before re-saving (actions/cache
# never overwrites an existing key). On pull_request runs from a fork, the
# token is read-only regardless of this declaration; the delete step is
# best-effort (continue-on-error) for exactly that case.
permissions:
contents: read
actions: write
env:
VCPKG_BINARY_SOURCES: "clear;x-gha,readwrite"
SCCACHE_DIR: /home/runner/.cache/sccache
# Caps each leg's on-disk sccache blob so ~11 legs stay well under GitHub's
# 10 GB per-repo actions-cache budget. See the cache save/restore steps
# below: keys are static per leg (no SHA/branch suffix) so the cache warms
# up once and is refreshed in place every run, instead of growing a new
# generation per commit that only gets reclaimed by GitHub's LRU eviction.
SCCACHE_CACHE_SIZE: "1G"
CLANG_VERSION: "22"
# MORPH_BUILD_FORMS_QML needs Qt 6.5+; ubuntu-24.04 apt still ships 6.4.2.
QT_VERSION: "6.8.1"
jobs:
# ── Windows: MSVC + clang-cl ──────────────────────────────────────────
windows:
name: Windows / ${{ matrix.preset }}
runs-on: windows-latest
strategy:
fail-fast: false
matrix:
preset: [cl-debug, cl-release, clangcl-debug, clangcl-release]
steps:
- uses: actions/checkout@v4
- name: Setup MSVC environment
uses: ilammy/msvc-dev-cmd@v1
- name: Setup vcpkg
uses: lukka/run-vcpkg@v11
with:
vcpkgGitCommitId: c3867e714dd3a51c272826eea77267876517ed99
- name: Export vcpkg GHA binary cache vars
uses: actions/github-script@v7
with:
script: |
core.exportVariable('ACTIONS_CACHE_URL', process.env.ACTIONS_CACHE_URL || '');
core.exportVariable('ACTIONS_RUNTIME_TOKEN', process.env.ACTIONS_RUNTIME_TOKEN || '');
- name: Configure
run: cmake --preset ${{ matrix.preset }}
- name: Build
run: cmake --build --preset ${{ matrix.preset }}
- name: Test
if: matrix.preset == 'cl-debug' || matrix.preset == 'clangcl-debug'
run: ctest --preset ${{ matrix.preset }}
# ── Linux: GCC and Clang plain builds ────────────────────────────────
linux-compilers:
name: Linux / ${{ matrix.preset }}
runs-on: ubuntu-24.04
strategy:
fail-fast: false
matrix:
preset: [gcc-debug, gcc-release, clang-debug, clang-release]
steps:
- uses: actions/checkout@v4
- name: Cache apt packages
uses: actions/cache@v4
with:
path: /var/cache/apt/archives
key: apt-compilers-${{ matrix.preset }}-${{ hashFiles('.github/workflows/ci.yml') }}
restore-keys: apt-compilers-${{ matrix.preset }}-
- name: Install GCC 15 and ninja
if: startsWith(matrix.preset, 'gcc-')
run: |
sudo apt-get update -q
sudo apt-get install -y software-properties-common
sudo add-apt-repository -y ppa:ubuntu-toolchain-r/test
sudo apt-get update -q
sudo apt-get install -y gcc-15 g++-15 ninja-build catch2
sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-15 15
sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-15 15
- name: Install Clang ${{ env.CLANG_VERSION }} from apt.llvm.org
if: startsWith(matrix.preset, 'clang-')
run: |
sudo apt-get update -q
sudo apt-get install -y ninja-build catch2
wget -qO- https://apt.llvm.org/llvm.sh | sudo bash -s -- ${{ env.CLANG_VERSION }}
- name: Restore sccache
uses: actions/cache/restore@v4
with:
path: /home/runner/.cache/sccache
key: sccache-compilers-${{ matrix.preset }}
- name: Install sccache
run: |
curl -sSL https://github.com/mozilla/sccache/releases/download/v0.9.1/sccache-v0.9.1-x86_64-unknown-linux-musl.tar.gz \
| tar -xz --strip-components=1 -C /usr/local/bin sccache-v0.9.1-x86_64-unknown-linux-musl/sccache
- name: Configure (gcc)
if: startsWith(matrix.preset, 'gcc-')
run: |
cmake --preset ${{ matrix.preset }} \
-DCMAKE_C_COMPILER_LAUNCHER=sccache \
-DCMAKE_CXX_COMPILER_LAUNCHER=sccache
- name: Configure (clang)
if: startsWith(matrix.preset, 'clang-')
run: |
cmake --preset ${{ matrix.preset }} \
-DCMAKE_C_COMPILER=clang-${{ env.CLANG_VERSION }} \
-DCMAKE_CXX_COMPILER=clang++-${{ env.CLANG_VERSION }} \
-DCMAKE_C_COMPILER_LAUNCHER=sccache \
-DCMAKE_CXX_COMPILER_LAUNCHER=sccache
- name: Build
run: cmake --build --preset ${{ matrix.preset }}
- name: Test
if: endsWith(matrix.preset, '-debug')
run: ctest --preset ${{ matrix.preset }}
# actions/cache never overwrites an existing key, so the previous
# generation under this static key is evicted first (best-effort — a
# forked-PR token can't do this, and that's fine: the save below just
# no-ops with a warning instead of refreshing the cache).
- name: Evict previous sccache entry
if: always()
continue-on-error: true
run: gh cache delete "sccache-compilers-${{ matrix.preset }}"
env:
GH_TOKEN: ${{ github.token }}
- name: Save sccache
if: always()
uses: actions/cache/save@v4
with:
path: /home/runner/.cache/sccache
key: sccache-compilers-${{ matrix.preset }}
# ── Linux: sanitizers + coverage (all clang) ─────────────────────────
linux-sanitizers:
name: Linux / ${{ matrix.preset }}
runs-on: ubuntu-24.04
strategy:
fail-fast: false
matrix:
preset: [clang-asan, clang-tsan, clang-ubsan, clang-coverage]
steps:
- uses: actions/checkout@v4
- name: Cache apt packages
uses: actions/cache@v4
with:
path: /var/cache/apt/archives
key: apt-sanitizers-${{ hashFiles('.github/workflows/ci.yml') }}
restore-keys: apt-sanitizers-
- name: Install Clang ${{ env.CLANG_VERSION }} from apt.llvm.org
run: |
sudo apt-get update -q
sudo apt-get install -y ninja-build catch2 libsqlite3-dev
wget -qO- https://apt.llvm.org/llvm.sh | sudo bash -s -- ${{ env.CLANG_VERSION }}
- name: Restore sccache
uses: actions/cache/restore@v4
with:
path: /home/runner/.cache/sccache
key: sccache-sanitizers-${{ matrix.preset }}
- name: Install sccache
run: |
curl -sSL https://github.com/mozilla/sccache/releases/download/v0.9.1/sccache-v0.9.1-x86_64-unknown-linux-musl.tar.gz \
| tar -xz --strip-components=1 -C /usr/local/bin sccache-v0.9.1-x86_64-unknown-linux-musl/sccache
# morph::net and the SQLite offline queue are opt-in, but they are also
# where the memory/threading/UB risk actually lives (raw sockets, an I/O
# thread, a hand-rolled frame reader, a C API). Left off, the sanitizers
# and the coverage number both silently skipped them. Qt/QML and the
# fuzzers stay out of this matrix — they are covered by the
# linux-all-features job, and a GUI stack under TSan is mostly noise.
- name: Configure
run: |
cmake --preset ${{ matrix.preset }} \
-DMORPH_BUILD_NET=ON \
-DMORPH_BUILD_OFFLINE_SQLITE=ON \
-DCMAKE_C_COMPILER=clang-${{ env.CLANG_VERSION }} \
-DCMAKE_CXX_COMPILER=clang++-${{ env.CLANG_VERSION }} \
-DCMAKE_C_COMPILER_LAUNCHER=sccache \
-DCMAKE_CXX_COMPILER_LAUNCHER=sccache
- name: Build
run: cmake --build --preset ${{ matrix.preset }}
- name: Test
run: |
if [ "${{ matrix.preset }}" = "clang-coverage" ]; then
LLVM_PROFILE_FILE="build/clang-coverage/%p.profraw" ctest --preset clang-coverage
else
ctest --preset ${{ matrix.preset }}
fi
- name: Generate coverage report
if: matrix.preset == 'clang-coverage'
run: bash scripts/coverage.sh
- name: Upload coverage to Codecov
if: matrix.preset == 'clang-coverage'
uses: codecov/codecov-action@v5
with:
files: build/clang-coverage/coverage.lcov
token: ${{ secrets.CODECOV_TOKEN }}
- name: Upload coverage HTML
if: matrix.preset == 'clang-coverage'
uses: actions/upload-artifact@v4
with:
name: coverage-report
path: build/clang-coverage/html/
- name: Evict previous sccache entry
if: always()
continue-on-error: true
run: gh cache delete "sccache-sanitizers-${{ matrix.preset }}"
env:
GH_TOKEN: ${{ github.token }}
- name: Save sccache
if: always()
uses: actions/cache/save@v4
with:
path: /home/runner/.cache/sccache
key: sccache-sanitizers-${{ matrix.preset }}
# ── Linux: Qt WebSocket backend build + tests ─────────────────────────
linux-qt:
name: Linux / Qt6 WebSockets
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v4
- name: Cache apt packages
uses: actions/cache@v4
with:
path: /var/cache/apt/archives
key: apt-qt-${{ hashFiles('.github/workflows/ci.yml') }}
restore-keys: apt-qt-
- name: Install GCC 15, ninja, catch2, Qt6 WebSockets
run: |
sudo apt-get update -q
sudo apt-get install -y software-properties-common
sudo add-apt-repository -y ppa:ubuntu-toolchain-r/test
sudo apt-get update -q
sudo apt-get install -y gcc-15 g++-15 ninja-build catch2 \
qt6-base-dev qt6-websockets-dev qt6-tools-dev libgl1-mesa-dev
sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-15 15
sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-15 15
- name: Restore sccache
uses: actions/cache/restore@v4
with:
path: /home/runner/.cache/sccache
key: sccache-qt
- name: Install sccache
run: |
curl -sSL https://github.com/mozilla/sccache/releases/download/v0.9.1/sccache-v0.9.1-x86_64-unknown-linux-musl.tar.gz \
| tar -xz --strip-components=1 -C /usr/local/bin sccache-v0.9.1-x86_64-unknown-linux-musl/sccache
- name: Configure (gcc-debug with MORPH_BUILD_QT=ON)
run: |
cmake --preset gcc-debug \
-DMORPH_BUILD_QT=ON \
-DCMAKE_C_COMPILER_LAUNCHER=sccache \
-DCMAKE_CXX_COMPILER_LAUNCHER=sccache
- name: Build
run: cmake --build --preset gcc-debug
- name: Test (offscreen Qt platform)
env:
QT_QPA_PLATFORM: offscreen
run: ctest --preset gcc-debug
- name: Evict previous sccache entry
if: always()
continue-on-error: true
run: gh cache delete "sccache-qt"
env:
GH_TOKEN: ${{ github.token }}
- name: Save sccache
if: always()
uses: actions/cache/save@v4
with:
path: /home/runner/.cache/sccache
key: sccache-qt
# ── Linux: every optional feature enabled at once ─────────────────────
# Every MORPH_BUILD_* option below is off by default, and until this job
# existed no CI configuration turned any of them on — so several thousand
# lines (morph::net, the Qt/QML forms renderer, the SQLite queue, the fuzz
# harnesses, the vetted-HMAC adapters, the soak/bench targets) were never
# compiled here, let alone tested. That is how a build that cannot configure
# (MORPH_REQUIRE_VETTED_HMAC) and a replay test matching the wrong file
# extension both reached master green. Enabling them together also proves
# they compose, which building each alone would not.
linux-all-features:
name: Linux / all optional features (${{ matrix.compiler }})
runs-on: ubuntu-24.04
strategy:
fail-fast: false
matrix:
include:
# Clang additionally builds the libFuzzer harnesses, which require it.
- compiler: clang
preset: clang-debug
fuzzers: 'ON'
- compiler: gcc
preset: gcc-debug
fuzzers: 'OFF'
steps:
- uses: actions/checkout@v4
- name: Cache apt packages
uses: actions/cache@v4
with:
path: /var/cache/apt/archives
key: apt-all-features-${{ matrix.compiler }}-${{ hashFiles('.github/workflows/ci.yml') }}
restore-keys: apt-all-features-${{ matrix.compiler }}-
- name: Install toolchain and the non-Qt dependencies
run: |
sudo apt-get update -q
sudo apt-get install -y software-properties-common
sudo add-apt-repository -y ppa:ubuntu-toolchain-r/test
sudo apt-get update -q
sudo apt-get install -y ninja-build catch2 \
libsqlite3-dev libsodium-dev libssl-dev \
libgl1-mesa-dev libxkbcommon-x11-0 libxcb-cursor0 libxcb-icccm4 \
libxcb-keysyms1 libxcb-shape0 libxcb-xinerama0
if [ "${{ matrix.compiler }}" = "gcc" ]; then
sudo apt-get install -y gcc-15 g++-15
sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-15 15
sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-15 15
else
wget -qO- https://apt.llvm.org/llvm.sh | sudo bash -s -- ${{ env.CLANG_VERSION }}
fi
# Not the distro's Qt: MORPH_BUILD_FORMS_QML needs 6.5+ (see the version
# floor in CMakeLists.txt) and Ubuntu 24.04 still ships 6.4.2, whose
# QQmlApplicationEngine has no loadFromModule.
- name: Install Qt ${{ env.QT_VERSION }}
uses: jurplel/install-qt-action@v4
with:
version: ${{ env.QT_VERSION }}
modules: qtwebsockets
cache: true
- name: Restore sccache
uses: actions/cache/restore@v4
with:
path: /home/runner/.cache/sccache
key: sccache-all-features-${{ matrix.compiler }}
- name: Install sccache
run: |
curl -sSL https://github.com/mozilla/sccache/releases/download/v0.9.1/sccache-v0.9.1-x86_64-unknown-linux-musl.tar.gz \
| tar -xz --strip-components=1 -C /usr/local/bin sccache-v0.9.1-x86_64-unknown-linux-musl/sccache
# MORPH_REQUIRE_VETTED_HMAC is deliberately combined with
# MORPH_BUILD_TESTS=ON (the preset default). docs/spec/security.md
# documents that pairing as supported; this is what keeps it that way.
- name: Configure (every optional feature ON)
run: |
EXTRA=""
if [ "${{ matrix.compiler }}" = "clang" ]; then
EXTRA="-DCMAKE_C_COMPILER=clang-${{ env.CLANG_VERSION }} -DCMAKE_CXX_COMPILER=clang++-${{ env.CLANG_VERSION }}"
fi
# shellcheck disable=SC2086
cmake --preset ${{ matrix.preset }} \
-DMORPH_BUILD_NET=ON \
-DMORPH_BUILD_QT=ON \
-DMORPH_BUILD_FORMS_QML=ON \
-DMORPH_BUILD_OFFLINE_SQLITE=ON \
-DMORPH_BUILD_LOAD_TESTS=ON \
-DMORPH_BUILD_HMAC_EXAMPLES=ON \
-DMORPH_BUILD_FUZZERS=${{ matrix.fuzzers }} \
-DMORPH_REQUIRE_VETTED_HMAC=ON \
$EXTRA \
-DCMAKE_C_COMPILER_LAUNCHER=sccache \
-DCMAKE_CXX_COMPILER_LAUNCHER=sccache
- name: Build
run: cmake --build --preset ${{ matrix.preset }}
# Includes the fuzz *replay* tests on the clang leg: each committed seed
# and crash reproducer is replayed once and must not crash. This is a
# deterministic regression check, not a fuzzing campaign.
- name: Test (offscreen Qt platform)
env:
QT_QPA_PLATFORM: offscreen
run: ctest --preset ${{ matrix.preset }} --output-on-failure
# A guard that never fires is indistinguishable from one that works, so
# assert the fuzz replay actually ran the committed crash reproducers
# rather than silently matching nothing (the `.txt`-vs-`.bin` glob bug).
- name: Verify the fuzz replay covered the committed reproducers
if: matrix.fuzzers == 'ON'
run: |
ctest --preset ${{ matrix.preset }} -R fuzz -V > fuzz-replay.log 2>&1
status=0
for finding in tests/fuzz/findings/*/*; do
if ! grep -qF "$(basename "$finding")" fuzz-replay.log; then
echo "::error::fuzz replay never referenced committed reproducer $finding"
status=1
fi
done
exit "$status"
- name: Evict previous sccache entry
if: always()
continue-on-error: true
run: gh cache delete "sccache-all-features-${{ matrix.compiler }}"
env:
GH_TOKEN: ${{ github.token }}
- name: Save sccache
if: always()
uses: actions/cache/save@v4
with:
path: /home/runner/.cache/sccache
key: sccache-all-features-${{ matrix.compiler }}
# ── Valgrind (memcheck) ───────────────────────────────────────────────
valgrind:
name: Valgrind memcheck
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v4
- name: Cache apt packages
uses: actions/cache@v4
with:
path: /var/cache/apt/archives
key: apt-valgrind-${{ hashFiles('.github/workflows/ci.yml') }}
restore-keys: apt-valgrind-
- name: Install GCC 15, ninja, catch2, valgrind
run: |
sudo apt-get update -q
sudo apt-get install -y software-properties-common
sudo add-apt-repository -y ppa:ubuntu-toolchain-r/test
sudo apt-get update -q
sudo apt-get install -y gcc-15 g++-15 ninja-build catch2 valgrind
sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-15 15
sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-15 15
- name: Restore sccache
uses: actions/cache/restore@v4
with:
path: /home/runner/.cache/sccache
key: sccache-valgrind
- name: Install sccache
run: |
curl -sSL https://github.com/mozilla/sccache/releases/download/v0.9.1/sccache-v0.9.1-x86_64-unknown-linux-musl.tar.gz \
| tar -xz --strip-components=1 -C /usr/local/bin sccache-v0.9.1-x86_64-unknown-linux-musl/sccache
# morph::net and the SQLite queue are where the raw pointers, manual
# buffers and C API calls live — precisely what memcheck is for — so they
# are built here rather than left to the default (Qt/QML stays out: it
# drags in a GUI stack whose own allocations dominate the report).
- name: Configure
run: |
cmake --preset gcc-debug \
-DMORPH_BUILD_NET=ON \
-DMORPH_BUILD_OFFLINE_SQLITE=ON \
-DCMAKE_C_COMPILER_LAUNCHER=sccache \
-DCMAKE_CXX_COMPILER_LAUNCHER=sccache
- name: Build
run: cmake --build --preset gcc-debug
- name: Run tests under Valgrind
run: |
status=0
for suite in tests/morph_tests tests/net/morph_net_tests tests/offline_sqlite/morph_offline_sqlite_tests; do
binary="build/gcc-debug/$suite"
if [ ! -x "$binary" ]; then
echo "::error::expected Valgrind suite $binary was not built"
exit 1
fi
echo "── memcheck: $suite ──"
valgrind \
--tool=memcheck \
--leak-check=full \
--show-leak-kinds=definite,indirect \
--errors-for-leak-kinds=definite,indirect \
--error-exitcode=1 \
--suppressions=cmake/valgrind.supp \
"$binary" || status=1
done
exit "$status"
- name: Evict previous sccache entry
if: always()
continue-on-error: true
run: gh cache delete "sccache-valgrind"
env:
GH_TOKEN: ${{ github.token }}
- name: Save sccache
if: always()
uses: actions/cache/save@v4
with:
path: /home/runner/.cache/sccache
key: sccache-valgrind
# ── clang-tidy-diff (changed lines only) ──────────────────────────────
clang-tidy:
name: clang-tidy-diff
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0 # need full history for git diff against base
- name: Cache apt packages
uses: actions/cache@v4
with:
path: /var/cache/apt/archives
key: apt-clang-tidy-${{ hashFiles('.github/workflows/ci.yml') }}
restore-keys: apt-clang-tidy-
- name: Install Clang ${{ env.CLANG_VERSION }}, clang-tidy, and the non-Qt deps
run: |
sudo apt-get update -q
sudo apt-get install -y ninja-build catch2 \
libsqlite3-dev libsodium-dev libssl-dev \
libgl1-mesa-dev libxkbcommon-x11-0 libxcb-cursor0 libxcb-icccm4 \
libxcb-keysyms1 libxcb-shape0 libxcb-xinerama0
wget -qO- https://apt.llvm.org/llvm.sh | sudo bash -s -- ${{ env.CLANG_VERSION }}
sudo apt-get install -y clang-tidy-${{ env.CLANG_VERSION }}
# See the linux-all-features job: the QML renderer needs Qt 6.5+.
- name: Install Qt ${{ env.QT_VERSION }}
uses: jurplel/install-qt-action@v4
with:
version: ${{ env.QT_VERSION }}
modules: qtwebsockets
cache: true
- name: Restore sccache
uses: actions/cache/restore@v4
with:
path: /home/runner/.cache/sccache
key: sccache-clang-tidy
- name: Install sccache
run: |
curl -sSL https://github.com/mozilla/sccache/releases/download/v0.9.1/sccache-v0.9.1-x86_64-unknown-linux-musl.tar.gz \
| tar -xz --strip-components=1 -C /usr/local/bin sccache-v0.9.1-x86_64-unknown-linux-musl/sccache
# Every optional feature is ON here purely so its sources land in
# compile_commands.json. clang-tidy only ever analyses *changed lines*, so
# this costs a wider build, not a wider lint. Configured narrowly before,
# the whole opt-in surface — morph::net, the Qt transport, the QML forms
# renderer, the SQLite queue, the fuzz harnesses — was invisible to the
# one gate in this workflow that reads code rather than running it.
- name: Configure (generates compile_commands.json over every optional feature)
run: |
cmake --preset clang-debug \
-DMORPH_BUILD_NET=ON \
-DMORPH_BUILD_QT=ON \
-DMORPH_BUILD_FORMS_QML=ON \
-DMORPH_BUILD_OFFLINE_SQLITE=ON \
-DMORPH_BUILD_LOAD_TESTS=ON \
-DMORPH_BUILD_HMAC_EXAMPLES=ON \
-DMORPH_BUILD_FUZZERS=ON \
-DCMAKE_C_COMPILER=clang-${{ env.CLANG_VERSION }} \
-DCMAKE_CXX_COMPILER=clang++-${{ env.CLANG_VERSION }} \
-DCMAKE_C_COMPILER_LAUNCHER=sccache \
-DCMAKE_CXX_COMPILER_LAUNCHER=sccache
- name: Build
run: cmake --build --preset clang-debug
- name: Run clang-tidy-diff on changed lines
run: |
if [ "${{ github.event_name }}" = "pull_request" ]; then
BASE_SHA="${{ github.event.pull_request.base.sha }}"
else
BASE_SHA="${{ github.event.before }}"
fi
CLANG_TIDY_DIFF="$(find /usr/lib/llvm-${{ env.CLANG_VERSION }}/share/clang /usr/share/clang \
-name 'clang-tidy-diff.py' 2>/dev/null | head -1)"
if [ -z "$CLANG_TIDY_DIFF" ]; then
echo "::error::clang-tidy-diff.py not found"
exit 1
fi
echo "Base SHA: $BASE_SHA"
echo "Script: $CLANG_TIDY_DIFF"
git diff -U0 "$BASE_SHA" | \
python3 "$CLANG_TIDY_DIFF" \
-path build/clang-debug \
-clang-tidy-binary clang-tidy-${{ env.CLANG_VERSION }} \
-p1 \
-j "$(nproc)" \
-extra-arg=-std=c++23 \
-extra-arg=-warnings-as-errors=* \
-quiet \
2>&1 | tee clang-tidy-report.txt
- name: Upload clang-tidy report
if: always()
uses: actions/upload-artifact@v4
with:
name: clang-tidy-report
path: clang-tidy-report.txt
- name: Evict previous sccache entry
if: always()
continue-on-error: true
run: gh cache delete "sccache-clang-tidy"
env:
GH_TOKEN: ${{ github.token }}
- name: Save sccache
if: always()
uses: actions/cache/save@v4
with:
path: /home/runner/.cache/sccache
key: sccache-clang-tidy
# ── Deprecation-marker format lint ────────────────────────────────────
deprecation-lint:
name: Deprecation marker format
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v4
# The checker itself is tested first. A lint gate nobody tests reports
# green whether or not it still detects anything — this one was blind to
# both the bare `[[deprecated]]` form and any message wrapped across
# lines, which is exactly what VERSIONING.md forbids.
- name: Self-test the deprecation-marker checker
run: bash scripts/test_check_deprecated_markers.sh
- name: Check [[deprecated]] markers cite a replacement and removal version
run: bash scripts/check_deprecated_markers.sh include/morph