Pipeline Architecture
Pipeline Stages
A pipeline is a sequence of automated stages. Each stage must pass for the next to run.
Source → Build → Test → Package → Deploy → Verify
| Stage | What Happens |
|---|---|
| Source | Commit or PR triggers the pipeline |
| Build | Dependencies installed, code compiled, lint/type checks |
| Test | Unit → integration → API → E2E tests, coverage check |
| Package | Docker image built and pushed, artifact archived |
| Deploy | Service updated on target environment |
| Verify | Smoke tests, health checks, monitoring baseline |
Failing fast matters: a lint failure in Build should not waste 5 minutes of Test compute.
Pipeline Types
Monolithic Pipeline
All stages in a single linear pipeline. Simple, works for small projects.
build → test → deploy
Problem: one slow E2E test blocks the whole pipeline.
Multi-Stage Pipeline
Stages run in dependency order. Stages without dependencies run in parallel.
┌── unit tests ──┐
build ──►│ ├──► package ──► deploy
└── lint/types ──┘
This is the most common pattern for production systems.
Distributed Pipelines
Each service has its own pipeline. An orchestrator coordinates cross-service flows.
service-a pipeline ──┐
service-b pipeline ──┼──► integration test pipeline ──► deploy
service-c pipeline ──┘
Used in microservices architectures.
Event-Driven Pipelines
Pipelines triggered by events beyond git commits: artifact publication, scheduled jobs, external webhooks, manual approvals.
New Docker image pushed → trigger downstream deploy pipeline
Nightly schedule → trigger regression suite
Slack approval → trigger production deploy
Pipeline Triggers
| Trigger | When to Use |
|---|---|
| Push to main/master | Deploy to staging; run full regression |
| Pull request opened/updated | Run CI checks; block merge on failure |
| Scheduled (cron) | Nightly full regression, security scans, soak tests |
| Manual | Production deploys requiring human approval |
| Tag / release creation | Versioned artifact builds |
| External webhook | Triggered by upstream service or artifact |
GitHub Actions Pipeline Structure
name: CI/CD
on:
push:
branches: [main]
pull_request:
branches: [main]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: astral-sh/setup-uv@v3
- run: uv sync
- run: uv run ruff check .
- run: uv run mypy .
test:
needs: build
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: astral-sh/setup-uv@v3
- run: uv run pytest -n auto --cov=src --cov-fail-under=90
deploy-staging:
needs: test
if: github.ref == 'refs/heads/main'
runs-on: ubuntu-latest
environment: staging
steps:
- uses: actions/checkout@v4
- run: ./scripts/deploy.sh staging
Pipeline as Code
Pipeline configuration must be: - Version-controlled — changes to the pipeline go through code review - Reproducible — running the same pipeline twice on the same commit gives the same result - Self-documenting — reading the YAML tells you exactly what runs
Never configure pipelines through a UI only. Config in UI is invisible, unreviewed, and drifts.