Răsfoiți Sursa

fix(ci): bound Windows process contention

Yichen Jiang 2 săptămâni în urmă
părinte
comite
4e1c87b1a2

+ 2 - 2
.agents/notes/implemented/process/2026-08-08-native-windows-pull-request-ci.i18n.yaml

@@ -2,5 +2,5 @@
 # side as of the last confirmed-consistent state. Both languages carry equal authority;
 # after editing either side, bring the other along and re-record with:
 #   pnpm run verify-translation-pairing --write .agents/notes/implemented/process/2026-08-08-native-windows-pull-request-ci.md
-2026-08-08-native-windows-pull-request-ci.md: 98f48029a86a8b07e53cd4498b27d637508e450b
-2026-08-08-native-windows-pull-request-ci.zh.md: b2dba91e4a88d0da637521aae2de937672b869a3
+2026-08-08-native-windows-pull-request-ci.md: 8faec10fdc8538c994954213ac477a2ed52e800c
+2026-08-08-native-windows-pull-request-ci.zh.md: f692aa85e33e2e02d04cd72d9316ed4fc139aced

Fișier diff suprimat deoarece este prea mare
+ 2 - 2
.agents/notes/implemented/process/2026-08-08-native-windows-pull-request-ci.md


Fișier diff suprimat deoarece este prea mare
+ 2 - 2
.agents/notes/implemented/process/2026-08-08-native-windows-pull-request-ci.zh.md


+ 1 - 1
.github/workflows/ci.yml

@@ -452,7 +452,7 @@ jobs:
     timeout-minutes: 120
     env:
       DSH_COVERAGE_MAX_WORKERS: '6'
-      DSH_COVERAGE_PARTITIONS: '6'
+      DSH_COVERAGE_PARTITIONS: '4'
       DSH_COVERAGE_TEST_TIMEOUT_MS: '30000'
       DSH_GATE_CONCURRENCY: '3'
     steps:

+ 3 - 1
packages/session/session-persistence-sqlite/tests/differential.spec.ts

@@ -193,6 +193,8 @@ const randomWorkload = fc.record({
   batchSizes,
 }))
 
+const randomizedDifferentialTimeoutMs = process.platform === 'win32' ? 120_000 : 60_000
+
 describe('SQLite cross-backend differential behavior', () => {
   it('matches JSONL/Zstandard for every packed kind, scalar fallback, suffix, partition, and reopen', async () => {
     const events = packingMatrixLog()
@@ -232,6 +234,6 @@ describe('SQLite cross-backend differential behavior', () => {
         await verifyBackend(name, join(directory, name), events, batchSizes)
       }
     }), { numRuns: 100, seed: 0x5A17E })
-  }, 60_000)
+  }, randomizedDifferentialTimeoutMs)
 
 })

+ 2 - 2
scripts/ci-workflow.spec.ts

@@ -98,9 +98,9 @@ describe('CI workflow', () => {
     ))
     expect(buildCommands.map(step => step.run)).toContain('pnpm run check:ci:windows-blocking')
 
-    // windows-coverage runs the 6-partition profile.
+    // windows-coverage uses the lower 4-partition profile.
     expect(windowsCoverage.name).toBe('windows node 24 / coverage')
-    expect(windowsCoverage.env).toMatchObject({ DSH_COVERAGE_PARTITIONS: '6' })
+    expect(windowsCoverage.env).toMatchObject({ DSH_COVERAGE_PARTITIONS: '4' })
     const coverageSteps = windowsCoverage.steps as unknown[]
     const coverageCommands = coverageSteps.filter((step): step is Record<string, unknown> & { run: string } => (
       isRecord(step) && typeof step.run === 'string'

+ 14 - 0
scripts/run-gates.spec.ts

@@ -194,6 +194,20 @@ describe('gate graph validation', () => {
     }
   })
 
+  it('runs the Windows built-bin smoke after other observational gates settle', () => {
+    const observational = withPnpmEntrypoint(() => gatesForMode('ci-windows-observational'))
+    const builtBin = observational.find(gate => gate.id === 'built-bin-smoke')
+
+    expect(builtBin?.after).toEqual(
+      observational.filter(gate => gate.id !== 'built-bin-smoke').map(gate => gate.id),
+    )
+
+    const completeBuiltBin = withPnpmEntrypoint(() => gatesForMode('ci-windows-complete'))
+      .find(gate => gate.id === 'built-bin-smoke')
+    expect(completeBuiltBin?.after).toContain('windows-site')
+    expect(completeBuiltBin?.after).not.toContain('docs-site-build')
+  })
+
   it('applies one configured test and polling timeout to both coverage gates', () => {
     const gates = withEnv('DSH_COVERAGE_TEST_TIMEOUT_MS', '15000', () =>
       withPnpmEntrypoint(() => gatesForMode('ci-windows-complete')))

+ 14 - 3
scripts/run-gates.ts

@@ -507,7 +507,10 @@ function ciWindowsCompleteGates(): Gate[] {
     .map(gate => ({
       ...gate,
       allowFailure: true,
-      after: [...new Set([...coverageAfter, ...(gate.after ?? [])])],
+      after: [...new Set([
+        ...coverageAfter,
+        ...(gate.after ?? []).map(id => id === 'docs-site-build' ? 'windows-site' : id),
+      ])],
     }))
   return [
     ciBuildGate(),
@@ -518,7 +521,7 @@ function ciWindowsCompleteGates(): Gate[] {
 }
 
 function ciWindowsObservationalGates(): Gate[] {
-  return [
+  const predecessors = [
     ...ciStaticGates({ ownsBuild: true }),
     // Linux owns required lint and snapshots; Windows omits those duplicates.
     pnpmScript('duplication', 'duplication'),
@@ -528,7 +531,15 @@ function ciWindowsObservationalGates(): Gate[] {
       needs: ['build'],
     }),
     builtPackageInvariantsGate(['build']),
-    builtBinSmokeGate(),
+  ]
+  return [
+    ...predecessors,
+    {
+      ...builtBinSmokeGate(),
+      // This smoke starts real application children with bounded startup
+      // deadlines. Let other Windows processes settle before measuring startup.
+      after: predecessors.map(gate => gate.id),
+    },
   ]
 }
 

Unele fișiere nu au fost afișate deoarece prea multe fișiere au fost modificate în acest diff