everything-dev
Version:
A consolidated product package for building Module Federation apps with oRPC APIs.
1 lines • 21.2 kB
Source Map (JSON)
{"version":3,"file":"deploy.cjs","names":["Effect","ResolutionSessionService","DeployTrainService","MISSING_CONFIG_MESSAGE","fetchRollbackHistory","summarizeSlotPins","fetchLiveConfig","isSnapshotLive","verifyRollbackSnapshot","publishRollbackSnapshot","fetchDeployManifests","process","isValidImageDigest","openResolution","runPostPublishLegs"],"sources":["../../src/handlers/deploy.ts"],"sourcesContent":["import process from \"node:process\";\nimport { Effect } from \"effect\";\nimport { MISSING_CONFIG_MESSAGE } from \"../config\";\nimport type {\n DeployResult,\n PublishResult,\n RollbackResult,\n WorkspaceDeployResult,\n} from \"../contract\";\nimport type { PublishTrainError, PublishTrainOk } from \"../services/deploy/errors\";\nimport { isValidImageDigest } from \"../services/deploy/image\";\nimport { runPostPublishLegs } from \"../services/deploy/legs\";\nimport { summarizeSlotPins, verifyRollbackSnapshot } from \"../services/deploy/rollback\";\nimport {\n fetchLiveConfig,\n fetchRollbackHistory,\n isSnapshotLive,\n publishRollbackSnapshot,\n} from \"../services/deploy/rollback-flow\";\nimport { type DeployTrainInput, DeployTrainService } from \"../services/deploy/train\";\nimport { fetchDeployManifests } from \"../services/registry/fastkv\";\nimport { openResolution, ResolutionSessionService } from \"../services/resolution/session\";\nimport type { BosConfig, BosConfigInput, RuntimeConfig } from \"../types\";\nimport type { BosBuilder } from \"./shared\";\n\ntype TrainErrorResult = {\n status: \"error\";\n registryUrl: string;\n error: string;\n txHash?: string;\n built?: string[];\n skipped?: string[];\n deployResults?: WorkspaceDeployResult[];\n};\n\ntype TrainOk = PublishTrainOk & { status: \"published\" | \"dry-run\" };\ntype TrainResult = TrainOk | TrainErrorResult;\n\nconst mapTrainError = (error: PublishTrainError) =>\n Effect.succeed({ ...error.toResult(), status: \"error\" as const }) as Effect.Effect<TrainResult>;\n\nfunction unknownAuthoredKeysError(keys: readonly string[]): string {\n return (\n `The authored config has unknown keys: ${keys.join(\", \")} — remove them from bos.app.ts. ` +\n \"ci.image in particular was retired (ADR 0034): children pin the runtime image via \" +\n 'platform: \"<version>\" (the platform release manifest resolves the image ref and digest ' +\n \"at deploy time); the root runtime derives its image from repository.\"\n );\n}\n\nexport function registerDeploy(builder: BosBuilder) {\n return {\n publish: builder.publish.effect(function* (_opts, input) {\n const session = yield* ResolutionSessionService;\n const train = yield* DeployTrainService;\n if (!session?.config) {\n return {\n status: \"error\" as const,\n registryUrl: \"\",\n error: MISSING_CONFIG_MESSAGE,\n } satisfies PublishResult;\n }\n\n const result: TrainResult = yield* train\n .publish({\n bosConfig: session.config,\n runtimeConfig: session.runtime,\n configDir: session.root,\n env: input.env,\n build: false,\n dryRun: input.dryRun,\n verbose: input.verbose,\n packages: \"all\",\n network: input.network,\n privateKey: input.privateKey,\n wallet: input.wallet,\n registry: input.registry,\n })\n .pipe(Effect.catchTag(\"PublishTrainError\", mapTrainError));\n\n return {\n status: result.status,\n registryUrl: result.registryUrl,\n txHash: result.txHash,\n ...(result.status === \"error\" && result.error ? { error: result.error } : {}),\n built: result.built,\n skipped: result.skipped,\n deployResults: result.deployResults,\n } satisfies PublishResult;\n }),\n\n rollback: builder.rollback.effect(function* (_opts, input) {\n const session = yield* ResolutionSessionService;\n if (!session) {\n return {\n status: \"error\" as const,\n registryUrl: \"\",\n error: MISSING_CONFIG_MESSAGE,\n } satisfies RollbackResult;\n }\n\n return yield* Effect.tryPromise({\n try: () => rollbackBody(session, input),\n catch: (error) => ({\n status: \"error\" as const,\n registryUrl: \"\",\n error: error instanceof Error ? error.message : String(error),\n }),\n });\n }),\n\n deploy: builder.deploy.effect(function* (_opts, input) {\n const session = yield* ResolutionSessionService;\n const train = yield* DeployTrainService;\n if (!session?.config) {\n return {\n status: \"error\" as const,\n registryUrl: \"\",\n error: MISSING_CONFIG_MESSAGE,\n } satisfies DeployResult;\n }\n const retiredKeys = session.unknownAuthoredKeys;\n if (retiredKeys.length > 0) {\n return {\n status: \"error\" as const,\n registryUrl: \"\",\n error: unknownAuthoredKeysError(retiredKeys),\n } satisfies DeployResult;\n }\n const config = session.config;\n const deploySession = {\n config,\n runtime: session.runtime,\n root: session.root,\n rawConfig: session.rawConfig,\n };\n\n return yield* Effect.tryPromise({\n try: () => deployBody(train, deploySession, input),\n catch: (error) => ({\n status: \"error\" as const,\n registryUrl: \"\",\n error: error instanceof Error ? error.message : String(error),\n }),\n });\n }),\n };\n}\n\nasync function rollbackBody(\n session: { config: BosConfig | null; runtime: RuntimeConfig | null; root: string },\n input: {\n registry?: string;\n limit: number;\n listOnly: boolean;\n version?: string;\n previous: boolean;\n force: boolean;\n env: \"production\" | \"staging\";\n dryRun: boolean;\n verbose: boolean;\n network?: \"mainnet\" | \"testnet\";\n privateKey?: string;\n wallet: boolean;\n },\n): Promise<RollbackResult> {\n const { account, domain } = session.config ?? {};\n if (!account || !domain) {\n return {\n status: \"error\",\n registryUrl: \"\",\n error: \"authored config must define account and domain to roll back\",\n };\n }\n\n let history: Awaited<ReturnType<typeof fetchRollbackHistory>>;\n try {\n history = await fetchRollbackHistory({\n account,\n domain,\n registry: input.registry,\n limit: input.limit,\n });\n } catch (error) {\n return {\n status: \"error\",\n registryUrl: \"\",\n error: `Failed to fetch publish history: ${error instanceof Error ? error.message : String(error)}`,\n };\n }\n\n if (history.length === 0) {\n return {\n status: \"error\",\n registryUrl: \"\",\n error: `No publish history for ${account}/${domain} — nothing to roll back to`,\n };\n }\n\n const historyEntries = history.map((entry) => ({\n blockHeight: entry.blockHeight,\n blockTimestamp: new Date(Number(entry.blockTimestampNs.slice(0, 13))).toISOString(),\n ...(entry.txHash ? { txHash: entry.txHash } : {}),\n summary: summarizeSlotPins(entry.value as BosConfigInput),\n }));\n\n if (input.listOnly) {\n return {\n status: \"list\",\n registryUrl: \"\",\n history: historyEntries,\n };\n }\n\n const target =\n input.version !== undefined\n ? history.find((entry) => {\n const iso = new Date(Number(entry.blockTimestampNs.slice(0, 13))).toISOString();\n return (\n String(entry.blockHeight) === input.version || iso.startsWith(input.version as string)\n );\n })\n : input.previous\n ? history[1]\n : undefined;\n\n if (!target) {\n return {\n status: \"error\",\n registryUrl: \"\",\n history: historyEntries,\n error: input.version\n ? `No history entry matches \"${input.version}\" — pick a block height from the listing`\n : \"Specify --version <block-height> or --previous (interactive selection happens CLI-side)\",\n };\n }\n\n const liveValue = await fetchLiveConfig({ account, domain, registry: input.registry });\n if (liveValue !== undefined && isSnapshotLive(target.value, liveValue)) {\n return {\n status: \"error\",\n registryUrl: \"\",\n error: \"The selected snapshot is identical to the live config — nothing to do\",\n };\n }\n\n const verification = await verifyRollbackSnapshot(target.value as BosConfigInput);\n const slotChecks = verification.slots.map((check) => ({\n slot: check.slot,\n ok: check.ok,\n ...(check.reason ? { reason: check.reason } : {}),\n }));\n if (!verification.ok && verification.verifiable) {\n return {\n status: \"error\",\n registryUrl: \"\",\n verification: slotChecks,\n error: \"Refusing to roll back — a pinned slot's bytes are gone or no longer match their SRI\",\n };\n }\n\n if (!verification.verifiable && !input.force) {\n return {\n status: \"error\",\n registryUrl: \"\",\n error:\n \"Snapshot predates version manifests and cannot be verified — its bytes were overwritten in place. Re-run with --force to publish it anyway.\",\n };\n }\n\n const rollback = await publishRollbackSnapshot(\n target.value,\n {\n account,\n domain,\n env: input.env,\n runtimeConfig: session.runtime,\n configDir: session.root,\n registry: input.registry,\n network: input.network,\n privateKey: input.privateKey,\n wallet: input.wallet,\n verbose: input.verbose,\n dryRun: input.dryRun,\n },\n { skipVerify: true },\n );\n if (!rollback.ok) {\n return {\n status: \"error\",\n registryUrl: rollback.registryUrl,\n history: historyEntries,\n error: rollback.error,\n };\n }\n\n return {\n status: rollback.dryRun ? \"dry-run\" : \"published\",\n registryUrl: rollback.registryUrl,\n txHash: rollback.txHash,\n history: historyEntries,\n ...(slotChecks.length > 0 ? { verification: slotChecks } : {}),\n };\n}\n\nasync function deployBody(\n train: {\n publish: (input: DeployTrainInput) => Effect.Effect<PublishTrainOk, PublishTrainError>;\n },\n session: {\n config: BosConfig;\n runtime: RuntimeConfig | null;\n root: string;\n rawConfig: BosConfigInput | null;\n },\n input: {\n registry?: string;\n statusList: boolean;\n env: \"production\" | \"staging\";\n build: boolean;\n dryRun: boolean;\n verbose: boolean;\n packages: string;\n network?: \"mainnet\" | \"testnet\";\n privateKey?: string;\n service?: string;\n imageDigest?: string;\n fullUpload: boolean;\n smoke: boolean;\n },\n): Promise<DeployResult> {\n if (input.statusList) {\n if (!session.config?.account || !session.config.domain) {\n return {\n status: \"error\",\n registryUrl: \"\",\n error: \"authored config must define account and domain to list deploy manifests\",\n };\n }\n try {\n const manifests = await fetchDeployManifests({\n accountId: session.config.account,\n gatewayId: session.config.domain,\n registry: input.registry,\n });\n return {\n status: \"list\",\n registryUrl: \"\",\n history: manifests.map((entry) => ({\n key: entry.key,\n blockHeight: entry.blockHeight,\n blockTimestamp: new Date(Number(entry.blockTimestampNs.slice(0, 13))).toISOString(),\n ...((entry.value as { txHash?: string } | undefined)?.txHash\n ? { txHash: (entry.value as { txHash?: string }).txHash }\n : {}),\n ...((entry.value as { publishedAt?: string } | undefined)?.publishedAt\n ? { publishedAt: (entry.value as { publishedAt?: string }).publishedAt }\n : {}),\n })),\n };\n } catch (error) {\n return {\n status: \"error\",\n registryUrl: \"\",\n error: `Failed to list deploy manifests: ${error instanceof Error ? error.message : String(error)}`,\n };\n }\n }\n\n const imageDigestInput = input.imageDigest ?? process.env.BOS_IMAGE_DIGEST;\n if (imageDigestInput && !isValidImageDigest(imageDigestInput)) {\n return {\n status: \"error\",\n registryUrl: \"\",\n error: `Invalid image digest \"${imageDigestInput}\" — expected sha256:<64 hex characters> (--image-digest / BOS_IMAGE_DIGEST)`,\n };\n }\n\n const result = await Effect.runPromise(\n train\n .publish({\n bosConfig: session.config,\n runtimeConfig: session.runtime,\n configDir: session.root,\n env: input.env,\n build: input.build,\n dryRun: input.dryRun,\n verbose: input.verbose,\n packages: input.packages,\n network: input.network,\n privateKey: input.privateKey,\n registry: input.registry,\n fullUpload: input.fullUpload,\n })\n .pipe(Effect.catchTag(\"PublishTrainError\", mapTrainError)),\n );\n\n if (result.status === \"error\") {\n return {\n status: \"error\",\n registryUrl: result.registryUrl,\n txHash: result.txHash,\n built: result.built,\n skipped: result.skipped,\n error: result.error,\n deployResults: result.deployResults,\n };\n }\n\n if (result.status === \"dry-run\") {\n return {\n status: \"dry-run\",\n registryUrl: result.registryUrl,\n built: result.built,\n skipped: result.skipped,\n };\n }\n\n let nextSession: { config: BosConfig | null; runtime: RuntimeConfig | null; root: string } = {\n config: session.config,\n runtime: session.runtime,\n root: session.root,\n };\n if (result.publishConfig) {\n const opened = await openResolution({ cwd: session.root });\n if (opened) {\n nextSession = { config: opened.config, runtime: opened.runtime, root: opened.root };\n }\n }\n\n const configPublished = {\n registryUrl: result.registryUrl,\n txHash: result.txHash,\n fingerprint: result.fingerprint,\n slotPins: result.slotPins,\n built: result.built,\n skipped: result.skipped,\n deployResults: result.deployResults,\n } as const;\n\n const legsOutcome = await runPostPublishLegs({\n sessionRoot: session.root,\n env: input.env,\n smoke: input.smoke,\n imageDigestInput,\n railwayService: input.service ?? nextSession.config?.ci?.railway?.service,\n registry: input.registry,\n network: input.network,\n privateKey: input.privateKey,\n verbose: input.verbose,\n account: nextSession.config?.account,\n domain: nextSession.config?.domain,\n runtimeConfig: nextSession.runtime,\n localConfig: session.rawConfig\n ? (session.rawConfig as unknown as Record<string, unknown>)\n : undefined,\n repository: nextSession.config?.repository,\n });\n\n if (legsOutcome.failure) {\n return {\n status: \"published\",\n ...configPublished,\n image: legsOutcome.image,\n service: legsOutcome.service,\n legs: legsOutcome.legs,\n error: legsOutcome.failure,\n };\n }\n\n return {\n status: \"deployed\",\n ...configPublished,\n image: legsOutcome.image,\n service: legsOutcome.service,\n legs: legsOutcome.legs,\n };\n}\n"],"mappings":"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"}