perf(ci): start runtime checks within the existing job ceiling
This commit is contained in:
1 parent
350dbb45df
commit
9e9a95f8dc
5 files changed
+55
-9
No files matched your search
@@ -9,8 +9,8 @@
|
||||
en: e5c984fa32cc5e69
|
||||
zh: 25d5742b2106d830
|
||||
/agent-note-pr-artifact-builds-and-aggregate-typescript-checks/decision:
|
||||
en: 69e2bf4a42c1e592
|
||||
zh: c46d637da116f836
|
||||
en: 6e84bceaba4573ca
|
||||
zh: 25a37c147a675643
|
||||
/agent-note-pr-artifact-builds-and-aggregate-typescript-checks/alternatives-considered:
|
||||
en: f61da066f9ddcd62
|
||||
zh: 816fd6e0063017cd
|
||||
|
||||
@@ -20,7 +20,7 @@ The Python executable builder selects artifact compilation with `--artifacts-onl
|
||||
|
||||
CI invokes the internal build helpers directly and keeps the root package manifest unchanged. Root manifest edits activate the separate native-addon platform matrix even when only build aliases change; avoiding that trigger preserves the existing workflow set and concurrent-job ceiling without weakening native validation.
|
||||
|
||||
Job inventory, runner selectors, and benchmark sample counts stay fixed; gate and worker ceilings do not increase. The three compatibility cases use at most two concurrent jobs; the two-target Python runtime matrix follows their completion. Before that matrix, four Linux lanes, two compatibility jobs, the Python SDK, and three Windows lanes permit at most ten worker jobs. Afterwards, the remaining eight lanes and two runtime targets keep the same ceiling. Coverage partitions reuse compact file-cost metadata within their platform and runner pool. Parallel release packing uses pnpm's existing bounded scheduler; serial publication keeps family order.
|
||||
Job inventory, runner selectors, and benchmark sample counts stay fixed; gate and worker ceilings do not increase. The three compatibility cases run one job at a time; the two-target Python runtime matrix starts after the keyless Python SDK job succeeds. Four Linux lanes, the Python SDK, three Windows lanes, and one compatibility job permit at most nine worker jobs initially. Once the SDK job finishes, the remaining seven independent lanes, one compatibility job, and two runtime targets permit at most ten. The runtime plan and wheel stages precede those targets and each use one job. This permits runtime validation to overlap the Node 22 build within the original ten-job ceiling. Coverage partitions reuse compact file-cost metadata within their platform and runner pool. Parallel release packing uses pnpm's existing bounded scheduler; serial publication keeps family order.
|
||||
|
||||
Each Node version runs the same seven source compatibility specs in one serial Vitest invocation. Both file parallelism and the CLI worker limit are fixed to one, and the gate sets `VITEST_MAX_WORKERS=1` because that environment variable overrides Vitest's CLI limit. Files retain fork isolation; the build-backed Node 22 lazy-search smoke keeps its separate build dependency. Three paired local samples preserve all 253 assertion outcomes and reduce startup-only median time from 11.52 to 8.69 seconds, without increasing owned descendant-process peak.
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@ Python executable builder 在验证 runtime closure 后,通过 `--artifacts-on
|
||||
|
||||
CI 直接调用内部 build helper,并保持 root package manifest 不变。即使只修改 build alias,root manifest 改动也会激活独立的 native-addon 平台矩阵;避免这一触发条件,可以在不削弱 native 验证的情况下保留现有 workflow 集合与并发 job 上限。
|
||||
|
||||
job 清单、runner 选择和 benchmark sample 数量保持固定;gate 与 worker 上限不提高。三个 compatibility case 最多并发两个 job;双目标 Python runtime 矩阵等待它们完成。该矩阵之前,四个 Linux lane、两个 compatibility job、Python SDK 和三个 Windows lane 最多占用十个 worker job。随后剩余八个 lane 加上两个 runtime target 保持相同上限。覆盖率分区在各自的平台和 runner pool 内复用精简的文件成本元数据。并行 release 打包使用 pnpm 现有的有界调度器;串行发布保持 family 顺序。
|
||||
job 清单、runner 选择和 benchmark sample 数量保持固定;gate 与 worker 上限不提高。三个 compatibility case 每次运行一个 job;双目标 Python runtime 矩阵在 keyless Python SDK job 成功后启动。四个 Linux lane、Python SDK、三个 Windows lane 和一个 compatibility job,初始最多占用九个 worker job。SDK job 完成后,剩余七个独立 lane、一个 compatibility job 和两个 runtime target,最多占用十个 job。runtime plan 与 wheel 阶段先于这些 target,各占一个 job。这允许 runtime 验证与 Node 22 构建重叠,同时保持原有十个 job 的上限。覆盖率分区在各自的平台和 runner pool 内复用精简的文件成本元数据。并行 release 打包使用 pnpm 现有的有界调度器;串行发布保持 family 顺序。
|
||||
|
||||
每个 Node 版本在一次串行 Vitest 调用中运行相同的七个 source compatibility spec。文件并行和 CLI worker 上限均固定为一,gate 还设置 `VITEST_MAX_WORKERS=1`,因为该环境变量会覆盖 Vitest 的 CLI 上限。文件保持 fork 隔离;依赖构建的 Node 22 lazy-search smoke 保留独立的 build 依赖。三对本地样本保持全部 253 个 assertion outcome,将启动开销比较的 median 从 11.52 秒降至 8.69 秒,且不增加所拥有 descendant process 的峰值。
|
||||
|
||||
|
||||
@@ -398,7 +398,7 @@ jobs:
|
||||
DSH_GATE_FAIL_FAST: '1'
|
||||
strategy:
|
||||
fail-fast: false
|
||||
max-parallel: 2
|
||||
max-parallel: 1
|
||||
matrix:
|
||||
include:
|
||||
- node: '22.19'
|
||||
@@ -499,7 +499,7 @@ jobs:
|
||||
# Linux ARM64 and both macOS architectures run in ci-master.yml.
|
||||
python-runtime:
|
||||
if: github.event_name == 'pull_request'
|
||||
needs: node-compat
|
||||
needs: python-sdk
|
||||
name: python runtime / release-shaped matrix
|
||||
uses: ./.github/workflows/build-exe-for-python-sdk.yml
|
||||
with:
|
||||
|
||||
@@ -14,13 +14,59 @@ const runnerPrivatePnpmDestination = /^\$\{\{ runner\.temp \}\}\/setup-pnpm-\$\{
|
||||
const nativeWindowsPnpmDestination = '${{ runner.temp }}/setup-pnpm-js-${{ github.run_id }}-${{ github.run_attempt }}-${{ github.job }}'
|
||||
|
||||
describe('CI workflow', () => {
|
||||
it('bounds compatibility jobs before the two runtime targets start', () => {
|
||||
it('keeps at most ten worker jobs active while runtime targets follow the SDK suite', () => {
|
||||
const ci = loadWorkflow('.github/workflows/ci.yml')
|
||||
const compatibility = workflowJob(ci, 'node-compat')
|
||||
const runtime = workflowJob(ci, 'python-runtime')
|
||||
expect(compatibility.strategy).toMatchObject({ 'max-parallel': 2 })
|
||||
expect(runtime.needs).toBe('node-compat')
|
||||
if (!isRecord(ci.jobs) || !isRecord(compatibility.strategy) || !isRecord(runtime.with)) {
|
||||
throw new TypeError('CI must define jobs, compatibility scheduling, and runtime inputs')
|
||||
}
|
||||
const compatibilityLimit = compatibility.strategy['max-parallel']
|
||||
const targets = runtime.with.targets
|
||||
if (typeof compatibilityLimit !== 'number' || typeof targets !== 'string') {
|
||||
throw new TypeError('CI requires a numeric compatibility limit and explicit runtime targets')
|
||||
}
|
||||
expect(Number.isInteger(compatibilityLimit)).toBe(true)
|
||||
expect(compatibilityLimit).toBeGreaterThan(0)
|
||||
expect(compatibility.strategy).toMatchObject({
|
||||
'fail-fast': false,
|
||||
matrix: { include: [{ node: '22.19' }, { node: '24.9' }, { node: 26 }] },
|
||||
})
|
||||
expect(workflowJob(ci, 'all-checks-passed').needs).toContain('node-compat')
|
||||
const ordinaryJobs = Object.entries(ci.jobs)
|
||||
.filter(([name]) => !['node-compat', 'python-runtime', 'all-checks-passed'].includes(name))
|
||||
for (const [name, job] of ordinaryJobs) {
|
||||
if (!isRecord(job)) throw new TypeError(`${name} must define a job`)
|
||||
expect(job).not.toHaveProperty('strategy')
|
||||
expect(job).not.toHaveProperty('uses')
|
||||
}
|
||||
expect(ordinaryJobs.map(([name]) => name)).toContain('python-sdk')
|
||||
expect(runtime.needs).toBe('python-sdk')
|
||||
expect(runtime.strategy).toBeUndefined()
|
||||
expect(runtime.with).toMatchObject({ targets: 'node24-linux-x64,node24-win-x64' })
|
||||
expect(runtime.uses).toBe('./.github/workflows/build-exe-for-python-sdk.yml')
|
||||
|
||||
const builder = loadWorkflow('.github/workflows/build-exe-for-python-sdk.yml')
|
||||
if (!isRecord(builder.jobs)) throw new TypeError('Python runtime builder must define jobs')
|
||||
expect(Object.keys(builder.jobs).sort()).toEqual(['build', 'plan', 'sdk-wheel'])
|
||||
const plan = workflowJob(builder, 'plan')
|
||||
const wheel = workflowJob(builder, 'sdk-wheel')
|
||||
const build = workflowJob(builder, 'build')
|
||||
expect(plan.needs).toBeUndefined()
|
||||
expect(plan.strategy).toBeUndefined()
|
||||
expect(plan.uses).toBeUndefined()
|
||||
expect(wheel.needs).toBe('plan')
|
||||
expect(wheel.strategy).toBeUndefined()
|
||||
expect(wheel.uses).toBeUndefined()
|
||||
expect(build.needs).toEqual(['plan', 'sdk-wheel'])
|
||||
expect(build.uses).toBeUndefined()
|
||||
if (!isRecord(build.strategy)) throw new TypeError('Python runtime build must define its target matrix')
|
||||
expect(build.strategy.matrix).toEqual({ include: '${{ fromJSON(needs.plan.outputs.matrix) }}' })
|
||||
|
||||
const beforeSdk = ordinaryJobs.length + compatibilityLimit
|
||||
const afterSdk = ordinaryJobs.length - 1 + compatibilityLimit + Math.max(1, targets.split(',').length)
|
||||
expect(beforeSdk).toBeLessThanOrEqual(10)
|
||||
expect(afterSdk).toBeLessThanOrEqual(10)
|
||||
})
|
||||
|
||||
it('retains aggregate diagnostics in required builds and protected publication', () => {
|
||||
|
||||
Reference in new issue
Block a user