Add auto-update system for DashCaddy instances
- self-updater.js: polls for new versions, downloads/verifies tarballs, triggers host-side rebuild via systemd path unit - dashcaddy-update.sh + systemd units: host-side container rebuild with automatic rollback on health check failure - 7 new /api/v1/system/* endpoints for version info, update check/apply, rollback, and update history - Frontend: DashCaddy tab in Updates modal with version display, changelog, update button, rollback, and notification dot - install.sh: updater service installation, volume mounts, env vars - build-release.sh + webhook-handler.js: release server pipeline (Gitea webhook → build tarball → deploy to get.dashcaddy.net) - Dockerfile: DASHCADDY_COMMIT build arg → VERSION file - Version bump to 1.1.0 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
111
dashcaddy-api/scripts/build-release.sh
Normal file
111
dashcaddy-api/scripts/build-release.sh
Normal file
@@ -0,0 +1,111 @@
|
||||
#!/usr/bin/env bash
|
||||
# DashCaddy Release Builder
|
||||
# Triggered by Gitea webhook on push to main.
|
||||
# Clones repo, builds tarball, writes version.json, deploys to web root.
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
readonly REPO_URL="http://100.98.123.59:3000/sami7777/dashcaddy.git"
|
||||
readonly RELEASE_DIR="/var/www/get.dashcaddy.net/release"
|
||||
readonly BUILD_DIR="/tmp/dashcaddy-build-$$"
|
||||
readonly MIRROR_HOST="root@100.98.123.59" # Contabo DE
|
||||
readonly BRANCH="main"
|
||||
|
||||
log() { echo "[build-release] $(date '+%Y-%m-%d %H:%M:%S') $*"; }
|
||||
|
||||
cleanup() { rm -rf "$BUILD_DIR"; }
|
||||
trap cleanup EXIT
|
||||
|
||||
main() {
|
||||
log "=== Starting release build ==="
|
||||
|
||||
# 1. Clone latest
|
||||
mkdir -p "$BUILD_DIR"
|
||||
log "Cloning ${BRANCH}..."
|
||||
git clone --depth 1 --branch "$BRANCH" "$REPO_URL" "$BUILD_DIR/repo" 2>&1
|
||||
cd "$BUILD_DIR/repo"
|
||||
|
||||
local commit
|
||||
commit=$(git rev-parse --short HEAD)
|
||||
log "Commit: ${commit}"
|
||||
|
||||
# 2. Read version from package.json
|
||||
local version
|
||||
version=$(python3 -c "import json; print(json.load(open('dashcaddy-api/package.json'))['version'])")
|
||||
log "Version: ${version}"
|
||||
|
||||
# 3. Build changelog (last 10 commits, one-liner)
|
||||
local changelog
|
||||
changelog=$(git log --oneline -10 --no-decorate 2>/dev/null || echo "${commit} (no log)")
|
||||
|
||||
# 4. Assemble tarball contents
|
||||
local staging="$BUILD_DIR/dashcaddy"
|
||||
mkdir -p "$staging/dashcaddy-api/routes" "$staging/status" "$staging/scripts"
|
||||
|
||||
# API files
|
||||
cp -f dashcaddy-api/*.js "$staging/dashcaddy-api/" 2>/dev/null || true
|
||||
cp -rf dashcaddy-api/routes/* "$staging/dashcaddy-api/routes/" 2>/dev/null || true
|
||||
cp -f dashcaddy-api/package.json "$staging/dashcaddy-api/"
|
||||
cp -f dashcaddy-api/package-lock.json "$staging/dashcaddy-api/" 2>/dev/null || true
|
||||
cp -f dashcaddy-api/Dockerfile "$staging/dashcaddy-api/"
|
||||
cp -f dashcaddy-api/openapi.yaml "$staging/dashcaddy-api/" 2>/dev/null || true
|
||||
|
||||
# Dashboard files
|
||||
cp -f status/index.html "$staging/status/"
|
||||
cp -f status/sw.js "$staging/status/" 2>/dev/null || true
|
||||
for dir in css js dist vendor assets; do
|
||||
[ -d "status/${dir}" ] && cp -rf "status/${dir}" "$staging/status/"
|
||||
done
|
||||
|
||||
# Updater scripts
|
||||
cp -f dashcaddy-api/scripts/dashcaddy-update.sh "$staging/scripts/" 2>/dev/null || true
|
||||
cp -f dashcaddy-api/scripts/dashcaddy-updater.path "$staging/scripts/" 2>/dev/null || true
|
||||
cp -f dashcaddy-api/scripts/dashcaddy-updater.service "$staging/scripts/" 2>/dev/null || true
|
||||
|
||||
# 5. Create tarball
|
||||
local tarball="dashcaddy-${version}.tar.gz"
|
||||
cd "$BUILD_DIR"
|
||||
tar czf "$tarball" dashcaddy/
|
||||
log "Tarball: ${tarball} ($(du -h "$tarball" | cut -f1))"
|
||||
|
||||
# 6. Compute SHA-256
|
||||
local sha256
|
||||
sha256=$(sha256sum "$tarball" | cut -d' ' -f1)
|
||||
log "SHA-256: ${sha256}"
|
||||
|
||||
# 7. Write version.json
|
||||
cat > version.json <<EOF
|
||||
{
|
||||
"version": "${version}",
|
||||
"commit": "${commit}",
|
||||
"date": "$(date -u +%Y-%m-%dT%H:%M:%SZ)",
|
||||
"sha256": "${sha256}",
|
||||
"changelog": $(python3 -c "import json; print(json.dumps('''${changelog}'''))"),
|
||||
"breaking": false,
|
||||
"tarball": "${tarball}"
|
||||
}
|
||||
EOF
|
||||
|
||||
# 8. Deploy to web root
|
||||
mkdir -p "$RELEASE_DIR"
|
||||
cp -f "$tarball" "$RELEASE_DIR/"
|
||||
cp -f version.json "$RELEASE_DIR/"
|
||||
# Also keep a "latest" symlink/copy
|
||||
cp -f "$tarball" "$RELEASE_DIR/latest.tar.gz"
|
||||
log "Deployed to ${RELEASE_DIR}"
|
||||
|
||||
# 9. Sync to mirror (Contabo DE)
|
||||
if ssh -o ConnectTimeout=5 "$MIRROR_HOST" true 2>/dev/null; then
|
||||
log "Syncing to mirror..."
|
||||
rsync -az --timeout=30 "$RELEASE_DIR/" "$MIRROR_HOST:/var/www/get2.dashcaddy.net/release/" 2>&1 || {
|
||||
log "WARNING: Mirror sync failed (non-fatal)"
|
||||
}
|
||||
log "Mirror synced"
|
||||
else
|
||||
log "WARNING: Mirror host unreachable, skipping sync"
|
||||
fi
|
||||
|
||||
log "=== Release build complete: v${version} (${commit}) ==="
|
||||
}
|
||||
|
||||
main "$@"
|
||||
Reference in New Issue
Block a user