Shift-Left in CI Pipelines

๐Ÿ“‹ Table of Contents โ–พ
  1. Embedding Shift-Left Checks into CI
  2. Common Mistakes

CI pipelines are a natural place to implement shift-left practices because they can run early checks on every change. By designing pipelines so that fast, meaningful tests run quickly, teams get immediate feedback and reduce the chance of broken code reaching later stages.

Embedding Shift-Left Checks into CI

A common pattern is to structure the pipeline with early stages for linting, static analysis and unit tests, followed by stages for API and UI tests. Fail-fast behaviour ensures that if early gates fail, later, slower stages do not even run.

# Example: early-stage checks in CI
stages:
  - lint
  - unit
  - api
  - ui

lint:
  stage: lint
  script: npm run lint

unit:
  stage: unit
  script: npm test -- --runInBand

api:
  stage: api
  script: npm run test:api

ui:
  stage: ui
  script: npm run test:ui
Note: Organising stages by feedback speed makes it clear where shift-left checks live and how they protect later stages.
Tip: Make early stages mandatory for every branch and pull request, while allowing heavier suites to run on selected branches or schedules.
Warning: If early checks are flaky or slow, developers may try to bypass the pipeline, undermining the entire shift-left effort.

QA can help decide which tests belong in early stages and which should run less frequently as deeper safety nets.

Common Mistakes

Mistake 1 โ€” Putting all checks in a single late stage

This delays feedback.

โŒ Wrong: Running linting, unit, API and UI tests only after merge.

โœ… Correct: Run fast checks on each commit and reserve heavy suites for later.

Mistake 2 โ€” Ignoring early stage failures

This breaks trust.

โŒ Wrong: Allowing merges even when linting or unit tests fail.

โœ… Correct: Treat early failures as blockers until fixed or explicitly justified.

🧠 Test Yourself

What is a good way to apply shift-left in CI?