Skip to content

Commit 9e5f428

Browse files
Refine build pipeline error handling and cache docs
Use CPU count to cap default thread workers and simplify webpack error checks. Ensure watch-once packaging failures surface as non-zero exits. Key CI webpack cache by full Node version. Clarify cache compression behavior in AGENTS documentation.
1 parent 2bba45b commit 9e5f428

File tree

3 files changed

+14
-18
lines changed

3 files changed

+14
-18
lines changed

.github/workflows/pre-release-build.yml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,18 +26,18 @@ jobs:
2626
node-version: 20
2727
cache: 'npm'
2828
cache-dependency-path: '**/package-lock.json'
29-
- name: Detect Node major version
30-
run: echo "NODE_MAJOR=$(node -p 'process.versions.node.split(".")[0]')" >> $GITHUB_ENV
29+
- name: Detect Node version
30+
run: echo "NODE_VERSION=$(node -p 'process.versions.node')" >> $GITHUB_ENV
3131
- run: npm ci
3232
- name: Cache Webpack filesystem cache
3333
uses: actions/cache@v4
3434
with:
3535
path: |
3636
.cache/webpack
3737
node_modules/.cache/webpack
38-
key: ${{ runner.os }}-node${{ env.NODE_MAJOR }}-webpack-${{ hashFiles('**/package-lock.json', 'build.mjs') }}
38+
key: ${{ runner.os }}-node${{ env.NODE_VERSION }}-webpack-${{ hashFiles('**/package-lock.json', 'build.mjs') }}
3939
restore-keys: |
40-
${{ runner.os }}-node${{ env.NODE_MAJOR }}-webpack-
40+
${{ runner.os }}-node${{ env.NODE_VERSION }}-webpack-
4141
- run: npm run build
4242

4343
- uses: josStorer/get-current-time@v2

AGENTS.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ Always reference these instructions first and fall back to search or bash comman
2828
- Default: `0` (no compression) for faster warm builds on CPU-bound SSD machines
2929
- Options: `0|false|none`, `gzip` (or `brotli` if explicitly desired)
3030
- Affects only `.cache/webpack` size/speed; does not change final artifacts
31+
- Note: Babel loader cache uses its own compression setting (currently disabled for speed) and is independent of BUILD_CACHE_COMPRESSION
3132
- BUILD_WATCH_ONCE (dev): When set, `npm run dev` runs a single build and exits (useful for timing)
3233
- BUILD_POOL_TIMEOUT: Override thread-loader production pool timeout (ms)
3334
- Default: `2000`. Increase if workers recycle too aggressively on slow machines/CI

build.mjs

Lines changed: 9 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ try {
5555
cpuCount = 1
5656
}
5757
function parseThreadWorkerCount(envValue, cpuCount) {
58-
const maxWorkers = Math.max(1, cpuCount - 1)
58+
const maxWorkers = Math.max(1, cpuCount)
5959
if (envValue !== undefined && envValue !== null) {
6060
const rawStr = String(envValue).trim()
6161
if (/^[1-9]\d*$/.test(rawStr)) {
@@ -413,10 +413,7 @@ async function runWebpack(isWithoutKatex, isWithoutTiktoken, minimal, sourceBuil
413413
if (isProduction) {
414414
// Ensure compiler is properly closed after production runs
415415
compiler.run((err, stats) => {
416-
const hasErrors = !!(
417-
err ||
418-
(stats && typeof stats.hasErrors === 'function' && stats.hasErrors())
419-
)
416+
const hasErrors = !!(err || stats?.hasErrors?.())
420417
let callbackFailed = false
421418
const finishClose = () =>
422419
compiler.close((closeErr) => {
@@ -445,10 +442,7 @@ async function runWebpack(isWithoutKatex, isWithoutTiktoken, minimal, sourceBuil
445442
})
446443
} else {
447444
const watching = compiler.watch({}, (err, stats) => {
448-
const hasErrors = !!(
449-
err ||
450-
(stats && typeof stats.hasErrors === 'function' && stats.hasErrors())
451-
)
445+
const hasErrors = !!(err || stats?.hasErrors?.())
452446
// Normalize callback return into a Promise to catch synchronous throws
453447
const ret = Promise.resolve().then(() => callback(err, stats))
454448
if (isWatchOnce) {
@@ -626,7 +620,7 @@ async function build() {
626620
minimal,
627621
tmpDir,
628622
async (err, stats) => {
629-
if (err || (stats && typeof stats.hasErrors === 'function' && stats.hasErrors())) {
623+
if (err || stats?.hasErrors?.()) {
630624
console.error(err || stats.toString())
631625
reject(err || new Error('webpack error'))
632626
return
@@ -665,10 +659,7 @@ async function build() {
665659

666660
await new Promise((resolve, reject) => {
667661
const ret = runWebpack(false, false, false, outdir, async (err, stats) => {
668-
const hasErrors = !!(
669-
err ||
670-
(stats && typeof stats.hasErrors === 'function' && stats.hasErrors())
671-
)
662+
const hasErrors = !!(err || stats?.hasErrors?.())
672663
if (hasErrors) {
673664
console.error(err || stats.toString())
674665
// In normal dev watch, keep process alive on initial errors; only fail when watch-once
@@ -683,6 +674,10 @@ async function build() {
683674
} catch (e) {
684675
// Packaging failure should stop even in dev to avoid silent success
685676
reject(e)
677+
if (isWatchOnce) {
678+
// Re-throw to surface an error and exit non-zero even if rejection isn't awaited
679+
throw e
680+
}
686681
}
687682
})
688683
// Early setup failures (e.g., dynamic imports) should fail fast

0 commit comments

Comments
 (0)