Skip to content

deps(deps): bump the npm-minor-and-patch group across 1 directory wit… #318

deps(deps): bump the npm-minor-and-patch group across 1 directory wit…

deps(deps): bump the npm-minor-and-patch group across 1 directory wit… #318

Workflow file for this run

name: CD
on:
push:
branches: ["**"]
workflow_dispatch:
permissions:
contents: read
packages: write
env:
REGISTRY: ghcr.io
OWNER: aet-devops26
jobs:
# ── Dry-run on every push & manual events (validates chart, no deploy) ──
helm-dry-run:
runs-on: ubuntu-latest
if: |
github.event_name == 'push' ||
github.event_name == 'workflow_dispatch'
steps:
- name: Checkout
uses: actions/checkout@v7
- name: Set up Helm
uses: azure/setup-helm@v5
with:
version: v3.17.0
- name: Helm lint
run: helm lint ./infra/helm/banking-app
- name: Helm template (dry-run)
run: |
helm template banking-app ./infra/helm/banking-app \
--namespace "test" \
--set tumid="test" \
--set postgres.database.password="admin" \
--set monitoring.grafana.adminPassword="admin" \
--set imagePullPolicy=Always \
--set gitCommitSha="${{ github.sha }}" \
--set accountService.image.tag="${{ github.sha }}" \
--set transactionService.image.tag="${{ github.sha }}" \
--set orchestratorService.image.tag="${{ github.sha }}" \
--set genaiService.image.tag="${{ github.sha }}" \
--set client.image.tag="${{ github.sha }}" \
--set bankingService.image.tag="${{ github.sha }}" \
--debug
# ── Build Docker images on every push; push to GHCR only on main or manual dispatch ──
build-and-push:
runs-on: ubuntu-latest
strategy:
matrix:
include:
- service: account-service
dockerfile: server/account-service/Dockerfile
context: server
- service: transaction-service
dockerfile: server/transaction-service/Dockerfile
context: server
- service: orchestrator-service
dockerfile: server/orchestrator-service/Dockerfile
context: server
- service: banking-service
dockerfile: server/banking-service/Dockerfile
context: server
- service: genai-service
dockerfile: genai/Dockerfile
context: genai
- service: client
dockerfile: client/Dockerfile
context: client
steps:
- uses: actions/checkout@v7
- name: Log in to GHCR
uses: docker/login-action@v4
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
# The client image expects a pre-built ./client/dist (see client/Dockerfile
# for why we build on the host instead of inside the container).
- name: Set up Node.js
if: matrix.service == 'client'
uses: actions/setup-node@v4
with:
node-version: "22"
cache: npm
cache-dependency-path: client/package-lock.json
- name: Build client bundle
if: matrix.service == 'client'
working-directory: client
run: |
npm ci
npm run build
- name: Build and Push
run: |
docker build \
-t $REGISTRY/$OWNER/${{ matrix.service }}:latest \
-t $REGISTRY/$OWNER/${{ matrix.service }}:${{ github.sha }} \
-f ${{ matrix.dockerfile }} \
${{ matrix.context }}
# Push only on manual dispatch or merge to main
if [[ "${{ github.event_name }}" == "workflow_dispatch" || "${{ github.ref_name }}" == "main" ]]; then
echo "Pushing images to GHCR"
docker push $REGISTRY/$OWNER/${{ matrix.service }}:latest
docker push $REGISTRY/$OWNER/${{ matrix.service }}:${{ github.sha }}
else
echo "Skipping push (branch: ${{ github.ref_name }}, event: ${{ github.event_name }})"
fi
# ── Real deploy: after build-and-push succeeds on main, or manual dispatch ──
deploy-k8s:
runs-on: ubuntu-latest
needs: [helm-dry-run, build-and-push]
permissions:
contents: read
packages: read
if: github.ref_name == 'main' || github.event_name == 'workflow_dispatch'
steps:
- name: Checkout
uses: actions/checkout@v7
- name: Set up Helm
uses: azure/setup-helm@v5
with:
version: v3.17.0
- name: Setup kubeconfig
run: |
mkdir -p ~/.kube
echo "${{ secrets.KUBECONFIG }}" | base64 -d > ~/.kube/config
chmod 600 ~/.kube/config
- name: Ensure GHCR image pull secret
run: |
ns="devops26"
kubectl create secret docker-registry ghcr-secret \
--namespace "$ns" \
--docker-server=ghcr.io \
--docker-username="${{ github.actor }}" \
--docker-password="${{ secrets.GITHUB_TOKEN }}" \
--dry-run=client -o yaml | kubectl apply -f -
- name: Verify cluster & project target
run: |
echo "=== Cluster info ==="
kubectl cluster-info | head -3
echo ""
echo "=== Namespace 'devops26' details ==="
kubectl get namespace devops26 -o yaml | grep -E '^\s+(name:|field.cattle.io/projectId:|management.cattle.io/)' || true
echo ""
echo "=== Full namespace labels ==="
kubectl get namespace devops26 -o jsonpath='{.metadata.labels}' | python3 -m json.tool || true
echo ""
echo "=== Full namespace annotations ==="
kubectl get namespace devops26 -o jsonpath='{.metadata.annotations}' | python3 -m json.tool || true
- name: Ensure namespace has Helm ownership
run: |
ns="devops26"
if kubectl get namespace "$ns" >/dev/null 2>&1; then
echo "Namespace '$ns' exists — adding Helm ownership metadata"
kubectl label namespace "$ns" \
app.kubernetes.io/managed-by=Helm \
--overwrite
kubectl annotate namespace "$ns" \
meta.helm.sh/release-name=banking-app \
meta.helm.sh/release-namespace="$ns" \
--overwrite
else
echo "Namespace '$ns' does not exist — Helm will create it"
fi
- name: Clear pending Helm release (if any)
run: |
ns="devops26"
# Remove stale pending-upgrade / pending-install locks from
# a previous interrupted deploy (timeout, runner killed, etc.)
kubectl delete secret -n "$ns" \
-l "owner=helm,name=banking-app,status=pending-upgrade" \
--ignore-not-found
kubectl delete secret -n "$ns" \
-l "owner=helm,name=banking-app,status=pending-install" \
--ignore-not-found
# Also clear any pending-rollback locks
kubectl delete secret -n "$ns" \
-l "owner=helm,name=banking-app,status=pending-rollback" \
--ignore-not-found
- name: Create Enable Banking private key secret
env:
EB_PRIVATE_KEY: ${{ secrets.EB_PRIVATE_KEY }}
run: |
ns="devops26"
if [ -n "$EB_PRIVATE_KEY" ]; then
kubectl create secret generic eb-private-key \
--namespace "$ns" \
--from-file=eb_private_key.pem=<(printf '%s' "$EB_PRIVATE_KEY") \
--dry-run=client -o yaml | kubectl apply -f -
echo "Enable Banking private key secret created/updated"
else
echo "EB_PRIVATE_KEY secret is empty"
fi
- name: Create GenAI Logos key secret
env:
LOGOS_KEY: ${{ secrets.LOGOS_KEY }}
run: |
ns="devops26"
if [ -n "$LOGOS_KEY" ]; then
kubectl create secret generic genai-logos-key \
--namespace "$ns" \
--from-literal=LOGOS_KEY="$LOGOS_KEY" \
--dry-run=client -o yaml | kubectl apply -f -
echo "Logos key secret created/updated"
else
echo "LOGOS_KEY secret is empty — genai will use local fallback"
fi
- name: Clean up conflicting ingresses from old namespaces
run: |
echo "=== Checking for conflicting ingresses outside devops26 ==="
kubectl get ingress --all-namespaces -o name 2>/dev/null \
| grep banking-ingress \
| while read ing; do
ing_ns=$(echo "$ing" | cut -d/ -f1)
if [ "$ing_ns" != "devops26" ]; then
echo "Deleting conflicting ingress: $ing"
kubectl delete "$ing" --ignore-not-found
fi
done
echo "=== Done ==="
- name: Deploy with Helm
run: |
ns="devops26"
# Use the existing password from the cluster so it never changes.
# The GitHub secret is only a fallback for the very first deploy.
if db_pass=$(kubectl get secret -n "$ns" postgres-credentials \
-o jsonpath='{.data.password}' 2>/dev/null | base64 -d); then
echo "Using existing postgres password from cluster secret"
else
db_pass="${{ secrets.POSTGRES_PASSWORD }}"
echo "First deploy — using password from GitHub secret"
fi
echo "=== Deploying with image tag: ${{ github.sha }} ==="
helm upgrade --install banking-app ./infra/helm/banking-app \
--namespace "$ns" \
--create-namespace \
--set postgres.database.password="$db_pass" \
--set monitoring.grafana.adminPassword="${{ secrets.GRAFANA_ADMIN_PASSWORD }}" \
--set monitoring.serviceMonitors.enabled=true \
--set monitoring.prometheusRules.enabled=true \
--set imagePullPolicy=Always \
--set gitCommitSha="${{ github.sha }}" \
--set deployTimestamp="$(date +%s)" \
--set accountService.image.tag="${{ github.sha }}" \
--set transactionService.image.tag="${{ github.sha }}" \
--set orchestratorService.image.tag="${{ github.sha }}" \
--set genaiService.image.tag="${{ github.sha }}" \
--set client.image.tag="${{ github.sha }}" \
--set bankingService.image.tag="${{ github.sha }}" \
--set-string bankingService.enableBanking.appId="${{ secrets.EB_APP_ID }}" \
--set-string orchestratorService.githubOauth.clientId="${{ secrets.GH_OAUTH_K8S_CLIENT_ID }}" \
--set-string orchestratorService.githubOauth.clientSecret="${{ secrets.GH_OAUTH_K8S_CLIENT_SECRET }}" \
--set genaiService.modelProvider="${{ vars.GENAI_MODEL_PROVIDER || 'logos' }}" \
--timeout 5m \
--wait \
--debug
- name: Show rollout status
if: always()
run: |
ns="devops26"
echo "=== Pods ==="
kubectl get pods -n "$ns" -o wide
echo ""
echo "=== Recent events ==="
kubectl get events -n "$ns" --sort-by='.lastTimestamp' | tail -20