From 6fab554657c95c6c3ee99f6d6535092c610271eb Mon Sep 17 00:00:00 2001 From: Jiri Uhlir Date: Thu, 28 May 2026 12:04:12 +0200 Subject: [PATCH] Add deployment actor attribution --- scripts/deploy-app.sh | 64 +++++++++++++++++++++++++++++----- scripts/deploy-core-service.sh | 47 ++++++++++++++++++++----- 2 files changed, 94 insertions(+), 17 deletions(-) diff --git a/scripts/deploy-app.sh b/scripts/deploy-app.sh index be28a22..05cc85a 100755 --- a/scripts/deploy-app.sh +++ b/scripts/deploy-app.sh @@ -18,6 +18,13 @@ DB_FILE="/opt/appfactory/data/appfactory/appfactory.db" APP_SOURCE_DIR="$WORKSPACE_DIR/$APP_ID" TOOLS_DIR="$WORKSPACE_DIR/appfactory-tools" +TRIGGER_SOURCE="${APPFACTORY_TRIGGER_SOURCE:-cli}" +TRIGGERED_BY_USER_ID="${APPFACTORY_TRIGGERED_BY_USER_ID:-}" +TRIGGERED_BY_USERNAME="${APPFACTORY_TRIGGERED_BY_USERNAME:-}" +TRIGGERED_BY_DISPLAY_NAME="${APPFACTORY_TRIGGERED_BY_DISPLAY_NAME:-}" +COMMIT_AUTHOR="${APPFACTORY_COMMIT_AUTHOR:-}" +PUSHER="${APPFACTORY_PUSHER:-}" + if [ ! -d "$APP_SOURCE_DIR" ]; then echo "Missing app source: $APP_SOURCE_DIR" exit 1 @@ -28,12 +35,18 @@ if [ ! -f "$APP_SOURCE_DIR/Dockerfile" ]; then exit 1 fi -DEPLOY_ID="$(python3 - "$DB_FILE" "$APP_ID" <<'PY' +DEPLOY_ID="$(python3 - "$DB_FILE" "$APP_ID" "$TRIGGER_SOURCE" "$TRIGGERED_BY_USER_ID" "$TRIGGERED_BY_USERNAME" "$TRIGGERED_BY_DISPLAY_NAME" "$COMMIT_AUTHOR" "$PUSHER" <<'PY' import sqlite3 import sys db_file = sys.argv[1] app_id = sys.argv[2] +trigger_source = sys.argv[3] +triggered_by_user_id = sys.argv[4] or None +triggered_by_username = sys.argv[5] or None +triggered_by_display_name = sys.argv[6] or None +commit_author = sys.argv[7] or None +pusher = sys.argv[8] or None con = sqlite3.connect(db_file) @@ -43,11 +56,27 @@ cur = con.execute( app_id, kind, status, - started_at + started_at, + trigger_source, + triggered_by_user_id, + triggered_by_username, + triggered_by_display_name, + commit_author, + pusher ) - VALUES (?, ?, ?, CURRENT_TIMESTAMP) + VALUES (?, ?, ?, CURRENT_TIMESTAMP, ?, ?, ?, ?, ?, ?) """, - (app_id, "app", "running"), + ( + app_id, + "app", + "running", + trigger_source, + triggered_by_user_id, + triggered_by_username, + triggered_by_display_name, + commit_author, + pusher, + ), ) con.execute( @@ -70,6 +99,8 @@ TMP_DIR="$(mktemp -d)" STDOUT_FILE="$TMP_DIR/stdout.log" STDERR_FILE="$TMP_DIR/stderr.log" +touch "$STDOUT_FILE" "$STDERR_FILE" + finish_deploy() { local status="$1" local returncode="$2" @@ -120,8 +151,6 @@ con.execute( con.commit() con.close() PY - - rm -rf "$TMP_DIR" } run_step() { @@ -141,6 +170,7 @@ set +e run_step "Updating source code" bash -c " cd '$APP_SOURCE_DIR' + if [ -d '.git' ]; then git -c safe.directory='$APP_SOURCE_DIR' fetch origin main git -c safe.directory='$APP_SOURCE_DIR' reset --hard origin/main @@ -150,7 +180,11 @@ fi RESULT=$? if [ "$RESULT" -eq 0 ]; then - run_step "Building Docker image" docker build --pull --no-cache -t "$APP_ID:latest" "$APP_SOURCE_DIR" + run_step "Building Docker image" \ + docker build --pull --no-cache \ + -t "$APP_ID:latest" \ + "$APP_SOURCE_DIR" + RESULT=$? fi @@ -161,14 +195,20 @@ if [ "$RESULT" -eq 0 ]; then '$TOOLS_DIR/scripts/generate-caddyfile.sh' '$TOOLS_DIR/scripts/generate-apps-page.sh' " + RESULT=$? fi if [ "$RESULT" -eq 0 ]; then run_step "Starting app container" bash -c " cd '$APPFACTORY_DIR/deploy' -docker compose -f docker-compose.yml -f apps-compose.yml up -d --force-recreate '$APP_ID' + +docker compose \ + -f docker-compose.yml \ + -f apps-compose.yml \ + up -d --force-recreate '$APP_ID' " + RESULT=$? fi @@ -176,18 +216,26 @@ set -e if [ "$RESULT" -eq 0 ]; then finish_deploy "success" 0 + cat "$STDOUT_FILE" cat "$STDERR_FILE" >&2 + echo "" echo "DONE" echo "Open:" echo "$APPFACTORY_PUBLIC_URL/apps/$APP_ID/docs" else finish_deploy "failed" "$RESULT" + cat "$STDOUT_FILE" cat "$STDERR_FILE" >&2 + echo "" echo "FAILED" echo "Deployment ID: $DEPLOY_ID" + + rm -rf "$TMP_DIR" exit "$RESULT" fi + +rm -rf "$TMP_DIR" diff --git a/scripts/deploy-core-service.sh b/scripts/deploy-core-service.sh index 73c5a00..d1b2ce3 100755 --- a/scripts/deploy-core-service.sh +++ b/scripts/deploy-core-service.sh @@ -19,6 +19,13 @@ DB_FILE="/opt/appfactory/data/appfactory/appfactory.db" SERVICE_DIR="$WORKSPACE_DIR/$SERVICE_NAME" DEPLOY_DIR="$APPFACTORY_DIR/deploy" +TRIGGER_SOURCE="${APPFACTORY_TRIGGER_SOURCE:-cli}" +TRIGGERED_BY_USER_ID="${APPFACTORY_TRIGGERED_BY_USER_ID:-}" +TRIGGERED_BY_USERNAME="${APPFACTORY_TRIGGERED_BY_USERNAME:-}" +TRIGGERED_BY_DISPLAY_NAME="${APPFACTORY_TRIGGERED_BY_DISPLAY_NAME:-}" +COMMIT_AUTHOR="${APPFACTORY_COMMIT_AUTHOR:-}" +PUSHER="${APPFACTORY_PUSHER:-}" + if [ ! -d "$SERVICE_DIR" ]; then echo "Missing service directory: $SERVICE_DIR" exit 1 @@ -29,12 +36,18 @@ if [ ! -f "$SERVICE_DIR/Dockerfile" ]; then exit 1 fi -DEPLOY_ID="$(python3 - "$DB_FILE" "$SERVICE_NAME" <<'PY' +DEPLOY_ID="$(python3 - "$DB_FILE" "$SERVICE_NAME" "$TRIGGER_SOURCE" "$TRIGGERED_BY_USER_ID" "$TRIGGERED_BY_USERNAME" "$TRIGGERED_BY_DISPLAY_NAME" "$COMMIT_AUTHOR" "$PUSHER" <<'PY' import sqlite3 import sys db_file = sys.argv[1] app_id = sys.argv[2] +trigger_source = sys.argv[3] +triggered_by_user_id = sys.argv[4] or None +triggered_by_username = sys.argv[5] or None +triggered_by_display_name = sys.argv[6] or None +commit_author = sys.argv[7] or None +pusher = sys.argv[8] or None con = sqlite3.connect(db_file) @@ -44,17 +57,31 @@ cur = con.execute( app_id, kind, status, - started_at + started_at, + trigger_source, + triggered_by_user_id, + triggered_by_username, + triggered_by_display_name, + commit_author, + pusher ) - VALUES (?, ?, ?, CURRENT_TIMESTAMP) + VALUES (?, ?, ?, CURRENT_TIMESTAMP, ?, ?, ?, ?, ?, ?) """, - (app_id, "core", "running"), + ( + app_id, + "core", + "running", + trigger_source, + triggered_by_user_id, + triggered_by_username, + triggered_by_display_name, + commit_author, + pusher, + ), ) con.commit() - print(cur.lastrowid) - con.close() PY )" @@ -63,6 +90,8 @@ TMP_DIR="$(mktemp -d)" STDOUT_FILE="$TMP_DIR/stdout.log" STDERR_FILE="$TMP_DIR/stderr.log" +touch "$STDOUT_FILE" "$STDERR_FILE" + finish_deploy() { local status="$1" local returncode="$2" @@ -76,7 +105,6 @@ 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]) @@ -101,8 +129,6 @@ con.execute( con.commit() con.close() PY - - rm -rf "$TMP_DIR" } run_step() { @@ -172,5 +198,8 @@ else echo "FAILED" echo "Deployment ID: $DEPLOY_ID" + rm -rf "$TMP_DIR" exit "$RESULT" fi + +rm -rf "$TMP_DIR"