https://github.com/c-rhodes created https://github.com/llvm/llvm-project/pull/175908
this is failing for backport PRs on the release branch: https://github.com/llvm/llvm-project/actions/runs/20988225951/job/60327079595?pr=175743 it landed not long before the branch yesterday and has had a number of follow up fixes: https://github.com/llvm/llvm-project/pull/175549 https://github.com/llvm/llvm-project/pull/175629 https://github.com/llvm/llvm-project/pull/175723 https://github.com/llvm/llvm-project/pull/175752 https://github.com/llvm/llvm-project/pull/175905 I think this needs time to stabilise on main and I want to avoid noise when merging changes to release branch so I propose we revert this for now. >From d415988465178655b731bf36b5522b8764dbb0d5 Mon Sep 17 00:00:00 2001 From: Cullen Rhodes <[email protected]> Date: Wed, 14 Jan 2026 09:28:44 +0000 Subject: [PATCH 1/3] Revert "Fix syntax error in ids-check.yml workflow (#175629)" This reverts commit d514b32c239570e3eeb8ca0cca43338923904c99. --- .github/workflows/ids-check.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ids-check.yml b/.github/workflows/ids-check.yml index 0c31fff9ade4a..4a9b61006a99e 100644 --- a/.github/workflows/ids-check.yml +++ b/.github/workflows/ids-check.yml @@ -21,13 +21,13 @@ jobs: timeout-minutes: 10 steps: - - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 + uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 with: repository: compnerd/ids path: ${{ github.workspace }}/ids ref: b3bf35dd13d7ff244a6a6d106fe58d0eedb5743e # main - - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 + uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 with: path: ${{ github.workspace }}/llvm-project fetch-depth: 2 >From 9a65a398ba6f9f4540d5e15e409dee2f39f6545c Mon Sep 17 00:00:00 2001 From: Cullen Rhodes <[email protected]> Date: Wed, 14 Jan 2026 09:31:09 +0000 Subject: [PATCH 2/3] Revert "[ci] Add ids workflow for checking llvm apis have been annotated with LLVM_ABI (#172673)" This reverts commit d0235a150df2048e34136f894ccaa304230f5209. --- .github/workflows/ids-check.yml | 104 -------- llvm/utils/git/ids-check-helper.py | 410 ----------------------------- llvm/utils/git/requirements.txt | 6 +- llvm/utils/git/requirements.txt.in | 1 - 4 files changed, 1 insertion(+), 520 deletions(-) delete mode 100644 .github/workflows/ids-check.yml delete mode 100755 llvm/utils/git/ids-check-helper.py diff --git a/.github/workflows/ids-check.yml b/.github/workflows/ids-check.yml deleted file mode 100644 index 4a9b61006a99e..0000000000000 --- a/.github/workflows/ids-check.yml +++ /dev/null @@ -1,104 +0,0 @@ -name: "Check LLVM ABI annotations" -on: - pull_request: - push: - branches: - - 'main' - - 'release/**' - -permissions: - contents: read - -concurrency: - group: ${{ github.workflow }}-${{ github.event.pull_request.number }} - cancel-in-progress: true - -jobs: - build: - if: github.repository_owner == 'llvm' - name: Check LLVM_ABI annotations with ids - runs-on: ubuntu-24.04 - timeout-minutes: 10 - - steps: - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 - with: - repository: compnerd/ids - path: ${{ github.workspace }}/ids - ref: b3bf35dd13d7ff244a6a6d106fe58d0eedb5743e # main - - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 - with: - path: ${{ github.workspace }}/llvm-project - fetch-depth: 2 - - - name: Get changed files - id: changed-files - uses: tj-actions/changed-files@24d32ffd492484c1d75e0c0b894501ddb9d30d62 # v47.0.0 - with: - separator: "," - skip_initial_fetch: true - base_sha: 'HEAD~1' - sha: 'HEAD' - - - name: Install dependencies - run: | - sudo apt install -y clang-19 ninja-build libclang-19-dev - pip install --require-hashes -r ${{ github.workspace }}/llvm-project/llvm/utils/git/requirements.txt - - - name: Configure and build minimal LLVM for use by ids - run: | - cmake -B ${{ github.workspace }}/llvm-project/build/ \ - -S ${{ github.workspace }}/llvm-project/llvm/ \ - -D CMAKE_BUILD_TYPE=Release \ - -D CMAKE_C_COMPILER=clang \ - -D CMAKE_CXX_COMPILER=clang++ \ - -D LLVM_ENABLE_PROJECTS=clang \ - -D LLVM_TARGETS_TO_BUILD="host" \ - -D CMAKE_EXPORT_COMPILE_COMMANDS=ON \ - -G Ninja - cd ${{ github.workspace }}/llvm-project/build/ - ninja -t targets all | grep "CommonTableGen: phony$" | grep -v "/" | sed 's/:.*//' - - - name: Configure ids - run: | - cmake -B ${{ github.workspace }}/ids/build/ \ - -S ${{ github.workspace }}/ids/ \ - -D CMAKE_BUILD_TYPE=Release \ - -D CMAKE_C_COMPILER=clang \ - -D CMAKE_CXX_COMPILER=clang++ \ - -D CMAKE_EXE_LINKER_FLAGS=-fuse-ld=lld \ - -D LLVM_DIR=/usr/lib/llvm-19/lib/cmake/llvm/ \ - -D Clang_DIR=/usr/lib/llvm-19/lib/cmake/clang/ \ - -D FILECHECK_EXECUTABLE=$(which FileCheck-19) \ - -D LIT_EXECUTABLE=$(which lit) \ - -G Ninja - - # TODO: Use an image with a prebuilt idt. - - name: Build ids - run: | - ninja -C ${{ github.workspace }}/ids/build/ all - - - name: Run ids check - env: - GITHUB_PR_NUMBER: ${{ github.event.pull_request.number }} - CHANGED_FILES: ${{ steps.changed-files.outputs.all_changed_files }} - working-directory: ${{ github.workspace }}/llvm-project - run: | - echo "[]" > comments && - python llvm/utils/git/ids-check-helper.py \ - --token ${{ secrets.GITHUB_TOKEN }} \ - --issue-number $GITHUB_PR_NUMBER \ - --idt-path ${{ github.workspace }}/ids/build/bin/idt \ - --compile-commands ${{ github.workspace }}/llvm-project/build/compile_commands.json \ - --start-rev HEAD~1 \ - --end-rev HEAD \ - --changed-files "$CHANGED_FILES" - - - name: Upload results - uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0 - if: always() - with: - name: workflow-args - path: | - llvm-project/comments diff --git a/llvm/utils/git/ids-check-helper.py b/llvm/utils/git/ids-check-helper.py deleted file mode 100755 index 62a498dd0a71f..0000000000000 --- a/llvm/utils/git/ids-check-helper.py +++ /dev/null @@ -1,410 +0,0 @@ -#!/usr/bin/env python3 -# -# 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 PRs properly -labels LLVM APIs with `LLVM_ABI` so as not to break the LLVM DLL build. It can -also be installed as a pre-commit git hook to check ABI annotations before -submitting. The canonical source of this script is in the LLVM source tree -under llvm/utils/git. - -This script uses the idt (Interface Diff Tool) to check for missing LLVM_ABI, -LLVM_C_ABI, and DEMANGLE_ABI annotations in header files. - -You can install this script as a git hook by symlinking it to the .git/hooks -directory: - -ln -s $(pwd)/llvm/utils/git/ids-check-helper.py .git/hooks/pre-commit - -You can control the exact path to idt and compile_commands.json with the -following environment variables: $IDT_PATH and $COMPILE_COMMANDS_PATH. -""" - - -class IdsCheckArgs: - start_rev: str = "" - end_rev: str = "" - changed_files: List[str] = [] - idt_path: str = "" - compile_commands: str = "" - repo: str = "" - token: str = "" - issue_number: int = 0 - verbose: bool = True - - def __init__(self, args: argparse.Namespace) -> None: - self.start_rev = args.start_rev - self.end_rev = args.end_rev - self.changed_files = args.changed_files - self.idt_path = args.idt_path - self.compile_commands = args.compile_commands - self.repo = getattr(args, "repo", "") - self.token = getattr(args, "token", "") - self.issue_number = getattr(args, "issue_number", 0) - self.verbose = getattr(args, "verbose", True) - - -class IdsChecker: - """ - Checker for LLVM ABI annotations using the idt tool. - """ - - COMMENT_TAG = "<!--LLVM IDS CHECK COMMENT-->" - name = "ids-check" - friendly_name = "LLVM ABI annotation checker" - comment: dict = {} - - # Macro definition used for all export macros - MACRO_DEFINITION = '__attribute__((visibility("default")))' - - @property - def comment_tag(self) -> str: - return self.COMMENT_TAG - - @property - def instructions(self) -> str: - # Provide basic usage instructions - return f"""git diff origin/main HEAD -- 'llvm/include/llvm/**/*.h' 'llvm/include/llvm-c/**/*.h' 'llvm/include/llvm/Demangle/**/*.h' -Then run idt on the changed files with appropriate --export-macro and --include-header flags.""" - - def pr_comment_text_for_diff(self, diff: 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} -`````````` - -:warning: -The reproduction instructions above might return results for more than one PR -in a stack if you are using a stacked PR workflow. You can limit the results by -changing `origin/main` to the base branch/commit you want to compare against. -:warning: - -</details> - -<details> -<summary> -View the diff from {self.name} here. -</summary> - -``````````diff -{diff} -`````````` - -</details> -""" - - def update_pr( - self, comment_text: str, args: IdsCheckArgs, create_new: bool - ) -> None: - import github - - repo = github.Github(auth=github.Auth.Token(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 = None - for comment in pr.as_issue().get_comments(): - if self.comment_tag in comment.body: - existing_comment = comment - break - - if existing_comment: - self.comment = {"body": comment_text, "id": existing_comment.id} - elif create_new: - self.comment = {"body": comment_text} - - # Define the file categories and their corresponding configurations - FILE_CATEGORIES = [ - { - "name": "LLVM headers", - "patterns": ["llvm/include/llvm/**/*.h"], - "excludes": [ - "llvm/include/llvm/Debuginfod/", - "llvm/include/llvm/Demangle/", - ], - "export_macro": "LLVM_ABI", - "include_header": "llvm/include/llvm/Support/Compiler.h", - }, - { - "name": "LLVM-C headers", - "patterns": ["llvm/include/llvm-c/**/*.h"], - "excludes": [], - "export_macro": "LLVM_C_ABI", - "include_header": "llvm/include/llvm-c/Visibility.h", - }, - { - "name": "LLVM Demangle headers", - "patterns": ["llvm/include/llvm/Demangle/**/*.h"], - "excludes": [], - "export_macro": "DEMANGLE_ABI", - "include_header": "llvm/Demangle/Visibility.h", - }, - ] - - def filter_files_for_category( - self, changed_files: List[str], category: dict - ) -> List[str]: - """Filter changed files based on category patterns and excludes.""" - filtered = [] - for path in changed_files: - # Check if file matches any pattern - matches_pattern = False - for pattern in category["patterns"]: - # Simple pattern matching for /**/*.h style patterns - pattern_prefix = pattern.replace("/**/*.h", "") - if path.startswith(pattern_prefix) and path.endswith(".h"): - matches_pattern = True - break - - if not matches_pattern: - continue - - # Check if file should be excluded - excluded = False - for exclude in category["excludes"]: - if path.startswith(exclude): - excluded = True - break - - if not excluded: - filtered.append(path) - - return filtered - - def run_idt_on_files( - self, - files: List[str], - category: dict, - args: IdsCheckArgs, - idt_path: str, - compile_commands: str, - ) -> bool: - """Run idt tool on the given files with category-specific configuration.""" - if not files: - return True - - if args.verbose: - print( - f"Running idt on {len(files)} {category['name']} file(s)...", - file=sys.stderr, - ) - - for file in files: - cmd = [ - idt_path, - "-p", - compile_commands, - "--apply-fixits", - "--inplace", - f"--export-macro={category['export_macro']}", - f"--include-header={category['include_header']}", - f"--extra-arg=-D{category['export_macro']}={self.MACRO_DEFINITION}", - "--extra-arg=-Wno-macro-redefined", - file, - ] - - if args.verbose: - print(f"Running: {' '.join(cmd)}", file=sys.stderr) - - subprocess.run(cmd) - - return True - - def get_changed_files(self, args: IdsCheckArgs) -> List[str]: - """Get list of changed files between revisions.""" - if args.changed_files: - return args.changed_files - - cmd = ["git", "diff", "--name-only", args.start_rev, args.end_rev] - if args.verbose: - print(f"Running: {' '.join(cmd)}", file=sys.stderr) - - proc = subprocess.run(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE) - if proc.returncode != 0: - print("Error: Failed to get changed files", file=sys.stderr) - sys.stderr.write(proc.stderr.decode("utf-8")) - return [] - - files = proc.stdout.decode("utf-8").strip().split("\n") - return [f for f in files if f] - - def check_for_diff(self) -> Optional[str]: - """Check if there are any uncommitted changes after running idt.""" - cmd = ["git", "diff"] - proc = subprocess.run(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE) - - diff = proc.stdout.decode("utf-8") - if diff: - return diff - return None - - def run(self, args: IdsCheckArgs) -> int: - """Main entry point for running ids check.""" - # Resolve idt path: prefer command line arg, then env var - idt_path = args.idt_path or os.environ.get("IDT_PATH") - if not idt_path: - print( - "Error: idt path not specified. Use --idt-path argument or set IDT_PATH environment variable", - file=sys.stderr, - ) - return 1 - - if not os.path.exists(idt_path): - print(f"Error: idt tool not found at {idt_path}", file=sys.stderr) - return 1 - - # Resolve compile_commands path: prefer command line arg, then env var - compile_commands = args.compile_commands or os.environ.get( - "COMPILE_COMMANDS_PATH" - ) - if not compile_commands: - print( - "Error: compile_commands.json path not specified. Use --compile-commands argument or set COMPILE_COMMANDS_PATH environment variable", - file=sys.stderr, - ) - return 1 - - if not os.path.exists(compile_commands): - print( - f"Error: compile_commands.json not found at {compile_commands}", - file=sys.stderr, - ) - return 1 - - # Get changed files - changed_files = self.get_changed_files(args) - if not changed_files: - if args.verbose: - print("No files changed, skipping ids check", file=sys.stderr) - return 0 - - # Process each category - any_processed = False - for category in self.FILE_CATEGORIES: - filtered_files = self.filter_files_for_category(changed_files, category) - if filtered_files: - any_processed = True - if not self.run_idt_on_files( - filtered_files, category, args, idt_path, compile_commands - ): - return 1 - - if not any_processed: - if args.verbose: - print( - "No relevant header files changed, skipping ids check", - file=sys.stderr, - ) - return 0 - - # Check for differences - diff = self.check_for_diff() - should_update_gh = args.token is not None and args.repo is not None - - if diff: - if should_update_gh: - comment_text = self.pr_comment_text_for_diff(diff) - self.update_pr(comment_text, args, create_new=True) - else: - print( - "\nError: idt found missing LLVM_ABI annotations", file=sys.stderr - ) - print( - "Apply the following diff to fix the LLVM_ABI annotations:\n", - file=sys.stderr, - ) - print(diff) - return 1 - else: - 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) - if args.verbose: - print("All files pass ids check", file=sys.stderr) - return 0 - - -if __name__ == "__main__": - parser = argparse.ArgumentParser( - description="Check LLVM ABI annotations in header files" - ) - parser.add_argument("--token", type=str, help="GitHub authentication token") - 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("--issue-number", type=int, help="GitHub issue/PR number") - 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 have been changed", - ) - parser.add_argument( - "--idt-path", - type=str, - help="Path to the idt executable (can also be set via IDT_PATH environment variable)", - ) - parser.add_argument( - "--compile-commands", - type=str, - help="Path to compile_commands.json (can also be set via COMPILE_COMMANDS_PATH environment variable)", - ) - parser.add_argument( - "--verbose", action="store_true", default=True, help="Enable verbose output" - ) - - parsed_args = parser.parse_args() - - # Parse changed files if provided - if parsed_args.changed_files: - parsed_args.changed_files = [ - f.strip() for f in parsed_args.changed_files.split(",") if f.strip() - ] - else: - parsed_args.changed_files = [] - - args = IdsCheckArgs(parsed_args) - checker = IdsChecker() - exit_code = checker.run(args) - - if checker.comment: - with open("comments", "w") as f: - import json - - json.dump([checker.comment], f) - - sys.exit(exit_code) diff --git a/llvm/utils/git/requirements.txt b/llvm/utils/git/requirements.txt index 51c489ad7abfa..bbb9059b6b260 100644 --- a/llvm/utils/git/requirements.txt +++ b/llvm/utils/git/requirements.txt @@ -1,5 +1,5 @@ # -# This file is autogenerated by pip-compile with Python 3.14 +# This file is autogenerated by pip-compile with Python 3.11 # by the following command: # # pip-compile --generate-hashes --output-file=requirements.txt requirements.txt.in @@ -218,10 +218,6 @@ idna==3.8 \ --hash=sha256:050b4e5baadcd44d760cedbd2b8e639f2ff89bbc7a5730fcc662954303377aac \ --hash=sha256:d838c2c0ed6fced7693d5e8ab8e734d5f8fda53a039c0164afb0b82e771e3603 # via requests -lit==18.1.8 \ - --hash=sha256:47c174a186941ae830f04ded76a3444600be67d5e5fb8282c3783fba671c4edb \ - --hash=sha256:a873ff7acd76e746368da32eb7355625e2e55a2baaab884c9cc130f2ee0300f7 - # via -r requirements.txt.in pycparser==2.22 \ --hash=sha256:491c8be9c040f5390f5bf44a5b07752bd07f56edf992381b05c701439eec10f6 \ --hash=sha256:c3702b6d3dd8c7abc1afa565d7e63d53a1d0bd86cdc24edd75470f4de499cfcc diff --git a/llvm/utils/git/requirements.txt.in b/llvm/utils/git/requirements.txt.in index dfd6d0637a545..e880e94e1de80 100644 --- a/llvm/utils/git/requirements.txt.in +++ b/llvm/utils/git/requirements.txt.in @@ -9,4 +9,3 @@ PyGithub==2.4.0 # >=1.59.1 For WorkflowRun.name # >= Fix for https://github.com/PyGithub/PyGithub/issues/3001 # (variables in graphql query). GitPython>=3.1.32 # https://security.snyk.io/vuln/SNYK-PYTHON-GITPYTHON-5840584 -lit>=18.1.8 # No entry on snyk as of 2026-12-01 >From cb8491db20276f67e737d6332e86b6e95dfe869f Mon Sep 17 00:00:00 2001 From: Cullen Rhodes <[email protected]> Date: Wed, 14 Jan 2026 09:37:40 +0000 Subject: [PATCH 3/3] Revert "GHA: Add the "Check LLVM ABI" flow to issue-write (#175549)" This reverts commit 670ecd7c358e3f29f852b564a0edfbe8a4e1734a. --- .github/workflows/issue-write.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/issue-write.yml b/.github/workflows/issue-write.yml index f6e412523322f..5e296e0deec82 100644 --- a/.github/workflows/issue-write.yml +++ b/.github/workflows/issue-write.yml @@ -9,7 +9,6 @@ on: - "Code lint" - "CI Checks" - "Test Issue Write" - - "Check LLVM ABI annotations" types: - completed _______________________________________________ llvm-branch-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
