Skip to content

fix(bestax-mcp): release with every bulma-ui release so the published index keeps up - #1027

Merged
allxsmith merged 2 commits into
mainfrom
fix/932-mcp-releases-with-library
Oct 10, 2026
Merged

allxsmith merged 2 commits into
mainfrom
fix/932-mcp-releases-with-library

Conversation

@allxsmith

@allxsmith allxsmith commented Oct 10, 2026 •

Copy link
Copy Markdown
Owner

#1018 fixed the first half of #932: the publish job now regenerates bestax-mcp's index after bulma-ui releases and before bestax-mcp does, so a run that releases both ships an index stamped with the library it just released. That only helps when bestax-mcp actually releases, though, and it only ever released on its own commits. Any run that shipped just the library left npm serving the old index. Right now the newest bestax-mcp on npm, 1.14.3, ships an index stamped bestax-bulma 5.27.2, and bestax-bulma is on 5.27.8.

So this makes bestax-mcp cut a patch every time bulma-ui releases. The index documents the library, so it should ship when the library does.

Why it's config and not a workflow change

The job already does the hard part in the right order. What was missing was a decision about when bestax-mcp releases, and that decision already has a home in bestax-mcp/release.config.js. Doing it in the workflow would have meant a second place that decides releases, plus a step that either fakes a commit or works around semantic-release, sitting in the job that holds the bypass token. Nothing under .github/ changes here.

How the rules work

  • The negated scope rule is now { scope: '!(bestax-mcp|bulma-ui)', release: false }, so it never meets a bulma-ui commit.
  • A new bulma-ui group gives a patch to feat, fix, perf, refactor and style, which are the types bulma-ui releases on, plus any breaking bulma-ui commit. It's a patch whatever bulma-ui's own bump, a major included. The server's tools and prompts don't change, only what they answer from, and a major would strand every bestax-mcp@1 install and listing.

The part that surprised me: the old comment said a matching release: false always wins. It doesn't quite. commit-analyzer walks the matching rules in order, a false replaces whatever came before it, a release type after a false replaces the false, and major ends the walk. That's why chore(bulma-ui) with a BREAKING CHANGE: footer releases a bulma-ui major today even though { type: 'chore', release: false } matches it: the major ends the walk first. Here the breaking rule gives a patch, which ends nothing, so it has to sit below the non-releasing types or a breaking build(bulma-ui) would release a library major and no index. The config says all of this next to the rules.

Two more things fell out of that. The glob change isn't what makes bulma-ui commits release here, since the bulma-ui rules come later and would beat that false anyway. What it buys is that the rule's place in the list stops mattering. And the glob change without the new rules would be worse than doing nothing: bulma-ui commits would fall through to the angular defaults and give bestax-mcp a minor or a major.

How I checked it

scripts/release-rules.test.mjs runs commits through the actual commit-analyzer, the copy semantic-release resolves for itself, rather than reading the rules. It takes every type commitlint accepts, with and without a BREAKING CHANGE: footer, scoped to bulma-ui, and holds bestax-mcp to a patch exactly when bulma-ui releases. It also checks mixes, bestax-mcp's own bumps, other scopes, the release job's own chore commits, and that the link only runs one way.

To make sure the test bites, I mutated the config and ran the test against each change: the breaking rule moved above the non-releasing types, a bulma-ui rule dropped, one set to minor, the whole group dropped, and the old glob moved to the end of the list. Every one fails. The one mutation that passes is putting the old glob back in its old spot, which gives the same answers.

The same commits through both versions of the config, with bulma-ui's unchanged config for comparison:

Commit bulma-ui bestax-mcp before bestax-mcp after
feat(bulma-ui) minor none patch
fix(bulma-ui) patch none patch
feat(bulma-ui) + BREAKING CHANGE: major none patch
build(bulma-ui) + BREAKING CHANGE: major none patch
docs(bulma-ui), chore(bulma-ui) none none none
fix(create-bestax), docs:, chore(release) none none none
feat(bestax-mcp) none minor minor
feat(bestax-mcp) + BREAKING CHANGE: none major major
feat(bulma-ui) + BREAKING CHANGE: and fix(bestax-mcp) major patch patch
feat(bulma-ui) and fix(create-bestax) and docs: minor none patch

I also ran the real commits on main since bestax-mcp@1.14.3. With main's config there's no release pending, with this branch's there's a patch from the bulma-ui fixes that already shipped, and bulma-ui's answer doesn't move. This commit is fix(bestax-mcp) too, so merging it releases bestax-mcp right away with the current index.

