diff --git a/.github/CI_PERMISSIONS.json b/.github/CI_PERMISSIONS.json new file mode 100644 index 000000000000..da6b01298653 --- /dev/null +++ b/.github/CI_PERMISSIONS.json @@ -0,0 +1,776 @@ +{ + "Alcanderian": { + "can_tag_run_ci_label": true, + "can_rerun_failed_ci": true, + "cooldown_interval_minutes": 0, + "reason": "custom override" + }, + "AniZpZ": { + "can_tag_run_ci_label": true, + "can_rerun_failed_ci": true, + "cooldown_interval_minutes": 0, + "reason": "custom override" + }, + "BBuf": { + "can_tag_run_ci_label": true, + "can_rerun_failed_ci": true, + "cooldown_interval_minutes": 0, + "reason": "top contributor" + }, + "BHZ-BER": { + "can_tag_run_ci_label": true, + "can_rerun_failed_ci": true, + "cooldown_interval_minutes": 60, + "reason": "custom override" + }, + "ByronHsu": { + "can_tag_run_ci_label": true, + "can_rerun_failed_ci": true, + "cooldown_interval_minutes": 0, + "reason": "custom override" + }, + "CatherineSue": { + "can_tag_run_ci_label": true, + "can_rerun_failed_ci": true, + "cooldown_interval_minutes": 0, + "reason": "top contributor" + }, + "DarkSharpness": { + "can_tag_run_ci_label": true, + "can_rerun_failed_ci": true, + "cooldown_interval_minutes": 0, + "reason": "custom override" + }, + "DiweiSun": { + "can_tag_run_ci_label": true, + "can_rerun_failed_ci": true, + "cooldown_interval_minutes": 0, + "reason": "custom override" + }, + "Edwardf0t1": { + "can_tag_run_ci_label": true, + "can_rerun_failed_ci": true, + "cooldown_interval_minutes": 0, + "reason": "custom override" + }, + "FlamingoPg": { + "can_tag_run_ci_label": true, + "can_rerun_failed_ci": true, + "cooldown_interval_minutes": 0, + "reason": "top contributor" + }, + "FrankLeeeee": { + "can_tag_run_ci_label": true, + "can_rerun_failed_ci": true, + "cooldown_interval_minutes": 0, + "reason": "custom override" + }, + "Fridge003": { + "can_tag_run_ci_label": true, + "can_rerun_failed_ci": true, + "cooldown_interval_minutes": 0, + "reason": "top contributor" + }, + "HaiShaw": { + "can_tag_run_ci_label": true, + "can_rerun_failed_ci": true, + "cooldown_interval_minutes": 0, + "reason": "custom override" + }, + "HanHan009527": { + "can_tag_run_ci_label": true, + "can_rerun_failed_ci": true, + "cooldown_interval_minutes": 0, + "reason": "custom override" + }, + "HandH1998": { + "can_tag_run_ci_label": true, + "can_rerun_failed_ci": true, + "cooldown_interval_minutes": 60, + "reason": "custom override" + }, + "Hanrui-Wang": { + "can_tag_run_ci_label": true, + "can_rerun_failed_ci": true, + "cooldown_interval_minutes": 60, + "reason": "custom override" + }, + "HydraQYH": { + "can_tag_run_ci_label": true, + "can_rerun_failed_ci": true, + "cooldown_interval_minutes": 0, + "reason": "custom override" + }, + "JeremieMelo": { + "can_tag_run_ci_label": true, + "can_rerun_failed_ci": true, + "cooldown_interval_minutes": 0, + "reason": "custom override" + }, + "Johnsonms": { + "can_tag_run_ci_label": true, + "can_rerun_failed_ci": true, + "cooldown_interval_minutes": 0, + "reason": "top contributor" + }, + "JustinTong0323": { + "can_tag_run_ci_label": true, + "can_rerun_failed_ci": true, + "cooldown_interval_minutes": 0, + "reason": "top contributor" + }, + "Kangyan-Zhou": { + "can_tag_run_ci_label": true, + "can_rerun_failed_ci": true, + "cooldown_interval_minutes": 0, + "reason": "top contributor" + }, + "LorrinWWW": { + "can_tag_run_ci_label": true, + "can_rerun_failed_ci": true, + "cooldown_interval_minutes": 60, + "reason": "custom override" + }, + "Oasis-Git": { + "can_tag_run_ci_label": true, + "can_rerun_failed_ci": true, + "cooldown_interval_minutes": 60, + "reason": "custom override" + }, + "Qiaolin-Yu": { + "can_tag_run_ci_label": true, + "can_rerun_failed_ci": true, + "cooldown_interval_minutes": 0, + "reason": "top contributor" + }, + "Qihang-Zhang": { + "can_tag_run_ci_label": true, + "can_rerun_failed_ci": true, + "cooldown_interval_minutes": 60, + "reason": "custom override" + }, + "ShangmingCai": { + "can_tag_run_ci_label": true, + "can_rerun_failed_ci": true, + "cooldown_interval_minutes": 0, + "reason": "top contributor" + }, + "SimonCqk": { + "can_tag_run_ci_label": true, + "can_rerun_failed_ci": true, + "cooldown_interval_minutes": 60, + "reason": "custom override" + }, + "TianQiLin666666": { + "can_tag_run_ci_label": true, + "can_rerun_failed_ci": true, + "cooldown_interval_minutes": 60, + "reason": "custom override" + }, + "Ubospica": { + "can_tag_run_ci_label": true, + "can_rerun_failed_ci": true, + "cooldown_interval_minutes": 60, + "reason": "custom override" + }, + "XiaotongJiang": { + "can_tag_run_ci_label": true, + "can_rerun_failed_ci": true, + "cooldown_interval_minutes": 60, + "reason": "custom override" + }, + "XucSh": { + "can_tag_run_ci_label": true, + "can_rerun_failed_ci": true, + "cooldown_interval_minutes": 0, + "reason": "custom override" + }, + "Ying1123": { + "can_tag_run_ci_label": true, + "can_rerun_failed_ci": true, + "cooldown_interval_minutes": 0, + "reason": "custom override" + }, + "ZailiWang": { + "can_tag_run_ci_label": true, + "can_rerun_failed_ci": true, + "cooldown_interval_minutes": 0, + "reason": "top contributor" + }, + "ZhengdQin": { + "can_tag_run_ci_label": true, + "can_rerun_failed_ci": true, + "cooldown_interval_minutes": 0, + "reason": "custom override" + }, + "acelyc111": { + "can_tag_run_ci_label": true, + "can_rerun_failed_ci": true, + "cooldown_interval_minutes": 0, + "reason": "top contributor" + }, + "adarshxs": { + "can_tag_run_ci_label": true, + "can_rerun_failed_ci": true, + "cooldown_interval_minutes": 0, + "reason": "custom override" + }, + "airMeng": { + "can_tag_run_ci_label": true, + "can_rerun_failed_ci": true, + "cooldown_interval_minutes": 60, + "reason": "custom override" + }, + "alisonshao": { + "can_tag_run_ci_label": true, + "can_rerun_failed_ci": true, + "cooldown_interval_minutes": 0, + "reason": "top contributor" + }, + "ayrnb": { + "can_tag_run_ci_label": true, + "can_rerun_failed_ci": true, + "cooldown_interval_minutes": 60, + "reason": "custom override" + }, + "azhurkevich": { + "can_tag_run_ci_label": true, + "can_rerun_failed_ci": true, + "cooldown_interval_minutes": 60, + "reason": "custom override" + }, + "b8zhong": { + "can_tag_run_ci_label": true, + "can_rerun_failed_ci": true, + "cooldown_interval_minutes": 0, + "reason": "top contributor" + }, + "byjiang1996": { + "can_tag_run_ci_label": true, + "can_rerun_failed_ci": true, + "cooldown_interval_minutes": 0, + "reason": "top contributor" + }, + "cctry": { + "can_tag_run_ci_label": true, + "can_rerun_failed_ci": true, + "cooldown_interval_minutes": 0, + "reason": "custom override" + }, + "ch-wan": { + "can_tag_run_ci_label": true, + "can_rerun_failed_ci": true, + "cooldown_interval_minutes": 0, + "reason": "top contributor" + }, + "cicirori": { + "can_tag_run_ci_label": true, + "can_rerun_failed_ci": true, + "cooldown_interval_minutes": 0, + "reason": "top contributor" + }, + "dougyster": { + "can_tag_run_ci_label": true, + "can_rerun_failed_ci": true, + "cooldown_interval_minutes": 0, + "reason": "custom override" + }, + "elfiegg": { + "can_tag_run_ci_label": true, + "can_rerun_failed_ci": true, + "cooldown_interval_minutes": 60, + "reason": "custom override" + }, + "fy1214": { + "can_tag_run_ci_label": true, + "can_rerun_failed_ci": true, + "cooldown_interval_minutes": 60, + "reason": "custom override" + }, + "fzyzcjy": { + "can_tag_run_ci_label": true, + "can_rerun_failed_ci": true, + "cooldown_interval_minutes": 0, + "reason": "top contributor" + }, + "gongwei-130": { + "can_tag_run_ci_label": true, + "can_rerun_failed_ci": true, + "cooldown_interval_minutes": 0, + "reason": "top contributor" + }, + "gongy": { + "can_tag_run_ci_label": true, + "can_rerun_failed_ci": true, + "cooldown_interval_minutes": 60, + "reason": "custom override" + }, + "guoyuhong": { + "can_tag_run_ci_label": true, + "can_rerun_failed_ci": true, + "cooldown_interval_minutes": 60, + "reason": "custom override" + }, + "hanming-lu": { + "can_tag_run_ci_label": true, + "can_rerun_failed_ci": true, + "cooldown_interval_minutes": 0, + "reason": "custom override" + }, + "harrisonlimh": { + "can_tag_run_ci_label": true, + "can_rerun_failed_ci": true, + "cooldown_interval_minutes": 60, + "reason": "custom override" + }, + "hebiao064": { + "can_tag_run_ci_label": true, + "can_rerun_failed_ci": true, + "cooldown_interval_minutes": 0, + "reason": "top contributor" + }, + "hlu1": { + "can_tag_run_ci_label": true, + "can_rerun_failed_ci": true, + "cooldown_interval_minutes": 0, + "reason": "top contributor" + }, + "hnyls2002": { + "can_tag_run_ci_label": true, + "can_rerun_failed_ci": true, + "cooldown_interval_minutes": 0, + "reason": "top contributor" + }, + "huangtingwei9988": { + "can_tag_run_ci_label": true, + "can_rerun_failed_ci": true, + "cooldown_interval_minutes": 0, + "reason": "top contributor" + }, + "hubertlu-tw": { + "can_tag_run_ci_label": true, + "can_rerun_failed_ci": true, + "cooldown_interval_minutes": 0, + "reason": "top contributor" + }, + "hyhieu": { + "can_tag_run_ci_label": true, + "can_rerun_failed_ci": true, + "cooldown_interval_minutes": 60, + "reason": "custom override" + }, + "hzh0425": { + "can_tag_run_ci_label": true, + "can_rerun_failed_ci": true, + "cooldown_interval_minutes": 0, + "reason": "top contributor" + }, + "iforgetmyname": { + "can_tag_run_ci_label": true, + "can_rerun_failed_ci": true, + "cooldown_interval_minutes": 0, + "reason": "top contributor" + }, + "ishandhanani": { + "can_tag_run_ci_label": true, + "can_rerun_failed_ci": true, + "cooldown_interval_minutes": 0, + "reason": "top contributor" + }, + "ispobock": { + "can_tag_run_ci_label": true, + "can_rerun_failed_ci": true, + "cooldown_interval_minutes": 0, + "reason": "top contributor" + }, + "jason-fxz": { + "can_tag_run_ci_label": true, + "can_rerun_failed_ci": true, + "cooldown_interval_minutes": 60, + "reason": "custom override" + }, + "jhinpan": { + "can_tag_run_ci_label": true, + "can_rerun_failed_ci": true, + "cooldown_interval_minutes": 60, + "reason": "custom override" + }, + "jinleic": { + "can_tag_run_ci_label": true, + "can_rerun_failed_ci": true, + "cooldown_interval_minutes": 60, + "reason": "custom override" + }, + "jinmingyi1998": { + "can_tag_run_ci_label": true, + "can_rerun_failed_ci": true, + "cooldown_interval_minutes": 0, + "reason": "top contributor" + }, + "kaixih": { + "can_tag_run_ci_label": true, + "can_rerun_failed_ci": true, + "cooldown_interval_minutes": 0, + "reason": "top contributor" + }, + "kevin85421": { + "can_tag_run_ci_label": true, + "can_rerun_failed_ci": true, + "cooldown_interval_minutes": 0, + "reason": "custom override" + }, + "key4ng": { + "can_tag_run_ci_label": true, + "can_rerun_failed_ci": true, + "cooldown_interval_minutes": 0, + "reason": "top contributor" + }, + "kkHuang-amd": { + "can_tag_run_ci_label": true, + "can_rerun_failed_ci": true, + "cooldown_interval_minutes": 0, + "reason": "top contributor" + }, + "kssteven418": { + "can_tag_run_ci_label": true, + "can_rerun_failed_ci": true, + "cooldown_interval_minutes": 0, + "reason": "custom override" + }, + "kushanam": { + "can_tag_run_ci_label": true, + "can_rerun_failed_ci": true, + "cooldown_interval_minutes": 60, + "reason": "custom override" + }, + "lanking520": { + "can_tag_run_ci_label": true, + "can_rerun_failed_ci": true, + "cooldown_interval_minutes": 60, + "reason": "custom override" + }, + "lifuhuang": { + "can_tag_run_ci_label": true, + "can_rerun_failed_ci": true, + "cooldown_interval_minutes": 0, + "reason": "top contributor" + }, + "liz-badada": { + "can_tag_run_ci_label": true, + "can_rerun_failed_ci": true, + "cooldown_interval_minutes": 60, + "reason": "custom override" + }, + "merrymercy": { + "can_tag_run_ci_label": true, + "can_rerun_failed_ci": true, + "cooldown_interval_minutes": 0, + "reason": "top contributor" + }, + "mickqian": { + "can_tag_run_ci_label": true, + "can_rerun_failed_ci": true, + "cooldown_interval_minutes": 0, + "reason": "top contributor" + }, + "mingfeima": { + "can_tag_run_ci_label": true, + "can_rerun_failed_ci": true, + "cooldown_interval_minutes": 0, + "reason": "custom override" + }, + "minleminzui": { + "can_tag_run_ci_label": true, + "can_rerun_failed_ci": true, + "cooldown_interval_minutes": 60, + "reason": "custom override" + }, + "nvcastet": { + "can_tag_run_ci_label": true, + "can_rerun_failed_ci": true, + "cooldown_interval_minutes": 0, + "reason": "custom override" + }, + "ocss884": { + "can_tag_run_ci_label": true, + "can_rerun_failed_ci": true, + "cooldown_interval_minutes": 60, + "reason": "custom override" + }, + "pansicheng": { + "can_tag_run_ci_label": true, + "can_rerun_failed_ci": true, + "cooldown_interval_minutes": 0, + "reason": "top contributor" + }, + "pavanimajety": { + "can_tag_run_ci_label": true, + "can_rerun_failed_ci": true, + "cooldown_interval_minutes": 60, + "reason": "custom override" + }, + "ping1jing2": { + "can_tag_run_ci_label": true, + "can_rerun_failed_ci": true, + "cooldown_interval_minutes": 0, + "reason": "custom override" + }, + "pranavm-nvidia": { + "can_tag_run_ci_label": true, + "can_rerun_failed_ci": true, + "cooldown_interval_minutes": 60, + "reason": "custom override" + }, + "pyc96": { + "can_tag_run_ci_label": true, + "can_rerun_failed_ci": true, + "cooldown_interval_minutes": 0, + "reason": "custom override" + }, + "qingquansong": { + "can_tag_run_ci_label": true, + "can_rerun_failed_ci": true, + "cooldown_interval_minutes": 60, + "reason": "custom override" + }, + "qywu": { + "can_tag_run_ci_label": true, + "can_rerun_failed_ci": true, + "cooldown_interval_minutes": 60, + "reason": "custom override" + }, + "rainj-me": { + "can_tag_run_ci_label": true, + "can_rerun_failed_ci": true, + "cooldown_interval_minutes": 0, + "reason": "top contributor" + }, + "ravi03071991": { + "can_tag_run_ci_label": true, + "can_rerun_failed_ci": true, + "cooldown_interval_minutes": 60, + "reason": "custom override" + }, + "rkooo567": { + "can_tag_run_ci_label": true, + "can_rerun_failed_ci": true, + "cooldown_interval_minutes": 60, + "reason": "custom override" + }, + "saienduri": { + "can_tag_run_ci_label": true, + "can_rerun_failed_ci": true, + "cooldown_interval_minutes": 0, + "reason": "top contributor" + }, + "sglang-bot": { + "can_tag_run_ci_label": true, + "can_rerun_failed_ci": true, + "cooldown_interval_minutes": 0, + "reason": "top contributor" + }, + "shaharmor98": { + "can_tag_run_ci_label": true, + "can_rerun_failed_ci": true, + "cooldown_interval_minutes": 60, + "reason": "custom override" + }, + "shanyu-sys": { + "can_tag_run_ci_label": true, + "can_rerun_failed_ci": true, + "cooldown_interval_minutes": 60, + "reason": "custom override" + }, + "shuaills": { + "can_tag_run_ci_label": true, + "can_rerun_failed_ci": true, + "cooldown_interval_minutes": 60, + "reason": "custom override" + }, + "sleepcoo": { + "can_tag_run_ci_label": true, + "can_rerun_failed_ci": true, + "cooldown_interval_minutes": 0, + "reason": "custom override" + }, + "slin1237": { + "can_tag_run_ci_label": true, + "can_rerun_failed_ci": true, + "cooldown_interval_minutes": 0, + "reason": "top contributor" + }, + "stmatengss": { + "can_tag_run_ci_label": true, + "can_rerun_failed_ci": true, + "cooldown_interval_minutes": 0, + "reason": "top contributor" + }, + "strgrb": { + "can_tag_run_ci_label": true, + "can_rerun_failed_ci": true, + "cooldown_interval_minutes": 0, + "reason": "custom override" + }, + "sundar24295s": { + "can_tag_run_ci_label": true, + "can_rerun_failed_ci": true, + "cooldown_interval_minutes": 0, + "reason": "custom override" + }, + "sunxxuns": { + "can_tag_run_ci_label": true, + "can_rerun_failed_ci": true, + "cooldown_interval_minutes": 0, + "reason": "custom override" + }, + "thecodingwizard": { + "can_tag_run_ci_label": true, + "can_rerun_failed_ci": true, + "cooldown_interval_minutes": 60, + "reason": "custom override" + }, + "timmy-feng": { + "can_tag_run_ci_label": true, + "can_rerun_failed_ci": true, + "cooldown_interval_minutes": 60, + "reason": "custom override" + }, + "trevor-m": { + "can_tag_run_ci_label": true, + "can_rerun_failed_ci": true, + "cooldown_interval_minutes": 0, + "reason": "top contributor" + }, + "vincentzed": { + "can_tag_run_ci_label": true, + "can_rerun_failed_ci": true, + "cooldown_interval_minutes": 0, + "reason": "top contributor" + }, + "wenscarl": { + "can_tag_run_ci_label": true, + "can_rerun_failed_ci": true, + "cooldown_interval_minutes": 60, + "reason": "custom override" + }, + "whybeyoung": { + "can_tag_run_ci_label": true, + "can_rerun_failed_ci": true, + "cooldown_interval_minutes": 0, + "reason": "top contributor" + }, + "wisclmy0611": { + "can_tag_run_ci_label": true, + "can_rerun_failed_ci": true, + "cooldown_interval_minutes": 0, + "reason": "custom override" + }, + "xiezhq-hermann": { + "can_tag_run_ci_label": true, + "can_rerun_failed_ci": true, + "cooldown_interval_minutes": 0, + "reason": "top contributor" + }, + "xutizhou": { + "can_tag_run_ci_label": true, + "can_rerun_failed_ci": true, + "cooldown_interval_minutes": 0, + "reason": "custom override" + }, + "yangsijia-serena": { + "can_tag_run_ci_label": true, + "can_rerun_failed_ci": true, + "cooldown_interval_minutes": 60, + "reason": "custom override" + }, + "yhyang201": { + "can_tag_run_ci_label": true, + "can_rerun_failed_ci": true, + "cooldown_interval_minutes": 0, + "reason": "top contributor" + }, + "yilian49": { + "can_tag_run_ci_label": true, + "can_rerun_failed_ci": true, + "cooldown_interval_minutes": 60, + "reason": "custom override" + }, + "yizhang2077": { + "can_tag_run_ci_label": true, + "can_rerun_failed_ci": true, + "cooldown_interval_minutes": 0, + "reason": "top contributor" + }, + "ykcombat": { + "can_tag_run_ci_label": true, + "can_rerun_failed_ci": true, + "cooldown_interval_minutes": 60, + "reason": "custom override" + }, + "ynwang007": { + "can_tag_run_ci_label": true, + "can_rerun_failed_ci": true, + "cooldown_interval_minutes": 60, + "reason": "custom override" + }, + "yuan-luo": { + "can_tag_run_ci_label": true, + "can_rerun_failed_ci": true, + "cooldown_interval_minutes": 0, + "reason": "top contributor" + }, + "yundai424": { + "can_tag_run_ci_label": true, + "can_rerun_failed_ci": true, + "cooldown_interval_minutes": 60, + "reason": "custom override" + }, + "yyihuang": { + "can_tag_run_ci_label": true, + "can_rerun_failed_ci": true, + "cooldown_interval_minutes": 60, + "reason": "custom override" + }, + "yzh119": { + "can_tag_run_ci_label": true, + "can_rerun_failed_ci": true, + "cooldown_interval_minutes": 60, + "reason": "custom override" + }, + "zhaochenyang20": { + "can_tag_run_ci_label": true, + "can_rerun_failed_ci": true, + "cooldown_interval_minutes": 0, + "reason": "custom override" + }, + "zhijian-liu": { + "can_tag_run_ci_label": true, + "can_rerun_failed_ci": true, + "cooldown_interval_minutes": 60, + "reason": "custom override" + }, + "zhuzilin": { + "can_tag_run_ci_label": true, + "can_rerun_failed_ci": true, + "cooldown_interval_minutes": 0, + "reason": "top contributor" + }, + "zhyncs": { + "can_tag_run_ci_label": true, + "can_rerun_failed_ci": true, + "cooldown_interval_minutes": 0, + "reason": "top contributor" + }, + "zminglei": { + "can_tag_run_ci_label": true, + "can_rerun_failed_ci": true, + "cooldown_interval_minutes": 0, + "reason": "top contributor" + }, + "zyksir": { + "can_tag_run_ci_label": true, + "can_rerun_failed_ci": true, + "cooldown_interval_minutes": 60, + "reason": "custom override" + } +} diff --git a/.github/README.md b/.github/README.md new file mode 100644 index 000000000000..ccbf94ec0474 --- /dev/null +++ b/.github/README.md @@ -0,0 +1,12 @@ +# Maintenance Tools + +This folder contains tools and workflows for automating maintenance tasks. + +## CI Permissions + +`CI_PERMISSIONS.json` defines the CI permissions granted to each user. +Maintainers can directly edit the file to add entries with `"reason": "custom override"`. +Maintainers can also run `update_ci_permission.py` to update it with some auto rules (e.g., top contributors in the last 90 days get full permissions). + +## Others +- `MAINTAINER.md` defines the code maintenance model. diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index bcb510888d10..940807b8833c 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -22,4 +22,5 @@ - [ ] Add unit tests according to the [Run and add unit tests](https://docs.sglang.ai/developer_guide/contribution_guide.html#run-and-add-unit-tests). - [ ] Update documentation according to [Write documentations](https://docs.sglang.ai/developer_guide/contribution_guide.html#write-documentations). - [ ] Provide accuracy and speed benchmark results according to [Test the accuracy](https://docs.sglang.ai/developer_guide/contribution_guide.html#test-the-accuracy) and [Benchmark the speed](https://docs.sglang.ai/developer_guide/contribution_guide.html#benchmark-the-speed). +- [ ] Follow the SGLang code style [guidance](https://docs.sglang.ai/developer_guide/contribution_guide.html#code-style-guidance). - [ ] Work with maintainers to merge your PR. See the [PR Merge Process](https://github.com/sgl-project/sglang/blob/main/.github/MAINTAINER.md#pull-request-merge-process) diff --git a/.github/update_ci_permission.py b/.github/update_ci_permission.py new file mode 100644 index 000000000000..2ed846676ff0 --- /dev/null +++ b/.github/update_ci_permission.py @@ -0,0 +1,196 @@ +""" +Update the CI permissions configuration file. + +This script updates the `CI_PERMISSIONS.json` file, which defines the CI permissions granted to each user. + +The format of `CI_PERMISSIONS.json` is as follows: + +{ + "username1": { + "can_tag_run_ci_label": true, + "can_rerun_failed_ci": true, + "cooldown_interval_minutes": 0, + "reason": "top contributor" + }, + "username2": { + "can_tag_run_ci_label": true, + "can_rerun_failed_ci": true, + "cooldown_interval_minutes": 60, + "reason": "custom override" + } +} + +Permissions are assigned according to the following rules: + +1. Add the top 50 contributors from the last 90 days with full permissions, no cooldown, and the reason "top contributor". +2. Load all users from the existing `CI_PERMISSIONS.json` file and update their entries as follows: + - If a user is already covered by rule 1, skip that user. + - If the old reason of a user is "top contributor" but they are not in the current top contributors list, change their configuration to: + { + "can_tag_run_ci_label": true, + "can_rerun_failed_ci": true, + "cooldown_interval_minutes": 60, + "reason": "custom override" + } + - For all other cases, preserve the original configuration unchanged. +3. All other users receive no permissions and a 120-minute cooldown (they are omitted from the file). + +Usage: + export GH_TOKEN="your_github_token" + python3 update_ci_permission.py +""" + +import json +import os +from collections import Counter +from datetime import datetime, timedelta, timezone + +import requests + +# 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", +} + + +def github_api_get(endpoint, params=None): + """Helper to make paginated GitHub API requests.""" + results = [] + url = f"https://api.github.com/repos/{REPO_OWNER}/{REPO_NAME}/{endpoint}" + + while url: + response = requests.get(url, headers=HEADERS, params=params) + if response.status_code != 200: + print(f"Error fetching {url}: {response.status_code} {response.text}") + # If we fail to fetch, strictly return what we have or empty to avoid crashing logic + break + + data = response.json() + if isinstance(data, list): + results.extend(data) + else: + return data # Non-list response (not paginated usually) + + # Handle pagination + url = None + if "link" in response.headers: + links = response.headers["link"].split(", ") + for link in links: + if 'rel="next"' in link: + url = link[link.find("<") + 1 : link.find(">")] + params = None # Params are included in the next link + break + return results + + +def get_write_access_users(): + """Fetches users with push (write) or admin access.""" + print("Fetching collaborators with write access...") + # Note: This endpoint usually requires admin rights on the token. + collaborators = github_api_get("collaborators", params={"per_page": 100}) + + writers = set() + for col in collaborators: + perms = col.get("permissions", {}) + # Check for admin, maintain, or push rights + if perms.get("admin") or perms.get("maintain") or perms.get("push"): + writers.add(col["login"]) + + print(f"Found {len(writers)} users with write access.") + return writers + + +def get_top_contributors(days=90, limit=50): + """Fetches top contributors based on commit count in the last N days.""" + print(f"Fetching commits from the last {days} days...") + since_date = (datetime.now(timezone.utc) - timedelta(days=days)).isoformat() + + # Fetch commits + commits = github_api_get("commits", params={"since": since_date, "per_page": 100}) + + author_counts = Counter() + for commit in commits: + # commit['author'] contains the GitHub user object (can be None if not linked) + if commit.get("author") and "login" in commit["author"]: + author_counts[commit["author"]["login"]] += 1 + + top_users = [user for user, _ in author_counts.most_common(limit)] + print(f"Found {len(top_users)} active contributors in the last {days} days.") + return set(top_users) + + +def load_existing_permissions(): + if os.path.exists(FILE_NAME): + try: + with open(FILE_NAME, "r") as f: + return json.load(f) + except json.JSONDecodeError: + print(f"Warning: {FILE_NAME} is invalid JSON. Starting fresh.") + return {} + + +def main(): + # Gather Data + try: + write_access_users = get_write_access_users() + except Exception as e: + print(f"Warning: Could not fetch collaborators (check token scope). Error: {e}") + write_access_users = set() + + top_contributors = get_top_contributors(days=90, limit=50) + old_permissions = load_existing_permissions() + + new_permissions = {} + + # Rule 1: Add Top 50 Contributors + for user in top_contributors: + new_permissions[user] = { + "can_tag_run_ci_label": True, + "can_rerun_failed_ci": True, + "cooldown_interval_minutes": 0, + "reason": "top contributor", + } + + # Rule 2: Process Existing Users (Merge Logic) + for user, config in old_permissions.items(): + if user in new_permissions: + # Already handled by Rule 1 or 2 + continue + + old_reason = config.get("reason", "") + + # If they fell off the top contributor list + if old_reason in ["top contributor"]: + new_permissions[user] = { + "can_tag_run_ci_label": True, + "can_rerun_failed_ci": True, + "cooldown_interval_minutes": 60, + "reason": "custom override", + } + else: + # Preserve custom overrides + new_permissions[user] = config + + # Save and Sort + # Sorting keys for cleaner diffs + sorted_permissions = dict(sorted(new_permissions.items())) + + with open(FILE_NAME, "w") as f: + json.dump(sorted_permissions, f, indent=4) + f.write("\n") # Add trailing newline + + print(f"Successfully updated {FILE_NAME}. Total users: {len(sorted_permissions)}") + + +if __name__ == "__main__": + main() diff --git a/docs/developer_guide/contribution_guide.md b/docs/developer_guide/contribution_guide.md index 5ae86595d37b..ae6f4a86100e 100644 --- a/docs/developer_guide/contribution_guide.md +++ b/docs/developer_guide/contribution_guide.md @@ -82,7 +82,7 @@ After the "run-ci" label is added, the PR author can trigger CI by: 1. Pushing new commits, or 2. Clicking "Re-run" / retrigger on the workflow page. -## General code style +## Code style guidance - Avoid code duplication. If the same code snippet (more than five lines) appears multiple times, extract it into a shared function. - Minimize device synchronization. Reduce expensive CPU-GPU synchronization operations, such as `tensor.item()` or `tensor.cpu()`, whenever possible. Use vectorized code. - Prioritize extreme efficiency. SGLang is a runtime, and most of your code runs on the critical path for every request. Optimize all minor overheads as much as possible, especially in the model forward code.