|
| 1 | +--- |
| 2 | +title: Deploy on push |
| 3 | +description: Graduate a Composer app from manual deploys to a Git workflow, with production deploys on push and an isolated preview environment per branch. |
| 4 | +url: /compute/deploy-on-push |
| 5 | +metaTitle: Deploy on push | Prisma Compute |
| 6 | +metaDescription: Connect a GitHub repository and deploy a Prisma Composer app from GitHub Actions with prisma/cloud-deploy-action - production on the default branch, isolated preview stages per branch, automatic teardown. |
| 7 | +--- |
| 8 | + |
| 9 | +You have a [Composer](/composer) app that you deploy by running `deploy module.ts` in a terminal. In this guide you connect its GitHub repository and add a deploy workflow, so pushing replaces that manual step: a push to the default branch updates production, every other branch gets an isolated preview environment, and deleting a branch cleans its preview up. |
| 10 | + |
| 11 | +## How it works |
| 12 | + |
| 13 | +Push-to-deploy has two parts, and you set up both: |
| 14 | + |
| 15 | +1. **The repository connection.** [`git connect`](/cli/git) installs the Prisma GitHub App and registers the repository with your project. This lets workflow runs authenticate: a job exchanges its GitHub OIDC token for a Prisma workspace token that expires after 30 minutes, so the workflow needs no repository secrets. The connection also subscribes the project to branch events, which is what tears a preview down when its Git branch is deleted. |
| 16 | +2. **The deploy workflow.** [prisma/cloud-deploy-action](https://github.com/prisma/cloud-deploy-action) runs in your repository's GitHub Actions. On each push it installs dependencies, runs your build, and runs the [`deploy` command](/cli/deploy) against production or a stage named after the branch. |
| 17 | + |
| 18 | +Connecting a repository does not deploy it; deploys come from the workflow. Without the connection, the workflow has no credential: the action prints a notice, sets its `outcome` output to `skipped-no-credential`, and exits successfully, so the run stays green. |
| 19 | + |
| 20 | +You can connect in the [Console](https://pris.ly/pdp) or from the CLI. The Console opens a pull request that adds the workflow file at the same time. The CLI registers the connection only, and you add the workflow file yourself. This guide uses the CLI. |
| 21 | + |
| 22 | +## Prerequisites |
| 23 | + |
| 24 | +- A Composer app that builds and deploys from your machine. The [full-stack tutorial](/full-stack-tutorial) ends with one. |
| 25 | +- Admin access to the GitHub repository, so you can install the Prisma GitHub App on it. |
| 26 | + |
| 27 | +## 1. Push the project to GitHub |
| 28 | + |
| 29 | +If the app is not on GitHub yet, create a repository from the project directory and push it. With the [GitHub CLI](https://cli.github.com/): |
| 30 | + |
| 31 | +```bash |
| 32 | +gh repo create my-app --private --source . --push |
| 33 | +``` |
| 34 | + |
| 35 | +## 2. Link the directory to the project |
| 36 | + |
| 37 | +The `git` commands operate on the project this directory is linked to. If you have deployed from this directory before, it is already linked and you can skip this step. Otherwise, link it to the project your deploys created: |
| 38 | + |
| 39 | +```npm |
| 40 | +npx prisma@latest project link my-app |
| 41 | +``` |
| 42 | + |
| 43 | +Run the command in the project root, next to `module.ts`. Linking records the current directory, and it accepts a parent directory without a warning. If later commands fail with `PROJECT.SETUP_REQUIRED`, re-run `project link` from the project root. See the [`project` command reference](/cli/project) for how the link is stored and resolved. |
| 44 | + |
| 45 | +## 3. Connect the repository |
| 46 | + |
| 47 | +Connect the project to the repository from step 1: |
| 48 | + |
| 49 | +```npm |
| 50 | +npx prisma@latest git connect https://github.com/you/my-app |
| 51 | +``` |
| 52 | + |
| 53 | +The command opens your browser to install the Prisma GitHub App if it is not installed yet, then registers the connection. It needs an interactive terminal. With `--no-interactive` it fails with `CLI.INTERACTION_REQUIRED`; if you cannot run it interactively, connect through the [Console](https://pris.ly/pdp) instead. |
| 54 | + |
| 55 | +## 4. Add the deploy workflow |
| 56 | + |
| 57 | +Commit a workflow that runs the deploy action on every push: |
| 58 | + |
| 59 | +```yaml title=".github/workflows/prisma-deploy.yml" |
| 60 | +name: prisma-deploy |
| 61 | + |
| 62 | +on: |
| 63 | + push: |
| 64 | + |
| 65 | +concurrency: |
| 66 | + group: prisma-deploy-${{ github.ref }} |
| 67 | + cancel-in-progress: false |
| 68 | + |
| 69 | +permissions: |
| 70 | + contents: read |
| 71 | + id-token: write |
| 72 | + |
| 73 | +jobs: |
| 74 | + deploy: |
| 75 | + if: github.ref_type == 'branch' |
| 76 | + runs-on: ubuntu-latest |
| 77 | + steps: |
| 78 | + - uses: actions/checkout@v4 |
| 79 | + - uses: actions/setup-node@v4 |
| 80 | + with: |
| 81 | + node-version: 22 |
| 82 | + - uses: oven-sh/setup-bun@v2 |
| 83 | + - uses: prisma/cloud-deploy-action@v1 |
| 84 | + with: |
| 85 | + build-command: npm run build |
| 86 | +``` |
| 87 | +
|
| 88 | +A few settings to be aware of: |
| 89 | +
|
| 90 | +- `id-token: write` lets the job request the OIDC token that the action exchanges for a workspace token. Without this permission the exchange cannot happen and the run skips. |
| 91 | +- `build-command` runs verbatim. The action does not detect your framework or build for you. If the app runs its source directly, set `build-command: none`. |
| 92 | +- The action requires Bun on the runner PATH, which `oven-sh/setup-bun@v2` provides. |
| 93 | + |
| 94 | +When the repository has a `prisma` devDependency, the action deploys with that installed version, so keep it current. The action's [README](https://github.com/prisma/cloud-deploy-action) documents the remaining inputs, including `module` for an entry file that is not `module.ts` and `working-directory` for monorepos. |
| 95 | + |
| 96 | +## 5. Push to deploy production |
| 97 | + |
| 98 | +Commit the workflow and push to your default branch. In the repository's **Actions** tab, the `prisma-deploy` run installs, builds, and deploys, and ends with the same deploy report you know from your terminal: |
| 99 | + |
| 100 | +```text no-copy |
| 101 | +my-app |
| 102 | +├─ db postgres-database db_def456 |
| 103 | +└─ api compute-service cps_abc123 |
| 104 | + https://xyz.ewr.prisma.build |
| 105 | +``` |
| 106 | + |
| 107 | +Every later push to the default branch updates production the same way, as if you had run `deploy module.ts` yourself. |
| 108 | + |
| 109 | +If the deploy step fails with `CLI.UNKNOWN_COMMAND`, the action release predates the unified CLI: releases up to v1.5.0 call the removed `prisma composer` commands. Use a release that runs the top-level `deploy` command; the action's [releases page](https://github.com/prisma/cloud-deploy-action/releases) lists what changed in each. If the run is green but its log shows `skipped-no-credential`, the repository is not connected; repeat step 3. Runs triggered from forks skip the same way, because GitHub does not issue OIDC tokens to them, so contributors' pushes keep a green CI without reaching your workspace. |
| 110 | + |
| 111 | +## 6. Preview a branch |
| 112 | + |
| 113 | +Push a branch to try the preview flow: |
| 114 | + |
| 115 | +```bash |
| 116 | +git switch -c feature/search |
| 117 | +git push -u origin feature/search |
| 118 | +``` |
| 119 | + |
| 120 | +The action deploys the branch as a [stage](/composer/deploying#production-and-stages) named after it, which is a [preview branch](/compute/branching) of the same project. The preview has its own services, its own databases assigned to that branch, its own buckets, and its own URL. The only thing it shares with production is the code. Confirm it from your terminal: |
| 121 | + |
| 122 | +```npm |
| 123 | +npx prisma@latest service list --branch feature/search |
| 124 | +``` |
| 125 | + |
| 126 | +Further pushes to the branch update the same preview. Its configuration comes from the branch's [environment variables](/compute/environment-variables), so a preview reads preview-scoped values rather than production ones. |
| 127 | + |
| 128 | +## 7. Delete the branch to clean up |
| 129 | + |
| 130 | +When the branch has served its purpose, delete it: |
| 131 | + |
| 132 | +```bash |
| 133 | +git push origin --delete feature/search |
| 134 | +``` |
| 135 | + |
| 136 | +The platform tears down the matching preview: its services, databases, and buckets are removed. This automation comes from the connection you set up in step 3, so it runs whether or not a workflow fires for the deletion. Automated cleanup skips your production and default branches. |
| 137 | + |
| 138 | +## Next steps |
| 139 | + |
| 140 | +- [GitHub integration](/compute/github): what the repository connection is and does. |
| 141 | +- [Branching](/compute/branching): how preview branches relate to Git branches. |
| 142 | +- [Deploying](/composer/deploying): stages, deploy state, and per-stage secrets, which apply to CI deploys too. |
0 commit comments