Git, CI/CD & GitOpsXLVII · Pipeline DependenciesDeclaration
needs and depends-on — declaring edges between jobs
What you'll learn
- Declare an edge in GitHub Actions with `needs:` and in GitLab CI with `needs:`
- Distinguish a single-element list from a multi-element list and predict the scheduler behaviour
- Recognise that the default semantics is "wait for successful completion"
- Use `needs:` with `outputs:` to express a typed data contract between jobs
Prerequisites
Verified against Git 2.55.x teaching target; 2.40+ minimum · GitHub Actions continuous service; Aug 2026 documentation baseline · Argo CD v3.5.x teaching target; v3.0+ minimum · Flux v2.9.x · Sigstore Cosign v3.1.x · SLSA v1.2 · OCI Distribution Specification v1.1 · Git LFS v3.7.1 · Kubernetes (cross-course target) 1.36.x
The needs: clause declares an edge in the pipeline
DAG. The current job waits for every job listed in
needs: to complete before starting. The list can
be a single job or many.
needs in GitHub Actions
jobs:
build:
runs-on: ubuntu-latest
test:
runs-on: ubuntu-latest
needs: build
package:
runs-on: ubuntu-latest
needs: [build, test]
deploy:
runs-on: ubuntu-latest
needs: package
A single predecessor can be a bare string or a one-element list; equivalent. Multiple predecessors must be a list. Default is to wait for successful completion.
needs in GitLab CI
package:
stage: package
needs: [unit, integration]
script: make package
package:
stage: package
needs:
- job: unit
artifacts: true
- job: integration
artifacts: true
script: make package
The first is a simple list; the second couples
needs: with the artifact download.
Single versus multiple predecessors
A list of one means “wait for this job”. A list of many means “wait for all of these jobs”. The scheduler starts the current job when every predecessor has completed.
grep -B 1 'needs:' .github/workflows/ci.yml
Implicit completion states
The default waits for successful completion only.
States: success, always, failure, cancelled.
GitHub Actions uses if: always(); GitLab CI uses
when: on_success / when: always.
Production discipline
- Declare
needs:explicitly; absent is immediate. - Use bare-string form for a single predecessor.
- Audit
needs:for cycles.
Cross-course references
- Ansible for Production Sysadmins - Part XXXVII uses the same pattern in AWX workflows.
- Linux for Production Sysadmins - Part XXX uses
the same edge for systemd
Requires=.
Quiz
Knowledge check · 4 questions
Q1. Job D has `needs: [A, B, C]`. What must be true before D starts?
Q2. By default, a job with `needs: [predecessor]` waits for the predecessor to succeed; if the predecessor fails, the dependent job is skipped.
Q3. In GitHub Actions, name the two equivalent ways to declare a single predecessor and explain why the artifact must be downloaded separately from `needs:`.
Q4. Diagnose why a deploy runs without the package it is supposed to deploy.
Team K: `build`, `package`, `deploy` jobs. `deploy` has no `needs:` but runs `actions/download-artifact` to fetch the package from `package`. Pipeline is green but deploy sometimes installs stale or missing package.
Passing score: 75%. Answers are checked in this browser.