GitHub Actions убрал Node 20 и отключает старые раннеры: что проверить

23 сентября GitHub окончательно убрал Node 20 из раннеров GitHub Actions. JavaScript-экшены теперь выполняются на Node 24, а временный выключатель ACTIONS_ALLOW_USE_UNSECURE_NODE_VERSION, которым можно было вернуть Node 20, больше не работает. Через шесть дней, 29 сентября, на GitHub Enterprise Cloud включилась полная проверка версий self-hosted раннеров.
Две новости за неделю, и обе ломают тихо.
Что происходит с node20-экшенами
Экшен, у которого в action.yml указано runs.using: node20, не отклоняется. Раннер принудительно запускает его на Node 24 и в конце джобы добавляет предупреждение со списком таких экшенов. Экшены на node12 и node16 сначала приравниваются к node20, так что тоже уезжают на Node 24.
Если экшен на Node 24 работает, вы получаете жёлтую аннотацию и зелёную джобу. Если нет — шаг падает, и вернуть Node 20 уже нечем.
Между Node 20 и Node 24 две мажорные версии. В Node 24 удалены, например, tls.createSecurePair и свойство path у fs.Dirent, а url.parse() получил runtime deprecation. Заденет ли это конкретный экшен, зависит от его кода и зависимостей. Пока экшен не прогнали на Node 24, считайте его непротестированным.
Где прячутся node20
Плавающий мажорный тег не спасает. На 1 октября node20 всё ещё объявляли:
actions/checkout@v4— Node 24 начинается сv5;actions/setup-node@v4— тоже сv5;actions/cache@v4— тоже сv5;actions/upload-artifact@v4и@v5— Node 24 только сv6.
upload-artifact показателен: новый мажор ещё не значит новый рантайм. Проверять надо сам action.yml на нужном теге, его можно открыть прямо в репозитории экшена на GitHub.
Пин по SHA — хорошая практика для supply chain, и он же замораживает рантайм навсегда. Хуже всего вложенные пины. Если чужой composite-экшен внутри своего action.yml пинит node20-экшен, Dependabot в вашем репозитории это не починит: пин живёт в репозитории, который вам не принадлежит.
Быстрее всего проблемные экшены находятся по аннотациям. В сводке джобы будет жёлтое предупреждение «Node.js 20 is deprecated» со списком экшенов, принудительно запущенных на Node 24. Но так видно только то, что недавно запускалось. Релизный workflow, который гоняют раз в квартал, всплывёт, когда упадёт.
Раннеры: вторая волна
29 сентября на Enterprise Cloud заработала полная проверка версий self-hosted раннеров. Изначально её объявляли на 25 сентября, потом дату сдвинули.
Требований два. Раннер ниже 2.329.0 не сможет зарегистрироваться или перерегистрироваться. А уже зарегистрированный раннер ниже минимальной версии для выполнения джоб перестанет их получать, и эта планка выше регистрационной.
Вторая планка едет вперёд. Каждый новый релиз раннера нужно поставить в течение 30 дней после выхода, иначе Actions перестаёт ставить на него джобы. Раннер, зафиксированный на 2.329.0, джобы получать перестанет. А при выходе критического security-обновления очередь на раннер встаёт на паузу, пока его не установят.
Диагностируется это плохо: машина жива, сервис раннера запущен, а workflow висит в очереди или падает.
Грабли
Auto-update закрывает 30-дневное требование, только если раннер может достучаться до сервиса обновлений. Раннер в закрытом контуре, за прокси без нужного доступа или с выключенным auto-update придётся обновлять руками, и регулярно.
Раннеры из старых образов VM, контейнеров и шаблонов после пересоздания поднимутся со старой версией. GitHub прямо советует обновить установочные скрипты и образы, а не только живые машины.
Node 24 несовместим с macOS 13.4 и старше и официально не поддерживает ARM32. Self-hosted раннеры на таких системах больше не поддерживаются, и решения на уровне Node для них нет: только arm64 или более новый macOS. Метки раннера тут не помогут — по документации GitHub не проверяет, что метки вроде x64 соответствуют реальной ОС и архитектуре.
Как проверить
Для экшенов: аннотации последних джоб и runs.using в action.yml каждой используемой версии, включая экшены, которые вызываются внутри composite.
Для раннеров: версия отдаётся в REST API по self-hosted раннерам. С 3 сентября есть отдельный эндпоинт GET /actions/runners/deprecations/{version}. Он возвращает для версии даты, когда закончатся регистрация и выполнение джоб, и на нём удобно строить алерты. Владельцы Enterprise Cloud могут посмотреть события регистрации в audit log: org.register_self_hosted_runner, repo.register_self_hosted_runner, enterprise.register_self_hosted_runner.
Кого касается
Удаление Node 20 — github.com и GitHub с Data Residency. Проверка версий раннеров по графику включилась на Enterprise Cloud, а на Enterprise Cloud with Data Residency действует с 31 июля. GitHub Enterprise Server проверка версий раннеров не затрагивает, а в объявлении об удалении Node 20 он не упомянут.
Если workflow сейчас зелёные, откройте аннотации последних запусков. Экшены из предупреждения про Node 20 обновите до мажора на node24 сейчас, пока джоба ещё проходит: когда первый из них упадёт, откатиться будет некуда. Self-hosted раннеры с выключенным auto-update поставьте в календарь на ежемесячное обновление — 30 дней теперь жёсткий срок.
Источники: удаление Node 20, график проверки версий раннеров
KioskNews shows a cleaned-up reading view extracted from the publisher’s page — the original always lives on their site, not ours.