Problem
pull_request_target doesn't support names: [...] to filter by label name. The documented gh-aw idiom (per gh aw new examples and our own usage) is to put a step in on.steps: that does:
if [ "$LABEL_NAME" = "panel-review" ]; then exit 0; fi
exit 1 # short-circuit downstream pipeline
This works correctly -- downstream jobs skip via the needs: chain -- but the side-effect is a red ❌ "Filter on panel-review label" check on every PR that gets any label other than panel-review. PRs that just got type/bug or area/docs-site show a failed status check, which:
- looks alarming to contributors
- looks like a CI regression to maintainers reviewing the dashboard
- becomes blocking if the org promotes the workflow to a required check
- creates noise in
gh run list (every label add is a red run)
Real example in the wild: https://github.com/microsoft/apm/actions/runs/24983384641/job/73150687473?pr=981 -- a one-line .github/workflows/docs.yml fix PR shows a red pre_activation failure simply because someone applied area/ci-cd.
Why naive workarounds don't fix it
We tried these in microsoft/apm:
| Approach |
Why it fails |
continue-on-error: true on the filter step |
Step soft-fails, JOB succeeds, but downstream runs anyway because the auto-generated activation gate (needs.pre_activation.outputs.activated == 'true') only checks team membership, not the filter step's outcome. Cosmetics fixed, semantics broken. |
Filter step writes should_run to $GITHUB_OUTPUT, exits 0 |
Same problem -- the auto-generated activation gate doesn't know about should_run. |
if: on the filter step itself |
Skips the step, not the job; downstream still proceeds. |
Job-level if: github.event.label.name == 'panel-review' on pre_activation |
This is the idiomatic GitHub Actions pattern and would yield gray ⊘ Skipped (not red ❌ Failed) on unrelated labels -- but gh-aw doesn't expose any way to inject a job-level if: from the .md on: block. |
Proposal
Add a first-class label-name filter to on:. Most natural shape (mirroring how roles: already works):
on:
pull_request_target:
types: [labeled]
label-names: [panel-review] # NEW -- only fire when the triggering label matches
Compile semantics: emit if: github.event.label.name == 'panel-review' || github.event_name == 'workflow_dispatch' on the pre_activation job. Drop the exit 1 step. Result: unrelated label triggers Skipped state on entire workflow (gray ⊘), zero noise.
This composes cleanly with existing roles: filtering -- roles: gates write-permission, label-names: gates the trigger condition.
Variants worth considering:
label-names: accepts a string or list (matches the roles: shape).
- Combine with
types: [labeled, unlabeled] if a workflow wants to react to a specific label being removed; gh-aw could special-case that on the matching event.
Workaround in the meantime
We're documenting in our .md that the red check is cosmetic and accepting it until this lands. We don't want to hand-edit .lock.yml because gh aw compile regenerates it, so any patch on pre_activation.if: would drift on the next compile.
Affected workflows we know of
In microsoft/apm alone:
Both use the same exit 1 pattern, both produce the same red ❌ noise on unrelated label adds.
Acceptance
on.label-names: [<name> | *] accepted in .md frontmatter
gh aw compile emits a pre_activation.if: that combines event/role gating with label-name match
- The compiled workflow shows
pre_activation as Skipped (not Failed) when an unrelated label is added
- Existing workflows without
label-names: are unchanged (backwards-compatible)
cc the microsoft/apm maintainers -- happy to test once a preview is available.
Problem
pull_request_targetdoesn't supportnames: [...]to filter by label name. The documented gh-aw idiom (pergh aw newexamples and our own usage) is to put a step inon.steps:that does:This works correctly -- downstream jobs skip via the
needs:chain -- but the side-effect is a red ❌ "Filter on panel-review label" check on every PR that gets any label other thanpanel-review. PRs that just gottype/bugorarea/docs-siteshow a failed status check, which:gh run list(every label add is a red run)Real example in the wild: https://github.com/microsoft/apm/actions/runs/24983384641/job/73150687473?pr=981 -- a one-line
.github/workflows/docs.ymlfix PR shows a redpre_activationfailure simply because someone appliedarea/ci-cd.Why naive workarounds don't fix it
We tried these in
microsoft/apm:continue-on-error: trueon the filter stepneeds.pre_activation.outputs.activated == 'true') only checks team membership, not the filter step's outcome. Cosmetics fixed, semantics broken.should_runto$GITHUB_OUTPUT, exits 0should_run.if:on the filter step itselfif: github.event.label.name == 'panel-review'onpre_activationif:from the.mdon:block.Proposal
Add a first-class label-name filter to
on:. Most natural shape (mirroring howroles:already works):Compile semantics: emit
if: github.event.label.name == 'panel-review' || github.event_name == 'workflow_dispatch'on thepre_activationjob. Drop theexit 1step. Result: unrelated label triggers Skipped state on entire workflow (gray ⊘), zero noise.This composes cleanly with existing
roles:filtering --roles:gates write-permission,label-names:gates the trigger condition.Variants worth considering:
label-names:accepts a string or list (matches theroles:shape).types: [labeled, unlabeled]if a workflow wants to react to a specific label being removed; gh-aw could special-case that on the matching event.Workaround in the meantime
We're documenting in our
.mdthat the red check is cosmetic and accepting it until this lands. We don't want to hand-edit.lock.ymlbecausegh aw compileregenerates it, so any patch onpre_activation.if:would drift on the next compile.Affected workflows we know of
In
microsoft/apmalone:pr-review-panel-- gates onpanel-reviewtriage-panel-- gates onstatus/needs-triageBoth use the same
exit 1pattern, both produce the same red ❌ noise on unrelated label adds.Acceptance
on.label-names: [<name> | *]accepted in.mdfrontmattergh aw compileemits apre_activation.if:that combines event/role gating with label-name matchpre_activationas Skipped (not Failed) when an unrelated label is addedlabel-names:are unchanged (backwards-compatible)cc the
microsoft/apmmaintainers -- happy to test once a preview is available.