The changelog

release-notes-generator already lists feat, fix and perf commits from every scope. bestax-mcp's CHANGELOG has bulma-ui and bestax-migrate entries in it today, so I left release-notes-generator as it is. What's new is that some bestax-mcp releases will be nothing but bulma-ui commits, and a breaking bulma-ui commit lands under BREAKING CHANGES in a bestax-mcp patch. I generated notes for a sample range to see it. It reads a little odd, but those are the changes the new index describes, and the config comment says so.

Prose the change made stale

The other release configs said a matching release: false always wins, which is the claim that makes the ordering above look unnecessary. They now say only that every rule is checked, comments only, and every config gives the same answers. VERSIONING.md also loses the table row that said docs, chore, ci, test and build release nothing in any scope, since a breaking build(bulma-ui) is a library major and now a bestax-mcp patch too. The docs-site contributing guide drops the same claim and points at the bestax-mcp patch, and bulma-ui/CLAUDE.md says its releases patch bestax-mcp.

The plugin and its listings

The bestax plugin pins bestax-mcp, and skills-publish.yml relays every bestax-mcp@ release into a publish run on main. Its version counts commits that touch bestax-mcp/package.json, so each bestax-mcp release also bumps the plugin. More bestax-mcp releases means more plugin publishes and more update prompts for plugin users. Nothing in that flow breaks: the relay already filters to bestax-mcp@ tags, publish runs share a concurrency group that never cancels one midway (a newer pending run replacing an older one loses nothing, since it checks out main later), and --require-published retries a 404 for about a minute before refusing a pin npm doesn't serve yet. The restamp commit only touches data/catalog.json, which isn't plugin content, so it adds no bump of its own. The MCP Registry gets a listing per release the same way it does now, and Glama already rebuilds on every GitHub release in the repo.

So the distribution guide's "A plugin release" bullet now applies to every bulma-ui release. The entries it names pin the plugin version by hand (awesome-copilot, the OpenAI directory, Kiro, Cursor Marketplace and Build with Claude), so each one that lists the plugin falls a release behind every time bulma-ui ships, and nothing in CI can see it. The bullet already says to update them when a release should reach them, and that stays a call per release rather than a chore for every bulma-ui PR. None of the other "What goes stale" triggers apply: these are patches, no skill or tool changes, and the start command and major stay put.

What this leaves alone

Index changes that don't come from a bulma-ui release, like a fix(docs) to an API page's usage section, a skill edit, or a bestax-migrate class map change, still wait for the next bulma-ui or bestax-mcp release. In practice that's usually the next bulma-ui release now.

Checked with the new test, test:scripts (coverage floors hold), check:conformance, prettier and eslint.

Fixes #932

… index keeps up

