name: Deploy to Kubernetes on: workflow_dispatch: inputs: environment: description: 'Deployment environment' required: true default: 'production' type: choice options: - production - staging image_tag: description: 'Docker image tag (optional, defaults to commit SHA)' required: false type: string env: APP_NAME: www-cialloo-com REGISTRY: ${{ secrets.DOCKER_REGISTRY }} IMAGE_NAME: ${{ secrets.DOCKER_REGISTRY }}/${{ secrets.DOCKER_REPOSITORY }} jobs: build-and-deploy: runs-on: ubuntu-latest environment: ${{ github.event.inputs.environment || 'production' }} steps: - name: Checkout code uses: actions/checkout@v4 - name: Set up Node.js uses: actions/setup-node@v4 with: node-version: 'latest' cache: 'npm' - name: Install dependencies run: npm ci - name: Run linting run: npm run lint - name: Build application run: npm run build - name: Set image tag id: image-tag run: | if [ -n "${{ github.event.inputs.image_tag }}" ]; then echo "tag=${{ github.event.inputs.image_tag }}" >> $GITHUB_OUTPUT else echo "tag=${{ github.sha }}" >> $GITHUB_OUTPUT fi - name: Log in to Docker Registry uses: docker/login-action@v3 with: registry: ${{ secrets.DOCKER_REGISTRY }} username: ${{ secrets.DOCKER_USERNAME }} password: ${{ secrets.DOCKER_PASSWORD }} - name: Build and push Docker image uses: docker/build-push-action@v5 with: context: . push: true tags: | ${{ env.IMAGE_NAME }}:${{ steps.image-tag.outputs.tag }} ${{ env.IMAGE_NAME }}:latest cache-from: type=gha cache-to: type=gha,mode=max - name: Set up kubectl uses: azure/setup-kubectl@v3 with: version: 'v1.28.0' - name: Configure kubectl run: | mkdir -p $HOME/.kube echo "${{ secrets.KUBECONFIG }}" | base64 -d > $HOME/.kube/config chmod 600 $HOME/.kube/config - name: Verify cluster connection run: kubectl cluster-info - name: Deploy to Kubernetes run: | # Replace placeholders in k8s manifests sed -i "s|{{IMAGE_TAG}}|${{ steps.image-tag.outputs.tag }}|g" k8s/deployment.yaml sed -i "s|{{IMAGE_NAME}}|${{ env.IMAGE_NAME }}|g" k8s/deployment.yaml sed -i "s|{{ENVIRONMENT}}|${{ github.event.inputs.environment || 'production' }}|g" k8s/deployment.yaml sed -i "s|{{ENVIRONMENT}}|${{ github.event.inputs.environment || 'production' }}|g" k8s/service.yaml sed -i "s|{{ENVIRONMENT}}|${{ github.event.inputs.environment || 'production' }}|g" k8s/namespace.yaml sed -i "s|{{ENVIRONMENT}}|${{ github.event.inputs.environment || 'production' }}|g" k8s/ingress.yaml # Apply manifests kubectl apply -f k8s/namespace.yaml kubectl apply -f k8s/deployment.yaml kubectl apply -f k8s/service.yaml kubectl apply -f k8s/ingress.yaml - name: Wait for deployment to be ready run: | kubectl rollout status deployment/${{ env.APP_NAME }} -n ${{ env.APP_NAME }}-${{ github.event.inputs.environment || 'production' }} --timeout=300s - name: Get deployment status run: | echo "### Deployment Status" >> $GITHUB_STEP_SUMMARY kubectl get pods -n ${{ env.APP_NAME }}-${{ github.event.inputs.environment || 'production' }} -o wide >> $GITHUB_STEP_SUMMARY echo "" >> $GITHUB_STEP_SUMMARY kubectl get services -n ${{ env.APP_NAME }}-${{ github.event.inputs.environment || 'production' }} >> $GITHUB_STEP_SUMMARY - name: Notify deployment success if: success() run: | echo "✅ Deployment successful!" echo "Image: ${{ env.IMAGE_NAME }}:${{ steps.image-tag.outputs.tag }}" echo "Environment: ${{ github.event.inputs.environment || 'production' }}" - name: Notify deployment failure if: failure() run: | echo "❌ Deployment failed!" kubectl describe pods -n ${{ env.APP_NAME }}-${{ github.event.inputs.environment || 'production' }} || true