This is an automated email from the ASF dual-hosted git repository.

tlopex pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/tvm.git


The following commit(s) were added to refs/heads/main by this push:
     new 5427e3c2de [CI] Remove stale GitHub automation (#19946)
5427e3c2de is described below

commit 5427e3c2dece19afd9e29696578139046bb1dd97
Author: Tianqi Chen <[email protected]>
AuthorDate: Sun Jul 5 13:21:10 2026 +0800

    [CI] Remove stale GitHub automation (#19946)
    
    Retire GitHub automation that is disabled, non-functional, unowned, or
    explicitly no longer wanted, together with its orphaned support code and
    tests.
    
    This removes the optional Dependabot version-update config; automatic
    team mentions and cc-review requests; last-successful and nightly branch
    advancement; reviewer pings; the disabled PR-comment bot; and the unused
    CI-resource upload path. Active CI, release, tvm-bot, and manual
    Docker-update workflows remain, with narrower permissions and event
    guards, plus refreshed issue-template and network-resource guidance.
    
    The behavior change is intentional: reviewer requests and team routing
    become manual, and the nightly and last-successful branches are no
    longer advanced by this repository. Dependabot security updates remain
    controlled by repository settings.
---
 .github/ISSUE_TEMPLATE/bug-report.md               |   6 +-
 .github/ISSUE_TEMPLATE/ci-problem.md               |   6 +-
 .github/ISSUE_TEMPLATE/config.yml                  |   2 +-
 .github/ISSUE_TEMPLATE/documentation.md            |   6 +-
 .github/ISSUE_TEMPLATE/feature-tracking.md         |   6 +-
 .github/ISSUE_TEMPLATE/flaky-test.md               |   6 +-
 .github/actions/setup/action.yml                   |   3 +
 .github/dependabot.yml                             |  15 -
 .github/disabled_workflows/pr_comment_bot.yml      |  55 --
 .github/workflows/cc_bot.yml                       |  47 -
 .github/workflows/lint.yml                         |   3 +
 .github/workflows/main.yml                         |   3 +
 .github/workflows/nightly_docker_update.yml        |   5 -
 .github/workflows/ping_reviewers.yml               |  23 -
 .github/workflows/tag_teams.yml                    |  41 -
 .github/workflows/tvmbot.yml                       |  12 +-
 .../workflows/update_last_successful_branch.yml    |  44 -
 .github/workflows/update_nightly_branch.yml        |  44 -
 .github/workflows/upload_ci_resource.yml           |  60 --
 ci/README.md                                       |   4 -
 ci/jenkins/README.md                               |   4 -
 ci/scripts/github/__init__.py                      |   4 +-
 ci/scripts/github/github_cc_reviewers.py           | 118 ---
 ci/scripts/github/github_commenter.py              | 139 ---
 ci/scripts/github/github_docs_comment.py           |  53 --
 ci/scripts/github/github_pr_comment.py             | 148 ---
 ci/scripts/github/github_skipped_tests_comment.py  | 263 ------
 ci/scripts/github/github_tag_teams.py              | 298 -------
 ci/scripts/github/github_tvmbot.py                 |   2 +-
 ci/scripts/github/ping_reviewers.py                | 264 ------
 ci/scripts/github/update_branch.py                 | 208 -----
 docs/contribute/code_guide.rst                     |  13 +-
 docs/contribute/pull_request.rst                   |   6 +-
 tests/python/ci/test_ci.py                         | 988 +--------------------
 tests/scripts/release/gather_prs.py                |   3 +-
 tests/scripts/request_hook/request_hook.py         |  17 +-
 36 files changed, 45 insertions(+), 2874 deletions(-)

diff --git a/.github/ISSUE_TEMPLATE/bug-report.md 
b/.github/ISSUE_TEMPLATE/bug-report.md
index 359a441ecf..e373b6dc0d 100644
--- a/.github/ISSUE_TEMPLATE/bug-report.md
+++ b/.github/ISSUE_TEMPLATE/bug-report.md
@@ -1,11 +1,11 @@
 ---
 name: "\U0001F41B Bug report"
-about: Please include a description of your environment, preferably a minimum 
script to reproduce the problem. Find the list of label tags at 
https://tinyurl.com/5fnd5rkn.
+about: Please include a description of your environment, preferably a minimum 
script to reproduce the problem. Find the list of label tags at 
https://github.com/apache/tvm/labels.
 title: "[Bug] "
 labels: "needs-triage, type: bug"
 ---
 
-Thanks for participating in the TVM community! We use https://discuss.tvm.ai 
for any general usage questions and discussions. The issue tracker is used for 
actionable items such as feature proposals discussion, roadmaps, and bug 
tracking.  You are always welcomed to post on the forum first :smile_cat:
+Thanks for participating in the TVM community! We use 
https://discuss.tvm.apache.org/ for any general usage questions and 
discussions. The issue tracker is used for actionable items such as feature 
proposals discussion, roadmaps, and bug tracking.  You are always welcomed to 
post on the forum first :smile_cat:
 
 Issues that are inactive for a period of time may get closed. We adopt this 
policy so that we won't lose track of actionable issues that may fall at the 
bottom of the pile. Feel free to reopen a new one if you feel there is an 
additional problem that needs attention when an old one gets closed.
 
@@ -27,6 +27,6 @@ Preferably a minimal script to cause the issue to occur.
 
 ### Triage
 
-Please refer to the list of label tags 
[here](https://github.com/apache/tvm/wiki/Issue-Triage-Labels) to find the 
relevant tags and add them below in a bullet format (example below).
+Please refer to the list of label tags 
[here](https://github.com/apache/tvm/labels) to find the relevant tags and add 
them below in a bullet format (example below).
 
 * needs-triage
diff --git a/.github/ISSUE_TEMPLATE/ci-problem.md 
b/.github/ISSUE_TEMPLATE/ci-problem.md
index b1b874e848..62d07b9bc6 100644
--- a/.github/ISSUE_TEMPLATE/ci-problem.md
+++ b/.github/ISSUE_TEMPLATE/ci-problem.md
@@ -1,11 +1,11 @@
 ---
 name: "\U0000274C CI Problem"
-about: To help the developers act on these problems, please give us as many 
details of the CI failure as possible. Find the list of label tags at 
https://tinyurl.com/5fnd5rkn.
+about: To help the developers act on these problems, please give us as many 
details of the CI failure as possible. Find the list of label tags at 
https://github.com/apache/tvm/labels.
 title: "[CI Problem] "
 labels: "needs-triage, type:ci"
 ---
 
-Thanks for participating in the TVM community! We use https://discuss.tvm.ai 
for any general usage questions and discussions. The issue tracker is used for 
actionable items such as feature proposals discussion, roadmaps, and bug 
tracking.  You are always welcomed to post on the forum first :smile_cat:
+Thanks for participating in the TVM community! We use 
https://discuss.tvm.apache.org/ for any general usage questions and 
discussions. The issue tracker is used for actionable items such as feature 
proposals discussion, roadmaps, and bug tracking.  You are always welcomed to 
post on the forum first :smile_cat:
 
 Issues that are inactive for a period of time may get closed. We adopt this 
policy so that we won't lose track of actionable issues that may fall at the 
bottom of the pile. Feel free to reopen a new one if you feel there is an 
additional problem that needs attention when an old one gets closed.
 
@@ -23,6 +23,6 @@ Have you seen this multiple times in this branch or in other 
branches?
 
 ### Triage
 
-Please refer to the list of label tags 
[here](https://github.com/apache/tvm/wiki/Issue-Triage-Labels) to find the 
relevant tags and add them below in a bullet format (example below).
+Please refer to the list of label tags 
[here](https://github.com/apache/tvm/labels) to find the relevant tags and add 
them below in a bullet format (example below).
 
 * needs-triage
diff --git a/.github/ISSUE_TEMPLATE/config.yml 
b/.github/ISSUE_TEMPLATE/config.yml
index ef55b63553..28322335cd 100644
--- a/.github/ISSUE_TEMPLATE/config.yml
+++ b/.github/ISSUE_TEMPLATE/config.yml
@@ -2,4 +2,4 @@ blank_issues_enabled: false  # default: true
 contact_links:
 - name: 💬 Discourse
   url: https://discuss.tvm.apache.org/
-  about: Thanks for participating in the TVM community! We use 
https://discuss.tvm.ai for any general usage questions and discussions. The 
issue tracker is used for actionable items such as feature proposals 
discussion, roadmaps, and bug tracking.  You are always welcomed to post on the 
forum first 😺
+  about: Thanks for participating in the TVM community! We use 
https://discuss.tvm.apache.org/ for any general usage questions and 
discussions. The issue tracker is used for actionable items such as feature 
proposals discussion, roadmaps, and bug tracking.  You are always welcomed to 
post on the forum first 😺
diff --git a/.github/ISSUE_TEMPLATE/documentation.md 
b/.github/ISSUE_TEMPLATE/documentation.md
index 49d0695b8e..0f18d72417 100644
--- a/.github/ISSUE_TEMPLATE/documentation.md
+++ b/.github/ISSUE_TEMPLATE/documentation.md
@@ -1,11 +1,11 @@
 ---
 name: "\U0001F4C4 Documentation"
-about: Use this template to suggest additions and changes to the 
documentation. Find the list of label tags at https://tinyurl.com/5fnd5rkn.
+about: Use this template to suggest additions and changes to the 
documentation. Find the list of label tags at 
https://github.com/apache/tvm/labels.
 title: "[Docs] "
 labels: "needs-triage, type: doc"
 ---
 
-Thanks for participating in the TVM community! We use https://discuss.tvm.ai 
for any general usage questions and discussions. The issue tracker is used for 
actionable items such as feature proposals discussion, roadmaps, and bug 
tracking.  You are always welcomed to post on the forum first :smile_cat:
+Thanks for participating in the TVM community! We use 
https://discuss.tvm.apache.org/ for any general usage questions and 
discussions. The issue tracker is used for actionable items such as feature 
proposals discussion, roadmaps, and bug tracking.  You are always welcomed to 
post on the forum first :smile_cat:
 
 Issues that are inactive for a period of time may get closed. We adopt this 
policy so that we won't lose track of actionable issues that may fall at the 
bottom of the pile. Feel free to reopen a new one if you feel there is an 
additional problem that needs attention when an old one gets closed.
 
@@ -21,6 +21,6 @@ Otherwise, specify what actions should be taken to provide 
additional clarity/re
 
 ### Triage
 
-Please refer to the list of label tags 
[here](https://github.com/apache/tvm/wiki/Issue-Triage-Labels) to find the 
relevant tags and add them below in a bullet format (example below).
+Please refer to the list of label tags 
[here](https://github.com/apache/tvm/labels) to find the relevant tags and add 
them below in a bullet format (example below).
 
 * needs-triage
diff --git a/.github/ISSUE_TEMPLATE/feature-tracking.md 
b/.github/ISSUE_TEMPLATE/feature-tracking.md
index af217215d6..3a7c6e3f11 100644
--- a/.github/ISSUE_TEMPLATE/feature-tracking.md
+++ b/.github/ISSUE_TEMPLATE/feature-tracking.md
@@ -1,11 +1,11 @@
 ---
 name: "\U0001F527 Feature Tracking"
-about: List clear, small actionable items so we can track the progress of the 
change. Find the list of label tags at https://tinyurl.com/5fnd5rkn.
+about: List clear, small actionable items so we can track the progress of the 
change. Find the list of label tags at https://github.com/apache/tvm/labels.
 title: "[Tracking Issue] "
 labels: "needs-triage, type:rfc-tracking"
 ---
 
-Thanks for participating in the TVM community! We use https://discuss.tvm.ai 
for any general usage questions and discussions. The issue tracker is used for 
actionable items such as feature proposals discussion, roadmaps, and bug 
tracking.  You are always welcomed to post on the forum first :smile_cat:
+Thanks for participating in the TVM community! We use 
https://discuss.tvm.apache.org/ for any general usage questions and 
discussions. The issue tracker is used for actionable items such as feature 
proposals discussion, roadmaps, and bug tracking.  You are always welcomed to 
post on the forum first :smile_cat:
 
 Issues that are inactive for a period of time may get closed. We adopt this 
policy so that we won't lose track of actionable issues that may fall at the 
bottom of the pile. Feel free to reopen a new one if you feel there is an 
additional problem that needs attention when an old one gets closed.
 
@@ -14,6 +14,6 @@ Issues that are inactive for a period of time may get closed. 
We adopt this poli
 
 ### Triage
 
-Please refer to the list of label tags 
[here](https://github.com/apache/tvm/wiki/Issue-Triage-Labels) to find the 
relevant tags and add them below in a bullet format (example below).
+Please refer to the list of label tags 
[here](https://github.com/apache/tvm/labels) to find the relevant tags and add 
them below in a bullet format (example below).
 
 * needs-triage
diff --git a/.github/ISSUE_TEMPLATE/flaky-test.md 
b/.github/ISSUE_TEMPLATE/flaky-test.md
index bf64c08bbe..7f905ac3c1 100644
--- a/.github/ISSUE_TEMPLATE/flaky-test.md
+++ b/.github/ISSUE_TEMPLATE/flaky-test.md
@@ -1,11 +1,11 @@
 ---
 name: "\U00002744 Flaky Test"
-about: Report flaky tests, make sure to include link to CI runs, a sample 
failure log, and the name of the test(s). Find the list of label tags at 
https://tinyurl.com/5fnd5rkn.
+about: Report flaky tests, make sure to include link to CI runs, a sample 
failure log, and the name of the test(s). Find the list of label tags at 
https://github.com/apache/tvm/labels.
 title: "[Flaky Test] "
 labels: "needs-triage, test: flaky"
 ---
 
-Thanks for participating in the TVM community! We use https://discuss.tvm.ai 
for any general usage questions and discussions. The issue tracker is used for 
actionable items such as feature proposals discussion, roadmaps, and bug 
tracking. You are always welcomed to post on the forum first :smile_cat:
+Thanks for participating in the TVM community! We use 
https://discuss.tvm.apache.org/ for any general usage questions and 
discussions. The issue tracker is used for actionable items such as feature 
proposals discussion, roadmaps, and bug tracking. You are always welcomed to 
post on the forum first :smile_cat:
 
 These tests were found to be flaky (intermittently failing on `main` or failed 
in a PR with unrelated changes). As per [the 
docs](https://github.com/apache/tvm/blob/main/docs/contribute/ci.rst#handling-flaky-failures),
 these failures will be disabled in a PR that references this issue until the 
test owners can fix the source of the flakiness.
 
@@ -19,6 +19,6 @@ These tests were found to be flaky (intermittently failing on 
`main` or failed i
 
 ### Triage
 
-Please refer to the list of label tags 
[here](https://github.com/apache/tvm/wiki/Issue-Triage-Labels) to find the 
relevant tags and add them below in a bullet format (example below).
+Please refer to the list of label tags 
[here](https://github.com/apache/tvm/labels) to find the relevant tags and add 
them below in a bullet format (example below).
 
 * needs-triage
diff --git a/.github/actions/setup/action.yml b/.github/actions/setup/action.yml
index 64a36dd6bd..980e5d087f 100644
--- a/.github/actions/setup/action.yml
+++ b/.github/actions/setup/action.yml
@@ -1,3 +1,6 @@
+name: Setup TVM CI environment
+description: Set up the cached conda build environment and install tvm-ffi.
+
 runs:
  using: "composite"
  steps:
diff --git a/.github/dependabot.yml b/.github/dependabot.yml
deleted file mode 100644
index 946ba5338d..0000000000
--- a/.github/dependabot.yml
+++ /dev/null
@@ -1,15 +0,0 @@
-# See 
https://docs.github.com/en/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file#about-the-dependabotyml-file
-version: 2
-
-updates:
-  - package-ecosystem: "npm"
-    directory: "/"
-    schedule:
-      interval: "monthly"
-    open-pull-requests-limit: 0
-
-  - package-ecosystem: "pip"
-    directory: "/"
-    schedule:
-      interval: "monthly"
-    open-pull-requests-limit: 0
diff --git a/.github/disabled_workflows/pr_comment_bot.yml 
b/.github/disabled_workflows/pr_comment_bot.yml
deleted file mode 100644
index 4362867685..0000000000
--- a/.github/disabled_workflows/pr_comment_bot.yml
+++ /dev/null
@@ -1,55 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements.  See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership.  The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License.  You may obtain a copy of the License at
-#
-#   http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied.  See the License for the
-# specific language governing permissions and limitations
-# under the License.
-
-name: comment-bot
-on:
-  pull_request_target:
-    types: [opened, reopened, edited, ready_for_review, labeled]
-  status:
-
-concurrency:
-  group: pr-comment-${{ github.event.number }}-${{ github.event.target_url }}
-  cancel-in-progress: true
-
-jobs:
-  run-comment-bot:
-    if: ${{ github.repository == 'apache/tvm' }}
-    runs-on: ubuntu-latest
-    steps:
-      - uses: actions/checkout@v2
-      - name: Comment bot comment (pr)
-        if: ${{ github.event.number }}
-        env:
-          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
-          PR_NUMBER: ${{ github.event.number }}
-        run: |
-          set -eux
-          python ci/scripts/github/github_pr_comment.py --pr "$PR_NUMBER"
-      - name: Comment bot comment (status)
-        if: ${{ github.event.state }}
-        env:
-          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
-          URL: ${{ github.event.target_url }}
-        run: |
-          set -eux
-          if [[ "$URL" == *"PR-"* ]]; then
-            echo "PR status, sending comment"
-            PR_NUMBER=$(echo $URL | sed 's/.*PR-//g' | sed 's/\/.*//g')
-            python ci/scripts/github/github_pr_comment.py --pr "$PR_NUMBER" || 
/bin/true
-          else
-            echo "Not a PR status, skipping"
-          fi
diff --git a/.github/workflows/cc_bot.yml b/.github/workflows/cc_bot.yml
deleted file mode 100644
index ae22871ec0..0000000000
--- a/.github/workflows/cc_bot.yml
+++ /dev/null
@@ -1,47 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements.  See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership.  The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License.  You may obtain a copy of the License at
-#
-#   http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied.  See the License for the
-# specific language governing permissions and limitations
-# under the License.
-
-# GH actions.
-# We use it to cover windows and mac builds
-# Jenkins is still the primary CI
-
-name: PR
-
-on:
-  # See 
https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#pull_request_target
-  pull_request_target:
-    types: [assigned, opened, synchronize, reopened, edited, ready_for_review]
-
-concurrency:
-  group: PR-${{ github.event.pull_request.number }}
-  cancel-in-progress: true
-
-jobs:
-  cc-reviewers:
-    if: github.repository == 'apache/tvm'
-    runs-on: ubuntu-latest
-    steps:
-      - uses: actions/[email protected]
-        with:
-          submodules: "recursive"
-      - name: Add cc'ed reviewers
-        env:
-          PR: ${{ toJson(github.event.pull_request) }}
-          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
-        run: |
-          set -eux
-          python ci/scripts/github/github_cc_reviewers.py || echo step failed
diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml
index 16fa502aaa..a9bff51f3b 100644
--- a/.github/workflows/lint.yml
+++ b/.github/workflows/lint.yml
@@ -23,6 +23,9 @@ on:
   pull_request:
     branches: [main]
 
+permissions:
+  contents: read
+
 concurrency:
   group: Lint-${{ github.event.pull_request.number || github.sha }}
   cancel-in-progress: true
diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml
index 08e025aca8..a0e4cb0490 100644
--- a/.github/workflows/main.yml
+++ b/.github/workflows/main.yml
@@ -30,6 +30,9 @@ on:
       - main
   workflow_dispatch:
 
+permissions:
+  contents: read
+
 concurrency:
   group: CI-${{ github.event.pull_request.number || github.sha }}
   cancel-in-progress: true
diff --git a/.github/workflows/nightly_docker_update.yml 
b/.github/workflows/nightly_docker_update.yml
index b9fecd9894..7b056342f5 100644
--- a/.github/workflows/nightly_docker_update.yml
+++ b/.github/workflows/nightly_docker_update.yml
@@ -10,13 +10,8 @@ concurrency:
 jobs:
   open_update_pr:
     permissions:
-      actions: write
-      checks: write
       contents: write
-      id-token: write
-      issues: write
       pull-requests: write
-      statuses: write
     if: github.repository == 'apache/tvm'
     runs-on: ubuntu-latest
     steps:
diff --git a/.github/workflows/ping_reviewers.yml 
b/.github/workflows/ping_reviewers.yml
deleted file mode 100644
index de68e57b58..0000000000
--- a/.github/workflows/ping_reviewers.yml
+++ /dev/null
@@ -1,23 +0,0 @@
-
-name: Ping Reviewers
-on:
-  schedule:
-    - cron: "0/15 * * * *"
-  workflow_dispatch:
-
-concurrency:
-  group: ping
-  cancel-in-progress: true
-
-jobs:
-  ping:
-    if: github.repository == 'apache/tvm'
-    runs-on: ubuntu-latest
-    steps:
-      - uses: actions/[email protected]
-      - name: Ping reviewers
-        env:
-          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
-        run: |
-          set -eux
-          python ci/scripts/github/ping_reviewers.py --wait-time-minutes 10080 
|| echo failed
diff --git a/.github/workflows/tag_teams.yml b/.github/workflows/tag_teams.yml
deleted file mode 100644
index 8fffba929c..0000000000
--- a/.github/workflows/tag_teams.yml
+++ /dev/null
@@ -1,41 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements.  See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership.  The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License.  You may obtain a copy of the License at
-#
-#   http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied.  See the License for the
-# specific language governing permissions and limitations
-# under the License.
-
-name: Teams
-
-on:
-  issues:
-    types: [opened, edited, reopened, labeled]
-
-concurrency:
-  group: Teams-${{ github.event.pull_request.number }}-${{ 
github.event.issue.number }}
-  cancel-in-progress: true
-
-jobs:
-  tag-teams:
-    if: github.repository == 'apache/tvm'
-    runs-on: ubuntu-latest
-    steps:
-      - uses: actions/[email protected]
-      - name: Tag people from relevant teams
-        env:
-          PR: ${{ toJson(github.event.pull_request) }}
-          ISSUE: ${{ toJson(github.event.issue) }}
-          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
-        run: |
-          set -eux
-          python ci/scripts/github/github_tag_teams.py || echo failed
diff --git a/.github/workflows/tvmbot.yml b/.github/workflows/tvmbot.yml
index 44d0ac8783..aa6bbcaace 100644
--- a/.github/workflows/tvmbot.yml
+++ b/.github/workflows/tvmbot.yml
@@ -1,26 +1,20 @@
 
 name: tvm-bot
 on:
-  pull_request_review:
-    types:
-      - submitted
   issue_comment:
+    types: [created]
 
 concurrency:
-  group: merge-${{ github.event.pull_request.number }}-${{ 
github.event.issue.number }}
+  group: merge-${{ github.event.issue.number }}
   cancel-in-progress: true
 
 jobs:
   run-tvm-bot:
     permissions:
-      actions: write
-      checks: write
       contents: write
-      id-token: write
       issues: write
       pull-requests: write
-      statuses: write
-    if: ${{ github.event.issue.pull_request && github.repository == 
'apache/tvm' }}
+    if: ${{ github.event.issue.pull_request && 
startsWith(github.event.comment.body, '@tvm-bot ') && github.repository == 
'apache/tvm' }}
     runs-on: ubuntu-latest
     steps:
       - uses: actions/[email protected]
diff --git a/.github/workflows/update_last_successful_branch.yml 
b/.github/workflows/update_last_successful_branch.yml
deleted file mode 100644
index 7f952a2210..0000000000
--- a/.github/workflows/update_last_successful_branch.yml
+++ /dev/null
@@ -1,44 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements.  See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership.  The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License.  You may obtain a copy of the License at
-#
-#   http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied.  See the License for the
-# specific language governing permissions and limitations
-# under the License.
-
-# GH actions.
-# We use it to cover windows and mac builds
-# Jenkins is still the primary CI
-
-name: Update last-successful branch
-
-on:
-  schedule:
-    - cron: "0/15 * * * *"
-  workflow_dispatch:
-
-concurrency:
-  group: update-last-successful-branch
-  cancel-in-progress: true
-
-jobs:
-  update-last-successful-branch:
-    if: github.repository == 'apache/tvm'
-    runs-on: ubuntu-latest
-    steps:
-      - uses: actions/[email protected]
-      - name: Update last-successful branch
-        env:
-          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
-        run: |
-          set -eux
-          python ci/scripts/github/update_branch.py || echo step failed
diff --git a/.github/workflows/update_nightly_branch.yml 
b/.github/workflows/update_nightly_branch.yml
deleted file mode 100644
index 4bc6d3f906..0000000000
--- a/.github/workflows/update_nightly_branch.yml
+++ /dev/null
@@ -1,44 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements.  See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership.  The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License.  You may obtain a copy of the License at
-#
-#   http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied.  See the License for the
-# specific language governing permissions and limitations
-# under the License.
-
-# Update a branch for nightly test results
-name: Update nightly branch
-
-on:
-  schedule:
-    # 9 PM PST
-    - cron: "0 5 * * *"
-  workflow_dispatch:
-
-concurrency:
-  group: update-nightly-branch
-  cancel-in-progress: true
-
-jobs:
-  update-nightly-branch:
-    if: github.repository == 'apache/tvm'
-    runs-on: ubuntu-latest
-    steps:
-      - uses: actions/[email protected]
-      - name: Update nightly branch
-        env:
-          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
-        run: |
-          set -eux
-          git checkout -B nightly
-          git log -5
-          git push origin --force nightly
diff --git a/.github/workflows/upload_ci_resource.yml 
b/.github/workflows/upload_ci_resource.yml
deleted file mode 100644
index 3c99490d83..0000000000
--- a/.github/workflows/upload_ci_resource.yml
+++ /dev/null
@@ -1,60 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements.  See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership.  The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License.  You may obtain a copy of the License at
-#
-#   http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied.  See the License for the
-# specific language governing permissions and limitations
-# under the License.
-name: Upload CI Resource
-
-on:
-  workflow_dispatch:
-    inputs:
-      url:
-        description: 'URL of the file (e.g. "https://example.com/file.zip";)'
-        required: true
-        type: string
-      sha256:
-        description: 'SHA256 of the file'
-        required: true
-        type: string
-      upload_path:
-        description: 'Path of the file in S3 (e.g. "my_folder/something.zip")'
-        required: true
-        type: string
-
-concurrency:
-  group: upload-ci-resource
-  cancel-in-progress: true
-
-jobs:
-  upload-ci-resource:
-    if: github.repository == 'apache/tvm'
-    runs-on: ubuntu-latest
-    steps:
-      - name: Download item and upload to S3
-        env:
-          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
-          AWS_ACCESS_KEY_ID: ${{ secrets.CI_RESOURCES_AWS_ACCESS_KEY_ID }}
-          AWS_SECRET_ACCESS_KEY: ${{ 
secrets.CI_RESOURCES_AWS_SECRET_ACCESS_KEY }}
-          URL: ${{ inputs.url }}
-          SHA256: ${{ inputs.sha256 }}
-          UPLOAD_PATH: ${{ inputs.upload_path }}
-          AWS_DEFAULT_REGION: us-west-2
-        run: |
-          set -eux
-          curl -L -o downloaded_file "$URL"
-          echo "$SHA256 downloaded_file" | sha256sum --check
-          aws s3 cp downloaded_file "s3://tvm-ci-resources/$UPLOAD_PATH"
-          echo "The item is available at 
https://tvm-ci-resources.s3.us-west-2.amazonaws.com/$UPLOAD_PATH";
-          echo "Add this line to tests/scripts/request_hook/request_hook.py"
-          echo "    \"$URL\": f\"{BASE}/$UPLOAD_PATH\","
diff --git a/ci/README.md b/ci/README.md
index 4658c8dae3..d66b289b4b 100644
--- a/ci/README.md
+++ b/ci/README.md
@@ -54,11 +54,7 @@ Jenkins runs all of the Linux-based TVM CI-enabled 
regression tests. This includ
 ## GitHub Actions
 
 GitHub Actions is used to run Windows jobs, MacOS jobs, and various on-GitHub 
automations. These are defined in [`.github/workflows`](../.github/workflows/). 
These automations include bots to:
-* [cc people based on subscribed 
teams/topics](https://github.com/apache/tvm/issues/10317)
 * [allow non-committers to merge approved / CI passing 
PRs](https://discuss.tvm.apache.org/t/rfc-allow-merging-via-pr-comments/12220)
-* [add cc-ed people as reviewers on 
GitHub](https://discuss.tvm.apache.org/t/rfc-remove-codeowners/12095)
-* [ping languishing PRs after no activity for a week (currently opt-in 
only)](https://github.com/apache/tvm/issues/9983)
-* [push a `last-successful` branch to GitHub with the last `main` commit that 
passed CI](https://github.com/apache/tvm/tree/last-successful)
 
 https://github.com/apache/tvm/actions has the logs for each of these 
workflows. Note that when debugging these workflows changes from PRs from 
forked repositories won't be reflected in the PR. These should be tested in the 
forked repository first and linked in the PR body.
 
diff --git a/ci/jenkins/README.md b/ci/jenkins/README.md
index e207751a73..dd6b652bee 100644
--- a/ci/jenkins/README.md
+++ b/ci/jenkins/README.md
@@ -26,11 +26,7 @@ Jenkins runs all of the linux-based TVM CI-enabled 
regression tests. This includ
 ## GitHub Actions
 
 GitHub Actions is used to run Windows jobs, MacOS jobs, and various on-GitHub 
automations. These are defined in 
[`.github/workflows`](../../.github/workflows/). These automations include bots 
to:
-* [cc people based on subscribed 
teams/topics](https://github.com/apache/tvm/issues/10317)
 * [allow non-committers to merge approved / CI passing 
PRs](https://discuss.tvm.apache.org/t/rfc-allow-merging-via-pr-comments/12220)
-* [add cc-ed people as reviewers on 
GitHub](https://discuss.tvm.apache.org/t/rfc-remove-codeowners/12095)
-* [ping languishing PRs after no activity for a week (currently opt-in 
only)](https://github.com/apache/tvm/issues/9983)
-* [push a `last-successful` branch to GitHub with the last `main` commit that 
passed CI](https://github.com/apache/tvm/tree/last-successful)
 
 https://github.com/apache/tvm/actions has the logs for each of these 
workflows. Note that when debugging these workflows changes from PRs from 
forked repositories won't be reflected in the PR. These should be tested in the 
forked repository first and linked in the PR body.
 
diff --git a/ci/scripts/github/__init__.py b/ci/scripts/github/__init__.py
index a6226fec29..fcdda82fc0 100644
--- a/ci/scripts/github/__init__.py
+++ b/ci/scripts/github/__init__.py
@@ -15,6 +15,4 @@
 # KIND, either express or implied.  See the License for the
 # specific language governing permissions and limitations
 # under the License.
-"""Package to enable testing of GitHub scripts"""
-
-from . import github_skipped_tests_comment, github_pr_comment, 
github_tag_teams, github_docs_comment
+"""Package to enable testing of GitHub scripts."""
diff --git a/ci/scripts/github/github_cc_reviewers.py 
b/ci/scripts/github/github_cc_reviewers.py
deleted file mode 100755
index 017878740f..0000000000
--- a/ci/scripts/github/github_cc_reviewers.py
+++ /dev/null
@@ -1,118 +0,0 @@
-#!/usr/bin/env python3
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements.  See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership.  The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License.  You may obtain a copy of the License at
-#
-#   http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied.  See the License for the
-# specific language governing permissions and limitations
-# under the License.
-# ruff: noqa: E402
-
-import argparse
-import json
-import os
-import re
-import sys
-from pathlib import Path
-from urllib import error
-
-# Hackery to enable importing of utils from ci/scripts/jenkins
-REPO_ROOT = Path(__file__).resolve().parent.parent.parent.parent
-sys.path.append(str(REPO_ROOT / "ci" / "scripts" / "jenkins"))
-
-from git_utils import GitHubRepo, git, parse_remote
-
-
-def find_reviewers(body: str) -> list[str]:
-    print(f"Parsing body:\n{body}")
-    matches = re.findall(r"(cc( @[-A-Za-z0-9]+)+)", body, flags=re.MULTILINE)
-    matches = [full for full, last in matches]
-
-    print("Found matches:", matches)
-    reviewers = []
-    for match in matches:
-        if match.startswith("cc "):
-            match = match.replace("cc ", "")
-        users = [x.strip() for x in match.split("@")]
-        reviewers += users
-
-    reviewers = set(x for x in reviewers if x != "")
-    return sorted(list(reviewers))
-
-
-if __name__ == "__main__":
-    help = "Add @cc'ed people in a PR body as reviewers"
-    parser = argparse.ArgumentParser(description=help)
-    parser.add_argument("--remote", default="origin", help="ssh remote to 
parse")
-    parser.add_argument("--testing-reviews-json", help="(testing only) reviews 
as JSON")
-    parser.add_argument(
-        "--dry-run",
-        action="store_true",
-        default=False,
-        help="run but don't send any request to GitHub",
-    )
-    args = parser.parse_args()
-
-    remote = git(["config", "--get", f"remote.{args.remote}.url"])
-    user, repo = parse_remote(remote)
-
-    pr = json.loads(os.environ["PR"])
-
-    number = pr["number"]
-    body = pr["body"]
-    if body is None:
-        body = ""
-
-    new_reviewers = find_reviewers(body)
-    print("Found these reviewers:", new_reviewers)
-
-    if args.testing_reviews_json:
-        existing_reviews = json.loads(args.testing_reviews_json)
-    else:
-        github = GitHubRepo(token=os.environ["GITHUB_TOKEN"], user=user, 
repo=repo)
-        existing_reviews = github.get(f"pulls/{number}/reviews")
-
-    existing_review_users = [review["user"]["login"] for review in 
existing_reviews]
-    print("PR has reviews from these users:", existing_review_users)
-    existing_review_users = set(r.lower() for r in existing_review_users)
-
-    existing_reviewers = [review["login"] for review in 
pr["requested_reviewers"]]
-    print("PR already had these reviewers requested:", existing_reviewers)
-
-    existing_reviewers_lower = {
-        existing_reviewer.lower() for existing_reviewer in existing_reviewers
-    }
-    to_add = []
-    for new_reviewer in new_reviewers:
-        if (
-            new_reviewer.lower() in existing_reviewers_lower
-            or new_reviewer.lower() in existing_review_users
-        ):
-            print(f"{new_reviewer} is already review requested, skipping")
-        else:
-            to_add.append(new_reviewer)
-
-    print(f"After filtering existing reviewers, adding: {to_add}")
-
-    if not args.dry_run:
-        github = GitHubRepo(token=os.environ["GITHUB_TOKEN"], user=user, 
repo=repo)
-
-        # Add reviewers 1 by 1 since GitHub will error out if any of the
-        # requested reviewers aren't members / contributors
-        for reviewer in to_add:
-            try:
-                github.post(f"pulls/{number}/requested_reviewers", 
{"reviewers": [reviewer]})
-            except KeyboardInterrupt:
-                sys.exit()
-            except (RuntimeError, error.HTTPError) as e:
-                # Catch any exception so other reviewers can be processed
-                print(f"Failed to add reviewer {reviewer}: {e}")
diff --git a/ci/scripts/github/github_commenter.py 
b/ci/scripts/github/github_commenter.py
deleted file mode 100644
index b193dc3b95..0000000000
--- a/ci/scripts/github/github_commenter.py
+++ /dev/null
@@ -1,139 +0,0 @@
-#!/usr/bin/env python3
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements.  See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership.  The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License.  You may obtain a copy of the License at
-#
-#   http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied.  See the License for the
-# specific language governing permissions and limitations
-# under the License.
-# ruff: noqa: E402, E501, RUF012
-
-import logging
-import re
-import sys
-from pathlib import Path
-from typing import Any
-
-# Hackery to enable importing of utils from ci/scripts/jenkins
-REPO_ROOT = Path(__file__).resolve().parent.parent.parent.parent
-sys.path.append(str(REPO_ROOT / "ci" / "scripts" / "jenkins"))
-
-from git_utils import GitHubRepo
-
-BOT_COMMENT_START = "<!---bot-comment-->"
-WELCOME_TEXT = "Thanks for contributing to TVM! Please refer to the 
contributing guidelines https://tvm.apache.org/docs/contribute/ for useful 
information and tips. Please request code reviews from 
[Reviewers](https://github.com/apache/incubator-tvm/blob/master/CONTRIBUTORS.md#reviewers)
 by @-ing them in a comment."
-
-
-class BotCommentBuilder:
-    ALLOWLIST_USERS = {"driazati", "gigiblender", "areusch"}
-
-    def __init__(self, github: GitHubRepo, data: dict[str, Any]):
-        self.github = github
-        self.pr_number = data["number"]
-        self.comment_data = data["comments"]["nodes"]
-        self.author = data["author"]["login"]
-
-    def find_bot_comment(self) -> dict[str, Any] | None:
-        """
-        Return the existing bot comment or None if it does not exist
-        """
-        for comment in self.comment_data:
-            logging.info(f"Checking comment {comment}")
-            if (
-                comment["author"]["login"] == "github-actions"
-                and BOT_COMMENT_START in comment["body"]
-            ):
-                logging.info("Found existing comment")
-                return comment
-        logging.info("No existing comment found")
-        return None
-
-    def find_existing_body(self) -> dict[str, str]:
-        """
-        Find existing dynamic bullet point items
-        """
-        existing_comment = self.find_bot_comment()
-        if existing_comment is None:
-            logging.info("No existing comment while searching for body items")
-            return {}
-
-        matches = re.findall(
-            
r"<!--bot-comment-([a-z][a-z-]+)-start-->([\S\s]*?)<!--bot-comment-([a-z-]+)-end-->",
-            existing_comment["body"],
-            flags=re.MULTILINE,
-        )
-        logging.info(f"Fetch body item matches: {matches}")
-
-        items = {}
-        for start, text, end in matches:
-            if start != end:
-                raise RuntimeError(
-                    f"Malformed comment found: {start} marker did not have 
matching end, found instead {end}"
-                )
-            items[start] = text.strip().lstrip("* ")
-
-        logging.info(f"Found body items: {items}")
-        return items
-
-    def _post_comment(self, body_items: dict[str, str]):
-        comment = BOT_COMMENT_START + "\n\n" + WELCOME_TEXT + "\n\n"
-        for key, content in body_items.items():
-            line = self.start_key(key) + "\n * " + content.strip() + 
self.end_key(key)
-            logging.info(f"Adding line {line}")
-            comment += line
-        comment += "\n\n<sub>Generated by 
[tvm-bot](https://github.com/apache/tvm/blob/main/ci/README.md#github-actions)</sub>"
-
-        data = {"body": comment}
-        url = f"issues/{self.pr_number}/comments"
-
-        logging.info(f"Commenting {comment} on {url}")
-
-        if self.author not in self.ALLOWLIST_USERS:
-            logging.info(f"Skipping comment for author {self.author}")
-            return
-
-        existing_comment = self.find_bot_comment()
-        if existing_comment is None:
-            # Comment does not exist, post it
-            r = self.github.post(url, data)
-        else:
-            # Comment does exist, update it
-            comment_url = f"issues/comments/{existing_comment['databaseId']}"
-            r = self.github.patch(comment_url, data)
-
-        logging.info(f"Got response from posting comment: {r}")
-
-    def start_key(self, key: str) -> str:
-        return f"<!--bot-comment-{key}-start-->"
-
-    def end_key(self, key: str) -> str:
-        return f"<!--bot-comment-{key}-end-->"
-
-    def post_items(self, items: list[tuple[str, str]]):
-        """
-        Update or post bullet points in the PR based on 'items' which is a
-        list of (key, text) pairs
-        """
-        # Find the existing bullet points
-        body_items = self.find_existing_body()
-
-        # Add or update the requested items
-        for key, text in items:
-            if text is None or text.strip() == "":
-                logging.info(f"Skipping {key} since it was empty")
-                continue
-            logging.info(f"Updating comment items {key} with {text}")
-            body_items[key] = text.strip()
-
-        # Post or update the comment
-        # print(body_items)
-        self._post_comment(body_items=body_items)
diff --git a/ci/scripts/github/github_docs_comment.py 
b/ci/scripts/github/github_docs_comment.py
deleted file mode 100755
index 287e736536..0000000000
--- a/ci/scripts/github/github_docs_comment.py
+++ /dev/null
@@ -1,53 +0,0 @@
-#!/usr/bin/env python3
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements.  See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership.  The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License.  You may obtain a copy of the License at
-#
-#   http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied.  See the License for the
-# specific language governing permissions and limitations
-# under the License.
-
-from typing import Any
-
-
-def build_docs_url(base_url_docs, pr_number, build_number):
-    return f"{base_url_docs}/PR-{pr_number!s}/{build_number!s}/docs/index.html"
-
-
-def find_target_url(pr_head: dict[str, Any]):
-    for status in pr_head["statusCheckRollup"]["contexts"]["nodes"]:
-        if status.get("context", "") == "tvm-ci/pr-head":
-            return status["targetUrl"]
-
-    raise RuntimeError(f"Unable to find tvm-ci/pr-head status in {pr_head}")
-
-
-def get_pr_and_build_numbers(target_url):
-    target_url = target_url[target_url.find("PR-") : len(target_url)]
-    split = target_url.split("/")
-    pr_number = split[0].strip("PR-")
-    build_number = split[1]
-    return {"pr_number": pr_number, "build_number": build_number}
-
-
-def get_doc_url(pr: dict[str, Any], base_docs_url: str = 
"https://pr-docs.tlcpack.ai";) -> str:
-    pr_head = pr["commits"]["nodes"][0]["commit"]
-    target_url = find_target_url(pr_head)
-    pr_and_build = get_pr_and_build_numbers(target_url)
-
-    commit_sha = pr_head["oid"]
-
-    docs_url = build_docs_url(
-        base_docs_url, pr_and_build["pr_number"], pr_and_build["build_number"]
-    )
-
-    return f"Built docs for commit {commit_sha} can be found 
[here]({docs_url})."
diff --git a/ci/scripts/github/github_pr_comment.py 
b/ci/scripts/github/github_pr_comment.py
deleted file mode 100755
index 2d523b21b3..0000000000
--- a/ci/scripts/github/github_pr_comment.py
+++ /dev/null
@@ -1,148 +0,0 @@
-#!/usr/bin/env python3
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements.  See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership.  The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License.  You may obtain a copy of the License at
-#
-#   http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied.  See the License for the
-# specific language governing permissions and limitations
-# under the License.
-# ruff: noqa: E402
-import argparse
-import json
-import os
-import sys
-from pathlib import Path
-
-# Hackery to enable importing of utils from ci/scripts/jenkins
-REPO_ROOT = Path(__file__).resolve().parent.parent.parent.parent
-sys.path.append(str(REPO_ROOT / "ci" / "scripts" / "jenkins"))
-
-from cmd_utils import init_log
-from git_utils import DRY_RUN, GitHubRepo, git, parse_remote
-from github_commenter import BotCommentBuilder
-from github_docs_comment import get_doc_url
-from github_skipped_tests_comment import get_skipped_tests_comment
-from github_tag_teams import get_tags
-
-PR_QUERY = """
-    query ($owner: String!, $name: String!, $number: Int!) {
-      repository(owner: $owner, name: $name) {
-        pullRequest(number: $number) {
-          title
-          body
-          state
-          number
-          author {
-            login
-          }
-          labels(first:100) {
-            nodes {
-              name
-            }
-          }
-          comments(last: 100) {
-            pageInfo {
-              hasPreviousPage
-            }
-            nodes {
-              author {
-                login
-              }
-              databaseId
-              body
-            }
-          }
-          commits(last: 1) {
-            nodes {
-              commit {
-                oid
-                statusCheckRollup {
-                  contexts(first: 100) {
-                    pageInfo {
-                      hasNextPage
-                    }
-                    nodes {
-                      ... on StatusContext {
-                        state
-                        context
-                        targetUrl
-                      }
-                    }
-                  }
-                }
-              }
-            }
-          }
-        }
-      }
-    }
-"""
-
-
-if __name__ == "__main__":
-    help = "Comment a welcome message on PRs"
-    parser = argparse.ArgumentParser(description=help)
-    parser.add_argument("--remote", default="origin", help="ssh remote to 
parse")
-    parser.add_argument("--pr", required=True)
-    parser.add_argument("--test-data", help="(testing) mock GitHub API data")
-    parser.add_argument("--test-comments", help="(testing) testing comments")
-    parser.add_argument(
-        "--dry-run",
-        action="store_true",
-        default=False,
-        help="run but don't send any request to GitHub",
-    )
-    args = parser.parse_args()
-    init_log()
-
-    remote = git(["config", "--get", f"remote.{args.remote}.url"])
-    user, repo = parse_remote(remote)
-
-    test_data = None
-    if args.test_data is not None:
-        test_data = json.loads(args.test_data)
-
-    github = GitHubRepo(
-        user=user,
-        repo=repo,
-        token=DRY_RUN if args.dry_run else os.environ["GITHUB_TOKEN"],
-        test_data=test_data,
-    )
-
-    pr_data = github.graphql(
-        PR_QUERY,
-        {
-            "owner": user,
-            "name": repo,
-            "number": int(args.pr),
-        },
-    )
-
-    pr_data = pr_data["data"]["repository"]["pullRequest"]
-    commenter = BotCommentBuilder(github=github, data=pr_data)
-
-    if args.test_comments is not None:
-        test_comments = json.loads(args.test_comments)
-        skipped_tests = test_comments["skipped-tests"]
-        ccs = test_comments["ccs"]
-        docs_info = test_comments["docs"]
-    else:
-        skipped_tests = get_skipped_tests_comment(pr_data, github=github)
-        ccs = get_tags(pr_data, github, team_issue=10317)
-        docs_info = get_doc_url(pr_data)
-
-    items = {
-        "ccs": ccs,
-        "skipped-tests": skipped_tests,
-        "docs": docs_info,
-    }
-    commenter.post_items(items=items.items())
diff --git a/ci/scripts/github/github_skipped_tests_comment.py 
b/ci/scripts/github/github_skipped_tests_comment.py
deleted file mode 100755
index 10789f7561..0000000000
--- a/ci/scripts/github/github_skipped_tests_comment.py
+++ /dev/null
@@ -1,263 +0,0 @@
-#!/usr/bin/env python3
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements.  See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership.  The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License.  You may obtain a copy of the License at
-#
-#   http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied.  See the License for the
-# specific language governing permissions and limitations
-# under the License.
-# ruff: noqa: E501
-import json
-import logging
-import os
-import subprocess
-from pathlib import Path
-from typing import Any
-from xml.etree import ElementTree
-
-
-def run_subprocess(command):
-    logging.info(f"Running command {command}")
-    proc = subprocess.run(command, shell=True, stdout=subprocess.PIPE, 
encoding="utf-8")
-    if proc.returncode != 0:
-        raise RuntimeError(f"Command failed 
{command}:\nstdout:\n{proc.stdout}")
-    return proc
-
-
-def retrieve_test_report(s3_url, target_dir):
-    command = f"aws --region us-west-2 s3 cp {s3_url} {target_dir} --recursive 
--no-sign-request"
-    run_subprocess(command)
-
-
-def get_common_commit_sha():
-    command = "git merge-base origin/main HEAD"
-    proc = run_subprocess(command)
-    return proc.stdout.strip()
-
-
-def get_main_jenkins_build_number(github, common_commit):
-    json = github.get(f"commits/{common_commit}/status")
-    for status in reversed(json["statuses"]):
-        if status["context"] != "tvm-ci/branch":
-            continue
-        state = status["state"]
-        target_url = str(status["target_url"])
-        build_number = (
-            target_url[target_url.find("job/main") : len(target_url)]
-            .strip("job/main/")
-            .strip("/display/redirect")
-        )
-        assert build_number.isdigit()
-        return {"build_number": build_number, "state": state}
-    raise RuntimeError(f"Failed to find main build number for commit 
{common_commit}")
-
-
-def retrieve_test_reports(
-    common_main_build, pr_number, build_number, s3_prefix, pr_test_report_dir, 
main_test_report_dir
-):
-    cur_build_s3_link = 
f"s3://{s3_prefix}/tvm/PR-{pr_number!s}/{build_number!s}/pytest-results"
-    retrieve_test_report(cur_build_s3_link, pr_test_report_dir)
-
-    common_build_s3_link = 
f"s3://{s3_prefix}/tvm/main/{common_main_build}/pytest-results"
-    retrieve_test_report(common_build_s3_link, main_test_report_dir)
-
-
-def get_pr_and_build_numbers(target_url):
-    target_url = target_url[target_url.find("PR-") : len(target_url)]
-    split = target_url.split("/")
-    pr_number = split[0].strip("PR-")
-    build_number = split[1]
-    return {"pr_number": pr_number, "build_number": build_number}
-
-
-def build_test_set(directory):
-    directory = Path(directory)
-    subdir_to_skipped = {}
-    subdirs = [
-        item for item in os.listdir(directory) if 
os.path.isdir(os.path.join(directory, item))
-    ]
-    for subdir in subdirs:
-        subdir_to_skipped[subdir] = set()
-        for root, _, files in os.walk(directory / subdir):
-            for file in files:
-                test_report = ElementTree.parse(Path(root) / file)
-                for testcase in test_report.iter("testcase"):
-                    skipped = testcase.find("skipped")
-                    if skipped is not None:
-                        key = testcase.attrib["classname"] + "#" + 
testcase.attrib["name"]
-                        subdir_to_skipped[subdir].add(key)
-    return subdir_to_skipped
-
-
-def to_node_name(dir_name: str):
-    return dir_name.replace("_", ": ", 1)
-
-
-def build_diff_comment_with_main(
-    common_commit_sha,
-    skipped_list,
-    commit_sha,
-):
-    if len(skipped_list) == 0:
-        return f"No diff in skipped tests with main found in this branch for 
commit {commit_sha}.\n"
-
-    text = (
-        f"The list below shows tests that ran in main {common_commit_sha} but 
were "
-        f"skipped in the CI build of {commit_sha}:\n"
-        f"```\n"
-    )
-    for skip in skipped_list:
-        text += skip + "\n"
-    text += "```\n"
-    return text
-
-
-def build_comment(
-    common_commit_sha,
-    common_main_build,
-    skipped_list,
-    additional_skipped_list,
-    pr_number,
-    build_number,
-    commit_sha,
-    jenkins_prefix,
-):
-    if common_main_build["state"] != "success":
-        return f"Unable to run tests bot because main failed to pass CI at 
{common_commit_sha}."
-
-    text = build_diff_comment_with_main(common_commit_sha, skipped_list, 
commit_sha)
-
-    if len(additional_skipped_list) != 0:
-        text += "\n"
-        text += (
-            "Additional tests that were skipped in the CI build and present in 
the [`required_tests_to_run`]"
-            
"(https://github.com/apache/tvm/blob/main/ci/scripts/github/required_tests_to_run.json)
 file:"
-            "\n```\n"
-        )
-        for skip in additional_skipped_list:
-            text += skip + "\n"
-        text += "```\n"
-
-    text += (
-        f"A detailed report of ran tests is 
[here](https://{jenkins_prefix}/job/tvm/job/PR-{pr_number!s}";
-        f"/{build_number!s}/testReport/)."
-    )
-    return text
-
-
-def find_target_url(pr_head: dict[str, Any]):
-    for status in pr_head["statusCheckRollup"]["contexts"]["nodes"]:
-        if status.get("context", "") == "tvm-ci/pr-head":
-            return status["targetUrl"]
-
-    raise RuntimeError(f"Unable to find tvm-ci/pr-head status in {pr_head}")
-
-
-def get_skipped_tests_comment(
-    pr: dict[str, Any],
-    github,
-    s3_prefix: str = "tvm-jenkins-artifacts-prod",
-    jenkins_prefix: str = "ci.tlcpack.ai",
-    pr_test_report_dir: str = "pr-reports",
-    main_test_report_dir: str = "main-reports",
-    common_commit_sha: str | None = None,
-    common_main_build: dict[str, Any] | None = None,
-    additional_tests_to_check_file: str = "required_tests_to_run.json",
-) -> str:
-    pr_head = pr["commits"]["nodes"][0]["commit"]
-    target_url = find_target_url(pr_head)
-    pr_and_build = get_pr_and_build_numbers(target_url)
-    logging.info(f"Getting comment for {pr_head} with target {target_url}")
-
-    commit_sha = pr_head["oid"]
-
-    is_dry_run = common_commit_sha is not None
-
-    if not is_dry_run:
-        logging.info("Fetching common commit sha and build info")
-        common_commit_sha = get_common_commit_sha()
-        common_main_build = get_main_jenkins_build_number(github, 
common_commit_sha)
-
-        retrieve_test_reports(
-            common_main_build=common_main_build["build_number"],
-            pr_number=pr_and_build["pr_number"],
-            build_number=pr_and_build["build_number"],
-            s3_prefix=s3_prefix,
-            main_test_report_dir=main_test_report_dir,
-            pr_test_report_dir=pr_test_report_dir,
-        )
-    else:
-        logging.info("Dry run, expecting PR and main reports on disk")
-
-    main_tests = build_test_set(main_test_report_dir)
-    build_tests = build_test_set(pr_test_report_dir)
-
-    skipped_list = []
-    for subdir, skipped_set in build_tests.items():
-        skipped_main = main_tests[subdir]
-        if skipped_main is None:
-            logging.warning(f"Could not find directory {subdir} in main.")
-            continue
-
-        diff_set = skipped_set - skipped_main
-        if len(diff_set) != 0:
-            for test in diff_set:
-                skipped_list.append(f"{to_node_name(subdir)} -> {test}")
-
-    # Sort the list to maintain an order in the output. Helps when validating 
the output in tests.
-    skipped_list.sort()
-
-    if len(skipped_list) == 0:
-        logging.info("No skipped tests found.")
-
-    if not is_dry_run:
-        current_file = Path(__file__).resolve()
-        additional_tests_to_check_file = Path(current_file).parent / 
"required_tests_to_run.json"
-
-    logging.info(
-        f"Checking additional tests in file {additional_tests_to_check_file} 
are not skipped."
-    )
-    try:
-        with open(additional_tests_to_check_file) as f:
-            additional_tests_to_check = json.load(f)
-    except OSError:
-        logging.info(
-            f"Failed to read additional tests from file: 
{additional_tests_to_check_file}."
-        )
-        additional_tests_to_check = {}
-
-    # Assert that tests present in "required_tests_to_run.json" are not 
skipped.
-    additional_skipped_tests = []
-    for subdir, test_set in additional_tests_to_check.items():
-        if subdir not in build_tests.keys():
-            logging.warning(f"Could not find directory {subdir} in the build 
test set.")
-            continue
-
-        for test in test_set:
-            if test in build_tests[subdir]:
-                additional_skipped_tests.append(f"{to_node_name(subdir)} -> 
{test}")
-
-    if len(additional_skipped_tests) == 0:
-        logging.info("No skipped tests found in the additional list.")
-
-    body = build_comment(
-        common_commit_sha,
-        common_main_build,
-        skipped_list,
-        additional_skipped_tests,
-        pr_and_build["pr_number"],
-        pr_and_build["build_number"],
-        commit_sha,
-        jenkins_prefix,
-    )
-
-    return body
diff --git a/ci/scripts/github/github_tag_teams.py 
b/ci/scripts/github/github_tag_teams.py
deleted file mode 100755
index f2c2102a93..0000000000
--- a/ci/scripts/github/github_tag_teams.py
+++ /dev/null
@@ -1,298 +0,0 @@
-#!/usr/bin/env python3
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements.  See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership.  The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License.  You may obtain a copy of the License at
-#
-#   http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied.  See the License for the
-# specific language governing permissions and limitations
-# under the License.
-# ruff: noqa: E402
-
-import argparse
-import json
-import logging
-import os
-import re
-import sys
-from pathlib import Path
-from typing import Any
-
-# Hackery to enable importing of utils from ci/scripts/jenkins
-REPO_ROOT = Path(__file__).resolve().parent.parent.parent.parent
-sys.path.append(str(REPO_ROOT / "ci" / "scripts" / "jenkins"))
-
-from cmd_utils import init_log, tags_from_title
-from git_utils import GitHubRepo, dry_run_token, find_ccs, git, parse_remote
-
-GITHUB_NAME_REGEX = r"@[a-zA-Z0-9-]+"
-
-
-def parse_line(line: str) -> tuple[str, list[str]]:
-    line = line.lstrip(" -")
-    line = line.split()
-
-    # Parse out the name as anything up until the first tagged person
-    tag_items = []
-    tag_end = 0
-    for i, piece in enumerate(line):
-        if piece.startswith("@"):
-            tag_end = i
-            break
-
-        tag_items.append(piece)
-
-    tag = " ".join(tag_items).rstrip(":")
-
-    # From the last word that was part of the tag name, start looking for users
-    # tagged with a '@'
-    users = []
-    for piece in line[tag_end:]:
-        if piece.startswith("@"):
-            users.append(piece.lstrip("@"))
-
-    return (tag, list(sorted(users)))
-
-
-def fetch_issue(github: GitHubRepo, issue_number: int):
-    query = """query($owner: String!, $name: String!, $number: Int!){
-    repository(owner: $owner, name: $name) {
-        issue(number: $number) {
-        body
-        comments(first:100) {
-            nodes {
-            body
-            }
-        }
-        }
-    }
-    }"""
-    r = github.graphql(
-        query,
-        variables={
-            "owner": github.user,
-            "name": github.repo,
-            "number": issue_number,
-        },
-    )
-    return r
-
-
-def parse_teams(r: dict[str, Any], issue_number: int) -> dict[str, str]:
-    """
-    Fetch an issue and parse out series of tagged people from the issue body
-    and comments
-    """
-    issue = r["data"]["repository"]["issue"]
-
-    if issue is None or issue.get("body") is None:
-        raise RuntimeError(f"Could not find issue 
#{issue_number}\n\n{json.dumps(r, indent=2)}")
-
-    result = {}
-
-    def add_tag(tag, users):
-        if tag in result:
-            result[tag] += users
-        else:
-            result[tag] = users
-
-    # Parse the issue body (only bullets are looked at)
-    for line in issue["body"].split("\n"):
-        line = line.strip()
-        if not line.startswith("- "):
-            continue
-        if "@" not in line:
-            continue
-
-        tag, users = parse_line(line)
-        add_tag(tag, users)
-
-    # Parse comment bodies
-    for comment in issue["comments"]["nodes"]:
-        for line in comment["body"].split("\n"):
-            if "@" not in line:
-                continue
-
-            tag, users = parse_line(line)
-            add_tag(tag, users)
-
-    # De-duplicate users listed twice for the same tag
-    for tag in result:
-        result[tag] = list(set(result[tag]))
-
-    return {k.lower(): v for k, v in result.items() if k.strip()}
-
-
-def tags_from_labels(labels: list[dict[str, Any]]) -> list[str]:
-    return [label["name"] for label in labels]
-
-
-def add_ccs_to_body(body: str, to_cc: list[str]) -> str:
-    lines = body.split("\n")
-
-    cc_line_idx = None
-    for i, line in enumerate(reversed(lines)):
-        if line.strip() == "":
-            continue
-        if line.startswith("cc @"):
-            cc_line_idx = len(lines) - i - 1
-        else:
-            break
-
-    def gen_cc_line(users):
-        users = sorted(users)
-        return "cc " + " ".join([f"@{user}" for user in users])
-
-    if cc_line_idx is None:
-        print("Did not find existing cc line")
-        lines.append("")
-        lines.append(gen_cc_line(to_cc))
-    else:
-        # Edit cc line in place
-        line = lines[cc_line_idx]
-        print(f"Found existing cc line at {cc_line_idx}: {line}")
-        existing_ccs = find_ccs(line)
-        print(f"Found cc's: {existing_ccs}")
-
-        if set(to_cc).issubset(set(existing_ccs)):
-            # Don't do anything if there is no update needed
-            return None
-
-        line = gen_cc_line(set(existing_ccs + to_cc))
-
-        lines[cc_line_idx] = line
-
-    return "\n".join(lines)
-
-
-def determine_users_to_cc(
-    issue: dict[str, Any], github: GitHubRepo, team_issue: str, issue_data: 
dict[str, Any] | None
-) -> list[str]:
-    if issue_data is None:
-        issue_data = fetch_issue(github, issue_number=int(team_issue))
-
-    # Fetch the list of teams
-    teams = parse_teams(issue_data, issue_number=int(team_issue))
-
-    logging.info(f"Found these teams in issue 
#{team_issue}\n{json.dumps(teams, indent=2)}")
-
-    title = issue["title"]
-    if "author" in issue:
-        author = issue["author"]["login"]
-    else:
-        author = issue["user"]["login"]
-    tags = tags_from_title(title)
-    if isinstance(issue["labels"], dict):
-        tags += tags_from_labels(issue["labels"]["nodes"])
-    else:
-        tags += tags_from_labels(issue["labels"])
-
-    tags = [t.lower() for t in tags]
-    logging.info(f"Found tags: {tags}")
-
-    # Update the PR or issue based on tags in the title and GitHub tags
-    to_cc = [teams.get(t, []) for t in tags]
-    to_cc = list(set(item for sublist in to_cc for item in sublist))
-    to_cc = [user for user in to_cc if user != author]
-    return to_cc
-
-
-def get_tags(pr_data: dict[str, Any], github: GitHubRepo, team_issue: int) -> 
str:
-    to_cc = determine_users_to_cc(
-        issue=pr_data, github=github, team_issue=team_issue, issue_data=None
-    )
-
-    logging.info(f"Users to cc based on labels: {to_cc}")
-    description = "<sub>See 
[#10317](https://github.com/apache/tvm/issues/10317) for details</sub>"
-    if len(to_cc) == 0:
-        return "No users to tag found in teams " + description
-
-    return "cc " + ", ".join([f"@{user}" for user in to_cc]) + " " + 
description
-
-
-if __name__ == "__main__":
-    help = "Automatically tag people based on PR / issue labels"
-    parser = argparse.ArgumentParser(description=help)
-    parser.add_argument("--remote", default="origin", help="ssh remote to 
parse")
-    parser.add_argument("--team-issue", default="10317", help="issue number to 
look at for ccs")
-    parser.add_argument(
-        "--team-issue-json", help="(testing only) issue JSON to parse rather 
than fetch from GitHub"
-    )
-    parser.add_argument(
-        "--dry-run",
-        action="store_true",
-        default=False,
-        help="run but don't send any request to GitHub",
-    )
-    args = parser.parse_args()
-    init_log()
-
-    remote = git(["config", "--get", f"remote.{args.remote}.url"])
-    user, repo = parse_remote(remote)
-
-    github = GitHubRepo(token=dry_run_token(args.dry_run), user=user, 
repo=repo)
-    if args.team_issue_json:
-        issue_data = json.loads(args.team_issue_json)
-    else:
-        issue_data = fetch_issue(github, issue_number=int(args.team_issue))
-
-    # Extract the payload from GitHub Actions
-    issue = json.loads(os.getenv("ISSUE", "null"))
-    pr = json.loads(os.getenv("PR", "null"))
-    if (issue is None and pr is None) or (issue is not None and pr is not 
None):
-        raise RuntimeError("Exactly one of $PR or $ISSUE must be set in the 
environment")
-
-    if pr is not None:
-        if pr["draft"]:
-            print(f"Terminating since {pr['number']} is a draft")
-            exit(0)
-
-    # PRs/issues have the same structure for the fields needed here
-    item = issue if issue is not None else pr
-    title = item["title"]
-    body = item["body"]
-
-    to_cc = determine_users_to_cc(
-        issue=item, github=github, team_issue=args.team_issue, 
issue_data=issue_data
-    )
-    existing_tags = list(set(re.findall(GITHUB_NAME_REGEX, body)))
-    existing_tags = set(tag.replace("@", "") for tag in existing_tags)
-    logging.info(f"Found existing tags: {existing_tags}")
-    to_cc = [user for user in to_cc if user not in existing_tags]
-    logging.info("Users to cc based on labels", to_cc)
-
-    # Create the new PR/issue body
-    if len(to_cc) == 0:
-        logging.info("No one to cc, exiting")
-        exit(0)
-
-    new_body = add_ccs_to_body(body, to_cc)
-    if new_body is None:
-        logging.info("Everyone to cc is already cc'ed, no update needed")
-        exit(0)
-
-    logging.info(f"Changing body 
from:\n----\n{body}\n----\nto:\n----\n{new_body}\n----")
-
-    # Set the PR/issue body on GitHub
-    data = {"body": new_body}
-    if issue is not None:
-        issue_number = issue["number"]
-        url = f"issues/{issue_number}"
-    elif pr is not None:
-        pr_number = pr["number"]
-        url = f"pulls/{pr_number}"
-    else:
-        raise RuntimeError("Unreachable, please report a bug with a link to 
the failed workflow")
-
-    if not args.dry_run:
-        github.post(url, data=data)
-    else:
-        logging.info(f"Dry run, would have updated {url} with {data}")
diff --git a/ci/scripts/github/github_tvmbot.py 
b/ci/scripts/github/github_tvmbot.py
index 557ff1be52..6975bc9d35 100755
--- a/ci/scripts/github/github_tvmbot.py
+++ b/ci/scripts/github/github_tvmbot.py
@@ -392,7 +392,7 @@ class PR:
     def processed_body(self) -> str:
         body = self.raw["body"].strip().replace("\r", "")
         # Remove any @-mentions of people
-        body = re.sub(r"(\s)@", "\g<1>", body)
+        body = re.sub(r"(\s)@", r"\g<1>", body)
 
         # Remove the auto-inserted text since it's not useful to have in the 
commit log
         body = re.sub(THANKS_MESSAGE, "\n\n", body)
diff --git a/ci/scripts/github/ping_reviewers.py 
b/ci/scripts/github/ping_reviewers.py
deleted file mode 100755
index bd1f434c10..0000000000
--- a/ci/scripts/github/ping_reviewers.py
+++ /dev/null
@@ -1,264 +0,0 @@
-#!/usr/bin/env python3
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements.  See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership.  The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License.  You may obtain a copy of the License at
-#
-#   http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied.  See the License for the
-# specific language governing permissions and limitations
-# under the License.
-# ruff: noqa: E402, E501, F821
-
-import argparse
-import datetime
-import json
-import re
-import sys
-import textwrap
-from pathlib import Path
-
-# Hackery to enable importing of utils from ci/scripts/jenkins
-REPO_ROOT = Path(__file__).resolve().parent.parent.parent.parent
-sys.path.append(str(REPO_ROOT / "ci" / "scripts" / "jenkins"))
-
-from git_utils import git, parse_remote
-
-GIT_DATE_FORMAT = "%Y-%m-%dT%H:%M:%SZ"
-
-
-def prs_query(user: str, repo: str, cursor: str | None = None):
-    after = ""
-    if cursor is not None:
-        after = f', before:"{cursor}"'
-    time_keys = "createdAt updatedAt lastEditedAt publishedAt"
-    return f"""
-        {{
-    repository(name: "{repo}", owner: "{user}") {{
-        pullRequests(states: [OPEN], last: 10{after}) {{
-        edges {{
-            cursor
-        }}
-        nodes {{
-            number
-            url
-            body
-            {time_keys}
-            isDraft
-            author {{
-                login
-            }}
-            reviews(last:100) {{
-                nodes {{
-                    {time_keys}
-                    bodyText
-                    author {{ login }}
-                    comments(last:100) {{
-                        nodes {{
-                            {time_keys}
-                            bodyText
-                        }}
-                    }}
-                }}
-            }}
-            comments(last:100) {{
-                nodes {{
-                    authorAssociation
-                    bodyText
-                    {time_keys}
-                    author {{
-                        login
-                    }}
-                }}
-            }}
-        }}
-        }}
-    }}
-    }}
-    """
-
-
-def find_reviewers(body: str) -> list[str]:
-    matches = re.findall(r"(cc( @[-A-Za-z0-9]+)+)", body, flags=re.MULTILINE)
-    matches = [full for full, last in matches]
-
-    reviewers = []
-    for match in matches:
-        if match.startswith("cc "):
-            match = match.replace("cc ", "")
-        users = [x.strip() for x in match.split("@")]
-        reviewers += users
-
-    reviewers = set(x for x in reviewers if x != "")
-    return list(reviewers)
-
-
-def check_pr(pr, wait_time, now):
-    last_action = None
-
-    author = pr["author"]["login"]
-
-    def update_last(new_time, description):
-        if isinstance(new_time, str):
-            new_time = datetime.datetime.strptime(new_time, GIT_DATE_FORMAT)
-        if new_time is None:
-            print(f"  time not found: {description}")
-            return
-        nonlocal last_action
-        if last_action is None or new_time > last_action[0]:
-            last_action = (new_time, description)
-
-    def check_obj(obj, name):
-        update_last(obj["publishedAt"], f"{name} publishedAt: {obj}")
-        update_last(obj["updatedAt"], f"{name} updatedAt: {obj}")
-        update_last(obj["lastEditedAt"], f"{name} lastEditedAt: {obj}")
-        update_last(obj["createdAt"], f"{name} lastEditedAt: {obj}")
-
-    check_obj(pr, "pr")
-
-    # GitHub counts comments left as part of a review separately than 
standalone
-    # comments
-    reviews = pr["reviews"]["nodes"]
-    review_comments = []
-    for review in reviews:
-        review_comments += review["comments"]["nodes"]
-        check_obj(review, "review")
-
-    # Collate all comments
-    comments = pr["comments"]["nodes"] + review_comments
-
-    # Find the last date of any comment
-    for comment in comments:
-        check_obj(comment, "comment")
-
-    time_since_last_action = now - last_action[0]
-
-    # Find reviewers in the PR's body
-    pr_body_reviewers = find_reviewers(pr["body"])
-
-    # Pull out reviewers from any cc @... text in a comment
-    cc_reviewers = [find_reviewers(c["bodyText"]) for c in comments]
-    cc_reviewers = [r for revs in cc_reviewers for r in revs]
-
-    # Anyone that has left a review as a reviewer (this may include the PR
-    # author since their responses count as reviews)
-    review_reviewers = list(set(r["author"]["login"] for r in reviews))
-
-    reviewers = cc_reviewers + review_reviewers + pr_body_reviewers
-    reviewers = list(set(reviewers))
-    reviewers = [r for r in reviewers if r != author]
-
-    if time_since_last_action > wait_time:
-        print(
-            "  Pinging reviewers",
-            reviewers,
-            "on",
-            pr["url"],
-            "since it has been",
-            time_since_last_action,
-            f"since anything happened on that PR (last action: 
{last_action[1]})",
-        )
-        return reviewers
-    else:
-        print(
-            f"  Not pinging PR {pr['number']} since it has been only 
{time_since_last_action} since the last action: {last_action[1]}"
-        )
-
-    return None
-
-
-def make_ping_message(pr, reviewers):
-    reviewers = [f"@{r}" for r in reviewers]
-    author = f"@{pr['author']['login']}"
-    text = (
-        "It has been a while since this PR was updated, "
-        + " ".join(reviewers)
-        + " please leave a review or address the outstanding comments. "
-        + f"{author} if this PR is still a work in progress, please [convert 
it to a 
draft](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/changing-the-stage-of-a-pull-request#converting-a-pull-request-to-a-draft)"
-        " until it is ready for review."
-    )
-    return text
-
-
-if __name__ == "__main__":
-    help = "Comment on languishing issues and PRs"
-    parser = argparse.ArgumentParser(description=help)
-    parser.add_argument("--remote", default="origin", help="ssh remote to 
parse")
-    parser.add_argument("--wait-time-minutes", required=True, type=int, 
help="ssh remote to parse")
-    parser.add_argument("--cutoff-pr-number", default=0, type=int, help="ssh 
remote to parse")
-    parser.add_argument("--dry-run", action="store_true", help="don't update 
GitHub")
-    parser.add_argument("--pr-json", help="(testing) data for testing to use 
instead of GitHub")
-    parser.add_argument("--now", help="(testing) custom string for current 
time")
-    args = parser.parse_args()
-
-    remote = git(["config", "--get", f"remote.{args.remote}.url"])
-    user, repo = parse_remote(remote)
-
-    wait_time = datetime.timedelta(minutes=int(args.wait_time_minutes))
-    cutoff_pr_number = int(args.cutoff_pr_number)
-    print(
-        "Running with:\n"
-        f"  time cutoff: {wait_time}\n"
-        f"  number cutoff: {cutoff_pr_number}\n"
-        f"  dry run: {args.dry_run}\n"
-        f"  user/repo: {user}/{repo}\n",
-        end="",
-    )
-
-    if args.pr_json:
-        r = json.loads(args.pr_json)
-    else:
-        q = prs_query(user, repo)
-        r = github.graphql(q)
-
-    now = datetime.datetime.utcnow()
-    if args.now:
-        now = datetime.datetime.strptime(args.now, GIT_DATE_FORMAT)
-
-    # Loop until all PRs have been checked
-    while True:
-        prs = r["data"]["repository"]["pullRequests"]["nodes"]
-
-        # Don't look at draft PRs at all
-        prs_to_check = []
-        for pr in prs:
-            if pr["isDraft"]:
-                print(f"Skipping #{pr['number']} since it's a draft")
-            elif pr["number"] <= cutoff_pr_number:
-                print(
-                    f"Skipping #{pr['number']} since it's too old 
({pr['number']} <= {cutoff_pr_number})"
-                )
-            else:
-                print(f"Checking #{pr['number']}")
-                prs_to_check.append(pr)
-
-        print(f"Summary: Checking {len(prs_to_check)} of {len(prs)} fetched")
-
-        # Ping reviewers on each PR in the response if necessary
-        for pr in prs_to_check:
-            print("Checking", pr["url"])
-            reviewers = check_pr(pr, wait_time, now)
-            if reviewers is not None:
-                message = make_ping_message(pr, reviewers)
-                if args.dry_run:
-                    print(
-                        f"Would have commented on 
#{pr['number']}:\n{textwrap.indent(message, prefix='  ')}"
-                    )
-                else:
-                    r = github.post(f"issues/{pr['number']}/comments", 
{"body": message})
-                    print(r)
-
-        edges = r["data"]["repository"]["pullRequests"]["edges"]
-        if len(edges) == 0:
-            # No more results to check
-            break
-
-        cursor = edges[0]["cursor"]
-        r = github.graphql(prs_query(user, repo, cursor))
diff --git a/ci/scripts/github/update_branch.py 
b/ci/scripts/github/update_branch.py
deleted file mode 100755
index e5195f7c67..0000000000
--- a/ci/scripts/github/update_branch.py
+++ /dev/null
@@ -1,208 +0,0 @@
-#!/usr/bin/env python3
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements.  See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership.  The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License.  You may obtain a copy of the License at
-#
-#   http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied.  See the License for the
-# specific language governing permissions and limitations
-# under the License.
-# ruff: noqa: E402
-
-import argparse
-import json
-import os
-import sys
-from pathlib import Path
-from typing import Any
-
-# Hackery to enable importing of utils from ci/scripts/jenkins
-REPO_ROOT = Path(__file__).resolve().parent.parent.parent.parent
-sys.path.append(str(REPO_ROOT / "ci" / "scripts" / "jenkins"))
-
-from git_utils import GitHubRepo, git, parse_remote
-
-_commit_query_fields = """
-    messageHeadline
-    oid
-    statusCheckRollup {
-        contexts(last:100) {
-            nodes {
-                ... on CheckRun {
-                    conclusion
-                    status
-                    name
-                    checkSuite {
-                        workflowRun {
-                            workflow {
-                                name
-                            }
-                        }
-                    }
-                }
-                ... on StatusContext {
-                    context
-                    state
-                }
-            }
-        }
-    }
-"""
-
-
-def commits_query(user: str, repo: str, cursor: str | None = None):
-    """
-    Create a GraphQL query to find the last N commits along with their statuses
-    and some metadata (paginated after 'cursor')
-    """
-    after = ""
-    if cursor is not None:
-        after = f', after:"{cursor}"'
-
-    return f"""
-    {{
-    repository(name: "{repo}", owner: "{user}") {{
-        defaultBranchRef {{
-        target {{
-            ... on Commit {{
-            history(first: 15{after}) {{
-                edges {{ cursor }}
-                nodes {{
-                    {_commit_query_fields}
-                }}
-            }}
-            }}
-        }}
-        }}
-    }}
-    }}
-    """
-
-
-EXPECTED_CI_JOBS = [
-    "cross-isa-minimal/branch",
-    "gpu/branch",
-    "arm/branch",
-    "cortexm/branch",
-    "cpu/branch",
-    "docker/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
-    """
-    statuses = commit["statusCheckRollup"]["contexts"]["nodes"]
-
-    # GitHub Actions statuses are different from external GitHub statuses, so
-    # unify them into 1 representation
-    # 
https://docs.github.com/en/developers/webhooks-and-events/webhooks/webhook-events-and-payloads
-    unified_statuses = []
-    for status in statuses:
-        if "context" in status:
-            # Parse non-GHA status
-            unified_statuses.append((status["context"], status["state"] == 
"SUCCESS"))
-        else:
-            # Parse GitHub Actions item
-            workflow = status["checkSuite"]["workflowRun"]["workflow"]["name"]
-            name = f"{workflow} / {status['name']}"
-            unified_statuses.append((name, status["conclusion"] == "SUCCESS"))
-
-    print(f"Statuses on {commit['oid']}:", json.dumps(unified_statuses, 
indent=2))
-
-    # 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)
-    job_names = {name for name, status in unified_statuses}
-    for job in EXPECTED_CI_JOBS:
-        if job not in job_names:
-            # Did not find expected job name
-            return False
-
-    passed_ci = all(status for name, status in unified_statuses)
-    return passed_ci
-
-
-def update_branch(user: str, repo: str, sha: str, branch_name: str) -> None:
-    git(["fetch", "origin", sha])
-    git(["reset", "--hard", "FETCH_HEAD"])
-    try:
-        git(["branch", "-D", branch_name])
-    except RuntimeError:
-        # Ignore failures (i.e. the branch did not exist in the first place)
-        pass
-    git(["checkout", "-b", branch_name])
-
-    # Create and push the branch
-    git(["push", "origin", "--force", branch_name])
-    print(f"Pushed branch {branch_name} with commit {sha}")
-
-
-if __name__ == "__main__":
-    help = "Push the a branch to the last commit that passed all CI runs"
-    parser = argparse.ArgumentParser(description=help)
-    parser.add_argument("--remote", default="origin", help="ssh remote to 
parse")
-    parser.add_argument("--dry-run", action="store_true", help="don't submit 
to GitHub")
-    parser.add_argument("--branch", default="last-successful", help="branch 
name")
-    parser.add_argument(
-        "--testonly-json", help="(testing) data to use instead of fetching 
from GitHub"
-    )
-    args = parser.parse_args()
-
-    remote = git(["config", "--get", f"remote.{args.remote}.url"])
-    user, repo = parse_remote(remote)
-
-    if args.testonly_json:
-        r = json.loads(args.testonly_json)
-    else:
-        github = GitHubRepo(token=os.environ["GITHUB_TOKEN"], user=user, 
repo=repo)
-        q = commits_query(user, repo)
-        r = github.graphql(q)
-
-    commits = 
r["data"]["repository"]["defaultBranchRef"]["target"]["history"]["nodes"]
-
-    # Limit GraphQL pagination
-    MAX_COMMITS_TO_CHECK = 50
-    i = 0
-
-    while i < MAX_COMMITS_TO_CHECK:
-        # Check each commit
-        for commit in commits:
-            if commit_passed_ci(commit):
-                print(f"Found last good commit: {commit['oid']}: 
{commit['messageHeadline']}")
-                if not args.dry_run:
-                    update_branch(
-                        user=user,
-                        repo=repo,
-                        sha=commit["oid"],
-                        branch_name=args.branch,
-                    )
-                # Nothing to do after updating the branch, exit early
-                exit(0)
-
-        # No good commit found, proceed to next page of results
-        edges = 
r["data"]["repository"]["defaultBranchRef"]["target"]["history"]["edges"]
-        if len(edges) == 0:
-            break
-        else:
-            q = commits_query(user, repo, cursor=edges[-1]["cursor"])
-            r = github.graphql(q)
-            commits = 
r["data"]["repository"]["defaultBranchRef"]["target"]["history"]["nodes"]
-
-        # Backstop to prevent looking through all the past commits
-        i += len(commits)
-
-    print(f"No good commits found in the last {len(commits)} commits")
-    exit(1)
diff --git a/docs/contribute/code_guide.rst b/docs/contribute/code_guide.rst
index 010ceed56a..1622af120c 100644
--- a/docs/contribute/code_guide.rst
+++ b/docs/contribute/code_guide.rst
@@ -161,15 +161,10 @@ In CI, downloading files from the Internet is a big 
source of flaky test failure
 server can go down or be slow), so try to avoid using the network at all 
during tests. In some cases
 this isn't a reasonable proposition (e.g. the docs tutorials which need to 
download models).
 
-In these cases you can re-host files in S3 for fast access in CI. A committer 
can upload a file,
-specified by a name, hash, and path in S3, using the ``workflow_dispatch`` 
event on `the
-upload_ci_resource.yml GitHub Actions workflow
-<https://github.com/apache/tvm/actions/workflows/upload_ci_resource.yml>`_.  
The sha256 must match
-the file or it will not be uploaded. The upload path is user-defined so it can 
be any path (no
-trailing or leading slashes allowed) but be careful not to collide with 
existing resources on
-accident. Once uploaded you should send a PR to update the ``URL_MAP`` in
-`request_hook.py 
<https://github.com/apache/tvm/blob/main/tests/scripts/request_hook/request_hook.py>`_
-with the new URL.
+New network downloads are rejected by the CI `request hook
+<https://github.com/apache/tvm/blob/main/tests/scripts/request_hook/request_hook.py>`_.
 Prefer
+checked-in fixtures or generated data. If a download is unavoidable, arrange a 
stable
+project-managed mirror with the maintainers and add an explicit ``URL_MAP`` 
entry.
 
 
 Handle Integer Constant Expression
diff --git a/docs/contribute/pull_request.rst b/docs/contribute/pull_request.rst
index 8ee4f2c65a..fe960c709a 100644
--- a/docs/contribute/pull_request.rst
+++ b/docs/contribute/pull_request.rst
@@ -51,9 +51,9 @@ Guidelines
 - Document the code you wrote, see more at :ref:`doc_guide`
 - `Create a pull request 
<https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/creating-a-pull-request>`_
 and fix the problems reported by CI checks.
 - Request code reviews from other contributors and improve your patch according
-  to their reviews by ``@``-ing them in your pull request. Tags in PR titles
-  will automatically tag subscribed users, so make sure to put relevant topics
-  in your PR titles (e.g. ``[microTVM] Add a cool change`` and not ``a cool 
change for microTVM``).
+  to their reviews by ``@``-ing them in your pull request. Use relevant topic
+  tags in PR titles to make the affected area clear (e.g. ``[microTVM] Add a
+  cool change`` and not ``a cool change for microTVM``).
   Please see the Commit Message Guideline below on the guidelines about the 
tags
   in a PR/commit title and how to write good PR/commit messages.
 
diff --git a/tests/python/ci/test_ci.py b/tests/python/ci/test_ci.py
index bfd4b32491..cc410712f3 100644
--- a/tests/python/ci/test_ci.py
+++ b/tests/python/ci/test_ci.py
@@ -14,33 +14,18 @@
 # KIND, either express or implied.  See the License for the
 # specific language governing permissions and limitations
 # under the License.
-# ruff: noqa: E501, RUF005
+# ruff: noqa: RUF005
 """Test various CI scripts and GitHub Actions workflows"""
 
 import json
-import logging
-import shutil
 import subprocess
-import sys
-import textwrap
 from pathlib import Path
 
 import pytest
 
 import tvm.testing
 
-from .test_utils import GITHUB_SCRIPT_ROOT, JENKINS_SCRIPT_ROOT, REPO_ROOT, 
TempGit, run_script
-
-# pylint: disable=wrong-import-position,wrong-import-order
-sys.path.insert(0, str(REPO_ROOT / "ci"))
-sys.path.insert(0, str(JENKINS_SCRIPT_ROOT))
-sys.path.insert(0, str(GITHUB_SCRIPT_ROOT))
-
-import scripts.github
-import scripts.jenkins
-from scripts.github.update_branch import EXPECTED_CI_JOBS
-
-# pylint: enable=wrong-import-position,wrong-import-order
+from .test_utils import JENKINS_SCRIPT_ROOT, TempGit, run_script
 
 
 def parameterize_named(**kwargs):
@@ -50,613 +35,6 @@ def parameterize_named(**kwargs):
     )
 
 
-# pylint: disable=line-too-long
-TEST_DATA_SKIPPED_BOT = {
-    "found-diff-no-additional": {
-        "main_xml_file": "unittest/file1.xml",
-        "main_xml_content": """<?xml version="1.0" encoding="utf-8"?>
-                <testsuites>
-                    <testsuite errors="0" failures="0" hostname="13e7c5f749d8" 
name="python-unittest-gpu-0-shard-1-ctypes" skipped="102"
-                               tests="165" time="79.312" 
timestamp="2022-08-10T22:39:36.673781">
-                        <testcase 
classname="ctypes.tests.python.unittest.test_auto_scheduler_search_policy"
-                                  
name="test_sketch_search_policy_cuda_rpc_runner" time="9.679">
-                        </testcase>
-                    </testsuite>
-                </testsuites>
-                """,
-        "pr_xml_file": "unittest/file2.xml",
-        "pr_xml_content": """<?xml version="1.0" encoding="utf-8"?>
-                <testsuites>
-                    <testsuite errors="0" failures="0" hostname="13e7c5f749d8" 
name="python-unittest-gpu-0-shard-1-ctypes" skipped="102"
-                               tests="165" time="79.312" 
timestamp="2022-08-10T22:39:36.673781">
-                        <testcase 
classname="ctypes.tests.python.unittest.test_auto_scheduler_search_policy"
-                                  
name="test_sketch_search_policy_cuda_rpc_runner" time="9.679">
-                            <skipped message="This test is skipped" 
type="pytest.skip">
-                                Skipped
-                            </skipped>
-                        </testcase>
-                        <testcase 
classname="ctypes.tests.python.unittest.test_roofline"
-                                  name="test_estimate_peak_bandwidth[cuda]" 
time="4.679">
-                            <skipped message="This is another skippe test" 
type="pytest.skip">
-                                Skipped
-                            </skipped>
-                        </testcase>
-                    </testsuite>
-                </testsuites>
-                """,
-        "additional_tests_to_check": """{
-                    "unittest": ["dummy_class#dummy_test"],
-                    "unittest_GPU": ["another_dummy_class#another_dummy_test"]
-                }
-                """,
-        "target_url": 
"https://ci.tlcpack.ai/job/tvm/job/PR-11594/3/display/redirect";,
-        "s3_prefix": "tvm-jenkins-artifacts-prod",
-        "jenkins_prefix": "ci.tlcpack.ai",
-        "common_main_build": """{"build_number": "4115", "state": 
"success"}""",
-        "commit_sha": "sha1234",
-        "expected_body": "The list below shows tests that ran in main sha1234 
but were skipped in the CI build of sha1234:\n```\nunittest -> 
ctypes.tests.python.unittest.test_auto_scheduler_search_policy#test_sketch_search_policy_cuda_rpc_runner\nunittest
 -> 
ctypes.tests.python.unittest.test_roofline#test_estimate_peak_bandwidth[cuda]\n```\nA
 detailed report of ran tests is 
[here](https://ci.tlcpack.ai/job/tvm/job/PR-11594/3/testReport/).",
-    },
-    "found-diff-skipped-additional": {
-        "main_xml_file": "unittest/file1.xml",
-        "main_xml_content": """<?xml version="1.0" encoding="utf-8"?>
-                <testsuites>
-                    <testsuite errors="0" failures="0" hostname="13e7c5f749d8" 
name="python-unittest-gpu-0-shard-1-ctypes" skipped="102"
-                               tests="165" time="79.312" 
timestamp="2022-08-10T22:39:36.673781">
-                        <testcase 
classname="ctypes.tests.python.unittest.test_auto_scheduler_search_policy"
-                                  
name="test_sketch_search_policy_cuda_rpc_runner" time="9.679">
-                        </testcase>
-                    </testsuite>
-                </testsuites>
-                """,
-        "pr_xml_file": "unittest/file2.xml",
-        "pr_xml_content": """<?xml version="1.0" encoding="utf-8"?>
-                <testsuites>
-                    <testsuite errors="0" failures="0" hostname="13e7c5f749d8" 
name="python-unittest-gpu-0-shard-1-ctypes" skipped="102"
-                               tests="165" time="79.312" 
timestamp="2022-08-10T22:39:36.673781">
-                        <testcase 
classname="ctypes.tests.python.unittest.test_auto_scheduler_search_policy"
-                                  
name="test_sketch_search_policy_cuda_rpc_runner" time="9.679">
-                            <skipped message="This test is skipped" 
type="pytest.skip">
-                                Skipped
-                            </skipped>
-                        </testcase>
-                        <testcase 
classname="ctypes.tests.python.unittest.test_roofline"
-                                  name="test_estimate_peak_bandwidth[cuda]" 
time="4.679">
-                            <skipped message="This is another skippe test" 
type="pytest.skip">
-                                Skipped
-                            </skipped>
-                        </testcase>
-                    </testsuite>
-                </testsuites>
-                """,
-        "additional_tests_to_check": """{
-                    "unittest": 
["ctypes.tests.python.unittest.test_auto_scheduler_search_policy#test_sketch_search_policy_cuda_rpc_runner",
 "dummy_class#dummy_test"],
-                    "unittest_GPU": ["another_dummy_class#another_dummy_test"]
-                }
-                """,
-        "target_url": 
"https://ci.tlcpack.ai/job/tvm/job/PR-11594/3/display/redirect";,
-        "s3_prefix": "tvm-jenkins-artifacts-prod",
-        "jenkins_prefix": "ci.tlcpack.ai",
-        "common_main_build": """{"build_number": "4115", "state": 
"success"}""",
-        "commit_sha": "sha1234",
-        "expected_body": "The list below shows tests that ran in main sha1234 
but were skipped in the CI build of sha1234:\n```\nunittest -> 
ctypes.tests.python.unittest.test_auto_scheduler_search_policy#test_sketch_search_policy_cuda_rpc_runner\nunittest
 -> 
ctypes.tests.python.unittest.test_roofline#test_estimate_peak_bandwidth[cuda]\n```\n\nAdditional
 tests that were skipped in the CI build and present in the 
[`required_tests_to_run`](https://github.com/apache/tvm/blob/main/ci/scripts/ 
[...]
-    },
-    "no-diff": {
-        "main_xml_file": "unittest/file1.xml",
-        "main_xml_content": """<?xml version="1.0" encoding="utf-8"?>
-                <testsuites>
-                    <testsuite errors="0" failures="0" hostname="13e7c5f749d8" 
name="python-unittest-gpu-0-shard-1-ctypes" skipped="102"
-                               tests="165" time="79.312" 
timestamp="2022-08-10T22:39:36.673781">
-                        <testcase 
classname="ctypes.tests.python.unittest.test_auto_scheduler_search_policy"
-                                  
name="test_sketch_search_policy_cuda_rpc_runner" time="9.679">
-                            <skipped message="This test is skipped" 
type="pytest.skip">
-                                Skipped
-                            </skipped>
-                        </testcase>
-                    </testsuite>
-                </testsuites>
-                """,
-        "pr_xml_file": "unittest/file2.xml",
-        "pr_xml_content": """<?xml version="1.0" encoding="utf-8"?>
-                <testsuites>
-                    <testsuite errors="0" failures="0" hostname="13e7c5f749d8" 
name="python-unittest-gpu-0-shard-1-ctypes" skipped="102"
-                               tests="165" time="79.312" 
timestamp="2022-08-10T22:39:36.673781">
-                        <testcase 
classname="ctypes.tests.python.unittest.test_auto_scheduler_search_policy"
-                                  
name="test_sketch_search_policy_cuda_rpc_runner" time="9.679">
-                            <skipped message="This test is skipped" 
type="pytest.skip">
-                                Skipped
-                            </skipped>
-                        </testcase>
-                    </testsuite>
-                </testsuites>
-                """,
-        "additional_tests_to_check": """{
-                }
-                """,
-        "target_url": 
"https://ci.tlcpack.ai/job/tvm/job/PR-11594/3/display/redirect";,
-        "s3_prefix": "tvm-jenkins-artifacts-prod",
-        "jenkins_prefix": "ci.tlcpack.ai",
-        "common_main_build": """{"build_number": "4115", "state": 
"success"}""",
-        "commit_sha": "sha1234",
-        "expected_body": "No diff in skipped tests with main found in this 
branch for commit sha1234.\nA detailed report of ran tests is 
[here](https://ci.tlcpack.ai/job/tvm/job/PR-11594/3/testReport/).",
-    },
-    "no-diff-skipped-additional": {
-        "main_xml_file": "unittest/file1.xml",
-        "main_xml_content": """<?xml version="1.0" encoding="utf-8"?>
-                <testsuites>
-                    <testsuite errors="0" failures="0" hostname="13e7c5f749d8" 
name="python-unittest-gpu-0-shard-1-ctypes" skipped="102"
-                               tests="165" time="79.312" 
timestamp="2022-08-10T22:39:36.673781">
-                        <testcase 
classname="ctypes.tests.python.unittest.test_auto_scheduler_search_policy"
-                                  
name="test_sketch_search_policy_cuda_rpc_runner" time="9.679">
-                            <skipped message="This test is skipped" 
type="pytest.skip">
-                                Skipped
-                            </skipped>
-                        </testcase>
-                    </testsuite>
-                </testsuites>
-                """,
-        "pr_xml_file": "unittest/file2.xml",
-        "pr_xml_content": """<?xml version="1.0" encoding="utf-8"?>
-                <testsuites>
-                    <testsuite errors="0" failures="0" hostname="13e7c5f749d8" 
name="python-unittest-gpu-0-shard-1-ctypes" skipped="102"
-                               tests="165" time="79.312" 
timestamp="2022-08-10T22:39:36.673781">
-                        <testcase 
classname="ctypes.tests.python.unittest.test_auto_scheduler_search_policy"
-                                  
name="test_sketch_search_policy_cuda_rpc_runner" time="9.679">
-                            <skipped message="This test is skipped" 
type="pytest.skip">
-                                Skipped
-                            </skipped>
-                        </testcase>
-                    </testsuite>
-                </testsuites>
-                """,
-        "additional_tests_to_check": """{
-                    "unittest": ["dummy_class#dummy_test", 
"ctypes.tests.python.unittest.test_auto_scheduler_search_policy#test_sketch_search_policy_cuda_rpc_runner"],
-                    "unittest_GPU": ["another_dummy_class#another_dummy_test"]
-                }
-                """,
-        "target_url": 
"https://ci.tlcpack.ai/job/tvm/job/PR-11594/3/display/redirect";,
-        "s3_prefix": "tvm-jenkins-artifacts-prod",
-        "jenkins_prefix": "ci.tlcpack.ai",
-        "common_main_build": """{"build_number": "4115", "state": 
"success"}""",
-        "commit_sha": "sha1234",
-        "expected_body": "No diff in skipped tests with main found in this 
branch for commit sha1234.\n\nAdditional tests that were skipped in the CI 
build and present in the 
[`required_tests_to_run`](https://github.com/apache/tvm/blob/main/ci/scripts/github/required_tests_to_run.json)
 file:\n```\nunittest -> 
ctypes.tests.python.unittest.test_auto_scheduler_search_policy#test_sketch_search_policy_cuda_rpc_runner\n```\nA
 detailed report of ran tests is [here](https://ci.tlcpack.ai/job/tvm [...]
-    },
-    "unable-to-run": {
-        "main_xml_file": "unittest/file1.xml",
-        "main_xml_content": """<?xml version="1.0" encoding="utf-8"?>
-                    <testsuites>
-                    </testsuites>
-                    """,
-        "pr_xml_file": "unittest/file2.xml",
-        "pr_xml_content": """<?xml version="1.0" encoding="utf-8"?>
-                    <testsuites>
-                    </testsuites>
-                    """,
-        "additional_tests_to_check": """{
-                    "unittest": 
["ctypes.tests.python.unittest.test_auto_scheduler_search_policy#test_sketch_search_policy_cuda_rpc_runner",
 "dummy_class#dummy_test"],
-                    "unittest_GPU": ["another_dummy_class#another_dummy_test"]
-                }
-                """,
-        "target_url": 
"https://ci.tlcpack.ai/job/tvm/job/PR-11594/3/display/redirect";,
-        "s3_prefix": "tvm-jenkins-artifacts-prod",
-        "jenkins_prefix": "ci.tlcpack.ai",
-        "common_main_build": """{"build_number": "4115", "state": "failed"}""",
-        "commit_sha": "sha1234",
-        "expected_body": "Unable to run tests bot because main failed to pass 
CI at sha1234.",
-    },
-}
-# pylint: enable=line-too-long
-
-
[email protected]_if_wheel_test
-@parameterize_named(**TEST_DATA_SKIPPED_BOT)
-# pylint: enable=line-too-long
-def test_skipped_tests_comment(
-    caplog,
-    tmpdir_factory,
-    main_xml_file,
-    main_xml_content,
-    pr_xml_file,
-    pr_xml_content,
-    additional_tests_to_check,
-    target_url,
-    s3_prefix,
-    jenkins_prefix,
-    common_main_build,
-    commit_sha,
-    expected_body,
-):
-    """
-    Test that a comment with a link to the docs is successfully left on PRs
-    """
-
-    def write_xml_file(root_dir, xml_file, xml_content):
-        shutil.rmtree(root_dir, ignore_errors=True)
-        file = root_dir / xml_file
-        file.parent.mkdir(parents=True)
-        with open(file, "w") as f:
-            f.write(textwrap.dedent(xml_content))
-
-    git = TempGit(tmpdir_factory.mktemp("tmp_git_dir"))
-    pr_test_report_dir = Path(git.cwd) / "pr-reports"
-    write_xml_file(pr_test_report_dir, pr_xml_file, pr_xml_content)
-    main_test_report_dir = Path(git.cwd) / "main-reports"
-    write_xml_file(main_test_report_dir, main_xml_file, main_xml_content)
-    with open(Path(git.cwd) / "required_tests_to_run.json", "w") as f:
-        f.write(additional_tests_to_check)
-
-    pr_data = {
-        "commits": {
-            "nodes": [
-                {
-                    "commit": {
-                        "oid": commit_sha,
-                        "statusCheckRollup": {
-                            "contexts": {
-                                "nodes": [
-                                    {
-                                        "context": "tvm-ci/pr-head",
-                                        "targetUrl": target_url,
-                                    }
-                                ]
-                            }
-                        },
-                    }
-                }
-            ]
-        }
-    }
-    with caplog.at_level(logging.INFO):
-        comment = 
scripts.github.github_skipped_tests_comment.get_skipped_tests_comment(
-            pr=pr_data,
-            github=None,
-            s3_prefix=s3_prefix,
-            jenkins_prefix=jenkins_prefix,
-            common_commit_sha=commit_sha,
-            pr_test_report_dir=pr_test_report_dir,
-            main_test_report_dir=main_test_report_dir,
-            common_main_build=json.loads(common_main_build),
-            additional_tests_to_check_file=Path(git.cwd) / 
"required_tests_to_run.json",
-        )
-    assert_in(expected_body, comment)
-    assert_in(f"with target {target_url}", caplog.text)
-
-
[email protected]_if_wheel_test
-@parameterize_named(
-    doc_link=dict(
-        
target_url="https://ci.tlcpack.ai/job/tvm/job/PR-11594/3/display/redirect";,
-        base_url="https://pr-docs.tlcpack.ai";,
-        commit_sha="SHA",
-        expected_body="Built docs for commit SHA can be found "
-        "[here](https://pr-docs.tlcpack.ai/PR-11594/3/docs/index.html).",
-    )
-)
-def test_docs_comment(target_url, base_url, commit_sha, expected_body):
-    """
-    Test that a comment with a link to the docs is successfully left on PRs
-    """
-    pr_data = {
-        "commits": {
-            "nodes": [
-                {
-                    "commit": {
-                        "oid": commit_sha,
-                        "statusCheckRollup": {
-                            "contexts": {
-                                "nodes": [
-                                    {
-                                        "context": "tvm-ci/pr-head",
-                                        "targetUrl": target_url,
-                                    }
-                                ]
-                            }
-                        },
-                    }
-                }
-            ]
-        }
-    }
-    comment = scripts.github.github_docs_comment.get_doc_url(
-        pr=pr_data,
-        base_docs_url=base_url,
-    )
-    assert_in(expected_body, comment)
-
-
[email protected]_if_wheel_test
-@parameterize_named(
-    cc_no_one=dict(
-        pr_body="abc", requested_reviewers=[], existing_review_users=[], 
expected_reviewers=[]
-    ),
-    cc_abc=dict(
-        pr_body="cc @abc",
-        requested_reviewers=[],
-        existing_review_users=[],
-        expected_reviewers=["abc"],
-    ),
-    bad_cc_line=dict(
-        pr_body="cc @", requested_reviewers=[], existing_review_users=[], 
expected_reviewers=[]
-    ),
-    cc_multiple=dict(
-        pr_body="cc @abc @def",
-        requested_reviewers=[],
-        existing_review_users=[],
-        expected_reviewers=["abc", "def"],
-    ),
-    with_existing=dict(
-        pr_body="some text cc @abc @def something else",
-        requested_reviewers=[],
-        existing_review_users=[],
-        expected_reviewers=["abc", "def"],
-    ),
-    with_existing_split=dict(
-        pr_body="some text cc @abc @def something else\n\n another cc @zzz z",
-        requested_reviewers=[],
-        existing_review_users=[],
-        expected_reviewers=["abc", "def", "zzz"],
-    ),
-    with_existing_request=dict(
-        pr_body="some text cc @abc @def something else\n\n another cc @zzz z",
-        requested_reviewers=["abc"],
-        existing_review_users=[],
-        expected_reviewers=["def", "zzz"],
-    ),
-    with_existing_reviewers=dict(
-        pr_body="some text cc @abc @def something else\n\n another cc @zzz z",
-        requested_reviewers=["abc"],
-        existing_review_users=["abc"],
-        expected_reviewers=["def", "zzz"],
-    ),
-    with_no_reviewers=dict(
-        pr_body="some text cc @abc @def something else\n\n another cc @zzz z",
-        requested_reviewers=[],
-        existing_review_users=["abc"],
-        expected_reviewers=["def", "zzz"],
-    ),
-)
-def test_cc_reviewers(
-    tmpdir_factory, pr_body, requested_reviewers, existing_review_users, 
expected_reviewers
-):
-    """
-    Test that reviewers are added from 'cc @someone' messages in PRs
-    """
-    reviewers_script = GITHUB_SCRIPT_ROOT / "github_cc_reviewers.py"
-
-    git = TempGit(tmpdir_factory.mktemp("tmp_git_dir"))
-    reviews = [{"user": {"login": r}} for r in existing_review_users]
-    requested_reviewers = [{"login": r} for r in requested_reviewers]
-    proc = run_script(
-        [reviewers_script, "--dry-run", "--testing-reviews-json", 
json.dumps(reviews)],
-        env={
-            "PR": json.dumps(
-                {"number": 1, "body": pr_body, "requested_reviewers": 
requested_reviewers}
-            )
-        },
-        cwd=git.cwd,
-    )
-
-    assert f"After filtering existing reviewers, adding: {expected_reviewers}" 
in proc.stdout
-
-
-def generate_good_commit_status():
-    return list([{"context": context, "state": "SUCCESS"} for context in 
EXPECTED_CI_JOBS])
-
-
-@parameterize_named(
-    # Missing expected gpu/branch test
-    missing_tvm_ci_branch=dict(
-        statuses=[
-            {
-                "context": "test",
-                "state": "SUCCESS",
-            }
-        ],
-        expected_rc=1,
-        expected_output="No good commits found in the last 1 commits",
-    ),
-    # Only has the right passing test
-    has_expected_test=dict(
-        statuses=generate_good_commit_status(),
-        expected_rc=0,
-        expected_output="Found last good commit: 123: hello",
-    ),
-    # Check with many statuses
-    many_statuses=dict(
-        statuses=generate_good_commit_status()
-        + [
-            {"context": "gpu/branch2", "state": "SUCCESS"},
-            {"context": "gpu/branch3", "state": "FAILED"},
-        ],
-        expected_rc=1,
-        expected_output="No good commits found in the last 1 commits",
-    ),
-    many_success_statuses=dict(
-        statuses=generate_good_commit_status()
-        + [
-            {"context": "gpu/branch2", "state": "SUCCESS"},
-            {"context": "gpu/branch3", "state": "SUCCESS"},
-        ],
-        expected_rc=0,
-        expected_output="Found last good commit: 123: hello",
-    ),
-)
-def test_update_branch(tmpdir_factory, statuses, expected_rc, expected_output):
-    """
-    Test that the last-successful branch script updates successfully
-    """
-    update_script = GITHUB_SCRIPT_ROOT / "update_branch.py"
-
-    git = TempGit(tmpdir_factory.mktemp("tmp_git_dir"))
-    commit = {
-        "statusCheckRollup": {"contexts": {"nodes": statuses}},
-        "oid": "123",
-        "messageHeadline": "hello",
-    }
-    data = {
-        "data": {
-            "repository": {
-                "defaultBranchRef": {"target": {"history": {"edges": [], 
"nodes": [commit]}}}
-            }
-        }
-    }
-    proc = run_script(
-        [update_script, "--dry-run", "--testonly-json", json.dumps(data)],
-        cwd=git.cwd,
-        check=False,
-    )
-
-    if proc.returncode != expected_rc:
-        raise RuntimeError(f"Wrong return 
code:\nstdout:\n{proc.stdout}\n\nstderr:\n{proc.stderr}")
-
-    if expected_output not in proc.stdout:
-        raise RuntimeError(
-            f"Missing 
{expected_output}:\nstdout:\n{proc.stdout}\n\nstderr:\n{proc.stderr}"
-        )
-
-
-# pylint: disable=line-too-long
-@parameterize_named(
-    author_gate=dict(
-        pr_author="abc",
-        comments=[],
-        expected="Skipping comment for author abc",
-    ),
-    new_comment=dict(
-        pr_author="driazati",
-        comments=[],
-        expected="No existing comment found",
-    ),
-    update_comment=dict(
-        pr_author="driazati",
-        comments=[
-            {
-                "author": {"login": "github-actions"},
-                "databaseId": "comment456",
-                "body": "<!---bot-comment--> abc",
-            }
-        ],
-        expected="PATCH to 
https://api.github.com/repos/apache/tvm/issues/comments/comment456";,
-    ),
-    new_body=dict(
-        pr_author="driazati",
-        comments=[],
-        expected="Commenting "
-        + textwrap.dedent(
-            """
-        <!---bot-comment-->
-
-        Thanks for contributing to TVM! Please refer to the contributing 
guidelines https://tvm.apache.org/docs/contribute/ for useful information and 
tips. Please request code reviews from 
[Reviewers](https://github.com/apache/incubator-tvm/blob/master/CONTRIBUTORS.md#reviewers)
 by @-ing them in a comment.
-
-        <!--bot-comment-ccs-start-->
-         * the 
cc<!--bot-comment-ccs-end--><!--bot-comment-skipped-tests-start-->
-         * the skipped 
tests<!--bot-comment-skipped-tests-end--><!--bot-comment-docs-start-->
-         * the docs<!--bot-comment-docs-end-->
-        """
-        ).strip(),
-    ),
-    update_body=dict(
-        pr_author="driazati",
-        comments=[
-            {
-                "author": {"login": "github-actions"},
-                "databaseId": "comment456",
-                "body": textwrap.dedent(
-                    """
-        <!---bot-comment-->
-
-        Thanks for contributing to TVM! Please refer to the contributing 
guidelines https://tvm.apache.org/docs/contribute/ for useful information and 
tips. Please request code reviews from 
[Reviewers](https://github.com/apache/incubator-tvm/blob/master/CONTRIBUTORS.md#reviewers)
 by @-ing them in a comment.
-
-        <!--bot-comment-ccs-start-->
-         * the 
cc<!--bot-comment-ccs-end--><!--bot-comment-something-tests-start-->
-         * something 
else<!--bot-comment-something-tests-end--><!--bot-comment-docs-start-->
-         * the docs<!--bot-comment-docs-end-->
-        """
-                ).strip(),
-            }
-        ],
-        expected="Commenting "
-        + textwrap.dedent(
-            """
-        <!---bot-comment-->
-
-        Thanks for contributing to TVM! Please refer to the contributing 
guidelines https://tvm.apache.org/docs/contribute/ for useful information and 
tips. Please request code reviews from 
[Reviewers](https://github.com/apache/incubator-tvm/blob/master/CONTRIBUTORS.md#reviewers)
 by @-ing them in a comment.
-
-        <!--bot-comment-ccs-start-->
-         * the 
cc<!--bot-comment-ccs-end--><!--bot-comment-something-tests-start-->
-         * something 
else<!--bot-comment-something-tests-end--><!--bot-comment-docs-start-->
-         * the 
docs<!--bot-comment-docs-end--><!--bot-comment-skipped-tests-start-->
-         * the skipped tests<!--bot-comment-skipped-tests-end-->
-        """
-        ).strip(),
-    ),
-)
-# pylint: enable=line-too-long
-def test_pr_comment(tmpdir_factory, pr_author, comments, expected):
-    """
-    Test the PR commenting bot
-    """
-    comment_script = GITHUB_SCRIPT_ROOT / "github_pr_comment.py"
-
-    git = TempGit(tmpdir_factory.mktemp("tmp_git_dir"))
-    target_url = 
"https://ci.tlcpack.ai/job/tvm/job/PR-11594/3/display/redirect";
-    commit = {
-        "commit": {
-            "oid": "sha1234",
-            "statusCheckRollup": {
-                "contexts": {
-                    "nodes": [
-                        {
-                            "context": "tvm-ci/pr-head",
-                            "targetUrl": target_url,
-                        }
-                    ]
-                }
-            },
-        }
-    }
-    data = {
-        "[1] POST - https://api.github.com/graphql": {},
-        "[2] POST - https://api.github.com/graphql": {
-            "data": {
-                "repository": {
-                    "pullRequest": {
-                        "number": 1234,
-                        "comments": {
-                            "nodes": comments,
-                        },
-                        "author": {
-                            "login": pr_author,
-                        },
-                        "commits": {
-                            "nodes": [commit],
-                        },
-                    }
-                }
-            }
-        },
-    }
-    comments = {
-        "ccs": "the cc",
-        "docs": "the docs",
-        "skipped-tests": "the skipped tests",
-    }
-    proc = run_script(
-        [
-            comment_script,
-            "--dry-run",
-            "--test-data",
-            json.dumps(data),
-            "--test-comments",
-            json.dumps(comments),
-            "--pr",
-            "1234",
-        ],
-        stderr=subprocess.STDOUT,
-        cwd=git.cwd,
-    )
-    assert_in(expected, proc.stdout)
-
-
 @parameterize_named(
     dont_skip_main=dict(
         commands=[],
@@ -783,119 +161,6 @@ def test_skip_globs(tmpdir_factory, files, should_skip):
         assert proc.returncode == 1
 
 
-def all_time_keys(time):
-    return {
-        "updatedAt": time,
-        "lastEditedAt": time,
-        "createdAt": time,
-        "publishedAt": time,
-    }
-
-
-@parameterize_named(
-    draft=dict(
-        pull_request={
-            "isDraft": True,
-            "number": 2,
-        },
-        check="Checking 0 of 1 fetched",
-    ),
-    not_draft=dict(
-        pull_request={
-            "isDraft": False,
-            "number": 2,
-        },
-        check="Checking 0 of 1 fetched",
-    ),
-    week_old=dict(
-        pull_request={
-            "number": 123,
-            "url": "https://github.com/apache/tvm/pull/123";,
-            "body": "cc @someone",
-            "isDraft": False,
-            "author": {"login": "user"},
-            "reviews": {"nodes": []},
-            **all_time_keys("2022-01-18T17:54:19Z"),
-            "comments": {"nodes": []},
-        },
-        check="Pinging reviewers ['someone'] on 
https://github.com/apache/tvm/pull/123";,
-    ),
-    # Old comment, ping
-    old_comment=dict(
-        pull_request={
-            "number": 123,
-            "url": "https://github.com/apache/tvm/pull/123";,
-            "body": "cc @someone",
-            "isDraft": False,
-            "author": {"login": "user"},
-            "reviews": {"nodes": []},
-            **all_time_keys("2022-01-18T17:54:19Z"),
-            "comments": {
-                "nodes": [
-                    {
-                        **all_time_keys("2022-01-18T17:54:19Z"),
-                        "bodyText": "abc",
-                    },
-                ]
-            },
-        },
-        check="Pinging reviewers ['someone'] on 
https://github.com/apache/tvm/pull/123";,
-    ),
-    # New comment, don't ping
-    new_comment=dict(
-        pull_request={
-            "number": 123,
-            "url": "https://github.com/apache/tvm/pull/123";,
-            "body": "cc @someone",
-            "isDraft": False,
-            "author": {"login": "user"},
-            "reviews": {"nodes": []},
-            **all_time_keys("2022-01-18T17:54:19Z"),
-            "comments": {
-                "nodes": [
-                    {**all_time_keys("2022-01-27T17:54:19Z"), "bodyText": 
"abc"},
-                ]
-            },
-        },
-        check="Not pinging PR 123",
-    ),
-)
-def test_ping_reviewers(tmpdir_factory, pull_request, check):
-    """
-    Test that reviewers are messaged after a time period of inactivity
-    """
-    reviewers_script = GITHUB_SCRIPT_ROOT / "ping_reviewers.py"
-
-    git = TempGit(tmpdir_factory.mktemp("tmp_git_dir"))
-
-    data = {
-        "data": {
-            "repository": {
-                "pullRequests": {
-                    "nodes": [pull_request],
-                    "edges": [],
-                }
-            }
-        }
-    }
-    proc = run_script(
-        [
-            reviewers_script,
-            "--dry-run",
-            "--wait-time-minutes",
-            "1",
-            "--cutoff-pr-number",
-            "5",
-            "--pr-json",
-            json.dumps(data),
-            "--now",
-            "2022-01-26T17:54:19Z",
-        ],
-        cwd=git.cwd,
-    )
-    assert_in(check, proc.stdout)
-
-
 def assert_in(needle: str, haystack: str):
     """
     Check that 'needle' is in 'haystack'
@@ -904,255 +169,6 @@ def assert_in(needle: str, haystack: str):
         raise AssertionError(f"item not found:\n{needle}\nin:\n{haystack}")
 
 
[email protected]_if_wheel_test
-@parameterize_named(
-    no_cc=dict(
-        source_type="ISSUE",
-        data={
-            "title": "A title",
-            "number": 1234,
-            "user": {
-                "login": "person5",
-            },
-            "labels": [{"name": "abc"}],
-            "body": textwrap.dedent(
-                """
-            hello
-            """.strip()
-            ),
-        },
-        check="No one to cc, exiting",
-    ),
-    no_additional_cc=dict(
-        source_type="ISSUE",
-        data={
-            "title": "A title",
-            "number": 1234,
-            "user": {
-                "login": "person5",
-            },
-            "labels": [{"name": "abc"}],
-            "body": textwrap.dedent(
-                """
-            hello
-
-            cc @test
-            """.strip()
-            ),
-        },
-        check="No one to cc, exiting",
-    ),
-    cc_update=dict(
-        source_type="ISSUE",
-        data={
-            "title": "A title",
-            "number": 1234,
-            "user": {
-                "login": "person5",
-            },
-            "labels": [{"name": "something"}],
-            "body": textwrap.dedent(
-                """
-                hello
-
-                something"""
-            ),
-        },
-        check="would have updated issues/1234 with {'body': "
-        "'\\nhello\\n\\nsomething\\n\\ncc @person1 @person2 @person4'}",
-    ),
-    already_cced=dict(
-        source_type="ISSUE",
-        data={
-            "title": "A title",
-            "number": 1234,
-            "user": {
-                "login": "person5",
-            },
-            "labels": [{"name": "something"}],
-            "body": textwrap.dedent(
-                """
-                hello
-
-                cc @person1 @person2 @person4"""
-            ),
-        },
-        check="No one to cc, exiting",
-    ),
-    not_already_cced=dict(
-        source_type="ISSUE",
-        data={
-            "title": "[something] A title",
-            "number": 1234,
-            "user": {
-                "login": "person5",
-            },
-            "labels": [{"name": "something2"}],
-            "body": textwrap.dedent(
-                """
-                hello
-
-                something"""
-            ),
-        },
-        check="would have updated issues/1234 with {'body': "
-        "'\\nhello\\n\\nsomething\\n\\ncc @person1 @person2 @person4'}",
-    ),
-    no_new_ccs=dict(
-        source_type="ISSUE",
-        data={
-            "title": "[something] A title",
-            "number": 1234,
-            "user": {
-                "login": "person5",
-            },
-            "labels": [{"name": "something2"}],
-            "body": textwrap.dedent(
-                """
-                hello
-
-                cc @person1 @person2 @person4"""
-            ),
-        },
-        check="No one to cc, exiting",
-    ),
-    mismatching_tags=dict(
-        source_type="PR",
-        data={
-            "title": "[something] A title",
-            "number": 1234,
-            "draft": False,
-            "user": {
-                "login": "person5",
-            },
-            "labels": [{"name": "something2"}],
-            "body": textwrap.dedent(
-                """
-                hello
-
-                cc @person1 @person2 @person4"""
-            ),
-        },
-        check="No one to cc, exiting",
-    ),
-    draft_pr=dict(
-        source_type="PR",
-        data={
-            "title": "[something] A title",
-            "number": 1234,
-            "draft": True,
-            "user": {
-                "login": "person5",
-            },
-            "labels": [{"name": "something2"}],
-            "body": textwrap.dedent(
-                """
-                hello
-
-                cc @person1 @person2 @person4"""
-            ),
-        },
-        check="Terminating since 1234 is a draft",
-    ),
-    edit_inplace=dict(
-        source_type="ISSUE",
-        data={
-            "title": "[something] A title",
-            "number": 1234,
-            "user": {
-                "login": "person5",
-            },
-            "labels": [{"name": "something2"}],
-            "body": "`mold` and `lld` can be a much faster alternative to `ld` 
from gcc. "
-            "We should modify our CMakeLists.txt to detect and use these when 
possible. cc @person1"
-            "\n\ncc @person4",
-        },
-        check="would have updated issues/1234 with {'body': '`mold` and `lld` 
can be a much"
-        " faster alternative to `ld` from gcc. We should modify our 
CMakeLists.txt to "
-        "detect and use these when possible. cc @person1\\n\\ncc @person2 
@person4'}",
-    ),
-    edit_out_of_place=dict(
-        source_type="ISSUE",
-        data={
-            "title": "[something3] A title",
-            "number": 1234,
-            "user": {
-                "login": "person5",
-            },
-            "labels": [{"name": "something2"}],
-            "body": "@person2 @SOME1-ONE-",
-        },
-        check="Dry run, would have updated issues/1234 with"
-        " {'body': '@person2 @SOME1-ONE-\\n\\ncc @person1'}",
-    ),
-    atted_but_not_cced=dict(
-        source_type="ISSUE",
-        data={
-            "title": "[] A title",
-            "number": 1234,
-            "user": {
-                "login": "person5",
-            },
-            "labels": [],
-            "body": "@person2 @SOME1-ONE-",
-        },
-        check="No one to cc, exiting",
-    ),
-)
-def test_github_tag_teams(tmpdir_factory, source_type, data, check):
-    """
-    Check that individuals are tagged from team headers
-    """
-    tag_script = GITHUB_SCRIPT_ROOT / "github_tag_teams.py"
-
-    git = TempGit(tmpdir_factory.mktemp("tmp_git_dir"))
-
-    issue_body = """
-    some text
-    [temporary] opt-in: @person5
-
-    - something: @person1 @person2
-    - something3: @person1 @person2 @SOME1-ONE-
-    - something else @person1 @person2
-    - something else2: @person1 @person2
-    - something-else @person1 @person2
-    """
-    comment1 = """
-    another thing: @person3
-    another-thing @person3
-    """
-    comment2 = """
-    something @person4
-    @person5
-    """
-    teams = {
-        "data": {
-            "repository": {
-                "issue": {
-                    "body": issue_body,
-                    "comments": {"nodes": [{"body": comment1}, {"body": 
comment2}]},
-                }
-            }
-        }
-    }
-    env = {
-        source_type: json.dumps(data),
-    }
-    proc = run_script(
-        [
-            tag_script,
-            "--dry-run",
-            "--team-issue-json",
-            json.dumps(teams),
-        ],
-        stderr=subprocess.STDOUT,
-        cwd=git.cwd,
-        env=env,
-    )
-
-    assert_in(check, proc.stdout)
-
-
 @tvm.testing.skip_if_wheel_test
 @parameterize_named(
     same_tags=dict(
diff --git a/tests/scripts/release/gather_prs.py 
b/tests/scripts/release/gather_prs.py
index 16829c497a..f12fc318d0 100644
--- a/tests/scripts/release/gather_prs.py
+++ b/tests/scripts/release/gather_prs.py
@@ -28,10 +28,9 @@ from typing import Any
 
 REPO_ROOT = Path(__file__).resolve().parent.parent.parent.parent
 sys.path.append(str(REPO_ROOT / "ci" / "scripts" / "jenkins"))
-sys.path.append(str(REPO_ROOT / "ci" / "scripts" / "github"))
 
+from cmd_utils import tags_from_title
 from git_utils import GitHubRepo, git
-from github_tag_teams import tags_from_title
 
 GITHUB_TOKEN = os.environ["GITHUB_TOKEN"]
 
diff --git a/tests/scripts/request_hook/request_hook.py 
b/tests/scripts/request_hook/request_hook.py
index df15942789..48ac5e2a30 100644
--- a/tests/scripts/request_hook/request_hook.py
+++ b/tests/scripts/request_hook/request_hook.py
@@ -16,7 +16,6 @@
 # KIND, either express or implied.  See the License for the
 # specific language governing permissions and limitations
 # under the License.
-# ruff: noqa: E501
 
 import logging
 import urllib.request
@@ -24,25 +23,19 @@ import urllib.request
 LOGGER = None
 
 
-# To update this list, run 
https://github.com/apache/tvm/actions/workflows/upload_ci_resource.yml
-# with the URL to download and the SHA-256 hash of the file.
-BASE = "https://tvm-ci-resources.s3.us-west-2.amazonaws.com";
-URL_MAP = {
-    
"https://github.com/onnx/models/raw/131c99da401c757207a40189385410e238ed0934/vision/classification/mobilenet/model/mobilenetv2-7.onnx":
 
f"{BASE}/onnx/models/raw/131c99da401c757207a40189385410e238ed0934/vision/classification/mobilenet/model/mobilenetv2-7.onnx",
-}
+URL_MAP = {}
 
 
 class TvmRequestHook(urllib.request.Request):
     def __init__(self, url, *args, **kwargs):
         LOGGER.info(f"Caught access to {url}")
         url = url.strip()
-        if url not in URL_MAP and not url.startswith(BASE):
-            # Dis-allow any accesses that aren't going through S3
+        if url not in URL_MAP:
+            # Disallow network accesses without an explicitly maintained 
mirror.
             msg = (
                 f"Uncaught URL found in CI: {url}. "
-                "A committer must upload the relevant file to S3 via "
-                
"https://github.com/apache/tvm/actions/workflows/upload_ci_resource.yml "
-                "and add it to the mapping in 
tests/scripts/request_hook/request_hook.py"
+                "Avoid network access or arrange a stable project-managed 
mirror, "
+                "then add it to URL_MAP in 
tests/scripts/request_hook/request_hook.py."
             )
             raise RuntimeError(msg)
 

Reply via email to