feat: publish a Homebrew cask and make update brew-aware - #35
Merged
Conversation
Add `brew install vyncint/tap/openshell-driver-applecontainer`. GoReleaser publishes a cask — not a formula — to vyncint/homebrew-tap on every release: Homebrew treats pre-built binaries as casks, and a cask can strip the quarantine bit our unsigned binary would otherwise be blocked by. The cask declares OpenShell as a dependency so brew installs the gateway too, unloads the driver's launchd agent on uninstall, and removes driver state on --zap. apple/container ships as a signed .pkg outside Homebrew and stays a caveat; install.sh remains the only path that installs everything. The workflow's GITHUB_TOKEN is scoped to this repository, so the tap is pushed over SSH with a deploy key that has write access to the tap and nothing else. Also fix two ways the two install paths corrupted each other: - `update` resolves symlinks to locate the running binary, which for a cask points inside Caskroom/<token>/<version>/. Replacing it there left Homebrew convinced it still had the version it staged. It now delegates to `brew upgrade --cask` and re-runs setup through the Homebrew symlink, and rejects --version, which a cask cannot honour. - install.sh would replace brew's symlink with a real file — install(1) does not write through symlinks — leaving brew owning a binary no longer on PATH. It now detects a cask install and explains both ways out. Verified against a local tap: install links and runs unquarantined, uninstall unloads the agent and removes the plist, and installing over an install.sh binary fails cleanly without touching it. Signed-off-by: Vyncint Ng <vyncint@users.noreply.github.com>
Homebrew auto-taps only the names given on the command line, never a dependency's, so on a host without the nvidia/openshell tap the cask's `depends_on formula:` warns and resolves to nothing — the driver installs without its gateway. Verified with a probe cask against an untapped third-party formula. Keep the declaration, which is correct and useful once the tap exists, but document the install as `brew install nvidia/openshell/openshell vyncint/tap/openshell-driver-applecontainer` — still one command, and it works on any host because both names are auto-tapped. Caveats say the same for anyone who installs the cask alone. Signed-off-by: Vyncint Ng <vyncint@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
brew install nvidia/openshell/openshell vyncint/tap/openshell-driver-applecontainernow works. Every release publishes a cask to vyncint/homebrew-tap.A cask, not a formula: Homebrew treats pre-built binaries that way, and a cask can strip the quarantine bit our unsigned binary would otherwise be blocked by.
brews:is deprecated in GoReleaser for exactly this reason.The cask:
depends_on arch: :arm64— an Intel Mac gets a clear message instead of "no such artifact"postflighthookuninstall launchctl:unloads the driver's launchd agent before its binary disappearszap trash:removes driver state, plist and logskip_upload: autokeeps pre-releases off the tap, sobrew upgradenever moves anyone onto onenvidia/openshell/openshellas a dependency — but see belowapple/container ships as a signed
.pkgoutside Homebrew and cannot be a dependency at all — it stays a caveat.install.shremains the only path that installs everything.Why OpenShell is named on the command line
Homebrew auto-taps only the names it is given, never a dependency's. Probed with a throwaway cask depending on an untapped third-party formula:
It warns and continues — so on a host without the
nvidia/openshelltap,depends_on formula:would install the driver with no gateway. Naming both taps in onebrew installworks on any host, and the declaration still earns its keep once the tap exists (brew installs the gateway with the driver, and warns before removing it out from under one).Publishing
The workflow's
GITHUB_TOKENis scoped to this repository and cannot commit to the tap. Rather than a PAT, the tap is pushed over SSH with a deploy key that has write access tovyncint/homebrew-tapand nothing else — narrower than any PAT, and revocable from the tap repo alone. The workflow stages it from theHOMEBREW_TAP_DEPLOY_KEYsecret into$RUNNER_TEMPand removes it in analways()step.Two ways the install paths corrupted each other
Both found by testing, both fixed here:
updateon a Homebrew install. It resolves symlinks to find the running binary, which for a cask isCaskroom/<token>/<version>/<binary>. Replacing it in place left Homebrew convinced it still had the version it staged, so a laterbrew upgrade/uninstallacted on the wrong files. It now detects a cask install, delegates tobrew upgrade --cask, and re-runssetupthrough the Homebrew symlink — the resolved path is gone once brew swaps the version directory.--versionis rejected there, since a cask only tracks the tap's latest.install.shover a Homebrew install.install(1)replaces a symlink rather than writing through it, so this left brew owning a binary that was no longer onPATHandbrew upgradesilently stopped taking effect. It now detects the cask symlink and explains both ways out.Verification
Built the cask with
goreleaser release --snapshot, served it from a local tap, and exercised the whole lifecycle on this machine:brew install --cask→ links/opt/homebrew/bin/…→ Caskroom, quarantine gone, binary runsbrew uninstall --cask→ unloadslocal.openshell-driver-applecontainer, removes the plist, unlinks the binaryinstall.shbinary →Error: It seems there is already a Binary at …, aborts without touching it (hence the migration steps now in the README)install(1)over a symlink → replaces it rather than writing through, confirming the second bug abovebrew styleclean for everything the config controls; the rest is GoReleaser's templateAlso
make lint,make sec,go test ./...,shellcheck install.sh,goreleaser check— all clean. The machine was restored to its pre-test state and re-setupafterwards.Follow-up
The cask only reaches the tap on the next tag, so
brew installstarts working with v0.2.8.