Files
codebase-memory-mcp/.github/workflows/_soak.yml
T
Andrew Hundt e8693d2443 fix(build): apply documented compiler and linker overrides
Append EXTRA_CFLAGS, EXTRA_CXXFLAGS, and EXTRA_LDFLAGS in Makefile.cbm after the optimized production defaults. Add EXTRA_CXXFLAGS to both ASan jobs in .github/workflows/_soak.yml so commit 87188913 sanitizer arguments instrument C++ sources as well as C sources and the final link.

Document the scripts/build.sh debug invocation in README.md while retaining -O2 and CBM_BIND_TS_ALLOCATOR=1 for ordinary builds. A forced make dry-run places distinct sentinels on the C compile, C++ compile, and link commands; bash -n, scripts/check-source-safety.sh, and git diff --check pass.

Signed-off-by: Andrew Hundt <ATHundt@gmail.com>
2026-07-14 13:47:39 -04:00

277 lines
10 KiB
YAML

# Reusable: soak tests (quick + ASan, all platforms)
name: Soak
on:
workflow_call:
inputs:
duration_minutes:
description: 'Soak duration in minutes'
type: number
default: 10
run_asan:
description: 'Run ASan soak in addition to quick soak'
type: boolean
default: false
version:
description: 'Version string for build'
type: string
default: ''
permissions:
contents: read
jobs:
soak-quick:
strategy:
fail-fast: false
matrix:
include:
- os: ubuntu-latest
goos: linux
goarch: amd64
cc: gcc
cxx: g++
- os: ubuntu-24.04-arm
goos: linux
goarch: arm64
cc: gcc
cxx: g++
- os: macos-14
goos: darwin
goarch: arm64
cc: cc
cxx: c++
- os: macos-15-intel
goos: darwin
goarch: amd64
cc: cc
cxx: c++
runs-on: ${{ matrix.os }}
# Nightly callers pass 240 minutes; include build, idle, and analysis headroom.
timeout-minutes: 300
steps:
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
- name: Install deps (Linux)
if: startsWith(matrix.os, 'ubuntu')
run: sudo apt-get update && sudo apt-get install -y zlib1g-dev python3 git
- name: Build
run: scripts/build.sh ${{ inputs.version && format('--version {0}', inputs.version) || '' }} CC=${{ matrix.cc }} CXX=${{ matrix.cxx }}
- name: Soak (${{ inputs.duration_minutes }} min)
run: scripts/soak-test.sh build/c/codebase-memory-mcp ${{ inputs.duration_minutes }}
# #581 guard: read-only soak (never reindex/mutate) so any memory growth is
# a query-path leak, not WAL/indexing. Reuses the build above.
- name: Query-leak soak (#581, read-only)
env:
CBM_SOAK_MODE: query-leak
CBM_SOAK_RESULTS_DIR: soak-results-query-leak
run: scripts/soak-test.sh build/c/codebase-memory-mcp ${{ inputs.duration_minutes }} --skip-crash-test
- name: Upload metrics
if: always()
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: soak-quick-${{ matrix.goos }}-${{ matrix.goarch }}
path: soak-results/
retention-days: 14
- name: Upload query-leak metrics
if: always()
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: soak-query-leak-${{ matrix.goos }}-${{ matrix.goarch }}
path: soak-results-query-leak/
retention-days: 14
soak-quick-windows:
runs-on: windows-latest
# BUG FIX (same 30→240 mismatch as soak-quick above): the caller passes
# duration_minutes: 240, so a 30-min cap truncated the nightly soak here
# too. 300 covers the 240-min nightly with headroom.
timeout-minutes: 300
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
mingw-w64-clang-x86_64-python3
make
git
coreutils
- name: Build
shell: msys2 {0}
run: scripts/build.sh ${{ inputs.version && format('--version {0}', inputs.version) || '' }} CC=clang CXX=clang++
- name: Soak (${{ inputs.duration_minutes }} min)
shell: msys2 {0}
run: |
BIN=build/c/codebase-memory-mcp
[ -f "${BIN}.exe" ] && BIN="${BIN}.exe"
scripts/soak-test.sh "$BIN" ${{ inputs.duration_minutes }}
# #581 guard on Windows — the platform the bug is reported on.
- name: Query-leak soak (#581, read-only)
shell: msys2 {0}
env:
CBM_SOAK_MODE: query-leak
CBM_SOAK_RESULTS_DIR: soak-results-query-leak
run: |
BIN=build/c/codebase-memory-mcp
[ -f "${BIN}.exe" ] && BIN="${BIN}.exe"
scripts/soak-test.sh "$BIN" ${{ inputs.duration_minutes }} --skip-crash-test
- name: Upload metrics
if: always()
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: soak-quick-windows-amd64
path: soak-results/
retention-days: 14
- name: Upload query-leak metrics
if: always()
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: soak-query-leak-windows-amd64
path: soak-results-query-leak/
retention-days: 14
soak-quick-windows-arm64:
# Native ARM64 Windows soak (CLANGARM64, no sanitizer — ASan is unavailable
# on native ARM64 Windows). Builds from source like soak-quick-windows.
runs-on: windows-11-arm
timeout-minutes: 300
steps:
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
- uses: msys2/setup-msys2@66cd2cce69caa17b53920067426061ca1de3a884 # v2
with:
msystem: CLANGARM64
path-type: inherit
install: >-
mingw-w64-clang-aarch64-clang
mingw-w64-clang-aarch64-zlib
mingw-w64-clang-aarch64-python3
make
git
coreutils
- name: Build
shell: msys2 {0}
run: scripts/build.sh ${{ inputs.version && format('--version {0}', inputs.version) || '' }} CC=clang CXX=clang++
- name: Soak (${{ inputs.duration_minutes }} min)
shell: msys2 {0}
run: |
BIN=build/c/codebase-memory-mcp
[ -f "${BIN}.exe" ] && BIN="${BIN}.exe"
scripts/soak-test.sh "$BIN" ${{ inputs.duration_minutes }}
# #581 guard on Windows — the platform the bug is reported on.
- name: Query-leak soak (#581, read-only)
shell: msys2 {0}
env:
CBM_SOAK_MODE: query-leak
CBM_SOAK_RESULTS_DIR: soak-results-query-leak
run: |
BIN=build/c/codebase-memory-mcp
[ -f "${BIN}.exe" ] && BIN="${BIN}.exe"
scripts/soak-test.sh "$BIN" ${{ inputs.duration_minutes }} --skip-crash-test
- name: Upload metrics
if: always()
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: soak-quick-windows-arm64
path: soak-results/
retention-days: 14
- name: Upload query-leak metrics
if: always()
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: soak-query-leak-windows-arm64
path: soak-results-query-leak/
retention-days: 14
soak-asan:
if: ${{ inputs.run_asan }}
strategy:
fail-fast: false
matrix:
include:
- os: ubuntu-latest
goos: linux
goarch: amd64
cc: gcc
cxx: g++
- os: ubuntu-24.04-arm
goos: linux
goarch: arm64
cc: gcc
cxx: g++
- os: macos-14
goos: darwin
goarch: arm64
cc: cc
cxx: c++
- os: macos-15-intel
goos: darwin
goarch: amd64
cc: cc
cxx: c++
runs-on: ${{ matrix.os }}
# ASan runs a fixed 15-minute workload, but ARM builds and teardown can be slow.
timeout-minutes: 240
steps:
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
- name: Install deps (Linux)
if: startsWith(matrix.os, 'ubuntu')
run: sudo apt-get update && sudo apt-get install -y zlib1g-dev python3 git
- name: Build (ASan)
run: |
SANITIZE="-fsanitize=address,undefined -fno-omit-frame-pointer"
scripts/build.sh ${{ inputs.version && format('--version {0}', inputs.version) || '' }} CC=${{ matrix.cc }} CXX=${{ matrix.cxx }} EXTRA_CFLAGS="$SANITIZE" EXTRA_CXXFLAGS="$SANITIZE" EXTRA_LDFLAGS="$SANITIZE"
- name: ASan soak (15 min)
env:
ASAN_OPTIONS: "detect_leaks=1:halt_on_error=0:log_path=soak-results/asan"
run: scripts/soak-test.sh build/c/codebase-memory-mcp 15
- name: Upload metrics
if: always()
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: soak-asan-${{ matrix.goos }}-${{ matrix.goarch }}
path: soak-results/
retention-days: 14
soak-asan-windows:
if: ${{ inputs.run_asan }}
runs-on: windows-latest
# Fixed 15-minute soak. The Windows ASan build and teardown are the slowest
# path, so retain the established four-hour job budget.
timeout-minutes: 240
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
mingw-w64-clang-x86_64-python3
make
git
coreutils
- name: Build (ASan)
shell: msys2 {0}
run: |
SANITIZE="-fsanitize=address,undefined -fno-omit-frame-pointer"
scripts/build.sh ${{ inputs.version && format('--version {0}', inputs.version) || '' }} CC=clang CXX=clang++ EXTRA_CFLAGS="$SANITIZE" EXTRA_CXXFLAGS="$SANITIZE" EXTRA_LDFLAGS="$SANITIZE"
- name: ASan soak (15 min, no leak detection)
shell: msys2 {0}
env:
ASAN_OPTIONS: "detect_leaks=0:halt_on_error=0:log_path=soak-results/asan"
run: |
BIN=build/c/codebase-memory-mcp
[ -f "${BIN}.exe" ] && BIN="${BIN}.exe"
scripts/soak-test.sh "$BIN" 15
- name: Upload metrics
if: always()
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: soak-asan-windows-amd64
path: soak-results/
retention-days: 14