100% Free Forever
AI-Powered Learning
Industry Expert Content
Certificates & Badges
Learn At Your Own Pace
YAML

Anatomy of a CI/CD Pipeline

A CI/CD pipeline is a series of automated stages — source, build, test, package, deploy — that a code change flows through, each acting as a quality gate before the next.

CI/CD FoundationsBeginner9 min readJul 8, 2026
Analogies

Anatomy of a CI/CD Pipeline

A CI/CD pipeline is the automated assembly line that takes a code change from a developer's commit to a running artifact in production. While specific tools structure this differently — GitHub Actions calls the top-level unit a 'workflow' made of 'jobs' and 'steps', GitLab CI calls it a 'pipeline' made of 'stages' and 'jobs', Jenkins calls it a 'pipeline' made of 'stages' and 'steps' — the conceptual anatomy is remarkably consistent across tools. Understanding the generic shape of a pipeline makes it much easier to pick up any specific tool's syntax, because you're learning where a concept lives rather than learning the concept itself for the first time.

🏏

Cricket analogy: Whether it's the IPL, the Ashes, or a domestic Ranji Trophy match, every cricket contest still has the same skeleton of innings, overs, and deliveries; once you know that shape, switching from watching Bumrah bowl in the IPL to following a Test match at Lord's is just learning new names for the same structure.

The Source Stage

Every pipeline begins by reacting to a trigger — most commonly a push to a branch or the opening/updating of a pull request — and checking out the exact commit that triggered it. This stage also typically resolves which pipeline configuration applies, since many tools allow different behavior for different branches or paths (a technique called path filtering, useful in monorepos to avoid rebuilding unrelated services).

🏏

Cricket analogy: A match only gets underway once the umpire signals play and the toss decides who bats first, much like a pipeline waits for a specific trigger — a push or a pull request — before it decides which set of rules, like a day-night pink-ball format, actually applies.

The Build Stage

The build stage compiles or transpiles source code, resolves and installs dependencies, and produces a build artifact — this might be a compiled binary, a bundled JavaScript application, a container image, or a packaged library. A well-designed build stage is deterministic: given the same commit and the same dependency lockfile, it produces a bit-for-bit reproducible artifact, which matters enormously for debugging and for trusting that what was tested is what gets deployed.

🏏

Cricket analogy: A bat maker at Kashmir Willow takes raw wood, shapes it to exact spec, and produces an identical-grade bat every time from the same batch of willow, the way a deterministic build stage turns the same commit and lockfile into a bit-for-bit identical artifact.

The Test Stage

Tests typically run in a pyramid: fast unit tests first (seconds), then integration tests against real or containerized dependencies (minutes), then slower end-to-end tests (potentially many minutes). Pipelines often 'fail fast' by ordering stages so that cheap, high-signal checks (linting, unit tests) run before expensive ones (E2E tests), so a broken pipeline reports failure as quickly as possible rather than burning ten minutes of compute before reporting a typo.

🏏

Cricket analogy: A batsman's coaching starts with shadow practice against no bowler, then throwdowns from a coach, then finally a full net session against real bowlers, mirroring the test pyramid's climb from instant unit tests to slower end-to-end checks.

yaml
stages:
  - build
  - test
  - package
  - deploy

build-job:
  stage: build
  script:
    - npm ci
    - npm run build
  artifacts:
    paths:
      - dist/

unit-tests:
  stage: test
  script:
    - npm run test:unit

integration-tests:
  stage: test
  script:
    - npm run test:integration

package-image:
  stage: package
  script:
    - docker build -t registry.example.com/app:$CI_COMMIT_SHA .
    - docker push registry.example.com/app:$CI_COMMIT_SHA

deploy-staging:
  stage: deploy
  script:
    - ./deploy.sh staging $CI_COMMIT_SHA
  environment: staging

The Package and Deploy Stages

Packaging wraps the build artifact into a deployable unit — most commonly a versioned container image pushed to a registry, tagged with something traceable like the commit SHA. Deploy stages then take that specific, immutable artifact and place it into an environment, whether that's a staging environment for further validation or production itself. Good pipelines never rebuild the artifact between staging and production; the exact same tested binary or image is promoted forward, a principle sometimes called 'build once, deploy many'.

🏏

Cricket analogy: A single match ball, sealed and stamped with a serial number by the manufacturer, is the exact same ball used from the toss through to the final over — nobody swaps it between innings — mirroring how the same tagged artifact is promoted from staging to production without being rebuilt.

Think of a pipeline as a series of increasingly expensive filters, like a funnel sorting rocks by size. The cheapest, fastest checks (syntax/lint) sit at the top and reject obviously bad input immediately; only what survives reaches the slow, expensive checks (full E2E suites, security scans) further down.

A frequent anti-pattern is rebuilding the artifact separately for each environment (dev, staging, prod) instead of building once and promoting the same artifact forward. This breaks the guarantee that what was tested is exactly what gets deployed, since a rebuild can pull in different dependency versions or use different build flags.

  • A pipeline's generic anatomy is: source/trigger, build, test, package, deploy — regardless of which specific tool implements it.
  • Build artifacts should be deterministic and reproducible from the same commit and lockfile.
  • Tests should run cheapest-and-fastest first to fail fast and save compute time.
  • 'Build once, deploy many' means the same artifact is promoted through environments rather than rebuilt for each one.
  • Path filtering lets monorepo pipelines skip stages unrelated to the changed files.
  • Every tool's terminology (workflow/job/step vs. pipeline/stage/job) maps onto this same underlying structure.

Practice what you learned

Was this page helpful?

Topics covered

#YAML#CICDToolsPipelinesStudyNotes#DevOps#AnatomyOfACICDPipeline#Anatomy#Pipeline#Source#Stage#StudyNotes#SkillVeris