From 5a3495c43126e39d09a99608ff96cb945e215180 Mon Sep 17 00:00:00 2001 From: Shahar Epstein <60007259+shahar1@users.noreply.github.com> Date: Thu, 4 Jun 2026 08:18:20 +0300 Subject: [PATCH] CI: Run CodeQL only on languages changed in a pull request (#67972) PR-triggered CodeQL is by far the most frequent workflow in the repo (~1,300+ runs/week), and every run fans out one job per language (python, javascript, actions, go, java) regardless of what changed. The java job in particular runs a full Gradle build on every PR even though java-sdk files change in well under 1% of PRs. Gate the language matrix on the files actually changed in the PR: a docs-only PR now runs nothing, and the common python-only PR runs a single job instead of five. push-to-main and scheduled runs still scan every language, so coverage of the main branch is unchanged. (cherry picked from commit c91dc3bb4bad9e88dfbdfdc4e6c253c29994917f) --- .github/workflows/codeql-analysis.yml | 46 ++++++++++++++++++++++++++- 1 file changed, 45 insertions(+), 1 deletion(-) diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index 271900ad15143..92c4cf470a380 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -33,13 +33,57 @@ concurrency: cancel-in-progress: true jobs: + detect-languages: + name: Detect languages to scan + runs-on: ["ubuntu-22.04"] + permissions: + contents: read + pull-requests: read + outputs: + languages: ${{ steps.set-languages.outputs.languages }} + steps: + - name: Compute CodeQL language matrix + id: set-languages + env: + GH_TOKEN: ${{ github.token }} + EVENT_NAME: ${{ github.event_name }} + PR_NUMBER: ${{ github.event.pull_request.number }} + REPOSITORY: ${{ github.repository }} + # On `pull_request` we only scan the languages whose files actually changed in the PR. + # On `push` (to main) and `schedule` we always scan every language to keep full main coverage. + run: | + set -euo pipefail + all_languages='["python","javascript","actions","go","java"]' + if [[ "${EVENT_NAME}" != "pull_request" ]]; then + echo "languages=${all_languages}" >> "${GITHUB_OUTPUT}" + exit 0 + fi + pr_files_path="repos/${REPOSITORY}/pulls/${PR_NUMBER}/files" + changed_files="$(gh api --paginate "${pr_files_path}" --jq '.[].filename')" + languages=() + grep -Eiq '\.(py|pyi)$' <<< "${changed_files}" && languages+=("python") + grep -Eiq '\.(js|jsx|mjs|cjs|ts|tsx|vue)$' <<< "${changed_files}" && languages+=("javascript") + grep -Eiq '^\.github/(workflows|actions)/' <<< "${changed_files}" && languages+=("actions") + grep -Eiq '(\.go$|/go\.(mod|sum)$)' <<< "${changed_files}" && languages+=("go") + grep -Eiq '(\.java$|\.gradle(\.kts)?$|\.kts$)' <<< "${changed_files}" && languages+=("java") + if [[ ${#languages[@]} -eq 0 ]]; then + echo "languages=[]" >> "${GITHUB_OUTPUT}" + else + json_languages="$(printf '%s\n' "${languages[@]}" \ + | jq -Rsc 'split("\n") | map(select(length > 0))')" + echo "languages=${json_languages}" >> "${GITHUB_OUTPUT}" + fi + analyze: name: Analyze + needs: detect-languages + # Skip entirely when no scannable language changed (e.g. docs-only PRs). + if: needs.detect-languages.outputs.languages != '[]' runs-on: ["ubuntu-22.04"] strategy: fail-fast: false matrix: - language: ['python', 'javascript', 'actions', 'go'] + language: ${{ fromJSON(needs.detect-languages.outputs.languages) }} permissions: actions: read contents: read