Skip to main content

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

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

Сведения о кэшировании зависимостей рабочего процесса

Рабочий процесс часто повторно использует одни и те же выходные данные или скачанные зависимости из одного запуска в другом. Например, средства управления пакетами и зависимостями, такие как Maven, Gradle, npm и Yarn, хранят локальный кэш скачанных зависимостей.

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

Чтобы кэшировать зависимости для задания, необходимо выполнить действие cache в GitHub. Это действие создает и восстанавливает кэш, определенный уникальным ключом. Кроме того, при кэшировании диспетчеров пакетов, перечисленных ниже, использование соответствующих действий setup-* требует минимальной конфигурации; после его выполнения будут созданы и восстановлены кэши зависимостей.

Диспетчеры пакетовДействие setup-* для кэширования
npm, Yarn, pnpmsetup-node
pip, pipenv, Poetrysetup-python
Gradle, Mavensetup-java
RubyGemssetup-ruby
Go go.sumsetup-go

Предупреждение. При использовании кэширования с GitHub Actions учитывайте следующее:

  • В кэше не рекомендуется хранить конфиденциальную информацию. Например, конфиденциальная информация может включать маркеры доступа или учетные данные для входа, хранящиеся в файле в пути к кэшу. Кроме того, программы интерфейса командной строки (CLI), такие как docker login, могут сохранять учетные данные для доступа в файле конфигурации. Любой пользователь с доступом на чтение может создать в репозитории запрос на вытягивание и получить доступ к содержимому кэша. Вилки репозитория также могут создавать запросы на вытягивание в базовой ветви и получить доступ к кэшу в базовой ветви.
  • При использовании локальных средств выполнения тестов кэши из рабочих процессов хранятся в облачном хранилище, принадлежащем GitHub. Решение для принадлежащего клиенту хранилища доступно только с GitHub Enterprise Server.

Сравнение артефактов и кэширования зависимостей

Артефакты и кэширование схожи, поскольку они предоставляют возможность хранить файлы в GitHub, но каждая функция предлагает разные варианты использования и они не являются взаимозаменяемыми.

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

Дополнительные сведения об артефактах выполнения рабочего процесса см. в статье Сохранение данных рабочего процесса с помощью артефактов.

Ограничения доступа к кэшу

Ограничения доступа обеспечивают изоляцию кэша и защиту путем создания логической границы между разными ветвями и тегами. Запуски рабочих процессов могут восстанавливать кэши, созданные в текущей ветви или ветви по умолчанию (обычно main). Если рабочий процесс запускается для запроса на вытягивание, он также может восстановить кэши, созданные в базовой ветви, включая базовые ветви вилки репозиториев. Например, если ветвь feature-b имеется базовая ветвь feature-a, запуск рабочего процесса, запущенный в запросе на вытягивание, будет иметь доступ к кэшам, созданным в ветви по умолчанию main , базовой feature-a ветви и текущей feature-b ветви.

Запуски рабочих процессов не могут восстанавливать кэши, созданные для дочерних или одноуровневых ветвей. Например, кэш, созданный для дочерней feature-b ветви, будет недоступен для запуска рабочего процесса, активированного в родительской main ветви. Аналогичным образом кэш, созданный для ветви feature-a с базовой main ветвью, будет недоступен для ее одноуровневой feature-c ветви с базовой main. Запуски рабочих процессов также не могут восстанавливать кэши, созданные для разных имен тегов. Например, кэш, созданный для тега release-a с базовым main значением , не будет доступен для запуска рабочего процесса, активированного для тега release-b с базовым mainзначением .

При создании кэша в результате выполнения рабочего процесса, активированного в запросе на вытягивание, кэш создается для ссылки на слияние (refs/pull/.../merge). Из-за этого кэш будет иметь ограниченную область и может быть восстановлен только при повторном выполнении запроса на вытягивание. Ее не может восстановить базовая ветвь или другие запросы на вытягивание, предназначенные для этой базовой ветви.

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

Использование действия cache

