From f8cb55db6df6024803986aa472a188eb4ce88551 Mon Sep 17 00:00:00 2001 From: Joey Stanford Date: Mon, 20 Jul 2026 19:46:17 -0600 Subject: [PATCH] fix: install pnpm dist/ for Flatpak offline builds - Copy pnpm-vendor/dist into .pnpm-bin beside the wrapper binary so pnpm 11+ can load dist/pnpm.mjs inside the Flatpak sandbox. - Enforce the copy in check:flatpak and add a manifest contract test. #700 kept the root-level pnpm binary via strip-components: 0, but the install step still omitted dist/, so Flatpak CI failed immediately with MODULE_NOT_FOUND for .pnpm-bin/dist/pnpm.mjs. --- org.coloradomesh.MeshClient.yml | 6 ++++-- scripts/check-flatpak.mjs | 9 +++++++++ scripts/flatpak-pnpm-bin.test.mjs | 18 ++++++++++++++++++ 3 files changed, 31 insertions(+), 2 deletions(-) create mode 100644 scripts/flatpak-pnpm-bin.test.mjs diff --git a/org.coloradomesh.MeshClient.yml b/org.coloradomesh.MeshClient.yml index 62dbe32a7..1f5ff9308 100644 --- a/org.coloradomesh.MeshClient.yml +++ b/org.coloradomesh.MeshClient.yml @@ -39,10 +39,12 @@ modules: PNPM_HOME: /run/build/mesh-client/.pnpm pnpm_config_cache: /run/build/mesh-client/.npm build-commands: - # Install pnpm standalone binary from archived release (no network needed). + # Install pnpm standalone from archived release (no network needed). # Archive extracts to pnpm-vendor/ (strip-components: 0) so the root `pnpm` binary is - # kept and the bundled dist/ does not collide with app dist/. + # kept and the bundled dist/ does not collide with app dist/. pnpm 11+ requires + # dist/pnpm.mjs next to the wrapper binary (install alone is not enough). - install -Dm755 pnpm-vendor/pnpm /run/build/mesh-client/.pnpm-bin/pnpm + - cp -a pnpm-vendor/dist /run/build/mesh-client/.pnpm-bin/dist # Offline install using generated-sources.json (retries @jsr temp-dir races). # --store-dir must use the sandbox-absolute path because the type:shell # source that writes .npmrc runs outside the sandbox, so $PWD there is diff --git a/scripts/check-flatpak.mjs b/scripts/check-flatpak.mjs index 32da05235..3ae4d4699 100644 --- a/scripts/check-flatpak.mjs +++ b/scripts/check-flatpak.mjs @@ -160,6 +160,15 @@ function checkManifestPnpmVersion(pkg) { } } + // The standalone wrapper requires dist/pnpm.mjs beside .pnpm-bin/pnpm. + if (!/cp\s+-a\s+pnpm-vendor\/dist\s+\/run\/build\/mesh-client\/\.pnpm-bin\/dist\b/.test(yaml)) { + violations.push({ + file: rel, + message: + 'manifest must copy pnpm-vendor/dist into .pnpm-bin/dist (pnpm 11+ wrapper needs dist/pnpm.mjs)', + }); + } + return violations; } diff --git a/scripts/flatpak-pnpm-bin.test.mjs b/scripts/flatpak-pnpm-bin.test.mjs new file mode 100644 index 000000000..e638cc328 --- /dev/null +++ b/scripts/flatpak-pnpm-bin.test.mjs @@ -0,0 +1,18 @@ +// @vitest-environment node +import fs from 'fs'; +import path from 'path'; +import { fileURLToPath } from 'url'; +import { describe, expect, it } from 'vitest'; + +const ROOT = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..'); +const MANIFEST = path.join(ROOT, 'org.coloradomesh.MeshClient.yml'); + +describe('Flatpak pnpm standalone install', () => { + it('copies pnpm-vendor/dist beside the wrapper binary (pnpm 11+ needs dist/pnpm.mjs)', () => { + const yaml = fs.readFileSync(MANIFEST, 'utf8'); + expect(yaml).toMatch( + /install -Dm755 pnpm-vendor\/pnpm \/run\/build\/mesh-client\/\.pnpm-bin\/pnpm/, + ); + expect(yaml).toMatch(/cp -a pnpm-vendor\/dist \/run\/build\/mesh-client\/\.pnpm-bin\/dist/); + }); +});