Как создать условный рабочий процесс с расширенными действиями GitHub

Как создать условный рабочий процесс с расширенными действиями GitHub

20 апреля 2022 г.

Постановка задачи 🍀


GitHub Actions предоставляет возможность создавать автоматизированные рабочие нагрузки и конвейеры CI/CD. У меня есть 3 разные ветки: dev, beta и main. У них один и тот же процесс, который заключается в сборке, тестировании и развертывании моего приложения в Google Cloud App Engine. Более подробная информация была рассмотрена в моей статье о процессе развертывания с GitHub на Google Cloud App Engine.


В моем случае отличаются только конфигурации (секреты и переменные окружения). Поддерживать 3 разных рабочих процесса GitHub Actions, по одному для каждого, не рекомендуется из-за дублирования кода. С учетом сказанного, как я могу создать один рабочий процесс, который использует разные секреты на основе запущенной ветки?


Прежде чем мы начнем, если вы не знакомы с GitHub Actions, вы можете прочитать мою [введение в статью о компонентах GitHub Actions] (https://hungvu.tech/what-is-github-actions-a-not-so-eli5). -введение-в-2022) первым!


Ключевые моменты 🍀


Могу ли я заставить все 3 ветки запускать один и тот же рабочий процесс? 🔑


Да, для этой цели есть ключ «on».


``ямл


Название: Мой рабочий процесс


Определите, какое действие запускает рабочий процесс


на:


Название действия


толкать:


Фильтруем, определяем, какая ветка запускает действие


Я хочу, чтобы все ветки запускали этот рабочий процесс


ветви:


  • dev # Прямая отправка разрешена, это развертывает на промежуточный сервер

  • beta # Защищенная ветвь, без прямой отправки, разрешено только принятое слияние

  • main # Защищенная ветвь, без прямой отправки, разрешено только принятое слияние

Как насчет оператора if / else if / else для проверки ветвлений? 🔑


GitHub Actions поддерживает ключ «if», но «else if/else» отсутствует. Кроме того, я могу использовать контексты, чтобы прочитать имя текущей ветки.


Синтаксис контекстов ${{ <context> }}, поэтому у меня есть что-то вроде ниже:


``ямл


шаги:


  • название: Мой шаг

Контекст github.ref используется для определения имени ветки


Он оценивается по имени ссылки git


Неправильный синтаксис


если: ${{ github.ref }} == 'что-то'


Правильный синтаксис


Здесь я должен использовать одинарную кавычку


Мне потребовалось некоторое время, чтобы определить, что двойная кавычка нарушила рабочий процесс


если: ${{ github.ref == 'ref/heads/main' }}


Клавиши else if / else не существует. 🔑


Ну, я могу использовать 3 разных «если» в 3 разных шагах. Каждый из них представляет определенную ветвь.


Я использую google-github-actions/auth на первом этапе своей работы для аутентификации в GCP. На данный момент у меня есть 6 разных секретов GitHub для проверки концепции. Каждая ветвь имеет два секрета в формате BRANCH_WIP и BRANCH_SA.


```ямл


Шаг для основной ветки


  • имя: ГЛАВНАЯ аутентификация

если: ${{ github.ref == 'ref/heads/main' }} && ${{ secrets.MAIN_WIP != null }} && ${{ secrets.MAIN_SA != null }}


использует: google-github-actions/auth@v0


с:


workload_identity_provider: ${{ секреты.MAIN_WIP }}


service_account: $${{ секреты.MAIN_SA }}


Шаги для веток beta и dev имеют одинаковую структуру


Но приведенный выше код НЕ будет работать, я объясню ниже


Я использую nektos/act для локального тестирования рабочего процесса, но он завершается с сообщением Error: exit with 'FAILURE': 1. Угадайте, что secrets нельзя использовать в ключе if, отсюда и ошибка.


Секреты GitHub нельзя прочитать в условном выражении. 🔑


GitHub Actions имеет ключ env для определения переменных среды в разных областях рабочего процесса. Я использую его на уровне шага для импорта «секретов», потому что «env» можно прочитать в ключе «if».


``ямл


  • имя: ГЛАВНАЯ аутентификация

среда:


Определите пару ключей, используя переменную окружения.


WIP: ${{ секреты.MAIN_WIP }}


SA: ${{ секреты.MAIN_SA }}


если: ${{ github.ref == 'ref/heads/main' }} && env.WIP != null && env.SA != null


использует: google-github-actions/auth@v0


с:


workload_identity_provider: ${{ env.WIP }}


service_account: ${{ env.SA }}


Обратите внимание, мне нужно использовать '${{ }}' в многоразовом рабочем процессе 'auth@v0' для чтения 'env'


При этом не обязательно в ключе 'if'.


Это стоило мне довольно много времени на отладку


Предварительно скомпилированная кодовая база может читать переменные окружения. 🔑


Однако помните, что только то, что выполняется внутри виртуальной машины GitHub, может читать переменные. Серверная часть, загружаемая в GAE, создается и тестируется в среде GCP. У него нет доступа к ресурсам GitHub.


``ямл


  • имя: Конфигурация для переменных среды React

если: ${{ github.ref == 'refs/heads/dev' }}


Шаг сборки может читать REACT_APP_DEV


запустить: |


эхо "REACT_APP_DEV=${{ secrets.DEV }}" >> $GITHUB_ENV


Создание действия 3 раза для 3 веток приводит к дублированию кода, должен ли быть способ его рефакторинга? 🔑


На данный момент область действия переменных среды ограничена шагом, на котором они остаются. Внутри задания у меня есть ключ steps, который содержит несколько шагов внизу. Поэтому, как минимум, мне нужно, чтобы переменные окружения имели область действия steps.


Действительно, область действия steps работает. В задании я могу записать переменные в $GITHUB_ENV на первом шаге в ключе steps, чтобы все последующие шаги могли получить доступ к переменным среды. Обратите внимание, я не могу создать условный оператор в области задания, так что, возможно, работает только область шаги.


Я столкнулся с подходом, использующим команду set-env. Однако set-env устарел из-за CVE-2020-15228 и больше не может использоваться.


Теперь вместо этого я использую echo "MY_ENV=${{ secrets.MY_SECRET }}" >> $GITHUB_ENV.


``ямл


имя: конвейер CI/CD


Определите, какое действие запускает рабочий процесс


на:


толкать:


ветви:


  • dev # Прямая отправка разрешена, это развертывает на промежуточный сервер

  • beta # Защищенная ветвь, без прямой отправки, разрешено только принятое слияние

  • main # Защищенная ветвь, без прямой отправки, разрешено только принятое слияние

вакансии:


авторизация:


имя: Аутентификация в GCP


запуски: ubuntu-последняя


стратегия:


матрица:


версия узла: [16.x]


разрешения:


содержание: читать


id-токен: написать


шаги:


Мне нужно объявить переменные окружения только один раз в начале


Последующие шаги могут получить доступ к переменным по умолчанию


  • имя: Конфигурация для основной ветки

если: ${{ github.ref == 'refs/heads/main' }}


Примечание: здесь я могу запустить любую команду Linux, а не только 'echo'


запустить: |


echo "GCP_WIP=${{ secrets.MAIN_WIP }}" >> $GITHUB_ENV


echo "GCP_SA=${{ secrets.MAIN_SA }}" >> $GITHUB_ENV


  • название: Конфигурация для бета-ветки

если: ${{ github.ref == 'refs/heads/beta' }}


запустить: |


echo "GCP_WIP=${{ secrets.BETA_WIP }}" >> $GITHUB_ENV


echo "GCP_SA=${{ secrets.BETA_SA }}" >> $GITHUB_ENV


  • название: Конфигурация для бета-ветки

если: ${{ github.ref == 'refs/heads/dev' }}


запустить: |


echo "GCP_WIP=${{ secrets.DEV_WIP }}" >> $GITHUB_ENV


echo "GCP_SA=${{ secrets.DEV_SA }}" >> $GITHUB_ENV


  • имя: Аутентификация в GCP

если: env.GCP_WIP != null && env.GCP_SA != null


использует: google-github-actions/auth@v0


с:


workload_identity_provider: ${{ env.GCP_WIP }}


service_account: ${{ env.GCP_SA }}


Подведение итогов 🍀


Первоначально мое использование GitHub Actions включало только простые действия, такие как «сборка», «тест». С условным рабочим процессом открывается совершенно новый набор возможностей. В статье основное внимание уделяется условному рабочему процессу. Однако я также должен знать о некоторых концепциях, которые прямо или косвенно прямо или косвенно упоминаются в статье.


  1. Контексты

  1. Область действия и иерархический доступ

  1. Повторно используемый рабочий процесс

  1. Пользовательские команды Linux (рабочий процесс запускается на виртуальной машине)

Затем я потрачу некоторое время на [документ GitHub Actions] (https://docs.github.com/en/actions).


  • Также опубликовано [здесь] (https://hungvu.tech/advanced-github-actions-conditional-workflow)*


Оригинал
PREVIOUS ARTICLE
NEXT ARTICLE