mirror of
https://github.com/stablyai/orca.git
synced 2026-10-31 00:57:45 +00:00
Cache mobile typechecks and overlap CI setup (#28192)
* ci: run mobile runtime test groups on separate runners * ci: use a lightweight runner for the mobile result gate * ci: distribute Bun tests across both mobile runners * ci: reuse mobile compiler state without adding runner queues * test: verify eviction of source variants in one cache bucket * test: baseline existing serializer limits in the capacity capture
This commit is contained in:
@@ -0,0 +1,47 @@
|
||||
import { existsSync, mkdtempSync, realpathSync, writeFileSync, unlinkSync } from 'node:fs'
|
||||
import { tmpdir } from 'node:os'
|
||||
import { join } from 'node:path'
|
||||
import { expect, it, vi } from 'vitest'
|
||||
import { removeTreeSync } from '../../src/shared/windows-transient-lock-removal'
|
||||
import { collectTypecheckPass, findTsNocheckFiles } from './check-tests-typecheck-ratchet.mjs'
|
||||
|
||||
it('rechecks changed types, diagnostics and test membership with incremental state', () => {
|
||||
const root = realpathSync(mkdtempSync(join(tmpdir(), 'orca-mobile-typecheck-')))
|
||||
const cache = join(root, '.cache')
|
||||
vi.stubEnv('ORCA_MOBILE_TYPECHECK_CACHE_DIR', cache)
|
||||
try {
|
||||
writeFileSync(
|
||||
join(root, 'tsconfig.test.json'),
|
||||
JSON.stringify({
|
||||
compilerOptions: { strict: true, skipLibCheck: true, types: [], target: 'ES2022' },
|
||||
include: ['*.ts']
|
||||
})
|
||||
)
|
||||
writeFileSync(join(root, 'model.ts'), 'export interface Shape { value: number }')
|
||||
const test = join(root, 'value.test.ts')
|
||||
const source = "import type { Shape } from './model'; const shape: Shape = { value: 1 }"
|
||||
writeFileSync(test, source)
|
||||
const clean = collectTypecheckPass(root)
|
||||
expect(clean).toEqual({ failing: [], programTestFiles: ['value.test.ts'] })
|
||||
expect(existsSync(join(cache, 'tests.tsbuildinfo'))).toBe(true)
|
||||
expect(collectTypecheckPass(root)).toEqual(clean)
|
||||
|
||||
writeFileSync(join(root, 'model.ts'), 'export interface Shape { value: string }')
|
||||
const failed = collectTypecheckPass(root)
|
||||
expect(failed.failing).toEqual(['value.test.ts'])
|
||||
expect(collectTypecheckPass(root)).toEqual(failed)
|
||||
|
||||
writeFileSync(join(root, 'new.test.ts'), 'export const value: number = 1')
|
||||
expect(collectTypecheckPass(root).programTestFiles).toEqual(['new.test.ts', 'value.test.ts'])
|
||||
writeFileSync(test, `// @ts-nocheck\n${source}`)
|
||||
const nocheck = collectTypecheckPass(root)
|
||||
expect(nocheck.failing).toEqual([])
|
||||
expect(findTsNocheckFiles(root, nocheck.programTestFiles)).toEqual(['value.test.ts'])
|
||||
|
||||
unlinkSync(test)
|
||||
expect(collectTypecheckPass(root)).toEqual({ failing: [], programTestFiles: ['new.test.ts'] })
|
||||
} finally {
|
||||
vi.unstubAllEnvs()
|
||||
removeTreeSync(root)
|
||||
}
|
||||
}, 15_000)
|
||||
@@ -1,4 +1,4 @@
|
||||
import { spawnSync } from 'node:child_process'
|
||||
import { runProcessSync } from '@orca/process-host'
|
||||
import fs from 'node:fs'
|
||||
import { createRequire } from 'node:module'
|
||||
import path from 'node:path'
|
||||
@@ -148,22 +148,26 @@ export function diffBaseline(current, baseline) {
|
||||
// script: on Windows the shim is tsc.CMD and an extensionless path gets .exe appended.
|
||||
function runTsc(root, args) {
|
||||
const entry = createRequire(import.meta.url).resolve('typescript/lib/tsc.js')
|
||||
const result = spawnSync(process.execPath, [entry, ...args], {
|
||||
return runProcessSync({
|
||||
program: process.execPath,
|
||||
args: [entry, ...args],
|
||||
cwd: root,
|
||||
encoding: 'utf8',
|
||||
shell: false,
|
||||
maxBuffer: 64 * 1024 * 1024
|
||||
timeoutMs: null,
|
||||
maxOutputBytes: 64 * 1024 * 1024
|
||||
})
|
||||
if (result.error) {
|
||||
throw result.error
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
// tsc exits non-zero on type errors, which is the expected state here, so only a crash is fatal.
|
||||
// One pass answers both questions: --listFiles names the program, the diagnostics name the failures.
|
||||
export function collectTypecheckPass(root = process.cwd()) {
|
||||
const result = runTsc(root, ['--noEmit', '--listFiles', '-p', PROJECT])
|
||||
const cache = process.env.ORCA_MOBILE_TYPECHECK_CACHE_DIR
|
||||
const result = runTsc(root, [
|
||||
'--noEmit',
|
||||
'--listFiles',
|
||||
'-p',
|
||||
PROJECT,
|
||||
...(cache ? ['--incremental', '--tsBuildInfoFile', path.join(cache, 'tests.tsbuildinfo')] : [])
|
||||
])
|
||||
const output = `${result.stdout ?? ''}${result.stderr ?? ''}`
|
||||
return {
|
||||
failing: parseFailingFiles(output),
|
||||
|
||||
Reference in New Issue
Block a user