ci: add migration integrity gate for migration-relevant changes

This commit is contained in:
Abhimanyu Saharan
2026-02-12 20:04:38 +00:00
parent 5695c0003d
commit e60734f3e7
3 changed files with 73 additions and 1 deletions

View File

@@ -62,6 +62,36 @@ jobs:
nextjs-${{ runner.os }}-node-${{ steps.setup-node.outputs.node-version }}-
- name: Run migration integrity gate
run: |
set -euo pipefail
if [ "${{ github.event_name }}" = "pull_request" ]; then
BASE_SHA="${{ github.event.pull_request.base.sha }}"
HEAD_SHA="${{ github.sha }}"
git fetch --no-tags --depth=1 origin "$BASE_SHA"
else
BASE_SHA="${{ github.event.before }}"
HEAD_SHA="${{ github.sha }}"
fi
CHANGED_FILES=$(git diff --name-only "$BASE_SHA" "$HEAD_SHA")
echo "Changed files:"
echo "$CHANGED_FILES"
if ! echo "$CHANGED_FILES" | grep -Eq '^backend/(app/models|db|migrations|alembic\.ini)'; then
echo "No migration-relevant backend changes detected; skipping migration gate."
exit 0
fi
if echo "$CHANGED_FILES" | grep -Eq '^backend/app/models/' && ! echo "$CHANGED_FILES" | grep -Eq '^backend/migrations/versions/'; then
echo "Model changes detected without a migration under backend/migrations/versions/."
exit 1
fi
make backend-migration-check
- name: Run backend checks
env:
# Keep CI builds deterministic.

View File

@@ -104,6 +104,28 @@ frontend-test: frontend-tooling ## Frontend tests (vitest)
backend-migrate: ## Apply backend DB migrations (uses backend/migrations)
cd $(BACKEND_DIR) && uv run alembic upgrade head
.PHONY: backend-migration-check
backend-migration-check: ## Validate Alembic migrations on clean Postgres (upgrade head + single-head sanity)
@set -euo pipefail; \
CONTAINER_NAME="mc-migration-check-$$RANDOM"; \
docker run -d --rm --name $$CONTAINER_NAME -e POSTGRES_PASSWORD=postgres -e POSTGRES_DB=migration_ci -p 55432:5432 postgres:16 >/dev/null; \
cleanup() { docker rm -f $$CONTAINER_NAME >/dev/null 2>&1 || true; }; \
trap cleanup EXIT; \
for i in $$(seq 1 30); do \
if docker exec $$CONTAINER_NAME pg_isready -U postgres -d migration_ci >/dev/null 2>&1; then break; fi; \
sleep 1; \
if [ $$i -eq 30 ]; then echo "Postgres did not become ready"; exit 1; fi; \
done; \
cd $(BACKEND_DIR) && \
AUTH_MODE=local \
LOCAL_AUTH_TOKEN=ci-local-token-ci-local-token-ci-local-token-ci-local-token \
DATABASE_URL=postgresql+psycopg://postgres:postgres@localhost:55432/migration_ci \
uv run alembic upgrade head && \
AUTH_MODE=local \
LOCAL_AUTH_TOKEN=ci-local-token-ci-local-token-ci-local-token-ci-local-token \
DATABASE_URL=postgresql+psycopg://postgres:postgres@localhost:55432/migration_ci \
uv run alembic heads | grep -q "(head)"
.PHONY: build
build: frontend-build ## Build artifacts

View File

@@ -1,3 +1,23 @@
# Development workflow
Placeholder: see root `README.md` for current setup steps.
## Migration integrity gate (CI)
CI enforces a migration integrity gate to prevent merge-time schema breakages.
### What it validates
- Alembic migrations can apply from a clean Postgres database (`upgrade head`)
- Alembic revision graph resolves to a head revision after migration apply
- On migration-relevant PRs, CI also checks that model changes are accompanied by migration updates
If any of these checks fails, CI fails and the PR is blocked.
### Local reproduction
From repo root:
```bash
make backend-migration-check
```
This command starts a temporary Postgres container, runs migration checks, and cleans up the container.