# SPDX-FileCopyrightText: Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. # SPDX-License-Identifier: Apache-2.0 name: CodeQL on: schedule: - cron: "29 5 * * *" workflow_dispatch: workflow_call: inputs: candidate_ref: description: Optional pre-release tag to scan instead of the triggering revision default: "" type: string fail-on-findings: description: Fail on HIGH/CRITICAL security findings (score at least 7.0) default: false type: boolean permissions: contents: read security-events: write concurrency: group: codeql-${{ github.workflow }}-${{ inputs.candidate_ref || github.ref }} cancel-in-progress: true jobs: analyze: name: CodeQL (${{ matrix.language }}) runs-on: ubuntu-latest timeout-minutes: 90 env: # Keep Rust test fixtures out of production-focused security results. CODEQL_EXTRACTOR_RUST_OPTION_CARGO_CFG_OVERRIDES: "-test" strategy: fail-fast: false matrix: include: - language: rust build-mode: none - language: go build-mode: manual - language: python build-mode: none - language: javascript-typescript build-mode: none steps: - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 id: checkout with: ref: ${{ inputs.candidate_ref && format('refs/tags/{0}', inputs.candidate_ref) || '' }} persist-credentials: false - name: Set up Go if: matrix.language == 'go' uses: actions/setup-go@b7ad1dad31e06c5925ef5d2fc7ad053ef454303e # v7.0.0 with: go-version-file: sdk/go/go.mod cache-dependency-path: sdk/go/go.sum - name: Initialize CodeQL uses: github/codeql-action/init@ff2f1c621b7f889edc0d3c761ac2e6a3f8cdb0dd # v4.37.7 with: languages: ${{ matrix.language }} build-mode: ${{ matrix.build-mode }} config-file: ./.github/codeql/codeql-config.yml - name: Build Go SDK if: matrix.language == 'go' working-directory: sdk/go run: go build ./... - name: Analyze id: analyze uses: github/codeql-action/analyze@ff2f1c621b7f889edc0d3c761ac2e6a3f8cdb0dd # v4.37.7 with: category: /language:${{ matrix.language }} output: codeql-results upload: never - name: Summarize findings id: findings if: always() env: LANGUAGE: ${{ matrix.language }} FAIL_ON_FINDINGS: ${{ inputs.fail-on-findings || false }} shell: bash run: | set -euo pipefail shopt -s globstar nullglob sarif_files=(codeql-results/**/*.sarif) { echo "### CodeQL: $LANGUAGE" echo if [ "${#sarif_files[@]}" -eq 0 ]; then echo "No SARIF report was produced." exit 1 else finding_count=$(jq -s '[.[].runs[].results[]] | length' "${sarif_files[@]}") high_count=$(jq -s ' [ .[].runs[] | . as $run | .results[] | select(all(.suppressions[]?; .status != "accepted")) | .ruleId as $id | ($run.tool.driver, $run.tool.extensions[]?) | .rules[]? | select(.id == $id) | select((.properties["security-severity"] // "0" | tonumber) >= 7) ] | length ' "${sarif_files[@]}") echo "high_count=$high_count" >> "$GITHUB_OUTPUT" echo "Findings: $finding_count" echo "HIGH/CRITICAL: $high_count" echo echo "Fail on HIGH/CRITICAL: $FAIL_ON_FINDINGS" fi } >> "$GITHUB_STEP_SUMMARY" - name: Upload SARIF to Code Scanning if: steps.analyze.outcome == 'success' uses: github/codeql-action/upload-sarif@ff2f1c621b7f889edc0d3c761ac2e6a3f8cdb0dd # v4.37.7 with: sarif_file: codeql-results ref: ${{ inputs.candidate_ref && format('refs/tags/{0}', inputs.candidate_ref) || '' }} sha: ${{ inputs.candidate_ref && steps.checkout.outputs.commit || '' }} category: /language:${{ matrix.language }} - name: Upload SARIF if: always() uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: name: codeql-${{ matrix.language }}-${{ github.run_id }} path: codeql-results if-no-files-found: ignore retention-days: 14 - name: Enforce HIGH/CRITICAL threshold if: ${{ !cancelled() && steps.findings.outcome == 'success' }} env: HIGH_COUNT: ${{ steps.findings.outputs.high_count }} FAIL_ON_FINDINGS: ${{ inputs.fail-on-findings || false }} run: | if [ "$HIGH_COUNT" -gt 0 ]; then if [ "$FAIL_ON_FINDINGS" = "true" ]; then echo "::error::CodeQL reported $HIGH_COUNT HIGH/CRITICAL findings." exit 1 fi echo "::warning::CodeQL reported $HIGH_COUNT HIGH/CRITICAL findings; enforcement is disabled." fi result: name: ${{ inputs.fail-on-findings && 'OpenShell / CodeQL' || 'OpenShell / CodeQL (informational)' }} if: always() needs: analyze runs-on: ubuntu-latest permissions: {} steps: - name: Evaluate analyzer execution env: ANALYZE_RESULT: ${{ needs.analyze.result }} shell: bash run: | if [ "$ANALYZE_RESULT" != "success" ]; then echo "::error::CodeQL execution or the configured finding threshold failed." exit 1 fi echo "All CodeQL analyzers completed and the configured finding threshold passed."