Skip to content

fix(workflows): add workflow_dispatch to pr-labels-ci.yml to prime workflow_run listener#24

Merged
cmeans-claude-dev[bot] merged 1 commit into
mainfrom
fix/pr-labels-ci-workflow-dispatch
Apr 20, 2026
Merged

fix(workflows): add workflow_dispatch to pr-labels-ci.yml to prime workflow_run listener#24
cmeans-claude-dev[bot] merged 1 commit into
mainfrom
fix/pr-labels-ci-workflow-dispatch

Conversation

@cmeans-claude-dev
Copy link
Copy Markdown
Contributor

@cmeans-claude-dev cmeans-claude-dev Bot commented Apr 20, 2026

Summary

Every PR opened on this repo since PR #19 merged has stuck at Awaiting CI and needed the Dev Active toggle workaround to promote. This PR is the real fix.

Diagnosis

pr-labels-ci.yml landed on main via PR #19 (workflow introduction) on 2026-04-20 at 02:15 UTC. Since then, zero event=workflow_run runs have been dispatched to it. All three runs in its history are event=push with conclusion=failure (startup failure on workflow files that don't declare a push trigger — GitHub validates on every push that touches the repo).

Corroborating symptom: gh api repos/.../actions/workflows | jq '.workflows[]' reports the workflow's name as .github/workflows/pr-labels-ci.yml (the file path), not the declared "PR Label Automation (CI)". That's consistent with the file never having been successfully parsed into the workflow catalogue. And the workflow_run dispatcher seems to route events by parsed metadata — so if the file isn't parsed, the listener doesn't receive dispatches.

mcp-clipboard's version of the same file works fine. The difference is just history: mcp-clipboard's file has had successful event=workflow_run runs since at least 2026-04-16, which registered it correctly.

Fix

Add a workflow_dispatch: trigger to the on: block of pr-labels-ci.yml. Manually running the workflow once after merge produces a clean "successful skipped" run:

  • workflow_dispatch satisfies the workflow's trigger.
  • Both jobs have if: guards that reference github.event.workflow_run.*. On a workflow_dispatch event, those fields don't exist, so the conditions evaluate to false and the jobs skip cleanly.
  • The successful run registers the file in GitHub's workflow catalogue.
  • From then on, workflow_run dispatches fire normally on CI completions.

Nothing in the existing logic changes. The only functional surface added is the manual-run capability.

Post-merge action required

After merge, go to the repo's Actions tab → PR Label Automation (CI)Run workflow → select mainRun workflow. Should complete in ~10 seconds with both jobs skipped. Next PR after that should auto-promote Awaiting CIReady for QA on CI pass without the Dev Active toggle.

I can run this via the API, but my bot token doesn't have Actions: write permission on this repo — last time we tested it returned Resource not accessible by integration. Either the maintainer runs it, or the App's permissions get updated (separate decision).

Cascade

cmeans/mcp-clipboard's pr-labels-ci.yml is already registered and working — it doesn't need this fix to function. However, propagating workflow_dispatch there preserves the verbatim-from-mcp-clipboard contract and gives the same manual-debugging handle that's useful when investigating label automation issues.

Recommendation: cascade to mcp-clipboard as a follow-up PR once this one's merged and validated. If you'd rather let yt-dont-recommend diverge intentionally (different history, different needs), that's also defensible — just note it.

Test plan (QA)

  • yaml.safe_load on .github/workflows/pr-labels-ci.yml — clean parse
  • Diff against cmeans/mcp-clipboard/.github/workflows/pr-labels-ci.yml — only difference should be the new workflow_dispatch: line and the accompanying comment block
  • pytest tests/ / ruff check src/ tests/ still green (non-code change)
  • After merge: verify the first manual workflow_dispatch run completes successfully with both jobs skipped
  • Next PR after the seeding run auto-promotes to Ready for QA on CI success (no Dev Active toggle required)

Caveat

