Skip to content

chore: add notable PostgreSQL bug fixes #56

chore: add notable PostgreSQL bug fixes

chore: add notable PostgreSQL bug fixes #56

# NixOS Runner: Local Test Workflow
#
# Runs all four test suites (health checks, managed DB validation, migration
# validation, PR audit) on the self-hosted NixOS runner against the PG
# instances your secrets point at (Neon / DigitalOcean / etc.).
#
# Triggers:
# - pull_request [opened, synchronize]: full matrix on PG15-18. Fork PRs
# get no secrets, so they fail at env validation. That's the point.
# - workflow_dispatch: pick a PG version and cloud_provider label.
#
# The NixOS runner already has psql, uv, and network access to the test PG
# instances. No Docker or local PG install needed.
#
# The cloud auth steps in managed-db-validate.yml (AWS/GCP/Azure CLI) are
# NOT replicated here. They need real cloud credentials and live DBs, and
# stay manual-dispatch only in CI.
name: NixOS Local Test Workflow
on:
workflow_dispatch:
inputs:
postgres_version:
description: 'PostgreSQL major version to test against'
required: true
type: choice
options:
- '15'
- '16'
- '17'
- '18'
default: '16'
cloud_provider:
description: 'Cloud provider label (for managed DB test output)'
required: false
type: choice
options:
- direct
- aws
- gcp
- azure
default: 'direct'
pull_request:
types: [opened, synchronize]
paths:
- pgFirstAid.sql
- view_pgFirstAid.sql
- view_pgFirstAid_managed.sql
- .github/workflows/**
- testing/local-workflows/**
- .github/workflows/nixos-local-test.yml
concurrency:
group: nixos-local-test-${{ github.ref }}
cancel-in-progress: true
jobs:
local-test:
runs-on: [self-hosted, nix, nixos, x86_64-linux]
# No job-level `if:`. The original conditional referenced
# `matrix.postgres_version` which is only valid in the strategy scope
# (after matrix evaluation), not at the job level. GitHub Actions
# rejects the workflow with "Unrecognized named-value: 'matrix'."
# The PR validation pass runs the full matrix unconditionally on
# pull_request; the workflow_dispatch path's per-version selection
# is handled by the strategy below.
permissions:
contents: read
concurrency:
group: nixos-local-test-${{ github.ref }}-${{ matrix.postgres_version }}
cancel-in-progress: true
strategy:
fail-fast: false
# here too. Without a matching leg, the job fails closed instead of
# silently defaulting to PG18.
matrix:
include:
- postgres_version: "15"
pg_host_secret: PG15_HOST
pg_port_secret: PG15_PORT
pg_user_secret: PG15_USER
pg_password_secret: PG15_PASSWORD
pg_database_secret: PG15_DATABASE
pg_database_url_secret: PG15_DATABASE_URL
- postgres_version: "16"
pg_host_secret: PG16_HOST
pg_port_secret: PG16_PORT
pg_user_secret: PG16_USER
pg_password_secret: PG16_PASSWORD
pg_database_secret: PG16_DATABASE
pg_database_url_secret: PG16_DATABASE_URL
- postgres_version: "17"
pg_host_secret: PG17_HOST
pg_port_secret: PG17_PORT
pg_user_secret: PG17_USER
pg_password_secret: PG17_PASSWORD
pg_database_secret: PG17_DATABASE
pg_database_url_secret: PG17_DATABASE_URL
- postgres_version: "18"
pg_host_secret: PG18_HOST
pg_port_secret: PG18_PORT
pg_user_secret: PG18_USER
pg_password_secret: PG18_PASSWORD
pg_database_secret: PG18_DATABASE
pg_database_url_secret: PG18_DATABASE_URL
defaults:
run:
shell: bash -l {0}
env:
PG_VERSION: ${{ matrix.postgres_version }}
PGHOST: ${{ secrets[matrix.pg_host_secret] }}
PGPORT: ${{ secrets[matrix.pg_port_secret] }}
PGUSER: ${{ secrets[matrix.pg_user_secret] }}
PGPASSWORD: ${{ secrets[matrix.pg_password_secret] }}
PGDATABASE: ${{ secrets[matrix.pg_database_secret] }}
PGSSLMODE: require
DATABASE_URL: ${{ secrets[matrix.pg_database_url_secret] }}
# cloud_provider input is undefined on pull_request. Default to 'direct'.
CLOUD_PROVIDER: ${{ inputs.cloud_provider || 'direct' }}
PGFIRSTAID_FAIL_SEVERITY: HIGH
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 1
ref: ${{ github.event.pull_request.head.sha || github.ref }}
- name: Add Nix profile paths
run: |
echo "/run/current-system/sw/bin" >> "$GITHUB_PATH"
echo "/nix/var/nix/profiles/default/bin" >> "$GITHUB_PATH"
echo "$HOME/.nix-profile/bin" >> "$GITHUB_PATH"
echo "/etc/profiles/per-user/$USER/bin" >> "$GITHUB_PATH"
- name: Validate PG connection vars
run: |
missing=0
for var in PGHOST PGPORT PGUSER PGPASSWORD PGDATABASE; do
if [ -z "${!var}" ]; then
echo "::error::Missing required secret/env: ${var} for PG${{ matrix.postgres_version }}"
missing=1
fi
done
if [ "$missing" -ne 0 ]; then exit 1; fi
echo "Target: PG${{ matrix.postgres_version }} @ $PGHOST:$PGPORT"
- name: Verify psql + uv
run: |
command -v psql >/dev/null 2>&1 || { echo "::error::psql not found"; exit 1; }
psql --version
command -v uv >/dev/null 2>&1 || { echo "::error::uv not found"; exit 1; }
uv --version
- name: "Test: Health Check Suite"
working-directory: testing/local-workflows
run: |
mkdir -p reports
./test_db_health_checks.sh
- name: "Test: Managed DB Validation"
working-directory: testing/local-workflows
run: |
./test_managed_db_validate.sh
- name: "Test: Pre/Post Migration Validation"
working-directory: testing/local-workflows
run: |
./test_pre_post_migration.sh
continue-on-error: true
- name: "Test: PR Audit Script"
working-directory: testing/local-workflows
run: |
uv pip install --quiet psycopg2-binary 2>/dev/null || uv pip install psycopg2-binary
./test_pr_audit.sh
continue-on-error: true
- name: Upload reports
uses: actions/upload-artifact@v4
if: always()
with:
name: test-reports-pg${{ matrix.postgres_version }}
path: testing/local-workflows/reports/
retention-days: 14
- name: Post summary
if: always()
run: |
{
echo "## NixOS Local Test Results: PG${{ matrix.postgres_version }}"
echo ""
echo "| Suite | Status |"
echo "|-------|--------|"
echo "| Health Check | ${{ job.status == 'success' && '✅' || '❌' }} |"
echo "| Managed DB Validate | ${{ job.status == 'success' && '✅' || '❌' }} |"
echo "| Migration Validate | ${{ job.status == 'success' && '✅' || '❌' }} |"
echo "| PR Audit | ${{ job.status == 'success' && '✅' || '❌' }} |"
echo ""
echo "Cloud provider label: ${{ inputs.cloud_provider || 'direct' }}"
} >> "$GITHUB_STEP_SUMMARY"