@rightkit/release 0.2.102 → 0.2.104

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -22,6 +22,23 @@ export function sha256File(path) {
22
22
  return createHash("sha256").update(readFileSync(path)).digest("hex");
23
23
  }
24
24
 
25
+ // The RightRelease PowerShell bootstrap is still generated and published to R2
26
+ // as the branded installer's outer verifier. It must not be embedded into the
27
+ // Membrane Tauri NSIS installer resource set: Section Install now lays the
28
+ // versioned payload down and runs `membrane activate` directly (see
29
+ // docs/MEMBRANE-INSTALLER-SIMPLIFICATION-CONTRACT-2026-09-02.md). This guard
30
+ // throws loudly if anyone re-wires the payload into that resource set.
31
+ export function assertBootstrapNotEmbeddedInNsis(product, resourceNames) {
32
+ if (product !== "membrane") return;
33
+ const embedded = [...(resourceNames ?? [])].filter((name) => /(^|[\\/])install\.ps1$/i.test(String(name)));
34
+ if (embedded.length) {
35
+ throw new Error(
36
+ `RightRelease bootstrap install.ps1 must not be embedded into the Membrane NSIS installer (${embedded.join(", ")}); ` +
37
+ "Section Install activates the release directly. See MEMBRANE-INSTALLER-SIMPLIFICATION-CONTRACT-2026-09-02.",
38
+ );
39
+ }
40
+ }
41
+
25
42
  export function collectReleaseAsset({
26
43
  target,
27
44
  name,
@@ -33,16 +33,22 @@ export function assertNsisInPlaceUpgradeContract(appRoot, options = {}) {
33
33
  "Windows NSIS template must declare the RightKit automatic in-place upgrade policy; uninstall/reinstall maintenance choices add unnecessary friction",
34
34
  );
35
35
  }
36
- if (
37
- !/\$\{If\}\s+\$WixMode\s*=\s*0[\s\S]{0,160}\$\{AndIf\}\s+\$R0\s*>=\s*0[\s\S]{0,80}\bAbort\b/.test(
36
+ // Two acceptable shapes:
37
+ // - legacy: Tauri's reinstall page is present but skipped for same-version
38
+ // repair and in-place upgrades (the $WixMode / $R0 skip logic);
39
+ // - no maintenance surface at all: the template declares no reinstall page,
40
+ // no components page and no custom page, so there is nothing to skip.
41
+ const legacySkipLogic =
42
+ /\$\{If\}\s+\$WixMode\s*=\s*0[\s\S]{0,160}\$\{AndIf\}\s+\$R0\s*>=\s*0[\s\S]{0,80}\bAbort\b/.test(
38
43
  source,
39
- )
40
- ) {
44
+ );
45
+ const maintenanceSurface = /\bPageReinstall\b|MUI_PAGE_COMPONENTS|^\s*Page\s+custom\b/m.test(source);
46
+ if (!legacySkipLogic && maintenanceSurface) {
41
47
  throw new Error(
42
- "Windows NSIS template is missing skip-page logic for same-version repair and in-place upgrades",
48
+ "Windows NSIS template has a reinstall or maintenance page without skip-page logic for same-version repair and in-place upgrades",
43
49
  );
44
50
  }
45
- return { templatePath };
51
+ return { templatePath, shape: legacySkipLogic ? "legacy-skip-page" : "no-maintenance-page" };
46
52
  }
47
53
 
48
54
  function readJson(file, label) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rightkit/release",
3
- "version": "0.2.102",
3
+ "version": "0.2.104",
4
4
  "description": "Portable release CLI/SDK with fail-closed public GitHub Releases and private R2 + RightApps distribution.",
5
5
  "license": "MIT OR Apache-2.0",
6
6
  "type": "module",
package/release.mjs CHANGED
@@ -726,7 +726,10 @@ async function validateHostedWorkflows(root, appName, workflows, policy) {
726
726
  // (Windows) and macos-sign (macOS), so publish is unreachable unless every
727
727
  // signing/qualification stage actually verified in this exact run.
728
728
  const legacyReleasePublishGate = /publish:\n needs: \[[^\n]*installed-qualification[^\n]*\]\n if: \$\{\{ startsWith\(github\.ref, 'refs\/tags\/v'\) && needs\.installed-qualification\.result == 'success'/.test(publishSource);
729
- const admittedReleasePublishGate = /publish:\n needs: \[(?=[^\n]*\badmission\b)(?=[^\n]*\binstalled-qualification\b)(?=[^\n]*\bmacos-sign\b)[^\n]*\]\n if: \$\{\{ needs\.admission\.outputs\.publish == 'true' && needs\.installed-qualification\.result == 'success' && needs\.macos-sign\.result == 'success' \}\}/.test(publishSource);
729
+ // Template 1.9.0 adds a dry-run rehearsal: publish is additionally unreachable
730
+ // when admission recorded `dry_run`. The clause only narrows the gate, so it
731
+ // is accepted as an optional trailing conjunct.
732
+ const admittedReleasePublishGate = /publish:\n needs: \[(?=[^\n]*\badmission\b)(?=[^\n]*\binstalled-qualification\b)(?=[^\n]*\bmacos-sign\b)[^\n]*\]\n if: \$\{\{ needs\.admission\.outputs\.publish == 'true' && needs\.installed-qualification\.result == 'success' && needs\.macos-sign\.result == 'success'(?: && needs\.admission\.outputs\.dry_run != 'true')? \}\}/.test(publishSource);
730
733
  const protectedReleasePublish = releaseChain
731
734
  && (legacyReleasePublishGate || admittedReleasePublishGate)
732
735
  && /\n permissions:\n contents: write\n/.test(publishSource);
@@ -22,7 +22,7 @@
22
22
  "@rightkit/logs": "0.1.4",
23
23
  "@rightkit/platform-ui": "0.1.1",
24
24
  "@rightkit/qa": "0.2.1",
25
- "@rightkit/release": "0.2.102",
25
+ "@rightkit/release": "0.2.104",
26
26
  "@rightkit/tauri": "0.1.1",
27
27
  "@rightkit/updates": "0.2.4"
28
28
  },