101 lines
4.1 KiB
Bash
101 lines
4.1 KiB
Bash
#!/usr/bin/env bash
|
|
# Push a build to the wallet VPS from the dev box. This is the routine
|
|
# deploy — deploy-wallet-web.sh is the one-time bootstrap.
|
|
#
|
|
# ops/push.sh web bundle + daemon sources, restart daemon
|
|
# ops/push.sh web web bundle only (no daemon restart)
|
|
# ops/push.sh daemon daemon sources only, restart daemon
|
|
#
|
|
# What it does:
|
|
# web — `npm run build -w @dgb-wallet/web-ui`, tar dist/ to the VPS,
|
|
# atomic swap into $SITE_ROOT/web/, verify the served bundle
|
|
# hash matches the local build, and warn if the inline script's
|
|
# CSP hash no longer matches the live Content-Security-Policy.
|
|
# daemon — ship packages/p2p/{src,bin} and packages/core/{src,dist}
|
|
# (the daemon runs from source via tsx and imports core's
|
|
# dist), chown to the service user, restart dgb-daemon, wait
|
|
# for /health.
|
|
#
|
|
# Requires an `ssh` host alias (default: silentmode) with root access.
|
|
set -euo pipefail
|
|
|
|
HOST="${DGB_VPS_HOST:-silentmode}"
|
|
REPO_DIR="${DGB_VPS_REPO:-/opt/dgb-wallet}"
|
|
SITE_ROOT="${DGB_VPS_SITE_ROOT:-/var/www/dgb-wallet}"
|
|
SNI_HOST="${DGB_SNI_HOST:-digibyte.x}"
|
|
WHAT="${1:-all}"
|
|
|
|
here="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
|
cd "$here"
|
|
|
|
log() { printf '\n\033[1;36m>>> %s\033[0m\n' "$*"; }
|
|
|
|
push_web() {
|
|
log "building web-ui"
|
|
# Plain production build → relative ./assets base + runtime <base> fix.
|
|
# Never DGB_UI_BASE=/web/ here (see deploy-wallet-web.sh).
|
|
MSYS_NO_PATHCONV=1 npm run build -w @dgb-wallet/web-ui >/dev/null
|
|
local js
|
|
js="$(ls packages/web-ui/dist/assets/index-*.js | head -1)"
|
|
local local_hash
|
|
local_hash="$(sha256sum "$js" | cut -c1-64)"
|
|
|
|
log "shipping bundle → $HOST:$SITE_ROOT/web/"
|
|
tar -cz -C packages/web-ui/dist . | ssh "$HOST" "set -e
|
|
mkdir -p '$SITE_ROOT/web.new'
|
|
tar -xz -C '$SITE_ROOT/web.new'
|
|
chown -R www-data:www-data '$SITE_ROOT/web.new'
|
|
rm -rf '$SITE_ROOT/web.old'
|
|
mv '$SITE_ROOT/web' '$SITE_ROOT/web.old'
|
|
mv '$SITE_ROOT/web.new' '$SITE_ROOT/web'
|
|
rm -rf '$SITE_ROOT/web.old'"
|
|
|
|
log "verifying served bundle"
|
|
local served
|
|
served="$(ssh "$HOST" "curl -sk --resolve $SNI_HOST:443:127.0.0.1 https://$SNI_HOST/web/ | grep -o 'index-[A-Za-z0-9_-]*\\.js' | head -1")"
|
|
local remote_hash
|
|
remote_hash="$(ssh "$HOST" "sha256sum '$SITE_ROOT/web/assets/$served' | cut -c1-64")"
|
|
if [[ "$remote_hash" != "$local_hash" ]]; then
|
|
echo "ERROR: served $served hash $remote_hash != local $local_hash" >&2
|
|
exit 1
|
|
fi
|
|
echo " served $served — hash matches"
|
|
|
|
# CSP hash drift check: the inline <base>-fix script in index.html is
|
|
# pinned by sha256 in the live nginx Content-Security-Policy.
|
|
local want live_csp
|
|
want="$(node packages/web-ui/scripts/csp-hash.mjs)"
|
|
live_csp="$(ssh "$HOST" "curl -sk -D - -o /dev/null --resolve $SNI_HOST:443:127.0.0.1 https://$SNI_HOST/web/ | tr -d '\\r' | grep -i '^content-security-policy' || true")"
|
|
if [[ -n "$live_csp" && "$live_csp" != *"$want"* ]]; then
|
|
echo "WARNING: live CSP does not contain the current inline-script hash ($want)." >&2
|
|
echo " Update ops/nginx-digibyte-x.conf + /etc/angie/http.d/digibyte-x.conf (Angie serves 443), or the wallet will not load." >&2
|
|
else
|
|
echo " CSP hash OK ($want)"
|
|
fi
|
|
}
|
|
|
|
push_daemon() {
|
|
log "typechecking p2p"
|
|
(cd packages/p2p && npx tsc --noEmit -p .)
|
|
log "shipping daemon sources → $HOST:$REPO_DIR"
|
|
tar -cz packages/p2p/src packages/p2p/bin packages/p2p/native/dgbpow.wasm packages/core/src packages/core/dist packages/core/package.json packages/p2p/package.json \
|
|
| ssh "$HOST" "set -e
|
|
tar -xz -C '$REPO_DIR'
|
|
chown -R dgb-wallet:dgb-wallet '$REPO_DIR/packages/p2p' '$REPO_DIR/packages/core'
|
|
systemctl restart dgb-daemon
|
|
for i in \$(seq 1 30); do
|
|
if curl -s -m 3 http://127.0.0.1:5174/health >/dev/null; then break; fi
|
|
sleep 2
|
|
done
|
|
systemctl is-active dgb-daemon
|
|
curl -s -m 5 http://127.0.0.1:5174/health | head -c 140; echo"
|
|
}
|
|
|
|
case "$WHAT" in
|
|
all) push_web; push_daemon ;;
|
|
web) push_web ;;
|
|
daemon) push_daemon ;;
|
|
*) echo "usage: ops/push.sh [all|web|daemon]" >&2; exit 1 ;;
|
|
esac
|
|
|
|
log "done"
|