@rightkit/release 0.2.81 → 0.2.82

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.
package/build-release.mjs CHANGED
@@ -168,7 +168,15 @@ try {
168
168
  // outlived the change that was supposed to retire them.
169
169
  pipeline: PIPELINE_FINGERPRINT,
170
170
  configSha256: hashFile(configPath),
171
- receiptInputs: ["raw-exe", "installer", "embedding"].map((phase) => path.join(receiptRoot, `windows-${phase}.json`)),
171
+ // Resolve each phase receipt the same way signing does: the config's
172
+ // sign.receipt / sign.installerReceipt override wins, the default
173
+ // windows-<phase>.json name is only the fallback. Hardcoding the default
174
+ // here made the seal read a path the signer never wrote whenever a config
175
+ // (e.g. an architecture-qualified receipt) overrode it.
176
+ receiptInputs: ["raw-exe", "installer", "embedding"].map((phase) => {
177
+ const configured = phase === "raw-exe" ? target.sign?.receipt : phase === "installer" ? target.sign?.installerReceipt : undefined;
178
+ return configured ? path.resolve(appRoot, configured) : path.join(receiptRoot, `windows-${phase}.json`);
179
+ }),
172
180
  } : null;
173
181
  if (signingIdentity) inputHashes[".right-release/signing-identity.json"] = hashFileText(JSON.stringify(signingIdentity));
174
182
  const cargoLock = nativeLayout.lockPath;
@@ -435,7 +443,15 @@ function sealRelease({ configRoot, managedCargoTarget, nativeLayout, sealedDir,
435
443
  commit,
436
444
  platform,
437
445
  cacheKey,
438
- signing: signingIdentity ? { ...signingIdentity, receipts: signingIdentity.receiptInputs.map((file) => ({ file, sha256: hashFile(file) })) } : null,
446
+ // Portable contracts sign only raw executables installer/embedding
447
+ // receipts legitimately never exist there. Seal every receipt that was
448
+ // produced, but never zero: a signed platform with no receipt at all is
449
+ // an unsound seal, not a portable release.
450
+ signing: signingIdentity ? { ...signingIdentity, receipts: (() => {
451
+ const present = signingIdentity.receiptInputs.filter((file) => existsSync(file));
452
+ if (present.length === 0) throw new Error(`no signing receipts found to seal; expected at least ${signingIdentity.receiptInputs[0]}`);
453
+ return present.map((file) => ({ file, sha256: hashFile(file) }));
454
+ })() } : null,
439
455
  files,
440
456
  routes,
441
457
  inputs: inputHashes,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rightkit/release",
3
- "version": "0.2.81",
3
+ "version": "0.2.82",
4
4
  "description": "Portable Right Suite release CLI/SDK: signed native archives, direct bootstrap transactions, immutable GitHub Release upload, R2 bootstrap publication, and add-on adoption.",
5
5
  "license": "MIT OR Apache-2.0",
6
6
  "type": "module",
package/release.mjs CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import { access, readFile, readdir } from "node:fs/promises";
3
3
  import { createHash } from "node:crypto";
4
- import { existsSync, mkdirSync, readFileSync, realpathSync, unlinkSync, writeFileSync } from "node:fs";
4
+ import { existsSync, mkdirSync, readFileSync, realpathSync, rmSync, unlinkSync, writeFileSync } from "node:fs";
5
5
  import path from "node:path";
6
6
  import { fileURLToPath, pathToFileURL } from "node:url";
7
7
  import { spawn, spawnSync } from "node:child_process";
@@ -378,6 +378,12 @@ async function runNativeFinalizer({ finalizer, nativeAssembly, target, root, sig
378
378
  ...finalizer,
379
379
  args: finalizer.args.map((arg) => expandFinalizerToken(arg, { provenance, outputPath, packageIdentity })),
380
380
  };
381
+ // A finalization receipt at outputPath from a PREVIOUS run must not
382
+ // survive into this one: the file is preferred over the finalizer's
383
+ // stdout below, and a stale receipt carries the prior run's provenance,
384
+ // which fails the identity check against this run's mint. Any file
385
+ // present after the finalizer returns was written by this run.
386
+ if (!opts.dryRun) rmSync(outputPath, { force: true });
381
387
  const stdout = await runCommand(finalizerCommand, root, {
382
388
  captureStdout: true,
383
389
  env: {
@@ -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.81",
25
+ "@rightkit/release": "0.2.82",
26
26
  "@rightkit/tauri": "0.1.1",
27
27
  "@rightkit/updates": "0.2.4"
28
28
  },