Действие cache попытается восстановить кэш на основе предоставленного вами key. Когда действие находит кэш, который точно соответствует ключу, действие восстанавливает кэшированные файлы в настроенный path . При необходимости можно указать список restore-keys для использования в случае, если key не соответствует существующему кэшу. Список полезно использовать при восстановлении кэша restore-keys из другой ветви, так как restore-keys может частично совпадать с ключами кэша. Дополнительные сведения о сопоставлении restore-keys см. в разделе Сопоставление ключа кэша.

Если имеется точное совпадение с указанным key, это считается попаданием в кэш. Если ни одно из кэшей точно не соответствует указанному key, это считается промахом кэша. При промахе кэша действие автоматически создает новый кэш, если задание успешно завершено. В новом кэше будет использоваться предоставленный вами key, а также будут содержаться файлы, указанные в path. Дополнительные сведения о том, как это обрабатывается, см. в разделе "Попадания и промахи кэша".

Содержимое существующего кэша изменить нельзя. Вместо этого можно создать новый кэш с новым ключом.

Входные параметры для действия cache

  • key. Требуется Ключ, созданный при сохранении кэша, и ключ, используемый для поиска кэша. Это может быть любое сочетание переменных, значений контекста, статических строк и функций. Ключи имеют максимальную длину в 512 символов, а использование ключей большей длины приведет к сбою действия.

  • path. Требуется (требуются) Путь (пути) в средстве выполнения тестов для кэширования или восстановления.

    • Вы можете указать один путь или добавить несколько путей в отдельных строках. Пример:

      - name: Cache Gradle packages
        uses: actions/cache@v3
        with:
          path: |
            ~/.gradle/caches
            ~/.gradle/wrapper
      
    • Вы можете указать либо каталоги, либо отдельные файлы. Также поддерживаются стандартные маски.

    • Можно указать абсолютные пути или пути относительно каталога рабочей области.

  • restore-keys. Необязательно Строка, содержащая альтернативные ключи восстановления, где каждый ключ восстановления, находится в новой строке. Если для key не происходит попадание в кэше, эти ключи восстановления используются последовательно в указанном порядке для поиска и восстановления кэша. Пример.

    restore-keys: |
      npm-feature-${{ hashFiles('package-lock.json') }}
      npm-feature-
      npm-
    

Входные параметры для действия cache

  • cache-hit. Логическое значение, указывающее, что для ключа найдено точное совпадение.

Попадания и промахи в кэше

Если key точно соответствует существующему кэшу, это называется попаданием в кэш, и действие восстанавливает кэшированные файлы в path каталог.

При отсутствии соответствия key существующему кэшу происходит промах кэша, и если задание успешно завершено, автоматически создается новый кэш.

При промахе кэша действие также выполняет поиск указанных restore-keys для любых совпадений:

  1. При указании restore-keys действие cache последовательно ищет все кэши, соответствующие списку restore-keys.
    • При точном совпадении действие восстанавливает файлы в кэше в каталог path.
    • Если точных совпадений нет, действие ищет частичные совпадения ключей восстановления. Когда действие находит частичное совпадение, в каталог path восстанавливается самый последний кэш.
  2. Действие cache завершается, и выполняется следующий шаг задания.
  3. Если задание завершено успешно, действие автоматически создает новый кэш с содержимым каталога path.

Более подробное описание процесса сопоставления кэша см. в статье Сопоставление ключа кэша.

Пример использования действия cache

В этом примере создается новый кэш при изменении пакетов в файле package-lock.json или при изменении операционной системы средства выполнения тестов. Ключ кэша использует контексты и выражения для создания ключа, который включает операционную систему средства выполнения тестов и хэш SHA-256 файла package-lock.json.

YAML
name: Caching with npm
on: push
jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3

      - name: Cache node modules
        id: cache-npm
        uses: actions/cache@v3
        env:
          cache-name: cache-node-modules
        with:
          # npm cache files are stored in `~/.npm` on Linux/macOS
          path: ~/.npm
          key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ hashFiles('**/package-lock.json') }}
          restore-keys: |
            ${{ runner.os }}-build-${{ env.cache-name }}-
            ${{ runner.os }}-build-
            ${{ runner.os }}-

      - if: ${{ steps.cache-npm.outputs.cache-hit != 'true' }}
        name: List the state of node modules
        continue-on-error: true
        run: npm list

      - name: Install dependencies
        run: npm install

      - name: Build
        run: npm run build

      - name: Test
        run: npm test

