|
| 1 | +name: Hardening |
| 2 | + |
| 3 | +# Memory-safety / data-race hardening for fluxgraph. |
| 4 | +# - tsan: ThreadSanitizer over the gRPC server (its state_mutex_ + tick_cv_ |
| 5 | +# worker coordination), exercised by the Python integration tests. |
| 6 | +# - valgrind: shared org leak-check over the core unit-test binary. |
| 7 | +# - fuzz: shared org libFuzzer runner over the JSON + YAML graph loaders |
| 8 | +# (the untrusted-input parsers). |
| 9 | +# Findings fail only when first-party; third-party false positives are scoped in |
| 10 | +# tsan.supp / valgrind.supp (first run per change = triage pass). |
| 11 | + |
| 12 | +on: |
| 13 | + push: |
| 14 | + branches: [main] |
| 15 | + paths-ignore: |
| 16 | + - "docs/**" |
| 17 | + - "**/*.md" |
| 18 | + pull_request: |
| 19 | + branches: [main] |
| 20 | + paths-ignore: |
| 21 | + - "docs/**" |
| 22 | + - "**/*.md" |
| 23 | + workflow_dispatch: |
| 24 | + |
| 25 | +concurrency: |
| 26 | + group: fluxgraph-hardening-${{ github.ref }} |
| 27 | + cancel-in-progress: true |
| 28 | + |
| 29 | +permissions: |
| 30 | + contents: read |
| 31 | + |
| 32 | +jobs: |
| 33 | + tsan: |
| 34 | + name: ThreadSanitizer (server) |
| 35 | + runs-on: ubuntu-24.04 |
| 36 | + timeout-minutes: 150 |
| 37 | + steps: |
| 38 | + - name: Checkout |
| 39 | + uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6 |
| 40 | + |
| 41 | + - name: Install system dependencies |
| 42 | + run: | |
| 43 | + sudo apt-get update |
| 44 | + sudo apt-get install -y ninja-build g++ |
| 45 | +
|
| 46 | + - uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6 |
| 47 | + with: |
| 48 | + python-version: "3.12" |
| 49 | + |
| 50 | + - uses: astral-sh/setup-uv@fac544c07dec837d0ccb6301d7b5580bf5edae39 # v8.2.0 |
| 51 | + with: |
| 52 | + enable-cache: true |
| 53 | + |
| 54 | + - name: Install Python integration deps |
| 55 | + run: uv sync --locked --extra dev |
| 56 | + |
| 57 | + - name: Setup vcpkg |
| 58 | + uses: anolishq/.github/.github/actions/setup-vcpkg@0f4d8cd3c04dcb17fe128248a147b237c1465e0c # v2 |
| 59 | + with: |
| 60 | + triplet: x64-linux |
| 61 | + |
| 62 | + - name: Configure |
| 63 | + run: cmake --preset ci-tsan -DPython3_EXECUTABLE="$(pwd)/.venv/bin/python" |
| 64 | + |
| 65 | + - name: Build |
| 66 | + run: cmake --build --preset ci-tsan --parallel |
| 67 | + |
| 68 | + - name: Generate Python protobuf bindings |
| 69 | + run: bash ./scripts/generate_proto_python.sh "$(pwd)/build/ci-tsan/python" |
| 70 | + |
| 71 | + - name: Run tests with TSAN |
| 72 | + env: |
| 73 | + TSAN_OPTIONS: "suppressions=${{ github.workspace }}/tsan.supp second_deadlock_stack=1 detect_deadlocks=1 history_size=7 log_path=${{ github.workspace }}/tsan-report" |
| 74 | + run: | |
| 75 | + set +e |
| 76 | + set -o pipefail |
| 77 | + export CTEST_PARALLEL_LEVEL=1 |
| 78 | + timeout 40m ctest --preset ci-tsan --timeout 600 -VV 2>&1 | tee tsan-output.log |
| 79 | + EXIT_CODE=${PIPESTATUS[0]} |
| 80 | +
|
| 81 | + if ls tsan-report.* >/dev/null 2>&1; then |
| 82 | + echo "::error::ThreadSanitizer reported data races (see tsan-logs artifact)" |
| 83 | + exit 1 |
| 84 | + fi |
| 85 | +
|
| 86 | + exit $EXIT_CODE |
| 87 | +
|
| 88 | + - name: Upload TSAN logs |
| 89 | + if: always() |
| 90 | + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7 |
| 91 | + with: |
| 92 | + name: tsan-logs-${{ github.run_number }} |
| 93 | + path: | |
| 94 | + tsan-report.* |
| 95 | + tsan-output.log |
| 96 | + build/ci-tsan/Testing/Temporary/LastTest.log |
| 97 | + if-no-files-found: ignore |
| 98 | + retention-days: 14 |
| 99 | + |
| 100 | + valgrind: |
| 101 | + name: Valgrind leak-check |
| 102 | + uses: anolishq/.github/.github/workflows/valgrind-leak.yml@0f4d8cd3c04dcb17fe128248a147b237c1465e0c # v2 |
| 103 | + with: |
| 104 | + triplet: x64-linux |
| 105 | + build-preset: ci-linux-release |
| 106 | + build-target: fluxgraph_tests |
| 107 | + run: "build/ci-linux-release/tests/fluxgraph_tests" |
| 108 | + suppressions: valgrind.supp |
| 109 | + |
| 110 | + fuzz: |
| 111 | + name: Fuzz (libFuzzer) |
| 112 | + uses: anolishq/.github/.github/workflows/fuzz.yml@0f4d8cd3c04dcb17fe128248a147b237c1465e0c # v2 |
| 113 | + with: |
| 114 | + triplet: x64-linux |
| 115 | + build-preset: ci-fuzz |
| 116 | + fuzz-binaries: "build/ci-fuzz/fuzz/fuzz_json_loader build/ci-fuzz/fuzz/fuzz_yaml_loader" |
| 117 | + corpus-root: fuzz/corpus |
| 118 | + max-total-time: "60" |
0 commit comments