Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 30 additions & 20 deletions .github/workflows/backend-cd.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
name: CD - Deploy Backend Services to AKS

on:
workflow_call: # Only callable from backend-ci
workflow_call:
inputs:
aks_cluster_name:
required: true
Expand All @@ -15,23 +15,26 @@ on:
image_tag:
required: true
type: string
secrets:
AZURE_CREDENTIALS:
required: true

jobs:
deploy_backend:
runs-on: ubuntu-latest
environment: Production

outputs:
PRODUCT_API_IP: ${{ steps.get_product_ip.outputs.external_ip }}
ORDER_API_IP: ${{ steps.get_order_ip.outputs.external_ip }}
PRODUCT_API_IP: ${{ steps.get_product_ip.outputs.ip }}
ORDER_API_IP: ${{ steps.get_order_ip.outputs.ip }}

steps:
- uses: actions/checkout@v4

- name: Log in to Azure
- name: Azure Login
uses: azure/login@v1
with:
creds: ${{ secrets.AZURE_CREDENTIALS }}
enable-AzPSSession: true

- name: Set Kubernetes context
run: |
Expand All @@ -41,25 +44,32 @@ jobs:

- name: Deploy Backend Infrastructure
run: |
kubectl apply -f k8s/configmaps.yaml
kubectl apply -f k8s/secrets.yaml
kubectl apply -f k8s/product-db.yaml
kubectl apply -f k8s/order-db.yaml
cd k8s/
kubectl apply -f configmaps.yaml
kubectl apply -f secrets.yaml
kubectl apply -f product-db.yaml
kubectl apply -f order-db.yaml

- name: Deploy Backend Microservices
run: |
kubectl apply -f k8s/product-service.yaml
kubectl apply -f k8s/order-service.yaml
cd k8s/
kubectl apply -f product-service.yaml
kubectl apply -f order-service.yaml

- name: Update Backend Images with Correct Tag
- name: Update Backend Images
run: |
kubectl set image deployment/product-service \
product-service=${{ inputs.aks_acr_name }}.azurecr.io/product_service:${{ inputs.image_tag }} -n default
kubectl set image deployment/order-service \
order-service=${{ inputs.aks_acr_name }}.azurecr.io/order_service:${{ inputs.image_tag }} -n default
kubectl set image deployment/product-service-w08e1 product-service-container=${{ inputs.aks_acr_name }}.azurecr.io/product_service:${{ inputs.image_tag }}
kubectl set image deployment/order-service-w08e1 order-service-container=${{ inputs.aks_acr_name }}.azurecr.io/order_service:${{ inputs.image_tag }}

- id: get_product_ip
run: echo "external_ip=$(kubectl get service product-service-w08e1 -o jsonpath='{.status.loadBalancer.ingress[0].ip}')" >> $GITHUB_OUTPUT

- id: get_order_ip
run: echo "external_ip=$(kubectl get service order-service-w08e1 -o jsonpath='{.status.loadBalancer.ingress[0].ip}')" >> $GITHUB_OUTPUT
- name: Get Product Service IP
id: get_product_ip
run: |
ip=$(kubectl get svc product-service-w08e1 -o jsonpath='{.status.loadBalancer.ingress[0].ip}')
echo "ip=$ip" >> $GITHUB_OUTPUT

- name: Get Order Service IP
id: get_order_ip
run: |
ip=$(kubectl get svc order-service-w08e1 -o jsonpath='{.status.loadBalancer.ingress[0].ip}')
echo "ip=$ip" >> $GITHUB_OUTPUT
118 changes: 89 additions & 29 deletions .github/workflows/backend_ci.yml → .github/workflows/ci-cd.yml
Original file line number Diff line number Diff line change
@@ -1,34 +1,27 @@
name: Backend CI - Test, Build and Push Images to ACR
name: Full CI/CD Pipeline - Backend + Frontend

on:
# Issue 1 + 3 fix: Run CI on PRs into main (test before production merge)
pull_request:
branches: [ main ]
paths:
- 'backend/**'
- '.github/workflows/backend-ci.yml'

