跳至主要內容

如何使用 GitHub Actions 和 Prisma Postgres 佈建預覽資料庫

15 分鐘

總覽

本指南將展示如何使用 GitHub Actions 和 Prisma Postgres 管理 API 自動建立與刪除 Prisma Postgres 資料庫。此設定會為每個合併請求(pull request)佈建一個新的資料庫,並使用範例資料進行填充(seeding),同時 github-actions 機器人會留下包含資料庫名稱與狀態的評論。

GitHub Actions comment

當 PR 關閉後,資料庫會自動刪除。這讓您能夠在隔離環境中測試變更,而不會影響主要開發資料庫。

先決條件

請確保您具備以下項目

  • Node.js 20 或更高版本
  • A帳戶
  • GitHub 儲存庫

1. 設定您的專案

初始化您的專案

mkdir prisma-gha-demo && cd prisma-gha-demo
npm init -y

2. 安裝並設定 Prisma

在本節中,您將在專案中設定 Prisma,並在整合至 GitHub Actions 之前驗證其在本機運作正常。這包括安裝 Prisma 的依賴項、連接至 Prisma Postgres 資料庫、定義資料模型、套用 schema 以及使用範例資料填充資料庫。

在本節結束時,您的專案將完全準備好在本機以及 CI 工作流程中使用 Prisma。

2.1. 安裝依賴項目

若要開始使用 Prisma,請安裝必要的依賴項

npm install prisma tsx @types/pg dotenv --save-dev
npm install @prisma/client @prisma/adapter-pg pg
資訊

如果您使用的是不同的資料庫提供者(MySQL、SQL Server、SQLite),請安裝相應的驅動程式適配器套件,而不是 @prisma/adapter-pg。如需更多資訊,請參閱資料庫驅動程式

安裝完成後,初始化 Prisma

npx prisma init --db --output ../src/generated/prisma

這會建立:

  • 包含 schema.prismaprisma/ 目錄
  • 包含 DATABASE_URL.env 檔案
  • src/generated/prisma 中產生的 client

2.2. 定義您的 Prisma schema

編輯 prisma/schema.prisma

prisma/schema.prisma
generator client {
provider = "prisma-client"
output = "../src/generated/prisma"
}

datasource db {
provider = "postgresql"
}

model User {
id Int @id @default(autoincrement())
email String @unique
name String?
posts Post[]
}

model Post {
id Int @id @default(autoincrement())
title String
content String?
published Boolean @default(false)
authorId Int
author User @relation(fields: [authorId], references: [id])
}

建立 prisma.config.ts 檔案以配置帶有填充功能的 Prisma

prisma.config.ts
import 'dotenv/config'
import { defineConfig, env } from 'prisma/config';

export default defineConfig({
schema: 'prisma/schema.prisma',
migrations: {
path: 'prisma/migrations',
seed: `tsx src/seed.ts`,
},
datasource: {
url: env('DATABASE_URL'),
},
});
注意

您需要安裝 dotenv 套件

npm install dotenv

2.3. 執行初始遷移並產生 client

npx prisma migrate dev --name init

接著生成 Prisma Client

npx prisma generate

這會推送您的 schema 並準備好 client。

2.4. 填充(Seed)資料庫

src/seed.ts 建立一個檔案

src/seed.ts
import { PrismaClient } from "../src/generated/prisma/client";
import { PrismaPg } from "@prisma/adapter-pg";
import "dotenv/config";

const adapter = new PrismaPg({
connectionString: process.env.DATABASE_URL!,
});

const prisma = new PrismaClient({
adapter,
});

const userData = [
{
name: "Alice",
email: "alice@prisma.io",
posts: {
create: [
{
title: "Join the Prisma Discord",
content: "https://pris.ly/discord",
published: true,
},
{
title: "Prisma on YouTube",
content: "https://pris.ly/youtube",
},
],
},
},
{
name: "Bob",
email: "bob@prisma.io",
posts: {
create: [
{
title: "Follow Prisma on Twitter",
content: "https://twitter.com/prisma",
published: true,
},
],
},
},
];

export async function main() {
for (const u of userData) {
await prisma.user.create({ data: u });
}
}

main()
.catch(console.error)
.finally(() => prisma.$disconnect());

