fix(esbuild): sort srcFiles so zip checksum is deterministic#7087
fix(esbuild): sort srcFiles so zip checksum is deterministic#7087lucasgarsha wants to merge 1 commit into
Conversation
The esbuild bundler returned `srcFiles: [...supportingSrcFiles, ...bundlePaths.keys()]` without sorting, so identical function content was archived in a run-dependent order and the zip sha256 changed every build. This defeats Netlify's content-addressed function-upload dedup, causing every function to re-upload on every deploy. The `zisi` and `nft` bundlers already `.sort()` their `srcFiles` for exactly this reason; this aligns the esbuild bundler with them. Entry order has no runtime effect, so sorting is safe. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
Linter diff in the way? Review this PR in Change Stack to focus on meaningful changes and expand context only when needed. No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (2)
📝 WalkthroughSummary by CodeRabbit
WalkthroughThe esbuild bundler now sorts the Estimated code review effort🎯 2 (Simple) | ⏱️ ~10 minutes Suggested labels
Suggested reviewers
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
Reviewed this — correct and well-scoped. Sorting the combined Things I checked that hold up:
Minor / optional:
For real-world context on why this matters: without it, identical source yields a different zip checksum every build, so the content-addressed function upload never dedups and every function re-uploads each deploy. On a site with ~220 functions (~2.5GB) that meant re-uploading the whole set every time, which intermittently exhausted memory in the upload step. Fixing it here at the source removes the need for downstream re-zip workarounds. 🙏 LGTM. |
Fixes #7086.
The esbuild bundler returned
srcFiles: [...supportingSrcFiles, ...bundlePaths.keys()]without sorting, so identical function content was archived in a run-dependent order and the zip sha256 changed every build — defeating Netlify's content-addressed function-upload dedup (every function re-uploads on every deploy). Thezisiandnftbundlers already.sort()for this exact reason; this aligns esbuild with them.Change
Add
.sort()to the returnedsrcFilesinpackages/zip-it-and-ship-it/src/runtimes/node/bundlers/esbuild/index.ts. Entry order has no runtime effect, so sorting is safe.Test
Added a Vitest regression test in
tests/esbuild.test.tsthat bundles the same function twice with the esbuild bundler while perturbing the source-file discovery order between runs, and asserts a byte-identical zip. It fails onmainand passes with this change.A plain "bundle twice and compare" test isn't sufficient here: within a single warm process the filesystem traversal order is incidentally stable, so identical checksums are produced even without the fix (the existing
'Produces deterministic checksums'test inmain.test.tspasses on buggymainfor this reason). The non-determinism only manifests across build environments, so the test reverses the discoveredsrcFilesorder on the second bundle to simulate that variance — which is exactly what the sort neutralizes.Evidence
ff807ba…vs2376cf0…) despite identical contents.This was originally found against the standalone
netlify/zip-it-and-ship-itrepo (now archived → redirects here); the affected code is unchanged after the move.