Голанг: как направлять

Усильте свои сборки и выпуски приложений Go

Научитесь автоматизировать свои сборки Go и выпуски конвейеров для различных целевых сред.

Введение

Кросс-компиляция приложений Go вручную для разных сред (например, операционных систем, архитектур и т. д.) не всегда сложно; проблема в том, что это может просто стать… «грязным». И быстро.

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

Я, наверное, проповедую хору здесь, но остается вопрос — почему так много разработчиков продолжают делать это трудным путем? Зачем продолжать создавать и поддерживать пользовательские сценарии сборки? Или продолжать дважды (или трижды) проверять свою работу, пока вы можете ее автоматизировать?

Если вы еще не слышали об этом, позвольте мне представить GoReleaser, инструмент с открытым исходным кодом, который позволяет создавать, выпускать и публиковать приложения во всех предполагаемых целевых средах с помощью единого команда.

Объедините это с GitHub Actions, и теперь ваши выпуски также могут быть автоматизированы. Кроме того, вы можете создавать, тестировать и развертывать свой код прямо из GitHub.

Все, что вам нужно сделать, это убедиться, что у вас есть правильное событие и триггер, которым может быть Git push-коммит, тег или нажатие кнопки.

📌 Отказ от ответственности: GitHub Actions предлагает бесплатную версию (до 2000 минут), которую мы будем использовать здесь, и другие платные. Это не одобрение или спонсорство — я просто пытаюсь привлечь ваше внимание к полезным и доступным вариантам, имеющимся в вашем распоряжении. Вы можете заменить действия GitHub своим любимым инструментом CI.

В этой статье вы узнаете, как автоматизировать сборку с помощью GitHub Actions и GoReleaser. В частности, мы будем использовать GoReleaser для управления процессом создания приложения (для нескольких целевых сред), его выпуска и, наконец, публикации на GitHub Releases.

❗️TL;DR

Вы можете легко автоматизировать свои сборки с помощью GoReleaser и GitHub Actions и впоследствии уменьшить необходимость ручной кросс-компиляции приложений Go в разных средах.

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

И GoReleaser, и GitHub Actions предлагают бесплатные версии, которые мы будем использовать в этой статье. Следуйте за, чтобы увидеть, как.

Давайте начнем!

Краткое предисловие

Предпосылки

  • Go: Умеренное понимание
  • Git, GitHub, выпуски GitHub и действия GitHub: базовое понимание

Что вы узнаете

GoReleaser

Что это такое и как это может мне помочь?

GoReleaser помогает автоматизировать процесс выпуска приложений Go (т. е. создание, выпуск и публикацию). Вы можете использовать его локально, однако в основном он предназначен для сред CI, где вы можете автоматизировать конвейер развертывания.

💡 Большая идея: GoReleaser стремится сделать все эти скрипты устаревшими. Вместо написания скриптов вы можете написать простой файл конфигурации YAML. И вместо многих инструментов вам (обычно) нужен только один двоичный файл goreleaser.

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

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

Это делает процесс выпуска вашего приложения Go в нескольких средах очень предсказуемым и рутинным.

Локальный запуск GoReleaser

Я знаю, что мы упоминали, что GoReleaser в основном предназначен для сред CI, но прежде чем мы сможем увидеть его там — GitHub Actions в нашем случае — давайте посмотрим, как он работает локально, и продолжим.

Монтаж

Во-первых, нам нужно установить GoReleaser. Самый простой способ сделать это — использовать команду go install:

go install github.com/goreleaser/goreleaser@latest

📖 Дополнительная литература: Существует несколько других способов установки GoReleaser в вашу систему, которые вы можете найти в официальной документации здесь.

Настройка GoReleaser

GoReleaser нуждается в файле .goreleaser.yaml в корне нашего проекта, который будет содержать необходимую конфигурацию для сборки и публикации нашего приложения, предназначенного для различных сред выполнения (например, ОС).

Для начала GoReleaser предоставляет команду инициализации, которую вы можете использовать, чтобы ускорить работу. Это создаст файл .goreleaser.yaml с разумными значениями по умолчанию:

goreleaser init

Сгенерированный файл .goreleaser.yaml будет выглядеть так (без комментариев):

before:
  hooks:
    - go mod tidy
    - go generate ./...
builds:
  - env:
      - CGO_ENABLED=0
    goos:
      - linux
      - windows
      - darwin
archives:
  - replacements:
      darwin: Darwin
      linux: Linux
      windows: Windows
      386: i386
      amd64: x86_64
