The diagnostic sequence is the same regardless of platform (GitHub Actions, GitLab CI, Jenkins) — isolate which stage failed and whether it's the code, the pipeline config, or the environment.
Identify which stage failed
Build (compile/package), test, or deploy each point at a different class of problem — read the failing job's name before reading a single line of its log.
Reproduce locally if it's a build or test failure
git checkout COMMIT_SHAChecks out the exact commit CI ran, ruling out 'it's different on my branch' before debugging further.
Run the same build/test command the pipeline runs, locally, with the same dependency versions if possible. If it passes locally but fails in CI, suspect an environment difference next, not the code.
Rule out environment differences
Common CI-only failures
A dependency version resolved differently (no lockfile, or a lockfile not actually committed), a test relying on local timezone/locale that differs on the runner, insufficient runner resources (OOM on a memory-heavy test suite), or a flaky test with a real race condition that a slower/busier CI runner exposes more often than a fast local machine.
Check for a secrets or permissions problem on deploy
A deploy stage failing with an auth error usually means an expired or rotated credential, a secret not available to that specific branch/environment (many CI systems scope secrets per-branch or per-environment), or a changed IAM/service account permission.
Check for a stale or corrupted cache
Most CI systems cache dependencies between runs for speed. A cache poisoned by a bad previous run, or one that didn't invalidate after a dependency change, can produce a failure that has nothing to do with the current commit at all — clearing the cache and rerunning is a legitimate diagnostic step, not just a hopeful retry.
Check for flakiness before treating it as a real failure
If a rerun with no code changes passes, the test (or the infrastructure it depends on) is flaky, not the commit. Track flaky tests explicitly rather than normalizing "just rerun it" — an untracked flaky test slowly erodes trust in the whole pipeline until real failures get rerun-and-ignored too.
Don't bypass a failing pipeline to unblock a deploy
Skipping CI/CD checks under time pressure is exactly how a real bug reaches production. Fix the pipeline or the code — if the checks themselves are wrong (a genuinely broken test, not a broken commit), fix that explicitly and visibly, not by merging around it.