@empire-builder-kit/nx 1.0.0-rc.4 → 1.0.0-rc.40
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 +18 -0
- package/executors.json +21 -1
- package/generators.json +10 -0
- package/package.json +31 -7
- package/src/aws/child-environment.d.ts +10 -0
- package/src/aws/child-environment.js +77 -0
- package/src/aws/identity.d.ts +13 -0
- package/src/aws/identity.js +41 -0
- package/src/aws-authority/index.d.ts +2 -0
- package/src/aws-authority/index.js +6 -0
- package/src/aws-authority/lambda-policy-ordering.d.ts +38 -0
- package/src/aws-authority/lambda-policy-ordering.js +56 -0
- package/src/aws-authority/stage-authority.d.ts +248 -0
- package/src/aws-authority/stage-authority.js +3558 -0
- package/src/blueprints/external-sandbox.js +21 -9
- package/src/blueprints/manifest.d.ts +1 -1
- package/src/blueprints/resolver.js +28 -15
- package/src/cli/bootstrap.d.ts +1 -1
- package/src/cli/deploy-runtime.d.ts +6 -0
- package/src/cli/deploy-runtime.js +58 -0
- package/src/cli/dev-command.d.ts +16 -4
- package/src/cli/dev-command.js +63 -0
- package/src/cli/main.d.ts +9 -1
- package/src/cli/main.js +139 -20
- package/src/cli/output.d.ts +1 -1
- package/src/cli/output.js +1 -1
- package/src/developer-agent/context.js +41 -9
- package/src/developer-agent/generator-planning.js +20 -6
- package/src/developer-agent/git-inspection.d.ts +6 -2
- package/src/developer-agent/git-inspection.js +78 -6
- package/src/developer-agent/model.d.ts +5 -3
- package/src/developer-agent/model.js +4 -4
- package/src/developer-agent/operation-registry.d.ts +5 -0
- package/src/developer-agent/operation-registry.js +286 -40
- package/src/developer-agent/planning.js +16 -13
- package/src/developer-agent/preview-changes.d.ts +2 -0
- package/src/developer-agent/preview-changes.js +14 -2
- package/src/developer-agent/preview-source.js +3 -0
- package/src/developer-agent/validation.js +25 -9
- package/src/developer-agent/workspace-inspection.js +60 -5
- package/src/executors/blueprint-trust/blueprint-trust.js +6 -0
- package/src/executors/deployment-plan/deployment-plan.d.ts +2 -0
- package/src/executors/deployment-plan/deployment-plan.js +57 -2
- package/src/executors/dev-doctor/dev-doctor.js +13 -6
- package/src/executors/dev-task-cleanup/dev-task-cleanup.d.ts +23 -0
- package/src/executors/dev-task-cleanup/dev-task-cleanup.js +145 -0
- package/src/executors/dev-task-cleanup/schema.json +9 -0
- package/src/executors/dev-task-cleanup/task-stack-absence.d.ts +27 -0
- package/src/executors/dev-task-cleanup/task-stack-absence.js +281 -0
- package/src/executors/dev-task-cleanup/task-stack-checkpoint.d.ts +12 -0
- package/src/executors/dev-task-cleanup/task-stack-checkpoint.js +92 -0
- package/src/executors/fleet/fleet.js +1 -1
- package/src/executors/foundation-preflight/foundation-preflight.d.ts +1 -0
- package/src/executors/foundation-preflight/foundation-preflight.js +6 -2
- package/src/executors/foundation-preflight/schema.json +5 -0
- package/src/executors/foundation-profile-preflight/foundation-profile-preflight.d.ts +13 -2
- package/src/executors/foundation-profile-preflight/foundation-profile-preflight.js +95 -31
- package/src/executors/foundation-profile-preflight/production-database-safeguard.d.ts +65 -0
- package/src/executors/foundation-profile-preflight/production-database-safeguard.js +223 -0
- package/src/executors/foundation-profile-preflight/schema.json +15 -4
- package/src/executors/foundation-remove-preflight/foundation-remove-preflight.d.ts +11 -1
- package/src/executors/foundation-remove-preflight/foundation-remove-preflight.js +70 -20
- package/src/executors/foundation-remove-preflight/schema.json +6 -1
- package/src/executors/github-bootstrap/github-bootstrap.d.ts +1 -0
- package/src/executors/github-bootstrap/github-bootstrap.js +3 -0
- package/src/executors/github-bootstrap/schema.json +7 -1
- package/src/executors/infrastructure-plan/infrastructure-plan.d.ts +29 -136
- package/src/executors/infrastructure-plan/infrastructure-plan.js +230 -3282
- package/src/executors/infrastructure-plan/schema.json +12 -52
- package/src/executors/local-deploy/federated-credential-transport.d.ts +48 -0
- package/src/executors/local-deploy/federated-credential-transport.js +252 -0
- package/src/executors/local-deploy/local-approval.d.ts +18 -0
- package/src/executors/local-deploy/local-approval.js +39 -0
- package/src/executors/local-deploy/local-deploy.d.ts +112 -0
- package/src/executors/local-deploy/local-deploy.js +1404 -0
- package/src/executors/local-deploy/schema.json +70 -0
- package/src/executors/refresh/refresh.js +2 -2
- package/src/executors/remove/remove.js +2 -2
- package/src/executors/router-waf-rehearsal/router-waf-rehearsal.d.ts +42 -0
- package/src/executors/router-waf-rehearsal/router-waf-rehearsal.js +1229 -0
- package/src/executors/router-waf-rehearsal/schema.json +29 -0
- package/src/executors/secret-initialize/schema.json +42 -0
- package/src/executors/secret-initialize/secret-initialize.d.ts +34 -0
- package/src/executors/secret-initialize/secret-initialize.js +297 -0
- package/src/executors/secret-metadata/schema.json +5 -0
- package/src/executors/secret-metadata/secret-metadata.d.ts +16 -2
- package/src/executors/secret-metadata/secret-metadata.js +129 -30
- package/src/executors/sst-lifecycle/generated-secret-retirement.d.ts +53 -0
- package/src/executors/sst-lifecycle/generated-secret-retirement.js +192 -0
- package/src/executors/sst-lifecycle/governed-native-operation.d.ts +48 -0
- package/src/executors/sst-lifecycle/governed-native-operation.js +162 -0
- package/src/executors/sst-lifecycle/logging-preflight.d.ts +5 -0
- package/src/executors/sst-lifecycle/logging-preflight.js +23 -13
- package/src/executors/sst-lifecycle/run-sst-command.d.ts +40 -6
- package/src/executors/sst-lifecycle/run-sst-command.js +779 -70
- package/src/executors/sst-lifecycle/schema.json +8 -1
- package/src/executors/sst-lifecycle/secret-preflight.d.ts +2 -0
- package/src/executors/sst-lifecycle/secret-preflight.js +13 -7
- package/src/executors/sst-lifecycle/sst-environment-source.d.ts +33 -0
- package/src/executors/sst-lifecycle/sst-environment-source.js +267 -0
- package/src/executors/sst-lifecycle/task-unlock.d.ts +15 -0
- package/src/executors/sst-lifecycle/task-unlock.js +126 -0
- package/src/executors/unlock/unlock.js +2 -2
- package/src/foundation/capability-plan.d.ts +43 -0
- package/src/foundation/capability-plan.js +168 -0
- package/src/foundation/discovery.d.ts +14 -11
- package/src/foundation/discovery.js +32 -6
- package/src/foundation/index.d.ts +4 -0
- package/src/foundation/index.js +11 -0
- package/src/foundation/local-database-contract.d.ts +20 -0
- package/src/foundation/local-database-contract.js +262 -13
- package/src/foundation/local-private-smoke-access.d.ts +20 -0
- package/src/foundation/local-private-smoke-access.js +197 -0
- package/src/foundation/logging-preflight.js +1 -1
- package/src/foundation/logging.d.ts +3 -1
- package/src/foundation/logging.js +1 -1
- package/src/foundation/partial-state.d.ts +10 -0
- package/src/foundation/partial-state.js +21 -0
- package/src/foundation/preflight.js +37 -18
- package/src/foundation/private-smoke-access.d.ts +25 -0
- package/src/foundation/private-smoke-access.js +135 -0
- package/src/foundation/private-smoke-admission.d.ts +45 -0
- package/src/foundation/private-smoke-admission.js +180 -0
- package/src/foundation/private-smoke-control-plane.d.ts +18 -0
- package/src/foundation/private-smoke-control-plane.js +184 -0
- package/src/foundation/provision-database-bindings.d.ts +5 -0
- package/src/foundation/provision-database-bindings.js +41 -8
- package/src/foundation/provision-logical-database.js +15 -8
- package/src/foundation/requirements.d.ts +3 -3
- package/src/foundation/requirements.js +24 -12
- package/src/foundation/router-waf-rate-rehearsal.d.ts +97 -0
- package/src/foundation/router-waf-rate-rehearsal.js +210 -0
- package/src/foundation/router-waf.d.ts +149 -0
- package/src/foundation/router-waf.js +809 -0
- package/src/foundation/stages.d.ts +1 -0
- package/src/foundation/stages.js +11 -0
- package/src/generators/blueprint/blueprint.d.ts +5 -0
- package/src/generators/blueprint/blueprint.js +102 -0
- package/src/generators/blueprint/files.d.ts +6 -0
- package/src/generators/blueprint/files.js +217 -0
- package/src/generators/blueprint/schema.d.ts +4 -0
- package/src/generators/blueprint/schema.json +18 -0
- package/src/generators/formatting.d.ts +8 -0
- package/src/generators/formatting.js +141 -0
- package/src/generators/function/function.js +38 -17
- package/src/generators/logging-registry.d.ts +2 -0
- package/src/generators/logging-registry.js +22 -0
- package/src/generators/post-generation-install.js +2 -2
- package/src/generators/preset/dependency-overrides.d.ts +8 -0
- package/src/generators/preset/dependency-overrides.js +55 -0
- package/src/generators/preset/generator.js +43 -3
- package/src/generators/preset/schema.d.ts +10 -0
- package/src/generators/preset/schema.json +47 -0
- package/src/generators/preset/tool-versions.d.ts +2 -0
- package/src/generators/preset/tool-versions.js +3 -1
- package/src/generators/preset/workspace-files-adopter-skills.d.ts +7 -0
- package/src/generators/preset/workspace-files-adopter-skills.js +303 -0
- package/src/generators/preset/workspace-files-ci-acceptance.d.ts +1 -0
- package/src/generators/preset/workspace-files-ci-acceptance.js +791 -0
- package/src/generators/preset/workspace-files-ci-install.d.ts +2 -0
- package/src/generators/preset/workspace-files-ci-install.js +196 -0
- package/src/generators/preset/workspace-files-developer-agent.d.ts +2 -0
- package/src/generators/preset/workspace-files-developer-agent.js +90 -28
- package/src/generators/preset/workspace-files-ecr-inspector.d.ts +18 -0
- package/src/generators/preset/workspace-files-ecr-inspector.js +298 -0
- package/src/generators/preset/workspace-files-foundation-workload-roles.js +5 -2
- package/src/generators/preset/workspace-files-performance-cost.d.ts +2 -2
- package/src/generators/preset/workspace-files-performance-cost.js +8 -8
- package/src/generators/preset/workspace-files-performance-load.d.ts +1 -1
- package/src/generators/preset/workspace-files-performance-load.js +39 -25
- package/src/generators/preset/workspace-files-stage-authority.d.ts +6 -0
- package/src/generators/preset/workspace-files-stage-authority.js +518 -0
- package/src/generators/preset/workspace-files-thin-deploy.d.ts +55 -0
- package/src/generators/preset/workspace-files-thin-deploy.js +2473 -0
- package/src/generators/preset/workspace-files-thin-docs.d.ts +7 -0
- package/src/generators/preset/workspace-files-thin-docs.js +352 -0
- package/src/generators/preset/workspace-files-thin-release.d.ts +14 -0
- package/src/generators/preset/workspace-files-thin-release.js +26 -0
- package/src/generators/preset/workspace-files-workload-role-baseline.js +254 -42
- package/src/generators/preset/workspace-files.d.ts +18 -2
- package/src/generators/preset/workspace-files.js +1504 -608
- package/src/generators/repository-policy/repository-policy.js +235 -5
- package/src/generators/repository-policy/schema.d.ts +10 -0
- package/src/generators/repository-policy/schema.json +80 -4
- package/src/generators/repository-policy/tree-policy.d.ts +3 -0
- package/src/generators/repository-policy/tree-policy.js +25 -0
- package/src/generators/slice/built-in-plan-api-contract-files.js +42 -7
- package/src/generators/slice/built-in-plan-api-files.d.ts +1 -1
- package/src/generators/slice/built-in-plan-api-files.js +130 -414
- package/src/generators/slice/built-in-plan-async-work-files.js +166 -1969
- package/src/generators/slice/built-in-plan-authorization-files.js +92 -329
- package/src/generators/slice/built-in-plan-authorization-infrastructure-files.js +60 -2
- package/src/generators/slice/built-in-plan-authorization-storage.d.ts +3 -0
- package/src/generators/slice/built-in-plan-authorization-storage.js +119 -0
- package/src/generators/slice/built-in-plan-background-work-files.d.ts +2 -0
- package/src/generators/slice/built-in-plan-background-work-files.js +99 -0
- package/src/generators/slice/built-in-plan-data-deletion-files.js +2 -830
- package/src/generators/slice/built-in-plan-data-export-infrastructure-files.js +5 -31
- package/src/generators/slice/built-in-plan-data-files.d.ts +1 -1
- package/src/generators/slice/built-in-plan-data-files.js +163 -1196
- package/src/generators/slice/built-in-plan-data-lifecycle-files.js +53 -28
- package/src/generators/slice/built-in-plan-data-lifecycle-runtime-files.js +37 -2
- package/src/generators/slice/built-in-plan-data-retention-job-files.js +7 -2443
- package/src/generators/slice/built-in-plan-data-retention-launcher-files.js +50 -8
- package/src/generators/slice/built-in-plan-data-rights-files.js +6 -4482
- package/src/generators/slice/built-in-plan-database-lifecycle-files.js +44 -25
- package/src/generators/slice/built-in-plan-database-retirement-rehearsal-files.js +20 -1
- package/src/generators/slice/built-in-plan-foundation-files.d.ts +2 -1
- package/src/generators/slice/built-in-plan-foundation-files.js +39 -18
- package/src/generators/slice/built-in-plan-frontend-files.js +7 -3
- package/src/generators/slice/built-in-plan-infrastructure-files.d.ts +1 -1
- package/src/generators/slice/built-in-plan-infrastructure-files.js +933 -729
- package/src/generators/slice/built-in-plan-infrastructure-safety-files.js +67 -11
- package/src/generators/slice/built-in-plan-key-value-cleanup.d.ts +4 -0
- package/src/generators/slice/built-in-plan-key-value-cleanup.js +100 -0
- package/src/generators/slice/built-in-plan-key-value-consumer.d.ts +4 -0
- package/src/generators/slice/built-in-plan-key-value-consumer.js +151 -0
- package/src/generators/slice/built-in-plan-key-value-deletion.d.ts +2 -0
- package/src/generators/slice/built-in-plan-key-value-deletion.js +377 -0
- package/src/generators/slice/built-in-plan-key-value-delivery.d.ts +2 -0
- package/src/generators/slice/built-in-plan-key-value-delivery.js +137 -0
- package/src/generators/slice/built-in-plan-key-value-export.d.ts +2 -0
- package/src/generators/slice/built-in-plan-key-value-export.js +595 -0
- package/src/generators/slice/built-in-plan-key-value-files.d.ts +2 -0
- package/src/generators/slice/built-in-plan-key-value-files.js +31 -0
- package/src/generators/slice/built-in-plan-key-value-holds.d.ts +2 -0
- package/src/generators/slice/built-in-plan-key-value-holds.js +189 -0
- package/src/generators/slice/built-in-plan-key-value-infrastructure.d.ts +2 -0
- package/src/generators/slice/built-in-plan-key-value-infrastructure.js +102 -0
- package/src/generators/slice/built-in-plan-key-value-performance.d.ts +5 -0
- package/src/generators/slice/built-in-plan-key-value-performance.js +530 -0
- package/src/generators/slice/built-in-plan-key-value-provider.d.ts +4 -0
- package/src/generators/slice/built-in-plan-key-value-provider.js +366 -0
- package/src/generators/slice/built-in-plan-key-value-records.d.ts +3 -0
- package/src/generators/slice/built-in-plan-key-value-records.js +232 -0
- package/src/generators/slice/built-in-plan-key-value-retention-infrastructure.d.ts +2 -0
- package/src/generators/slice/built-in-plan-key-value-retention-infrastructure.js +103 -0
- package/src/generators/slice/built-in-plan-key-value-retention-job-files.d.ts +2 -0
- package/src/generators/slice/built-in-plan-key-value-retention-job-files.js +160 -0
- package/src/generators/slice/built-in-plan-key-value-retention-maintenance.d.ts +2 -0
- package/src/generators/slice/built-in-plan-key-value-retention-maintenance.js +329 -0
- package/src/generators/slice/built-in-plan-key-value-retention-worker.d.ts +2 -0
- package/src/generators/slice/built-in-plan-key-value-retention-worker.js +477 -0
- package/src/generators/slice/built-in-plan-key-value-retention.d.ts +2 -0
- package/src/generators/slice/built-in-plan-key-value-retention.js +184 -0
- package/src/generators/slice/built-in-plan-metadata-files.d.ts +1 -1
- package/src/generators/slice/built-in-plan-metadata-files.js +157 -28
- package/src/generators/slice/built-in-plan-native-runtime-authority-files.d.ts +2 -0
- package/src/generators/slice/built-in-plan-native-runtime-authority-files.js +324 -0
- package/src/generators/slice/built-in-plan-operations-files.d.ts +1 -1
- package/src/generators/slice/built-in-plan-operations-files.js +585 -97
- package/src/generators/slice/built-in-plan-performance-files.d.ts +2 -1
- package/src/generators/slice/built-in-plan-performance-files.js +220 -1074
- package/src/generators/slice/built-in-plan-project-files.js +141 -135
- package/src/generators/slice/built-in-plan-release-files.d.ts +1 -1
- package/src/generators/slice/built-in-plan-release-files.js +310 -70
- package/src/generators/slice/built-in-plan-reliability-files.d.ts +1 -1
- package/src/generators/slice/built-in-plan-reliability-files.js +279 -43
- package/src/generators/slice/built-in-plan-secret-runtime-files.d.ts +1 -1
- package/src/generators/slice/built-in-plan-secret-runtime-files.js +87 -76
- package/src/generators/slice/built-in-plan-shared.d.ts +4 -2
- package/src/generators/slice/built-in-plan-shared.js +41 -19
- package/src/generators/slice/built-in-plan-sql-events.d.ts +2 -0
- package/src/generators/slice/built-in-plan-sql-events.js +276 -0
- package/src/generators/slice/built-in-plan-testing-files.d.ts +1 -1
- package/src/generators/slice/built-in-plan-testing-files.js +304 -172
- package/src/generators/slice/built-in-plan-testing-persistence-files.d.ts +2 -0
- package/src/generators/slice/built-in-plan-testing-persistence-files.js +178 -0
- package/src/generators/slice/built-in-plan-thin-release-files.d.ts +11 -0
- package/src/generators/slice/built-in-plan-thin-release-files.js +162 -0
- package/src/generators/slice/built-in-plan-verification-files.js +76 -2
- package/src/generators/slice/built-in-plan-web-files.d.ts +1 -1
- package/src/generators/slice/built-in-plan-web-files.js +223 -16
- package/src/generators/slice/built-in-plan-workload-role-files.d.ts +1 -1
- package/src/generators/slice/built-in-plan-workload-role-files.js +143 -279
- package/src/generators/slice/built-in-plan.d.ts +11 -1
- package/src/generators/slice/built-in-plan.js +80 -29
- package/src/generators/slice/data-policy-review-seed.d.ts +2 -0
- package/src/generators/slice/data-policy-review-seed.js +22 -0
- package/src/generators/slice/deployed-smoke-readiness.d.ts +2 -0
- package/src/generators/slice/deployed-smoke-readiness.js +214 -0
- package/src/generators/slice/local-source-identity.d.ts +2 -0
- package/src/generators/slice/local-source-identity.js +31 -0
- package/src/generators/slice/persistence-contract.d.ts +14 -0
- package/src/generators/slice/persistence-contract.js +32 -0
- package/src/generators/slice/slice.js +61 -50
- package/src/generators/sql/schema.d.ts +7 -0
- package/src/generators/sql/schema.json +38 -0
- package/src/generators/sql/sql.d.ts +6 -0
- package/src/generators/sql/sql.js +53 -0
- package/src/generators/upgrade/sql-seeded-reconciliation.d.ts +2 -0
- package/src/generators/upgrade/sql-seeded-reconciliation.js +170 -0
- package/src/generators/upgrade/upgrade.d.ts +15 -1
- package/src/generators/upgrade/upgrade.js +435 -44
- package/src/generators/workload/performance-registration.d.ts +1 -0
- package/src/generators/workload/performance-registration.js +9 -11
- package/src/generators/workload/service-performance-files.d.ts +1 -0
- package/src/generators/workload/service-performance-files.js +27 -7
- package/src/generators/workload/workload.d.ts +1 -1
- package/src/generators/workload/workload.js +105 -29
- package/src/git-policy/action-pins.d.ts +5 -0
- package/src/git-policy/action-pins.js +5 -0
- package/src/git-policy/github-bootstrap.d.ts +39 -8
- package/src/git-policy/github-bootstrap.js +329 -175
- package/src/git-policy/routing.d.ts +7 -1
- package/src/git-policy/routing.js +62 -1
- package/src/index.d.ts +1 -0
- package/src/index.js +1 -0
- package/src/infrastructure-change/local-capability.d.ts +73 -0
- package/src/infrastructure-change/local-capability.js +114 -0
- package/src/infrastructure-change/model.d.ts +25 -4
- package/src/infrastructure-change/model.js +1 -0
- package/src/infrastructure-change/normalize.d.ts +4 -0
- package/src/infrastructure-change/normalize.js +47 -7
- package/src/infrastructure-change/plan.d.ts +30 -3
- package/src/infrastructure-change/plan.js +323 -13
- package/src/infrastructure-change/risk.d.ts +3 -1
- package/src/infrastructure-change/risk.js +96 -16
- package/src/local-dev/browser-verification.d.ts +37 -0
- package/src/local-dev/browser-verification.js +281 -0
- package/src/local-dev/contracts.d.ts +10 -1
- package/src/local-dev/contracts.js +114 -13
- package/src/local-dev/dev-command-core.js +24 -5
- package/src/local-dev/docker-credential-health.d.ts +14 -0
- package/src/local-dev/docker-credential-health.js +94 -0
- package/src/local-dev/environment-inspector.d.ts +7 -0
- package/src/local-dev/environment-inspector.js +42 -15
- package/src/local-dev/environment-state.js +2 -2
- package/src/local-dev/errors.d.ts +1 -1
- package/src/local-dev/errors.js +2 -0
- package/src/local-dev/fleet-client.js +2 -2
- package/src/local-dev/fleet-configuration.js +57 -25
- package/src/local-dev/fleet-inventory.js +46 -18
- package/src/local-dev/fleet-ipc.d.ts +7 -0
- package/src/local-dev/fleet-ipc.js +14 -2
- package/src/local-dev/fleet-launcher.d.ts +6 -0
- package/src/local-dev/fleet-launcher.js +14 -2
- package/src/local-dev/fleet-logs.js +50 -22
- package/src/local-dev/fleet-process.d.ts +20 -1
- package/src/local-dev/fleet-process.js +197 -41
- package/src/local-dev/fleet-runner-evidence.d.ts +5 -0
- package/src/local-dev/fleet-runner-evidence.js +56 -0
- package/src/local-dev/fleet-runtime.js +268 -229
- package/src/local-dev/fleet-session.d.ts +2 -0
- package/src/local-dev/fleet-session.js +28 -11
- package/src/local-dev/fleet-slice-runner-daemon.js +4 -0
- package/src/local-dev/fleet-state.d.ts +5 -2
- package/src/local-dev/fleet-state.js +25 -4
- package/src/local-dev/fleet-supervisor.d.ts +3 -0
- package/src/local-dev/fleet-supervisor.js +66 -11
- package/src/local-dev/fleet-web-start.d.ts +12 -0
- package/src/local-dev/fleet-web-start.js +48 -0
- package/src/local-dev/identity.js +3 -14
- package/src/local-dev/index.d.ts +1 -0
- package/src/local-dev/index.js +1 -0
- package/src/local-dev/native-completion.d.ts +9 -0
- package/src/local-dev/native-completion.js +130 -0
- package/src/local-dev/nx-workspace.d.ts +4 -2
- package/src/local-dev/nx-workspace.js +11 -6
- package/src/local-dev/personal-stage.d.ts +4 -5
- package/src/local-dev/personal-stage.js +6 -54
- package/src/local-dev/port-claims.d.ts +13 -0
- package/src/local-dev/port-claims.js +46 -0
- package/src/local-dev/ports.d.ts +14 -2
- package/src/local-dev/ports.js +78 -3
- package/src/local-dev/private-state.d.ts +11 -0
- package/src/local-dev/private-state.js +146 -40
- package/src/local-dev/process-group.d.ts +4 -0
- package/src/local-dev/process-group.js +29 -0
- package/src/local-dev/process-identity.d.ts +8 -0
- package/src/local-dev/process-identity.js +31 -1
- package/src/local-dev/proxy.js +11 -12
- package/src/local-dev/runtime-paths.js +1 -1
- package/src/local-dev/slice-claim.js +1 -1
- package/src/local-dev/slice-runner.d.ts +15 -6
- package/src/local-dev/slice-runner.js +189 -54
- package/src/local-dev/task-attachment.d.ts +17 -0
- package/src/local-dev/task-attachment.js +73 -0
- package/src/local-dev/task-authority.d.ts +10 -0
- package/src/local-dev/task-authority.js +27 -0
- package/src/local-dev/task-identity.d.ts +33 -0
- package/src/local-dev/task-identity.js +418 -0
- package/src/local-dev/task-native-writer.d.ts +18 -0
- package/src/local-dev/task-native-writer.js +329 -0
- package/src/local-dev/tls.js +8 -2
- package/src/local-dev/web-launch.d.ts +9 -0
- package/src/local-dev/web-launch.js +130 -0
- package/src/ownership/composition.d.ts +2 -1
- package/src/ownership/composition.js +1 -0
- package/src/performance/cost-collection.d.ts +1 -1
- package/src/performance/cost-collection.js +4 -2
- package/src/performance/cost-controls.d.ts +8 -4
- package/src/performance/cost-controls.js +39 -28
- package/src/performance/evidence.d.ts +1 -1
- package/src/performance/evidence.js +5 -3
- package/src/performance/load-safety.js +5 -3
- package/src/performance/model.d.ts +4 -4
- package/src/performance/model.js +4 -5
- package/src/performance/scenario.d.ts +22 -0
- package/src/performance/scenario.js +100 -92
- package/src/release/index.d.ts +0 -2
- package/src/release/index.js +0 -2
- package/src/release/source-authority.d.ts +5 -5
- package/src/release/source-authority.js +141 -124
- package/src/repository-policy/aurora-preflight.d.ts +1 -1
- package/src/repository-policy/aurora-preflight.js +4 -1
- package/src/repository-policy/capacity-migration.d.ts +3 -0
- package/src/repository-policy/capacity-migration.js +21 -0
- package/src/repository-policy/deployment-plan.d.ts +4 -1
- package/src/repository-policy/deployment-plan.js +9 -0
- package/src/repository-policy/foundation-profile.js +10 -1
- package/src/repository-policy/policy.d.ts +57 -3
- package/src/repository-policy/policy.js +497 -11
- package/src/schemas/blueprint-v1.json +5 -4
- package/src/schemas/foundation-requirement-v1.json +5 -4
- package/src/schemas/performance-policy-v1.json +3 -3
- package/src/schemas/repository-policy-v1.json +130 -6
- package/src/schemas/testing-evidence-result-v1.json +1 -1
- package/src/secrets/adapters.d.ts +7 -2
- package/src/secrets/adapters.js +34 -3
- package/src/secrets/aws-control-plane.d.ts +10 -1
- package/src/secrets/aws-control-plane.js +67 -0
- package/src/secrets/generated-aws-control-plane.d.ts +23 -0
- package/src/secrets/generated-aws-control-plane.js +259 -0
- package/src/secrets/metadata.js +38 -10
- package/src/secrets/model.d.ts +8 -1
- package/src/secrets/model.js +24 -3
- package/src/secrets/operator.d.ts +91 -3
- package/src/secrets/operator.js +463 -13
- package/src/secrets/registry.d.ts +2 -1
- package/src/secrets/registry.js +18 -1
- package/src/secrets/verification.js +9 -1
- package/src/secrets/workload-access.js +10 -2
- package/src/sst-environment-source-format.d.ts +6 -0
- package/src/sst-environment-source-format.js +199 -0
- package/src/supply-chain/action-pins.js +61 -7
- package/src/supply-chain/blueprint-trust-git.js +85 -24
- package/src/supply-chain/blueprint-verification-authority.js +55 -3
- package/src/supply-chain/build-output-bounds.d.ts +2 -0
- package/src/supply-chain/build-output-bounds.js +12 -0
- package/src/supply-chain/build-output.d.ts +7 -1
- package/src/supply-chain/build-output.js +177 -24
- package/src/supply-chain/ecr-scanning.d.ts +5 -3
- package/src/supply-chain/ecr-scanning.js +11 -7
- package/src/supply-chain/ecs-deployed-image.d.ts +5 -3
- package/src/supply-chain/ecs-deployed-image.js +6 -4
- package/src/supply-chain/generated-blueprint-trust-command.js +18 -1
- package/src/supply-chain/generated-command.js +1 -0
- package/src/supply-chain/generated-container-release-command.js +1285 -124
- package/src/supply-chain/generated-ecr-collector-command.d.ts +0 -1
- package/src/supply-chain/generated-ecr-collector-command.js +200 -93
- package/src/supply-chain/generated-files.js +25 -14
- package/src/supply-chain/generated-scanner-command.js +2 -1
- package/src/supply-chain/index.d.ts +1 -1
- package/src/supply-chain/index.js +2 -1
- package/src/supply-chain/sbom.d.ts +1 -1
- package/src/supply-chain/sbom.js +30 -5
- package/src/supply-chain/scanner.js +3 -0
- package/src/testing-evidence/fixture-scope.d.ts +2 -1
- package/src/testing-evidence/fixture-scope.js +4 -2
- package/src/testing-evidence/result.d.ts +2 -1
- package/src/testing-evidence/result.js +18 -4
- package/src/workload-roles/account-baseline.d.ts +11 -0
- package/src/workload-roles/account-baseline.js +253 -16
- package/src/workload-roles/authority.d.ts +3 -1
- package/src/workload-roles/authority.js +48 -2
- package/src/workload-roles/aws-s3-state.js +27 -0
- package/src/workload-roles/boundary.d.ts +2 -1
- package/src/workload-roles/boundary.js +9 -2
- package/src/workload-roles/handler.js +52 -24
- package/src/workload-roles/index.d.ts +10 -17
- package/src/workload-roles/index.js +5 -18
- package/src/workload-roles/injection.js +1 -1
- package/src/workload-roles/provisioner.js +12 -4
- package/src/workload-roles/registration.d.ts +1 -0
- package/src/workload-roles/registration.js +5 -0
- package/src/workload-roles/stage-boundary.js +1 -1
- package/src/workload-roles/standard-slice.js +3 -3
- package/src/workspace-deployment/affected-lifecycle.d.ts +53 -0
- package/src/workspace-deployment/affected-lifecycle.js +84 -0
- package/src/workspace-deployment/identity.d.ts +3 -0
- package/src/workspace-deployment/identity.js +22 -0
- package/src/workspace-deployment/index.d.ts +4 -0
- package/src/workspace-deployment/index.js +8 -0
- package/src/workspace-deployment/migration-evidence.d.ts +29 -0
- package/src/workspace-deployment/migration-evidence.js +83 -0
- package/src/workspace-deployment/migration.d.ts +27 -0
- package/src/workspace-deployment/migration.js +109 -0
- package/src/workspace-deployment/ownership.d.ts +81 -0
- package/src/workspace-deployment/ownership.js +381 -0
- package/src/api-contract/baseline-update.js.map +0 -1
- package/src/api-contract/compatibility.js.map +0 -1
- package/src/api-contract/contract-graph.js.map +0 -1
- package/src/api-contract/evidence.js.map +0 -1
- package/src/api-contract/index.js.map +0 -1
- package/src/api-contract/model.fixtures.d.ts +0 -2
- package/src/api-contract/model.fixtures.js +0 -81
- package/src/api-contract/model.fixtures.js.map +0 -1
- package/src/api-contract/model.js.map +0 -1
- package/src/api-contract/rollout.js.map +0 -1
- package/src/authorization/compatibility.js.map +0 -1
- package/src/authorization/index.js.map +0 -1
- package/src/blueprints/execution.js.map +0 -1
- package/src/blueprints/external-sandbox.js.map +0 -1
- package/src/blueprints/index.js.map +0 -1
- package/src/blueprints/inputs.js.map +0 -1
- package/src/blueprints/manifest.js.map +0 -1
- package/src/blueprints/resolver.js.map +0 -1
- package/src/blueprints/transitions.js.map +0 -1
- package/src/cli/agent-command.js.map +0 -1
- package/src/cli/agent-runtime.js.map +0 -1
- package/src/cli/blueprint-authority.js.map +0 -1
- package/src/cli/blueprint-command.js.map +0 -1
- package/src/cli/bootstrap.js.map +0 -1
- package/src/cli/dev-command.js.map +0 -1
- package/src/cli/main.js.map +0 -1
- package/src/cli/output.js.map +0 -1
- package/src/cli/personal-secret-runtime.js.map +0 -1
- package/src/cli/secret-terminal.js.map +0 -1
- package/src/container-images.js.map +0 -1
- package/src/data-lifecycle/index.js.map +0 -1
- package/src/data-lifecycle/model.fixtures.d.ts +0 -2
- package/src/data-lifecycle/model.fixtures.js +0 -244
- package/src/data-lifecycle/model.fixtures.js.map +0 -1
- package/src/data-lifecycle/model.js.map +0 -1
- package/src/data-lifecycle/sensitive-artifacts.js.map +0 -1
- package/src/data-lifecycle/validation.js.map +0 -1
- package/src/database-retirement/contract.js.map +0 -1
- package/src/database-retirement/index.js.map +0 -1
- package/src/deterministic-order.js.map +0 -1
- package/src/developer-agent/context.js.map +0 -1
- package/src/developer-agent/generator-planning.js.map +0 -1
- package/src/developer-agent/generator-preview.js.map +0 -1
- package/src/developer-agent/git-inspection.js.map +0 -1
- package/src/developer-agent/handoff.js.map +0 -1
- package/src/developer-agent/index.js.map +0 -1
- package/src/developer-agent/model.js.map +0 -1
- package/src/developer-agent/operation-registry.js.map +0 -1
- package/src/developer-agent/ordering.js.map +0 -1
- package/src/developer-agent/planning.js.map +0 -1
- package/src/developer-agent/preview-changes.js.map +0 -1
- package/src/developer-agent/preview-source.js.map +0 -1
- package/src/developer-agent/validation.js.map +0 -1
- package/src/developer-agent/workspace-inspection.js.map +0 -1
- package/src/developer-agent/workspace-path.js.map +0 -1
- package/src/executors/blueprint-trust/blueprint-trust.js.map +0 -1
- package/src/executors/blueprint-verification/blueprint-verification.js.map +0 -1
- package/src/executors/deploy/deploy.js.map +0 -1
- package/src/executors/deployment-plan/deployment-plan.js.map +0 -1
- package/src/executors/dev/dev.js.map +0 -1
- package/src/executors/dev-doctor/dev-doctor.js.map +0 -1
- package/src/executors/dev-setup/dev-setup.js.map +0 -1
- package/src/executors/developer-context/developer-context.js.map +0 -1
- package/src/executors/fleet/fleet.js.map +0 -1
- package/src/executors/foundation-preflight/foundation-preflight.js.map +0 -1
- package/src/executors/foundation-profile-preflight/foundation-profile-preflight.js.map +0 -1
- package/src/executors/foundation-remove-preflight/foundation-remove-preflight.js.map +0 -1
- package/src/executors/github-bootstrap/github-bootstrap.js.map +0 -1
- package/src/executors/infrastructure-plan/infrastructure-plan.js.map +0 -1
- package/src/executors/refresh/refresh.js.map +0 -1
- package/src/executors/remove/remove.js.map +0 -1
- package/src/executors/secret-guardrails/secret-guardrails.js.map +0 -1
- package/src/executors/secret-metadata/secret-metadata.js.map +0 -1
- package/src/executors/sst-lifecycle/logging-preflight.js.map +0 -1
- package/src/executors/sst-lifecycle/run-sst-command.js.map +0 -1
- package/src/executors/sst-lifecycle/secret-preflight.js.map +0 -1
- package/src/executors/unlock/unlock.js.map +0 -1
- package/src/executors/work-markers/work-markers.js.map +0 -1
- package/src/foundation/discovery.js.map +0 -1
- package/src/foundation/index.js.map +0 -1
- package/src/foundation/local-database-contract.js.map +0 -1
- package/src/foundation/logging-preflight.js.map +0 -1
- package/src/foundation/logging.js.map +0 -1
- package/src/foundation/preflight.js.map +0 -1
- package/src/foundation/provision-database-bindings.js.map +0 -1
- package/src/foundation/provision-logical-database.js.map +0 -1
- package/src/foundation/requirements.js.map +0 -1
- package/src/foundation/router-origin-proof.js.map +0 -1
- package/src/foundation/stages.js.map +0 -1
- package/src/frontend-security/index.js.map +0 -1
- package/src/frontend-security/security-headers.js.map +0 -1
- package/src/generators/feature-registry.js.map +0 -1
- package/src/generators/function/function.js.map +0 -1
- package/src/generators/job/job.js.map +0 -1
- package/src/generators/logging-registry.js.map +0 -1
- package/src/generators/post-generation-install.js.map +0 -1
- package/src/generators/preset/generator.js.map +0 -1
- package/src/generators/preset/tool-versions.js.map +0 -1
- package/src/generators/preset/workspace-files-developer-agent.js.map +0 -1
- package/src/generators/preset/workspace-files-foundation-workload-roles.js.map +0 -1
- package/src/generators/preset/workspace-files-performance-cost.js.map +0 -1
- package/src/generators/preset/workspace-files-performance-load.js.map +0 -1
- package/src/generators/preset/workspace-files-workload-role-baseline.js.map +0 -1
- package/src/generators/preset/workspace-files.js.map +0 -1
- package/src/generators/repository-policy/repository-policy.js.map +0 -1
- package/src/generators/service/service.js.map +0 -1
- package/src/generators/slice/built-in-plan-api-contract-files.js.map +0 -1
- package/src/generators/slice/built-in-plan-api-files.js.map +0 -1
- package/src/generators/slice/built-in-plan-async-work-files.js.map +0 -1
- package/src/generators/slice/built-in-plan-authorization-files.js.map +0 -1
- package/src/generators/slice/built-in-plan-authorization-infrastructure-files.js.map +0 -1
- package/src/generators/slice/built-in-plan-data-deletion-files.js.map +0 -1
- package/src/generators/slice/built-in-plan-data-export-infrastructure-files.js.map +0 -1
- package/src/generators/slice/built-in-plan-data-files.js.map +0 -1
- package/src/generators/slice/built-in-plan-data-lifecycle-files.js.map +0 -1
- package/src/generators/slice/built-in-plan-data-lifecycle-runtime-files.js.map +0 -1
- package/src/generators/slice/built-in-plan-data-retention-job-files.js.map +0 -1
- package/src/generators/slice/built-in-plan-data-retention-launcher-files.js.map +0 -1
- package/src/generators/slice/built-in-plan-data-rights-files.js.map +0 -1
- package/src/generators/slice/built-in-plan-database-lifecycle-files.js.map +0 -1
- package/src/generators/slice/built-in-plan-database-retirement-rehearsal-files.js.map +0 -1
- package/src/generators/slice/built-in-plan-foundation-files.js.map +0 -1
- package/src/generators/slice/built-in-plan-frontend-files.js.map +0 -1
- package/src/generators/slice/built-in-plan-infrastructure-files.js.map +0 -1
- package/src/generators/slice/built-in-plan-infrastructure-safety-files.js.map +0 -1
- package/src/generators/slice/built-in-plan-metadata-files.js.map +0 -1
- package/src/generators/slice/built-in-plan-operations-files.js.map +0 -1
- package/src/generators/slice/built-in-plan-performance-files.js.map +0 -1
- package/src/generators/slice/built-in-plan-project-files.js.map +0 -1
- package/src/generators/slice/built-in-plan-release-files.js.map +0 -1
- package/src/generators/slice/built-in-plan-reliability-files.js.map +0 -1
- package/src/generators/slice/built-in-plan-secret-runtime-files.js.map +0 -1
- package/src/generators/slice/built-in-plan-shared.js.map +0 -1
- package/src/generators/slice/built-in-plan-testing-files.js.map +0 -1
- package/src/generators/slice/built-in-plan-verification-files.js.map +0 -1
- package/src/generators/slice/built-in-plan-web-files.js.map +0 -1
- package/src/generators/slice/built-in-plan-workload-role-files.js.map +0 -1
- package/src/generators/slice/built-in-plan.js.map +0 -1
- package/src/generators/slice/slice.js.map +0 -1
- package/src/generators/upgrade/upgrade.js.map +0 -1
- package/src/generators/workload/frozen-container.js.map +0 -1
- package/src/generators/workload/performance-registration.js.map +0 -1
- package/src/generators/workload/reliability-registration.js.map +0 -1
- package/src/generators/workload/service-performance-files.js.map +0 -1
- package/src/generators/workload/workload.js.map +0 -1
- package/src/git-policy/action-pins.js.map +0 -1
- package/src/git-policy/github-bootstrap.js.map +0 -1
- package/src/git-policy/index.js.map +0 -1
- package/src/git-policy/routing.js.map +0 -1
- package/src/index.js.map +0 -1
- package/src/infrastructure-change/convergence.js.map +0 -1
- package/src/infrastructure-change/drift.js.map +0 -1
- package/src/infrastructure-change/index.js.map +0 -1
- package/src/infrastructure-change/model.js.map +0 -1
- package/src/infrastructure-change/normalize.js.map +0 -1
- package/src/infrastructure-change/plan.js.map +0 -1
- package/src/infrastructure-change/risk.js.map +0 -1
- package/src/infrastructure-change/summary.js.map +0 -1
- package/src/local-dev/context-discovery.js.map +0 -1
- package/src/local-dev/contract-validation.js.map +0 -1
- package/src/local-dev/contracts.js.map +0 -1
- package/src/local-dev/control-contract.js.map +0 -1
- package/src/local-dev/dev-command-core.js.map +0 -1
- package/src/local-dev/effects.js.map +0 -1
- package/src/local-dev/environment-inspector.js.map +0 -1
- package/src/local-dev/environment-state.js.map +0 -1
- package/src/local-dev/errors.js.map +0 -1
- package/src/local-dev/fleet-client.js.map +0 -1
- package/src/local-dev/fleet-configuration.js.map +0 -1
- package/src/local-dev/fleet-inventory.js.map +0 -1
- package/src/local-dev/fleet-ipc.js.map +0 -1
- package/src/local-dev/fleet-launcher.js.map +0 -1
- package/src/local-dev/fleet-lock.js.map +0 -1
- package/src/local-dev/fleet-logs.js.map +0 -1
- package/src/local-dev/fleet-process.js.map +0 -1
- package/src/local-dev/fleet-runtime.js.map +0 -1
- package/src/local-dev/fleet-session.js.map +0 -1
- package/src/local-dev/fleet-slice-runner-daemon.js.map +0 -1
- package/src/local-dev/fleet-startup.js.map +0 -1
- package/src/local-dev/fleet-state.js.map +0 -1
- package/src/local-dev/fleet-supervisor-daemon.js.map +0 -1
- package/src/local-dev/fleet-supervisor.js.map +0 -1
- package/src/local-dev/gateway-daemon.js.map +0 -1
- package/src/local-dev/gateway.js.map +0 -1
- package/src/local-dev/identity.js.map +0 -1
- package/src/local-dev/index.js.map +0 -1
- package/src/local-dev/local-context.js.map +0 -1
- package/src/local-dev/nx-workspace.js.map +0 -1
- package/src/local-dev/personal-secret-ledger.js.map +0 -1
- package/src/local-dev/personal-stage.js.map +0 -1
- package/src/local-dev/portless.js.map +0 -1
- package/src/local-dev/ports.js.map +0 -1
- package/src/local-dev/private-state.js.map +0 -1
- package/src/local-dev/process-identity.js.map +0 -1
- package/src/local-dev/proxy.js.map +0 -1
- package/src/local-dev/runtime-paths.js.map +0 -1
- package/src/local-dev/secret-slice-claim.js.map +0 -1
- package/src/local-dev/slice-claim.js.map +0 -1
- package/src/local-dev/slice-runner.js.map +0 -1
- package/src/local-dev/tls.js.map +0 -1
- package/src/ownership/composition.js.map +0 -1
- package/src/ownership/foundation-record.js.map +0 -1
- package/src/ownership/hash.js.map +0 -1
- package/src/ownership/index.js.map +0 -1
- package/src/ownership/json-ownership.js.map +0 -1
- package/src/ownership/record.js.map +0 -1
- package/src/ownership/workspace-record.js.map +0 -1
- package/src/performance/cost-collection.js.map +0 -1
- package/src/performance/cost-controls.js.map +0 -1
- package/src/performance/evidence.js.map +0 -1
- package/src/performance/index.js.map +0 -1
- package/src/performance/load-safety.js.map +0 -1
- package/src/performance/model.js.map +0 -1
- package/src/performance/pr-artifact-budget.js.map +0 -1
- package/src/performance/runner.js.map +0 -1
- package/src/performance/scenario-endpoint.js.map +0 -1
- package/src/performance/scenario.js.map +0 -1
- package/src/performance/test-fixtures.d.ts +0 -7
- package/src/performance/test-fixtures.js +0 -169
- package/src/performance/test-fixtures.js.map +0 -1
- package/src/performance/unit-cost.js.map +0 -1
- package/src/release/index.js.map +0 -1
- package/src/release/lifecycle.js.map +0 -1
- package/src/release/manifest.js.map +0 -1
- package/src/release/rollout.js.map +0 -1
- package/src/release/source-authority.js.map +0 -1
- package/src/repository-policy/aurora-preflight.js.map +0 -1
- package/src/repository-policy/deployment-plan.js.map +0 -1
- package/src/repository-policy/foundation-profile.js.map +0 -1
- package/src/repository-policy/index.js.map +0 -1
- package/src/repository-policy/policy.js.map +0 -1
- package/src/secrets/adapters.js.map +0 -1
- package/src/secrets/aws-control-plane.js.map +0 -1
- package/src/secrets/declaration-verification.js.map +0 -1
- package/src/secrets/guardrails.js.map +0 -1
- package/src/secrets/index.js.map +0 -1
- package/src/secrets/metadata.js.map +0 -1
- package/src/secrets/model.js.map +0 -1
- package/src/secrets/operator.js.map +0 -1
- package/src/secrets/permissions.js.map +0 -1
- package/src/secrets/personal-command.js.map +0 -1
- package/src/secrets/personal-ledger.js.map +0 -1
- package/src/secrets/registry.js.map +0 -1
- package/src/secrets/verification.js.map +0 -1
- package/src/secrets/workload-access.js.map +0 -1
- package/src/supply-chain/action-pins.js.map +0 -1
- package/src/supply-chain/blueprint-trust-git.js.map +0 -1
- package/src/supply-chain/blueprint-trust-process.js.map +0 -1
- package/src/supply-chain/blueprint-trust.js.map +0 -1
- package/src/supply-chain/blueprint-verification-authority.js.map +0 -1
- package/src/supply-chain/blueprint-verification-execution.js.map +0 -1
- package/src/supply-chain/build-output.js.map +0 -1
- package/src/supply-chain/common.js.map +0 -1
- package/src/supply-chain/container-artifact-contract.js.map +0 -1
- package/src/supply-chain/container-release.js.map +0 -1
- package/src/supply-chain/ecr-applicability.js.map +0 -1
- package/src/supply-chain/ecr-scanning.js.map +0 -1
- package/src/supply-chain/ecs-deployed-image.js.map +0 -1
- package/src/supply-chain/errors.js.map +0 -1
- package/src/supply-chain/generated-blueprint-trust-command.js.map +0 -1
- package/src/supply-chain/generated-command.js.map +0 -1
- package/src/supply-chain/generated-container-release-command.js.map +0 -1
- package/src/supply-chain/generated-ecr-collector-command.js.map +0 -1
- package/src/supply-chain/generated-files.js.map +0 -1
- package/src/supply-chain/generated-scanner-command.js.map +0 -1
- package/src/supply-chain/index.js.map +0 -1
- package/src/supply-chain/inventory.js.map +0 -1
- package/src/supply-chain/license-expression.js.map +0 -1
- package/src/supply-chain/pnpm-toolchain-authority.js.map +0 -1
- package/src/supply-chain/policy.js.map +0 -1
- package/src/supply-chain/publication.js.map +0 -1
- package/src/supply-chain/sbom.js.map +0 -1
- package/src/supply-chain/scanner.js.map +0 -1
- package/src/supply-chain/vendored-source.js.map +0 -1
- package/src/testing-evidence/fixture-scope.js.map +0 -1
- package/src/testing-evidence/index.js.map +0 -1
- package/src/testing-evidence/quarantine.js.map +0 -1
- package/src/testing-evidence/result.js.map +0 -1
- package/src/testing-evidence/runner-adapter.js.map +0 -1
- package/src/testing-evidence/sensitive-artifacts.js.map +0 -1
- package/src/validation.js.map +0 -1
- package/src/work-markers/index.js.map +0 -1
- package/src/work-markers/work-markers.js.map +0 -1
- package/src/workload-roles/account-baseline.js.map +0 -1
- package/src/workload-roles/authority.js.map +0 -1
- package/src/workload-roles/aws-adapter.js.map +0 -1
- package/src/workload-roles/aws-internal-handler.js.map +0 -1
- package/src/workload-roles/aws-s3-state.js.map +0 -1
- package/src/workload-roles/aws-sdk-control-plane.js.map +0 -1
- package/src/workload-roles/boundary.js.map +0 -1
- package/src/workload-roles/convergence.js.map +0 -1
- package/src/workload-roles/effective-policy.js.map +0 -1
- package/src/workload-roles/handler.js.map +0 -1
- package/src/workload-roles/history.js.map +0 -1
- package/src/workload-roles/index.js.map +0 -1
- package/src/workload-roles/injection.js.map +0 -1
- package/src/workload-roles/manifest.js.map +0 -1
- package/src/workload-roles/provisioner.js.map +0 -1
- package/src/workload-roles/registration.js.map +0 -1
- package/src/workload-roles/stage-boundary.js.map +0 -1
- package/src/workload-roles/standard-slice.js.map +0 -1
|
@@ -0,0 +1,1404 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.localWorkingTreeDigest = localWorkingTreeDigest;
|
|
4
|
+
exports.deployedSourceCommit = deployedSourceCommit;
|
|
5
|
+
exports.localDeploymentProjectOrder = localDeploymentProjectOrder;
|
|
6
|
+
exports.runLocalDeploy = runLocalDeploy;
|
|
7
|
+
const node_crypto_1 = require("node:crypto");
|
|
8
|
+
const node_child_process_1 = require("node:child_process");
|
|
9
|
+
const node_fs_1 = require("node:fs");
|
|
10
|
+
const node_path_1 = require("node:path");
|
|
11
|
+
const devkit_1 = require("@nx/devkit");
|
|
12
|
+
const client_sts_1 = require("@aws-sdk/client-sts");
|
|
13
|
+
const index_js_1 = require("../../aws-authority/index.js");
|
|
14
|
+
const capacity_migration_js_1 = require("../../repository-policy/capacity-migration.js");
|
|
15
|
+
const affected_lifecycle_js_1 = require("../../workspace-deployment/affected-lifecycle.js");
|
|
16
|
+
const child_environment_js_1 = require("../../aws/child-environment.js");
|
|
17
|
+
const identity_js_1 = require("../../aws/identity.js");
|
|
18
|
+
const index_js_2 = require("../../repository-policy/index.js");
|
|
19
|
+
const production_database_safeguard_js_1 = require("../foundation-profile-preflight/production-database-safeguard.js");
|
|
20
|
+
const private_state_js_1 = require("../../local-dev/private-state.js");
|
|
21
|
+
const federated_credential_transport_js_1 = require("./federated-credential-transport.js");
|
|
22
|
+
const local_approval_js_1 = require("./local-approval.js");
|
|
23
|
+
const container_release_js_1 = require("../../supply-chain/container-release.js");
|
|
24
|
+
const run_sst_command_js_1 = require("../sst-lifecycle/run-sst-command.js");
|
|
25
|
+
const index_js_3 = require("../../workspace-deployment/index.js");
|
|
26
|
+
const private_smoke_access_js_1 = require("../../foundation/private-smoke-access.js");
|
|
27
|
+
const local_private_smoke_access_js_1 = require("../../foundation/local-private-smoke-access.js");
|
|
28
|
+
const capability_plan_js_1 = require("../../foundation/capability-plan.js");
|
|
29
|
+
const sst_environment_source_js_1 = require("../sst-lifecycle/sst-environment-source.js");
|
|
30
|
+
const SHA = /^[a-f0-9]{40,64}$/u;
|
|
31
|
+
const ROLE = /^arn:(aws|aws-us-gov|aws-cn):iam::\d{12}:role\/[A-Za-z0-9+=,.@_/-]{1,512}$/u;
|
|
32
|
+
const MAX_LOCAL_RELEASE_CANDIDATE_FILE_BYTES = 64 * 1024;
|
|
33
|
+
const MAX_LOCAL_RELEASE_ARTIFACTS_BYTES = 64 * 1024 * 1024;
|
|
34
|
+
const MAX_LOCAL_RELEASE_CANDIDATE_FILES = 32;
|
|
35
|
+
const MAX_LOCAL_RELEASE_CANDIDATE_BYTES = MAX_LOCAL_RELEASE_ARTIFACTS_BYTES +
|
|
36
|
+
(MAX_LOCAL_RELEASE_CANDIDATE_FILES - 1) *
|
|
37
|
+
MAX_LOCAL_RELEASE_CANDIDATE_FILE_BYTES;
|
|
38
|
+
function partitionForRegion(region) {
|
|
39
|
+
if (region.startsWith('cn-'))
|
|
40
|
+
return 'aws-cn';
|
|
41
|
+
if (region.startsWith('us-gov-'))
|
|
42
|
+
return 'aws-us-gov';
|
|
43
|
+
return 'aws';
|
|
44
|
+
}
|
|
45
|
+
function git(root, args, run) {
|
|
46
|
+
const result = run('git', args, {
|
|
47
|
+
cwd: root,
|
|
48
|
+
encoding: 'utf8',
|
|
49
|
+
env: process.env,
|
|
50
|
+
maxBuffer: 32 * 1024 * 1024,
|
|
51
|
+
shell: false,
|
|
52
|
+
});
|
|
53
|
+
if (result.status !== 0) {
|
|
54
|
+
throw new Error(`Local deployment Git preflight failed: ${String(result.stderr).trim()}`);
|
|
55
|
+
}
|
|
56
|
+
return String(result.stdout);
|
|
57
|
+
}
|
|
58
|
+
function confinedWorkspacePath(root, candidate) {
|
|
59
|
+
if (!candidate || (0, node_path_1.isAbsolute)(candidate) || candidate.includes('\0')) {
|
|
60
|
+
throw new Error('Working-tree inventory contains an invalid path.');
|
|
61
|
+
}
|
|
62
|
+
const absolute = (0, node_path_1.join)(root, candidate);
|
|
63
|
+
const confined = (0, node_path_1.relative)(root, absolute);
|
|
64
|
+
if (confined === '..' || confined.startsWith('../') || (0, node_path_1.isAbsolute)(confined)) {
|
|
65
|
+
throw new Error('Working-tree inventory escapes the workspace.');
|
|
66
|
+
}
|
|
67
|
+
return absolute;
|
|
68
|
+
}
|
|
69
|
+
/** Bind a development deployment to the exact tracked diff and untracked
|
|
70
|
+
* source bytes without requiring a commit. Ignored caches and build output are
|
|
71
|
+
* intentionally outside this identity. */
|
|
72
|
+
function localWorkingTreeDigest(root, run = node_child_process_1.spawnSync) {
|
|
73
|
+
const commit = git(root, ['rev-parse', 'HEAD'], run).trim();
|
|
74
|
+
if (!SHA.test(commit)) {
|
|
75
|
+
throw new Error('Local deployment could not resolve one exact Git HEAD.');
|
|
76
|
+
}
|
|
77
|
+
const status = git(root, ['status', '--porcelain=v1', '--untracked-files=all'], run);
|
|
78
|
+
const trackedDiff = git(root, ['diff', '--binary', 'HEAD'], run);
|
|
79
|
+
const untracked = git(root, ['ls-files', '--others', '--exclude-standard', '-z'], run)
|
|
80
|
+
.split('\0')
|
|
81
|
+
.filter(Boolean)
|
|
82
|
+
.sort();
|
|
83
|
+
const hash = (0, node_crypto_1.createHash)('sha256');
|
|
84
|
+
hash.update('ebk-working-tree-v1\0');
|
|
85
|
+
hash.update(commit);
|
|
86
|
+
hash.update('\0');
|
|
87
|
+
hash.update(status);
|
|
88
|
+
hash.update('\0');
|
|
89
|
+
hash.update(trackedDiff);
|
|
90
|
+
hash.update('\0');
|
|
91
|
+
for (const path of untracked) {
|
|
92
|
+
const absolute = confinedWorkspacePath(root, path);
|
|
93
|
+
const stat = (0, node_fs_1.lstatSync)(absolute);
|
|
94
|
+
hash.update(path);
|
|
95
|
+
hash.update('\0');
|
|
96
|
+
if (stat.isSymbolicLink()) {
|
|
97
|
+
hash.update('symlink\0');
|
|
98
|
+
hash.update((0, node_fs_1.readlinkSync)(absolute));
|
|
99
|
+
}
|
|
100
|
+
else if (stat.isFile()) {
|
|
101
|
+
hash.update('file\0');
|
|
102
|
+
hash.update((0, node_fs_1.readFileSync)(absolute));
|
|
103
|
+
}
|
|
104
|
+
else {
|
|
105
|
+
throw new Error(`Untracked deployment source ${path} is not a regular file or symbolic link.`);
|
|
106
|
+
}
|
|
107
|
+
hash.update('\0');
|
|
108
|
+
}
|
|
109
|
+
return { clean: status === '', commit, digest: hash.digest('hex') };
|
|
110
|
+
}
|
|
111
|
+
function assertDeploymentSourceUnchanged(root, expected, run) {
|
|
112
|
+
const current = localWorkingTreeDigest(root, run);
|
|
113
|
+
if (current.clean !== expected.clean ||
|
|
114
|
+
current.commit !== expected.commit ||
|
|
115
|
+
current.digest !== expected.workingTreeDigest) {
|
|
116
|
+
throw new Error('Deployment source changed after lifecycle authority was established; downstream execution is blocked.');
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
function projectDescriptors(context) {
|
|
120
|
+
return Object.entries(context.projectsConfigurations?.projects ?? {}).map(([name, configuration]) => ({
|
|
121
|
+
name,
|
|
122
|
+
root: configuration.root,
|
|
123
|
+
tags: configuration.tags ?? [],
|
|
124
|
+
targets: configuration.targets ?? {},
|
|
125
|
+
}));
|
|
126
|
+
}
|
|
127
|
+
function supportsTarget(project, target) {
|
|
128
|
+
return Object.prototype.hasOwnProperty.call(project.targets, target);
|
|
129
|
+
}
|
|
130
|
+
const LOCAL_CONTAINER_TARGETS = Object.freeze([
|
|
131
|
+
'release-candidate',
|
|
132
|
+
'container-release-amd64',
|
|
133
|
+
'container-release-arm64',
|
|
134
|
+
'container-release-assemble',
|
|
135
|
+
]);
|
|
136
|
+
function requiresLocalContainerPreparation(profile, stage) {
|
|
137
|
+
return ((profile === 'starter' && stage === 'production') ||
|
|
138
|
+
(profile === 'production-isolated' && stage === 'staging'));
|
|
139
|
+
}
|
|
140
|
+
function confinedEvidenceSegments(root, candidate) {
|
|
141
|
+
const confined = (0, node_path_1.relative)(root, candidate);
|
|
142
|
+
if (confined === '' ||
|
|
143
|
+
confined === '..' ||
|
|
144
|
+
confined.startsWith(`..${node_path_1.sep}`) ||
|
|
145
|
+
(0, node_path_1.isAbsolute)(confined)) {
|
|
146
|
+
throw new Error('Local container evidence path escapes the workspace.');
|
|
147
|
+
}
|
|
148
|
+
const segments = confined.split(node_path_1.sep);
|
|
149
|
+
if (segments.some((segment) => segment === '' ||
|
|
150
|
+
segment === '.' ||
|
|
151
|
+
segment === '..' ||
|
|
152
|
+
segment.includes('\0'))) {
|
|
153
|
+
throw new Error('Local container evidence path is invalid.');
|
|
154
|
+
}
|
|
155
|
+
return segments;
|
|
156
|
+
}
|
|
157
|
+
function assertSafeEvidenceTree(path) {
|
|
158
|
+
let entries = 0;
|
|
159
|
+
const visit = (directory) => {
|
|
160
|
+
for (const entry of (0, node_fs_1.readdirSync)(directory, { withFileTypes: true })) {
|
|
161
|
+
entries += 1;
|
|
162
|
+
if (entries > 4096) {
|
|
163
|
+
throw new Error('Local container evidence tree is unexpectedly large.');
|
|
164
|
+
}
|
|
165
|
+
const child = (0, node_path_1.join)(directory, entry.name);
|
|
166
|
+
const identity = (0, node_fs_1.lstatSync)(child);
|
|
167
|
+
if (identity.isSymbolicLink()) {
|
|
168
|
+
throw new Error('Local container evidence cleanup refuses symbolic links.');
|
|
169
|
+
}
|
|
170
|
+
if (identity.isDirectory()) {
|
|
171
|
+
visit(child);
|
|
172
|
+
}
|
|
173
|
+
else if (!identity.isFile()) {
|
|
174
|
+
throw new Error('Local container evidence cleanup accepts only regular files and directories.');
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
};
|
|
178
|
+
visit(path);
|
|
179
|
+
}
|
|
180
|
+
function removeExactLocalEvidenceDirectory(root, path) {
|
|
181
|
+
const segments = confinedEvidenceSegments(root, path);
|
|
182
|
+
let current = root;
|
|
183
|
+
const rootIdentity = (0, node_fs_1.lstatSync)(current);
|
|
184
|
+
if (!rootIdentity.isDirectory() || rootIdentity.isSymbolicLink()) {
|
|
185
|
+
throw new Error('Local deployment workspace root is absent or unsafe.');
|
|
186
|
+
}
|
|
187
|
+
for (const segment of segments) {
|
|
188
|
+
current = (0, node_path_1.join)(current, segment);
|
|
189
|
+
if (!(0, node_fs_1.existsSync)(current))
|
|
190
|
+
return;
|
|
191
|
+
const identity = (0, node_fs_1.lstatSync)(current);
|
|
192
|
+
if (!identity.isDirectory() || identity.isSymbolicLink()) {
|
|
193
|
+
throw new Error('Local container evidence cleanup encountered an unsafe path.');
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
assertSafeEvidenceTree(current);
|
|
197
|
+
(0, node_fs_1.rmSync)(current, { recursive: true });
|
|
198
|
+
}
|
|
199
|
+
function ensurePrivateEvidenceDirectory(root, path) {
|
|
200
|
+
const segments = confinedEvidenceSegments(root, path);
|
|
201
|
+
let current = root;
|
|
202
|
+
for (const segment of segments) {
|
|
203
|
+
current = (0, node_path_1.join)(current, segment);
|
|
204
|
+
if ((0, node_fs_1.existsSync)(current)) {
|
|
205
|
+
const identity = (0, node_fs_1.lstatSync)(current);
|
|
206
|
+
if (!identity.isDirectory() || identity.isSymbolicLink()) {
|
|
207
|
+
throw new Error('Local container evidence directory encountered an unsafe path.');
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
(0, private_state_js_1.ensurePrivateDirectory)(current);
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
function resetLocalContainerWorkingEvidence(input) {
|
|
214
|
+
const projectRoot = confinedWorkspacePath(input.root, input.project.root);
|
|
215
|
+
for (const path of [
|
|
216
|
+
(0, node_path_1.join)(projectRoot, '.ebk', 'evidence', 'release-candidate'),
|
|
217
|
+
(0, node_path_1.join)(input.root, '.ebk', 'evidence', 'release-candidate', 'packages', input.project.name),
|
|
218
|
+
(0, node_path_1.join)(input.root, '.ebk', 'evidence', 'container-release', 'partials', input.stage, input.project.name),
|
|
219
|
+
(0, node_path_1.join)(input.root, '.ebk', 'evidence', 'container-release', input.stage, 'packages', input.project.name),
|
|
220
|
+
]) {
|
|
221
|
+
removeExactLocalEvidenceDirectory(input.root, path);
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
/** Materialize the same bounded workspace-level candidate layout restored by
|
|
225
|
+
* protected GitHub deployment. The generated container helper and SST image
|
|
226
|
+
* resolver both consume this exact path. */
|
|
227
|
+
function materializeLocalReleaseCandidate(input) {
|
|
228
|
+
if (!/^[A-Za-z0-9][A-Za-z0-9._-]{0,127}$/u.test(input.project.name)) {
|
|
229
|
+
throw new Error(`Local container release project ${input.project.name} has an unsafe evidence identity.`);
|
|
230
|
+
}
|
|
231
|
+
const projectRoot = confinedWorkspacePath(input.root, input.project.root);
|
|
232
|
+
const source = (0, node_path_1.join)(projectRoot, '.ebk', 'evidence', 'release-candidate');
|
|
233
|
+
const sourceIdentity = (0, node_fs_1.lstatSync)(source);
|
|
234
|
+
if (!sourceIdentity.isDirectory() || sourceIdentity.isSymbolicLink()) {
|
|
235
|
+
throw new Error(`Local release candidate for ${input.project.name} is absent or unsafe.`);
|
|
236
|
+
}
|
|
237
|
+
const entries = (0, node_fs_1.readdirSync)(source, { withFileTypes: true }).sort((left, right) => left.name < right.name ? -1 : left.name > right.name ? 1 : 0);
|
|
238
|
+
if (entries.length === 0 ||
|
|
239
|
+
entries.length > MAX_LOCAL_RELEASE_CANDIDATE_FILES ||
|
|
240
|
+
entries.some((entry) => !entry.isFile() ||
|
|
241
|
+
entry.isSymbolicLink() ||
|
|
242
|
+
!/^[A-Za-z0-9][A-Za-z0-9._-]{0,127}\.json$/u.test(entry.name))) {
|
|
243
|
+
throw new Error(`Local release candidate for ${input.project.name} has an invalid file inventory.`);
|
|
244
|
+
}
|
|
245
|
+
let totalBytes = 0;
|
|
246
|
+
const files = entries.map(({ name }) => {
|
|
247
|
+
const path = (0, node_path_1.join)(source, name);
|
|
248
|
+
const identity = (0, node_fs_1.lstatSync)(path);
|
|
249
|
+
const maximumBytes = name === 'release-artifacts.json'
|
|
250
|
+
? MAX_LOCAL_RELEASE_ARTIFACTS_BYTES
|
|
251
|
+
: MAX_LOCAL_RELEASE_CANDIDATE_FILE_BYTES;
|
|
252
|
+
if (!identity.isFile() ||
|
|
253
|
+
identity.isSymbolicLink() ||
|
|
254
|
+
identity.size <= 0 ||
|
|
255
|
+
identity.size > maximumBytes) {
|
|
256
|
+
throw new Error(`Local release candidate file ${input.project.name}/${name} is absent or unsafe.`);
|
|
257
|
+
}
|
|
258
|
+
totalBytes += identity.size;
|
|
259
|
+
return { name, path };
|
|
260
|
+
});
|
|
261
|
+
if (totalBytes > MAX_LOCAL_RELEASE_CANDIDATE_BYTES) {
|
|
262
|
+
throw new Error(`Local release candidate for ${input.project.name} exceeds the bounded inventory size.`);
|
|
263
|
+
}
|
|
264
|
+
const candidateFiles = files.map(({ name, path }) => ({
|
|
265
|
+
contents: (0, node_fs_1.readFileSync)(path),
|
|
266
|
+
name,
|
|
267
|
+
}));
|
|
268
|
+
const candidateFile = candidateFiles.find(({ name }) => name === 'candidate.json');
|
|
269
|
+
let candidate;
|
|
270
|
+
try {
|
|
271
|
+
candidate = JSON.parse(candidateFile?.contents.toString('utf8') ?? '');
|
|
272
|
+
}
|
|
273
|
+
catch {
|
|
274
|
+
throw new Error(`Local release candidate for ${input.project.name} is invalid JSON.`);
|
|
275
|
+
}
|
|
276
|
+
if (candidate.kind !== 'ebk-release-candidate' ||
|
|
277
|
+
candidate.schemaVersion !== 1 ||
|
|
278
|
+
candidate.slice !== input.project.name ||
|
|
279
|
+
candidate.sourceCommit !== input.sourceCommit) {
|
|
280
|
+
throw new Error(`Local release candidate for ${input.project.name} differs from the exact deployment source.`);
|
|
281
|
+
}
|
|
282
|
+
const destination = (0, node_path_1.join)(input.root, '.ebk', 'evidence', 'release-candidate', 'packages', input.project.name);
|
|
283
|
+
removeExactLocalEvidenceDirectory(input.root, destination);
|
|
284
|
+
ensurePrivateEvidenceDirectory(input.root, destination);
|
|
285
|
+
for (const { contents, name } of candidateFiles) {
|
|
286
|
+
if (name === 'release-artifacts.json') {
|
|
287
|
+
(0, private_state_js_1.atomicWritePrivateFileWithMaximumBytes)((0, node_path_1.join)(destination, name), contents, MAX_LOCAL_RELEASE_ARTIFACTS_BYTES);
|
|
288
|
+
}
|
|
289
|
+
else {
|
|
290
|
+
(0, private_state_js_1.atomicWritePrivateFile)((0, node_path_1.join)(destination, name), contents);
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
function attestLocalContainerBinding(input) {
|
|
295
|
+
const path = (0, node_path_1.join)(input.root, '.ebk', 'evidence', 'container-release', input.stage, 'packages', input.project.name, 'binding.json');
|
|
296
|
+
const identity = (0, node_fs_1.lstatSync)(path);
|
|
297
|
+
if (!identity.isFile() ||
|
|
298
|
+
identity.isSymbolicLink() ||
|
|
299
|
+
identity.size <= 0 ||
|
|
300
|
+
identity.size > 64 * 1024 * 1024) {
|
|
301
|
+
throw new Error(`Local protected container binding for ${input.project.name} is absent or unsafe.`);
|
|
302
|
+
}
|
|
303
|
+
const binding = (0, container_release_js_1.validateContainerReleaseBinding)(JSON.parse((0, node_fs_1.readFileSync)(path, 'utf8')));
|
|
304
|
+
if (binding.accountId !== input.account ||
|
|
305
|
+
binding.region !== input.region ||
|
|
306
|
+
binding.slice !== input.project.name ||
|
|
307
|
+
binding.sourceCommit !== input.sourceCommit ||
|
|
308
|
+
binding.stage !== input.stage) {
|
|
309
|
+
throw new Error(`Local protected container binding for ${input.project.name} differs from the exact deployment authority.`);
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
/** Read only the bounded public outputs SST writes after a successful native
|
|
313
|
+
* deploy. This is post-operation smoke input, never preview or mutation
|
|
314
|
+
* authority. Stage and project identity prevent a stale output file from
|
|
315
|
+
* selecting another deployment. */
|
|
316
|
+
function readDeployedSmokeTarget(workspaceRoot, project, stage) {
|
|
317
|
+
const projectRoot = confinedWorkspacePath(workspaceRoot, project.root);
|
|
318
|
+
const outputPath = (0, node_path_1.join)(projectRoot, '.sst', 'outputs.json');
|
|
319
|
+
const identity = (0, node_fs_1.lstatSync)(outputPath);
|
|
320
|
+
if (!identity.isFile() ||
|
|
321
|
+
identity.isSymbolicLink() ||
|
|
322
|
+
identity.size < 2 ||
|
|
323
|
+
identity.size > 64 * 1024) {
|
|
324
|
+
throw new Error(`Native SST outputs for ${project.name} are absent or unsafe.`);
|
|
325
|
+
}
|
|
326
|
+
const value = JSON.parse((0, node_fs_1.readFileSync)(outputPath, 'utf8'));
|
|
327
|
+
let api;
|
|
328
|
+
let web;
|
|
329
|
+
try {
|
|
330
|
+
api = new URL(String(value.apiUrl ?? ''));
|
|
331
|
+
web = new URL(String(value.webUrl ?? ''));
|
|
332
|
+
}
|
|
333
|
+
catch {
|
|
334
|
+
throw new Error(`Native SST outputs for ${project.name} contain invalid smoke URLs.`);
|
|
335
|
+
}
|
|
336
|
+
const credentialFreeHttps = (url) => url.protocol === 'https:' &&
|
|
337
|
+
!url.username &&
|
|
338
|
+
!url.password &&
|
|
339
|
+
!url.search &&
|
|
340
|
+
!url.hash;
|
|
341
|
+
if (value.name !== project.name ||
|
|
342
|
+
value.stage !== stage ||
|
|
343
|
+
!credentialFreeHttps(api) ||
|
|
344
|
+
!credentialFreeHttps(web) ||
|
|
345
|
+
api.pathname !== '/' ||
|
|
346
|
+
web.pathname.replace(/\/$/u, '') !== `/${project.name}` ||
|
|
347
|
+
!/^[a-z0-9]{1,128}$/u.test(String(value.authClientId ?? '')) ||
|
|
348
|
+
!/^[A-Za-z0-9_-]{1,128}_[A-Za-z0-9]{1,128}$/u.test(String(value.authUserPoolId ?? ''))) {
|
|
349
|
+
throw new Error(`Native SST outputs for ${project.name} do not match the deployed stage and smoke target.`);
|
|
350
|
+
}
|
|
351
|
+
return {
|
|
352
|
+
apiUrl: api.href,
|
|
353
|
+
clientId: String(value.authClientId),
|
|
354
|
+
userPoolId: String(value.authUserPoolId),
|
|
355
|
+
webUrl: web.href,
|
|
356
|
+
};
|
|
357
|
+
}
|
|
358
|
+
const GIT_SHA = /^[a-f0-9]{40,64}$/u;
|
|
359
|
+
// A trunk promotion deploys the immutable artifacts built from the release
|
|
360
|
+
// source (EBK_RELEASE_SOURCE_COMMIT, the staging-built head) while it runs
|
|
361
|
+
// under the promotion commit. The deployed smoke must expect the build
|
|
362
|
+
// identity the deployed Functions report, not the commit the workflow runs
|
|
363
|
+
// under (EBK-INT-2026-086); receipts keep binding the promotion commit.
|
|
364
|
+
function deployedSourceCommit(sourceCommit, environment = process.env) {
|
|
365
|
+
const release = environment.EBK_RELEASE_SOURCE_COMMIT ?? '';
|
|
366
|
+
return GIT_SHA.test(release) ? release : sourceCommit;
|
|
367
|
+
}
|
|
368
|
+
const RUN_NUMBER = /^[1-9][0-9]*$/u;
|
|
369
|
+
/** Resolve which projects this deployment must touch. Anything that cannot be
|
|
370
|
+
* proven unchanged since the baseline receipt deploys; governing changes deploy
|
|
371
|
+
* everything. Local runs default to the full lifecycle. */
|
|
372
|
+
function baselineRunIdentity(value) {
|
|
373
|
+
if (typeof value === 'number') {
|
|
374
|
+
return Number.isSafeInteger(value) && value >= 1 ? String(value) : '';
|
|
375
|
+
}
|
|
376
|
+
return value?.trim() ?? '';
|
|
377
|
+
}
|
|
378
|
+
function resolveLifecycleScope(input) {
|
|
379
|
+
const requestedMode = input.options.lifecycleScope === 'affected' ? 'affected' : 'full';
|
|
380
|
+
const receiptPath = input.options.baselineReceipt?.trim() ?? '';
|
|
381
|
+
// Nx parses digits-only arguments as numbers; the workflow passes the run
|
|
382
|
+
// id and attempt as digits (EBK-INT-2026-084).
|
|
383
|
+
const runId = baselineRunIdentity(input.options.baselineRunId);
|
|
384
|
+
const runAttempt = baselineRunIdentity(input.options.baselineRunAttempt);
|
|
385
|
+
const withoutBaseline = (reason) => ({
|
|
386
|
+
baseline: null,
|
|
387
|
+
mode: 'full',
|
|
388
|
+
projects: Object.fromEntries(input.orderedProjects.map((project) => [project, 'deploy'])),
|
|
389
|
+
reason,
|
|
390
|
+
});
|
|
391
|
+
if (requestedMode === 'full')
|
|
392
|
+
return withoutBaseline('requested-full');
|
|
393
|
+
if (receiptPath === '')
|
|
394
|
+
return withoutBaseline('no-baseline');
|
|
395
|
+
if ((0, node_path_1.isAbsolute)(receiptPath) === false && receiptPath.includes('..')) {
|
|
396
|
+
return withoutBaseline('baseline-path-rejected');
|
|
397
|
+
}
|
|
398
|
+
if (!RUN_NUMBER.test(runId) || !RUN_NUMBER.test(runAttempt)) {
|
|
399
|
+
return withoutBaseline('baseline-run-rejected');
|
|
400
|
+
}
|
|
401
|
+
let receipt;
|
|
402
|
+
try {
|
|
403
|
+
const parsed = JSON.parse((0, node_fs_1.readFileSync)(receiptPath, 'utf8'));
|
|
404
|
+
receipt = validateBaselineReceipt(parsed);
|
|
405
|
+
}
|
|
406
|
+
catch (error) {
|
|
407
|
+
devkit_1.logger.warn(`[lifecycle-scope] baseline receipt rejected: ${error instanceof Error ? error.message : String(error)}`);
|
|
408
|
+
return withoutBaseline('baseline-receipt-rejected');
|
|
409
|
+
}
|
|
410
|
+
const baselineCommit = receipt.source.commit;
|
|
411
|
+
const git = (args) => input.run('git', args, {
|
|
412
|
+
cwd: input.context.root,
|
|
413
|
+
encoding: 'utf8',
|
|
414
|
+
maxBuffer: 16 * 1024 * 1024,
|
|
415
|
+
});
|
|
416
|
+
const ancestry = git([
|
|
417
|
+
'merge-base',
|
|
418
|
+
'--is-ancestor',
|
|
419
|
+
baselineCommit,
|
|
420
|
+
input.source.commit,
|
|
421
|
+
]);
|
|
422
|
+
if (ancestry.status !== 0)
|
|
423
|
+
return withoutBaseline('baseline-not-ancestor');
|
|
424
|
+
const governing = git([
|
|
425
|
+
'diff',
|
|
426
|
+
'--name-only',
|
|
427
|
+
`${baselineCommit}..${input.source.commit}`,
|
|
428
|
+
'--',
|
|
429
|
+
...affected_lifecycle_js_1.LIFECYCLE_GOVERNING_FILES,
|
|
430
|
+
]);
|
|
431
|
+
if (governing.status !== 0)
|
|
432
|
+
return withoutBaseline('governing-diff-unavailable');
|
|
433
|
+
const changedGoverningFiles = String(governing.stdout)
|
|
434
|
+
.split('\n')
|
|
435
|
+
.map((line) => line.trim())
|
|
436
|
+
.filter((line) => line.length > 0);
|
|
437
|
+
const affected = input.run(process.execPath, [
|
|
438
|
+
(0, node_path_1.join)(input.context.root, 'node_modules', 'nx', 'dist', 'bin', 'nx.js'),
|
|
439
|
+
'show',
|
|
440
|
+
'projects',
|
|
441
|
+
'--affected',
|
|
442
|
+
`--base=${baselineCommit}`,
|
|
443
|
+
`--head=${input.source.commit}`,
|
|
444
|
+
'--json',
|
|
445
|
+
], {
|
|
446
|
+
cwd: input.context.root,
|
|
447
|
+
encoding: 'utf8',
|
|
448
|
+
env: { ...process.env, NX_DAEMON: 'false' },
|
|
449
|
+
maxBuffer: 16 * 1024 * 1024,
|
|
450
|
+
});
|
|
451
|
+
let affectedProjects = null;
|
|
452
|
+
if (affected.status === 0) {
|
|
453
|
+
try {
|
|
454
|
+
const parsed = JSON.parse(String(affected.stdout));
|
|
455
|
+
affectedProjects = Array.isArray(parsed)
|
|
456
|
+
? parsed.filter((entry) => typeof entry === 'string')
|
|
457
|
+
: null;
|
|
458
|
+
}
|
|
459
|
+
catch {
|
|
460
|
+
affectedProjects = null;
|
|
461
|
+
}
|
|
462
|
+
}
|
|
463
|
+
return (0, affected_lifecycle_js_1.selectLifecycleScope)({
|
|
464
|
+
affectedProjects,
|
|
465
|
+
baseline: { commit: baselineCommit, receipt, runAttempt, runId },
|
|
466
|
+
changedGoverningFiles,
|
|
467
|
+
frameworkVersion: input.frameworkVersion,
|
|
468
|
+
orderedProjects: input.orderedProjects,
|
|
469
|
+
requestedMode,
|
|
470
|
+
stage: input.options.stage,
|
|
471
|
+
});
|
|
472
|
+
}
|
|
473
|
+
function validateBaselineReceipt(value) {
|
|
474
|
+
const record = value;
|
|
475
|
+
if (!record ||
|
|
476
|
+
typeof record !== 'object' ||
|
|
477
|
+
Object.prototype.hasOwnProperty.call(record, 'selectedSlices') ||
|
|
478
|
+
record.kind !== 'ebk-deployment-receipt' ||
|
|
479
|
+
record.schemaVersion !== 1 ||
|
|
480
|
+
typeof record.outcome !== 'string' ||
|
|
481
|
+
typeof record.stage !== 'string' ||
|
|
482
|
+
typeof record.frameworkVersion !== 'string' ||
|
|
483
|
+
!record.source ||
|
|
484
|
+
typeof record.source !== 'object' ||
|
|
485
|
+
!GIT_SHA.test(String(record.source.commit ?? '')) ||
|
|
486
|
+
!Array.isArray(record.children) ||
|
|
487
|
+
record.children.some((child) => !child ||
|
|
488
|
+
typeof child !== 'object' ||
|
|
489
|
+
typeof child.project !== 'string' ||
|
|
490
|
+
typeof child.target !== 'string' ||
|
|
491
|
+
typeof child.outcome !== 'string')) {
|
|
492
|
+
throw new Error('Baseline deployment receipt is malformed.');
|
|
493
|
+
}
|
|
494
|
+
return {
|
|
495
|
+
children: record.children,
|
|
496
|
+
frameworkVersion: record.frameworkVersion,
|
|
497
|
+
outcome: record.outcome,
|
|
498
|
+
source: { commit: String(record.source.commit) },
|
|
499
|
+
stage: record.stage,
|
|
500
|
+
};
|
|
501
|
+
}
|
|
502
|
+
/** Determine the one native deployment order. Foundation is always first and
|
|
503
|
+
* production Slice admission remains a committed policy decision. */
|
|
504
|
+
function localDeploymentProjectOrder(policy, context, stage, requestedSlices) {
|
|
505
|
+
if (!(0, index_js_2.isActiveDeploymentStage)(policy.deploymentProfile, stage)) {
|
|
506
|
+
throw new Error(`Deployment stage ${stage} is inactive for the ${policy.deploymentProfile} deployment profile.`);
|
|
507
|
+
}
|
|
508
|
+
const projects = projectDescriptors(context);
|
|
509
|
+
const foundations = projects.filter((project) => project.tags.includes('scope:foundation') &&
|
|
510
|
+
supportsTarget(project, 'deploy'));
|
|
511
|
+
if (foundations.length !== 1) {
|
|
512
|
+
throw new Error(`Local deployment requires exactly one deployable Foundation; found ${foundations.length}.`);
|
|
513
|
+
}
|
|
514
|
+
const slices = projects
|
|
515
|
+
.filter((project) => project.tags.includes('type:slice') &&
|
|
516
|
+
supportsTarget(project, 'deploy'))
|
|
517
|
+
.sort((left, right) => left.name < right.name ? -1 : left.name > right.name ? 1 : 0);
|
|
518
|
+
if (stage === 'production') {
|
|
519
|
+
const missing = slices
|
|
520
|
+
.filter(({ name }) => policy.slices[name] === undefined)
|
|
521
|
+
.map(({ name }) => name);
|
|
522
|
+
if (missing.length > 0) {
|
|
523
|
+
throw new Error(`Registered Product Slices lack an explicit production policy: ${missing.join(', ')}.`);
|
|
524
|
+
}
|
|
525
|
+
}
|
|
526
|
+
const eligibleSlices = stage === 'production'
|
|
527
|
+
? slices.filter(({ name }) => {
|
|
528
|
+
const status = policy.slices[name]?.productionStatus;
|
|
529
|
+
return status === 'pilot' || status === 'ready';
|
|
530
|
+
})
|
|
531
|
+
: slices;
|
|
532
|
+
if (requestedSlices !== undefined &&
|
|
533
|
+
(!Array.isArray(requestedSlices) ||
|
|
534
|
+
requestedSlices.length === 0 ||
|
|
535
|
+
requestedSlices.length > 64 ||
|
|
536
|
+
new Set(requestedSlices).size !== requestedSlices.length ||
|
|
537
|
+
requestedSlices.some((name) => typeof name !== 'string' || !/^[a-z0-9][a-z0-9-]{0,62}$/.test(name)))) {
|
|
538
|
+
throw new Error('Local deployment Slice selection must contain unique, bounded Slice names.');
|
|
539
|
+
}
|
|
540
|
+
for (const name of requestedSlices ?? []) {
|
|
541
|
+
if (!eligibleSlices.some((slice) => slice.name === name)) {
|
|
542
|
+
throw new Error(`Selected Slice ${name} is not deployable in ${stage}; inspect its project and committed production policy.`);
|
|
543
|
+
}
|
|
544
|
+
}
|
|
545
|
+
const selectedSlices = requestedSlices === undefined
|
|
546
|
+
? eligibleSlices
|
|
547
|
+
: eligibleSlices.filter(({ name }) => requestedSlices.includes(name));
|
|
548
|
+
const selected = [
|
|
549
|
+
{ kind: 'foundation', name: foundations[0]?.name ?? '' },
|
|
550
|
+
...selectedSlices.map(({ name }) => ({ kind: 'slice', name })),
|
|
551
|
+
];
|
|
552
|
+
const decision = (0, index_js_2.evaluateRepositoryPolicyRequest)(policy, {
|
|
553
|
+
action: 'deploy',
|
|
554
|
+
projects: selected,
|
|
555
|
+
stage,
|
|
556
|
+
});
|
|
557
|
+
if (!decision.allowed) {
|
|
558
|
+
throw new Error(`Repository Operating Policy rejected local deployment:\n${decision.reasons.map((reason) => `- ${reason}`).join('\n')}`);
|
|
559
|
+
}
|
|
560
|
+
return selected.map(({ name }) => name);
|
|
561
|
+
}
|
|
562
|
+
function frameworkVersion(root) {
|
|
563
|
+
const candidates = [
|
|
564
|
+
(0, node_path_1.join)(root, 'node_modules', '@empire-builder-kit', 'nx', 'package.json'),
|
|
565
|
+
(0, node_path_1.join)(root, 'package.json'),
|
|
566
|
+
];
|
|
567
|
+
for (const path of candidates) {
|
|
568
|
+
try {
|
|
569
|
+
const value = JSON.parse((0, node_fs_1.readFileSync)(path, 'utf8'));
|
|
570
|
+
if (value.name === '@empire-builder-kit/nx' && value.version) {
|
|
571
|
+
return value.version;
|
|
572
|
+
}
|
|
573
|
+
const dependency = value.devDependencies?.['@empire-builder-kit/nx'] ??
|
|
574
|
+
value.dependencies?.['@empire-builder-kit/nx'];
|
|
575
|
+
if (dependency)
|
|
576
|
+
return dependency;
|
|
577
|
+
}
|
|
578
|
+
catch {
|
|
579
|
+
// Try the next deterministic package identity.
|
|
580
|
+
}
|
|
581
|
+
}
|
|
582
|
+
return 'unknown';
|
|
583
|
+
}
|
|
584
|
+
function prepareReceiptDestination(root) {
|
|
585
|
+
const directory = (0, node_path_1.join)(root, '.ebk', 'evidence', 'deployment');
|
|
586
|
+
ensurePrivateEvidenceDirectory(root, directory);
|
|
587
|
+
const path = (0, node_path_1.join)(directory, 'latest.json');
|
|
588
|
+
if ((0, node_fs_1.existsSync)(path))
|
|
589
|
+
(0, private_state_js_1.assertPrivatePath)(path, 'file');
|
|
590
|
+
return path;
|
|
591
|
+
}
|
|
592
|
+
function writeReceipt(root, receipt) {
|
|
593
|
+
(0, private_state_js_1.atomicWritePrivateFile)(prepareReceiptDestination(root), `${JSON.stringify(receipt, null, 2)}\n`);
|
|
594
|
+
}
|
|
595
|
+
function invalidatePriorReceipt(root) {
|
|
596
|
+
const path = prepareReceiptDestination(root);
|
|
597
|
+
if (!(0, node_fs_1.existsSync)(path))
|
|
598
|
+
return;
|
|
599
|
+
(0, private_state_js_1.assertPrivatePath)(path, 'file');
|
|
600
|
+
(0, node_fs_1.rmSync)(path, { force: true });
|
|
601
|
+
if ((0, node_fs_1.existsSync)(path)) {
|
|
602
|
+
throw new Error('Prior deployment receipt invalidation failed.');
|
|
603
|
+
}
|
|
604
|
+
}
|
|
605
|
+
class NativeChildReconciliationError extends Error {
|
|
606
|
+
constructor(primary, reconciliation) {
|
|
607
|
+
const describe = (error) => error instanceof Error ? error.message : String(error);
|
|
608
|
+
super(`${describe(primary)}; source reconciliation also failed: ${describe(reconciliation)}`);
|
|
609
|
+
}
|
|
610
|
+
}
|
|
611
|
+
async function runNxTarget(input) {
|
|
612
|
+
const forwarded = [
|
|
613
|
+
`--stage=${input.stage}`,
|
|
614
|
+
`--expectedRoleArn=${input.expectedRoleArn}`,
|
|
615
|
+
`--region=${input.region}`,
|
|
616
|
+
...(input.profile ? [`--profile=${input.profile}`] : []),
|
|
617
|
+
];
|
|
618
|
+
const args = [
|
|
619
|
+
(0, node_path_1.join)(input.context.root, 'node_modules', 'nx', 'dist', 'bin', 'nx.js'),
|
|
620
|
+
'run',
|
|
621
|
+
`${input.project}:${input.target}`,
|
|
622
|
+
'--',
|
|
623
|
+
...forwarded,
|
|
624
|
+
];
|
|
625
|
+
const projectRoot = input.context.projectsConfigurations?.projects[input.project]?.root;
|
|
626
|
+
if (!projectRoot)
|
|
627
|
+
throw new Error(`Deployment project ${input.project} lacks its source root.`);
|
|
628
|
+
const nextSource = (0, sst_environment_source_js_1.captureNextEnvironmentSource)({
|
|
629
|
+
projectRoot: confinedWorkspacePath(input.context.root, projectRoot),
|
|
630
|
+
workspaceRoot: input.context.root,
|
|
631
|
+
});
|
|
632
|
+
let primaryFailure;
|
|
633
|
+
try {
|
|
634
|
+
const result = input.runSync
|
|
635
|
+
? input.runSync(process.execPath, args, {
|
|
636
|
+
cwd: input.context.root,
|
|
637
|
+
env: input.environment,
|
|
638
|
+
shell: false,
|
|
639
|
+
stdio: 'inherit',
|
|
640
|
+
})
|
|
641
|
+
: await (0, run_sst_command_js_1.runGovernedChildProcess)({
|
|
642
|
+
args,
|
|
643
|
+
cwd: input.context.root,
|
|
644
|
+
environment: input.environment,
|
|
645
|
+
executable: process.execPath,
|
|
646
|
+
...(input.spawnChild ? { spawnChild: input.spawnChild } : {}),
|
|
647
|
+
});
|
|
648
|
+
if (result.error || result.signal || result.status !== 0) {
|
|
649
|
+
throw new Error(result.error
|
|
650
|
+
? `${input.target} failed for ${input.project}: ${result.error.message}`
|
|
651
|
+
: result.signal
|
|
652
|
+
? `${input.target} failed for ${input.project} with signal ${result.signal}.`
|
|
653
|
+
: `${input.target} failed for ${input.project} with status ${result.status ?? 'unknown'}.`);
|
|
654
|
+
}
|
|
655
|
+
}
|
|
656
|
+
catch (error) {
|
|
657
|
+
primaryFailure = { error };
|
|
658
|
+
}
|
|
659
|
+
// Reconcile after every settled child, retaining its error until cleanup ends.
|
|
660
|
+
// Native Next may run in an Nx dependency before the SST executor starts.
|
|
661
|
+
try {
|
|
662
|
+
(0, sst_environment_source_js_1.reconcileNextEnvironmentSource)(nextSource, input.context.root);
|
|
663
|
+
}
|
|
664
|
+
catch (error) {
|
|
665
|
+
if (primaryFailure)
|
|
666
|
+
throw new NativeChildReconciliationError(primaryFailure.error, error);
|
|
667
|
+
throw error;
|
|
668
|
+
}
|
|
669
|
+
if (primaryFailure)
|
|
670
|
+
throw primaryFailure.error;
|
|
671
|
+
}
|
|
672
|
+
const FOUNDATION_DESCRIPTOR_PATH = 'packages/foundation/contracts/foundation.json';
|
|
673
|
+
/** The committed Foundation declaration is the only SQL signal; the generated
|
|
674
|
+
* Foundation publishes database discovery exactly when it declares postgres. */
|
|
675
|
+
function productionFoundationDeclaresPostgres(root) {
|
|
676
|
+
let descriptor;
|
|
677
|
+
try {
|
|
678
|
+
descriptor = JSON.parse((0, node_fs_1.readFileSync)((0, node_path_1.join)(root, FOUNDATION_DESCRIPTOR_PATH), 'utf8'));
|
|
679
|
+
}
|
|
680
|
+
catch {
|
|
681
|
+
throw new Error(`Production deployment requires the committed Foundation capability declaration ${FOUNDATION_DESCRIPTOR_PATH}.`);
|
|
682
|
+
}
|
|
683
|
+
return (0, capability_plan_js_1.planFoundationCapabilities)({ current: descriptor, requirements: [] })
|
|
684
|
+
.resources.postgres;
|
|
685
|
+
}
|
|
686
|
+
/** Declarations are monotonic: a SQL-free Foundation must never observe, gain,
|
|
687
|
+
* or lose a production database during a native deployment. The
|
|
688
|
+
* `priorDiscovery` check is a redundant second line: the preflight already
|
|
689
|
+
* rejects an existing database before any child deploys, so a prior `existing`
|
|
690
|
+
* state cannot reach the postflights today and no spec exercises that branch. */
|
|
691
|
+
function assertSqlFreeProductionDatabase(discovery, priorDiscovery) {
|
|
692
|
+
if (discovery.state !== 'absent' || priorDiscovery?.state === 'existing') {
|
|
693
|
+
throw new Error('Production Foundation database discovery is present although the Foundation does not declare postgres; deployment is blocked.');
|
|
694
|
+
}
|
|
695
|
+
}
|
|
696
|
+
function productionConfirmation(account, region, commit) {
|
|
697
|
+
return `deploy:production:${account}:${region}:${commit}`;
|
|
698
|
+
}
|
|
699
|
+
async function defaultIdentifyGithubCaller(region) {
|
|
700
|
+
return new client_sts_1.STSClient({
|
|
701
|
+
endpoint: (0, identity_js_1.canonicalStsEndpoint)(region),
|
|
702
|
+
region,
|
|
703
|
+
}).send(new client_sts_1.GetCallerIdentityCommand({}));
|
|
704
|
+
}
|
|
705
|
+
function assertGithubDeploymentAuthority(input) {
|
|
706
|
+
const repository = process.env.GITHUB_REPOSITORY?.trim() ?? '';
|
|
707
|
+
const ref = process.env.GITHUB_REF?.trim() ?? '';
|
|
708
|
+
const eventName = process.env.GITHUB_EVENT_NAME?.trim() ?? '';
|
|
709
|
+
const callerWorkflow = process.env.GITHUB_WORKFLOW_REF?.trim() ?? '';
|
|
710
|
+
const calledWorkflow = process.env.EBK_GITHUB_JOB_WORKFLOW_REF?.trim() ?? '';
|
|
711
|
+
const expectedBranch = input.stage === 'production' ? 'main' : 'develop';
|
|
712
|
+
const expectedRef = `refs/heads/${expectedBranch}`;
|
|
713
|
+
const expectedCalledWorkflow = `${repository}/.github/workflows/deploy.yml@${expectedRef}`;
|
|
714
|
+
const expectedCallerWorkflow = eventName === 'push'
|
|
715
|
+
? `${repository}/.github/workflows/ci.yml@${expectedRef}`
|
|
716
|
+
: eventName === 'workflow_dispatch'
|
|
717
|
+
? expectedCalledWorkflow
|
|
718
|
+
: undefined;
|
|
719
|
+
const allowedEvent = eventName === 'workflow_dispatch' ||
|
|
720
|
+
(eventName === 'push' && input.policy.deploymentProfile !== 'starter');
|
|
721
|
+
if (process.env.GITHUB_ACTIONS !== 'true' ||
|
|
722
|
+
!repository ||
|
|
723
|
+
!allowedEvent ||
|
|
724
|
+
process.env.GITHUB_SHA !== input.commit ||
|
|
725
|
+
ref !== expectedRef ||
|
|
726
|
+
callerWorkflow !== expectedCallerWorkflow ||
|
|
727
|
+
calledWorkflow !== expectedCalledWorkflow) {
|
|
728
|
+
throw new Error('Protected deployment requires the exact generated GitHub caller and reusable deploy workflows, branch, and immutable source commit.');
|
|
729
|
+
}
|
|
730
|
+
if (input.policy.deploymentProfile === 'starter' &&
|
|
731
|
+
input.stage === 'staging') {
|
|
732
|
+
throw new Error('The starter deployment profile has no staging stage.');
|
|
733
|
+
}
|
|
734
|
+
const clean = git(input.root, ['status', '--porcelain=v1', '--untracked-files=all'], input.run);
|
|
735
|
+
if (clean !== '') {
|
|
736
|
+
throw new Error('Protected GitHub deployment requires a clean checkout.');
|
|
737
|
+
}
|
|
738
|
+
}
|
|
739
|
+
async function runLocalDeploy(options, context, dependencies = {}) {
|
|
740
|
+
const run = dependencies.run ?? node_child_process_1.spawnSync;
|
|
741
|
+
const now = dependencies.now ?? (() => new Date());
|
|
742
|
+
const startedAt = now().toISOString();
|
|
743
|
+
const children = [];
|
|
744
|
+
const migrations = {};
|
|
745
|
+
const smoke = {};
|
|
746
|
+
let lifecycleScope;
|
|
747
|
+
let selectedSlices;
|
|
748
|
+
let account = '';
|
|
749
|
+
let actor = '';
|
|
750
|
+
let policy;
|
|
751
|
+
let region = '';
|
|
752
|
+
let source = { clean: false, commit: '', workingTreeDigest: '' };
|
|
753
|
+
let transport;
|
|
754
|
+
let productionDatabaseBefore;
|
|
755
|
+
let productionDatabaseAfterFoundation;
|
|
756
|
+
let productionPostgresDeclared = true;
|
|
757
|
+
let outcome = 'failed';
|
|
758
|
+
let failure;
|
|
759
|
+
let finalPhase = 'validation';
|
|
760
|
+
let receiptDestinationPrepared = false;
|
|
761
|
+
const githubAuthority = process.env.GITHUB_ACTIONS === 'true';
|
|
762
|
+
const retain = () => {
|
|
763
|
+
if (!policy || !receiptDestinationPrepared)
|
|
764
|
+
return;
|
|
765
|
+
writeReceipt(context.root, {
|
|
766
|
+
account,
|
|
767
|
+
actor,
|
|
768
|
+
authority: githubAuthority ? 'github' : 'local',
|
|
769
|
+
children,
|
|
770
|
+
completedAt: now().toISOString(),
|
|
771
|
+
frameworkVersion: frameworkVersion(context.root),
|
|
772
|
+
...(failure ? { failure } : {}),
|
|
773
|
+
kind: 'ebk-deployment-receipt',
|
|
774
|
+
...(lifecycleScope ? { lifecycleScope } : {}),
|
|
775
|
+
migrations,
|
|
776
|
+
outcome,
|
|
777
|
+
profile: policy.deploymentProfile,
|
|
778
|
+
region,
|
|
779
|
+
schemaVersion: 1,
|
|
780
|
+
...(selectedSlices ? { selectedSlices } : {}),
|
|
781
|
+
smoke,
|
|
782
|
+
source,
|
|
783
|
+
stage: options.stage,
|
|
784
|
+
startedAt,
|
|
785
|
+
});
|
|
786
|
+
};
|
|
787
|
+
try {
|
|
788
|
+
invalidatePriorReceipt(context.root);
|
|
789
|
+
receiptDestinationPrepared = true;
|
|
790
|
+
(0, run_sst_command_js_1.assertGovernedAwsLifecyclePlatform)(dependencies.platform);
|
|
791
|
+
policy = (0, index_js_2.readRepositoryOperatingPolicy)(context.root);
|
|
792
|
+
if (options.stage === 'production') {
|
|
793
|
+
(0, capacity_migration_js_1.assertWorkspaceCapacityMigrationChoice)(context.root, policy.productionFoundation.profile);
|
|
794
|
+
}
|
|
795
|
+
if (!(0, index_js_2.isActiveDeploymentStage)(policy.deploymentProfile, options.stage)) {
|
|
796
|
+
throw new Error(`Deployment stage ${options.stage} is inactive for the ${policy.deploymentProfile} deployment profile.`);
|
|
797
|
+
}
|
|
798
|
+
if (!githubAuthority &&
|
|
799
|
+
(0, index_js_2.requiresGithubDeployment)(policy.deploymentProfile, options.stage)) {
|
|
800
|
+
throw new Error(`The ${policy.deploymentProfile} profile requires GitHub deployment authority for ${options.stage}.`);
|
|
801
|
+
}
|
|
802
|
+
if (!ROLE.test(options.expectedRoleArn)) {
|
|
803
|
+
throw new Error('Local deployment requires one exact IAM role ARN.');
|
|
804
|
+
}
|
|
805
|
+
region = (0, index_js_2.configuredDeploymentRegion)(policy.deploymentRegion);
|
|
806
|
+
account = (0, index_js_2.configuredDeploymentAccountForStage)(policy.deploymentProfile, policy.deploymentAccounts, options.stage);
|
|
807
|
+
const expectedRoleArn = (0, index_js_1.createStageAuthorityIdentity)({
|
|
808
|
+
accountId: account,
|
|
809
|
+
partition: partitionForRegion(region),
|
|
810
|
+
region,
|
|
811
|
+
stage: options.stage,
|
|
812
|
+
}).deploymentRoleArn;
|
|
813
|
+
if (options.expectedRoleArn !== expectedRoleArn) {
|
|
814
|
+
throw new Error(`Deployment role must equal the committed ${options.stage} stage authority role ${expectedRoleArn}.`);
|
|
815
|
+
}
|
|
816
|
+
if (options.slices !== undefined &&
|
|
817
|
+
(githubAuthority || options.lifecycleScope === 'affected')) {
|
|
818
|
+
throw new Error('Explicit Slice selection is local-only and cannot be combined with affected lifecycle or protected GitHub deployment.');
|
|
819
|
+
}
|
|
820
|
+
const orderedProjects = localDeploymentProjectOrder(policy, context, options.stage, options.slices);
|
|
821
|
+
if (options.slices)
|
|
822
|
+
selectedSlices = orderedProjects.slice(1);
|
|
823
|
+
const identity = localWorkingTreeDigest(context.root, run);
|
|
824
|
+
source = {
|
|
825
|
+
clean: identity.clean,
|
|
826
|
+
commit: identity.commit,
|
|
827
|
+
workingTreeDigest: identity.digest,
|
|
828
|
+
};
|
|
829
|
+
if ((githubAuthority || options.stage !== 'development') && !source.clean) {
|
|
830
|
+
throw new Error(`Local ${options.stage} deployment requires a completely clean source tree.`);
|
|
831
|
+
}
|
|
832
|
+
if (options.stage === 'production') {
|
|
833
|
+
// Read only after the clean-source check so the declaration is bound to
|
|
834
|
+
// the digested tree, and before any AWS authority or transport exists.
|
|
835
|
+
productionPostgresDeclared = productionFoundationDeclaresPostgres(context.root);
|
|
836
|
+
}
|
|
837
|
+
if (githubAuthority) {
|
|
838
|
+
if (options.profile) {
|
|
839
|
+
throw new Error('Protected GitHub deployment must use ambient OIDC credentials, not a local AWS profile.');
|
|
840
|
+
}
|
|
841
|
+
assertGithubDeploymentAuthority({
|
|
842
|
+
commit: source.commit,
|
|
843
|
+
policy,
|
|
844
|
+
root: context.root,
|
|
845
|
+
run,
|
|
846
|
+
stage: options.stage,
|
|
847
|
+
});
|
|
848
|
+
const caller = await (dependencies.identifyGithubCaller ?? defaultIdentifyGithubCaller)(region);
|
|
849
|
+
if (caller.Account?.trim() !== account ||
|
|
850
|
+
!(0, identity_js_1.matchesExpectedAssumedRoleArn)(account, caller.Arn?.trim() ?? '', expectedRoleArn)) {
|
|
851
|
+
throw new Error('Protected GitHub deployment caller does not match the committed account and exact assumed role.');
|
|
852
|
+
}
|
|
853
|
+
actor = process.env.GITHUB_ACTOR?.trim() ?? '';
|
|
854
|
+
if (!actor) {
|
|
855
|
+
throw new Error('Protected GitHub deployment actor is absent.');
|
|
856
|
+
}
|
|
857
|
+
}
|
|
858
|
+
else if (options.stage === 'staging') {
|
|
859
|
+
const challenge = `approve:deploy:staging:${source.commit}`;
|
|
860
|
+
let acknowledged = false;
|
|
861
|
+
try {
|
|
862
|
+
acknowledged = await (dependencies.approve ?? (0, local_approval_js_1.createTtyLocalMutationApprover)())({
|
|
863
|
+
action: 'deploy',
|
|
864
|
+
challenge,
|
|
865
|
+
sourceCommit: source.commit,
|
|
866
|
+
stage: options.stage,
|
|
867
|
+
});
|
|
868
|
+
}
|
|
869
|
+
catch (error) {
|
|
870
|
+
if (error instanceof local_approval_js_1.LocalMutationApprovalUnavailableError) {
|
|
871
|
+
outcome = 'review-required';
|
|
872
|
+
}
|
|
873
|
+
throw error;
|
|
874
|
+
}
|
|
875
|
+
if (!acknowledged) {
|
|
876
|
+
outcome = 'review-required';
|
|
877
|
+
throw new Error('Local staging deployment acknowledgement was declined.');
|
|
878
|
+
}
|
|
879
|
+
}
|
|
880
|
+
if (!githubAuthority && options.stage === 'production') {
|
|
881
|
+
const expected = productionConfirmation(account, region, source.commit);
|
|
882
|
+
let acknowledged = false;
|
|
883
|
+
try {
|
|
884
|
+
acknowledged = await (dependencies.approve ?? (0, local_approval_js_1.createTtyLocalMutationApprover)())({
|
|
885
|
+
action: 'deploy',
|
|
886
|
+
challenge: expected,
|
|
887
|
+
sourceCommit: source.commit,
|
|
888
|
+
stage: options.stage,
|
|
889
|
+
});
|
|
890
|
+
}
|
|
891
|
+
catch (error) {
|
|
892
|
+
if (error instanceof local_approval_js_1.LocalMutationApprovalUnavailableError) {
|
|
893
|
+
outcome = 'review-required';
|
|
894
|
+
}
|
|
895
|
+
throw error;
|
|
896
|
+
}
|
|
897
|
+
if (!acknowledged) {
|
|
898
|
+
outcome = 'review-required';
|
|
899
|
+
throw new Error('Local production deployment acknowledgement was declined.');
|
|
900
|
+
}
|
|
901
|
+
}
|
|
902
|
+
lifecycleScope = resolveLifecycleScope({
|
|
903
|
+
context,
|
|
904
|
+
frameworkVersion: frameworkVersion(context.root),
|
|
905
|
+
options,
|
|
906
|
+
orderedProjects,
|
|
907
|
+
run: dependencies.run ?? node_child_process_1.spawnSync,
|
|
908
|
+
source,
|
|
909
|
+
});
|
|
910
|
+
devkit_1.logger.info(`[lifecycle-scope] ${lifecycleScope.mode} (${lifecycleScope.reason}): ` +
|
|
911
|
+
orderedProjects
|
|
912
|
+
.map((project) => `${project}=${lifecycleScope?.projects[project]}`)
|
|
913
|
+
.join(' '));
|
|
914
|
+
const descriptors = projectDescriptors(context);
|
|
915
|
+
const localProtectedContainerStage = !githubAuthority &&
|
|
916
|
+
requiresLocalContainerPreparation(policy.deploymentProfile, options.stage)
|
|
917
|
+
? options.stage
|
|
918
|
+
: undefined;
|
|
919
|
+
const localProtectedContainerProjects = localProtectedContainerStage
|
|
920
|
+
? orderedProjects
|
|
921
|
+
.map((project) => descriptors.find((candidate) => candidate.name === project))
|
|
922
|
+
.filter((project) => project?.tags.includes('type:slice') === true)
|
|
923
|
+
: [];
|
|
924
|
+
for (const project of localProtectedContainerProjects) {
|
|
925
|
+
const missingTargets = LOCAL_CONTAINER_TARGETS.filter((target) => !supportsTarget(project, target));
|
|
926
|
+
if (missingTargets.length > 0) {
|
|
927
|
+
throw new Error(`Local ${policy.deploymentProfile} ${options.stage} requires the complete immutable OCI target set for ${project.name}: ${missingTargets.join(', ')}.`);
|
|
928
|
+
}
|
|
929
|
+
}
|
|
930
|
+
if (!githubAuthority) {
|
|
931
|
+
transport = await (dependencies.createTransport ?? federated_credential_transport_js_1.createLocalFederatedCredentialTransport)({
|
|
932
|
+
account,
|
|
933
|
+
expectedRoleArn,
|
|
934
|
+
...(options.profile ? { profile: options.profile } : {}),
|
|
935
|
+
region,
|
|
936
|
+
});
|
|
937
|
+
const firstIdentity = await transport.refresh();
|
|
938
|
+
actor = firstIdentity.actorArn;
|
|
939
|
+
}
|
|
940
|
+
const ownershipEnvironment = transport
|
|
941
|
+
? transport.childEnvironment((0, child_environment_js_1.sanitizeGovernedAwsChildEnvironment)(process.env))
|
|
942
|
+
: (0, child_environment_js_1.sanitizeGovernedAwsChildEnvironment)(process.env, {
|
|
943
|
+
preserveVerifiedGithubCredentials: true,
|
|
944
|
+
});
|
|
945
|
+
await (dependencies.ownership ?? index_js_3.assertWorkspaceStageOwnershipForWorkspace)(context.root, options.stage, {
|
|
946
|
+
...(ownershipEnvironment.AWS_CONFIG_FILE
|
|
947
|
+
? { configFilepath: ownershipEnvironment.AWS_CONFIG_FILE }
|
|
948
|
+
: {}),
|
|
949
|
+
...(ownershipEnvironment.AWS_SHARED_CREDENTIALS_FILE
|
|
950
|
+
? {
|
|
951
|
+
credentialsFilepath: ownershipEnvironment.AWS_SHARED_CREDENTIALS_FILE,
|
|
952
|
+
}
|
|
953
|
+
: {}),
|
|
954
|
+
...(transport ? { profile: transport.profile } : {}),
|
|
955
|
+
});
|
|
956
|
+
if (options.stage === 'production') {
|
|
957
|
+
if (transport)
|
|
958
|
+
await transport.refresh();
|
|
959
|
+
const boundaryEnvironment = transport
|
|
960
|
+
? transport.childEnvironment((0, child_environment_js_1.sanitizeGovernedAwsChildEnvironment)(process.env))
|
|
961
|
+
: (0, child_environment_js_1.sanitizeGovernedAwsChildEnvironment)(process.env, {
|
|
962
|
+
preserveVerifiedGithubCredentials: true,
|
|
963
|
+
});
|
|
964
|
+
productionDatabaseBefore = await (dependencies.attestProductionDatabase ??
|
|
965
|
+
production_database_safeguard_js_1.attestProductionDatabaseLifecycle)({
|
|
966
|
+
...(boundaryEnvironment.AWS_CONFIG_FILE
|
|
967
|
+
? { configFilepath: boundaryEnvironment.AWS_CONFIG_FILE }
|
|
968
|
+
: {}),
|
|
969
|
+
...(boundaryEnvironment.AWS_SHARED_CREDENTIALS_FILE
|
|
970
|
+
? {
|
|
971
|
+
credentialsFilepath: boundaryEnvironment.AWS_SHARED_CREDENTIALS_FILE,
|
|
972
|
+
}
|
|
973
|
+
: {}),
|
|
974
|
+
expectedAccountId: account,
|
|
975
|
+
expectedRegion: region,
|
|
976
|
+
expectedRoleArn,
|
|
977
|
+
now: now(),
|
|
978
|
+
...(transport ? { profile: transport.profile } : {}),
|
|
979
|
+
requireExisting: false,
|
|
980
|
+
});
|
|
981
|
+
// Fail before any mutation: deploying a SQL-free Foundation over an
|
|
982
|
+
// existing database would retire it outside the separate retirement path.
|
|
983
|
+
if (!productionPostgresDeclared) {
|
|
984
|
+
assertSqlFreeProductionDatabase(productionDatabaseBefore);
|
|
985
|
+
}
|
|
986
|
+
}
|
|
987
|
+
const localContainerRunId = localProtectedContainerProjects.length === 0
|
|
988
|
+
? ''
|
|
989
|
+
: ((0, node_crypto_1.randomBytes)(8).readBigUInt64BE() + 1n).toString();
|
|
990
|
+
for (const project of localProtectedContainerProjects) {
|
|
991
|
+
resetLocalContainerWorkingEvidence({
|
|
992
|
+
project,
|
|
993
|
+
root: context.root,
|
|
994
|
+
stage: localProtectedContainerStage,
|
|
995
|
+
});
|
|
996
|
+
for (const target of LOCAL_CONTAINER_TARGETS) {
|
|
997
|
+
if (transport)
|
|
998
|
+
await transport.refresh();
|
|
999
|
+
const environment = {
|
|
1000
|
+
...(transport
|
|
1001
|
+
? transport.childEnvironment((0, child_environment_js_1.sanitizeGovernedAwsChildEnvironment)(process.env))
|
|
1002
|
+
: (0, child_environment_js_1.sanitizeGovernedAwsChildEnvironment)(process.env)),
|
|
1003
|
+
AWS_EXPECTED_ACCOUNT_ID: account,
|
|
1004
|
+
AWS_REGION: region,
|
|
1005
|
+
EBK_LOCAL_CONTAINER_RUN_ID: localContainerRunId,
|
|
1006
|
+
EBK_LOCAL_DEPLOYMENT_MODE: 'federated',
|
|
1007
|
+
EBK_DEPLOYMENT_PROFILE: policy.deploymentProfile,
|
|
1008
|
+
EBK_NX_STAGE_LIFECYCLE: 'local',
|
|
1009
|
+
EBK_RELEASE_SOURCE_COMMIT: source.commit,
|
|
1010
|
+
EBK_SOURCE_COMMIT: source.commit,
|
|
1011
|
+
EBK_STAGE: options.stage,
|
|
1012
|
+
EBK_WORKING_TREE_DIRTY: 'false',
|
|
1013
|
+
};
|
|
1014
|
+
assertDeploymentSourceUnchanged(context.root, source, run);
|
|
1015
|
+
const childStartedAt = now().toISOString();
|
|
1016
|
+
try {
|
|
1017
|
+
await runNxTarget({
|
|
1018
|
+
context,
|
|
1019
|
+
environment,
|
|
1020
|
+
expectedRoleArn,
|
|
1021
|
+
...(transport ? { profile: transport.profile } : {}),
|
|
1022
|
+
project: project.name,
|
|
1023
|
+
region,
|
|
1024
|
+
...(dependencies.run ? { runSync: dependencies.run } : {}),
|
|
1025
|
+
...(dependencies.spawnChild
|
|
1026
|
+
? { spawnChild: dependencies.spawnChild }
|
|
1027
|
+
: {}),
|
|
1028
|
+
stage: options.stage,
|
|
1029
|
+
target,
|
|
1030
|
+
});
|
|
1031
|
+
if (target === 'release-candidate') {
|
|
1032
|
+
materializeLocalReleaseCandidate({
|
|
1033
|
+
project,
|
|
1034
|
+
root: context.root,
|
|
1035
|
+
sourceCommit: source.commit,
|
|
1036
|
+
});
|
|
1037
|
+
}
|
|
1038
|
+
if (target === 'container-release-assemble') {
|
|
1039
|
+
(dependencies.attestContainerBinding ?? attestLocalContainerBinding)({
|
|
1040
|
+
account,
|
|
1041
|
+
project,
|
|
1042
|
+
region,
|
|
1043
|
+
root: context.root,
|
|
1044
|
+
sourceCommit: source.commit,
|
|
1045
|
+
stage: options.stage,
|
|
1046
|
+
});
|
|
1047
|
+
}
|
|
1048
|
+
children.push({
|
|
1049
|
+
completedAt: now().toISOString(),
|
|
1050
|
+
outcome: 'succeeded',
|
|
1051
|
+
project: project.name,
|
|
1052
|
+
startedAt: childStartedAt,
|
|
1053
|
+
target,
|
|
1054
|
+
});
|
|
1055
|
+
}
|
|
1056
|
+
catch (error) {
|
|
1057
|
+
children.push({
|
|
1058
|
+
completedAt: now().toISOString(),
|
|
1059
|
+
outcome: 'failed',
|
|
1060
|
+
project: project.name,
|
|
1061
|
+
startedAt: childStartedAt,
|
|
1062
|
+
target,
|
|
1063
|
+
});
|
|
1064
|
+
throw error;
|
|
1065
|
+
}
|
|
1066
|
+
}
|
|
1067
|
+
}
|
|
1068
|
+
for (const project of orderedProjects) {
|
|
1069
|
+
const descriptor = descriptors.find((candidate) => candidate.name === project);
|
|
1070
|
+
if (!descriptor) {
|
|
1071
|
+
throw new Error(`Local deployment project ${project} disappeared.`);
|
|
1072
|
+
}
|
|
1073
|
+
if (lifecycleScope?.projects[project] === 'skip-unchanged' &&
|
|
1074
|
+
lifecycleScope.baseline) {
|
|
1075
|
+
const skippedAt = now().toISOString();
|
|
1076
|
+
children.push({
|
|
1077
|
+
completedAt: skippedAt,
|
|
1078
|
+
outcome: 'skipped-unchanged',
|
|
1079
|
+
project,
|
|
1080
|
+
reused: lifecycleScope.baseline,
|
|
1081
|
+
startedAt: skippedAt,
|
|
1082
|
+
target: 'deploy',
|
|
1083
|
+
});
|
|
1084
|
+
migrations[project] = 'unchanged-since-baseline';
|
|
1085
|
+
smoke[project] = 'unchanged-since-baseline';
|
|
1086
|
+
continue;
|
|
1087
|
+
}
|
|
1088
|
+
if (transport)
|
|
1089
|
+
await transport.refresh();
|
|
1090
|
+
const environment = {
|
|
1091
|
+
...(transport
|
|
1092
|
+
? transport.childEnvironment((0, child_environment_js_1.sanitizeGovernedAwsChildEnvironment)(process.env))
|
|
1093
|
+
: (0, child_environment_js_1.sanitizeGovernedAwsChildEnvironment)(process.env, {
|
|
1094
|
+
preserveVerifiedGithubCredentials: true,
|
|
1095
|
+
})),
|
|
1096
|
+
AWS_EXPECTED_ACCOUNT_ID: account,
|
|
1097
|
+
AWS_REGION: region,
|
|
1098
|
+
EBK_LOCAL_SOURCE_TREE: source.workingTreeDigest,
|
|
1099
|
+
EBK_NX_STAGE_LIFECYCLE: githubAuthority ? 'github' : 'local',
|
|
1100
|
+
EBK_SOURCE_COMMIT: source.commit,
|
|
1101
|
+
EBK_WORKING_TREE_DIRTY: source.clean ? 'false' : 'true',
|
|
1102
|
+
};
|
|
1103
|
+
assertDeploymentSourceUnchanged(context.root, source, run);
|
|
1104
|
+
const childStartedAt = now().toISOString();
|
|
1105
|
+
try {
|
|
1106
|
+
await runNxTarget({
|
|
1107
|
+
context,
|
|
1108
|
+
environment,
|
|
1109
|
+
expectedRoleArn,
|
|
1110
|
+
...(transport ? { profile: transport.profile } : {}),
|
|
1111
|
+
project,
|
|
1112
|
+
region,
|
|
1113
|
+
...(dependencies.run ? { runSync: dependencies.run } : {}),
|
|
1114
|
+
...(dependencies.spawnChild
|
|
1115
|
+
? { spawnChild: dependencies.spawnChild }
|
|
1116
|
+
: {}),
|
|
1117
|
+
stage: options.stage,
|
|
1118
|
+
target: 'deploy',
|
|
1119
|
+
});
|
|
1120
|
+
children.push({
|
|
1121
|
+
completedAt: now().toISOString(),
|
|
1122
|
+
outcome: 'succeeded',
|
|
1123
|
+
project,
|
|
1124
|
+
startedAt: childStartedAt,
|
|
1125
|
+
target: 'deploy',
|
|
1126
|
+
});
|
|
1127
|
+
}
|
|
1128
|
+
catch (error) {
|
|
1129
|
+
children.push({
|
|
1130
|
+
completedAt: now().toISOString(),
|
|
1131
|
+
outcome: 'failed',
|
|
1132
|
+
project,
|
|
1133
|
+
startedAt: childStartedAt,
|
|
1134
|
+
target: 'deploy',
|
|
1135
|
+
});
|
|
1136
|
+
throw error;
|
|
1137
|
+
}
|
|
1138
|
+
if (options.stage === 'production' &&
|
|
1139
|
+
descriptor.tags.includes('scope:foundation')) {
|
|
1140
|
+
if (transport)
|
|
1141
|
+
await transport.refresh();
|
|
1142
|
+
const boundaryEnvironment = transport
|
|
1143
|
+
? transport.childEnvironment((0, child_environment_js_1.sanitizeGovernedAwsChildEnvironment)(process.env))
|
|
1144
|
+
: (0, child_environment_js_1.sanitizeGovernedAwsChildEnvironment)(process.env, {
|
|
1145
|
+
preserveVerifiedGithubCredentials: true,
|
|
1146
|
+
});
|
|
1147
|
+
const postflightStartedAt = now().toISOString();
|
|
1148
|
+
const profile = (0, index_js_2.productionFoundationProfileContract)(policy.productionFoundation.profile).contract;
|
|
1149
|
+
try {
|
|
1150
|
+
productionDatabaseAfterFoundation = await (dependencies.attestProductionDatabase ??
|
|
1151
|
+
production_database_safeguard_js_1.attestProductionDatabaseLifecycle)({
|
|
1152
|
+
...(boundaryEnvironment.AWS_CONFIG_FILE
|
|
1153
|
+
? { configFilepath: boundaryEnvironment.AWS_CONFIG_FILE }
|
|
1154
|
+
: {}),
|
|
1155
|
+
...(boundaryEnvironment.AWS_SHARED_CREDENTIALS_FILE
|
|
1156
|
+
? {
|
|
1157
|
+
credentialsFilepath: boundaryEnvironment.AWS_SHARED_CREDENTIALS_FILE,
|
|
1158
|
+
}
|
|
1159
|
+
: {}),
|
|
1160
|
+
expectedAccountId: account,
|
|
1161
|
+
...(productionPostgresDeclared
|
|
1162
|
+
? {
|
|
1163
|
+
expectedCapacity: {
|
|
1164
|
+
max: Number.parseFloat(profile.aurora.max),
|
|
1165
|
+
min: Number.parseFloat(profile.aurora.min),
|
|
1166
|
+
},
|
|
1167
|
+
}
|
|
1168
|
+
: {}),
|
|
1169
|
+
expectedRegion: region,
|
|
1170
|
+
expectedRoleArn,
|
|
1171
|
+
now: now(),
|
|
1172
|
+
priorDiscovery: productionDatabaseBefore,
|
|
1173
|
+
...(transport ? { profile: transport.profile } : {}),
|
|
1174
|
+
requireExisting: productionPostgresDeclared,
|
|
1175
|
+
});
|
|
1176
|
+
if (!productionPostgresDeclared) {
|
|
1177
|
+
assertSqlFreeProductionDatabase(productionDatabaseAfterFoundation, productionDatabaseBefore);
|
|
1178
|
+
}
|
|
1179
|
+
children.push({
|
|
1180
|
+
completedAt: now().toISOString(),
|
|
1181
|
+
outcome: 'succeeded',
|
|
1182
|
+
project,
|
|
1183
|
+
startedAt: postflightStartedAt,
|
|
1184
|
+
target: 'production-database-postflight',
|
|
1185
|
+
});
|
|
1186
|
+
}
|
|
1187
|
+
catch (error) {
|
|
1188
|
+
children.push({
|
|
1189
|
+
completedAt: now().toISOString(),
|
|
1190
|
+
outcome: 'failed',
|
|
1191
|
+
project,
|
|
1192
|
+
startedAt: postflightStartedAt,
|
|
1193
|
+
target: 'production-database-postflight',
|
|
1194
|
+
});
|
|
1195
|
+
throw error;
|
|
1196
|
+
}
|
|
1197
|
+
}
|
|
1198
|
+
migrations[project] = supportsTarget(descriptor, 'db-migrate')
|
|
1199
|
+
? 'completed-by-deploy-target'
|
|
1200
|
+
: 'not-applicable';
|
|
1201
|
+
if (supportsTarget(descriptor, 'smoke-deployed')) {
|
|
1202
|
+
if (transport)
|
|
1203
|
+
await transport.refresh();
|
|
1204
|
+
const smokeTarget = readDeployedSmokeTarget(context.root, descriptor, options.stage);
|
|
1205
|
+
assertDeploymentSourceUnchanged(context.root, source, run);
|
|
1206
|
+
const smokeStartedAt = now().toISOString();
|
|
1207
|
+
try {
|
|
1208
|
+
const runSmoke = () => runNxTarget({
|
|
1209
|
+
context,
|
|
1210
|
+
environment: {
|
|
1211
|
+
...(transport
|
|
1212
|
+
? transport.childEnvironment((0, child_environment_js_1.sanitizeGovernedAwsChildEnvironment)(process.env))
|
|
1213
|
+
: (0, child_environment_js_1.sanitizeGovernedAwsChildEnvironment)(process.env, {
|
|
1214
|
+
preserveVerifiedGithubCredentials: true,
|
|
1215
|
+
})),
|
|
1216
|
+
AWS_EXPECTED_ACCOUNT_ID: account,
|
|
1217
|
+
AWS_REGION: region,
|
|
1218
|
+
EBK_NX_STAGE_LIFECYCLE: githubAuthority ? 'github' : 'local',
|
|
1219
|
+
EBK_SOURCE_COMMIT: source.commit,
|
|
1220
|
+
EBK_DEPLOYED_SOURCE_COMMIT: deployedSourceCommit(source.commit),
|
|
1221
|
+
EBK_SMOKE_API_URL: smokeTarget.apiUrl,
|
|
1222
|
+
EBK_SMOKE_AUTHORITY_VERSION: 'cognito-admin-cloudwatch-observe-v1',
|
|
1223
|
+
EBK_SMOKE_CLIENT_ID: smokeTarget.clientId,
|
|
1224
|
+
EBK_SMOKE_URL: smokeTarget.webUrl,
|
|
1225
|
+
EBK_SMOKE_USER_POOL_ID: smokeTarget.userPoolId,
|
|
1226
|
+
EBK_STAGE: options.stage,
|
|
1227
|
+
},
|
|
1228
|
+
expectedRoleArn,
|
|
1229
|
+
...(transport ? { profile: transport.profile } : {}),
|
|
1230
|
+
project,
|
|
1231
|
+
region,
|
|
1232
|
+
...(dependencies.run ? { runSync: dependencies.run } : {}),
|
|
1233
|
+
...(dependencies.spawnChild
|
|
1234
|
+
? { spawnChild: dependencies.spawnChild }
|
|
1235
|
+
: {}),
|
|
1236
|
+
stage: options.stage,
|
|
1237
|
+
target: 'smoke-deployed',
|
|
1238
|
+
});
|
|
1239
|
+
if (githubAuthority) {
|
|
1240
|
+
await (dependencies.privateSmoke ?? private_smoke_access_js_1.runGithubPrivateSmoke)({
|
|
1241
|
+
account,
|
|
1242
|
+
deploymentProfile: policy.deploymentProfile,
|
|
1243
|
+
root: context.root,
|
|
1244
|
+
source: source.commit,
|
|
1245
|
+
stage: options.stage,
|
|
1246
|
+
url: smokeTarget.webUrl,
|
|
1247
|
+
workspace: JSON.parse((0, node_fs_1.readFileSync)((0, node_path_1.join)(context.root, 'package.json'), 'utf8')).name,
|
|
1248
|
+
run: runSmoke,
|
|
1249
|
+
});
|
|
1250
|
+
}
|
|
1251
|
+
else {
|
|
1252
|
+
if (!transport)
|
|
1253
|
+
throw new Error('Local smoke requires the verified federated transport.');
|
|
1254
|
+
await (dependencies.localPrivateSmoke ?? local_private_smoke_access_js_1.runLocalPrivateSmoke)({
|
|
1255
|
+
account,
|
|
1256
|
+
deploymentProfile: policy.deploymentProfile,
|
|
1257
|
+
root: context.root,
|
|
1258
|
+
source: source.commit,
|
|
1259
|
+
stage: options.stage,
|
|
1260
|
+
url: smokeTarget.webUrl,
|
|
1261
|
+
workspace: JSON.parse((0, node_fs_1.readFileSync)((0, node_path_1.join)(context.root, 'package.json'), 'utf8')).name,
|
|
1262
|
+
credentialEnvironment: transport.childEnvironment({}),
|
|
1263
|
+
run: runSmoke,
|
|
1264
|
+
});
|
|
1265
|
+
}
|
|
1266
|
+
children.push({
|
|
1267
|
+
completedAt: now().toISOString(),
|
|
1268
|
+
outcome: 'succeeded',
|
|
1269
|
+
project,
|
|
1270
|
+
startedAt: smokeStartedAt,
|
|
1271
|
+
target: 'smoke-deployed',
|
|
1272
|
+
});
|
|
1273
|
+
smoke[project] = 'passed';
|
|
1274
|
+
}
|
|
1275
|
+
catch (error) {
|
|
1276
|
+
children.push({
|
|
1277
|
+
completedAt: now().toISOString(),
|
|
1278
|
+
outcome: 'failed',
|
|
1279
|
+
project,
|
|
1280
|
+
startedAt: smokeStartedAt,
|
|
1281
|
+
target: 'smoke-deployed',
|
|
1282
|
+
});
|
|
1283
|
+
throw error;
|
|
1284
|
+
}
|
|
1285
|
+
}
|
|
1286
|
+
else {
|
|
1287
|
+
smoke[project] = 'not-applicable';
|
|
1288
|
+
}
|
|
1289
|
+
}
|
|
1290
|
+
if (options.stage === 'production') {
|
|
1291
|
+
if (!productionDatabaseAfterFoundation) {
|
|
1292
|
+
throw new Error('Production Foundation database postflight was not completed before final deployment acceptance.');
|
|
1293
|
+
}
|
|
1294
|
+
if (transport)
|
|
1295
|
+
await transport.refresh();
|
|
1296
|
+
const boundaryEnvironment = transport
|
|
1297
|
+
? transport.childEnvironment((0, child_environment_js_1.sanitizeGovernedAwsChildEnvironment)(process.env))
|
|
1298
|
+
: (0, child_environment_js_1.sanitizeGovernedAwsChildEnvironment)(process.env, {
|
|
1299
|
+
preserveVerifiedGithubCredentials: true,
|
|
1300
|
+
});
|
|
1301
|
+
const finalPostflightStartedAt = now().toISOString();
|
|
1302
|
+
const foundationProject = orderedProjects[0] ?? 'foundation';
|
|
1303
|
+
const profile = (0, index_js_2.productionFoundationProfileContract)(policy.productionFoundation.profile).contract;
|
|
1304
|
+
try {
|
|
1305
|
+
const finalDiscovery = await (dependencies.attestProductionDatabase ??
|
|
1306
|
+
production_database_safeguard_js_1.attestProductionDatabaseLifecycle)({
|
|
1307
|
+
...(boundaryEnvironment.AWS_CONFIG_FILE
|
|
1308
|
+
? { configFilepath: boundaryEnvironment.AWS_CONFIG_FILE }
|
|
1309
|
+
: {}),
|
|
1310
|
+
...(boundaryEnvironment.AWS_SHARED_CREDENTIALS_FILE
|
|
1311
|
+
? {
|
|
1312
|
+
credentialsFilepath: boundaryEnvironment.AWS_SHARED_CREDENTIALS_FILE,
|
|
1313
|
+
}
|
|
1314
|
+
: {}),
|
|
1315
|
+
expectedAccountId: account,
|
|
1316
|
+
...(productionPostgresDeclared
|
|
1317
|
+
? {
|
|
1318
|
+
expectedCapacity: {
|
|
1319
|
+
max: Number.parseFloat(profile.aurora.max),
|
|
1320
|
+
min: Number.parseFloat(profile.aurora.min),
|
|
1321
|
+
},
|
|
1322
|
+
}
|
|
1323
|
+
: {}),
|
|
1324
|
+
expectedRegion: region,
|
|
1325
|
+
expectedRoleArn,
|
|
1326
|
+
now: now(),
|
|
1327
|
+
priorDiscovery: productionDatabaseAfterFoundation,
|
|
1328
|
+
...(transport ? { profile: transport.profile } : {}),
|
|
1329
|
+
requireExisting: productionPostgresDeclared,
|
|
1330
|
+
});
|
|
1331
|
+
if (!productionPostgresDeclared) {
|
|
1332
|
+
assertSqlFreeProductionDatabase(finalDiscovery, productionDatabaseAfterFoundation);
|
|
1333
|
+
}
|
|
1334
|
+
children.push({
|
|
1335
|
+
completedAt: now().toISOString(),
|
|
1336
|
+
outcome: 'succeeded',
|
|
1337
|
+
project: foundationProject,
|
|
1338
|
+
startedAt: finalPostflightStartedAt,
|
|
1339
|
+
target: 'production-database-final-postflight',
|
|
1340
|
+
});
|
|
1341
|
+
}
|
|
1342
|
+
catch (error) {
|
|
1343
|
+
children.push({
|
|
1344
|
+
completedAt: now().toISOString(),
|
|
1345
|
+
outcome: 'failed',
|
|
1346
|
+
project: foundationProject,
|
|
1347
|
+
startedAt: finalPostflightStartedAt,
|
|
1348
|
+
target: 'production-database-final-postflight',
|
|
1349
|
+
});
|
|
1350
|
+
throw error;
|
|
1351
|
+
}
|
|
1352
|
+
}
|
|
1353
|
+
finalPhase = 'final-source-validation';
|
|
1354
|
+
assertDeploymentSourceUnchanged(context.root, source, run);
|
|
1355
|
+
if (transport) {
|
|
1356
|
+
finalPhase = 'credential-cleanup';
|
|
1357
|
+
transport.cleanup();
|
|
1358
|
+
transport = undefined;
|
|
1359
|
+
}
|
|
1360
|
+
outcome = 'succeeded';
|
|
1361
|
+
retain();
|
|
1362
|
+
devkit_1.logger.info(`${githubAuthority ? 'Protected GitHub' : 'Local'} ${options.stage} deployment completed through native SST for ${children.filter(({ target }) => target === 'deploy').length} project(s).`);
|
|
1363
|
+
return { success: true };
|
|
1364
|
+
}
|
|
1365
|
+
catch (error) {
|
|
1366
|
+
devkit_1.logger.error(error instanceof Error ? error.message : String(error));
|
|
1367
|
+
if (transport) {
|
|
1368
|
+
try {
|
|
1369
|
+
transport.cleanup();
|
|
1370
|
+
transport = undefined;
|
|
1371
|
+
}
|
|
1372
|
+
catch {
|
|
1373
|
+
finalPhase = 'credential-cleanup';
|
|
1374
|
+
devkit_1.logger.error('Local federated credential transport cleanup failed; deployment acceptance is blocked.');
|
|
1375
|
+
}
|
|
1376
|
+
}
|
|
1377
|
+
const failedChild = [...children]
|
|
1378
|
+
.reverse()
|
|
1379
|
+
.find((child) => child.outcome === 'failed');
|
|
1380
|
+
const project = failedChild?.project ?? context.projectName ?? 'workspace';
|
|
1381
|
+
failure = {
|
|
1382
|
+
project,
|
|
1383
|
+
operation: 'deploy',
|
|
1384
|
+
...(error instanceof NativeChildReconciliationError
|
|
1385
|
+
? { secondaryPhases: ['source-reconciliation'] }
|
|
1386
|
+
: {}),
|
|
1387
|
+
phase: finalPhase === 'credential-cleanup'
|
|
1388
|
+
? finalPhase
|
|
1389
|
+
: (failedChild?.target ?? finalPhase),
|
|
1390
|
+
mutationStatus: children.some((child) => child.target === 'deploy')
|
|
1391
|
+
? 'may-have-changed'
|
|
1392
|
+
: 'not-attempted',
|
|
1393
|
+
nextAction: githubAuthority
|
|
1394
|
+
? 'Resolve the reported native failure, then retry the protected Deploy workflow for this source and stage.'
|
|
1395
|
+
: `Resolve the reported native failure, then rerun pnpm nx run ${context.projectName ?? 'workspace'}:deploy-local -- --stage=${options.stage} --expectedRoleArn=<stage-role-arn> with the configured temporary credential profile.`,
|
|
1396
|
+
};
|
|
1397
|
+
devkit_1.logger.error(`Deployment failed: project=${failure.project}; operation=${failure.operation}; phase=${failure.phase}; mutation=${failure.mutationStatus}. ${failure.nextAction}`);
|
|
1398
|
+
retain();
|
|
1399
|
+
return { success: false };
|
|
1400
|
+
}
|
|
1401
|
+
}
|
|
1402
|
+
const executor = (options, context) => runLocalDeploy(options, context);
|
|
1403
|
+
exports.default = executor;
|
|
1404
|
+
//# sourceMappingURL=local-deploy.js.map
|