- Introduce cache busting (to circumvent aggressive caching on iOS - but ideal in other contexts as well)

- Change the build process to allow cache busting
- Optimisations to the build process
- Several improvements of UI geared towards mobile experience
-
This commit is contained in:
Josako
2025-09-25 17:28:01 +02:00
parent cc47ce2d32
commit 16ce59ae98
32 changed files with 1538 additions and 899 deletions

View File

@@ -1,7 +1,49 @@
#!/bin/bash
# Exit on any error
set -e
# Safer bash: we manage errors manually (no -e) but detect pipeline failures
set -o pipefail
# Quiet mode default; enable verbose with --verbose
QUIET=${QUIET:-true}
# Parse --verbose early (we'll reparse fully later as well)
for arg in "$@"; do
if [[ "$arg" == "--verbose" ]]; then QUIET=false; fi
done
# Per-run logs directory
RUN_TS=$(date +%Y%m%d_%H%M%S)
LOG_DIR="./build_logs/$RUN_TS"
mkdir -p "$LOG_DIR"
# Error aggregation
ERRORS=()
ERROR_LINES=()
EXIT_CODE=0
# Helper: run_quiet SERVICE STEP -- CMD ARGS...
run_quiet() {
local SERVICE="$1"; shift
local STEP="$1"; shift
# Expect a literal "--" separator before the command
if [[ "$1" == "--" ]]; then shift; fi
local LOG_FILE="$LOG_DIR/${SERVICE}.${STEP}.log"
if [[ "$QUIET" == "true" ]]; then
"$@" > /dev/null 2> >(tee -a "$LOG_FILE" >&2)
else
"$@" > >(tee -a "$LOG_FILE") 2> >(tee -a "$LOG_FILE" >&2)
fi
local RC=$?
echo "$LOG_FILE" > "$LOG_DIR/.last_${SERVICE}_${STEP}.path"
return $RC
}
record_error() {
local SERVICE="$1"; local STEP="$2"; local MESSAGE="$3"; local LOG_FILE="$4"
ERRORS+=("$SERVICE|$STEP|$LOG_FILE|$MESSAGE")
ERROR_LINES+=("$MESSAGE")
EXIT_CODE=1
}
source ./podman_env_switch.sh dev
@@ -39,7 +81,7 @@ BASE_ONLY=""
# Function to display usage information
usage() {
echo "Usage: $0 [-b|-p|-bb|--base-only] [--no-cache] [--progress=plain] [--debug] [service1 service2 ...]"
echo "Usage: $0 [-b|-p|-bb|--base-only] [--no-cache] [--progress=plain] [--debug] [--verbose] [service1 service2 ...]"
echo " -b: Build only"
echo " -p: Push only"
echo " -bb: Build base image (in addition to services)"
@@ -47,6 +89,7 @@ usage() {
echo " --no-cache: Perform a clean build without using cache"
echo " --progress=plain: Show detailed progress of the build"
echo " --debug: Enable debug mode for the build"
echo " --verbose: Show full output of build/push (default is quiet; logs always saved under ./build_logs/<timestamp>)"
echo " If no option is provided, both build and push will be performed."
echo " If no services are specified, all eveai_ services and nginx will be processed."
echo " All images are built for AMD64 platform (compatible with both x86_64 and Apple Silicon via emulation)."
@@ -55,6 +98,10 @@ usage() {
# Parse command-line options
while [[ $# -gt 0 ]]; do
case $1 in
--verbose)
QUIET=false
shift
;;
-b)
ACTION="build"
shift
@@ -96,13 +143,13 @@ done
# Function to build base image
build_base_image() {
echo "🏗️ Building base image..."
echo "🏗️ Building base image... =============================================================="
local BASE_IMAGE_NAME="$REGISTRY/$ACCOUNT/eveai-base:$TAG"
echo "Building base image for platform: $PLATFORM"
echo "Base image tag: $BASE_IMAGE_NAME"
podman build \
run_quiet base build -- podman build \
--platform "$PLATFORM" \
$NO_CACHE \
$PROGRESS \
@@ -111,12 +158,24 @@ build_base_image() {
-t "$BASE_IMAGE_NAME" \
-f Dockerfile.base \
..
if [ $? -ne 0 ]; then
LOG_FILE="$LOG_DIR/base.build.log"
echo "❌ Failed to build base image"
record_error base build "❌ Failed to build base image" "$LOG_FILE"
return 1
fi
if [ "$ACTION" = "push" ] || [ "$ACTION" = "both" ]; then
echo "Pushing base image to registry..."
podman push "$BASE_IMAGE_NAME"
run_quiet base push -- podman push "$BASE_IMAGE_NAME"
if [ $? -ne 0 ]; then
LOG_FILE="$LOG_DIR/base.push.log"
echo "❌ Failed to push base image"
record_error base push "❌ Failed to push base image" "$LOG_FILE"
return 1
fi
fi
echo "✅ Base image built successfully"
}
@@ -132,7 +191,7 @@ should_build_base() {
# Function to build and/or push a service
process_service() {
local SERVICE="$1"
echo "Processing $SERVICE..."
echo "Processing $SERVICE... =================================================================="
# Extract the build context and dockerfile from the compose file
CONTEXT=$(yq e ".services.$SERVICE.build.context" compose_dev.yaml)
@@ -160,8 +219,8 @@ process_service() {
# Build and/or push based on ACTION
if [ "$ACTION" = "build" ]; then
echo "Building $SERVICE for $PLATFORM..."
podman build \
echo "🛠️ Building $SERVICE for $PLATFORM..."
run_quiet "$SERVICE" build -- podman build \
--platform "$PLATFORM" \
$NO_CACHE \
$PROGRESS \
@@ -170,26 +229,27 @@ process_service() {
-t "$REGISTRY_IMAGE_NAME" \
-f "$CONTEXT/$DOCKERFILE" \
"$CONTEXT"
if [ $? -ne 0 ]; then
LOG_FILE="$LOG_DIR/${SERVICE}.build.log"
echo "❌ Failed to build $SERVICE"
record_error "$SERVICE" build "❌ Failed to build $SERVICE" "$LOG_FILE"
return 1
fi
elif [ "$ACTION" = "push" ]; then
echo "Building and pushing $SERVICE for $PLATFORM..."
podman build \
--platform "$PLATFORM" \
$NO_CACHE \
$PROGRESS \
$DEBUG \
-t "$LOCAL_IMAGE_NAME" \
-t "$REGISTRY_IMAGE_NAME" \
-f "$CONTEXT/$DOCKERFILE" \
"$CONTEXT"
echo "Pushing $SERVICE to registry..."
podman push "$REGISTRY_IMAGE_NAME"
echo "📤 Pushing $SERVICE to registry..."
run_quiet "$SERVICE" push -- podman push "$REGISTRY_IMAGE_NAME"
if [ $? -ne 0 ]; then
LOG_FILE="$LOG_DIR/${SERVICE}.push.log"
echo "❌ Failed to push $SERVICE"
record_error "$SERVICE" push "❌ Failed to push $SERVICE" "$LOG_FILE"
return 1
fi
else
# Both build and push
echo "Building $SERVICE for $PLATFORM..."
podman build \
echo "🛠️ Building $SERVICE for $PLATFORM..."
run_quiet "$SERVICE" build -- podman build \
--platform "$PLATFORM" \
$NO_CACHE \
$PROGRESS \
@@ -198,9 +258,21 @@ process_service() {
-t "$REGISTRY_IMAGE_NAME" \
-f "$CONTEXT/$DOCKERFILE" \
"$CONTEXT"
if [ $? -ne 0 ]; then
LOG_FILE="$LOG_DIR/${SERVICE}.build.log"
echo "❌ Failed to build $SERVICE"
record_error "$SERVICE" build "❌ Failed to build $SERVICE" "$LOG_FILE"
return 1
fi
echo "Pushing $SERVICE to registry..."
podman push "$REGISTRY_IMAGE_NAME"
echo "📤 Pushing $SERVICE to registry..."
run_quiet "$SERVICE" push -- podman push "$REGISTRY_IMAGE_NAME"
if [ $? -ne 0 ]; then
LOG_FILE="$LOG_DIR/${SERVICE}.push.log"
echo "❌ Failed to push $SERVICE"
record_error "$SERVICE" push "❌ Failed to push $SERVICE" "$LOG_FILE"
return 1
fi
fi
}
@@ -231,22 +303,87 @@ fi
echo "Using simplified AMD64-only approach for maximum compatibility..."
echo "Images will be tagged as: $REGISTRY/$ACCOUNT/[service]:$TAG"
# Reorder to ensure nginx builds before eveai_* if both are present
HAS_NGINX=false
HAS_APPS=false
for S in "${SERVICES[@]}"; do
if [[ "$S" == "nginx" ]]; then HAS_NGINX=true; fi
if [[ "$S" == eveai_* ]]; then HAS_APPS=true; fi
done
if $HAS_NGINX && $HAS_APPS; then
ORDERED_SERVICES=("nginx")
for S in "${SERVICES[@]}"; do
if [[ "$S" != "nginx" ]]; then ORDERED_SERVICES+=("$S"); fi
done
SERVICES=("${ORDERED_SERVICES[@]}")
fi
# Loop through services
for SERVICE in "${SERVICES[@]}"; do
if [[ "$SERVICE" == "nginx" ]]; then
./copy_specialist_svgs.sh ../config ../nginx/static/assets 2>/dev/null || echo "Warning: copy_specialist_svgs.sh not found or failed"
run_quiet nginx copy-specialist-svgs -- ./copy_specialist_svgs.sh ../config ../nginx/static/assets
if [ $? -ne 0 ]; then
LOG_FILE="$LOG_DIR/nginx.copy-specialist-svgs.log"
echo "⚠️ copy_specialist_svgs.sh not found or failed"
record_error nginx copy-specialist-svgs "⚠️ copy_specialist_svgs.sh not found or failed" "$LOG_FILE"
fi
run_quiet nginx rebuild-chat-client -- ./rebuild_chat_client.sh
if [ $? -ne 0 ]; then
LOG_FILE="$LOG_DIR/nginx.rebuild-chat-client.log"
echo "❌ rebuild_chat_client.sh failed"
record_error nginx rebuild-chat-client "❌ rebuild_chat_client.sh failed" "$LOG_FILE"
fi
MANIFEST_SRC="../nginx/static/dist/manifest.json"
MANIFEST_DST_DIR="../config/static-manifest"
MANIFEST_DST="$MANIFEST_DST_DIR/manifest.json"
if [ ! -f "$MANIFEST_SRC" ]; then
if $HAS_NGINX; then
echo "⚠️ manifest.json not found at $MANIFEST_SRC yet. nginx should be built first in this run."
else
echo "❌ manifest.json not found at $MANIFEST_SRC. Please build nginx (assets) first."
exit 1
fi
fi
mkdir -p "$MANIFEST_DST_DIR"
if [ -f "$MANIFEST_SRC" ]; then
cp -f "$MANIFEST_SRC" "$MANIFEST_DST"
echo "📄 Staged manifest at $MANIFEST_DST"
fi
fi
if [[ "$SERVICE" == "nginx" || "$SERVICE" == eveai_* || "$SERVICE" == "prometheus" || "$SERVICE" == "grafana" ]]; then
if process_service "$SERVICE"; then
echo "✅ Successfully processed $SERVICE"
else
echo "❌ Failed to process $SERVICE"
ERROR_LINES+=("❌ Failed to process $SERVICE")
EXIT_CODE=1
fi
else
echo "⏭️ Skipping $SERVICE as it's not nginx, prometheus, grafana or doesn't start with eveai_"
fi
done
echo -e "\033[32m✅ All specified services processed successfully!\033[0m"
echo -e "\033[32m📦 Images are available locally and in registry\033[0m"
echo -e "\033[32m🕐 Finished at $(date +"%d/%m/%Y %H:%M:%S")\033[0m"
if [ ${#ERRORS[@]} -eq 0 ]; then
echo -e "\033[32m✅ All specified services processed successfully!\033[0m"
echo -e "\033[32m📦 Images are available locally and in registry\033[0m"
else
echo -e "\033[31m❌ One or more errors occurred during build/push\033[0m"
# Reprint short failure lines (your concise messages)
for LINE in "${ERROR_LINES[@]}"; do
echo "$LINE"
done
echo ""
echo "Details (see logs for full output):"
for ITEM in "${ERRORS[@]}"; do
SERVICE_STEP_MSG_LOG=$(echo "$ITEM")
IFS='|' read -r SVC STEP LOGFILE MSG <<< "$SERVICE_STEP_MSG_LOG"
echo "- Service: $SVC | Step: $STEP"
echo " ↳ Log: $LOGFILE"
done
EXIT_CODE=1
fi
# Always print finished timestamp
echo -e "\033[32m🕐 Finished at $(date +"%d/%m/%Y %H:%M:%S")\033[0m"
exit $EXIT_CODE