更新您的 package.json

package.json
{
{
"name": "prisma-gha-demo",
"version": "1.0.0",
"description": "",
"scripts": {
"seed": "tsx src/seed.ts"
},
// other configurations...
}

然後執行

npm run seed
npx prisma studio

導航至 https://:5555 並驗證資料庫是否已填充範例資料。現在您已準備好使用 GitHub Actions 自動化此流程。

3. 新增 GitHub Actions 工作流程

在此步驟中,您將設定一個 GitHub Actions 工作流程,當開啟新的合併請求 (PR) 時,自動佈建 Prisma Postgres 資料庫。一旦 PR 關閉,工作流程將會清理該資料庫。

3.1 建立工作流程檔案

首先建立必要的目錄與檔案

mkdir -p .github/workflows
touch .github/workflows/prisma-postgres-management.yml

此檔案將包含依據每個 PR 管理資料庫的邏輯。此 GitHub Actions 工作流程會

  • 在開啟 PR 時佈建一個暫時的 Prisma Postgres 資料庫
  • 使用測試資料填充資料庫
  • 在 PR 關閉時清理資料庫
  • 支援手動觸發佈建與清理
注意

此工作流程使用 us-east-1 作為 Prisma Postgres 的預設區域。您可以透過修改 API 呼叫中的 region 參數,甚至在工作流程中加入 region 輸入項來變更為您偏好的區域。

3.2. 加入基礎配置

將以下內容貼入 .github/workflows/prisma-postgres-management.yml。這會設定工作流程何時執行並提供必要的環境變數。

.github/workflows/prisma-postgres-management.yml
name: Prisma Postgres Management API Workflow

on:
pull_request:
types: [opened, reopened, closed]
workflow_dispatch:
inputs:
action:
description: "Action to perform"
required: true
default: "provision"
type: choice
options:
- provision
- cleanup
database_name:
description: "Database name (for testing, will be sanitized)"
required: false
type: string

env:
PRISMA_POSTGRES_SERVICE_TOKEN: ${{ secrets.PRISMA_POSTGRES_SERVICE_TOKEN }}
PRISMA_PROJECT_ID: ${{ secrets.PRISMA_PROJECT_ID }}
# Sanitize database name once at workflow level
DB_NAME: ${{ github.event.pull_request.number != null && format('pr-{0}-{1}', github.event.pull_request.number, github.event.pull_request.head.ref) || (inputs.database_name != '' && inputs.database_name || format('test-{0}', github.run_number)) }}

# Prevent concurrent runs of the same PR
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

現在您將在此工作流程中加入佈建與清理任務(jobs)。這些任務將根據合併請求事件處理 Prisma Postgres 資料庫的建立與刪除。

3.3. 在工作流程中加入佈建任務

現在加入一個任務,在 PR 開啟或手動觸發時佈建資料庫。佈建任務會

  • 安裝依賴項
  • 檢查現有的資料庫
  • 如有需要則建立一個新的
  • 填充資料庫
  • 在 PR 上評論狀態

將以下內容附加到您工作流程檔案中的 jobs: 鍵下方

.github/workflows/prisma-postgres-management.yml
jobs:
provision-database:
if: (github.event_name == 'pull_request' && github.event.action != 'closed') || (github.event_name == 'workflow_dispatch' && inputs.action == 'provision')
runs-on: ubuntu-latest
permissions: write-all
timeout-minutes: 15
steps:
- name: Checkout
uses: actions/checkout@v4

- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: "22"
cache: "npm"

- name: Install Dependencies
run: npm install

- name: Validate Environment Variables
run: |
if [ -z "${{ env.PRISMA_POSTGRES_SERVICE_TOKEN }}" ]; then
echo "Error: PRISMA_POSTGRES_SERVICE_TOKEN secret is not set"
exit 1
fi
if [ -z "${{ env.PRISMA_PROJECT_ID }}" ]; then
echo "Error: PRISMA_PROJECT_ID secret is not set"
exit 1
fi

- name: Sanitize Database Name
run: |
# Sanitize the database name to match Prisma's requirements
DB_NAME="$(echo "${{ env.DB_NAME }}" | tr '/' '_' | tr '-' '_' | tr '[:upper:]' '[:lower:]')"
echo "DB_NAME=$DB_NAME" >> $GITHUB_ENV

- name: Check If Database Exists
id: check-db
run: |
echo "Fetching all databases..."
RESPONSE=$(curl -s -X GET \
-H "Authorization: Bearer ${{ env.PRISMA_POSTGRES_SERVICE_TOKEN }}" \
-H "Content-Type: application/json" \
"https://api.prisma.io/v1/projects/${{ env.PRISMA_PROJECT_ID }}/databases")

echo "Looking for database with name: ${{ env.DB_NAME }}"

# Extract database ID using jq to properly parse JSON
DB_EXISTS=$(echo "$RESPONSE" | jq -r ".data[]? | select(.name == \"${{ env.DB_NAME }}\") | .id")

if [ ! -z "$DB_EXISTS" ] && [ "$DB_EXISTS" != "null" ]; then
echo "Database ${{ env.DB_NAME }} exists with ID: $DB_EXISTS."
echo "exists=true" >> $GITHUB_OUTPUT
echo "db-id=$DB_EXISTS" >> $GITHUB_OUTPUT
else
echo "No existing database found with name ${{ env.DB_NAME }}"
echo "exists=false" >> $GITHUB_OUTPUT
fi

- name: Create Database
id: create-db
if: steps.check-db.outputs.exists != 'true'
run: |
echo "Creating database ${{ env.DB_NAME }}..."
RESPONSE=$(curl -s -X POST \
-H "Authorization: Bearer ${{ env.PRISMA_POSTGRES_SERVICE_TOKEN }}" \
-H "Content-Type: application/json" \
-d "{\"name\": \"${{ env.DB_NAME }}\", \"region\": \"us-east-1\"}" \
"https://api.prisma.io/v1/projects/${{ env.PRISMA_PROJECT_ID }}/databases")

# Check if response contains an id (success case)
if echo "$RESPONSE" | grep -q '"id":'; then
echo "Database created successfully"
CONNECTION_STRING=$(echo "$RESPONSE" | jq -r '.data.connectionString')
echo "connection-string=$CONNECTION_STRING" >> $GITHUB_OUTPUT
else
echo "Failed to create database"
echo "$RESPONSE"
exit 1
fi

- name: Get Connection String for Existing Database
id: get-connection
if: steps.check-db.outputs.exists == 'true'
run: |
echo "Creating new connection string for existing database..."
CONNECTION_RESPONSE=$(curl -s -X POST \
-H "Authorization: Bearer ${{ env.PRISMA_POSTGRES_SERVICE_TOKEN }}" \
-H "Content-Type: application/json" \
-d '{"name":"read_write_key"}' \
"https://api.prisma.io/v1/databases/${{ steps.check-db.outputs.db-id }}/connections")

CONNECTION_STRING=$(echo "$CONNECTION_RESPONSE" | jq -r '.data.connectionString')
echo "connection-string=$CONNECTION_STRING" >> $GITHUB_OUTPUT

- name: Setup Database Schema
run: |
# Get connection string from appropriate step
if [ "${{ steps.check-db.outputs.exists }}" = "true" ]; then
CONNECTION_STRING="${{ steps.get-connection.outputs.connection-string }}"
else
CONNECTION_STRING="${{ steps.create-db.outputs.connection-string }}"
fi

# Set the DATABASE_URL
export DATABASE_URL="$CONNECTION_STRING"

# Generate Prisma Client
npx prisma generate

# Push schema to database
npx prisma db push

- name: Seed Database
run: |
# Get connection string from appropriate step
if [ "${{ steps.check-db.outputs.exists }}" = "true" ]; then
CONNECTION_STRING="${{ steps.get-connection.outputs.connection-string }}"
else
CONNECTION_STRING="${{ steps.create-db.outputs.connection-string }}"
fi

# Set the DATABASE_URL environment variable for the seed script
export DATABASE_URL="$CONNECTION_STRING"

# Generate Prisma Client
npx prisma generate

# Run the seed script
npm run seed

- name: Comment PR
if: success() && github.event_name == 'pull_request'
uses: actions/github-script@v7
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: `🗄️ Database provisioned successfully!\n\nDatabase name: ${{ env.DB_NAME }}\nStatus: Ready and seeded with sample data`
})

