diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a89354b..b426c66 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -79,7 +79,65 @@ jobs: cleanup docker compose --env-file .env.example up -d db - docker compose --env-file .env.example --profile tools run --build --rm migrate + + # One historical production-reset migration intentionally requires the + # functional admin account to exist before it runs. On a brand-new CI + # database, prove the chain stops at that exact guard, seed only that + # historical prerequisite, then continue. The historical migration is + # deliberately left untouched. + bootstrap_log="$(mktemp)" + set +e + docker compose --env-file .env.example --profile tools run --build --rm migrate 2>&1 | tee "$bootstrap_log" + bootstrap_status=${PIPESTATUS[0]} + set -e + if [ "$bootstrap_status" -eq 0 ]; then + echo "ERROR: clean migration rehearsal unexpectedly passed without the historical admin prerequisite." >&2 + exit 1 + fi + grep -Fq 'Production reset aborted: expected exactly one username admin, found 0' "$bootstrap_log" || { + echo "ERROR: migration rehearsal failed before the expected historical admin guard." >&2 + exit 1 + } + rm -f "$bootstrap_log" + + docker compose --env-file .env.example exec -T db \ + psql -v ON_ERROR_STOP=1 -U dhv2_owner -d dhv2 <<'SQL' + DO $$ + DECLARE + admin_user_id uuid; + admin_role_id uuid; + BEGIN + SELECT id INTO admin_role_id + FROM roles + WHERE code = 'admin'; + + IF admin_role_id IS NULL THEN + RAISE EXCEPTION 'CI bootstrap failed: admin role is missing before production reset'; + END IF; + + INSERT INTO users ( + username, + password_hash, + first_name, + last_name, + status, + must_change_password + ) VALUES ( + 'admin', + 'CI_BOOTSTRAP_ONLY_NOT_A_REAL_PASSWORD_HASH', + 'CI', + 'Bootstrap', + 'ACTIVE', + true + ) + RETURNING id INTO admin_user_id; + + INSERT INTO user_roles (user_id, role_id) + VALUES (admin_user_id, admin_role_id); + END $$; + SQL + + docker compose --env-file .env.example --profile tools run --rm migrate docker compose --env-file .env.example exec -T db \ psql -v ON_ERROR_STOP=1 -U dhv2_owner -d dhv2 <<'SQL'