cscenter/lms

Проблемы с кешем github actions

Closed this issue · 1 comments

Вот это небольшое исправление 4f6ff7f#diff-1db27d93186e46d3b441ece35801b244db8ee144ff1405ca27a163bfe878957fR52 сломало кеширование докеровского образа с продакш-зависимостями.

Мотивация для изменения была логичная - зависимости приложения зависят от содержимого файла Pipfile.lock.

Коммит с исправлением key на ${{ runner.os }}-django-buildx-${{ hashFiles('**/Pipfile.lock') }} прилетел в составе вот этого билда https://github.com/cscenter/lms/runs/4209532119?check_suite_focus=true. На первый взгляд всё хорошо, кеш восстановился из предыдущего билда, файл Pipfile.lock не обновлялся.

Кажется, кеш может быть переиспользован, но по логу сборки видно, что обновился хеш python-образа, поэтому кеш во время сборки не использовался:

Из лога сборки закешированного образа
#6 [builder 1/3] FROM docker.io/library/python:3.9-slim-buster@sha256:76eaa9e5bd357d6983a88ddc9c4545ef4ad64c50f84f081ba952c7ed08e3bdd6

Из лога сборки текущей версии
#19 [builder 1/3] FROM docker.io/library/python:3.9-slim-buster@sha256:407802663f1207c1a874fcb21b3401d7984eeaaed578d1c1cf3a61b25d3d2b22

После сборки кеш был успешно сохранён.

Теперь происходит следующее в новых билдах:

  1. Восстанавливаем кеш по primary key. Github actions не обновляет значение кеша, если он был восстановлен из primary key (по точному совпадению, а не из restore-keys)

  2. Начинаем сборку нового образа. Видим, что python-образ снова обновился (кажется, опубликовали версию 3.9.9, а в кеше сидит версия 3.9.8)

#19 [stage-1  1/11] FROM docker.io/library/python:3.9-slim-buster@sha256:f7c184f986c591d9be54b63c6732b0f1406a4e7ddc86700a615fc8c9a927f08c

Т.е. кеш не используется и сборка образа идёт с нуля.

  1. После сборки кеш не сохраняется, т.к. был восстановлен по точному ключу.

  2. В итоге получаем, что пока жив кеш (живёт неделю, если не было сборок), сборка будет запускаться заново

Варианты решения:

  1. Залочиться на более точную версию 3.9.x Такое решение мне не нравится, т.к. лишаемся патчей и нужно самим следить за их выходом
  2. Вернуть восстановление ключа из значений restore-keys. Решение, но кеш каждый раз будет аплоадиться.
  3. Найти способ выцеплять hash базового образа, используемого в докеровском образе и подсовывать его в кеш.

Пока завязался на 3й вариант - hash(Pipfile.lock) + hash(manifest list). Выцеплять хэш манифеста под конкретную архитектуру легко не получится. Возможно, прокатит вариант docker manifest inspect --verbose docker.io/library/python:3.9-slim-buster (на mac os работает очень долго, но работает)