diff --git a/.github/CI_PERMISSIONS.json b/.github/CI_PERMISSIONS.json index 367a49260..80cc0fedb 100644 --- a/.github/CI_PERMISSIONS.json +++ b/.github/CI_PERMISSIONS.json @@ -258,6 +258,13 @@ "reason": "custom override", "can_rerun_stage": true }, + "YAMY1234": { + "can_tag_run_ci_label": true, + "can_rerun_failed_ci": true, + "cooldown_interval_minutes": 0, + "reason": "custom override", + "can_rerun_stage": true + }, "Ying1123": { "can_tag_run_ci_label": true, "can_rerun_failed_ci": true, @@ -930,13 +937,6 @@ "reason": "custom override", "can_rerun_stage": true }, - "YAMY1234": { - "can_tag_run_ci_label": true, - "can_rerun_failed_ci": true, - "cooldown_interval_minutes": 0, - "reason": "custom override", - "can_rerun_stage": true - }, "yanbing-j": { "can_tag_run_ci_label": true, "can_rerun_failed_ci": true, diff --git a/.github/update_ci_permission.py b/.github/update_ci_permission.py index 2ed846676..bbf695149 100644 --- a/.github/update_ci_permission.py +++ b/.github/update_ci_permission.py @@ -38,33 +38,40 @@ Permissions are assigned according to the following rules: Usage: export GH_TOKEN="your_github_token" python3 update_ci_permission.py + + # Sort-only mode (no network calls, no GH_TOKEN required) + python3 update_ci_permission.py --sort-only """ +import argparse import json import os from collections import Counter from datetime import datetime, timedelta, timezone -import requests +try: + import requests +except ImportError: + requests = None # Only needed for non-sort-only runs # Configuration REPO_OWNER = "sgl-project" REPO_NAME = "sglang" -FILE_NAME = "CI_PERMISSIONS.json" -GH_TOKEN = os.getenv("GH_TOKEN") - -if not GH_TOKEN: - raise ValueError("Error: GH_TOKEN environment variable is not set.") - -HEADERS = { - "Authorization": f"Bearer {GH_TOKEN}", - "Accept": "application/vnd.github+json", - "X-GitHub-Api-Version": "2022-11-28", -} +FILE_NAME = os.path.join(os.path.dirname(__file__), "CI_PERMISSIONS.json") +HEADERS = {} def github_api_get(endpoint, params=None): """Helper to make paginated GitHub API requests.""" + if requests is None: + raise RuntimeError( + "The requests package is required. Install it or use --sort-only." + ) + if not HEADERS: + raise RuntimeError( + "GitHub headers not initialized. Set GH_TOKEN or use --sort-only." + ) + results = [] url = f"https://api.github.com/repos/{REPO_OWNER}/{REPO_NAME}/{endpoint}" @@ -139,7 +146,46 @@ def load_existing_permissions(): return {} +def sort_permissions_file(): + """Sort the existing CI permissions file alphabetically and exit.""" + if not os.path.exists(FILE_NAME): + print(f"{FILE_NAME} not found. Nothing to sort.") + return + + old_permissions = load_existing_permissions() + sorted_permissions = dict(sorted(old_permissions.items())) + + with open(FILE_NAME, "w") as f: + json.dump(sorted_permissions, f, indent=4) + f.write("\n") + + print(f"Sorted {FILE_NAME}. Total users: {len(sorted_permissions)}") + + def main(): + parser = argparse.ArgumentParser(description="Update or sort CI permissions.") + parser.add_argument( + "--sort-only", + action="store_true", + help="Only sort CI_PERMISSIONS.json alphabetically without fetching data.", + ) + args = parser.parse_args() + + if args.sort_only: + sort_permissions_file() + return + + gh_token = os.getenv("GH_TOKEN") + if not gh_token: + raise ValueError("Error: GH_TOKEN environment variable is not set.") + + global HEADERS + HEADERS = { + "Authorization": f"Bearer {gh_token}", + "Accept": "application/vnd.github+json", + "X-GitHub-Api-Version": "2022-11-28", + } + # Gather Data try: write_access_users = get_write_access_users() diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 2ed015eb7..447eec5d6 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -75,3 +75,11 @@ repos: args: - '--keep-output' - '--extra-keys=metadata.kernelspec metadata.language_info.version' + - repo: local + hooks: + - id: sort-ci-permissions + name: sort CI_PERMISSIONS.json + entry: python3 .github/update_ci_permission.py --sort-only + language: system + files: ^\.github/CI_PERMISSIONS\.json$ + pass_filenames: false