# IMPORTANT: Before this workflow will function, configure the following # repository secrets in Forgejo (Settings → Secrets): # DEPLOY_HOST — hostname or IP of the target server # DEPLOY_USER — SSH user on the target server # DEPLOY_SSH_KEY — private SSH key (PEM or OpenSSH format) # DEPLOY_PATH — absolute path to the project directory on the server # (must contain a docker-compose.yml + a .env file # that sets LIFE_TOWERS_IMAGE to the registry tag, # e.g. LIFE_TOWERS_IMAGE=registry.example.com/life-towers:latest) name: Deploy on: workflow_dispatch: push: tags: - 'v*' jobs: deploy: runs-on: ubuntu-latest steps: - name: Install SSH key run: | mkdir -p ~/.ssh chmod 700 ~/.ssh printf '%s\n' "${{ secrets.DEPLOY_SSH_KEY }}" > ~/.ssh/deploy_key chmod 600 ~/.ssh/deploy_key ssh-keyscan -H "${{ secrets.DEPLOY_HOST }}" >> ~/.ssh/known_hosts chmod 644 ~/.ssh/known_hosts - name: Deploy via SSH run: | set -euo pipefail # Pulls the new image referenced by $LIFE_TOWERS_IMAGE in the # server's .env, restarts the service, then verifies health. ssh -i ~/.ssh/deploy_key \ -o StrictHostKeyChecking=yes \ "${{ secrets.DEPLOY_USER }}@${{ secrets.DEPLOY_HOST }}" \ "set -euo pipefail cd '${{ secrets.DEPLOY_PATH }}' docker compose pull docker compose up -d --remove-orphans # Wait for healthcheck (max ~60s) for i in \$(seq 1 30); do status=\$(docker compose ps --format json life-towers | python3 -c 'import sys,json;[print(json.loads(l).get(\"Health\",\"\")) for l in sys.stdin]' || true) if [ \"\$status\" = healthy ]; then echo deploy_healthy; exit 0; fi sleep 2 done echo deploy_unhealthy >&2 docker compose logs --tail 50 life-towers >&2 exit 1"