Кеш сборки в CI: что происходит после сохранения
Кеш в CI — не «папка, которую runner помнит»: ключ, область доступа и момент записи определяют, восстановится ли нужный результат. Разбираем механику GitHub Actions Cache v4 и случаи, когда попадание в кеш не ускоряет сборку.

В GitHub Actions кеш может восстановиться по похожему ключу, но это не гарантирует, что сборка использует именно нужные файлы. На результат влияют состав ключа, область видимости кеша и то, когда runner его записывает. Ниже — внутреннее устройство actions/cache v4 и способ измерить пользу без выдуманных цифр.
Что именно кешируется
Кеш CI — сохранённый набор файлов, который следующий запуск может скачать вместо повторного создания. Это могут быть загруженные зависимости, промежуточные результаты компиляции или другие повторно используемые данные. Сам GitHub Actions не решает, какие файлы проекта безопасно переиспользовать: пути задаёт workflow.
Важно различать кеш и артефакт. Кеш ускоряет будущие запуски и может быть удалён по правилам хранения платформы. Артефакт передают между заданиями или сохраняют как результат запуска — например, чтобы скачать собранный пакет. Кеш не должен быть единственным местом, где лежит результат, потеря которого ломает релиз.
Термин: ключ кеша — строка, по которой workflow ищет сохранённый набор файлов. Если ключ зависит от версии среды или входных файлов, изменение этих данных может привести к созданию нового кеша.
Путь от запроса до восстановления
Рассмотрим actions/cache v4 — официальный action для кеширования в GitHub Actions. В workflow задают пути и ключ. На новом запуске action сначала ищет точное совпадение, а затем, если указаны резервные префиксы, может восстановить кеш с подходящим ключом. При частичном совпадении workflow получает старые файлы, но это не подтверждает, что они актуальны для текущей сборки.
У кеша есть и область доступности. GitHub ограничивает, какие запуски могут читать кеши других веток; в частности, кеш базовой ветки доступен workflow для pull request, но доступ к кешу из произвольной ветки не универсален. Поэтому ситуация «ключ совпал, а кеша нет» не всегда означает ошибку в строке ключа: проверьте ветку и контекст запуска.
Ещё одно отличие от обычной папки — кеши по ключу неизменяемы. Если ключ уже сохранён, повторный запуск с тем же ключом не перезаписывает его обновлённым содержимым. Для нового набора файлов нужен новый ключ. При этом action может восстановить кеш по префиксу, а затем сохранить результат уже под точным новым ключом.
Почему запись происходит не там, где её ждут
В типичном сценарии action восстанавливает кеш в начале задания, а сохранение делает в конце — через post-job шаг. Поэтому успешное сообщение о восстановлении ещё ничего не говорит о том, что новый кеш будет записан. Если задание отменилось или завершилось раньше, до сохранения дело может не дойти.
На состав кеша влияет не только список путей. В GitHub Actions версия кеша также связана с путями и способом упаковки, поэтому одинаковый на вид ключ не всегда означает возможность восстановить один и тот же архив. Это один из ответов на вопрос, почему изменение конфигурации кеширования или среды может привести к промаху при прежнем ключе.
Кеш — это подсказка для ускорения, а не хранилище истины: сборка должна оставаться корректной и без него.
Где теряется выигрыш
Кеш не ускоряет автоматически. Runner тратит время на поиск, скачивание и распаковку. Если каталог большой, редко меняется или быстро пересобирается, стоимость передачи может оказаться сравнима с повторной работой либо превысить её. Если кеш включает лишние файлы, архив растёт, а восстановление становится тяжелее.
Полезно отдельно думать о трёх слоях. Они решают разные задачи и не обязаны жить под одним ключом:
| Что сохраняют | Что даёт | Что может пойти не так |
|---|---|---|
| Загруженные зависимости | Меньше повторных скачиваний | Ключ не учитывает lock-файл или версию среды, и набор становится несовместимым |
| Промежуточные файлы сборки | Меньше повторной компиляции | Инструмент сборки не проверяет корректность старых результатов или не видит изменения входов |
| Готовый результат сборки | Можно передать его другому заданию | Кеш ошибочно используют вместо артефакта, который должен быть доступен для публикации |
Не объединяйте всё в один огромный архив только ради одного попадания. Разные данные имеют разные причины инвалидироваться: lock-файл меняет зависимости, исходники — результат компиляции, а версия компилятора или операционной системы может менять совместимость промежуточных файлов.
Что ломается первым
- Ключ слишком общий. Изменились зависимости, а workflow восстановил старый набор. Учитывайте в ключе файлы, которые определяют содержимое кеша, а не только имя ветки.
- Ключ слишком точный. Каждое изменение исходников создаёт отдельный архив, и повторного использования почти нет. В таком случае проверьте, можно ли использовать резервный префикс и безопасно обновлять данные после восстановления.
- Кеш считают обязательным. Холодный запуск падает или выдаёт другой результат. Уберите кеш и выполните сборку заново: если она не проходит, проблема не в ускорении, а в зависимости проекта от сохранённых файлов.
- Ожидают перезаписи. Под тем же ключом уже есть старый кеш. Измените версионирующую часть ключа, чтобы создать новый, вместо попытки обновить неизменяемую запись.
- Сравнивают только время сборки. Скачивание и распаковка тоже занимают время. Смотрите длительность задания целиком и отдельно фиксируйте, был ли точный hit, частичное восстановление или промах.
Как проверить эффект на своём проекте
Универсальных цифр ускорения нет: результат зависит от размера архива, скорости runner, сети и того, сколько работы кеш действительно убирает. Проведите сравнение на одном workflow и сопоставимых запусках. Зафиксируйте тип runner, ветку, объём проекта и число параллельных заданий — иначе сравнение будет шумным.
- Запустите сборку без кеша и запишите полное время задания, а не только время компилятора.
- Добавьте кеш только для одного слоя, например зависимостей, и проверьте точное восстановление по логам action.
- Повторите запуск с теми же входами, затем измените lock-файл или другой вход, который должен менять ключ.
- Сравните холодный запуск, точное попадание и частичное восстановление. Отдельно проверьте, что результат сборки совпадает и тесты проходят.
- Если скачивание и распаковка съедают выигрыш, сократите список путей или откажитесь от этого кеша.
Не делайте вывод по одному запуску: очереди и сетевые условия меняются. Сравните несколько сопоставимых прогонов и смотрите на медиану времени. Это рекомендация по измерению, а не обещание конкретного процента ускорения.
Что делать дальше
Начните с одного кешируемого каталога и проверьте, какие входы действительно меняют его содержимое. Затем измерьте время полного задания при холодном запуске и попадании в кеш. Если кеш нужен для передачи собранного результата между заданиями или для публикации, храните его как артефакт, а не рассчитывайте на правила жизни кеша. Инвалидация кеша — отдельная тема; здесь важны устройство восстановления и проверка его эффекта.
Проверка рекламы на риски: Что в макете вызовет вопросы ФАС: превосходные степени, сравнения, обещания результата, маркировка.
Спросить за 40 ₽Источники: GitHub Docs: Caching dependencies to speed up workflows, GitHub: actions/cache
Частые вопросы
Почему GitHub Actions не восстановил кеш, хотя ключ не менялся?
Можно ли обновить содержимое кеша, оставив тот же ключ?
Почему кеш восстановился, но сборка всё равно долгая?
Что будет, если кеш удалить или он станет недоступен?
Чем кеш отличается от артефакта в GitHub Actions?
Стоит ли кешировать весь каталог проекта?
Материал носит информационный характер и подготовлен редакцией «Агентуры». Он не является офертой, рекламой или индивидуальной консультацией. Упомянутые продукты, компании и торговые знаки принадлежат их правообладателям. Перед принятием решений, влекущих юридические или финансовые последствия, обратитесь к профильному специалисту.