mirror of
https://github.com/DeusData/codebase-memory-mcp.git
synced 2026-11-06 17:49:47 +00:00
Bring CodeQL back to pull requests as jobs of PR CI itself (needed by ci-ok, no polling), narrowed to first-party code, while push to main, the weekly run, the dry run and the release keep the full scan. - codeql.yml: one leg per language (c-cpp, javascript-typescript, python, actions), scope in .github/codeql/codeql-config.yml. The full scan traces the whole build, vendored C included. The PR scan (light: true) analyses each selected language's whole first-party scope; c-cpp compiles the third-party objects before tracing (scripts/build.sh --vendored-only) and then traces the first-party build plus the vendored files the PR changes (--reuse-vendored --retrace-from, make -W). Diff-informed analysis (codeql-action v4.38.1, forced on for PR calls) only restricts reported alerts. The alert check moves into each leg and reads the analysed ref. Push and PR runs cancel superseded runs per language; dispatched runs never cancel. Compiler cache off so every compile is traced. - pr.yml: a codeql job runs the legs of the selected codeql-* lanes; ci-ok needs it. - select-lanes.sh: codeql-cpp/-js/-py/-actions lanes, selected by a change in their scope (any C/C++ incl. vendored; JS/TS, Python and workflows inside the config's paths minus paths-ignore) and by every full run (undeterminable diff, workflows, build, CodeQL machinery). --codeql-scope LANGUAGE prints a list's in-scope paths. - codeql-retrace-vendored.sh: the vendored C files a PR changes (empty, never narrowing, when the diff cannot be determined). - Makefile.cbm: cbm-third-party builds the vendored prod objects only. - tests: the gate contract pins the new layout; the selector contract pins that a C change always selects the C scan, an undeterminable diff selects every language, and a vendored-only change retraces exactly the changed vendored files. Selector fixtures, ci-ok's job map, the replay's codeql-action failures (lane codeql-cpp) and the interface probes follow. Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
165 lines
6.7 KiB
YAML
165 lines
6.7 KiB
YAML
# Manual trigger: test everything before pushing a release.
|
|
# Each step can be skipped for faster iteration.
|
|
#
|
|
# Pipeline: lint → test → build + candidate scan/select → smoke/soak
|
|
# Security: security-static + license-gate (independent island)
|
|
# CodeQL: codeql.yml full scan of this commit + alert check (independent island)
|
|
#
|
|
# Security and CodeQL do NOT block lint/test/build/smoke/soak. All jobs must pass
|
|
# for the overall workflow to be green.
|
|
#
|
|
# Candidate VirusTotal scanning and tuple-local selection are part of the
|
|
# reusable build boundary. Smoke and soak therefore start only after all 16
|
|
# stripped/unstripped candidates have completed and the selected exact bytes
|
|
# have been packaged under the canonical artifact names.
|
|
#
|
|
# The skips are independent because they answer different questions:
|
|
# skip_builds no artifacts at all "do lint and tests pass?"
|
|
# skip_smoke build + scan/select, no smoke "does this diff scan red?"
|
|
# skip_virustotal default-stripped + smoke, no scan "do the archives pass CI?"
|
|
#
|
|
# skip_virustotal is a conspicuous dry-run-only bypass for API-quota-sensitive
|
|
# iteration. It records unscanned-dry-run and deterministically chooses stripped
|
|
# within each tuple. release.yml has no corresponding bypass.
|
|
name: Dry Run
|
|
|
|
on:
|
|
workflow_dispatch:
|
|
inputs:
|
|
skip_lint:
|
|
description: 'Skip lint (cppcheck + clang-format)'
|
|
type: boolean
|
|
default: false
|
|
skip_tests:
|
|
description: 'Skip unit/integration tests'
|
|
type: boolean
|
|
default: false
|
|
skip_builds:
|
|
description: 'Skip build + smoke (also skips VirusTotal — nothing to scan)'
|
|
type: boolean
|
|
default: false
|
|
skip_smoke:
|
|
description: 'Skip smoke (candidate scan/select still runs inside build)'
|
|
type: boolean
|
|
default: false
|
|
skip_virustotal:
|
|
description: 'Skip candidate scan; mark unscanned and default to stripped'
|
|
type: boolean
|
|
default: false
|
|
skip_memwaste:
|
|
description: 'Skip the waste sanitizer (report-only) and the fuzz smoke'
|
|
type: boolean
|
|
default: false
|
|
soak_level:
|
|
description: 'Soak: full (quick+asan), quick (10min), none'
|
|
type: choice
|
|
options: ['full', 'quick', 'none']
|
|
default: 'quick'
|
|
|
|
permissions:
|
|
contents: read
|
|
|
|
jobs:
|
|
# ── Security (independent island — does not block main pipeline) ──
|
|
security:
|
|
uses: ./.github/workflows/_security.yml
|
|
# No job in _security.yml reads code scanning or the Actions API any more
|
|
# (the CodeQL gate moved to codeql.yml), so the token stays read-only.
|
|
permissions:
|
|
contents: read
|
|
secrets: inherit
|
|
|
|
# ── CodeQL: full scan of this exact commit + the open-alert check ──
|
|
# Every language, vendored C included (PRs run the narrower PR scan).
|
|
# codeql.yml uploads results and reads the alerts: a called workflow
|
|
# cannot request more than its caller grants, so withholding either
|
|
# permission fails the whole run at startup.
|
|
codeql:
|
|
uses: ./.github/workflows/codeql.yml
|
|
permissions:
|
|
contents: read
|
|
security-events: write
|
|
actions: read
|
|
|
|
# ── Lint (cppcheck + clang-format) ────────────────────────────
|
|
lint:
|
|
if: ${{ inputs.skip_lint != true }}
|
|
uses: ./.github/workflows/_lint.yml
|
|
|
|
# ── Tests (all platforms, perf tests skipped on CI) ────────────
|
|
test:
|
|
needs: [lint]
|
|
if: ${{ inputs.skip_tests != true && !cancelled() && (needs.lint.result == 'success' || needs.lint.result == 'skipped') }}
|
|
uses: ./.github/workflows/_test.yml
|
|
with:
|
|
skip_perf: true
|
|
broad_platforms: true
|
|
shard_suites: true
|
|
|
|
# ── Build all platforms ────────────────────────────────────────
|
|
build:
|
|
if: ${{ inputs.skip_builds != true && !cancelled() && (needs.test.result == 'success' || needs.test.result == 'skipped') }}
|
|
needs: [test]
|
|
permissions:
|
|
contents: read
|
|
id-token: write
|
|
attestations: write
|
|
uses: ./.github/workflows/_build.yml
|
|
with:
|
|
attest: false
|
|
scan_candidates: ${{ !inputs.skip_virustotal }}
|
|
secrets: inherit
|
|
|
|
# ── Smoke test every binary ────────────────────────────────────
|
|
# Run unless builds were skipped or a build leg FAILED. Every build leg
|
|
# (including the macos-15-intel darwin-amd64 binary) is blocking now, so a
|
|
# failed/missing platform binary correctly stops smoke — see _build.yml.
|
|
smoke:
|
|
if: ${{ inputs.skip_builds != true && inputs.skip_smoke != true && !cancelled() && needs.build.result != 'failure' && needs.build.result != 'skipped' }}
|
|
needs: [build]
|
|
uses: ./.github/workflows/_smoke.yml
|
|
with:
|
|
broad_platforms: true
|
|
|
|
# ── Waste sanitizer, REPORT-ONLY (independent island) ─────────
|
|
# Event lane on Linux, macOS and Windows, access lane and the per-function
|
|
# scaling lane on Linux. Uploads reports; fails only when the measurement is
|
|
# unsound (a defect of the tool itself).
|
|
memwaste:
|
|
if: ${{ inputs.skip_memwaste != true }}
|
|
uses: ./.github/workflows/_memwaste.yml
|
|
with:
|
|
mode: full
|
|
|
|
# ── Fuzz smoke (independent island) ───────────────────────────
|
|
# A fixed number of executions from a fixed seed per target, so the verdict is
|
|
# a function of the commit (O9). A crash here is a real defect in a parser
|
|
# that reads untrusted input; its reproducer is uploaded.
|
|
fuzz:
|
|
if: ${{ inputs.skip_memwaste != true }}
|
|
runs-on: ubuntu-latest
|
|
timeout-minutes: 90
|
|
steps:
|
|
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
- name: Install deps
|
|
run: sudo apt-get update && sudo apt-get install -y zlib1g-dev clang llvm libclang-rt-dev
|
|
- name: Fuzz smoke (extract, cypher, config)
|
|
run: scripts/fuzz.sh all --runs 20000 --seed 1
|
|
- name: Upload reproducers
|
|
if: ${{ failure() }}
|
|
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
|
|
with:
|
|
name: fuzz-artifacts
|
|
path: build/fuzz/artifacts-*/
|
|
if-no-files-found: ignore
|
|
|
|
# ── Soak tests (optional, parallel with smoke) ────────────────
|
|
soak:
|
|
if: ${{ inputs.soak_level != 'none' && !cancelled() && needs.build.result != 'failure' && needs.build.result != 'skipped' }}
|
|
needs: [build]
|
|
uses: ./.github/workflows/_soak.yml
|
|
with:
|
|
duration_minutes: 10
|
|
run_asan: ${{ inputs.soak_level == 'full' }}
|
|
use_release_artifacts: true
|