mirror of
https://github.com/deepseek-ai/deepseek-harness
synced 2026-08-15 21:04:50 +00:00
fix(typert): prepare remote contracts for source gates
This commit is contained in:
@@ -60,6 +60,7 @@ describe('gate graph validation', () => {
|
||||
'ci-linux-primary',
|
||||
'ci-static',
|
||||
'ci-lint',
|
||||
'ci-lint-contracts-ready',
|
||||
'ci-coverage',
|
||||
'ci-snapshot',
|
||||
'ci-artifacts',
|
||||
@@ -141,6 +142,57 @@ describe('Oxlint gate', () => {
|
||||
})
|
||||
})
|
||||
|
||||
describe('TypeRT contract preparation', () => {
|
||||
it('prepares primary source consumers once before they run', () => {
|
||||
const subject = withPnpmEntrypoint(() => gatesForMode('ci-primary'))
|
||||
|
||||
expect(subject.find(item => item.id === 'typert-contracts')).toMatchObject({
|
||||
displayCommand: 'pnpm run build:lib:host',
|
||||
args: ['/private/pnpm.cjs', 'run', 'build:lib:host'],
|
||||
})
|
||||
for (const [id, script] of [
|
||||
['typecheck', 'typecheck:contracts-ready'],
|
||||
['lint', 'lint:contracts-ready'],
|
||||
['doc-typecheck', 'doc-typecheck:contracts-ready'],
|
||||
] as const) {
|
||||
expect(subject.find(item => item.id === id)).toMatchObject({
|
||||
displayCommand: `pnpm run ${script}`,
|
||||
args: ['/private/pnpm.cjs', 'run', script],
|
||||
needs: ['typert-contracts'],
|
||||
})
|
||||
}
|
||||
expect(subject.find(item => item.id === 'build')?.needs).toEqual([
|
||||
'typecheck',
|
||||
'lint',
|
||||
'doc-typecheck',
|
||||
])
|
||||
})
|
||||
|
||||
it('reuses contracts from the validated consumer build', () => {
|
||||
const subject = withPnpmEntrypoint(() => gatesForMode('ci-consumers'))
|
||||
|
||||
expect(subject.find(item => item.id === 'lint-and-duplication')).toMatchObject({
|
||||
displayCommand: 'pnpm run check:ci:lint:contracts-ready',
|
||||
args: ['/private/pnpm.cjs', 'run', 'check:ci:lint:contracts-ready'],
|
||||
})
|
||||
expect(subject.find(item => item.id === 'doc-typecheck')).toMatchObject({
|
||||
displayCommand: 'pnpm run doc-typecheck:contracts-ready',
|
||||
args: ['/private/pnpm.cjs', 'run', 'doc-typecheck:contracts-ready'],
|
||||
})
|
||||
})
|
||||
|
||||
it('keeps standalone aggregates responsible for preparation', () => {
|
||||
const lint = withPnpmEntrypoint(() => gatesForMode('ci-lint')[0])
|
||||
const preparedLint = withPnpmEntrypoint(() => gatesForMode('ci-lint-contracts-ready')[0])
|
||||
const docTypecheck = withPnpmEntrypoint(() =>
|
||||
gatesForMode('doc-sync').find(item => item.id === 'doc-typecheck'))
|
||||
|
||||
expect(lint?.displayCommand).toBe('pnpm run lint')
|
||||
expect(preparedLint?.displayCommand).toBe('pnpm run lint:contracts-ready')
|
||||
expect(docTypecheck?.displayCommand).toBe('pnpm run doc-typecheck')
|
||||
})
|
||||
})
|
||||
|
||||
describe('Node compatibility graph', () => {
|
||||
it('runs the jsdom environment smoke on every advertised Node line', () => {
|
||||
const subject = withPnpmEntrypoint(() => gatesForMode('node-compat'))
|
||||
|
||||
@@ -17,6 +17,7 @@ export type Mode =
|
||||
| 'ci-linux-primary'
|
||||
| 'ci-static'
|
||||
| 'ci-lint'
|
||||
| 'ci-lint-contracts-ready'
|
||||
| 'ci-coverage'
|
||||
| 'ci-snapshot'
|
||||
| 'ci-artifacts'
|
||||
@@ -102,6 +103,7 @@ function parseMode(raw: string | undefined): Mode {
|
||||
case 'ci-linux-primary':
|
||||
case 'ci-static':
|
||||
case 'ci-lint':
|
||||
case 'ci-lint-contracts-ready':
|
||||
case 'ci-coverage':
|
||||
case 'ci-snapshot':
|
||||
case 'ci-artifacts':
|
||||
@@ -115,7 +117,7 @@ function parseMode(raw: string | undefined): Mode {
|
||||
return raw
|
||||
default:
|
||||
throw new Error(
|
||||
`run-gates: expected mode ci-primary | ci-linux-primary | ci-static | ci-lint | ci-coverage | ci-snapshot | ci-artifacts | ci-consumers | ci-windows-blocking | ci-windows-complete | ci-windows-observational | node-compat | check-all | doc-sync, got ${JSON.stringify(raw)}.`,
|
||||
`run-gates: expected mode ci-primary | ci-linux-primary | ci-static | ci-lint | ci-lint-contracts-ready | ci-coverage | ci-snapshot | ci-artifacts | ci-consumers | ci-windows-blocking | ci-windows-complete | ci-windows-observational | node-compat | check-all | doc-sync, got ${JSON.stringify(raw)}.`,
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -202,6 +204,11 @@ export function gatesForMode(selected: Mode): Gate[] {
|
||||
lintGate(),
|
||||
pnpmScript('duplication', 'duplication'),
|
||||
]
|
||||
case 'ci-lint-contracts-ready':
|
||||
return [
|
||||
lintGate({ contractsReady: true }),
|
||||
pnpmScript('duplication', 'duplication'),
|
||||
]
|
||||
case 'ci-coverage':
|
||||
return coverageGates()
|
||||
case 'ci-snapshot':
|
||||
@@ -233,6 +240,7 @@ export function gatesForMode(selected: Mode): Gate[] {
|
||||
...docSyncLeafGates({
|
||||
docTypecheckNeeds: ['build'],
|
||||
docTypecheckEnv: { DSH_DOC_TYPECHECK_USE_BUILD_OUTPUT: '1' },
|
||||
docTypecheckScript: 'doc-typecheck:contracts-ready',
|
||||
}),
|
||||
pnpmScript('module-graph', 'verify-module-graph', { label: 'module graph' }),
|
||||
]
|
||||
@@ -254,19 +262,23 @@ function ciSharedStaticGates(): Gate[] {
|
||||
function ciPrimaryGates(): Gate[] {
|
||||
return [
|
||||
...ciSharedStaticGates(),
|
||||
pnpmScript('typecheck', 'typecheck'),
|
||||
lintGate(),
|
||||
typertContractsGate(),
|
||||
pnpmScript('typecheck', 'typecheck:contracts-ready', { needs: ['typert-contracts'] }),
|
||||
lintGate({ contractsReady: true, needs: ['typert-contracts'] }),
|
||||
pnpmScript('duplication', 'duplication'),
|
||||
...coverageGates(),
|
||||
...nodeCompatSmokeGates(),
|
||||
snapshotGate(),
|
||||
...docSyncLeafGates(),
|
||||
...docSyncLeafGates({
|
||||
docTypecheckNeeds: ['typert-contracts'],
|
||||
docTypecheckScript: 'doc-typecheck:contracts-ready',
|
||||
}),
|
||||
pnpmScript('module-graph', 'verify-module-graph', { label: 'module graph' }),
|
||||
pnpmScript('knip', 'knip'),
|
||||
// typecheck and build both drive the Host and Client tsc graphs; without
|
||||
// the dependency concurrent runs race the same tsbuildinfo files.
|
||||
// The tsc step is an incremental no-op after typecheck.
|
||||
pnpmScript('build', 'build', { needs: ['typecheck'] }),
|
||||
// The prepared typecheck and build both drive Client tsc, while build also
|
||||
// repeats the Host contract pass. Wait for all three consumers so build
|
||||
// neither races tsbuildinfo nor replaces declarations while they are read.
|
||||
pnpmScript('build', 'build', { needs: ['typecheck', 'lint', 'doc-typecheck'] }),
|
||||
pnpmScript('publint', 'publint', { needs: ['build'] }),
|
||||
pnpmScript('node-next-types', 'verify-node-next-types', {
|
||||
label: 'node-next types',
|
||||
@@ -355,6 +367,7 @@ function ciStaticGates(options: { ownsBuild: boolean }): Gate[] {
|
||||
? {
|
||||
docTypecheckNeeds: ['build'],
|
||||
docTypecheckEnv: { DSH_DOC_TYPECHECK_USE_BUILD_OUTPUT: '1' },
|
||||
docTypecheckScript: 'doc-typecheck:contracts-ready',
|
||||
}
|
||||
: {},
|
||||
docsBuildScript: 'docs:build:mpa',
|
||||
@@ -385,13 +398,13 @@ function ciConsumerGates(): Gate[] {
|
||||
pnpmScript('node-compat', 'check:node-compat', { label: 'Node compatibility' }),
|
||||
pnpmScript('publint', 'publint', { needs: builtTree }),
|
||||
builtPackageInvariantsGate(['publint']),
|
||||
pnpmScript('lint-and-duplication', 'check:ci:lint', {
|
||||
pnpmScript('lint-and-duplication', 'check:ci:lint:contracts-ready', {
|
||||
label: 'lint and duplication',
|
||||
needs: validatedBuild,
|
||||
}),
|
||||
snapshotGate(validatedBuild),
|
||||
webSnapshotGate(validatedBuild),
|
||||
pnpmScript('doc-typecheck', 'doc-typecheck', {
|
||||
pnpmScript('doc-typecheck', 'doc-typecheck:contracts-ready', {
|
||||
needs: validatedBuild,
|
||||
env: { DSH_DOC_TYPECHECK_USE_BUILD_OUTPUT: '1' },
|
||||
}),
|
||||
@@ -447,11 +460,19 @@ function ciWindowsObservationalGates(): Gate[] {
|
||||
]
|
||||
}
|
||||
|
||||
function lintGate(): Gate {
|
||||
function typertContractsGate(): Gate {
|
||||
return pnpmScript('typert-contracts', 'build:lib:host', { label: 'TypeRT contracts' })
|
||||
}
|
||||
|
||||
function lintGate(options: { contractsReady?: boolean; needs?: string[] } = {}): Gate {
|
||||
const raw = process.env.DSH_OXLINT_THREADS
|
||||
return pnpmScript('lint', 'lint', raw === undefined || raw === ''
|
||||
? {}
|
||||
: { displayCommand: `DSH_OXLINT_THREADS=${raw} pnpm run lint` })
|
||||
const script = options.contractsReady === true ? 'lint:contracts-ready' : 'lint'
|
||||
return pnpmScript('lint', script, {
|
||||
...raw === undefined || raw === ''
|
||||
? {}
|
||||
: { displayCommand: `DSH_OXLINT_THREADS=${raw} pnpm run ${script}` },
|
||||
...options.needs === undefined ? {} : { needs: options.needs },
|
||||
})
|
||||
}
|
||||
|
||||
// The heavy suites run uninstrumented beside the thresholded gate: their
|
||||
@@ -554,6 +575,7 @@ function docSyncLeafGates(options: {
|
||||
includeDocTypecheck?: boolean
|
||||
docTypecheckNeeds?: string[]
|
||||
docTypecheckEnv?: Record<string, string | undefined>
|
||||
docTypecheckScript?: 'doc-typecheck' | 'doc-typecheck:contracts-ready'
|
||||
docsBuildScript?: 'docs:build' | 'docs:build:mpa'
|
||||
} = {}): Gate[] {
|
||||
const docTypecheckOptions: Partial<Gate> = {}
|
||||
@@ -562,7 +584,7 @@ function docSyncLeafGates(options: {
|
||||
return [
|
||||
...options.includeDocTypecheck === false
|
||||
? []
|
||||
: [pnpmScript('doc-typecheck', 'doc-typecheck', docTypecheckOptions)],
|
||||
: [pnpmScript('doc-typecheck', options.docTypecheckScript ?? 'doc-typecheck', docTypecheckOptions)],
|
||||
pnpmScript('cordis-catalog', 'verify-cordis-catalog', { label: 'cordis catalog' }),
|
||||
pnpmScript('export-jsdoc', 'verify-export-jsdoc', { label: 'export jsdoc' }),
|
||||
pnpmScript('tool-catalog', 'verify-tool-catalog', { label: 'tool catalog' }),
|
||||
|
||||
Reference in New Issue
Block a user