[CI] Answer unrecognized slash commands instead of skipping silently (#38736)

This commit is contained in:
Alison Shao
2026-09-09 18:01:18 -07:00
committed by GitHub
parent 92d831d3d7
commit a7e00b7576
3 changed files with 78 additions and 2 deletions
+8 -1
View File
@@ -14,6 +14,10 @@ jobs:
slash_command: slash_command:
# Only run if it is a PR and the comment contains a recognized command # Only run if it is a PR and the comment contains a recognized command
# Use contains() since startsWith() can't handle leading whitespace/newlines # Use contains() since startsWith() can't handle leading whitespace/newlines
#
# The trailing startsWith() namespace clauses admit *unrecognized* commands
# so the script can answer them; they are startsWith() because
# contains('/run-') would fire on any comment quoting `scripts/run-tests.sh`.
if: > if: >
github.event.issue.pull_request && github.event.issue.pull_request &&
(contains(github.event.comment.body, '/tag-run-ci-label') || (contains(github.event.comment.body, '/tag-run-ci-label') ||
@@ -24,7 +28,10 @@ jobs:
contains(github.event.comment.body, '/rerun-full-ci') || contains(github.event.comment.body, '/rerun-full-ci') ||
contains(github.event.comment.body, '/rerun-extra-ci') || contains(github.event.comment.body, '/rerun-extra-ci') ||
contains(github.event.comment.body, '/rerun-group') || contains(github.event.comment.body, '/rerun-group') ||
contains(github.event.comment.body, '/rerun-test')) contains(github.event.comment.body, '/rerun-test') ||
startsWith(github.event.comment.body, '/tag-') ||
startsWith(github.event.comment.body, '/rerun-') ||
startsWith(github.event.comment.body, '/run-'))
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
@@ -141,6 +141,8 @@ Selective reruns do not build or install a PR-local `sglang-kernel` wheel. If a
If you have permission, the [Slash Command Handler](https://github.com/sgl-project/sglang/actions/workflows/slash-command-handler.yml) will run your command and react with a 👍 to your comment. It may take up to a few minutes for the reaction to appear. Here’s a usage [example](https://github.com/sgl-project/sglang/pull/14253#issuecomment-3599509302). If you have permission, the [Slash Command Handler](https://github.com/sgl-project/sglang/actions/workflows/slash-command-handler.yml) will run your command and react with a 👍 to your comment. It may take up to a few minutes for the reaction to appear. Here’s a usage [example](https://github.com/sgl-project/sglang/pull/14253#issuecomment-3599509302).
If a command isn't recognized, the handler reacts 😕 instead, and replies with the closest matching command when there is one. A comment with no reaction at all means the handler never saw it — check the command is spelled as listed above.
To avoid spamming a PR with too many `/rerun-failed-ci` comments, you can also trigger the command by editing an existing comment and adding any suffix (e.g., `/rerun-failed-ci try again`). To avoid spamming a PR with too many `/rerun-failed-ci` comments, you can also trigger the command by editing an existing comment and adding any suffix (e.g., `/rerun-failed-ci try again`).
If you don’t have permission and you’re not the PR author, please ask maintainers to trigger CI for you. If you don’t have permission and you’re not the PR author, please ask maintainers to trigger CI for you.
+68 -1
View File
@@ -1,3 +1,4 @@
import difflib
import glob import glob
import json import json
import os import os
@@ -1615,6 +1616,72 @@ def handle_rerun_group(
) )
# Namespaces this handler owns. Anything else reaching the script is a comment
# that merely quoted a path, and is left alone.
OWNED_COMMAND_PREFIXES = ("/tag-", "/rerun-", "/run-")
# Suggestion targets. Documented spellings only, so a typo is pointed at the
# canonical name rather than at an undocumented alias.
KNOWN_COMMANDS = (
"/tag-run-ci-label",
"/tag-and-rerun-ci",
"/rerun-failed-ci",
"/rerun-group",
"/rerun-test",
"/run-full-ci",
"/run-extra-ci",
)
# Removed commands, kept because they were documented long enough that muscle
# memory still sends them and difflib would suggest something unrelated.
RETIRED_COMMANDS = {
"/rerun-stage": (
"`/rerun-stage` was removed. Use `/rerun-test <test-spec>` for specific "
"tests, or `/rerun-failed-ci` for everything that didn't pass."
),
}
def handle_unknown_command(pr, comment, first_line):
"""
Answer a comment addressed to this handler that matched no command.
A silent skip is indistinguishable from the bot being down, so always react;
comment only when there is something concrete to say, to avoid turning every
stray `/run-...` into PR noise.
"""
tokens = first_line.split()
command = tokens[0] if tokens else first_line
if not command.startswith(OWNED_COMMAND_PREFIXES):
print(f"Not addressed to this handler: {first_line[:60]!r}")
return
print(f"Unrecognized command: {command}")
try:
comment.create_reaction("confused")
except Exception as e:
print(f"Failed to add reaction: {e}")
hint = RETIRED_COMMANDS.get(command)
if hint is None:
close = difflib.get_close_matches(command, KNOWN_COMMANDS, n=1, cutoff=0.6)
hint = f"Did you mean `{close[0]}`?" if close else None
if hint is None:
print("No close match; reaction only.")
return
try:
pr.create_issue_comment(
f"⛔ `{command}` isn't a recognized CI command. {hint}\n\n"
"See the [command reference]"
"(https://docs.sglang.io/docs/developer_guide/contribution_guide"
"#how-to-trigger-ci-tests)."
)
except Exception as e:
print(f"Failed to post hint comment: {e}")
def main(): def main():
# 1. Load Environment Variables # 1. Load Environment Variables
token = get_env_var("GITHUB_TOKEN") token = get_env_var("GITHUB_TOKEN")
@@ -1740,7 +1807,7 @@ def main():
) )
else: else:
print(f"Unknown or ignored command: {first_line}") handle_unknown_command(pr, comment, first_line)
if __name__ == "__main__": if __name__ == "__main__":