From d354b3525a0a4ab3cfd86199e901e11adbf9a081 Mon Sep 17 00:00:00 2001 From: antopoid Date: Sun, 22 Feb 2026 20:05:40 +0100 Subject: [PATCH] ci: Gitea Actions pipeline (build, deploy, health check) --- .gitea/workflows/deploy.yml | 156 ++++++++++++++++++++++++++++++++++++ 1 file changed, 156 insertions(+) create mode 100644 .gitea/workflows/deploy.yml diff --git a/.gitea/workflows/deploy.yml b/.gitea/workflows/deploy.yml new file mode 100644 index 0000000..8f3f44a --- /dev/null +++ b/.gitea/workflows/deploy.yml @@ -0,0 +1,156 @@ +name: Build & Deploy SimO + +on: + push: + branches: + - main + - master + paths: + - 'src/**' + - 'package.json' + - 'package-lock.json' + - 'tailwind.config.ts' + - 'next.config.mjs' + - 'postcss.config.js' + - 'tsconfig.json' + - 'Dockerfile' + - 'nginx.conf' + - 'docker-stack.yml' + - '.gitea/workflows/deploy.yml' + workflow_dispatch: + +env: + IMAGE_NAME: simo/web + +jobs: + build-and-deploy: + name: ๐Ÿ—๏ธ Build & Deploy + runs-on: ubuntu-latest + steps: + - name: ๐Ÿ“ฅ Checkout code + uses: https://github.com/actions/checkout@v4 + + - name: ๐Ÿ” Debug - Check secrets + run: | + echo "SWARM_MANAGER_HOST length: ${#SWARM_MANAGER_HOST}" + echo "SWARM_USER length: ${#SWARM_USER}" + echo "SWARM_SSH_KEY length: ${#SWARM_SSH_KEY}" + if [ -z "$SWARM_MANAGER_HOST" ]; then echo "โŒ SWARM_MANAGER_HOST is empty!"; fi + if [ -z "$SWARM_USER" ]; then echo "โŒ SWARM_USER is empty!"; fi + if [ -z "$SWARM_SSH_KEY" ]; then echo "โŒ SWARM_SSH_KEY is empty!"; fi + env: + SWARM_MANAGER_HOST: ${{ secrets.SWARM_MANAGER_HOST }} + SWARM_USER: ${{ secrets.SWARM_USER }} + SWARM_SSH_KEY: ${{ secrets.SWARM_SSH_KEY }} + + - name: ๐Ÿ” Setup SSH + env: + SSH_KEY: ${{ secrets.SWARM_SSH_KEY }} + SSH_HOST: ${{ secrets.SWARM_MANAGER_HOST }} + run: | + mkdir -p ~/.ssh + echo "$SSH_KEY" > ~/.ssh/deploy_key + chmod 600 ~/.ssh/deploy_key + ssh-keyscan -H $SSH_HOST >> ~/.ssh/known_hosts + + - name: ๐Ÿ“ฆ Copy source to server + env: + SSH_USER: ${{ secrets.SWARM_USER }} + SSH_HOST: ${{ secrets.SWARM_MANAGER_HOST }} + run: | + tar -czf /tmp/source.tar.gz \ + --exclude='node_modules' \ + --exclude='.next' \ + --exclude='out' \ + --exclude='.git' \ + . + scp -i ~/.ssh/deploy_key /tmp/source.tar.gz "$SSH_USER@$SSH_HOST":/tmp/simo-source.tar.gz + echo "โœ… Source copied" + + - name: ๐Ÿณ Build Docker Image + env: + SSH_USER: ${{ secrets.SWARM_USER }} + SSH_HOST: ${{ secrets.SWARM_MANAGER_HOST }} + run: | + COMMIT_SHA=$(git rev-parse --short HEAD) + echo "๐Ÿ“Œ Commit: $COMMIT_SHA" + + ssh -i ~/.ssh/deploy_key ${SSH_USER}@${SSH_HOST} << ENDSSH + set -e + mkdir -p /tmp/simo-build + cd /tmp/simo-build + rm -rf * + tar -xzf /tmp/simo-source.tar.gz + + echo "๐Ÿณ Building image: simo/web:$COMMIT_SHA" + docker build -t simo/web:$COMMIT_SHA \ + -t simo/web:latest . + + echo "๐Ÿงน Cleaning old images..." + docker image prune -f + + echo "โœ… Image built: simo/web:$COMMIT_SHA" + ENDSSH + + - name: ๐Ÿš€ Deploy to Swarm + env: + SSH_USER: ${{ secrets.SWARM_USER }} + SSH_HOST: ${{ secrets.SWARM_MANAGER_HOST }} + run: | + COMMIT_SHA=$(git rev-parse --short HEAD) + + scp -i ~/.ssh/deploy_key ./docker-stack.yml ${SSH_USER}@${SSH_HOST}:/tmp/simo-stack.yml + + ssh -i ~/.ssh/deploy_key ${SSH_USER}@${SSH_HOST} << ENDSSH + set -e + + echo "๐Ÿš€ Deploying stack..." + IMAGE_TAG=$COMMIT_SHA docker stack deploy -c /tmp/simo-stack.yml simo + + echo "๐Ÿ”„ Forcing service update..." + docker service update --force --image simo/web:$COMMIT_SHA simo_web + + echo "โณ Waiting for service to stabilize..." + sleep 10 + + echo "๐Ÿ“Š Service status:" + docker service ls --filter name=simo + docker service ps simo_web --no-trunc + + echo "โœ… Deployment complete!" + ENDSSH + + - name: ๐Ÿฅ Health Check + env: + SSH_USER: ${{ secrets.SWARM_USER }} + SSH_HOST: ${{ secrets.SWARM_MANAGER_HOST }} + run: | + ssh -i ~/.ssh/deploy_key ${SSH_USER}@${SSH_HOST} << ENDSSH + echo "๐Ÿฅ Running health check..." + + for i in 1 2 3 4 5 6 7 8 9 10; do + STATUS=\$(curl -sf -o /dev/null -w "%{http_code}" https://simo.antopoid.com/ 2>/dev/null || echo "000") + if [ "\$STATUS" = "200" ]; then + echo "โœ… SimO is live! (HTTP \$STATUS)" + echo "๐ŸŒ https://simo.antopoid.com" + exit 0 + fi + echo "โณ Waiting for SimO... (\$i/10) โ€” HTTP \$STATUS" + sleep 5 + done + + echo "โŒ Health check failed!" + echo "" + echo "๐Ÿ“‹ Service logs:" + docker service logs simo_web --tail 50 + echo "" + echo "๐Ÿ“Š Service tasks:" + docker service ps simo_web --no-trunc + exit 1 + ENDSSH + + - name: ๐Ÿงน Cleanup + if: always() + run: | + rm -f ~/.ssh/deploy_key + echo "โœ… Pipeline finished!"