@rightkit/release 0.2.147 → 0.2.149

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rightkit/release",
3
- "version": "0.2.147",
3
+ "version": "0.2.149",
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
@@ -742,7 +742,8 @@ async function validateHostedWorkflows(root, appName, workflows, policy) {
742
742
  fail(`${appName} right-git-ci-only policy requires a valid .rightgit.json`);
743
743
  }
744
744
  const lanes = manifest?.lanes;
745
- const safeLanes = new Set(["ci", "release-candidate"]);
745
+ // Mirrors the `lanes` enum in @rightkit/git manifest.schema.json.
746
+ const safeLanes = new Set(["ci", "qualification", "package-smoke", "release-candidate", "publish-npm", "publish-package-managers", "regenerate"]);
746
747
  if (manifest?.schemaVersion !== 1
747
748
  || manifest?.compile !== "github-actions-only"
748
749
  || !Array.isArray(lanes)
@@ -750,7 +751,7 @@ async function validateHostedWorkflows(root, appName, workflows, policy) {
750
751
  || !lanes.includes("ci")
751
752
  || new Set(lanes).size !== lanes.length
752
753
  || lanes.some((lane) => !safeLanes.has(lane))) {
753
- fail(`${appName} right-git-ci-only policy requires compile=github-actions-only plus unique .rightgit.json lanes drawn from ["ci", "release-candidate"] and including "ci"`);
754
+ fail(`${appName} right-git-ci-only policy requires compile=github-actions-only plus unique .rightgit.json lanes drawn from [${[...safeLanes].map((lane) => `"${lane}"`).join(", ")}] and including "ci"`);
754
755
  }
755
756
  const expectedWorkflows = lanes.map((lane) => `${lane}.yml`).sort();
756
757
  if (JSON.stringify(workflows) !== JSON.stringify(expectedWorkflows)) {
@@ -798,6 +799,31 @@ async function validateHostedWorkflows(root, appName, workflows, policy) {
798
799
  const protectedMacosSigning = workflow === "release-candidate.yml"
799
800
  && manifest?.candidate?.signMacos === true
800
801
  && (legacySigningGate("macos-sign").test(macosSource) || admittedSigningGate("macos-sign").test(macosSource));
802
+ // @rightkit/git `devArtifact.mac: "sign"` renders a `dev-mac-sign` job into
803
+ // the managed ci.yml: push to the default branch only, release environment,
804
+ // Developer ID certificate secrets only (no notarization keys).
805
+ // @rightkit/git `regenerate` lane: manual-only, opens a pull request from a
806
+ // right-git/regenerate-<run> branch and never writes to the default branch.
807
+ // `contents: write` and `pull-requests: write` are accepted only inside that
808
+ // job, only when the manifest declares `regenerate`, and only when the
809
+ // workflow has no trigger other than workflow_dispatch and pushes solely to
810
+ // the right-git/regenerate-* branch namespace.
811
+ const regenerateSpan = workflow === "regenerate.yml" ? jobSpan("regenerate") : null;
812
+ const regenerateSource = regenerateSpan ? source.slice(regenerateSpan.start, regenerateSpan.end) : "";
813
+ const protectedRegenerate = workflow === "regenerate.yml"
814
+ && manifest?.regenerate && typeof manifest.regenerate.script === "string"
815
+ && /^on:\n workflow_dispatch:\n(?! )/m.test(source)
816
+ && /regenerate:\n needs: \[private-repo-guard\]\n if: \$\{\{ github\.event_name == 'workflow_dispatch' \}\}\n/.test(regenerateSource)
817
+ && /branch="right-git\/regenerate-\$\{\{ github\.run_id \}\}-\$\{\{ github\.run_attempt \}\}"\n/.test(regenerateSource)
818
+ && /git push origin "HEAD:refs\/heads\/\$branch"\n/.test(regenerateSource)
819
+ && !/git push(?![^\n]*"HEAD:refs\/heads\/\$branch")/.test(regenerateSource);
820
+ const allowedRegeneratePermissions = new Set(["contents", "pull-requests"]);
821
+ const devMacSpan = workflow === "ci.yml" ? jobSpan("dev-mac-sign") : null;
822
+ const devMacSource = devMacSpan ? source.slice(devMacSpan.start, devMacSpan.end) : "";
823
+ const allowedDevMacSecrets = new Set(["APPLE_CERTIFICATE_BASE64", "APPLE_CERTIFICATE_PASSWORD", "APPLE_KEYCHAIN_PASSWORD"]);
824
+ const protectedDevMacSigning = workflow === "ci.yml"
825
+ && manifest?.devArtifact?.mac === "sign"
826
+ && /dev-mac-sign:\n(?: #[^\n]*\n)* needs: \[ci\]\n if: \$\{\{ github\.event_name == 'push' && github\.ref_name == github\.event\.repository\.default_branch \}\}\n environment: /.test(devMacSource);
801
827
  const releaseChain = workflow === "release-candidate.yml" ? manifest?.candidate?.releaseChain : undefined;
802
828
  const allowedReleaseSecrets = new Set(releaseChain?.publishSecrets ?? []);
803
829
  const writePermissions = [...source.matchAll(/^\s*(actions|attestations|checks|contents|deployments|discussions|id-token|issues|models|packages|pages|pull-requests|security-events|statuses):\s*write\s*$/gmi)].map((match) => ({ name: match[1].toLowerCase(), index: match.index }));
@@ -815,12 +841,16 @@ async function validateHostedWorkflows(root, appName, workflows, policy) {
815
841
  && (legacyReleasePublishGate || admittedReleasePublishGate)
816
842
  && /\n permissions:\n contents: write\n/.test(publishSource);
817
843
  if (/^\s*permissions:\s*write-all\s*$/mi.test(source)
818
- || writePermissions.some(({ name, index }) => name === "id-token"
819
- ? !(protectedWindowsSigning && inside(index, windowsSpan))
820
- : name !== "contents" || !protectedReleasePublish || !inside(index, publishSpan))
844
+ || writePermissions.some(({ name, index }) => {
845
+ if (protectedRegenerate && inside(index, regenerateSpan) && allowedRegeneratePermissions.has(name)) return false;
846
+ return name === "id-token"
847
+ ? !(protectedWindowsSigning && inside(index, windowsSpan))
848
+ : name !== "contents" || !protectedReleasePublish || !inside(index, publishSpan);
849
+ })
821
850
  || /pull_request_target\s*:/i.test(source)
822
851
  || /\bsecrets\s*\[/i.test(source)
823
852
  || requestedSecrets.some(({ name, index }) => !(protectedMacosSigning && inside(index, macosSpan) && allowedMacosSecrets.has(name))
853
+ && !(protectedDevMacSigning && inside(index, devMacSpan) && allowedDevMacSecrets.has(name))
824
854
  && !(protectedReleasePublish && inside(index, publishSpan) && allowedReleaseSecrets.has(name)))) {
825
855
  fail(`${appName} right-git managed ${workflow} requests release-capable permissions or secrets`);
826
856
  }
@@ -16,7 +16,7 @@
16
16
  "@rightkit/app-shell": "0.3.0",
17
17
  "@rightkit/ax": "0.2.4",
18
18
  "@rightkit/doc-render": "0.1.4",
19
- "@rightkit/git": "0.2.33",
19
+ "@rightkit/git": "0.2.36",
20
20
  "@rightkit/hooks": "0.1.2",
21
21
  "@rightkit/i18n": "0.1.0",
22
22
  "@rightkit/legal": "0.3.1",
@@ -29,7 +29,7 @@
29
29
  "@rightkit/platform-ui": "0.2.0",
30
30
  "@rightkit/qa": "0.4.0",
31
31
  "@rightkit/qa-chrome": "0.1.3",
32
- "@rightkit/release": "0.2.147",
32
+ "@rightkit/release": "0.2.149",
33
33
  "@rightkit/settings-ui": "0.3.0",
34
34
  "@rightkit/shell": "0.1.0",
35
35
  "@rightkit/tauri": "0.2.0",
@@ -74,7 +74,10 @@
74
74
  "0.2.29",
75
75
  "0.2.30",
76
76
  "0.2.31",
77
- "0.2.32"
77
+ "0.2.32",
78
+ "0.2.33",
79
+ "0.2.34",
80
+ "0.2.35"
78
81
  ],
79
82
  "@rightkit/legal-ui": [
80
83
  "0.1.0",
@@ -179,7 +182,9 @@
179
182
  "0.2.143",
180
183
  "0.2.144",
181
184
  "0.2.145",
182
- "0.2.146"
185
+ "0.2.146",
186
+ "0.2.147",
187
+ "0.2.148"
183
188
  ],
184
189
  "@rightkit/qa": [
185
190
  "0.1.0",
@@ -378,7 +383,7 @@
378
383
  "@rightkit/app-shell": "0.3.0",
379
384
  "@rightkit/ax": "0.2.4",
380
385
  "@rightkit/doc-render": "0.1.4",
381
- "@rightkit/git": "0.2.33",
386
+ "@rightkit/git": "0.2.36",
382
387
  "@rightkit/hooks": "0.1.2",
383
388
  "@rightkit/i18n": "0.1.0",
384
389
  "@rightkit/legal": "0.3.1",
@@ -391,7 +396,7 @@
391
396
  "@rightkit/platform-ui": "0.2.0",
392
397
  "@rightkit/qa": "0.4.0",
393
398
  "@rightkit/qa-chrome": "0.1.3",
394
- "@rightkit/release": "0.2.147",
399
+ "@rightkit/release": "0.2.148",
395
400
  "@rightkit/settings-ui": "0.3.0",
396
401
  "@rightkit/shell": "0.1.0",
397
402
  "@rightkit/tauri": "0.2.0",