Использование контекстов для создания ключей кэша

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

Использование выражений для создания key позволяет автоматически создавать новый кэш при изменении зависимостей.

Например, можно создать key с помощью выражения, которое вычисляет хэш файла npm package-lock.json. Таким образом, при изменении зависимостей, составляющих изменение файла package-lock.json, изменяется ключ кэша и автоматически создается новый кэш.

npm-${{ hashFiles('package-lock.json') }}

GitHub вычисляет выражение hash "package-lock.json" для получения окончательного key.

npm-d5ea0750

Использование выходных данных действия cache

Выходные данные действия cache можно использовать для выполнения действий в зависимости от того, произошло ли попадание в кэш или произошел промах. В случае нахождения точного совпадения для кэша для указанного key для выходных данных cache-hit задается значение true.

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

- if: ${{ steps.cache-npm.outputs.cache-hit != 'true' }}
  name: List the state of node modules
  continue-on-error: true
  run: npm list

Сопоставление ключа кэша

Действие cache сначала ищет попадания в кэш и key версию кэша в ветви, содержащей выполнение рабочего процесса. Если попадания нет, выполняется поиск restore-keys и версия. Если в текущей ветви по-прежнему нет попаданий, cache действие повторяет те же действия, что и в ветви по умолчанию. Обратите внимание, что ограничения области применяются во время поиска. Дополнительные сведения см. в разделе Ограничения доступа к кэшу.

Версия кэша — это способ пометить кэш метаданными path и средством сжатия, используемым при создании кэша. Это гарантирует, что выполнение используемого рабочего процесса однозначно совпадает с кэшем, который он фактически может распаковыть и использовать. Дополнительные сведения см. в разделе Версия кэша документации по кэшу действий.

restore-keys позволяет указать список альтернативных ключей восстановления, используемых в случае промаха кэша в key. Можно создать несколько ключей восстановления, упорядоченных от наиболее определенных до наименее определенных. Действие cache выполняет поиск restore-keys в последовательном порядке. Если ключ не совпадает напрямую, действие выполняет поиск ключей с префиксом ключа восстановления. При наличии нескольких частичных совпадений для ключа восстановления действие возвращает последний созданный кэш.

Пример использования нескольких ключей восстановления

restore-keys: |
  npm-feature-${{ hashFiles('package-lock.json') }}
  npm-feature-
  npm-

Средство выполнения тестов вычисляет выражения, которые разрешаются в следующие restore-keys:

restore-keys: |
  npm-feature-d5ea0750
  npm-feature-
  npm-

Ключ восстановления npm-feature- соответствует любому ключу, который начинается со строки npm-feature-. Например, оба ключа npm-feature-fd3052de и npm-feature-a9b253ff совпадают с ключом восстановления. Будет использоваться кэш с последней датой создания. Ключи в этом примере выполняются в следующем порядке:

  1. npm-feature-d5ea0750 соответствует определенному хэшу.
  2. npm-feature- соответствует ключам кэша с префиксом npm-feature-.
  3. npm- соответствует любым ключам с префиксом npm-.

Пример приоритета поиска

key:
  npm-feature-d5ea0750
restore-keys: |
  npm-feature-
  npm-

Например, если запрос на вытягивание содержит ветвь feature и нацелен на ветвь по умолчанию (main), действие выполняет поиск key и restore-keys в следующем порядке:

  1. Ключ npm-feature-d5ea0750 в ветви feature
  2. Ключ npm-feature- в ветви feature
  3. Ключ npm- в ветви feature
  4. Ключ npm-feature-d5ea0750 в ветви main
  5. Ключ npm-feature- в ветви main
  6. Ключ npm- в ветви main

Ограничения использования и политика вытеснения

GitHub удалит все записи кэша, к которым не удалось получить доступ в течение 7 дней. Количество кэшей, которые можно хранить, не ограничено, но общий размер всех кэшей в репозитории ограничен до 10 ГБ.

