@rightkit/release 0.6.3 → 0.6.5

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.
Files changed (48) hide show
  1. package/README.md +67 -5
  2. package/admission-files.mjs +279 -0
  3. package/admission-host.mjs +403 -0
  4. package/admission.mjs +146 -0
  5. package/app-check.mjs +869 -0
  6. package/bin/darwin/rightkit-swap +0 -0
  7. package/bin/rightkit-gate.mjs +68 -29
  8. package/build-release.mjs +81 -21
  9. package/cli/right-release.mjs +39 -5
  10. package/deterministic-scans.mjs +42 -15
  11. package/development.mjs +3 -2
  12. package/hosted-workflow-policy.mjs +111 -0
  13. package/inventory-check.mjs +12 -1
  14. package/ios-dev.mjs +2 -2
  15. package/ios-host.mjs +7 -7
  16. package/ios-package-recipe.mjs +2 -2
  17. package/local-publish.mjs +1 -1
  18. package/local-qualify.mjs +3 -3
  19. package/local-runtime.mjs +1 -1
  20. package/ownership-dependency-allowlist.json +2 -0
  21. package/package.json +5 -3
  22. package/pipeline-admission.mjs +5 -4
  23. package/pipeline-receipts.mjs +302 -302
  24. package/pipeline-scan.mjs +3 -3
  25. package/pipeline-tools.mjs +175 -171
  26. package/prebuild-gates.mjs +191 -0
  27. package/progress-control.mjs +1 -1
  28. package/publish-update.mjs +4 -3
  29. package/qa-admission-policy.json +5 -0
  30. package/release-config.mjs +353 -330
  31. package/release-qa-audit.mjs +37 -11
  32. package/release-qa-command.mjs +46 -5
  33. package/release-qa-fixtures.mjs +127 -0
  34. package/release-qa-floor.json +6 -1
  35. package/release-qa-hardening.mjs +173 -0
  36. package/release-qa-policy.mjs +168 -0
  37. package/release-qa-receipt.mjs +21 -1
  38. package/release-switch-scan.mjs +137 -6
  39. package/release.mjs +333 -231
  40. package/rightapps-register.mjs +3 -1
  41. package/rightkit-drift.mjs +1 -1
  42. package/rightkit-ownership.json +15 -5
  43. package/rightkit-versions.json +50 -37
  44. package/stage-sidecar.mjs +17 -15
  45. package/suite-api-literal.mjs +109 -0
  46. package/suite-api.generated.mjs +78 -0
  47. package/swap-helper-bundle.mjs +2 -2
  48. package/win-package-recipe.mjs +7 -4
