Условия 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
Поддержать проект