Files
Orchestrator/privat/CV/andreknie.de/.gitea/workflows/deploy.yml

112 lines
4.0 KiB
YAML

name: Deploy CV Site (andreknie.de)
on:
push:
branches:
- master
- main
workflow_dispatch:
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: Checkout Code
uses: actions/checkout@v3
- name: Install & Build Frontend
run: |
npm ci
npm run build
node scripts/check-bundle.mjs
test -s dist/index.html
test -d dist/assets
test -n "$(find dist/assets -type f -print -quit)"
- name: Copy project files to VM
uses: appleboy/scp-action@v0.1.7
with:
host: ${{ secrets.DEPLOY_SSH_HOST }}
username: ${{ secrets.DEPLOY_SSH_USER }}
key: ${{ secrets.DEPLOY_SSH_KEY }}
source: "Caddyfile,docker-compose.yml,Dockerfile,server/**,package.json,package-lock.json,dist/**,dist/.*"
target: "/opt/orchestrator/privat/CV/andreknie.de"
- name: Execute Deployment on VM
uses: appleboy/ssh-action@v1.0.3
with:
host: ${{ secrets.DEPLOY_SSH_HOST }}
username: ${{ secrets.DEPLOY_SSH_USER }}
key: ${{ secrets.DEPLOY_SSH_KEY }}
script: |
set -Eeuo pipefail
cd /opt/orchestrator/privat/CV/andreknie.de
# 1. Sichere .env aus den Gitea Secrets generieren
cat <<EOF > .env
PORT=3003
NODE_ENV=production
BASE_URL=https://andreknie.de
SMTP_HOST=smtp.ionos.de
SMTP_PORT=587
SMTP_USER=${{ secrets.SMTP_USER }}
SMTP_PASS=${{ secrets.SMTP_PASS }}
STAKEHOLDER_EMAIL=kontakt@d-hive.de
DATABASE_URL=postgresql://umami:${{ secrets.UMAMI_DB_PASS }}@umami-db:5432/umami
POSTGRES_DB=umami
POSTGRES_USER=umami
POSTGRES_PASSWORD=${{ secrets.UMAMI_DB_PASS }}
HASH_SALT=${{ secrets.UMAMI_HASH_SALT }}
EOF
# 2. Vollständiges Frontend als begrenztes Release vorbereiten.
# Die Release-ID stammt aus dem Commit und bleibt rückverfolgbar.
test -s dist/index.html
test -d dist/assets
release_id="${{ github.sha }}"
test -n "$release_id"
case "$release_id" in
(*[!A-Za-z0-9._-]*) echo "Ungültige Release-ID"; exit 1 ;;
esac
release_dir="releases/release-${release_id}"
previous_dir="releases/previous"
mkdir -p releases
if [ -e "$release_dir" ]; then rm -rf -- "$release_dir"; fi
mkdir -p "$release_dir"
cp -a dist/. "$release_dir/"
test -s "$release_dir/index.html"
test -n "$(find "$release_dir/assets" -type f -print -quit)"
rollback() {
if [ -d "$previous_dir" ]; then
rm -rf -- site
mv -- "$previous_dir" site
echo "Rollback auf das vorherige Release ausgeführt."
fi
}
trap rollback ERR
if [ -e site ]; then
rm -rf -- "$previous_dir"
mv -- site "$previous_dir"
fi
mv -- "$release_dir" site
# Debugging: Zeige an, ob die Dateien wirklich da sind
echo "INHALT VON SITE:"
ls -la site/
# 3. Docker Container neustarten
docker compose up -d --build
echo "CADDYFILE CSP AUF HOST:"
grep -n "Content-Security-Policy" Caddyfile
echo "CADDYFILE CSP IM CONTAINER:"
docker compose exec -T caddy grep -n "Content-Security-Policy" /etc/caddy/Caddyfile
docker compose exec -T caddy caddy reload --config /etc/caddy/Caddyfile || true
docker compose up -d --force-recreate caddy
trap - ERR
# Abgebrochene temporäre Releases entfernen. Neben site bleibt
# höchstens ein klar benannter Rollback-Stand erhalten.
find releases -mindepth 1 -maxdepth 1 -type d -name 'release-*' -exec rm -rf -- {} +