Skip to content

dependabot-automerge: workflow_dispatch fails — number-typed pull-request-number rejects string dispatch input #382

Description

@leynos

Summary

The workflow_dispatch re-trigger path for dependabot-automerge.yml fails at
workflow-file validation — no job is ever created — because the reusable
workflow's pull-request-number input is typed number, but a
workflow_dispatch input is delivered to the with: block as a string.
GitHub rejects the string→number reusable-input assignment with the generic
"This run likely failed because of a workflow file issue", so manual dispatch
can never succeed as currently written.

The pull_request_target path is unaffected, because
github.event.pull_request.number is a genuine number.

Reproduction

A caller wires the reusable workflow like this (the documented pattern):

on:
  pull_request_target:
    types: [opened, reopened, synchronize, labeled, ready_for_review]
  workflow_dispatch:
    inputs:
      pull-request-number:
        type: number
        required: true

jobs:
  automerge:
    if: ${{ github.event_name == 'workflow_dispatch' || github.actor == 'dependabot[bot]' }}
    uses: leynos/shared-actions/.github/workflows/dependabot-automerge.yml@<sha>
    with:
      pull-request-number: ${{ inputs.pull-request-number || github.event.pull_request.number }}

Triggering via workflow_dispatch (e.g. gh workflow run dependabot-automerge.yml -f pull-request-number=404)
produces a run that fails immediately with no jobs:

Root cause

In .github/workflows/dependabot-automerge.yml the input is declared:

on:
  workflow_call:
    inputs:
      pull-request-number:
        type: number
        required: false

workflow_dispatch inputs — even those declared type: number in the caller —
arrive as strings when referenced in expressions and passed through with:.
Passing that string to a number-typed workflow_call input fails reusable-
workflow input validation before the run starts. The || coalescing does not
help: the dispatch branch is still a string.

Suggested fix

Preferred — make the reusable input accept a string and coerce/validate
internally:

    inputs:
      pull-request-number:
        type: string      # was: number
        required: false

The workflow already resolves the PR number via the GitHub API; treating it as
a string end-to-end (and validating it is numeric where needed) removes the
mismatch for every caller without requiring caller changes.

Alternative — leave the input as number and document that callers must coerce
on the dispatch branch, e.g.
pull-request-number: ${{ github.event.pull_request.number || fromJSON(inputs.pull-request-number) }}.
This pushes a sharp edge onto every caller and is easy to get wrong, so the
reusable-side change is preferred.

Impact / why it matters

When a Dependabot PR misses the required label at creation time (e.g. labels did
not yet exist on the repo's first Dependabot run), the intended remediation is to
label the PR and re-trigger auto-merge via workflow_dispatch — which is exactly
what the pull-request-number input exists for. Because that path is broken,
operators currently have to fall back to @dependabot rebase or enabling
auto-merge by hand.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workinghighHigh criticality issuetesting

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions