#!/usr/bin/env bash # # CluPilot — pull the latest code and apply it. # # Order matters: migrations run BEFORE the new containers take traffic, because # code that expects a column the database does not have yet answers with 500s. # The queue workers are restarted at the end — they are long-running processes # and keep the old classes in memory otherwise. set -euo pipefail cd "$(dirname "$0")/.." BRANCH="${BRANCH:-main}" log() { printf '\n\033[1;34m==>\033[0m %s\n' "$*"; } log "Fetching $BRANCH" git fetch --quiet origin "$BRANCH" before="$(git rev-parse HEAD)" git merge --quiet --ff-only "origin/$BRANCH" after="$(git rev-parse HEAD)" if [[ "$before" == "$after" ]]; then log "Already up to date ($(git rev-parse --short HEAD))" exit 0 fi log "Updating $(git rev-parse --short "$before") → $(git rev-parse --short "$after")" git --no-pager log --oneline "$before..$after" | sed 's/^/ /' # Rebuilt only when the image definition actually changed — a rebuild is # minutes, a no-op check is seconds. if ! git diff --quiet "$before" "$after" -- docker/ composer.json composer.lock package.json package-lock.json; then log "Rebuilding the image" docker compose build --quiet app fi log "Applying migrations" docker compose exec -T app php artisan migrate --force log "Rebuilding assets" docker compose exec -T app npm run build log "Restarting services" docker compose up -d # Workers hold their PHP classes for the life of the process; without this they # keep running the code from before the update. docker compose restart queue queue-provisioning scheduler reverb docker compose exec -T app php artisan config:clear >/dev/null docker compose exec -T app php artisan view:clear >/dev/null log "Done — now on $(git rev-parse --short HEAD)"