Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/execute-notebook.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ on:
paths:
- "python/sglang/**"
- "docs/**"
types: [synchronize, labeled]
types: [synchronize]
workflow_dispatch:


Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/pr-benchmark-rust.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ on:
branches: [ main ]
paths:
- "sgl-router/**"
types: [synchronize, labeled]
types: [synchronize]
workflow_dispatch:

concurrency:
Expand Down
96 changes: 96 additions & 0 deletions .github/workflows/pr-gate.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
on:
workflow_call:

jobs:
pr-gate:
runs-on: ubuntu-latest
steps:
- name: Fetch latest PR info
id: pr
if: github.event_name == 'pull_request'
uses: actions/github-script@v7
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
const pr = await github.rest.pulls.get({
owner: context.repo.owner,
repo: context.repo.repo,
pull_number: context.issue.number
});
core.setOutput("labels", JSON.stringify(pr.data.labels.map(l => l.name)));
core.setOutput("draft", pr.data.draft);
core.setOutput("user", pr.data.user.login);

- name: Block draft PR
if: github.event_name == 'pull_request' && fromJson(steps.pr.outputs.draft)
run: |
echo "PR is draft. Blocking CI."
exit 1

- name: Require run-ci label
if: github.event_name == 'pull_request'
run: |
labels='${{ steps.pr.outputs.labels }}'
echo "Labels: $labels"
if [[ "${{ contains(fromJson(steps.pr.outputs.labels), 'run-ci') }}" == "false" ]]; then
echo "Missing required label 'run-ci'."
exit 1
fi

- name: Enforce rate limit for low-permission actors
if: github.event_name == 'pull_request' || github.event_name == 'workflow_dispatch'
uses: actions/github-script@v7
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
const HOURS = 2;
const owner = context.repo.owner;
const repo = context.repo.repo;
const eventName = context.eventName;
const curRun = await github.rest.actions.getWorkflowRun({
owner, repo, run_id: context.runId
});
const triggeringActor = curRun.data.triggering_actor?.login || context.actor;

async function hasHighPermission(username) {
try {
const { data } = await github.rest.repos.getCollaboratorPermissionLevel({ owner, repo, username });
const perm = data.permission || 'none';
return perm === 'write' || perm === 'maintain' || perm === 'admin';
} catch (e) {
if (e.status === 404 || e.status === 403) return false;
throw e;
}
}

if (await hasHighPermission(triggeringActor)) {
core.info(`Triggering user '${triggeringActor}' has high permission. No rate limit applied.`);
return;
}

const cutoff = new Date(Date.now() - HOURS * 60 * 60 * 1000);
core.info(`Checking for workflow runs since ${cutoff.toISOString()} (last ${HOURS} hours) for event '${eventName}'.`);

const { data } = await github.rest.actions.listWorkflowRuns({
owner,
repo,
workflow_id: 'pr-test.yml',
event: eventName,
per_page: 100,
});

const runs = data.workflow_runs || [];
const recentFound = runs.find((run) => {
if (String(run.id) === String(context.runId)) return false;
if (new Date(run.created_at) < cutoff) return false;
return (run.actor?.login === triggeringActor) || (run.triggering_actor?.login === triggeringActor);
});

if (recentFound) {
core.setFailed(
`User '${triggeringActor}' already triggered '${context.workflow}' via '${eventName}' at ${recentFound.created_at}. ` +
`Please wait ${HOURS} hours before triggering again.`
);
} else {
core.info(`No recent runs detected within the last ${HOURS} hours; proceeding.`);
}
20 changes: 6 additions & 14 deletions .github/workflows/pr-test-amd.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,35 +19,26 @@ on:
- "test/**"
- "sgl-kernel/**"
- ".github/workflows/pr-test-amd.yml"
types: [synchronize, labeled]
types: [synchronize]
workflow_dispatch:

concurrency:
group: pr-test-amd-${{ github.ref }}
cancel-in-progress: true

jobs:
call-gate:
uses: ./.github/workflows/pr-gate.yml
secrets: inherit
check-changes:
needs: [call-gate]
runs-on: ubuntu-latest
outputs:
main_package: ${{ steps.filter.outputs.main_package }}
sgl_kernel: ${{ steps.filter.outputs.sgl_kernel }}
steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Fail if the PR does not have the 'run-ci' label
if: github.event_name == 'pull_request' && !contains(github.event.pull_request.labels.*.name, 'run-ci')
run: |
echo "This pull request does not have the 'run-ci' label. Failing the workflow."
exit 1

- name: Fail if the PR is a draft
if: github.event_name == 'pull_request' && github.event.pull_request.draft == true
run: |
echo "This pull request is a draft. Failing the workflow."
exit 1

