| # Copyright 2026 The IREE Authors |
| # |
| # Licensed under the Apache License v2.0 with LLVM Exceptions. |
| # See https://llvm.org/LICENSE.txt for license information. |
| # SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
| |
| # This workflow uses the newest clang-tidy binary built from source after the |
| # latest integrate. This way we get the newest checks (incl., llvm-specific |
| # ones). |
| |
| name: Clang Tidy |
| |
| on: |
| pull_request: |
| paths: |
| - '**.h' |
| - '**.c' |
| - '**.cpp' |
| - '.clang-tidy' |
| - '.github/workflows/clang_tidy.yml' |
| |
| permissions: |
| contents: write |
| pull-requests: write |
| |
| concurrency: |
| group: ${{ github.workflow }}-${{ github.event.pull_request.number }} |
| cancel-in-progress: true |
| |
| jobs: |
| clang-tidy: |
| runs-on: ubuntu-24.04 |
| container: |
| image: ghcr.io/iree-org/cpubuilder_ubuntu_jammy@sha256:78a558b999b230f7e1da376639e14b44f095f30f1777d6a272ba48c0bbdd4ccb |
| defaults: |
| run: |
| shell: bash |
| env: |
| BUILD_DIR: build |
| steps: |
| - name: Check out repository |
| uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 |
| with: |
| submodules: false |
| fetch-depth: 0 |
| |
| - name: Initialize submodules |
| run: | |
| git config --global --add safe.directory "$GITHUB_WORKSPACE" |
| git submodule update --init --depth=1 |
| |
| - name: Download iree-clang-tidy artifact |
| uses: dawidd6/action-download-artifact@b6e2e70617bc3265edd6dab6c906732b2f1ae151 # v21 |
| with: |
| workflow: build_clang_tidy.yml |
| name: iree-clang-tidy-linux-x86_64 |
| path: .iree-clang-tidy |
| |
| - name: Setup iree-clang-tidy |
| run: | |
| # Make executable (artifact download doesn't preserve permissions). |
| chmod +x .iree-clang-tidy/clang-tidy |
| echo "Using clang-tidy from llvm-project revision:" |
| cat .iree-clang-tidy/llvm-project-revision.txt |
| .iree-clang-tidy/clang-tidy --version |
| |
| - name: Install Python requirements |
| run: | |
| # Use uv instead of plain pip since cpp-linter uses it anyway. |
| curl -LsSf https://astral.sh/uv/install.sh | sh |
| echo "$HOME/.local/bin" >> "$GITHUB_PATH" |
| export PATH="$HOME/.local/bin:$PATH" |
| uv pip install --system -r ./runtime/bindings/python/iree/runtime/build_requirements.txt |
| uv pip install --system -r ./build_tools/github_actions/ci_requirements.txt |
| |
| - name: Generate compilation database (compile_commands.json) |
| run: | |
| IREE_CONFIGURE_ONLY=1 ./build_tools/cmake/build_all.sh "${BUILD_DIR}" |
| |
| - name: Select clang-tidy diff mode |
| id: tidy-diff-mode |
| env: |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} |
| PR_NUMBER: ${{ github.event.pull_request.number }} |
| run: | |
| status_code=$(curl -sS -o /tmp/pr.diff -w "%{http_code}" \ |
| -H "Authorization: Bearer ${GITHUB_TOKEN}" \ |
| -H "Accept: application/vnd.github.v3.diff" \ |
| "${GITHUB_API_URL}/repos/${GITHUB_REPOSITORY}/pulls/${PR_NUMBER}") |
| if [[ "${status_code}" == "200" ]]; then |
| echo "use_cpp_linter=true" >> "${GITHUB_OUTPUT}" |
| else |
| echo "GitHub PR diff request returned ${status_code}; running clang-tidy locally on changed files." |
| echo "use_cpp_linter=false" >> "${GITHUB_OUTPUT}" |
| fi |
| |
| - name: Run clang-tidy |
| if: steps.tidy-diff-mode.outputs.use_cpp_linter == 'true' |
| uses: cpp-linter/cpp-linter-action@77c390c5ba9c947ebc185a3e49cc754f1558abb5 # v1.11.4 |
| id: linter |
| env: |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} |
| with: |
| version: .iree-clang-tidy |
| style: '' # Disable clang-format (already handled by pre-commit). |
| tidy-checks: '' # Use .clang-tidy config files. |
| database: ${{ env.BUILD_DIR }} |
| files-changed-only: true |
| lines-changed-only: diff |
| ignore: 'third_party' |
| thread-comments: false |
| step-summary: true |
| |
| - name: Skip clang-tidy on large diff |
| if: steps.tidy-diff-mode.outputs.use_cpp_linter == 'false' |
| env: |
| BASE_SHA: ${{ github.event.pull_request.base.sha }} |
| HEAD_SHA: ${{ github.event.pull_request.head.sha }} |
| run: | |
| changed_files="${RUNNER_TEMP}/clang-tidy-changed-files.txt" |
| |
| git diff --name-only --diff-filter=ACMRT "${BASE_SHA}" "${HEAD_SHA}" \ |
| | grep -E '\.(c|h|C|H|cpp|hpp|cc|hh|c\+\+|h\+\+|cxx|hxx)$' \ |
| | grep -Ev '(^|/)third_party/' \ |
| | sort -u > "${changed_files}" || true |
| |
| if [[ ! -s "${changed_files}" ]]; then |
| echo "No changed C/C++ files found." |
| exit 0 |
| fi |
| |
| echo "::warning title=clang-tidy skipped::GitHub refused the PR diff because it exceeds the 20,000-line API limit, so cpp-linter cannot compute changed-line diagnostics for $(wc -l < "${changed_files}") changed C/C++ files." |