We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
[ci] `last-successful` job is disabled
The job from #10056: https://github.com/apache/tvm/actions/workflows/update_last_successful_branch.yml was disabled a few months ago in concert with the change to split up the Jenkins CI job from one job into many jobs (see #13337). To fix this we'd need to update the CI checking script to know about the new job names and find the last commit in which they all passed.

cc @Mousius @areusch @gigiblender @leandron

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `ci/scripts/github/update_branch.py`
Content:
```
1 #!/usr/bin/env python3
2 # Licensed to the Apache Software Foundation (ASF) under one
3 # or more contributor license agreements.  See the NOTICE file
4 # distributed with this work for additional information
5 # regarding copyright ownership.  The ASF licenses this file
6 # to you under the Apache License, Version 2.0 (the
7 # "License"); you may not use this file except in compliance
8 # with the License.  You may obtain a copy of the License at
9 #
10 #   http://www.apache.org/licenses/LICENSE-2.0
11 #
12 # Unless required by applicable law or agreed to in writing,
13 # software distributed under the License is distributed on an
14 # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 # KIND, either express or implied.  See the License for the
16 # specific language governing permissions and limitations
17 # under the License.
18 
19 import os
20 import json
21 import argparse
22 import sys
23 from pathlib import Path
24 from typing import Any, Dict
25 
26 # Hackery to enable importing of utils from ci/scripts/jenkins
27 REPO_ROOT = Path(__file__).resolve().parent.parent.parent.parent
28 sys.path.append(str(REPO_ROOT / "ci" / "scripts" / "jenkins"))
29 
30 from git_utils import git, GitHubRepo, parse_remote
31 
32 
33 _commit_query_fields = """
34     messageHeadline
35     oid
36     statusCheckRollup {
37         contexts(last:100) {
38             nodes {
39                 ... on CheckRun {
40                     conclusion
41                     status
42                     name
43                     checkSuite {
44                         workflowRun {
45                             workflow {
46                                 name
47                             }
48                         }
49                     }
50                 }
51                 ... on StatusContext {
52                     context
53                     state
54                 }
55             }
56         }
57     }
58 """
59 
60 
61 def commits_query(user: str, repo: str, cursor: str = None):
62     """
63     Create a GraphQL query to find the last N commits along with their statuses
64     and some metadata (paginated after 'cursor')
65     """
66     after = ""
67     if cursor is not None:
68         after = f', after:"{cursor}"'
69 
70     return f"""
71     {{
72     repository(name: "{repo}", owner: "{user}") {{
73         defaultBranchRef {{
74         target {{
75             ... on Commit {{
76             history(first: 15{after}) {{
77                 edges {{ cursor }}
78                 nodes {{
79                     {_commit_query_fields}
80                 }}
81             }}
82             }}
83         }}
84         }}
85     }}
86     }}
87     """
88 
89 
90 def commit_passed_ci(commit: Dict[str, Any]) -> bool:
91     """
92     Returns true if all of a commit's statuses are SUCCESS
93     """
94     statuses = commit["statusCheckRollup"]["contexts"]["nodes"]
95 
96     # GitHub Actions statuses are different from external GitHub statuses, so
97     # unify them into 1 representation
98     # https://docs.github.com/en/developers/webhooks-and-events/webhooks/webhook-events-and-payloads
99     unified_statuses = []
100     for status in statuses:
101         if "context" in status:
102             # Parse non-GHA status
103             unified_statuses.append((status["context"], status["state"] == "SUCCESS"))
104         else:
105             # Parse GitHub Actions item
106             workflow = status["checkSuite"]["workflowRun"]["workflow"]["name"]
107             name = f"{workflow} / {status['name']}"
108             unified_statuses.append((name, status["conclusion"] == "SUCCESS"))
109 
110     print(f"Statuses on {commit['oid']}:", json.dumps(unified_statuses, indent=2))
111 
112     # Assert that specific jobs are present in the commit statuses (i.e. don't
113     # approve if CI was broken and didn't schedule a job)
114     expected_jobs = {"tvm-ci/branch"}
115     job_names = {name for name, status in unified_statuses}
116     for job in expected_jobs:
117         if job not in job_names:
118             # Did not find expected job name
119             return False
120 
121     passed_ci = all(status for name, status in unified_statuses)
122     return passed_ci
123 
124 
125 def update_branch(user: str, repo: str, sha: str, branch_name: str) -> None:
126     git(["fetch", "origin", sha])
127     git(["reset", "--hard", "FETCH_HEAD"])
128     try:
129         git(["branch", "-D", branch_name])
130     except RuntimeError:
131         # Ignore failures (i.e. the branch did not exist in the first place)
132         pass
133     git(["checkout", "-b", branch_name])
134 
135     # Create and push the branch
136     git(["push", "origin", "--force", branch_name])
137     print(f"Pushed branch {branch_name} with commit {sha}")
138 
139 
140 if __name__ == "__main__":
141     help = "Push the a branch to the last commit that passed all CI runs"
142     parser = argparse.ArgumentParser(description=help)
143     parser.add_argument("--remote", default="origin", help="ssh remote to parse")
144     parser.add_argument("--dry-run", action="store_true", help="don't submit to GitHub")
145     parser.add_argument("--branch", default="last-successful", help="branch name")
146     parser.add_argument(
147         "--testonly-json", help="(testing) data to use instead of fetching from GitHub"
148     )
149     args = parser.parse_args()
150 
151     remote = git(["config", "--get", f"remote.{args.remote}.url"])
152     user, repo = parse_remote(remote)
153     # TODO: Remove this before landing
154     user, repo = ("apache", "tvm")
155 
156     if args.testonly_json:
157         r = json.loads(args.testonly_json)
158     else:
159         github = GitHubRepo(token=os.environ["GITHUB_TOKEN"], user=user, repo=repo)
160         q = commits_query(user, repo)
161         r = github.graphql(q)
162 
163     commits = r["data"]["repository"]["defaultBranchRef"]["target"]["history"]["nodes"]
164 
165     # Limit GraphQL pagination
166     MAX_COMMITS_TO_CHECK = 50
167     i = 0
168 
169     while i < MAX_COMMITS_TO_CHECK:
170         # Check each commit
171         for commit in commits:
172             if commit_passed_ci(commit):
173                 print(f"Found last good commit: {commit['oid']}: {commit['messageHeadline']}")
174                 if not args.dry_run:
175                     update_branch(
176                         user=user,
177                         repo=repo,
178                         sha=commit["oid"],
179                         branch_name=args.branch,
180                     )
181                 # Nothing to do after updating the branch, exit early
182                 exit(0)
183 
184         # No good commit found, proceed to next page of results
185         edges = r["data"]["repository"]["defaultBranchRef"]["target"]["history"]["edges"]
186         if len(edges) == 0:
187             break
188         else:
189             q = commits_query(user, repo, cursor=edges[-1]["cursor"])
190             r = github.graphql(q)
191             commits = r["data"]["repository"]["defaultBranchRef"]["target"]["history"]["nodes"]
192 
193         # Backstop to prevent looking through all the past commits
194         i += len(commits)
195 
196     print(f"No good commits found in the last {len(commits)} commits")
197     exit(1)
198
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/ci/scripts/github/update_branch.py b/ci/scripts/github/update_branch.py
--- a/ci/scripts/github/update_branch.py
+++ b/ci/scripts/github/update_branch.py
@@ -87,6 +87,22 @@
     """
 
 
+EXPECTED_CI_JOBS = [
+    "cross-isa-minimal/branch",
+    "gpu/branch",
+    "hexagon/branch",
+    "arm/branch",
+    "cortexm/branch",
+    "cpu/branch",
+    "docker/branch",
+    "i386/branch",
+    "lint/branch",
+    "minimal/branch",
+    "riscv/branch",
+    "wasm/branch",
+]
+
+
 def commit_passed_ci(commit: Dict[str, Any]) -> bool:
     """
     Returns true if all of a commit's statuses are SUCCESS
@@ -111,9 +127,8 @@
 
     # Assert that specific jobs are present in the commit statuses (i.e. don't
     # approve if CI was broken and didn't schedule a job)
-    expected_jobs = {"tvm-ci/branch"}
     job_names = {name for name, status in unified_statuses}
-    for job in expected_jobs:
+    for job in EXPECTED_CI_JOBS:
         if job not in job_names:
             # Did not find expected job name
             return False

{"golden_diff": "diff --git a/ci/scripts/github/update_branch.py b/ci/scripts/github/update_branch.py\n--- a/ci/scripts/github/update_branch.py\n+++ b/ci/scripts/github/update_branch.py\n@@ -87,6 +87,22 @@\n     \"\"\"\n \n \n+EXPECTED_CI_JOBS = [\n+    \"cross-isa-minimal/branch\",\n+    \"gpu/branch\",\n+    \"hexagon/branch\",\n+    \"arm/branch\",\n+    \"cortexm/branch\",\n+    \"cpu/branch\",\n+    \"docker/branch\",\n+    \"i386/branch\",\n+    \"lint/branch\",\n+    \"minimal/branch\",\n+    \"riscv/branch\",\n+    \"wasm/branch\",\n+]\n+\n+\n def commit_passed_ci(commit: Dict[str, Any]) -> bool:\n     \"\"\"\n     Returns true if all of a commit's statuses are SUCCESS\n@@ -111,9 +127,8 @@\n \n     # Assert that specific jobs are present in the commit statuses (i.e. don't\n     # approve if CI was broken and didn't schedule a job)\n-    expected_jobs = {\"tvm-ci/branch\"}\n     job_names = {name for name, status in unified_statuses}\n-    for job in expected_jobs:\n+    for job in EXPECTED_CI_JOBS:\n         if job not in job_names:\n             # Did not find expected job name\n             return False\n", "issue": "[ci] `last-successful` job is disabled\nThe job from #10056: https://github.com/apache/tvm/actions/workflows/update_last_successful_branch.yml was disabled a few months ago in concert with the change to split up the Jenkins CI job from one job into many jobs (see #13337). To fix this we'd need to update the CI checking script to know about the new job names and find the last commit in which they all passed.\n\ncc @Mousius @areusch @gigiblender @leandron\n", "before_files": [{"content": "#!/usr/bin/env python3\n# Licensed to the Apache Software Foundation (ASF) under one\n# or more contributor license agreements.  See the NOTICE file\n# distributed with this work for additional information\n# regarding copyright ownership.  The ASF licenses this file\n# to you under the Apache License, Version 2.0 (the\n# \"License\"); you may not use this file except in compliance\n# with the License.  You may obtain a copy of the License at\n#\n#   http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing,\n# software distributed under the License is distributed on an\n# \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n# KIND, either express or implied.  See the License for the\n# specific language governing permissions and limitations\n# under the License.\n\nimport os\nimport json\nimport argparse\nimport sys\nfrom pathlib import Path\nfrom typing import Any, Dict\n\n# Hackery to enable importing of utils from ci/scripts/jenkins\nREPO_ROOT = Path(__file__).resolve().parent.parent.parent.parent\nsys.path.append(str(REPO_ROOT / \"ci\" / \"scripts\" / \"jenkins\"))\n\nfrom git_utils import git, GitHubRepo, parse_remote\n\n\n_commit_query_fields = \"\"\"\n    messageHeadline\n    oid\n    statusCheckRollup {\n        contexts(last:100) {\n            nodes {\n                ... on CheckRun {\n                    conclusion\n                    status\n                    name\n                    checkSuite {\n                        workflowRun {\n                            workflow {\n                                name\n                            }\n                        }\n                    }\n                }\n                ... on StatusContext {\n                    context\n                    state\n                }\n            }\n        }\n    }\n\"\"\"\n\n\ndef commits_query(user: str, repo: str, cursor: str = None):\n    \"\"\"\n    Create a GraphQL query to find the last N commits along with their statuses\n    and some metadata (paginated after 'cursor')\n    \"\"\"\n    after = \"\"\n    if cursor is not None:\n        after = f', after:\"{cursor}\"'\n\n    return f\"\"\"\n    {{\n    repository(name: \"{repo}\", owner: \"{user}\") {{\n        defaultBranchRef {{\n        target {{\n            ... on Commit {{\n            history(first: 15{after}) {{\n                edges {{ cursor }}\n                nodes {{\n                    {_commit_query_fields}\n                }}\n            }}\n            }}\n        }}\n        }}\n    }}\n    }}\n    \"\"\"\n\n\ndef commit_passed_ci(commit: Dict[str, Any]) -> bool:\n    \"\"\"\n    Returns true if all of a commit's statuses are SUCCESS\n    \"\"\"\n    statuses = commit[\"statusCheckRollup\"][\"contexts\"][\"nodes\"]\n\n    # GitHub Actions statuses are different from external GitHub statuses, so\n    # unify them into 1 representation\n    # https://docs.github.com/en/developers/webhooks-and-events/webhooks/webhook-events-and-payloads\n    unified_statuses = []\n    for status in statuses:\n        if \"context\" in status:\n            # Parse non-GHA status\n            unified_statuses.append((status[\"context\"], status[\"state\"] == \"SUCCESS\"))\n        else:\n            # Parse GitHub Actions item\n            workflow = status[\"checkSuite\"][\"workflowRun\"][\"workflow\"][\"name\"]\n            name = f\"{workflow} / {status['name']}\"\n            unified_statuses.append((name, status[\"conclusion\"] == \"SUCCESS\"))\n\n    print(f\"Statuses on {commit['oid']}:\", json.dumps(unified_statuses, indent=2))\n\n    # Assert that specific jobs are present in the commit statuses (i.e. don't\n    # approve if CI was broken and didn't schedule a job)\n    expected_jobs = {\"tvm-ci/branch\"}\n    job_names = {name for name, status in unified_statuses}\n    for job in expected_jobs:\n        if job not in job_names:\n            # Did not find expected job name\n            return False\n\n    passed_ci = all(status for name, status in unified_statuses)\n    return passed_ci\n\n\ndef update_branch(user: str, repo: str, sha: str, branch_name: str) -> None:\n    git([\"fetch\", \"origin\", sha])\n    git([\"reset\", \"--hard\", \"FETCH_HEAD\"])\n    try:\n        git([\"branch\", \"-D\", branch_name])\n    except RuntimeError:\n        # Ignore failures (i.e. the branch did not exist in the first place)\n        pass\n    git([\"checkout\", \"-b\", branch_name])\n\n    # Create and push the branch\n    git([\"push\", \"origin\", \"--force\", branch_name])\n    print(f\"Pushed branch {branch_name} with commit {sha}\")\n\n\nif __name__ == \"__main__\":\n    help = \"Push the a branch to the last commit that passed all CI runs\"\n    parser = argparse.ArgumentParser(description=help)\n    parser.add_argument(\"--remote\", default=\"origin\", help=\"ssh remote to parse\")\n    parser.add_argument(\"--dry-run\", action=\"store_true\", help=\"don't submit to GitHub\")\n    parser.add_argument(\"--branch\", default=\"last-successful\", help=\"branch name\")\n    parser.add_argument(\n        \"--testonly-json\", help=\"(testing) data to use instead of fetching from GitHub\"\n    )\n    args = parser.parse_args()\n\n    remote = git([\"config\", \"--get\", f\"remote.{args.remote}.url\"])\n    user, repo = parse_remote(remote)\n    # TODO: Remove this before landing\n    user, repo = (\"apache\", \"tvm\")\n\n    if args.testonly_json:\n        r = json.loads(args.testonly_json)\n    else:\n        github = GitHubRepo(token=os.environ[\"GITHUB_TOKEN\"], user=user, repo=repo)\n        q = commits_query(user, repo)\n        r = github.graphql(q)\n\n    commits = r[\"data\"][\"repository\"][\"defaultBranchRef\"][\"target\"][\"history\"][\"nodes\"]\n\n    # Limit GraphQL pagination\n    MAX_COMMITS_TO_CHECK = 50\n    i = 0\n\n    while i < MAX_COMMITS_TO_CHECK:\n        # Check each commit\n        for commit in commits:\n            if commit_passed_ci(commit):\n                print(f\"Found last good commit: {commit['oid']}: {commit['messageHeadline']}\")\n                if not args.dry_run:\n                    update_branch(\n                        user=user,\n                        repo=repo,\n                        sha=commit[\"oid\"],\n                        branch_name=args.branch,\n                    )\n                # Nothing to do after updating the branch, exit early\n                exit(0)\n\n        # No good commit found, proceed to next page of results\n        edges = r[\"data\"][\"repository\"][\"defaultBranchRef\"][\"target\"][\"history\"][\"edges\"]\n        if len(edges) == 0:\n            break\n        else:\n            q = commits_query(user, repo, cursor=edges[-1][\"cursor\"])\n            r = github.graphql(q)\n            commits = r[\"data\"][\"repository\"][\"defaultBranchRef\"][\"target\"][\"history\"][\"nodes\"]\n\n        # Backstop to prevent looking through all the past commits\n        i += len(commits)\n\n    print(f\"No good commits found in the last {len(commits)} commits\")\n    exit(1)\n", "path": "ci/scripts/github/update_branch.py"}], "after_files": [{"content": "#!/usr/bin/env python3\n# Licensed to the Apache Software Foundation (ASF) under one\n# or more contributor license agreements.  See the NOTICE file\n# distributed with this work for additional information\n# regarding copyright ownership.  The ASF licenses this file\n# to you under the Apache License, Version 2.0 (the\n# \"License\"); you may not use this file except in compliance\n# with the License.  You may obtain a copy of the License at\n#\n#   http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing,\n# software distributed under the License is distributed on an\n# \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n# KIND, either express or implied.  See the License for the\n# specific language governing permissions and limitations\n# under the License.\n\nimport os\nimport json\nimport argparse\nimport sys\nfrom pathlib import Path\nfrom typing import Any, Dict\n\n# Hackery to enable importing of utils from ci/scripts/jenkins\nREPO_ROOT = Path(__file__).resolve().parent.parent.parent.parent\nsys.path.append(str(REPO_ROOT / \"ci\" / \"scripts\" / \"jenkins\"))\n\nfrom git_utils import git, GitHubRepo, parse_remote\n\n\n_commit_query_fields = \"\"\"\n    messageHeadline\n    oid\n    statusCheckRollup {\n        contexts(last:100) {\n            nodes {\n                ... on CheckRun {\n                    conclusion\n                    status\n                    name\n                    checkSuite {\n                        workflowRun {\n                            workflow {\n                                name\n                            }\n                        }\n                    }\n                }\n                ... on StatusContext {\n                    context\n                    state\n                }\n            }\n        }\n    }\n\"\"\"\n\n\ndef commits_query(user: str, repo: str, cursor: str = None):\n    \"\"\"\n    Create a GraphQL query to find the last N commits along with their statuses\n    and some metadata (paginated after 'cursor')\n    \"\"\"\n    after = \"\"\n    if cursor is not None:\n        after = f', after:\"{cursor}\"'\n\n    return f\"\"\"\n    {{\n    repository(name: \"{repo}\", owner: \"{user}\") {{\n        defaultBranchRef {{\n        target {{\n            ... on Commit {{\n            history(first: 15{after}) {{\n                edges {{ cursor }}\n                nodes {{\n                    {_commit_query_fields}\n                }}\n            }}\n            }}\n        }}\n        }}\n    }}\n    }}\n    \"\"\"\n\n\nEXPECTED_CI_JOBS = [\n    \"cross-isa-minimal/branch\",\n    \"gpu/branch\",\n    \"hexagon/branch\",\n    \"arm/branch\",\n    \"cortexm/branch\",\n    \"cpu/branch\",\n    \"docker/branch\",\n    \"i386/branch\",\n    \"lint/branch\",\n    \"minimal/branch\",\n    \"riscv/branch\",\n    \"wasm/branch\",\n]\n\n\ndef commit_passed_ci(commit: Dict[str, Any]) -> bool:\n    \"\"\"\n    Returns true if all of a commit's statuses are SUCCESS\n    \"\"\"\n    statuses = commit[\"statusCheckRollup\"][\"contexts\"][\"nodes\"]\n\n    # GitHub Actions statuses are different from external GitHub statuses, so\n    # unify them into 1 representation\n    # https://docs.github.com/en/developers/webhooks-and-events/webhooks/webhook-events-and-payloads\n    unified_statuses = []\n    for status in statuses:\n        if \"context\" in status:\n            # Parse non-GHA status\n            unified_statuses.append((status[\"context\"], status[\"state\"] == \"SUCCESS\"))\n        else:\n            # Parse GitHub Actions item\n            workflow = status[\"checkSuite\"][\"workflowRun\"][\"workflow\"][\"name\"]\n            name = f\"{workflow} / {status['name']}\"\n            unified_statuses.append((name, status[\"conclusion\"] == \"SUCCESS\"))\n\n    print(f\"Statuses on {commit['oid']}:\", json.dumps(unified_statuses, indent=2))\n\n    # Assert that specific jobs are present in the commit statuses (i.e. don't\n    # approve if CI was broken and didn't schedule a job)\n    job_names = {name for name, status in unified_statuses}\n    for job in EXPECTED_CI_JOBS:\n        if job not in job_names:\n            # Did not find expected job name\n            return False\n\n    passed_ci = all(status for name, status in unified_statuses)\n    return passed_ci\n\n\ndef update_branch(user: str, repo: str, sha: str, branch_name: str) -> None:\n    git([\"fetch\", \"origin\", sha])\n    git([\"reset\", \"--hard\", \"FETCH_HEAD\"])\n    try:\n        git([\"branch\", \"-D\", branch_name])\n    except RuntimeError:\n        # Ignore failures (i.e. the branch did not exist in the first place)\n        pass\n    git([\"checkout\", \"-b\", branch_name])\n\n    # Create and push the branch\n    git([\"push\", \"origin\", \"--force\", branch_name])\n    print(f\"Pushed branch {branch_name} with commit {sha}\")\n\n\nif __name__ == \"__main__\":\n    help = \"Push the a branch to the last commit that passed all CI runs\"\n    parser = argparse.ArgumentParser(description=help)\n    parser.add_argument(\"--remote\", default=\"origin\", help=\"ssh remote to parse\")\n    parser.add_argument(\"--dry-run\", action=\"store_true\", help=\"don't submit to GitHub\")\n    parser.add_argument(\"--branch\", default=\"last-successful\", help=\"branch name\")\n    parser.add_argument(\n        \"--testonly-json\", help=\"(testing) data to use instead of fetching from GitHub\"\n    )\n    args = parser.parse_args()\n\n    remote = git([\"config\", \"--get\", f\"remote.{args.remote}.url\"])\n    user, repo = parse_remote(remote)\n    # TODO: Remove this before landing\n    user, repo = (\"apache\", \"tvm\")\n\n    if args.testonly_json:\n        r = json.loads(args.testonly_json)\n    else:\n        github = GitHubRepo(token=os.environ[\"GITHUB_TOKEN\"], user=user, repo=repo)\n        q = commits_query(user, repo)\n        r = github.graphql(q)\n\n    commits = r[\"data\"][\"repository\"][\"defaultBranchRef\"][\"target\"][\"history\"][\"nodes\"]\n\n    # Limit GraphQL pagination\n    MAX_COMMITS_TO_CHECK = 50\n    i = 0\n\n    while i < MAX_COMMITS_TO_CHECK:\n        # Check each commit\n        for commit in commits:\n            if commit_passed_ci(commit):\n                print(f\"Found last good commit: {commit['oid']}: {commit['messageHeadline']}\")\n                if not args.dry_run:\n                    update_branch(\n                        user=user,\n                        repo=repo,\n                        sha=commit[\"oid\"],\n                        branch_name=args.branch,\n                    )\n                # Nothing to do after updating the branch, exit early\n                exit(0)\n\n        # No good commit found, proceed to next page of results\n        edges = r[\"data\"][\"repository\"][\"defaultBranchRef\"][\"target\"][\"history\"][\"edges\"]\n        if len(edges) == 0:\n            break\n        else:\n            q = commits_query(user, repo, cursor=edges[-1][\"cursor\"])\n            r = github.graphql(q)\n            commits = r[\"data\"][\"repository\"][\"defaultBranchRef\"][\"target\"][\"history\"][\"nodes\"]\n\n        # Backstop to prevent looking through all the past commits\n        i += len(commits)\n\n    print(f\"No good commits found in the last {len(commits)} commits\")\n    exit(1)\n", "path": "ci/scripts/github/update_branch.py"}]}