The release job regenerates bestax-mcp's index after bulma-ui releases and before bestax-mcp
does (#1018), but bestax-mcp only released on its own commits, so a run that shipped only the
library left npm serving an index stamped with an older bestax-bulma.

bestax-mcp's release rules now give a patch to every commit that releases bulma-ui, a bulma-ui
major included, and the negated scope rule leaves bulma-ui out. The breaking rule sits last
because commit-analyzer walks the rules in order and a patch, unlike bulma-ui's major, does not
end the walk before a type's `release: false`.

scripts/release-rules.test.mjs runs commits through the commit-analyzer semantic-release loads
and holds the two packages' rules together. VERSIONING.md states the exception, and CLAUDE.md,
CONTRIBUTING.md and bestax-mcp/CLAUDE.md point to it.

Fixes #932
@coderabbitai

coderabbitai Bot commented Oct 10, 2026 •

Copy link
Copy Markdown

Warning

Review limit reached

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

Next included review available in 53 minutes.

Check out review usage here.

View limit details

Limit details: You’ve used the included review currently available.

Learn how review limits work.

Review configuration:

⚙️ Run configuration
  • Configuration used: Repository: allxsmith/bestax/.coderabbit.yaml
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 3efefbee-939f-4a22-acb4-053c981dde2b

📥 Commits

Reviewing files that changed from the base of the PR and between 9680d85 and 77047b4.


📒 Files selected for processing (12)
  • CLAUDE.md
  • CONTRIBUTING.md
  • VERSIONING.md
  • bestax-mcp/CLAUDE.md
  • bestax-mcp/release.config.js
  • bestax-migrate/release.config.js
  • bulma-ui/CLAUDE.md
  • bulma-ui/release.config.js
  • create-bestax/release.config.js
  • docs/docs/guides/getting-started/contributing.md
  • eslint-plugin/release.config.js
  • scripts/release-rules.test.mjs

  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions

Copy link
Copy Markdown
Contributor

Preview Deployment

Preview URL: https://559f8fb3.bestax.pages.dev

Comment thread CLAUDE.md
Comment thread VERSIONING.md Outdated

@claude claude Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Deep review — 0 blocking · 2 advisory

# Severity Area Finding Location
1 🔵 Advisory Robustness PR body's "Listings: nothing applies" contradicts its own "The plugin" section — the A plugin release bullet now fires per bulma-ui release CLAUDE.md:121 (PR body; no line of its own)
2 🔵 Advisory Correctness Surviving release prose contradicts the mechanism this PR documents: the non-releasing-types table row, release: false "always wins" in three other configs, and the un-mirrored CONTRIBUTING bullet VERSIONING.md:33

Overall: The change is sound, and the reasoning in bestax-mcp/release.config.js is correct where it matters most — I read analyze-commit.js and compare-release-types.js at the resolved commit-analyzer@13.0.1 and confirmed that release: false has index -1, so later wins in both directions, which is exactly why the bulma-ui breaking rule has to sit below the release: false types. The riskiest part is not the rules but the blast radius: every bulma-ui release now also cuts bestax-mcp, which cuts a plugin version, which reaches hand-maintained third-party listings — and the PR body tells the maintainer no listing is affected. Focus there first; the rules themselves are the best-tested thing in the diff.

Residual risk:

  • Ordering regression in the rule list. Refuted — the new suite bites. TYPES is the union of commitlint's type-enum and every type either rule list names, so moving { breaking: true, scope: 'bulma-ui', release: 'patch' } above { type: 'build', release: false } flips build(bulma-ui) + footer from patch to null while bulma-ui still says major, and the equivalence assertion fails. I verified all five new tests pass (pnpm test:scripts, exit 0, floors held) and that the seen vacuity guard really collects major/minor/patch/null.
  • A new releasing type added to bulma-ui and not mirrored here. Refuted — covered by the same union plus equivalence assertion; the test does not read the rules, it runs the analyzer semantic-release resolves.
  • The negated-glob widening (!(bestax-mcp) to !(bestax-mcp|bulma-ui)) letting a bulma-ui commit fall through to the angular defaults and over-bump. Refuted by enumeration: the only commitlint type with no rule in either group is revert, and revert(bulma-ui) reaches the defaults where neither the revert flag (the angular revertPattern never matches the parenthesised form) nor the type matches — null both before and after. With a footer it hits the new breaking rule for a patch.
  • Git-style Revert "…". Unchanged: it has no scope, so neither glob ever matched it, and { revert: true, release: 'patch' } in the defaults patch-releases every package exactly as commitlint.config.js already documents.
  • Unscoped feat:/fix: would give bestax-mcp a minor, not the "patch whatever bulma-ui's bump" the comment promises — the defaults, not the new group, decide it. Open but not reachable past commitlint's release-scope-required, and pre-existing for every package. The new suite covers unscoped docs:/chore:/chore(release): but no unscoped releasing type.
  • A bestax-mcp release in a run where bulma-ui does not release. Open, and newly automatic. If bulma-ui's prepare lands the tag and publish fails, the version is spent (VERSIONING.md); the next push to main now releases bestax-mcp alone, and pnpm publish resolves its @allxsmith/bestax-bulma: workspace:^ against the bumped bulma-ui/package.json, pinning a range npm does not serve. Pre-existing shape — any fix(bestax-mcp) did the same — but this PR guarantees the next push triggers it. The inverse ordering (bulma-ui succeeds, bestax-mcp's step fails) I checked and it is the recovery path: Regenerate the MCP index reruns and the tarball gets the right stamp.
  • Downstream frequency. Named rather than refuted: skills-publish.yml's relay filter (startsWith(github.event.release.tag_name, 'bestax-mcp@')), its skills-publish group with cancel-in-progress: false, and --require-published's bounded backoff all check out as the body claims — but each is now exercised per bulma-ui release, so an npm propagation lag longer than that backoff reds a publish run proportionally more often. Same for mcp-registry.yml and Glama's per-release rebuild.
  • Index freshness on a non-bulma-ui change (a fix(docs) to an API page, a skill edit, a bestax-migrate class map change) still waits for the next release. Stated in the body and genuinely out of scope here.

