Template
CI reads Infisical staging as the read-only convexmonorepo-ci machine identity, deploys the Convex functions, builds and pushes the image, and asks the VPS to redeploy. Payload schema changes now ship as migrations that production runs on startup; the baseline matches the production schema and is recorded as applied there. The local stack moves to its own ports and syncs the Convex runtime env, and the scripts pick up Infisical account switching, dev-kill and a cache-safe CI install.
101 lines
4.0 KiB
Bash
Executable File
101 lines
4.0 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
set -euo pipefail
|
|
|
|
SCRIPT_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)"
|
|
ROOT_DIR="$(cd -- "$SCRIPT_DIR/../.." && pwd)"
|
|
COMPOSE_FILE="$ROOT_DIR/docker/compose.local.yml"
|
|
STATE_FILE="$ROOT_DIR/.local/dev.generated.env"
|
|
ENV_FILE=""
|
|
|
|
info() { printf '▶ %s\n' "$*"; }
|
|
die() { printf 'Error: %s\n' "$*" >&2; exit 1; }
|
|
|
|
if command -v docker >/dev/null 2>&1; then RUNTIME=docker
|
|
elif command -v podman >/dev/null 2>&1; then RUNTIME=podman
|
|
else die "Docker or Podman is required."; fi
|
|
"$RUNTIME" info >/dev/null 2>&1 || die "$RUNTIME is not usable."
|
|
|
|
mkdir -p "$ROOT_DIR/.local"
|
|
cleanup() { [ -z "$ENV_FILE" ] || rm -f "$ENV_FILE"; }
|
|
trap cleanup EXIT
|
|
|
|
refresh_env() {
|
|
local next
|
|
next="$(mktemp "${TMPDIR:-/tmp}/convex-monorepo-local.XXXXXX.env")"
|
|
sh "$ROOT_DIR/scripts/export-env" dev > "$next" || { rm -f "$next"; die "Unable to export Infisical dev."; }
|
|
[ -z "$ENV_FILE" ] || rm -f "$ENV_FILE"
|
|
ENV_FILE="$next"
|
|
set -a
|
|
# shellcheck disable=SC1090
|
|
source "$ENV_FILE"
|
|
set +a
|
|
}
|
|
dc() { "$RUNTIME" compose --env-file "$ENV_FILE" -f "$COMPOSE_FILE" "$@"; }
|
|
upsert_state() {
|
|
local key="$1" value="$2" tmp escaped
|
|
tmp="$(mktemp "${TMPDIR:-/tmp}/convex-monorepo-state.XXXXXX.env")"
|
|
[ ! -f "$STATE_FILE" ] || grep -v "^${key}=" "$STATE_FILE" > "$tmp" || true
|
|
escaped="$(printf '%s' "$value" | sed "s/'/'\\\\''/g")"
|
|
printf "%s='%s'\n" "$key" "$escaped" >> "$tmp"
|
|
mv "$tmp" "$STATE_FILE"
|
|
}
|
|
|
|
refresh_env
|
|
info "Starting local Payload Postgres, Convex, and dashboard"
|
|
dc up -d
|
|
|
|
info "Waiting for Payload Postgres"
|
|
for i in $(seq 1 30); do
|
|
dc exec -T postgres pg_isready -U "${POSTGRES_USER:-convexmonorepo}" >/dev/null 2>&1 && break
|
|
[ "$i" -lt 30 ] || die "Postgres did not become ready."
|
|
sleep 1
|
|
done
|
|
|
|
info "Waiting for Convex at http://localhost:${BACKEND_PORT:-3240}"
|
|
for i in $(seq 1 60); do
|
|
curl -fs "http://localhost:${BACKEND_PORT:-3240}/version" >/dev/null 2>&1 && break
|
|
[ "$i" -lt 60 ] || die "Convex did not become ready."
|
|
sleep 2
|
|
done
|
|
|
|
if [ -z "${CONVEX_SELF_HOSTED_ADMIN_KEY:-}" ]; then
|
|
admin_key="$(dc exec -T convex-backend ./generate_admin_key.sh 2>/dev/null | grep -E '.+\|.+' | tail -n1 | tr -d '\r')"
|
|
[ -n "$admin_key" ] || die "Unable to generate the Convex admin key."
|
|
upsert_state CONVEX_SELF_HOSTED_ADMIN_KEY "$admin_key"
|
|
refresh_env
|
|
info "Generated the machine-local Convex admin key"
|
|
fi
|
|
|
|
info "Deploying Convex schema and functions"
|
|
(cd "$ROOT_DIR/packages/backend" && bun run setup)
|
|
|
|
# Env sync runs after the deploy: changing deployment env re-analyzes the
|
|
# deployed modules, which fails on a fresh volume before the first deploy.
|
|
info "Synchronizing the Convex function runtime environment"
|
|
sh "$ROOT_DIR/scripts/with-env" dev -- bash "$ROOT_DIR/scripts/sync-local-convex-env"
|
|
|
|
convex_env_names="$(
|
|
sh "$ROOT_DIR/scripts/with-env" dev -- bash -c \
|
|
'cd packages/backend && bunx convex env list' 2>/dev/null \
|
|
| sed -n 's/^\([A-Za-z_][A-Za-z0-9_]*\)=.*/\1/p'
|
|
)"
|
|
if ! printf '%s\n' "$convex_env_names" | grep -qx 'JWT_PRIVATE_KEY' \
|
|
|| ! printf '%s\n' "$convex_env_names" | grep -qx 'JWKS' \
|
|
|| ! printf '%s\n' "$convex_env_names" | grep -qx 'SITE_URL'; then
|
|
info "Configuring local Convex Auth keys"
|
|
auth_keys="$(node "$ROOT_DIR/scripts/generate-convex-auth-keys.mjs")"
|
|
jwt="$(printf '%s\n' "$auth_keys" | sed -n 's/^JWT_PRIVATE_KEY="\(.*\)"$/\1/p')"
|
|
jwks="$(printf '%s\n' "$auth_keys" | sed -n 's/^JWKS=//p')"
|
|
JWT_VAL="$jwt" JWKS_VAL="$jwks" sh "$ROOT_DIR/scripts/with-env" dev -- bash -c '
|
|
cd packages/backend
|
|
bunx convex env set "JWT_PRIVATE_KEY=$JWT_VAL" >/dev/null
|
|
bunx convex env set "JWKS=$JWKS_VAL" >/dev/null
|
|
bunx convex env set "SITE_URL=http://localhost:3000" >/dev/null
|
|
'
|
|
fi
|
|
|
|
info "Seeding local Payload from snapshot if needed"
|
|
bash "$ROOT_DIR/scripts/db/seed-payload" --yes
|
|
|
|
printf '\nLocal stack ready:\n App: http://localhost:3000\n Convex: http://localhost:%s\n Dashboard: http://localhost:%s\n Payload Postgres: localhost:%s\n' "${BACKEND_PORT:-3240}" "${DASHBOARD_PORT:-6794}" "${POSTGRES_PORT:-5436}"
|