checksum:
  name_template: 'checksums.txt'
snapshot:
  name_template: "{{ incpatch .Version }}-next"
changelog:
  sort: asc
  filters:
    exclude:
      - '^docs:'
      - '^test:'

Как видно из приведенного выше файла конфигурации по умолчанию, GoReleaser охватывает множество областей:

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

  • pre_build: выполняется перед сборкой двоичных файлов.
  • post_build: выполняется после сборки двоичных файлов.
  • pre_release: выполняется перед выпуском двоичных файлов
  • post_release: выполняется после выпуска двоичных файлов

При сбое хука процесс выпуска будет прерван.

Сборки
Сборки позволяют настроить сборку приложений Go из целевого двоичного файла с помощью параметров GOOS, GOARCH и GOARM , которые являются стандартными для Go. Они могут помочь вам скомпилировать исходный код, создать файлы пакетов (например, ZIP-архивы), создать документацию и многое другое.

С помощью сборок вы можете указать GoReleaser собрать ваше приложение для каждой платформы, поддерживаемой Go, на которую вы хотите ориентироваться.

📖 Дополнительная литература:Вы можете узнать больше о билдах здесь

Архивы
Архивы помогают настроить имя архива, дополнительные файлы и формат по своему усмотрению. Они содержат двоичные файлы (и/или другие элементы), созданные в процессе сборки, и позволяют удобно упаковывать их для дальнейшего распространения и установки.

📖 Дополнительная литература: Вы можете узнать больше об Архиве здесь

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

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

Выпуск приложения локально

Теперь, когда у нас есть настройка GoReleaser, мы можем проверить, работает ли она, выполнив команду goreleaser release --snapshot.

goreleaser release --snapshot --rm-dist

💡 Основная идея: Флаг --rm-dist информирует GoReleaser о необходимости удалить предыдущий каталог dist, созданный предыдущими выпусками. Флаг --snapshot позволяет нам выпустить его локально на основе последнего коммита без тега git.

В вашем каталоге dist вы сможете увидеть все двоичные файлы, которые были созданы в вашем каталоге. Вот пример вывода конфигурации GoReleaser по умолчанию:

👉 Примечание. Мы создали исполняемые двоичные файлы Go для нашего приложения для всех основных ОС с помощью одной команды.

Как упоминалось ранее, вы можете настроить свои конфигурации GoReleaser, чтобы создать приложение Go так, как вы считаете нужным.

Распространение через выпуски GitHub

Выход из локальной среды

Итак, мы рассмотрели, как запускать релизы локально. Но, к сожалению, мы не собираемся распространять наши релизы таким образом; вместо этого мы будем распространять их через GitHub Releases.

👉 Примечание.GoReleaser также поддерживает несколько каналов выпуска, включая выпуски Docker, GitHub и GitLab.

По умолчанию GoReleaser попытается выяснить как можно больше информации без необходимости указывать ее.

Если вы запустите команду goreleaser release внутри репозитория, размещенного на GitHub, созданный выпуск будет находиться в GitHub Releases. То же самое относится к Gitlab и так далее. Конечно, вы можете настроить эту информацию, перейдя к официальной документации здесь, если хотите.

Создание тега Git и токена

Чтобы создать выпуск на GitHub, давайте начнем с создания тега Git в нашем репозитории и отправки его удаленно:

git tag -a v0.).1 -m "Release message - could be anything"
git push origin v0.1.1

В нашем случае выше мы пометим его как v0.0.1 .

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

❗️ Важно.Пожалуйста, убедитесь, что вы держите токен в секрете и правильно его определяете, используя Принцип наименьших привилегий.

Получив токен, установите его как переменную среды — назовем его GITHUB_TOKEN, чтобы GoReleaser мог его использовать.

export GITHUB_TOKEN="TOKEN HERE"

Создание релиза

Далее давайте запустим командуgoreleaser release для создания релиза. Мы также укажем каталог --rm-dist, чтобы очистить каталог dist, так как релиз завершится ошибкой, если он будет пуст.

goreleaser release --rm-dist 

☝️ Это соберет наше приложение, создаст релиз в GitHub Releases и загрузит бинарники. Он также добавит журнал изменений для выпуска, используя фиксации между текущим и последним тегом.

Как упоминалось ранее, вы можете настроить поведение генерации журнала изменений, обратившись к этим документам здесь.

Запуск действий GitHub

Автоматизация релизов с помощью тегов версий

