diff --git a/.github/workflows/01-ci.yml b/.github/workflows/01-ci.yml index 8206db43..52549a22 100644 --- a/.github/workflows/01-ci.yml +++ b/.github/workflows/01-ci.yml @@ -1,6 +1,10 @@ name: 01 - CI on: + pull_request: + branches: + - main + # Trigger the workflow on push to main branch push: branches: @@ -150,17 +154,10 @@ jobs: creds: ${{ secrets.AZURE_CREDENTIALS }} - name: Login to Azure Container Registry - run: | - az acr login --name ${{ vars.ACR_NAME }} + run: az acr login --name ${{ vars.ACR_NAME }} - name: Build Docker image - run: | - docker build \ - --platform linux/amd64 \ - -t ${{ vars.ACR_LOGIN_SERVER }}/${{ matrix.image }}:${{ github.sha }} \ - ./${{ matrix.service }} + run: docker build --platform=linux/amd64 --tag="${{ vars.ACR_LOGIN_SERVER }}/${{ matrix.image }}:${{ github.sha }}" "./${{ matrix.service }}" - name: Push Docker image with commit SHA - run: | - docker push \ - ${{ vars.ACR_LOGIN_SERVER }}/${{ matrix.image }}:${{ github.sha }} + run: docker push "${{ vars.ACR_LOGIN_SERVER }}/${{ matrix.image }}:${{ github.sha }}" \ No newline at end of file diff --git a/.github/workflows/02-deploy-staging.yml b/.github/workflows/02-deploy-staging.yml index 006bb70d..aa8bbd32 100644 --- a/.github/workflows/02-deploy-staging.yml +++ b/.github/workflows/02-deploy-staging.yml @@ -1,3 +1,4 @@ + name: 02 - Deploy to Staging on: @@ -9,41 +10,62 @@ on: branches: - main + workflow_dispatch: + inputs: + image_tag: + description: "Full commit SHA from a successful CI build" + required: true + type: string + +permissions: + contents: read + jobs: deploy-staging: name: Deploy to Staging runs-on: ubuntu-latest - if: > - ${{ github.event.workflow_run.conclusion == 'success' }} + if: >- + ${{ + github.event_name == 'workflow_dispatch' || + ( + github.event.workflow_run.conclusion == 'success' && + github.event.workflow_run.event == 'push' + ) + }} - environment: - name: staging + env: + IMAGE_TAG: ${{ inputs.image_tag || github.event.workflow_run.head_sha }} steps: + # 1. Checkout the tested commit - name: Checkout tested commit uses: actions/checkout@v4 with: - ref: ${{ github.event.workflow_run.head_sha }} + ref: ${{ env.IMAGE_TAG }} + # 2. Login to Azure - name: Login to Azure - uses: azure/login@v3 + uses: azure/login@v2 with: creds: ${{ secrets.AZURE_CREDENTIALS }} + # 3. Connect to AKS - name: Get AKS credentials run: | az aks get-credentials \ - --resource-group ${{ vars.AKS_RESOURCE_GROUP }} \ - --name ${{ vars.AKS_CLUSTER_NAME }} \ + --resource-group "${{ vars.AKS_RESOURCE_GROUP }}" \ + --name "${{ vars.AKS_CLUSTER_NAME }}" \ --overwrite-existing + # 4. Create staging namespace - name: Create staging namespace run: | kubectl create namespace staging \ --dry-run=client \ -o yaml | kubectl apply -f - + # 5. Create PostgreSQL secret - name: Create PostgreSQL secret run: | kubectl create secret generic postgres-secret \ @@ -53,6 +75,7 @@ jobs: --dry-run=client \ -o yaml | kubectl apply -f - + # 6. Create application secret - name: Create application secret run: | kubectl create secret generic application-secret \ @@ -67,85 +90,98 @@ jobs: --dry-run=client \ -o yaml | kubectl apply -f - + # 7. Apply Kubernetes manifests - name: Apply Kubernetes manifests run: | - kubectl apply \ - -f kubernetes/staging/ + kubectl apply -f kubernetes/staging/ + # 8. Update frontend image - name: Update frontend image run: | kubectl set image deployment/frontend \ - frontend=${{ vars.ACR_LOGIN_SERVER }}/koalatech-frontend:${{ github.event.workflow_run.head_sha }} \ + frontend="${{ vars.ACR_LOGIN_SERVER }}/koalatech-frontend:${IMAGE_TAG}" \ -n staging + # 9. Update user-service image - name: Update user-service image run: | kubectl set image deployment/user-service \ - user-service=${{ vars.ACR_LOGIN_SERVER }}/koalatech-user-service:${{ github.event.workflow_run.head_sha }} \ + user-service="${{ vars.ACR_LOGIN_SERVER }}/koalatech-user-service:${IMAGE_TAG}" \ -n staging + # 10. Update student-service image - name: Update student-service image run: | kubectl set image deployment/student-service \ - student-service=${{ vars.ACR_LOGIN_SERVER }}/koalatech-student-service:${{ github.event.workflow_run.head_sha }} \ + student-service="${{ vars.ACR_LOGIN_SERVER }}/koalatech-student-service:${IMAGE_TAG}" \ -n staging + # 11. Update lecturer-service image - name: Update lecturer-service image run: | kubectl set image deployment/lecturer-service \ - lecturer-service=${{ vars.ACR_LOGIN_SERVER }}/koalatech-lecturer-service:${{ github.event.workflow_run.head_sha }} \ + lecturer-service="${{ vars.ACR_LOGIN_SERVER }}/koalatech-lecturer-service:${IMAGE_TAG}" \ -n staging + # 12. Update course-service image - name: Update course-service image run: | kubectl set image deployment/course-service \ - course-service=${{ vars.ACR_LOGIN_SERVER }}/koalatech-course-service:${{ github.event.workflow_run.head_sha }} \ + course-service="${{ vars.ACR_LOGIN_SERVER }}/koalatech-course-service:${IMAGE_TAG}" \ -n staging + # 13. Update enrollment-service image - name: Update enrollment-service image run: | kubectl set image deployment/enrollment-service \ - enrollment-service=${{ vars.ACR_LOGIN_SERVER }}/koalatech-enrollment-service:${{ github.event.workflow_run.head_sha }} \ + enrollment-service="${{ vars.ACR_LOGIN_SERVER }}/koalatech-enrollment-service:${IMAGE_TAG}" \ -n staging + # 14. Verify frontend rollout - name: Wait for frontend rollout run: | kubectl rollout status deployment/frontend \ -n staging \ --timeout=300s + # 15. Verify user-service rollout - name: Wait for user-service rollout run: | kubectl rollout status deployment/user-service \ -n staging \ --timeout=300s + # 16. Verify student-service rollout - name: Wait for student-service rollout run: | kubectl rollout status deployment/student-service \ -n staging \ --timeout=300s + # 17. Verify lecturer-service rollout - name: Wait for lecturer-service rollout run: | kubectl rollout status deployment/lecturer-service \ -n staging \ --timeout=300s + # 18. Verify course-service rollout - name: Wait for course-service rollout run: | kubectl rollout status deployment/course-service \ -n staging \ --timeout=300s + # 19. Verify enrollment-service rollout - name: Wait for enrollment-service rollout run: | kubectl rollout status deployment/enrollment-service \ -n staging \ --timeout=300s + # 20. Display staging resources - name: Show staging resources run: | kubectl get pods -n staging kubectl get services -n staging - kubectl get pvc -n staging \ No newline at end of file + kubectl get pvc -n staging diff --git a/.github/workflows/03-staging-test.yml b/.github/workflows/03-staging-test.yml index 01daf5fa..9b2ec49d 100644 --- a/.github/workflows/03-staging-test.yml +++ b/.github/workflows/03-staging-test.yml @@ -14,9 +14,8 @@ jobs: name: Staging Smoke Test runs-on: ubuntu-latest - if: > - ${{ github.event.workflow_run.conclusion == 'success' }} - + if: github.event.workflow_run.conclusion == 'success' + environment: name: staging diff --git a/.github/workflows/04-deploy-production.yml b/.github/workflows/04-deploy-production.yml index 969d646b..36a08f34 100644 --- a/.github/workflows/04-deploy-production.yml +++ b/.github/workflows/04-deploy-production.yml @@ -1,6 +1,17 @@ name: 04 - Deploy to Production on: + # Continuous Deployment: promote to production automatically + # once the staging smoke test has passed for a commit on main + workflow_run: + workflows: + - "03 - Test Staging" + types: + - completed + branches: + - main + + # Kept for manual deployments / rollbacks to a specific image workflow_dispatch: inputs: image_tag: @@ -13,12 +24,21 @@ jobs: name: Deploy to Production runs-on: ubuntu-latest + # Only deploy if the staging tests succeeded (or when run manually) + if: github.event_name == 'workflow_dispatch' || github.event.workflow_run.conclusion == 'success' + environment: name: production + env: + # Automatic runs use the tested commit SHA; manual runs use the input + IMAGE_TAG: ${{ inputs.image_tag || github.event.workflow_run.head_sha }} + steps: - - name: Checkout repository + - name: Checkout tested commit uses: actions/checkout@v4 + with: + ref: ${{ env.IMAGE_TAG }} - name: Login to Azure uses: azure/login@v3 @@ -69,37 +89,37 @@ jobs: - name: Update frontend image run: | kubectl set image deployment/frontend \ - frontend=${{ vars.ACR_LOGIN_SERVER }}/koalatech-frontend:${{ inputs.image_tag }} \ + frontend=${{ vars.ACR_LOGIN_SERVER }}/koalatech-frontend:${{ env.IMAGE_TAG }} \ -n production - name: Update user-service image run: | kubectl set image deployment/user-service \ - user-service=${{ vars.ACR_LOGIN_SERVER }}/koalatech-user-service:${{ inputs.image_tag }} \ + user-service=${{ vars.ACR_LOGIN_SERVER }}/koalatech-user-service:${{ env.IMAGE_TAG }} \ -n production - name: Update student-service image run: | kubectl set image deployment/student-service \ - student-service=${{ vars.ACR_LOGIN_SERVER }}/koalatech-student-service:${{ inputs.image_tag }} \ + student-service=${{ vars.ACR_LOGIN_SERVER }}/koalatech-student-service:${{ env.IMAGE_TAG }} \ -n production - name: Update lecturer-service image run: | kubectl set image deployment/lecturer-service \ - lecturer-service=${{ vars.ACR_LOGIN_SERVER }}/koalatech-lecturer-service:${{ inputs.image_tag }} \ + lecturer-service=${{ vars.ACR_LOGIN_SERVER }}/koalatech-lecturer-service:${{ env.IMAGE_TAG }} \ -n production - name: Update course-service image run: | kubectl set image deployment/course-service \ - course-service=${{ vars.ACR_LOGIN_SERVER }}/koalatech-course-service:${{ inputs.image_tag }} \ + course-service=${{ vars.ACR_LOGIN_SERVER }}/koalatech-course-service:${{ env.IMAGE_TAG }} \ -n production - name: Update enrollment-service image run: | kubectl set image deployment/enrollment-service \ - enrollment-service=${{ vars.ACR_LOGIN_SERVER }}/koalatech-enrollment-service:${{ inputs.image_tag }} \ + enrollment-service=${{ vars.ACR_LOGIN_SERVER }}/koalatech-enrollment-service:${{ env.IMAGE_TAG }} \ -n production - name: Wait for frontend rollout diff --git a/frontend/src/components/Header.jsx b/frontend/src/components/Header.jsx index d1a76071..7b5f5d46 100644 --- a/frontend/src/components/Header.jsx +++ b/frontend/src/components/Header.jsx @@ -43,7 +43,7 @@ const Header = () => { fontWeight: 600, }} > - KoalaTech University + KoalaTech University - Deployed by CD