fix(heroku): pin Node 22 and provide tree-sitter CLI so deploys succeed#69
Open
Kamehameya wants to merge 2 commits into
Open
fix(heroku): pin Node 22 and provide tree-sitter CLI so deploys succeed#69Kamehameya wants to merge 2 commits into
Kamehameya wants to merge 2 commits into
Conversation
|
Thanks for the contribution! Unfortunately we can't verify the commit author(s): Amey Mandalik <a***@s***.com>. One possible solution is to add that email to your GitHub account. Alternatively you can change your commits to another email and force push the change. After getting your commits associated with your GitHub account, refresh the status of this Pull Request. |
setu4993
approved these changes
Jul 13, 2026
Heroku deploys had been failing on every push (43/43 builds). Two independent
blockers, plus a caching bug in the static server, are fixed here.
1. engines.node was ">=18.0.0". The Heroku Node buildpack prioritizes
engines.node over the NODE_VERSION config var and resolves the open range to
the newest release (Node 26), against which the tree-sitter native module
fails to compile (node-gyp build error), aborting pnpm install. Pin to 22.x
to match mise.toml/CI and the tested toolchain.
2. heroku-postbuild runs pnpm build, which invokes `tree-sitter generate`, but
the CLI is not present on the buildpack. Download the 0.25.10 linux-x64
binary into .heroku-bin/ and prepend it to PATH for the build, mirroring what
.github/workflows/ci.yml already does. .heroku-bin/ is gitignored.
3. The static server's hash detection used /\.[a-f0-9]{8,}\.\w+$/, which
requires a dot before a lowercase-hex hash. Vite emits name-<base64url>.ext
(e.g. index-FMgzpBhJ.js), so every UI asset fell through to max-age=60
instead of the intended 1-year immutable cache. Replace with
isContentHashed(), recognizing both Vite (-hash) and Docusaurus (.hash/-hash)
content hashes while excluding plain kebab-case names so unhashed files are
never frozen in caches; HTML is always revalidated.
Verified end-to-end in the real heroku/heroku:24-build image (x86_64, Node 22,
NODE_ENV=production): 16/16 build tasks green and apps/ui/dist/{index.html,
docs/index.html} produced. Cache logic checked against all 274 built files with
0 false positives and 0 missed hashes; path-traversal regression suite passes.
27af196 to
f7033f7
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
Heroku deploys for the playground app have been failing on every push — 43 of 43 builds failed. The build log only shows
pnpm install→ELIFECYCLE Command failed with exit code 1, because the buildpack runs withNPM_CONFIG_LOGLEVEL=errorand suppresses the detail.Reproducing under Heroku-like conditions surfaced two independent blockers:
1. Heroku builds on Node 26, which can't compile the parser
engines.nodewas>=18.0.0. The Heroku Node buildpack prioritizesengines.nodeover theNODE_VERSIONconfig var and resolves the open range to the newest release (Node 26.5.0) — the buildpack log even warns about the "wide range". Thetree-sitternative module fails to compile against Node 26's V8 headers:This is why repeatedly setting
NODE_VERSIONon the app never took effect.2.
heroku-postbuildneeds the tree-sitter CLI, which the buildpack lacksOnce Node is pinned and
pnpm installsucceeds (parser.cand prebuilds are committed),heroku-postbuildrunspnpm build, which callstree-sitter generate:Fix
engines.nodeto22.x— matchesmise.toml, CI, and the tested toolchain, and stops the buildpack from selecting Node 26.heroku-postbuildinto.heroku-bin/and prepend it toPATHfor the build, mirroring what.github/workflows/ci.ymlalready does. Added.heroku-bin/to.gitignore.Verification
Ran the exact
heroku-postbuildscript, unmodified, inside the realheroku/heroku:24-buildimage (emulated x86_64 to match dynos), with Node 22 andNODE_ENV=production, source copied in as a fresh slug:cargo).pnpm install --frozen-lockfile✅heroku-postbuildbuild step ✅ — 16/16 turbo tasks greenapps/ui/dist/index.htmlandapps/ui/dist/docs/index.html(whatserver.mjsserves) ✅🤖 Generated with Claude Code