Skip to content

Bug: workflow_dispatch item_number not wired into expression extraction for label trigger shorthand #19773

@deyaaeldeen

Description

@deyaaeldeen

Bug: workflow_dispatch item_number not wired into expression extraction

Summary

When the label trigger shorthand (e.g., on: pull_request labeled my-label) auto-generates a workflow_dispatch trigger with inputs.item_number, the compiler does NOT wire inputs.item_number as a fallback for entity number expressions like github.event.pull_request.number. This makes manual dispatch effectively broken — the prompt receives empty values for the PR/issue number.

Reproduction

  1. Create a workflow with label trigger shorthand:

    ---
    on: pull_request labeled architecture-review-needed
    ---
    Review pull request #\${{ github.event.pull_request.number }}
  2. Compile with gh aw compile

  3. In the compiled lock file, observe:

    • Expected: GH_AW_GITHUB_EVENT_PULL_REQUEST_NUMBER: \${{ github.event.pull_request.number || inputs.item_number }}
    • Actual: GH_AW_GITHUB_EVENT_PULL_REQUEST_NUMBER: \${{ github.event.pull_request.number }}
  4. Trigger via workflow_dispatch with item_number=42 → the prompt says "Review pull request #" (empty number)

Root Cause

The ExpressionExtractor in pkg/workflow/expression_extraction.go maps expressions 1:1 from markdown to env vars:

// expression_extraction.go — ExtractExpressions()
mapping := &ExpressionMapping{
    Original: originalExpr,
    EnvVar:   envVar,
    Content:  content,  // e.g. "github.event.pull_request.number"
}

Then env vars are emitted with the raw Content value in two places:

compiler_yaml_helpers.go:generatePlaceholderSubstitutionStep():

fmt.Fprintf(yaml, indent+"    %s: \${{ %s }}\n", mapping.EnvVar, content)
// Emits: GH_AW_GITHUB_EVENT_PULL_REQUEST_NUMBER: \${{ github.event.pull_request.number }}

template.go:generateInterpolationAndTemplateStep():

fmt.Fprintf(yaml, "          %s: \${{ %s }}\n", mapping.EnvVar, mapping.Content)
// Emits: GH_AW_GITHUB_EVENT_PULL_REQUEST_NUMBER: \${{ github.event.pull_request.number }}

There is no mechanism to enhance the Content with || inputs.item_number when a workflow_dispatch with item_number coexists with the entity trigger.

Affected Lines in Compiled Output

For a pull_request labeled shorthand workflow using \${{ github.event.pull_request.number }}:

Line Purpose Current Value Expected Value
Concurrency group Dedup concurrent runs github.event.pull_request.number || github.ref || github.run_id github.event.pull_request.number || inputs.item_number || github.ref || github.run_id
Interpolation env Prompt variable \${{ github.event.pull_request.number }} \${{ github.event.pull_request.number || inputs.item_number }}
Substitution env Placeholder substitution \${{ github.event.pull_request.number }} \${{ github.event.pull_request.number || inputs.item_number }}

Concurrency group impact: Falls back to github.ref (e.g., refs/heads/main), causing concurrent workflow_dispatch runs for different PRs to cancel each other.

Proposed Fix

Add a post-processing step after expression extraction in compiler_yaml.go (after filterExpressionsForActivation()):

// applyWorkflowDispatchFallbacks enhances entity number expressions with
// inputs.item_number fallback when the workflow has both an entity trigger
// and a workflow_dispatch with item_number input.
func applyWorkflowDispatchFallbacks(mappings []*ExpressionMapping, data *WorkflowData) {
    // Check if workflow_dispatch with item_number exists in the on: section
    if !hasWorkflowDispatchItemNumber(data) {
        return
    }
    
    // Map of entity number expressions to their enhanced versions
    fallbacks := map[string]string{
        "github.event.pull_request.number": "github.event.pull_request.number || inputs.item_number",
        "github.event.issue.number":        "github.event.issue.number || inputs.item_number",
        "github.event.discussion.number":   "github.event.discussion.number || inputs.item_number",
    }
    
    for _, mapping := range mappings {
        if enhanced, ok := fallbacks[mapping.Content]; ok {
            mapping.Content = enhanced
        }
    }
}

Also update the concurrency group generation to include inputs.item_number in the fallback chain when workflow_dispatch with item_number is present.

Impact

This affects all workflows using label trigger shorthand syntax:

  • on: pull_request labeled <label>
  • on: issue labeled <label>
  • on: discussion labeled <label>

Manual dispatch via the auto-generated workflow_dispatch is broken: the agent receives no item number, so it cannot find or interact with the target PR/issue/discussion.

Related

Metadata

Metadata

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions