Skip to content

prisma/compute-deploy

Repository files navigation

Deploy to Prisma Compute — GitHub Action

A composite GitHub Action that deploys applications to Prisma Compute using the @prisma/compute-sdk. Supports both standard Bun apps (default mode) and frameworks with custom build pipelines (pre-built mode).

Usage

Default mode (Bun application)

The action installs dependencies, builds the application via the SDK, uploads the artifact, and polls until the deployment reaches running status.

name: Deploy

on:
  push:
    branches: [main]

permissions:
  contents: read
  deployments: write # For automatic GitHub deployment tracking

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Deploy to Prisma Compute
        id: deploy
        uses: prisma/compute-deploy@main
        with:
          api-token: ${{ secrets.PRISMA_API_TOKEN }}
          compute-service-id: ${{ vars.COMPUTE_SERVICE_ID }}

      - name: Print deployment info
        run: |
          echo "Version: ${{ steps.deploy.outputs.version-id }}"
          echo "Service endpoint: ${{ steps.deploy.outputs.service-endpoint-domain }}"
          echo "Version endpoint: ${{ steps.deploy.outputs.version-endpoint-domain }}"

Pre-built mode (custom build pipeline)

For frameworks that produce their own build output, build first and then deploy the artifact with artifact-path. The entrypoint input is required in this mode.

name: Deploy (pre-built)

on:
  push:
    branches: [main]

permissions:
  contents: read
  deployments: write # For automatic GitHub deployment tracking

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - uses: oven-sh/setup-bun@v2

      - name: Install dependencies
        run: bun install --frozen-lockfile

      - name: Build
        run: bun run build

      - name: Deploy to Prisma Compute
        id: deploy
        uses: prisma/compute-deploy@main
        with:
          api-token: ${{ secrets.PRISMA_API_TOKEN }}
          compute-service-id: ${{ vars.COMPUTE_SERVICE_ID }}
          artifact-path: dist
          entrypoint: server.js
          bun-install: "false"

      - name: Print deployment info
        run: |
          echo "Version: ${{ steps.deploy.outputs.version-id }}"
          echo "Service endpoint: ${{ steps.deploy.outputs.service-endpoint-domain }}"
          echo "Version endpoint: ${{ steps.deploy.outputs.version-endpoint-domain }}"

Replace dist and server.js with whatever directory and entrypoint your build pipeline produces.

Inputs

Input Required Default Description
api-token Yes Prisma API service token. Store as a GitHub secret.
compute-service-id Yes Target compute service ID (e.g. cps_...).
app-path No . Path to the application directory.
entrypoint No auto Application entrypoint file. Required when artifact-path is set.
env-vars No Runtime environment variables as newline-separated KEY=VALUE pairs.
api-url No Management API base URL override (SDK default when omitted).
timeout No 120 Seconds to wait for the version to reach running status.
build-type No auto Build strategy: auto (default), bun, or nextjs.
artifact-path No Path to pre-built application output. Enables skip-build mode.
bun-install No auto Control Bun setup and dependency installation. See Dependency installation.
github-deployment No auto Control GitHub Deployment tracking. See GitHub Deployment tracking.
environment No auto GitHub environment name for deployment tracking. Auto-detects when empty: production on the default branch, preview on all others.
skip-promote No false Deploy the new version without promoting it to the service endpoint.
destroy-old-version No false Delete the old version after stopping it. Cannot be combined with skip-promote.
github-token No GITHUB_TOKEN GitHub token for creating deployment statuses. Override with a PAT if the default token lacks permissions.

Outputs

Output Description
version-id The created compute version ID (e.g. cpv_...).
version-endpoint-domain The version-specific endpoint domain.
service-endpoint-domain The stable service endpoint domain (after promotion).
deployment-id The GitHub Deployment ID (empty if tracking was skipped or unavailable).

Build modes

Default mode

When artifact-path is not set, the action handles the full lifecycle:

  1. Sets up Bun and installs application dependencies (unless overridden via bun-install).
  2. Invokes the deploy SDK which builds, packages, uploads, and starts the version.
  3. Polls until the version reaches running status.
  4. Promotes the version to the service endpoint (unless skip-promote: true).

This is the simplest path for standard Bun applications.

Pre-built mode

When artifact-path is set, the action skips building and deploys the provided directory:

  1. Invokes the SDK with the pre-built artifact and the supplied entrypoint.
  2. Polls until the version reaches running status.
  3. Promotes the version to the service endpoint (unless skip-promote: true).

Use this mode for frameworks with custom build pipelines, monorepo setups, or when you need full control over dependency installation.

Dependency installation

The bun-install input controls whether the action sets up Bun and installs application dependencies:

Value Bun setup Dependency install Use case
auto (default) Only if bun is not already on PATH Only when node_modules/ is missing and artifact-path is not set Zero-config for simple apps; respects existing Bun version and installed dependencies
true Always (may override an existing Bun version) Always Force a clean install regardless of existing node_modules/
false No No Complex workflows where you manage Bun setup and dependencies yourself

Note: auto is the only mode that respects a Bun version you set up in a prior step. true always runs setup-bun, which may override a previously configured version. Use auto or false if you need a specific Bun version.

When bun-install is false, the action assumes bun is already on PATH (required for the deploy step). Set up Bun in a prior workflow step if needed:

- uses: oven-sh/setup-bun@v2

- name: Install and build
  run: |
    bun install --frozen-lockfile
    bun run build

- uses: prisma/compute-deploy@main
  with:
    api-token: ${{ secrets.PRISMA_API_TOKEN }}
    compute-service-id: ${{ vars.COMPUTE_SERVICE_ID }}
    artifact-path: dist
    entrypoint: server.js
    bun-install: "false"

GitHub Deployment tracking

The action automatically creates GitHub Deployments so deployment status and history appear in your repository's Environments sidebar.

The github-deployment input controls this behavior:

Value Behavior
auto (default) Creates a deployment and reports success/failure. Silently skips if the token lacks permission.
true Same as auto but fails the workflow if deployment tracking cannot be set up.
false Disables deployment tracking entirely.

To enable tracking in auto mode, add deployments: write to your workflow permissions:

permissions:
  contents: read
  deployments: write

Without this permission the action still deploys normally — it just skips the GitHub Deployment status update and logs a notice.

When environment is not set, the action auto-detects the environment name based on the branch: main or master maps to production, all other branches map to preview.

Note: This auto-detection is intentionally simple. Once the platform supports branching and preview environments natively, this logic should be revisited to align with the platform's environment model.

To override, set the environment input explicitly:

- uses: prisma/compute-deploy@main
  with:
    api-token: ${{ secrets.PRISMA_API_TOKEN }}
    compute-service-id: ${{ vars.COMPUTE_SERVICE_ID }}
    environment: staging

Authentication

The action authenticates with the Management API using a service token:

  1. Go to Prisma Console → Settings → Service Tokens.
  2. Create a new service token.
  3. Add it as a GitHub Actions secret (e.g. PRISMA_API_TOKEN).
  4. Pass it via the api-token input.

The token is automatically masked in workflow logs.

Environment variables

Pass runtime environment variables to your compute service using the env-vars input:

- uses: prisma/compute-deploy@main
  with:
    api-token: ${{ secrets.PRISMA_API_TOKEN }}
    compute-service-id: ${{ vars.COMPUTE_SERVICE_ID }}
    env-vars: |
      DATABASE_URL=${{ secrets.DATABASE_URL }}
      NODE_ENV=production
      LOG_LEVEL=info

Versioning

This action is consumed by Git ref. Pin to a tagged release for reproducible builds:

- uses: prisma/compute-deploy@v1

Or pin to a commit SHA for maximum reproducibility:

- uses: prisma/compute-deploy@<commit-sha>

Using @main will track the default branch and may pick up breaking changes.

Error handling

The action fails the workflow step with a descriptive error when:

  • The deployment version reaches failed status.
  • The version does not reach running within the configured timeout.
  • Required inputs are missing or invalid.
  • The SDK returns an error from the deploy pipeline.

Development

Project structure

.
├── action.yml                          # Composite action definition
├── scripts/
│   ├── deploy.ts                       # Deployment orchestration (TypeScript, uses @prisma/compute-sdk)
│   ├── create-deployment.sh            # GitHub Deployment API: create + set in_progress
│   ├── update-deployment-status.sh     # GitHub Deployment API: mark success/failure
│   └── write-job-summary.sh            # Render step summary markdown table
├── examples/
│   ├── hello-bun/                      # Tiny app for the default-mode smoke test
│   └── hello-prebuilt/                 # Tiny app for the pre-built-mode smoke test
├── .github/workflows/
│   ├── ci.yml                          # Biome + type-check on every PR (no secrets)
│   ├── smoke-deploy-default.yml        # End-to-end deploy in default mode (push / dispatch)
│   └── smoke-deploy-prebuilt.yml       # End-to-end deploy in pre-built mode (push / dispatch)
├── package.json                        # Pins @prisma/compute-sdk and @prisma/management-api-sdk
├── biome.jsonc                         # Lint/format config
├── tsconfig.json                       # Type-check config
└── README.md

