SPEC §9: peer-derived text in observer-facing errors (boundary unresolved) #2108
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: "CodeQL Advanced" | |
| on: | |
| push: | |
| branches: [main] | |
| pull_request: | |
| branches: [main] | |
| schedule: | |
| - cron: '0 7 * * 1' # Monday 7am UTC (security.yml at 6am) | |
| workflow_dispatch: | |
| concurrency: | |
| group: codeql-${{ github.ref }} | |
| cancel-in-progress: ${{ github.event_name == 'pull_request' }} | |
| permissions: {} | |
| jobs: | |
| changes: | |
| name: Detect changes | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: read | |
| pull-requests: read | |
| outputs: | |
| matrix: ${{ steps.set-matrix.outputs.matrix }} | |
| swift: ${{ steps.set-matrix.outputs.swift }} | |
| steps: | |
| - uses: dorny/paths-filter@ceb8a2b8f2d89434be7ff52d3de7ec3738c5cc9d # v4.0.3 | |
| if: github.event_name == 'pull_request' | |
| id: filter | |
| with: | |
| filters: | | |
| go: | |
| - 'go/**' | |
| typescript: | |
| - 'typescript/**' | |
| ruby: | |
| - 'ruby/**' | |
| swift: | |
| - 'swift/**' | |
| kotlin: | |
| - 'kotlin/**' | |
| python: | |
| - 'python/**' | |
| actions: | |
| - '.github/**' | |
| config: | |
| - '.github/codeql/**' | |
| - '.github/workflows/codeql.yml' | |
| - name: Build language matrix | |
| id: set-matrix | |
| env: | |
| EVENT: ${{ github.event_name }} | |
| GO: ${{ steps.filter.outputs.go }} | |
| TS: ${{ steps.filter.outputs.typescript }} | |
| RUBY: ${{ steps.filter.outputs.ruby }} | |
| SWIFT: ${{ steps.filter.outputs.swift }} | |
| KOTLIN: ${{ steps.filter.outputs.kotlin }} | |
| PYTHON: ${{ steps.filter.outputs.python }} | |
| ACTIONS: ${{ steps.filter.outputs.actions }} | |
| CONFIG: ${{ steps.filter.outputs.config }} | |
| run: | | |
| matrix='[]' | |
| add() { matrix=$(echo "$matrix" | jq -c --arg l "$1" --arg m "$2" '. + [{"language": $l, "build-mode": $m}]'); } | |
| if [ "$EVENT" != "pull_request" ] || [ "$CONFIG" = "true" ]; then | |
| add actions none | |
| add go manual | |
| add javascript none | |
| add ruby none | |
| add python none | |
| add java-kotlin manual | |
| swift=true | |
| else | |
| if [ "$ACTIONS" = "true" ]; then add actions none; fi | |
| if [ "$GO" = "true" ]; then add go manual; fi | |
| if [ "$TS" = "true" ]; then add javascript none; fi | |
| if [ "$RUBY" = "true" ]; then add ruby none; fi | |
| if [ "$PYTHON" = "true" ]; then add python none; fi | |
| if [ "$KOTLIN" = "true" ]; then add java-kotlin manual; fi | |
| swift=$SWIFT | |
| fi | |
| echo "matrix=$matrix" >> "$GITHUB_OUTPUT" | |
| echo "swift=$swift" >> "$GITHUB_OUTPUT" | |
| analyze: | |
| name: Analyze (${{ matrix.language }}) | |
| needs: changes | |
| if: ${{ needs.changes.outputs.matrix != '[]' }} | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 30 | |
| permissions: | |
| contents: read | |
| security-events: write | |
| packages: read | |
| actions: read | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| include: ${{ fromJSON(needs.changes.outputs.matrix) }} | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 | |
| with: | |
| persist-credentials: false | |
| # --- Language setup (conditional) --- | |
| - name: Set up Go | |
| if: matrix.language == 'go' | |
| uses: actions/setup-go@b7ad1dad31e06c5925ef5d2fc7ad053ef454303e # v7.0.0 | |
| with: | |
| go-version-file: 'go/go.mod' | |
| cache-dependency-path: 'go/go.sum' | |
| - name: Set up Java | |
| if: matrix.language == 'java-kotlin' | |
| uses: actions/setup-java@b6effb05e454b25005698d916606bdc6ffcbf961 # v5.7.0 | |
| with: | |
| distribution: 'temurin' | |
| java-version: '17' | |
| - name: Setup Gradle | |
| if: matrix.language == 'java-kotlin' | |
| uses: gradle/actions/setup-gradle@9c971963bec38e04b3d30dcc455b5382be2fdbfb # v6.3.0 | |
| with: | |
| cache-provider: basic | |
| # --- CodeQL init --- | |
| - name: Initialize CodeQL | |
| uses: github/codeql-action/init@5595ccaf912efad79be6eef63a5619ff05969be3 # v4.37.6 | |
| with: | |
| languages: ${{ matrix.language }} | |
| build-mode: ${{ matrix.build-mode }} | |
| config-file: ./.github/codeql/codeql-config.yml | |
| # --- Build steps (manual mode only) --- | |
| - name: Build (Go) | |
| if: matrix.language == 'go' | |
| working-directory: go | |
| env: | |
| CODEQL_EXTRACTOR_GO_BUILD_TRACING: 'on' | |
| run: go build ./... | |
| # CodeQL extracts Kotlin by tracing the compiler, so the compile task must | |
| # actually run: gradle.properties enables the build cache and setup-gradle | |
| # restores it, and an UP-TO-DATE compile emits nothing (empty database). | |
| # Scoped to :basecamp-sdk — :generator is in neither codeql-config.yml's | |
| # paths-ignore nor the SARIF filter, so building it would leak alerts. | |
| - name: Build (Kotlin) | |
| if: matrix.language == 'java-kotlin' | |
| working-directory: kotlin | |
| run: ./gradlew --no-build-cache clean :basecamp-sdk:compileKotlinJvm | |
| # --- Analysis (fails build on real errors) --- | |
| - name: Perform CodeQL Analysis | |
| uses: github/codeql-action/analyze@5595ccaf912efad79be6eef63a5619ff05969be3 # v4.37.6 | |
| with: | |
| category: "/language:${{ matrix.language }}" | |
| upload: never | |
| output: sarif-results | |
| # --- Filter generated-code alerts --- | |
| # paths-ignore in codeql-config.yml only governs source extraction | |
| # (effective for JS/Ruby). For compiled languages the extractor traces | |
| # the build, so generated code enters the database. Strip those results | |
| # from SARIF before upload. | |
| - name: Filter generated-code alerts from SARIF | |
| if: always() && matrix.language != 'actions' | |
| run: | | |
| for sarif in sarif-results/*.sarif; do | |
| [ -f "$sarif" ] || continue | |
| before=$(jq '[.runs[].results // [] | length] | add // 0' "$sarif") | |
| jq ' | |
| .runs |= map(.results |= (. // [] | map( | |
| select( | |
| (.locations // [])[0].physicalLocation.artifactLocation.uri // "" | | |
| test("(^|/)(go/pkg/generated/|typescript/(src/generated|dist)/|ruby/lib/basecamp/generated/|swift/Sources/Basecamp/Generated/|kotlin/sdk/src/commonMain/kotlin/com/basecamp/sdk/generated/)") | not | |
| ) | |
| ))) | |
| ' "$sarif" > "${sarif}.tmp" && mv "${sarif}.tmp" "$sarif" | |
| after=$(jq '[.runs[].results | length] | add // 0' "$sarif") | |
| filtered=$((before - after)) | |
| echo "$(basename "$sarif"): $before findings, filtered $filtered generated-code alerts, $after remaining" | |
| done | |
| # --- Upload (tolerates GHAS unavailability) --- | |
| - name: Upload SARIF to GitHub Security tab | |
| uses: github/codeql-action/upload-sarif@5595ccaf912efad79be6eef63a5619ff05969be3 # v4.37.6 | |
| if: always() | |
| continue-on-error: true # Requires GitHub Advanced Security | |
| with: | |
| sarif_file: sarif-results | |
| category: "/language:${{ matrix.language }}" | |
| analyze-swift: | |
| name: Analyze (swift) | |
| needs: changes | |
| if: needs.changes.outputs.swift == 'true' | |
| runs-on: macos-15 | |
| timeout-minutes: 30 | |
| permissions: | |
| contents: read | |
| security-events: write | |
| packages: read | |
| actions: read | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 | |
| with: | |
| persist-credentials: false | |
| - name: Initialize CodeQL | |
| uses: github/codeql-action/init@5595ccaf912efad79be6eef63a5619ff05969be3 # v4.37.6 | |
| with: | |
| languages: swift | |
| build-mode: manual | |
| config-file: ./.github/codeql/codeql-config.yml | |
| - name: Build (Swift) | |
| working-directory: swift | |
| run: swift build | |
| - name: Perform CodeQL Analysis | |
| uses: github/codeql-action/analyze@5595ccaf912efad79be6eef63a5619ff05969be3 # v4.37.6 | |
| with: | |
| category: "/language:swift" | |
| upload: never | |
| output: sarif-results | |
| - name: Filter generated-code alerts from SARIF | |
| if: always() | |
| run: | | |
| for sarif in sarif-results/*.sarif; do | |
| [ -f "$sarif" ] || continue | |
| before=$(jq '[.runs[].results // [] | length] | add // 0' "$sarif") | |
| jq ' | |
| .runs |= map(.results |= (. // [] | map( | |
| select( | |
| (.locations // [])[0].physicalLocation.artifactLocation.uri // "" | | |
| test("(^|/)(go/pkg/generated/|typescript/(src/generated|dist)/|ruby/lib/basecamp/generated/|swift/Sources/Basecamp/Generated/|kotlin/sdk/src/commonMain/kotlin/com/basecamp/sdk/generated/)") | not | |
| ) | |
| ))) | |
| ' "$sarif" > "${sarif}.tmp" && mv "${sarif}.tmp" "$sarif" | |
| after=$(jq '[.runs[].results | length] | add // 0' "$sarif") | |
| filtered=$((before - after)) | |
| echo "$(basename "$sarif"): $before findings, filtered $filtered generated-code alerts, $after remaining" | |
| done | |
| - name: Upload SARIF to GitHub Security tab | |
| uses: github/codeql-action/upload-sarif@5595ccaf912efad79be6eef63a5619ff05969be3 # v4.37.6 | |
| if: always() | |
| continue-on-error: true # Requires GitHub Advanced Security | |
| with: | |
| sarif_file: sarif-results | |
| category: "/language:swift" |