- name: Output Database Info
if: success() && github.event_name == 'workflow_dispatch'
run: |
echo "🗄️ Database provisioned successfully!"
echo "Database name: ${{ env.DB_NAME }}"
echo "Status: Ready and seeded with sample data"

3.4. 在工作流程中加入清理任務

當合併請求關閉時,您可以透過加入清理任務自動移除相關的資料庫。清理任務會

  • 依據名稱尋找資料庫
  • 從 Prisma Postgres 專案中刪除它
  • 也可以透過 action: cleanup 手動觸發

將以下內容附加到您 jobs: 區段的 provision-database 任務之後

.github/workflows/prisma-postgres-management.yml
  cleanup-database:
if: (github.event_name == 'pull_request' && github.event.action == 'closed') || (github.event_name == 'workflow_dispatch' && inputs.action == 'cleanup')
runs-on: ubuntu-latest
timeout-minutes: 5
steps:
- name: Checkout
uses: actions/checkout@v4

- name: Validate Environment Variables
run: |
if [ -z "${{ env.PRISMA_POSTGRES_SERVICE_TOKEN }}" ]; then
echo "Error: PRISMA_POSTGRES_SERVICE_TOKEN secret is not set"
exit 1
fi
if [ -z "${{ env.PRISMA_PROJECT_ID }}" ]; then
echo "Error: PRISMA_PROJECT_ID secret is not set"
exit 1
fi

