You will build an end-to-end pipeline that tests, builds a container, scans it, and deploys on a successful merge to main. By the end every release is automated, gated, and traceable to a commit.

Learning Objectives

  • Chain test, build, scan, and deploy stages.
  • Gate deployment on passing tests and a clean scan.
  • Deploy a container to a target on merge to main.
  • Time: ~5 hours · Difficulty: Advanced · Prereqs: the GitHub Actions and Docker labs.

Architecture Overview

Environment Setup

You will need: GitHub Actions, a container registry, Trivy, and a deploy target (kubectl/SSH).

Before you begin: store registry and deploy credentials as GitHub secrets.

Step-by-Step Execution

01
Test then build a tagged image
jobs:
  build:
    needs: test
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - run: docker build -t ghcr.io/tyfsadik/app:${{ github.sha }} .
02
Scan and fail on critical CVEs
trivy image --exit-code 1 --severity CRITICAL ghcr.io/tyfsadik/app:${{ github.sha }}
03
Deploy on merge to main
$ kubectl set image deploy/app app=ghcr.io/tyfsadik/app:$GITHUB_SHA && kubectl rollout status deploy/app
deployment "app" successfully rolled out

Progress So Far

Testing & Validation

gh run list --workflow=cicd.yml --limit 1 && kubectl get deploy app -o jsonpath='{.spec.template.spec.containers[0].image}'

The latest run should be green and the deployment image tag should match the merged commit SHA, proving end-to-end traceability.

Troubleshooting
  • Deploy runs on every branch: guard the deploy job with if: github.ref == 'refs/heads/main'.
  • Registry push denied: authenticate with a token scoped to packages.
  • Scan blocks valid release: triage the CVE; only fail on fixable criticals where appropriate.

Extension Ideas

  • Add a manual approval gate for production.
  • Deploy to AKS instead of a single cluster.
  • Add IaC apply with Terraform in the pipeline.

Key Results

  • Automated test, build, scan, and deploy from one commit.
  • Blocked releases with critical CVEs before deploy.
  • Tagged images with the commit SHA for full traceability.
  • Deployed only from main, gated on green checks.