@@ -0,0 +1,78 @@
1
+ // GENERATED by scripts/gen-suite-api.mjs from contracts/right-suite-api.v1.json; do not edit.
2
+ // Right Suite API host constants (contract right-suite-api.v1) for @rightkit/release.
3
+
4
+ export const RIGHT_SUITE_API_HOST = "api.orthiclabs.com";
5
+ export const RIGHT_SUITE_API_ORIGIN = "https://api.orthiclabs.com";
6
+ export const RIGHT_SUITE_LEGACY_HOSTS = ["api.spoares.com"];
7
+ export const RIGHT_SUITE_UPDATER_MANIFEST_PATH = "/v1/apps/{app}/releases/latest.json?platform={{target}}";
8
+ export const RIGHT_SUITE_RELEASE_STATUS_PATH = "/v1/apps/{app}/releases/status.json";
9
+ export const RIGHT_SUITE_ADMIN_PATCHES_PATH = "/v1/admin/apps/patches";
10
+ export const RIGHT_SUITE_ADMIN_RELEASES_PATH = "/v1/admin/apps/releases";
11
+ export const RIGHT_SUITE_ADMIN_RUNTIME_ARTIFACTS_PATH = "/v1/admin/apps/runtime-artifacts";
12
+ export const RIGHT_SUITE_GATED_ARTIFACT_HOST = "rightapps-license-gate.adrdsouza.workers.dev";
13
+ export const RIGHT_SUITE_PUBLIC_ARTIFACT_HOST = "pub-6c73208d46c245a9b4881d5e02f6b618.r2.dev";
14
+ export const RIGHT_SUITE_PUBLIC_INSTALLER_BASE = "https://pub-6c73208d46c245a9b4881d5e02f6b618.r2.dev";
15
+ export const RIGHT_SUITE_ARTIFACT_PATH_PREFIX = "/{app}";
16
+ export const APP_ARTIFACT_HOSTS = {
17
+ "coderight": [
18
+ "rightapps-license-gate.adrdsouza.workers.dev",
19
+ "pub-6c73208d46c245a9b4881d5e02f6b618.r2.dev"
20
+ ],
21
+ "heardright": [
22
+ "rightapps-license-gate.adrdsouza.workers.dev",
23
+ "pub-6c73208d46c245a9b4881d5e02f6b618.r2.dev"
24
+ ],
25
+ "mailright": [
26
+ "rightapps-license-gate.adrdsouza.workers.dev",
27
+ "pub-6c73208d46c245a9b4881d5e02f6b618.r2.dev"
28
+ ],
29
+ "viewright": [
30
+ "pub-6c73208d46c245a9b4881d5e02f6b618.r2.dev"
31
+ ]
32
+ };
33
+ export const RIGHT_SUITE_API_CONTRACT = {
34
+ "apps": {
35
+ "coderight": {
36
+ "artifactHosts": [
37
+ "gated",
38
+ "public"
39
+ ]
40
+ },
41
+ "heardright": {
42
+ "artifactHosts": [
43
+ "gated",
44
+ "public"
45
+ ]
46
+ },
47
+ "mailright": {
48
+ "artifactHosts": [
49
+ "gated",
50
+ "public"
51
+ ]
52
+ },
53
+ "viewright": {
54
+ "artifactHosts": [
55
+ "public"
56
+ ]
57
+ }
58
+ },
59
+ "artifactHostSets": {
60
+ "gated": "rightapps-license-gate.adrdsouza.workers.dev",
61
+ "public": "pub-6c73208d46c245a9b4881d5e02f6b618.r2.dev"
62
+ },
63
+ "artifactPathPrefix": "/{app}",
64
+ "host": "api.orthiclabs.com",
65
+ "origin": "https://api.orthiclabs.com",
66
+ "paths": {
67
+ "adminPatches": "/v1/admin/apps/patches",
68
+ "adminReleases": "/v1/admin/apps/releases",
69
+ "adminRuntimeArtifacts": "/v1/admin/apps/runtime-artifacts",
70
+ "releaseStatus": "/v1/apps/{app}/releases/status.json",
71
+ "updaterManifest": "/v1/apps/{app}/releases/latest.json?platform={{target}}"
72
+ },
73
+ "pendingNativeUpdater": [
74
+ "heardright"
75
+ ],
76
+ "publicInstallerBase": "https://pub-6c73208d46c245a9b4881d5e02f6b618.r2.dev",
77
+ "schema": "right-suite-api.v1"
78
+ };
@@ -37,7 +37,7 @@ export function isSwapHelperSigned(file, { execFileSync = nodeExecFileSync } = {
37
37
  }
38
38
 
39
39
  /**
40
- * Local-pack step. darwin: build through the managed cargo wrapper (`run("cargo", ...)` is `rightkit cargo` in
40
+ * Local-pack step. darwin: build through the managed cargo wrapper (`run("cargo", ...)` is `rustright cargo` in
41
41
  * local-publish), copy to <packageDir>/bin/darwin/rightkit-swap, Developer ID sign with the shared identity
42
42
  * resolver and `macCodesignArgs` (--options runtime --timestamp), verify strictly, write a sha256 receipt.
43
43
  * Anywhere else: refuse unless the helper is present and its receipt matches its bytes. Fails closed with SwapHelperError.
@@ -66,7 +66,7 @@ export function prepareSwapHelper({
66
66
  }
67
67
  const fail = (code, message) => { throw new SwapHelperError(code, message); };
68
68
  const built = run("cargo", SWAP_HELPER_CARGO_ARGS, { cwd: workspaceRoot, env });
69
- if (built.error || built.status !== 0) fail("SWAP_HELPER_BUILD_FAILED", `rightkit cargo ${SWAP_HELPER_CARGO_ARGS.join(" ")} failed (${built.error?.message ?? `exit ${built.status}`})\n${tail(`${built.stdout ?? ""}\n${built.stderr ?? ""}`)}`);
69
+ if (built.error || built.status !== 0) fail("SWAP_HELPER_BUILD_FAILED", `rustright cargo ${SWAP_HELPER_CARGO_ARGS.join(" ")} failed (${built.error?.message ?? `exit ${built.status}`})\n${tail(`${built.stdout ?? ""}\n${built.stderr ?? ""}`)}`);
70
70
  const meta = run("cargo", ["metadata", "--format-version", "1", "--no-deps"], { cwd: workspaceRoot, env });
71
71
  let targetDir;
72
72
  try { targetDir = JSON.parse(meta.stdout).target_directory; } catch { /* refused below */ }