# Issue 1 fix: Run CI on pushes to development branch
push:
branches: [ development ]
paths:
- 'backend/**'
- '.github/workflows/backend-ci.yml'

workflow_dispatch:
branches:
- development # Run on pushes to development
pull_request:
branches:
- main # Run on PRs into main
workflow_dispatch: # Manual trigger option

env:
ACR_LOGIN_SERVER: ${{ secrets.AZURE_CONTAINER_REGISTRY }}
IMAGE_TAG: ${{ github.sha }}

jobs:
test_and_lint_backends:
# -----------------------------
# 1. Backend - Test & Lint
# -----------------------------
test_and_lint_backend:
runs-on: ubuntu-latest
# Issue 7 fix: Matrix testing
strategy:
matrix:
python-version: ["3.9", "3.10", "3.11"]
os: [ubuntu-latest, windows-latest]
services:
product_db:
image: postgres:15
Expand All @@ -49,13 +42,13 @@ jobs:
POSTGRES_USER: postgres
POSTGRES_PASSWORD: postgres
POSTGRES_DB: orders
ports:
- 5433:5432
options: >-
--health-cmd "pg_isready -U postgres"
--health-interval 10s
--health-timeout 5s
--health-retries 5
ports:
- 5433:5432

steps:
- uses: actions/checkout@v4
Expand All @@ -65,7 +58,6 @@ jobs:
with:
python-version: ${{ matrix.python-version }}

# Issue 5 fix: Cache dependencies
- name: Cache Python packages
uses: actions/cache@v4
with:
Expand All @@ -80,15 +72,30 @@ jobs:

- name: Run product_service tests
working-directory: backend/product_service
env:
POSTGRES_HOST: localhost
POSTGRES_PORT: 5432
POSTGRES_DB: products
POSTGRES_USER: postgres
POSTGRES_PASSWORD: postgres
run: pytest tests --maxfail=1 --disable-warnings -q

- name: Run order_service tests
working-directory: backend/order_service
env:
POSTGRES_HOST: localhost
POSTGRES_PORT: 5433
POSTGRES_DB: orders
POSTGRES_USER: postgres
POSTGRES_PASSWORD: postgres
run: pytest tests --maxfail=1 --disable-warnings -q

build_and_push_images:
# -----------------------------
# 2. Backend - Build & Push Images
# -----------------------------
build_backend_images:
runs-on: ubuntu-latest
needs: test_and_lint_backends
needs: test_and_lint_backend
steps:
- uses: actions/checkout@v4

Expand All @@ -97,15 +104,13 @@ jobs:
with:
creds: ${{ secrets.AZURE_CREDENTIALS }}

# Issue 6 fix: Use docker/login-action
- name: Docker Login to ACR
uses: docker/login-action@v2
with:
registry: ${{ env.ACR_LOGIN_SERVER }}
username: ${{ secrets.AZURE_CLIENT_ID }}
password: ${{ secrets.AZURE_CLIENT_SECRET }}

# Issue 4 fix: Use SHA-based tags
- name: Build and Push Product Service Image
run: |
docker build -t ${{ env.ACR_LOGIN_SERVER }}/product_service:${{ env.IMAGE_TAG }} ./backend/product_service/
Expand All @@ -116,13 +121,68 @@ jobs:
docker build -t ${{ env.ACR_LOGIN_SERVER }}/order_service:${{ env.IMAGE_TAG }} ./backend/order_service/
docker push ${{ env.ACR_LOGIN_SERVER }}/order_service:${{ env.IMAGE_TAG }}

# Issue 2 fix: CI calls backend CD
# -----------------------------
# 3. Backend - Deploy to AKS
# -----------------------------
deploy_backend:
needs: build_and_push_images
needs: build_backend_images
uses: ./.github/workflows/backend-cd.yml
with:
aks_cluster_name: sit722-aks
aks_cluster_name: sit722wk09aks
aks_resource_group: sit722-rg
aks_acr_name: sit722acr9
image_tag: ${{ github.sha }}
#test
secrets:
AZURE_CREDENTIALS: ${{ secrets.AZURE_CREDENTIALS }}

