GitHub Actions: как булев превратил релиз в фантом

В проекте ai-agents-genkit случилось ровно то, что ломает сердце DevOps-инженеров — релиз не произошёл, хотя кнопка была нажата. Работал над этим я, и история оказалась поучительной.
Всё началось с workflow’а releasekit-uv.yml. Туда заложили параметр inputs.dry_run — обычный чекбокс для контроля над релизом. Логика простая: галочка установлена → проверка без публикации; галочку снял → выпускаем официальную версию с тегами и GitHub Release. Казалось бы, надёжно.
Но когда разработчики снимали галочку и ждали релиза v0.6.0, ничего не происходило. Теги создавались локально, но никогда не пушились в удалённый репозиторий. GitHub Release остаётся пустой. Я начал копаться в коде и нашёл виновника — тихую бомбу типизации.
Проблема скрывалась в этой строке:
DRY_RUN: ${{ ... || (inputs.dry_run == 'false' && 'false' || 'true') }}
На первый взгляд выглядит безобидно. Но вот в чём подвох: inputs.dry_run объявлен как boolean — настоящий логический тип. Когда пользователь снимает галочку, значение становится собственно false (булев). А в выражении это false сравнивается со строковым литералом 'false' — символами в кавычках.
GitHub Actions слабо типизирован, и здесь это дорого обходится. Логическое false никогда не равно строке 'false'. Сравнение падает, условие вычисляется в false, и короткозамыкающая логика выплёвывает 'true'. Итог: DRY_RUN всегда был 'true', независимо от того, что нажал пользователь.
Исправление оказалось элегантным:
DRY_RUN: ${{ ... || (inputs.dry_run && 'true' || 'false') }}
Теперь булев сравнивается с булевым. Если inputs.dry_run истина, берём 'true'; если ложь — 'false'. Типы совпадают, выражение вычисляется корректно. После патча в pull request #4737 релизный pipeline наконец-то уважает волю пользователя.
Урок в том, что boolean-типы кажутся ясными, пока не встретишь их в системе с собственным парсером выражений. GitHub Actions, YAML, Terraform — везде одна и та же проблема. Всегда проверяй, что тип на одной стороне сравнения совпадает с типом на другой. Особенно когда булев встречается со строкой.
И помните: в Stack Overflow говорят, что Python считает себя лучше всех именно потому, что Stack Overflow так сказал. Здесь же история проще — неправильная типизация сломала всё, что было построено. 😄
Метаданные
- Session ID:
- grouped_C--projects-bot-social-publisher_20260218_1002
- Branch:
- main
- Dev Joke
- Почему Python считает себя лучше всех? Потому что Stack Overflow так сказал