Compare commits

...

1 Commits

Author SHA1 Message Date
Nikhil Sonti
fb845fbf7c feat(build): add build:server:ci script with --compile-only flag
Add a compile-only mode to the server build pipeline for CI/CD
environments that don't have R2 credentials. The --compile-only flag
skips resource staging and upload, producing only compiled binaries.
2026-03-26 11:15:20 -07:00
5 changed files with 50 additions and 15 deletions

View File

@@ -19,6 +19,7 @@
"start:agent": "bun ./scripts/build/controller-ext.ts && bun run --filter @browseros/agent dev",
"build": "bun run build:server && bun run build:agent && bun run build:ext",
"build:server": "FORCE_COLOR=1 bun scripts/build/server.ts --target=all",
"build:server:ci": "FORCE_COLOR=1 bun scripts/build/server.ts --target=all --compile-only",
"build:server:test": "FORCE_COLOR=1 bun scripts/build/server.ts --target=darwin-arm64 --no-upload",
"start:server:test": "bun run build:server:test && set -a && . apps/server/.env.development && set +a && dist/prod/server/.tmp/binaries/browseros-server-darwin-arm64",
"build:agent:dev": "FORCE_COLOR=1 bun run --filter @browseros/agent --elide-lines=0 build:dev",

View File

@@ -21,16 +21,24 @@ export function parseBuildArgs(argv: string[]): BuildArgs {
)
.option('--upload', 'Upload artifact zips to R2')
.option('--no-upload', 'Skip zip upload to R2')
.option(
'--compile-only',
'Compile binaries only (skip R2 staging and upload)',
)
program.parse(argv, { from: 'user' })
const options = program.opts<{
target: string
manifest: string
upload: boolean
compileOnly: boolean
}>()
const compileOnly = options.compileOnly ?? false
return {
targets: resolveTargets(options.target),
manifestPath: options.manifest,
upload: options.upload ?? true,
upload: compileOnly ? false : (options.upload ?? true),
compileOnly,
}
}

View File

@@ -74,7 +74,14 @@ function validateProductionEnv(envVars: Record<string, string>): void {
}
}
export function loadBuildConfig(rootDir: string): BuildConfig {
export interface LoadBuildConfigOptions {
compileOnly?: boolean
}
export function loadBuildConfig(
rootDir: string,
options: LoadBuildConfigOptions = {},
): BuildConfig {
const fileEnv = loadProdEnv(rootDir)
const envVars = buildInlineEnv(fileEnv)
validateProductionEnv(envVars)
@@ -85,6 +92,10 @@ export function loadBuildConfig(rootDir: string): BuildConfig {
...process.env,
}
if (options.compileOnly) {
return { version: readServerVersion(rootDir), envVars, processEnv }
}
return {
version: readServerVersion(rootDir),
envVars,

View File

@@ -15,19 +15,14 @@ export async function runProdResourceBuild(argv: string[]): Promise<void> {
process.chdir(rootDir)
const args = parseBuildArgs(argv)
const manifestPath = resolve(rootDir, args.manifestPath)
if (!existsSync(manifestPath)) {
throw new Error(`Manifest not found: ${manifestPath}`)
}
const buildConfig = loadBuildConfig(rootDir)
const manifest = loadManifest(manifestPath)
const distRoot = getDistProdRoot()
const buildConfig = loadBuildConfig(rootDir, {
compileOnly: args.compileOnly,
})
log.header(`Building BrowserOS server artifacts v${buildConfig.version}`)
log.info(`Targets: ${args.targets.map((target) => target.id).join(', ')}`)
log.info(`Manifest: ${manifestPath}`)
log.info(`Upload: ${args.upload ? 'enabled' : 'disabled'}`)
log.info(`Mode: ${args.compileOnly ? 'compile-only' : 'full'}`)
const compiled = await compileServerBinaries(
args.targets,
@@ -36,7 +31,26 @@ export async function runProdResourceBuild(argv: string[]): Promise<void> {
buildConfig.version,
)
const client = createR2Client(buildConfig.r2)
if (args.compileOnly) {
log.done('Compile-only build completed')
for (const binary of compiled) {
log.info(`${binary.target.id}: ${binary.binaryPath}`)
}
return
}
const manifestPath = resolve(rootDir, args.manifestPath)
if (!existsSync(manifestPath)) {
throw new Error(`Manifest not found: ${manifestPath}`)
}
const manifest = loadManifest(manifestPath)
const distRoot = getDistProdRoot()
const r2 = buildConfig.r2
if (!r2) {
throw new Error('R2 configuration is required for full builds')
}
const client = createR2Client(r2)
const stagedArtifacts = []
try {
@@ -51,7 +65,7 @@ export async function runProdResourceBuild(argv: string[]): Promise<void> {
binary.target,
rules,
client,
buildConfig.r2,
r2,
buildConfig.version,
)
stagedArtifacts.push(staged)
@@ -62,7 +76,7 @@ export async function runProdResourceBuild(argv: string[]): Promise<void> {
stagedArtifacts,
buildConfig.version,
client,
buildConfig.r2,
r2,
args.upload,
)

View File

@@ -21,6 +21,7 @@ export interface BuildArgs {
targets: BuildTarget[]
manifestPath: string
upload: boolean
compileOnly: boolean
}
export interface R2Config {
@@ -36,7 +37,7 @@ export interface BuildConfig {
version: string
envVars: Record<string, string>
processEnv: NodeJS.ProcessEnv
r2: R2Config
r2?: R2Config
}
export interface ResourceSource {