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
66 changes: 52 additions & 14 deletions .github/workflows/pgschema-plan-multi.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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<<EOF" >> $GITHUB_OUTPUT
echo "$PLAN_OUTPUT" >> $GITHUB_OUTPUT
echo "EOF" >> $GITHUB_OUTPUT
env:
PGPASSWORD: ${{ secrets.DB_PASSWORD }}

- name: Comment PR
uses: actions/github-script@v7
Expand All @@ -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

<details>
<summary>Click to expand plan details</summary>
Expand All @@ -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) {
Expand Down
67 changes: 53 additions & 14 deletions .github/workflows/pgschema-plan-single.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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<<EOF" >> $GITHUB_OUTPUT
echo "$PLAN_OUTPUT" >> $GITHUB_OUTPUT
echo "EOF" >> $GITHUB_OUTPUT
env:
PGPASSWORD: ${{ secrets.DB_PASSWORD }}

- name: Comment PR
uses: actions/github-script@v7
Expand All @@ -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

<details>
<summary>Click to expand plan details</summary>
Expand All @@ -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) {
Expand Down
21 changes: 10 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,28 +15,26 @@ 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
- Place SQL files in the `multifile/` directory
- 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
Expand Down Expand Up @@ -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

Expand Down
Loading