From 3034fa90930e0ac4ba938d8e05a8fe829734a7ed Mon Sep 17 00:00:00 2001 From: Admin Date: Sun, 29 Mar 2026 21:47:04 +0000 Subject: [PATCH] Add build storage and backup scripts - upload-release.sh: Upload artifacts to Hetzner Storage Box - create-release.sh: Create Gitea releases with tag and artifacts - post-deploy.sh: Auto-backup DB and upload after deploy - setup-storagebox.sh: One-time storage box directory setup --- scripts/create-release.sh | 62 +++++++++++++++++++++++++++++++++++++ scripts/post-deploy.sh | 44 ++++++++++++++++++++++++++ scripts/setup-storagebox.sh | 44 ++++++++++++++++++++++++++ scripts/upload-release.sh | 52 +++++++++++++++++++++++++++++++ 4 files changed, 202 insertions(+) create mode 100755 scripts/create-release.sh create mode 100755 scripts/post-deploy.sh create mode 100755 scripts/setup-storagebox.sh create mode 100755 scripts/upload-release.sh diff --git a/scripts/create-release.sh b/scripts/create-release.sh new file mode 100755 index 0000000..040de26 --- /dev/null +++ b/scripts/create-release.sh @@ -0,0 +1,62 @@ +#!/bin/bash +# Create Gitea release with build artifacts +# Usage: create-release.sh [notes] +set -euo pipefail + +VERSION=${1:-"v1.0.0"} +NOTES=${2:-"Release $VERSION"} +GITEA_URL="http://10.10.10.40:3000" +GITEA_TOKEN="admin:TaskTeam2026!" +REPO="admin/task-team" + +cd /opt/task-team + +echo "[$(date +%H:%M:%S)] Creating release $VERSION..." + +# Create and push tag +if git rev-parse "$VERSION" >/dev/null 2>&1; then + echo "Tag $VERSION already exists, skipping tag creation" +else + git tag -a "$VERSION" -m "$NOTES" + echo "Tag $VERSION created" +fi + +# Push tag to Gitea +git push origin "$VERSION" 2>/dev/null || echo "Tag already pushed" + +# Create release via Gitea API +RELEASE_RESP=$(curl -s -u "$GITEA_TOKEN" -X POST "$GITEA_URL/api/v1/repos/$REPO/releases" -H "Content-Type: application/json" -d "{\"tag_name\":\"$VERSION\",\"name\":\"Task Team $VERSION\",\"body\":\"$NOTES\",\"draft\":false,\"prerelease\":false}") + +RELEASE_ID=$(echo "$RELEASE_RESP" | python3 -c "import sys,json; print(json.load(sys.stdin).get(\"id\",\"\"))" 2>/dev/null || echo "") + +if [ -z "$RELEASE_ID" ]; then + echo "WARN: Could not create release (may already exist)" + echo "Response: $RELEASE_RESP" + # Try to get existing release + RELEASE_ID=$(curl -s -u "$GITEA_TOKEN" "$GITEA_URL/api/v1/repos/$REPO/releases/tags/$VERSION" | python3 -c "import sys,json; print(json.load(sys.stdin).get(\"id\",\"\"))" 2>/dev/null || echo "") +fi + +echo "Release ID: $RELEASE_ID" + +# Upload APK if exists +APK_DIR="/opt/task-team/mobile/dist/android" +APK=$(ls -t $APK_DIR/*.apk 2>/dev/null | head -1) +if [ -n "${APK:-}" ] && [ -f "$APK" ] && [ -n "$RELEASE_ID" ]; then + echo "Uploading APK: $APK" + curl -s -u "$GITEA_TOKEN" -X POST "$GITEA_URL/api/v1/repos/$REPO/releases/$RELEASE_ID/assets" -F "attachment=@$APK" -F "name=task-team-$VERSION.apk" >/dev/null + echo "APK attached to release" +fi + +# Upload web bundle if exists +WEB_BUNDLE="/opt/task-team/web/.next" +if [ -d "$WEB_BUNDLE" ] && [ -n "$RELEASE_ID" ]; then + BUNDLE_FILE="/tmp/task-team-web-$VERSION.tar.gz" + tar czf "$BUNDLE_FILE" -C /opt/task-team/web .next public package.json next.config.ts 2>/dev/null || true + if [ -f "$BUNDLE_FILE" ]; then + curl -s -u "$GITEA_TOKEN" -X POST "$GITEA_URL/api/v1/repos/$REPO/releases/$RELEASE_ID/assets" -F "attachment=@$BUNDLE_FILE" -F "name=task-team-web-$VERSION.tar.gz" >/dev/null + rm -f "$BUNDLE_FILE" + echo "Web bundle attached to release" + fi +fi + +echo "[$(date +%H:%M:%S)] Done: $GITEA_URL/$REPO/releases/tag/$VERSION" diff --git a/scripts/post-deploy.sh b/scripts/post-deploy.sh new file mode 100755 index 0000000..c178bec --- /dev/null +++ b/scripts/post-deploy.sh @@ -0,0 +1,44 @@ +#!/bin/bash +# Post-deploy: backup DB + upload artifacts to storage box +# Run after each successful deploy +set -uo pipefail + +VERSION=$(cd /opt/task-team && git describe --tags --always 2>/dev/null || echo "unknown") +DATE=$(date +%Y%m%d_%H%M) +REMOTE="u458763-sub3@u458763.your-storagebox.de" +PORT=23 +LOG="/var/log/taskteam-backup.log" + +echo "[$(date +%H:%M:%S)] Post-deploy backup starting: $VERSION" | tee -a $LOG + +# 1. DB backup +echo "[$(date +%H:%M:%S)] Running DB backup..." | tee -a $LOG +/opt/task-team/backup.sh >> $LOG 2>&1 +DB_EXIT=$? + +# 2. Upload latest DB backup to storage box +LATEST_BACKUP=$(ls -t /opt/task-team/backups/*.gz 2>/dev/null | head -1) +if [ -f "${LATEST_BACKUP:-}" ]; then + echo "[$(date +%H:%M:%S)] Uploading DB backup: $(basename $LATEST_BACKUP)" | tee -a $LOG + scp -P $PORT -o ConnectTimeout=10 -o BatchMode=yes "$LATEST_BACKUP" "$REMOTE:releases/backups/" 2>>$LOG || echo "[$(date +%H:%M:%S)] WARN: Storage box upload failed (DB backup saved locally)" | tee -a $LOG +fi + +# 3. Upload APK if exists +APK_DIR="/opt/task-team/mobile/dist/android" +APK=$(ls -t $APK_DIR/*.apk 2>/dev/null | head -1) +if [ -f "${APK:-}" ]; then + echo "[$(date +%H:%M:%S)] Uploading APK: $(basename $APK)" | tee -a $LOG + scp -P $PORT -o ConnectTimeout=10 -o BatchMode=yes "$APK" "$REMOTE:releases/android/task-team-${VERSION}-${DATE}.apk" 2>>$LOG || echo "[$(date +%H:%M:%S)] WARN: Storage box APK upload failed" | tee -a $LOG +fi + +# 4. Upload web build if exists +if [ -d "/opt/task-team/web/.next" ]; then + WEB_ARCHIVE="/tmp/task-team-web-${VERSION}-${DATE}.tar.gz" + tar czf "$WEB_ARCHIVE" -C /opt/task-team/web .next public package.json next.config.ts 2>/dev/null || true + if [ -f "$WEB_ARCHIVE" ]; then + scp -P $PORT -o ConnectTimeout=10 -o BatchMode=yes "$WEB_ARCHIVE" "$REMOTE:releases/web/" 2>>$LOG || true + rm -f "$WEB_ARCHIVE" + fi +fi + +echo "[$(date +%H:%M:%S)] Post-deploy backup complete: $VERSION (DB exit: $DB_EXIT)" | tee -a $LOG diff --git a/scripts/setup-storagebox.sh b/scripts/setup-storagebox.sh new file mode 100755 index 0000000..845464a --- /dev/null +++ b/scripts/setup-storagebox.sh @@ -0,0 +1,44 @@ +#!/bin/bash +# Setup storage box directories and install SSH key +# Run once when setting up storage box access +set -euo pipefail + +REMOTE="u458763-sub3@u458763.your-storagebox.de" +PORT=23 +PUBKEY=$(cat /home/devops/.ssh/id_ed25519.pub) + +echo "=== Storage Box Setup ===" +echo "Remote: $REMOTE (port $PORT)" +echo "Public key: $PUBKEY" +echo + +# Test connection +echo "Testing connection..." +if sftp -P $PORT -oBatchMode=yes $REMOTE </dev/null +ls +bye +SFTP +then + echo "Connection OK" +else + echo "ERROR: Cannot connect to storage box" + echo "Please install the public key via Hetzner Robot panel:" + echo " 1. Login to https://robot.your-server.de" + echo " 2. Go to Storage Boxes -> u458763 -> Sub-accounts -> sub3" + echo " 3. Add SSH key: $PUBKEY" + exit 1 +fi + +# Create release directories +echo "Creating release directories..." +sftp -P $PORT -oBatchMode=yes $REMOTE < +set -euo pipefail + +VERSION=${1:-$(date +%Y%m%d_%H%M)} +PLATFORM=${2:-android} +FILE=$3 + +if [ -z "${FILE:-}" ]; then + echo "Usage: upload-release.sh " + echo " version: e.g. v1.0.0 or 20260329_1400" + echo " platform: android|ios|web" + echo " file: path to build artifact" + exit 1 +fi + +if [ ! -f "$FILE" ]; then + echo "ERROR: File not found: $FILE" + exit 1 +fi + +REMOTE="u458763-sub3@u458763.your-storagebox.de" +PORT=23 +EXT=$(echo "$FILE" | rev | cut -d. -f1 | rev) +REMOTE_NAME="task-team-${VERSION}.${EXT}" + +echo "[$(date +%H:%M:%S)] Uploading $FILE to releases/$PLATFORM/$REMOTE_NAME..." + +# Try direct upload first +if scp -P $PORT -o ConnectTimeout=10 -o BatchMode=yes "$FILE" "$REMOTE:releases/$PLATFORM/$REMOTE_NAME" 2>/dev/null; then + echo "[$(date +%H:%M:%S)] OK: Uploaded to releases/$PLATFORM/$REMOTE_NAME" + exit 0 +fi + +echo "[$(date +%H:%M:%S)] Direct upload failed, trying via mngmt relay..." +# Fallback: relay through mngmt (46.62.219.52) +TEMP_FILE="/tmp/release-upload-$$.tmp" +if scp -P 22770 -o ConnectTimeout=10 "$FILE" root@46.62.219.52:$TEMP_FILE 2>/dev/null; then + ssh -p 22770 -o ConnectTimeout=10 root@46.62.219.52 "scp -P 23 -o BatchMode=yes $TEMP_FILE $REMOTE:releases/$PLATFORM/$REMOTE_NAME 2>/dev/null; rm -f $TEMP_FILE" + if [ $? -eq 0 ]; then + echo "[$(date +%H:%M:%S)] OK: Uploaded via mngmt relay" + exit 0 + fi +fi + +# Last resort: save locally +LOCAL_ARCHIVE="/opt/task-team/backups/releases" +mkdir -p "$LOCAL_ARCHIVE/$PLATFORM" +cp "$FILE" "$LOCAL_ARCHIVE/$PLATFORM/$REMOTE_NAME" +echo "[$(date +%H:%M:%S)] WARN: Storage box unreachable. Saved locally: $LOCAL_ARCHIVE/$PLATFORM/$REMOTE_NAME" +exit 1