diff --git a/.forgejo/workflows/build.yml b/.forgejo/workflows/build.yml index cb3a60b..85bd033 100644 --- a/.forgejo/workflows/build.yml +++ b/.forgejo/workflows/build.yml @@ -89,12 +89,30 @@ on: # makes the milestone-362 gate verifiable at all: a gate has to be watched # rejecting something before anyone can believe it is wired up. # -# Note this is a STRING comparison, not a boolean. Forgejo delivers -# workflow_dispatch inputs as strings, so `inputs.refresh` is 'true'/'false' -# and `&&` on it would treat the string 'false' as truthy. +# The input is normalised through `format()` before it is compared, and that +# is not defensive styling — the direct comparison is WRONG and fails silently. +# +# `type: boolean` delivers a real boolean, and GitHub expression semantics cast +# operands to numbers when their types differ: `true == 'true'` compares 1 +# against NaN and is FALSE. Measured on run 5270, whose own log says it — +# +# expression '(github.event_name == 'schedule' +# || github.event.inputs.refresh == 'true') && 'true' || 'false'' +# evaluated to '%!t(string=false)' +# trigger: raw inputs refresh='true' +# +# — the input arrived as `true` and the expression still said false. The run +# then went green with every step skipped, because a refresh that evaluates +# false behaves exactly like an ordinary push. That is the whole hazard: the +# failure has no symptom. +# +# `force_build` never hit this because it never compares in an expression. It +# passes the raw value into an env var and tests it in the shell, where +# everything is already a string. `format('{0}', x)` buys the same thing here, +# where a step-level `if:` needs the answer before any shell runs. env: - IS_REFRESH: ${{ (github.event_name == 'schedule' || github.event.inputs.refresh == 'true') && 'true' || 'false' }} - BUILD_REF: ${{ (github.event_name == 'schedule' || github.event.inputs.refresh == 'true') && 'main' || github.ref }} + IS_REFRESH: ${{ (github.event_name == 'schedule' || format('{0}', github.event.inputs.refresh) == 'true') && 'true' || 'false' }} + BUILD_REF: ${{ (github.event_name == 'schedule' || format('{0}', github.event.inputs.refresh) == 'true') && 'main' || github.ref }} # Requires repo secret RELEASE_TOKEN — a Forgejo PAT with scopes: # - write:package, read:package (for docker push to git.fabledsword.com)