Если это ограничение превышено, GitHub сохранит новый кэш, но начнет вытеснять кэши до тех пор, пока общий размер не станет меньше ограничения репозитория. Процесс вытеснения кэша может привести к обмотке кэша, когда кэши создаются и удаляются с высокой частотой. Чтобы уменьшить это, можно просмотреть кэши для репозитория и выполнить действия по исправлению, такие как удаление кэширования из определенных рабочих процессов. Дополнительные сведения см. в разделе Управление кэшами.

Управление кэшами

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

  • Просмотр списка всех записей кэша для репозитория.
  • Отфильтруйте и отсортируйте список кэшей, используя определенные метаданные, такие как размер кэша, время создания или время последнего обращения.
  • Удаление записей кэша из репозитория.
  • Мониторинг совокупного использования кэша для репозиториев и организаций.

Существует несколько способов управления кэшами для репозиториев:

  • Использование веб-интерфейса GitHub, как показано ниже.
  • Использование REST API. Дополнительные сведения см. в документации по REST API GitHub Actions.
  • Установка расширения GitHub CLI для управления кэшами из командной строки. Дополнительные сведения см. в разделе расширение gh-actions-cache .

Просмотр записей кэша

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

  1. На GitHub.com перейдите на главную страницу репозитория. 1. Щелкните Действия под именем репозитория. Вкладка "Действия" на главной панели навигации по репозиторию 1. На левой боковой панели в разделе "Управление" щелкните Кэши.

  2. Просмотрите список записей кэша для репозитория.

    • Чтобы найти записи кэша, используемые для определенной ветви, щелкните раскрывающееся меню Ветвь и выберите ветвь. В списке кэша будут отображаться все кэши, используемые для выбранной ветви.
    • Для поиска записей кэша с определенным ключом кэша используйте синтаксис key: key-name в поле Фильтрация кэшей . В списке кэша будут отображаться кэши из всех ветвей, в которых использовался ключ.

    Снимок экрана: список записей кэша

Удаление записей кэша

Пользователи с write доступом к репозиторию могут использовать веб-интерфейс GitHub для удаления записей кэша.

  1. На GitHub.com перейдите на главную страницу репозитория. 1. Щелкните Действия под именем репозитория. Вкладка "Действия" на главной панели навигации по репозиторию 1. На левой боковой панели в разделе "Управление" щелкните Кэши.

  2. Справа от записи кэша, которую вы хотите удалить, щелкните .

    Снимок экрана: список записей кэша

Принудительное удаление записей кэша

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

Например, в репозитории может быть открыто много новых запросов на вытягивание, каждый из которых имеет собственные кэши, ограниченные этой ветвью. Эти кэши могут занимать большую часть хранилища кэша для этого репозитория. Когда репозиторий достигнет максимального объема хранилища кэша, политика вытеснения кэша создаст пространство, удалив самые старые кэши в репозитории. Чтобы предотвратить регулирование кэша в этом случае, можно настроить рабочие процессы для удаления кэшей быстрее, чем политика вытеснения кэша. Расширение CLI можно использовать gh-actions-cache для удаления кэшей для определенных ветвей.

В этом примере рабочего процесса используется gh-actions-cache для удаления всех кэшей, созданных ветвью после закрытия запроса на вытягивание.

name: cleanup caches by a branch
on:
  pull_request:
    types:
      - closed
  workflow_dispatch:

jobs:
  cleanup:
    runs-on: ubuntu-latest
    steps:
      - name: Check out code
        uses: actions/checkout@v3
        
      - name: Cleanup
        run: |
          gh extension install actions/gh-actions-cache
          
          REPO=${{ github.repository }}
          BRANCH=${{ github.ref }}

          echo "Fetching list of cache key"
          cacheKeysForPR=$(gh actions-cache list -R $REPO -B $BRANCH | cut -f 1 )

          ## Setting this to not fail the workflow while deleting cache keys. 
          set +e
          echo "Deleting caches..."
          for cacheKey in $cacheKeysForPR
          do
              gh actions-cache delete $cacheKey -R $REPO -B $BRANCH --confirm
          done
          echo "Done"
        env:
          GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}

Кроме того, вы можете использовать API для программного удаления кэшей по собственной частоте. Дополнительные сведения см. в разделе Удаление кэшей GitHub Actions для репозитория.