@rightkit/release 0.4.1 → 0.5.0

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.
@@ -3,6 +3,7 @@ import path from "node:path";
3
3
  import { spawn } from "../background-process.mjs";
4
4
  import { fileURLToPath } from "node:url";
5
5
  import { assertReleaseExecutionAllowed } from "../execution-policy.mjs";
6
+ import { hostUploadRefusalMessage } from "../host-upload-refusal.mjs";
6
7
 
7
8
  const packageRoot = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "..");
8
9
  const commands = new Map([
@@ -19,6 +20,7 @@ const commands = new Map([
19
20
  ["sign-windows", "sign-windows.mjs"],
20
21
  ["sign-updater", "sign-updater.mjs"],
21
22
  ["sign-dev-artifact", "sign-dev-artifact.mjs"],
23
+ ["sign-qa-bundle", "sign-qa-bundle.mjs"],
22
24
  ["sign-candidate", "sign-candidate.mjs"],
23
25
  ["engine-locate", "engine-locator.mjs"],
24
26
  ["stage-sidecar", "stage-sidecar-command.mjs"],
@@ -65,6 +67,7 @@ try {
65
67
  || first?.startsWith("-")
66
68
  || (first === "addon" && args[1] === "build")
67
69
  || (first === "dmg" && args[1] === "build")
70
+ || first === "qualify"
68
71
  || (first === "publish" && ["cargo", "swift"].includes(args[1]))) {
69
72
  assertReleaseExecutionAllowed({ command: `right-release ${args.join(" ")}`.trim() });
70
73
  }
@@ -103,8 +106,25 @@ if (first === "--version" || first === "-v") {
103
106
  run("dmg-build.mjs", args.slice(1));
104
107
  } else if (first === "apple") {
105
108
  run("apple-profile-renew.mjs", args.slice(1));
109
+ } else if (first === "qualify") {
110
+ // Local qualification (default): both native hosts qualify the crates through the RustRight broker and a candidate is cut.
111
+ // It uploads nothing; the approval commit and publish-reviewed.yml publish the pinned bytes (docs/CI.md "Local qualification").
112
+ run("local-qualify.mjs", args.slice(1));
106
113
  } else if (first === "publish") {
107
114
  const rest = args.slice(1);
115
+ // RightKit crates and @rightkit packages reach a registry from CI only: publish.yml qualification, the approval
116
+ // commit in ci/approved-artifacts.json, then publish-reviewed.yml uploads exactly the approved bytes (docs/CI.md).
117
+ // Every host-side upload path is refused on every host; preflight, --dry-run and --qualify-only still run.
118
+ if (rest[0] === "cargo" || rest[0] === "npm") {
119
+ const uploads = rest[0] === "npm"
120
+ ? rest.includes("--publish") || rest.includes("--local")
121
+ : !rest.includes("--dry-run") && !rest.includes("--qualify-only");
122
+ // Unconditional: a caller-set GITHUB_ACTIONS=true never lifts it (CI uploads use scripts/ci/publish.mjs and reviewed-candidate.mjs).
123
+ if (uploads) {
124
+ console.error(hostUploadRefusalMessage(`right-release publish ${rest[0]}`));
125
+ process.exit(2);
126
+ }
127
+ }
108
128
  if ((rest[0] === "cargo" || rest[0] === "npm") && rest.includes("--local")) {
109
129
  run("local-publish.mjs", rest);
110
130
  } else if (rest[0] === "cargo") {
@@ -237,6 +257,8 @@ Commands:
237
257
  Fail when a built web dist/ carries a forbidden marker string or mock/fixture chunk name (dev, mock or fixture code in release)
238
258
  sign-dev-artifact --artifact <dir> --manifest <sign.json> [--metadata <payload.json>] [--evidence <path>] [--dry-run]
239
259
  Developer ID sign an existing CI dev artifact per file with fixed identifiers; never builds, notarizes or publishes (macOS)
260
+ sign-qa-bundle --app <abs .app> --qa-root <abs dir> [--entitlements <abs plist>] [--out <evidence.json>]
261
+ QA ONLY: ad hoc sign a bundle inside a QA scratch root, nested code first, outer last, never --deep, never the signing agent (macOS); not a release artifact
240
262
  sign-candidate --platform win|mac --artifact <dir> --candidate-receipt <receipt.json> --out <binding.json> [--manifest <sign.json>] [--publisher <subject>] [--dry-run]
241
263
  Sign the exact unsigned candidate bytes (sha256 checked against the candidate receipt) instead of rebuilding; writes a candidate-sha -> signed-sha binding receipt
242
264
  engine-locate --engine cutright|genright [--sha256 <hex>] [--json]
@@ -268,6 +290,13 @@ Commands:
268
290
  Verify on source host; export crate bytes & gate evidence without uploading
269
291
  publish cargo --crate <name> --from-evidence <gate.json>
270
292
  Reuse exact HEAD/artifact proof on upload host; recheck archive hash & registry bytes
293
+ qualify cargo --crates <a,b> [--hosts win,mac] [--id <id>] [--allow-ignored-units <a,b>] [--jobs <1-64>] [--concurrency <1-8>] [--out <dir>] [--no-release] [--with-ci]
294
+ Qualify the crates on BOTH native hosts through the RustRight broker (Dell: Windows, Mac: macOS over ssh), seal one packed
295
+ asset and one receipt per host, attach them to the prerelease candidate-<id> and print the candidate and approval entry.
296
+ Needs a clean checkout with HEAD on origin/main (the other host at the same HEAD). Never uploads to a registry.
297
+ --with-ci also dispatches publish.yml for the same commit when the hosts start and pins that run in the candidate as clean-room proof
298
+ (Linux-required units and runtime owners no local workload covers are planned only with --with-ci, and then need that run to succeed).
299
+ Any repository: owner/name from its origin remote; hosts, approvals file and promotion workflow from .rightkit-gate.json
271
300
  publish swift [--dry-run] [--evidence <file>] [--workspace <dir>]
272
301
  Check main, a clean tree, and the publication evidence, then tag RightKitSwift at its VERSION on origin
273
302
  inventory check [--json] [--warn-only] [--md <file>] [--no-cache]