Skip to content

deps(ui-kit): publish the stranded recharts v3 migration, and guard the class - #9977

Merged
JSONbored merged 2 commits into
mainfrom
fix/ui-kit-release-stranded-9937
Jul 31, 2026
Merged

deps(ui-kit): publish the stranded recharts v3 migration, and guard the class#9977
JSONbored merged 2 commits into
mainfrom
fix/ui-kit-release-stranded-9937

Conversation

@JSONbored

Copy link
Copy Markdown
Owner

Why ui-kit is stuck, and why it is not a stale issue

@loopover/ui-kit has been on 1.3.0 while carrying an unreleased, user-visible change. chore(deps): migrate recharts to v3 across all three workspaces (#8610) rewrote packages/loopover-ui-kit/src/components/chart.tsx — real shipped code — and it has shipped to nobody.

Unlike its sibling #9875 (which I closed: engine is already past it at 3.18.0), this one is structural. release-please will never cut this release on its own. Its own dry run, run against this repo:

✔ Building candidate release pull request for path: packages/loopover-ui-kit
✔ No user facing commits found since 0fa52ed838... - skipping

"User facing" means the commit's type is not hidden: true in changelog-sections. chore is hidden here, so the commit is filtered out before a release candidate is built.

Worth stating precisely, because it is not what I first assumed: this is not a question of how much to bump. Asked directly, DefaultVersioningStrategy turns that same commit into a patch:

1.3.0 -> 1.3.1   | types=["chore"] | chore(deps): migrate recharts to v3 ...

It simply never gets asked. That gap between "would bump" and "never considered" is why this needed checking against the real tool rather than reasoning.

Two commits

1. deps(ui-kit): — cuts the release

Deliberately typed deps, this repo's own non-hidden Dependencies section, because that is exactly what the release publishes: the recharts v3 migration.

Release-As: was the other candidate and does not work here. The skip above is changelogEmpty(releaseNotesBody) at strategies/base.js:168, which runs after the version is computed — so a Release-As footer on a hidden-type commit still produces an empty changelog and is still skipped.

The diff is the coverage that migration never had. chart.tsx had zero tests, so the load-bearing parts of a major-version rewrite were resting on the type-checker alone:

  • payload/label now arrive through context, not as Tooltip props — the v3 change itself
  • config labels, not raw dataKeys, are what a reader sees (the most likely silent regression: it still "renders fine")
  • an inactive or empty payload paints nothing — both arms, since !active || !payload?.length is two conditions
  • both arms of ChartConfig's color/theme union reach the stylesheet
  • useChart throws its named error outside a provider

ResponsiveContainer is replaced with a passthrough and nothing else is: it measures through a ResizeObserver that never resolves under jsdom, so it renders nothing and discards its children — which would have made the "renders nothing" assertions pass for entirely the wrong reason. (I hit exactly that while writing them.)

Mutation-tested — each fails, baseline restored green:

Mutation Result
Tooltip always renders (drop the active/empty guard) 1 failed
Invert ChartStyle's empty-config guard 2 failed
Drop useChart's provider check 1 failed

2. ci(release): — stops it recurring

A check that fails when a commit changes a released package's published source under a type release-please treats as invisible.

  • The config is the source of truth. Both the released package paths and the hidden-type set are read from release-please-config.json, so adding a package or unhiding a type moves the guard with it.
  • Test files are excluded, even though they sit under src/. Every package excludes src/**/*.test.* from its build and none list tests in files, so a test is not published — and test: is itself hidden, making test(pkg): add a test the single most common hidden-type commit there is. Flagging it would fire the guard on the ordinary case and get it switched off. I found this by running the guard against the very commit that added it.
  • Release-As: is exempt — a guard that rejects the remedy its own failure message recommends is a broken guard.
  • Breaking changes (chore!:) are exempt; breaking is user-facing whatever the type.

24 unit tests, including the historical recharts commit asserted against the real config, so unhiding chore or renaming a package path cannot leave the guard quietly asserting nothing.

Note on merge order

This targets main but CI will stay red until #9976 lands — an unrelated repo-wide breakage where a node_modules cache hit skips postinstall, so apps/loopover-ui typechecks against a collections/* module that was never generated. Not caused by this PR; it fails every PR right now.

Verification

  • typecheck, checkers-wired:check, dead-source-files:check, dead-exports:check, import-specifiers:check, coverage-boltons:check, release-commit-parsing:check, validate:no-hand-written-js green
  • The new guard passes on its own branch (2 commit(s) checked, none would be stranded)
  • test:ui-kit-pack green; ui-kit suite 53 tests passed (was 43)

Closes #9937

…at it rewrote

@loopover/ui-kit has been stuck on 1.3.0 while carrying an unreleased,
user-visible change: `chore(deps): migrate recharts to v3 across all three
workspaces (#8610)` rewrote src/components/chart.tsx and shipped to nobody.

release-please would never cut that release on its own. It decides whether a
component HAS a release before it decides how much to bump, and that decision
keeps only "user facing" commits -- those whose type is not `hidden: true` in
changelog-sections. `chore` is hidden here, so its own dry run says:

  ✔ Building candidate release pull request for path: packages/loopover-ui-kit
  ✔ No user facing commits found since 0fa52ed... - skipping

This is deliberately typed `deps` -- the repo's own non-hidden "Dependencies"
section -- because that is what the release publishes: the recharts v3
migration. `Release-As:` was the other candidate and does not work here; the
skip above is on an empty changelog and runs after the version is computed, so
a footer on a hidden-type commit is still skipped.

The diff is the coverage that migration never had. chart.tsx had NO tests at
all, so the load-bearing parts of a major-version rewrite were resting on the
type-checker: that payload/label now arrive through context rather than as
Tooltip props, that config labels (not raw dataKeys) are what a reader sees,
that an inactive or empty payload paints nothing, and that both arms of
ChartConfig's color/theme union reach the stylesheet.

ResponsiveContainer is replaced with a passthrough for these tests and nothing
else is: it measures through a ResizeObserver that never resolves under jsdom,
so it renders nothing and discards its children -- which would have made the
"renders nothing" assertions pass for entirely the wrong reason.

Mutation-tested: forcing the tooltip to always render, inverting ChartStyle's
empty-config guard, and dropping useChart's provider check each fail.
…er release

The recharts v3 migration rewrote packages/loopover-ui-kit/src/components/
chart.tsx under a `chore(deps):` subject. It merged, CI was green, and the
package sat on 1.3.0 with that change unpublished. Nothing was red; the only
symptom was a drift issue whose checklist said "merge the release-please PR"
for a PR that could never exist.

release-please filters commits whose type is `hidden: true` in
changelog-sections BEFORE building a release candidate, so a hidden type on
published source strands the change. Note this is not the same question as how
much to bump: asked directly, DefaultVersioningStrategy turns a `chore` into a
patch (1.3.0 -> 1.3.1). It simply never gets asked. That gap is why this has to
be checked rather than reasoned about.

The config is the source of truth, not a list here. Both the released package
paths and the hidden-type set are read out of release-please-config.json, so
adding a package or unhiding a type moves the check with it.

Test files are excluded even though they sit under src/. Every package excludes
src/**/*.test.* from its build and none list tests in `files`, so a test is not
published -- and `test:` is itself hidden, which makes `test(pkg): add a test`
the most common hidden-type commit there is. Flagging it would fire the guard on
the ordinary case and get the guard switched off. Found by running the guard
against the very commit that added it.

A `Release-As:` footer is exempt: that is release-please's own mechanism for
forcing a version, so a commit using it has already answered the question -- and
a guard that rejects the remedy its own message recommends is a broken guard.
@loopover-orb

loopover-orb Bot commented Jul 31, 2026

Copy link
Copy Markdown
Contributor

Tip

✅ LoopOver review result - approve/merge recommended

Review updated: 2026-07-31 01:10:25 UTC

4 files · 1 AI reviewer · no blockers · readiness 98/100 · CI green · clean

✅ Suggested Action - Approve/Merge

  • safe to merge

Review summary
Adds a new CI guard (check-releasable-commit-types.ts) that detects commits touching published package source under a release-please 'hidden' commit type, wires it into test:ci, and separately adds a real test file for chart.tsx (the untested recharts v3 migration) plus tests for the guard itself. The logic is sound and well-tested: hidden-type detection, published-source prefixing, test-file exclusion, breaking-change exemption, and Release-As footer exemption are each covered with both positive and negative cases, including an INVARIANT test pinning the real release-please-config.json. The PR title/description frame this as fixing a real, verified problem (release-please's own dry run confirms the ui-kit component never gets a release candidate because its migrating commit was typed chore), not a fabricated scenario.

Nits — 5 non-blocking
  • scripts/check-releasable-commit-types.ts:121 uses `.slice(0,8)` for the short SHA with no named constant — minor, purely cosmetic.
  • The self-execution block (`if (process.argv[1] && ...)`) is v8-ignored so its git/process plumbing (commitsOnThisBranch, catch/skip path) has no direct test coverage beyond the pure functions it calls — acceptable per the file's own comment but worth confirming coverage tooling agrees.
  • chart.test.tsx mocks `recharts`'s `ResponsiveContainer` for all tests; consider a short comment/test noting this doesn't accidentally mask a real width/height prop-passing regression between ResponsiveContainer and its children, since that boundary is now fully stubbed.
  • Consider extracting the short-sha length (8) in describeStranded into a named constant for clarity, though this is very minor.
  • If not already covered elsewhere, add a one-line assertion that publishedSourcePrefixes trims a trailing slash from a configured package path (the `.replace(/\/+$/, "")` call) to lock in that edge case.

Decision drivers

  • ✅ Code review — No blockers (1 reviewer)
  • ✅ Gate result — Passing (No configured blocker found.)
Context & advisory signals — never blocks the verdict
Signal Result Evidence
Linked issue ✅ Linked #9937
Related work ✅ No active overlap found No same-issue or scoped active PR overlap found.
Change scope ✅ 20/20 Low review scope from cached public metadata (1 linked issue).
Validation posture ✅ 25/25 PR body includes validation/test evidence.
Contributor workload ✅ 10/10 Author activity: 9 registered-repo PR(s), 8 merged, 281 issue(s).
Contributor context ✅ Confirmed Gittensor contributor JSONbored; Gittensor profile; 9 PR(s), 281 issue(s).
Improvement ✅ Minor risk: clean · value: minor · LLM: significant
Linked issue satisfaction

Partially addressed
The PR adds a guard script and test coverage for chart.tsx to prevent future stranded releases, and the description claims a separate commit retypes the migration as `deps:` to unblock release-please, but the diff shown contains no version bump in packages/loopover-ui-kit/package.json nor any other checklist item (build, test:ui-kit-pack, tagging, publish) from the issue.

Review context
  • Author: JSONbored
  • Role context: owner (maintainer lane)
  • Public audience mode: oss maintainer
  • Lane context: Repository is configured for direct PR review.
  • Public profile languages: Python, TypeScript, Ruby, Go, MDX, Shell, Solidity, JavaScript
  • Official Gittensor activity: 9 PR(s), 281 issue(s).
  • PR-specific overlap: none found.
Contributor next steps
  • Start here: Treat this as maintainer-lane context rather than normal contributor-lane activity.
Signal definitions
  • Related work = same linked issue, overlapping active PRs, or title/path similarity.
  • Change scope = cached public metadata such as size labels, draft state, and review-burden hints.
  • Validation posture = whether the PR provides enough public validation/test evidence for maintainer review.
  • Contributor workload = public contributor activity and cleanup pressure, not a repo-wide quality failure.
  • Contributor context = public GitHub/Gittensor identity context; non-Gittensor status is not a blocker.
🧪 Chat with LoopOver

Ask LoopOver a question about this PR directly in a comment — grounded only in the same cached, public-safe facts shown above, never a new claim.

  • @loopover ask <question> answers contribution-quality Q&A with source citations and freshness.
  • @loopover chat <question> answers in natural prose from cached decision-pack facts via local inference (maintainer/collaborator; read-only).
  • A plain-language @loopover mention with a real question is routed to the closest matching read-only command automatically — no exact syntax required.

Full command reference: https://loopover.ai/docs/loopover-commands

🧪 Experimental — new and may change.

Visual preview
Route Viewport Before (production) After (this PR's preview) Diff
/ desktop before /
before /
after /
after /
/ mobile before / (mobile)
before / (mobile)
after / (mobile)
after / (mobile)

Click any thumbnail to open the full-size screenshot. Before = production · After = this PR's preview deploy.

Scroll preview
Route Before (production) After (this PR's preview)
/ before / (scroll)
before / (scroll)
after / (scroll)
after / (scroll)

A short scroll-through clip (desktop) — click either thumbnail to open the full animation. Evidence for scroll-linked behavior a single screenshot can't show.

🟩 Safe / merged · 🟦 Advisory · 🟨 Held for review · 🟥 Blocked / closed


💰 Earn for open-source contributions like this. Gittensor lets GitHub contributors earn for the work they already do — register to start earning →.

Checked by LoopOver, a quiet PR intelligence layer for OSS maintainers.

  • Re-run LoopOver review

@superagent-security

Copy link
Copy Markdown
Contributor

Superagent didn't find any vulnerabilities or security issues in this PR.

@cloudflare-workers-and-pages

Copy link
Copy Markdown

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

Status Name Latest Commit Preview URL Updated (UTC)
✅ Deployment successful!
View logs
loopover-ui 6be3f90 Commit Preview URL

Branch Preview URL
Jul 31 2026, 12:48 AM

@codecov

codecov Bot commented Jul 31, 2026

Copy link
Copy Markdown

Bundle Report

Bundle size has no change ✅

@codecov

codecov Bot commented Jul 31, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 91.88%. Comparing base (a790a9e) to head (6be3f90).
✅ All tests successful. No failed tests found.

Additional details and impacted files
@@           Coverage Diff           @@
##             main    #9977   +/-   ##
=======================================
  Coverage   91.88%   91.88%           
=======================================
  Files         928      928           
  Lines      113722   113722           
  Branches    27436    27436           
=======================================
  Hits       104489   104489           
  Misses       7936     7936           
  Partials     1297     1297           
Flag Coverage Δ
backend 95.67% <ø> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.

@JSONbored JSONbored self-assigned this Jul 31, 2026
@JSONbored
JSONbored merged commit c6fcee9 into main Jul 31, 2026
13 checks passed
@JSONbored
JSONbored deleted the fix/ui-kit-release-stranded-9937 branch July 31, 2026 01:10
JSONbored added a commit that referenced this pull request Jul 31, 2026
…9988)

The tests added in #9977 were never run through prettier, and `ui:lint` runs
`format:check` across the ui-kit workspace as part of `test:ci` -- so main has
been failing lint since that merge, and every PR inherits it.

My regression, and the same cause as the last one: I ran a checker subset
(typecheck, dead-exports, the pack test, the ui-kit suite) and not `ui:lint`,
which is the one that would have caught it. No behaviour changes -- prettier
reflow only, and the 10 tests still pass.
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.

Ui-kit release due: 1.3.1

1 participant