This PR is itself affected by the same bug. Expect it to stick at Awaiting CI after CI passes — I'll still need to do the Dev Active toggle to promote it. The fix only takes effect on subsequent PRs after the post-merge seeding run.

🤖 Generated with Claude Code

…rkflow_run listener

yt-dont-recommend's pr-labels-ci.yml has never received a workflow_run
event since PR #19 merged. Every run in its history is event=push with
conclusion=failure (startup). The GitHub API also reports the
workflow's name as the file path rather than the declared
"PR Label Automation (CI)" — consistent with the file never having
been successfully parsed into the workflow catalogue.

This is why every PR since #19 has stuck at "Awaiting CI" and needed
the Dev Active toggle workaround to promote to Ready for QA — the
on-ci-pass job is never dispatched.

Fix: add a workflow_dispatch trigger. When the maintainer runs the
workflow manually once (Actions -> Run workflow), the existing
if: guards (which all reference github.event.workflow_run.*) don't
match, so both jobs skip cleanly — producing a successful run that
registers the file in GitHub's workflow catalogue. After that, the
workflow_run dispatcher fires on CI completions and the promotion
works automatically.

Cascade: mcp-clipboard's pr-labels-ci.yml is already registered and
working correctly, so it doesn't need this fix to function — but
propagating workflow_dispatch there preserves the verbatim-from-
mcp-clipboard contract and gives the same debugging handle. Noted
in the PR body for the maintainer to decide.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@github-actions github-actions Bot added the Awaiting CI Dev complete, waiting for CI to pass before QA label Apr 20, 2026
@cmeans-claude-dev cmeans-claude-dev Bot added Dev Active Developer is actively working on this PR; QA should not start and removed Dev Active Developer is actively working on this PR; QA should not start labels Apr 20, 2026
@github-actions github-actions Bot added Ready for QA Dev work complete — QA can begin review and removed Awaiting CI Dev complete, waiting for CI to pass before QA labels Apr 20, 2026
@codecov-commenter
Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

Copy link
Copy Markdown
Owner

@cmeans cmeans left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM 🤞

@cmeans cmeans added the QA Active QA is actively reviewing; Dev should not push changes label Apr 20, 2026
@github-actions github-actions Bot removed the Ready for QA Dev work complete — QA can begin review label Apr 20, 2026
Copy link
Copy Markdown
Owner

@cmeans cmeans left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[QA] Review — zero findings, Ready for QA Signoff.

Verified in this session

Check Result
YAML parse of pr-labels-ci.yml Clean; on: block now carries both workflow_dispatch: (null value, standard GHA shape) and the existing workflow_run: trigger.
Diff vs cmeans/mcp-clipboard/.github/workflows/pr-labels-ci.yml Only adds: the 15-line comment block (lines 14–28) explaining seeding + debugging purposes, and the workflow_dispatch: line. Zero changes to any job, if: guard, env, or shell. Exactly what the PR body claims.
pytest tests/ 259/259 pass (non-code change).
ruff check src/ tests/ All checks passed!

Diagnosis independently confirmed via gh api

The repo's actions/workflows endpoint confirms the listener-registration failure exactly as Dev described:

  • pr-labels-ci.yml reports name = ".github/workflows/pr-labels-ci.yml" (file path). Its siblings correctly report declared names — pr-labels.ymlPR Label Automation, qa-gate.ymlQA Gate. The name-is-path symptom is diagnostic of a never-successfully-parsed workflow.
  • actions/workflows/pr-labels-ci.yml/runstotal_count=10; every entry is event=push conclusion=failure. Zero event=workflow_run runs since the file landed on main. The listener has genuinely never fired.

That matches Dev's claim verbatim and validates the workflow_dispatch prime as the correct fix.

if: guard behaviour on workflow_dispatch

Spot-checked: both jobs' if: conditions reference github.event.workflow_run.conclusion and github.event.workflow_run.event. On a workflow_dispatch event these context fields don't exist, so the == 'success' / == 'failure' comparisons evaluate to false and the jobs skip cleanly. The manual-run will be a successful-no-op exactly as Dev describes — no accidental logic execution.