@@ -130,6 +130,9 @@ export function validateWinPackage({ appRoot, config = {}, target } = {}) {
130
130
  }
131
131
  }
132
132
  if (spec.updater === true && target.updater !== undefined && !isPlainObject(target.updater)) issues.push("target.updater must be an object when winPackage.updater is true");
133
+ if (isPlainObject(target.updater) && Object.prototype.hasOwnProperty.call(target.updater, "keyFile")) {
134
+ issues.push("target.updater.keyFile is not supported: updater signing keys come from the OS credential provider (rightkit-credentials, namespace rightsuite-updater-key; see protected-credentials.mjs and sign-updater.mjs), never from a key file. Remove updater.keyFile");
135
+ }
133
136
 
134
137
  if (issues.length) throw new WinPackageConfigError(issues);
135
138
  return Object.freeze({
@@ -142,7 +145,6 @@ export function validateWinPackage({ appRoot, config = {}, target } = {}) {
142
145
  installerFile,
143
146
  sidecars: Object.freeze(sidecars),
144
147
  tauriCwd,
145
- updaterKeyFile: typeof target.updater?.keyFile === "string" ? target.updater.keyFile : null,
146
148
  });
147
149
  }
148
150
 
@@ -181,11 +183,12 @@ export function defaultWinPackageDeps({ appRoot, target, env }) {
181
183
  const evidence = JSON.parse(readFileSync(receipt, "utf8"));
182
184
  return evidence.files.map((item) => ({ file: path.resolve(item.file), sha256: item.after?.sha256 }));
183
185
  },
184
- signUpdater(file, { keyFile, dryRun = false }) {
186
+ // The signing key comes from the OS credential provider inside sign-updater; no key path is ever passed down.
187
+ signUpdater(file, { dryRun = false } = {}) {
185
188
  const childEnv = { ...env };
186
189
  delete childEnv.TAURI_SIGNING_PRIVATE_KEY;
187
190
  delete childEnv.TAURI_SIGNING_PRIVATE_KEY_PASSWORD;
188
- const result = spawn("node", [SIGN_UPDATER, "--file", file, ...(dryRun ? ["--dry-run"] : []), ...(keyFile ? ["--key-file", keyFile] : [])], { cwd: appRoot, env: childEnv });
191
+ const result = spawn("node", [SIGN_UPDATER, "--file", file, ...(dryRun ? ["--dry-run"] : [])], { cwd: appRoot, env: childEnv });
189
192
  if (result.error || result.status !== 0) throw new Error(`sign-updater exited ${result.status ?? result.error?.message}`);
190
193
  },
191
194
  patchMarker: (file, options) => patchTauriBundleType(file, options),
@@ -299,7 +302,7 @@ export function runWinPackageRecipe({ appRoot, config = {}, target, deps = {} }
299
302
  if (plan.updater) {
300
303
  phase("updater", () => {
301
304
  if (!dry) fs.rmSync(`${installer}.sig`, { force: true });
302
- d.signUpdater(installer, { keyFile: plan.updaterKeyFile, dryRun: dry });
305
+ d.signUpdater(installer, { dryRun: dry });
303
306
  if (dry) return;
304
307
  if (!fs.existsSync(`${installer}.sig`)) throw new Error(`sign-updater did not write ${installer}.sig`);
305
308
  updaterSignature = `${installer}.sig`;