Add smart watch-loop.sh: detects changed products, builds only what changed, pushes to registry
This commit is contained in:
75
products/watch-loop.sh
Executable file
75
products/watch-loop.sh
Executable file
@@ -0,0 +1,75 @@
|
||||
#!/bin/bash
|
||||
|
||||
# dd0c Watch Loop (replaces the old git pull + docker compose up loop)
|
||||
# Run this on the NAS: watch -n300 './watch-loop.sh'
|
||||
# Or as a cron: */5 * * * * cd ~/services/dd0c/products && ./watch-loop.sh >> /tmp/dd0c-watch.log 2>&1
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
||||
cd "$SCRIPT_DIR"
|
||||
|
||||
REGISTRY="${REGISTRY:-localhost:5000}"
|
||||
LOCK="/tmp/dd0c-watch.lock"
|
||||
|
||||
# Prevent concurrent runs
|
||||
if [ -f "$LOCK" ]; then
|
||||
PID=$(cat "$LOCK")
|
||||
if kill -0 "$PID" 2>/dev/null; then
|
||||
echo "$(date -u '+%H:%M:%S') Already running (pid $PID), skipping"
|
||||
exit 0
|
||||
fi
|
||||
fi
|
||||
echo $$ > "$LOCK"
|
||||
trap 'rm -f "$LOCK"' EXIT
|
||||
|
||||
# Pull latest code
|
||||
BEFORE=$(git rev-parse HEAD 2>/dev/null || echo "none")
|
||||
git pull --ff-only 2>/dev/null || { echo "$(date -u '+%H:%M:%S') git pull failed"; exit 1; }
|
||||
AFTER=$(git rev-parse HEAD 2>/dev/null || echo "none")
|
||||
|
||||
if [ "$BEFORE" = "$AFTER" ]; then
|
||||
echo "$(date -u '+%H:%M:%S') No changes"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
echo "$(date -u '+%H:%M:%S') New commits: $BEFORE → $AFTER"
|
||||
|
||||
# Detect which products changed
|
||||
CHANGED=$(git diff --name-only "$BEFORE" "$AFTER" 2>/dev/null || echo "")
|
||||
|
||||
declare -A SERVICES=(
|
||||
["02-iac-drift-detection"]="dd0c-drift:02-iac-drift-detection/saas"
|
||||
["03-alert-intelligence"]="dd0c-alert:03-alert-intelligence"
|
||||
["04-lightweight-idp"]="dd0c-portal:04-lightweight-idp"
|
||||
["05-aws-cost-anomaly"]="dd0c-cost:05-aws-cost-anomaly"
|
||||
["06-runbook-automation"]="dd0c-run:06-runbook-automation/saas"
|
||||
)
|
||||
|
||||
REBUILT=0
|
||||
for prefix in "${!SERVICES[@]}"; do
|
||||
if echo "$CHANGED" | grep -q "products/$prefix/"; then
|
||||
IFS=: read -r img ctx <<< "${SERVICES[$prefix]}"
|
||||
TAG="${REGISTRY}/${img}:latest"
|
||||
echo "$(date -u '+%H:%M:%S') Building $img..."
|
||||
if docker build -t "$TAG" "./$ctx" --no-cache && docker push "$TAG"; then
|
||||
echo "$(date -u '+%H:%M:%S') ✓ $img pushed"
|
||||
((REBUILT++)) || true
|
||||
else
|
||||
echo "$(date -u '+%H:%M:%S') ✗ $img build failed"
|
||||
fi
|
||||
fi
|
||||
done
|
||||
|
||||
if [ "$REBUILT" -gt 0 ]; then
|
||||
echo "$(date -u '+%H:%M:%S') Deploying $REBUILT service(s)..."
|
||||
docker compose pull
|
||||
docker compose up -d
|
||||
echo "$(date -u '+%H:%M:%S') Done"
|
||||
else
|
||||
# Still might need compose changes (new infra services, env vars, etc.)
|
||||
if echo "$CHANGED" | grep -q "docker-compose.yml"; then
|
||||
echo "$(date -u '+%H:%M:%S') Compose file changed, redeploying..."
|
||||
docker compose up -d
|
||||
fi
|
||||
fi
|
||||
Reference in New Issue
Block a user