- name: Sanitize Database Name
run: |
# Sanitize the database name
DB_NAME="$(echo "${{ env.DB_NAME }}" | tr '/' '_' | tr '-' '_' | tr '[:upper:]' '[:lower:]')"
echo "DB_NAME=$DB_NAME" >> $GITHUB_ENV

- name: Delete Database
run: |
echo "Fetching all databases..."
RESPONSE=$(curl -s -X GET \
-H "Authorization: Bearer ${{ env.PRISMA_POSTGRES_SERVICE_TOKEN }}" \
-H "Content-Type: application/json" \
"https://api.prisma.io/v1/projects/${{ env.PRISMA_PROJECT_ID }}/databases")

echo "Looking for database with name: ${{ env.DB_NAME }}"

# Extract database ID using jq to properly parse JSON
DB_EXISTS=$(echo "$RESPONSE" | jq -r ".data[]? | select(.name == \"${{ env.DB_NAME }}\") | .id")

if [ ! -z "$DB_EXISTS" ] && [ "$DB_EXISTS" != "null" ]; then
echo "Database ${{ env.DB_NAME }} exists with ID: $DB_EXISTS. Deleting..."
DELETE_RESPONSE=$(curl -s -X DELETE \
-H "Authorization: Bearer ${{ env.PRISMA_POSTGRES_SERVICE_TOKEN }}" \
-H "Content-Type: application/json" \
"https://api.prisma.io/v1/databases/$DB_EXISTS")

echo "Delete API Response: $DELETE_RESPONSE"

if echo "$DELETE_RESPONSE" | grep -q '"error":'; then
ERROR_MSG=$(echo "$DELETE_RESPONSE" | jq -r '.message // "Unknown error"')
echo "Failed to delete database: $ERROR_MSG"
exit 1
else
echo "Database deletion initiated successfully"
fi
else
echo "No existing database found with name ${{ env.DB_NAME }}"
fi

這便完成了您的 Prisma Postgres 管理工作流程設定。在下一個步驟中,您將配置必要的 GitHub secrets 以對 Prisma API 進行驗證。

4. 將程式碼儲存至 GitHub

初始化 git 儲存庫並推送到 GitHub

如果您尚未在 GitHub 上建立儲存庫,請在 GitHub 上建立一個。儲存庫準備好後,執行以下指令

git add .
git commit -m "Initial commit with Prisma Postgres integration"
git branch -M main
git remote add origin https://github.com/<your-username>/<repository-name>.git
git push -u origin main
注意

<your-username><repository-name> 取代為您的 GitHub 使用者名稱與儲存庫名稱。

5. 取得工作流程所需的 secrets

5.1. 取得您的 Prisma Postgres 服務權杖 (Service Token)

