Skip to content

CI/CD and GitHub Actions

🎯 Learning Goals

By the end of this lesson, you will be able to:

  • Configure GitHub Actions to automatically run tests on every push or pull request.
  • Set up workflows to build and deploy Docker images for your FastAPI app.
  • Use versioning and Git tags to manage releases in production.

⚡ Step 1: Automated Testing with GitHub Actions

Create a workflow file:

📄 .github/workflows/test.yml

name: Run FastAPI Tests

on:
  push:
    branches: [ "main" ]
  pull_request:
    branches: [ "main" ]

jobs:
  test:
    runs-on: ubuntu-latest

    steps:
    - name: Checkout code
      uses: actions/checkout@v3

    - name: Set up Python
      uses: actions/setup-python@v4
      with:
        python-version: "3.11"

    - name: Install dependencies
      run: |
        python -m pip install --upgrade pip
        pip install -r requirements.txt
        pip install pytest

    - name: Run tests
      run: pytest -v

🔍 What’s happening?

  • Runs on every push or PR to main.
  • Sets up Python 3.11.
  • Installs dependencies.
  • Runs pytest to execute your test suite.

⚡ Step 2: Automated Deployment with Docker

Add another workflow for building and pushing Docker images.

📄 .github/workflows/deploy.yml

name: Build and Deploy FastAPI Docker Image

on:
  push:
    tags:
      - "v*.*.*"   # run only on version tags

jobs:
  build:
    runs-on: ubuntu-latest

    steps:
    - name: Checkout code
      uses: actions/checkout@v3

    - name: Log in to Docker Hub
      uses: docker/login-action@v2
      with:
        username: ${{ secrets.DOCKER_USERNAME }}
        password: ${{ secrets.DOCKER_PASSWORD }}

    - name: Build and push Docker image
      uses: docker/build-push-action@v4
      with:
        context: .
        push: true
        tags: your-dockerhub-username/fastapi-taskmanager:${{ github.ref_name }}

🔍 What’s happening?

  • Workflow triggers only when you push a Git tag like v1.0.0.
  • Logs in to Docker Hub using secrets.
  • Builds and pushes the image tagged with the version.

⚡ Step 3: Versioning and Tagging

🧠 Why Versioning?

  • Helps track changes across releases.
  • Ensures deployments are reproducible.
  • Communicates stability and compatibility to users.

📄 Semantic Versioning

Follow the MAJOR.MINOR.PATCH convention:

  • MAJOR: incompatible API changes
  • MINOR: new features, backward-compatible
  • PATCH: bug fixes

Example:

  • v1.0.0 → first stable release
  • v1.1.0 → new features added
  • v1.1.1 → bug fix

📄 Creating a Tag

git tag v1.0.0
git push origin v1.0.0

This triggers the deployment workflow.


⚡ Step 4: Putting It All Together

  • Develop locally → commit changes → push to GitHub.
  • GitHub Actions runs tests automatically.
  • If tests pass, you create a version tag (v1.0.0).
  • GitHub Actions builds and pushes a Docker image to Docker Hub.
  • Your deployment platform (e.g. Kubernetes, ECS, Cloud Run) pulls the new image.

🧠 Best Practices

  • Keep workflows modular: one for testing, one for deployment.
  • Use GitHub Secrets for credentials (never hardcode passwords).
  • Automate linting and type checks (e.g. flake8, mypy).
  • Use semantic versioning consistently.
  • Protect your main branch with required checks (tests must pass before merging).

🧪 Practice Challenge

  1. Add a linting step (flake8) to your test workflow.
  2. Configure deployment to AWS ECS or GCP Cloud Run using GitHub Actions.
  3. Create a release pipeline that automatically updates your staging environment on every push to develop, and production only on tagged releases.

🧠 Recap

In this lesson, you:

  • Configured GitHub Actions for automated testing.
  • Set up Docker build and deployment triggered by Git tags.
  • Learned how to use semantic versioning and tagging for production releases.