From aabcbb566d5cddf0d5a30f9b62803d3097f9f180 Mon Sep 17 00:00:00 2001 From: dipto0321 Date: Sun, 1 Nov 2026 23:58:39 +0600 Subject: [PATCH] docs(release): correct the tap_migrations.json format and document the hand-off MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The checklist showed a nested `{"Formula": {"nodeup": "Cask"}}` object. Homebrew's `Tap#tap_migrations` parses the file with `JSON.parse` and looks the name up directly, so the format is a flat `{old: new}` hash — the nested form resolves to nothing and the migration never fires. Also document the two traps the v1.2.2 migration actually hit: - The formula removal, the `tap_migrations.json`, and the cask must all land in the same update cycle. With the formula still present, `brew install dipto0321/tap/nodeup` resolves to the *formula* (Homebrew prints "Treating ... as a formula"), so the cask's quarantine-stripping hook would never reach users. - The cask's sha256 values must come from the release's own `checksums.txt`, not from a local `goreleaser --snapshot` render. Go builds are not byte-reproducible, so snapshot hashes do not match the published assets and the install fails with "Cask nodeup reports different checksum". --- docs/installation.md | 14 +++++++++++--- docs/release-checklist.md | 29 ++++++++++++++++++++++------- 2 files changed, 33 insertions(+), 10 deletions(-) diff --git a/docs/installation.md b/docs/installation.md index fd58c8b..b98d1cc 100644 --- a/docs/installation.md +++ b/docs/installation.md @@ -47,9 +47,17 @@ holds the cask and is auto-pushed by GoReleaser on every > **Upgrading from the old formula:** `nodeup` shipped as a Homebrew > formula up to v1.2.1 and switched to a cask in v1.2.2. The command > is unchanged (`brew install dipto0321/tap/nodeup` still works), but -> Homebrew treats a formula and a cask as different packages — so if -> you installed the formula, run `brew uninstall --formula nodeup` -> after upgrading the tap. +> Homebrew treats a formula and a cask as different packages. The tap +> carries a `tap_migrations.json`, so **`brew update` performs the +> hand-off for you**: it unlinks the old keg, installs the cask, and +> tells you to run +> `brew uninstall --formula --force nodeup` to clean up the old keg. +> If you'd rather do it by hand: +> +> ```bash +> brew uninstall --formula --force nodeup +> brew install dipto0321/tap/nodeup +> ``` **Tradeoffs:** upgrades happen via `brew upgrade`, which all Homebrew users already run on a schedule. The install lives in Homebrew's diff --git a/docs/release-checklist.md b/docs/release-checklist.md index 8cde201..85e9ab0 100644 --- a/docs/release-checklist.md +++ b/docs/release-checklist.md @@ -54,24 +54,39 @@ prefers casks for "download a binary and put it on PATH" distributions. Homebrew treats a formula and a cask of the same name as two different packages, so the old formula has to be removed from the tap by hand, and the tap needs a `tap_migrations.json` so Homebrew can -perform the hand-off automatically on `brew update`: +perform the hand-off automatically on `brew update`. + +The file is a **flat** `{old_name: new_name}` hash (not a nested +`{"Formula": {...}}` object — Homebrew's `Tap#tap_migrations` parses +it with `JSON.parse(...read)` and looks the name up directly): ```json { - "Formula": { - "nodeup": "Cask", - "nodeup@1.2.1": "Cask" - } + "nodeup": "nodeup" } ``` - [ ] `tap_migrations.json` present in `dipto0321/homebrew-tap` with - the `Formula → Cask` mapping for `nodeup` + the flat `{"nodeup": "nodeup"}` mapping - [ ] The old `nodeup.rb` formula removed from the tap (GoReleaser pushes the cask but does not delete the formula) +- [ ] The formula removal, the `tap_migrations.json`, and the cask all + land in the **same** update cycle — with the formula still + present, `brew install dipto0321/tap/nodeup` resolves to the + *formula* (Homebrew prints "Treating ... as a formula"), so the + cask's quarantine-stripping hook would never reach users - [ ] `brew install dipto0321/tap/nodeup` verified on a scratch tap - [ ] Existing formula installs get the hand-off on `brew update` - (Homebrew tells them to `brew uninstall --formula --force nodeup`) + (Homebrew unlinks the old keg, installs the cask, and tells the + user to `brew uninstall --formula --force nodeup`) + +> **Checksum trap.** Do not hand-edit the sha256 values in the cask +> from a local `goreleaser --snapshot` render — Go builds are not +> byte-reproducible, so the snapshot hashes will not match the +> published release assets and the install fails with "Cask nodeup +> reports different checksum". Generate the cask from the release's own +> `checksums.txt`, or let GoReleaser push it at tag time (which is +> what actually happens for every release after v1.2.2). ### Publishing `nodeupx` (`nodeup-npm/`) to the npm registry