Module 1: Introduction to CI/CD and GitHub Actions
2. What CI/CD Is and Why AI Needs It
Overview
CI/CD is not a tool — it's an engineering practice that automates the validation and delivery of software. In this capsule you're going to understand what Continuous Integration and Continuous Deployment/Delivery mean, how they differ, and why AI applications have unique reasons to adopt it: non-determinism in outputs, the risk of runaway costs, and the fragility of prompts.
By the end of this capsule you'll be clear on the "why" behind everything you'll build in this guide. It's not abstract theory — it's the reasoning that justifies every pipeline, every check, and every automation you'll implement.
The problem: An AI Engineer's manual flow
Imagine your day-to-day without CI/CD:
1. You write code on your laptop
2. You push to the repo
3. You run tests... when you remember
4. If they pass (or you didn't run them), you merge
5. You connect to the server over SSH
6. git pull
7. docker build (you wait 5 min)
8. docker-compose up
9. You manually check that it "looks fine"
10. You cross your fingers and go to sleep
This flow has obvious problems:
- There's no automatic validation. If you forgot to run the tests, a bug reaches production.
- There's no reproducibility. Your laptop has different dependencies than the server. "It works on my machine" is your most repeated phrase.
- There's no traceability. If something breaks, which commit caused it? You don't know.
- There's no protection. Anyone can push to main and deploy without review.
For traditional software, these problems are annoying. For AI applications, they're dangerous.
Why AI systems need CI/CD more than traditional software
1. Non-determinism: The same input, different outputs
In traditional software, a function that receives 2 + 2 always returns 4. If it doesn't, you have a bug. In AI systems, the same prompt can generate different responses every time:
# Traditional software: deterministic
def add(a, b):
return a + b # ALWAYS returns the same thing
# AI application: non-deterministic
def summarize(text, client):
response = client.chat.completions.create(
model="gpt-4o-mini",
messages=[{"role": "user", "content": f"Summarize: {text}"}]
)
return response.choices[0].message.content
# Every call can return a different summary
Implication for CI/CD: You can't simply compare output == expected. You need more sophisticated evaluations: does the summary cover the key points? Is the length within range? Is the tone consistent? This is what you'll build in Module 3 with prompt regression testing.
2. Cost risks: A badly designed prompt can cost you thousands
In traditional software, a bug costs developer time. In AI systems, a bug in a prompt can cost real money — a lot of money:
# Efficient prompt: ~50 tokens → $0.0001 per request
prompt_v1 = "Summarize this text in 2 sentences."
# Accidentally verbose prompt: ~2000 tokens → $0.004 per request
prompt_v2 = """
You are an expert summarizer with decades of experience...
[unnecessarily long instructions]
Please provide a comprehensive yet concise summary...
[more redundant context]
"""
# 40x more expensive. At 10,000 requests/day = $40/day vs $1/day.
# In a month: $1,200 vs $30. A single prompt change.
Implication for CI/CD: You need automatic cost estimation checks that detect when a prompt change significantly increases the cost before it reaches production. You'll implement this in Module 3.
3. Prompt fragility: Subtle changes, big impacts
A refactor that changes one word in the system prompt can degrade the quality of the responses without any traditional test failing:
# Prompt v1: works well
system_prompt_v1 = "You are a helpful assistant. Respond in JSON format."
# Output: {"answer": "Python is an interpreted language", "confidence": 0.95}
# Prompt v2: "small change"
system_prompt_v2 = "You are a knowledgeable assistant. Respond in JSON."
# Output: {"answer": "Python is an interpreted language", "confidence": 0.9}
# The confidence dropped and the phrasing shifted. The structure tests pass,
# but the behavior changed. Without prompt regression testing, nobody notices.
Implication for CI/CD: You need prompt regression testing that detects changes in the behavior of your prompts — not just that the output has the right structure, but that quality and consistency hold up.
4. Model updates: Your code didn't change, but the output did
LLM providers update their models without telling you. OpenAI can update gpt-4o-mini on a Tuesday, and your application starts generating slightly different responses — without you touching a single line of code:
Monday: "gpt-4o-mini" → style A responses (what you expected)
Tuesday: OpenAI updates the model silently
Wednesday: "gpt-4o-mini" → style B responses (subtly different)
Without CI/CD: nobody finds out until a user reports that "something feels off"
With CI/CD: a scheduled workflow detects the change automatically
Implication for CI/CD: You need scheduled workflows that run periodic evaluations to detect changes in the model's outputs, even when your code hasn't changed. You'll build this in Module 7.
What Continuous Integration (CI) is
Continuous Integration is the practice of automatically validating every code change before integrating it into the main branch.
The CI flow
Developer pushes
↓
CI activates automatically
↓
┌─────────────────────┐
│ 1. Checkout code │
│ 2. Install deps │
│ 3. Run linting │
│ 4. Run tests │
│ 5. Run AI checks │ ← Unique to AI apps
│ 6. Build Docker │
│ 7. Report results │
└─────────────────────┘
↓
✅ Everything passed → PR can be merged
❌ Something failed → PR blocked until fixed
CI solves
- ✅ "Does it work?" — Tests run automatically on every push
- ✅ "In which environment?" — On a clean, reproducible runner, not on your laptop
- ✅ "Who validated it?" — The machine, without depending on someone remembering
- ✅ "What broke?" — Direct traceability: this commit, this test, this line
CI for AI: What this guide adds
Generic CI runs tests and lint. CI for AI adds:
| Generic check | AI-specific check |
|---|---|
| pytest (unit tests) | Prompt regression testing |
| flake8/ruff (linting) | Cost estimation checks |
| mypy (type checking) | Model version tracking |
| Docker build test | Output quality evaluation |
What Continuous Deployment/Delivery (CD) is
There are two variants of CD, and the difference matters:
Continuous Delivery
The validated code is ready to deploy, but a human decides when to do it:
CI passes ✅ → Image ready in registry → Human approves → Deploy to production
Continuous Deployment
The validated code is deployed automatically to production without human intervention:
CI passes ✅ → Image ready in registry → Automatic deploy to production
Which one to use for AI systems?
For most AI applications, Continuous Delivery with approval gates is the right choice:
CI passes
↓
Automatic deploy to STAGING
↓
Verification in staging (smoke tests)
↓
Reviewer approves ← Human in the loop
↓
Deploy to PRODUCTION
Why not fully automatic deployment?
Because AI applications have risks that traditional software doesn't:
- A prompt regression may not be detected by automated tests 100% of the time
- A cost change isn't always obvious in CI
- Output quality is partly subjective
The approval gate is your safety net. In Module 6 you'll implement exactly this flow.
CI/CD vs "just running tests locally"
| Aspect | Local tests | CI/CD |
|---|---|---|
| When it runs | When you remember | On every push, automatically |
| Where it runs | Your laptop (with your configs) | Clean, reproducible runner |
| What it verifies | Whatever you choose to run | Everything, always, no exceptions |
| Who finds out | Only you | The whole team (in the PR) |
| Python versions | Yours | Multiple (matrix testing) |
| If it fails | You decide whether to ignore it | The PR is blocked automatically |
| Cost | Your time | Free (GitHub Actions free tier) |
The clearest analogy: local tests are like checking your own work before handing it in. CI/CD is like having an independent reviewer who checks always, everything, automatically — and who doesn't get tired, doesn't forget, and isn't in a hurry to go to lunch.
The complete pipeline you'll build in this guide
So that you have the full picture, this is the pipeline you'll have by the end of Module 8:
git push
│
▼
┌────────────────────────────────┐
│ CI STAGE │
│ │
│ ✅ Lint (ruff) │
│ ✅ Type check (mypy) │
│ ✅ Unit tests (pytest) │
│ ✅ Prompt regression tests │ ← AI-specific
│ ✅ Cost estimation check │ ← AI-specific
│ │
└────────────┬───────────────────┘
│
▼
┌────────────────────────────────┐
│ BUILD STAGE │
│ │
│ ✅ Docker build (with caching)│
│ ✅ Security scan (trivy) │
│ ✅ Push to GHCR (tagged) │
│ │
└────────────┬───────────────────┘
│
▼
┌────────────────────────────────┐
│ DEPLOY STAGING │
│ │
│ ✅ Deploy to staging │
│ ✅ Smoke tests │
│ ✅ Slack notification │
│ │
└────────────┬───────────────────┘
│
▼
┌────────────────────────────────┐
│ APPROVAL GATE │
│ │
│ ⏸️ Waiting for approval │
│ 👤 Reviewer reviews staging │
│ ✅ Approve │
│ │
└────────────┬───────────────────┘
│
▼
┌────────────────────────────────┐
│ DEPLOY PRODUCTION │
│ │
│ ✅ Deploy to production │
│ ✅ Post-deploy validation │
│ ✅ Success notification │
│ 🔄 Rollback if it fails │
│ │
└────────────────────────────────┘
Each block corresponds to specific modules of this guide. In the end, everything integrates into a single automated pipeline.
Comparison: CI/CD for Traditional Software vs AI Systems
| Aspect | Traditional Software | AI Systems |
|---|---|---|
| Tests | Unit + integration | + Prompt regression + evaluations |
| Quality checks | Lint, types | + Cost estimation, output quality |
| Determinism | Same input → same output | Same input → variable output |
| Cost risk | CPU/memory | + API costs per request |
| Deployment risk | Functional bug | + Subtle quality degradation |
| Monitoring | Uptime, latency | + Response quality, cost drift |
| Scheduled checks | Dependency updates | + Model update detection |
| Rollback trigger | Crash, error rate | + Quality degradation |
The right-hand column is what makes this guide special. Generic CI/CD covers the left-hand column. This guide covers both.
Troubleshooting
"Isn't CI/CD only for big teams?"
No. CI/CD is valuable even for a single developer:
- Protection against yourself: That Friday at 6pm when you make a "quick" push without running tests — CI catches it
- Reproducibility: Your code works on the CI runner, not just on your laptop with Python 3.12.1 and that specific version of torch
- Living documentation: The workflow YAML documents exactly which checks run and in what order
- Portfolio: A repo with a CI/CD pipeline is more impressive than one without it
"Isn't that a lot of setup for something simple?"
The initial setup takes ~30 minutes (Modules 1-2). After that, every push is validated automatically forever. The ROI is positive from the first week.
"Is GitHub Actions the best option?"
For this guide, yes. GitHub Actions is the most widely adopted platform, it integrates natively with GitHub (where your code already lives), it has a generous free tier (2,000 min/month), and the community of reusable actions is enormous. Other options (Jenkins, GitLab CI, CircleCI) are valid, but learning one well is better than knowing three superficially.
Exercises
Exercise 1: Identify the risks
You have an AI application that uses OpenAI to generate summaries of articles. Without CI/CD, what are the 3 most critical risks?
See solution
-
Undetected prompt regression: A change in the system prompt can degrade the quality of the summaries without anyone noticing until a user complains.
-
Cost explosion: A refactor that changes the prompt from 50 tokens to 2,000 tokens multiplies costs by 40x. Without cost estimation in CI, the first signal is the OpenAI bill at the end of the month.
-
Broken deploy with no rollback: A manual deploy that breaks production requires manual intervention to revert. Meanwhile, users see errors or low-quality responses.
Bonus: Silent model update — OpenAI updates gpt-4o-mini and the summaries change in style/quality without your code having changed.
Exercise 2: CI vs CD
Classify each action as CI or CD:
- Running pytest automatically on every push
- Deploying to staging when the tests pass
- Verifying that the Dockerfile builds correctly
- Sending a Slack notification when the production deploy succeeds
- Calculating the estimated cost of a prompt before merge
- Waiting for a reviewer's approval before deploying to production
See solution
- CI — Code validation (testing)
- CD — Automatic delivery to an environment
- CI — Build validation
- CD — Post-deployment notification
- CI — Pre-merge validation (quality gate)
- CD — Approval gate in the delivery pipeline
Pattern: CI = everything that validates and verifies. CD = everything that delivers and deploys.
Exercise 3: Design your pipeline
You have an AI project with FastAPI + OpenAI + ChromaDB (RAG). Draw (in text) which checks you would include in your CI/CD pipeline. You don't need to know how to implement them yet — just list them.
See solution
CI:
├── Lint (ruff)
├── Type check (mypy)
├── Unit tests (pytest) — mock OpenAI
├── Integration tests — queries to ChromaDB
├── Prompt regression — verify quality of RAG responses
├── Cost estimation — average tokens per query
└── Docker build test — verify the Dockerfile
CD:
├── Docker build + push to registry
├── Deploy to staging
├── Smoke tests in staging (health check + test query)
├── Approval gate (reviewer)
├── Deploy to production
├── Post-deploy validation
└── Automatic rollback if it fails
Note: You don't need to implement all of this now. By the end of this guide (Module 8), you'll have this complete pipeline working.
Exercise 4: Calculate the ROI
Your team of 3 developers does an average of 10 deploys per week. Each manual deploy takes 15 minutes. Each developer runs tests locally "sometimes" (50% of pushes). How much time do you save with CI/CD per month?
See solution
Manual deploy:
- 10 deploys × 15 min = 150 min/week
- 150 × 4 = 600 min/month (10 hours)
Tests not run:
- If they run tests only 50% of the time, the other 50% can introduce bugs
- Let's assume 1 bug/week that takes 2 hours to debug: 8 hours/month
Total saved: ~18 hours/month
CI/CD setup: ~4-6 hours (one time only)
Positive ROI: first week.
Summary
- ✅ CI (Continuous Integration) automatically validates every change: tests, lint, type checks, and for AI: prompt regression and cost estimation
- ✅ CD (Continuous Delivery/Deployment) automates delivery: build → deploy staging → approval → deploy production
- ✅ AI systems need CI/CD more than traditional software for 4 reasons: non-determinism, cost risks, prompt fragility, and silent model updates
- ✅ GitHub Actions is the platform you'll use in this guide — native integration with GitHub, generous free tier, enormous community
- ✅ The complete pipeline you'll build: lint → test → AI checks → Docker build → deploy staging → approve → deploy production → rollback if it fails
- ✅ The ROI is immediate — the setup takes hours, the savings are permanent
Additional resources
- GitHub Actions Documentation - Official GitHub Actions documentation
- What is CI/CD? (GitHub) - GitHub's official explanation of CI/CD
- Continuous Integration (Martin Fowler) - The classic article that defined CI
- Testing LLM Applications (DeepLearning.AI) - Context on testing AI
- GitHub Actions Pricing - Free tier details
- The DevOps Handbook - Reference on modern DevOps practices