Files
server/deploy/update-test-server.sh
T
2026-07-25 20:41:01 -04:00

134 lines
3.3 KiB
Bash
Executable File

#!/bin/sh
# Update the test deployment, including the independently cloned modules.
# Run this script as root when DEPLOY_OWNER requires chown privileges.
set -eu
SCRIPT_DIR=$(CDPATH= cd -- "$(dirname -- "$0")" && pwd)
PROJECT_ROOT=${PROJECT_ROOT:-$(dirname -- "$SCRIPT_DIR")}
DEPLOY_OWNER=${DEPLOY_OWNER:-www-data:www-data}
LOCK_FILE=${LOCK_FILE:-/tmp/ktrix-test-update.lock}
# Composer and npm can invoke Git themselves, bypassing git_in(). Pass the
# deployment exceptions to every child Git process without changing global
# Git configuration.
GIT_CONFIG_COUNT=2
GIT_CONFIG_KEY_0=safe.directory
GIT_CONFIG_VALUE_0=$PROJECT_ROOT
GIT_CONFIG_KEY_1=safe.directory
GIT_CONFIG_VALUE_1=$PROJECT_ROOT/modules/*
export GIT_CONFIG_COUNT GIT_CONFIG_KEY_0 GIT_CONFIG_VALUE_0
export GIT_CONFIG_KEY_1 GIT_CONFIG_VALUE_1
log()
{
printf '%s %s\n' "$(date '+%Y-%m-%d %H:%M:%S')" "$*"
}
require_command()
{
if ! command -v "$1" >/dev/null 2>&1; then
log "ERROR: Required command not found: $1"
exit 1
fi
}
git_in()
{
repository=$1
shift
git -c "safe.directory=$repository" -C "$repository" "$@"
}
update_repository()
{
repository=$1
name=$2
if [ -n "$(git_in "$repository" status --porcelain)" ]; then
log "ERROR: $name has local changes; refusing to overwrite them"
exit 1
fi
if ! git_in "$repository" rev-parse --abbrev-ref '@{upstream}' >/dev/null 2>&1; then
log "ERROR: $name's current branch has no upstream"
exit 1
fi
log "Updating $name"
git_in "$repository" pull --ff-only
}
install_dependencies()
{
directory=$1
name=$2
if [ -f "$directory/composer.json" ]; then
log "Installing PHP dependencies for $name"
composer install \
--working-dir="$directory" \
--no-interaction \
--prefer-dist \
--optimize-autoloader
fi
if [ -f "$directory/package-lock.json" ]; then
log "Installing Node dependencies for $name"
npm ci --prefix "$directory"
fi
}
restore_ownership()
{
status=$?
trap - EXIT HUP INT TERM
log "Setting ownership to $DEPLOY_OWNER"
if ! chown -R "$DEPLOY_OWNER" "$PROJECT_ROOT"; then
log "ERROR: Could not restore project ownership"
exit 1
fi
if [ "$status" -ne 0 ]; then
log "ERROR: Update failed with exit code $status"
fi
exit "$status"
}
for command in git composer npm flock chown; do
require_command "$command"
done
if [ ! -d "$PROJECT_ROOT/.git" ]; then
log "ERROR: PROJECT_ROOT is not a Git clone: $PROJECT_ROOT"
exit 1
fi
exec 9>"$LOCK_FILE"
if ! flock -n 9; then
log "Another update is already running; exiting"
exit 0
fi
trap restore_ownership EXIT HUP INT TERM
log "Starting test-server update in $PROJECT_ROOT"
update_repository "$PROJECT_ROOT" "server"
for module in "$PROJECT_ROOT"/modules/*; do
[ -d "$module/.git" ] || continue
update_repository "$module" "module $(basename -- "$module")"
done
install_dependencies "$PROJECT_ROOT" "server"
for module in "$PROJECT_ROOT"/modules/*; do
[ -d "$module" ] || continue
install_dependencies "$module" "module $(basename -- "$module")"
done
log "Building server and modules"
npm run build:all --prefix "$PROJECT_ROOT"
log "Test-server update completed successfully"