Create a private Tap with a custom formula and cask
Petros Amoiridis
In this tutorial we will create a private Homebrew Tap repository, add a formula and a cask to it, connect it to Workbrew, and confirm that both packages appear in the Workbrew Console. Along the way we will learn how Workbrew discovers Taps and what repository structure it expects.
Before we start, we need a GitHub organization with the Workbrew GitHub App already installed and at least one managed Device in our Workspace. If the GitHub App is not installed yet, follow Sync and authenticate private Taps with Workbrew first, then come back here.
Create the repository
First, we create a new private repository in our GitHub organization. We name it homebrew-internal. The homebrew- prefix is how Workbrew identifies Tap repositories, so the name matters.
Now we clone it and set up the directory structure:
git clone git@github.com:acme-corp/homebrew-internal.git
cd homebrew-internal
mkdir Formula Casks
Let's confirm the structure looks right:
ls -1
We should see:
Casks
Formula
Notice the capitalization: Formula is singular with a capital F, and Casks is plural with a capital C. Workbrew only looks in directories with these exact names.
Add a formula
We create a file called hello-internal.rb inside the Formula directory. This formula defines a simple internal tool:
class HelloInternal < Formula
desc "A simple greeting script from a private tap"
homepage "https://github.com/acme-corp/homebrew-internal"
url "https://github.com/acme-corp/hello-internal/releases/download/v1.0.0/hello-internal-1.0.0.tar.gz"
sha256 "e3b0c44298fc1c149afb4c8996fb92427ae41e4649b934ca495991b7852b855"
version "1.0.0"
def install
bin.install "hello-internal" => "hello-internal"
end
end
The url and sha256 point to where the source archive is hosted. For now, we are focused on getting the Tap structure right. We will come back to hosting the actual archive later.
Add a cask
Next, we create a file called example-app.rb inside the Casks directory. This cask defines an internal macOS application:
cask "example-app" do
version "1.0.0"
sha256 "b5bb9d8014a0f9b1d61e21e796d78dccdf1352f23cd32812f4850b878ae4944c"
url "https://github.com/acme-corp/example-app/releases/download/v1.0.0/ExampleApp-1.0.0.dmg"
name "Example App"
desc "An internal macOS application"
homepage "https://github.com/acme-corp/example-app"
app "Example App.app"
end
Let's check our directory tree one more time before we commit:
find . -not -path './.git/*' -not -path './.git' | sort
We should see:
.
./Casks
./Casks/example-app.rb
./Formula
./Formula/hello-internal.rb
This is exactly what Workbrew expects. Files must be inside Formula/ or Casks/ to be discovered. Anything in the repository root is ignored.
Push to the default branch
We commit and push our work:
git add Formula/hello-internal.rb Casks/example-app.rb
git commit -m "Add hello-internal formula and example-app cask"
git push origin main
Enable the Tap in Workbrew
Now we switch to the Workbrew Console. We open Workspace settings and navigate to the GitHub Installations tab.
Our homebrew-internal repository should appear in the list of available Taps. We check the box next to it to enable it, then click Sync Now.
After a moment, the sync completes. We can confirm it worked by checking the Tap's detail page in the Console. We should see both hello-internal listed as a formula and example-app listed as a cask.
What we have built
We now have a private Homebrew Tap that Workbrew has discovered and synced. The formula and cask definitions are visible in the Console and available to managed Devices in our Workspace.
If the Tap appears but no packages are listed, we should check that the formula and cask files are valid Ruby that Homebrew can parse, that they are inside Formula/ and Casks/, and that they were pushed to the default branch.
To make the formula and cask installable on Devices, their url fields must point to archives that Devices can download. See the Private Taps reference for details on URL accessibility and other constraints. For more on the formula and cask DSL, see Homebrew's How to Create and Maintain a Tap.