name: Deploy QR Rapido on: push: branches: [ main, develop ] pull_request: branches: [ main ] env: REGISTRY: registry.redecarneir.us IMAGE_NAME: qrrapido jobs: test: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Setup .NET uses: actions/setup-dotnet@v4 with: dotnet-version: 8.0.x - name: Cache dependencies uses: actions/cache@v3 with: path: ~/.nuget/packages key: ${{ runner.os }}-nuget-${{ hashFiles('**/*.csproj') }} restore-keys: | ${{ runner.os }}-nuget- - name: Restore dependencies run: dotnet restore - name: Build run: dotnet build --no-restore --configuration Release - name: Test run: dotnet test --no-build --configuration Release --verbosity normal --collect:"XPlat Code Coverage" - name: Upload coverage uses: codecov/codecov-action@v3 with: files: coverage.cobertura.xml build-and-push: needs: test runs-on: [self-hosted, arm64, bcards] if: github.ref == 'refs/heads/main' || github.ref == 'refs/heads/develop' steps: - name: Checkout uses: actions/checkout@v4 - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3 - name: Build and push to registry run: | # Determina a tag baseada na branch if [ "${{ github.ref }}" = "refs/heads/main" ]; then TAG="latest" else TAG="develop" fi # Build da imagem para ARM64 (servidores Ampere OCI) docker buildx build \ --platform linux/arm64 \ --tag ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:$TAG \ --push \ . echo "IMAGE_TAG=$TAG" >> $GITHUB_ENV deploy-staging: needs: build-and-push runs-on: [self-hosted, arm64, bcards] if: github.ref == 'refs/heads/develop' steps: - name: Deploy to Staging Servers run: | # Configura SSH mkdir -p ~/.ssh echo "${{ secrets.SSH_PRIVATE_KEY }}" > ~/.ssh/id_rsa chmod 600 ~/.ssh/id_rsa # Deploy no Servidor 1 ssh -o StrictHostKeyChecking=no ubuntu@141.148.162.114 << 'EOF' # Para o container atual se existir docker stop qrrapido-staging || true docker rm qrrapido-staging || true # Remove imagem antiga docker rmi ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:develop || true # Puxa nova imagem docker pull ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:develop # Executa novo container docker run -d \ --name qrrapido-staging \ --restart unless-stopped \ -p 5000:8080 \ --add-host=host.docker.internal:host-gateway \ -e ASPNETCORE_ENVIRONMENT=Staging \ ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:develop EOF # Deploy no Servidor 2 ssh -o StrictHostKeyChecking=no ubuntu@129.146.116.218 << 'EOF' # Para o container atual se existir docker stop qrrapido-staging || true docker rm qrrapido-staging || true # Remove imagem antiga docker rmi ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:develop || true # Puxa nova imagem docker pull ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:develop # Executa novo container docker run -d \ --name qrrapido-staging \ --restart unless-stopped \ -p 5000:8080 \ --add-host=host.docker.internal:host-gateway \ -e ASPNETCORE_ENVIRONMENT=Staging \ ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:develop EOF deploy-production: needs: build-and-push runs-on: ubuntu-latest if: github.ref == 'refs/heads/main' environment: production steps: - name: Deploy to Production Swarm run: | # Debug SSH setup echo "=== Configurando SSH ===" mkdir -p ~/.ssh echo "${{ secrets.SSH_PRIVATE_KEY }}" > ~/.ssh/id_rsa chmod 600 ~/.ssh/id_rsa # Verifica se a chave foi criada echo "=== Verificando chave SSH ===" ls -la ~/.ssh/ echo "Primeiras linhas da chave:" head -2 ~/.ssh/id_rsa # Testa conexão SSH com debug echo "=== Testando conexão SSH ===" ssh -o StrictHostKeyChecking=no -o ConnectTimeout=10 -v ubuntu@141.148.162.114 'echo "Conexão SSH funcionando!"' || echo "Falha na conexão SSH" # Se a conexão funcionou, continua com o deploy echo "=== Iniciando Deploy no Docker Swarm ===" # Deploy via Docker Swarm (apenas no manager - servidor 1) ssh -o StrictHostKeyChecking=no ubuntu@141.148.162.114 << 'EOF' # Puxa nova imagem docker pull ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest # Cria o diretório de chaves no host e define as permissões corretas sudo mkdir -p /app/keys sudo chown -R 1000:1000 /app/keys # Atualiza o service ou cria se não existir docker service update \ --image ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest \ qrrapido-prod \ || \ docker service create \ --name qrrapido-prod \ --replicas 2 \ --network host \ --mount type=bind,source=/app/keys,target=/app/keys \ --env ASPNETCORE_ENVIRONMENT=Production \ --env ASPNETCORE_URLS=http://+:5001 \ --update-delay 30s \ --update-parallelism 1 \ --update-order start-first \ --restart-condition on-failure \ --restart-max-attempts 3 \ ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest # Aguarda o service estar estável echo "Aguardando service estabilizar..." sleep 30 # Verifica se o service está funcionando docker service ps qrrapido-prod # Recarrega NGINX para garantir que está apontando para o novo container sudo nginx -t && sudo systemctl reload nginx EOF - name: Health Check Swarm run: | # Aguarda um pouco para o service estabilizar sleep 15 # Verifica o status do service no swarm echo "Verificando status do service no Swarm..." ssh -o StrictHostKeyChecking=no ubuntu@141.148.162.114 'docker service ps qrrapido-prod' # Verifica se os serviços estão respondendo em ambos servidores echo "Verificando Servidor 1..." ssh -o StrictHostKeyChecking=no ubuntu@141.148.162.114 'curl -f http://localhost:5001/health || echo "Servidor 1 pode não estar respondendo"' echo "Verificando Servidor 2..." ssh -o StrictHostKeyChecking=no ubuntu@129.146.116.218 'curl -f http://localhost:5001/health || echo "Servidor 2 pode não estar respondendo"' # Testa o site principal echo "Testando site principal..." curl -f https://qrrapido.site || echo "Site principal pode não estar respondendo"