@intentius/chant 0.124.32 → 0.124.33
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/dist/ci-jobs.d.ts +4 -0
- package/dist/ci-jobs.d.ts.map +1 -1
- package/dist/ci-jobs.js +9 -2
- package/dist/cli/handlers/build.d.ts.map +1 -1
- package/dist/cli/handlers/build.js +18 -3
- package/dist/cli/handlers/lifecycle-health.d.ts +16 -0
- package/dist/cli/handlers/lifecycle-health.d.ts.map +1 -0
- package/dist/cli/handlers/lifecycle-health.js +150 -0
- package/dist/cli/handlers/lifecycle.d.ts +26 -0
- package/dist/cli/handlers/lifecycle.d.ts.map +1 -1
- package/dist/cli/handlers/lifecycle.js +1 -1
- package/dist/cli/handlers/pr.d.ts +2 -0
- package/dist/cli/handlers/pr.d.ts.map +1 -1
- package/dist/cli/handlers/pr.js +124 -2
- package/dist/cli/handlers/promote.d.ts.map +1 -1
- package/dist/cli/handlers/promote.js +16 -1
- package/dist/cli/handlers/release.d.ts +16 -1
- package/dist/cli/handlers/release.d.ts.map +1 -1
- package/dist/cli/handlers/release.js +83 -11
- package/dist/cli/main.d.ts.map +1 -1
- package/dist/cli/main.js +81 -21
- package/dist/cli/parse-args.d.ts.map +1 -1
- package/dist/cli/parse-args.js +23 -1
- package/dist/cli/registry.d.ts +18 -4
- package/dist/cli/registry.d.ts.map +1 -1
- package/dist/components/deploy-inputs.d.ts +91 -0
- package/dist/components/deploy-inputs.d.ts.map +1 -0
- package/dist/components/deploy-inputs.js +184 -0
- package/dist/components/driver.d.ts.map +1 -1
- package/dist/components/driver.js +9 -0
- package/dist/components/gate-plan.d.ts +8 -0
- package/dist/components/gate-plan.d.ts.map +1 -1
- package/dist/components/gate-plan.js +6 -0
- package/dist/components/pr-pipeline.d.ts +33 -10
- package/dist/components/pr-pipeline.d.ts.map +1 -1
- package/dist/components/pr-pipeline.js +42 -11
- package/dist/components/pr-run.d.ts +1 -1
- package/dist/components/pr-run.d.ts.map +1 -1
- package/dist/components/release-compile.d.ts +37 -2
- package/dist/components/release-compile.d.ts.map +1 -1
- package/dist/components/release-compile.js +64 -8
- package/dist/components/release-promote.d.ts +17 -3
- package/dist/components/release-promote.d.ts.map +1 -1
- package/dist/components/release-promote.js +79 -18
- package/dist/components/verbs/bom-writer.d.ts +1 -1
- package/dist/components/verbs/bom-writer.d.ts.map +1 -1
- package/dist/components/verbs/lockfile-sbom-generator.d.ts +20 -0
- package/dist/components/verbs/lockfile-sbom-generator.d.ts.map +1 -1
- package/dist/components/verbs/lockfile-sbom-generator.js +41 -4
- package/dist/components/wave-plan.d.ts +10 -0
- package/dist/components/wave-plan.d.ts.map +1 -1
- package/dist/components/wave-plan.js +32 -4
- package/dist/graph-detail.d.ts.map +1 -1
- package/dist/graph-detail.js +32 -7
- package/dist/health.d.ts +110 -0
- package/dist/health.d.ts.map +1 -0
- package/dist/health.js +105 -0
- package/dist/health.schema.json +191 -0
- package/dist/lexicon.d.ts +27 -0
- package/dist/lexicon.d.ts.map +1 -1
- package/dist/lifecycle/merge-record.d.ts +104 -0
- package/dist/lifecycle/merge-record.d.ts.map +1 -0
- package/dist/lifecycle/merge-record.js +102 -0
- package/dist/lifecycle/publish-attachments.d.ts +8 -5
- package/dist/lifecycle/publish-attachments.d.ts.map +1 -1
- package/dist/lifecycle/publish-attachments.js +27 -13
- package/dist/lifecycle/publish-npm.d.ts +3 -2
- package/dist/lifecycle/publish-npm.d.ts.map +1 -1
- package/dist/lifecycle/publish-npm.js +4 -3
- package/dist/lifecycle/release-at.d.ts +40 -0
- package/dist/lifecycle/release-at.d.ts.map +1 -0
- package/dist/lifecycle/release-at.js +83 -0
- package/dist/lifecycle/release-cut.d.ts.map +1 -1
- package/dist/lifecycle/release-cut.js +23 -12
- package/dist/lifecycle/release-publish.d.ts +28 -12
- package/dist/lifecycle/release-publish.d.ts.map +1 -1
- package/dist/lifecycle/release-publish.js +29 -17
- package/dist/lifecycle/release-store.d.ts +25 -2
- package/dist/lifecycle/release-store.d.ts.map +1 -1
- package/dist/lifecycle/release-store.js +40 -13
- package/dist/lifecycle/run-ledger.d.ts.map +1 -1
- package/dist/lifecycle/run-ledger.js +1 -0
- package/dist/lint/rules/op/index.d.ts +2 -1
- package/dist/lint/rules/op/index.d.ts.map +1 -1
- package/dist/lint/rules/op/index.js +4 -2
- package/dist/lint/rules/op/ops018-shell-image-digest.d.ts +10 -0
- package/dist/lint/rules/op/ops018-shell-image-digest.d.ts.map +1 -0
- package/dist/lint/rules/op/ops018-shell-image-digest.js +38 -0
- package/dist/op/activities/activity-contracts.d.ts +5 -0
- package/dist/op/activities/activity-contracts.d.ts.map +1 -1
- package/dist/op/activities/activity-contracts.js +3 -0
- package/dist/op/activities/shell.d.ts +38 -0
- package/dist/op/activities/shell.d.ts.map +1 -1
- package/dist/op/activities/shell.js +89 -3
- package/dist/op/builders.d.ts +7 -0
- package/dist/op/builders.d.ts.map +1 -1
- package/dist/op/builders.js +7 -0
- package/dist/op/runtime.d.ts +2 -0
- package/dist/op/runtime.d.ts.map +1 -1
- package/dist/pr-loop.d.ts +14 -3
- package/dist/pr-loop.d.ts.map +1 -1
- package/dist/pr-loop.js +15 -5
- package/dist/pr-report-url.d.ts +2 -2
- package/dist/pr-report-url.d.ts.map +1 -1
- package/dist/runner-start.d.ts +179 -0
- package/dist/runner-start.d.ts.map +1 -0
- package/dist/runner-start.js +277 -0
- package/dist/wave-runtime.mjs +235 -228
- package/dist/workspace/check.schema.json +70 -2
- package/dist/workspace/checks/security.d.ts +35 -0
- package/dist/workspace/checks/security.d.ts.map +1 -0
- package/dist/workspace/checks/security.js +305 -0
- package/dist/workspace/checks.d.ts +2 -0
- package/dist/workspace/checks.d.ts.map +1 -1
- package/dist/workspace/checks.js +5 -0
- package/dist/workspace/ci-builds.d.ts +163 -0
- package/dist/workspace/ci-builds.d.ts.map +1 -0
- package/dist/workspace/ci-builds.js +315 -0
- package/dist/workspace/ci-green-cli.d.ts +2 -1
- package/dist/workspace/ci-green-cli.d.ts.map +1 -1
- package/dist/workspace/ci-green-cli.js +25 -5
- package/dist/workspace/ci-green-forge.d.ts +12 -0
- package/dist/workspace/ci-green-forge.d.ts.map +1 -1
- package/dist/workspace/ci-green-forge.js +12 -0
- package/dist/workspace/ci-green-workflow.d.ts +55 -1
- package/dist/workspace/ci-green-workflow.d.ts.map +1 -1
- package/dist/workspace/ci-green-workflow.js +128 -1
- package/dist/workspace/ci-green.d.ts +89 -4
- package/dist/workspace/ci-green.d.ts.map +1 -1
- package/dist/workspace/ci-green.js +310 -23
- package/dist/workspace/ci-last-green.schema.json +49 -0
- package/dist/workspace/ci-list.schema.json +35 -1
- package/dist/workspace/ci-run-index.d.ts +1 -1
- package/dist/workspace/ci-run-index.d.ts.map +1 -1
- package/dist/workspace/ci-run-index.schema.json +1 -1
- package/dist/workspace/ci-run.d.ts +12 -6
- package/dist/workspace/ci-run.d.ts.map +1 -1
- package/dist/workspace/ci-run.js +72 -16
- package/dist/workspace/ci-runner-start.d.ts +77 -0
- package/dist/workspace/ci-runner-start.d.ts.map +1 -0
- package/dist/workspace/ci-runner-start.js +185 -0
- package/dist/workspace/ci-serve.d.ts +76 -7
- package/dist/workspace/ci-serve.d.ts.map +1 -1
- package/dist/workspace/ci-serve.js +153 -19
- package/dist/workspace/declaration.d.ts +17 -0
- package/dist/workspace/declaration.d.ts.map +1 -1
- package/dist/workspace/declaration.js +3 -0
- package/dist/workspace/declaration.schema.json +23 -0
- package/dist/workspace/ls.d.ts +2 -0
- package/dist/workspace/ls.d.ts.map +1 -1
- package/dist/workspace/ls.js +1 -1
- package/dist/workspace/ls.schema.json +2 -1
- package/dist/workspace/member-pipeline.d.ts +1 -0
- package/dist/workspace/member-pipeline.d.ts.map +1 -1
- package/dist/workspace/member-pipeline.js +2 -0
- package/dist/workspace/merge-record.schema.json +49 -0
- package/dist/workspace/pr-report.schema.json +3 -3
- package/dist/workspace/reason-codes.d.ts +17 -0
- package/dist/workspace/reason-codes.d.ts.map +1 -1
- package/dist/workspace/reason-codes.js +18 -0
- package/dist/workspace/release-candidates.d.ts +129 -0
- package/dist/workspace/release-candidates.d.ts.map +1 -0
- package/dist/workspace/release-candidates.js +233 -0
- package/dist/workspace/release-candidates.schema.json +353 -0
- package/dist/workspace/security.d.ts +40 -0
- package/dist/workspace/security.d.ts.map +1 -0
- package/dist/workspace/security.js +99 -0
- package/package.json +8 -1
- package/src/__fixtures__/pr-loop/pr-plan.note.golden.md +1 -1
- package/src/ci-jobs.ts +11 -2
- package/src/cli/handlers/build.test.ts +36 -0
- package/src/cli/handlers/build.ts +18 -3
- package/src/cli/handlers/lifecycle-health.test.ts +123 -0
- package/src/cli/handlers/lifecycle-health.ts +157 -0
- package/src/cli/handlers/lifecycle.ts +1 -1
- package/src/cli/handlers/pr-deploy-inputs.test.ts +209 -0
- package/src/cli/handlers/pr-record.test.ts +201 -0
- package/src/cli/handlers/pr.test.ts +22 -0
- package/src/cli/handlers/pr.ts +127 -4
- package/src/cli/handlers/promote.test.ts +17 -0
- package/src/cli/handlers/promote.ts +16 -1
- package/src/cli/handlers/release-cut-at.e2e.test.ts +115 -0
- package/src/cli/handlers/release-publish-targets.e2e.test.ts +2 -2
- package/src/cli/handlers/release-verify.e2e.test.ts +12 -10
- package/src/cli/handlers/release.e2e.test.ts +19 -28
- package/src/cli/handlers/release.ts +81 -11
- package/src/cli/main.ts +81 -21
- package/src/cli/parse-args.ts +17 -1
- package/src/cli/registry.ts +18 -4
- package/src/components/deploy-inputs.test.ts +108 -0
- package/src/components/deploy-inputs.ts +225 -0
- package/src/components/driver.ts +11 -0
- package/src/components/gate-plan.ts +9 -0
- package/src/components/pr-pipeline.ts +56 -15
- package/src/components/pr-run.ts +1 -1
- package/src/components/release-compile.test.ts +34 -0
- package/src/components/release-compile.ts +89 -8
- package/src/components/release-promote.test.ts +55 -2
- package/src/components/release-promote.ts +93 -23
- package/src/components/verbs/bom-writer.ts +1 -1
- package/src/components/verbs/lockfile-sbom-generator.test.ts +36 -0
- package/src/components/verbs/lockfile-sbom-generator.ts +43 -5
- package/src/components/wave-plan.ts +32 -4
- package/src/graph-detail.test.ts +57 -0
- package/src/graph-detail.ts +33 -7
- package/src/health.schema.json +191 -0
- package/src/health.test.ts +62 -0
- package/src/health.ts +178 -0
- package/src/lexicon.ts +41 -1
- package/src/lifecycle/merge-record.test.ts +111 -0
- package/src/lifecycle/merge-record.ts +154 -0
- package/src/lifecycle/publish-attachments.ts +25 -13
- package/src/lifecycle/publish-npm.ts +4 -3
- package/src/lifecycle/publish-targets.test.ts +34 -4
- package/src/lifecycle/release-at.test.ts +48 -0
- package/src/lifecycle/release-at.ts +100 -0
- package/src/lifecycle/release-cut.test.ts +41 -0
- package/src/lifecycle/release-cut.ts +22 -11
- package/src/lifecycle/release-publish.test.ts +43 -13
- package/src/lifecycle/release-publish.ts +38 -18
- package/src/lifecycle/release-store.ts +57 -13
- package/src/lifecycle/run-ledger.test.ts +13 -0
- package/src/lifecycle/run-ledger.ts +1 -0
- package/src/lint/rules/op/index.ts +4 -2
- package/src/lint/rules/op/ops018-shell-image-digest.test.ts +60 -0
- package/src/lint/rules/op/ops018-shell-image-digest.ts +48 -0
- package/src/op/activities/activity-contracts.ts +3 -0
- package/src/op/activities/shell-container.e2e.test.ts +67 -0
- package/src/op/activities/shell.test.ts +44 -1
- package/src/op/activities/shell.ts +110 -3
- package/src/op/builders.ts +7 -0
- package/src/op/runtime.ts +2 -0
- package/src/op/step-console.test.ts +4 -2
- package/src/pr-loop.test.ts +29 -0
- package/src/pr-loop.ts +26 -7
- package/src/pr-report-url.ts +2 -2
- package/src/runner-start-bundle.test.ts +29 -0
- package/src/runner-start.test.ts +179 -0
- package/src/runner-start.ts +329 -0
- package/src/workspace/check-contract.test.ts +3 -2
- package/src/workspace/check.schema.json +70 -2
- package/src/workspace/checks/security.test.ts +138 -0
- package/src/workspace/checks/security.ts +305 -0
- package/src/workspace/checks.ts +5 -0
- package/src/workspace/ci-builds.e2e.test.ts +208 -0
- package/src/workspace/ci-builds.test.ts +174 -0
- package/src/workspace/ci-builds.ts +385 -0
- package/src/workspace/ci-green-builds.test.ts +180 -0
- package/src/workspace/ci-green-cli.test.ts +54 -0
- package/src/workspace/ci-green-cli.ts +26 -5
- package/src/workspace/ci-green-forge.ts +24 -0
- package/src/workspace/ci-green-workflow.test.ts +84 -1
- package/src/workspace/ci-green-workflow.ts +139 -2
- package/src/workspace/ci-green.test.ts +5 -2
- package/src/workspace/ci-green.ts +359 -27
- package/src/workspace/ci-last-green.schema.json +49 -0
- package/src/workspace/ci-list.schema.json +35 -1
- package/src/workspace/ci-run-index.schema.json +1 -1
- package/src/workspace/ci-run-index.ts +1 -1
- package/src/workspace/ci-run.test.ts +24 -7
- package/src/workspace/ci-run.ts +78 -16
- package/src/workspace/ci-runner-start.test.ts +151 -0
- package/src/workspace/ci-runner-start.ts +193 -0
- package/src/workspace/ci-serve-builds.test.ts +86 -0
- package/src/workspace/ci-serve.test.ts +59 -0
- package/src/workspace/ci-serve.ts +177 -22
- package/src/workspace/declaration.schema.json +23 -0
- package/src/workspace/declaration.test.ts +17 -0
- package/src/workspace/declaration.ts +22 -1
- package/src/workspace/ls.schema.json +2 -1
- package/src/workspace/ls.ts +3 -2
- package/src/workspace/member-pipeline.ts +2 -1
- package/src/workspace/merge-record.schema.json +49 -0
- package/src/workspace/pr-report.schema.json +3 -3
- package/src/workspace/reason-codes.test.ts +2 -0
- package/src/workspace/reason-codes.ts +18 -0
- package/src/workspace/release-candidates.schema.json +353 -0
- package/src/workspace/release-candidates.test.ts +106 -0
- package/src/workspace/release-candidates.ts +315 -0
- package/src/workspace/security.test.ts +70 -0
- package/src/workspace/security.ts +118 -0
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* `chant ci run plan|apply` (#4094, epic #4101): run one pull-request job as
|
|
2
|
+
* `chant ci run plan|record|apply` (#4094, epic #4101, record #4168): run one pull-request job as
|
|
3
3
|
* a pipeline Op, the first slice of the chant runner.
|
|
4
4
|
*
|
|
5
5
|
* The job is the typed value `prLoopJobs` (../components/pr-pipeline.ts)
|
|
@@ -78,7 +78,7 @@ import type { OpRunFailureReason, OpRunRecord } from "../op/runtime.js";
|
|
|
78
78
|
import type { OpConfig } from "../op/types.js";
|
|
79
79
|
import { type Redact } from "../op/redact.js";
|
|
80
80
|
import { type CiSecrets } from "./ci-secrets.js";
|
|
81
|
-
/** The
|
|
81
|
+
/** The jobs a pull-request pipeline has: plan, and on merge record (#4168) or, opted in, apply. */
|
|
82
82
|
export type CiJobName = PrLoopJob["jobName"];
|
|
83
83
|
export declare const CI_JOB_NAMES: readonly CiJobName[];
|
|
84
84
|
/** The Op each job is recorded as, which `ci.green` phases match. */
|
|
@@ -193,7 +193,7 @@ export interface CiStatusConfig {
|
|
|
193
193
|
urlTemplate?: string;
|
|
194
194
|
}
|
|
195
195
|
/**
|
|
196
|
-
* A job's status context: `chant/pr-plan` for the plan, and for the apply
|
|
196
|
+
* A job's status context: `chant/pr-plan` for the plan, `chant/pr-record` for the record (#4168), and for the apply
|
|
197
197
|
* `chant/<gate>`, which is `chant/pr-apply` unless `--gate` renamed the gate.
|
|
198
198
|
* pr-plan's own status is `chant/plan` (../pr-loop.ts), a different context.
|
|
199
199
|
*/
|
|
@@ -304,6 +304,12 @@ export interface CiRunRequest {
|
|
|
304
304
|
* `runOrigin: { forge: "local" }` and `runtime: "local"`.
|
|
305
305
|
*/
|
|
306
306
|
local?: boolean;
|
|
307
|
+
/**
|
|
308
|
+
* `--require-runner-start` (#4147): refuse the job before its first step
|
|
309
|
+
* unless a runner-start statement, signed by a runner key
|
|
310
|
+
* `.chant/trust.json` at `base` lists, names this forge job.
|
|
311
|
+
*/
|
|
312
|
+
requireRunnerStart?: boolean;
|
|
307
313
|
/**
|
|
308
314
|
* `--wave <k>` (#4003, #4156): the one wave a generated apply job runs, as
|
|
309
315
|
* `pr-apply --wave <k>`. Needs `--wave-gate`.
|
|
@@ -361,12 +367,12 @@ export declare function formatCiRun(r: CiRunResult): string;
|
|
|
361
367
|
* The generator's options from `ci run`'s and `ci serve`'s flags, as `chant
|
|
362
368
|
* build --components --generate <lexicon> --pr-loop` takes them: `--gate`,
|
|
363
369
|
* `--branch`, `--events-json`, `--report-url`, `--pr-build`,
|
|
364
|
-
* `--pr-build-command`, `--wave-gate` (#4003) and `--
|
|
365
|
-
* (#
|
|
370
|
+
* `--pr-build-command`, `--wave-gate` (#4003) and `--require-review`
|
|
371
|
+
* (#4168; `--no-require-review`, the default, is still accepted).
|
|
366
372
|
*/
|
|
367
373
|
export declare function ciLoopOptions(args: CommandContext["args"]): PrLoopPipelineOptions;
|
|
368
374
|
/** The secrets file `--secrets` names, else the one `CHANT_CI_SECRETS` names, read; undefined when neither names one (#4096). */
|
|
369
375
|
export declare function ciSecretsOf(flag: string | undefined, env?: Record<string, string | undefined>): CiSecrets | undefined;
|
|
370
|
-
/** `chant ci run plan|apply` (#4094). */
|
|
376
|
+
/** `chant ci run plan|record|apply` (#4094, #4168). */
|
|
371
377
|
export declare function runCiRun(ctx: CommandContext): Promise<number>;
|
|
372
378
|
//# sourceMappingURL=ci-run.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ci-run.d.ts","sourceRoot":"","sources":["../../src/workspace/ci-run.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsEG;AAMH,OAAO,EAA+E,KAAK,SAAS,EAAE,KAAK,qBAAqB,EAAE,MAAM,2BAA2B,CAAC;AACpK,OAAO,EAAiE,KAAK,YAAY,EAAE,KAAK,SAAS,EAAE,MAAM,aAAa,CAAC;AAE/H,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAEtD,OAAO,EAAgB,KAAK,SAAS,EAAE,MAAM,6BAA6B,CAAC;AAK3E,OAAO,EAA8B,KAAK,WAAW,EAAE,KAAK,UAAU,EAAE,MAAM,sBAAsB,CAAC;AACrG,OAAO,KAAK,EAAE,kBAAkB,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AACrE,OAAO,KAAK,EAAgB,QAAQ,EAAmB,MAAM,aAAa,CAAC;AAC3E,OAAO,EAAc,KAAK,MAAM,EAAE,MAAM,cAAc,CAAC;AAMvD,OAAO,EAA2D,KAAK,SAAS,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"ci-run.d.ts","sourceRoot":"","sources":["../../src/workspace/ci-run.ts"],"names":[],"mappings":"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"}
|
package/dist/workspace/ci-run.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* `chant ci run plan|apply` (#4094, epic #4101): run one pull-request job as
|
|
2
|
+
* `chant ci run plan|record|apply` (#4094, epic #4101, record #4168): run one pull-request job as
|
|
3
3
|
* a pipeline Op, the first slice of the chant runner.
|
|
4
4
|
*
|
|
5
5
|
* The job is the typed value `prLoopJobs` (../components/pr-pipeline.ts)
|
|
@@ -94,9 +94,17 @@ import { resolveMemberContext } from "./member-pipeline.js";
|
|
|
94
94
|
import { signOpRunRecord } from "./trust/op-run-statement.js";
|
|
95
95
|
import { gitTop } from "./tree.js";
|
|
96
96
|
import { hostRunnerKey } from "./ci-runner-key.js";
|
|
97
|
-
|
|
97
|
+
import { requireRunnerStart } from "./ci-runner-start.js";
|
|
98
|
+
import { securityGroupsAt } from "./security.js";
|
|
99
|
+
export const CI_JOB_NAMES = ["plan", "apply", "record"];
|
|
98
100
|
/** The Op each job is recorded as, which `ci.green` phases match. */
|
|
99
|
-
export const CI_JOB_OPS = { plan: "pr-plan", apply: "pr-apply" };
|
|
101
|
+
export const CI_JOB_OPS = { plan: "pr-plan", apply: "pr-apply", record: "pr-record" };
|
|
102
|
+
/** What each job's Op says it does. */
|
|
103
|
+
const CI_JOB_OVERVIEWS = {
|
|
104
|
+
plan: "Plan the members this pull request reaches",
|
|
105
|
+
apply: "Apply the plan a reviewer approved",
|
|
106
|
+
record: "Record the plan on the merged commit; nothing applies",
|
|
107
|
+
};
|
|
100
108
|
/** Where a job the chant runner ran says it ran (#4094). */
|
|
101
109
|
export const CHANT_RUNNER_ORIGIN = { forge: "chant" };
|
|
102
110
|
/** Where a job `chant ci run --local` ran says it ran (#4161): this machine, outside CI. */
|
|
@@ -207,7 +215,7 @@ export function ciJobOp(input) {
|
|
|
207
215
|
const op = CI_JOB_OPS[input.job.jobName];
|
|
208
216
|
return {
|
|
209
217
|
name: op,
|
|
210
|
-
overview: input.job.jobName
|
|
218
|
+
overview: CI_JOB_OVERVIEWS[input.job.jobName],
|
|
211
219
|
labels: { Env: input.env, Pipeline: "pr", Job: input.job.jobName },
|
|
212
220
|
phases,
|
|
213
221
|
};
|
|
@@ -289,12 +297,12 @@ export function ciJobFailure(input) {
|
|
|
289
297
|
const STATUS_DESCRIPTION = 140;
|
|
290
298
|
const cut = (text, max = STATUS_DESCRIPTION) => (text.length > max ? `${text.slice(0, max - 3)}...` : text);
|
|
291
299
|
/**
|
|
292
|
-
* A job's status context: `chant/pr-plan` for the plan, and for the apply
|
|
300
|
+
* A job's status context: `chant/pr-plan` for the plan, `chant/pr-record` for the record (#4168), and for the apply
|
|
293
301
|
* `chant/<gate>`, which is `chant/pr-apply` unless `--gate` renamed the gate.
|
|
294
302
|
* pr-plan's own status is `chant/plan` (../pr-loop.ts), a different context.
|
|
295
303
|
*/
|
|
296
304
|
export function ciStatusContext(job, gate) {
|
|
297
|
-
return job === "apply" ? `chant/${gate ?? PR_APPLY_GATE}` : `chant/${CI_JOB_OPS
|
|
305
|
+
return job === "apply" ? `chant/${gate ?? PR_APPLY_GATE}` : `chant/${CI_JOB_OPS[job]}`;
|
|
298
306
|
}
|
|
299
307
|
/**
|
|
300
308
|
* The link a job's status carries: the `--status-url` template with `{key}`
|
|
@@ -466,6 +474,10 @@ export async function ciRun(req) {
|
|
|
466
474
|
throw new CiRunError(`the pull-request pipeline has no ${req.job} job; it has ${jobs.map((j) => j.jobName).join(" and ")}`);
|
|
467
475
|
if (req.wave !== undefined && (req.job !== "apply" || !req.loop?.waveGate))
|
|
468
476
|
throw new CiRunError("--wave names the one wave an apply runs, and takes --wave-gate: ci run apply --wave-gate <gate> --wave <k>");
|
|
477
|
+
// #4147: before anything runs or any secret reaches a step, the provisioner's word that this runner was started for this job.
|
|
478
|
+
// #4168: under the isolated-runners security group an apply job requires the statement too, unless it runs on this machine.
|
|
479
|
+
const isolated = !req.requireRunnerStart && !req.local && req.job === "apply" && securityGroupsAt(cwd).has("isolated-runners");
|
|
480
|
+
const started = req.requireRunnerStart || isolated ? runnerStartFor(req, { top, commit, hostEnv }) : undefined;
|
|
469
481
|
// A generated wave job's command, as prLoopWaveJobs writes it. #4161: a local job's command posts no status or note.
|
|
470
482
|
const command = `${found.command}${req.wave !== undefined ? ` --wave ${req.wave}` : ""}${req.local ? " --no-status" : ""}`;
|
|
471
483
|
const job = { ...found, command, ...(req.wave !== undefined ? { wave: req.wave } : {}) };
|
|
@@ -484,7 +496,8 @@ export async function ciRun(req) {
|
|
|
484
496
|
// In place the forge's own variables come too; one whose value is short, such as a flag, is left out, so it can't blank common words.
|
|
485
497
|
const redact = ciRedactor(req.inPlace ? { ...longValues(jobEnv), ...own } : jobEnv, req.secrets);
|
|
486
498
|
try {
|
|
487
|
-
const
|
|
499
|
+
const ran = await runCiJob(req, { cwd, top, commit, place, job, jobEnv, ...(redact ? { redact } : {}) });
|
|
500
|
+
const result = started ? { ...ran, notes: [started, ...ran.notes] } : ran;
|
|
488
501
|
return redact ? { ...result, warnings: result.warnings.map(redact), notes: result.notes.map(redact), ...(result.pushWarning ? { pushWarning: redact(result.pushWarning) } : {}) } : result;
|
|
489
502
|
}
|
|
490
503
|
catch (err) {
|
|
@@ -493,6 +506,23 @@ export async function ciRun(req) {
|
|
|
493
506
|
throw err;
|
|
494
507
|
}
|
|
495
508
|
}
|
|
509
|
+
/**
|
|
510
|
+
* `--require-runner-start` (#4147): the runner-start statement for this
|
|
511
|
+
* forge job, checked against `.chant/trust.json` at `--base` (the commit
|
|
512
|
+
* before the change, as a push's `before` is), or at the job's commit
|
|
513
|
+
* without one. Throws {@link CiRunError} unless it verifies.
|
|
514
|
+
*/
|
|
515
|
+
function runnerStartFor(req, at) {
|
|
516
|
+
if (req.local)
|
|
517
|
+
throw new CiRunError("--require-runner-start checks a forge job's runner, and --local runs the job on this machine");
|
|
518
|
+
const base = req.base ? resolveJobCommit(at.top, req.base) : at.commit;
|
|
519
|
+
try {
|
|
520
|
+
return requireRunnerStart({ top: at.top, base, commit: at.commit, env: at.hostEnv }).reason;
|
|
521
|
+
}
|
|
522
|
+
catch (err) {
|
|
523
|
+
throw new CiRunError(message(err));
|
|
524
|
+
}
|
|
525
|
+
}
|
|
496
526
|
/** The generator's options for a `--local` job (#4161): the same, with no report URL. */
|
|
497
527
|
function localLoop(loop) {
|
|
498
528
|
const { reportUrl: _dropped, ...rest } = loop ?? {};
|
|
@@ -722,8 +752,8 @@ export function formatCiRun(r) {
|
|
|
722
752
|
* The generator's options from `ci run`'s and `ci serve`'s flags, as `chant
|
|
723
753
|
* build --components --generate <lexicon> --pr-loop` takes them: `--gate`,
|
|
724
754
|
* `--branch`, `--events-json`, `--report-url`, `--pr-build`,
|
|
725
|
-
* `--pr-build-command`, `--wave-gate` (#4003) and `--
|
|
726
|
-
* (#
|
|
755
|
+
* `--pr-build-command`, `--wave-gate` (#4003) and `--require-review`
|
|
756
|
+
* (#4168; `--no-require-review`, the default, is still accepted).
|
|
727
757
|
*/
|
|
728
758
|
export function ciLoopOptions(args) {
|
|
729
759
|
return {
|
|
@@ -734,13 +764,13 @@ export function ciLoopOptions(args) {
|
|
|
734
764
|
...(args.prBuild ? { build: true } : {}),
|
|
735
765
|
...(args.prBuildCommand ? { buildCommand: args.prBuildCommand } : {}),
|
|
736
766
|
...(args.waveGate ? { waveGate: args.waveGate } : {}),
|
|
737
|
-
...(args.requireReview ===
|
|
767
|
+
...(args.requireReview === true ? { requireReview: true } : {}),
|
|
738
768
|
};
|
|
739
769
|
}
|
|
740
|
-
const USAGE = "chant ci run plan|apply --env <env> --base <sha> [--pr <n>] [--commit <sha>] [--forge github|gitlab|forgejo] " +
|
|
770
|
+
const USAGE = "chant ci run plan|record|apply --env <env> --base <sha> [--pr <n>] [--commit <sha>] [--forge github|gitlab|forgejo] " +
|
|
741
771
|
"[--gate <name>] [--wave-gate <name>] [--wave <k>] [--branch <name>] [--events-json] [--report-url <url>] [--run-index-limit <n>] [--image <image>] [--before-script <line>]... " +
|
|
742
|
-
"[--pr-build] [--pr-build-command <line>] [--
|
|
743
|
-
"[--chant <command>] [--pass-env <NAME>]... [--secrets <file>] [--key <runner key.pem>] [-o <dir>] [--in-place | --local] [--no-push] [--verbose] | chant ci run --setup-key [--trust [--principal <name>]] [--state <dir>] [--branch <name>]";
|
|
772
|
+
"[--pr-build] [--pr-build-command <line>] [--require-review] [--no-status] [--status-url <url template>] " +
|
|
773
|
+
"[--chant <command>] [--pass-env <NAME>]... [--secrets <file>] [--key <runner key.pem>] [-o <dir>] [--in-place | --local] [--no-push] [--verbose] | chant ci run --at <sha> | chant ci run --setup-key [--trust [--principal <name>]] [--state <dir>] [--branch <name>]";
|
|
744
774
|
const ENV_NAME = /^[A-Za-z_][A-Za-z0-9_]*$/;
|
|
745
775
|
/** The host's runner key in `--state`, or in ci serve's default state directory, when `--setup-key` made one there (#4099). */
|
|
746
776
|
function hostRunnerKeyAt(cwd, statePath) {
|
|
@@ -760,15 +790,40 @@ export function ciSecretsOf(flag, env = process.env) {
|
|
|
760
790
|
const file = flag ?? (env[CI_SECRETS_ENV] || undefined);
|
|
761
791
|
return file === undefined ? undefined : readCiSecrets(resolve(file));
|
|
762
792
|
}
|
|
763
|
-
/**
|
|
793
|
+
/**
|
|
794
|
+
* `chant ci run --at <sha>` (#4169): ask for every required phase to be built
|
|
795
|
+
* at a commit of the green branch. On GitHub, with a token in the
|
|
796
|
+
* environment, the workflows holding the phases start at once.
|
|
797
|
+
*/
|
|
798
|
+
async function requestBuildCommand(at) {
|
|
799
|
+
const { requestBuild } = await import("./ci-green.js");
|
|
800
|
+
const { ciForgeFromEnv } = await import("./ci-green-forge.js");
|
|
801
|
+
let forge;
|
|
802
|
+
try {
|
|
803
|
+
forge = process.env.GITHUB_REPOSITORY ? ciForgeFromEnv("github") : undefined;
|
|
804
|
+
}
|
|
805
|
+
catch {
|
|
806
|
+
forge = undefined;
|
|
807
|
+
}
|
|
808
|
+
const r = await requestBuild({ cwd: process.cwd(), at, ...(forge ? { forge } : {}) });
|
|
809
|
+
for (const w of r.warnings)
|
|
810
|
+
console.error(formatWarning({ message: w }));
|
|
811
|
+
const what = `${r.request.phases.join(", ")} at ${r.request.commit.slice(0, 12)}`;
|
|
812
|
+
console.log(`${r.existed ? `${r.request.tag} already asks for a build` : `Asked for ${what}: ${r.request.tag}`}. ` +
|
|
813
|
+
(r.dispatched.length > 0 ? `Started ${r.dispatched.join(", ")}.` : "The next ci tick starts it on GitHub, and ci serve --build-command serves it for chant runs."));
|
|
814
|
+
return 0;
|
|
815
|
+
}
|
|
816
|
+
/** `chant ci run plan|record|apply` (#4094, #4168). */
|
|
764
817
|
export async function runCiRun(ctx) {
|
|
765
818
|
const { args } = ctx;
|
|
766
819
|
try {
|
|
767
820
|
if (args.setupKey)
|
|
768
821
|
return (await import("./ci-serve.js")).runnerKeySetupCommand(ctx);
|
|
822
|
+
if (args.at !== undefined && args.extraPositional === undefined)
|
|
823
|
+
return await requestBuildCommand(args.at);
|
|
769
824
|
const job = args.extraPositional;
|
|
770
|
-
if (job !== "plan" && job !== "apply")
|
|
771
|
-
throw new CiRunError(`ci run takes the job to run, plan or apply${job ? `, not ${JSON.stringify(job)}` : ""}`);
|
|
825
|
+
if (job !== "plan" && job !== "apply" && job !== "record")
|
|
826
|
+
throw new CiRunError(`ci run takes the job to run, plan, record or apply${job ? `, not ${JSON.stringify(job)}` : ""}`);
|
|
772
827
|
if (!args.env)
|
|
773
828
|
throw new CiRunError("--env names the environment the pipeline is for, as chant build --components --generate <lexicon> --pr-loop took it: --env <env>");
|
|
774
829
|
const forge = args.forge ?? detectForge(process.env);
|
|
@@ -806,6 +861,7 @@ export async function runCiRun(ctx) {
|
|
|
806
861
|
...(args.local ? { local: true } : {}),
|
|
807
862
|
...(args.noPush ? { push: false } : {}),
|
|
808
863
|
...(args.wave !== undefined ? { wave: args.wave } : {}),
|
|
864
|
+
...(args.requireRunnerStart ? { requireRunnerStart: true } : {}),
|
|
809
865
|
...(args.runIndexLimit ? { runIndexLimit: args.runIndexLimit } : {}),
|
|
810
866
|
...(args.image ? { image: args.image } : {}),
|
|
811
867
|
...(args.beforeScript?.length ? { beforeScript: args.beforeScript } : {}),
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `chant ci runner-start sign|verify` and `chant ci run --require-runner-start`
|
|
3
|
+
* (#4147): the runner-start statement (../runner-start.ts) checked against
|
|
4
|
+
* `.chant/trust.json` at base.
|
|
5
|
+
*
|
|
6
|
+
* - `sign` is for the provisioner that starts a runner for one job: it signs
|
|
7
|
+
* the job's ids with a runner key the job never holds and prints the
|
|
8
|
+
* envelope, which the provisioner puts where the job looks for it.
|
|
9
|
+
* - `verify` is for the job: it names itself from the forge's variables,
|
|
10
|
+
* reads the statement, and fails unless a runner key `.chant/trust.json`
|
|
11
|
+
* at base lists, whose principal holds the `runner` role, signed it for
|
|
12
|
+
* this job.
|
|
13
|
+
* - `ci run --require-runner-start` makes the same check before the job's
|
|
14
|
+
* first step, so an apply refuses before it trades for any credentials.
|
|
15
|
+
*
|
|
16
|
+
* Requiring the statement is opt-in (#4156). With nothing asking for it,
|
|
17
|
+
* nothing reads it, and a runner with none never refuses, warns or hides
|
|
18
|
+
* anything.
|
|
19
|
+
*
|
|
20
|
+
* {@link runnerStartReadiness} says whether a repository could require it
|
|
21
|
+
* at base, and what is missing, for the isolated-runners security group
|
|
22
|
+
* (#4168, section 8), whose WSP165 check reports these gaps.
|
|
23
|
+
*/
|
|
24
|
+
import type { CommandContext } from "../cli/registry.js";
|
|
25
|
+
import { type CiJobIdentity, type RunnerStartVerdict } from "../runner-start.js";
|
|
26
|
+
import { type TrustPolicy } from "./trust/policy.js";
|
|
27
|
+
/**
|
|
28
|
+
* Check this job's runner-start statement against `.chant/trust.json` at
|
|
29
|
+
* `base`. `commit` is the commit the job runs, in place of the forge's
|
|
30
|
+
* variable. Never throws.
|
|
31
|
+
*/
|
|
32
|
+
export declare function checkRunnerStart(input: {
|
|
33
|
+
top: string;
|
|
34
|
+
base: string;
|
|
35
|
+
env?: Record<string, string | undefined>;
|
|
36
|
+
commit?: string;
|
|
37
|
+
readFile?: (path: string) => string;
|
|
38
|
+
}): RunnerStartVerdict;
|
|
39
|
+
/** One thing a repository lacks before it can require runner-start statements. */
|
|
40
|
+
export interface RunnerStartGap {
|
|
41
|
+
/** Not a read-contract reason code: the isolated-runners group (#4168) maps each to its own security code. */
|
|
42
|
+
gap: "no-runner-key" | "no-runner-role" | "trust-unreadable";
|
|
43
|
+
reason: string;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Whether `.chant/trust.json` in `policy` lets a job require a runner-start
|
|
47
|
+
* statement: a key under `runners` whose principal holds the `runner` role.
|
|
48
|
+
* `configured` is true when there are no gaps. For the isolated-runners
|
|
49
|
+
* security group (#4168); nothing here refuses or warns.
|
|
50
|
+
*/
|
|
51
|
+
export declare function runnerStartReadiness(policy: TrustPolicy): {
|
|
52
|
+
configured: boolean;
|
|
53
|
+
gaps: RunnerStartGap[];
|
|
54
|
+
};
|
|
55
|
+
/** {@link runnerStartReadiness} for the repository around `cwd` at `base` (default `HEAD`). */
|
|
56
|
+
export declare function runnerStartReadinessAt(cwd: string, base?: string): {
|
|
57
|
+
configured: boolean;
|
|
58
|
+
gaps: RunnerStartGap[];
|
|
59
|
+
};
|
|
60
|
+
/** The job named by `--job`: JSON, or `@<file>` holding it. */
|
|
61
|
+
export declare function parseJobSpec(spec: string): CiJobIdentity;
|
|
62
|
+
/** `chant ci runner-start sign|verify`. */
|
|
63
|
+
export declare function runCiRunnerStart(ctx: CommandContext): Promise<number>;
|
|
64
|
+
/**
|
|
65
|
+
* The check `ci run --require-runner-start` makes before the job's first
|
|
66
|
+
* step: the statement for this job, verified against `.chant/trust.json` at
|
|
67
|
+
* `base`. Throws with the verdict's reason unless it verified.
|
|
68
|
+
*/
|
|
69
|
+
export declare function requireRunnerStart(input: {
|
|
70
|
+
top: string;
|
|
71
|
+
base: string;
|
|
72
|
+
commit: string;
|
|
73
|
+
env: Record<string, string | undefined>;
|
|
74
|
+
}): Extract<RunnerStartVerdict, {
|
|
75
|
+
status: "verified";
|
|
76
|
+
}>;
|
|
77
|
+
//# sourceMappingURL=ci-runner-start.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ci-runner-start.d.ts","sourceRoot":"","sources":["../../src/workspace/ci-runner-start.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAKH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAEtD,OAAO,EAKL,KAAK,aAAa,EAElB,KAAK,kBAAkB,EACxB,MAAM,iBAAiB,CAAC;AAIzB,OAAO,EAAgC,KAAK,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAOhF;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,CAAA;CAAE,GAAG,kBAAkB,CAUzL;AAED,kFAAkF;AAClF,MAAM,WAAW,cAAc;IAC7B,8GAA8G;IAC9G,GAAG,EAAE,eAAe,GAAG,gBAAgB,GAAG,kBAAkB,CAAC;IAC7D,MAAM,EAAE,MAAM,CAAC;CAChB;AAED;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,WAAW,GAAG;IAAE,UAAU,EAAE,OAAO,CAAC;IAAC,IAAI,EAAE,cAAc,EAAE,CAAA;CAAE,CAezG;AAED,+FAA+F;AAC/F,wBAAgB,sBAAsB,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,SAAS,GAAG;IAAE,UAAU,EAAE,OAAO,CAAC;IAAC,IAAI,EAAE,cAAc,EAAE,CAAA;CAAE,CAKlH;AAkBD,+DAA+D;AAC/D,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,aAAa,CAuBxD;AAID,2CAA2C;AAC3C,wBAAsB,gBAAgB,CAAC,GAAG,EAAE,cAAc,GAAG,OAAO,CAAC,MAAM,CAAC,CA+B3E;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAA;CAAE,GAAG,OAAO,CAAC,kBAAkB,EAAE;IAAE,MAAM,EAAE,UAAU,CAAA;CAAE,CAAC,CAMrL"}
|
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `chant ci runner-start sign|verify` and `chant ci run --require-runner-start`
|
|
3
|
+
* (#4147): the runner-start statement (../runner-start.ts) checked against
|
|
4
|
+
* `.chant/trust.json` at base.
|
|
5
|
+
*
|
|
6
|
+
* - `sign` is for the provisioner that starts a runner for one job: it signs
|
|
7
|
+
* the job's ids with a runner key the job never holds and prints the
|
|
8
|
+
* envelope, which the provisioner puts where the job looks for it.
|
|
9
|
+
* - `verify` is for the job: it names itself from the forge's variables,
|
|
10
|
+
* reads the statement, and fails unless a runner key `.chant/trust.json`
|
|
11
|
+
* at base lists, whose principal holds the `runner` role, signed it for
|
|
12
|
+
* this job.
|
|
13
|
+
* - `ci run --require-runner-start` makes the same check before the job's
|
|
14
|
+
* first step, so an apply refuses before it trades for any credentials.
|
|
15
|
+
*
|
|
16
|
+
* Requiring the statement is opt-in (#4156). With nothing asking for it,
|
|
17
|
+
* nothing reads it, and a runner with none never refuses, warns or hides
|
|
18
|
+
* anything.
|
|
19
|
+
*
|
|
20
|
+
* {@link runnerStartReadiness} says whether a repository could require it
|
|
21
|
+
* at base, and what is missing, for the isolated-runners security group
|
|
22
|
+
* (#4168, section 8), whose WSP165 check reports these gaps.
|
|
23
|
+
*/
|
|
24
|
+
import { execFileSync } from "node:child_process";
|
|
25
|
+
import { readFileSync, writeFileSync } from "node:fs";
|
|
26
|
+
import { resolve } from "node:path";
|
|
27
|
+
import { formatError } from "../cli/format.js";
|
|
28
|
+
import { ciJobFromEnv, RUNNER_START_SIGNER_ROLE, signRunnerStart, verifyRunnerStartForJob, } from "../runner-start.js";
|
|
29
|
+
import { gitRevisionSource } from "./record-source.js";
|
|
30
|
+
import { gitTop } from "./tree.js";
|
|
31
|
+
import { loadRunnerKey } from "./trust/dsse.js";
|
|
32
|
+
import { emptyPolicy, readTrustPolicy } from "./trust/policy.js";
|
|
33
|
+
/** The policy at `base` in the repository around `cwd`. */
|
|
34
|
+
function policyAt(top, base) {
|
|
35
|
+
return readTrustPolicy(gitRevisionSource(top, base), base);
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Check this job's runner-start statement against `.chant/trust.json` at
|
|
39
|
+
* `base`. `commit` is the commit the job runs, in place of the forge's
|
|
40
|
+
* variable. Never throws.
|
|
41
|
+
*/
|
|
42
|
+
export function checkRunnerStart(input) {
|
|
43
|
+
const policy = policyAt(input.top, input.base);
|
|
44
|
+
if (policy.problems.length > 0)
|
|
45
|
+
return { status: "untrusted", reason: `.chant/trust.json at ${input.base.slice(0, 12)} cannot be read: ${policy.problems.join("; ")}` };
|
|
46
|
+
return verifyRunnerStartForJob({
|
|
47
|
+
runners: policy.runners,
|
|
48
|
+
roles: policy.roles,
|
|
49
|
+
...(input.env ? { env: input.env } : {}),
|
|
50
|
+
...(input.commit ? { commit: input.commit } : {}),
|
|
51
|
+
...(input.readFile ? { readFile: input.readFile } : {}),
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Whether `.chant/trust.json` in `policy` lets a job require a runner-start
|
|
56
|
+
* statement: a key under `runners` whose principal holds the `runner` role.
|
|
57
|
+
* `configured` is true when there are no gaps. For the isolated-runners
|
|
58
|
+
* security group (#4168); nothing here refuses or warns.
|
|
59
|
+
*/
|
|
60
|
+
export function runnerStartReadiness(policy) {
|
|
61
|
+
const gaps = [];
|
|
62
|
+
if (policy.problems.length > 0) {
|
|
63
|
+
gaps.push({ gap: "trust-unreadable", reason: `.chant/trust.json cannot be read: ${policy.problems.join("; ")}` });
|
|
64
|
+
return { configured: false, gaps };
|
|
65
|
+
}
|
|
66
|
+
if (policy.runners.length === 0) {
|
|
67
|
+
gaps.push({ gap: "no-runner-key", reason: ".chant/trust.json lists no key under runners for a provisioner to sign with: chant workspace trust runner add <principal> --key <ssh-ed25519 line>" });
|
|
68
|
+
}
|
|
69
|
+
else {
|
|
70
|
+
const holders = new Set((policy.roles[RUNNER_START_SIGNER_ROLE] ?? []).map((p) => p.normalize("NFKC").trim().toLowerCase()));
|
|
71
|
+
if (!policy.runners.some((r) => holders.has(r.principal.normalize("NFKC").trim().toLowerCase()))) {
|
|
72
|
+
gaps.push({ gap: "no-runner-role", reason: `no principal under runners holds the ${RUNNER_START_SIGNER_ROLE} role in .chant/trust.json: "roles": { "${RUNNER_START_SIGNER_ROLE}": ["<principal>"] }` });
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
return { configured: gaps.length === 0, gaps };
|
|
76
|
+
}
|
|
77
|
+
/** {@link runnerStartReadiness} for the repository around `cwd` at `base` (default `HEAD`). */
|
|
78
|
+
export function runnerStartReadinessAt(cwd, base = "HEAD") {
|
|
79
|
+
const top = gitTop(cwd);
|
|
80
|
+
if (!top)
|
|
81
|
+
return runnerStartReadiness(emptyPolicy(null, [`${cwd} is not in a git repository`]));
|
|
82
|
+
const commit = revParse(top, base);
|
|
83
|
+
return runnerStartReadiness(commit ? policyAt(top, commit) : emptyPolicy(null, [`${base} is not a commit`]));
|
|
84
|
+
}
|
|
85
|
+
function revParse(top, rev) {
|
|
86
|
+
try {
|
|
87
|
+
return execFileSync("git", ["rev-parse", "--verify", "-q", `${rev}^{commit}`], { cwd: top, encoding: "utf8", stdio: ["ignore", "pipe", "ignore"] }).trim() || undefined;
|
|
88
|
+
}
|
|
89
|
+
catch {
|
|
90
|
+
return undefined;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
/** The base `verify` reads trust at: `--base`, else the remote's default branch, else `HEAD`. */
|
|
94
|
+
function verifyBase(top, base) {
|
|
95
|
+
const rev = base ?? (revParse(top, "refs/remotes/origin/HEAD") ? "refs/remotes/origin/HEAD" : "HEAD");
|
|
96
|
+
const commit = revParse(top, rev);
|
|
97
|
+
if (!commit)
|
|
98
|
+
throw new Error(`--base ${rev} is not a commit in this repository`);
|
|
99
|
+
return commit;
|
|
100
|
+
}
|
|
101
|
+
/** The job named by `--job`: JSON, or `@<file>` holding it. */
|
|
102
|
+
export function parseJobSpec(spec) {
|
|
103
|
+
const text = spec.startsWith("@") ? readFileSync(resolve(spec.slice(1)), "utf8") : spec;
|
|
104
|
+
let raw;
|
|
105
|
+
try {
|
|
106
|
+
raw = JSON.parse(text);
|
|
107
|
+
}
|
|
108
|
+
catch {
|
|
109
|
+
throw new Error("--job takes the job as JSON, or @<file> holding it: {\"system\":\"github\",\"repo\":\"owner/name\",\"run\":\"<id>\",\"attempt\":\"1\",\"job\":\"apply\",\"commit\":\"<sha>\",\"runner\":\"<name>\"}");
|
|
110
|
+
}
|
|
111
|
+
if (raw === null || typeof raw !== "object" || Array.isArray(raw))
|
|
112
|
+
throw new Error("--job takes a JSON object");
|
|
113
|
+
const o = raw;
|
|
114
|
+
const str = (k) => (o[k] === undefined ? undefined : String(o[k]));
|
|
115
|
+
const known = ["system", "repo", "run", "attempt", "job", "commit", "runner"];
|
|
116
|
+
const extra = Object.keys(o).filter((k) => !known.includes(k));
|
|
117
|
+
if (extra.length > 0)
|
|
118
|
+
throw new Error(`--job has fields chant does not know: ${extra.join(", ")}`);
|
|
119
|
+
return {
|
|
120
|
+
system: (str("system") ?? ""),
|
|
121
|
+
repo: str("repo") ?? "",
|
|
122
|
+
run: str("run") ?? "",
|
|
123
|
+
attempt: str("attempt") ?? "1",
|
|
124
|
+
job: str("job") ?? "",
|
|
125
|
+
commit: str("commit") ?? "",
|
|
126
|
+
...(str("runner") ? { runner: str("runner") } : {}),
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
const USAGE = "chant ci runner-start sign --key <runner key.pem> --principal <name> --job <json|@file> [-o <file>]\n chant ci runner-start verify [--base <rev>] [--commit <sha>] [--json]";
|
|
130
|
+
/** `chant ci runner-start sign|verify`. */
|
|
131
|
+
export async function runCiRunnerStart(ctx) {
|
|
132
|
+
const { args } = ctx;
|
|
133
|
+
const action = args.extraPositional;
|
|
134
|
+
try {
|
|
135
|
+
if (action === "sign") {
|
|
136
|
+
if (!args.key)
|
|
137
|
+
throw new Error("--key names the provisioner's runner key, an Ed25519 private key in PEM, which the job never holds");
|
|
138
|
+
if (!args.ciPrincipal)
|
|
139
|
+
throw new Error("--principal names the principal .chant/trust.json lists the key for under runners");
|
|
140
|
+
if (!args.ciJob)
|
|
141
|
+
throw new Error("--job names the job the runner was started for, as JSON or @<file>");
|
|
142
|
+
const job = parseJobSpec(args.ciJob);
|
|
143
|
+
const pem = readFileSync(resolve(args.key), "utf8");
|
|
144
|
+
const loaded = loadRunnerKey(pem);
|
|
145
|
+
const envelope = signRunnerStart(job, { principal: args.ciPrincipal, key: loaded.key, publicKey: loaded.publicKey });
|
|
146
|
+
const text = `${JSON.stringify(envelope)}\n`;
|
|
147
|
+
if (args.output)
|
|
148
|
+
writeFileSync(resolve(args.output), text, { mode: 0o644 });
|
|
149
|
+
else
|
|
150
|
+
process.stdout.write(text);
|
|
151
|
+
return 0;
|
|
152
|
+
}
|
|
153
|
+
if (action === "verify") {
|
|
154
|
+
const top = gitTop(process.cwd());
|
|
155
|
+
if (!top)
|
|
156
|
+
throw new Error("verify reads .chant/trust.json at a commit, and this directory is not in a git repository");
|
|
157
|
+
const base = verifyBase(top, args.base);
|
|
158
|
+
const verdict = checkRunnerStart({ top, base, ...(args.commit ? { commit: args.commit } : {}) });
|
|
159
|
+
if (args.json)
|
|
160
|
+
process.stdout.write(`${JSON.stringify({ ...verdict, base })}\n`);
|
|
161
|
+
else
|
|
162
|
+
console.error(`ci runner-start: ${verdict.status}: ${verdict.reason}`);
|
|
163
|
+
return verdict.status === "verified" ? 0 : 1;
|
|
164
|
+
}
|
|
165
|
+
throw new Error(`ci runner-start takes sign or verify${action ? `, not ${JSON.stringify(action)}` : ""}`);
|
|
166
|
+
}
|
|
167
|
+
catch (err) {
|
|
168
|
+
console.error(formatError({ message: `chant ci runner-start: ${err instanceof Error ? err.message : String(err)}`, hint: USAGE }));
|
|
169
|
+
return 1;
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
/**
|
|
173
|
+
* The check `ci run --require-runner-start` makes before the job's first
|
|
174
|
+
* step: the statement for this job, verified against `.chant/trust.json` at
|
|
175
|
+
* `base`. Throws with the verdict's reason unless it verified.
|
|
176
|
+
*/
|
|
177
|
+
export function requireRunnerStart(input) {
|
|
178
|
+
const named = ciJobFromEnv(input.env);
|
|
179
|
+
if (!named.ok)
|
|
180
|
+
throw new Error(`--require-runner-start needs a forge job to check: ${named.reason}`);
|
|
181
|
+
const verdict = checkRunnerStart({ top: input.top, base: input.base, env: input.env, commit: input.commit });
|
|
182
|
+
if (verdict.status !== "verified")
|
|
183
|
+
throw new Error(`--require-runner-start: ${verdict.status}: ${verdict.reason}`);
|
|
184
|
+
return verdict;
|
|
185
|
+
}
|