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
105 changes: 89 additions & 16 deletions .github/workflows/01-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,27 @@ name: 01 - CI

on:
# Trigger the workflow on push to main branch
# (merging a pull request into main is a push to main)
push:
branches:
- main


# Run the tests on every pull request into main, so changes are
# validated before they are merged and deployed (Task 9.3C)
pull_request:
branches:
- main

# Manual trigger for the workflow
workflow_dispatch:

permissions:
contents: read

jobs:

# =========================================================
# Backend Tests
# Stage 1: Backend Tests
# =========================================================
backend-test:
name: Test ${{ matrix.service }}
Expand Down Expand Up @@ -103,13 +112,18 @@ jobs:


# =========================================================
# Build and Push Docker Images
# Stage 2: Build, Security Scan (Docker Scout) and Push
# Images are scanned BEFORE they are pushed to ACR, so an
# image with fixable critical/high CVEs never reaches the
# registry or the cluster.
# =========================================================
build-and-push:
name: Build and Push ${{ matrix.image }}
build-scan-push:
name: Build, scan and push ${{ matrix.image }}
runs-on: ubuntu-latest

# All backend tests must pass before this job starts
# All backend tests must pass. The Azure infrastructure (AKS, ACR,
# storage) is already provisioned, so the Terraform stage was removed
# for Task 9.3C, which focuses on the deployment stages.
needs:
- backend-test

Expand Down Expand Up @@ -139,6 +153,9 @@ jobs:
- service: enrollment-service
image: koalatech-enrollment-service

env:
IMAGE_REF: ${{ vars.ACR_LOGIN_SERVER }}/${{ matrix.image }}:${{ github.sha }}

steps:

- name: Checkout repository
Expand All @@ -153,14 +170,70 @@ jobs:
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 }}
# Docker Scout requires a Docker Hub account
- name: Login to Docker Hub (for Docker Scout)
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}

- name: Push Docker image with commit SHA
run: |
docker push \
${{ vars.ACR_LOGIN_SERVER }}/${{ matrix.image }}:${{ github.sha }}
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3

- name: Build Docker image (load locally for scanning)
uses: docker/build-push-action@v6
with:
context: ./${{ matrix.service }}
platforms: linux/amd64
load: true
push: false
tags: ${{ env.IMAGE_REF }}

- name: Docker Scout - vulnerability report (all severities)
uses: docker/scout-action@v1
with:
command: quickview,cves
image: local://${{ env.IMAGE_REF }}
sarif-file: scout-${{ matrix.service }}.sarif
summary: true
exit-code: false

- name: Docker Scout - base image recommendations
uses: docker/scout-action@v1
with:
command: recommendations
image: local://${{ env.IMAGE_REF }}
summary: true

- name: Upload Docker Scout report
if: always()
uses: actions/upload-artifact@v4
with:
name: docker-scout-${{ matrix.service }}
path: scout-${{ matrix.service }}.sarif
if-no-files-found: ignore

# Security gate: fail the build if the image contains
# critical/high vulnerabilities that already have a fix.
- name: Docker Scout - security gate
uses: docker/scout-action@v1
with:
command: cves
image: local://${{ env.IMAGE_REF }}
only-severities: ${{ vars.SCOUT_FAIL_SEVERITIES || 'critical,high' }}
only-fixed: true
summary: false
exit-code: true

# Only reached when the gate passes. Rebuilds from the build
# cache and pushes with an SBOM and provenance attestation
# (supply-chain policy finding from Task 10.1P).
- name: Push image with SBOM and provenance
uses: docker/build-push-action@v6
with:
context: ./${{ matrix.service }}
platforms: linux/amd64
push: true
sbom: true
provenance: mode=max
tags: ${{ env.IMAGE_REF }}
Loading