Skip to content

fix: close BUG-022..027, BUG-029, BUG-031, BUG-033 from QA sweep #100

fix: close BUG-022..027, BUG-029, BUG-031, BUG-033 from QA sweep

fix: close BUG-022..027, BUG-029, BUG-031, BUG-033 from QA sweep #100

Workflow file for this run

name: Quality Gate
on:
push:
branches:
- main
- master
pull_request:
jobs:
# BUG-023: build and lint the React frontend on every PR. Without this job,
# TypeScript errors, unresolved imports, and broken components can merge
# to main with all other checks green.
frontend-build:
name: frontend (build + lint)
runs-on: ubuntu-latest
defaults:
run:
working-directory: frontend
steps:
- name: Checkout
uses: actions/checkout@v7
- name: Setup Node
uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'
cache-dependency-path: frontend/package-lock.json
- name: Install dependencies
run: npm ci
- name: Lint
run: npm run lint
- name: Build
# vite build performs the full production build; nitro then type-checks
# the SSR bundle. Any TypeScript error, missing import, or broken route
# tree fails this step.
run: npm run build
# Fast, deterministic checks — no database, no network beyond pip.
free-tier:
name: free-tier (unit, lint, health, evals-p)
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v7
- name: Setup Python
uses: actions/setup-python@v7
with:
python-version: '3.11'
- name: Install dev dependencies
# api/requirements.txt is needed too: tests/test_api.py imports FastAPI
# at module level, so without it pytest collection fails.
run: pip install -r requirements-dev.txt -r api/requirements.txt
- name: Unit / regression / security / snapshot tests — final result
run: |
python3 scripts/test_report.py \
--markers "unit or regression or security or snapshot" --strict
- name: Lint (flake8 + bandit)
run: make lint
- name: Component health check
run: make health
- name: Evals — Tier P (offline validator scenarios)
run: python3 evals/runner.py --tiers p --verbose
# Reports (incl. the VCRM gap report) are written to evals/reports/ and
# would otherwise vanish with the runner — keep them for auditability.
- name: Upload eval reports
if: always()
uses: actions/upload-artifact@v7
with:
name: eval-reports-free-tier
path: evals/reports/
if-no-files-found: ignore
retention-days: 30
# Full integration surface: Tier I deploys env_dev.sql twice (idempotency),
# Tier S runs the 142-assertion SQL suite, then the PG-gated pytest tiers run.
integration-postgres:
name: integration (postgres service)
runs-on: ubuntu-latest
services:
postgres:
image: postgres:16-alpine
env:
POSTGRES_PASSWORD: postgres
ports:
- 5432:5432
options: >-
--health-cmd "pg_isready -U postgres"
--health-interval 5s
--health-timeout 5s
--health-retries 10
env:
PGHOST: localhost
PGPORT: "5432"
PGUSER: postgres
PGPASSWORD: postgres
PGDATABASE: te_mgmt_dev
steps:
- name: Checkout
uses: actions/checkout@v7
- name: Setup Python
uses: actions/setup-python@v7
with:
python-version: '3.11'
- name: Install dev dependencies
# api/requirements.txt is needed too: tests/test_api.py imports FastAPI
# at module level, so without it pytest collection fails.
run: pip install -r requirements-dev.txt -r api/requirements.txt
- name: Install PostgreSQL client
run: sudo apt-get update && sudo apt-get install -y --no-install-recommends postgresql-client
- name: Write CI database config
run: |
cat > build/config.local.env <<'EOF'
DB_ENGINE="postgresql"
PG_HOST="localhost"
PG_PORT="5432"
PG_SUPERUSER="postgres"
PG_SUPERUSER_PASSWORD="postgres"
PG_DB_DEV="te_mgmt_dev"
PG_SCHEMA_DEV="te_dev"
PG_DB_TEST="te_mgmt_test"
PG_SCHEMA_TEST="te_test"
PG_DB_STAGING="te_mgmt_staging"
PG_SCHEMA_STAGING="te_staging"
PG_DB_PROD="te_mgmt_prod"
PG_SCHEMA_PROD="te_prod"
EOF
# env_*.sql scripts do not create their databases — deploy_all.sh does that
# before invoking them (see build/te_core_schema.sql:41). Mirror it here.
# Only *.example.sql are committed (concrete env_<env>.sql are gitignored),
# so materialise them before anything that deploys an environment.
- name: Materialise environment launchers from templates
run: |
for env in dev test staging prod; do
cp "build/environments/env_${env}.example.sql" \
"build/environments/env_${env}.sql"
done
ls -1 build/environments/
- name: Create environment databases
run: |
for db in te_mgmt_dev te_mgmt_test te_mgmt_staging te_mgmt_prod; do
if [ -z "$(psql -d postgres -tA -c "SELECT 1 FROM pg_database WHERE datname = '$db'")" ]; then
psql -v ON_ERROR_STOP=1 -d postgres -c \
"CREATE DATABASE \"$db\" WITH OWNER = postgres ENCODING = 'UTF8' TEMPLATE = template0 CONNECTION LIMIT = -1"
fi
done
- name: Deploy all environments (for cross-env parity)
run: |
for env in dev test staging prod; do
bash build/deploy_all.sh "$env"
done
- name: Evals — Tiers X, E (post-deploy, before test artifacts)
run: python3 evals/runner.py --tiers x,e --verbose
- name: Evals — Tiers P, I, S
run: python3 evals/runner.py --tiers p,i,s --verbose
# Prints a final block accounting for every test: PASSED / FAILED /
# ERROR / SKIPPED (with reasons) / NOT RUN (deselected). --strict fails
# the build on any skip.
- name: Full test suite — final result with skip accounting
run: python3 scripts/test_report.py --strict
- name: Upload eval reports
if: always()
uses: actions/upload-artifact@v7
with:
name: eval-reports-integration
path: evals/reports/
if-no-files-found: ignore
retention-days: 30
# Windows surface: starts the pre-installed PostgreSQL service, provisions
# databases, and runs the full suite + Tier P evals. Proves the pipeline
# works on Windows and closes GAP_ANALYSIS.md G2.
windows-postgres:
name: windows (postgres, full suite)
runs-on: windows-latest
env:
PGHOST: localhost
PGPORT: "5432"
PGUSER: postgres
PGPASSWORD: postgres
PGDATABASE: te_mgmt_dev
steps:
- name: Checkout
uses: actions/checkout@v7
- name: Setup Python
uses: actions/setup-python@v7
with:
python-version: '3.11'
- name: Install dev dependencies
run: pip install -r requirements-dev.txt -r api/requirements.txt
- name: Start PostgreSQL and verify connection
shell: pwsh
run: |
# Locate the PostgreSQL bin directory
$pgDir = (Get-ItemProperty 'HKLM:\SOFTWARE\PostgreSQL\Installations\*' -ErrorAction SilentlyContinue |
Select-Object -First 1).Base_Directory
if (-not $pgDir) {
$pgDir = (Get-ChildItem "C:\Program Files\PostgreSQL\*\bin\psql.exe" -ErrorAction SilentlyContinue |
Select-Object -First 1).Directory.Parent.FullName
}
if (-not $pgDir) {
Write-Error "No PostgreSQL installation found on this runner"
exit 1
}
$binDir = Join-Path $pgDir "bin"
Write-Host "PostgreSQL bin: $binDir"
echo "$binDir" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append
# Use a writable temp directory for the data cluster — Program Files
# is not writable by the runner user.
$dataDir = Join-Path $env:RUNNER_TEMP "pgdata"
Write-Host "Data directory: $dataDir"
# Initialise a fresh cluster owned by the current user
if (-not (Test-Path (Join-Path $dataDir "PG_VERSION"))) {
Write-Host "Running initdb"
& "$binDir\initdb" -U postgres -D $dataDir --encoding=UTF8 --auth=trust
if ($LASTEXITCODE -ne 0) {
Write-Error "initdb failed"; exit 1
}
}
# Start the server directly with pg_ctl (no Windows service needed)
$logFile = Join-Path $env:RUNNER_TEMP "pg.log"
& "$binDir\pg_ctl" -D $dataDir -l $logFile -o "-p 5432" start
Start-Sleep -Seconds 5
# Verify it is running
& "$binDir\pg_isready" -p 5432
if ($LASTEXITCODE -ne 0) {
Get-Content $logFile -Tail 30
Write-Error "PostgreSQL did not start"; exit 1
}
# Set password and switch to md5 auth
& "$binDir\psql" -U postgres -d postgres -p 5432 -c "ALTER USER postgres PASSWORD 'postgres';"
$hbaPath = Join-Path $dataDir "pg_hba.conf"
(Get-Content $hbaPath) -replace 'trust$','md5' | Set-Content $hbaPath
& "$binDir\pg_ctl" -D $dataDir reload
Start-Sleep -Seconds 2
& "$binDir\psql" -U postgres -d postgres -p 5432 -c "SELECT version();"
- name: Write CI database config
shell: pwsh
run: |
@"
DB_ENGINE="postgresql"
PG_HOST="localhost"
PG_PORT="5432"
PG_SUPERUSER="postgres"
PG_SUPERUSER_PASSWORD="postgres"
PG_DB_DEV="te_mgmt_dev"
PG_SCHEMA_DEV="te_dev"
PG_DB_TEST="te_mgmt_test"
PG_SCHEMA_TEST="te_test"
PG_DB_STAGING="te_mgmt_staging"
PG_SCHEMA_STAGING="te_staging"
PG_DB_PROD="te_mgmt_prod"
PG_SCHEMA_PROD="te_prod"
"@ | Out-File -FilePath "build/config.local.env" -Encoding utf8
- name: Materialise environment launchers from templates
shell: pwsh
run: |
foreach ($env_name in @("dev", "test", "staging", "prod")) {
Copy-Item "build/environments/env_${env_name}.example.sql" `
"build/environments/env_${env_name}.sql"
}
Get-ChildItem build/environments/
- name: Create environment databases
shell: pwsh
run: |
foreach ($db in @("te_mgmt_dev", "te_mgmt_test", "te_mgmt_staging", "te_mgmt_prod")) {
$exists = & psql -U postgres -d postgres -tA -c "SELECT 1 FROM pg_database WHERE datname = '$db'"
if (-not $exists) {
& psql -U postgres -d postgres -v ON_ERROR_STOP=1 -c `
"CREATE DATABASE `"$db`" WITH OWNER = postgres ENCODING = 'UTF8' TEMPLATE = template0 CONNECTION LIMIT = -1"
}
}
- name: Deploy all environments (for cross-env parity)
shell: bash
run: |
for env in dev test staging prod; do
bash build/deploy_all.sh "$env"
done
- name: Evals — Tiers X, E (post-deploy, before test artifacts)
run: python3 evals/runner.py --tiers x,e --verbose
- name: Evals — Tier P (offline validator scenarios)
run: python3 evals/runner.py --tiers p --verbose
- name: Full test suite — final result with skip accounting
run: python3 scripts/test_report.py --strict
- name: Upload eval reports
if: always()
uses: actions/upload-artifact@v7
with:
name: eval-reports-windows
path: evals/reports/
if-no-files-found: ignore
retention-days: 30