From d6a43cff987f85867e172f722f9639cd0410e810 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 13 Feb 2026 16:15:44 +0000 Subject: [PATCH 1/6] Add separate detection checks for CodeQL languages (cpp, python, actions) Co-authored-by: greenc-FNAL <2372949+greenc-FNAL@users.noreply.github.com> --- .github/workflows/codeql-analysis.yaml | 221 ++++++++++++++++++++++++- 1 file changed, 218 insertions(+), 3 deletions(-) diff --git a/.github/workflows/codeql-analysis.yaml b/.github/workflows/codeql-analysis.yaml index 2a82a695a..6e23a98dc 100644 --- a/.github/workflows/codeql-analysis.yaml +++ b/.github/workflows/codeql-analysis.yaml @@ -40,6 +40,22 @@ on: description: "The full name of the PR base repository" required: false type: string + pr-base-sha: + description: "Base SHA of the PR for relevance check" + required: false + type: string + pr-head-sha: + description: "Head SHA of the PR for relevance check" + required: false + type: string + ref: + description: "The branch, ref, or SHA to checkout" + required: false + type: string + repo: + description: "The repository to checkout from" + required: false + type: string permissions: actions: read @@ -51,25 +67,224 @@ env: CPP_COMPILER: g++ jobs: + pre-check: + runs-on: ubuntu-latest + outputs: + is_act: ${{ steps.detect_act.outputs.is_act }} + ref: ${{ (github.event_name == 'workflow_call' && inputs.ref) || (github.event_name == 'workflow_dispatch' && (github.event.inputs.ref || github.ref)) || github.sha }} + repo: ${{ (github.event_name == 'workflow_call' && inputs.repo) || github.repository }} + base_sha: ${{ (github.event_name == 'workflow_call' && inputs.pr-base-sha) || github.event.pull_request.base.sha || github.event.before }} + skip_detection: ${{ steps.should_skip.outputs.skip }} + local_checkout_path: ${{ (github.event_name == 'workflow_call' && inputs.checkout-path) || format('{0}-src', github.event.repository.name) }} + steps: + - name: Detect act environment + id: detect_act + uses: Framework-R-D/phlex/.github/actions/detect-act-env@main + + - name: Determine if detection should be skipped + id: should_skip + run: | + # Skip detection for scheduled runs, workflow_dispatch, or workflow_call with language-matrix override + if [ "${{ github.event_name }}" = "schedule" ] || \ + [ "${{ github.event_name }}" = "workflow_dispatch" ] || \ + [ "${{ github.event_name }}" = "push" ] || \ + { [ "${{ github.event_name }}" = "workflow_call" ] && [ -n "${{ inputs.language-matrix }}" ]; } || \ + [ "${{ steps.detect_act.outputs.is_act }}" = "true" ]; then + echo "skip=true" >> "$GITHUB_OUTPUT" + else + echo "skip=false" >> "$GITHUB_OUTPUT" + fi + + detect-changes-cpp: + needs: pre-check + if: > + needs.pre-check.result == 'success' && + needs.pre-check.outputs.skip_detection != 'true' + runs-on: ubuntu-latest + permissions: + contents: read + outputs: + has_changes: ${{ steps.filter.outputs.matched }} + steps: + - name: Checkout code + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + fetch-depth: 0 + path: ${{ needs.pre-check.outputs.local_checkout_path }} + ref: ${{ needs.pre-check.outputs.ref }} + repository: ${{ needs.pre-check.outputs.repo }} + + - name: Detect C++ relevant changes + id: filter + uses: Framework-R-D/phlex/.github/actions/detect-relevant-changes@main + with: + repo-path: ${{ needs.pre-check.outputs.local_checkout_path }} + base-ref: ${{ needs.pre-check.outputs.base_sha }} + head-ref: ${{ needs.pre-check.outputs.ref }} + file-type: | + cpp + cmake + + - name: Report detection outcome + run: | + if [ "${{ steps.filter.outputs.matched }}" != "true" ]; then + echo "::notice::No C++ relevant changes detected; C++ CodeQL scan will be skipped." + else + echo "::group::C++ CodeQL relevant files" + printf '%s\n' "${{ steps.filter.outputs.matched_files }}" + echo "::endgroup::" + fi + + detect-changes-python: + needs: pre-check + if: > + needs.pre-check.result == 'success' && + needs.pre-check.outputs.skip_detection != 'true' + runs-on: ubuntu-latest + permissions: + contents: read + outputs: + has_changes: ${{ steps.filter.outputs.matched }} + steps: + - name: Checkout code + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + fetch-depth: 0 + path: ${{ needs.pre-check.outputs.local_checkout_path }} + ref: ${{ needs.pre-check.outputs.ref }} + repository: ${{ needs.pre-check.outputs.repo }} + + - name: Detect Python relevant changes + id: filter + uses: Framework-R-D/phlex/.github/actions/detect-relevant-changes@main + with: + repo-path: ${{ needs.pre-check.outputs.local_checkout_path }} + base-ref: ${{ needs.pre-check.outputs.base_sha }} + head-ref: ${{ needs.pre-check.outputs.ref }} + file-type: python + + - name: Report detection outcome + run: | + if [ "${{ steps.filter.outputs.matched }}" != "true" ]; then + echo "::notice::No Python relevant changes detected; Python CodeQL scan will be skipped." + else + echo "::group::Python CodeQL relevant files" + printf '%s\n' "${{ steps.filter.outputs.matched_files }}" + echo "::endgroup::" + fi + + detect-changes-actions: + needs: pre-check + if: > + needs.pre-check.result == 'success' && + needs.pre-check.outputs.skip_detection != 'true' + runs-on: ubuntu-latest + permissions: + contents: read + outputs: + has_changes: ${{ steps.filter.outputs.matched }} + steps: + - name: Checkout code + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + fetch-depth: 0 + path: ${{ needs.pre-check.outputs.local_checkout_path }} + ref: ${{ needs.pre-check.outputs.ref }} + repository: ${{ needs.pre-check.outputs.repo }} + + - name: Detect Actions/workflow relevant changes + id: filter + uses: Framework-R-D/phlex/.github/actions/detect-relevant-changes@main + with: + repo-path: ${{ needs.pre-check.outputs.local_checkout_path }} + base-ref: ${{ needs.pre-check.outputs.base_sha }} + head-ref: ${{ needs.pre-check.outputs.ref }} + include-globs: | + .github/workflows/*.yaml + .github/workflows/*.yml + .github/actions/**/action.yaml + .github/actions/**/action.yml + + - name: Report detection outcome + run: | + if [ "${{ steps.filter.outputs.matched }}" != "true" ]; then + echo "::notice::No Actions/workflow relevant changes detected; Actions CodeQL scan will be skipped." + else + echo "::group::Actions CodeQL relevant files" + printf '%s\n' "${{ steps.filter.outputs.matched_files }}" + echo "::endgroup::" + fi + + determine-languages: + needs: [pre-check, detect-changes-cpp, detect-changes-python, detect-changes-actions] + if: always() && needs.pre-check.result == 'success' + runs-on: ubuntu-latest + outputs: + languages: ${{ steps.build_matrix.outputs.languages }} + steps: + - name: Build language matrix + id: build_matrix + run: | + # If detection was skipped, use all languages or the provided language-matrix + if [ "${{ needs.pre-check.outputs.skip_detection }}" = "true" ]; then + if [ "${{ github.event_name }}" = "workflow_call" ] && [ -n "${{ inputs.language-matrix }}" ]; then + echo "languages=${{ inputs.language-matrix }}" >> "$GITHUB_OUTPUT" + else + echo 'languages=["cpp", "python", "actions"]' >> "$GITHUB_OUTPUT" + fi + exit 0 + fi + + # Build array based on detection results + langs=() + if [ "${{ needs.detect-changes-cpp.result }}" = "success" ] && [ "${{ needs.detect-changes-cpp.outputs.has_changes }}" = "true" ]; then + langs+=("cpp") + fi + if [ "${{ needs.detect-changes-python.result }}" = "success" ] && [ "${{ needs.detect-changes-python.outputs.has_changes }}" = "true" ]; then + langs+=("python") + fi + if [ "${{ needs.detect-changes-actions.result }}" = "success" ] && [ "${{ needs.detect-changes-actions.outputs.has_changes }}" = "true" ]; then + langs+=("actions") + fi + + # Convert bash array to JSON array + if [ "${#langs[@]}" -eq 0 ]; then + echo 'languages=[]' >> "$GITHUB_OUTPUT" + else + json_array="[" + for i in "${!langs[@]}"; do + if [ "$i" -gt 0 ]; then + json_array+="," + fi + json_array+="\"${langs[$i]}\"" + done + json_array+="]" + echo "languages=$json_array" >> "$GITHUB_OUTPUT" + fi + codeql: + needs: [pre-check, determine-languages] + if: > + needs.determine-languages.result == 'success' && + needs.determine-languages.outputs.languages != '[]' name: Analyze ${{ matrix.language }} with CodeQL runs-on: ubuntu-24.04 container: image: ghcr.io/framework-r-d/phlex-ci:latest env: - local_checkout_path: ${{ (github.event_name == 'workflow_call' && inputs.checkout-path) || format('{0}-src', github.event.repository.name) }} + local_checkout_path: ${{ needs.pre-check.outputs.local_checkout_path }} local_build_path: ${{ (github.event_name == 'workflow_call' && inputs.build-path) || format('{0}-build', github.event.repository.name) }} CODEQL_EXTRACTOR_CPP_COMPILATION_DATABASE: ${{ github.workspace }}/${{ (github.event_name == 'workflow_call' && inputs.build-path) || format('{0}-build', github.event.repository.name) }}/compile_commands.json strategy: fail-fast: false matrix: - language: ${{ fromJson((github.event_name == 'workflow_call' && inputs.language-matrix) || '["cpp", "python", "actions"]') }} + language: ${{ fromJson(needs.determine-languages.outputs.languages) }} timeout-minutes: 120 steps: - name: Checkout repository uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: - ref: ${{ github.event_name == 'workflow_dispatch' && github.event.inputs.ref || github.ref }} + ref: ${{ needs.pre-check.outputs.ref }} path: ${{ env.local_checkout_path }} fetch-depth: 0 From c5fa1fffd366e391f41ec7728b9680fcbcef89a2 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 13 Feb 2026 16:16:29 +0000 Subject: [PATCH 2/6] Update documentation for CodeQL language-specific detection Co-authored-by: greenc-FNAL <2372949+greenc-FNAL@users.noreply.github.com> --- .github/CodeQL-README.md | 25 +++++++++++++++++++++++-- .github/REUSABLE_WORKFLOWS.md | 20 +++++++++++++++++++- 2 files changed, 42 insertions(+), 3 deletions(-) diff --git a/.github/CodeQL-README.md b/.github/CodeQL-README.md index cff74fd46..1f8d7abd9 100644 --- a/.github/CodeQL-README.md +++ b/.github/CodeQL-README.md @@ -1,13 +1,34 @@ # CodeQL scanning for this repository -This repository uses C++ (C++20 / moving to C++23) built with CMake under the phlex-src directory, plus some Python and CI bits (Bash). The repository includes a CodeQL GitHub Actions workflow on branch `copilot/codeql-workflow` that: +This repository uses C++ (C++20 / moving to C++23) built with CMake under the phlex-src directory, plus some Python and CI bits (Bash). The repository includes a CodeQL GitHub Actions workflow that: - Runs on pushes to `main`, PRs targeting `main`, a weekly schedule, and can be run manually. - Uses the repository's existing Phlex CMake build actions (not CodeQL autobuild) so the same build configuration is used for tests and release builds. - Scans C++ and Python sources and is scoped to the `phlex-src` tree (see the CodeQL config). - Uses RelWithDebInfo build type in CI so debug symbols are present while keeping realistic optimization. +- **Implements intelligent language detection**: On pull requests, only languages with relevant file changes are analyzed, significantly reducing CI time. -Important workflow-specific notes +## Language-Specific Analysis and Automatic Detection + +The CodeQL workflow analyzes three language categories: + +1. **C++** (`cpp`): Analyzes C++ and header files, plus CMake files +2. **Python** (`python`): Analyzes Python source files +3. **GitHub Actions** (`actions`): Analyzes workflow and action YAML files + +### Detection Behavior by Event Type + +- **Pull Requests**: Only languages with relevant file changes are analyzed + - Example: A PR changing only Python files will skip C++ and Actions analysis (saves 35-70 minutes) + - Example: A PR changing only C++ files will skip Python and Actions analysis (saves 10-20 minutes) + - Example: A PR changing only workflow files will skip C++ and Python analysis +- **Pushes to main/develop**: All languages are analyzed (no detection) +- **Scheduled runs**: All languages are analyzed (no detection) +- **Manual runs** (`workflow_dispatch`): All languages are analyzed (no detection) + +This detection mechanism follows the same pattern used by other workflows in this repository (python-check, clang-tidy-check, etc.) and uses the `detect-relevant-changes` action. + +## Important workflow-specific notes - The workflow sets `autobuild: false` during the CodeQL init so the repository's own configure / build steps run. This is intentional: the Phlex build actions are used to build exactly what you ship. - The workflow tries to locate and copy a compile_commands.json (from `phlex-src/build/` or `phlex-build/`) to the workspace root so diagnostic tools and manual inspection have a predictable path. diff --git a/.github/REUSABLE_WORKFLOWS.md b/.github/REUSABLE_WORKFLOWS.md index 6e1c05a05..8a2487bb1 100644 --- a/.github/REUSABLE_WORKFLOWS.md +++ b/.github/REUSABLE_WORKFLOWS.md @@ -414,6 +414,12 @@ jobs: Performs static analysis on the codebase using GitHub CodeQL to identify potential security vulnerabilities and coding errors. +**Key Features:** + +- **Automatic Relevance Detection**: On pull requests, the workflow automatically detects which languages have relevant file changes and only runs CodeQL analysis for those languages. This significantly reduces CI time when changes affect only a subset of languages. +- **Language-Specific Scanning**: Supports separate analysis for C++, Python, and GitHub Actions workflows. +- **Fallback to Full Scan**: Scheduled runs, manual triggers (`workflow_dispatch`), and pushes to main branches always run all language scans regardless of changes. + #### Usage Example ```yaml @@ -426,10 +432,22 @@ jobs: - `checkout-path` (string, optional): Path to check out code to. - `build-path` (string, optional): Path for build artifacts. -- `language-matrix` (string, optional, default: `'["cpp", "python", "actions"]'`): JSON array of languages to analyze. +- `language-matrix` (string, optional, default: `'["cpp", "python", "actions"]'`): JSON array of languages to analyze. When provided in `workflow_call`, bypasses automatic detection and forces analysis of specified languages. - `pr-number` (string, optional): PR number if run in PR context. - `pr-head-repo` (string, optional): The full name of the PR head repository. - `pr-base-repo` (string, optional): The full name of the PR base repository. +- `pr-base-sha` (string, optional): Base SHA of the PR for relevance check. +- `pr-head-sha` (string, optional): Head SHA of the PR for relevance check. +- `ref` (string, optional): The branch, ref, or SHA to checkout. +- `repo` (string, optional): The repository to checkout from. + +#### Behavior Notes + +- **Pull Requests**: Only languages with relevant file changes are analyzed. For example, a PR that only modifies Python files will skip C++ and Actions analysis, saving 35-70 minutes of CI time. +- **Manual Runs** (`workflow_dispatch`): All languages are analyzed regardless of changes. +- **Scheduled Runs**: All languages are analyzed regardless of changes. +- **Pushes to main/develop**: All languages are analyzed regardless of changes. +- **Language Override**: Providing the `language-matrix` input in `workflow_call` bypasses automatic detection. ### Other Workflows From afcfd4ad4a316ef2c15cffce2813c36b63b2019d Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 13 Feb 2026 16:18:43 +0000 Subject: [PATCH 3/6] Add validation for language-matrix input to prevent invalid JSON Co-authored-by: greenc-FNAL <2372949+greenc-FNAL@users.noreply.github.com> --- .github/workflows/codeql-analysis.yaml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.github/workflows/codeql-analysis.yaml b/.github/workflows/codeql-analysis.yaml index 6e23a98dc..c40fe2e47 100644 --- a/.github/workflows/codeql-analysis.yaml +++ b/.github/workflows/codeql-analysis.yaml @@ -228,6 +228,11 @@ jobs: # If detection was skipped, use all languages or the provided language-matrix if [ "${{ needs.pre-check.outputs.skip_detection }}" = "true" ]; then if [ "${{ github.event_name }}" = "workflow_call" ] && [ -n "${{ inputs.language-matrix }}" ]; then + # Validate that language-matrix is valid JSON + if ! echo '${{ inputs.language-matrix }}' | python3 -c "import sys, json; json.load(sys.stdin)" 2>/dev/null; then + echo "::error::Invalid language-matrix input: must be valid JSON array" + exit 1 + fi echo "languages=${{ inputs.language-matrix }}" >> "$GITHUB_OUTPUT" else echo 'languages=["cpp", "python", "actions"]' >> "$GITHUB_OUTPUT" From 4f0c0c6dde02dd96cbf890c82278490d43b5d474 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 13 Feb 2026 16:20:07 +0000 Subject: [PATCH 4/6] Fix command injection vulnerability by using environment variable for language-matrix input Co-authored-by: greenc-FNAL <2372949+greenc-FNAL@users.noreply.github.com> --- .github/workflows/codeql-analysis.yaml | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/.github/workflows/codeql-analysis.yaml b/.github/workflows/codeql-analysis.yaml index c40fe2e47..9d31e23b1 100644 --- a/.github/workflows/codeql-analysis.yaml +++ b/.github/workflows/codeql-analysis.yaml @@ -224,16 +224,18 @@ jobs: steps: - name: Build language matrix id: build_matrix + env: + LANGUAGE_MATRIX: ${{ inputs.language-matrix }} run: | # If detection was skipped, use all languages or the provided language-matrix if [ "${{ needs.pre-check.outputs.skip_detection }}" = "true" ]; then - if [ "${{ github.event_name }}" = "workflow_call" ] && [ -n "${{ inputs.language-matrix }}" ]; then + if [ "${{ github.event_name }}" = "workflow_call" ] && [ -n "$LANGUAGE_MATRIX" ]; then # Validate that language-matrix is valid JSON - if ! echo '${{ inputs.language-matrix }}' | python3 -c "import sys, json; json.load(sys.stdin)" 2>/dev/null; then + if ! echo "$LANGUAGE_MATRIX" | python3 -c "import sys, json; json.load(sys.stdin)" 2>/dev/null; then echo "::error::Invalid language-matrix input: must be valid JSON array" exit 1 fi - echo "languages=${{ inputs.language-matrix }}" >> "$GITHUB_OUTPUT" + echo "languages=$LANGUAGE_MATRIX" >> "$GITHUB_OUTPUT" else echo 'languages=["cpp", "python", "actions"]' >> "$GITHUB_OUTPUT" fi From 9b2ea9e0184b1aea165f9a322954bfa42ec12962 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 13 Feb 2026 16:39:38 +0000 Subject: [PATCH 5/6] Fix language-matrix default and head-ref pattern for workflow_call support - Remove default value from language-matrix input to enable proper detection - Update head-ref in all detect-changes jobs to use pr-head-sha pattern - Follows established pattern from python-check, cmake-build workflows Co-authored-by: greenc-FNAL <2372949+greenc-FNAL@users.noreply.github.com> --- .github/workflows/codeql-analysis.yaml | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/.github/workflows/codeql-analysis.yaml b/.github/workflows/codeql-analysis.yaml index 9d31e23b1..7eb46a844 100644 --- a/.github/workflows/codeql-analysis.yaml +++ b/.github/workflows/codeql-analysis.yaml @@ -27,7 +27,6 @@ on: description: "JSON array of languages to analyze" required: false type: string - default: '["cpp", "python", "actions"]' pr-number: description: "PR number if run in PR context" required: false @@ -120,7 +119,7 @@ jobs: with: repo-path: ${{ needs.pre-check.outputs.local_checkout_path }} base-ref: ${{ needs.pre-check.outputs.base_sha }} - head-ref: ${{ needs.pre-check.outputs.ref }} + head-ref: ${{ (github.event_name == 'workflow_call' && inputs.pr-head-sha) || needs.pre-check.outputs.ref }} file-type: | cpp cmake @@ -160,7 +159,7 @@ jobs: with: repo-path: ${{ needs.pre-check.outputs.local_checkout_path }} base-ref: ${{ needs.pre-check.outputs.base_sha }} - head-ref: ${{ needs.pre-check.outputs.ref }} + head-ref: ${{ (github.event_name == 'workflow_call' && inputs.pr-head-sha) || needs.pre-check.outputs.ref }} file-type: python - name: Report detection outcome @@ -198,7 +197,7 @@ jobs: with: repo-path: ${{ needs.pre-check.outputs.local_checkout_path }} base-ref: ${{ needs.pre-check.outputs.base_sha }} - head-ref: ${{ needs.pre-check.outputs.ref }} + head-ref: ${{ (github.event_name == 'workflow_call' && inputs.pr-head-sha) || needs.pre-check.outputs.ref }} include-globs: | .github/workflows/*.yaml .github/workflows/*.yml From 2999701daea5b71d87663bc42ecba4356aa8f3be Mon Sep 17 00:00:00 2001 From: Chris Green Date: Mon, 16 Feb 2026 17:48:13 -0600 Subject: [PATCH 6/6] Address @knoepfel review comments --- .github/CodeQL-README.md | 6 +++--- .github/REUSABLE_WORKFLOWS.md | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/CodeQL-README.md b/.github/CodeQL-README.md index 1f8d7abd9..22d461060 100644 --- a/.github/CodeQL-README.md +++ b/.github/CodeQL-README.md @@ -1,6 +1,6 @@ # CodeQL scanning for this repository -This repository uses C++ (C++20 / moving to C++23) built with CMake under the phlex-src directory, plus some Python and CI bits (Bash). The repository includes a CodeQL GitHub Actions workflow that: +This repository uses C++23 built with CMake under the phlex-src directory, plus some Python and CI bits (Bash). The repository includes a CodeQL GitHub Actions workflow that: - Runs on pushes to `main`, PRs targeting `main`, a weekly schedule, and can be run manually. - Uses the repository's existing Phlex CMake build actions (not CodeQL autobuild) so the same build configuration is used for tests and release builds. @@ -19,8 +19,8 @@ The CodeQL workflow analyzes three language categories: ### Detection Behavior by Event Type - **Pull Requests**: Only languages with relevant file changes are analyzed - - Example: A PR changing only Python files will skip C++ and Actions analysis (saves 35-70 minutes) - - Example: A PR changing only C++ files will skip Python and Actions analysis (saves 10-20 minutes) + - Example: A PR changing only Python files will skip C++ and Actions analysis + - Example: A PR changing only C++ files will skip Python and Actions analysis - Example: A PR changing only workflow files will skip C++ and Python analysis - **Pushes to main/develop**: All languages are analyzed (no detection) - **Scheduled runs**: All languages are analyzed (no detection) diff --git a/.github/REUSABLE_WORKFLOWS.md b/.github/REUSABLE_WORKFLOWS.md index 8a2487bb1..b721e3de4 100644 --- a/.github/REUSABLE_WORKFLOWS.md +++ b/.github/REUSABLE_WORKFLOWS.md @@ -443,7 +443,7 @@ jobs: #### Behavior Notes -- **Pull Requests**: Only languages with relevant file changes are analyzed. For example, a PR that only modifies Python files will skip C++ and Actions analysis, saving 35-70 minutes of CI time. +- **Pull Requests**: Only languages with relevant file changes are analyzed. For example, a PR that only modifies Python files will skip C++ and Actions analysis. - **Manual Runs** (`workflow_dispatch`): All languages are analyzed regardless of changes. - **Scheduled Runs**: All languages are analyzed regardless of changes. - **Pushes to main/develop**: All languages are analyzed regardless of changes.