- name: Detect file changes
id: filter
uses: dorny/paths-filter@v3
Expand Down Expand Up @@ -416,6 +407,7 @@ jobs:
pr-test-amd-finish:
needs:
[
call-gate,
check-changes,

sgl-kernel-unit-test-amd,
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/pr-test-npu.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ on:
- "scripts/ci/**"
- "test/**"
- ".github/workflows/pr-test-npu.yml"
types: [synchronize, labeled]
types: [synchronize]
workflow_dispatch:

concurrency:
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/pr-test-pd-router.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ on:
- 'python/sglang/srt/disaggregation/**'
- 'scripts/ci/ci_start_disaggregation_servers.sh'
- 'sgl-router/**'
types: [synchronize, labeled]
types: [synchronize]
workflow_dispatch:

concurrency:
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/pr-test-rust.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ on:
branches: [ main ]
paths:
- "sgl-router/**"
types: [synchronize, labeled]
types: [synchronize]
workflow_dispatch:

concurrency:
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/pr-test-xeon.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ on:
- "sgl-kernel/**"
- ".github/workflows/pr-test-xeon.yml"
- "docker/xeon.Dockerfile"
types: [synchronize, labeled]
types: [synchronize]
workflow_dispatch:

concurrency:
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/pr-test-xpu.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ on:
- "test/**"
- "sgl-kernel/**"
- ".github/workflows/pr-test-xpu.yml"
types: [synchronize, labeled]
types: [synchronize]
workflow_dispatch:

concurrency:
Expand Down
77 changes: 6 additions & 71 deletions .github/workflows/pr-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ on:
branches: [main]
pull_request:
branches: [main]
types: [synchronize, labeled]
types: [synchronize]
workflow_dispatch:
inputs:
version:
Expand All @@ -22,8 +22,12 @@ concurrency:
cancel-in-progress: true

jobs:
call-gate:
uses: ./.github/workflows/pr-gate.yml
secrets: inherit
# =============================================== check changes ====================================================
check-changes:
needs: [call-gate]
runs-on: ubuntu-latest
outputs:
main_package: ${{ steps.filter.outputs.main_package }}
Expand All @@ -33,76 +37,6 @@ jobs:
- name: Checkout code
uses: actions/checkout@v4

- name: Fail if the PR does not have the 'run-ci' label
if: github.event_name == 'pull_request' && !contains(github.event.pull_request.labels.*.name, 'run-ci')
run: |
echo "This pull request does not have the 'run-ci' label. Failing the workflow."
exit 1

- name: Fail if the PR is a draft
if: github.event_name == 'pull_request' && github.event.pull_request.draft == true
run: |
echo "This pull request is a draft. Failing the workflow."
exit 1

- name: Enforce rate limit for low-permission actors
if: github.event_name == 'pull_request' || github.event_name == 'workflow_dispatch'
uses: actions/github-script@v7
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
const HOURS = 2;
const owner = context.repo.owner;
const repo = context.repo.repo;
const eventName = context.eventName;
const curRun = await github.rest.actions.getWorkflowRun({
owner, repo, run_id: context.runId
});
const triggeringActor = curRun.data.triggering_actor?.login || context.actor;

async function hasHighPermission(username) {
try {
const { data } = await github.rest.repos.getCollaboratorPermissionLevel({ owner, repo, username });
const perm = data.permission || 'none';
return perm === 'write' || perm === 'maintain' || perm === 'admin';
} catch (e) {
if (e.status === 404 || e.status === 403) return false;
throw e;
}
}

if (await hasHighPermission(triggeringActor)) {
core.info(`Triggering user '${triggeringActor}' has high permission. No rate limit applied.`);
return;
}

const cutoff = new Date(Date.now() - HOURS * 60 * 60 * 1000);
core.info(`Checking for workflow runs since ${cutoff.toISOString()} (last ${HOURS} hours) for event '${eventName}'.`);

const { data } = await github.rest.actions.listWorkflowRuns({
owner,
repo,
workflow_id: 'pr-test.yml',
event: eventName,
per_page: 100,
});

const runs = data.workflow_runs || [];
const recentFound = runs.find((run) => {
if (String(run.id) === String(context.runId)) return false;
if (new Date(run.created_at) < cutoff) return false;
return (run.actor?.login === triggeringActor) || (run.triggering_actor?.login === triggeringActor);
});

if (recentFound) {
core.setFailed(
`User '${triggeringActor}' already triggered '${context.workflow}' via '${eventName}' at ${recentFound.created_at}. ` +
`Please wait ${HOURS} hours before triggering again.`
);
} else {
core.info(`No recent runs detected within the last ${HOURS} hours; proceeding.`);
}

- name: Detect file changes
id: filter
uses: dorny/paths-filter@v3
Expand Down Expand Up @@ -959,6 +893,7 @@ jobs:
pr-test-finish:
needs:
[
call-gate,
check-changes,

sgl-kernel-build-wheels,
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/quantization-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ on:
- "scripts/ci/**"
- "test/**"
- ".github/workflows/quantization-test.yml"
types: [synchronize, labeled]
types: [synchronize]
workflow_dispatch:

concurrency:
Expand Down
Loading