← Back to Home
βš™οΈ

Building a CI Pipeline

Put the pieces together into a real pipeline that guards your main branch.

⏱11 min readπŸ“šDevOps Fundamentals

You know the pieces β€” now let’s build a real CI pipeline: the automated gate that every change must pass before it can be merged. This is the workflow that keeps a codebase healthy.


🎯 Learning Objectives

By the end of this lesson you will:


What a CI Pipeline Should Do

A good CI pipeline runs on every push and pull request and answers one question: is this change safe to merge? It typically:

  1. Checks out the code
  2. Installs dependencies (cached)
  3. Lints for style and obvious errors
  4. Tests the code
  5. Builds the production artifact
  6. Uploads the artifact for later use

πŸ’‘ Fail fast, cheapest first

Order steps so the quickest checks run first. Linting fails in seconds; a full test suite takes minutes. Putting lint before tests means an obvious mistake stops the pipeline early, saving time and runner minutes.


A Complete CI Workflow

yaml
name: CI
on:
push:
  branches: [main]
pull_request:
  branches: [main]

jobs:
ci:
  runs-on: ubuntu-latest
  steps:
    - name: Check out code
      uses: actions/checkout@v4

    - name: Set up Node
      uses: actions/setup-node@v4
      with:
        node-version: 20
        cache: npm

    - name: Install dependencies
      run: npm ci

    - name: Lint
      run: npm run lint

    - name: Test
      run: npm test

    - name: Build
      run: npm run build

    - name: Upload build output
      uses: actions/upload-artifact@v4
      with:
        name: dist
        path: dist/

Each step is named so the Actions UI reads clearly. npm ci (not npm install) gives clean, reproducible installs from the lockfile β€” the right choice for CI.

bash β€” 80Γ—24
student@devops:~$# The run summary in the Actions tab:

Artifacts β€” Keeping the Output

The build step produces a dist/ folder. Uploading it as an artifact means you can download it from the run, or hand it to a deploy job later:

yaml
- uses: actions/upload-artifact@v4
with:
  name: dist
  path: dist/
  retention-days: 7

⚠ npm ci vs npm install in CI

Always use npm ci in pipelines. It installs exactly what’s in package-lock.json and fails if the lockfile is out of sync β€” giving you reproducible builds. npm install can silently update the lockfile, causing β€œworks locally, fails in CI” surprises.


Making It a Required Check

A pipeline only protects you if it blocks bad merges. In the repository’s branch protection settings, mark the CI workflow as a required status check on main.

Now a pull request cannot be merged until CI passes:

text
Pull request  β†’  CI runs  β†’  βœ“ green  β†’  merge allowed
                        β†’  βœ— red    β†’  merge blocked

πŸ’‘ This is the heart of CI

Branch protection + a required CI check is what actually keeps main deployable. Without it, the pipeline is just advisory β€” people can merge over a red build.


πŸ§ͺ Hands-on Lab

πŸ“

Design a CI Pipeline

  1. Write a CI workflow that runs on pushes and PRs to main
  2. Include install (cached), lint, test, and build steps in the right order
  3. Upload the build output as an artifact

🧠 Knowledge Check

Knowledge Check

Why should linting run before the full test suite in a CI pipeline?

Knowledge Check

What makes a CI pipeline actually prevent broken code from reaching main?


πŸ’Ό Interview Preparation

Interview Q&A

Walk me through a CI pipeline you would build for a web application.


Summary

You’ve built a complete CI pipeline: checkout, cached install, lint, test, build, and artifact upload β€” enforced as a required check. Next, you’ll safely add deployment using secrets and environments to reach true CD.

Up Next

Secrets & Deployment

You've mastered this lesson. Continue your journey to becoming a DevOps Engineer.

Start Next Lesson→