ci: dispatch pr-test-extra.yml from pr-test.yml on the scheduled cron (#25320)
Co-authored-by: hnyls2002 <lsyincs@gmail.com> Co-authored-by: Liangsheng Yin <hnyls2002@gmail.com>
This commit is contained in:
co-authored by
hnyls2002
Liangsheng Yin
parent
66ef97c00f
commit
4adfc6cf7e
@@ -0,0 +1,124 @@
|
||||
name: PR Awareness Comment
|
||||
# Reusable workflow maintaining an "awareness block" at the bottom of the PR
|
||||
# body: extra-CI opt-in state + latest PR Test / PR Test Extra run URLs.
|
||||
# Called from pr-test.yml + pr-test-extra.yml after their check-changes job so
|
||||
# the block appears ~30s in, not after downstream stages. Each caller updates
|
||||
# only its own slot; the other slot is preserved verbatim.
|
||||
#
|
||||
# pulls.update fires `pull_request: edited`, which is NOT in the default
|
||||
# trigger types, so this does not loop back into the CI workflows.
|
||||
|
||||
on:
|
||||
workflow_call:
|
||||
inputs:
|
||||
workflow_kind:
|
||||
description: "Which workflow is calling: 'pr-test' or 'pr-test-extra'"
|
||||
required: true
|
||||
type: string
|
||||
|
||||
permissions:
|
||||
pull-requests: write
|
||||
|
||||
jobs:
|
||||
update-pr-body:
|
||||
if: github.event_name == 'pull_request'
|
||||
runs-on: ubuntu-latest
|
||||
# Serialize concurrent writers from pr-test + pr-test-extra: both race on
|
||||
# get/modify/update of the PR body, and the later `pulls.update` clobbers
|
||||
# the earlier writer's slot. Group is per-PR so unrelated PRs don't block.
|
||||
# cancel-in-progress MUST be false — cancelling would drop the earlier update.
|
||||
concurrency:
|
||||
group: pr-awareness-${{ github.event.pull_request.number }}
|
||||
cancel-in-progress: false
|
||||
steps:
|
||||
- name: Update awareness block in PR body
|
||||
uses: actions/github-script@v7
|
||||
env:
|
||||
# Pass input via env (process.env) instead of `${{ }}` interpolation
|
||||
# into the JS body, so future user-controlled values can't inject JS.
|
||||
KIND: ${{ inputs.workflow_kind }}
|
||||
with:
|
||||
script: |
|
||||
const kind = process.env.KIND;
|
||||
const labels = context.payload.pull_request.labels.map(l => l.name);
|
||||
const hasExtra = labels.includes('run-ci-extra');
|
||||
const runUrl = `${context.serverUrl}/${context.repo.owner}/${context.repo.repo}/actions/runs/${context.runId}`;
|
||||
|
||||
const outerStart = '<!-- pr-awareness:start -->';
|
||||
const outerEnd = '<!-- pr-awareness:end -->';
|
||||
const ptStart = '<!-- slot:pr-test:start -->';
|
||||
const ptEnd = '<!-- slot:pr-test:end -->';
|
||||
const peStart = '<!-- slot:pr-test-extra:start -->';
|
||||
const peEnd = '<!-- slot:pr-test-extra:end -->';
|
||||
|
||||
const { data: pr } = await github.rest.pulls.get({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
pull_number: context.issue.number,
|
||||
});
|
||||
const body = pr.body || '';
|
||||
|
||||
// Extract existing block + slots so we preserve the other workflow's URL
|
||||
const blockRe = new RegExp(`${outerStart}[\\s\\S]*?${outerEnd}`);
|
||||
const existingBlock = (body.match(blockRe) || [''])[0];
|
||||
|
||||
function extractSlot(text, start, end) {
|
||||
const re = new RegExp(`${start}([\\s\\S]*?)${end}`);
|
||||
const m = text.match(re);
|
||||
return m ? m[1] : null;
|
||||
}
|
||||
const prevPrTest = extractSlot(existingBlock, ptStart, ptEnd);
|
||||
const prevPrExtra = extractSlot(existingBlock, peStart, peEnd);
|
||||
|
||||
// Each caller updates only its own slot; the other slot is preserved.
|
||||
// For pr-test-extra without the label: the rest of its graph is
|
||||
// label-gate-skipped, so linking to that run would mislead — inline
|
||||
// a warning notice in the slot instead.
|
||||
// When kind=pr-test and hasExtra=false, force-reset the extra slot
|
||||
// rather than carrying prevPrExtra forward — otherwise an old Run
|
||||
// URL from a previous opt-in lingers after the label is removed,
|
||||
// until pr-test-extra runs again and rewrites the slot.
|
||||
const notEnabledText = ':warning: **Not enabled** — add `run-ci-extra` label to opt in.';
|
||||
const newPrTest = (kind === 'pr-test')
|
||||
? `[Run #${context.runId}](${runUrl})`
|
||||
: (prevPrTest || '_Not run yet_');
|
||||
const newPrExtra = (kind === 'pr-test-extra')
|
||||
? (hasExtra
|
||||
? `[Run #${context.runId}](${runUrl})`
|
||||
: notEnabledText)
|
||||
: (hasExtra
|
||||
? (prevPrExtra || '_Not run yet_')
|
||||
: notEnabledText);
|
||||
|
||||
const newBlock = [
|
||||
outerStart,
|
||||
'---',
|
||||
'### CI Awareness',
|
||||
'',
|
||||
`Latest PR Test: ${ptStart}${newPrTest}${ptEnd}`,
|
||||
`Latest PR Test (Extra): ${peStart}${newPrExtra}${peEnd}`,
|
||||
outerEnd,
|
||||
].join('\n');
|
||||
|
||||
// Replace existing block in place, or append at body end.
|
||||
let newBody;
|
||||
if (blockRe.test(body)) {
|
||||
newBody = body.replace(blockRe, newBlock);
|
||||
} else {
|
||||
const sep = body.length === 0
|
||||
? ''
|
||||
: (body.endsWith('\n') ? '\n---\n\n' : '\n\n---\n\n');
|
||||
newBody = `${body}${sep}${newBlock}`;
|
||||
}
|
||||
|
||||
if (newBody !== body) {
|
||||
await github.rest.pulls.update({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
pull_number: context.issue.number,
|
||||
body: newBody,
|
||||
});
|
||||
core.info(`Updated PR body awareness block (caller=${kind}).`);
|
||||
} else {
|
||||
core.info(`PR body awareness block already up-to-date (caller=${kind}).`);
|
||||
}
|
||||
@@ -49,6 +49,7 @@ on:
|
||||
|
||||
jobs:
|
||||
run:
|
||||
name: check-changes
|
||||
runs-on: ubuntu-latest
|
||||
outputs:
|
||||
# Use API-based detection for target_stage mode (filter-api), otherwise use dorny/paths-filter (filter)
|
||||
|
||||
@@ -73,6 +73,7 @@ env:
|
||||
|
||||
jobs:
|
||||
run:
|
||||
name: ${{ inputs.self_name }} (${{ matrix.partition }})
|
||||
# target_stage takes precedence; otherwise default per-commit gating
|
||||
# runs on schedule / parallel-dispatch / non-failed PR with main_package
|
||||
# or sgl_kernel changes.
|
||||
|
||||
@@ -67,7 +67,7 @@ env:
|
||||
SGLANG_IS_IN_CI: true
|
||||
SGLANG_CUDA_COREDUMP: "1"
|
||||
SGLANG_JIT_DEEPGEMM_FAST_WARMUP: true
|
||||
SKIP_STAGE_HEALTH_CHECK: ${{ inputs.skip_stage_health_check == true && 'true' || 'false' }}
|
||||
SKIP_STAGE_HEALTH_CHECK: ${{ (inputs.skip_stage_health_check == true || inputs.run_all_tests == true) && 'true' || 'false' }}
|
||||
FORCE_REBUILD_DEEPEP: '1'
|
||||
PR_TEST_BYPASS_MAINTENANCE_ON_MAIN: ${{ github.ref == 'refs/heads/main' && 'true' || 'false' }}
|
||||
USE_VENV: false
|
||||
@@ -105,6 +105,19 @@ jobs:
|
||||
pr_test_yml: '.github/workflows/pr-test-extra.yml'
|
||||
secrets: inherit
|
||||
|
||||
# always(): on a PR without `run-ci-extra` the rest of this workflow's graph
|
||||
# is skipped, but we still want the awareness block updated so the author
|
||||
# sees this run was a no-op.
|
||||
call-pr-awareness:
|
||||
needs: check-changes
|
||||
if: always() && github.event_name == 'pull_request'
|
||||
permissions:
|
||||
pull-requests: write
|
||||
uses: ./.github/workflows/_pr-awareness-comment.yml
|
||||
with:
|
||||
workflow_kind: pr-test-extra
|
||||
secrets: inherit
|
||||
|
||||
# =============================================== sgl-kernel ====================================================
|
||||
sgl-kernel-build-wheels:
|
||||
needs: check-changes
|
||||
|
||||
@@ -35,6 +35,11 @@ on:
|
||||
required: false
|
||||
type: boolean
|
||||
default: false
|
||||
run_all_tests:
|
||||
description: "Run all tests (mirrors the scheduled cron's behavior — combine with test_parallel_dispatch for full sim)"
|
||||
required: false
|
||||
type: boolean
|
||||
default: false
|
||||
workflow_call:
|
||||
inputs:
|
||||
git_ref:
|
||||
@@ -67,7 +72,7 @@ env:
|
||||
SGLANG_IS_IN_CI: true
|
||||
SGLANG_CUDA_COREDUMP: "1"
|
||||
SGLANG_JIT_DEEPGEMM_FAST_WARMUP: true
|
||||
SKIP_STAGE_HEALTH_CHECK: ${{ inputs.skip_stage_health_check == true && 'true' || 'false' }}
|
||||
SKIP_STAGE_HEALTH_CHECK: ${{ (inputs.skip_stage_health_check == true || inputs.test_parallel_dispatch == true || inputs.run_all_tests == true) && 'true' || 'false' }}
|
||||
# TEMP: rebuild deepep against the new torch for torch-211-merge PR only — revert before merging to main.
|
||||
FORCE_REBUILD_DEEPEP: '1'
|
||||
# Schedule / main-branch dispatch / workflow_call from main use refs/heads/main; PR events use refs/pull/*/merge
|
||||
@@ -93,6 +98,25 @@ jobs:
|
||||
force_continue_on_error: ${{ inputs.force_continue_on_error == true }}
|
||||
secrets: inherit
|
||||
|
||||
# Runs right after check-changes so the awareness block is injected ~30s in
|
||||
# rather than waiting for downstream stages.
|
||||
call-pr-awareness:
|
||||
needs: check-changes
|
||||
if: always() && github.event_name == 'pull_request'
|
||||
permissions:
|
||||
pull-requests: write
|
||||
uses: ./.github/workflows/_pr-awareness-comment.yml
|
||||
with:
|
||||
workflow_kind: pr-test
|
||||
secrets: inherit
|
||||
|
||||
call-pr-test-extra:
|
||||
if: github.event_name == 'schedule' || inputs.test_parallel_dispatch == true
|
||||
uses: ./.github/workflows/pr-test-extra.yml
|
||||
with:
|
||||
run_all_tests: true
|
||||
secrets: inherit
|
||||
|
||||
# =============================================== Wait Jobs for Sequential PR Execution ====================================================
|
||||
# These jobs poll GitHub API to wait for previous stages to complete.
|
||||
# For PR runs: wait jobs run and enforce sequential execution via polling.
|
||||
|
||||
Reference in New Issue
Block a user