Merge latest origin/master into worktree/ci-under-minute

This commit is contained in:
Tianyi Cui
2026-07-22 17:20:09 +08:00
38 changed files with 209 additions and 194 deletions

View File

@@ -26,7 +26,6 @@ type Mode =
| 'ci-windows-complete'
| 'ci-windows-observational'
| 'node-compat'
| 'pre-push'
| 'doc-sync'
type GateStatus = 'pending' | 'running' | 'passed' | 'failed' | 'skipped'
@@ -104,21 +103,20 @@ function parseMode(raw: string | undefined): Mode {
case 'ci-windows-complete':
case 'ci-windows-observational':
case 'node-compat':
case 'pre-push':
case 'doc-sync':
return raw
default:
throw new Error(
`run-gates: expected mode ci-primary | ci-primary-cpu | ci-primary-large-runner | ci-static | ci-lint | ci-coverage | ci-snapshot | ci-artifacts | ci-windows-blocking | ci-windows-complete | ci-windows-observational | node-compat | pre-push | doc-sync, got ${JSON.stringify(raw)}.`,
`run-gates: expected mode ci-primary | ci-primary-cpu | ci-primary-large-runner | ci-static | ci-lint | ci-coverage | ci-snapshot | ci-artifacts | ci-windows-blocking | ci-windows-complete | ci-windows-observational | node-compat | doc-sync, got ${JSON.stringify(raw)}.`,
)
}
}
function defaultConcurrency(selectedMode: Mode, total: number): ConcurrencyDefault {
const available = availableParallelism()
// Local modes cap workers: several doc gates each build a full ts.Program,
// The local doc mode caps workers: several gates each build a full ts.Program,
// so an uncapped default on a large host trades wall clock for memory blowups.
const localCap = selectedMode === 'pre-push' || selectedMode === 'doc-sync'
const localCap = selectedMode === 'doc-sync'
const modeLimit = localCap ? Math.min(4, available) : available
return {
workers: Math.min(total, modeLimit),
@@ -204,21 +202,6 @@ function gatesForMode(selected: Mode): Gate[] {
return ciWindowsObservationalGates()
case 'node-compat':
return nodeCompatGates()
case 'pre-push':
return [
pnpmScript('runtime-closure', 'verify-runtime-closure', { label: 'runtime closure' }),
pnpmScript('cordis-config', 'verify-cordis-config', { label: 'Cordis config' }),
pnpmScript('test', 'test'),
pnpmScript('duplication', 'duplication'),
snapshotGate(),
pnpmScript('build', 'build'),
...hygieneLeafGates({ artifactNeeds: ['build'] }),
...docSyncLeafGates({
docTypecheckNeeds: ['build'],
docTypecheckEnv: { DSH_DOC_TYPECHECK_USE_BUILD_OUTPUT: '1' },
}),
pnpmScript('module-graph', 'verify-module-graph', { label: 'module graph' }),
]
case 'doc-sync':
return docSyncLeafGates()
}
@@ -426,8 +409,8 @@ function coverageGate(): Gate {
}
// The snapshot suite boots the example bins in `lib` mode (built artifact under plain Node,
// plugins via real exports) CI and pre-push already build, so they exercise what ships rather
// than the tsx/source path dev uses. It therefore waits on `build`.
// plugins via real exports). CI normally pairs it with `build`, so it exercises what ships rather
// than the tsx/source path dev uses; callers with prebuilt output may omit that dependency.
function snapshotGate(needs: string[] = ['build']): Gate {
const lane = selectSnapshotLane(process.env.DSH_SNAPSHOT_LANE)
return pnpmExec('snapshot', [
@@ -470,21 +453,6 @@ function flagEnabled(envName: string): boolean {
return true
}
function hygieneLeafGates(options: { artifactNeeds?: string[] } = {}): Gate[] {
const artifactOptions = options.artifactNeeds === undefined ? {} : { needs: options.artifactNeeds }
return [
pnpmScript('knip', 'knip'),
pnpmScript('publint', 'publint', artifactOptions),
pnpmScript('constraints', 'constraints'),
pnpmScript('package-invariants', 'verify-package-invariants', { label: 'package invariants' }),
builtPackageInvariantsGate(options.artifactNeeds),
pnpmScript('node-next-types', 'verify-node-next-types', {
label: 'node-next types',
...artifactOptions,
}),
]
}
function docSyncLeafGates(options: {
docTypecheckNeeds?: string[]
docTypecheckEnv?: Record<string, string | undefined>