/** * Stage the two simulator inputs the DEFAULT bake's install path depends on: * * .celilo-website-cache/ ← modules/celilo-website/site/dist/ — what the * celilo-website-sim COPYs, i.e. where install.sh * is served from. * .npm-registry-cache/ ← bun pm pack of each @celilo/* workspace pkg — * what the npm-registry-sim COPYs, i.e. what * install.sh's `bun add -g` installs. * * `cele2e build` (cli/build.ts stageSimulatorInputs) stages these PLUS the * apt-repo and libsignal inputs, which nothing in the bake's install path * reads. The bake calls the two functions here directly so a standalone * `e2e-bake-management` re-stages exactly what it is about to install, and * not the debs too — without this, the bake reinstalls whatever tarballs the * last full build left in the cache, silently shipping a CLI without the * tree's changes (celilo#1299). * * Both are .gitignored build outputs, and both images COPY them at docker * build time — re-staging alone does nothing until the sim images are * rebuilt, which is the bake caller's job. */ import { spawnSync } from 'node:child_process'; import { cpSync, existsSync, mkdirSync, readdirSync, rmSync } from 'node:fs'; import { join } from 'node:path'; const dim = '\x1b[2m'; const green = '\x1b[32m'; const red = '\x1b[31m'; const reset = '\x1b[0m'; /** * Build the celilo-website static site and stage its dist/ into * `/.celilo-website-cache/`. Throws (does not exit) so library * callers — the bake — fail their own run with context rather than killing * the process mid-flight. */ export function stageWebsiteDist(repoRoot: string, pkgDir: string): void { const websiteSrc = join(repoRoot, 'modules', 'celilo-website', 'site'); const websiteCache = join(pkgDir, '.celilo-website-cache'); if (!existsSync(websiteSrc)) return; process.stdout.write(` ${'celilo-website (build)'.padEnd(28)} `); const t0 = Date.now(); let result = spawnSync('bun', ['install'], { cwd: websiteSrc, stdio: 'pipe' }); if (result.status !== 0) { console.log(`${red}✗${reset}`); throw new Error(`bun install in ${websiteSrc} failed:\n${result.stderr?.toString()}`); } result = spawnSync('bun', ['run', 'build'], { cwd: websiteSrc, stdio: 'pipe' }); if (result.status !== 0) { console.log(`${red}✗${reset}`); throw new Error(`bun run build in ${websiteSrc} failed:\n${result.stderr?.toString()}`); } console.log(`${green}✔${reset} ${dim}${Math.round((Date.now() - t0) / 1000)}s${reset}`); process.stdout.write(` ${'celilo-website (stage)'.padEnd(28)} `); rmSync(websiteCache, { recursive: true, force: true }); mkdirSync(websiteCache, { recursive: true }); cpSync(join(websiteSrc, 'dist'), websiteCache, { recursive: true }); console.log(`${green}✔${reset}`); } /** * Pack the @celilo/* workspace packages into `/.npm-registry-cache/` * by running scripts/pack-celilo-packages.ts, whose manifest records the tree * fingerprint the tarballs were packed from (see that script). Re-runs are * cheap and always clean the destination first, so the cache can never mix * tarballs from two trees. */ export function packNpmRegistryTarballs(repoRoot: string, pkgDir: string): void { const packScript = join(pkgDir, 'scripts', 'pack-celilo-packages.ts'); if (!existsSync(packScript)) return; process.stdout.write(` ${'npm-registry (pack)'.padEnd(28)} `); const t0 = Date.now(); const npmCache = join(pkgDir, '.npm-registry-cache'); const result = spawnSync('bun', ['run', packScript, `--dest=${npmCache}`], { cwd: repoRoot, stdio: 'pipe', }); if (result.status !== 0) { console.log(`${red}✗${reset}`); throw new Error(`pack-celilo-packages failed:\n${result.stderr?.toString()}`); } const tarballCount = existsSync(npmCache) ? readdirSync(npmCache).filter((f) => f.endsWith('.tgz')).length : 0; console.log( `${green}✔${reset} ${dim}${Math.round((Date.now() - t0) / 1000)}s, ${tarballCount} tarball(s)${reset}`, ); }