178 lines
7.5 KiB
YAML
178 lines
7.5 KiB
YAML
# Reusable: unit + integration tests on all platforms
|
|
name: Test
|
|
|
|
on:
|
|
workflow_call:
|
|
inputs:
|
|
skip_perf:
|
|
description: 'Skip incremental perf tests (phases 2-7)'
|
|
type: boolean
|
|
default: true
|
|
broad_platforms:
|
|
description: 'Test the broad platform matrix (older glibc + extra OS versions) instead of the core set'
|
|
type: boolean
|
|
default: false
|
|
|
|
permissions:
|
|
contents: read
|
|
|
|
jobs:
|
|
# Emit the platform matrices as JSON. The CORE set is the default (fast,
|
|
# unchanged); the BROAD set adds extra free runners (older glibc /
|
|
# additional OS versions) for a wider "does it build everywhere" picture.
|
|
setup-matrix:
|
|
runs-on: ubuntu-latest
|
|
timeout-minutes: 5
|
|
outputs:
|
|
unix: ${{ steps.set.outputs.unix }}
|
|
windows: ${{ steps.set.outputs.windows }}
|
|
steps:
|
|
- name: Compute matrices
|
|
id: set
|
|
env:
|
|
BROAD: ${{ inputs.broad_platforms }}
|
|
run: |
|
|
CORE_UNIX='[
|
|
{"os":"ubuntu-latest","cc":"gcc","cxx":"g++"},
|
|
{"os":"ubuntu-24.04-arm","cc":"gcc","cxx":"g++"},
|
|
{"os":"macos-14","cc":"cc","cxx":"c++"},
|
|
{"os":"macos-15-intel","cc":"cc","cxx":"c++"}
|
|
]'
|
|
# Broad matrix legs are REQUIRED gates (no optional/continue-on-error
|
|
# escape hatches): the release dry run must be all-green, every platform.
|
|
BROAD_UNIX='[
|
|
{"os":"ubuntu-22.04","cc":"gcc","cxx":"g++"},
|
|
{"os":"ubuntu-22.04-arm","cc":"gcc","cxx":"g++"},
|
|
{"os":"macos-15","cc":"cc","cxx":"c++"}
|
|
]'
|
|
# Each Windows leg pins the msys2 environment + package arch to the
|
|
# RUNNER architecture so the build is native, never emulated:
|
|
# x86-64 runners -> CLANG64 (mingw-w64-clang-x86_64-*)
|
|
# ARM64 runner -> CLANGARM64 (mingw-w64-clang-aarch64-*)
|
|
# windows-11-arm previously used the x86-64 CLANG64 toolchain, so its
|
|
# binary ran under Windows-on-ARM x86-64 emulation and ASan's function
|
|
# interception crashed (interception_win: unhandled instruction). With
|
|
# the native ARM64 toolchain ASan instruments native ARM64 code, so it
|
|
# is a real (non-optional) gate, not a tolerated emulated-flake.
|
|
CORE_WIN='[{"os":"windows-latest","msystem":"CLANG64","pkg":"x86_64"}]'
|
|
BROAD_WIN='[{"os":"windows-2025","msystem":"CLANG64","pkg":"x86_64"},{"os":"windows-11-arm","msystem":"CLANGARM64","pkg":"aarch64"}]'
|
|
if [ "$BROAD" = "true" ]; then
|
|
UNIX=$(jq -cn --argjson a "$CORE_UNIX" --argjson b "$BROAD_UNIX" '$a + $b')
|
|
WIN=$(jq -cn --argjson a "$CORE_WIN" --argjson b "$BROAD_WIN" '$a + $b')
|
|
else
|
|
UNIX=$(jq -cn --argjson a "$CORE_UNIX" '$a')
|
|
WIN=$(jq -cn --argjson a "$CORE_WIN" '$a')
|
|
fi
|
|
echo "unix={\"include\":$UNIX}" >> "$GITHUB_OUTPUT"
|
|
echo "windows={\"include\":$WIN}" >> "$GITHUB_OUTPUT"
|
|
|
|
test-unix:
|
|
needs: setup-matrix
|
|
strategy:
|
|
fail-fast: false
|
|
matrix: ${{ fromJSON(needs.setup-matrix.outputs.unix) }}
|
|
runs-on: ${{ matrix.os }}
|
|
# Broad-only legs (extra OS versions) are informational: visible but
|
|
# non-blocking, so a flaky/less-common runner can't block a release.
|
|
continue-on-error: ${{ matrix.optional == true }}
|
|
timeout-minutes: 240
|
|
steps:
|
|
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
|
|
|
- name: Install deps (Ubuntu)
|
|
if: startsWith(matrix.os, 'ubuntu')
|
|
run: sudo apt-get update && sudo apt-get install -y zlib1g-dev
|
|
|
|
- name: Test
|
|
run: scripts/test.sh CC=${{ matrix.cc }} CXX=${{ matrix.cxx }}
|
|
env:
|
|
CBM_SKIP_PERF: ${{ inputs.skip_perf && '1' || '' }}
|
|
|
|
test-tsan:
|
|
runs-on: ubuntu-latest
|
|
timeout-minutes: 120
|
|
steps:
|
|
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
|
|
|
- name: Install deps (Ubuntu)
|
|
run: sudo apt-get update && sudo apt-get install -y clang zlib1g-dev
|
|
|
|
- name: ThreadSanitizer tests
|
|
run: make -f Makefile.cbm test-tsan CC=clang CXX=clang++
|
|
|
|
test-windows:
|
|
needs: setup-matrix
|
|
strategy:
|
|
fail-fast: false
|
|
matrix: ${{ fromJSON(needs.setup-matrix.outputs.windows) }}
|
|
runs-on: ${{ matrix.os }}
|
|
continue-on-error: ${{ matrix.optional == true }}
|
|
timeout-minutes: 240
|
|
steps:
|
|
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
|
|
|
- uses: msys2/setup-msys2@66cd2cce69caa17b53920067426061ca1de3a884 # v2
|
|
with:
|
|
msystem: ${{ matrix.msystem }}
|
|
path-type: inherit
|
|
install: >-
|
|
mingw-w64-clang-${{ matrix.pkg }}-clang
|
|
mingw-w64-clang-${{ matrix.pkg }}-compiler-rt
|
|
mingw-w64-clang-${{ matrix.pkg }}-zlib
|
|
make
|
|
git
|
|
|
|
- name: Test
|
|
shell: msys2 {0}
|
|
# AddressSanitizer is unavailable on native ARM64 Windows (LLVM ships no
|
|
# libclang_rt.asan for aarch64-w64-windows-gnu) and cannot intercept the
|
|
# system DLLs under x86-64 emulation either, so windows-11-arm runs the
|
|
# native ARM64 build with SANITIZE= (no sanitizer) — still a real
|
|
# functional gate. ASan/UBSan coverage comes from the other 9 legs,
|
|
# including native-ARM Linux/macOS. x86-64 Windows keeps full sanitizers.
|
|
run: scripts/test.sh CC=clang CXX=clang++ ${{ matrix.os == 'windows-11-arm' && 'SANITIZE=' || '' }}
|
|
env:
|
|
CBM_SKIP_PERF: ${{ inputs.skip_perf && '1' || '' }}
|
|
|
|
# Windows product-surface regression guards. Distinct from test-windows above
|
|
# (the sanitizer C suite): these drive a real product binary + embedded HTTP UI
|
|
# over stdio / CLI / HTTP and fail if a Windows bug already fixed on main comes
|
|
# back -- non-ASCII repo paths dropping definitions (#636/#357, fixed by #700),
|
|
# the PreToolUse hook augmenter no-op on drive-letter cwd (#618, fixed by #619),
|
|
# the UI directory picker not enumerating drives (#548, roots field), and non-ASCII
|
|
# CLI arguments being mangled by the narrow-argv main() (#423/#20, fixed by the
|
|
# wide-argv entrypoint that reads GetCommandLineW).
|
|
test-windows-guards:
|
|
runs-on: windows-latest
|
|
timeout-minutes: 60
|
|
steps:
|
|
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
|
|
|
- uses: msys2/setup-msys2@66cd2cce69caa17b53920067426061ca1de3a884 # v2
|
|
with:
|
|
msystem: CLANG64
|
|
path-type: inherit
|
|
install: >-
|
|
mingw-w64-clang-x86_64-clang
|
|
mingw-w64-clang-x86_64-zlib
|
|
make
|
|
git
|
|
|
|
- uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
|
|
with:
|
|
node-version: "22"
|
|
|
|
- name: Build product binary with embedded UI
|
|
shell: msys2 {0}
|
|
# --with-ui builds the frontend (npm) and embeds it, so the drive-picker
|
|
# guard's HTTP UI is available. Functional gate only (no sanitizers).
|
|
run: scripts/build.sh --with-ui CC=clang CXX=clang++
|
|
|
|
- name: Windows regression guards (#636/#357, #618, #548, #423/#20)
|
|
shell: pwsh
|
|
# -GuardsOnly runs the four green guards and gates on them. The runner sets
|
|
# CBM_INDEX_SUPERVISOR=0 for determinism, but the non-ASCII CLI guard drops that
|
|
# override so it exercises the real supervisor->worker spawn (where #423/#20's
|
|
# second half lives); the other guards test path/hook/drive fixes in-process.
|
|
run: ./scripts/test-windows.ps1 -GuardsOnly -Binary build/c/codebase-memory-mcp.exe
|