Non-trivial shell logic lives in scripts/ rather than inline in action.yml. The action passes all required values (step outputs, outcome, tokens) as env: variables so the scripts stay free of ${{ }} expressions and can be read and tested independently.

Local checks

bun install
bunx biome ci .          # Lint + format check
bun run check:types      # TypeScript type check

Smoke tests

Two end-to-end workflows verify the action against a real Prisma Compute instance, one per build mode:

Workflow Mode Example app What it covers
smoke-deploy-default.yml Default examples/hello-bun Action sets up Bun, installs deps, runs the SDK build pipeline, and promotes the new version.
smoke-deploy-prebuilt.yml Pre-built examples/hello-prebuilt Workflow runs bun build, then the action deploys dist/ via artifact-path + entrypoint.

Both workflows trigger on push to main (when action.yml, scripts/, the relevant example, or the workflow file changes) and on workflow_dispatch. They intentionally do not trigger on pull_request — once this repo is public, that would expose deploy secrets to untrusted PR code. To verify a PR end-to-end, push it to a branch and trigger the workflow manually with workflow_dispatch.

The two workflows run in independent concurrency groups, so they don't race against each other, but each is serialized against itself to avoid stomping on the same compute service.

Required secrets and variables

Configure these on the repository (Settings → Secrets and variables → Actions):

Name Type Notes
SMOKE_PRISMA_API_TOKEN Secret Workspace-scoped Prisma service token; shared by both smoke workflows.
SMOKE_DEFAULT_COMPUTE_SERVICE_ID Variable Compute service ID that smoke-deploy-default.yml deploys into.
SMOKE_PREBUILT_COMPUTE_SERVICE_ID Variable Compute service ID that smoke-deploy-prebuilt.yml deploys into.

Use two distinct compute services — one per mode — so the workflows don't overwrite each other's deployments.

Updating the SDK

The deploy script depends on @prisma/compute-sdk and @prisma/management-api-sdk. To bump them:

  1. Update the versions in package.json.
  2. Run bun install to refresh the lockfile.
  3. Open a PR — ci.yml will run Biome and the type check on the diff. The smoke-deploy workflows do not run on pull_request (see Smoke tests for why), so trigger them via workflow_dispatch against the PR branch if you want to verify a real deploy before merge.
  4. Merge — both smoke-deploy workflows run automatically on push to main and exercise the action end-to-end.

Script injection prevention

GitHub Actions expressions (${{ }}) interpolated directly into run: blocks are vulnerable to script injection. A maliciously crafted input or branch name could break out of the intended context and execute arbitrary commands.

This action mitigates injection by never using ${{ }} expressions inline in shell code. All external values are passed through env: blocks, which bind them as environment variables rather than interpolating them into the script text:

# WRONG — injectable: a branch named `"; curl evil.com #` would execute
run: |
  curl --data '{"ref":"${{ github.head_ref }}"}' ...

# CORRECT — safe: the value is an env var, not part of the script text
run: |
  curl --data "$(jq --null-input --arg ref "$INPUT_REF" '{"ref":$ref}')" ...
env:
  INPUT_REF: ${{ github.head_ref || github.ref_name }}

When adding new steps or modifying existing ones, keep all ${{ }} usage confined to env: blocks.

Step labels in composite actions

GitHub Actions does not render the name: field of composite action steps in workflow logs. Instead, it displays ► Run <first line of the run: block>. To produce readable log output, every run: block starts with a comment that acts as the de-facto step label:

- name: Create GitHub Deployment
  shell: bash
  run: |
    # Create GitHub Deployment
    bash "${GITHUB_ACTION_PATH}/scripts/create-deployment.sh"

This renders as ► Run # Create GitHub Deployment in the workflow log — not perfect, but far more scannable than raw commands or if statements.

License

Apache-2.0

About

No description, website, or topics provided.

Resources

Code of conduct

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors