Как использовать GoReleaser для автоматизации выпусков сборки GoLang

Как использовать GoReleaser для автоматизации выпусков сборки GoLang

11 апреля 2022 г.

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


В статье все примеры будут для GitHub. Но эти же методы могут быть легко адаптированы


закрывать проекты тоже.


Я подготовил простой проект, чтобы продемонстрировать возможности GoReleaser. Этот проект состоит из двух частей клиентской и серверной. Сервер может подсчитывать количество слов


в тексте, и клиент может обратиться к серверу с запросом на количество слов.


Мне нужно сделать использование приложения максимально удобным для пользователя, и мне потребуется:


  • бинарный сервер (mac/linux/windows)

  • бинарный клиент (mac/linux/windows)

:::Информация


GoReleaser — утилита, написанная на Go, которая может выполнять все эти действия на основе простого yaml-скрипта (на самом деле утилита еще может делать много полезного).


После установки на вашу ОС вам нужно запустить команду для начала работы:


```javascript


инициализация goreleaser


• Создание файла .goreleaser.yaml


• конфиг создан; пожалуйста, отредактируйте в соответствии с вашими потребностями file=.goreleaser.yaml


Эта команда создает файл .goreleaser.yaml в корне проекта. Пока он пуст и ничего не делает, и я должен его заполнить. Так,


```javascript


Это пример файла .goreleaser.yml с некоторыми разумными значениями по умолчанию.


Обязательно ознакомьтесь с документацией на https://goreleaser.com


до:


крючки:


Вы можете удалить это, если не используете модули go.


  • приведи мод в порядок

вы можете удалить это, если вам не нужно идти генерировать


  • иди генерируй ./...

строит:


  • среда:

  • CGO_ENABLED=0

сладкие:


  • линукс

  • окна

  • Дарвин

архивы:


  • замены:

Дарвин: Дарвин


линукс: линукс


окна: окна


386: и386


амд64: x86_64


контрольная сумма:


name_template: 'контрольные суммы.txt'


снимок:


name_template: "{{ incpatch .Version }}-следующий"


журнал изменений:


сортировка: по возрастанию


фильтры:


исключать:


  • '^документы:'

  • '^ тест:'

Начну с описания раздела builds. Он определяет сборки go, которые должны быть запущены. Это создаст нужные нам двоичные файлы. Опишем это:


```javascript


строит:


  • идентификатор: срв

двоичный файл: срв


среда:


  • CGO_ENABLED=0

сладкие:


  • линукс

  • окна

  • Дарвин

основной: ./cmd/сервер/main.go


  • идентификатор: кли

бинарный: кли


среда:


  • CGO_ENABLED=0

сладкие:


  • линукс

  • окна

  • Дарвин

основной: ./cmd/client/main.go


В этой конфигурации я установил две сборки, потому что необходимо собрать сервер и клиент. Обе сборки выглядят примерно одинаково. Я указываю, какой main.go следует использовать и как следует вызывать полученный двоичный файл.


Также я указал GOOS и перечислил платформы, для которых мне нужно собрать бинарники, то есть в результате должно получиться не один файл клиента и сервера, а три: Linux, Mac и Windows. Если бы построение производилось вручную, это выглядело бы так:


```javascript


CGO_ENABLED=0 GOOS=darwin go build -o srv


Это пример только для Mac и только для сервера. То есть один корпус из 6. Помимо ОС можно указать еще и архитектуры:


```javascript


гоарх:


  • amd64

  • рука

  • рука64

И потом, каждая ОС все равно будет собирать дополнительный бинарник для каждой архитектуры. Чтобы не собирать какие-то конкретные пары ОС/архитектура, которые вам не нужны, нужно указать их в списке:


```javascript


игнорировать:


  • гус: Дарвин

гоарх: 386


  • гус: линукс

гоарх: рука


гоарм: 7


В своем примере я этого делать не буду, чтобы не усложнять понимание результата большим количеством результирующих файлов. Позже читатель сможет добавить это в свои реальные проекты. Также часто могут быть затронуты дополнительные переменные среды. Например, в своих последних проектах я использовал GOPROXY, GOPRIVATE. Все их можно указать в разделе env, который для каждой сборки отдельный.


Позвольте мне показать вам, как работает строительство:


```javascript


выпуск goreleaser --skip-publish --snapshot


• освобождение...


• загрузка конфигурационного файла file=.goreleaser.yaml


• загрузка переменных окружения


• получение и проверка состояния git


• игнорирование ошибок, поскольку это моментальный снимок error=git не содержит никаких тегов. Либо добавьте тег, либо используйте --snapshot


• создание... commit=87eea7148d7e07b947cdef49e0b1b6a8c406a60e последний тег=v0.0.0


• ошибка пропущенного канала = отключено в режиме моментального снимка


• тег синтаксического анализа


• бег перед крюками


• бегущий хук = иди мод аккуратно


• работающий хук=иди сгенерируй ./...


• установка значений по умолчанию


• моментальные снимки


• создание моментального снимка... версия=0.0.1-следующая


• проверка каталога дистрибутива


• загрузка информации о моде


• создавать предварительные условия


• написание эффективного конфигурационного файла


• запись config=dist/config.yaml


• создание двоичных файлов


• сборка бинарника=/Users/antgubarev/project/gorelex/dist/srv_darwin_arm64/srv


• сборка бинарника=/Users/antgubarev/project/gorelex/dist/srv_linux_amd64/srv


• сборка бинарника=/Users/antgubarev/project/gorelex/dist/srv_windows_386/srv.exe


• сборка бинарника=/Users/antgubarev/project/gorelex/dist/srv_linux_arm64/srv


• сборка бинарника=/Users/antgubarev/project/gorelex/dist/srv_windows_arm64/srv.exe


• сборка бинарника=/Users/antgubarev/project/gorelex/dist/srv_windows_amd64/srv.exe


• сборка бинарника=/Users/antgubarev/project/gorelex/dist/srv_linux_386/srv


• сборка бинарника=/Users/antgubarev/project/gorelex/dist/srv_darwin_amd64/srv


• сборка бинарника=/Users/antgubarev/project/gorelex/dist/cli_windows_386/cli.exe


• сборка бинарника=/Users/antgubarev/project/gorelex/dist/cli_windows_amd64/cli.exe


• сборка бинарника=/Users/antgubarev/project/gorelex/dist/cli_linux_386/cli


• сборка бинарника=/Users/antgubarev/project/gorelex/dist/cli_linux_amd64/cli


• сборка бинарника=/Users/antgubarev/project/gorelex/dist/cli_linux_arm64/cli


• сборка бинарника=/Users/antgubarev/project/gorelex/dist/cli_darwin_amd64/cli


• сборка бинарника=/Users/antgubarev/project/gorelex/dist/cli_darwin_arm64/cli


• сборка бинарника=/Users/antgubarev/project/gorelex/dist/cli_windows_arm64/cli.exe


• архивы


• создание архива=dist/gorelex_0.0.1-next_Linux_x86_64.tar.gz


• создание архива=dist/gorelex_0.0.1-next_Linux_arm64.tar.gz


• создание архива=dist/gorelex_0.0.1-next_Darwin_x86_64.tar.gz


• создание архива=dist/gorelex_0.0.1-next_Darwin_arm64.tar.gz


• создание архива=dist/gorelex_0.0.1-next_Windows_arm64.tar.gz


• создание архива=dist/gorelex_0.0.1-next_Windows_i386.tar.gz


• создание архива=dist/gorelex_0.0.1-next_Linux_i386.tar.gz


• создание архива=dist/gorelex_0.0.1-next_Windows_x86_64.tar.gz


• вычисление контрольных сумм


• хранение списка артефактов


• запись файла=dist/artifacts.json


• релиз успешен через 3,39 с


Из журнала видно, какие файлы были собраны и что все они находятся в каталоге /dist. Я передал два аргумента в начале команды:


  • --skip-publish По умолчанию GoReleaser немедленно публикует файлы. Это пока не требуется, так как мы все еще занимаемся отладкой, но нам это понадобится позже.

  • --snapshot Выпуск должен быть создан с версией. GoReleaser берет версию из последнего тега git. И так как еще нет, мне нужен этот флаг.

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


:::Информация


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


По умолчанию имя архива создается с использованием следующего шаблона {{ .ProjectName }}_{{ .Version }}_{{ .Os }}_{{ .Arch }}{{ if .Arm }}v{{ .Arm }}{{ end }}{{ if .Mips }}_{{ .Mips }}{{ end }}


(вы также можете заменить этот шаблон для ваших нужд). В разделе замены указаны соответствующие замены для переменных в шаблоне. По умолчанию этот параметр пуст, но, к счастью, в созданном .goreleaser.yaml уже указаны комбинации, которых достаточно.


Текущие созданные архивы содержат файлы srv и client. Иногда может быть необходимо иметь их в разных архивах. Это можно легко сделать:


```javascript


архивы:


идентификатор: срв


строит:


  • срв

замены:


Дарвин: Дарвин


линукс: линукс


окна: окна


386: и386


амд64: x86_64


name_template: "{{ .ProjectName }}srv{{ .Version }}{{ .Os }}{{ .Arch }}"


файлы:


  • ЛИЦЕНЗИЯ

  • README.md

  • документ/сервер/*

идентификатор: кли


строит:


  • кли

замены:


Дарвин: Дарвин


линукс: линукс


окна: окна


386: и386


амд64: x86_64


name_template: "{{ .ProjectName }}cli{{ .Version }}{{ .Os }}{{ .Arch }}"


файлы:


  • ЛИЦЕНЗИЯ

  • README.md

  • документ/кли/*

В этом примере я перечислил архивы, которые необходимо создать. В разделе «сборки» я перечислил сборки, которые необходимо заархивировать. То есть вы можете распространять любые файлы для удобства пользователей. Это может быть полезно в таких проектах, где много компонентов.


Например, помимо клиента и сервера могут быть другие агенты и утилиты для резервного копирования и мониторинга. Тогда будет повод отделить утилиту CLI от остальных серверов.


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


И я не могу не упомянуть еще одну возможность. Его крючки.


```javascript


до:


крючки:


  • сделать чистым

  • приведи мод в порядок

Этот функционал позволяет выполнять дополнительные действия перед сборкой. Например, удалите лишние пакеты или создайте файл конфигурации по умолчанию и т. д. Я бы рекомендовал сделать это в качестве шага конвейера, когда дело доходит до встраивания GoReleaser в вашу систему непрерывной доставки. Но когда эта опция недоступна, крючки будут очень кстати. Я обычно добавляю:


```javascript


rm -rf расстояние/


Это удобно при отладке, потому что для сборки целевой каталог должен быть пустым.


Итак, проект готов к первому релизу. Напомню, что в рамках этой статьи я выпущу ее на GitHub. Зафиксируйте наш .goreleaser.yaml. Не забудьте добавить /dist к . gitignore! Эти файлы артефактов точно не принадлежат репозиторию. Теперь нужно создать тег и сразу его нажать.


```javascript


Git-тег v0.1.0


git push --tags мастер происхождения


GoReleaser требует токен GitHub, чтобы иметь возможность использовать GitHub API для создания и редактирования выпусков. Вы можете создать его в своих настройках. Вам просто нужно поставить на управление публичными репозиториями флаг «Доступ к публичным репозиториям».


```javascript


экспортировать GITHUB_TOKEN=xxx


Наконец-то начните строительство без дополнительных флагов


В логи добавлена ​​информация о создании релиза в репозиторий GitHub.


```javascript


• публикация


• SCM-релизы


• создание или обновление репозитория релиза=antgubarev/pet tag=v0.1.0


• обновленный релиз url=https://github.com/antgubarev/pet/releases/tag/v0.1.0


• загрузка в релиз file=dist/checksums.txt name=checksums.txt


• загрузка в релиз file=dist/pet_cli_0.1.0_Linux_x86_64.tar.gz name=pet_cli_0.1.0_Linux_x86_64.tar.gz


• загрузка в релиз file=dist/pet_srv_0.1.0_Windows_i386.tar.gz name=pet_srv_0.1.0_Windows_i386.tar.gz


• загрузка в релиз file=dist/pet_srv_0.1.0_Linux_x86_64.tar.gz name=pet_srv_0.1.0_Linux_x86_64.tar.gz


• загрузка в релиз file=dist/pet_srv_0.1.0_Linux_i386.tar.gz name=pet_srv_0.1.0_Linux_i386.tar.gz


• загрузка в релиз file=dist/pet_srv_0.1.0_Darwin_x86_64.tar.gz name=pet_srv_0.1.0_Darwin_x86_64.tar.gz


• загрузка в релиз file=dist/pet_cli_0.1.0_Linux_i386.tar.gz name=pet_cli_0.1.0_Linux_i386.tar.gz


• загрузка в релиз file=dist/pet_srv_0.1.0_Windows_arm64.tar.gz name=pet_srv_0.1.0_Windows_arm64.tar.gz


• загрузка в релиз file=dist/pet_cli_0.1.0_Darwin_arm64.tar.gz name=pet_cli_0.1.0_Darwin_arm64.tar.gz


• загрузка в релиз file=dist/pet_cli_0.1.0_Windows_i386.tar.gz name=pet_cli_0.1.0_Windows_i386.tar.gz


• загрузка в релиз file=dist/pet_srv_0.1.0_Linux_arm64.tar.gz name=pet_srv_0.1.0_Linux_arm64.tar.gz


• загрузка в релиз file=dist/pet_cli_0.1.0_Windows_arm64.tar.gz name=pet_cli_0.1.0_Windows_arm64.tar.gz


• загрузка в релиз file=dist/pet_srv_0.1.0_Darwin_arm64.tar.gz name=pet_srv_0.1.0_Darwin_arm64.tar.gz


• загрузка в релиз file=dist/pet_cli_0.1.0_Windows_x86_64.tar.gz name=pet_cli_0.1.0_Windows_x86_64.tar.gz


• загрузка в релиз file=dist/pet_cli_0.1.0_Darwin_x86_64.tar.gz name=pet_cli_0.1.0_Darwin_x86_64.tar.gz


• загрузка в релиз file=dist/pet_cli_0.1.0_Linux_arm64.tar.gz name=pet_cli_0.1.0_Linux_arm64.tar.gz


• загрузка в релиз file=dist/pet_srv_0.1.0_Windows_x86_64.tar.gz name=pet_srv_0.1.0_Windows_x86_64.tar.gz


• объявление


• релиз успешен через 7,08 с


Перейдите на страницу выпуска и посмотрите



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


Вот такую ​​простую вещь я и сделал за короткое время, чтобы организовать релизы проекта. Конечно, с помощью GitHub Workflow автоматизировать это было даже удобнее. Но это выходит за рамки этой темы. В будущих статьях я опишу, как можно сделать проект с открытым исходным кодом еще более привлекательным с помощью GitHub Workflow и возможностей golangci-lint.



Оригинал
PREVIOUS ARTICLE
NEXT ARTICLE