Repository navigation
build: pin libpg_query commit + emsdk 6.0.3; generate every Makefile from x-publish (#170) - #174
Conversation
…e every Makefile from x-publish Each version's libpg_query repo, branch and commit now live in package.json x-publish and are applied by copy:templates, so regenerating no longer flips 15/17/18 back to pganalyze sources or drops the v18 memory knobs. The build checks out the pinned commit and keys the source cache by it; wasm:make runs the emscripten/emsdk:6.0.3 image instead of the floating default tag.
|
I'll fix CI failures and address comments from users with write access. I'll skip comments containing "(aside)".
|
|
Review complete. 🟡 3 medium 💬 Inline comments (1)
📍 Findings outside the diff (2) — 🟡 2 medium — defects on lines GitHub can't attach comments to🟡 Medium — Pin validation throw is swallowed; script exits 0 · copy-templates.js:39–56 · // scripts/copy-templates.js
39 if (version && libpgQueryTag) {
40 if (!libpgQueryRepo || !/^[0-9a-f]{40}$/.test(libpgQueryCommit || '')) {
41 throw new Error(`x-publish needs libpgQueryRepo and a full 40-char libpgQueryCommit`);
42 }
43 configs[version] = {
44 tag: libpgQueryTag,
45 repo: libpgQueryRepo,
46 commit: libpgQueryCommit,
47 hasEmscriptenPatch: version === '13', // Only version 13 needs the patch
48 fullApi
49 };
50 console.log(` Version ${version}: ${libpgQueryTag} @ ${libpgQueryCommit.slice(0, 7)}${fullApi ? ' (full API)' : ''}`);The new validation 🟡 Medium — fetch-protos 404s for repointed pg15/pg17 refs · fetch-protos.js:73 · // scripts/fetch-protos.js
73 const url = `https://raw.githubusercontent.com/pganalyze/libpg_query/refs/tags/${libpgQueryTag}/protobuf/pg_query.proto`;This PR repoints versions 15 and 17 to The change adds
Reviewed commit: 0b8713c |
There was a problem hiding this comment.
This PR switches libpg_query source pinning from tags to explicit fork repo/commit pins across all six version Makefiles and package.json files, with template regeneration support.
Key findings
- 🟡 Pin validation throw is swallowed; script exits 0 — copy-templates.js:39
- 🟡 Failed pin checkout leaves poisoned, unpinned cache dir — Makefile.template:50
- 🟡 fetch-protos 404s for repointed pg15/pg17 refs — fetch-protos.js:73
| $(LIBPG_QUERY_DIR): | ||
| mkdir -p $(CACHE_DIR) | ||
| git clone -b $(LIBPG_QUERY_TAG) --single-branch $(LIBPG_QUERY_REPO) $(LIBPG_QUERY_DIR) | ||
| git -C $(LIBPG_QUERY_DIR) -c advice.detachedHead=false checkout $(LIBPG_QUERY_COMMIT) |
There was a problem hiding this comment.
🟡 bug · medium
Failed pin checkout leaves poisoned, unpinned cache dir
The $(LIBPG_QUERY_DIR) rule stamps the target by directory existence while the new git checkout $(LIBPG_QUERY_COMMIT) line (templates/Makefile.template:53) can fail — e.g. the commit is not reachable from the single ref fetched by git clone -b $(LIBPG_QUERY_TAG) --single-branch, or the run is interrupted. When that happens the directory already exists, so the next make considers the target up to date and silently skips clone, checkout, and the v13 emscripten patch, building against whatever revision the clone was left at instead of the pin. This defeats the byte-for-byte reproducibility the pin was added for.
📋 Prompt for AI Agents
In templates/Makefile.template lines 51-53 (then regenerate all versions/*/Makefile via npm run copy:templates), the $(LIBPG_QUERY_DIR) rule runs mkdir, git clone -b $(LIBPG_QUERY_TAG) --single-branch ..., and git checkout $(LIBPG_QUERY_COMMIT) as separate recipe lines against a directory-existence target: if the checkout fails, the directory remains and later make runs skip the whole recipe, silently building from the branch tip instead of the pin. Combine the clone and checkout into one chained recipe that removes the directory on failure (git clone ... && git -C ... checkout ... || { rm -rf $(LIBPG_QUERY_DIR); exit 1; }), and consider fetching the pinned commit explicitly (git -C $(LIBPG_QUERY_DIR) fetch origin $(LIBPG_QUERY_COMMIT)) so a commit not reachable from the single-branch ref can still be checked out.
… failed checkout; fail on a bad pin - fetch-protos.js downloads pg_query.proto from libpgQueryRepo@libpgQueryCommit (the 17-constructive / fix/negative-int-pg15 branch names 404 on pganalyze tags), only writes the file after a complete 200 (a 404 used to truncate the committed proto to 0 bytes) and exits 1 on any failure. - Makefile clone + checkout is one recipe line that removes the directory if either step fails, so make never reuses a clone at the wrong commit. - copy-templates.js no longer swallows x-publish validation errors.
…tch drops the clone
…ld types that no longer exist
Summary
Fixes #170: release builds now record exactly what they were built from, and nothing floats. Build config and scripts only: no wrapper code, proto or generated-type changes.
What was floating before
LIBPG_QUERY_TAGfor v15/17/18 named a branch ofconstructive-io/libpg_query, so the source could change without any commit here.wasm:makeranemscripten/emsdkwith no tag. Today that pulls 6.0.13, not the 6.0.3 the releases were actually built with.copy:templateshard-coded the pganalyze repo URL. Running it switched 15/17/18 back to pganalyze sources and removed v18'sWASM_*memory knobs (REPO_NOTES.mdwarned about this).Change
x-publishin eachversions/*/package.jsonnow carrieslibpgQueryRepo,libpgQueryTagandlibpgQueryCommit(a full SHA, enforced bycopy:templates).x-publishagain. The build clones the branch, runsgit checkout $(LIBPG_QUERY_COMMIT), and keys the source cache by commit, so a stale cached clone can't be reused.wasm:makenow usesemscripten/emsdk:6.0.3in all versions.WASM_INITIAL_MEMORY/WASM_MAXIMUM_MEMORY/WASM_STACK_SIZEoverrides move into the template, so every version gets them. Defaults are unchanged (128 MiB / 1 GiB / 32 MiB).x-publishships in the publishedpackage.json, so the source commit is recorded in npm metadata next togitHead.Build-script hardening
fetch:protosdownloadspg_query.protofromlibpgQueryRepo@libpgQueryCommit, the same source the WASM builds from. Before, it built a pganalyze tag URL, which 404s for the fork branch names. It now writes the file only after a complete 200 and exits 1 on failure. Onmain, a 404 truncated the committed.prototo 0 bytes and the script still exited 0.git clone ... && git -C $(LIBPG_QUERY_DIR) checkout $(LIBPG_QUERY_COMMIT) $(LIBPG_QUERY_PATCH) || \ { rm -rf $(LIBPG_QUERY_DIR); exit 1; } # v13 only, under EMSCRIPTEN: LIBPG_QUERY_PATCH := && patch -d $(LIBPG_QUERY_DIR) -p1 < $(CURDIR)/patches/emscripten_disable_spinlocks.patchunknown type name 'slock_t', which happened on a local v13 build.copy:templatesno longer swallowsx-publishvalidation errors, so a bad pin exits 1.Pins are the current branch heads, so a build today produces the same thing it did before this PR:
13-2.2.01097b2c14-3.0.0397cbb9fix/negative-int-pg15ae1050416-5.2.0fce106a17-constructive1ade88018-constructiveb0f5f33Existing local caches are keyed by tag, so after this PR every version clones fresh once.
WASM hashes
publish-single-version.jswritesx-publish.wasmSha256(the sha256 ofwasm/libpg-query.wasmandwasm/libpg-query.js) into the package.json it publishes, so anyone can rebuild from the pins and compare. Ifwasm/libpg-query.wasmis missing it exits 1. Building stays optional. Tested withnpm packon v17: the hashes in the packed package.json matchsha256sumof the files in the tarball.mainand from this branch with emsdk 6.0.3 gives byte-identical.wasmand.jsoutput, so this PR changes no binary or memory setting.Docs
PUBLISH.mdgets a "Keeping the C source in sync" section: how to move a pin, what "skip build" means for the pins, and how to checkx-publishafter publishing. It also drops thelatest/legacyparser build types, which no longer exist, and the rootbuild:parser:legacyscript, which failed with "Invalid build type".Not changed here: the committed
protos/17/pg_query.protopredates the v17 pin. Runningfetch:protosadds upstream'sSummaryResultmessage, and regenerating types from it would add strayTable/Function/FilterColumnnode types to@pgsql/types. So the proto is left as it is.Evidence
pnpm run copy:templateson this branch produces no diff.pnpm run wasm:buildon this branch reproduces the published npm packages byte-for-byte:[email protected]: wasm378b64e6…, js219217cc…[email protected]: wasm06fbfc24…fetch:protoson this branch: v13/14/15/16/18 come out byte-identical to the committed protos. v17 only gains the fork'sSummaryResultmessage. That file is not committed here, and no types are regenerated.copy:templatesexit 1;fetch:protosexit 1 with the committed proto intact;LIBPG_QUERY_COMMITmakesmakeexit non-zero, and the clone directory is removed.make EMSCRIPTEN=1 <clone dir>:makesays "is up to date" (exit 0) without patching;s_lock.hhas the__sync_lock_test_and_setfallback.main(fix(wasm): replace the module after an exception escapes a WASM call #175): a clean v13 build withemsdk:6.0.3passespnpm test(72 pass, 0 fail, 20 skipped). v17 and v18 tests pass locally.Link to Devin session: https://app.devin.ai/sessions/bcd8b2f791164247acb7a659b481efc2
Open in Devin Desktop: https://app.devin.ai/desktop/session/bcd8b2f791164247acb7a659b481efc2?variant=devin
Requested by: @pyramation