Условия if и зависимости needs
Выстраиваем граф jobs и включаем шаги только тогда, когда нужно.
needsзадаёт зависимости между jobs (порядок и граф), аifвключает или выключает job/step по условию.
needs: из параллели в последовательность
По умолчанию jobs параллельны. needs заставляет один job ждать другой:
jobs:
test:
runs-on: ubuntu-latest
steps:
- run: echo "тесты"
build:
needs: test # стартует только после успешного test
runs-on: ubuntu-latest
steps:
- run: echo "сборка"
deploy:
needs: build # после build
runs-on: ubuntu-latest
steps:
- run: echo "деплой"
Получается конвейер test → build → deploy. Если test упал, зависимые jobs не запускаются. needs может ссылаться и на несколько jobs: needs: [lint, test] — ждать оба.
if на уровне job
Деплоить хочется только из main, не из каждой ветки:
deploy:
needs: build
if: github.ref == 'refs/heads/main'
runs-on: ubuntu-latest
steps:
- run: echo "Катим, потому что это main"
Если условие ложно, весь job помечается как skipped и не выполняется.
Статусные функции
Важная тонкость: если перед шагом другой шаг упал, по умолчанию последующие шаги пропускаются. Чтобы шаг выполнился несмотря на провал (например, отправить уведомление о падении), используют статусные функции:
success() | истина, если предыдущие шаги успешны (поведение по умолчанию) |
failure() | истина, если что-то ранее упало |
always() | истина всегда — шаг выполнится при любом исходе |
- name: Уведомить о падении
if: failure()
run: echo "Сборка упала, шлю алерт"
- name: Прибраться в любом случае
if: always()
run: echo "Чищу временные файлы"
Комбинирование условий
Условия можно объединять логикой: задеплоить только если всё прошло и это main —
if: success() && github.ref == 'refs/heads/main'
Итог
needsстроит граф jobs и делает их последовательными;needs: [a, b]ждёт несколько.ifна уровне job/step включает их по условию; иначе — skipped.failure()иalways()позволяют выполнять шаги даже после провала (уведомления, очистка).
Проверьте себя
1. Что делает ключ needs: test у job build?
AЗапускает build параллельно с test
BЗаставляет build ждать успешного завершения test
CКопирует файлы из test
DОтключает job test
2. Как сделать, чтобы шаг отправки уведомления выполнялся только при падении пайплайна?
Aif: success()
Bif: failure()
Cif: always()
DПросто поставить его последним
3. Что произойдёт с job, у которого условие if ложно?
AОн упадёт с ошибкой
BОн будет помечен как skipped и не выполнится
CОн выполнится с задержкой
DОн заблокирует весь workflow