Кэширование зависимостей в GitHub Action

Источник: «Caching Dependencies on GitHub Actions»
GitHub Actions предлагает два способа хранения файлов: кэширование для зависимостей и артефакты для результатов работы, таких как логи и бинарники. Несмотря на похожие названия, эти методы служат разным целям.

GitHub Actions предоставляет два способа хранения файлов: кэширование для таких вещей, как dependencies, и artifacts для результатов работы, таких как логи или бинарники. Хотя звучат они похоже, используются они для разных целей. Так, мы будем использовать кэширование, чтобы ускорить выполнение рабочих процессов.

Ещё один момент: доступ к кэшу будет ограничен только несколькими ветками: current branch, base branch для pull request и default branch. Кэши, созданные в несвязанных ветках, будут недоступны, но в большинстве случаев это не повлияет на нас, поскольку мы обычно работаем либо с текущей, либо с базовой веткой.

Правильное использование кэширования может помочь сократить время сборки, особенно для проектов, чьи зависимости меняются нечасто.

Выбор правильного ключа кэша

Можно создавать ключи кэша на основе метаданных, например хэшей ОС или коммитов, позволяющие повторно использовать зависимости только в случае крайней необходимости. Также можно использовать ключи восстановления для получения близких соответствий для кэшей, что поможет минимизировать время пересборки.

Как правило, для рабочих процессов, выполняющихся на нескольких ОС, хорошей практикой является изоляция кэшей для каждой ОС, позволяющая избежать лишних пересборок между платформами. Иногда можно даже использовать временные кэши, действительные только для одного запуска, что удобно, когда не требуется длительное повторное использование.


- uses: actions/cache@v4
with:
path: path/to/dependencies
# Генерирование ключа кэша на основе хэша lockfiles
key: cache-${{ hashFiles('**/lockfiles') }}

- uses: actions/cache@v4
with:
path: path/to/dependencies
key: cache-${{ hashFiles('**/lockfiles') }}
# Восстановление ключей для ближайших совпадений. Это минимизирует время, затрачиваемое на загрузку новых зависимостей
restore-keys: |
cache-npm-


- uses: actions/cache@v4
with:
path: path/to/dependencies
#key: cache-${{ hashFiles('**/lockfiles') }}
# Кэши, ориентированные на конкретную ОС, позволяют избежать ненужных ребилдов на разных платформах
key: ${{ runner.os }}-cache
restore-keys: |
cache-npm-



- uses: actions/cache@v4
with:
path: path/to/dependencies
#key: cache-${{ hashFiles('**/lockfiles') }}
#key: ${{ runner.os }}-cache
# Недолговечные кэши для разового использования
key: cache-${{ github.run_id }}-${{ github.run_attempt }}
restore-keys: |
cache-npm-

Также можно разделять кэши между заданиями, централизуя создание кэша для экономии времени, и обеспечивать сохранение кэшей даже при неудачной сборке используя условие always().


# Централизованное использование кэша

- id: cache-primes-save
uses: actions/cache/save@v4 # Сохранение кэша
with:
key: ${{ runner.os }}-${{ hashFiles('**/lockfiles') }}

- uses: actions/cache/restore@v4 # Восстановление кэша
with:
key: ${{ runner.os }}-${{ hashFiles('**/lockfiles') }}

# Сохранение кэша после сбоя сборки
- uses: actions/cache@v4
with:
path: path/to/dependencies
key: cache-${{ hashFiles('**/lockfiles') }}
if: always()

Примеры кэширования менеджера пакетов GitHub Actions

Я собрал несколько примеров кэширования для различных менеджеров пакетов: npm, pip, Maven и NuGet. Следующая конфигурация позволит избежать повторной загрузки зависимостей при каждом запуске рабочего процесса. Например, при использовании npm мы не кэшируем node_modules, чтобы избежать проблем с разными версиями Node.

Вместо этого мы динамически кэшируем сам npm. Кэш pip должен быть разным в зависимости от ОС, и то же самое делается для Maven и NuGet для их путей к репозиториям и файлам блокировки.


# Кэширование зависимостей npm
- uses: actions/cache@v4
with:
path: ~/.npm
key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
restore-keys: |
${{ runner.os }}-node-


# Кэширование зависимостей pip
- uses: actions/cache@v4
with:
path: ~/.cache/pip
key: ${{ runner.os }}-pip-${{ hashFiles('**/requirements.txt') }}

# Кэширование зависимостей Maven
- uses: actions/cache@v4
with:
path: ~/.m2/repository
key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }}

# Кэширование зависимостей NuGet
- uses: actions/cache@v4
with:
path: ~/.nuget/packages
key: ${{ runner.os }}-nuget-${{ hashFiles('**/packages.lock.json') }}
restore-keys: ${{ runner.os }}-nuget-

Заключение

Кэширование в GitHub Actions подразумевает оптимизацию рабочего процесса непрерывной интеграции за счёт отказа от дублирования задач, например, повторной загрузки зависимостей. Тщательный выбор ключей кэша на основе метаданных, операционной системы или файла блокировки, поиск близких совпадений с ключами восстановления и уменьшение их количества значительно сократит время сборки. Храните отдельно кэши для разных операционных систем и используйте транзитные кэши для разовой сборки.

Комментарии


Дополнительные материалы

Предыдущая Статья

Хук useState в React: Полное руководство

Следующая Статья

Ключевое слово stretch: лучшая альтернатива width: 100% в CSS