Verdict

Applying Ready for QA Signoff. Zero findings in scope.

Post-merge action (for you)

  1. Actions tab → PR Label Automation (CI)Run workflow → branch mainRun workflow. Expect ~10s, both jobs skipped.
  2. Confirm actions/workflows now reports name = "PR Label Automation (CI)" instead of the file path — that's the registration proof.
  3. Next PR should auto-promote Awaiting CIReady for QA on CI pass without the Dev Active toggle.

Cascade

Filed cmeans/mcp-clipboard#89 to propagate workflow_dispatch there once this one's merged and validated. Classified nice-to-have (not blocking anything in mcp-clipboard today — its listener is already registered). Preserves the verbatim-from-mcp-clipboard contract and gives the same manual-debugging handle.

@cmeans cmeans added the Ready for QA Signoff QA passed — ready for maintainer final review and merge label Apr 20, 2026
@github-actions github-actions Bot removed the QA Active QA is actively reviewing; Dev should not push changes label Apr 20, 2026
@cmeans cmeans added QA Approved Manual QA testing completed and passed and removed Ready for QA Signoff QA passed — ready for maintainer final review and merge labels Apr 20, 2026
@cmeans-claude-dev cmeans-claude-dev Bot merged commit de55591 into main Apr 20, 2026
32 checks passed
@cmeans-claude-dev cmeans-claude-dev Bot deleted the fix/pr-labels-ci-workflow-dispatch branch April 20, 2026 16:17
cmeans-claude-dev Bot pushed a commit that referenced this pull request Apr 20, 2026
…un context

Attempting to seed the workflow via workflow_dispatch on main after PR
#24 merged failed with:

  Failed to queue workflow run: Invalid Argument - failed to parse
  workflow: (Line: 55, Col: 14): An expression was expected,
  (Line: 111, Col: 14): An expression was expected

Lines 55 and 111 are `run: |` in both jobs. The real problem is a few
lines earlier: the step-level env: references
`github.event.workflow_run.id` and `github.event.workflow_run.head_branch`,
which are absent when the workflow is triggered via workflow_dispatch
(or a validation push). GitHub evaluates step-level env: expressions
at queue time — before the job-level `if:` has a chance to skip the
job — so the missing context is fatal even though the logic would
skip cleanly.

This is also the likely explanation for the push-event startup
failures in this workflow's run history: every push GitHub validates
has been failing to resolve these env: expressions, which is what
prevented the file from being registered in the workflow catalogue
and made the workflow_run listener never fire.

Fix: add `|| ''` null-coalesce fallbacks to both env: expressions.
On workflow_run events (the happy path), the fallback is never
exercised — behaviour is unchanged. On workflow_dispatch and push
events, the env: assignments cleanly resolve to empty strings, the
job-level `if:` fails as designed, and the job skips — producing a
successful run that finally registers the file with GitHub.

Cascade: cmeans/mcp-clipboard should pick up the same fallbacks.
They don't exercise workflow_dispatch today, so the bug is latent
there, but the guard is strictly more defensive and preserves the
verbatim contract.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
cmeans-claude-dev Bot pushed a commit that referenced this pull request Apr 20, 2026
…actual bug)

Root cause for the workflow_dispatch parse failures that defeated PRs
#24, #25, #26, and #27: GitHub Actions substitutes '\${{ ... }}'
expressions inside run: blocks *before* the shell sees them, including
sequences inside shell comments. Three comments in this file contained
the literal string '\${{ }}' (empty expression). GHA's queue-time parser
tried to evaluate an empty expression and bailed with 'An expression was
expected', always pointing at 'run: |' (col 14) because that's the
parent scope.

