Недавно мною был открыт исходный код инструмента командной строки Swift под названием chatty, который дает вам возможность использовать ChatGPT от Open AI прямо из терминала.
Помимо возможности выпустить проект с открытым исходным кодом, я потратил некоторое время на то, чтобы автоматизировать процесс выпуска моего нового инструмента командной строки с помощью GitHub Actions.
Процесс выпуска
Я хотел сделать процесс выпуска chatty максимально простым и автоматизированным, при этом оставив для пользователей установку исполняемого файла через популярный и устоявшийся способ.
По этой причине я решил распространять мой инструмент командной строки через два различных канала:
- Homebrew - популярный менеджер пакетов для macOS, широко используемый для установки приложений командной строки.
- GitHub релизы, где пользователи могут загружать артефакты напрямую. Homebrew использует этот метод для установки исполняемых инструментов.
Обратите внимание, что приложение chatty доступно только для macOS (Intel и Apple Silicon), но в будущих версиях я планирую добавить поддержку для Linux и Windows 👀.
Поскольку проект с открытым исходным кодом, а GitHub предлагает неограниченное количество бесплатных минут для публичных репозиториев, я решил использовать GitHub Actions в качестве провайдера CI/CD, что, в свою очередь, позволило мне воспользоваться широкой экосистемой действий, управляемых сообществом, для упрощения процесса.
Создание рабочего процесса выпуска
Первый шаг к настройке рабочего процесса GitHub Actions - это создание нового файла в каталоге .github/workflows вашего репозитория. Имя файла может быть любым, я решил назвать свой release.yml.
Вызов при каждом нажатии тега
Как только я поместил файл рабочего процесса в нужную директорию, я добавил событие push с фильтром, чтобы рабочий процесс срабатывал только тогда, когда тег релиза (v*.*.*.*) будет помещен в хранилище:
release.yml
name: Release
on:
push:
tags:
- v*.*.*
Сборка исполняемого файла для выпуска
Чтобы разместить приложение, сначала мне нужно было собрать его для архитектур, которые я хотел поддерживать (macOS arm64 и x86_64).
Для этого мне нужно было указать рабочему процессу запускаться на последней версии macOS, проверить репозиторий и собрать исполняемый продукт с двумя архитектурными срезами с помощью swift build:
release.yml
name: Release
on:
push:
tags:
- v*.*.*
jobs:
release:
runs-on: macos-latest
steps:
- uses: actions/checkout@v3
- name: Build executable for release
run: swift build -c release --arch a
Создание релиза на GitHub
Затем мне нужно было создать релиз на GitHub с тегом ref в качестве имени и прикрепленным из предыдущего шага сжатым архивом артефакта:
ame: Release
on:
push:
tags:
- v*.*.*
jobs:
release:
runs-on: macos-latest
steps:
- uses: actions/checkout@v3
- name: Build executable for release
run: swift build -c release --arch arm64 --arch x86_64 --product chatty
- name: Compress archive
run: tar -czf ${{ github.ref_name }}.tar.gz -C .build/apple/Products/Release chatty
- name: Release
uses: softprops/action-gh-release@v1
with:
files: ${{ github.ref_name }}.tar.gz
token: ${{ secrets.GITHUB_TOKEN }}
Наименование тарбол архива важно, так как в следующем разделе оно используется для определения URL-адреса исполняемого файла формулы Homebrew.
Как видно в рабочем процессе выше, я обнаружил, что использование softprops' action-gh-release action было самым простым способом создания и настройки релиза для GitHub.
Создание новой версии формулы Homebrew
Как я уже упоминал в статье, мне хотелось сделать chatty доступным в Homebrew, так как это самый популярный способ установки инструментов командной строки на macOS.
Чтобы распространять мой инструмент в Homebrew, мне сначала нужно было опубликовать формулу. Я использовал существующий отвод Homebrew, который я создал для другого проекта, и добавил совершенно новую формулу, указывающую на существующий исполняемый файл chatty:
Formula/chatty-cli.rb
class ChattyCli < Formula
desc "A command line application to interact with ChatGPT directly from the terminal"
homepage ""
url "https://github.com/polpielladev/chatty-cli/archive/v1.0.2.tar.gz"
sha256 "a258e0d6d96488bbcb01b51a97e2370185c0207aea7a31565f48716060eabf56"
license ""
version "1.0.2"
def install
bin.install "chatty"
end
end
Формула имеет описание и URL-адрес к архиву релиза с соответствующей контрольной суммой SHA256. Также у неё есть метод install, который сообщает Homebrew установить исполняемый файл под названием 'chatty' (найденный в корне тарбол) в директорию двоичных файлов Homebrew пользователя.
Не смотря на то, что все работало отлично, я хотел автоматизировать данный процесс и максимально его упростить. Исследуя возможности для этого, я наткнулся на великолепный GitHub экшн от Mislav Marohnić, который, в частности, используется Fastlane для автоматического обновления их формулы Homebrew при каждом релизе.
Затем я выполнил данный экшн непосредственно после создания релиза GitHub в моем рабочем процессе:
release.yml
name: Release
on:
push:
tags:
- v*.*.*
jobs:
release:
runs-on: macos-latest
steps:
- uses: actions/checkout@v3
- name: Build executable for release
run: swift build -c release --arch arm64 --arch x86_64 --product chatty
- name: Compress archive
run: tar -czf ${{ github.ref_name }}.tar.gz -C .build/apple/Products/Release chatty
- name: Release
uses: softprops/action-gh-release@v1
with:
files: ${{ github.ref_name }}.tar.gz
token: ${{ secrets.GITHUB_TOKEN }}
- uses: mislav/bump-homebrew-formula-action@v2
with:
formula-name: chatty-cli
homebrew-tap: polpielladev/homebrew-tap
base-branch: main
download-url: https://github.com/polpielladev/chatty-cli/releases/download/${{ github.ref_name }}/${{ github.ref_name }}.tar.gz
env:
COMMITTER_TOKEN: ${{ secrets.CHATTY_COMMITTER_TOKEN }}
Мне пришлось указать в действии homebrew имя формулы (formula-name), имя моего персонального Homebrew-тапа (polpielladev/homebrew-tap), поскольку по умолчанию он использует Homebrew/homebrew-core, имя ветки для коммита новой формулы в репозиторий тапа (main) и URL-адрес загрузки исполняемого архива.
Поскольку действию необходимо создавать коммит в отдельный репозиторий, мне пришлось создать новый токен доступа к персональным данным с областью public_repo (вам может потребоваться создать его с областью repo, если ваш тап размещен в частном репозитории), добавить его в секреты репозитория как CHATTY_COMMITTER_TOKEN и передать его экшену через переменную окружения с именем COMMITTER_TOKEN.
Теперь каждый раз, когда я пушу новый тег в репозиторий, рабочий процесс будет создавать релиз GitHub, собирать исполняемый файл для macOS arm64 и x86_64, сжимать его в тарбол-архив, загружать его в релиз и создавать новую версию формулы Homebrew.
Куда идти дальше
Как я уже упоминал ранее, chatty - полностью с открытым исходным кодом, поэтому вы можете посмотреть полный рабочий процесс в репозитории GitHub.
Также, если у вас есть какие-либо предложения по улучшению данного процесса релиза, не стесняйтесь создавать issue или pull request, или пишите мне в Twitter.