In August a customer told us that our catalogue search went strange for most of an hour every time we released. Products vanished from results and came back. I checked the deploy history against our search latency and every manual deploy since May lined up with a full rebuild of the product index, forty minutes of it.
Our production deploy is a GitHub Actions workflow started by hand with workflow_dispatch. In May somebody added a boolean input, rebuild_index, shown on the run form as a checkbox, unticked by default, for the rare release that changes the index mapping. The step that rebuilds the index had the condition if: github.event.inputs.rebuild_index.
That condition was true on every run. GitHub passes manual inputs in two contexts. The inputs context keeps a boolean as a boolean. The older github.event.inputs carries the same values as strings, and the documentation says so. An unticked box arrives there as the text false. In an Actions expression the only falsy values are false, zero, null and the empty string, so a non empty string is truthy, including that one. The step ran, the log showed it running, and because it was meant to run sometimes, nobody reading a green deploy thought it odd.
It had been tested. The author ticked the box on a staging run and watched the rebuild happen. Nobody ran it unticked and checked that nothing happened, because nothing happening is not something you go looking for.
The condition now reads if: inputs.rebuild_index, which gets a real boolean. Anywhere we still compare strings, the comparison is written out, == 'true', so the intent is visible. Every manual run starts by writing its resolved inputs to the job summary, one line each, so the person who pressed the button sees what the workflow believed they asked for. The rebuild itself now writes into a new index and switches an alias when it finishes, so even a rebuild we did ask for no longer empties the search while it runs. And our workflow tests run each optional step both ways and assert that it is skipped when its input is off.
A checkbox is a boolean until it crosses into text. After that, false is just a word, and every word is true.
– Sergey Shinder







