@kindgi/cli 0.1.11-rc.0 → 0.2.0-rc.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +77 -33
- package/dist/build/containerfile.d.ts +2 -0
- package/dist/build/containerfile.d.ts.map +1 -1
- package/dist/build/containerfile.js +14 -3
- package/dist/build/containerfile.js.map +1 -1
- package/dist/build/defaults.d.ts +2 -0
- package/dist/build/defaults.d.ts.map +1 -1
- package/dist/build/defaults.js +8 -0
- package/dist/build/defaults.js.map +1 -1
- package/dist/build/hosted.d.ts +2 -9
- package/dist/build/hosted.d.ts.map +1 -1
- package/dist/build/hosted.js +4 -2
- package/dist/build/hosted.js.map +1 -1
- package/dist/build/pack-blocks.d.ts +51 -0
- package/dist/build/pack-blocks.d.ts.map +1 -0
- package/dist/build/pack-blocks.js +98 -0
- package/dist/build/pack-blocks.js.map +1 -0
- package/dist/build/runners.d.ts +5 -1
- package/dist/build/runners.d.ts.map +1 -1
- package/dist/cli.js +4 -0
- package/dist/cli.js.map +1 -1
- package/dist/commands/adapters.d.ts.map +1 -1
- package/dist/commands/adapters.js +12 -6
- package/dist/commands/adapters.js.map +1 -1
- package/dist/commands/agents.js +8 -8
- package/dist/commands/agents.js.map +1 -1
- package/dist/commands/auth.d.ts.map +1 -1
- package/dist/commands/auth.js +155 -39
- package/dist/commands/auth.js.map +1 -1
- package/dist/commands/blocks.d.ts.map +1 -1
- package/dist/commands/blocks.js +1 -1
- package/dist/commands/blocks.js.map +1 -1
- package/dist/commands/build.d.ts +17 -6
- package/dist/commands/build.d.ts.map +1 -1
- package/dist/commands/build.js +136 -89
- package/dist/commands/build.js.map +1 -1
- package/dist/commands/connection-apps.d.ts +3 -0
- package/dist/commands/connection-apps.d.ts.map +1 -0
- package/dist/commands/connection-apps.js +239 -0
- package/dist/commands/connection-apps.js.map +1 -0
- package/dist/commands/connections.d.ts +44 -0
- package/dist/commands/connections.d.ts.map +1 -0
- package/dist/commands/connections.js +385 -0
- package/dist/commands/connections.js.map +1 -0
- package/dist/commands/conversations.js +1 -1
- package/dist/commands/conversations.js.map +1 -1
- package/dist/commands/deploy.d.ts.map +1 -1
- package/dist/commands/deploy.js +178 -97
- package/dist/commands/deploy.js.map +1 -1
- package/dist/commands/dev.d.ts +10 -0
- package/dist/commands/dev.d.ts.map +1 -1
- package/dist/commands/dev.js +177 -87
- package/dist/commands/dev.js.map +1 -1
- package/dist/commands/doctor.js +7 -7
- package/dist/commands/doctor.js.map +1 -1
- package/dist/commands/env-scoped.d.ts.map +1 -1
- package/dist/commands/env-scoped.js +37 -22
- package/dist/commands/env-scoped.js.map +1 -1
- package/dist/commands/env.d.ts.map +1 -1
- package/dist/commands/env.js +35 -22
- package/dist/commands/env.js.map +1 -1
- package/dist/commands/eval-runs.js +6 -6
- package/dist/commands/eval-runs.js.map +1 -1
- package/dist/commands/eval-suites.js +9 -9
- package/dist/commands/eval-suites.js.map +1 -1
- package/dist/commands/exports.d.ts.map +1 -1
- package/dist/commands/exports.js +35 -9
- package/dist/commands/exports.js.map +1 -1
- package/dist/commands/feedback.d.ts.map +1 -1
- package/dist/commands/feedback.js +4 -3
- package/dist/commands/feedback.js.map +1 -1
- package/dist/commands/gate-policies.d.ts.map +1 -1
- package/dist/commands/gate-policies.js +7 -7
- package/dist/commands/gate-policies.js.map +1 -1
- package/dist/commands/helpers.d.ts +9 -0
- package/dist/commands/helpers.d.ts.map +1 -1
- package/dist/commands/helpers.js +20 -0
- package/dist/commands/helpers.js.map +1 -1
- package/dist/commands/index.d.ts.map +1 -1
- package/dist/commands/index.js +8 -0
- package/dist/commands/index.js.map +1 -1
- package/dist/commands/init.d.ts +1 -1
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +57 -45
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/judge-classes.js +4 -4
- package/dist/commands/judge-classes.js.map +1 -1
- package/dist/commands/judging-queue.d.ts +3 -0
- package/dist/commands/judging-queue.d.ts.map +1 -0
- package/dist/commands/judging-queue.js +105 -0
- package/dist/commands/judging-queue.js.map +1 -0
- package/dist/commands/judging-rules.d.ts +3 -0
- package/dist/commands/judging-rules.d.ts.map +1 -0
- package/dist/commands/judging-rules.js +351 -0
- package/dist/commands/judging-rules.js.map +1 -0
- package/dist/commands/judgments.d.ts.map +1 -1
- package/dist/commands/judgments.js +78 -36
- package/dist/commands/judgments.js.map +1 -1
- package/dist/commands/key.d.ts.map +1 -1
- package/dist/commands/key.js +107 -9
- package/dist/commands/key.js.map +1 -1
- package/dist/commands/license.d.ts.map +1 -1
- package/dist/commands/license.js +67 -15
- package/dist/commands/license.js.map +1 -1
- package/dist/commands/mcp.d.ts.map +1 -1
- package/dist/commands/mcp.js +4 -4
- package/dist/commands/mcp.js.map +1 -1
- package/dist/commands/people.js +8 -14
- package/dist/commands/people.js.map +1 -1
- package/dist/commands/promote.js +1 -1
- package/dist/commands/promote.js.map +1 -1
- package/dist/commands/proposals.d.ts.map +1 -1
- package/dist/commands/proposals.js +83 -30
- package/dist/commands/proposals.js.map +1 -1
- package/dist/commands/run-waits.d.ts +68 -19
- package/dist/commands/run-waits.d.ts.map +1 -1
- package/dist/commands/run-waits.js +82 -8
- package/dist/commands/run-waits.js.map +1 -1
- package/dist/commands/runs.d.ts.map +1 -1
- package/dist/commands/runs.js +70 -30
- package/dist/commands/runs.js.map +1 -1
- package/dist/commands/schedules.d.ts.map +1 -1
- package/dist/commands/schedules.js +35 -12
- package/dist/commands/schedules.js.map +1 -1
- package/dist/commands/secrets-copy.d.ts.map +1 -1
- package/dist/commands/secrets-copy.js +20 -12
- package/dist/commands/secrets-copy.js.map +1 -1
- package/dist/commands/secrets.d.ts.map +1 -1
- package/dist/commands/secrets.js +13 -8
- package/dist/commands/secrets.js.map +1 -1
- package/dist/commands/sign-in.js +2 -2
- package/dist/commands/sign-in.js.map +1 -1
- package/dist/commands/sites.d.ts.map +1 -1
- package/dist/commands/sites.js +13 -6
- package/dist/commands/sites.js.map +1 -1
- package/dist/commands/skills.d.ts +54 -3
- package/dist/commands/skills.d.ts.map +1 -1
- package/dist/commands/skills.js +169 -38
- package/dist/commands/skills.js.map +1 -1
- package/dist/commands/tokens.d.ts.map +1 -1
- package/dist/commands/tokens.js +9 -1
- package/dist/commands/tokens.js.map +1 -1
- package/dist/commands/upgrade.d.ts.map +1 -1
- package/dist/commands/upgrade.js +9 -8
- package/dist/commands/upgrade.js.map +1 -1
- package/dist/commands/webhooks.d.ts.map +1 -1
- package/dist/commands/webhooks.js +62 -24
- package/dist/commands/webhooks.js.map +1 -1
- package/dist/config.d.ts +6 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +18 -3
- package/dist/config.js.map +1 -1
- package/dist/context.d.ts +12 -0
- package/dist/context.d.ts.map +1 -1
- package/dist/context.js +2 -0
- package/dist/context.js.map +1 -1
- package/dist/deploy/pack-blocks-gate.d.ts +12 -0
- package/dist/deploy/pack-blocks-gate.d.ts.map +1 -0
- package/dist/deploy/pack-blocks-gate.js +34 -0
- package/dist/deploy/pack-blocks-gate.js.map +1 -0
- package/dist/deploy/post.d.ts +9 -0
- package/dist/deploy/post.d.ts.map +1 -1
- package/dist/deploy/post.js +20 -3
- package/dist/deploy/post.js.map +1 -1
- package/dist/dev/defaults.d.ts.map +1 -1
- package/dist/dev/defaults.js +8 -1
- package/dist/dev/defaults.js.map +1 -1
- package/dist/dev/dev-only-imports.d.ts +7 -4
- package/dist/dev/dev-only-imports.d.ts.map +1 -1
- package/dist/dev/dev-only-imports.js +5 -5
- package/dist/dev/dev-only-imports.js.map +1 -1
- package/dist/dev/log-view.d.ts +4 -4
- package/dist/dev/log-view.d.ts.map +1 -1
- package/dist/dev/log-view.js +4 -4
- package/dist/dev/log-view.js.map +1 -1
- package/dist/dev/pack-service.d.ts +7 -1
- package/dist/dev/pack-service.d.ts.map +1 -1
- package/dist/dev/pack-service.js +36 -3
- package/dist/dev/pack-service.js.map +1 -1
- package/dist/dev/preview-expiry.d.ts +6 -7
- package/dist/dev/preview-expiry.d.ts.map +1 -1
- package/dist/dev/preview-expiry.js +7 -8
- package/dist/dev/preview-expiry.js.map +1 -1
- package/dist/dev/providers.d.ts +2 -1
- package/dist/dev/providers.d.ts.map +1 -1
- package/dist/dev/providers.js +28 -12
- package/dist/dev/providers.js.map +1 -1
- package/dist/dev/runners.d.ts +19 -0
- package/dist/dev/runners.d.ts.map +1 -1
- package/dist/dev/runtime-container.d.ts.map +1 -1
- package/dist/dev/runtime-container.js +2 -2
- package/dist/dev/runtime-container.js.map +1 -1
- package/dist/dev/runtime-env.d.ts +2 -1
- package/dist/dev/runtime-env.d.ts.map +1 -1
- package/dist/dev/runtime-env.js +5 -5
- package/dist/dev/runtime-env.js.map +1 -1
- package/dist/dev/runtime-image.d.ts +2 -2
- package/dist/dev/runtime-image.d.ts.map +1 -1
- package/dist/dev/runtime-image.js +2 -2
- package/dist/dev/runtime-image.js.map +1 -1
- package/dist/dev/runtime-registry.d.ts +8 -10
- package/dist/dev/runtime-registry.d.ts.map +1 -1
- package/dist/dev/runtime-registry.js +27 -27
- package/dist/dev/runtime-registry.js.map +1 -1
- package/dist/dev/sandbox/index.js +1 -1
- package/dist/dev/sandbox/notices.d.ts +2 -0
- package/dist/dev/sandbox/notices.d.ts.map +1 -1
- package/dist/dev/sandbox/notices.js +5 -2
- package/dist/dev/sandbox/notices.js.map +1 -1
- package/dist/env/defaults.d.ts.map +1 -1
- package/dist/env/defaults.js +3 -1
- package/dist/env/defaults.js.map +1 -1
- package/dist/env/pack-env-plan.d.ts +4 -0
- package/dist/env/pack-env-plan.d.ts.map +1 -1
- package/dist/env/pack-env-plan.js +8 -2
- package/dist/env/pack-env-plan.js.map +1 -1
- package/dist/exports/create.d.ts +2 -0
- package/dist/exports/create.d.ts.map +1 -1
- package/dist/exports/create.js +10 -2
- package/dist/exports/create.js.map +1 -1
- package/dist/exports/plan.d.ts.map +1 -1
- package/dist/exports/plan.js +20 -0
- package/dist/exports/plan.js.map +1 -1
- package/dist/feedback/store.d.ts.map +1 -1
- package/dist/feedback/store.js +8 -19
- package/dist/feedback/store.js.map +1 -1
- package/dist/help.d.ts +6 -0
- package/dist/help.d.ts.map +1 -1
- package/dist/help.js +35 -1
- package/dist/help.js.map +1 -1
- package/dist/init/agent-access.d.ts +3 -2
- package/dist/init/agent-access.d.ts.map +1 -1
- package/dist/init/agent-access.js +5 -1
- package/dist/init/agent-access.js.map +1 -1
- package/dist/init/augment-scaffolder.d.ts +7 -0
- package/dist/init/augment-scaffolder.d.ts.map +1 -1
- package/dist/init/augment-scaffolder.js +15 -14
- package/dist/init/augment-scaffolder.js.map +1 -1
- package/dist/init/dependency-specs.d.ts +1 -0
- package/dist/init/dependency-specs.d.ts.map +1 -1
- package/dist/init/dependency-specs.js +27 -7
- package/dist/init/dependency-specs.js.map +1 -1
- package/dist/init/java-augment.d.ts +3 -0
- package/dist/init/java-augment.d.ts.map +1 -1
- package/dist/init/java-augment.js +16 -15
- package/dist/init/java-augment.js.map +1 -1
- package/dist/init/python-augment.d.ts +3 -0
- package/dist/init/python-augment.d.ts.map +1 -1
- package/dist/init/python-augment.js +15 -14
- package/dist/init/python-augment.js.map +1 -1
- package/dist/init/scala-augment.d.ts +8 -1
- package/dist/init/scala-augment.d.ts.map +1 -1
- package/dist/init/scala-augment.js +32 -17
- package/dist/init/scala-augment.js.map +1 -1
- package/dist/key/defaults.d.ts.map +1 -1
- package/dist/key/defaults.js +6 -1
- package/dist/key/defaults.js.map +1 -1
- package/dist/key/runners.d.ts +4 -1
- package/dist/key/runners.d.ts.map +1 -1
- package/dist/license/renew.d.ts +6 -0
- package/dist/license/renew.d.ts.map +1 -1
- package/dist/license/renew.js +8 -5
- package/dist/license/renew.js.map +1 -1
- package/dist/main.d.ts +10 -0
- package/dist/main.d.ts.map +1 -1
- package/dist/main.js +19 -5
- package/dist/main.js.map +1 -1
- package/dist/output.d.ts +6 -0
- package/dist/output.d.ts.map +1 -1
- package/dist/output.js +8 -0
- package/dist/output.js.map +1 -1
- package/dist/parse.d.ts +1 -1
- package/dist/parse.d.ts.map +1 -1
- package/dist/parse.js +1 -1
- package/dist/parse.js.map +1 -1
- package/dist/private-file.d.ts +23 -0
- package/dist/private-file.d.ts.map +1 -0
- package/dist/private-file.js +65 -0
- package/dist/private-file.js.map +1 -0
- package/dist/progress-head.d.ts +13 -0
- package/dist/progress-head.d.ts.map +1 -0
- package/dist/progress-head.js +30 -0
- package/dist/progress-head.js.map +1 -0
- package/dist/progress-lines.d.ts +29 -0
- package/dist/progress-lines.d.ts.map +1 -0
- package/dist/progress-lines.js +35 -0
- package/dist/progress-lines.js.map +1 -0
- package/dist/sdk-skills/kindgi-authoring-agents/SKILL.md +6 -6
- package/dist/sdk-skills/kindgi-authoring-flows/SKILL.md +1 -1
- package/dist/sdk-skills/kindgi-authoring-guardrails/SKILL.md +2 -2
- package/dist/sdk-skills/kindgi-authoring-mcp-servers/SKILL.md +1 -1
- package/dist/sdk-skills/kindgi-authoring-providers/SKILL.md +3 -3
- package/dist/sdk-skills/kindgi-authoring-tools/SKILL.md +39 -6
- package/dist/sdk-skills/kindgi-fix-corrections/SKILL.md +262 -0
- package/dist/sdk-skills/kindgi-framework-feedback/SKILL.md +1 -1
- package/dist/sdk-skills/kindgi-getting-started/SKILL.md +43 -9
- package/dist/sdk-skills/kindgi-java-authoring-agents/SKILL.md +5 -5
- package/dist/sdk-skills/kindgi-java-authoring-flows/SKILL.md +1 -1
- package/dist/sdk-skills/kindgi-java-authoring-guardrails/SKILL.md +1 -1
- package/dist/sdk-skills/kindgi-java-authoring-tools/SKILL.md +91 -9
- package/dist/sdk-skills/kindgi-java-getting-started/SKILL.md +38 -9
- package/dist/sdk-skills/kindgi-python-authoring-agents/SKILL.md +4 -4
- package/dist/sdk-skills/kindgi-python-authoring-flows/SKILL.md +1 -1
- package/dist/sdk-skills/kindgi-python-authoring-guardrails/SKILL.md +1 -1
- package/dist/sdk-skills/kindgi-python-authoring-tools/SKILL.md +43 -8
- package/dist/sdk-skills/kindgi-python-getting-started/SKILL.md +39 -11
- package/dist/sdk-skills/kindgi-scala-authoring-agents/SKILL.md +5 -5
- package/dist/sdk-skills/kindgi-scala-authoring-flows/SKILL.md +1 -1
- package/dist/sdk-skills/kindgi-scala-authoring-guardrails/SKILL.md +1 -1
- package/dist/sdk-skills/kindgi-scala-authoring-tools/SKILL.md +82 -7
- package/dist/sdk-skills/kindgi-scala-getting-started/SKILL.md +38 -9
- package/dist/sdk-skills/kindgi-using/SKILL.md +50 -21
- package/dist/templates/drupal/AGENTS.md +2 -1
- package/dist/templates/follow-up/.nvmrc +1 -0
- package/dist/templates/follow-up/AGENTS.md +83 -0
- package/dist/templates/follow-up/README.md.tmpl +111 -0
- package/dist/templates/follow-up/agents/follow-up/index.test.ts.tmpl +26 -0
- package/dist/templates/follow-up/agents/follow-up/index.ts.tmpl +53 -0
- package/dist/templates/follow-up/gitignore +8 -0
- package/dist/templates/follow-up/kindgi.config.ts.tmpl +45 -0
- package/dist/templates/follow-up/package.json.tmpl +30 -0
- package/dist/templates/follow-up/pnpm-workspace.yaml +9 -0
- package/dist/templates/follow-up/tools/gmail-send/index.test.ts.tmpl +60 -0
- package/dist/templates/follow-up/tools/gmail-send/index.ts.tmpl +14 -0
- package/dist/templates/follow-up/tsconfig.json.tmpl +27 -0
- package/dist/templates/follow-up/vitest.config.ts.tmpl +14 -0
- package/dist/templates/java/AGENTS.md +2 -1
- package/dist/templates/minimal/AGENTS.md +2 -1
- package/dist/templates/python/AGENTS.md +2 -1
- package/dist/templates/sample/AGENTS.md +2 -1
- package/dist/templates/scala/AGENTS.md +2 -1
- package/dist/templates/woocommerce/AGENTS.md +12 -3
- package/dist/templates/woocommerce/README.md.tmpl +29 -5
- package/dist/templates/woocommerce/agents/store-agent/index.test.ts.tmpl +38 -7
- package/dist/templates/woocommerce/agents/store-agent/index.ts.tmpl +7 -12
- package/dist/templates/woocommerce/blocks/store-agent-prompt.json.tmpl +10 -0
- package/dist/templates/woocommerce/blocks/store-agent-prompt.liquid.tmpl +7 -0
- package/dist/templates/woocommerce/kindgi.config.ts.tmpl +1 -0
- package/dist/value-target.d.ts +4 -2
- package/dist/value-target.d.ts.map +1 -1
- package/dist/value-target.js +8 -5
- package/dist/value-target.js.map +1 -1
- package/package.json +13 -13
package/dist/commands/deploy.js
CHANGED
|
@@ -18,7 +18,8 @@
|
|
|
18
18
|
* `buildLogsUrl`).
|
|
19
19
|
* 5. Compute `Idempotency-Key: sha256(canonicalBody)` (or `--idempotency-key`).
|
|
20
20
|
* 6. If `--dry-run`: print the curl-equivalent + body + headers to
|
|
21
|
-
* stderr, exit 0.
|
|
21
|
+
* stderr, exit 0. An unsigned envelope shows the body less the
|
|
22
|
+
* signature's fields, and no derived key.
|
|
22
23
|
* 7. Otherwise POST via `ctx.fetch`, waiting out the server's rate
|
|
23
24
|
* limits (`429` with `Retry-After`) for up to 10 minutes in all.
|
|
24
25
|
* 8. Handle response (201 / 200 / 4xx / 5xx / transport).
|
|
@@ -26,22 +27,27 @@
|
|
|
26
27
|
*/
|
|
27
28
|
import { stat } from 'node:fs/promises';
|
|
28
29
|
import { isAbsolute, join, resolve } from 'node:path';
|
|
30
|
+
import { readPackBlocks, resolveDiscovery } from '@kindgi/handler-runtime';
|
|
29
31
|
import { LOCAL_ENV_NAME, packValues, readPackEnv } from '@kindgi/secrets-dotenv';
|
|
30
32
|
import { deployApiAddress, hostedApiAddress } from '../api-address.js';
|
|
33
|
+
import { describeFiles } from '../build/pack-blocks.js';
|
|
31
34
|
import { isEnvelopeSigned } from '../deploy/envelope-loader.js';
|
|
35
|
+
import { packBlocksRefusal } from '../deploy/pack-blocks-gate.js';
|
|
32
36
|
import { packServiceProblemText, packServiceRetiredText } from '../deploy/pack-service-text.js';
|
|
33
|
-
import { buildPostBody, deriveIdempotencyKey, deriveSyncSecretsIdempotencyKey, } from '../deploy/post.js';
|
|
37
|
+
import { buildPostBody, deriveIdempotencyKey, deriveSyncSecretsIdempotencyKey, unsignedPostBody, } from '../deploy/post.js';
|
|
34
38
|
import { promotionPath } from '../deploy/promotion-path.js';
|
|
35
39
|
import { renderResponse } from '../deploy/response.js';
|
|
36
40
|
import { envProjectRefs } from '../env-projects.js';
|
|
37
41
|
import { packEnvProblemLines, packEnvSecretSetCommand, packEnvSetCommand, } from '../env/pack-env-hint.js';
|
|
38
|
-
import { describePackEnvPlan, plainSecretReason, planPackEnv, } from '../env/pack-env-plan.js';
|
|
42
|
+
import { describePackEnvPlan, packEnvPlanLines, packEnvPlanWarnings, plainSecretReason, planPackEnv, } from '../env/pack-env-plan.js';
|
|
39
43
|
import { renderJson } from '../output.js';
|
|
40
44
|
import { loadPackConfig } from '../pack-config.js';
|
|
45
|
+
import { progressLines } from '../progress-lines.js';
|
|
41
46
|
import { PROJECT_ID_RE } from '../project-ref.js';
|
|
42
47
|
import { isWait, sendWaitingOutRateLimits } from '../rate-limit-wait.js';
|
|
43
48
|
import { SLUG } from '../slug.js';
|
|
44
49
|
import { environmentsOf, resolveValueTarget } from '../value-target.js';
|
|
50
|
+
import { CLI_VERSION } from '../version-info.js';
|
|
45
51
|
import { runBuild } from './build.js';
|
|
46
52
|
/** Default relative path to look for a pre-built envelope. */
|
|
47
53
|
export const DEFAULT_ENVELOPE_RELATIVE_PATH = '.kindgi/build/deploy-envelope.json';
|
|
@@ -160,10 +166,19 @@ export async function runDeploy(ctx) {
|
|
|
160
166
|
if (parsed.kind === 'error')
|
|
161
167
|
return parsed;
|
|
162
168
|
const args = parsed.args;
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
169
|
+
// Deploy's lines, its inline build's among them: each to stderr as it
|
|
170
|
+
// comes when the CLI streams them, else kept for the result. A failure's
|
|
171
|
+
// error comes after them either way. `--quiet` keeps errors and warnings
|
|
172
|
+
// only, as `kindgi dev` does: a refusal, a secret sync that failed, and
|
|
173
|
+
// its warnings.
|
|
174
|
+
const out = progressLines(ctx.progress, ctx.globals.format === 'quiet');
|
|
175
|
+
const result = await deployWith(ctx, runners, args, out);
|
|
176
|
+
if (result.kind === 'error')
|
|
177
|
+
return { ...result, stderr: `${out.kept()}${result.stderr}` };
|
|
178
|
+
return { ...result, rendered: { ...result.rendered, stderr: out.kept() } };
|
|
179
|
+
}
|
|
180
|
+
async function deployWith(ctx, runners, args, out) {
|
|
181
|
+
const { line } = out;
|
|
167
182
|
line('');
|
|
168
183
|
line(` Environment: ${args.envName}`);
|
|
169
184
|
line(` API: ${args.endpoint}`);
|
|
@@ -175,7 +190,7 @@ export async function runDeploy(ctx) {
|
|
|
175
190
|
// Every name the pack declares in env.required needs a value or a
|
|
176
191
|
// Secret Manager reference for this environment; a secret given in
|
|
177
192
|
// the clear is refused. Checked before anything is built or sent.
|
|
178
|
-
const envRefusal = checkPackEnv(args,
|
|
193
|
+
const envRefusal = checkPackEnv(args, out);
|
|
179
194
|
if (envRefusal !== undefined)
|
|
180
195
|
return envRefusal;
|
|
181
196
|
// On a runtime that keeps its values under one env, a pack environment
|
|
@@ -221,8 +236,33 @@ export async function runDeploy(ctx) {
|
|
|
221
236
|
const hostedEnvRefusal = refuseHostedConfigEnv(args, project.id);
|
|
222
237
|
if (hostedEnvRefusal !== undefined)
|
|
223
238
|
return hostedEnvRefusal;
|
|
239
|
+
// A pack with blocks deploys only to a runtime that publishes them
|
|
240
|
+
// (`deploy/pack-blocks-gate.ts`): read before a build or an upload, from
|
|
241
|
+
// the pack's block files when the envelope is still to be built, and
|
|
242
|
+
// from the envelope's index (step 3) otherwise. Not on --dry-run, which
|
|
243
|
+
// sends nothing.
|
|
244
|
+
let blocksChecked = false;
|
|
245
|
+
const refuseBlocks = async (brought) => {
|
|
246
|
+
if (args.dryRun || blocksChecked)
|
|
247
|
+
return undefined;
|
|
248
|
+
blocksChecked = true;
|
|
249
|
+
return packBlocksRefusal({
|
|
250
|
+
endpoint: args.endpoint,
|
|
251
|
+
fetchImpl: ctx.fetch,
|
|
252
|
+
...(ctx.stopSignal !== undefined && { signal: ctx.stopSignal }),
|
|
253
|
+
brought,
|
|
254
|
+
release: CLI_VERSION,
|
|
255
|
+
});
|
|
256
|
+
};
|
|
257
|
+
if (!args.explicitEnvelope && !(await pathExists(args.envelopePath))) {
|
|
258
|
+
const read = await readPackBlocks(args.packDir, args.blocksPattern);
|
|
259
|
+
const found = new Set([...read.files, ...read.errors.map((e) => e.filePath)]).size;
|
|
260
|
+
const refused = found > 0 ? await refuseBlocks(describeFiles(args.blocksPattern, found)) : undefined;
|
|
261
|
+
if (refused !== undefined)
|
|
262
|
+
return failure(refused);
|
|
263
|
+
}
|
|
224
264
|
// ---- 2. Ensure envelope on disk -------------------------------------
|
|
225
|
-
const envelopeReady = await ensureEnvelopeExists(ctx, args, runners,
|
|
265
|
+
const envelopeReady = await ensureEnvelopeExists(ctx, args, runners, out, project.id);
|
|
226
266
|
if (envelopeReady.kind === 'error')
|
|
227
267
|
return envelopeReady;
|
|
228
268
|
// ---- 3. Load + validate envelope ------------------------------------
|
|
@@ -233,34 +273,34 @@ export async function runDeploy(ctx) {
|
|
|
233
273
|
`Regenerate with \`kindgi build --env=${args.envName}\` or point --from-envelope at a valid file.\n`);
|
|
234
274
|
}
|
|
235
275
|
const envelope = loaded.envelope;
|
|
276
|
+
const indexBlocks = Array.isArray(envelope.index.blocks) ? envelope.index.blocks.length : 0;
|
|
277
|
+
if (indexBlocks > 0) {
|
|
278
|
+
const refused = await refuseBlocks(`${indexBlocks} ${indexBlocks === 1 ? 'block' : 'blocks'} in its index`);
|
|
279
|
+
if (refused !== undefined)
|
|
280
|
+
return failure(refused);
|
|
281
|
+
}
|
|
236
282
|
// ---- 4. Signed-envelope gate ----------------------------------------
|
|
237
283
|
if (!isEnvelopeSigned(envelope)) {
|
|
238
|
-
if (!args.dryRun)
|
|
239
|
-
return failure(
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
}
|
|
243
|
-
line(' ⚠ Envelope is unsigned — --dry-run is proceeding for inspection only.');
|
|
244
|
-
line('');
|
|
284
|
+
if (!args.dryRun)
|
|
285
|
+
return failure(UNSIGNED_REFUSAL);
|
|
286
|
+
out.problem(' ⚠ Envelope is unsigned — --dry-run is proceeding for inspection only.');
|
|
287
|
+
out.problem('');
|
|
245
288
|
}
|
|
246
289
|
// ---- 5. Consistency check: envelope.tenantId vs --tenant override ---
|
|
247
290
|
if (args.explicitTenantId !== undefined && args.explicitTenantId !== envelope.tenantId) {
|
|
248
291
|
return failure(`--tenant mismatch: envelope was signed against tenantId="${envelope.tenantId}", but --tenant was passed as "${args.explicitTenantId}". The server re-canonicalises using the token's tenantId + verifies the signature — a mismatch would fail with signature-invalid. Either drop --tenant or re-run \`kindgi build --tenant=${args.explicitTenantId}\`.\n`);
|
|
249
292
|
}
|
|
250
293
|
// ---- 6. Build POST body + Idempotency-Key ---------------------------
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
const idempotencyKey = args.idempotencyKeyOverride !== undefined
|
|
262
|
-
? args.idempotencyKeyOverride
|
|
263
|
-
: deriveIdempotencyKey(postBody);
|
|
294
|
+
//
|
|
295
|
+
// An unsigned envelope comes this far only under --dry-run (step 4). It
|
|
296
|
+
// has no POST body: the dry run shows the body less the signature's
|
|
297
|
+
// fields, and no derived Idempotency-Key, which hashes the signed body.
|
|
298
|
+
const projectField = project.id !== undefined ? { projectId: project.id } : {};
|
|
299
|
+
const postBody = isEnvelopeSigned(envelope)
|
|
300
|
+
? { ...buildPostBody(envelope), ...projectField }
|
|
301
|
+
: undefined;
|
|
302
|
+
const idempotencyKey = args.idempotencyKeyOverride ??
|
|
303
|
+
(postBody !== undefined ? deriveIdempotencyKey(postBody) : undefined);
|
|
264
304
|
// ---- 7. Secrets sync detection + warning ---------------------------
|
|
265
305
|
//
|
|
266
306
|
// `POST /v1/deployments/:id/secrets` lands after a successful
|
|
@@ -285,34 +325,12 @@ export async function runDeploy(ctx) {
|
|
|
285
325
|
}
|
|
286
326
|
// ---- 8. Dry-run ------------------------------------------------------
|
|
287
327
|
if (args.dryRun) {
|
|
288
|
-
|
|
289
|
-
line
|
|
290
|
-
line(` curl -X POST ${args.endpoint.replace(/\/+$/, '')}/v1/deployments \\`);
|
|
291
|
-
line(' -H "Authorization: Bearer <redacted>" \\');
|
|
292
|
-
line(' -H "Content-Type: application/json" \\');
|
|
293
|
-
line(` -H "Idempotency-Key: ${idempotencyKey}" \\`);
|
|
294
|
-
line(" -d @- <<'JSON'");
|
|
295
|
-
for (const bodyLine of JSON.stringify(postBody, null, 2).split('\n')) {
|
|
296
|
-
line(` ${bodyLine}`);
|
|
297
|
-
}
|
|
298
|
-
line(' JSON');
|
|
299
|
-
line('');
|
|
300
|
-
line(' --dry-run set. No request sent. Exiting 0.');
|
|
301
|
-
line('');
|
|
302
|
-
const summary = {
|
|
303
|
-
envName: args.envName,
|
|
304
|
-
endpoint: args.endpoint,
|
|
305
|
-
envelopePath: args.envelopePath,
|
|
306
|
-
idempotencyKey,
|
|
307
|
-
dryRun: true,
|
|
308
|
-
wouldPost: postBody,
|
|
309
|
-
};
|
|
310
|
-
const rendered = renderJson(summary, ctx.globals.format);
|
|
311
|
-
return {
|
|
312
|
-
kind: 'ok',
|
|
313
|
-
rendered: { stdout: rendered.stdout, stderr: `${banner.join('\n')}\n` },
|
|
314
|
-
};
|
|
328
|
+
const shown = postBody ?? { ...unsignedPostBody(envelope), ...projectField };
|
|
329
|
+
return dryRunResult(ctx, args, line, shown, idempotencyKey);
|
|
315
330
|
}
|
|
331
|
+
// Step 4 refused an unsigned envelope without --dry-run; this tells the types.
|
|
332
|
+
if (postBody === undefined || idempotencyKey === undefined)
|
|
333
|
+
return failure(UNSIGNED_REFUSAL);
|
|
316
334
|
// ---- 9. POST ---------------------------------------------------------
|
|
317
335
|
//
|
|
318
336
|
// A `429 rate-limit-exceeded` with `Retry-After` is waited out and the
|
|
@@ -340,15 +358,16 @@ export async function runDeploy(ctx) {
|
|
|
340
358
|
idempotencyKey,
|
|
341
359
|
promotionPath,
|
|
342
360
|
});
|
|
343
|
-
|
|
344
|
-
line(l);
|
|
361
|
+
// A refused deployment's banner is its error: said under `--quiet` too.
|
|
345
362
|
if (rendered.exitCode !== 0) {
|
|
346
363
|
return {
|
|
347
364
|
kind: 'error',
|
|
348
|
-
stderr: `${
|
|
365
|
+
stderr: rendered.banner.map((l) => `${l}\n`).join(''),
|
|
349
366
|
exitCode: rendered.exitCode,
|
|
350
367
|
};
|
|
351
368
|
}
|
|
369
|
+
for (const l of rendered.banner)
|
|
370
|
+
line(l);
|
|
352
371
|
// ---- 11. Post-deploy secrets sync ----------------------------------
|
|
353
372
|
//
|
|
354
373
|
// Runs iff `--sync-secrets` is passed AND the deploy landed OK AND
|
|
@@ -361,7 +380,7 @@ export async function runDeploy(ctx) {
|
|
|
361
380
|
const syncSummary = { performed: false };
|
|
362
381
|
const deployedRecord = result.kind === 'created' || result.kind === 'replayed' ? result.record : null;
|
|
363
382
|
if (args.syncSecrets && deployedRecord !== null) {
|
|
364
|
-
const syncOutcome = await runSecretsSync(ctx, args, syncEnvName, runners, deployedRecord.deploymentId,
|
|
383
|
+
const syncOutcome = await runSecretsSync(ctx, args, syncEnvName, runners, deployedRecord.deploymentId, out);
|
|
365
384
|
Object.assign(syncSummary, syncOutcome);
|
|
366
385
|
}
|
|
367
386
|
// ---- 12. Hosted: wait for the deployment's pack service --------------
|
|
@@ -372,7 +391,7 @@ export async function runDeploy(ctx) {
|
|
|
372
391
|
if (args.hosted && deployedRecord !== null && deployedRecord.endpoint !== undefined) {
|
|
373
392
|
const waited = await waitForPackService(ctx, args, runners, deployedRecord, line, project.id);
|
|
374
393
|
if (waited.kind === 'error') {
|
|
375
|
-
return { kind: 'error', stderr:
|
|
394
|
+
return { kind: 'error', stderr: waited.message, exitCode: 1 };
|
|
376
395
|
}
|
|
377
396
|
packService = waited.endpoint;
|
|
378
397
|
}
|
|
@@ -383,7 +402,7 @@ export async function runDeploy(ctx) {
|
|
|
383
402
|
}, ctx.globals.format);
|
|
384
403
|
return {
|
|
385
404
|
kind: 'ok',
|
|
386
|
-
rendered: { stdout: jsonOut.stdout, stderr:
|
|
405
|
+
rendered: { stdout: jsonOut.stdout, stderr: '' },
|
|
387
406
|
};
|
|
388
407
|
}
|
|
389
408
|
/**
|
|
@@ -415,7 +434,8 @@ function deployRefusal(result) {
|
|
|
415
434
|
*/
|
|
416
435
|
async function runSecretsSync(ctx, args,
|
|
417
436
|
/** The env the values go under: `--env`, or the one a runtime that keeps its values under one serves. */
|
|
418
|
-
envName, runners, deploymentId,
|
|
437
|
+
envName, runners, deploymentId, out) {
|
|
438
|
+
const { line, problem } = out;
|
|
419
439
|
const file = await detectSecretsFile(args, '');
|
|
420
440
|
if (file === null || file.entries.length === 0) {
|
|
421
441
|
line(' --sync-secrets set, but no `.env.<envName>` entries to sync. Skipping.');
|
|
@@ -428,10 +448,10 @@ envName, runners, deploymentId, line) {
|
|
|
428
448
|
// impossible to miss.
|
|
429
449
|
const shaped = file.entries.filter((e) => plainSecretReason(e.name, e.value) !== undefined);
|
|
430
450
|
if (shaped.length > 0) {
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
451
|
+
problem(` ! secret-shaped keys detected in .env.${args.envName}: ${shaped.map((e) => e.name).join(', ')}`);
|
|
452
|
+
problem(' Keep secrets out of .env files: store them with `kindgi secrets`.');
|
|
453
|
+
problem(` Consider: kindgi secrets set --env=${args.envName} <name> <value>`);
|
|
454
|
+
problem('');
|
|
435
455
|
}
|
|
436
456
|
const syncBody = {
|
|
437
457
|
envName,
|
|
@@ -466,22 +486,27 @@ envName, runners, deploymentId, line) {
|
|
|
466
486
|
};
|
|
467
487
|
}
|
|
468
488
|
if (result.kind === 'wire-error') {
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
line('');
|
|
489
|
+
// Errors: said under `--quiet` too, though the exit code stays 0.
|
|
490
|
+
problem(` ✗ ${result.status} ${result.error.code}: ${result.error.message}`);
|
|
491
|
+
syncFailedHint(problem);
|
|
473
492
|
return { performed: false, error: { code: result.error.code, message: result.error.message } };
|
|
474
493
|
}
|
|
475
|
-
|
|
476
|
-
|
|
494
|
+
problem(` ✗ transport error: ${result.message}`);
|
|
495
|
+
syncFailedHint(problem);
|
|
477
496
|
return { performed: false, error: { code: 'transport-error', message: result.message } };
|
|
478
497
|
}
|
|
498
|
+
/** After a secret sync that failed: the deployment is in place; how to sync again. */
|
|
499
|
+
function syncFailedHint(problem) {
|
|
500
|
+
problem(' The deployment landed OK; only the secret sync failed. Retry with');
|
|
501
|
+
problem(' `kindgi deploy --sync-secrets` (idempotent).');
|
|
502
|
+
problem('');
|
|
503
|
+
}
|
|
479
504
|
/**
|
|
480
505
|
* The deploy preflight for the pack service's env (R4): the plan's lines
|
|
481
506
|
* when the pack declares any, and the refusal when a required name has no
|
|
482
507
|
* value (unless `--allow-missing-env`) or a secret is given in the clear.
|
|
483
508
|
*/
|
|
484
|
-
function checkPackEnv(args,
|
|
509
|
+
function checkPackEnv(args, out) {
|
|
485
510
|
// A hosted pack service gets the values set in the workspace, not these:
|
|
486
511
|
// `refuseHostedConfigEnv`, once the project is known.
|
|
487
512
|
if (args.hosted)
|
|
@@ -490,18 +515,33 @@ function checkPackEnv(args, line) {
|
|
|
490
515
|
if (plan.entries.length === 0 && plan.problems.length === 0 && plan.warnings.length === 0) {
|
|
491
516
|
return undefined;
|
|
492
517
|
}
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
518
|
+
const refusal = packEnvRefusal(args, plan);
|
|
519
|
+
if (refusal !== undefined) {
|
|
520
|
+
// A refusal's reason is the plan: said under `--quiet` too.
|
|
521
|
+
for (const l of describePackEnvPlan(plan))
|
|
522
|
+
out.problem(l);
|
|
523
|
+
out.problem('');
|
|
524
|
+
return failure(refusal);
|
|
525
|
+
}
|
|
526
|
+
// A plan that deploys: under `--quiet`, its warnings alone.
|
|
527
|
+
for (const l of packEnvPlanLines(plan))
|
|
528
|
+
out.line(l);
|
|
529
|
+
for (const l of packEnvPlanWarnings(plan))
|
|
530
|
+
out.problem(l);
|
|
531
|
+
(plan.warnings.length > 0 ? out.problem : out.line)('');
|
|
532
|
+
if (plan.missing.length > 0) {
|
|
533
|
+
out.problem(` ⚠ --allow-missing-env: deploying without ${plan.missing.join(', ')}`);
|
|
534
|
+
out.problem('');
|
|
535
|
+
}
|
|
536
|
+
return undefined;
|
|
537
|
+
}
|
|
538
|
+
/** Why the pack service's env refuses the deploy (`checkPackEnv`), when it does. */
|
|
539
|
+
function packEnvRefusal(args, plan) {
|
|
496
540
|
if (plan.problems.length > 0) {
|
|
497
|
-
return
|
|
541
|
+
return `kindgi deploy: the pack service's env for ${args.envName} gives a secret in the clear or is malformed (above). Fix environments.${args.envName}.env in kindgi.config and deploy again.\n`;
|
|
498
542
|
}
|
|
499
543
|
if (plan.missing.length > 0 && !args.allowMissingEnv) {
|
|
500
|
-
return
|
|
501
|
-
}
|
|
502
|
-
if (plan.missing.length > 0) {
|
|
503
|
-
line(` ⚠ --allow-missing-env: deploying without ${plan.missing.join(', ')}`);
|
|
504
|
-
line('');
|
|
544
|
+
return `kindgi deploy: ${plan.missing.join(', ')} ${plan.missing.length === 1 ? 'is' : 'are'} required by the pack and ${plan.missing.length === 1 ? 'has' : 'have'} no value in environments.${args.envName}.env, so the pack service wouldn't be ready. Add ${plan.missing.length === 1 ? 'it' : 'them'}, or deploy anyway with --allow-missing-env.\n`;
|
|
505
545
|
}
|
|
506
546
|
return undefined;
|
|
507
547
|
}
|
|
@@ -529,7 +569,8 @@ function refuseHostedConfigEnv(args, projectId) {
|
|
|
529
569
|
// ---------------------------------------------------------------------
|
|
530
570
|
// Envelope existence — either read from disk or inline-build
|
|
531
571
|
// ---------------------------------------------------------------------
|
|
532
|
-
async function ensureEnvelopeExists(ctx, args, runners,
|
|
572
|
+
async function ensureEnvelopeExists(ctx, args, runners, out, projectId) {
|
|
573
|
+
const { line } = out;
|
|
533
574
|
const exists = await pathExists(args.envelopePath);
|
|
534
575
|
if (exists)
|
|
535
576
|
return { kind: 'ok' };
|
|
@@ -538,8 +579,8 @@ async function ensureEnvelopeExists(ctx, args, runners, line, projectId) {
|
|
|
538
579
|
}
|
|
539
580
|
// Auto-detect path is missing → run build inline.
|
|
540
581
|
line(` Envelope missing — running \`kindgi build --env=${args.envName}\` inline...`);
|
|
541
|
-
line('');
|
|
542
582
|
if (runners.runBuild !== undefined) {
|
|
583
|
+
line('');
|
|
543
584
|
const buildArgv = buildInlineArgv(ctx, args, projectId);
|
|
544
585
|
const outcome = await runners.runBuild({
|
|
545
586
|
buildArgv,
|
|
@@ -569,13 +610,9 @@ async function ensureEnvelopeExists(ctx, args, runners, line, projectId) {
|
|
|
569
610
|
// No inline runner available — invoke the same-package `runBuild`
|
|
570
611
|
// directly. This is the production path when
|
|
571
612
|
// `deployRunners.runBuild` is omitted (see `deploy/defaults.ts`).
|
|
572
|
-
const built = await runInlineBuild(ctx, args, projectId);
|
|
613
|
+
const built = await runInlineBuild(ctx, args, projectId, out);
|
|
573
614
|
if (built.kind === 'error')
|
|
574
615
|
return built;
|
|
575
|
-
if (built.banner.length > 0) {
|
|
576
|
-
line(built.banner);
|
|
577
|
-
line('');
|
|
578
|
-
}
|
|
579
616
|
return { kind: 'ok' };
|
|
580
617
|
}
|
|
581
618
|
/**
|
|
@@ -583,14 +620,17 @@ async function ensureEnvelopeExists(ctx, args, runners, line, projectId) {
|
|
|
583
620
|
* `CommandContext` (buildRunners, buildConfigLoader, env, cwd, etc.)
|
|
584
621
|
* but with an argument set derived from the deploy invocation. We
|
|
585
622
|
* clone the context with `options` replaced so the build command sees
|
|
586
|
-
* only build-relevant flags.
|
|
623
|
+
* only build-relevant flags. Its lines go out with deploy's (`out`), in
|
|
624
|
+
* order.
|
|
587
625
|
*/
|
|
588
|
-
async function runInlineBuild(ctx, args, projectId) {
|
|
626
|
+
async function runInlineBuild(ctx, args, projectId, out) {
|
|
589
627
|
const buildOptions = buildInlineOptions(ctx, args, projectId);
|
|
590
628
|
// A hosted build runs at the API this deploy goes to: the build resolves
|
|
591
629
|
// the same address, with the same key, from the same config.
|
|
592
630
|
const buildCtx = { ...ctx, options: buildOptions };
|
|
593
|
-
|
|
631
|
+
// Through deploy's own `out`, `--quiet` and all. None are kept here:
|
|
632
|
+
// deploy's `out` streams or keeps them.
|
|
633
|
+
const result = await runBuild(buildCtx, { ...out, kept: () => '' });
|
|
594
634
|
if (result.kind === 'error') {
|
|
595
635
|
return {
|
|
596
636
|
kind: 'error',
|
|
@@ -607,10 +647,7 @@ async function runInlineBuild(ctx, args, projectId) {
|
|
|
607
647
|
exitCode: 1,
|
|
608
648
|
};
|
|
609
649
|
}
|
|
610
|
-
return {
|
|
611
|
-
kind: 'ok',
|
|
612
|
-
banner: result.rendered.stderr.trim(),
|
|
613
|
-
};
|
|
650
|
+
return { kind: 'ok' };
|
|
614
651
|
}
|
|
615
652
|
function buildInlineOptions(ctx, args, projectId) {
|
|
616
653
|
const opts = {};
|
|
@@ -1023,6 +1060,7 @@ async function resolveDeployArgs(ctx) {
|
|
|
1023
1060
|
environments: environmentsOf(cfg),
|
|
1024
1061
|
packEnv: packEnv.plan,
|
|
1025
1062
|
allowMissingEnv: ctx.options['allow-missing-env'] === true,
|
|
1063
|
+
blocksPattern: resolveDiscovery(cfg.discovery).blocks,
|
|
1026
1064
|
},
|
|
1027
1065
|
};
|
|
1028
1066
|
}
|
|
@@ -1088,9 +1126,52 @@ async function pathExists(path) {
|
|
|
1088
1126
|
return false;
|
|
1089
1127
|
}
|
|
1090
1128
|
}
|
|
1129
|
+
/**
|
|
1130
|
+
* `--dry-run`'s answer: the curl-equivalent and body as progress, the
|
|
1131
|
+
* summary on stdout. An unsigned envelope's body lacks the signature's
|
|
1132
|
+
* fields, and has no derived Idempotency-Key, which hashes the signed body.
|
|
1133
|
+
*/
|
|
1134
|
+
function dryRunResult(ctx, args, line, body, idempotencyKey) {
|
|
1135
|
+
const missing = idempotencyKey === undefined
|
|
1136
|
+
? 'signerKeyId, signerPublicKey and signature a signed build adds, and the Idempotency-Key, which hashes that body'
|
|
1137
|
+
: 'signerKeyId, signerPublicKey and signature a signed build adds';
|
|
1138
|
+
line('signature' in body
|
|
1139
|
+
? ' Dry run — would POST the following:'
|
|
1140
|
+
: ` Dry run — would POST the following, plus the ${missing}:`);
|
|
1141
|
+
line('');
|
|
1142
|
+
line(` curl -X POST ${args.endpoint.replace(/\/+$/, '')}/v1/deployments \\`);
|
|
1143
|
+
line(' -H "Authorization: Bearer <redacted>" \\');
|
|
1144
|
+
line(' -H "Content-Type: application/json" \\');
|
|
1145
|
+
if (idempotencyKey !== undefined)
|
|
1146
|
+
line(` -H "Idempotency-Key: ${idempotencyKey}" \\`);
|
|
1147
|
+
line(" -d @- <<'JSON'");
|
|
1148
|
+
for (const bodyLine of JSON.stringify(body, null, 2).split('\n')) {
|
|
1149
|
+
line(` ${bodyLine}`);
|
|
1150
|
+
}
|
|
1151
|
+
line(' JSON');
|
|
1152
|
+
line('');
|
|
1153
|
+
line(' --dry-run set. No request sent. Exiting 0.');
|
|
1154
|
+
line('');
|
|
1155
|
+
const summary = {
|
|
1156
|
+
envName: args.envName,
|
|
1157
|
+
endpoint: args.endpoint,
|
|
1158
|
+
envelopePath: args.envelopePath,
|
|
1159
|
+
...(idempotencyKey !== undefined && { idempotencyKey }),
|
|
1160
|
+
dryRun: true,
|
|
1161
|
+
wouldPost: body,
|
|
1162
|
+
};
|
|
1163
|
+
const rendered = renderJson(summary, ctx.globals.format);
|
|
1164
|
+
return {
|
|
1165
|
+
kind: 'ok',
|
|
1166
|
+
rendered: { stdout: rendered.stdout, stderr: '' },
|
|
1167
|
+
};
|
|
1168
|
+
}
|
|
1091
1169
|
function failure(stderr) {
|
|
1092
1170
|
return { kind: 'error', stderr, exitCode: 1 };
|
|
1093
1171
|
}
|
|
1172
|
+
const UNSIGNED_REFUSAL = 'deploy-envelope.json is unsigned. The server will refuse the deployment.\n' +
|
|
1173
|
+
'Re-run `kindgi build` without --skip-sign, or pass --dry-run to inspect ' +
|
|
1174
|
+
'what would be POSTed.\n';
|
|
1094
1175
|
function countIndexPrimitives(index) {
|
|
1095
1176
|
const asArrLen = (v) => (Array.isArray(v) ? v.length : 0);
|
|
1096
1177
|
return {
|