-
Notifications
You must be signed in to change notification settings - Fork 14.9k
[GitHub][CI] Add clang-tidy premerge workflow #154829
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
@llvm/pr-subscribers-github-workflow Author: Baranov Victor (vbvictor) ChangesKEY POINTS
FOUND ISSUES + open questions
TO DO
TEST RUN A working example can be found here #154223, with this #154223 (comment). Note that I made 2 total violations in the code: one in --- a/.github/workflows/pr-code-lint.yml
+++ b/.github/workflows/pr-code-lint.yml
@@ -49,8 +49,8 @@ jobs:
- name: Fetch code linting utils
uses: actions/checkout@<!-- -->08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
with:
- repository: ${{ github.repository }}
- ref: ${{ github.base_ref }}
+ repository: ${{ github.event.pull_request.head.repo.full_name }}
+ ref: ${{ github.event.pull_request.head.ref }}
sparse-checkout: |
llvm/utils/git/code-lint-helper.py
llvm/utils/git/requirements_linting.txt Patch is 41.54 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/154829.diff 5 Files Affected:
diff --git a/.github/workflows/issue-write.yml b/.github/workflows/issue-write.yml
index 3036582a64a58..db9389b6afe53 100644
--- a/.github/workflows/issue-write.yml
+++ b/.github/workflows/issue-write.yml
@@ -6,6 +6,7 @@ on:
- "Check code formatting"
- "Check for private emails used in PRs"
- "PR Request Release Note"
+ - "Code lint"
types:
- completed
diff --git a/.github/workflows/pr-code-lint.yml b/.github/workflows/pr-code-lint.yml
new file mode 100644
index 0000000000000..89d5f5e499724
--- /dev/null
+++ b/.github/workflows/pr-code-lint.yml
@@ -0,0 +1,126 @@
+name: "Code lint"
+
+permissions:
+ contents: read
+
+on:
+ pull_request:
+ branches:
+ - main
+ - 'users/**'
+ paths:
+ - 'clang-tools-extra/clang-tidy/**'
+
+jobs:
+ code_linter:
+ if: github.repository_owner == 'llvm'
+ runs-on: ubuntu-24.04
+ defaults:
+ run:
+ shell: bash
+ container:
+ image: 'ghcr.io/llvm/ci-ubuntu-24.04:latest'
+ timeout-minutes: 60
+ concurrency:
+ group: ${{ github.workflow }}-${{ github.ref }}
+ cancel-in-progress: true
+ steps:
+ - name: Fetch LLVM sources
+ uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
+ with:
+ fetch-depth: 2
+
+ - name: Get changed files
+ id: changed-files
+ uses: step-security/changed-files@3dbe17c78367e7d60f00d78ae6781a35be47b4a1 # v45.0.1
+ with:
+ separator: ","
+ skip_initial_fetch: true
+ base_sha: 'HEAD~1'
+ sha: 'HEAD'
+
+ - name: Listed files
+ env:
+ CHANGED_FILES: ${{ steps.changed-files.outputs.all_changed_files }}
+ run: |
+ echo "Changed files:"
+ echo "$CHANGED_FILES"
+
+ - name: Fetch code linting utils
+ uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
+ with:
+ repository: ${{ github.repository }}
+ ref: ${{ github.base_ref }}
+ sparse-checkout: |
+ llvm/utils/git/code-lint-helper.py
+ llvm/utils/git/requirements_linting.txt
+ clang-tools-extra/clang-tidy/tool/clang-tidy-diff.py
+ sparse-checkout-cone-mode: false
+ path: code-lint-tools
+
+ - uses: actions/setup-python@v5
+ id: setup_python
+ with:
+ python-version: '3.12'
+
+ - name: Install dependencies
+ run: |
+ python3 -m venv .venv
+ source .venv/bin/activate
+ python3 -m pip install -r code-lint-tools/llvm/utils/git/requirements_linting.txt
+
+ - name: Install clang-tidy
+ uses: aminya/setup-cpp@17c11551771948abc5752bbf3183482567c7caf0 # v1.1.1
+ with:
+ clang-tidy: 20.1.8
+
+ # FIXME: create special mapping for 'gen' targets, for now build predefined set
+ - name: Configure and CodeGen
+ run: |
+ git config --global --add safe.directory '*'
+
+ source <(git diff --name-only HEAD~1...HEAD | python3 .ci/compute_projects.py)
+
+ if [[ "${projects_to_build}" == "" ]]; then
+ echo "No projects to analyze"
+ exit 0
+ fi
+
+ cmake -G Ninja \
+ -B build \
+ -S llvm \
+ -DLLVM_ENABLE_ASSERTIONS=OFF \
+ -DLLVM_ENABLE_PROJECTS="${projects_to_build}" \
+ -DCMAKE_CXX_COMPILER=clang++ \
+ -DCMAKE_C_COMPILER=clang \
+ -DCMAKE_EXPORT_COMPILE_COMMANDS=ON \
+ -DLLVM_INCLUDE_TESTS=OFF \
+ -DCLANG_INCLUDE_TESTS=OFF \
+ -DCMAKE_BUILD_TYPE=Release
+
+ ninja -C build \
+ clang-tablegen-targets \
+ genconfusable # for "ConfusableIdentifierCheck.h"
+
+ - name: Run code linter
+ env:
+ GITHUB_PR_NUMBER: ${{ github.event.pull_request.number }}
+ CHANGED_FILES: ${{ steps.changed-files.outputs.all_changed_files }}
+ run: |
+ source .venv/bin/activate
+ echo "[]" > comments &&
+ python3 ./code-lint-tools/llvm/utils/git/code-lint-helper.py \
+ --token ${{ secrets.GITHUB_TOKEN }} \
+ --issue-number $GITHUB_PR_NUMBER \
+ --start-rev HEAD~1 \
+ --end-rev HEAD \
+ --verbose \
+ --changed-files "$CHANGED_FILES"
+
+ - name: Upload results
+ uses: actions/upload-artifact@26f96dfa697d77e81fd5907df203aa23a56210a8 #v4.3.0
+ if: always()
+ with:
+ name: workflow-args
+ path: |
+ comments
diff --git a/llvm/utils/git/code-lint-helper.py b/llvm/utils/git/code-lint-helper.py
new file mode 100755
index 0000000000000..fc6532f084e90
--- /dev/null
+++ b/llvm/utils/git/code-lint-helper.py
@@ -0,0 +1,365 @@
+#!/usr/bin/env python3
+#
+# ====- clang-tidy-helper, runs clang-tidy from the ci --*- python -*-------==#
+#
+# Part of the LLVM Project, 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
+#
+# ==-------------------------------------------------------------------------==#
+
+import argparse
+import os
+import subprocess
+import sys
+from typing import List, Optional
+
+"""
+This script is run by GitHub actions to ensure that the code in PR's conform to
+the coding style of LLVM. The canonical source of this script is in the LLVM
+source tree under llvm/utils/git.
+
+You can learn more about the LLVM coding style on llvm.org:
+https://llvm.org/docs/CodingStandards.html
+"""
+
+
+class LintArgs:
+ start_rev: str = None
+ end_rev: str = None
+ repo: str = None
+ changed_files: List[str] = []
+ token: str = None
+ verbose: bool = True
+ issue_number: int = 0
+
+ def __init__(self, args: argparse.Namespace = None) -> None:
+ if not args is None:
+ self.start_rev = args.start_rev
+ self.end_rev = args.end_rev
+ self.repo = args.repo
+ self.token = args.token
+ self.changed_files = args.changed_files
+ self.issue_number = args.issue_number
+ self.verbose = args.verbose
+
+
+class LintHelper:
+ COMMENT_TAG = "<!--LLVM CODE LINT COMMENT: {linter}-->"
+ name: str
+ friendly_name: str
+ comment: dict = None
+
+ @property
+ def comment_tag(self) -> str:
+ return self.COMMENT_TAG.replace("linter", self.name)
+
+ @property
+ def instructions(self) -> str:
+ raise NotImplementedError()
+
+ def has_tool(self) -> bool:
+ raise NotImplementedError()
+
+ def lint_run(self, changed_files: List[str], args: LintArgs) -> Optional[str]:
+ raise NotImplementedError()
+
+ def pr_comment_text_for_output(self, warning: str) -> str:
+ return f"""
+:warning: {self.friendly_name} {self.name} found issues in your code. :warning:
+
+<details>
+<summary>
+You can test this locally with the following command:
+</summary>
+
+``````````bash
+{self.instructions}
+``````````
+
+</details>
+
+<details>
+<summary>
+View the output from {self.name} here.
+</summary>
+
+``````````
+{warning}
+``````````
+
+</details>
+"""
+
+ def find_comment(self, pr: any) -> any:
+ for comment in pr.as_issue().get_comments():
+ if self.comment_tag in comment.body:
+ return comment
+ return None
+
+ def update_pr(self, comment_text: str, args: LintArgs, create_new: bool) -> None:
+ import github
+
+ repo = github.Github(args.token).get_repo(args.repo)
+ pr = repo.get_issue(args.issue_number).as_pull_request()
+
+ comment_text = self.comment_tag + "\n\n" + comment_text
+
+ existing_comment = self.find_comment(pr)
+
+ if create_new or existing_comment:
+ self.comment = {"body": comment_text}
+ if existing_comment:
+ self.comment["id"] = existing_comment.id
+ return
+
+ def run(self, changed_files: List[str], args: LintArgs) -> bool:
+ changed_files = [arg for arg in changed_files if "third-party" not in arg]
+ diff = self.lint_run(changed_files, args)
+ should_update_gh = args.token is not None and args.repo is not None
+
+ if diff is None:
+ if should_update_gh:
+ comment_text = (
+ ":white_check_mark: With the latest revision "
+ f"this PR passed the {self.friendly_name}."
+ )
+ self.update_pr(comment_text, args, create_new=False)
+ return True
+ elif len(diff) > 0:
+ if should_update_gh:
+ comment_text = self.pr_comment_text_for_output(diff)
+ self.update_pr(comment_text, args, create_new=True)
+ else:
+ print(
+ f"Warning: {self.friendly_name}, {self.name} detected "
+ "some issues with your code formatting..."
+ )
+ return False
+ else:
+ # The linter failed but didn't output a result (e.g. some sort of
+ # infrastructure failure).
+ comment_text = (
+ f":warning: The {self.friendly_name} failed without printing "
+ "a diff. Check the logs for stderr output. :warning:"
+ )
+ self.update_pr(comment_text, args, create_new=False)
+ return False
+
+
+class ClangTidyDiffHelper(LintHelper):
+ name = "clang-tidy"
+ friendly_name = "C/C++ code linter"
+
+ def __init__(self, build_path: str, clang_tidy_binary: str):
+ self.build_path = build_path
+ self.clang_tidy_binary = clang_tidy_binary
+ self.cpp_files = []
+
+ def _clean_clang_tidy_output(self, output: str) -> str:
+ """
+ - Remove 'Running clang-tidy in X threads...' line
+ - Remove 'N warnings generated.' line
+ - Strip leading workspace path from file paths
+ """
+ if not output or output == "No relevant changes found.":
+ return None
+
+ lines = output.split("\n")
+ cleaned_lines = []
+
+ for line in lines:
+ if line.startswith("Running clang-tidy in") or line.endswith("generated."):
+ continue
+
+ # Remove everything up to rightmost "llvm-project/" for correct files names
+ idx = line.rfind("llvm-project/")
+ if idx != -1:
+ line = line[idx + len("llvm-project/") :]
+
+ cleaned_lines.append(line)
+
+ if cleaned_lines:
+ return "\n".join(cleaned_lines)
+ return None
+
+ @property
+ def instructions(self) -> str:
+ files_str = " ".join(self.cpp_files)
+ return f"""
+git diff -U0 origin/main..HEAD -- {files_str} |
+python3 clang-tools-extra/clang-tidy/tool/clang-tidy-diff.py \\
+ -path build -p1 -quiet"""
+
+ # For add other paths/files to this function
+ def should_lint_file(self, filepath):
+ return filepath.startswith("clang-tools-extra/clang-tidy/")
+
+ def filter_changed_files(self, changed_files: List[str]) -> List[str]:
+ filtered_files = []
+ for filepath in changed_files:
+ _, ext = os.path.splitext(filepath)
+ if ext not in (".cpp", ".c", ".h", ".hpp", ".hxx", ".cxx"):
+ continue
+ if not self.should_lint_file(filepath):
+ continue
+ if os.path.exists(filepath):
+ filtered_files.append(filepath)
+
+ return filtered_files
+
+ def has_tool(self) -> bool:
+ cmd = [self.clang_tidy_binary, "--version"]
+ proc = None
+ try:
+ proc = subprocess.run(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+ except:
+ return False
+ return proc.returncode == 0
+
+ def lint_run(self, changed_files: List[str], args: LintArgs) -> Optional[str]:
+ cpp_files = self.filter_changed_files(changed_files)
+ if not cpp_files:
+ print("no c/c++ files found")
+ return None
+
+ self.cpp_files = cpp_files
+
+ git_diff_cmd = [
+ "git",
+ "diff",
+ "-U0",
+ f"{args.start_rev}..{args.end_rev}",
+ "--",
+ ] + cpp_files
+
+ diff_proc = subprocess.run(
+ git_diff_cmd,
+ stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE,
+ text=True,
+ check=False,
+ )
+
+ if diff_proc.returncode != 0:
+ print(f"Git diff failed: {diff_proc.stderr}")
+ return None
+
+ diff_content = diff_proc.stdout
+ if not diff_content.strip():
+ print("No diff content found")
+ return None
+
+ tidy_diff_cmd = [
+ "code-lint-tools/clang-tools-extra/clang-tidy/tool/clang-tidy-diff.py",
+ "-path",
+ self.build_path,
+ "-p1",
+ "-quiet",
+ ]
+
+ if args.verbose:
+ print(f"Running clang-tidy-diff: {' '.join(tidy_diff_cmd)}")
+
+ proc = subprocess.run(
+ tidy_diff_cmd,
+ input=diff_content,
+ stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE,
+ text=True,
+ check=False,
+ )
+
+ return self._clean_clang_tidy_output(proc.stdout.strip())
+
+
+if __name__ == "__main__":
+ parser = argparse.ArgumentParser()
+ parser.add_argument(
+ "--token", type=str, required=True, help="GitHub authentication token"
+ )
+ parser.add_argument("--issue-number", type=int, required=True)
+ parser.add_argument(
+ "--repo",
+ type=str,
+ default=os.getenv("GITHUB_REPOSITORY", "llvm/llvm-project"),
+ help="The GitHub repository that we are working with in the form of <owner>/<repo> (e.g. llvm/llvm-project)",
+ )
+ parser.add_argument(
+ "--start-rev",
+ type=str,
+ required=True,
+ help="Compute changes from this revision.",
+ )
+ parser.add_argument(
+ "--end-rev", type=str, required=True, help="Compute changes to this revision"
+ )
+ parser.add_argument(
+ "--changed-files",
+ type=str,
+ help="Comma separated list of files that has been changed",
+ )
+ parser.add_argument(
+ "--build-path",
+ type=str,
+ default="build",
+ help="Path to build directory with compile_commands.json",
+ )
+ parser.add_argument(
+ "--clang-tidy-binary",
+ type=str,
+ default="clang-tidy",
+ help="Path to clang-tidy binary",
+ )
+ parser.add_argument(
+ "--verbose", action="store_true", default=True, help="Verbose output"
+ )
+
+ parsed_args = parser.parse_args()
+ args = LintArgs(parsed_args)
+
+ changed_files = []
+ if args.changed_files:
+ changed_files = args.changed_files.split(",")
+
+ if args.verbose:
+ print(f"got changed files: {changed_files}")
+
+ all_linters = [
+ ClangTidyDiffHelper(
+ build_path=parsed_args.build_path,
+ clang_tidy_binary=parsed_args.clang_tidy_binary,
+ )
+ ]
+
+ failed_linters = []
+ comments = []
+
+ for linter in all_linters:
+ if not linter.has_tool():
+ print(f"Couldn't find {linter.friendly_name}: {linter.name}")
+ continue
+
+ if args.verbose:
+ print(f"running linter {linter.name}")
+
+ if not linter.run(changed_files, args):
+ if args.verbose:
+ print(f"linter {linter.name} failed")
+ failed_linters.append(linter.name)
+
+ if linter.comment:
+ if args.verbose:
+ print(f"linter {linter.name} has comment: {linter.comment}")
+ comments.append(linter.comment)
+
+ if len(comments) > 0:
+ with open("comments", "w") as f:
+ import json
+
+ json.dump(comments, f)
+
+ if len(failed_linters) > 0:
+ print(f"error: some linters failed: {' '.join(failed_linters)}")
+ # Do not fail job for as it may be unstable
+ # sys.exit(1)
diff --git a/llvm/utils/git/requirements_linting.txt b/llvm/utils/git/requirements_linting.txt
new file mode 100644
index 0000000000000..b985b80aa869e
--- /dev/null
+++ b/llvm/utils/git/requirements_linting.txt
@@ -0,0 +1,324 @@
+#
+# This file is autogenerated by pip-compile with Python 3.12
+# by the following command:
+#
+# pip-compile --generate-hashes --output-file=requirements_linting.txt requirements_linting.txt.in
+#
+certifi==2025.8.3 \
+ --hash=sha256:e564105f78ded564e3ae7c923924435e1daa7463faeab5bb932bc53ffae63407 \
+ --hash=sha256:f6c12493cfb1b06ba2ff328595af9350c65d6644968e5d3a2ffd78699af217a5
+ # via requests
+cffi==1.17.1 \
+ --hash=sha256:045d61c734659cc045141be4bae381a41d89b741f795af1dd018bfb532fd0df8 \
+ --hash=sha256:0984a4925a435b1da406122d4d7968dd861c1385afe3b45ba82b750f229811e2 \
+ --hash=sha256:0e2b1fac190ae3ebfe37b979cc1ce69c81f4e4fe5746bb401dca63a9062cdaf1 \
+ --hash=sha256:0f048dcf80db46f0098ccac01132761580d28e28bc0f78ae0d58048063317e15 \
+ --hash=sha256:1257bdabf294dceb59f5e70c64a3e2f462c30c7ad68092d01bbbfb1c16b1ba36 \
+ --hash=sha256:1c39c6016c32bc48dd54561950ebd6836e1670f2ae46128f67cf49e789c52824 \
+ --hash=sha256:1d599671f396c4723d016dbddb72fe8e0397082b0a77a4fab8028923bec050e8 \
+ --hash=sha256:28b16024becceed8c6dfbc75629e27788d8a3f9030691a1dbf9821a128b22c36 \
+ --hash=sha256:2bb1a08b8008b281856e5971307cc386a8e9c5b625ac297e853d36da6efe9c17 \
+ --hash=sha256:30c5e0cb5ae493c04c8b42916e52ca38079f1b235c2f8ae5f4527b963c401caf \
+ --hash=sha256:31000ec67d4221a71bd3f67df918b1f88f676f1c3b535a7eb473255fdc0b83fc \
+ --hash=sha256:386c8bf53c502fff58903061338ce4f4950cbdcb23e2902d86c0f722b786bbe3 \
+ --hash=sha256:3edc8d958eb099c634dace3c7e16560ae474aa3803a5df240542b305d14e14ed \
+ --hash=sha256:45398b671ac6d70e67da8e4224a065cec6a93541bb7aebe1b198a61b58c7b702 \
+ --hash=sha256:46bf43160c1a35f7ec506d254e5c890f3c03648a4dbac12d624e4490a7046cd1 \
+ --hash=sha256:4ceb10419a9adf4460ea14cfd6bc43d08701f0835e979bf821052f1805850fe8 \
+ --hash=sha256:51392eae71afec0d0c8fb1a53b204dbb3bcabcb3c9b807eedf3e1e6ccf2de903 \
+ --hash=sha256:5da5719280082ac6bd9aa7becb3938dc9f9cbd57fac7d2871717b1feb0902ab6 \
+ --hash=sha256:610faea79c43e44c71e1ec53a554553fa22321b65fae24889706c0a84d4ad86d \
+ --hash=sha256:636062ea65bd0195bc012fea9321aca499c0504409f413dc88af450b57ffd03b \
+ --hash=sha256:6883e737d7d9e4899a8a695e00ec36bd4e5e4f18fabe0aca0efe0a4b44cdb13e \
+ --hash=sha256:6b8b4a92e1c65048ff98cfe1f735ef8f1ceb72e3d5f0c25fdb12087a23da22be \
+ --hash=sha256:6f17be4345073b0a7b8ea599688f692ac3ef23ce28e5df79c04de519dbc4912c \
+ --hash=sha256:706510fe141c86a69c8ddc029c7910003a17353970cff3b904ff0686a5927683 \
+ --hash=sha256:72e72408cad3d5419375fc87d289076ee319835bdfa2caad331e377589aebba9 \
+ --hash=sha256:733e99bc2df47476e3848417c5a4540522f234dfd4ef3ab7fafdf555b082ec0c \
+ --hash=sha256:7596d6620d3fa590f677e9ee430df2958d2d6d6de2feeae5b20e82c00b76fbf8 \
+ --hash=sha256:78122be759c3f8a014ce010908ae03364d00a1f81ab5c7f4a7a5120607ea56e1 \
+ --hash=sha256:805b4371bf7197c329fcb3ead37e710d1bca9da5d583f5073b799d5c5bd1eee4 \
+ --hash=sha256:85a950a4ac9c359340d5963966e3e0a94a676bd6245a4b55bc43949eee26a655 \
+ --hash=sha256:8f2cdc858323644ab277e9bb925ad72ae0e67f69e804f4898c070998d50b1a67 \
+ --hash=sha256:9755e4345d1ec879e3849e62222a18c7174d65a6a92d5b346b1863912168b595 \
+ --hash=sha256:98e3969bcff97cae1b2def8ba499ea3d6f31ddfdb7635374834cf89a1a08ecf0 \
+ --hash=sha256:a08d7e755f8ed21095a310a693525137cfe756ce62d066e53f502a83dc550f65 \
+ --hash=sha256:a1ed2dd2972641495a3ec98445e09766f077aee98a1c896dcb4ad0d303628e41 \
+ --hash=sha256:a24ed04c8ffd54b0729c07cee15a81d964e6fee0e3d4d342a27b020d22959dc6 \
+ --hash=sha256:a45e3c6913c5b87b3ff120dcdc03f6131fa0065027d0ed7ee6190736a74cd401 \
+ --hash=sha256:a9b15d491f3ad5d692e11f6b71f7857e7835eb677955c00cc0aefcd0669adaf6 \
+ --hash=sha256:ad9413ccdeda48c5afdae7e4fa2192157e991ff761e7ab8fdd8926f40b160cc3 \
+ --hash=sha256:b2ab587605f4ba0bf81dc0cb08a41bd1c0a5906bd59243d56bad7668a6fc6c16 \
+ ...
[truncated]
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
code-lint-helper.py
currently very closely follows the structure of code-format-helper.py
. I'm not convinced any of the abstractions there are actually useful, at least currently.
You suggest making it in "plain script" format without any abstractions? |
Yes. |
Done, it didn't become much shorter, but removed some complexity though. |
KEY POINTS
clang-tools-extra/clang-tidy
. It's chosen this way asclang-tools-extra/clang-tidy
is almost 100%clang-tidy
complaint, thus we would automatically enforce a high quality standard for clang-tidy source code. ([clang-tidy][NFC] add '.clang-tidy' config for clang-tidy project #147793)code-lint-helper.py
locally.FOUND ISSUES + open questions
clang-tidy
plus additional ~4 mins to configure and CodeGen targets. I see thatpremerge.yaml
runs on specialllvm-premerge-linux-runners
runners which can usesccache
for speed. Can we use the same runners for this job? Exact timings can be found here.TO DO
code-lint-helper.py
andcode-format-helper.py
into a separate file and reuse it in both CI's.projects_to_build
, for nowclang-tablegen-targets
is hardcoded forclang-tools-extra/
..yaml
forclang-apply-replacements
clang-tidy
in other projects so that Maintainers of LLVM components could choose if they wantclang-tidy
or not.pylint
,ruff
in the future.TEST RUN
A working example can be found here #154223, with this #154223 (comment). Note that I made 2 total violations in the code: one in
clang-tools-extra/clangd/AST.cpp
and other inclang-tools-extra/clang-tidy/performance/MoveConstArgCheck.cpp
, but workflow intentionally reported only the one fromclang-tools-extra/clang-tidy
because we only lint this directory as an MVP.The only difference between "test" PR and current one is (which was needed for test purposes since we don't have needed files in main branch):