Skip to content

Merge pull request #221 from od-hunter/feature/dark-mode-theme #31

Merge pull request #221 from od-hunter/feature/dark-mode-theme

Merge pull request #221 from od-hunter/feature/dark-mode-theme #31

name: Blue-Green Deployment
on:
push:
branches:
- main
workflow_dispatch:
env:
SERVICE_NAME: api-gateway
DOCKER_REGISTRY: ghcr.io/${{ github.repository_owner }}
KUBE_NAMESPACE: production
jobs:
build:
name: Build and Push
runs-on: ubuntu-latest
outputs:
image_tag: ${{ steps.meta.outputs.tags }}
steps:
- uses: actions/checkout@v3
- name: Docker meta
id: meta
uses: docker/metadata-action@v4
with:
images: ${{ env.DOCKER_REGISTRY }}/${{ env.SERVICE_NAME }}
tags: |
type=sha,format=long
- name: Login to GHCR
uses: docker/login-action@v2
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Build and push
uses: docker/build-push-action@v4
with:
context: .
file: microservices/api-gateway/Dockerfile
push: true
tags: ${{ steps.meta.outputs.tags }}
deploy-green:
name: Deploy Green
needs: build
runs-on: ubuntu-latest
environment: production
steps:
- uses: actions/checkout@v3
- name: Set Kubeconfig
uses: azure/k8s-set-context@v3
with:
method: kubeconfig
kubeconfig: ${{ secrets.KUBECONFIG }}
- name: Deploy Green Version
run: |
# Identify current active color (blue or green)
CURRENT_COLOR=$(kubectl get service ${{ env.SERVICE_NAME }} -n ${{ env.KUBE_NAMESPACE }} -o jsonpath='{.spec.selector.color}')
if [ "$CURRENT_COLOR" == "blue" ]; then
NEW_COLOR="green"
else
NEW_COLOR="blue"
fi
echo "Current: $CURRENT_COLOR, Deploying: $NEW_COLOR"
echo "NEW_COLOR=$NEW_COLOR" >> $GITHUB_ENV
# Deploy new version
envsubst < k8s/deployment-template.yaml | kubectl apply -f -
# Wait for rollout
kubectl rollout status deployment/${{ env.SERVICE_NAME }}-$NEW_COLOR -n ${{ env.KUBE_NAMESPACE }} --timeout=5m
- name: Verify Health
run: |
# Expose via port-forward or temporary service to check health
# For this script, we assume we can reach the pod IP or a temp service
# Create temp service
kubectl expose deployment ${{ env.SERVICE_NAME }}-${{ env.NEW_COLOR }} --name=${{ env.SERVICE_NAME }}-test --port=80 --target-port=3000 -n ${{ env.KUBE_NAMESPACE }}
# Wait for IP
sleep 10
# Run verification script
chmod +x scripts/verify-deployment.sh
./scripts/verify-deployment.sh http://${{ env.SERVICE_NAME }}-test.${{ env.KUBE_NAMESPACE }}.svc.cluster.local/health 30
- name: Switch Traffic
if: success()
run: |
echo "Switching traffic to ${{ env.NEW_COLOR }}..."
kubectl patch service ${{ env.SERVICE_NAME }} -n ${{ env.KUBE_NAMESPACE }} -p "{\"spec\":{\"selector\":{\"color\":\"${{ env.NEW_COLOR }}\"}}}"
- name: Cleanup
if: always()
run: |
kubectl delete service ${{ env.SERVICE_NAME }}-test -n ${{ env.KUBE_NAMESPACE }} --ignore-not-found
rollback:
name: Rollback
if: failure()
needs: deploy-green
runs-on: ubuntu-latest
steps:
- name: Rollback Traffic
run: |
# If deploy-green failed, we might not have switched, but if we did, we need to switch back.
# Ideally, we check what is currently active.
# Simplest safe rollback: Ensure traffic points to the *old* color.
# But we need to know what the old color was.
# Assuming we can fetch state or just rely on the fact that if 'Switch Traffic' failed, we are safe.
# If 'Switch Traffic' succeeded but post-checks failed (not implemented above), we would need to revert.
echo "Rollback initiated. (In this workflow, failure prevents switch, so manual check might be needed if switch happened)"