#!/usr/bin/env bash set -euo pipefail SERVICE_NAME="${1:-}" if [ -z "$SERVICE_NAME" ]; then echo "Usage: ./deploy-core-service.sh " exit 1 fi CONFIG_FILE="/opt/appfactory/config/appfactory.env" source "$CONFIG_FILE" export DOCKER_CONFIG="/tmp/.docker" mkdir -p "$DOCKER_CONFIG" DB_FILE="/opt/appfactory/data/appfactory/appfactory.db" SERVICE_DIR="$WORKSPACE_DIR/$SERVICE_NAME" DEPLOY_DIR="$APPFACTORY_DIR/deploy" if [ ! -d "$SERVICE_DIR" ]; then echo "Missing service directory: $SERVICE_DIR" exit 1 fi if [ ! -f "$SERVICE_DIR/Dockerfile" ]; then echo "Missing Dockerfile: $SERVICE_DIR/Dockerfile" exit 1 fi DEPLOY_ID="$(python3 - "$DB_FILE" "$SERVICE_NAME" <<'PY' import sqlite3 import sys db_file = sys.argv[1] app_id = sys.argv[2] con = sqlite3.connect(db_file) cur = con.execute( """ INSERT INTO deployments ( app_id, kind, status, started_at ) VALUES (?, ?, ?, CURRENT_TIMESTAMP) """, (app_id, "core", "running"), ) con.commit() print(cur.lastrowid) con.close() PY )" TMP_DIR="$(mktemp -d)" STDOUT_FILE="$TMP_DIR/stdout.log" STDERR_FILE="$TMP_DIR/stderr.log" finish_deploy() { local status="$1" local returncode="$2" python3 - "$DB_FILE" "$DEPLOY_ID" "$status" "$returncode" "$STDOUT_FILE" "$STDERR_FILE" <<'PY' import sqlite3 import sys from pathlib import Path db_file = sys.argv[1] deploy_id = sys.argv[2] status = sys.argv[3] returncode = int(sys.argv[4]) stdout_file = Path(sys.argv[5]) stderr_file = Path(sys.argv[6]) stdout = stdout_file.read_text(errors="replace") if stdout_file.exists() else "" stderr = stderr_file.read_text(errors="replace") if stderr_file.exists() else "" con = sqlite3.connect(db_file) con.execute( """ UPDATE deployments SET status = ?, finished_at = CURRENT_TIMESTAMP, stdout = ?, stderr = ?, returncode = ? WHERE id = ? """, (status, stdout, stderr, returncode, deploy_id), ) con.commit() con.close() PY rm -rf "$TMP_DIR" } run_step() { local title="$1" shift { echo "" echo "==================================================" echo "$title" echo "==================================================" "$@" } >>"$STDOUT_FILE" 2>>"$STDERR_FILE" } set +e run_step "Updating source" bash -c " cd '$SERVICE_DIR' git \ -c safe.directory='$SERVICE_DIR' \ fetch origin main git \ -c safe.directory='$SERVICE_DIR' \ reset --hard origin/main " RESULT=$? if [ "$RESULT" -eq 0 ]; then run_step "Building image" docker build --pull --no-cache -t "$SERVICE_NAME:latest" "$SERVICE_DIR" RESULT=$? fi if [ "$RESULT" -eq 0 ]; then run_step "Recreating container" bash -c " cd '$DEPLOY_DIR' docker compose \ -f docker-compose.yml \ -f apps-compose.yml \ up -d --force-recreate '$SERVICE_NAME' " RESULT=$? fi set -e if [ "$RESULT" -eq 0 ]; then finish_deploy "success" 0 cat "$STDOUT_FILE" cat "$STDERR_FILE" >&2 echo "" echo "DONE" echo "Core service deployed: $SERVICE_NAME" else finish_deploy "failed" "$RESULT" cat "$STDOUT_FILE" cat "$STDERR_FILE" >&2 echo "" echo "FAILED" echo "Deployment ID: $DEPLOY_ID" exit "$RESULT" fi