Status check - сигнал от внешней системы про состояние коммита или PR. Источники checks:
- GitHub Actions - встроенная CI/CD, runs становятся checks автоматически.
- External CI через Commit Status API: CircleCI, Jenkins, Travis, и др. Они пушат статус через API.
- GitHub Apps -плагины маркетплейса: code coverage, security scanning, license compliance.
Каждый check имеет:
name- имя, отображается на PR.status: queued / in_progress / completed.conclusion(если completed): success / failure / cancelled / skipped / timed_out / action_required / neutral.
На странице PR check'и видны в нижней секции «Checks». Зелёная галка -conclusion success. Красный крестик -failure. Жёлтый кружок - in_progress.
Required checks
В branch-protection выбираешь конкретные check-имена, без которых merge запрещён. Это и есть «required checks».
GitHub узнаёт о доступных именах из недавних runs репо. Чтобы сделать check required, он должен хотя бы раз отработать на каком-то PR. Сначала пушишь workflow, ждёшь первый run, потом в Settings -> Branches -> Edit -> Status checks выбираешь его из списка.
Подводные камни
- Переименовал workflow / job -старое имя осталось required.
GitHub держит required-list по строковому имени. Если ты в
.github/workflows/ci.ymlпоменялname: buildнаname: build-and-test, в branch protection старое «build» становится «failing» (ничего не отрабатывает с таким именем). Зайди в protection, удали старое, добавь новое. - External CI не пушит статус -merge заблокирован навсегда. Если интеграция сломалась, нужно либо починить интеграцию, либо временно убрать check из required.
- Required не значит «прошёл недавно». GitHub считает check выполненным, если последний commit в PR имеет успешный run с таким именем. Если ты сделал force-push без commit'а -старый run может остаться актуальным.
- Status API vs Checks API. Это два разных GitHub API, оба создают то, что видно как «check». Старые external CI часто через Status API, новые - через Checks API. На UI разницы нет.
Что делать с flaky checks
Если check иногда падает не по делу (flaky), не ставь его в required. Required check должен быть детерминированным. Альтернатива:
- Retry в самом workflow через
if: failure()+ повторный шаг. - Ручной retry:
gh run rerun --failed. - Убрать из required, оставить как «информационный».
Required check - это контракт «без меня нельзя смерджить». Контракт работает только если check честный.
Что делать, когда required check не нужен на этом PR
Иногда workflow не запускается для конкретного PR (например, PR только в docs/, а required check - test suite, которому делать на docs нечего). Решения:
- Path filters в workflow.
on.pull_request.paths: ['src/**']-workflow не запускается на docs-only PR. - «Required» + path-filtered = проблема: required check не запустился, merge заблокирован.
Стандартное решение: добавить «skip job»: workflow срабатывает
всегда, но первое условие if пропускает работу на docs-only.
Job завершается с success. Required удовлетворён, реальной работы
не делалось.