fix(deploy-tradein): track SQL migrations with _schema_migrations + baseline (#637)
This commit is contained in:
parent
bd3e5c8216
commit
40002cfcd2
1 changed files with 54 additions and 6 deletions
|
|
@ -156,18 +156,66 @@ jobs:
|
||||||
docker compose -p gendesign-tradein -f docker-compose.prod.yml pull
|
docker compose -p gendesign-tradein -f docker-compose.prod.yml pull
|
||||||
docker compose -p gendesign-tradein -f docker-compose.prod.yml up -d
|
docker compose -p gendesign-tradein -f docker-compose.prod.yml up -d
|
||||||
|
|
||||||
# Применяем SQL миграции (если есть data/sql/*.sql)
|
# Применяем SQL миграции (если есть backend/data/sql/*.sql)
|
||||||
# Postgres init load *.sql из /docker-entrypoint-initdb.d ТОЛЬКО при первом
|
# Postgres init load *.sql из /docker-entrypoint-initdb.d ТОЛЬКО при первом
|
||||||
# старте volume. Здесь — для повторных миграций после первого запуска.
|
# старте volume. Здесь — для повторных миграций после первого запуска.
|
||||||
|
# Tracking через _schema_migrations (порт паттерна из deploy.yml):
|
||||||
|
# каждый .sql применяется РОВНО один раз, failed migration → exit 1
|
||||||
|
# (никаких swallowed errors). cwd = /opt/gendesign/tradein-mvp.
|
||||||
sleep 5
|
sleep 5
|
||||||
|
|
||||||
|
# Pre-existence detection ДО CREATE TABLE: если таблицы ещё нет, это
|
||||||
|
# первый deploy после внедрения tracking на уже-наполненной prod-БД
|
||||||
|
# (миграции 001-076 живут в схеме). 7 из них (002/003/052/053/054/063/072)
|
||||||
|
# содержат INSERT-seed БЕЗ ON CONFLICT — повторный прогон под строгим
|
||||||
|
# ON_ERROR_STOP упал бы на PK violation. Поэтому: baseline (см. ниже).
|
||||||
|
migrations_table_existed=$(docker compose -p gendesign-tradein -f docker-compose.prod.yml exec -T postgres \
|
||||||
|
psql -U "${TRADEIN_POSTGRES_USER:-tradein}" -d tradein -tAc \
|
||||||
|
"SELECT to_regclass('public._schema_migrations') IS NOT NULL;" | tr -d '[:space:]')
|
||||||
|
|
||||||
|
docker compose -p gendesign-tradein -f docker-compose.prod.yml exec -T postgres \
|
||||||
|
psql -U "${TRADEIN_POSTGRES_USER:-tradein}" -d tradein -v ON_ERROR_STOP=on -c "
|
||||||
|
CREATE TABLE IF NOT EXISTS _schema_migrations (
|
||||||
|
filename TEXT PRIMARY KEY,
|
||||||
|
applied_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
||||||
|
);
|
||||||
|
"
|
||||||
|
|
||||||
|
if [ "$migrations_table_existed" != "t" ]; then
|
||||||
|
# BASELINE: таблицы не было → seed ВСЕ текущие миграции как applied
|
||||||
|
# БЕЗ их прогона. prod уже работает на этой схеме; помечаем её
|
||||||
|
# текущим состоянием, чтобы под строгий gate попадали только НОВЫЕ
|
||||||
|
# (077+) миграции. INSERT ... ON CONFLICT DO NOTHING — идемпотентно.
|
||||||
|
echo "→ _schema_migrations отсутствовала — baseline существующих миграций (без прогона)"
|
||||||
|
for sql_file in $(ls -1 backend/data/sql/*.sql 2>/dev/null | sort); do
|
||||||
|
fname=$(basename "$sql_file")
|
||||||
|
echo " baseline: $fname"
|
||||||
|
docker compose -p gendesign-tradein -f docker-compose.prod.yml exec -T postgres \
|
||||||
|
psql -U "${TRADEIN_POSTGRES_USER:-tradein}" -d tradein -v ON_ERROR_STOP=on -c \
|
||||||
|
"INSERT INTO _schema_migrations (filename) VALUES ('$fname') ON CONFLICT DO NOTHING;"
|
||||||
|
done
|
||||||
|
echo "Baseline complete — existing schema marked as applied."
|
||||||
|
fi
|
||||||
|
|
||||||
for sql_file in $(ls -1 backend/data/sql/*.sql 2>/dev/null | sort); do
|
for sql_file in $(ls -1 backend/data/sql/*.sql 2>/dev/null | sort); do
|
||||||
fname=$(basename "$sql_file")
|
fname=$(basename "$sql_file")
|
||||||
echo "→ Migration: $fname"
|
applied=$(docker compose -p gendesign-tradein -f docker-compose.prod.yml exec -T postgres \
|
||||||
docker compose -p gendesign-tradein -f docker-compose.prod.yml exec -T postgres \
|
psql -U "${TRADEIN_POSTGRES_USER:-tradein}" -d tradein -tAc \
|
||||||
psql -U "${TRADEIN_POSTGRES_USER:-tradein}" -d tradein \
|
"SELECT COUNT(*) FROM _schema_migrations WHERE filename='$fname'" | tr -d '[:space:]')
|
||||||
-v ON_ERROR_STOP=on < "$sql_file" \
|
if [ "$applied" = "0" ]; then
|
||||||
|| echo " (skipped — already applied or error: $fname)"
|
echo "→ Applying migration: $fname"
|
||||||
|
docker compose -p gendesign-tradein -f docker-compose.prod.yml exec -T postgres \
|
||||||
|
psql -U "${TRADEIN_POSTGRES_USER:-tradein}" -d tradein -v ON_ERROR_STOP=on \
|
||||||
|
< "$sql_file" \
|
||||||
|
|| { echo "FAILED on migration: $fname"; exit 1; }
|
||||||
|
docker compose -p gendesign-tradein -f docker-compose.prod.yml exec -T postgres \
|
||||||
|
psql -U "${TRADEIN_POSTGRES_USER:-tradein}" -d tradein -c \
|
||||||
|
"INSERT INTO _schema_migrations (filename) VALUES ('$fname') ON CONFLICT DO NOTHING;"
|
||||||
|
else
|
||||||
|
echo "✓ Already applied: $fname"
|
||||||
|
fi
|
||||||
done
|
done
|
||||||
|
echo "All migrations applied."
|
||||||
|
|
||||||
# Retry backend lifespan hook AFTER migrations applied.
|
# Retry backend lifespan hook AFTER migrations applied.
|
||||||
# tradein-backend startup runs ensure_fdw_user_mapping which needs
|
# tradein-backend startup runs ensure_fdw_user_mapping which needs
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue