diff --git a/packages/cli/src/cli.ts b/packages/cli/src/cli.ts index e48d9eee..c82cbb12 100644 --- a/packages/cli/src/cli.ts +++ b/packages/cli/src/cli.ts @@ -187,7 +187,11 @@ export const cliGroups: Readonly< run: "project create my-app", brief: "Create a Project, link this directory", }, - { run: "git connect", brief: "Connect GitHub so every push deploys" }, + { + run: "git connect", + brief: + "Connect GitHub; branches carrying the deploy workflow deploy on push", + }, { run: "project env add KEY=value --role preview", brief: "Set env vars services get at deploy", @@ -262,9 +266,9 @@ export const cliGroups: Readonly< }, git: { brief: - "Manage the GitHub connection that deploys on push. Connect or disconnect a repository", + "Manage the GitHub connection behind deploy-on-push. Connect or disconnect a repository", description: - "Connecting a GitHub repository turns on deploy-on-push: pushing a Git branch builds and deploys it to a matching Platform Branch. Disconnecting stops push deploys without touching anything already deployed.", + "Connecting a GitHub repository turns on deploy-on-push: the repository's prisma/cloud-deploy-action workflow authenticates through the connection and deploys every pushed branch to a matching Platform Branch. The platform does not build on push; the workflow does. Disconnecting stops push deploys without touching anything already deployed.", }, service: { brief: @@ -468,7 +472,11 @@ export function buildCli(): Cli { run: "project create my-app", brief: "Create a Project, link this directory", }, - { run: "git connect", brief: "Connect GitHub so every push deploys" }, + { + run: "git connect", + brief: + "Connect GitHub; branches carrying the deploy workflow deploy on push", + }, { run: "deploy", brief: "Or build and deploy straight from this machine", diff --git a/packages/cli/src/commands/git/connect.ts b/packages/cli/src/commands/git/connect.ts index ddf212dc..8a436c3d 100644 --- a/packages/cli/src/commands/git/connect.ts +++ b/packages/cli/src/commands/git/connect.ts @@ -38,6 +38,18 @@ import { } from "./context"; import { installWaitFailedError } from "./errors"; +/** Where the deploy workflow's inputs and the minimal file are documented. */ +const WORKFLOW_DOCS_URL = + "https://github.com/prisma/cloud-deploy-action#readme"; + +/** The platform never builds on push; the repository's own Actions workflow + * does, so a connection without one deploys nothing. Console import writes + * the file through a setup pull request; this command does not. */ +const WORKFLOW_DETAIL = + "Deploys run from the repository's GitHub Actions workflow (prisma/cloud-deploy-action), which must exist on each pushed branch; the platform does not build on push."; +const WORKFLOW_NEXT_STEP = + "If the repository has no .github/workflows/prisma-deploy.yml yet, add one running prisma/cloud-deploy-action@v1 with `id-token: write`; a push of any branch that lacks the file deploys nothing."; + /** The legacy wait line, printed once before the poll loop. */ const WAIT_MESSAGE = "Waiting for GitHub App installation or repository access approval..."; @@ -120,6 +132,8 @@ async function resolveInstalledRepository( return match; } +/** The connect result in every mode: the connection card, plus the + * workflow step the platform will not do for you. */ function connectPresentations( result: ProjectRepositoryConnectionResult, ): Presentations { @@ -127,7 +141,17 @@ function connectPresentations( return { stdout: () => [], json: () => result, - next: () => [], + next: () => [ + { + kind: "edit-file", + label: WORKFLOW_NEXT_STEP, + }, + { + kind: "open-url", + label: "Workflow reference (prisma/cloud-deploy-action)", + url: WORKFLOW_DOCS_URL, + }, + ], human: (): Block[] => [ { kind: "summary", @@ -143,7 +167,10 @@ function connectPresentations( { label: "status", value: connection.status }, ], }, - { kind: "list", items: [formatGitConnectionDetail(connection.status)] }, + { + kind: "list", + items: [formatGitConnectionDetail(connection.status), WORKFLOW_DETAIL], + }, ], }; } @@ -159,9 +186,10 @@ export const gitConnectCommand = defineCommand({ flags: { project: projectFlag }, }, help: { - summary: "Connect a project to a GitHub repository so every push deploys", + summary: + "Connect a project to a GitHub repository so its deploy workflow deploys every push", description: - "Turns on deploy-on-push: once connected, pushing a Git branch builds and deploys it to a matching Platform Branch, an isolated environment with its own services, databases, and buckets. If the Prisma GitHub App does not cover the repository yet, the command opens the install page and waits. Run without a URL to use this repository's origin remote.", + "Links the repository to the project. Once connected, the repository's prisma/cloud-deploy-action workflow authenticates each run through GitHub's OIDC token and deploys every pushed branch to a matching Platform Branch, an isolated environment with its own services, databases, and buckets. The platform does not build on push itself: a repository without the workflow must add .github/workflows/prisma-deploy.yml (importing in the Console opens a pull request that adds it). If the Prisma GitHub App does not cover the repository yet, the command opens the install page and waits. Run without a URL to use this repository's origin remote.", examples: [ "git connect", "git connect git@github.com:prisma/prisma-cli.git", diff --git a/packages/cli/tests/git.test.ts b/packages/cli/tests/git.test.ts index 9c4d3ad2..54842286 100644 --- a/packages/cli/tests/git.test.ts +++ b/packages/cli/tests/git.test.ts @@ -265,7 +265,10 @@ describe("prisma git connect", () => { }, { kind: "list", - items: ["GitHub branch automation is active for this project."], + items: [ + "GitHub branch automation is active for this project.", + "Deploys run from the repository's GitHub Actions workflow (prisma/cloud-deploy-action), which must exist on each pushed branch; the platform does not build on push.", + ], }, ]); }); @@ -683,7 +686,18 @@ describe("prisma git connect", () => { automation: { branches: true, pullRequests: false, comments: false }, }, }, - nextActions: [], + nextActions: [ + { + kind: "edit-file", + label: + "If the repository has no .github/workflows/prisma-deploy.yml yet, add one running prisma/cloud-deploy-action@v1 with `id-token: write`; a push of any branch that lacks the file deploys nothing.", + }, + { + kind: "open-url", + label: "Workflow reference (prisma/cloud-deploy-action)", + url: "https://github.com/prisma/cloud-deploy-action#readme", + }, + ], }); }); diff --git a/skills/prisma-platform-core-concepts/SKILL.md b/skills/prisma-platform-core-concepts/SKILL.md index b40ad9c0..bd768259 100644 --- a/skills/prisma-platform-core-concepts/SKILL.md +++ b/skills/prisma-platform-core-concepts/SKILL.md @@ -3,7 +3,7 @@ name: prisma-platform-core-concepts metadata: library: "prisma" library_version: "8.0.0-rc.15" - version: 2026.9.1 + version: 2026.9.2 description: >- Use when hosting, deploying, or operating an app on the Prisma Platform: projects, branches, preview environments, services and their versions, @@ -119,8 +119,9 @@ another project or branch explicitly. There is no separate "preview environment" object to create or configure. The branch is the environment, and branches come into being by deploying to them: -1. **Push a git branch** (with the GitHub integration connected): the - platform creates the branch environment on the fly, builds, and deploys. +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` 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 @@ -142,13 +143,48 @@ Preview lifecycle rules: ## Two ways to deploy -**GitHub (recommended).** Install the Prisma GitHub app and connect the -repository: `prisma git connect`, or import the repository in the Console. -From then on, every push builds and deploys on the platform. A push to the -default branch deploys production; a push to any other branch creates or -updates that branch's preview environment. No workflow file is required, and -previews come free with every branch. Opening a pull request does not itself -deploy anything; previews track branch pushes. +**GitHub (recommended).** Two pieces, both required: the Prisma GitHub App +connected to the repository, and a GitHub Actions workflow in the repository +that runs `prisma/cloud-deploy-action`. The platform does not build on push. +The workflow builds in the repository's own Actions and deploys with a +short-lived credential exchanged from the run's OIDC token; the connection +is what authorises that exchange, and it also tears a preview down when its +git branch is deleted. Importing the repository in the Console opens a setup +pull request that adds the workflow. `prisma git connect` only creates the +connection, so a repository connected from the CLI adds the workflow itself. +The minimal `.github/workflows/prisma-deploy.yml`: + +```yaml +name: prisma-deploy +on: + push: +permissions: + contents: read + id-token: write +jobs: + deploy: + if: github.ref_type == 'branch' + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-node@v4 + with: + node-version: 24 + - uses: oven-sh/setup-bun@v2 + - uses: prisma/cloud-deploy-action@v1 + with: + build-command: npm run build +``` + +From then on, every push of a branch that carries the workflow file runs +it; GitHub reads workflows from the pushed commit, so a branch created +before the file was added deploys nothing until it contains the file. A +push to the default branch deploys production; a push to any other branch +creates or updates that branch's preview environment, so previews come free +with every branch. +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 ` for a preview. Authenticate once with `prisma auth login` @@ -324,6 +360,12 @@ Windows is not supported for the local stack yet. 10. **A deployed service errors on its first timestamp read (`RUNTIME.TEMPORAL_UNAVAILABLE`).** The runtime has no global `Temporal`; see the Compute runtime section for the polyfill. +11. **The repository is connected, but a push built nothing.** The platform + does not build on push; the repository's own workflow does. Make sure + `.github/workflows/prisma-deploy.yml` exists on the pushed branch and + that a run appears under the repository's Actions tab. A connected + repository with no workflow records the branch and deploys nothing, and + no error is raised anywhere. ## What the platform doesn't do yet @@ -340,6 +382,9 @@ Name the gap instead of inventing an API: enough to name here. 4. **No bucket rename** and no bucket-to-branch re-association after creation; re-create instead. +5. **No build on push without a workflow.** The GitHub connection authorises + deploys and tears previews down; it never starts a build. The + `prisma/cloud-deploy-action` workflow is the build. For anything else missing, run the nearest group with `--help` before concluding it does not exist, and route requests with `prisma feedback`