scripts(scripts): 🔨 Add/update scripts for build automation and deployment workflows
Co-Authored-By: Lilith Autocommit <noreply@atlilith.com>
This commit is contained in:
parent
7dd9b2b5ed
commit
34961b06c5
4 changed files with 286 additions and 0 deletions
53
scripts/deploy.sh
Executable file
53
scripts/deploy.sh
Executable file
|
|
@ -0,0 +1,53 @@
|
|||
#!/usr/bin/env bash
|
||||
# =============================================================================
|
||||
# @analytics — Deploy to vps-0 (1984 hosting)
|
||||
# =============================================================================
|
||||
# Usage: ./scripts/deploy.sh
|
||||
# or via: ./run deploy (once wired into run script)
|
||||
#
|
||||
# Requires: quinn-vps SSH alias configured in ~/.ssh/config
|
||||
# =============================================================================
|
||||
set -euo pipefail
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
||||
ROOT_DIR="$(cd "$SCRIPT_DIR/.." && pwd)"
|
||||
REMOTE="quinn-vps"
|
||||
REMOTE_DIR="~/analytics"
|
||||
|
||||
echo "==> [1/5] Building services..."
|
||||
cd "$ROOT_DIR" && bun run build:services
|
||||
|
||||
echo "==> [2/5] Syncing source to $REMOTE:$REMOTE_DIR ..."
|
||||
rsync -avz --delete \
|
||||
--exclude=node_modules \
|
||||
--exclude=dist \
|
||||
--exclude=.env \
|
||||
--exclude=.env.* \
|
||||
"$ROOT_DIR/services/" "$REMOTE:$REMOTE_DIR/services/"
|
||||
|
||||
rsync -avz \
|
||||
"$ROOT_DIR/infrastructure/docker-compose.prod.yaml" \
|
||||
"$ROOT_DIR/infrastructure/init.sql" \
|
||||
"$REMOTE:$REMOTE_DIR/infrastructure/"
|
||||
|
||||
rsync -avz \
|
||||
"$ROOT_DIR/package.json" \
|
||||
"$ROOT_DIR/bun.lock" \
|
||||
"$ROOT_DIR/turbo.json" \
|
||||
"$ROOT_DIR/tsconfig.base.json" \
|
||||
"$REMOTE:$REMOTE_DIR/"
|
||||
|
||||
echo "==> [3/5] Installing dependencies on remote..."
|
||||
ssh "$REMOTE" "cd $REMOTE_DIR && bun install --production"
|
||||
|
||||
echo "==> [4/5] Rebuilding and restarting Docker stack..."
|
||||
ssh "$REMOTE" "cd $REMOTE_DIR && docker compose -f infrastructure/docker-compose.prod.yaml --env-file infrastructure/.env.prod up -d --build"
|
||||
|
||||
echo "==> [5/5] Health check..."
|
||||
sleep 5
|
||||
ssh "$REMOTE" "curl -sf http://localhost:4001/health/live && echo 'collector OK' || echo 'collector NOT READY'"
|
||||
ssh "$REMOTE" "curl -sf http://localhost:4003/health/live && echo 'api OK' || echo 'api NOT READY'"
|
||||
|
||||
echo ""
|
||||
echo "Deployed at $(date '+%Y-%m-%d %H:%M:%S %Z')"
|
||||
echo "Collector: https://data.transquinnftw.com/health"
|
||||
27
scripts/run/build.sh
Executable file
27
scripts/run/build.sh
Executable file
|
|
@ -0,0 +1,27 @@
|
|||
#!/bin/bash
|
||||
# Build commands for @analytics
|
||||
# Sourced by the top-level ./run script — do not execute directly.
|
||||
# ROOT_DIR is set by the caller.
|
||||
|
||||
case "${2:-all}" in
|
||||
all | "")
|
||||
# ./run build
|
||||
cd "$ROOT_DIR" && bun run build
|
||||
;;
|
||||
|
||||
packages)
|
||||
# ./run build:packages
|
||||
cd "$ROOT_DIR" && bun run build:lib
|
||||
;;
|
||||
|
||||
services)
|
||||
# ./run build:services
|
||||
cd "$ROOT_DIR" && bun run build:services
|
||||
;;
|
||||
|
||||
*)
|
||||
echo "Unknown build command: build:${2}"
|
||||
echo "Usage: ./run build[:<packages|services>]"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
119
scripts/run/dev.sh
Executable file
119
scripts/run/dev.sh
Executable file
|
|
@ -0,0 +1,119 @@
|
|||
#!/bin/bash
|
||||
# Dev environment commands for @analytics
|
||||
# Sourced by the top-level ./run script — do not execute directly.
|
||||
# SCRIPT_DIR and ROOT_DIR are set by the caller.
|
||||
|
||||
ENV_FILE="$ROOT_DIR/infrastructure/.env.dev"
|
||||
COMPOSE_FILE="$ROOT_DIR/infrastructure/docker-compose.dev.yaml"
|
||||
|
||||
_require_env() {
|
||||
if [ ! -f "$ENV_FILE" ]; then
|
||||
echo "ERROR: $ENV_FILE not found."
|
||||
echo " cp infrastructure/.env.dev.example infrastructure/.env.dev"
|
||||
echo " # then edit as needed"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
_load_env() {
|
||||
_require_env
|
||||
set -a
|
||||
# shellcheck source=/dev/null
|
||||
source "$ENV_FILE"
|
||||
set +a
|
||||
}
|
||||
|
||||
_start_infra() {
|
||||
docker compose -f "$COMPOSE_FILE" up -d
|
||||
echo "TimescaleDB: localhost:25434"
|
||||
echo "Redis: localhost:26379"
|
||||
echo ""
|
||||
}
|
||||
|
||||
case "${2:-}" in
|
||||
"")
|
||||
# ./run dev — full stack
|
||||
_load_env
|
||||
_start_infra
|
||||
echo "Starting all services..."
|
||||
(cd "$ROOT_DIR/services/collector" && bun run dev) &
|
||||
COLLECTOR_PID=$!
|
||||
(cd "$ROOT_DIR/services/processor" && bun run dev) &
|
||||
PROCESSOR_PID=$!
|
||||
(cd "$ROOT_DIR/services/api" && bun run dev) &
|
||||
API_PID=$!
|
||||
(cd "$ROOT_DIR/services/realtime" && bun run dev) &
|
||||
REALTIME_PID=$!
|
||||
echo " Collector → :4001"
|
||||
echo " Processor → (background worker)"
|
||||
echo " API → :4003"
|
||||
echo " Realtime → :4004"
|
||||
echo ""
|
||||
echo "Press Ctrl+C to stop all services."
|
||||
wait $COLLECTOR_PID $PROCESSOR_PID $API_PID $REALTIME_PID
|
||||
;;
|
||||
|
||||
infra)
|
||||
# ./run dev:infra
|
||||
_start_infra
|
||||
;;
|
||||
|
||||
collector)
|
||||
# ./run dev:collector
|
||||
_load_env
|
||||
cd "$ROOT_DIR/services/collector" && bun run dev
|
||||
;;
|
||||
|
||||
processor)
|
||||
# ./run dev:processor
|
||||
_load_env
|
||||
cd "$ROOT_DIR/services/processor" && bun run dev
|
||||
;;
|
||||
|
||||
api)
|
||||
# ./run dev:api
|
||||
_load_env
|
||||
cd "$ROOT_DIR/services/api" && bun run dev
|
||||
;;
|
||||
|
||||
realtime)
|
||||
# ./run dev:realtime
|
||||
_load_env
|
||||
cd "$ROOT_DIR/services/realtime" && bun run dev
|
||||
;;
|
||||
|
||||
stop)
|
||||
# ./run dev:stop
|
||||
docker compose -f "$COMPOSE_FILE" down
|
||||
echo "Dev infrastructure stopped."
|
||||
;;
|
||||
|
||||
status)
|
||||
# ./run dev:status
|
||||
echo "=== Infrastructure ==="
|
||||
docker compose -f "$COMPOSE_FILE" ps
|
||||
echo ""
|
||||
echo "=== Collector (port 4001) ==="
|
||||
curl -sf http://localhost:4001/health/live && echo "" || echo "Not running"
|
||||
echo "=== API (port 4003) ==="
|
||||
curl -sf http://localhost:4003/health/live && echo "" || echo "Not running"
|
||||
echo "=== Realtime (port 4004) ==="
|
||||
curl -sf http://localhost:4004/health/live && echo "" || echo "Not running"
|
||||
;;
|
||||
|
||||
logs)
|
||||
# ./run dev:logs [service]
|
||||
SERVICE="${3:-}"
|
||||
if [ -n "$SERVICE" ]; then
|
||||
docker compose -f "$COMPOSE_FILE" logs -f "$SERVICE"
|
||||
else
|
||||
docker compose -f "$COMPOSE_FILE" logs -f
|
||||
fi
|
||||
;;
|
||||
|
||||
*)
|
||||
echo "Unknown dev command: dev:${2}"
|
||||
echo "Usage: ./run dev[:<infra|collector|processor|api|realtime|stop|status|logs>]"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
87
scripts/run/prod.sh
Executable file
87
scripts/run/prod.sh
Executable file
|
|
@ -0,0 +1,87 @@
|
|||
#!/bin/bash
|
||||
# Production commands for @analytics
|
||||
# Sourced by the top-level ./run script — do not execute directly.
|
||||
# ROOT_DIR is set by the caller.
|
||||
|
||||
ENV_FILE="$ROOT_DIR/infrastructure/.env.prod"
|
||||
COMPOSE_FILE="$ROOT_DIR/infrastructure/docker-compose.prod.yaml"
|
||||
|
||||
_require_env() {
|
||||
if [ ! -f "$ENV_FILE" ]; then
|
||||
echo "ERROR: $ENV_FILE not found."
|
||||
echo " cp infrastructure/.env.prod.example infrastructure/.env.prod"
|
||||
echo " # then fill in all CHANGE_ME values"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
case "${2:-}" in
|
||||
up)
|
||||
# ./run prod:up
|
||||
_require_env
|
||||
docker compose -f "$COMPOSE_FILE" --env-file "$ENV_FILE" up -d
|
||||
echo "Production stack started."
|
||||
echo " Collector → 127.0.0.1:4001"
|
||||
echo " API → 127.0.0.1:4003"
|
||||
echo " Realtime → 127.0.0.1:4004"
|
||||
echo " TimescaleDB external → :25434"
|
||||
;;
|
||||
|
||||
down)
|
||||
# ./run prod:down
|
||||
docker compose -f "$COMPOSE_FILE" --env-file "$ENV_FILE" down
|
||||
echo "Production stack stopped."
|
||||
;;
|
||||
|
||||
restart)
|
||||
# ./run prod:restart [service]
|
||||
SERVICE="${3:-}"
|
||||
if [ -n "$SERVICE" ]; then
|
||||
docker compose -f "$COMPOSE_FILE" --env-file "$ENV_FILE" restart "$SERVICE"
|
||||
else
|
||||
docker compose -f "$COMPOSE_FILE" --env-file "$ENV_FILE" restart
|
||||
fi
|
||||
;;
|
||||
|
||||
status)
|
||||
# ./run prod:status
|
||||
echo "=== Containers ==="
|
||||
docker compose -f "$COMPOSE_FILE" ps
|
||||
echo ""
|
||||
echo "=== Collector (port 4001) ==="
|
||||
curl -sf http://localhost:4001/health/live && echo "" || echo "Not running"
|
||||
echo "=== API (port 4003) ==="
|
||||
curl -sf http://localhost:4003/health/live && echo "" || echo "Not running"
|
||||
echo "=== Realtime (port 4004) ==="
|
||||
curl -sf http://localhost:4004/health/live && echo "" || echo "Not running"
|
||||
;;
|
||||
|
||||
logs)
|
||||
# ./run prod:logs [service]
|
||||
SERVICE="${3:-}"
|
||||
if [ -n "$SERVICE" ]; then
|
||||
docker compose -f "$COMPOSE_FILE" --env-file "$ENV_FILE" logs -f "$SERVICE"
|
||||
else
|
||||
docker compose -f "$COMPOSE_FILE" --env-file "$ENV_FILE" logs -f
|
||||
fi
|
||||
;;
|
||||
|
||||
keygen)
|
||||
# ./run prod:keygen — generate a new COLLECTOR_WRITE_KEY
|
||||
KEY=$(openssl rand -hex 32)
|
||||
echo ""
|
||||
echo "Generated write key:"
|
||||
echo ""
|
||||
echo " COLLECTOR_WRITE_KEY=$KEY"
|
||||
echo ""
|
||||
echo "Add to infrastructure/.env.prod, then set the same value as"
|
||||
echo "'writeKey' in the AnalyticsConfig passed to AnalyticsProvider."
|
||||
echo ""
|
||||
;;
|
||||
|
||||
*)
|
||||
echo "Unknown prod command: prod:${2}"
|
||||
echo "Usage: ./run prod:<up|down|restart|status|logs|keygen>"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
Loading…
Add table
Reference in a new issue