Some checks failed
Release production image / production-image (push) Has been cancelled
40 lines
3.1 KiB
Bash
Executable File
40 lines
3.1 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
set -euo pipefail
|
|
umask 077
|
|
ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
|
IMAGE="${CONDUCTOR_TEST_IMAGE:-conductor:slice8-test}"
|
|
PROJECT="conductor-release-test-${RANDOM}"
|
|
PORT="${CONDUCTOR_TEST_PORT:-3202}"
|
|
work="$(mktemp -d)"
|
|
env_file="${work}/.env"
|
|
backup_dir="${work}/backups"
|
|
compose=(docker compose -p "$PROJECT" --env-file "$env_file" -f "$ROOT/compose.production.yml")
|
|
cleanup() { "${compose[@]}" down -v --remove-orphans >/dev/null 2>&1 || true; rm -rf -- "$work"; }
|
|
trap cleanup EXIT
|
|
|
|
if [[ "${1:-}" != "--skip-build" ]]; then docker build -f "$ROOT/Dockerfile.production" -t "$IMAGE" "$ROOT"; fi
|
|
if docker run --rm "$IMAGE" >/dev/null 2>&1; then echo "Production image started without required keys." >&2; exit 1; fi
|
|
cat > "$env_file" <<EOF
|
|
CONDUCTOR_SECRET_KEY=1111111111111111111111111111111111111111111111111111111111111111
|
|
CONDUCTOR_SESSION_KEY=22222222222222222222222222222222
|
|
CONDUCTOR_IMAGE=${IMAGE%:*}
|
|
CONDUCTOR_VERSION=${IMAGE##*:}
|
|
CONDUCTOR_BIND_ADDRESS=127.0.0.1
|
|
CONDUCTOR_PORT=${PORT}
|
|
EOF
|
|
"${compose[@]}" up -d --no-build
|
|
curl --fail --silent --show-error --retry 20 --retry-delay 1 --retry-all-errors "http://127.0.0.1:${PORT}/api/health" >/dev/null
|
|
curl --fail --silent --show-error "http://127.0.0.1:${PORT}/" | grep -qi '<!doctype html>'
|
|
curl --fail --silent --show-error "http://127.0.0.1:${PORT}/apps/test/details" | grep -qi '<!doctype html>'
|
|
api_status="$(curl --silent --output /dev/null --write-out '%{http_code}' "http://127.0.0.1:${PORT}/api/not-a-route")"
|
|
[[ "$api_status" == 404 ]] || { echo "Unknown API routes must return 404, not the SPA." >&2; exit 1; }
|
|
"${compose[@]}" exec -T conductor node -e 'const D=require("better-sqlite3");const d=new D("/data/conductor.db");d.prepare("INSERT INTO projects(name,description,project_json) VALUES(?,?,?)").run("release-restore-marker","test","{}");d.close()'
|
|
COMPOSE_PROJECT_NAME="$PROJECT" "$ROOT/scripts/production/backup-conductor.sh" --compose-file "$ROOT/compose.production.yml" --env-file "$env_file" --backup-dir "$backup_dir" --retention-days 1 >/dev/null
|
|
archive="$(find "$backup_dir" -name 'conductor_*.tar.gz' -type f | head -n1)"
|
|
"${compose[@]}" exec -T conductor node -e 'const D=require("better-sqlite3");const d=new D("/data/conductor.db");d.prepare("DELETE FROM projects WHERE name=?").run("release-restore-marker");d.close()'
|
|
COMPOSE_PROJECT_NAME="$PROJECT" "$ROOT/scripts/production/restore-conductor.sh" --compose-file "$ROOT/compose.production.yml" --env-file "$env_file" --backup-dir "$backup_dir" --backup-file "$archive" --skip-safety-backup --force >/dev/null
|
|
count="$("${compose[@]}" exec -T conductor node -e 'const D=require("better-sqlite3");const d=new D("/data/conductor.db",{readonly:true});process.stdout.write(String(d.prepare("SELECT count(*) FROM projects WHERE name=?").pluck().get("release-restore-marker")));d.close()')"
|
|
[[ "$count" == 1 ]] || { echo "Restore marker was not recovered." >&2; exit 1; }
|
|
docker inspect "$("${compose[@]}" ps -q conductor)" --format '{{.Config.User}} {{.HostConfig.ReadonlyRootfs}}' | grep -q '^conductor true$'
|
|
echo '{"productionValidation":"passed"}'
|