# -----------------------------
# 4. Frontend - Build & Push Image
# -----------------------------
build_frontend_image:
runs-on: ubuntu-latest
needs: deploy_backend
steps:
- uses: actions/checkout@v4

- name: Azure Login
uses: azure/login@v1
with:
creds: ${{ secrets.AZURE_CREDENTIALS }}

- name: Docker Login to ACR
uses: docker/login-action@v2
with:
registry: ${{ env.ACR_LOGIN_SERVER }}
username: ${{ secrets.AZURE_CLIENT_ID }}
password: ${{ secrets.AZURE_CLIENT_SECRET }}

- name: Cache Node modules
uses: actions/cache@v4
with:
path: ~/.npm
key: ${{ runner.os }}-node-${{ hashFiles('frontend/package-lock.json') }}

- name: Inject Backend IPs into frontend code
run: |
sed -i "s|_PRODUCT_API_URL_|http://${{ needs.deploy_backend.outputs.PRODUCT_API_IP }}:8000|g" frontend/main.js
sed -i "s|_ORDER_API_URL_|http://${{ needs.deploy_backend.outputs.ORDER_API_IP }}:8001|g" frontend/main.js

- name: Build and Push Frontend Image
run: |
docker build -t ${{ env.ACR_LOGIN_SERVER }}/frontend:${{ env.IMAGE_TAG }} ./frontend/
docker push ${{ env.ACR_LOGIN_SERVER }}/frontend:${{ env.IMAGE_TAG }}

# -----------------------------
# 5. Frontend - Deploy to AKS
# -----------------------------
deploy_frontend:
needs: build_frontend_image
uses: ./.github/workflows/frontend-cd.yml
with:
aks_cluster_name: sit722wk09aks # ✅ matches real cluster
aks_resource_group: sit722-rg
aks_acr_name: sit722acr9 # ✅ ACR passed in
image_tag: ${{ github.sha }}
secrets:
AZURE_CREDENTIALS: ${{ secrets.AZURE_CREDENTIALS }}

31 changes: 12 additions & 19 deletions .github/workflows/frontend-cd.yml
Original file line number Diff line number Diff line change
@@ -1,23 +1,23 @@
name: CD - Deploy Frontend to AKS

on:
workflow_call: # Only callable by frontend-ci
workflow_call:
inputs:
product_api_ip:
required: true
type: string
order_api_ip:
required: true
type: string
aks_cluster_name:
required: true
type: string
aks_resource_group:
required: true
type: string
aks_acr_name:
required: true
type: string
image_tag:
required: true
type: string
secrets:
AZURE_CREDENTIALS:
required: true

jobs:
deploy_frontend:
Expand All @@ -32,21 +32,14 @@ jobs:
with:
creds: ${{ secrets.AZURE_CREDENTIALS }}

- name: Inject Backend IPs into Frontend main.js
run: |
sed -i "s|_PRODUCT_API_URL_|${{ inputs.product_api_ip }}|g" frontend/main.js
sed -i "s|_ORDER_API_URL_|${{ inputs.order_api_ip }}|g" frontend/main.js

- name: Build and Push Frontend Image
run: |
docker build -t ${{ secrets.AZURE_CONTAINER_REGISTRY }}/frontend:${{ inputs.image_tag }} ./frontend/
docker push ${{ secrets.AZURE_CONTAINER_REGISTRY }}/frontend:${{ inputs.image_tag }}

- name: Set Kubernetes context
uses: azure/aks-set-context@v3
with:
resource-group: ${{ inputs.aks_resource_group }}
cluster-name: ${{ inputs.aks_cluster_name }}

- name: Deploy Frontend to AKS
run: kubectl apply -f k8s/frontend.yaml
- name: Deploy Frontend
run: |
cd k8s/
kubectl apply -f frontend.yaml
kubectl set image deployment/frontend frontend-container=${{ inputs.aks_acr_name }}.azurecr.io/frontend:${{ inputs.image_tag }}
Loading
Loading