feat: complete production naming and reference lifecycle gates
This commit is contained in:
78
scripts/run-chrome-partdesign-reference-lifecycle.mjs
Normal file
78
scripts/run-chrome-partdesign-reference-lifecycle.mjs
Normal file
@@ -0,0 +1,78 @@
|
||||
import { createServer } from 'node:http'
|
||||
import { createHash } from 'node:crypto'
|
||||
import { existsSync } from 'node:fs'
|
||||
import { readFile, writeFile } from 'node:fs/promises'
|
||||
import { resolve } from 'node:path'
|
||||
import { spawn } from 'node:child_process'
|
||||
import { createChromeProfile, removeChromeProfile } from './chrome-profile.mjs'
|
||||
|
||||
const root = resolve(new URL('..', import.meta.url).pathname)
|
||||
const reportPath = resolve(root, 'config/chrome-partdesign-reference-lifecycle-verification.json')
|
||||
const evidencePaths = [
|
||||
'public/chrome-partdesign-reference-lifecycle-harness.html',
|
||||
'src/facade/externalPartDesignLinks.ts',
|
||||
'src/facade/mockFacade.ts',
|
||||
'src/facade/geometryRuntime.ts',
|
||||
'src/facade/geometryWorker.ts',
|
||||
'node_modules/@bitbybit-dev/occt/bitbybit-dev-occt/bitbybit-dev-occt.a4a6ec2a.wasm',
|
||||
]
|
||||
const collectEvidenceInputs = async () => Promise.all(evidencePaths.map(async (path) => {
|
||||
const bytes = await readFile(resolve(root, path))
|
||||
return { path, bytes: bytes.byteLength, sha256: createHash('sha256').update(bytes).digest('hex') }
|
||||
}))
|
||||
const waitForPort = (child) => new Promise((resolvePort, reject) => {
|
||||
let output = ''
|
||||
const timer = setTimeout(() => reject(new Error(`Vite did not announce a port: ${output.slice(-2000)}`)), 30_000)
|
||||
const onData = (chunk) => { output += String(chunk); const match = output.match(/http:\/\/127\.0\.0\.1:(\d+)/); if (match) { clearTimeout(timer); resolvePort(Number(match[1])) } }
|
||||
child.stdout.on('data', onData)
|
||||
child.stderr.on('data', onData)
|
||||
})
|
||||
|
||||
const vite = spawn('./nodew', ['node_modules/vite/bin/vite.js', '--host', '127.0.0.1'], { cwd: root, stdio: ['ignore', 'pipe', 'pipe'] })
|
||||
let vitePort
|
||||
try { vitePort = await waitForPort(vite) } catch (error) { vite.kill('SIGTERM'); throw error }
|
||||
let resolveReport
|
||||
const reportPromise = new Promise((resolveValue) => { resolveReport = resolveValue })
|
||||
const server = createServer(async (request, response) => {
|
||||
response.setHeader('Cross-Origin-Opener-Policy', 'same-origin')
|
||||
response.setHeader('Cross-Origin-Embedder-Policy', 'require-corp')
|
||||
response.setHeader('Cross-Origin-Resource-Policy', 'same-origin')
|
||||
if (request.method === 'POST' && request.url === '/__partdesign-reference-lifecycle-report') {
|
||||
let body = ''
|
||||
request.setEncoding('utf8')
|
||||
request.on('data', (chunk) => { body += chunk })
|
||||
request.on('end', async () => {
|
||||
const report = { ...JSON.parse(body), evidenceInputs: await collectEvidenceInputs() }
|
||||
await writeFile(reportPath, `${JSON.stringify(report, null, 2)}\n`)
|
||||
resolveReport(report)
|
||||
response.writeHead(204)
|
||||
response.end()
|
||||
})
|
||||
return
|
||||
}
|
||||
if (request.url?.startsWith('/chrome-partdesign-reference-lifecycle-harness.html')) {
|
||||
response.setHeader('content-type', 'text/html; charset=utf-8')
|
||||
response.end(await readFile(resolve(root, 'public/chrome-partdesign-reference-lifecycle-harness.html')))
|
||||
return
|
||||
}
|
||||
try {
|
||||
const upstream = await fetch(`http://127.0.0.1:${vitePort}${request.url}`, { headers: { ...request.headers } })
|
||||
response.writeHead(upstream.status, Object.fromEntries(upstream.headers.entries()))
|
||||
response.end(Buffer.from(await upstream.arrayBuffer()))
|
||||
} catch (error) { response.writeHead(502); response.end(String(error)) }
|
||||
})
|
||||
await new Promise((resolveServer) => server.listen(0, '127.0.0.1', resolveServer))
|
||||
const port = server.address().port
|
||||
const executable = process.env.CHROME_BIN || '/home/mes123456/.local/bin/google-chrome'
|
||||
if (!existsSync(executable)) throw new Error(`Chrome executable is missing: ${executable}`)
|
||||
const profile = await createChromeProfile('partdesign-reference-lifecycle')
|
||||
const chrome = spawn(executable, ['--headless=new', '--no-sandbox', '--disable-gpu', '--disable-dev-shm-usage', '--noerrdialogs', '--no-first-run', `--user-data-dir=${profile}`, `http://127.0.0.1:${port}/chrome-partdesign-reference-lifecycle-harness.html`], { cwd: root, stdio: ['ignore', 'ignore', 'ignore'] })
|
||||
const report = await Promise.race([reportPromise, new Promise((resolveTimeout) => setTimeout(() => resolveTimeout({ status: 'timeout', browserId: 'chrome' }), 180_000))])
|
||||
chrome.kill('SIGTERM')
|
||||
vite.kill('SIGTERM')
|
||||
server.closeAllConnections?.()
|
||||
server.close()
|
||||
await removeChromeProfile(profile)
|
||||
console.log(JSON.stringify(report, null, 2))
|
||||
if (report.status !== 'pass') process.exit(1)
|
||||
process.exit(0)
|
||||
Reference in New Issue
Block a user