@deployfoundation/foundation-deploy

中文文档
0.2.55发布于 2026/10/27UNLICENSEDTypeScriptES Module近 30 天下载 3661

Deploys one Foundation instance from a published, signed release: the CDK app and the deploy tool.

原始使用文档
文档目录8 节
  1. The CDK app
  2. The deploy tool
  3. Deploying a release
  4. The license check
  5. Artifacts
  6. The release account (Foundry 41's own)
  7. Publishing
  8. Tests

@deployfoundation/foundation-deploy

The CDK app that deploys one Foundation instance, and foundation-deploy, the tool an instance's pipeline runs.

Foundation ships no instance file and no company configuration. Everything that identifies a deployment — account, region, Slack workspace, GitHub org, naming prefixes, which integrations are provisioned — lives in an instance YAML the deployment's own repository owns. Both halves of this package take the path to that file and derive the rest.

The CDK app

cd packages/infra
bunx cdk synth --all -c instanceFile=../../../my-instance/instance.yaml
bunx cdk deploy --all -c instanceFile=/abs/path/instance.yaml -c agentImageTag=abc1234

Context keys:

KeyMeaning
instanceFileRequired. Path to the instance YAML, absolute or relative to the working directory.
adminsCSV of Slack admin ids. Defaults to admins in the instance's runtime config.
alarmEmailDLQ alarm subscriber. Defaults to none.
agentImageTagRequired when deploying the AgentCore runtime from a local build; a release names the image instead.
releaseDeploy a published release: vX.Y.Z. The manifest is read from $FOUNDATION_RELEASE_DIR or the per-version cache directory foundation-deploy writes.
releaseManifestPath to a verified release manifest, which is what foundation-deploy --release passes.
releaseBucketThe Foundation release bucket the manifest's keys live in. Required in release mode (or FOUNDATION_RELEASE_BUCKET).
deployRuntime=falseBootstrap phase: every stack except the runtime.
pipelineInstanceFileWhere the instance file sits inside the repo a CodePipeline sources, when that differs from the path given here.
vpcId, createVpcEndpoints, skipEndpoints, agentSubnetIdsNetwork escape hatches, unchanged.

instance.config is resolved relative to the instance file's own directory, so an instance repository whose layout is .foundation/{instance.yaml,config.yaml} writes config: config.yaml and nothing else.

FOUNDATION_SKIP_BUNDLE=1 swaps every Lambda bundle for an inline stub. It is what the tests use and what a synth check on a host without Docker or Bun should use.

The deploy tool

bun run packages/infra/bin/foundation-deploy.ts <command> --instance <path>
CommandWhat it does
deployBuild and push the agent image, cdk deploy --all, refresh the runtime secret (and cdk deploy once more when that changed it, so no container boots on the old one), sync config.
post-deploySmoke DEFAULT, probe the persistent mount, promote live, smoke live.
config:syncUpload the runtime config (for the deployed Foundation version, which must be this tool's) and Foundation's product skills to S3.
setupFirst-deploy orchestration, idempotent.
github-app-createCreate the instance's GitHub App from the shipped manifest template.
slack-manifestPrint the instance's Slack app manifest as JSON (the Slack CLI's get-manifest hook contract).
stage-customizationValidate and stage a tenant-owned runtime config.
crm-keyWrite the company CRM's crm/1 key, piped in with --stdin, into <secretPrefix>/crm/http (crm.provider kind http).
crm-checkRun the crm/1 conformance suite: the read cases against the instance's CRM with its stored key, or, with --base-url --tenant --key-stdin and no instance, any server, write cases included, every case strict given the server's harness endpoint (--harness-url) and the deployment's inputs (docs/crm-provider-contract.md#crm-check). A CRM can also import the suite: @deployfoundation/foundation-deploy/crm-conformance.
crm-replayReplay the agent's CRM writes (JSONL) into the instance's own table after a rollback to the DynamoDB provider.

--instance <path> is required for every command (or FOUNDATION_INSTANCE_FILE in a pipeline), except crm-check --base-url, which checks a server rather than a deployment. There is no instance name, no instances/ directory and no default: a deploy that guessed its target would be a deploy into the wrong account.

Deploying a release

# an instance repo's whole build step
npx @deployfoundation/foundation-deploy@$(cat foundation.version) deploy \
  --instance .foundation/instance.yaml

A copy of the tool installed from npm has no Foundation workspace to build from, so it deploys the release matching its own version: it fetches releases/vX.Y.Z/manifest.json from the Foundation release bucket, verifies the KMS signature and every artifact's sha256, and only then deploys. In a Foundation checkout the same command builds locally, as it always did. --release <vX.Y.Z>, --manifest <path|s3://…> and --release-bucket <name> override the choice.

Until the release account exists, set FOUNDATION_RELEASE_KMS_KEY_ARN to the published signing key ARN: the tool ships no default, because trusting the wrong key is worse than checking nothing.

The license check

deploy verifies the instance's license.key against https://license.foundry41.com/v1/verify (override with FOUNDATION_LICENSE_ENDPOINT) before it deploys, sending the key, the instance id and the version — nothing else. An instance with no key is skipped with a warning. A definite refusal stops the deploy; an unreachable endpoint does not, for 30 days, on the verification cached in the instance's own <prefix>/license/last-verified secret.

The tool never imports the agent package. It runs in a pipeline, not in the agent container.

Artifacts

src/artifacts.ts is the single place that decides where the deployed bytes come from, and it has two modes:

  • local build (the default). Every Lambda bundle is built from this checkout at synth with the pinned Bun, and deploy builds and pushes the agent image to the instance's own ECR first. A contributor deploys their working tree this way.
  • release. -c release=vX.Y.Z (or -c releaseManifest=<path>) plus -c releaseBucket=<name>: each Lambda's code is Code.fromBucket(...) on the key the signed manifest names, and the agent image is Foundation's own repository pinned by digest. Nothing is built, so the pipeline needs no Docker, no Bun and no Foundation checkout.

src/release/manifest.ts is the manifest itself — schema, builder, the canonical bytes a signature covers, and verifyManifest, which checks the KMS signature before any artifact is read and then every artifact's sha256. src/release/kms.ts is the AWS-facing half. A manifest reaching a synth has already been verified by foundation-deploy.

The release account (Foundry 41's own)

src/stacks/release-account-stack.ts is the only stack here that is not an instance's. It holds what a release is published from: the release bucket, the foundation/agent image repository, the KMS signing key, and the OIDC role .github/workflows/release.yml assumes on a tag push. Customers appear in exactly one place — the account-id list that opens the bucket, the repository and the key.

cd packages/infra
bunx cdk --app 'bun run bin/release-account.ts' diff FoundationRelease \
  -c customerAccountIds=111122223333,444455556666
bunx cdk --app 'bun run bin/release-account.ts' deploy FoundationRelease \
  -c customerAccountIds=111122223333,444455556666

Deployed once, by hand, into the release account. Its outputs are the four repository variables the release workflow needs (FOUNDATION_RELEASE_BUCKET, FOUNDATION_RELEASE_KMS_KEY_ARN, FOUNDATION_RELEASE_ROLE_ARN, and the image repository), plus the signing key ARN customers verify against. Adding a customer is a redeploy with a longer customerAccountIds.

Publishing

bun run --cwd packages/infra build   # dist/, Node target, ESM
cd packages/infra && npm pack --dry-run

The build bundles the three entry points — the CLI, the CDK app and the release-account app — into dist/, inlining the workspace packages (which are not published) and leaving every declared dependency external, so npm installs one aws-cdk-lib and both halves of the tool see it. aws-cdk itself is a dependency, not a devDependency: the tool shells out to the CDK CLI and resolves it through this package rather than through PATH.

The tarball carries dist/, src/ (the manifest templates are read from there at runtime), the agent image's Dockerfile, the reference buildspec and cdk.json. It does NOT carry bin/: those TypeScript entry points need Bun and the workspace, and shipping an app entry that cannot run is how a deploy picks the wrong one. node dist/bin/foundation-deploy.js --help works from an extracted tarball with only the runtime dependencies installed — no Bun, no Foundation checkout — which is exactly what an instance's pipeline has.

Tests

bun test packages/infra

They run under bun test with the rest of the repo — no jest, no ts-node. The snapshot test shells out to cdk synth for both fixtures, so it needs the workspace installed but no AWS credentials and no Docker.

Fixtures are synthetic (test/fixtures/): acme turns every integration on, beta is a minimal instance deployed by CodePipeline. No real company appears anywhere in this package.

版本与发布记录

@deployfoundation/foundation-deploy 共发布 60 个版本,首次发布于 2026/09/25;过去 12 个月发布了 60 个版本。

版本发布日期距今
0.2.55latest2026/10/2715 天前
0.2.542026/10/2716 天前
0.2.532026/10/2616 天前
0.2.522026/10/2617 天前
0.2.512026/10/2617 天前
0.2.502026/10/2518 天前

关于 @deployfoundation/foundation-deploy 的常见问题

@deployfoundation/foundation-deploy 是什么?

Deploys one Foundation instance from a published, signed release: the CDK app and the deploy tool.

如何安装 @deployfoundation/foundation-deploy?

在项目目录运行 npm install @deployfoundation/foundation-deploy,或使用 pnpm add / yarn add / bun add。它还提供命令行工具 foundation-deploy,可以用 npx foundation-deploy 直接运行。

@deployfoundation/foundation-deploy 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@deployfoundation/foundation-deploy 支持 ESM 还是 CommonJS?

以 ES Module 形式发布,推荐使用 import 引入。在 CommonJS 项目中,Node.js 20.19+ / 22.12+ 可以直接 require() 不含顶层 await 的 ES Module,更早的版本需要改用动态 import()。

@deployfoundation/foundation-deploy 可以商用吗?

@deployfoundation/foundation-deploy 使用 UNLICENSED 许可。作者声明为 UNLICENSED,即不授予公开使用许可(与公共领域的 Unlicense 不同)。使用前需获得作者授权。以上为概括,不构成法律意见,请以许可原文为准。

@deployfoundation/foundation-deploy 的下载量有多少?

根据 npm 官方下载统计,@deployfoundation/foundation-deploy 在 2026/10/12 – 2026/11/10 这 30 天内被下载 3,661 次,日均约 122 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@deployfoundation/foundation-deploy 还在维护吗?

最新版本 0.2.55 发布于 2026/10/27(15 天前);至今共发布 60 个版本,其中过去 12 个月发布了 60 个;首次发布于 2026/09/25。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。