При ревью запроса на слияние периодически приходится сталкиваться с подозрительными изменениями go.mod и go.sum. Например, когда изменяется только один файл из двух, или когда в Go коде мы не видим то, что могло бы привести к изменениям go.mod и go.sum.
В таких случаях возникают закономерные вопросы: нужны ли эти изменения? почему они появились?
Что могло пойти не так?
- Изменения случайно попали в коммит.
- Коллега забыл добавить один из файлов в коммит.
- Коллега забыл запустить
go mod tidy
после удаления зависимости. - Кто-то в прошлом сделал коммит с проблемой из первых 3-х пунктов.
- Или, может быть, всё хорошо, и коллега обновил версию Go в go.mod или обновил версию зависимости.
Чтобы не проверять вручную первые 4 пункта, можно автоматизировать проверку актуальности состояния файлов go.mod и go.sum.
На примере Gitlab CI такое задание может выглядеть так:
image: golang:1.21.5
stages:
- check
check-go-dependencies:
stage: check
script:
- go mod tidy
- git diff --exit-code
go mod tidy
— это команда, которая приведет в соответствие исходный кода модуля и файлов go.mod и go.sum.git diff --exit-code
— эта команда покажет различия между закоммиченными файлами и файлами, получившимися после предыдущей команды. Если различия есть, то благодаря флагу--exit-code
ненулевое значение кода выхода приведёт к завершению задания с ошибкой.
Это задание простое в реализации, но если оно падает с ошибкой, то не понятно, что с этим делать. Хорошо бы добавить полезную информацию для коллег или себя из будущего о том, как эту проблему можно решить. Поэтому внесем некоторые доработки в проверку:
image: golang:1.21.5
stages:
- check
check-go-dependencies:
stage: check
script:
- go mod tidy
- |
git diff --exit-code && exit 0 || true
echo -e "\033[0;31m"
echo '######################################################################'
echo
echo "ERROR: go.mod or go.sum is different from the committed version"
echo "Try using 'go mod tidy' to fix the go.mod and go.sum files"
echo "Also, don't forget to commit and push changes"
echo
echo '######################################################################'
exit 1
Как это работает?
- В начале — всё тот же
go mod tidy
, а дальше интересней. - Так как пайплайн завершается при первой же ошибке, сложно разложить проверку на отдельные вызовы
команд. Решаем это
через многострочный скрипт, используя
- |
. - Далее, в случае если
git diff --exit-code
ничего не находит, то выходим с нулевым кодомexit 0
. А вот если код выхода не нулевой, то перехватываем и пропускаем его за счет командыtrue
. - Следом устанавливаем красный цвет для сообщения об ошибке, выводим нужное сообщение и выходим с ненулевым кодом, чтобы задание завершилось с ошибкой.
Такое задание закрывает основные потребности проверки актуальности go.mod и go.sum. Вывод подробного
сообщения об ошибке помогает улучшить пользовательский опыт и снизить количество вопросов,
возникающих при падении задания. Дополнительно текст сообщения напоминает нам и коллегам о варианте
исправления проблемы командой go mod tidy
.