Skip to content
Closed
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
178 changes: 171 additions & 7 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -1,9 +1,23 @@
name: CI Pipeline

on:
# Trigger the pipeline when a Pull Request targets main
pull_request:
branches:
- main

# Trigger the pipeline when code is pushed to main
push:
branches:
- main

# Manual trigger for the workflow
workflow_dispatch:

# Required for Azure OIDC authentication
permissions:
id-token: write
contents: read

jobs:

Expand Down Expand Up @@ -78,10 +92,10 @@ jobs:
steps:

- name: Checkout repository
uses: actions/checkout@v4
uses: actions/checkout@v6

- name: Set up Python
uses: actions/setup-python@v5
uses: actions/setup-python@v6
with:
python-version: "3.12"

Expand All @@ -97,18 +111,54 @@ jobs:
pytest -v


# =========================================================
# Frontend Tests
# =========================================================
frontend-test:
name: Test frontend
runs-on: ubuntu-latest

env:
VITE_USER_SERVICE_URL: /api/user-service
VITE_STUDENT_SERVICE_URL: /api/student-service
VITE_LECTURER_SERVICE_URL: /api/lecturer-service
VITE_COURSE_SERVICE_URL: /api/course-service
VITE_ENROLLMENT_SERVICE_URL: /api/enrollment-service

steps:

- name: Checkout repository
uses: actions/checkout@v6

- name: Set up Node.js
uses: actions/setup-node@v6
with:
node-version: "20"

- name: Install frontend dependencies
working-directory: frontend
run: |
npm ci

- name: Run frontend tests
working-directory: frontend
run: |
npm run test:run


# =========================================================
# Build and Push Docker Images
# =========================================================
build-and-push:
name: Build and Push ${{ matrix.image }}
runs-on: ubuntu-latest

# All backend tests must pass before this job starts
# Tests must pass before images are built
needs:
- backend-test
- frontend-test

# Build and push when code is pushed to main or manually triggered
# Only build/push for main pushes or manual runs
if: github.event_name == 'push' || github.event_name == 'workflow_dispatch'

strategy:
Expand Down Expand Up @@ -137,17 +187,28 @@ jobs:
steps:

- name: Checkout repository
uses: actions/checkout@v4
uses: actions/checkout@v6

# =====================================================
# Azure OIDC Login
# =====================================================
- name: Login to Azure
uses: azure/login@v2
uses: azure/login@v3
with:
creds: ${{ secrets.AZURE_CREDENTIALS }}
client-id: ${{ secrets.AZURE_CLIENT_ID }}
tenant-id: ${{ secrets.AZURE_TENANT_ID }}
subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }}

# =====================================================
# Azure Container Registry Login
# =====================================================
- name: Login to Azure Container Registry
run: |
az acr login --name ${{ vars.ACR_NAME }}

# =====================================================
# Build Docker Image
# =====================================================
- name: Build Docker image
run: |
docker build \
Expand All @@ -156,12 +217,115 @@ jobs:
-t ${{ vars.ACR_LOGIN_SERVER }}/${{ matrix.image }}:latest \
./${{ matrix.service }}

# =====================================================
# Push SHA Tagged Image
# =====================================================
- name: Push Docker image with commit SHA
run: |
docker push \
${{ vars.ACR_LOGIN_SERVER }}/${{ matrix.image }}:${{ github.sha }}

# =====================================================
# Push Latest Tagged Image
# =====================================================
- name: Push Docker image with latest tag
run: |
docker push \
${{ vars.ACR_LOGIN_SERVER }}/${{ matrix.image }}:latest


# =========================================================
# Continuous Deployment to Azure Kubernetes Service
# =========================================================
deploy-to-aks:
name: Deploy to AKS
runs-on: ubuntu-latest

# Deploy only after all Docker images are successfully pushed
needs:
- build-and-push

# Only deploy for pushes to main or manual runs
if: github.event_name == 'push' || github.event_name == 'workflow_dispatch'

steps:

# =====================================================
# Checkout Repository
# =====================================================
- name: Checkout repository
uses: actions/checkout@v6

# =====================================================
# Azure OIDC Login
# =====================================================
- name: Login to Azure
uses: azure/login@v3
with:
client-id: ${{ secrets.AZURE_CLIENT_ID }}
tenant-id: ${{ secrets.AZURE_TENANT_ID }}
subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }}

# =====================================================
# Configure kubectl for AKS
# =====================================================
- name: Set AKS context
uses: azure/aks-set-context@v4
with:
resource-group: koalatech-week07-rg
cluster-name: koalatech-week07-aks

- name: Set up kubectl
uses: azure/setup-kubectl@v4

# =====================================================
# Apply Kubernetes Manifests
# =====================================================
- name: Deploy Kubernetes manifests
run: |
kubectl apply -f k8s/databases.yaml
kubectl apply -f k8s/apps.yaml
kubectl apply -f k8s/frontend.yaml

# =====================================================
# Update Deployments to Exact Git Commit Image
# =====================================================
- name: Deploy images
run: |
kubectl set image deployment/user-service \
user-service=${{ vars.ACR_LOGIN_SERVER }}/koalatech-user-service:${{ github.sha }}

kubectl set image deployment/student-service \
student-service=${{ vars.ACR_LOGIN_SERVER }}/koalatech-student-service:${{ github.sha }}

kubectl set image deployment/lecturer-service \
lecturer-service=${{ vars.ACR_LOGIN_SERVER }}/koalatech-lecturer-service:${{ github.sha }}

kubectl set image deployment/course-service \
course-service=${{ vars.ACR_LOGIN_SERVER }}/koalatech-course-service:${{ github.sha }}

kubectl set image deployment/enrollment-service \
enrollment-service=${{ vars.ACR_LOGIN_SERVER }}/koalatech-enrollment-service:${{ github.sha }}

kubectl set image deployment/frontend \
frontend=${{ vars.ACR_LOGIN_SERVER }}/koalatech-frontend:${{ github.sha }}

# =====================================================
# Wait for Successful Rollout
# =====================================================
- name: Verify deployments
run: |
kubectl rollout status deployment/user-service --timeout=180s
kubectl rollout status deployment/student-service --timeout=180s
kubectl rollout status deployment/lecturer-service --timeout=180s
kubectl rollout status deployment/course-service --timeout=180s
kubectl rollout status deployment/enrollment-service --timeout=180s
kubectl rollout status deployment/frontend --timeout=180s

# =====================================================
# Verify Kubernetes Pods and Services
# =====================================================
- name: Verify Kubernetes pods
run: |
kubectl get pods
kubectl get services
4 changes: 2 additions & 2 deletions frontend/src/pages/Login.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ const Login = () => {
variant="h4"
gutterBottom
>
KoalaTech University
KoalaTech University - Continuous Deployment Demo
</Typography>

<Typography
Expand Down Expand Up @@ -155,4 +155,4 @@ const Login = () => {
);
};

export default Login;
export default Login;
Loading