Using Homebrew for distributing Go apps (part 2)
2023-04-13
For personal reference:
This is a followup on a previous post that is a bit more manual. This is a little bit easier.
a) Create your own Homebrew tap
Create a new GitHub public repository with a prefix homebrew-
, i.e. homebrew-tap
. This will host all the apps that you want to distribute via your tap. Users will install your apps using the following commands:
# No need to include the 'homebrew-' prefix
$ brew tap flowerinthenight/tap
$ brew install <toolname>
# Or one-liner
$ brew install flowerinthenight/tap/<toolname>
b) Let’s use Github Actions to setup goreleaser
First, add a .goreleaser.yml
config file to your Go repo. Here’s an example:
version: 2 builds: - id: "kubepfm" binary: kubepfm goos: - linux - darwin goarch: - amd64 checksum: name_template: 'checksums.txt' dist: /tmp/kubepfm/dist changelog: sort: asc filters: exclude: - '^docs:' - '^test:' release: github: owner: flowerinthenight name: kubepfm brews: - repository: owner: flowerinthenight name: homebrew-tap name: kubepfm homepage: "https://github.com/flowerinthenight/kubepfm" description: "A simple port-forward wrapper tool for multiple pods/deployments/services." directory: Formula install: | bin.install "kubepfm" test: | assert_match /A simple port-forward wrapper tool for multiple pods\/deployments\/services/, shell_output("#{bin}/kubepfm -h", 0)
The section of note here is the brews:
part. You can check goreleaser’s Quickstart guide for more information.
Here’s an example of a GitHub Action config on how to setup goreleaser to do the release for our tags.
--- name: main on: push: branches: [ master ] tags: ['*'] pull_request: branches: [ master ] jobs: codeberg: name: Codeberg runs-on: ubuntu-latest steps: - name: Checkout code uses: actions/checkout@v4 with: fetch-depth: 0 - name: Mirror to Codeberg uses: yesolutions/mirror-action@master with: REMOTE: "https://codeberg.org/flowerinthenight/kubepfm.git" GIT_USERNAME: flowerinthenight GIT_PASSWORD: ${{ secrets.GIT_PASSWORD }} build: name: Build if: "!contains(github.event.commits[0].message, 'ci skip')" runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 with: fetch-depth: 0 - name: Setup Go uses: actions/setup-go@v4 with: go-version: '1.21' - name: Run tests run: go test -v ./... - name: Build binary run: go build -v - name: Run goreleaser uses: goreleaser/goreleaser-action@v3 if: startsWith(github.ref, 'refs/tags/') with: distribution: goreleaser version: latest args: release --clean env: GITHUB_TOKEN: ${{ secrets.GH_PAT }}
See the name: Run goreleaser
section. You need to add a personal access token with repo, workflow, write:packages
permissions to your repository’s secrets. In this example, the name used is GH_PAT
but you can use other names as well.
c) Do a tagged release
Tagged releases should now do a deployment to your tap.
$ git tag v1.0.0
$ git push --tags