🏄 Dude, this one's a clean little drop-in — the rules ride the analyzer's actual walk instead of guessing at it, and the test paddles out and checks every type with and without a breaking footer, so nobody's getting worked by a stale index again. Only thing dragging is the prose on the beach behind it: the listings note says the tide didn't move when the PR's own plugin section says it did. Patch the sign, send it. 🌊

…ch contradicts

- VERSIONING.md loses the table row saying the non-releasing types release nothing in any
  scope. A breaking `build(bulma-ui)` is a bestax-bulma major and a bestax-mcp patch, and the
  rows and the footer note left behind are all true.
- The other release configs no longer say a matching `release: false` always wins. A release
  type matching after a `false` replaces it, so the claim and the rule it justified both go.
  Comments only: every config gives the same answers.
- The docs-site contributing guide drops the same "don't publish" claim and points at the
  bestax-mcp patch, and bulma-ui/CLAUDE.md says its releases patch bestax-mcp.
@allxsmith

Copy link
Copy Markdown
Owner Author

deep-review: verify

Every open thread has a reply: fixed, with the commit, or refuted with a reason. This settles them on 77047b4.

@github-actions

Copy link
Copy Markdown
Contributor

Preview Deployment

Preview URL: https://649d76c2.bestax.pages.dev

@claude claude Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Deep review (verify) — 2 resolved · 0 open

# Severity Area Finding Location
1 🔵 Advisory Robustness PR body's "Listings" section contradicted its own "The plugin" section — verified fixed, the two are now one "The plugin and its listings" section that names the hand-pinned entries PR body (anchored CLAUDE.md:121)
2 🔵 Advisory Correctness Release prose contradicting the mechanism (the "(any scope)" table row, "a release: false always wins" in four configs, the docs-site mirror and bulma-ui/CLAUDE.md) — verified fixed by deletion in all three places VERSIONING.md:33

Overall: This pass settled threads and reviewed no commits. Both of the previous review's advisory threads are addressed in 77047b4b, by deletion rather than by added qualifiers, and both are now resolved. I re-read each site against the current tree and ran scripts/release-rules.test.mjs through pnpm test:scripts: all seven release-rules tests pass, including bestax-mcp patches on exactly the bulma-ui commits that release bulma-ui; the only failures in that run are the documented bulma-ui/dist is absent artefacts of a checkout without a build. While checking thread 2 I also confirmed the one claim the deleted row left exposed — A commit scoped to docs never releases any package — is true, since the suite asserts a breaking feat(create-bestax) gives bestax-mcp null, so a matching release: false does not fall through to the angular defaults.

Residual risk: none identified for this pass — it settles threads only and raises nothing new. A reader who wants the current code reviewed should ask with a deep-review: fresh steer.

🏄 Author caught both advisories clean and paddled back with deletions instead of word salad — the table's tighter, the four configs stopped claiming something the analyzer never did, and the tests still roll in. Zero open threads, good to go.

@github-actions github-actions Bot added the review-converged Deep review converged: no blocking findings, all review threads resolved, checks green label Oct 10, 2026
@allxsmith allxsmith added the needs-human-review Loop converged (or contested): awaiting owner review + manual merge label Oct 10, 2026
@github-actions

Copy link
Copy Markdown
Contributor

📸 Story screenshots at handoff — 77047b4

No Storybook stories map to this PR's changed files — nothing to screenshot. (workflow run)

@github-actions github-actions Bot added review-converged Deep review converged: no blocking findings, all review threads resolved, checks green and removed review-converged Deep review converged: no blocking findings, all review threads resolved, checks green labels Oct 10, 2026
@allxsmith
allxsmith merged commit 618e483 into main Oct 10, 2026
77 checks passed
@allxsmith
allxsmith deleted the fix/932-mcp-releases-with-library branch October 10, 2026 22:44
bestax-release-bot Bot pushed a commit that referenced this pull request Oct 10, 2026
## [1.14.4](https://github.com/allxsmith/bestax/compare/bestax-mcp@1.14.3...bestax-mcp@1.14.4) (2026-10-10)

### Bug Fixes

