Files
sciagent/be0/scripts/apply-migration-007.sh
T
Thinh Lam 688fac73e9
CI/CD / backend (push) Failing after 2m8s
CI/CD / frontend (push) Failing after 1m40s
CI/CD / deploy (push) Has been skipped
sciagent code + Gitea Actions CI/CD
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-30 09:38:30 +07:00

87 lines
3.1 KiB
Bash
Executable File

#!/usr/bin/env bash
# Apply migration 007 (user_roles.admin_from_email_policy) to an EXISTING Postgres.
# initdb scripts in docker-entrypoint-initdb.d run only on first volume creation.
#
# Default (full SQL file): adds column, runs one-time policy DELETE/UPDATE (see
# be0/migrations/007_user_roles_email_policy_admin.sql before running on prod).
#
# Usage (from anywhere):
# ./be0/scripts/apply-migration-007.sh
# ./be0/scripts/apply-migration-007.sh --schema-only # only ADD COLUMN (safest repeat)
#
# On a remote host (SSH to be0/docker host, repo or copy of migrations present):
# export POSTGRES_CONTAINER=initiative-postgres POSTGRES_USER=initiative POSTGRES_DB=initiatives
# ./be0/scripts/apply-migration-007.sh
#
# From repo root (wrapper):
# ./scripts/apply-migration-007-postgres.sh
set -euo pipefail
SCHEMA_ONLY=0
for arg in "$@"; do
case "$arg" in
--schema-only) SCHEMA_ONLY=1 ;;
-h|--help)
sed -n '2,20p' "$0"
exit 0
;;
esac
done
BE0_ROOT="$(cd "$(dirname "$0")/.." && pwd)"
SQL_FULL="$BE0_ROOT/migrations/007_user_roles_email_policy_admin.sql"
CONTAINER="${POSTGRES_CONTAINER:-initiative-postgres}"
PGUSER="${POSTGRES_USER:-initiative}"
PGDATABASE="${POSTGRES_DB:-initiatives}"
if ! docker info >/dev/null 2>&1; then
echo "error: Docker is not reachable (is the daemon running?)" >&2
exit 1
fi
if ! docker inspect "$CONTAINER" >/dev/null 2>&1; then
echo "error: container not found: $CONTAINER (set POSTGRES_CONTAINER)" >&2
exit 1
fi
if [[ "$(docker inspect -f '{{.State.Running}}' "$CONTAINER" 2>/dev/null || echo false)" != "true" ]]; then
echo "error: container is not running: $CONTAINER" >&2
exit 1
fi
apply_schema_only() {
docker exec -i "$CONTAINER" psql -U "$PGUSER" -d "$PGDATABASE" -v ON_ERROR_STOP=1 <<'SQL'
ALTER TABLE user_roles ADD COLUMN IF NOT EXISTS admin_from_email_policy BOOLEAN NOT NULL DEFAULT FALSE;
COMMENT ON COLUMN user_roles.admin_from_email_policy IS
'TRUE when admin was granted by email allow-list (AUTH_ADMIN_EMAILS). Reconciliation may DELETE this row if the user email is no longer in the list. FALSE preserves manually granted admin (future / exceptional).';
SQL
}
apply_full() {
if [[ ! -f "$SQL_FULL" ]]; then
echo "error: missing migration file: $SQL_FULL" >&2
exit 1
fi
docker exec -i "$CONTAINER" psql -U "$PGUSER" -d "$PGDATABASE" -v ON_ERROR_STOP=1 <"$SQL_FULL"
}
verify_column() {
local out
out="$(docker exec "$CONTAINER" psql -U "$PGUSER" -d "$PGDATABASE" -tAc \
"SELECT 1 FROM information_schema.columns WHERE table_schema = 'public' AND table_name = 'user_roles' AND column_name = 'admin_from_email_policy'")"
if [[ "${out//$'\r'/}" != "1" ]]; then
echo "error: verification failed: column admin_from_email_policy missing on public.user_roles" >&2
exit 1
fi
}
if (( SCHEMA_ONLY )); then
echo "Applying schema only (ADD COLUMN + COMMENT) → $CONTAINER / $PGDATABASE"
apply_schema_only
else
echo "Applying full 007_user_roles_email_policy_admin.sql → $CONTAINER / $PGDATABASE"
apply_full
fi
verify_column
echo "ok: user_roles.admin_from_email_policy is present; admin register/login should work with current be0."