[llvm] [Github] Only delete branches seen previously in pruning workflow (PR #181430)

Aiden Grossman via llvm-commits llvm-commits at lists.llvm.org
Fri Feb 13 14:30:03 PST 2026


https://github.com/boomanaiden154 updated https://github.com/llvm/llvm-project/pull/181430

>From e56aee7fb2fd6e682956809229fcf29dae43173d Mon Sep 17 00:00:00 2001
From: Aiden Grossman <aidengrossman at google.com>
Date: Fri, 13 Feb 2026 22:16:57 +0000
Subject: [PATCH 1/3] [Github] Only delete branches seen previously in pruning
 workflow

This eliminates any possibility of race conditions around the workflow
deleting branches that were created around when it starts.
---
 .github/workflows/prune-unused-branches.py | 41 ++++++++++++++++++++--
 1 file changed, 39 insertions(+), 2 deletions(-)

diff --git a/.github/workflows/prune-unused-branches.py b/.github/workflows/prune-unused-branches.py
index a7bd74f1ad566..a5a2474027a96 100644
--- a/.github/workflows/prune-unused-branches.py
+++ b/.github/workflows/prune-unused-branches.py
@@ -2,9 +2,14 @@
 import sys
 import os
 import logging
+import zipfile
+import io
+import urllib.request
 
 import github
 
+GITHUB_WORKFLOW_ID = 57373867111
+
 
 def get_branches() -> list[str]:
     git_process = subprocess.run(
@@ -65,7 +70,7 @@ def get_branches_from_open_prs(github_token) -> list[str]:
 
 
 def get_user_branches_to_remove(
-    user_branches: list[str], user_branches_from_prs: list[str]
+    user_branches: list[str], user_branches_from_prs: list[str], previous_run_branches: list[str]
 ) -> list[str]:
     user_branches_to_remove = set(user_branches)
     for pr_user_branch in set(user_branches_from_prs):
@@ -77,6 +82,9 @@ def get_user_branches_to_remove(
             )
             continue
         user_branches_to_remove.remove(pr_user_branch)
+    for branch in list(user_branches_to_remove):
+        if branch not in previous_run_branches:
+            user_branches_to_remove.remove(branch)
     return list(user_branches_to_remove)
 
 
@@ -132,6 +140,33 @@ def delete_branches(branches_to_remove: list[str]):
         print(f"Deleted branch {branch}")
 
 
+def get_branches_found_in_previous_run(github_token: str) -> list[str]:
+    gh = github.Github(auth=github.Auth.Token(github_token))
+    repo = gh.get_repo("llvm/llvm-project")
+    workflow_run = None
+    for workflow_run in iter(
+        repo.get_workflow("prune-branches.yml").get_runs(branch="main")
+    ):
+        if workflow_run.status == "completed":
+            break
+    assert workflow_run
+    workflow_artifact = None
+    for workflow_artifact in iter(workflow_run.get_artifacts()):
+        if workflow_artifact.name == "BranchList":
+            break
+    assert workflow_artifact
+    status, headers, response = workflow_artifact._requester.requestJson(
+        "GET", workflow_artifact.archive_download_url
+    )
+    # Github will always send a redirect to where the file actuall lives.
+    assert status == 302
+    with urllib.request.urlopen(headers["location"]) as response:
+        raw_bytes = response.read()
+    with zipfile.ZipFile(io.BytesIO(raw_bytes)) as zip_file:
+        branch_names = zip_file.read("branches.txt").decode("utf-8").split("\n")[:-1]
+        return branch_names
+
+
 def main(github_token):
     if len(sys.argv) != 2:
         print(
@@ -139,6 +174,8 @@ def main(github_token):
         )
         sys.exit(1)
 
+    previous_run_branches = get_branches_found_in_previous_run(github_token)
+    print(f"{len(previous_run_branches)} branches existed the last time the workflow ran.")
     user_branches = get_branches()
     output_dir = sys.argv[1]
     with open(os.path.join(output_dir, "branches.txt"), "w") as branches_file:
@@ -147,7 +184,7 @@ def main(github_token):
     print(f"Found {len(user_branches)} user branches in the repository")
     print(f"Found {len(user_branches_from_prs)} user branches associated with PRs")
     user_branches_to_remove = get_user_branches_to_remove(
-        user_branches, user_branches_from_prs
+        user_branches, user_branches_from_prs, previous_run_branches
     )
     print(f"Deleting {len(user_branches_to_remove)} user branches.")
     generate_patches_for_all_branches(

>From 9a323a4e9744753d33e10dedfc985cc50aae7f6d Mon Sep 17 00:00:00 2001
From: Aiden Grossman <aidengrossman at google.com>
Date: Fri, 13 Feb 2026 22:18:21 +0000
Subject: [PATCH 2/3] formatting

---
 .github/workflows/prune-unused-branches.py | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/.github/workflows/prune-unused-branches.py b/.github/workflows/prune-unused-branches.py
index a5a2474027a96..791ee4a2cf2e1 100644
--- a/.github/workflows/prune-unused-branches.py
+++ b/.github/workflows/prune-unused-branches.py
@@ -70,7 +70,9 @@ def get_branches_from_open_prs(github_token) -> list[str]:
 
 
 def get_user_branches_to_remove(
-    user_branches: list[str], user_branches_from_prs: list[str], previous_run_branches: list[str]
+    user_branches: list[str],
+    user_branches_from_prs: list[str],
+    previous_run_branches: list[str],
 ) -> list[str]:
     user_branches_to_remove = set(user_branches)
     for pr_user_branch in set(user_branches_from_prs):
@@ -175,7 +177,9 @@ def main(github_token):
         sys.exit(1)
 
     previous_run_branches = get_branches_found_in_previous_run(github_token)
-    print(f"{len(previous_run_branches)} branches existed the last time the workflow ran.")
+    print(
+        f"{len(previous_run_branches)} branches existed the last time the workflow ran."
+    )
     user_branches = get_branches()
     output_dir = sys.argv[1]
     with open(os.path.join(output_dir, "branches.txt"), "w") as branches_file:

>From 752bf058d75a798619a08ed27ba0dfded0a39eaa Mon Sep 17 00:00:00 2001
From: Aiden Grossman <aidengrossman at google.com>
Date: Fri, 13 Feb 2026 22:29:52 +0000
Subject: [PATCH 3/3] remove unused

---
 .github/workflows/prune-unused-branches.py | 2 --
 1 file changed, 2 deletions(-)

diff --git a/.github/workflows/prune-unused-branches.py b/.github/workflows/prune-unused-branches.py
index 791ee4a2cf2e1..21b7540989738 100644
--- a/.github/workflows/prune-unused-branches.py
+++ b/.github/workflows/prune-unused-branches.py
@@ -8,8 +8,6 @@
 
 import github
 
-GITHUB_WORKFLOW_ID = 57373867111
-
 
 def get_branches() -> list[str]:
     git_process = subprocess.run(



More information about the llvm-commits mailing list