Initial commit: self-healing Kubernetes platform #1
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: CI/CD Pipeline | |
| on: | |
| push: | |
| branches: [main] | |
| pull_request: | |
| branches: [main] | |
| env: | |
| IMAGE_NAME: ${{ secrets.DOCKERHUB_USERNAME }}/self-healing-app | |
| jobs: | |
| # ------------------------------------------------------- | |
| # Job 1: Build & push Docker image to Docker Hub | |
| # ------------------------------------------------------- | |
| build-push: | |
| name: Build & Push | |
| runs-on: ubuntu-latest | |
| outputs: | |
| image_tag: ${{ steps.meta.outputs.tag }} | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Set image tag | |
| id: meta | |
| run: echo "tag=${{ github.sha }}" >> $GITHUB_OUTPUT | |
| - name: Log in to Docker Hub | |
| uses: docker/login-action@v3 | |
| with: | |
| username: ${{ secrets.DOCKERHUB_USERNAME }} | |
| password: ${{ secrets.DOCKERHUB_TOKEN }} | |
| - name: Build & push image | |
| uses: docker/build-push-action@v5 | |
| with: | |
| context: ./app | |
| push: true | |
| tags: | | |
| ${{ env.IMAGE_NAME }}:${{ github.sha }} | |
| ${{ env.IMAGE_NAME }}:latest | |
| # ------------------------------------------------------- | |
| # Job 2: Deploy to Kubernetes using Helm | |
| # ------------------------------------------------------- | |
| deploy: | |
| name: Deploy to K8s | |
| runs-on: ubuntu-latest | |
| needs: build-push | |
| if: github.ref == 'refs/heads/main' | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Set up kubectl | |
| uses: azure/setup-kubectl@v3 | |
| - name: Set up Helm | |
| uses: azure/setup-helm@v3 | |
| - name: Configure kubeconfig | |
| run: | | |
| mkdir -p ~/.kube | |
| echo "${{ secrets.KUBECONFIG }}" | base64 -d > ~/.kube/config | |
| - name: Helm upgrade (deploy new image) | |
| run: | | |
| helm upgrade --install app-a ./helm-chart \ | |
| --set image.repository=${{ env.IMAGE_NAME }} \ | |
| --set image.tag=${{ needs.build-push.outputs.image_tag }} \ | |
| --wait \ | |
| --timeout 120s | |
| # ------------------------------------------------------- | |
| # Post-deploy health check — auto-rollback if pods crash | |
| # ------------------------------------------------------- | |
| - name: Health check & auto-rollback | |
| run: | | |
| echo "Waiting 30s for pods to stabilize..." | |
| sleep 30 | |
| FAILED=$(kubectl get pods -l app=app-a --field-selector=status.phase=Failed --no-headers 2>/dev/null | wc -l) | |
| CRASH=$(kubectl get pods -l app=app-a --no-headers 2>/dev/null | grep -c "CrashLoopBackOff" || true) | |
| if [ "$FAILED" -gt 0 ] || [ "$CRASH" -gt 0 ]; then | |
| echo "Unhealthy pods detected. Rolling back..." | |
| helm rollback app-a | |
| echo "Rollback complete. Check Helm history:" | |
| helm history app-a | |
| exit 1 | |
| fi | |
| echo "All pods healthy. Deploy successful." | |
| kubectl get pods -l app=app-a |