From e4984ddce2c76e81c4992719b2570f42d829863f Mon Sep 17 00:00:00 2001 From: Orion Kindel Date: Sun, 16 Jul 2023 23:47:16 -0400 Subject: [PATCH] chore: rework migrations flow --- .env.schema | 1 - .gitignore | 1 - docker-compose.yml | 4 ++-- scripts/build.sh | 46 ++++++++++++++++++++-------------------------- scripts/diff.sh | 41 +++++++++++++++++++++-------------------- scripts/migrate.sh | 14 +++++++------- 6 files changed, 50 insertions(+), 57 deletions(-) diff --git a/.env.schema b/.env.schema index e520b19..429bba0 100644 --- a/.env.schema +++ b/.env.schema @@ -1,3 +1,2 @@ POSTGRES_USER=postgres POSTGRES_PASSWORD=password -POSTGRES_DB=dnim diff --git a/.gitignore b/.gitignore index fa2436b..0764e3b 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,3 @@ .env data tmp -migrations diff --git a/docker-compose.yml b/docker-compose.yml index 0e882ee..6336640 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -5,7 +5,7 @@ services: container_name: "base" image: "postgres:15.3-bullseye" ports: - - "5433:5432" + - "5432:5432" volumes: - "./data/base:/var/lib/postgresql/data" env_file: @@ -15,7 +15,7 @@ services: image: "postgres:15.3-bullseye" restart: "always" ports: - - "5432:5432" + - "5433:5432" volumes: - "./data/head:/var/lib/postgresql/data" env_file: diff --git a/scripts/build.sh b/scripts/build.sh index 9a8e4de..7cca97d 100755 --- a/scripts/build.sh +++ b/scripts/build.sh @@ -1,41 +1,35 @@ #! /bin/bash -set -ex +set -e source ./scripts/env.sh ./.env.schema -rev=${1:-HEAD} +docker compose down -if [[ -n $(git status --porcelain) ]]; then - echo "git working tree dirty" 1>&2; - exit 1; -fi +base_or_head="$1" +rev="$2" -if [[ "$rev" = "HEAD" ]]; then - head="" - port=5432 -else - head=$(git show --format=format:%h -q) - git reset --quiet --hard "$rev" +git worktree remove "./$base_or_head" || true +git worktree add "./$base_or_head" --detach "$rev" + +mkdir -p "./$base_or_head/data/$base_or_head" +ln -sr "../data/$base_or_head" "./$base_or_head/data/$base_or_head" +cp docker-compose.yml "./$base_or_head/docker-compose.yml" + +cd "./$base_or_head" +docker compose up -d "$base_or_head" +cd "../$base_or_head" + +if [[ "$base_or_head" = "head" ]]; then port=5433 +else + port=5432 fi -switch_back_to_head() { - if [[ -n "$head" ]]; then - git reset --quiet --hard "$head" - fi -} -trap 'switch_back_to_head' EXIT - url=postgresql://$POSTGRES_USER:$POSTGRES_PASSWORD@localhost:$port dropdb=$(mktemp) echo "drop database dnim with (force); create database dnim;" > "$dropdb" -psql --quiet "$url/postgres" --file="$dropdb" 1>/dev/null +psql --quiet "$url/postgres" --file="$dropdb" -ls ./schema/ | xargs -I{} \ - psql \ - --quiet \ - "$url/dnim" \ - --file=./schema/{} \ - 1>/dev/null +ls ./schema/ | xargs -I{} psql --quiet "$url/dnim" --file=./schema/{} diff --git a/scripts/diff.sh b/scripts/diff.sh index 1bc75f1..d39426d 100755 --- a/scripts/diff.sh +++ b/scripts/diff.sh @@ -4,40 +4,41 @@ set -e source ./scripts/env.sh ./.env.schema -rev=$(echo "$1" | xargs) -head_arg=$(echo "$2" | xargs) +base="$1" +head_arg="$2" head=$(git show --format=format:%h -q | xargs) if [[ -n "$head_arg" ]]; then head="$head_arg" fi; -migration="./migrations/${rev}_to_${head}.sql" +cd ./migrations 1>&2 +git pull +cd ../ 1>&2 -head_url=postgresql://$POSTGRES_USER:$POSTGRES_PASSWORD@localhost:5432/dnim -base_url=postgresql://$POSTGRES_USER:$POSTGRES_PASSWORD@localhost:5433/dnim +migration="./migrations/${base}_to_${head}.sql" -if [[ -z "$rev" ]]; then - echo "revision to diff is required" 1>&2; +base_url=postgresql://$POSTGRES_USER:$POSTGRES_PASSWORD@localhost:5432/dnim +head_url=postgresql://$POSTGRES_USER:$POSTGRES_PASSWORD@localhost:5433/dnim + +if [[ -z "$base" ]] || [ -z "$head" ]; then + echo "revisions to diff are required ex. ./scripts/diff.sh abc bcd" 1>&2; exit 1; fi -docker compose up -d 1>&2 - -rm -r ./migrations || true -git fetch --all 1>&2 -git restore ./migrations --source origin/manual_migrations 1>&2 - if [[ ! -f "$migration" ]]; then - ./scripts/build.sh "$rev" 1>&2 - ./scripts/build.sh HEAD 1>&2 - - echo "migrate from $rev => HEAD" 1>&2 + ./scripts/build.sh base "$base" 1>&2 + ./scripts/build.sh head "$head" 1>&2 - migra --unsafe $base_url $head_url >> "$migration" \ + until (pg_isready -p 5432 && pg_isready -p 5433) 1>/dev/null; do true; done; + + migra --unsafe "$base_url" "$head_url" > "$migration" \ || echo "migra exited with code $?. this is /probably/ fine" 1>&2 + + cd ./migrations + git add --all + git commit -m "$migration" + git push fi echo "$migration" - -docker compose down 1>&2 diff --git a/scripts/migrate.sh b/scripts/migrate.sh index c8fb8bd..510ba44 100755 --- a/scripts/migrate.sh +++ b/scripts/migrate.sh @@ -18,22 +18,22 @@ if [[ "$dnim_database_count" = "0" ]]; then echo "fresh database" psql "$POSTGRES_URI/postgres" -c "create database dnim;" ls ./schema/ | xargs -I{} psql --quiet "$POSTGRES_URI/dnim" --file=./schema/{} - last_revision='empty' + rev_last='empty' script='' else - get_last_revision="copy (select to_revision from migration order by performed_on desc limit 1) to stdout with null as '';" - last_revision=$(psql "$POSTGRES_URI/dnim" -c "$get_last_revision") - migration_file=$(./scripts/diff.sh "$last_revision" "$to_tag") + get_rev_last="copy (select to_revision from migration order by performed_on desc limit 1) to stdout with null as '';" + rev_last=$(psql "$POSTGRES_URI/dnim" -c "$get_rev_last") + migration=$(./scripts/diff.sh "$rev_last" "$to_tag") if [[ "$2" = "--greenlight" ]]; then - psql "$POSTGRES_URI/dnim" -v ON_ERROR_STOP=1 --single-transaction -f "$migration_file" + psql "$POSTGRES_URI/dnim" -v ON_ERROR_STOP=1 --single-transaction -f "$migration" else - echo "migration available at $migration_file" + echo "migration available at $migration" echo "review and rerun with --greenlight to apply" exit fi fi -insert_migration="insert into migration (from_revision, to_revision) values ('$last_revision', '$to_tag');" +insert_migration="insert into migration (from_revision, to_revision) values ('$rev_last', '$to_tag');" psql "$POSTGRES_URI/dnim" -c "$insert_migration" echo "inserted migration"