#!/usr/bin/env python3 import datetime import json import os import re import urllib.error import urllib.parse import urllib.request from pathlib import Path from typing import NamedTuple API_ROOT = "https://api.github.com" REPOSITORY = "radixark/miles" REPOSITORY_ID = 1072725553 CLEAR_COMMAND = "clear-labels" RERUN_COMMAND = "rerun-failed-ci" RUN_FILE_COMMAND = "rerun-test" RUN_FILE_WORKFLOW = "run-ci-file.yml" RUN_FILE_WORKFLOW_REF = "main" CLEAR_EXACT_LABELS = frozenset({"nightly", "bypass-fastfail"}) RERUN_WORKFLOWS = ( ("pre-commit.yml", ".github/workflows/pre-commit.yml"), ("pr-test.yml", ".github/workflows/pr-test.yml"), ("pr-test-rocm.yml", ".github/workflows/pr-test-rocm.yml"), ) COMMAND_PATTERN = re.compile(r"/(run-ci-[A-Za-z0-9][A-Za-z0-9_.-]*|bypass-fastfail)") # "/run-ci" remains the label-family marker, while "/rerun-test" owns targeted # file runs; either family must parse as one exact command or fail loudly. COMMAND_MARKERS = ("/run-ci", "/rerun-test", "/bypass-fastfail", "/clear-labels", "/rerun-failed-ci") # Registered test files only: fixed roots, path segments that cannot form # ".." or an absolute path, and a test_*.py basename. The dispatched workflow # re-validates the same shape before the path reaches any shell command. TEST_FILE_PATTERN = re.compile( r"tests/(?:e2e|fast|fast-gpu|ci)(?:/[A-Za-z0-9_][A-Za-z0-9_.-]*)*/test_[A-Za-z0-9_][A-Za-z0-9_.-]*\.py" ) RUN_FILE_COMMAND_PATTERN = re.compile(rf"/{RUN_FILE_COMMAND} +({TEST_FILE_PATTERN.pattern})") # PR-body dependency pins, mirroring the exact patterns the pr-test.yml # resolve steps grep for; each match is forwarded as one dispatch input. PR_BODY_PINS = ( ( "ci_image_tag", re.compile(r"^ci-image-tag:\s+(\S+)", re.MULTILINE), re.compile(r"[A-Za-z0-9_][A-Za-z0-9_.-]{0,127}"), ), ( "ci_megatron_pr", re.compile(r"^ci-megatron-pr:\s+(\S+)", re.MULTILINE), re.compile(r"#[0-9]+|[A-Za-z0-9_][A-Za-z0-9_./-]*"), ), ( "ci_sglang_pr", re.compile(r"^ci-sglang-pr:\s+(\S+)", re.MULTILINE), re.compile(r"#[0-9]+|[A-Za-z0-9_][A-Za-z0-9_./-]*"), ), ) LABEL_PATTERN = re.compile(r"(?:run-ci-[A-Za-z0-9][A-Za-z0-9_.-]*|bypass-fastfail)") SHA_PATTERN = re.compile(r"[0-9a-f]{40}") WORKFLOW_RUN_URL_PATTERN = re.compile(rf"https://github\.com/{re.escape(REPOSITORY)}/actions/runs/[1-9][0-9]*") # Suite names come from the resolver, and reach a comment body verbatim. SUITE_PATTERN = re.compile(r"[a-z0-9][a-z0-9-]*") POLICY_PERMISSIONS = frozenset({"write", "admin"}) POLICY_GROUPS = frozenset({"add_label_access", "repo_write_access", "prior_contributor_access"}) # The comment payload's author_association enum, as GitHub defines it. Groups # may allow a subset; associations outside the enum fail loudly. AUTHOR_ASSOCIATIONS = frozenset( { "COLLABORATOR", "CONTRIBUTOR", "FIRST_TIMER", "FIRST_TIME_CONTRIBUTOR", "MANNEQUIN", "MEMBER", "NONE", "OWNER", } ) class CommentCommandError(Exception): pass class AddLabel(NamedTuple): label: str class ClearLabels(NamedTuple): pass class RerunFailedCI(NamedTuple): pass class RunTestFile(NamedTuple): test_file: str class CommandSpec(NamedTuple): policy_key: str capability: str handler: object resource_key: object resource_loader: object resource_getter: object allows_user_ids: bool audit_key: str audit_value: object success_reaction: str class CommandContext(NamedTuple): api: object pull_number: int actor_id: int actor_login: str author_association: str allowed_permissions: frozenset allowed_user_ids: frozenset allowed_author_associations: frozenset current_labels: frozenset head_sha: str head_repository_id: int head_owner_login: str head_ref: str body: str def _strict_object(pairs): result = {} for key, value in pairs: if key in result: raise CommentCommandError(f"duplicate JSON key: {key}") result[key] = value return result def _reject_json_constant(value): raise CommentCommandError(f"non-standard JSON number: {value}") def load_json(path): try: text = Path(path).read_text(encoding="utf-8") return json.loads( text, object_pairs_hook=_strict_object, parse_constant=_reject_json_constant, ) except (OSError, UnicodeDecodeError, json.JSONDecodeError) as error: raise CommentCommandError(f"cannot read JSON from {path}: {error}") from error def _validate_permissions(name, values): if not isinstance(values, list) or not values: raise CommentCommandError(f"{name} must be a non-empty array") if any(type(value) is not str or value not in POLICY_PERMISSIONS for value in values): raise CommentCommandError(f"{name} must contain only write or admin") if len(set(values)) != len(values): raise CommentCommandError(f"{name} contains duplicate permissions") return frozenset(values) def _validate_author_associations(name, values): if not isinstance(values, list) or not values: raise CommentCommandError(f"{name} must be a non-empty array") if any(type(value) is not str or value not in AUTHOR_ASSOCIATIONS for value in values): raise CommentCommandError(f"{name} must contain only GitHub author associations") if len(set(values)) != len(values): raise CommentCommandError(f"{name} contains duplicate author associations") return frozenset(values) def _validate_labels(name, values): if not isinstance(values, list) or not values: raise CommentCommandError(f"{name} must be a non-empty array") for label in values: if not isinstance(label, str) or LABEL_PATTERN.fullmatch(label) is None: raise CommentCommandError(f"invalid exact CI label: {label!r}") if len(set(values)) != len(values): raise CommentCommandError(f"{name} contains duplicate labels") return frozenset(values) def load_policy(path): raw = load_json(path) if not isinstance(raw, dict) or set(raw) != {"version", "groups", "commands"}: raise CommentCommandError("policy must contain only version, groups, and commands") if type(raw["version"]) is not int or raw["version"] != 4: raise CommentCommandError("policy version must be 4") raw_groups = raw["groups"] if not isinstance(raw_groups, dict) or set(raw_groups) != POLICY_GROUPS: raise CommentCommandError( "policy groups must contain only add_label_access, repo_write_access, and prior_contributor_access" ) groups = {} for name, raw_group in raw_groups.items(): expected_keys = {"repository_permissions"} if name in {"add_label_access", "prior_contributor_access"}: expected_keys.add("users") if name == "prior_contributor_access": expected_keys.add("author_associations") if not isinstance(raw_group, dict) or set(raw_group) != expected_keys: raise CommentCommandError(f"invalid fields for policy group {name}") groups[name] = { "repository_permissions": _validate_permissions( f"groups.{name}.repository_permissions", raw_group["repository_permissions"], ), "user_ids": ( frozenset(user["id"] for user in raw_group["users"]) if "users" in raw_group else frozenset() ), "author_associations": ( _validate_author_associations( f"groups.{name}.author_associations", raw_group["author_associations"], ) if "author_associations" in raw_group else frozenset() ), } specs_by_key = {spec.policy_key: spec for spec in COMMAND_REGISTRY.values()} if len(specs_by_key) != len(COMMAND_REGISTRY): raise CommentCommandError("command registry contains duplicate policy keys") raw_commands = raw["commands"] if not isinstance(raw_commands, dict) or set(raw_commands) != set(specs_by_key): raise CommentCommandError("policy commands do not match the static command registry") commands = {} for name, spec in specs_by_key.items(): raw_command = raw_commands[name] expected_keys = {"group"} if spec.resource_key is not None: expected_keys.add(spec.resource_key) if not isinstance(raw_command, dict) or set(raw_command) != expected_keys: raise CommentCommandError(f"invalid fields for policy command {name}") group_name = raw_command["group"] if not isinstance(group_name, str) or group_name not in groups: raise CommentCommandError(f"policy command {name} references an unknown group") if not spec.allows_user_ids and groups[group_name]["user_ids"]: raise CommentCommandError(f"policy command {name} cannot grant access by user ID") command = {"group": group_name} if spec.resource_key is not None: command[spec.resource_key] = spec.resource_loader( f"commands.{name}.{spec.resource_key}", raw_command[spec.resource_key], ) commands[name] = command return {"groups": groups, "commands": commands} def parse_command(body): if not isinstance(body, str): raise CommentCommandError("comment body must be a string") command = body.strip() if command == f"/{CLEAR_COMMAND}": return ClearLabels() if command == f"/{RERUN_COMMAND}": return RerunFailedCI() match = COMMAND_PATTERN.fullmatch(command) if match is not None: return AddLabel(match.group(1)) match = RUN_FILE_COMMAND_PATTERN.fullmatch(command) if match is not None: return RunTestFile(match.group(1)) if any(marker in command for marker in COMMAND_MARKERS): raise CommentCommandError( "comment must contain one exact /