ZDDC/deploy
2026-06-11 13:32:31 -05:00

94 lines
3.4 KiB
Bash
Executable file

#!/bin/sh
set -eu
# deploy — sync built artifacts and/or hand-edited content to the live site.
#
# The build pipeline (`./build alpha|beta|release`) produces self-contained
# bundles in dist/release-output/ but does NOT touch the live site. This
# script is the explicit deploy step. Two sync paths, independent:
#
# ./deploy push everything: content + releases
# ./deploy --content push only ~/src/zddc-website/ → /srv/zddc/
# (excludes /releases/ so releases stay intact)
# ./deploy --releases push only dist/release-output/ → /srv/zddc/releases/
#
# Both paths use rsync with --delete-after, so the live tree exactly
# mirrors the source — files removed locally go away on the live site.
# Mostly-atomic per-file; brief mixed-state during a sync is acceptable
# for a low-traffic static site. Caddy bind-mounts /srv/zddc as :ro and
# serves whatever is there at request time.
#
# Override the source paths via env if you want:
# ZDDC_CONTENT_DIR default: ~/src/zddc-website
# ZDDC_DEPLOY_RELEASES_DIR default: <this-script-dir>/dist/release-output
# ZDDC_LIVE_DIR default: /srv/zddc
SCRIPT_DIR=$(cd "$(dirname "$0")" && pwd)
CONTENT_SRC="${ZDDC_CONTENT_DIR:-$HOME/src/zddc-website}"
RELEASES_SRC="${ZDDC_DEPLOY_RELEASES_DIR:-$SCRIPT_DIR/dist/release-output}"
LIVE="${ZDDC_LIVE_DIR:-/srv/zddc}"
case "${1:-all}" in
-h|--help|help)
sed -n '4,21p' "$0" | sed 's/^# \{0,1\}//'
exit 0
;;
--content|content)
WHAT=content
;;
--releases|releases)
WHAT=releases
;;
all|"")
WHAT=all
;;
*)
echo "deploy: unknown subcommand '$1'. Try './deploy help'." >&2
exit 1
;;
esac
if [ ! -d "$LIVE" ]; then
echo "deploy: $LIVE does not exist. Create it and chown to your user first:" >&2
echo " sudo mkdir -p $LIVE && sudo chown -R \$USER:\$USER $LIVE" >&2
exit 1
fi
if [ "$WHAT" = content ] || [ "$WHAT" = all ]; then
if [ ! -d "$CONTENT_SRC" ]; then
echo "deploy: content source $CONTENT_SRC does not exist" >&2
exit 1
fi
echo "=== Syncing content: $CONTENT_SRC/ → $LIVE/ ==="
# --exclude=/releases/ keeps the live site's releases dir untouched
# by content syncs. --exclude=.git so the .git dir doesn't end up
# under /usr/share/caddy. --exclude=.claude keeps local Claude Code
# tooling state (settings.json, settings.local.json, etc.) off the
# public site.
rsync -av --delete-after \
--exclude='/releases/' \
--exclude='/.git*' \
--exclude='/.claude/' \
--exclude='/README.md' \
--exclude='/LICENSE' \
"$CONTENT_SRC/" "$LIVE/"
fi
if [ "$WHAT" = releases ] || [ "$WHAT" = all ]; then
if [ ! -d "$RELEASES_SRC" ] || [ -z "$(ls -A "$RELEASES_SRC" 2>/dev/null)" ]; then
echo "deploy: releases source $RELEASES_SRC is empty or missing" >&2
echo " Run ./build alpha|beta|release first to populate it." >&2
if [ "$WHAT" = all ]; then
echo " (Skipping releases sync; content was synced.)" >&2
exit 0
fi
exit 1
fi
mkdir -p "$LIVE/releases"
echo "=== Syncing releases: $RELEASES_SRC/ → $LIVE/releases/ ==="
rsync -av --delete-after "$RELEASES_SRC/" "$LIVE/releases/"
fi
echo ""
echo "=== Deploy done ==="
echo "Live: https://zddc.varasys.io/"