為了管理 Prisma Postgres 資料庫,您需要一個服務權杖。請遵循以下步驟來取得它

  1. 確保您位於上一個步驟建立專案所在的同一個工作區 (workspace) 中。
  2. 導航至工作區的 Settings 頁面並選取 Service Tokens
  3. 點選 New Service Token
  4. 複製產生的權杖並將其儲存於 .env 檔案中作為 PRISMA_POSTGRES_SERVICE_TOKEN。此權杖在下一個步驟的腳本中為必須,且也必須加入至您的 GitHub Actions secrets 中。

5.2 取得您要佈建 Prisma Postgres 資料庫的專案 ID

為了避免與開發資料庫產生衝突,您現在將為 CI 工作流程建立一個專用的專案。使用以下 curl 指令,透過 Prisma Postgres 管理 API 建立一個新的 Prisma Postgres 專案

curl -X POST https://api.prisma.io/v1/projects \
-H "Authorization: Bearer $PRISMA_POSTGRES_SERVICE_TOKEN" \
-H "Content-Type: application/json" \
-d "{\"region\": \"us-east-1\", \"name\": \"$PROJECT_NAME\"}"
注意

請務必將 $PRISMA_POSTGRES_SERVICE_TOKEN 變數替換為您稍早儲存的服務權杖。

將 $PRISMA_POSTGRES_SERVICE_TOKEN 替換為服務權杖,並將 $PROJECT_NAME 替換為您的專案名稱(例如 my-gha-preview)。該腳本將在 us-east-1 區域中建立一個新的 Prisma Postgres 專案。

CLI 輸出將如下所示

{
"data": {
"id": "$PRISMA_PROJECT_ID",
"type": "project",
"name": "$PROJECT_NAME",
"createdAt": "2025-07-15T08:35:10.546Z",
"workspace": {
"id": "$PRISMA_WORKSPACE_ID",
"name": "$PRISMA_WORKSPACE_NAME"
}
}
}

從輸出中複製並儲存 $PRISMA_PROJECT_ID。這是您的 Prisma 專案 ID,您將在下一個步驟中使用它。

6. 在 GitHub 中加入 secrets

若要加入 secrets

  1. 前往您的 GitHub 儲存庫。
  2. 導航至 Settings
  3. 點選並展開 Secrets and variables 區段。
  4. 點選 Actions
  5. 點選 New repository secret
  6. 加入以下項目
    • PRISMA_PROJECT_ID - 來自 Prisma Console 的 Prisma 專案 ID。
    • PRISMA_POSTGRES_SERVICE_TOKEN - 您的服務權杖。

這些 secrets 將透過 env 在工作流程檔案中被存取。

7. 試用工作流程

您可以透過兩種方式測試此設定

選項 1:透過 PR 自動觸發

  1. 在儲存庫中開啟合併請求。
  2. GitHub Actions 將佈建一個新的 Prisma Postgres 資料庫。
  3. 它會推送您的 schema 並填充資料庫。
  4. PR 上將會新增一則確認資料庫已建立的評論。
  5. 當 PR 關閉時,資料庫將自動刪除。

選項 2:手動觸發

  1. 前往儲存庫中的 Actions 標籤。
  2. 在左側側邊欄選擇 Prisma Postgres Management API Workflow
  3. 點選 Run workflow 下拉選單
  4. 選擇 provision 作為動作,並可選擇性提供自訂資料庫名稱。您也可以選擇 cleanup 來刪除「現有的」資料庫。
  5. 點選 Run workflow

後續步驟

您現在擁有了一個用於管理臨時 Prisma Postgres 資料庫的完全自動化 GitHub Actions 設定。

這讓您擁有

  • 每個合併請求都有隔離的資料庫。
  • 自動化的 schema 同步與填充。
  • 合併後清理未使用的資料庫。

此設定能提升對變更的信心並降低共享資料庫衝突的風險。您可以透過整合測試套件,或將其整合至您的工作流程中來擴展此功能。


與 Prisma 保持聯繫

透過以下方式與我們聯繫,繼續您的 Prisma 旅程: 我們的活躍社群。保持資訊靈通、參與其中,並與其他開發者合作

我們衷心感謝您的參與,並期待您成為我們社群的一份子!

© . This site is unofficial and not affiliated with Prisma Data, Inc.