Yeda AI Tips · #137

Español

Order CI Stages Cheapest and Most Likely to Fail First

Your CI wastes ten minutes catching a typo that lint could flag in thirty seconds. The fix isn't a faster machine — it's ordering. Run the cheapest, most likely-to-fail checks first, and a bad commit dies in seconds instead of after the full test suite.

Why order beats horsepower

The later a defect is caught, the more it costs to fix. The IBM Systems Sciences Institute's often-cited figures put a defect found in design at 1x, in implementation ~6.5x, in testing ~15x, and after release 60–100x. The same logic applies inside a single CI run at the scale of minutes: a typo caught by lint costs you 30 seconds; the same typo caught only when the test job crashes costs you the whole ten-minute run plus the context switch.

So the goal of a pipeline isn't just "run every check." It's surface the cheapest failure as early as possible. Every second a doomed commit spends in your slow stages is pure waste.

The ordering rule

Sort stages by two axes and run them in this order: cheap-and-flaky first, expensive-and-solid last.

StageTypical timeCatchesOrder
Format + lintsecondsStyle, typos, unused imports, obvious bugs1st
Type-checkseconds–1 minWrong signatures, null misuse, renamed APIs2nd
Unit + integration testsminutesLogic, regressions3rd
Build / package / deployminutes+Bundling, artifacts, env wiring4th

Read it top-down: lint fails a typo before the type-checker ever boots; the type-checker rejects a bad signature before a single test spins up; tests catch logic before you burn a build. Each gate is cheaper and more likely to trip than the one below it, so the average failing commit exits early.

Make CI actually stop early

Ordering only pays off if a failed stage blocks the next one. In GitHub Actions, chain jobs with needs so an expensive job never starts until its cheap predecessor is green:

jobs:
  lint:
    runs-on: ubuntu-latest
    steps: [ { uses: actions/checkout@v4 }, { run: make lint } ]
  typecheck:
    needs: lint
    runs-on: ubuntu-latest
    steps: [ { uses: actions/checkout@v4 }, { run: make typecheck } ]
  test:
    needs: typecheck
    runs-on: ubuntu-latest
    steps: [ { uses: actions/checkout@v4 }, { run: make test } ]

If a job a downstream job needs fails or is skipped, GitHub Actions skips the dependent job by default — so test never runs when lint is red.

Power moves

The payoff

A typo now fails fast and loud in seconds, not after a ten-minute run. Your slow, expensive stages only ever run on commits that already cleared the cheap ones — so your runner minutes, and your attention, go to the changes that actually deserve them.

Resources

Shipping AI-assisted code fast? Yeda AI designs and audits the pipelines that keep speed from becoming breakage.

Talk to us · Read the blog