Dry Run #73
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Dry Run | |
| on: | |
| workflow_dispatch: | |
| inputs: | |
| skip_lint: | |
| description: 'Skip lint step (faster iteration)' | |
| type: boolean | |
| default: false | |
| skip_tests: | |
| description: 'Skip test steps (faster iteration on build/smoke)' | |
| type: boolean | |
| default: false | |
| skip_builds: | |
| description: 'Skip build+smoke steps (faster iteration on lint/tests)' | |
| type: boolean | |
| default: false | |
| permissions: | |
| contents: read | |
| jobs: | |
| # ── Step 1: Lint (clang-format + cppcheck) ─────────────────── | |
| lint: | |
| if: ${{ !inputs.skip_lint }} | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Install build deps | |
| run: sudo apt-get update && sudo apt-get install -y zlib1g-dev cmake | |
| - name: Install LLVM 20 | |
| run: | | |
| wget -qO- https://apt.llvm.org/llvm-snapshot.gpg.key | sudo tee /etc/apt/trusted.gpg.d/apt.llvm.org.asc | |
| echo "deb http://apt.llvm.org/noble/ llvm-toolchain-noble-20 main" | sudo tee /etc/apt/sources.list.d/llvm-20.list | |
| sudo apt-get update | |
| sudo apt-get install -y clang-format-20 | |
| - uses: actions/cache@v4 | |
| id: cppcheck-cache | |
| with: | |
| path: /opt/cppcheck | |
| key: cppcheck-2.20.0-ubuntu-amd64 | |
| - name: Build cppcheck 2.20.0 | |
| if: steps.cppcheck-cache.outputs.cache-hit != 'true' | |
| run: | | |
| git clone --depth 1 --branch 2.20.0 https://github.com/danmar/cppcheck.git /tmp/cppcheck | |
| cmake -S /tmp/cppcheck -B /tmp/cppcheck/build -DCMAKE_BUILD_TYPE=Release -DHAVE_RULES=OFF -DCMAKE_INSTALL_PREFIX=/opt/cppcheck | |
| cmake --build /tmp/cppcheck/build -j$(nproc) | |
| cmake --install /tmp/cppcheck/build | |
| - name: Add cppcheck to PATH | |
| run: echo "/opt/cppcheck/bin" >> "$GITHUB_PATH" | |
| - name: Lint | |
| run: scripts/lint.sh CLANG_FORMAT=clang-format-20 | |
| # ── Step 1b: Security audit (source-only, runs parallel with lint+tests) ── | |
| # No build needed — scans source files and vendored deps only. | |
| # Binary-level security (L2/L3/L4/L7) runs in smoke jobs per-platform. | |
| security-static: | |
| if: ${{ !inputs.skip_lint }} | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: "Layer 1: Static allow-list audit" | |
| run: scripts/security-audit.sh | |
| - name: "Layer 6: UI security audit" | |
| run: scripts/security-ui.sh | |
| - name: "Layer 8: Vendored dependency integrity" | |
| run: scripts/security-vendored.sh | |
| # ── Step 2: Unit tests (ASan + UBSan) ─────────────────────── | |
| # macOS: use cc (Apple Clang) — GCC on macOS doesn't ship ASan runtime | |
| # Linux: use system gcc — full ASan/UBSan support | |
| # Windows: MSYS2 MinGW GCC | |
| test-unix: | |
| if: ${{ !inputs.skip_tests && always() && (needs.lint.result == 'success' || needs.lint.result == 'skipped') }} | |
| needs: [lint] | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| include: | |
| - os: ubuntu-latest | |
| arch: amd64 | |
| cc: gcc | |
| cxx: g++ | |
| - os: ubuntu-24.04-arm | |
| arch: arm64 | |
| cc: gcc | |
| cxx: g++ | |
| - os: macos-14 | |
| arch: arm64 | |
| cc: cc | |
| cxx: c++ | |
| - os: macos-15-intel | |
| arch: amd64 | |
| cc: cc | |
| cxx: c++ | |
| runs-on: ${{ matrix.os }} | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - 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 }} | |
| test-windows: | |
| if: ${{ !inputs.skip_tests && always() && (needs.lint.result == 'success' || needs.lint.result == 'skipped') }} | |
| needs: [lint] | |
| runs-on: windows-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: msys2/setup-msys2@v2 | |
| with: | |
| msystem: CLANG64 | |
| path-type: inherit | |
| install: >- | |
| mingw-w64-clang-x86_64-clang | |
| mingw-w64-clang-x86_64-compiler-rt | |
| mingw-w64-clang-x86_64-zlib | |
| make | |
| - name: Test | |
| shell: msys2 {0} | |
| run: scripts/test.sh CC=clang CXX=clang++ | |
| # ── Step 3: Build binaries (standard + UI, all OS) ────────── | |
| build-unix: | |
| if: ${{ !inputs.skip_builds && always() && (needs.test-unix.result == 'success' || needs.test-unix.result == 'skipped') && (needs.test-windows.result == 'success' || needs.test-windows.result == 'skipped') }} | |
| needs: [test-unix, test-windows] | |
| strategy: | |
| 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 }} | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Install deps (Ubuntu) | |
| if: startsWith(matrix.os, 'ubuntu') | |
| run: sudo apt-get update && sudo apt-get install -y zlib1g-dev | |
| - uses: actions/setup-node@v4 | |
| with: | |
| node-version: "22" | |
| - name: Build standard binary | |
| run: scripts/build.sh CC=${{ matrix.cc }} CXX=${{ matrix.cxx }} | |
| - name: Archive standard binary | |
| run: | | |
| tar -czf codebase-memory-mcp-${{ matrix.goos }}-${{ matrix.goarch }}.tar.gz \ | |
| -C build/c codebase-memory-mcp | |
| - name: Build UI binary | |
| run: scripts/build.sh --with-ui CC=${{ matrix.cc }} CXX=${{ matrix.cxx }} | |
| - name: Frontend integrity scan (post-build dist/) | |
| if: matrix.goos == 'linux' && matrix.goarch == 'amd64' | |
| run: scripts/security-ui.sh | |
| - name: Archive UI binary | |
| run: | | |
| tar -czf codebase-memory-mcp-ui-${{ matrix.goos }}-${{ matrix.goarch }}.tar.gz \ | |
| -C build/c codebase-memory-mcp | |
| - uses: actions/upload-artifact@v4 | |
| with: | |
| name: binaries-${{ matrix.goos }}-${{ matrix.goarch }} | |
| path: "*.tar.gz" | |
| build-windows: | |
| if: ${{ !inputs.skip_builds && always() && (needs.test-unix.result == 'success' || needs.test-unix.result == 'skipped') && (needs.test-windows.result == 'success' || needs.test-windows.result == 'skipped') }} | |
| needs: [test-unix, test-windows] | |
| runs-on: windows-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: msys2/setup-msys2@v2 | |
| with: | |
| msystem: CLANG64 | |
| path-type: inherit | |
| install: >- | |
| mingw-w64-clang-x86_64-clang | |
| mingw-w64-clang-x86_64-zlib | |
| make | |
| zip | |
| - uses: actions/setup-node@v4 | |
| with: | |
| node-version: "22" | |
| - name: Build standard binary | |
| shell: msys2 {0} | |
| run: scripts/build.sh CC=clang CXX=clang++ | |
| - name: Archive standard binary | |
| shell: msys2 {0} | |
| run: | | |
| BIN=build/c/codebase-memory-mcp | |
| [ -f "${BIN}.exe" ] && BIN="${BIN}.exe" | |
| cp "$BIN" codebase-memory-mcp.exe | |
| zip codebase-memory-mcp-windows-amd64.zip codebase-memory-mcp.exe | |
| - name: Build UI binary | |
| shell: msys2 {0} | |
| run: scripts/build.sh --with-ui CC=clang CXX=clang++ | |
| - name: Archive UI binary | |
| shell: msys2 {0} | |
| run: | | |
| BIN=build/c/codebase-memory-mcp | |
| [ -f "${BIN}.exe" ] && BIN="${BIN}.exe" | |
| cp "$BIN" codebase-memory-mcp-ui.exe | |
| zip codebase-memory-mcp-ui-windows-amd64.zip codebase-memory-mcp-ui.exe | |
| - uses: actions/upload-artifact@v4 | |
| with: | |
| name: binaries-windows-amd64 | |
| path: "*.zip" | |
| # ── Step 4: Smoke test every binary ───────────────────────── | |
| smoke-unix: | |
| if: ${{ !inputs.skip_builds }} | |
| needs: [build-unix] | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| include: | |
| - os: ubuntu-latest | |
| goos: linux | |
| goarch: amd64 | |
| - os: ubuntu-24.04-arm | |
| goos: linux | |
| goarch: arm64 | |
| - os: macos-14 | |
| goos: darwin | |
| goarch: arm64 | |
| - os: macos-15-intel | |
| goos: darwin | |
| goarch: amd64 | |
| variant: [standard, ui] | |
| runs-on: ${{ matrix.os }} | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: actions/download-artifact@v4 | |
| with: | |
| name: binaries-${{ matrix.goos }}-${{ matrix.goarch }} | |
| - name: Extract binary | |
| run: | | |
| SUFFIX=${{ matrix.variant == 'ui' && '-ui' || '' }} | |
| tar -xzf codebase-memory-mcp${SUFFIX}-${{ matrix.goos }}-${{ matrix.goarch }}.tar.gz | |
| chmod +x codebase-memory-mcp | |
| - name: Smoke test (${{ matrix.variant }}, ${{ matrix.goos }}-${{ matrix.goarch }}) | |
| run: scripts/smoke-test.sh ./codebase-memory-mcp | |
| - name: Binary string audit (${{ matrix.goos }}-${{ matrix.goarch }}) | |
| if: matrix.variant == 'standard' | |
| run: scripts/security-strings.sh ./codebase-memory-mcp | |
| - name: Install output audit (${{ matrix.goos }}-${{ matrix.goarch }}) | |
| if: matrix.variant == 'standard' | |
| run: scripts/security-install.sh ./codebase-memory-mcp | |
| - name: Network egress test (${{ matrix.goos }}-${{ matrix.goarch }}) | |
| if: matrix.variant == 'standard' | |
| run: scripts/security-network.sh ./codebase-memory-mcp | |
| - name: MCP robustness test | |
| if: matrix.variant == 'standard' && matrix.goos == 'linux' && matrix.goarch == 'amd64' | |
| run: scripts/security-fuzz.sh ./codebase-memory-mcp | |
| smoke-windows: | |
| if: ${{ !inputs.skip_builds }} | |
| needs: [build-windows] | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| variant: [standard, ui] | |
| runs-on: windows-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: msys2/setup-msys2@v2 | |
| with: | |
| msystem: CLANG64 | |
| path-type: inherit | |
| install: >- | |
| mingw-w64-clang-x86_64-python3 | |
| unzip | |
| - uses: actions/download-artifact@v4 | |
| with: | |
| name: binaries-windows-amd64 | |
| - name: Extract binary | |
| shell: msys2 {0} | |
| run: | | |
| SUFFIX=${{ matrix.variant == 'ui' && '-ui' || '' }} | |
| unzip -o "codebase-memory-mcp${SUFFIX}-windows-amd64.zip" | |
| [ -n "$SUFFIX" ] && cp "codebase-memory-mcp${SUFFIX}.exe" codebase-memory-mcp.exe || true | |
| - name: Smoke test (${{ matrix.variant }}, windows-amd64) | |
| shell: msys2 {0} | |
| run: scripts/smoke-test.sh ./codebase-memory-mcp.exe | |
| - name: Binary string audit (windows-amd64) | |
| if: matrix.variant == 'standard' | |
| shell: msys2 {0} | |
| run: scripts/security-strings.sh ./codebase-memory-mcp.exe | |
| - name: Install output audit (windows-amd64) | |
| if: matrix.variant == 'standard' | |
| shell: msys2 {0} | |
| run: scripts/security-install.sh ./codebase-memory-mcp.exe |