Files
BrowserOS/packages/browseros-agent/scripts/build/cli.ts
Nikhil 6c053a5f29 feat: upload CLI binaries to CDN and gate release to core team (#602)
* feat: upload CLI binaries to CDN during release and gate workflow to core team

- Extend scripts/build/cli/upload.ts with uploadCliRelease() that pushes
  archives + checksums to R2 under versioned (cli/v{VERSION}/) and latest
  (cli/latest/) paths, plus a version.txt for lightweight latest resolution
- Update scripts/build/cli.ts entry point with --release/--version/--binaries-dir
  flags (existing no-args behavior preserved for upload:cli-installers)
- Rewrite install.sh and install.ps1 to fetch from cdn.browseros.com instead of
  GitHub releases API — eliminates rate limits and API dependency
- Add environment: release-core to release-cli.yml for core-team gating via
  GitHub environment protection rules
- Add Bun setup + CDN upload step to the workflow between build and GitHub release

* fix: address review feedback for PR #602

- Make loadProdEnv return empty map when .env.production is absent so
  pickEnv falls through to process.env in CI (Greptile P1)
- Add semver format validation for version string in install.sh and
  install.ps1 to guard against malformed CDN responses
- Pass inputs.version via env var instead of inline ${{ }} interpolation
  to prevent command injection in workflow shell
2026-03-27 11:47:31 -07:00

48 lines
1.2 KiB
TypeScript

#!/usr/bin/env bun
import { Command } from 'commander'
import { runCliInstallerUpload, runCliRelease } from './cli/upload'
const program = new Command('cli-upload')
.description('Upload BrowserOS CLI artifacts to CDN')
.option(
'--release',
'Upload full release (binaries + installers + version.txt)',
)
.option('--version <version>', 'Release version (required with --release)')
.option(
'--binaries-dir <dir>',
'Directory containing built archives (required with --release)',
)
.parse()
const opts = program.opts<{
release?: boolean
version?: string
binariesDir?: string
}>()
async function main(): Promise<void> {
if (opts.release) {
if (!opts.version) {
throw new Error('--version is required with --release')
}
if (!opts.binariesDir) {
throw new Error('--binaries-dir is required with --release')
}
await runCliRelease({
version: opts.version,
binariesDir: opts.binariesDir,
})
} else {
await runCliInstallerUpload()
}
}
main().catch((error) => {
const message = error instanceof Error ? error.message : String(error)
console.error(`\n✗ ${message}\n`)
process.exit(1)
})