From 77192572f62174aeb9d5d42e8901773aae611f50 Mon Sep 17 00:00:00 2001 From: Vincent Koc Date: Tue, 28 Apr 2026 03:14:07 -0700 Subject: [PATCH] ci: split macos codeql shard Split the slow macOS CodeQL job into its own weekly/manual workflow and keep the daily CodeQL default on the fast JS/Actions security path. --- .../codeql-macos-critical-security.yml | 89 +++++++++++++++++++ .github/workflows/codeql.yml | 72 --------------- docs/ci.md | 9 +- 3 files changed, 96 insertions(+), 74 deletions(-) create mode 100644 .github/workflows/codeql-macos-critical-security.yml diff --git a/.github/workflows/codeql-macos-critical-security.yml b/.github/workflows/codeql-macos-critical-security.yml new file mode 100644 index 00000000000..d2261691b5c --- /dev/null +++ b/.github/workflows/codeql-macos-critical-security.yml @@ -0,0 +1,89 @@ +name: CodeQL macOS Critical Security + +on: + workflow_dispatch: + schedule: + - cron: "0 8 * * 1" + +concurrency: + group: codeql-macos-critical-security-${{ github.workflow }}-${{ github.event_name == 'workflow_dispatch' && github.run_id || github.sha }} + cancel-in-progress: false + +env: + FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: "true" + +permissions: + actions: read + contents: read + security-events: write + +jobs: + macos: + name: Critical Security (macOS) + runs-on: blacksmith-6vcpu-macos-latest + timeout-minutes: 45 + steps: + - name: Checkout + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 + with: + submodules: false + + - name: Select Xcode + run: | + sudo xcode-select -s /Applications/Xcode_26.1.app + xcodebuild -version + swift --version + + - name: Initialize CodeQL + uses: github/codeql-action/init@95e58e9a2cdfd71adc6e0353d5c52f41a045d225 # v4 + with: + languages: swift + build-mode: manual + config-file: ./.github/codeql/codeql-macos-critical-security.yml + + - name: Build macOS for CodeQL + run: swift build --package-path apps/macos --product OpenClaw + + - name: Analyze + id: analyze + uses: github/codeql-action/analyze@95e58e9a2cdfd71adc6e0353d5c52f41a045d225 # v4 + with: + output: sarif-results + upload: failure-only + category: "/codeql-critical-security/macos" + + - name: Remove dependency build results + env: + SARIF_OUTPUT: sarif-results + run: | + set -euo pipefail + shopt -s nullglob + + if [ ! -d "$SARIF_OUTPUT" ]; then + echo "SARIF output directory not found: $SARIF_OUTPUT" >&2 + exit 1 + fi + + mkdir -p sarif-results-filtered + + files=("$SARIF_OUTPUT"/*.sarif) + if [ "${#files[@]}" -eq 0 ]; then + echo "No SARIF files found in $SARIF_OUTPUT" >&2 + exit 1 + fi + + for file in "${files[@]}"; do + jq ' + def in_dependency_build: + ((.locations // []) | length > 0) + and all(.locations[]; (.physicalLocation.artifactLocation.uri? // "") | test("^apps/macos/\\.build/")); + + .runs |= map(.results = ((.results // []) | map(select(in_dependency_build | not)))) + ' "$file" > "sarif-results-filtered/$(basename "$file")" + done + + - name: Upload filtered SARIF + uses: github/codeql-action/upload-sarif@95e58e9a2cdfd71adc6e0353d5c52f41a045d225 # v4 + with: + sarif_file: sarif-results-filtered + category: "/codeql-critical-security/macos" diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index 9179a571228..e376ed6a7b1 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -11,7 +11,6 @@ on: options: - all - security - - macos-security schedule: - cron: "0 6 * * *" @@ -61,74 +60,3 @@ jobs: uses: github/codeql-action/analyze@95e58e9a2cdfd71adc6e0353d5c52f41a045d225 # v4 with: category: "/codeql-critical-security/${{ matrix.language }}" - - macos-security: - name: Critical Security (macOS) - if: ${{ github.event_name == 'workflow_dispatch' && inputs.profile == 'macos-security' }} - runs-on: blacksmith-6vcpu-macos-latest - timeout-minutes: 45 - steps: - - name: Checkout - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 - with: - submodules: false - - - name: Select Xcode - run: | - sudo xcode-select -s /Applications/Xcode_26.1.app - xcodebuild -version - swift --version - - - name: Initialize CodeQL - uses: github/codeql-action/init@95e58e9a2cdfd71adc6e0353d5c52f41a045d225 # v4 - with: - languages: swift - build-mode: manual - config-file: ./.github/codeql/codeql-macos-critical-security.yml - - - name: Build macOS for CodeQL - run: swift build --package-path apps/macos --product OpenClaw - - - name: Analyze - id: analyze - uses: github/codeql-action/analyze@95e58e9a2cdfd71adc6e0353d5c52f41a045d225 # v4 - with: - output: sarif-results - upload: failure-only - category: "/codeql-critical-security/macos" - - - name: Remove dependency build results - env: - SARIF_OUTPUT: sarif-results - run: | - set -euo pipefail - shopt -s nullglob - - if [ ! -d "$SARIF_OUTPUT" ]; then - echo "SARIF output directory not found: $SARIF_OUTPUT" >&2 - exit 1 - fi - - mkdir -p sarif-results-filtered - - files=("$SARIF_OUTPUT"/*.sarif) - if [ "${#files[@]}" -eq 0 ]; then - echo "No SARIF files found in $SARIF_OUTPUT" >&2 - exit 1 - fi - - for file in "${files[@]}"; do - jq ' - def in_dependency_build: - ((.locations // []) | length > 0) - and all(.locations[]; (.physicalLocation.artifactLocation.uri? // "") | test("^apps/macos/\\.build/")); - - .runs |= map(.results = ((.results // []) | map(select(in_dependency_build | not)))) - ' "$file" > "sarif-results-filtered/$(basename "$file")" - done - - - name: Upload filtered SARIF - uses: github/codeql-action/upload-sarif@95e58e9a2cdfd71adc6e0353d5c52f41a045d225 # v4 - with: - sarif_file: sarif-results-filtered - category: "/codeql-critical-security/macos" diff --git a/docs/ci.md b/docs/ci.md index edde7c58a7d..7f57c3c8b98 100644 --- a/docs/ci.md +++ b/docs/ci.md @@ -230,14 +230,19 @@ or overlapping changed hunks. The `CodeQL` workflow is intentionally a narrow first-pass security scanner, not the full repository sweep. Daily and manual runs scan Actions workflow code plus the highest-risk JavaScript/TypeScript auth, secrets, sandbox, cron, and -gateway surfaces with high-precision security queries. macOS remains a manual -security shard so its runtime and alert quality can be tracked separately. +gateway surfaces with high-precision security queries. The `CodeQL Android Critical Security` workflow is the scheduled Android security shard. It builds the Android app manually for CodeQL on the smallest Blacksmith Linux runner label accepted by workflow sanity and uploads results under the `/codeql-critical-security/android` category. +The `CodeQL macOS Critical Security` workflow is the weekly/manual macOS +security shard. It builds the macOS app manually for CodeQL on Blacksmith macOS, +filters dependency build results out of the uploaded SARIF, and uploads results +under the `/codeql-critical-security/macos` category. Keep it outside the daily +default workflow because the macOS build dominates runtime even when clean. + The `CodeQL Critical Quality` workflow is the matching non-security shard. It runs only error-severity, non-security JavaScript/TypeScript quality queries over narrow high-value surfaces. Its baseline job scans the same auth, secrets,