name: Build and Deploy to k3s on: push: branches: [main] workflow_dispatch: env: NAMESPACE: student-enrollment API_IMAGE: student-api FRONTEND_IMAGE: student-frontend jobs: # Build jobs run in parallel for speed build-api: runs-on: ubuntu-latest steps: - name: Checkout uses: actions/checkout@v4 - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3 - name: Build API with cache uses: docker/build-push-action@v5 with: context: . file: deploy/docker/Dockerfile.api push: false load: true tags: ${{ env.API_IMAGE }}:${{ github.sha }} cache-from: type=gha cache-to: type=gha,mode=max - name: Save API image run: docker save ${{ env.API_IMAGE }}:${{ github.sha }} | gzip > /tmp/api-image.tar.gz - name: Upload API artifact uses: actions/upload-artifact@v4 with: name: api-image path: /tmp/api-image.tar.gz retention-days: 1 build-frontend: runs-on: ubuntu-latest steps: - name: Checkout uses: actions/checkout@v4 - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3 - name: Build Frontend with cache uses: docker/build-push-action@v5 with: context: . file: deploy/docker/Dockerfile.frontend push: false load: true tags: ${{ env.FRONTEND_IMAGE }}:${{ github.sha }} cache-from: type=gha cache-to: type=gha,mode=max - name: Save Frontend image run: docker save ${{ env.FRONTEND_IMAGE }}:${{ github.sha }} | gzip > /tmp/frontend-image.tar.gz - name: Upload Frontend artifact uses: actions/upload-artifact@v4 with: name: frontend-image path: /tmp/frontend-image.tar.gz retention-days: 1 deploy: runs-on: ubuntu-latest needs: [build-api, build-frontend] steps: - name: Checkout uses: actions/checkout@v4 - name: Download API image uses: actions/download-artifact@v4 with: name: api-image path: /tmp - name: Download Frontend image uses: actions/download-artifact@v4 with: name: frontend-image path: /tmp - name: Import images to k3s run: | gunzip -c /tmp/api-image.tar.gz | sudo k3s ctr images import - gunzip -c /tmp/frontend-image.tar.gz | sudo k3s ctr images import - - name: Update deployments with new tag run: | kubectl -n ${{ env.NAMESPACE }} set image deployment/student-api \ api=${{ env.API_IMAGE }}:${{ github.sha }} kubectl -n ${{ env.NAMESPACE }} set image deployment/student-frontend \ frontend=${{ env.FRONTEND_IMAGE }}:${{ github.sha }} - name: Wait for rollout run: | kubectl -n ${{ env.NAMESPACE }} rollout status deployment/student-api --timeout=120s kubectl -n ${{ env.NAMESPACE }} rollout status deployment/student-frontend --timeout=60s - name: Health check run: | sleep 10 API_POD=$(kubectl -n ${{ env.NAMESPACE }} get pods -l app=student-api -o jsonpath='{.items[0].metadata.name}') kubectl -n ${{ env.NAMESPACE }} exec $API_POD -- wget -q --spider http://localhost:5000/health || exit 1 echo "Deployment healthy!"