Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
83 changes: 83 additions & 0 deletions charly.yml
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,29 @@ nodejs:
components: main
var:
PNPM_VERSION: "10.33.4"
# The allowBuilds KEY FORM a consumer's pnpm-workspace.yaml must use for a
# GIT-SPECIFIER dependency is VERSION-COUPLED, and the coupling is invisible:
# the two forms fail on each other's pin, so there is no form that works at
# both. MEASURED in the real build image (Fedora 43, node 22.22.2) against
# pod-dsh's dsh-web profile — opencharly/layer-nodejs#5:
#
# allowBuilds key form pnpm 10.33.4 pnpm 10.34.6
# bare name "@perrylink/dsh-github": true PASS ERR_PNPM_GIT_DEP_PREPARE_NOT_ALLOWED
# URL key "@perrylink/dsh-github@https://codeload.github.com/...": true
# ERR_PNPM_INVALID_VERSION_UNION PASS
#
# So a pin bump across that band MUST re-measure the form and move BOTH
# constants below in the SAME change; the `check:` step beneath makes
# forgetting it RED instead of a hard-failed consumer profile install. The
# band boundary is deliberately NOT extrapolated from the two probed
# endpoints (only those two were measured) — a new pin must re-measure and
# record, which is the whole point. Consumer status: pod-dsh vendored its
# git-hosted plugins as prebuilt `file:` tarballs (pod-dsh#28, merged
# 2026-10-07), so no git dep remains THERE today — the rule still binds any
# consumer that pins one.
PNPM_ALLOWBUILDS_GIT_KEY_FORM: bare
PNPM_ALLOWBUILDS_PROBED_BARE: "10.33.4"
PNPM_ALLOWBUILDS_PROBED_URL: "10.34.6"
plan:
- run: |
command=case "${BUILD_ARCH}" in
Expand Down Expand Up @@ -123,6 +146,43 @@ nodejs:
package:
package: nodejs
installed: true
- # The pin <-> allowBuilds-key-form coupling, ASSERTED rather than remembered
# (opencharly/layer-nodejs#5). A pin bump across the measured band silently
# hard-fails a consumer's profile install at image build time; this step makes
# that a RED check on the bump instead. It asserts only what was MEASURED (the
# two probed versions), never an extrapolated boundary: any other pin fails
# loudly and asks the author to re-measure and record the form here.
#
# ZERO `${...}` and ZERO `$` ANYWHERE in this command, deliberately: a check
# step's command goes through charly's variable substitution, which reads
# `${X}` as a charly variable and SKIPS the whole step when it cannot resolve
# one — trading a red check for a silently absent one, which is exactly the
# silent-no-op class this assertion exists to prevent. `var:` values are
# exported as ENV before this step, so the script reads them with
# `process.env[...]` and the messages are built by CONCATENATION, never by a
# template literal. The grep that proves it: `grep -c '\$'` over this command
# returns 0, so substitution has no token to act on and the step cannot be
# skipped.
check: the pinned pnpm version's allowBuilds git-key form matches the recorded measurement
exit_status: 0
command: |
node -e '
const keys = ["PNPM_VERSION", "PNPM_ALLOWBUILDS_GIT_KEY_FORM", "PNPM_ALLOWBUILDS_PROBED_BARE", "PNPM_ALLOWBUILDS_PROBED_URL"];
const values = keys.map((k) => process.env[k] || "");
const missing = keys.filter((k) => !process.env[k]);
if (missing.length > 0) { console.error("these pnpm pin band vars are not exported: " + missing.join(", ")); process.exit(1); }
const measured = new Map([[values[2], "bare"], [values[3], "url"]]);
const want = measured.get(values[0]);
if (want === undefined) {
console.error("pnpm " + values[0] + " is UNMEASURED for the allowBuilds git-key form. Bump only with a measurement: run a consumer profile that installs a git-specifier dep with a build script and record which form passes, then move PNPM_ALLOWBUILDS_GIT_KEY_FORM and the PROBED_* pair together (opencharly/layer-nodejs#5).");
process.exit(1);
}
if (values[1] !== want) {
console.error("pnpm " + values[0] + " requires the allowBuilds git-key form \"" + want + "\", but PNPM_ALLOWBUILDS_GIT_KEY_FORM is \"" + values[1] + "\" (opencharly/layer-nodejs#5)");
process.exit(1);
}
console.log("pnpm " + values[0] + ": allowBuilds git-key form \"" + values[1] + "\" matches the recorded measurement");
'

nodejs-skill:
skill:
Expand Down Expand Up @@ -167,6 +227,29 @@ nodejs-skill:
binary on `/usr/local/bin` is on the default system PATH for every user (incl.
root — Immich runs its pnpm build as root). Immich and other pnpm consumers use
this pnpm to drive their build.

### The pin and a consumer's `allowBuilds` KEY FORM are a COUPLED PAIR

pnpm >= 10 blocks a dependency's build/install scripts unless it is allowlisted,
and for a **git-specifier** dependency the KEY FORM of that allowlist entry is
version-coupled: the two forms fail on each other's pin, so no single form works
at both. MEASURED in the real build image (Fedora 43, node 22.22.2) against
pod-dsh's `dsh-web` profile — `opencharly/layer-nodejs#5`:

| `allowBuilds` key form | pnpm `10.33.4` | pnpm `10.34.6` |
|---|---|---|
| bare name — `"@perrylink/dsh-github": true` | PASS | `ERR_PNPM_GIT_DEP_PREPARE_NOT_ALLOWED` |
| fully-qualified URL key — `"@perrylink/dsh-github@https://codeload.github.com/<owner>/<repo>/.git": true` | `ERR_PNPM_INVALID_VERSION_UNION` | PASS |

A wrong pair hard-fails the consumer's profile install at IMAGE BUILD time. So
`PNPM_VERSION`, `PNPM_ALLOWBUILDS_GIT_KEY_FORM` and the two PROBED_* constants move
together, and the candy's own
`check: the pinned pnpm version's allowBuilds git-key form matches the recorded measurement`
makes a bump that forgets them RED instead of a hard-failed consumer build. Only the
two probed versions are accepted: a bump to any other pin must RE-MEASURE the form and
record it. (pod-dsh vendored its git-hosted plugins as prebuilt `file:` tarballs in
pod-dsh#28, so no git dep remains there today — the rule still binds any consumer
that pins one.)

## Usage

Expand Down
Loading