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
4 changes: 2 additions & 2 deletions packages/cli/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@
"dependencies": {
"@manypkg/tools": "^2.1.2",
"@prisma/cli-engine": "workspace:0.9.0",
"@prisma/composer-cli": "0.34.0",
"@prisma/composer-cli": "0.35.0",
"@prisma/compute-sdk": "0.43.0",
"@prisma/management-api-sdk": "1.80.0",
"@prisma/orm-toolchain": "8.0.0-rc.20",
Expand All @@ -62,7 +62,7 @@
"open": "^11.0.0"
},
"devDependencies": {
"@prisma/composer": "0.34.0",
"@prisma/composer": "0.35.0",
"@prisma/credentials-store": "^7.8.0",
"@repo/cli-conformance": "workspace:8.0.0-rc.27",
"@repo/cli-telemetry": "workspace:8.0.0-rc.27",
Expand Down
9 changes: 7 additions & 2 deletions packages/cli/src/cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -346,6 +346,10 @@ export const cliGroups: Readonly<
"A ref is a named pointer to a contract, letting commands target a contract by a stable name. Set, list, and delete refs here.",
},
orm: { brief: "Initialize a Prisma ORM project" },
deploy: {
brief:
"Deploy your app to Prisma Cloud, and list what a stage has deployed",
},
dev: {
brief:
"Run your app on this machine, with no Prisma account. Start it, print a node's local URL, stop it",
Expand Down Expand Up @@ -421,9 +425,10 @@ export const mountedCommands: Readonly<Record<string, AnyCommand>> = {
"service domain delete": serviceDomainDeleteCommand,
"service domain retry": serviceDomainRetryCommand,
"service domain wait": serviceDomainWaitCommand,
// Composer's product verbs: deploy and dev at the root, dev's
// children beneath it, and the local emulators under their own group.
// Composer's product verbs: deploy and dev at the root, their
// children beneath them, and the local emulators under their own group.
deploy: composerCommandFamily.commands.deploy,
"deploy list": composerCommandFamily.commands["deploy list"],
dev: composerCommandFamily.commands.dev,
"dev url": composerCommandFamily.commands["dev url"],
"dev stop": composerCommandFamily.commands["dev stop"],
Expand Down
1 change: 1 addition & 0 deletions packages/cli/tests/bin.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -533,6 +533,7 @@ describe("buildCli", () => {
"--json",
"--config",
configPath,
"--entry",
"src/service.ts",
],
});
Expand Down
62 changes: 58 additions & 4 deletions packages/cli/tests/composer-mount.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,13 @@
* what a pipe receives, not Composer's dev logic, which Composer's own
* integration tests run against real emulators.
*/
import { createTestCli } from "@prisma/cli-engine/testing";
import { createTestCli, mintTestJwt } from "@prisma/cli-engine/testing";
import { defineConfig as composer } from "@prisma/composer/config";
import { nodeBuild } from "@prisma/composer/node/control";
import {
createComposerFamily,
type DeployedNode,
type ListDeployed,
type ListEmulators,
} from "@prisma/composer-cli/family";
import { createOperationsDouble } from "@prisma/composer-cli/testing";
Expand Down Expand Up @@ -70,30 +72,73 @@ const ONE_INSTANCE = listing([
{ kind: "database", running: false, url: null, instances: [], error: null },
]);

const COMPOSER_PATHS = ["dev", "dev url", "dev stop", "emulator list"];
const DEPLOYED: readonly DeployedNode[] = [
{ address: "shop", kind: "project", platformId: "proj_1", url: null },
{
address: "shop.api",
kind: "service",
platformId: "cps_1",
url: "https://api.example.prisma.build",
},
];

const listDeployed: ListDeployed = async () => ({
ok: true,
value: DEPLOYED,
assertOk: () => DEPLOYED,
assertNotOk: () => {
throw new Error("listDeployed succeeded");
},
});

const COMPOSER_PATHS = [
"deploy list",
"dev",
"dev url",
"dev stop",
"emulator list",
];

function shell(emulators: Listing = listing([])) {
const family = createComposerFamily({
operations: createOperationsDouble().operations,
listEmulators: async () => emulators,
listDeployed,
});
const commands = Object.fromEntries(
COMPOSER_PATHS.map((path) => [path, family.commands[path]]),
);
return createTestCli({
commandFamilies: [family],
commands,
groups: { dev: cliGroups.dev, emulator: cliGroups.emulator },
groups: {
deploy: cliGroups.deploy,
dev: cliGroups.dev,
emulator: cliGroups.emulator,
},
config: { composer: COMPOSER_SECTION },
sessions: [
{
workspaceId: "ws_1",
workspaceName: "Acme Inc",
credential: {
token: mintTestJwt({ sub: "usr_1", workspace_id: "ws_1" }),
refreshToken: undefined,
expiresAt: undefined,
},
},
],
selectedWorkspaceId: "ws_1",
now: () => new Date(0),
});
}

describe("Composer's commands in the shell", () => {
it("mounts Composer's dev children and emulator list where the shell says", () => {
it("mounts Composer's deploy and dev children and emulator list where the shell says", () => {
for (const path of COMPOSER_PATHS) {
expect(mountedCommands[path], path).toBeDefined();
}
expect(cliGroups.deploy).toBeDefined();
expect(cliGroups.dev).toBeDefined();
expect(cliGroups.emulator?.description).toContain("emulator");
});
Expand All @@ -112,6 +157,15 @@ describe("Composer's commands in the shell", () => {
expect(result.stdout).toBe("");
});

it("pipes one tab-separated line per deployed node from deploy list", async () => {
const result = await shell().run(["deploy", "list"]);

expect(result.exitCode).toBe(0);
expect(result.stdout).toBe(
"shop\tproject\tproj_1\t\nshop.api\tservice\tcps_1\thttps://api.example.prisma.build\n",
);
});

it("lists emulators", async () => {
const result = await shell().run(["emulator", "list"]);

Expand Down
2 changes: 2 additions & 0 deletions packages/cli/tests/e2e-coverage.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,8 @@ const EXCLUSIONS: Readonly<Record<string, string>> = {
"Needs a connected repository, which `git connect` cannot create here.",
deploy:
"Provisions real cloud infrastructure for an app entry point, through a child `alchemy deploy`. Standing that up per CI run is neither cheap nor unattended-safe.",
"deploy list":
"Lists a deployed Composer app's stage, and this suite deploys none (see `deploy`). Composer's e2e deploy workflow runs it after every deploy and checks it against the platform.",
dev: "A session command: it runs until SIGINT or SIGTERM, redeploying on file change, so it has no happy path that terminates on its own.",
"dev url": LOCAL_EMULATOR_REASON,
"dev stop": LOCAL_EMULATOR_REASON,
Expand Down
1 change: 1 addition & 0 deletions packages/cli/tests/mount-coverage.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@ const EXPECTED_MOUNT_PATHS: readonly string[] = [
"db update",
"db verify",
"deploy",
"deploy list",
"dev",
"dev stop",
"dev url",
Expand Down
2 changes: 1 addition & 1 deletion packages/prisma/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@
"dependencies": {
"@manypkg/tools": "^2.1.2",
"@prisma/cli-engine": "workspace:0.9.0",
"@prisma/composer-cli": "0.34.0",
"@prisma/composer-cli": "0.35.0",
"@prisma/compute-sdk": "0.43.0",
"@prisma/management-api-sdk": "1.80.0",
"@prisma/orm-toolchain": "8.0.0-rc.20",
Expand Down
27 changes: 14 additions & 13 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

12 changes: 8 additions & 4 deletions skills/prisma-platform-core-concepts/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ import { defineConfig as orm } from "@prisma/orm-postgres/config";

export default definePrismaConfig({
composer: composer({
entry: "./module.ts",
extensions: [prismaCloud(), nodeBuild()],
state: prismaState(),
}),
Expand Down Expand Up @@ -144,7 +145,7 @@ branch is the environment, and branches come into being by deploying to them:
1. **Push a git branch** (with the GitHub integration connected and the
deploy workflow in the repository): the workflow builds and deploys, and
the platform creates the branch environment on the fly.
2. **Deploy a stage from the CLI**: `prisma deploy module.ts --stage pr-42`
2. **Deploy a stage from the CLI**: `prisma deploy --stage pr-42`
creates a branch named `pr-42` and deploys the identical app graph into
it. A stage name must be a valid git ref name; an invalid name is a hard
error.
Expand Down Expand Up @@ -208,8 +209,11 @@ Opening a pull request does not itself deploy anything; previews track
branch pushes. A connected repository without the workflow gets branch
bookkeeping and preview teardown from the platform, and no builds.

**CLI.** `prisma deploy module.ts` deploys production directly; add
`--stage <name>` for a preview. Authenticate once with `prisma auth login`
**CLI.** `prisma deploy` deploys production directly; add `--stage <name>`
for a preview. It deploys the entry file named by `entry` in the `composer`
section of `prisma.config.ts`; `--entry <path>` overrides it. `prisma deploy
Comment thread
coderabbitai[bot] marked this conversation as resolved.
Resolved
list` (same `--stage`) lists each deployed node's address, kind, platform ID
and URL. Authenticate once with `prisma auth login`
(interactive), or set `PRISMA_SERVICE_TOKEN` (plus `PRISMA_WORKSPACE_ID`
when the token can see more than one workspace) for CI and other headless
runs. The first deploy creates the project, named after your module; the
Expand Down Expand Up @@ -350,7 +354,7 @@ over deploying whenever you want to show the user a change or verify your
own work:

1. Build the app exactly as you would for deploy, then run
`prisma dev module.ts`. It provisions a local Prisma Postgres database,
`prisma dev` (it runs the config's `entry`, like deploy). It provisions a local Prisma Postgres database,
applies the schema, creates local stand-ins for declared buckets, starts
the services, and prints a local URL. It watches built output and
restarts a service when its build changes.
Expand Down
Loading