DEV Community

Shannon
Shannon

Posted on • Edited on

Creating your own Homebrew tap and grabbing binaries from S3

Recently, I set up my own homebrew in order to easily distribute a kubectl plugin binary that I created. By creating my own homebrew, it allows me to easily download the binaries to any home dev environment without having to pull down the code from GitHub, compile it, and then add it somewhere in my $PATH in order to utilize it globally.

I ran into a few hiccups along the way, so I figured it's best to document it for next time (or if someone stumbles into this post)

Set up your own homebrew repo in GitHub

For my personal repo, I opted to name it homebrew-homebrew, as you can see here: https://github.com/lucassha/homebrew-homebrew.

The reason I chose this is because of the naming convention when tapping a new repository in brew. If, for instance, I named my repository homebrew-lucassha then I would have to run brew tap lucassha/lucassha. brew is specifically looking for repositories prepended with homebrew-.

Now, I'll tap my instance: brew tap lucassha/homebrew. You can then see all tapped repositories with just brew tap.

Add the formula to download from S3

Once you have the repo set up, you'll need to add a formula to it. Here is my specific example:

class ShowSecrets < Formula
    desc "CLI to show decoded Kubernetes secrets"
    homepage "https://github.com/lucassha/show-secrets"
    url "https://lucassha-show-secrets-releases.s3.us-west-2.amazonaws.com/releases/v0.0.1"

    # to get the latest SHA:
    # find latest release: aws s3api list-objects --bucket lucassha-show-secrets-releases | jq '.Contents[].Key'
    # download release: aws s3 cp s3://lucassha-show-secrets-releases/releases/v0.0.1 . 
    # get sha: shasum -a 256 v0.0.1
    sha256 "36018cff6708dea3587c086e366ff80bed7a2750ddda9aa7e8c1af8311b17649"

    depends_on "kubernetes-cli"

    def install
        bin.install "show-secrets"
        # add kubectl binary to make it a kubectl plugin
        bin.install "kubectl-show-secrets"
    end

    def caveats; <<-EOS
        This tool may be used as a standalone CLI or a kubectl plugin
        # example
        show-secrets -n default
        kubectl show secrets -n default
    EOS
    end
end
Enter fullscreen mode Exit fullscreen mode

The important bits to highlight here are the URL and SHA. Specifically, the URL is from S3 instead of a GitHub .tgz file. Similarly, the SHA is tarball that brew is using and not the binary. You must create a tarball.

S3 Policies

Interestingly, I was surprised that a fully public bucket still needs a GetBucket policy in order to let an anonymous user download it. You can test this with a public bucket and just running curl against it. It will fail. Similarly, you'll get a 403 error when trying to install it via brew. Because of this, a bucket policy is needed. Here is the JSON I added for the public bucket:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "Allow Public Access to All Objects",
            "Effect": "Allow",
            "Principal": "*",
            "Action": "s3:GetObject",
            "Resource": "arn:aws:s3:::lucassha-show-secrets-releases/*"
        }
    ]
}
Enter fullscreen mode Exit fullscreen mode

Install the binary

Now, you should be able to install the package!
brew install lucassha/homebrew/show-secrets

This should create two binaries, which can be seen with this command: which *show-secrets

C'est tout!

Top comments (0)