Repository navigation
Allow frontmatter to augment the needs list of any compiler-generated job #43918
Description
Proposal
Let workflow frontmatter explicitly augment the needs list of any compiler-generated job (pre_activation, activation, agent, detection, safe_outputs, conclusion, and any future generated jobs).
The compiler already accepts arbitrary job definitions under jobs:. The proposal is to also honor a needs property when the job name matches a generated job, merging it (additively, de-duplicated) into that job's computed needs:
jobs:
detection:
needs: [select_model]This gives workflow authors an explicit, per-job escape hatch instead of relying solely on the compiler's implicit scan of engine.env for needs.<job>.outputs.* references.
Motivation
The compiler decides each generated job's needs list on its own. When a workflow defines a custom job (via jobs: or an import) that a generated job must depend on, the only mechanism today is the implicit engine.env scan, and that scan has been implemented job-by-job with gaps that keep surfacing:
- Agent 'needs' does not incorporate jobs in engine.env expressions (#30232) -- fixed in #30239.
- Activation 'needs' does not incorporate jobs in engine.env expressions (#30790) -- open; the only workaround is the
on.permissions: {}coercion. - Threat detection 'needs' does not incorporate jobs in engine.env expressions (#43917) -- open; no known workaround.
An explicit, author-controlled needs augmentation would have unblocked all three regardless of whether the implicit scan covered that particular job.
How this would have provided a workaround for each
- Agent 'needs' does not incorporate jobs in engine.env expressions #30232 (agent):
jobs.agent.needs: [custom_job]would have added the dependency directly, unblocking the workflow before the Fix agent job needs not populated from engine.env needs expressions #30239 auto-fix landed. - Activation 'needs' does not incorporate jobs in engine.env expressions #30790 (activation):
jobs.activation.needs: [custom_job]would have added the dependency directly, avoiding the fragileon.permissions: {}coercion. - Threat detection 'needs' does not incorporate jobs in engine.env expressions #43917 (detection):
jobs.detection.needs: [select_model]would have added the dependency to the threat-detection job -- the case that currently has no workaround at all.
Relationship to on.needs (#30780)
Including on.needs for custom jobs results in invalid workflow (#30780) covers the existing on.needs property, which is a narrow, partial version of this idea: it only augments pre_activation/activation, and it is currently buggy (the on.needs value leaks into the compiled workflow, producing invalid YAML). This proposal generalizes the concept to every generated job with a clean per-job syntax and would supersede on.needs.
Current behavior
Today, specifying a generated job name under jobs: is silently ignored. For example, with:
jobs:
detection:
needs: [select_model]
select_model:
runs-on: ubuntu-slim
steps:
- id: pick
shell: bash
run: echo "model=claude-sonnet-4.6" >> "$GITHUB_OUTPUT"
outputs:
model: ${{ steps.pick.outputs.model }}the compiled detection job's needs remains [activation, agent] -- the select_model entry is dropped, with no error or warning.
Suggested semantics
- Additive merge: the frontmatter
needsis unioned with the compiler-computedneedsand de-duplicated; it never removes computed dependencies. - Validation: referenced jobs must exist (a custom job in
jobs:or an imported job); otherwise emit a compile error. - Reserved names: for generated job names, honor
needsaugmentation and reject (or clearly define behavior for) other properties, so authors do not accidentally believe they can redefine a generated job's steps. - Explicit over implicit: because the dependency is stated by the author, it is not subject to the substring false-match concern noted in Agent 'needs' does not incorporate jobs in engine.env expressions #30232 for the implicit
needs.<job>.scan.
Activity