Challenge 3: Justify Every Job Dependency — Possible Solution ==================================================================== 1. build-and-push: needs: test -> Enforces Chapter 2/Chapter 6's principle: a broken build is never containerized or pushed at all. If removed: build-and-push would run in PARALLEL with (or even before) test finishes, meaning a Docker image could be built and pushed to the registry EVEN IF the test suite is still running or has already failed. A genuinely broken commit's image could end up in the registry, available for later jobs to pull and deploy, completely defeating the "tests gate everything downstream" purpose CI is built around (Chapter 1). 2. deploy-staging: needs: build-and-push -> Enforces Chapter 2's basic ordering principle: you can't deploy an image that hasn't been built and pushed yet. If removed: deploy-staging could attempt to run BEFORE build-and-push has actually finished pushing the image to the registry — the deploy script would try to pull an image tag (${{ github.sha }}) that doesn't exist in the registry yet, failing immediately, or worse, silently pulling a STALE previous image if the deploy script isn't careful, deploying old code under the pretense of deploying the current commit. 3. deploy-production: needs: deploy-staging -> Enforces this capstone's own staging-then-production sequencing, and indirectly Chapter 7's point about validating a deploy before wider exposure. If removed: deploy-production could run in PARALLEL with deploy-staging (or even if deploy-staging failed), meaning production could receive a deployment that was NEVER actually verified against staging first — completely undermining the purpose of having a staging environment as an intermediate validation step before reaching real users. 4. deploy-production also implicitly depends on deploy-staging SUCCEEDING (not just running) — GitHub Actions' default needs: behavior is to skip a job if any of its dependencies FAILED, not just to wait for them to finish. -> Enforces Chapter 7's health-check-and-rollback principle transitively: if deploy-staging's own health check fails and triggers staging's rollback (Challenge 1's fix), deploy-staging itself would typically report as failed or degraded, which naturally prevents deploy-production from ever running at all. If this default behavior were somehow overridden (e.g. using always() or continue-on-error incorrectly): production could be deployed even after staging was confirmed broken, exactly the scenario the staging→production sequence exists to prevent. WHY THIS WORKS AS AN ANSWER ------------------------------ Each needs: relationship in this capstone's workflow enforces a SPECIFIC principle introduced in an earlier chapter — test-gates-build (Ch.2/Ch.6), build-before-deploy ordering (Ch.2), staging-before- production validation (Ch.7's core rationale for staged rollouts), and failure-propagation through the dependency chain (Ch.2's dependency- graph model, combined with Ch.7's rollback material). Removing any one of them doesn't just make the pipeline "less neat" — it reopens a specific, concrete failure mode that an earlier chapter identified and was designed to close.