@intentius/chant 0.124.32 → 0.124.34
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 +277 -74
- 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 +99 -22
- package/dist/cli/parse-args.d.ts.map +1 -1
- package/dist/cli/parse-args.js +30 -1
- package/dist/cli/registry.d.ts +21 -5
- 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/promote-rounds.d.ts +102 -0
- package/dist/components/promote-rounds.d.ts.map +1 -0
- package/dist/components/promote-rounds.js +174 -0
- 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-gate.d.ts +30 -0
- package/dist/components/release-gate.d.ts.map +1 -1
- package/dist/components/release-gate.js +92 -42
- 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-declared.d.ts +4 -0
- package/dist/graph-declared.d.ts.map +1 -1
- package/dist/graph-declared.js +11 -1
- 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 +236 -229
- package/dist/workspace/__fixtures__/contract-repo.d.ts.map +1 -1
- package/dist/workspace/__fixtures__/contract-repo.js +13 -2
- package/dist/workspace/check.schema.json +88 -2
- package/dist/workspace/checks/ci-workflow.d.ts +17 -0
- package/dist/workspace/checks/ci-workflow.d.ts.map +1 -0
- package/dist/workspace/checks/ci-workflow.js +123 -0
- package/dist/workspace/checks/security.d.ts +50 -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 +8 -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-init.d.ts +100 -0
- package/dist/workspace/ci-init.d.ts.map +1 -0
- package/dist/workspace/ci-init.js +434 -0
- 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/ci-workflow.d.ts +91 -0
- package/dist/workspace/ci-workflow.d.ts.map +1 -0
- package/dist/workspace/ci-workflow.js +33 -0
- package/dist/workspace/declaration.d.ts +35 -0
- package/dist/workspace/declaration.d.ts.map +1 -1
- package/dist/workspace/declaration.js +12 -2
- package/dist/workspace/declaration.schema.json +51 -0
- package/dist/workspace/init.js +2 -2
- 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 +26 -0
- package/dist/workspace/reason-codes.d.ts.map +1 -1
- package/dist/workspace/reason-codes.js +28 -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/release-workflow.d.ts +31 -0
- package/dist/workspace/release-workflow.d.ts.map +1 -0
- package/dist/workspace/release-workflow.js +150 -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 +296 -84
- 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 +99 -22
- package/src/cli/parse-args.ts +22 -1
- package/src/cli/registry.ts +21 -5
- 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/promote-rounds.test.ts +220 -0
- package/src/components/promote-rounds.ts +232 -0
- package/src/components/release-compile.test.ts +34 -0
- package/src/components/release-compile.ts +89 -8
- package/src/components/release-gate.test.ts +47 -0
- package/src/components/release-gate.ts +111 -46
- 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-declared-exports.test.ts +40 -0
- package/src/graph-declared.ts +9 -1
- 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/__fixtures__/contract-repo.ts +11 -2
- package/src/workspace/check-contract.test.ts +4 -2
- package/src/workspace/check.schema.json +88 -2
- package/src/workspace/checks/ci-workflow.test.ts +150 -0
- package/src/workspace/checks/ci-workflow.ts +129 -0
- package/src/workspace/checks/security.test.ts +138 -0
- package/src/workspace/checks/security.ts +305 -0
- package/src/workspace/checks.ts +8 -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-init.test.ts +159 -0
- package/src/workspace/ci-init.ts +445 -0
- package/src/workspace/ci-last-green.schema.json +49 -0
- package/src/workspace/ci-list.schema.json +35 -1
- package/src/workspace/ci-report-url.test.ts +6 -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/ci-workflow.ts +71 -0
- package/src/workspace/declaration.schema.json +51 -0
- package/src/workspace/declaration.test.ts +17 -0
- package/src/workspace/declaration.ts +53 -3
- package/src/workspace/init.ts +2 -2
- 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 +4 -0
- package/src/workspace/reason-codes.ts +28 -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/release-workflow.ts +167 -0
- package/src/workspace/security.test.ts +70 -0
- package/src/workspace/security.ts +118 -0
|
@@ -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
|
+
}
|
|
@@ -3,11 +3,15 @@
|
|
|
3
3
|
* host. It polls the forge for the open pull requests into the target branch
|
|
4
4
|
* and for the branch's head, and runs the pull-request jobs with
|
|
5
5
|
* {@link ciRun} (./ci-run.ts): `plan` for each new pull request head, and
|
|
6
|
-
* `
|
|
7
|
-
* the previous poll saw (the push's `before`).
|
|
6
|
+
* `record` for each new commit on the target branch (#4168), measured from
|
|
7
|
+
* the head the previous poll saw (the push's `before`). The record applies
|
|
8
|
+
* nothing; with `applyOnMerge` (`--apply-on-merge`) the commit gets `apply`
|
|
9
|
+
* in its place, as before #4168. After each job settles it runs `ci tick`
|
|
10
|
+
* from the runs the jobs recorded, when the declaration has `ci.green`.
|
|
11
|
+
* What the list below says of the apply holds for it under `applyOnMerge`.
|
|
8
12
|
*
|
|
9
13
|
* - Dedupe. A state file in the state directory keeps every job it started,
|
|
10
|
-
* keyed by job and commit (`plan:<pr>:<sha>`, `apply:<sha>`), with how it
|
|
14
|
+
* keyed by job and commit (`plan:<pr>:<sha>`, `record:<sha>`, `apply:<sha>`), with how it
|
|
11
15
|
* ended, and the target head the last apply was measured to. A job already
|
|
12
16
|
* in it is not started again, unless it failed and `rerunFailed` asks for
|
|
13
17
|
* it: the forge's "re-run failed jobs".
|
|
@@ -37,6 +41,14 @@
|
|
|
37
41
|
* - `[skip ci]` (#4122). A target head or pull request head whose commit
|
|
38
42
|
* message says `[skip ci]` or `[ci skip]` is recorded as seen and not run,
|
|
39
43
|
* as Actions does.
|
|
44
|
+
* - Build requests (#4169). With `buildCommand`, each `ci/build/<sha>`
|
|
45
|
+
* tag the tick or `ci run --at` pushed is served once: the command runs
|
|
46
|
+
* in a fresh detached worktree of the commit, with `CHANT_BUILD_COMMIT`,
|
|
47
|
+
* `CHANT_BUILD_PHASES` (comma-separated) and `CHANT_BUILD_REASON` set,
|
|
48
|
+
* and is expected to run the phases' Ops (`chant run <op>`), whose
|
|
49
|
+
* records the tick reads. A build counts against `maxJobs`, and the state
|
|
50
|
+
* file keeps it under `build:<sha>`. Without `buildCommand` the tags are
|
|
51
|
+
* left alone.
|
|
40
52
|
* - The forge's ledger (#4121). Before each job, when no other job of this
|
|
41
53
|
* serve runs, the clone's `chant/lifecycle` follows the forge's: it is
|
|
42
54
|
* deleted when the forge has none, and reset to the forge's when neither
|
|
@@ -53,6 +65,7 @@
|
|
|
53
65
|
* {@link ciServeObserve} is the poll that makes them; a webhook handler would
|
|
54
66
|
* turn a checked payload into the same triggers and schedule them.
|
|
55
67
|
*/
|
|
68
|
+
import { type BuildRequest } from "./ci-builds.js";
|
|
56
69
|
import { type OpenPullRequest } from "../pr-forge.js";
|
|
57
70
|
import type { CommandContext } from "../cli/registry.js";
|
|
58
71
|
import { type CiJobName, type CiRunRequest, type CiRunResult } from "./ci-run.js";
|
|
@@ -65,7 +78,11 @@ export interface CiServeForge {
|
|
|
65
78
|
/** The merged pull request that produced a commit, as pr-apply finds it (`pullRequestFor`). Without it an apply gets no `--pr`. */
|
|
66
79
|
pullRequestFor?(sha: string): Promise<number | null>;
|
|
67
80
|
}
|
|
68
|
-
/**
|
|
81
|
+
/**
|
|
82
|
+
* A job the forge's state calls for: the plan of a pull request's head, or
|
|
83
|
+
* for a target-branch commit its record (#4168) or, with `applyOnMerge`,
|
|
84
|
+
* its apply.
|
|
85
|
+
*/
|
|
69
86
|
export type CiServeTrigger = {
|
|
70
87
|
job: "plan";
|
|
71
88
|
commit: string;
|
|
@@ -73,7 +90,7 @@ export type CiServeTrigger = {
|
|
|
73
90
|
pr: number;
|
|
74
91
|
rerun?: boolean;
|
|
75
92
|
} | {
|
|
76
|
-
job: "apply";
|
|
93
|
+
job: "apply" | "record";
|
|
77
94
|
commit: string;
|
|
78
95
|
base: string;
|
|
79
96
|
rerun?: boolean;
|
|
@@ -108,6 +125,13 @@ export interface CiServeState {
|
|
|
108
125
|
jobs: Record<string, CiServeJobState>;
|
|
109
126
|
/** Plans seen and not run, by state key, with why (#4122). */
|
|
110
127
|
skipped?: Record<string, "skip-ci">;
|
|
128
|
+
/** The build requests served (#4169), by `build:<sha>`, with how each ended. */
|
|
129
|
+
builds?: Record<string, {
|
|
130
|
+
tag: string;
|
|
131
|
+
status: "running" | "ok" | "fail";
|
|
132
|
+
startedAt: string;
|
|
133
|
+
settledAt?: string;
|
|
134
|
+
}>;
|
|
111
135
|
}
|
|
112
136
|
/** What a pass did, in order, for the log. */
|
|
113
137
|
export type CiServeEvent = {
|
|
@@ -158,6 +182,17 @@ export type CiServeEvent = {
|
|
|
158
182
|
action: "deleted" | "reset";
|
|
159
183
|
local: string;
|
|
160
184
|
forge?: string;
|
|
185
|
+
} | {
|
|
186
|
+
type: "build";
|
|
187
|
+
commit: string;
|
|
188
|
+
phases: string[];
|
|
189
|
+
status: "started" | "ok" | "fail" | "held";
|
|
190
|
+
exitCode?: number;
|
|
191
|
+
}
|
|
192
|
+
/** `ci tick` after the pass (#4168): the tags it made from the runs. */
|
|
193
|
+
| {
|
|
194
|
+
type: "tick";
|
|
195
|
+
made: string[];
|
|
161
196
|
} | {
|
|
162
197
|
type: "error";
|
|
163
198
|
message: string;
|
|
@@ -180,6 +215,18 @@ export interface CiServeOptions {
|
|
|
180
215
|
authors?: readonly string[];
|
|
181
216
|
/** Run again the failed apply at the target's head, and the failed plans of open heads. */
|
|
182
217
|
rerunFailed?: boolean;
|
|
218
|
+
/**
|
|
219
|
+
* Apply each new target-branch commit (#4168), as `ci serve` did before
|
|
220
|
+
* #4168. Default false: each new commit gets the record job, which applies
|
|
221
|
+
* nothing.
|
|
222
|
+
*/
|
|
223
|
+
applyOnMerge?: boolean;
|
|
224
|
+
/**
|
|
225
|
+
* Run after each pass that settled a job (#4168): `ci tick` from the runs
|
|
226
|
+
* the jobs recorded. Returns the tags it made, or undefined when the
|
|
227
|
+
* declaration has no `ci.green`. The command passes one; a test may not.
|
|
228
|
+
*/
|
|
229
|
+
tick?: () => Promise<string[] | undefined>;
|
|
183
230
|
/** Passed to each job. `job.hostEnv` gets `GITHUB_REPOSITORY` set to `repo`. */
|
|
184
231
|
job?: CiServeJobOptions;
|
|
185
232
|
/** This process's lease identity. Default `currentHolderId()`. */
|
|
@@ -189,10 +236,22 @@ export interface CiServeOptions {
|
|
|
189
236
|
now?: () => Date;
|
|
190
237
|
/** Runs a job. Default {@link ciRun}. */
|
|
191
238
|
run?: (req: CiRunRequest) => Promise<CiRunResult>;
|
|
239
|
+
/**
|
|
240
|
+
* The shell line that builds a requested commit (#4169), run in a fresh
|
|
241
|
+
* worktree of it. Without it `ci/build/<sha>` tags are not served.
|
|
242
|
+
*/
|
|
243
|
+
buildCommand?: string;
|
|
244
|
+
/** Runs a build. Default: `sh -c <buildCommand>` in a detached worktree of the commit. */
|
|
245
|
+
build?: (input: {
|
|
246
|
+
top: string;
|
|
247
|
+
request: BuildRequest;
|
|
248
|
+
command: string;
|
|
249
|
+
}) => Promise<number>;
|
|
192
250
|
}
|
|
193
251
|
/** The jobs this process runs now, by state key, shared by every pass of one loop. */
|
|
194
252
|
export interface CiServeRuntime {
|
|
195
|
-
|
|
253
|
+
/** Jobs and build requests (#4169) alike, by state key: they share `maxJobs`. */
|
|
254
|
+
inflight: Map<string, Promise<unknown>>;
|
|
196
255
|
}
|
|
197
256
|
export declare const newCiServeRuntime: () => CiServeRuntime;
|
|
198
257
|
/** The state key of a job. */
|
|
@@ -247,11 +306,21 @@ export interface CiServeScheduled {
|
|
|
247
306
|
* reported and not recorded, so the next poll finds it again.
|
|
248
307
|
*/
|
|
249
308
|
export declare function ciServeSchedule(opts: CiServeOptions, triggers: readonly CiServeTrigger[], rt?: CiServeRuntime): Promise<CiServeScheduled>;
|
|
250
|
-
/** One pass: observe, schedule, and with `wait` wait for the jobs it started. */
|
|
309
|
+
/** One pass: observe, schedule, serve build requests, and with `wait` wait for the jobs it started. */
|
|
251
310
|
export declare function ciServePass(opts: CiServeOptions, rt?: CiServeRuntime, wait?: boolean): Promise<{
|
|
252
311
|
events: CiServeEvent[];
|
|
253
312
|
jobs: CiServeJobState[];
|
|
254
313
|
}>;
|
|
314
|
+
/**
|
|
315
|
+
* Serve the build requests (#4169): fetch the `ci/build/*` tags, and start
|
|
316
|
+
* `buildCommand` for each one not in the state file yet, oldest first, while
|
|
317
|
+
* fewer than `maxJobs` jobs run. A build that fails is recorded and not run
|
|
318
|
+
* again; the tick decides what its phases say.
|
|
319
|
+
*/
|
|
320
|
+
export declare function ciServeBuilds(opts: CiServeOptions, rt: CiServeRuntime): {
|
|
321
|
+
started: Promise<void>[];
|
|
322
|
+
events: CiServeEvent[];
|
|
323
|
+
};
|
|
255
324
|
/**
|
|
256
325
|
* The loop: a pass every `intervalMs` until `signal` aborts, jobs running
|
|
257
326
|
* across passes up to `maxJobs`. A pass the forge fails is logged and the
|