Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions src/core/project/backends/cdk/credentials.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ import { ProjectSpecSchema } from "../../../../projectSchemas/project";
import type { CoreOptions } from "../../../types";
import { EnvLocalFile } from "../../envLocal";
import { v0Fixture } from "../../legacy/fixtures-test-support";
import { translateV0Spec } from "../../legacy/translate";
import {
createCredentialProvisioner,
createCredentialRemover,
Expand Down Expand Up @@ -87,7 +86,7 @@ async function legacyProject(credentials: unknown[], envLocal?: string): Promise
const v0Spec = v0Fixture("baseline.json");
return {
...(await project(credentials, envLocal)),
legacy: { format: "v0", v0Spec, extras: translateV0Spec(v0Spec).extras },
legacy: { format: "v0", v0Spec },
};
}

Expand Down
10 changes: 8 additions & 2 deletions src/core/project/legacy/deploy.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import type { InheritedProcessOptions, InheritedProcessRunner } from "../../../i
import { executeV0Deploy, V0_CLI_PACKAGE } from "./deploy";

describe("executeV0Deploy", () => {
test("pins the final v0 CLI and forwards deploy flags from the project root", async () => {
test("uses the latest v0 CLI and forwards deploy flags from the project root", async () => {
const calls: Array<{ command: string[]; options: InheritedProcessOptions }> = [];
const runner: InheritedProcessRunner = async (command, options) => {
calls.push({ command, options });
Expand All @@ -14,6 +14,7 @@ describe("executeV0Deploy", () => {
{
projectRoot: "/workspace/project",
target: "staging",
region: "eu-west-1",
yes: true,
json: true,
},
Expand All @@ -30,6 +31,8 @@ describe("executeV0Deploy", () => {
"deploy",
"--target",
"staging",
"--region",
"eu-west-1",
"--yes",
"--json",
],
Expand All @@ -50,6 +53,7 @@ describe("executeV0Deploy", () => {
{
projectRoot: "/workspace/project",
target: "default",
region: "us-east-1",
yes: false,
json: false,
},
Expand All @@ -59,6 +63,8 @@ describe("executeV0Deploy", () => {
},
);

expect(commands).toEqual([["npx", "--yes", V0_CLI_PACKAGE, "deploy", "--target", "default"]]);
expect(commands).toEqual([
["npx", "--yes", V0_CLI_PACKAGE, "deploy", "--target", "default", "--region", "us-east-1"],
]);
});
});
6 changes: 4 additions & 2 deletions src/core/project/legacy/deploy.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import { runInheritedProcess, type InheritedProcessRunner } from "../../../io";

export const V0_CLI_VERSION = "0.31.1";
export const V0_CLI_PACKAGE = `@aws/agentcore@${V0_CLI_VERSION}`;
export const V0_CLI_PACKAGE = "@aws/agentcore@0";

export type V0DeployInput = {
projectRoot: string;
target: string;
region: string;
yes: boolean;
json: boolean;
};
Expand All @@ -25,6 +25,8 @@ export async function executeV0Deploy(
"deploy",
"--target",
input.target,
"--region",
input.region,
...(input.yes ? ["--yes"] : []),
...(input.json ? ["--json"] : []),
];
Expand Down
4 changes: 2 additions & 2 deletions src/core/project/legacy/load.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,11 @@ import { translateV0Spec } from "./translate";
/** Parse a v0 project with v0's schema and expose a translated, read-only in-memory view. */
export async function loadLegacyProject(rootPath: string, json: ReadWriteJson): Promise<Project> {
const v0Spec = await json.read(projectSpecPath(rootPath), V0AgentCoreProjectSpecSchema);
const { spec, extras } = translateV0Spec(v0Spec);
const { spec } = translateV0Spec(v0Spec);
return {
name: v0Spec.name,
rootPath,
spec,
legacy: { format: "v0", v0Spec, extras },
legacy: { format: "v0", v0Spec },
};
}
24 changes: 16 additions & 8 deletions src/core/project/legacy/translate.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,16 +11,17 @@ describe("translateV0Spec", () => {
expect("$schema" in spec).toBe(false);
});

test("moves v0-only collections into extras and drops httpGateways", () => {
const { spec, extras } = translateV0Spec(v0Fixture("top-abTests-nonempty.json"));
for (const key of ["abTests", "datasets", "capacityProviders", "httpGateways"]) {
test("drops collections that have no v1 equivalent from the translated view", () => {
const { spec } = translateV0Spec(v0Fixture("top-abTests-nonempty.json"));
for (const key of [
"abTests",
"datasets",
"capacityProviders",
"unassignedTargets",
"httpGateways",
]) {
expect(key in spec).toBe(false);
}
expect(extras.abTests?.length).toBeGreaterThan(0);

const unassigned = translateV0Spec(v0Fixture("top-unassignedTargets.json"));
expect("unassignedTargets" in unassigned.spec).toBe(false);
expect(unassigned.extras.unassignedTargets?.length).toBeGreaterThan(0);
});

test("renames mcpRuntimeTools to toolRuntimes and artifact to build", () => {
Expand All @@ -36,6 +37,13 @@ describe("translateV0Spec", () => {
expect("toolRuntimes" in spec).toBe(false);
});

test("omits toolRuntimes when v0 had an empty mcpRuntimeTools array", () => {
const v0 = v0Fixture("baseline.json");
v0.mcpRuntimeTools = [];
const { spec } = translateV0Spec(v0);
expect("toolRuntimes" in spec).toBe(false);
});

test("renames artifact to build on gateway target compute", () => {
const { spec } = translateV0Spec(
v0Fixture("gateway-target-mcpServer-agentcoreRuntime-compute.json"),
Expand Down
35 changes: 17 additions & 18 deletions src/core/project/legacy/translate.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import type { ProjectSpec } from "../../../projectSchemas/project";
import type { V0ProjectSpec } from "../../../projectSchemas/v0";
import type { LegacyExtras } from "./types";

type Json = Record<string, unknown>;

Expand All @@ -21,20 +20,21 @@ function renameArtifact(compute: unknown): unknown {
* another name. Callers that need a valid v1 spec (migrate) validate the result.
*
* - `version` becomes 2 and `$schema` is dropped.
* - `abTests`, `datasets`, `capacityProviders`, and `unassignedTargets` move into
* the returned extras; `httpGateways` (always empty in v0) is dropped.
* - `abTests`, `datasets`, `capacityProviders`, `unassignedTargets`, and
* `httpGateways` have no v1 equivalent and are dropped from the translated
* view. They remain available on `legacy.v0Spec`.
* - `mcpRuntimeTools` becomes `toolRuntimes`, and every tool runtime's and gateway
* target's `compute.runtime.artifact` becomes `build`.
* - Runtime `capacityProviderVolume` mounts are dropped: v1 has no capacity
* providers, and its code switches over the mount kinds it knows.
*/
export function translateV0Spec(v0: V0ProjectSpec): { spec: ProjectSpec; extras: LegacyExtras } {
export function translateV0Spec(v0: V0ProjectSpec): { spec: ProjectSpec } {
const {
$schema: _schema,
abTests,
datasets,
capacityProviders,
unassignedTargets,
abTests: _abTests,
datasets: _datasets,
capacityProviders: _capacityProviders,
unassignedTargets: _unassignedTargets,
httpGateways: _httpGateways,
mcpRuntimeTools,
...rest
Expand All @@ -60,16 +60,15 @@ export function translateV0Spec(v0: V0ProjectSpec): { spec: ProjectSpec; extras:
version: 2,
runtimes,
agentCoreGateways,
...(mcpRuntimeTools && {
toolRuntimes: (mcpRuntimeTools as Json[]).map((tool) => ({
...tool,
compute: renameArtifact(tool.compute),
})),
}),
...(mcpRuntimeTools?.length
? {
toolRuntimes: (mcpRuntimeTools as Json[]).map((tool) => ({
...tool,
compute: renameArtifact(tool.compute),
})),
}
: {}),
} as unknown as ProjectSpec;

return {
spec,
extras: { abTests, datasets, capacityProviders, unassignedTargets } as LegacyExtras,
};
return { spec };
}
7 changes: 0 additions & 7 deletions src/core/project/legacy/types.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,7 @@
import type { V0ProjectSpec } from "../../../projectSchemas/v0";

/** The v0 collections that have no place in v1's spec, kept aside by the translator. */
export type LegacyExtras = Pick<
V0ProjectSpec,
"abTests" | "datasets" | "capacityProviders" | "unassignedTargets"
>;

export type LegacyProjectInfo = {
format: "v0";
/** The v0 spec as parsed by the v0 schema; the source of truth for v0-only reads. */
v0Spec: V0ProjectSpec;
extras: LegacyExtras;
};
6 changes: 0 additions & 6 deletions src/handlers/project/buildDeploy.screen.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -216,12 +216,6 @@ describe("project deploy screen", () => {
legacy: {
format: "v0",
v0Spec: {} as never,
extras: {
abTests: [],
datasets: [],
capacityProviders: [],
unassignedTargets: [],
},
},
} as Project;
core.projectManager.listTargets = async () => [
Expand Down
7 changes: 4 additions & 3 deletions src/handlers/project/deploy/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,7 @@ describe("project deploy handler", () => {
test.each(["--yes", "--json"])(
"delegates a legacy deploy with %s before resolving an account or using v1 CDK",
async (flag) => {
const projectRoot = await inProjectWithTargets();
const projectRoot = await inProjectWithTargets("[]");
const specPath = join(projectRoot, "agentcore", "agentcore.json");
const manifestPath = join(projectRoot, "agentcore", "cdk", "package.json");
await writeFile(specPath, JSON.stringify({ name: "orders", version: 1 }));
Expand All @@ -189,14 +189,15 @@ describe("project deploy handler", () => {
},
});

await subject.run([flag]);
await subject.run(["--region", "eu-west-2", flag]);

expect(subject.calls).toEqual([]);
expect(accountCalls).toEqual([]);
expect(legacyDeploys).toEqual([
{
projectRoot,
target: "default",
region: "eu-west-2",
yes: flag === "--yes",
json: flag === "--json",
},
Expand All @@ -205,7 +206,7 @@ describe("project deploy handler", () => {
expect(subject.io.stderr()).toBe(
flag === "--json"
? ""
: "This is a v0 project; running AgentCore CLI 0.31.1 deploy in compatibility mode.",
: "This is a v0 project; running the latest v0 AgentCore CLI deploy in compatibility mode.",
);
expect(
await Promise.all([readFile(specPath, "utf8"), readFile(manifestPath, "utf8")]),
Expand Down
10 changes: 4 additions & 6 deletions src/handlers/project/deploy/index.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,7 @@
import { createInterface } from "node:readline/promises";
import z from "zod";
import { enclosingProjectRoot, isV0Project } from "../../../core/project/fsUtils";
import {
runV0Deploy,
V0_CLI_VERSION,
type V0DeployRunner,
} from "../../../core/project/legacy/deploy";
import { runV0Deploy, type V0DeployRunner } from "../../../core/project/legacy/deploy";
import { SilentCLIError, UserCancellationError } from "../../../errors";
import type { AppIO } from "../../../io";
import { DEFAULT_TARGET_NAME } from "../../../projectSchemas/aws-targets";
Expand Down Expand Up @@ -87,6 +83,7 @@ export const createDeployProjectHandler = (config: DeployProjectHandlerConfig) =
await delegateV0Deploy(config, {
projectRoot: project.rootPath,
target: flags.target,
region: ctx.require(RegionKey),
yes: flags.yes,
json: jsonOutput,
});
Expand Down Expand Up @@ -198,6 +195,7 @@ function withV0Deploy(config: DeployProjectHandlerConfig): Middleware {
await delegateV0Deploy(config, {
projectRoot,
target: flags.target as string,
region: ctx.require(RegionKey),
yes: flags.yes as boolean,
json: ctx.require(JsonKey),
});
Expand All @@ -214,7 +212,7 @@ async function delegateV0Deploy(
): Promise<void> {
if (!input.json) {
config.io.stderr.write(
`This is a v0 project; running AgentCore CLI ${V0_CLI_VERSION} deploy in compatibility mode.\n`,
"This is a v0 project; running the latest v0 AgentCore CLI deploy in compatibility mode.\n",
);
}
const exitCode = await (config.runV0Deploy ?? runV0Deploy)(input);
Expand Down
10 changes: 2 additions & 8 deletions src/handlers/project/dev/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -256,7 +256,6 @@ describe("project dev selection and dispatch", () => {
configuredProject.legacy = {
format: "v0",
v0Spec: {} as never,
extras: {} as never,
};
const subject = harness({ project: configuredProject });

Expand Down Expand Up @@ -695,12 +694,6 @@ describe("project dev harnesses", () => {
configuredProject.legacy = {
format: "v0",
v0Spec: {} as never,
extras: {
abTests: [],
datasets: [],
capacityProviders: [],
unassignedTargets: [],
},
};
const subject = harness({ project: configuredProject });

Expand All @@ -710,12 +703,13 @@ describe("project dev harnesses", () => {
{
projectRoot: configuredProject.rootPath,
target: "staging",
region: "us-west-2",
yes: true,
json: false,
},
]);
expect(subject.deployments).toEqual([]);
expect(subject.io.stderr()).toContain("running AgentCore CLI 0.31.1 deploy");
expect(subject.io.stderr()).toContain("running the latest v0 AgentCore CLI deploy");
});

test.each([
Expand Down
Loading