Skip to content

Make the Homebrew submission automatic by being the tap - #39

Merged
bojieli merged 4 commits into
mainfrom
packaging/tap-is-this-repo
Sep 7, 2026
Merged

Make the Homebrew submission automatic by being the tap#39
bojieli merged 4 commits into
mainfrom
packaging/tap-is-this-repo

Conversation

@bojieli

@bojieli bojieli commented Sep 7, 2026

Copy link
Copy Markdown
Owner

The last manual step in a release was "copy packaging/homebrew/donottype.rb into the tap's Casks/ and push". The runbook called it unavoidable because a submission is a pull request to somebody else's repository — but that is only true of homebrew-cask, which this project has not applied to. The tap it actually told people to install from, bojieli/tap, does not exist, so the cask's own install line had never worked.

This repository becomes the tap

Casks/ is one of the three directories Homebrew looks in, so the file somebody installs is the file reviewed here. One copy, no submission, nothing to forget.

brew tap bojieli/donottype https://github.com/bojieli/DoNotType
brew install --cask donottype

The URL is needed because a tap is normally located by the name homebrew-<x> and this repository is named for the product. That is the entire cost, and it buys away a second repository, a cross-repository token, and a copy that can go stale between releases.

The bump runs itself

New packaging.yml runs on release: published, points the cask at that version with scripts/update-packaging.sh, and commits the result.

That trigger rather than the tag, because the cask cannot be correct any earlier: the script reads the checksum from the release's own .sha256 asset, which 404s while the release is still a draft. It is also the moment the artifacts become real, so it is when the tap should follow them. The rolling latest prerelease is excluded, since every green build on main republishes it and a cask following that would hand users a development build.

Kept separate from release.yml rather than bolted on: that workflow is tag-driven and ends by drafting a release for a human to read, and adding a release trigger there would have meant guarding every existing job against an event none of them want.

Three real defects Homebrew's own checks caught

Found by tapping this branch locally and running brew audit, not by reading:

  • verified: is deprecated. It warned on every command a tapped user ran, and was always redundant here — the default check is that the download host matches homepage, which it does.
  • No minimum macOS. The app requires Sonoma, per LSMinimumSystemVersion and Package.swift, but the cask promised nothing. Homebrew would install onto an older system and the app would refuse to launch.
  • The string form of depends_on macos: is deprecated too. Now the symbol form. macos_requirement.rb defaults the comparator to >=, so it is still a floor, confirmed by a dry run on macOS 26 that installs.

Verified end to end

Tapped from this branch and installed for real, into a temporary --appdir so the working install was untouched:

  • brew audit --cask --online exits 0.
  • brew install --cask downloads from the release, verifies the checksum, and installs.
  • The installed bundle reports 0.6.2 and passes Gatekeeper as Notarized Developer ID.
  • brew uninstall --cask is clean.

🤖 Generated with Claude Code

bojieli and others added 4 commits September 7, 2026 10:02
The last manual step in a release was "copy packaging/homebrew/donottype.rb into
the tap's Casks/ and push". It was documented as unavoidable because a
submission is a pull request to somebody else's repository — but that was only
true of homebrew-cask, which this project has not applied to. The tap it
actually told people to install from, bojieli/tap, did not exist, so the cask's
own install line had never worked.

So this repository becomes the tap. `Casks/` is one of the three directories
Homebrew looks in, which makes the file somebody installs the file reviewed
here: one copy, no submission, nothing to forget.

    brew tap bojieli/donottype https://github.com/bojieli/DoNotType
    brew install --cask donottype

The URL is needed because a tap is normally located by the name `homebrew-<x>`
and this repository is named for the product. That is the entire cost, and it
buys away a second repository, a cross-repository token, and a copy that can go
stale between releases.

The new packaging.yml does the bump on `release: published` and commits it. That
trigger rather than the tag, because the cask cannot be correct any earlier:
update-packaging.sh reads the checksum from the release's own .sha256 asset,
which 404s while the release is still a draft. It is also the moment the
artifacts become real, so it is when the tap should follow them. The rolling
`latest` prerelease is excluded — every green build on main republishes it, and
a cask following that would hand users a development build.

Kept separate from release.yml rather than bolted onto it: that workflow is
tag-driven and ends by drafting a release for a human to read, and adding a
release trigger there would have meant guarding every existing job against an
event none of them want.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Homebrew warns on it now, on every command a tapped user runs. It was always
redundant here: the default check is that the download host matches homepage,
and both are github.com/bojieli/DoNotType.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
brew audit caught it: the app's artifact requires Sonoma, matching
LSMinimumSystemVersion in Resources/Info.plist and .macOS(.v14) in
Package.swift, but the cask promised nothing. Homebrew would install onto an
older system and the app would refuse to launch, which is a worse way to learn
the requirement than being told before the download starts.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The string form warned on every command a tapped user ran. Homebrew's own
deprecation names the replacement, and macos_requirement.rb defaults the
comparator to >=, so the bare symbol is still a floor and not an exact match.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@bojieli
bojieli merged commit a84624e into main Sep 7, 2026
18 of 19 checks passed
@bojieli
bojieli deleted the packaging/tap-is-this-repo branch September 7, 2026 02:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant