name: Build & Deploy Shannon on: push: branches: - main - master paths: - 'app.py' - 'core/**' - 'views/**' - 'requirements.txt' - 'Dockerfile' - 'docker-stack.yml' - '.streamlit/**' - '.gitea/workflows/deploy-shannon.yml' workflow_dispatch: env: IMAGE_NAME: shannon/streamlit jobs: build-and-deploy: name: ๐Ÿ—๏ธ Build & Deploy Shannon runs-on: ubuntu-latest steps: - name: ๐Ÿ“ฅ Checkout code uses: https://github.com/actions/checkout@v4 - 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/shannon-source.tar.gz \ --exclude='.git' \ --exclude='.venv' \ --exclude='__pycache__' \ --exclude='*.db' \ --exclude='*.pyc' \ -C . . scp -i ~/.ssh/deploy_key /tmp/shannon-source.tar.gz "$SSH_USER@$SSH_HOST":/tmp/ 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 cd /tmp rm -rf shannon-build mkdir -p shannon-build cd shannon-build tar -xzf /tmp/shannon-source.tar.gz echo "๐Ÿณ Building image with tag: $COMMIT_SHA" docker build -t shannon/streamlit:$COMMIT_SHA \ -t shannon/streamlit:latest . echo "๐Ÿงน Cleaning old images..." docker image prune -f echo "โœ… Image built: $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/shannon-docker-stack.yml ssh -i ~/.ssh/deploy_key ${SSH_USER}@${SSH_HOST} << ENDSSH set -e echo "๐Ÿš€ Deploying stack..." docker stack deploy -c /tmp/shannon-docker-stack.yml shannon echo "๐Ÿ”„ Forcing service update to use new image..." docker service update --force --image shannon/streamlit:$COMMIT_SHA shannon_shannon echo "โณ Waiting for service to update..." sleep 15 echo "๐Ÿ“Š Service status:" docker service ls --filter name=shannon_shannon docker service ps shannon_shannon --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 11 12; do HTTP_CODE=\$(curl -s -o /dev/null -w "%{http_code}" https://shannon.antopoid.com/_stcore/health) if [ "\$HTTP_CODE" = "200" ]; then echo "โœ… Shannon is accessible (HTTP 200)!" exit 0 fi echo "โณ Waiting for Shannon... (\$i/12) - Status: \$HTTP_CODE" sleep 5 done echo "โŒ Health check failed!" echo "๐Ÿ“‹ Service logs:" docker service logs shannon_shannon --tail 50 exit 1 ENDSSH - name: ๐Ÿงน Cleanup run: | rm -f ~/.ssh/deploy_key echo "โœ… Deployment finished!"