@ -1,10 +1,10 @@
import { spawnSync } from 'node:child_process'
import { spawnSync } from 'node:child_process'
import { readFile } from 'node:fs/promises'
import { readFile } from 'node:fs/promises'
import { createServer , type Server } from 'node:http'
import { createServer , type Server } from 'node:http'
import type { AddressInfo } from 'node:net'
import { extname , join , resolve } from 'node:path'
import { extname , join , resolve } from 'node:path'
import { fileURLToPath } from 'node:url'
import { fileURLToPath } from 'node:url'
import getPort from 'get-port'
import { chromium , type BrowserServer } from 'playwright-chromium'
import { chromium , type BrowserServer } from 'playwright-chromium'
import { ALT_PREFIX , SUB_PREFIX } from './constants'
import { ALT_PREFIX , SUB_PREFIX } from './constants'
@ -23,8 +23,9 @@ const types: Record<string, string> = {
'.zip' : 'application/zip'
'.zip' : 'application/zip'
}
}
// listens on an os-assigned port (the other suites run in parallel on CI,
// so a pre-picked "free" port can be taken before we bind it)
function serveStatic (
function serveStatic (
port : number ,
mounts : [ prefix : string , root : string ] [ ] ,
mounts : [ prefix : string , root : string ] [ ] ,
cors : boolean
cors : boolean
) : Promise < Server > {
) : Promise < Server > {
@ -48,18 +49,19 @@ function serveStatic(
res . writeHead ( 404 )
res . writeHead ( 404 )
res . end ( 'not found' )
res . end ( 'not found' )
} )
} )
return new Promise ( ( r ) = > server . listen ( port , ( ) = > r ( server ) ) )
return new Promise ( ( r ) = > server . listen ( 0 , ( ) = > r ( server ) ) )
}
}
const portOf = ( server : Server ) = > ( server . address ( ) as AddressInfo ) . port
let browserServer : BrowserServer
let browserServer : BrowserServer
let servers : Server [ ] = [ ]
let servers : Server [ ] = [ ]
export async function setup() {
export async function setup() {
const [ subPort , pagesPort , cdnPort ] = await Promise . all ( [
// the cdn server starts before its dist exists (requests just 404 until
getPort ( ) ,
// the build lands) so the real port can be baked into assetsBase
getPort ( ) ,
const cdnServer = await serveStatic ( [ [ '/' , dist ( 'cdn' ) ] ] , true )
getPort ( )
const cdnPort = portOf ( cdnServer )
] )
// each flavor builds in its own process: the markdown renderer is a
// each flavor builds in its own process: the markdown renderer is a
// process-wide singleton, so sequential in-process builds would leak the
// process-wide singleton, so sequential in-process builds would leak the
@ -82,15 +84,14 @@ export async function setup() {
servers = [
servers = [
// one relative-base build mounted at two unrelated prefixes
// one relative-base build mounted at two unrelated prefixes
await serveStatic (
await serveStatic (
subPort ,
[
[
[ SUB_PREFIX , dist ( 'relative' ) ] ,
[ SUB_PREFIX , dist ( 'relative' ) ] ,
[ ALT_PREFIX , dist ( 'relative' ) ]
[ ALT_PREFIX , dist ( 'relative' ) ]
] ,
] ,
false
false
) ,
) ,
await serveStatic ( pagesPort , [ [ '/' , dist ( 'cdn' ) ] ] , false ) ,
await serveStatic ( [ [ '/' , dist ( 'cdn' ) ] ] , false ) ,
await serveStatic ( cdnPort , [ [ '/' , dist ( 'cdn' ) ] ] , true )
cdnServer
]
]
browserServer = await chromium . launchServer ( {
browserServer = await chromium . launchServer ( {
@ -101,8 +102,8 @@ export async function setup() {
} )
} )
process . env [ 'WS_ENDPOINT' ] = browserServer . wsEndpoint ( )
process . env [ 'WS_ENDPOINT' ] = browserServer . wsEndpoint ( )
process . env [ 'SUB_PORT' ] = String ( subPort )
process . env [ 'SUB_PORT' ] = String ( portOf( servers [ 0 ] ! ) )
process . env [ 'PAGES_PORT' ] = String ( p agesP ort)
process . env [ 'PAGES_PORT' ] = String ( p ortOf( servers [ 1 ] ! ) )
process . env [ 'VP_CDN_PORT' ] = String ( cdnPort )
process . env [ 'VP_CDN_PORT' ] = String ( cdnPort )
}
}