4.5.10 · D5Software Engineering

Question bank — CI - CD — pipeline stages, GitHub Actions - GitLab CI concepts

1,820 words8 min readBack to topic

True or false — justify

Fail-fast means a later stage that would have failed is reported as failed.
False — if an earlier stage fails, later stages are skipped, not run, so they show as skipped/blocked. Their real status is unknown; you fixed the earlier stage first.
Continuous Delivery ships every passing build straight to production.
False — Delivery prepares a deployable artifact and stops at a manual approval gate; only Continuous Deployment removes the human button.
Jobs in the same stage always run in parallel.
Half-true — they run in parallel only if enough runners are free; with fewer runners than jobs they queue into waves, and a needs:/dependency can still force ordering.
"Green pipeline" guarantees the code has no bugs.
False — it only guarantees the checks you wrote passed. Untested paths, missing edge-case tests, and flaky-but-skipped tests can all hide real defects.
CI's main value is running the test suite.
False — CI's value is frequent integration: merging small changes so conflicts and regressions stay tiny. Tests are the check that makes frequent merging safe, not the goal itself.
Putting a secret directly in the YAML is fine because the file lives in a private repo.
False — the YAML is committed, so the secret enters git history permanently and is visible to anyone with repo access forever. Use the platform secret store instead.
Adding more runners always shortens total pipeline time.
False — speedup caps once runners equal the number of independent jobs (), and any dependent stages still run serially regardless of runner count.
A GitHub Actions Workflow is the same concept level as a GitLab Stage.
False — a Workflow maps to a GitLab Pipeline (the whole thing). The level order is Workflow→Job→Step (GitHub) and Pipeline→Stage→Job (GitLab).
If tests pass on my laptop, they will pass on the runner.
False — the runner is a clean container with no hidden global installs, different OS/timezone, and missing secrets, so environment gaps commonly turn local-green into CI-red.
Caching dependencies changes the result of a build.
False — a correct cache only replaces a slow deterministic install with a fast restore of the same files. If the result changes, the cache key was wrong (stale cache), which is a bug.
The Lint stage runs the program to find bugs.
False — lint/static analysis reads the code without executing it, which is why it's cheap and placed early; it catches style issues and obvious mistakes only.
Continuous Deployment and Continuous Delivery abbreviate differently on purpose.
True — both are "CD", which is deliberately ambiguous; you must read context. Delivery = manual prod gate, Deployment = automatic prod release.

Spot the error

"We put the Deploy stage before Test so users get features faster."
Wrong order — deploying unverified code ships bugs to users. Stages go cheapest-fail-first (Build→Lint→Test→Package→Deploy); Deploy is last because it's the most expensive mistake.
"Our pipeline has 3 identical test jobs and 1 runner, so parallel time = single-job time."
Error — with 1 runner the 3 jobs can't overlap; they run serially into 3 waves. Parallel time equals single-job time only when runners ≥ jobs.
"Delivery = a human still deploys, so it's not really automated."
Error — Delivery is automated up to a versioned, tested, ready artifact; only the final prod release is manual. The automation isn't absent, it's gated.
"We cache node_modules with the key deps and never change the key."
Error — a static key never invalidates, so after you change package-lock.json the pipeline restores stale dependencies. The cache key must include a hash of the lockfile.
"The e2e tests are flaky, so we made them run first to fail fast."
Error — fail-fast orders by cheap→expensive, and e2e is the slowest test. Put unit tests first; flakiness is a test-quality problem, not something reordering fixes.
"Independent jobs run faster if we chain them with needs: so they queue neatly."
Error — needs: creates a dependency, forcing serial order and removing the parallelism. Independent jobs should have no needs: between them so they overlap.
"The build passed, so we skip the lint stage to save time."
Error — build success means the code compiles/installs, not that it's clean. Lint catches a different class of problems (style, dead code, obvious bugs) and is cheap, so skipping it removes value for little gain.

Why questions

Why are pipeline stages ordered cheapest-and-fastest-fail-first?
Because you shouldn't pay for a slow deploy when a 2-second lint already proves the code is broken; failing early (shift-left) makes each fix cheaper and faster to find. See DevOps Principles & Shift-Left.
Why are dependencies the classic thing to cache but source code is not?
Dependency install is repeated, deterministic, and large — perfect for memoization; source code changes every commit, so caching it would just serve stale files.
Why is the pipeline written as YAML config inside the repo instead of clicked in a UI?
Config-as-code makes the build versioned, reviewable, and reproducible — you can diff, roll back, and see exactly how any past commit was built. Ties to Infrastructure as Code.
Why do modern engines model stages as a DAG via needs: instead of strict linear stages?
A strict line makes a fast job wait for an unrelated slow one; a directed acyclic graph lets independent jobs start as soon as their inputs are ready, shortening total wall-clock time.
Why does parallel speedup have a ceiling instead of growing forever?
You can't split work into more pieces than there are independent jobs, and any serial (dependent) portion is untouched by extra runners — an Amdahl-style limit. See Amdahl's Law.
Why does a test needing API_KEY pass locally but fail only in CI?
Your laptop has the key set in a hidden global/env file; the CI runner is clean and injects secrets only from the secret store, so a missing/unconfigured secret surfaces there first.
Why run runners as containers/images at all?
A fresh, identical container per run removes "works on my machine" drift and lets you reproduce a failure locally with the same image. Ties to Docker & Containerization.
Why is merging frequently central to CI, rather than merging once at the end?
Small, frequent merges keep conflicts and regressions tiny and easy to trace; a giant end-of-project merge hides which change broke what and is exponentially costlier to untangle. See Version Control & Git Branching.

Edge cases

What is the parallel time when there are more runners than jobs ()?
The extra runners sit idle; time is just (one wave), the same as . You can't go faster than one job's duration.
What happens to the pipeline when the first stage (Build) fails?
Every later stage is skipped, so lint/test/deploy never run; the only actionable signal is the build failure itself, and other stages report skipped, not passed.
If a stage has jobs that each depend on the previous job's artifact, what is the real speedup?
Zero from parallelism within that chain — the dependency forces serial execution, so total time is the sum of the jobs regardless of runner count.
What is the effect of a cache hit whose restored files are stale (wrong key)?
The job runs fast but against the wrong dependencies, producing green-but-invalid results or confusing failures; correctness broke even though timing improved.
What does an empty/zero-job stage cost in the pipeline?
Effectively nothing to execute, but it can still act as a synchronization barrier — later stages wait for it to "complete," which is instant, so it just passes through.
For Continuous Deployment, what is the human gate before production?
There is none — that's the defining difference from Delivery; the passing build releases to production automatically with no approval step.
What happens when two jobs in the same stage both write to the same shared artifact path?
A race condition — running in parallel, they can overwrite each other's output nondeterministically; artifacts should be per-job or the jobs made dependent/ordered.

Recall One-line self-test before you leave

Say aloud: "Delivery has a gate, Deployment does not; stages fail fast, so red-later means skipped; parallel speedup caps at ; secrets live in the store, never the YAML; the runner is a clean container." If any clause surprised you, reread that trap.


Connections

  • Parent: CI/CD topic note
  • DevOps Principles & Shift-Left — the fail-fast ordering rationale.
  • Amdahl's Law — why parallel speedup is capped.
  • Docker & Containerization — clean-container runners and reproducibility.
  • Version Control & Git Branching — why frequent merging is the point of CI.
  • Infrastructure as Code — config-as-code motivation for YAML pipelines.