Автоматизация процессов разработки с помощью GitHub Actions стала стандартом де-факто для современных проектов. Однако по мере роста проекта количество файлов конфигурации в директории .github/workflows увеличивается, а код внутри них начинает дублироваться. Чтобы избежать хаоса и следовать принципу DRY (Don’t Repeat Yourself), GitHub предлагает мощный инструмент — Reusable Workflows (переиспользуемые рабочие процессы).
В этой статье мы разберем, как работают Reusable Workflows, как организовать взаимодействие между различными сценариями и как передавать данные между ними, даже если они находятся в разных репозиториях.
Что такое Reusable Workflows?
Reusable Workflows — это возможность определить рабочий процесс в одном YAML-файле и вызывать его из других workflows. Это превращает ваши сценарии автоматизации в модульные компоненты или шаблоны.
Ключевые преимущества:
- Централизованное управление: Измените код в одном месте, и он обновится во всех проектах, которые его используют.
- Чистота кода: Основные файлы сценариев становятся короче и понятнее.
- Безопасность: Вы можете вынести сложные проверки безопасности в отдельный шаблон, к которому у разработчиков будет доступ только на чтение.
Создание переиспользуемого workflow
Чтобы сделать workflow переиспользуемым, необходимо использовать специальный триггер — workflow_call. Именно он сообщает GitHub, что данный сценарий может быть вызван извне.
Пример структуры (reusable-template.yml):
name: Reusable Workflow Pattern
on:
workflow_call:
inputs:
title:
description: 'Заголовок для вывода в лог'
required: true
type: string
default: 'Default Title'
secrets:
API_TOKEN:
description: 'Секретный токен приложения'
required: false
jobs:
log-data:
runs-on: ubuntu-latest
steps:
- name: Print Input Title
run: echo "Переданный заголовок: ${{ inputs.title }}"
Обратите внимание, что мы можем гибко настраивать входные параметры (inputs) и секреты (secrets), указывая их типы и обязательность.
Как вызвать переиспользуемый workflow
Вызов осуществляется с помощью ключевого слова uses. Путь к файлу зависит от того, где находится шаблон.
1. В рамках одного репозитория
Если шаблон лежит в той же папке .github/workflows, путь указывается от корня:
jobs:
call-local:
uses: ./.github/workflows/reusable-template.yml
with:
title: 'Мой кастомный заголовок'
2. Из внешнего репозитория
Это киллер-фича для организаций. Вы можете создать один репозиторий (например, org-name/shared-workflows) и подключать шаблоны во все проекты компании.
jobs:
call-external:
uses: your-login/repository-name/.github/workflows/reusable-template.yml@main
with:
title: 'Внешний вызов'
secrets:
API_TOKEN: ${{ secrets.GLOBAL_TOKEN }}
Взаимодействие и передача данных (Outputs)
Часто недостаточно просто запустить скрипт — нужно получить результат его работы. Reusable Workflows позволяют возвращать данные (outputs) обратно в вызывающий сценарий.
Цепочка передачи данных:
- На уровне шага (Step): Создаем переменную и записываем её в файл
$GITHUB_OUTPUT. - На уровне задачи (Job): Прокидываем output шага в output всей задачи.
- На уровне Workflow: Описываем выходные параметры в блоке
workflow_call.
Пример возврата даты в шаблоне:
on:
workflow_call:
outputs:
generated-date:
description: "Дата генерации"
value: ${{ jobs.generate.outputs.date }}
jobs:
generate:
runs-on: ubuntu-latest
outputs:
date: ${{ steps.set-date.outputs.current_date }}
steps:
- id: set-date
run: echo "current_date=$(date)" >> $GITHUB_OUTPUT
Теперь в основном workflow вы сможете обратиться к этому значению через контекст needs.
Особенности работы с контекстом и файлами
Важно понимать, что когда вы вызываете Reusable Workflow, он выполняется в контексте вызывающего репозитория.
- Файловая система: Если вы используете
actions/checkoutвнутри переиспользуемого workflow, он скачает файлы того репозитория, который сделал вызов, а не того, где лежит сам шаблон. - Секреты: Секреты должны быть явно переданы из вызывающего workflow, либо использовано ключевое слово
secrets: inheritдля автоматической передачи всех доступных секретов.
Заключение
Использование Reusable Workflows — это переход на новый уровень владения CI/CD. Это позволяет создавать масштабируемую инфраструктуру, которую легко поддерживать. Начните с выноса часто повторяющихся задач (сборка Docker-образа, деплой на стейджинг, запуск линтеров) в отдельные шаблоны, и вы заметите, насколько проще станет управлять вашими GitHub Actions.