* **bestax-mcp:** release with every bulma-ui release so the published index keeps up ([#1027](#1027)) ([618e483](618e483))
* **bulma-ui:** accept material-symbols 0.47 in the peer range ([539cca2](539cca2))
* **bulma-ui:** drop a Field label's for when nothing it holds takes it ([#1020](#1020)) ([3604c14](3604c14))
* **bulma-ui:** keep a Notification's text clear of its close button ([#1017](#1017)) ([91ebb63](91ebb63))
* **bulma-ui:** keep Theme's component-variable check out of production ([537d90d](537d90d))
* **bulma-ui:** let a caller's aria-label or aria-labelledby name both range Slider thumbs ([047ff7c](047ff7c)), closes [#974](#974)
* **bulma-ui:** name a composed DateRangeInputBase's group from a Field label ([75aa6cb](75aa6cb))
* **bulma-ui:** name a range Slider's thumbs from a hand-wired Field label's id ([355065b](355065b))
* **bulma-ui:** name Autocomplete's list from a hand-wired Field label's id ([ad46c06](ad46c06))
* **bulma-ui:** name Autocomplete's suggestion list from a surrounding Field's label ([190183f](190183f)), closes [#998](#998)
* **bulma-ui:** name each range Slider thumb from its label ([6b962e3](6b962e3)), closes [#981](#981)
* **bulma-ui:** name the date and time picker bases from a Field label ([e7ae797](e7ae797))
* **bulma-ui:** say a label placed in Field.Label reaches no thumbs or list ([07c2a99](07c2a99))
* **bulma-ui:** say FieldLabel renders the label column, not a label ([2a6ab10](2a6ab10))
* **bulma-ui:** say the label prop needs wiring to reach thumbs or list in an inner Field ([9b33d8d](9b33d8d))
* **bulma-ui:** say which controls a hand-wired Field label's id reaches ([514127f](514127f))
* **bulma-ui:** warn when Theme is given a variable Bulma sets on the component ([bb8f9b8](bb8f9b8)), closes [#1021](#1021)
* **create-bestax:** announce the starter's notifications through a status region ([91dbfd5](91dbfd5))
* **create-bestax:** give each starter notification a status region of its own ([f1ef4df](f1ef4df))
* **create-bestax:** keep focus on the counter when Reset disables itself ([733e505](733e505))
* **create-bestax:** keep the reason for the stylesheet order in every scaffolded entry file ([f4591e0](f4591e0))
* **create-bestax:** pin material-symbols to the newest range bestax-bulma accepts ([ff4f820](ff4f820))
* **create-bestax:** return focus when the starter's notification closes, and tighten guards ([67e3678](67e3678))
* **create-bestax:** say which helper props render nothing under the no-helpers flavors ([b29985b](b29985b))
* **create-bestax:** stop the no-helpers CLAUDE.md offering helper props as the way out ([a96c203](a96c203))
* **create-bestax:** stop the vite-ts build shadowing its config, and fix the starter page ([1dd964d](1dd964d))
* **docs:** give the mixin note the modifier caveat its lead carries ([1427f08](1427f08))
* **docs:** keep the modifier caveat for mixin variables in the MCP index ([e227663](e227663))
* **docs:** name the one edge of the rule for which variables Theme reaches ([b33ebfa](b33ebfa))
* **docs:** qualify the guide and the theming skill on what Theme reaches ([9c2347b](9c2347b))
* **docs:** read only a component's own mixin as its home ([f40cd2c](f40cd2c))
* **docs:** refuse a CSS-variable scope the page cannot fully word ([c815602](c815602))
* **docs:** say where component-scoped Bulma variables have to be set ([771d5bd](771d5bd)), closes [#1021](#1021)
@bestax-release-bot

Copy link
Copy Markdown

🎉 This PR is included in version 1.14.4 🎉

The release is available on:

Your semantic-release bot 📦🚀

bestax-release-bot Bot pushed a commit that referenced this pull request Oct 12, 2026
# [5.28.0](https://github.com/allxsmith/bestax/compare/@allxsmith/bestax-bulma@5.27.8...@allxsmith/bestax-bulma@5.28.0) (2026-10-12)

### Bug Fixes

* **bestax-mcp:** release with every bulma-ui release so the published index keeps up ([#1027](#1027)) ([618e483](618e483))

### Features

* **bulma-ui:** add HoverCard, a card that opens on hover or keyboard focus ([#1030](#1030)) ([0eb41df](0eb41df))
@bestax-release-bot

Copy link
Copy Markdown

🎉 This PR is included in version 5.28.0 🎉

The release is available on:

Your semantic-release bot 📦🚀

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

deep-review needs-human-review Loop converged (or contested): awaiting owner review + manual merge released review-converged Deep review converged: no blocking findings, all review threads resolved, checks green

Projects

None yet

Development

Successfully merging this pull request may close these issues.

bestax-mcp's published index is stamped a release behind and lags the library between releases

1 participant