What is CI/CD and Why Does it Matter?

CI/CD (Continuous Integration / Continuous Deployment) is the practice of automatically running tests every single time a developer pushes code to GitHub. If a test fails, the code is blocked from going to production โ€” automatically, without a human needing to notice.

The Problem without CI: A developer changes a Lambda function on a Monday. Nobody notices the change broke the S3 upload logic. On Friday, the app crashes in production. 5,000 users can't upload files. The engineering team spends a weekend debugging.

With MiniStack CI: The broken code is rejected instantly on Monday as soon as the developer pushes. The test suite catches it in 30 seconds. The developer fixes a 2-line bug before going to lunch.

What is GitHub Actions?

GitHub Actions is a free built-in task runner inside GitHub. Every time code is pushed, GitHub spins up a fresh Linux computer (called a "runner"), runs a script you define (called a "workflow"), and reports if everything passed or failed directly on the Pull Request.

We are going to write a GitHub Actions workflow that starts Ministack, runs our PyTest test suite against it, and fails the build if any AWS tests break.

The Complete Workflow File

Create this file at .github/workflows/aws-tests.yml in your repository. GitHub automatically detects and runs it:

# .github/workflows/aws-tests.yml

name: AWS Integration Tests

on:
  push:
    branches: [ main, develop ]
  pull_request:
    branches: [ main ]

jobs:
  test:
    runs-on: ubuntu-latest

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

      - name: Start MiniStack (Fake AWS Cloud)
        run: docker run -d -p 4566:4566 nahuelnucera/ministack
        # -d runs it in the background so the script continues

      - name: Wait for MiniStack to be ready
        run: |
          echo 'Waiting for MiniStack...'
          for i in $(seq 1 10); do
            curl -s http://localhost:4566/_ministack/health && break
            sleep 2
          done

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

      - name: Install dependencies
        run: pip install pytest boto3

      - name: Run AWS Tests
        run: pytest tests/ -v
        env:
          AWS_ACCESS_KEY_ID: test
          AWS_SECRET_ACCESS_KEY: test
          AWS_DEFAULT_REGION: us-east-1

What Happens When a Test Fails?

If any PyTest assertion fails, the GitHub Actions step turns red. GitHub automatically marks the Pull Request as "Failed" and blocks the merge button. The developer gets an email explaining which test broke and why.

No human reviewer needed to catch the broken AWS logic. The robot caught it. This is the power of having a fake cloud in your CI pipeline.

๐Ÿ’ก Pro Tip: Since MiniStack starts up in under 2 seconds and your tests run against local memory (not the internet), your entire AWS test suite typically finishes in under 30 seconds. Compared to 10+ minutes with a real AWS dev environment, this dramatically tightens your feedback loop.

Want to learn how to write those PyTest tests? Head to the PyTest AWS Guide or start from the beginning with AWS Testing 101.