diff --git a/.github/workflows/pgschema-plan-multi.yml b/.github/workflows/pgschema-plan-multi.yml index 924b270..ff7f030 100644 --- a/.github/workflows/pgschema-plan-multi.yml +++ b/.github/workflows/pgschema-plan-multi.yml @@ -15,6 +15,24 @@ jobs: pgschema-plan-multi: runs-on: ubuntu-latest + env: + PGPASSWORD: postgres + + services: + postgres: + image: postgres:17 + env: + POSTGRES_PASSWORD: postgres + POSTGRES_USER: postgres + POSTGRES_DB: testdb + options: >- + --health-cmd pg_isready + --health-interval 10s + --health-timeout 5s + --health-retries 5 + ports: + - 5432:5432 + steps: - name: Checkout code uses: actions/checkout@v4 @@ -27,29 +45,49 @@ jobs: - name: Install pgschema run: go install github.com/pgschema/pgschema@latest + - name: Setup baseline schema from main branch + run: | + # Checkout main branch to get baseline schema + git fetch origin main + git checkout origin/main -- multifile/ || { + echo "::error::Could not checkout multifile/ from main branch" + exit 1 + } + + # Copy main branch schema to temporary location + cp -r multifile /tmp/main_multifile + + # Restore current branch schema + git checkout HEAD -- multifile/ + + # Apply main branch schema to establish baseline database state + echo "::group::Applying baseline schema" + pgschema apply \ + --auto-approve \ + --host localhost \ + --port 5432 \ + --db testdb \ + --user postgres \ + --file /tmp/main_multifile/main.sql \ + || echo "::warning::Failed to apply baseline schema" + echo "::endgroup::" + - name: Run pgschema plan id: plan run: | - # Run pgschema plan with directory of SQL files + # Run pgschema plan PLAN_OUTPUT=$(pgschema plan \ - --host "${{ secrets.DB_HOST }}" \ - --port "${{ secrets.DB_PORT }}" \ - --db "${{ secrets.DB_NAME }}" \ - --user "${{ secrets.DB_USER }}" \ + --host localhost \ + --port 5432 \ + --db testdb \ + --user postgres \ --file "${{ github.workspace }}/multifile/main.sql" \ --format human 2>&1) - # Escape special characters for GitHub Actions - PLAN_OUTPUT="${PLAN_OUTPUT//'%'/'%25'}" - PLAN_OUTPUT="${PLAN_OUTPUT//$'\n'/'%0A'}" - PLAN_OUTPUT="${PLAN_OUTPUT//$'\r'/'%0D'}" - # Set output echo "plan<> $GITHUB_OUTPUT echo "$PLAN_OUTPUT" >> $GITHUB_OUTPUT echo "EOF" >> $GITHUB_OUTPUT - env: - PGPASSWORD: ${{ secrets.DB_PASSWORD }} - name: Comment PR uses: actions/github-script@v7 @@ -61,7 +99,7 @@ jobs: // Decode the escaped output const decodedOutput = decodeURIComponent(planOutput); - const body = `## pgschema Plan Output (Multi File) + const body = `## pgschema Plan Output
Click to expand plan details @@ -83,7 +121,7 @@ jobs: const botComment = comments.find(comment => comment.user.type === 'Bot' && - comment.body.includes('pgschema Plan Output (Multi File)') + comment.body.includes('pgschema Plan Output') ); if (botComment) { diff --git a/.github/workflows/pgschema-plan-single.yml b/.github/workflows/pgschema-plan-single.yml index e282c9f..4b8f353 100644 --- a/.github/workflows/pgschema-plan-single.yml +++ b/.github/workflows/pgschema-plan-single.yml @@ -15,6 +15,24 @@ jobs: pgschema-plan-single: runs-on: ubuntu-latest + env: + PGPASSWORD: postgres + + services: + postgres: + image: postgres:17 + env: + POSTGRES_PASSWORD: postgres + POSTGRES_USER: postgres + POSTGRES_DB: testdb + options: >- + --health-cmd pg_isready + --health-interval 10s + --health-timeout 5s + --health-retries 5 + ports: + - 5432:5432 + steps: - name: Checkout code uses: actions/checkout@v4 @@ -27,29 +45,50 @@ jobs: - name: Install pgschema run: go install github.com/pgschema/pgschema@latest + - name: Setup baseline schema from main branch + run: | + # Checkout main branch to get baseline schema + git fetch origin main + git checkout origin/main -- singlefile/schema.sql || { + echo "::error::Could not checkout schema.sql from main branch" + exit 1 + } + + # Copy main branch schema to temporary location + cp singlefile/schema.sql /tmp/main_schema.sql + + # Restore current branch schema + git checkout HEAD -- singlefile/schema.sql + + # Apply main branch schema to establish baseline database state + echo "::group::Applying baseline schema" + pgschema apply \ + --auto-approve \ + --host localhost \ + --port 5432 \ + --db testdb \ + --user postgres \ + --file /tmp/main_schema.sql \ + || echo "::warning::Failed to apply baseline schema" + echo "::endgroup::" + - name: Run pgschema plan id: plan run: | - # Run pgschema plan and capture output + # Run pgschema plan PLAN_OUTPUT=$(pgschema plan \ - --host "${{ secrets.DB_HOST }}" \ - --port "${{ secrets.DB_PORT }}" \ - --db "${{ secrets.DB_NAME }}" \ - --user "${{ secrets.DB_USER }}" \ + --debug \ + --host localhost \ + --port 5432 \ + --db testdb \ + --user postgres \ --file "${{ github.workspace }}/singlefile/schema.sql" \ --format human 2>&1) - # Escape special characters for GitHub Actions - PLAN_OUTPUT="${PLAN_OUTPUT//'%'/'%25'}" - PLAN_OUTPUT="${PLAN_OUTPUT//$'\n'/'%0A'}" - PLAN_OUTPUT="${PLAN_OUTPUT//$'\r'/'%0D'}" - # Set output echo "plan<> $GITHUB_OUTPUT echo "$PLAN_OUTPUT" >> $GITHUB_OUTPUT echo "EOF" >> $GITHUB_OUTPUT - env: - PGPASSWORD: ${{ secrets.DB_PASSWORD }} - name: Comment PR uses: actions/github-script@v7 @@ -61,7 +100,7 @@ jobs: // Decode the escaped output const decodedOutput = decodeURIComponent(planOutput); - const body = `## pgschema Plan Output (Single File) + const body = `## pgschema Plan Output
Click to expand plan details @@ -83,7 +122,7 @@ jobs: const botComment = comments.find(comment => comment.user.type === 'Bot' && - comment.body.includes('pgschema Plan Output (Single File)') + comment.body.includes('pgschema Plan Output') ); if (botComment) { diff --git a/README.md b/README.md index ba37a11..5b48af3 100644 --- a/README.md +++ b/README.md @@ -15,21 +15,17 @@ Both workflows automatically: ## Setup -### 1. Required GitHub Secrets +### 1. GitHub Secrets -Configure the following secrets in your repository settings: - -- `DB_HOST` - PostgreSQL database host (default: localhost) -- `DB_PORT` - PostgreSQL database port (default: 5432) -- `DB_NAME` - Database name -- `DB_USER` - Database username -- `DB_PASSWORD` - Database password +No secrets required! Both workflows use a PostgreSQL 17 test container for demonstration purposes, making them fully self-contained. ### 2. Schema Organization #### Single File Approach - Place your complete schema in `singlefile/schema.sql` - All tables, indexes, functions, and triggers in one file +- Uses PostgreSQL 17 test container (no external database needed) +- Compares current branch schema against main branch schema - Workflow: `.github/workflows/pgschema-plan-single.yml` #### Multi File Approach @@ -37,6 +33,8 @@ Configure the following secrets in your repository settings: - Uses `main.sql` as the entry point with psql `\i` directives - Organize files by type in subdirectories (tables/, functions/, views/, etc.) - Each file contains a specific database object +- Uses PostgreSQL 17 test container (no external database needed) +- Compares current branch schema against main branch schema - Workflow: `.github/workflows/pgschema-plan-multi.yml` ## Usage @@ -72,9 +70,10 @@ This structure demonstrates how to organize complex schemas across multiple file ## Security Notes -- Database credentials are stored as encrypted GitHub secrets -- The workflow only has read access to your database (it runs `plan`, not `apply`) -- Consider using a read-only database user for additional security +- Both workflows use isolated PostgreSQL 17 test containers +- No external database credentials required +- Safe for demonstration and testing purposes +- Containers are ephemeral and destroyed after each workflow run ## Next Steps