diff --git a/.forgejo/workflows/ci-tradein.yml b/.forgejo/workflows/ci-tradein.yml index d5764313..e724c832 100644 --- a/.forgejo/workflows/ci-tradein.yml +++ b/.forgejo/workflows/ci-tradein.yml @@ -191,6 +191,31 @@ jobs: done echo "✓ схема собрана: $(docker exec "$CI_PG" psql -U tradein -d tradein -tAc \ "SELECT count(*) FROM information_schema.tables WHERE table_schema='public'") таблиц" + # Гейт невалидных индексов (#2990). Оборванный CREATE INDEX CONCURRENTLY + # оставляет индекс с indisvalid=false: планировщик им не пользуется, + # ошибки нет, а re-run миграции с IF NOT EXISTS видит его как + # существующий и молча пропускает. Тот же запрос стоит в деплое + # (deploy-tradein.yml, шаг 3b) — там он ловит битые индексы на живом + # проде; здесь он ловит миграцию, которая рождает невалидный индекс + # прямо из чистой схемы, до раскатки. + invalid=$(docker exec "$CI_PG" psql -U tradein -d tradein -tAc "SELECT count(*) + FROM pg_index i + JOIN pg_class c ON c.oid = i.indexrelid + JOIN pg_namespace n ON n.oid = c.relnamespace + WHERE NOT i.indisvalid + AND n.nspname NOT IN ('pg_catalog', 'information_schema')") \ + || { echo "::error::не удалось прочитать pg_index"; exit 1; } + if [ "${invalid:-0}" != "0" ]; then + echo "::error::после применения миграций невалидных индексов: $invalid" + docker exec "$CI_PG" psql -U tradein -d tradein -c "SELECT i.indexrelid::regclass AS idx, i.indrelid::regclass AS tbl + FROM pg_index i + JOIN pg_class c ON c.oid = i.indexrelid + JOIN pg_namespace n ON n.oid = c.relnamespace + WHERE NOT i.indisvalid + AND n.nspname NOT IN ('pg_catalog', 'information_schema')" 2>&1 || true + exit 1 + fi + echo "✓ невалидных индексов нет" - name: Install uv # Официальный standalone-инсталлер. НЕ astral-sh/setup-uv — он ломается