GitHubActionsでリリースとHomeBrewのformulaレポジトリ更新を一度に行う
個人でHomeBrew通してバイナリを公開する時、formulaを作成してレポジトリを立ち上げる必要があります。
そこにはバージョンやリリースしたいファイルのURL、SHA256 checksumを含めなくてはならないのですが、バイナリをアップデートしたい時にソースコードのレポジトリだけでなくformulaのレポジトリも更新しなくてはならず面倒です。
そこでGitHubActionsで2つのレポジトリを連携してリリースとformulaの更新を一度に行える様にしてみました。
対象レポジトリ
Rustで書いたCLIアプリであるGitHub - QWYNG/harvest: stashes grep tool with rustとそのformulaである GitHub - QWYNG/homebrew-harvestが対象レポジトリです。
workflow
まずリリースする側のレポジトリのworkflowの設定です。長いので中略してます。
name: Release on: push: tags: - 'v*.*.*' jobs: build: strategy: matrix: os: [ubuntu-latest, macOS-latest] rust: [stable] runs-on: ${{ matrix.os }} steps: ~~~ snip ~~~ - name: Set version id: set_version run: echo ::set-output name=version::${GITHUB_REF/refs\/tags\//} env: GITHUB_REF: ${{ github.ref }} - name: Build for linux if: matrix.os == 'ubuntu-latest' run: | cargo build --release --target=x86_64-unknown-linux-musl zip -j harvest-${VERSION}-x86_64-lnx.zip target/x86_64-unknown-linux-musl/release/harvest env: VERSION: ${{ steps.set_version.outputs.version }} - name: Build for macOS if: matrix.os == 'macOS-latest' run: | cargo build --release --target=x86_64-apple-darwin zip -j harvest-${VERSION}-x86_64-mac.zip target/x86_64-apple-darwin/release/harvest env: VERSION: ${{ steps.set_version.outputs.version }} - name: Set SHA256 if: matrix.os == 'macOS-latest' id: sha_256 run: | echo "::set-output name=sha::$(shasum -a 256 harvest-${VERSION}-x86_64-mac.zip |awk '{print $1}')" env: VERSION: ${{ steps.set_version.outputs.version }} - name: Release id: release uses: softprops/action-gh-release@v1 with: files: '*.zip' env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - name: Dispatch homebrew Repo update if: matrix.os == 'macOS-latest' uses: peter-evans/repository-dispatch@v1 with: token: ${{ secrets.HOMEBREW_REPO_GITHUB_TOKEN }} repository: QWYNG/homebrew-harvest event-type: update client-payload: '{"version": "${{ steps.set_version.outputs.version }}", "sha": "${{ steps.sha_256.outputs.sha }}" }'
Build for macOS
ではビルドとzipへの圧縮を行っています。
GitHubActionsは::set-output name={name}::{value}
の形で後のstepでsteps.<step id>.outputs.{name}
として値を使用できます。これを利用してSet version
とSet SHA256
でバージョンとzipファイルのchecksumをセットしています。
最後に取得したバージョンとchecksumをrepository-dispatchをつかってformulaレポジトリに投げます。普通にcurlで発火させることもできますが、今回は
GitHub - peter-evans/repository-dispatch: A GitHub action to create a repository dispatch eventが便利そうだったので使ってみました。
dispatchを受け取るformulaレポジトリ側のworkflowは以下
name: Release on: repository_dispatch jobs: build: runs-on: ubuntu-latest steps: - uses: actions/checkout@master with: persist-credentials: false fetch-depth: 0 - name: Create local version change run: | truncate version.rb --size 0 echo 'VERSION = "${{ github.event.client_payload.version }}"' > version.rb echo 'SHA = "${{ github.event.client_payload.sha }}"' >> version.rb - name: Commit version change run: | git config --local user.email "action@github.com" git config --local user.name "GitHub Action" git commit -m "update version" -a - name: Push changes uses: ad-m/github-push-action@master with: github_token: ${{ secrets.GITHUB_TOKEN }}
dispatchで受け取ったペイロードを使ってversion.rb
を書き直してコミットしてプッシュしてます。
無事自動でformulaレポジトリを更新できました。
まとめ
愚直な実装なのでHomeBrewに詳しければもう少しスマートにできるかもしれないです。
後harvestをgit diffではなくgit stash show -pの結果で検索するように改良し、更に標準出力にページャを導入しました。大分使いやすくなったので満足。