Skip to content

scripts/build-info.mjs

22 lines · 1.8 KB · JavaScript
Raw
// Writes app/build-info.ts: a content hash of the app + assets (the cache/update version),
// the git commit the build was made from, and the build time.
import { createHash } from 'node:crypto'
import { readFileSync, readdirSync, statSync, writeFileSync } from 'node:fs'
import { execSync } from 'node:child_process'
import { join } from 'node:path'
const files = []
const walk = (d) => { for (const f of readdirSync(d).sort()) { const p = join(d, f); statSync(p).isDirectory() ? walk(p) : files.push(p) } }
walk('app'); walk('public')
// Embed public/ files into app/assets.ts so the router serves them itself (no separate asset host).
const types = { '.png': 'image/png', '.jpg': 'image/jpeg', '.svg': 'image/svg+xml' }
const assets = {}
for (const f of files) if (f.startsWith('public' + '/')) { const ext = f.slice(f.lastIndexOf('.')); if (types[ext]) assets[f.slice('public'.length)] = { type: types[ext], b64: readFileSync(f).toString('base64') } }
writeFileSync('app/assets.ts', '// Generated by scripts/build-info.mjs from public/. Do not edit by hand.\nexport const ASSETS: Record<string, { type: string; b64: string }> = ' + JSON.stringify(assets) + '\n')
const h = createHash('sha256')
for (const f of files) if (f !== join('app', 'build-info.ts') && f !== join('app', 'assets.ts')) h.update(f).update(readFileSync(f))
const buildId = h.digest('hex').slice(0, 12)
let sourceCommit = ''
try { sourceCommit = execSync('git rev-parse HEAD', { stdio: ['ignore', 'pipe', 'ignore'] }).toString().trim() } catch {}
const builtAt = process.env.BUILD_TIME || new Date().toISOString()
writeFileSync('app/build-info.ts', `// Generated by scripts/build-info.mjs. Do not edit by hand.\nexport const BUILD = ${JSON.stringify({ buildId, sourceCommit, builtAt }, null, '\t')} as const\n`)
console.log('build', buildId, 'from', sourceCommit.slice(0, 7), 'at', builtAt)