chore(ci): enable brew publish + re-flag nextjs advisory - #241
Conversation
Two coordinated CI/release changes: 1. Enable Homebrew publish via cargo-dist. The `aram-devdocs/homebrew-plumb` tap repo exists (PR #240 renamed it from `plumb-dev/homebrew-tap`), and `HOMEBREW_TAP_TOKEN` will be added as a repo secret before the next release-please PR merges. `dist-workspace.toml` now sets `tap = "aram-devdocs/homebrew-plumb"`, so `cargo dist host` in `release.yml` will push the formula on each release tag. The release-security and install-smoke validators, the v0 release-readiness runbook, and the release-prep doc all move from "brew gated" to "brew wired (live verification pending)" in lockstep so `just check` stays green. npm (#52) stays prep-only — the `@plumb` scope and `NPM_TOKEN` blockers are unchanged. 2. Re-add `continue-on-error: \${{ matrix.framework == 'nextjs' }}` on the e2e-sites matrix step. PR #235's static-export refactor did not resolve the Linux + Windows non-determinism: chromiumoxide still emits `Invalid message: data did not match any variant of untagged enum Message` warnings followed by `Request timed out` during Next.js's hydration phase. The bug fires before any wait_for selector polls, so moving the data-plumb-ready sentinel didn't help. macOS remains stable. The leg stays advisory until upstream chromiumoxide handles the Next.js hydration message stream. Tracking via re-opened #233.
|
Now I have all the context I need. Let me do the formal review. PR #241 Review —
|
| Bucket | Files |
|---|---|
ci |
.github/workflows/e2e-sites.yml, .github/workflows/release.yml |
deps |
dist-workspace.toml |
docs |
docs/src/ci/release-prep.md, docs/runbooks/v0-release-readiness-spec.yaml |
xtask (shell validators) |
tests/install-smoke-validate.sh, tests/release-readiness-matrix-validate.sh, tests/release-security-validate.sh |
No Rust changes. Determinism invariants, workspace layering, error-handling, and unsafe rules are not triggered.
Findings
release.yml — HOMEBREW_TAP_TOKEN never threaded into the publish step
The workflow header comment (lines ~9–10) now reads:
cargo-dist pushes the formula to
aram-devdocs/homebrew-plumbusing theHOMEBREW_TAP_TOKENrepo secret on each tag.
The publish job's only step that could perform this push is cargo dist host:
- name: cargo dist host
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: cargo dist host --tag "${{ github.ref_name }}" --steps=upload --steps=releaseHOMEBREW_TAP_TOKEN is not in the env: block. GitHub Actions does not auto-expose repo secrets — they must be explicitly declared. GITHUB_TOKEN is scoped to aram-devdocs/plumb and cannot write to aram-devdocs/homebrew-plumb. cargo-dist therefore has no credential to push the formula. When the first release tag fires (after the secret is added to GitHub repo settings), the formula push will fail silently or the cargo dist host step will error.
The fix is a one-liner in the publish job's cargo dist host step:
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
HOMEBREW_TAP_TOKEN: ${{ secrets.HOMEBREW_TAP_TOKEN }}release.yml — publish job, cargo dist host step env block.
tests/install-smoke-validate.sh — Stale pass message
The grep was updated to search for 'Issue #51 is wired in this repo state.' (dropping the "but unverified" phrasing), but the pass message still reads:
"release prep doc records #51 as wired-but-unverified and #52 as prep-only"
The message and the check are now out of sync. Under the no-legacy-code policy, test output text that contradicts the actual assertion is dead weight. Should read: "release prep doc records #51 as wired and #52 as prep-only".
tests/install-smoke-validate.sh — the pass call inside the #51 / #52 gate check.
Positive observations
- e2e advisory: The
continue-on-error: ${{ matrix.framework == 'nextjs' }}gate is correctly scoped and the comment is precise — names the root cause (chromiumoxide WSInvalid message), explains why the static-export refactor didn't fix it, and links the tracking issue (e2e(nextjs): convert Next.js fixture to pure static export #233). Clean. - Inversion in
release-security-validate.sh: The tap field check flipped from "must not be set" to "must be set toaram-devdocs/homebrew-plumb" and the regex is anchored correctly (^\s*tap\s*=\s*"aram-devdocs/homebrew-plumb"\s*$). No false-positive risk from substring matches. release-readiness-matrix-validate.sh: The runbook grep strings match the updated YAML verbatim.docs/src/ci/release-prep.md: Humanizer check passes — no banned phrases, MUST/MUST NOT used per RFC 2119, honest about the "wired but unverified until first tag" distinction.
Punch list
| # | File | Location | Severity | Description |
|---|---|---|---|---|
| 1 | release.yml |
publish job cargo dist host env block |
REQUEST_CHANGES | Missing HOMEBREW_TAP_TOKEN: ${{ secrets.HOMEBREW_TAP_TOKEN }} — formula push will fail when first release tag fires even after the secret is added to GitHub settings |
| 2 | tests/install-smoke-validate.sh |
pass call inside the #51/#52 gate check |
Warning | Pass message says "wired-but-unverified" but the grep now checks for "wired in this repo state" — message should say "wired" |
Verdict: REQUEST_CHANGES
Summary
Two coordinated CI/release-engineering changes that share the same merge window.
1. Enable Homebrew publish via cargo-dist
PR #240 renamed the brew tap repo to
aram-devdocs/homebrew-plumb, which now exists. TheHOMEBREW_TAP_TOKENrepo secret will be added before the next release-please PR (#101) merges, so cargo-dist can push the generated formula on each release tag.dist-workspace.tomlnow setstap = "aram-devdocs/homebrew-plumb". Thecargo dist hoststep inrelease.ymlalready drives the publish — no new steps required.To keep
just checkgreen, the brew-gating contract moves from "must not be set" to "must be set to the correct tap" across:tests/release-security-validate.sh— section 5 inverts (was: "tap must not be set"; is: "tap must bearam-devdocs/homebrew-plumb"). The "release workflow has no active brew publish" check is dropped because publish now goes throughcargo dist host, which is the intended publish path.tests/release-readiness-matrix-validate.sh— runbook expectation updates from "Homebrew (feat(release): plumb-dev/homebrew-tap + cargo-dist wiring #51) and npm (feat(release): @plumb npm org + @plumb/cli wrapper package #52) remain prep-only" to "Cargo, curl, and Homebrew (feat(release): plumb-dev/homebrew-tap + cargo-dist wiring #51) are current non-manual channels; npm (feat(release): @plumb npm org + @plumb/cli wrapper package #52) remains prep-only".tests/install-smoke-validate.sh— release-prep doc check updates to expect the new "wired but unverified" wording.docs/runbooks/v0-release-readiness-spec.yaml— acceptance criterion text updated.docs/src/ci/release-prep.md— Homebrew section rewritten to describe wired state and the live-verification gate that still keeps the install-smokebrewlegs gated..github/workflows/release.yml— header comment updated to describe brew as active and to scope the prep-only narrative to npm only.npm (#52) stays prep-only. Blockers are unchanged: the
@plumbscope,@plumb/cliownership, andNPM_TOKENare all still external to this repo.2. Re-add Next.js advisory leg in e2e-sites
PR #235 refactored the Next.js fixture to a pure static export. Subsequent CI runs confirmed the refactor did NOT fix the Linux/Windows non-determinism — same chromiumoxide WS
Invalid message: data did not match any variant of untagged enum Messagewarnings followed byRequest timed out. macOS remains stable.The bug fires BEFORE any
wait_forselector polls, so moving thedata-plumb-readysentinel to server-render didn't help. Real fix is upstream in chromiumoxide handling Next.js's hydration message stream.Re-added on the e2e harness step:
Tracking via re-opened #233.
Plumb non-negotiables
tapvalue is exactlyaram-devdocs/homebrew-plumb(matches the rename in PR chore(ci): rename brew tap to aram-devdocs/homebrew-plumb (closes #51) #240).Test plan
just checkpasses locally (verified — all 510 nextest cases + every release/security/install-smoke validator green).just determinism-checkpasses locally (verified — three runs byte-identical).cargo auditclean (verified).aram-devdocs/homebrew-plumb. Once verified end-to-end on macOS + Linux, follow up with a PR that ungates thebrewinstall-smoke legs and updatestests/install-smoke-validate.shaccordingly.Follow-ups (not in this PR)
@plumbscope and@plumb/clipackage are not reserved yet; until they are, the npm channel stays prep-only.continue-on-errorflag and close e2e(nextjs): convert Next.js fixture to pure static export #233.