{{ message }}
Repository navigation
Filter matrix expressions from runner label warnings - #59
Merged
nodeselector merged 3 commits intoJun 16, 2026
Merged
Conversation
Expressions like ${{ matrix.os }} can't be passed as literal runner
labels. Strip them from extractBracketedLabels so the remediation hint
only shows actionable labels. When all labels are expressions, the
generic <label> placeholder is shown instead.
Workflows where runs-on is a template expression (e.g. ${{ matrix.os }})
were lumped into the self-hosted-runner bucket. The user couldn't tell
whether a workflow was skipped because it uses a custom runner vs.
because runs-on is a dynamic expression that might resolve to a hosted
runner at runtime.
New ExpressionRunner category with distinct terminal output:
! 2 workflows skipped — runs-on uses expressions that can't be resolved statically
↳ ci.yaml, maccloud-unified.yml
↳ if the matrix resolves to hosted runners, pin these workflows manually
The self-hosted-runner warning now only shows literal non-hosted labels
and the --allow-runners hint no longer includes raw ${{ }} expressions.
There was a problem hiding this comment.
⚠️ Not ready to approve
ExpressionRunner findings are not fully integrated into validity/actionability logic, which can make expression-only workflows incorrectly fail validation and be treated as needing pin-planning attention.
Pull request overview
This PR improves runner-label diagnostics by separating dynamic runs-on template expressions (e.g. ${{ matrix.os }}) from literal non-hosted runner labels, keeping --allow-runners guidance actionable and less confusing.
Changes:
- Split non-hosted runner labels into expression vs literal labels during diagnosis, emitting a new
ExpressionRunnercategory for expression-only cases. - Update terminal rendering to (a) filter expressions out of
--allow-runnershints and (b) show a dedicated “expression-runner” skipped-workflow warning with distinct guidance. - Suppress
expression-runnerwarnings from JSON output (same treatment as other informational skip warnings) and extend warning classification to recognize the new category.
File summaries
Copilot's findings
- Files reviewed: 6/6 changed files
- Comments generated: 4
Note
Your feedback helps us improve the quality of this feature.
Please use 👍 or 👎 to tell us whether this assessment is correct.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
- Use "${" instead of "${{" in diagnose.go and isExpression() to
match the parser's expression detection in runson.go:132
- Add ExpressionRunner to IsValid() and NeedsAttention() skip lists so
expression-only workflows don't cause non-zero exit or trigger pin
planning
- Key IsWarning() off Severity (matching LocalAction/SelfHostedRunner)
so future error elevation works correctly
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.

When
runs-onuses a template expression like${{ matrix.os }}, the toolpreviously lumped it into the self-hosted-runner bucket. This was confusing:
the
--allow-runnershint would print raw${{ matrix.os }}as a label topass, and users couldn't tell whether a workflow was skipped because it uses
a real custom runner vs. a dynamic expression that might resolve to a hosted
runner at runtime.
Changes:
extractBracketedLabelsnow filters out${{ }}expressions so the--allow-runnershint only shows actionable literal labelsExpressionRunnercategory splits expression-basedruns-oninto itsown warning with distinct messaging and guidance:
treatment as local-action and self-hosted-runner)
IsWarning()extended to recognize the new categoryThe self-hosted-runner warning is now reserved for literal non-hosted labels
only, keeping the
--allow-runnersremediation hint clean and actionable.