#!/usr/bin/env bash set -euo pipefail ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" cd "$ROOT" PROJECT_ID="${RAILWAY_PROJECT_ID:-a6bc4ea7-e89c-42da-819a-8879fb022a0d}" ENVIRONMENT="${RAILWAY_ENVIRONMENT:-production}" ENV_FILE="${RAILWAY_ENV_FILE:-$ROOT/.env}" SERVICE_SELECTOR="all" MESSAGE="" SYNC_ENV=false DRY_RUN=false DETACH=true usage() { cat <<'USAGE' Deploy Railway services from this monorepo. Usage: scripts/railway-deploy.sh [all|platform|extraction] [options] Options: --project Railway project ID (default: $RAILWAY_PROJECT_ID or script default) --env Railway environment name (default: $RAILWAY_ENVIRONMENT or production) --message Deployment message --sync-env Sync variables from .env before deploying (uses railway-sync-env.sh) --env-file Env file path used when --sync-env is set (default: ./.env) --attach Attach to deployment logs instead of detached mode --dry-run Print what would run without deploying -h, --help Show help Examples: scripts/railway-deploy.sh all scripts/railway-deploy.sh extraction --message "hotfix: parser" scripts/railway-deploy.sh platform --sync-env --env-file .env USAGE } if [[ $# -gt 0 && "${1#-}" == "$1" ]]; then SERVICE_SELECTOR="$1" shift fi while [[ $# -gt 0 ]]; do case "$1" in --project) PROJECT_ID="${2:-}" shift 2 ;; --env) ENVIRONMENT="${2:-}" shift 2 ;; --message) MESSAGE="${2:-}" shift 2 ;; --sync-env) SYNC_ENV=true shift ;; --env-file) ENV_FILE="${2:-}" shift 2 ;; --attach) DETACH=false shift ;; --dry-run) DRY_RUN=true shift ;; -h|--help) usage exit 0 ;; *) echo "Unknown arg: $1" >&2 usage exit 2 ;; esac done SERVICES=() case "$SERVICE_SELECTOR" in all) SERVICES=("platform-service" "extraction-service") ;; platform|platform-service) SERVICES=("platform-service") ;; extraction|extraction-service) SERVICES=("extraction-service") ;; *) echo "Unknown service selector: $SERVICE_SELECTOR" >&2 usage exit 2 ;; esac if [[ -z "$PROJECT_ID" ]]; then echo "Missing Railway project ID. Use --project or set RAILWAY_PROJECT_ID." >&2 exit 2 fi if [[ -z "$ENVIRONMENT" ]]; then echo "Missing Railway environment. Use --env or set RAILWAY_ENVIRONMENT." >&2 exit 2 fi if [[ -z "$MESSAGE" ]]; then if command -v git >/dev/null 2>&1 && git rev-parse --git-dir >/dev/null 2>&1; then sha="$(git rev-parse --short HEAD 2>/dev/null || true)" dirty="" if [[ -n "$(git status --porcelain 2>/dev/null || true)" ]]; then dirty=" (dirty)" fi MESSAGE="deploy ${sha}${dirty}" else MESSAGE="deploy $(date -u +%Y-%m-%dT%H:%M:%SZ)" fi fi if ! command -v railway >/dev/null 2>&1; then echo "railway CLI not found. Install with: npm i -g @railway/cli" >&2 exit 1 fi if [[ "$DRY_RUN" == false ]]; then if ! railway whoami >/dev/null 2>&1; then echo "Railway CLI is not authenticated. Run: railway login" >&2 exit 1 fi fi if [[ "$SYNC_ENV" == true ]]; then sync_cmd=( "scripts/railway-sync-env.sh" "$SERVICE_SELECTOR" "--project" "$PROJECT_ID" "--env" "$ENVIRONMENT" "--env-file" "$ENV_FILE" ) if [[ "$DRY_RUN" == true ]]; then sync_cmd+=("--dry-run") fi echo "Syncing variables before deployment..." "${sync_cmd[@]}" fi for svc in "${SERVICES[@]}"; do cmd=(railway up -p "$PROJECT_ID" -e "$ENVIRONMENT" -s "$svc" -m "$MESSAGE") if [[ "$DETACH" == true ]]; then cmd+=(-d) fi if [[ "$DRY_RUN" == true ]]; then printf 'DRY RUN:' printf ' %q' "${cmd[@]}" printf '\n' continue fi echo "Deploying $svc (project=$PROJECT_ID, env=$ENVIRONMENT)..." "${cmd[@]}" done echo "Deployment command(s) submitted." echo "To verify status quickly:" echo " railway link --project $PROJECT_ID --environment $ENVIRONMENT" echo " railway service status -a -e $ENVIRONMENT"