#!/usr/bin/env bash # # Deploy Solid Scribe. Run this ON the server, from inside the repo. # # cd /path/to/SolidScribe && ./deploy.sh # # Replaces buildAndUpdateProd.sh, which built the old Vue 2 client and rsynced a # tarball to /home/mab/pi -- a directory that no longer exists. # # Assumes: # - this repo is a git clone with a tracking branch # - node + pnpm are on PATH for the user running this (on NixOS that means # environment.systemPackages or the user's profile -- NOT only inside a # nix-shell, or this will fail at the install step) # - pm2 is already managing NoteServer (pm2 resurrect on boot) # - nginx serves client/dist with an SPA fallback to index.html # # nginx is NOT touched here. On NixOS it is declarative -- see configs/. # set -euo pipefail REPO="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" cd "$REPO" step(){ printf '\n\033[32m::--:: %s\033[0m\n' "$1"; } # --- sanity checks before changing anything ------------------------------ for tool in git pnpm pm2; do command -v "$tool" >/dev/null || { echo "$tool is not on PATH" >&2; exit 1; } done if [ -n "$(git status --porcelain --untracked-files=no)" ]; then echo "Working tree has local modifications. Commit or stash them first:" >&2 git status --short >&2 exit 1 fi # --- pull ---------------------------------------------------------------- step "Pulling $(git rev-parse --abbrev-ref HEAD)..." # --ff-only: refuse to create a merge commit on the server. If this fails the # server has diverged and wants a human. git pull --ff-only # --- dependencies -------------------------------------------------------- step "Installing server dependencies..." pnpm install --frozen-lockfile step "Installing client dependencies..." pnpm install --frozen-lockfile --dir client # --- build --------------------------------------------------------------- # dist is gitignored, so the server builds it. Built into a temp dir first so a # failed build leaves the currently-served files untouched. step "Building client..." rm -rf client/dist.new pnpm --dir client exec vite build --outDir dist.new --emptyOutDir if [ ! -f client/dist.new/index.html ] || [ ! -f client/dist.new/sw.js ]; then echo "Build output looks wrong (missing index.html or sw.js) -- keeping the previous build." >&2 rm -rf client/dist.new exit 1 fi step "Swapping in the new build..." rm -rf client/dist.old [ -d client/dist ] && mv client/dist client/dist.old mv client/dist.new client/dist rm -rf client/dist.old # --- restart ------------------------------------------------------------- step "Reloading the API server..." # reload, not restart: graceful in cluster mode. --update-env so changes to # ecosystem.config.js are picked up. pm2 reload "$REPO/server/ecosystem.config.js" --env production --update-env # Persist the process list so `pm2 resurrect` on boot gets the current state. pm2 save step "Done." pm2 list