[llvm] [llvm][utils] Make git-llvm-push set the skip-precommit-approval label (PR #174833)
Petr Hosek via llvm-commits
llvm-commits at lists.llvm.org
Wed Jan 7 11:02:45 PST 2026
https://github.com/petrhosek created https://github.com/llvm/llvm-project/pull/174833
skip-precommit-approval label is intended for simple PR that don't require approval. To reduce the volume of notifications, label all PRs created using the git-llvm-push script with the skip-precommit-approval label.
Fixes 174825
>From de163999154f300e7e30569b11aea773657fac3b Mon Sep 17 00:00:00 2001
From: Petr Hosek <phosek at google.com>
Date: Wed, 7 Jan 2026 08:54:03 +0000
Subject: [PATCH] [llvm][utils] Make git-llvm-push set the
skip-precommit-approval label
skip-precommit-approval label is intended for simple PR that don't
require approval. To reduce the volume of notifications, label all PRs
created using the git-llvm-push script with the skip-precommit-approval
label.
Fixes 174825
---
llvm/utils/git-llvm-push | 79 +++++++++++++++++++++++++---------------
1 file changed, 49 insertions(+), 30 deletions(-)
diff --git a/llvm/utils/git-llvm-push b/llvm/utils/git-llvm-push
index c18783d81daa8..a1599d7650cca 100644
--- a/llvm/utils/git-llvm-push
+++ b/llvm/utils/git-llvm-push
@@ -21,6 +21,8 @@ BASE_BRANCH = "main"
GITHUB_REMOTE_NAME = "origin"
UPSTREAM_REMOTE_NAME = "upstream"
+DEFAULT_LABEL = "skip-precommit-approval"
+
LLVM_GITHUB_TOKEN_VAR = "LLVM_GITHUB_TOKEN"
LLVM_REPO = "llvm/llvm-project"
GITHUB_API = "https://api.github.com"
@@ -44,6 +46,7 @@ class PRAutomatorConfig:
upstream_remote: str
prefix: str
draft: bool
+ labels: List[str]
no_merge: bool
auto_merge: bool
@@ -188,7 +191,11 @@ class GitHubAPI:
title: str,
body: str,
draft: bool,
- ) -> Optional[str]:
+ ) -> int:
+ if self.runner.dry_run:
+ self.runner.print(f"[Dry Run] Would create pull request for '{head_branch}'...")
+ return 0
+
self.runner.print(f"Creating pull request for '{head_branch}'...")
data = {
"title": title,
@@ -200,10 +207,8 @@ class GitHubAPI:
response_data = self._request_and_parse_json(
"POST", f"/repos/{LLVM_REPO}/pulls", json_payload=data
)
- pr_url = response_data.get("html_url")
- if not self.runner.dry_run:
- self.runner.print(f"Pull request created: {pr_url}")
- return pr_url
+ self.runner.print(f"Pull request created: {response_data.get("html_url")}")
+ return response_data.get("number")
def get_repo_settings(self) -> dict:
return self._request_and_parse_json("GET", f"/repos/{LLVM_REPO}")
@@ -214,6 +219,22 @@ class GitHubAPI:
"GET", f"/repos/{LLVM_REPO}/pulls/{pr_number}"
)
+ def add_labels(
+ self,
+ pr_number: int,
+ labels: List[str],
+ ) -> bool:
+ if self.runner.dry_run:
+ self.runner.print(f"[Dry Run] Would set labels for #{pr_number}: {' '.join(labels)}")
+ return None
+
+ self.runner.print(f"Setting labels for #{pr_number}: {' '.join(labels)}")
+
+ self._request_and_parse_json(
+ "POST", f"/repos/{LLVM_REPO}/issues/{pr_number}/labels",
+ json_payload={"labels": labels},
+ )
+
def _attempt_squash_merge(self, pr_number: str) -> bool:
"""Attempts to squash merge a PR, returning True on success."""
try:
@@ -230,22 +251,14 @@ class GitHubAPI:
# Re-raise other HTTP errors.
raise e
- def merge_pr(self, pr_url: str) -> Optional[str]:
- if not pr_url:
- return None
-
+ def merge_pr(self, pr_number: int) -> Optional[str]:
if self.runner.dry_run:
- self.runner.print(f"[Dry Run] Would merge {pr_url}")
+ self.runner.print(f"[Dry Run] Would merge #{pr_number}")
return None
- pr_number_match = re.search(r"/pull/(\d+)", pr_url)
- if not pr_number_match:
- raise LlvmPrError(f"Could not extract PR number from URL: {pr_url}")
- pr_number = pr_number_match.group(1)
-
for i in range(MERGE_MAX_RETRIES):
self.runner.print(
- f"Attempting to merge {pr_url} (attempt {i + 1}/{MERGE_MAX_RETRIES})..."
+ f"Attempting to merge #{pr_number} (attempt {i + 1}/{MERGE_MAX_RETRIES})..."
)
pr_data = self._get_pr_details(pr_number)
@@ -267,20 +280,12 @@ class GitHubAPI:
raise LlvmPrError(f"PR was not mergeable after {MERGE_MAX_RETRIES} attempts.")
- def enable_auto_merge(self, pr_url: str) -> None:
- if not pr_url:
- return
-
+ def enable_auto_merge(self, pr_number: int) -> None:
if self.runner.dry_run:
- self.runner.print(f"[Dry Run] Would enable auto-merge for {pr_url}")
+ self.runner.print(f"[Dry Run] Would enable auto-merge for #{pr_number}")
return
- pr_number_match = re.search(r"/pull/(\d+)", pr_url)
- if not pr_number_match:
- raise LlvmPrError(f"Could not extract PR number from URL: {pr_url}")
- pr_number = pr_number_match.group(1)
-
- self.runner.print(f"Enabling auto-merge for {pr_url}...")
+ self.runner.print(f"Enabling auto-merge for #{pr_number}...")
data = {
"enabled": True,
"merge_method": "squash",
@@ -481,7 +486,7 @@ class LLVMPRAutomator:
temp_branch = self._create_and_push_branch_for_commit(
commit_hash, base_branch_name, index
)
- pr_url = self.github_api.create_pr(
+ pr_number = self.github_api.create_pr(
head_branch=f"{self.config.user_login}:{temp_branch}",
base_branch=self.config.base_branch,
title=commit_title,
@@ -489,13 +494,20 @@ class LLVMPRAutomator:
draft=self.config.draft,
)
+ # TODO: There's a possibility of a race with PR labelers workflow.
+ # To avoid it, we could create the PR as a draft, set the labels
+ # and change the status, but that requires the use of GraphQL API.
+
+ if self.config.labels:
+ self.github_api.add_labels(pr_number, self.config.labels)
+
if self.config.no_merge:
return
if self.config.auto_merge:
- self.github_api.enable_auto_merge(pr_url)
+ self.github_api.enable_auto_merge(pr_number)
else:
- merged_branch = self.github_api.merge_pr(pr_url)
+ merged_branch = self.github_api.merge_pr(pr_number)
if merged_branch and not self.repo_settings.get("delete_branch_on_merge"):
# After a merge, the branch should be deleted.
self.github_api.delete_branch(merged_branch)
@@ -600,6 +612,12 @@ def main() -> None:
parser.add_argument(
"--draft", action="store_true", help="Create pull requests as drafts."
)
+ parser.add_argument(
+ "--labels",
+ nargs='*',
+ default=[DEFAULT_LABEL],
+ help=f"Set the PR labels (default: {DEFAULT_LABEL})."
+ )
merging = parser.add_mutually_exclusive_group()
merging.add_argument(
"--no-merge", action="store_true", help="Create PRs but do not merge them."
@@ -651,6 +669,7 @@ def main() -> None:
upstream_remote=args.upstream_remote,
prefix=args.prefix,
draft=args.draft,
+ labels=args.labels,
no_merge=args.no_merge,
auto_merge=args.auto_merge,
)
More information about the llvm-commits
mailing list