Skip to content

fix: harden tap bump against layout changes and bad downloads - #294

Merged
inureyes merged 1 commit into
mainfrom
fix/homebrew-bump-stanza-substitution
Jul 27, 2026
Merged

fix: harden tap bump against layout changes and bad downloads#294
inureyes merged 1 commit into
mainfrom
fix/homebrew-bump-stanza-substitution

Conversation

@inureyes

Copy link
Copy Markdown
Member

Problem

update_homebrew_formula.yml rewrote each checksum by line position:

gsed -i "/ARTIFACT\"/!b;n;c\      sha256 \"${sha}\""

It matched the url line, advanced one line (n), and replaced whatever it landed on (c\). Correct only while sha256 sits directly beneath url inside an on_macos / on_linux block, which is how Formula/all-smi.rb is written today.

lablup/mlxcel and lablup/bssh carried the same construct, all three copied from a common source. In mlxcel it went wrong: the formula moved its url to the top level with a version stanza in between, so the next bump overwrote version with the new checksum and left the previous release's sha256 below it:

  url ".../v0.4.3/mlxcel-macos-aarch64.zip"
      sha256 "dea8a5c2..."   # new hash, wrong indent, replaced `version`
  sha256 "83a0b702..."       # stale v0.4.2 hash, and this is the one that wins

No version stanza, two sha256 lines, brew install failing on checksum. Nothing validated the result and it sat broken in the tap for three days (lablup/homebrew-tap 9969ec4).

all-smi is not broken today, but it is one formula edit away from the same outcome. This is the last of the three copies.

Fix

Stanzas are located by name. set_artifact finds the url stanza whose value contains a given artifact, rewrites it, then rewrites the first sha256 stanza below it, preserving indentation. Anything in between is skipped rather than clobbered. Guards abort when the formula does not hold exactly one matching url, or when no sha256 follows it.

Two other faults, both shared with bssh and fixed the same way:

  • curl -Ls with no -f. A missing or renamed asset produced a zero-byte file whose checksum went to the tap unnoticed. Now -f --retry 3, plus an empty-file check and an archive integrity check (unzip -t / tar -tzf).
  • Unconditional git commit. Re-running for a version already in the tap failed on an empty index. It now exits cleanly.

A validation step runs ruby -c and brew style, checks the version stanza, and requires exactly the three checksums downloaded this run, which catches a substitution that silently no-ops.

Verification

test result
bump Formula/all-smi.rb to a synthetic version all three urls and checksums in the right place
validation replay (version, sha256 count, each sha present) passes
brew style on the result no offenses
workflow YAML parse OK, 8 steps
live n;c\ constructs remaining none, only the comment quoting the old form

ruby -c alone is not sufficient: the corrupted mlxcel formula was valid Ruby and passes a syntax check. That is why brew style is in the validation step.

Unrelated observation, deliberately left alone

The download base is still https://github.com/inureyes/all-smi, which works only through GitHub's rename redirect to lablup/all-smi. It also lands in the tap formula's url stanzas. Worth changing deliberately rather than as a side effect of this fix, since it alters what gets written to the tap.

Related

This workflow rewrote each checksum by line position:

    gsed -i "/ARTIFACT\"/!b;n;c\      sha256 \"${sha}\""

It matched the url line, advanced one line, and replaced whatever it
landed on. Correct only while sha256 sits directly beneath url inside an
on_macos or on_linux block, which is how Formula/all-smi.rb is written
today.

lablup/mlxcel and lablup/bssh carried the same construct, all three copied
from a common source. In mlxcel it went wrong: the formula moved its url to
the top level with a `version` stanza in between, so the next bump
overwrote `version` with the new checksum and left the previous release's
sha256 below it. The formula ended up with no version and two sha256 lines,
the second of which wins, so `brew install` failed on checksum. Nothing
validated the result and it sat broken in the tap for three days
(lablup/homebrew-tap 9969ec4).

all-smi is not broken today, but it is one formula edit away from the same
outcome. This is the last of the three copies.

Stanzas are now located by name. `set_artifact` finds the url stanza whose
value contains a given artifact, rewrites it, then rewrites the first
sha256 stanza below it, preserving indentation. Anything in between is
skipped rather than clobbered. Guards abort the run when the formula does
not hold exactly one matching url, or when no sha256 follows it, instead of
editing the wrong line.

Two other faults, both shared with bssh and fixed the same way:

Downloads used `curl -Ls` with no `-f`, so a missing or renamed asset
produced a zero-byte file and its checksum went to the tap unnoticed. They
now use `-f --retry 3`, reject empty files, and verify each archive is
readable with `unzip -t` or `tar -tzf`.

`git commit` ran unconditionally, so re-running for a version already in
the tap failed on an empty index. It now exits cleanly.

A validation step runs `ruby -c` and `brew style` on the formula, checks the
version stanza, and requires exactly the three checksums downloaded this
run, which catches a substitution that silently no-ops. `ruby -c` alone is
not enough: the corrupted mlxcel formula was valid Ruby.

Verified against the current tap formula. Bumping to a synthetic version
puts all three urls and checksums in the right place, the validation checks
pass, and `brew style` reports no offenses. The workflow YAML parses.

Unrelated observation, left alone here: the download base is still
https://github.com/inureyes/all-smi, which works only through GitHub's
rename redirect to lablup/all-smi. It also lands in the tap formula's url
stanzas. Worth changing deliberately rather than as a side effect of this
fix, since it alters what gets written to the tap.
@inureyes
inureyes merged commit 77058d0 into main Jul 27, 2026
4 checks passed
@inureyes
inureyes deleted the fix/homebrew-bump-stanza-substitution branch July 27, 2026 16:33
inureyes added a commit that referenced this pull request Jul 31, 2026
Bump the version to 0.25.0 across Cargo.toml, Cargo.lock, the manpage,
and debian/changelog, and add the README "Recent Updates" entry.

Covers the 10 commits since v0.24.2: local collection pipeline
parallelization (#299), continuous IOReport sampling and a dedicated
local polling cadence (#286), time-scrolling history graphs (#285), the
local-mode collection cost benchmark and its topology, pinning, and
affinity-mask reporting (#289, #291, #296, #298), and the Homebrew tap
bump workflow hardening and repository rename fix (#294, #295).
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