Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ VITE_SUPABASE_ANON_KEY=your-supabase-anon-key
GOOGLE_SHEETS_API_KEY=your-google-sheets-api-key
GOOGLE_SHEETS_CLIENT_EMAIL=your-service-account@project.iam.gserviceaccount.com
GOOGLE_SHEETS_PRIVATE_KEY=your-google-sheets-private-key
# Or use service account JSON (base64 encoded or file path):
GOOGLE_SA_JSON={"type":"service_account","project_id":"your-project",...}

# ===== Analytics Configuration =====
ANALYTICS_ENABLED=true
Expand Down
87 changes: 87 additions & 0 deletions .github/workflows/db-bootstrap.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
name: Database Bootstrap

# This workflow runs database migrations manually with approval
# to prevent accidental schema changes in production

on:
workflow_dispatch:
inputs:
environment:
description: 'Target environment'
required: true
default: 'production'
type: choice
options:
- production
- staging

jobs:
migrate:
name: Run Database Migrations
runs-on: ubuntu-latest
# Require manual approval for production deployments
environment: ${{ github.event.inputs.environment }}
permissions:
contents: read

steps:
- name: Checkout repository
uses: actions/checkout@v4

- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '18'

- name: Install pnpm
uses: pnpm/action-setup@v2
with:
version: 8

- name: Get pnpm store directory
id: pnpm-cache
shell: bash
run: |
echo "STORE_PATH=$(pnpm store path)" >> $GITHUB_OUTPUT

- name: Setup pnpm cache
uses: actions/cache@v3
with:
path: ${{ steps.pnpm-cache.outputs.STORE_PATH }}
key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }}
restore-keys: |
${{ runner.os }}-pnpm-store-

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

- name: Install PostgreSQL client
run: |
sudo apt-get update
sudo apt-get install -y postgresql-client

- name: Run migrations
env:
DATABASE_URL: ${{ secrets.DATABASE_URL }}
PGSSLMODE: require
run: |
echo "Running database migrations..."
pnpm run migrate:up

- name: Apply seed data
if: github.event.inputs.environment == 'staging'
env:
DATABASE_URL: ${{ secrets.DATABASE_URL }}
PGSSLMODE: require
run: |
echo "Applying seed data (staging only)..."
if [ -f "database/seeds/0001_seeds.sql" ]; then
psql "$DATABASE_URL" < database/seeds/0001_seeds.sql || echo "Seed data might already exist"
fi

- name: Migration Summary
run: |
echo "✅ Database migrations completed successfully"
echo "Environment: ${{ github.event.inputs.environment }}"
echo "Commit: ${{ github.sha }}"
echo "Branch: ${{ github.ref_name }}"
23 changes: 23 additions & 0 deletions database/migration-config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/**
* node-pg-migrate configuration
* Reads DATABASE_URL and PGSSLMODE from environment variables
*/

const databaseUrl = process.env.DATABASE_URL;
const pgsslmode = process.env.PGSSLMODE || 'require';

if (!databaseUrl) {
throw new Error('DATABASE_URL environment variable is required');
}

module.exports = {
databaseUrl,
dir: 'database/migrations',
migrationsTable: 'pgmigrations',
direction: 'up',
ssl: pgsslmode === 'require' || pgsslmode === 'verify-full',
decamelize: true,
createSchema: true,
createMigrationsSchema: false,
verbose: true,
};
Loading
Loading