Skip to content

Fix fractional medication and clinic workflow gaps (#337) #155

Fix fractional medication and clinic workflow gaps (#337)

Fix fractional medication and clinic workflow gaps (#337) #155

Workflow file for this run

name: Apply migrations
# Schema changes ship with the code that needs them. Each environment is an
# explicit job so no matrix expression can receive broad access to repository
# secrets or choose a secret name dynamically.
on:
push:
branches: [main]
workflow_dispatch:
inputs:
target:
description: Environment to migrate
required: true
type: choice
default: demo
options:
- demo
- production
production_confirmation:
description: Type MIGRATE_PRODUCTION for a production run
required: false
type: string
release_sha:
description: Exact 40-character main commit to migrate
required: false
type: string
permissions:
contents: read
concurrency:
group: apply-migrations-${{ inputs.target || 'demo' }}
queue: max
cancel-in-progress: false
jobs:
reject-non-main-dispatch:
name: reject non-main dispatch
if: github.event_name == 'workflow_dispatch' && github.ref != 'refs/heads/main'
runs-on: ubuntu-latest
steps:
- run: |
echo "::error::Migration dispatches must run from the main branch."
exit 1
validate-production-request:
name: validate production request
if: github.event_name == 'workflow_dispatch' && github.ref == 'refs/heads/main' && inputs.target == 'production'
runs-on: ubuntu-latest
steps:
- name: Require exact revision confirmation
env:
PRODUCTION_CONFIRMATION: ${{ inputs.production_confirmation }}
REQUESTED_RELEASE_SHA: ${{ inputs.release_sha }}
run: |
if [ "$PRODUCTION_CONFIRMATION" != "MIGRATE_PRODUCTION" ]; then
echo "::error::Production migration confirmation did not match MIGRATE_PRODUCTION."
exit 1
fi
if [[ ! "$REQUESTED_RELEASE_SHA" =~ ^[0-9a-f]{40}$ ]] || [ "$REQUESTED_RELEASE_SHA" != "$GITHUB_SHA" ]; then
echo "::error::Production migration release SHA must match the exact dispatched main commit."
exit 1
fi
production:
name: production
needs: validate-production-request
if: github.event_name == 'workflow_dispatch' && github.ref == 'refs/heads/main' && inputs.target == 'production'
environment: Production
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
- uses: pnpm/action-setup@f520eceda224fe1a4aed5a2a27a194379a409996 # v6
- uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7
with:
node-version: 24
cache: "pnpm"
- run: pnpm install --frozen-lockfile
- name: Require production database credentials
id: configured
env:
DATABASE_URL: ${{ secrets.PRODUCTION_DATABASE_URL }}
APP_DB_PASSWORD: ${{ secrets.OPENPIMS_APP_DB_PASSWORD }}
run: |
if [[ -z "$DATABASE_URL" || "$DATABASE_URL" =~ ^[[:space:]]*$ ]]; then
echo "::error::PRODUCTION_DATABASE_URL is not configured."
exit 1
fi
if [[ -z "$APP_DB_PASSWORD" || "$APP_DB_PASSWORD" =~ ^[[:space:]]*$ ]]; then
echo "::error::OPENPIMS_APP_DB_PASSWORD is not configured."
exit 1
fi
echo "ready=true" >> "$GITHUB_OUTPUT"
- name: Schema state before
if: steps.configured.outputs.ready == 'true'
continue-on-error: true
env:
DATABASE_URL: ${{ secrets.PRODUCTION_DATABASE_URL }}
run: pnpm db:drift
- name: Verify RLS deployment ownership
if: steps.configured.outputs.ready == 'true'
env:
DATABASE_URL: ${{ secrets.PRODUCTION_DATABASE_URL }}
run: pnpm db:rls:preflight
- name: Apply migrations
if: steps.configured.outputs.ready == 'true'
env:
DATABASE_URL: ${{ secrets.PRODUCTION_DATABASE_URL }}
run: pnpm db:migrate
- name: Re-apply row-level security
if: steps.configured.outputs.ready == 'true'
env:
DATABASE_URL: ${{ secrets.PRODUCTION_DATABASE_URL }}
OPENPIMS_APP_DB_PASSWORD: ${{ secrets.OPENPIMS_APP_DB_PASSWORD }}
run: pnpm db:rls
- name: Verify schema matches the code
if: steps.configured.outputs.ready == 'true'
env:
DATABASE_URL: ${{ secrets.PRODUCTION_DATABASE_URL }}
run: pnpm db:drift
demo:
name: demo
if: github.event_name == 'push' || (github.event_name == 'workflow_dispatch' && github.ref == 'refs/heads/main' && inputs.target == 'demo')
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
- uses: pnpm/action-setup@f520eceda224fe1a4aed5a2a27a194379a409996 # v6
- uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7
with:
node-version: 24
cache: "pnpm"
- run: pnpm install --frozen-lockfile
- name: Check environment is configured
id: configured
env:
DATABASE_URL: ${{ secrets.DEMO_DATABASE_URL }}
run: |
if [ -z "$DATABASE_URL" ]; then
echo "::notice::DEMO_DATABASE_URL is not set — skipping demo."
echo "ready=false" >> "$GITHUB_OUTPUT"
else
echo "ready=true" >> "$GITHUB_OUTPUT"
fi
- name: Schema state before
if: steps.configured.outputs.ready == 'true'
continue-on-error: true
env:
DATABASE_URL: ${{ secrets.DEMO_DATABASE_URL }}
run: pnpm db:drift
- name: Verify RLS deployment ownership
if: steps.configured.outputs.ready == 'true'
env:
DATABASE_URL: ${{ secrets.DEMO_DATABASE_URL }}
run: pnpm db:rls:preflight
- name: Apply migrations
if: steps.configured.outputs.ready == 'true'
env:
DATABASE_URL: ${{ secrets.DEMO_DATABASE_URL }}
run: pnpm db:migrate
- name: Re-apply row-level security
if: steps.configured.outputs.ready == 'true'
env:
DATABASE_URL: ${{ secrets.DEMO_DATABASE_URL }}
OPENPIMS_APP_DB_PASSWORD: ${{ secrets.OPENPIMS_APP_DB_PASSWORD }}
run: pnpm db:rls
- name: Verify schema matches the code
if: steps.configured.outputs.ready == 'true'
env:
DATABASE_URL: ${{ secrets.DEMO_DATABASE_URL }}
run: pnpm db:drift