94057c3d3e
PR Test (NPU) / check-changes (push) Has been cancelled
PR Test (NPU) / pr-gate (push) Has been cancelled
PR Test (NPU) / set-image-config (push) Has been cancelled
PR Test (NPU) / stage-b-test-1-npu-a2 (0) (push) Has been cancelled
PR Test (NPU) / stage-b-test-1-npu-a2 (1) (push) Has been cancelled
PR Test (NPU) / stage-b-test-2-npu-a2 (0) (push) Has been cancelled
PR Test (NPU) / stage-b-test-2-npu-a2 (1) (push) Has been cancelled
PR Test (NPU) / stage-b-test-4-npu-a3 (push) Has been cancelled
PR Test (NPU) / stage-b-test-16-npu-a3 (push) Has been cancelled
PR Test (NPU) / multimodal-gen-test-1-npu-a3 (push) Has been cancelled
PR Test (NPU) / multimodal-gen-test-2-npu-a3 (push) Has been cancelled
PR Test (Arm64) / pr-gate (push) Has been cancelled
PR Test (Arm64) / check-changes (push) Has been cancelled
PR Test (Arm64) / build-test (push) Has been cancelled
PR Test (sgl-router) / gate (push) Has been cancelled
PR Test (sgl-router) / tier-1 — lint (push) Has been cancelled
PR Test (sgl-router) / tier-2 — build + test (push) Has been cancelled
PR Test (sgl-router) / tier-3 — docker (placeholder) (push) Has been cancelled
PR Test (sgl-router) / tier-3 — k8s integration (push) Has been cancelled
PR Test (sgl-router) / tier-3 — e2e (push) Has been cancelled
PR Test (sgl-router) / finish (push) Has been cancelled
PR Test (NPU) / single-node-poc (map[name:qwen3_6_27b_w8a8_1p_in64k_out1k_50ms runner:linux-aarch64-a3-2 test_case:test/registered/ascend/performance/qwen3_6_27b/test_npu_qwen3_6_27b_w8a8_1p_in64k_out1k_50ms.py test_type:perf]) (push) Has been cancelled
PR Test (NPU) / pr-test-npu-finish (push) Has been cancelled
PR Test (Xeon) / pr-gate (push) Has been cancelled
PR Test (Xeon) / check-changes (push) Has been cancelled
PR Test (Xeon) / build-test (, xeon-gnr, base-b-test-cpu) (push) Has been cancelled
PR Test (XPU) / check-changes (push) Has been cancelled
PR Test (XPU) / pr-gate (push) Has been cancelled
PR Test (XPU) / stage-a-test-1-gpu-xpu (push) Has been cancelled
PR Test (XPU) / wait-for-stage-a (push) Has been cancelled
PR Test (XPU) / stage-b-test-1-gpu-xpu (push) Has been cancelled
PR Test (XPU) / finish (push) Has been cancelled
CI Model Inventory / build-inventory (push) Has been cancelled
Lint / lint (push) Has been cancelled
PR Benchmark (SMG Components) / Benchmark Compilation Check (push) Has been cancelled
PR Benchmark (SMG Components) / Benchmark - Manual Policy (push) Has been cancelled
PR Benchmark (SMG Components) / Benchmark - Request Processing (push) Has been cancelled
PR Benchmark (SMG Components) / Benchmark Summary (push) Has been cancelled
PR Test (SMG) / build-wheel (push) Has been cancelled
Release SGLang Model Gateway to PyPI / build on windows (x86_64 - auto) (push) Has been cancelled
Release SGLang Model Gateway to PyPI / build on macos (x86_64 - auto) (push) Has been cancelled
PR Test (SMG) / python-unit-tests (push) Has been cancelled
PR Test (SMG) / unit-tests (push) Has been cancelled
PR Test (SMG) / benchmarks (push) Has been cancelled
PR Test (SMG) / chat-completions (push) Has been cancelled
PR Test (SMG) / chat-completions-4gpu (push) Has been cancelled
PR Test (SMG) / e2e (push) Has been cancelled
PR Test (SMG) / docker-build-test (push) Has been cancelled
PR Test (SMG) / k8s-integration (push) Has been cancelled
PR Test (SMG) / finish (push) Has been cancelled
PR Test (SMG) / summarize-benchmarks (push) Has been cancelled
Release SGLang Model Gateway Docker Image / publish (push) Has been cancelled
Release SGLang Model Gateway to PyPI / build on macos (aarch64 - auto) (push) Has been cancelled
Release SGLang Model Gateway to PyPI / build on linux (aarch64 - auto) (push) Has been cancelled
Release SGLang Model Gateway to PyPI / build on linux (x86_64 - auto) (push) Has been cancelled
Release SGLang Model Gateway to PyPI / build on linux (aarch64 - musllinux_1_1) (push) Has been cancelled
Release SGLang Model Gateway to PyPI / build on linux (x86_64 - musllinux_1_1) (push) Has been cancelled
Release SGLang Model Gateway to PyPI / Build SDist (push) Has been cancelled
Release SGLang Model Gateway to PyPI / Upload to PyPI (push) Has been cancelled
Release SGLang Kernels / build-cu129-matrix (aarch64, 12.9, 3.10, arm-kernel-build-node) (push) Has been cancelled
Release SGLang Kernels / build-cu129-matrix (x86_64, 12.9, 3.10, x64-kernel-build-node) (push) Has been cancelled
Release SGLang Kernels / release-cu129 (push) Has been cancelled
Release SGLang Kernels / build-cu130-matrix (aarch64, 13.0, 3.10, arm-kernel-build-node) (push) Has been cancelled
Release SGLang Kernels / build-cu130-matrix (x86_64, 13.0, 3.10, x64-kernel-build-node) (push) Has been cancelled
Release SGLang Kernels / release-cu130 (push) Has been cancelled
Release SGLang Kernels / build-rocm-matrix (3.10, 700) (push) Has been cancelled
Release SGLang Kernels / build-rocm-matrix (3.10, 720) (push) Has been cancelled
Release SGLang Kernels / release-rocm700 (push) Has been cancelled
Release SGLang Kernels / release-rocm720 (push) Has been cancelled
Release SGLang Kernels / build-musa43 (43, 3.10) (push) Has been cancelled
Release SGLang Kernels / release-musa43 (push) Has been cancelled
140 lines
4.5 KiB
Python
Executable File
140 lines
4.5 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
"""
|
|
Update the per-batch status icon in a /rerun-test reply comment.
|
|
|
|
State machine for one batch line (anchored by a unique HTML-comment marker
|
|
written by the slash-command handler):
|
|
|
|
dispatched ⏳ ... <!--rrt:i--> (handler, on dispatch)
|
|
running 🔄 ... <!--rrt:i--> (start-beacon, on the test runner)
|
|
done ✅/❌ ... <!--rrt:i:done--> (finalizer, after the test job)
|
|
|
|
The leading 🚀 on the line is the visual anchor that this came from a
|
|
slash-command trigger and is preserved across all states.
|
|
|
|
Idempotency:
|
|
- :done marker present -> no-op (covers reruns and start-after-finalizer race)
|
|
- running and line already has 🔄 -> no-op
|
|
- marker not found after retries -> warn and exit 0 so a single placeholder
|
|
glitch does not amplify into N noisy job failures.
|
|
|
|
Concurrent updates against the same comment from different batches can race
|
|
on the body (read-modify-write of the same field). The finalizer
|
|
serializes itself via job-level concurrency; the beacon does not, because
|
|
splitting it into its own job would re-queue the GPU runner. Worst case
|
|
for the beacon race is one missed 🔄 flicker - comment stays consistent.
|
|
"""
|
|
|
|
import argparse
|
|
import json
|
|
import os
|
|
import sys
|
|
import time
|
|
import urllib.error
|
|
import urllib.request
|
|
|
|
RETRY_DELAYS_SEC = [0, 5, 15]
|
|
|
|
STATUS_ICONS = {
|
|
"running": "🔄",
|
|
"success": "✅",
|
|
"failure": "❌",
|
|
}
|
|
|
|
TERMINAL_STATUSES = {"success", "failure"}
|
|
|
|
|
|
def gh_request(method, url, token, body=None):
|
|
headers = {
|
|
"Authorization": f"Bearer {token}",
|
|
"Accept": "application/vnd.github+json",
|
|
"X-GitHub-Api-Version": "2022-11-28",
|
|
}
|
|
data = json.dumps(body).encode() if body is not None else None
|
|
req = urllib.request.Request(url, data=data, method=method, headers=headers)
|
|
if data is not None:
|
|
req.add_header("Content-Type", "application/json")
|
|
try:
|
|
with urllib.request.urlopen(req, timeout=15) as resp:
|
|
return resp.status, resp.read().decode()
|
|
except urllib.error.HTTPError as e:
|
|
return e.code, e.read().decode()
|
|
|
|
|
|
def main():
|
|
ap = argparse.ArgumentParser()
|
|
ap.add_argument("--comment-id", required=True, type=int)
|
|
ap.add_argument(
|
|
"--marker", required=True, help="Per-batch marker, e.g. <!--rrt:0-->"
|
|
)
|
|
ap.add_argument(
|
|
"--status",
|
|
required=True,
|
|
choices=list(STATUS_ICONS.keys()),
|
|
)
|
|
ap.add_argument("--repo", required=True, help="owner/repo")
|
|
args = ap.parse_args()
|
|
|
|
token = os.environ.get("GITHUB_TOKEN")
|
|
if not token:
|
|
print("ERROR: GITHUB_TOKEN not set")
|
|
return 1
|
|
|
|
icon = STATUS_ICONS[args.status]
|
|
is_terminal = args.status in TERMINAL_STATUSES
|
|
done_marker = args.marker.replace("-->", ":done-->")
|
|
|
|
url = f"https://api.github.com/repos/{args.repo}/issues/comments/{args.comment_id}"
|
|
|
|
body = None
|
|
for attempt, delay in enumerate(RETRY_DELAYS_SEC):
|
|
if delay:
|
|
time.sleep(delay)
|
|
status, text = gh_request("GET", url, token)
|
|
if status != 200:
|
|
print(f"GET failed: {status} {text}")
|
|
return 1
|
|
body = json.loads(text).get("body") or ""
|
|
if done_marker in body:
|
|
print(f"Marker {done_marker} already present; nothing to do.")
|
|
return 0
|
|
if args.marker in body:
|
|
break
|
|
print(
|
|
f"Marker {args.marker} not found "
|
|
f"(attempt {attempt + 1}/{len(RETRY_DELAYS_SEC)}); will retry."
|
|
)
|
|
else:
|
|
print(
|
|
f"WARNING: marker {args.marker} not found after "
|
|
f"{len(RETRY_DELAYS_SEC)} attempts; skipping. "
|
|
f"The handler may have failed to edit the placeholder comment."
|
|
)
|
|
return 0
|
|
|
|
new_lines = []
|
|
for line in body.splitlines(keepends=True):
|
|
if args.marker in line:
|
|
if not is_terminal and icon in line:
|
|
print(f"Line already has {icon}; nothing to do.")
|
|
return 0
|
|
for prior in ("⏳", "🔄"):
|
|
if prior in line:
|
|
line = line.replace(prior, icon, 1)
|
|
break
|
|
if is_terminal:
|
|
line = line.replace(args.marker, done_marker)
|
|
new_lines.append(line)
|
|
|
|
new_body = "".join(new_lines)
|
|
status, text = gh_request("PATCH", url, token, body={"body": new_body})
|
|
if status != 200:
|
|
print(f"PATCH failed: {status} {text}")
|
|
return 1
|
|
print(f"Updated comment {args.comment_id}: {args.marker} -> {icon}")
|
|
return 0
|
|
|
|
|
|
if __name__ == "__main__":
|
|
sys.exit(main())
|