Diagnostic that confirmed this: the reported line numbers shifted
between my earlier attempts (55/111 -> 53/126 after the jq
refactor). The error position is file-structure-dependent; col 14 is
always the '|' of 'run: |'. Meanwhile the literal '\${{ }}' was
identical across every version of the file since the security-hardening
cascade (mcp-clipboard#87), which is why every '|| X' fallback
experiment missed — the fallbacks were on the wrong expressions.

Fix: rewrite the three comments to describe the concept without the
literal '\${{ }}' characters. Zero logic change.

Why this only surfaced on workflow_dispatch (not on normal workflow_run
firings): the normal workflow_run code path apparently tolerates empty
expressions where the queue-time parser for workflow_dispatch does not.
mcp-clipboard has the same latent bug — it just never tripped it
because nobody dispatched manually.

Cascade: the same fix needs to land on cmeans/mcp-clipboard's file to
preserve verbatim parity and to unblock manual dispatch there as well.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
cmeans-claude-dev Bot added a commit to cmeans/mcp-clipboard that referenced this pull request Apr 20, 2026
…commend#24 (#93)

## Summary

Restores template parity for `pr-labels-ci.yml` with
`cmeans/yt-dont-recommend`, which diverged by adding a
`workflow_dispatch:` trigger in PR #24 (needed over there to prime the
`workflow_run` dispatcher after its fresh-repo cascade). The diff
applied here is verbatim from that upstream PR.

The new trigger has two purposes, documented inline in the file:

1. **Seeding** — in a fresh-repo cascade, the `workflow_run` dispatcher
doesn't always register until the workflow has produced at least one
non-startup-failure run. A manual dispatch produces a clean skipped run
and primes the dispatcher.
2. **Debugging** — gives maintainers a manual "Run workflow" button from
the Actions UI without having to piggyback on a real CI run.

**No-op on existing PRs.** Both jobs' `if:` guards require
`github.event.workflow_run.*`, which are absent on a `workflow_dispatch`
event, so a manual run always skips cleanly.

**Side benefit:** a manual dispatch now serves as direct confirmation
that the queue-time parser accepts this file. Prior to PR #92 landing
(removing the literal empty GHA expression from two shell comments), a
manual dispatch here would have failed with "An expression was expected"
— so this PR is the natural post-fix validation point.

Closes #89.

## Test plan

- [x] `yaml.safe_load` on the file — clean parse with both triggers
present (verified locally; confirms both `workflow_dispatch:` and
`workflow_run:` keys present).
- [x] CI (unchanged) runs green.
- [ ] Post-merge: Actions tab -> "PR Label Automation (CI)" -> "Run
workflow" -> main. Expected: clean queue, both jobs skip via `if:`
guards, run completes in a few seconds. This is the direct validation
that PR #92's fix works at the queue-time parser level.
- [ ] Subsequent PRs continue to auto-promote from `Awaiting CI` to
`Ready for QA` as before (no regression on the `workflow_run` path).

## Related

- Upstream template change: `cmeans/yt-dont-recommend#24`
- Prerequisite on this repo: #92 (removed the literal empty GHA
expression that would have made a manual dispatch fail)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: cmeans-claude-dev[bot] <3223881+cmeans-claude-dev[bot]@users.noreply.github.com>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
cmeans-claude-dev Bot added a commit that referenced this pull request Apr 22, 2026
…CI fix (#36)

Pre-release audit against `git log v0.4.2..main` surfaced three gaps in the
`[Unreleased]` section:

- No entry for PR #19 (QA workflow + PR label state machine) — a major
  infrastructure addition precedented by v0.4.2's Ruff entry.
- No entry for the #24-#28 `workflow_run` registration fix saga.
- The coverage push entry did not call out the `# pragma: no cover` sweep,
  which is a hard-rule policy for the project.

Adds an Added entry for #19, a Fixed entry for #24-#28, and tacks a sentence
onto the existing coverage entry. No code changes.

Co-authored-by: cmeans-claude-dev[bot] <3223881+cmeans-claude-dev[bot]@users.noreply.github.com>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@cmeans cmeans mentioned this pull request Apr 23, 2026
7 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

QA Approved Manual QA testing completed and passed

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants