import { execSync } from 'child_process'; import { readFileSync } from 'fs'; import { resolve, dirname } from 'path'; import { fileURLToPath } from 'url'; import process from 'process'; const __dirname = dirname(fileURLToPath(import.meta.url)); const ROOT = resolve(__dirname, '..'); // colors const G = (s) => `\x1b[0;32m${s}\x1b[0m`; const Y = (s) => `\x1b[1;33m${s}\x1b[0m`; const R = (s) => `\x1b[0;31m${s}\x1b[0m`; const log = (msg) => console.log(`${G('[OK]')} ${msg}`); const warn = (msg) => console.warn(`${Y('[WARN]')} ${msg}`); const err = (msg) => { console.error(`${R('[ERR]')} ${msg}`); process.exit(1); }; const cmd = (...args) => execSync(args.join(' '), { cwd: ROOT, stdio: 'inherit' }); const exists = (c) => { try { execSync(`which ${c}`, { stdio: 'pipe' }); return true; } catch { return false; } }; // ── 1. Rust ── if (exists('rustc')) { log(`Rust ${execSync('rustc --version', { encoding: 'utf8' }).trim()}`); } else { warn('Rust not found, installing via rustup...'); execSync('curl --proto "=https" --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y', { stdio: 'inherit' }); } // ── 2. Node.js ── if (exists('node')) { log(`Node.js ${execSync('node --version', { encoding: 'utf8' }).trim()}`); } else { warn('Node.js not found, install manually or via nvm'); } // ── 3. Bun ── if (exists('bun')) { log(`Bun ${execSync('bun --version', { encoding: 'utf8' }).trim()}`); } else { warn('Bun not found, installing...'); execSync('curl -fsSL https://bun.sh/install | bash', { stdio: 'inherit' }); } // ── 4. Docker ── if (exists('docker')) { log(`Docker ${execSync('docker --version', { encoding: 'utf8' }).trim()}`); } else { warn('Docker not found, installing...'); execSync('curl -fsSL https://get.docker.com | sh', { stdio: 'inherit' }); } // ── 5. Frontend build ── log('Running bun install...'); cmd('bun', 'install'); log('Running bun run build...'); cmd('bun', 'run', 'build'); // ── 6. Rust release build ── log('Running cargo build --release --workspace...'); cmd('cargo', 'build', '--release', '--workspace'); // ── 7. Docker images ── const tag = execSync('git rev-parse --short HEAD', { encoding: 'utf8', cwd: ROOT }).trim(); log(`Building Docker images with tag: ${tag}`); const images = [ ['docker/app.Dockerfile', `app:${tag}`], ['docker/email.Dockerfile', `email-worker:${tag}`], ['docker/githook.Dockerfile', `git-hook:${tag}`], ['docker/gitserver.Dockerfile', `gitserver:${tag}`], ['docker/metrics.Dockerfile', `metrics-aggregator:${tag}`], ['docker/static.Dockerfile', `static-server:${tag}`], ['docker/gingress.Dockerfile', `gingress:${tag}`], ]; for (const [df, t] of images) { log(`Building ${t}...`); execSync(`docker build -f "${df}" -t "${t}" .`, { cwd: ROOT, stdio: 'inherit' }); } log('All images built successfully.');