From 972c1d1036ba55aa604d9a8ca57c7d706cc8cac0 Mon Sep 17 00:00:00 2001 From: Arjun Komath Date: Thu, 16 Oct 2025 07:28:43 +1100 Subject: [PATCH] Add migrate ops workflow --- .github/workflows/migrate-ops.yml | 71 +++++++++++++++++++++++++++++++ ops/useOps.ts | 5 --- package.json | 3 +- scripts/migrate-ops.ts | 52 ++++++++++++++++++++++ 4 files changed, 125 insertions(+), 6 deletions(-) create mode 100644 .github/workflows/migrate-ops.yml create mode 100644 scripts/migrate-ops.ts diff --git a/.github/workflows/migrate-ops.yml b/.github/workflows/migrate-ops.yml new file mode 100644 index 0000000..4101b58 --- /dev/null +++ b/.github/workflows/migrate-ops.yml @@ -0,0 +1,71 @@ +name: Migrate Ops Database +permissions: + contents: read + +on: + push: + branches: + - main + - release + paths: + - 'ops/drizzle/**' + workflow_dispatch: + inputs: + environment: + description: 'Environment to migrate' + required: true + type: choice + options: + - staging + - prod + +jobs: + migrate-staging: + name: Run Staging Ops Migration + runs-on: ubuntu-latest + timeout-minutes: 10 + environment: staging + if: (github.event_name == 'push' && github.ref == 'refs/heads/main') || (github.event_name == 'workflow_dispatch' && github.event.inputs.environment == 'staging') + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Setup Bun + uses: oven-sh/setup-bun@v2 + with: + bun-version: latest + + - name: Install dependencies + run: bun install --frozen-lockfile + + - name: Run ops migration (Staging) + env: + DATABASE_URL: ${{ secrets.DATABASE_URL }} + DATABASE_SSL: ${{ secrets.DATABASE_SSL }} + run: bun run migrate:ops + + migrate-prod: + name: Run Prod Ops Migration + runs-on: ubuntu-latest + timeout-minutes: 10 + environment: prod + if: (github.event_name == 'push' && github.ref == 'refs/heads/release') || (github.event_name == 'workflow_dispatch' && github.event.inputs.environment == 'prod') + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Setup Bun + uses: oven-sh/setup-bun@v2 + with: + bun-version: latest + + - name: Install dependencies + run: bun install --frozen-lockfile + + - name: Run ops migration (prod) + env: + DATABASE_URL: ${{ secrets.DATABASE_URL }} + DATABASE_SSL: ${{ secrets.DATABASE_SSL }} + run: bun run migrate:ops diff --git a/ops/useOps.ts b/ops/useOps.ts index b6ecf0a..2a7d039 100644 --- a/ops/useOps.ts +++ b/ops/useOps.ts @@ -1,7 +1,5 @@ -import path from "node:path"; import type { UserJSON } from "@clerk/nextjs/server"; import { drizzle } from "drizzle-orm/node-postgres"; -import { migrate } from "drizzle-orm/node-postgres/migrator"; import * as schema from "./drizzle/schema"; import type { OpsDatabase } from "./drizzle/types"; @@ -12,9 +10,6 @@ export async function getOpsDatabase(): Promise { schema, }); - const migrationsFolder = path.resolve(process.cwd(), "ops/drizzle"); - await migrate(ownerDb, { migrationsFolder: migrationsFolder }); - return ownerDb; } diff --git a/package.json b/package.json index 6321388..d6c21c0 100644 --- a/package.json +++ b/package.json @@ -11,7 +11,8 @@ "lint:fix": "biome lint --write", "fix": "biome format --write && biome lint --write", "generate:migrations": "drizzle-kit generate", - "migrate:tenants": "bun scripts/migrate-all-tenants.ts" + "migrate:tenants": "bun scripts/migrate-all-tenants.ts", + "migrate:ops": "bun scripts/migrate-ops.ts" }, "dependencies": { "@aws-sdk/client-s3": "^3.623.0", diff --git a/scripts/migrate-ops.ts b/scripts/migrate-ops.ts new file mode 100644 index 0000000..34ff799 --- /dev/null +++ b/scripts/migrate-ops.ts @@ -0,0 +1,52 @@ +import path from "node:path"; +import { drizzle } from "drizzle-orm/node-postgres"; +import { migrate } from "drizzle-orm/node-postgres/migrator"; +import * as opsSchema from "../ops/drizzle/schema"; + +async function migrateOpsDatabase(): Promise<{ + success: boolean; + error?: string; +}> { + try { + const sslMode = + process.env.DATABASE_SSL === "true" ? "?sslmode=require" : ""; + + const opsDb = drizzle(`${process.env.DATABASE_URL}/manage${sslMode}`, { + schema: opsSchema, + }); + + const migrationsFolder = path.resolve(process.cwd(), "ops/drizzle"); + await migrate(opsDb, { migrationsFolder }); + + return { success: true }; + } catch (error) { + return { + success: false, + error: error instanceof Error ? error.message : String(error), + }; + } +} + +async function main() { + console.log("Starting ops database migration...\n"); + + if (!process.env.DATABASE_URL) { + console.error("ERROR: DATABASE_URL environment variable is not set"); + process.exit(1); + } + + const result = await migrateOpsDatabase(); + + if (result.success) { + console.log("✓ Ops database migrated successfully!\n"); + } else { + console.log(`✗ Migration failed: ${result.error || "Unknown error"}\n`); + process.exit(1); + } +} + +main().catch((error) => { + const errorMessage = error instanceof Error ? error.message : String(error); + console.error("Fatal error:", errorMessage); + process.exit(1); +});