Как откатить миграции базы данных в CI/CD с помощью Goose и Golang
При доставке приложений через CI/CD (например, GitLab CI) часто возникает задача не только применить миграции базы данных, но и автоматически откатить их при необходимости. Особенно это актуально для Go-проектов, где популярен инструмент Goose. Рассмотрим, как организовать отмену миграций в пайплайне, избегая ручного труда и путаницы с версиями.
Проблема отката миграций в автоматических релизах
Когда релиз включает несколько файлов миграций (например, 00100_add_table.sql и 00101_add_fields_to_table.sql), простое применение через стандартные инструменты не запоминает, какие именно миграции были выполнены в рамках конкретного релиза. При откате нужно точно знать, какие шаги отменять, особенно если между релизами были промежуточные изменения.
Варианты решения для CI/CD
- Тегирование миграций - присвоение общего тега (например, ID релиза) всем файлам миграций в рамках одного MR.
- Хранение списка - ведение отдельной таблицы или файла с перечнем применённых миграций для каждого релиза.
- Динамический анализ - использование
git diffдля выявления добавленных или изменённых файлов миграций в Merge Request. - Ручной откат - не рекомендуется из-за риска ошибок и потери времени.
Реализация отката с Goose в Golang
Goose поддерживает команды up и down, но для автоматического отката в CI/CD нужно передать точное количество шагов или версию. Лучший подход - сохранять в переменных окружения или артефактах пайплайна список версий миграций, применённых в текущем релизе. Например, в GitLab CI можно записать номера миграций в файл и передать его в джобу отката.
Пример пайплайна с Goose
В .gitlab-ci.yml можно добавить шаг:
migrate:apply:
script:
- goose up
- goose version > migrations.txt
artifacts:
paths:
- migrations.txtДля отката:
migrate:rollback:
script:
- count=$(wc -l < migrations.txt)
- goose down $countЭтот метод гарантирует, что откатятся только те миграции, которые были применены в данном релизе.
Альтернативные инструменты миграций для Go
Кроме Goose, популярны golang-migrate и sql-migrate. Они также поддерживают тегирование и версионирование. Например, golang-migrate позволяет использовать файлы с префиксами версий и команды down N. Выбор зависит от предпочтений команды и интеграции с базой данных.
Рекомендации для надёжного отката
- Всегда храните артефакты версий миграций в CI/CD.
- Используйте уникальные идентификаторы релизов (например, теги Git) для группировки миграций.
- Тестируйте откат на стейджинге перед применением в продакшене.
- Документируйте процесс для разработчиков, чтобы избежать путаницы.
Автоматизация отката миграций с Goose в CI/CD - реальная задача, решаемая через сохранение списка версий и передачу его в джобу отката. Это исключает ручные ошибки и ускоряет развёртывание.