Недавно я подключил свой проект к действиям github для непрерывной интеграции. Я создал два отдельных задания: первое проверяет, принимает ли наш линтер код в пулл-реквесте, а второе проверяет, проходит ли код набор тестов. Мне нравится, что наличие двух таких заданий отображается как две отдельные галочки на веб-странице Github для запроса на вытягивание:
Проблема, с которой я столкнулся сейчас, заключается в том, что в файле YAML рабочего процесса есть дублированный код: первые 3 шага, которые устанавливают Lua и Luarocks. Это не только раздражает в обслуживании, но и тратит впустую минуты CI, выполняя одни и те же действия дважды. Есть ли способ избежать этого? Чтобы код установки был написан только в одном месте и запускался только один раз при выполнении рабочего процесса?
Но я в замешательстве, как правильно поступить:
Вот текущий файл YAML для моего рабочего процесса:
name: Github Actions CI
on: [ pull_request ]
jobs:
lint:
name: Lint
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: leafo/[email protected]
- uses: leafo/[email protected]
- run: luarocks install luacheck
- run: ./run-linter.sh
test:
name: Test
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: leafo/[email protected]
- uses: leafo/[email protected]
- run: luarocks install busted
- run: ./build-project.sh
- run: ./run-test-suite.sh
Я попытался найти похожие вопросы, но не смог найти ничего, что точно ответило бы на мой вопрос:
На сегодняшний день (август 2021 г.) составное действие больше не ограничивается run
. GitHub Actions: уменьшите дублирование с помощью композиции действий
name: "Publish to Docker"
description: "Pushes built artifacts to Docker"
inputs:
registry_username:
description: “Username for image registry”
required: true
registry_password:
description: “Password for image registry”
required: true
runs:
using: "composite"
steps:
- uses: docker/setup-buildx-action@v1
- uses: docker/login-action@v1
with:
username: ${{inputs.registry_username}}
password: ${{inputs.registry_password}}
- uses: docker/build-push-action@v2
with:
context: .
push: true
tags: user/app:latest
Старый ответ
То, что вы ищете, — это составное действие, которое поможет вам повторно использовать один раз определенный набор шагов.
jobs:
lint:
name: Lint
runs-on: ubuntu-latest
steps:
- uses: octocat/say-hello@v1
- run: luarocks install luacheck
- run: ./run-linter.sh
test:
name: Test
runs-on: ubuntu-latest
steps:
- uses: octocat/say-hello@v1
- run: luarocks install busted
- run: ./build-project.sh
- run: ./run-test-suite.sh
octocat/привет-привет/action.yml:
runs:
using: "composite"
steps:
- run: echo "Nice to meet you!"
shell: pwsh
Для получения более подробной информации вы также можете проверить ДОПОГ здесь.
И почему вы не можете просто запустить его один раз для всех заданий, потому что каждое задание может выполняться на разных машинах.
Задание — это набор шагов, которые выполняются на одном и том же бегуне. По умолчанию рабочий процесс с несколькими заданиями будет выполнять эти задания параллельно. Вы также можете настроить рабочий процесс для последовательного запуска заданий. Например, рабочий процесс может иметь два последовательных задания, которые создают и тестируют код, причем задание тестирования зависит от состояния задания сборки. В случае сбоя задания сборки тестовое задание не будет запущено.
@AJNinja теперь это поддерживается!
Можете ли вы определить это составное действие в том же репозитории, где оно будет использоваться? Например, у меня есть 4 задания, которые запускаются при открытии PR в репозитории, но всем им требуется один и тот же ряд шагов «настройки». Во всех примерах, которые я вижу, действие находится в отдельном репо.
Да. Конечно, вы можете иметь составное действие в том же репо. Взгляните сюда: github.com/kmadof/github-actions-manual/blob/main/.github/…
Приведенный ниже фрагмент кода должен сделать всю работу за вас. Вместо создания двух заданий, одного для lint и другого для теста, вы можете использовать одно задание и создать несколько задач.
name: Github Actions CI
on: [ pull_request ]
jobs:
lint:
name: Lint and Test
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: leafo/[email protected]
- uses: leafo/[email protected]
- name: Install Luacheck
run: luarocks install luacheck
- name: Run Lint Check
- run: ./run-linter.sh
- name: Install Busted
run: luarocks install busted
- name: Build Project
run: ./build-project.sh
- name: Run Test Suite
- run: ./run-test-suite.sh
Это не позволяет выполнять линтер и модульные тесты параллельно, а также не выявляет сбои модульных тестов до тех пор, пока ошибки линта не будут устранены.
Существует 3 основных подхода к повторному использованию кода в GitHub Actions:
Есть статья с описанием их плюсов и минусов.
В вашем случае, если дублированные шаги находятся в одном рабочем процессе, вы также можете:
Я пытался использовать маршрут загрузки артефактов, но он ужасно медленный. Конечно, я также загружал репозиторий, который я проверял, с включенным node_modules
. Но я не думаю, что мне нужно запускать проверку и npm i
для каждой работы, которая в этом нуждается. Это ненужное дублирование.
1. Вы можете кэшировать зависимости узлов 2. Вы можете извлекать повторяющиеся шаги в составное действие, которое выполняется на одном и том же воркере в контексте вашей работы, разделяя файловую систему
Да, но составные действия просто позволяют группировать общие задачи. Каждое задание по-прежнему должно выполнять те общие задачи, которые являются избыточными. Должен быть способ иметь 1 задание, на которое полагаются все остальные задания, с помощью ключевого слова needs
, которое выполняет то, что должно быть однократной работой по настройке.
Отвечает ли это на ваш вопрос? Действия Github разделяют рабочее пространство/артефакты между заданиями?