ci: validate migrations before nas deploy
Backend CI / Backend (push) Successful in 13m6s

This commit is contained in:
2026-05-01 12:37:15 +08:00
parent 079b361679
commit 9074b7927b
2 changed files with 125 additions and 18 deletions
+71
View File
@@ -122,6 +122,77 @@ jobs:
chmod 700 ~/.ssh
ssh-keyscan -p "${NAS_PORT}" "${NAS_HOST}" >> ~/.ssh/known_hosts
- name: Validate migrations on empty Postgres
run: |
set -eu
test_name="geo-migration-preflight-${GITHUB_RUN_ID:-manual}-${GITHUB_RUN_NUMBER:-0}"
network_name="${test_name}-net"
postgres_name="${test_name}-postgres"
migrate_image="${test_name}-migrate"
cleanup() {
docker rm -f "${postgres_name}" >/dev/null 2>&1 || true
docker network rm "${network_name}" >/dev/null 2>&1 || true
docker image rm "${migrate_image}" >/dev/null 2>&1 || true
}
trap cleanup EXIT INT TERM
docker network create "${network_name}" >/dev/null
docker run -d \
--name "${postgres_name}" \
--network "${network_name}" \
-e POSTGRES_DB=geo \
-e POSTGRES_USER=geo \
-e POSTGRES_PASSWORD=geo_dev \
postgres:16-alpine >/dev/null
echo "Waiting for empty Postgres..."
for i in $(seq 1 60); do
if docker exec "${postgres_name}" pg_isready -U geo -d geo >/dev/null 2>&1; then
break
fi
if [ "${i}" -eq 60 ]; then
docker logs "${postgres_name}" || true
echo "::error::Postgres did not become ready"
exit 1
fi
sleep 1
done
docker exec "${postgres_name}" createdb -U geo geo_monitoring
echo "Building migration image..."
DOCKER_BUILDKIT=1 docker build \
--target migrate \
--tag "${migrate_image}" \
-f server/Dockerfile \
server/
database_url="postgres://geo:geo_dev@${postgres_name}:5432/geo?sslmode=disable"
monitoring_database_url="postgres://geo:geo_dev@${postgres_name}:5432/geo_monitoring?sslmode=disable"
ops_database_url="postgres://geo:geo_dev@${postgres_name}:5432/geo?sslmode=disable&x-migrations-table=schema_migrations_ops"
echo "Running tenant migrations on an empty database..."
docker run --rm --network "${network_name}" "${migrate_image}" \
-path /migrations \
-database "${database_url}" \
up
echo "Running monitoring migrations on an empty database..."
docker run --rm --network "${network_name}" "${migrate_image}" \
-path /migrations_monitoring \
-database "${monitoring_database_url}" \
up
echo "Running ops migrations on an empty database..."
docker run --rm --network "${network_name}" "${migrate_image}" \
-path /migrations_ops \
-database "${ops_database_url}" \
up
echo "Migration preflight passed."
- name: Upload release to NAS
run: |
set -eu
@@ -1,24 +1,60 @@
ALTER TABLE brand_questions
ADD COLUMN IF NOT EXISTS question_text TEXT;
UPDATE brand_questions q
SET question_text = COALESCE(
(
SELECT v.question_text
FROM brand_question_versions v
WHERE v.id = q.current_version_id
LIMIT 1
),
(
SELECT v.question_text
FROM brand_question_versions v
WHERE v.question_id = q.id
ORDER BY v.version_no DESC, v.id DESC
LIMIT 1
),
''
)
WHERE q.question_text IS NULL;
DO $$
BEGIN
IF to_regclass('public.brand_question_versions') IS NOT NULL
AND EXISTS (
SELECT 1
FROM information_schema.columns
WHERE table_schema = 'public'
AND table_name = 'brand_questions'
AND column_name = 'current_version_id'
)
THEN
EXECUTE $sql$
UPDATE brand_questions q
SET question_text = COALESCE(
(
SELECT v.question_text
FROM brand_question_versions v
WHERE v.id = q.current_version_id
LIMIT 1
),
(
SELECT v.question_text
FROM brand_question_versions v
WHERE v.question_id = q.id
ORDER BY v.version_no DESC, v.id DESC
LIMIT 1
),
q.question_text,
''
)
WHERE q.question_text IS NULL
$sql$;
ELSIF to_regclass('public.brand_question_versions') IS NOT NULL THEN
EXECUTE $sql$
UPDATE brand_questions q
SET question_text = COALESCE(
(
SELECT v.question_text
FROM brand_question_versions v
WHERE v.question_id = q.id
ORDER BY v.version_no DESC, v.id DESC
LIMIT 1
),
q.question_text,
''
)
WHERE q.question_text IS NULL
$sql$;
END IF;
END $$;
UPDATE brand_questions
SET question_text = ''
WHERE question_text IS NULL;
ALTER TABLE brand_questions
ALTER COLUMN question_text SET NOT NULL;