From cb2cbe3ae1a96ab5f413af0c19288ebd245c9254 Mon Sep 17 00:00:00 2001 From: Joris Wouter Jonkers Date: Sat, 29 Aug 2026 22:59:00 +0200 Subject: [PATCH] fix(budget): pass the watchdog thresholds as numbers, not expressions The first dispatched run failed with zero jobs allocated. The callee declares allowance-minutes, warn-percent and critical-percent as 'type: number', and the caller forwarded them as "${{ inputs.x || N }}" -- an interpolated expression, which is a string. The caller is rejected before any job is created. That failure mode is worth naming: a zero-job run failing in seconds looks exactly like an exhausted Actions quota, which is the very condition this workflow exists to detect. A watchdog that dies in the shape of the outage it watches for is worse than no watchdog. The thresholds are now literal YAML numbers, and the dispatch inputs are gone -- their only purpose was to be forwarded. The values are easier to find where they are now anyway. Refs JorisJonkers-dev/github-workflows#126 --- .github/workflows/actions-budget-watchdog.yml | 29 +++++++------------ 1 file changed, 10 insertions(+), 19 deletions(-) diff --git a/.github/workflows/actions-budget-watchdog.yml b/.github/workflows/actions-budget-watchdog.yml index a5f0bbc..d221622 100644 --- a/.github/workflows/actions-budget-watchdog.yml +++ b/.github/workflows/actions-budget-watchdog.yml @@ -25,23 +25,12 @@ name: 'Actions Budget Watchdog' # deprioritises the congested boundaries first, and every schedule in this # estate that fires reliably sits off them. - cron: '41 */6 * * *' + # No inputs. The callee declares these as `type: number`, and forwarding a + # dispatch input through `${{ ... }}` yields a string, which the caller + # rejects before any job is created -- a zero-job run that reads exactly like + # an exhausted quota. The thresholds are set as literal YAML numbers below, + # where they are also easier to find. workflow_dispatch: - inputs: - allowance-minutes: - description: 'Included standard-runner minutes per month (GitHub Team is 3000).' - required: false - type: number - default: 3000 - warn-percent: - description: 'Warn at or above this percentage of the allowance.' - required: false - type: number - default: 70 - critical-percent: - description: 'Fail and raise the alert at or above this percentage.' - required: false - type: number - default: 85 permissions: contents: 'read' @@ -54,9 +43,11 @@ jobs: budget: uses: 'JorisJonkers-dev/github-workflows/.github/workflows/actions-budget-watchdog.yml@main' with: - allowance-minutes: "${{ inputs.allowance-minutes || 3000 }}" - warn-percent: "${{ inputs.warn-percent || 70 }}" - critical-percent: "${{ inputs.critical-percent || 85 }}" + # Literal numbers, not interpolated expressions: these inputs are + # `type: number` on the callee. + allowance-minutes: 3000 + warn-percent: 70 + critical-percent: 85 # The alert lands here rather than in the offending repo: the budget is # an org-level fact, and when it is exhausted the private repos are # exactly the ones that cannot run anything.