#!/usr/bin/env bash # # Run scripts/build-and-push.sh once per service listed in a project file. # Continues after a failure and prints a summary when the batch finishes. # That summary is also written to deploy-YYYYMMDD-HHMMSS.log in the directory # from which the script was launched. # # The list path is required (--services). Relative service paths are resolved # against the directory that contains that file, not the caller's cwd. # An optional second field, java or web, selects the Dockerfile location. set -euo pipefail IFS=$'\n\t' readonly SCRIPT_DIR="$(cd "$(dirname "$(readlink -f "$0")")" && pwd)" readonly BUILD_SCRIPT="${SCRIPT_DIR}/build-and-push.sh" SERVICES_FILE="" REMOTE="" forward_args=() # ---------- logging ---------- if [[ -t 1 ]]; then readonly C_INFO=$'\033[0;36m' readonly C_OK=$'\033[0;32m' readonly C_WARN=$'\033[0;33m' readonly C_ERR=$'\033[0;31m' readonly C_RESET=$'\033[0m' else readonly C_INFO="" C_OK="" C_WARN="" C_ERR="" C_RESET="" fi log() { printf '%s[INFO]%s %s\n' "$C_INFO" "$C_RESET" "$*"; } ok() { printf '%s[OK]%s %s\n' "$C_OK" "$C_RESET" "$*"; } warn() { printf '%s[WARN]%s %s\n' "$C_WARN" "$C_RESET" "$*" >&2; } err() { printf '%s[ERROR]%s %s\n' "$C_ERR" "$C_RESET" "$*" >&2; } die() { err "$*"; exit 1; } on_error() { local exit_code=$? err "Script aborted on line ${BASH_LINENO[0]} (exit ${exit_code})." exit "$exit_code" } trap on_error ERR # ---------- helpers ---------- usage() { cat <"$log_path"; then warn "Could not write log file: ${log_path}" return 0 fi log "Log file: ${log_path}" } total="${#service_paths[@]}" index=0 ok_count=0 fail_count=0 result_paths=() result_notes=() launch_dir="$(pwd)" run_started="$(date '+%Y-%m-%d %H:%M:%S %z')" log_stamp="$(date '+%Y%m%d-%H%M%S')" log_path="${launch_dir}/deploy-${log_stamp}.log" if [[ -e "$log_path" ]]; then log_path="${launch_dir}/deploy-${log_stamp}-$$.log" fi log "Services file: ${SERVICES_FILE}" log "Remote: ${REMOTE}" log "Services: ${total}" while [[ "$index" -lt "$total" ]]; do entry="${service_paths[$index]}" app_type="${service_types[$index]}" index=$((index + 1)) resolved="$(normalize_path "$(resolve_service "$entry")")" if [[ -d "$resolved" ]]; then resolved="$(cd "$resolved" && pwd)" fi printf '\n%s========== [%s/%s] %s ==========%s\n' \ "$C_INFO" "$index" "$total" "$resolved" "$C_RESET" if [[ ! -d "$resolved" ]]; then err "Service directory not found: ${resolved}" result_paths+=("$resolved") result_notes+=("not found") fail_count=$((fail_count + 1)) continue fi exit_code=0 if run_build "$resolved" "$app_type"; then ok "Finished ${resolved}" result_paths+=("$resolved") result_notes+=("0") ok_count=$((ok_count + 1)) else exit_code=$? err "Failed ${resolved} (exit ${exit_code})" result_paths+=("$resolved") result_notes+=("exit ${exit_code}") fail_count=$((fail_count + 1)) fi done printf '\n%s========== Summary ==========%s\n' "$C_INFO" "$C_RESET" summary_index=0 while [[ "$summary_index" -lt "$total" ]]; do note="${result_notes[$summary_index]}" path="${result_paths[$summary_index]}" if [[ "$note" == "0" ]]; then ok "${path}" else err "${path} (${note})" fi summary_index=$((summary_index + 1)) done batch_exit=0 if [[ "$fail_count" -gt 0 ]]; then err "${ok_count} succeeded, ${fail_count} failed." batch_exit=1 else ok "${ok_count} succeeded, 0 failed." fi write_summary_log exit "$batch_exit"