From 35fa968128bae7f2649d8dd12a706db6b8c9ec6e Mon Sep 17 00:00:00 2001 From: enlineawork Date: Tue, 8 Sep 2026 22:08:08 -0300 Subject: [PATCH] ci: rehearse all migrations on clean PostGIS before merge --- .github/workflows/ci.yml | 72 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 72 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 392d46b..858bdaa 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -69,6 +69,78 @@ jobs: grep -Fq -- '$STAGE/android-app:/android-app:ro' scripts/deploy-github.sh - name: Validate Compose run: docker compose --env-file .env.example config >/dev/null + - name: Rehearse complete migrations on clean PostGIS + run: | + set -Eeuo pipefail + cleanup() { + docker compose --env-file .env.example --profile tools down -v --remove-orphans >/dev/null 2>&1 || true + } + trap cleanup EXIT + cleanup + + docker compose --env-file .env.example up -d db + docker compose --env-file .env.example --profile tools run --build --rm migrate + + docker compose --env-file .env.example exec -T db \ + psql -v ON_ERROR_STOP=1 -U dhv2_owner -d dhv2 <<'SQL' + DO $$ + DECLARE + f5_migrations integer; + real_inventory integer; + source_areas integer; + source_yacimientos integer; + source_installations integer; + source_subinstallations integer; + source_findings integer; + BEGIN + SELECT COUNT(*) INTO f5_migrations + FROM typeorm_migrations + WHERE name IN ( + 'F5InventoryPhysicalInstance1790087100000', + 'F5AuthoritativeTerritory1790087200000', + 'F5OperationalContextCompatibility1790087250000', + 'F5AuthoritativeInventoryCatalog1790087300000' + ); + IF f5_migrations <> 4 THEN + RAISE EXCEPTION 'Expected 4 F5 migrations, got %', f5_migrations; + END IF; + + SELECT COUNT(*) INTO real_inventory + FROM assets WHERE is_inventory_instance=true AND information_status<>'INACTIVE'; + IF real_inventory <> 0 THEN + RAISE EXCEPTION 'Fresh F5 database must start with 0 real Inventory instances, got %', real_inventory; + END IF; + + SELECT COUNT(DISTINCT asset.id) FILTER (WHERE type.operational_role='AREA'), + COUNT(DISTINCT asset.id) FILTER (WHERE lower(type.code)='yacimiento') + INTO source_areas,source_yacimientos + FROM source_documents document + JOIN asset_source_documents link ON link.document_id=document.id + JOIN assets asset ON asset.id=link.asset_id + JOIN asset_types type ON type.id=asset.asset_type_id + WHERE document.document_number='DH-F5-TERRITORY'; + IF source_areas <> 64 OR source_yacimientos <> 230 THEN + RAISE EXCEPTION 'F5 territory preload mismatch: areas %, yacimientos %', source_areas,source_yacimientos; + END IF; + + SELECT COUNT(*) FILTER (WHERE level='INSTALLATION'), + COUNT(*) FILTER (WHERE level='SUBINSTALLATION') + INTO source_installations,source_subinstallations + FROM inventory_families + WHERE is_active=true AND source_reference LIKE 'F5:final_modelov2.xlsx%'; + IF source_installations <> 14 OR source_subinstallations <> 109 THEN + RAISE EXCEPTION 'F5 family preload mismatch: installations %, subinstallations %', source_installations,source_subinstallations; + END IF; + + SELECT COUNT(*) INTO source_findings + FROM finding_catalog_items item + JOIN finding_categories category ON category.id=item.category_id + WHERE lower(category.code)='f5model' AND item.is_active=true; + IF source_findings <> 177 THEN + RAISE EXCEPTION 'F5 finding preload mismatch: %', source_findings; + END IF; + END $$; + SQL - name: VPS-equivalent isolated API preflight run: | set -Eeuo pipefail