Capstone: Building a Full Pipeline for a Real App

CI/CD Pipelines
Chapter 9 ยท Capstone: Building a Full Pipeline for a Real App

๐Ÿ Capstone: Building a Full Pipeline for a Real App

Every previous chapter built one piece in isolation. This capstone assembles a complete pipeline for a small Node.js API โ€” test, containerize, and deploy to staging automatically, then to production behind a manual approval gate โ€” using every technique from the course.

The App

A small Node.js/Express API, nothing fancy โ€” just enough to give the pipeline something real to build, test, and deploy.

โš™๏ธ The Full Workflow

name: CI/CD on: [push, pull_request] jobs: test: strategy: matrix: node-version: [18, 20, 22] # Ch.4 โ€” matrix build runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 # Ch.3 โ€” always first - uses: actions/setup-node@v4 with: node-version: ${{ matrix.node-version }} cache: 'npm' # Ch.4 โ€” lockfile-hashed cache - run: npm ci - run: npm test build-and-push: needs: test # Ch.2/Ch.6 โ€” no image without passing tests if: github.ref == 'refs/heads/main' # Ch.2 โ€” only push-to-main deploys runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - run: docker build -t ghcr.io/myorg/api:${{ github.sha }} . # Ch.6 โ€” SHA tag - run: echo "${{ secrets.REGISTRY_TOKEN }}" | docker login ghcr.io -u ${{ github.actor }} --password-stdin # Ch.5 - run: docker push ghcr.io/myorg/api:${{ github.sha }} deploy-staging: needs: build-and-push runs-on: ubuntu-latest environment: staging # Ch.8 โ€” no reviewers, deploys automatically steps: - run: ./deploy.sh staging ${{ github.sha }} - run: curl -f https://staging.example.com/health # Ch.7 โ€” health check deploy-production: needs: deploy-staging runs-on: ubuntu-latest environment: production # Ch.8 โ€” required reviewer configured steps: - run: ./deploy.sh production ${{ github.sha }} # Ch.6 โ€” the SAME image, never rebuilt - run: curl -f https://example.com/health || ./rollback.sh ${{ github.sha }} # Ch.7

Walking Through a Real Run

  1. A developer pushes to main โ€” the test job runs across three Node versions in parallel
  2. Once all three pass, build-and-push builds and pushes one SHA-tagged image
  3. deploy-staging deploys that image automatically, then checks its health endpoint
  4. The team reviews staging; a designated reviewer approves the production environment gate
  5. deploy-production deploys the exact same image โ€” never rebuilt โ€” checking health again, with rollback ready if it fails

What's Simplified Here

No database migrations, no canary/blue-green rollout mechanics (Chapter 7 covered the concepts; a real production app would implement one), no monitoring/alerting integration.

What This Capstone Focuses On

The structural correctness of the pipeline itself โ€” every job dependency, every gate, every safety mechanism from Chapters 2โ€“8, wired together correctly.

Chapter 1's Manual Process vs This Pipeline

Manual (Chapter 1)

Remember to run tests, manually build, manually copy files, manually restart โ€” every step a chance to forget something.

This Capstone's Pipeline

Every step automated and gated appropriately โ€” nothing depends on a human remembering anything except the one deliberate approval this app's stakes actually warrant.

๐Ÿ’ป Coding Challenges

Challenge 1: Add a Rollback Job for Staging

The deploy-staging job currently checks health but doesn't roll back on failure. Add a rollback step to it, mirroring deploy-production's pattern.

Goal: Practice extending the capstone's own pipeline with a missing safety mechanism.

โ†’ Solution

Challenge 2: Trace What Happens on a Pull Request

Trace this capstone's workflow for a pull request (not a push to main) โ€” which jobs run, which don't, and why, citing the specific YAML condition responsible.

Goal: Practice tracing trigger-to-stage behavior through a real, complete workflow file.

โ†’ Solution

Challenge 3: Justify Every Job Dependency

For each of the four needs: relationships in this capstone's workflow, state which earlier chapter's principle it enforces and what would go wrong if that dependency were removed.

Goal: Practice holding the entire course's material together as one coherent system.

โ†’ Solution

โš ๏ธ Gotcha: Testing Pipeline Changes Against Production Itself

The pipeline defined in this capstone is itself code โ€” and it deserves the same "test before it affects everyone" caution as the application it deploys. A change to the workflow file (a new job, a modified deploy script) that's merged straight to main and immediately exercised against the real staging/production environments risks the exact kind of incident this whole course exists to prevent, just one level up. Test pipeline changes the same way application changes are tested: open a PR first (exercising only the test job, per Chapter 2's trigger mapping), and consider a manual workflow_dispatch run against a scratch environment before trusting a modified pipeline with real staging or production traffic.

๐ŸŽ“ Course Complete

This closes out CI/CD Pipelines โ€” from why automation matters, through pipeline anatomy, GitHub Actions fundamentals, building and testing, secrets, Docker, deployment strategies, environments and approval gates, and finally this capstone assembling a complete, real pipeline end to end.