Two consecutive PeerCortex deploys today (2026-07-16) broke in the same way: server.js requires local files (src/backend/config.js, src/backend/services/smtp.js) that were never actually uploaded to Erik, because the deploy process was ad-hoc 'cat file | ssh' per-file uploads with no systematic check that every require() target actually exists on the target machine. A missing npm dependency (pg) caused the same class of problem separately. - .github/workflows/build-verify.yml: runs on every push/PR (Gitea Actions already has a working runner for this repo, confirmed via the existing .github/workflows/security-scan.yml on the github-import/main branch). npm ci, syntax-checks server.js + the other top-level .js files, verifies every local require() target resolves to an actual file, typechecks (informational for now -- see the step comment for why), builds dist/, runs the existing vitest suite. Catches both of today's failures before they'd ever reach Erik. - deploy-from-git.sh: replaces the per-file upload process with a single git pull + npm ci + require()-check + syntax-check + build + backup + pm2 restart sequence, run manually on Erik. Deliberately NOT wired to a Gitea Action with SSH secrets -- Erik hosts many unrelated production services and main can contain code that hasn't been live-verified yet, so the actual deploy trigger stays a human decision. CI catches what's broken; this makes running the fix a single repeatable command instead of a manually-assembled file list.
62 lines
2.1 KiB
Bash
Executable File
62 lines
2.1 KiB
Bash
Executable File
#!/bin/bash
|
|
# Git-pull-based deploy for Erik. Replaces the ad-hoc per-file `cat file | ssh`
|
|
# uploads used on 2026-07-16, which twice missed files that server.js actually
|
|
# requires (src/backend/config.js, src/backend/services/smtp.js) because
|
|
# uploading was a manual, easy-to-forget step instead of a single `git pull`.
|
|
#
|
|
# Run this ON Erik, from /opt/peercortex-app. Deliberately manual (not wired
|
|
# to a Gitea Action) -- Erik hosts many unrelated production services and
|
|
# main can contain code that hasn't been live-tested yet (see project memory).
|
|
#
|
|
# Usage: ./deploy-from-git.sh [branch] (default: main)
|
|
|
|
set -euo pipefail
|
|
cd "$(dirname "$0")"
|
|
|
|
BRANCH="${1:-main}"
|
|
BACKUP_DIR=/opt/_rollbacks/peercortex-app
|
|
TS=$(date -u +%Y%m%dT%H%M%SZ)
|
|
mkdir -p "$BACKUP_DIR"
|
|
|
|
echo "[1/7] Backing up current server.js + public/index.html..."
|
|
cp -p server.js "$BACKUP_DIR/server.js.$TS"
|
|
cp -p public/index.html "$BACKUP_DIR/index.html.$TS"
|
|
|
|
echo "[2/7] Fetching + checking out $BRANCH..."
|
|
git fetch origin
|
|
git checkout "$BRANCH"
|
|
git pull origin "$BRANCH"
|
|
|
|
echo "[3/7] npm ci..."
|
|
npm ci
|
|
|
|
echo "[4/7] Verifying every local require() target actually exists..."
|
|
MISSING=0
|
|
for f in server.js local-db-client.js bio-rd-client.js; do
|
|
[ -f "$f" ] || continue
|
|
for req in $(grep -oE "require\(['\"]\./[^'\"]+['\"]\)" "$f" | sed -E "s/require\(['\"]\.\/([^'\"]+)['\"]\)/\1/"); do
|
|
if [ ! -f "$req" ] && [ ! -f "$req.js" ] && [ ! -d "$req" ]; then
|
|
echo " MISSING: $f requires ./$req -- not found" >&2
|
|
MISSING=1
|
|
fi
|
|
done
|
|
done
|
|
if [ "$MISSING" = "1" ]; then
|
|
echo "Aborting: fix the missing file(s) above before deploying." >&2
|
|
exit 1
|
|
fi
|
|
|
|
echo "[5/7] Syntax check..."
|
|
node --check server.js
|
|
node --check local-db-client.js
|
|
|
|
echo "[6/7] Building dist/ (TypeScript API server)..."
|
|
npm run build
|
|
|
|
echo "[7/7] Restarting peercortex (and peercortex-api if configured)..."
|
|
pm2 restart peercortex --update-env
|
|
pm2 restart peercortex-api --update-env 2>/dev/null || echo " (peercortex-api not running yet, skipped)"
|
|
|
|
echo ""
|
|
echo "Done. Rollback: cp $BACKUP_DIR/server.js.$TS server.js && cp $BACKUP_DIR/index.html.$TS public/index.html && pm2 restart peercortex"
|