Files
Assistant/deploy/apply-migrations.sh
m 89924a417a
CI / test (push) Successful in 23s
CI / test (pull_request) Successful in 23s
fix(deploy): use shell-safe migration history values
2026-08-22 14:51:59 +03:00

54 lines
2.1 KiB
Bash
Executable File

#!/usr/bin/env bash
set -euo pipefail
REPO_DIR="${REPO_DIR:-$(CDPATH= cd -- "$(dirname -- "$0")/.." && pwd)}"
ENV_FILE="${ENV_FILE:-/home/m/assistant-deploy/production-compose.env}"
POSTGRES_CONTAINER="${POSTGRES_CONTAINER:-assistant-postgres-1}"
if [[ ! -f "$ENV_FILE" ]]; then
echo "migration runner: env file is missing" >&2
exit 1
fi
set -a
# The deployment env file is controlled by the production operator. Values
# are used only by the local Docker/psql boundary and are never logged.
. "$ENV_FILE"
set +a
: "${POSTGRES_SUPERUSER:?POSTGRES_SUPERUSER is required}"
POSTGRES_SUPERUSER="${POSTGRES_SUPERUSER//$'\r'/}"
DATABASE="${POSTGRES_DB:-assistant}"
DATABASE="${DATABASE//$'\r'/}"
psql_exec() {
docker exec -i "$POSTGRES_CONTAINER" psql -v ON_ERROR_STOP=1 -U "$POSTGRES_SUPERUSER" -d "$DATABASE" "$@"
}
psql_exec -c "CREATE TABLE IF NOT EXISTS public.assistant_migration_history (migration_id TEXT PRIMARY KEY, applied_at_unix_millis BIGINT NOT NULL CHECK (applied_at_unix_millis > 0));"
if [[ -n "${MIGRATION_BASELINE:-}" ]]; then
if [[ ! "$MIGRATION_BASELINE" =~ ^[0-9]{3}$ ]]; then
echo "migration runner: invalid MIGRATION_BASELINE" >&2
exit 1
fi
now_ms="$(date +%s%3N)"
for file in "$REPO_DIR"/database/migrations/[0-9][0-9][0-9]_*.sql; do
migration_id="$(basename "$file" .sql)"
number="${migration_id:0:3}"
if (( 10#$number <= 10#$MIGRATION_BASELINE )); then
psql_exec -c "INSERT INTO public.assistant_migration_history(migration_id, applied_at_unix_millis) VALUES ('$migration_id', $now_ms) ON CONFLICT (migration_id) DO NOTHING;"
fi
done
fi
for file in "$REPO_DIR"/database/migrations/[0-9][0-9][0-9]_*.sql; do
[[ -f "$file" ]] || continue
migration_id="$(basename "$file" .sql)"
applied="$(psql_exec -At -c "SELECT 1 FROM public.assistant_migration_history WHERE migration_id='$migration_id' LIMIT 1;")"
[[ "$applied" == "1" ]] && continue
psql_exec < "$file"
now_ms="$(date +%s%3N)"
psql_exec -c "INSERT INTO public.assistant_migration_history(migration_id, applied_at_unix_millis) VALUES ('$migration_id', $now_ms);"
done