Skip to content

Commit d1db522

Browse files
chore: update the build cache logic for cache friendly build, for a pr safety build check
1 parent 3a03523 commit d1db522

1 file changed

Lines changed: 29 additions & 6 deletions

File tree

scripts/build.ts

Lines changed: 29 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ function countMdFiles(dir: string): number {
9494
return count
9595
}
9696

97-
/** Compute a fast hash of a directory's file mtimes + sizes for change detection */
97+
/** Compute a stable content hash for change detection across fresh checkouts. */
9898
function hashDir(dir: string): string {
9999
const h = createHash('sha256')
100100
function walk(d: string) {
@@ -104,15 +104,36 @@ function hashDir(dir: string): string {
104104
if (e.name.startsWith('.')) continue
105105
const full = join(d, e.name)
106106
if (e.isDirectory()) { walk(full); continue }
107-
const s = statSync(full)
108-
h.update(`${relative(dir, full)}:${s.size}:${s.mtimeMs}\n`)
107+
h.update(`file:${relative(dir, full)}\n`)
108+
h.update(readFileSync(full))
109+
h.update('\n')
109110
}
110111
} catch { /* ignore */ }
111112
}
112113
walk(dir)
113114
return h.digest('hex').substring(0, 16)
114115
}
115116

117+
function hashFile(path: string): string {
118+
const h = createHash('sha256')
119+
if (!existsSync(path)) return ''
120+
h.update(readFileSync(path))
121+
return h.digest('hex').substring(0, 16)
122+
}
123+
124+
function hashBuildInputs(): string {
125+
const h = createHash('sha256')
126+
for (const [label, value] of [
127+
['site', hashDir(MAIN_VP)],
128+
['package', hashFile(join(PROJECT_ROOT, 'package.json'))],
129+
['lockfile', hashFile(join(PROJECT_ROOT, 'pnpm-lock.yaml'))],
130+
['build-script', hashFile(join(PROJECT_ROOT, 'scripts', 'build.ts'))],
131+
]) {
132+
h.update(`${label}:${value}\n`)
133+
}
134+
return h.digest('hex').substring(0, 16)
135+
}
136+
116137
// ── Manifest (incremental build state) ──────────────────────
117138

118139
interface ManifestEntry { hash: string; timestamp: string }
@@ -232,10 +253,11 @@ interface SearchIndexSource {
232253
lang: 'zh' | 'en' | 'mixed'
233254
}
234255

235-
function prepareVolume(vol: Volume, lang: 'zh' | 'en', manifest: Manifest): BuildTask {
256+
function prepareVolume(vol: Volume, lang: 'zh' | 'en', manifest: Manifest, buildInputsHash: string): BuildTask {
236257
const volDocDir = lang === 'en' ? join(DOCUMENTS, 'en', vol.srcDir) : join(DOCUMENTS, vol.srcDir)
237258
const id = lang === 'en' ? `${vol.name}-en` : vol.name
238-
const cacheKey = existsSync(volDocDir) ? hashDir(volDocDir) : ''
259+
const docHash = existsSync(volDocDir) ? hashDir(volDocDir) : ''
260+
const cacheKey = `${buildInputsHash}-${docHash}`
239261
const prev = manifest[id]
240262
const cached = !FORCE_REBUILD && prev && prev.hash === cacheKey && existsSync(join(CACHE_DIR, 'output', id))
241263
return { id, vol, lang, cacheKey, cached }
@@ -585,6 +607,7 @@ async function main() {
585607
mkdirSync(join(BUILD_TMP, 'output'), { recursive: true })
586608

587609
const manifest = readManifest()
610+
const buildInputsHash = hashBuildInputs()
588611

589612
// ── Step 1: Build root ──────────────────────────────────
590613
logStep('Step 1/4: Building root site (index, tags)')
@@ -629,7 +652,7 @@ async function main() {
629652
for (const lang of ['zh', 'en'] as const) {
630653
const volDocDir = lang === 'en' ? join(DOCUMENTS, 'en', vol.srcDir) : join(DOCUMENTS, vol.srcDir)
631654
if (!existsSync(volDocDir)) continue
632-
tasks.push(prepareVolume(vol, lang, manifest))
655+
tasks.push(prepareVolume(vol, lang, manifest, buildInputsHash))
633656
}
634657
}
635658

0 commit comments

Comments
 (0)