The DAG that needs: draws
Each job declares zero or more upstream jobs via needs:. GitHub forms a DAG out of these and runs the jobs in topological order. Jobs with no path between them run in parallel.
Common shapes:
- Linear — A → B → C. Each waits on the previous.
- Fan-out, fan-in — A → [B, C, D] → E. B/C/D run in parallel after A, then E waits on all three.
- Diamond — A → [B, C] → D. Common for build-then-(test, lint)-then-deploy.
- Disjoint chains — independent pipelines living in the same workflow.
Failure propagation
By default, a job is skipped if any of its needs: failed or was cancelled. You can override with if: always() or if: failure() for cleanup / notification jobs that must run anyway.