Skip to content

feat: establish peer database runtime contract #75

feat: establish peer database runtime contract

feat: establish peer database runtime contract #75

Workflow file for this run

name: Repository and artifact checks
on:
pull_request:
push:
branches:
- develop
- main
workflow_dispatch:
inputs:
preview_pr:
description: Trusted pull request number to deploy after checks pass
required: false
type: number
permissions:
checks: read
contents: read
pull-requests: read
concurrency:
group: repository-${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
env:
PDM_CHECK_UPDATE: "false"
jobs:
dependency-review:
name: Dependency security review
if: github.event_name == 'pull_request'
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v5
- name: Reject new high-severity vulnerabilities
uses: actions/dependency-review-action@v5.0.0
with:
fail-on-severity: high
fail-on-scopes: development, runtime
repository:
name: Hermetic repository contract
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v5
with:
fetch-depth: 0
- name: Set up Python and PDM
uses: pdm-project/setup-pdm@v4.5
with:
python-version-file: .python-version
version: 2.27.0
cache: true
- name: Install locked dependencies
run: pdm install -G dev --frozen-lockfile
- name: Run repository contract
run: pdm run check
- name: Enforce append-only migration history
if: github.event_name == 'pull_request'
run: pdm run check:migration-history "origin/${{ github.base_ref }}"
- name: Enforce append-only migration history on push
if: github.event_name == 'push'
run: pdm run check:migration-history "${{ github.event.before }}"
- name: Run pre-commit contract
run: pdm run pre-commit run --all-files
artifact:
name: Portable peer database runtime
runs-on: ubuntu-latest
services:
postgres:
image: >-
pgvector/pgvector:pg17@sha256:d2ef61f42ef767baa5a1475393303cc235bcd92febd9d7014eddb48b41f3bad0
env:
POSTGRES_DB: inkcre
POSTGRES_USER: postgres
POSTGRES_PASSWORD: postgres
ports:
- 5432:5432
options: >-
--health-cmd "pg_isready -U postgres -d inkcre"
--health-interval 5s
--health-timeout 5s
--health-retries 12
env:
CORE_DATABASE_PASSWORD: ci-core-database-password-at-least-32-bytes
DATABASE_URL: >-
postgresql+psycopg://inkcre_core:ci-core-database-password-at-least-32-bytes@127.0.0.1:5432/inkcre
INKCRE_ENV_FILE: ""
JWT_SECRET: ci-development-jwt-secret-at-least-32-bytes
MIGRATION_DATABASE_URL: >-
postgresql+psycopg://postgres:postgres@127.0.0.1:5432/inkcre
OBSRV__LOGGING_BACKEND: none
POSTGREST_DATABASE_PASSWORD: ci-postgrest-database-password-at-least-32-bytes
POSTGREST_IMAGE: >-
postgrest/postgrest:v14.15@sha256:2f8e7b656f09db697a8875177694b417b35cb76c21370de07fc54e711e902326
IMAGE_TAG: inkcre-core:${{ github.sha }}
steps:
- name: Checkout
uses: actions/checkout@v5
- name: Build frozen artifact
run: >-
docker build
--build-arg "SOURCE_REVISION=${{ github.sha }}"
--tag "$IMAGE_TAG"
.
- name: Inspect artifact contents
run: >-
docker run --rm --entrypoint python "$IMAGE_TAG" -c
"from pathlib import Path;
required = (
'app', 'libs', 'utils', 'extensions', 'migrations/versions',
'alembic.ini', 'scripts/container.py', 'scripts/database.py',
'scripts/verify_postgrest_contract.py', 'data/ai/prompts'
);
missing = [path for path in required if not Path(path).exists()];
assert not missing, missing"
- name: Initialize fresh database twice
run: |
docker run --rm --network host \
--env CORE_DATABASE_PASSWORD \
--env MIGRATION_DATABASE_URL \
--env POSTGREST_DATABASE_PASSWORD \
"$IMAGE_TAG" db init --profile development
docker run --rm --network host \
--env CORE_DATABASE_PASSWORD \
--env MIGRATION_DATABASE_URL \
--env POSTGREST_DATABASE_PASSWORD \
"$IMAGE_TAG" db init --profile development
- name: Verify migration, metadata, and machine readiness
run: |
docker run --rm --network host \
--env MIGRATION_DATABASE_URL \
"$IMAGE_TAG" db ready --profile development --json
docker run --rm --network host --env MIGRATION_DATABASE_URL \
--entrypoint alembic "$IMAGE_TAG" check
- name: Prove readiness rejects contract drift
run: |
docker run --rm --network host \
--env CORE_DATABASE_PASSWORD \
--env MIGRATION_DATABASE_URL \
--env POSTGREST_DATABASE_PASSWORD \
--entrypoint python \
"$IMAGE_TAG" \
scripts/verify_database_contract_failures.py
- name: Start PostgREST and verify peer read/write contract
run: |
postgrest_database_url="postgresql://authenticator:${POSTGREST_DATABASE_PASSWORD}@127.0.0.1:5432/inkcre"
postgrest_id="$(
docker run --detach --network host \
--env "PGRST_DB_URI=$postgrest_database_url" \
--env PGRST_DB_SCHEMAS=inkcre \
--env PGRST_DB_ANON_ROLE=anonymous \
--env PGRST_DB_PRE_REQUEST=inkcre_internal.check_jwt \
--env "PGRST_JWT_SECRET=$JWT_SECRET" \
--env PGRST_JWT_AUD=inkcre-api \
--env PGRST_SERVER_PORT=13000 \
"$POSTGREST_IMAGE"
)"
trap 'docker logs "$postgrest_id"; docker rm --force "$postgrest_id"' EXIT
for _ in $(seq 1 30); do
if docker run --rm --network host \
"$IMAGE_TAG" \
db contract --json >/dev/null &&
docker run --rm --network host \
--entrypoint python \
"$IMAGE_TAG" \
scripts/verify_postgrest_contract.py \
--base-url http://127.0.0.1:13000 \
--jwt-secret "$JWT_SECRET" \
--wrong-jwt-secret ci-wrong-jwt-secret-at-least-32-bytes; then
exit 0
fi
sleep 1
done
exit 1
- name: Verify deterministic reset twice
run: |
fingerprint() {
docker run --rm --network host \
--env MIGRATION_DATABASE_URL \
--entrypoint python \
"$IMAGE_TAG" \
-c "from app.database_contract.catalog import development_baseline_fingerprint as f; print(f())"
}
baseline="$(fingerprint)"
docker run --rm --network host \
--env CORE_DATABASE_PASSWORD \
--env MIGRATION_DATABASE_URL \
--env POSTGREST_DATABASE_PASSWORD \
"$IMAGE_TAG" db reset-dev --confirm reset-development-data
test "$(fingerprint)" = "$baseline"
docker run --rm --network host \
--env CORE_DATABASE_PASSWORD \
--env MIGRATION_DATABASE_URL \
--env POSTGREST_DATABASE_PASSWORD \
"$IMAGE_TAG" db reset-dev --confirm reset-development-data
test "$(fingerprint)" = "$baseline"
- name: Start and probe web artifact
run: |
container_id="$(
docker run --detach --network host \
--env DATABASE_URL \
--env JWT_SECRET \
--env INKCRE_ENV_FILE \
--env MIGRATION_DATABASE_URL \
--env PORT=18080 \
"$IMAGE_TAG" web
)"
trap 'docker logs "$container_id"; docker rm --force "$container_id"' EXIT
for _ in $(seq 1 30); do
if curl --fail --silent http://127.0.0.1:18080/livez >/dev/null; then
break
fi
sleep 1
done
curl --fail --silent http://127.0.0.1:18080/livez
curl --fail --silent http://127.0.0.1:18080/readyz
preview:
name: Deploy trusted preview
if: github.event_name == 'workflow_dispatch' && inputs.preview_pr != 0
needs:
- repository
- artifact
runs-on: ubuntu-latest
environment: preview
steps:
- name: Checkout trusted bootstrap source
uses: actions/checkout@v5
with:
ref: ${{ github.sha }}
persist-credentials: false
- name: Verify exact pull request head
uses: ./.github/actions/preview-verify
with:
github_token: ${{ github.token }}
head_sha: ${{ github.sha }}
pr_number: ${{ inputs.preview_pr }}
- name: Build web and release images without deployment secrets
env:
HEAD_SHA: ${{ github.sha }}
run: |
docker build \
--target heroku-web \
--tag "inkcre-preview-web:$HEAD_SHA" \
.
docker build \
--target heroku-release \
--tag "inkcre-preview-release:$HEAD_SHA" \
.
- name: Deliver preview
uses: ./.github/actions/preview-delivery
with:
core_database_password: ${{ secrets.CORE_DATABASE_PASSWORD }}
head_sha: ${{ github.sha }}
heroku_api_key: ${{ secrets.HEROKU_API_KEY }}
llm_sp_ak: ${{ secrets.LLM_SP_AK }}
llm_sp_base_url: ${{ secrets.LLM_SP_BASE_URL }}
neon_api_key: ${{ secrets.NEON_API_KEY }}
neon_project_id: ${{ vars.NEON_PROJECT_ID }}
postgrest_database_password: ${{ secrets.POSTGREST_DATABASE_PASSWORD }}
pr_number: ${{ inputs.preview_pr }}