До сих пор мы делали все вручную, что не идеально. Наша цель — автоматизировать процесс и снизить вероятность совершения ошибок в будущем.

Есть несколько доступных CI для работы, но мне особенно нравится GitHub Actions. Мы будем использовать его здесь для создания релиза каждый раз, когда создается новый тег версии. Это позволит нам выпустить наше приложение Go, просто создав тег и отправив его удаленно.

Теперь вы можете изменить это поведение, создав релиз для коммитов для таких вещей, как релизы, но это выходит за рамки этой статьи.

Итак, во-первых, давайте запустим наш рабочий процесс только при отправке тегов; мы будем использовать globs, чтобы убедиться, что мы нацеливаем теги, начинающиеся с v для версии:

on:
  push:
    tags:
      - "v*"

📖 Дополнительная информация: см. здесь для получения дополнительной информации о триггерах GitHub Actions.

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

Внутри задания релиза мы выполним git checkout репозитория и настроим Go, используя actions/setup-go:

jobs:
  # the workflow can contain other jobs, such as linting, testing, etc.
  release:
    runs-on: ubuntu-latest
    steps:
      # run git checkout
      - name: Checkout
        uses: actions/checkout@v3
        with:
          fetch-depth: 0

      # setup go
      - name: Set up Go
        uses: actions/setup-go@v3
        with:
          go-version: 1.19.x

Выпуск нашего приложения Go

Наконец, давайте используем действие goreleaser/goreleaser-action, чтобы выпустить наше приложение Go. Это должно создать выпуск GitHub со всеми загруженными артефактами сборки:

jobs:
  # ...
  release:
    # ...
    steps:
      # ... other steps specified above

      # run goreleaser
      - name: Run GoReleaser
        uses: goreleaser/goreleaser-action@v4
        with:
          version: latest
          args: release --rm-dist
          distribution: goreleaser
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

И это все для нашей акции GitHub! Вот как теперь должен выглядеть наш рабочий процесс:

name: Release

on:
  push:
    tags:
      - "v*"
jobs:
  # the workflow can contain other jobs, such as linting, testing, etc.
  release:
    runs-on: ubuntu-latest
    steps:
      # run git checkout
      - name: Checkout
        uses: actions/checkout@v3
        with:
          fetch-depth: 0

      # setup go
      - name: Set up Go
        uses: actions/setup-go@v3
        with:
          go-version: 1.19.x

      # run goreleaser
      - name: Run GoReleaser
        uses: goreleaser/goreleaser-action@v4
        with:
          version: latest
          args: release --rm-dist
          distribution: goreleaser
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

Запуск действия

Наконец — еще одно. Чтобы запустить наше действие GitHub, давайте создадим новый тег (начиная с v для версии) и отправим его в наш репозиторий. Таким образом, наше действие Github должно запуститься и создать релиз для соответствующего тега.

git tag -a v0.1.3 -m "Release notes"
git push origin v0.0.3

Заключение

В этом посте мы рассмотрели, как можно улучшить процесс выпуска приложений Go с помощью GoReleaser, сделав этот процесс менее болезненным и менее суетливым. Мы также узнали, как использовать GitHub Actions для автоматизации процесса выпуска всякий раз, когда новый тег отправляется в удаленный репозиторий.

Основные выводы

  • GoReleaser — это инструмент, который помогает автоматизировать процесс выпуска приложений Go путем их создания, выпуска и публикации.
  • Это также может помочь с другими аспектами процесса, такими как создание журналов изменений и их публикация в GitHub Releases.
  • Он настраивается с помощью файла YAML и поставляется с настройками по умолчанию для каждого шага процесса выпуска.
  • GoReleaser в основном предназначен для использования в средах непрерывной интеграции, но его также можно использовать локально. Чтобы использовать GoReleaser локально, необходимо установить его и создать файл конфигурации. Затем можно использовать команду goreleaser release --snapshot для проверки процесса выпуска.
  • Действия GitHub и теги Git могут помочь вам автоматизировать выпуски приложений Go, уменьшая вероятность ошибок при последовательном выполнении нескольких команд. Вы также можете создать тег и отправить его удаленно, чтобы выпустить приложение.

Другие статьи, которые могут вас заинтересовать





Раскрытие информации: в соответствии с правилами и рекомендациями Medium.com я публично подтверждаю финансовую компенсацию от UniDoc за эту статью. Все мысли, мнения, код, изображения, записи и т. д. принадлежат мне.