В рабочем процессе действий github есть ли способ, чтобы несколько заданий повторно использовали одну и ту же настройку?

Недавно я подключил свой проект к действиям github для непрерывной интеграции. Я создал два отдельных задания: первое проверяет, принимает ли наш линтер код в пулл-реквесте, а второе проверяет, проходит ли код набор тестов. Мне нравится, что наличие двух таких заданий отображается как две отдельные галочки на веб-странице Github для запроса на вытягивание:

Проблема, с которой я столкнулся сейчас, заключается в том, что в файле YAML рабочего процесса есть дублированный код: первые 3 шага, которые устанавливают Lua и Luarocks. Это не только раздражает в обслуживании, но и тратит впустую минуты CI, выполняя одни и те же действия дважды. Есть ли способ избежать этого? Чтобы код установки был написан только в одном месте и запускался только один раз при выполнении рабочего процесса?

Но я в замешательстве, как правильно поступить:

  1. Должен ли я создать свой собственный Github Action с общим кодом установки?
  2. Должен ли я создать образ Docker, в котором уже предустановлены Lua и Luarocks?
  3. Должен ли я использовать одну работу? Могу ли я по-прежнему иметь независимые галочки для линтера и набора тестов, если они являются этапами одной и той же работы?
  4. Что-то другое?

Вот текущий файл 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

Я попытался найти похожие вопросы, но не смог найти ничего, что точно ответило бы на мой вопрос:

  1. Кэширование APT-пакетов в рабочем процессе GitHub Actions: я не могу использовать это решение, потому что у меня нет возможности точно указать все версии всех зависимостей, которые я использую, чтобы они могли кэшироваться. Я также не возражаю, если отдельные прогоны рабочего процесса не кэшируются. Меня больше беспокоит дублирование кода.
  2. Действия Github разделяют рабочее пространство/артефакты между заданиями? Я не хочу заниматься выгрузкой артефактов на отдельный сервис, а потом их удалением.
  3. Повторно используйте часть действия github для разных заданий: В этом вопросе единственная разница между заданиями — это одна переменная, поэтому принятый ответ — использовать матрицу сборки. Но я не думаю, что матрица сборки сработала бы в моем случае, когда одинаковый только код установки?
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
101
1
69 441
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

На сегодняшний день (август 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 теперь это поддерживается!

Krzysztof Madej 26.08.2021 17:55

Можете ли вы определить это составное действие в том же репозитории, где оно будет использоваться? Например, у меня есть 4 задания, которые запускаются при открытии PR в репозитории, но всем им требуется один и тот же ряд шагов «настройки». Во всех примерах, которые я вижу, действие находится в отдельном репо.

TemporaryFix 11.01.2023 00:16

Да. Конечно, вы можете иметь составное действие в том же репо. Взгляните сюда: github.com/kmadof/github-actions-manual/blob/main/.github/…

Krzysztof Madej 11.01.2023 12:20

Приведенный ниже фрагмент кода должен сделать всю работу за вас. Вместо создания двух заданий, одного для 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

Это не позволяет выполнять линтер и модульные тесты параллельно, а также не выявляет сбои модульных тестов до тех пор, пока ошибки линта не будут устранены.

Charles Stover 24.08.2021 21:31
Ответ принят как подходящий

Существует 3 основных подхода к повторному использованию кода в GitHub Actions:

Есть статья с описанием их плюсов и минусов.

В вашем случае, если дублированные шаги находятся в одном рабочем процессе, вы также можете:

  1. извлечь их на задание "подготовка"
  2. загрузить артефакты сборки
  3. добавить задание «подготовка» к ключу «нужно» обоих заданий
  4. загрузить артефакт сборки в обоих заданиях

Я пытался использовать маршрут загрузки артефактов, но он ужасно медленный. Конечно, я также загружал репозиторий, который я проверял, с включенным node_modules. Но я не думаю, что мне нужно запускать проверку и npm i для каждой работы, которая в этом нуждается. Это ненужное дублирование.

TemporaryFix 11.01.2023 00:19

1. Вы можете кэшировать зависимости узлов 2. Вы можете извлекать повторяющиеся шаги в составное действие, которое выполняется на одном и том же воркере в контексте вашей работы, разделяя файловую систему

Cardinal 12.01.2023 17:40

Да, но составные действия просто позволяют группировать общие задачи. Каждое задание по-прежнему должно выполнять те общие задачи, которые являются избыточными. Должен быть способ иметь 1 задание, на которое полагаются все остальные задания, с помощью ключевого слова needs, которое выполняет то, что должно быть однократной работой по настройке.

TemporaryFix 12.01.2023 17:59

Другие вопросы по теме