Skip to content

Move a site's status out of SiteRow into a hook - #593

Merged
zaerl merged 3 commits into
trunkfrom
update/site-status-hook
Oct 2, 2026
Merged

zaerl merged 3 commits into
trunkfrom
update/site-status-hook

Conversation

@zaerl

@zaerl zaerl commented Oct 2, 2026

Copy link
Copy Markdown
Contributor

Why

#554 took eight domains out of SiteRow, and the largest thing it left behind is the one nearly every hook and card reads: what the main process says about the site. Thirteen pieces of state, set by one function, sat in the middle of the component. The redesign's page header and sites list (#556) need that status from outside the site's view, and a hook is the first step to handing it to them.

What changes

  • src/renderer/hooks/use-site-status.jsx is the site's status. Whether it is installed and built, the ticket it is working on, what is applied to it, the age of its trunk, and the two states the app reads and never writes over: a site the old engine made, and a merge left unfinished outside the app. With them, loadStatus, which reads them all in one answer, and the effect that calls it when the site's view mounts.
  • Five setters are handed out, as they were used before: linking or leaving a ticket and moving one onto trunk, the dev server's start, skipping the first-run checklist, and discarding every change. The other eight values change only through loadStatus.
  • It is a move. The lines are SiteRow's own.
  • One new journey, site-status.spec.js, for the one wiring the move reshaped: the status reports to the sites list through a ref that is now an argument, and nothing read that the report arrives.

This goes to trunk and not to redesign/wpds because nothing on screen changes; trunk is merged into the redesign branch afterwards.

How to test this

Platforms: any. This has no surface of its own: the screen is the same before and after.

From the repository root, npm run test:e2e runs the journeys, all of which read a site's status one way or another. The ones that would notice a status not read, or read wrong, are legacy-site, merge-in-progress, pr-checkout, patch-apply, trunk-update-watch, store-persistence, build-watch and the new site-status; the audit in the review outcome says which.

site-status.spec.js seeds the store with a trunk thirty days old for a checkout whose trunk is minutes old, and expects the site's entry in the list to end up with the name of a site that has nothing to report. It is red when the report is dropped, when the hook is handed another ref, and when the date is left out of the report.

What must not have happened:

  • A site's view does not read its status more often than before: loadStatus keeps its identity for as long as the site's path does, so the effect that calls it on mount runs once.

Risks and limitations

  • Two dependency lists gain a value that was already stable: loadStatus lists the ref it reports through, and the callback that skips the checklist lists a setter that now comes from the hook.
  • One effect changes place. The read on mount now runs before the effect that clears the copy button's timer, which shares nothing with it.
  • Six of the things the audit broke are not noticed by any journey, and were not before the move. They are listed in the review outcome; none is new.
  • loadStatus swallows a failed read, as it did in SiteRow: the site then looks not installed and not built, nothing is logged, and the setup chain does not start. Fixing it would stop this being a move, so it is left for its own change.
  • Discarding all changes with a patch applied has no journey. That path does not read the status again, so one setter is all that clears the applied-patch banner.
  • What is reported to the sites list is decided inside the hook, out of the unit tests' reach. It should move to a module before Page header with the site menu and the collapsible details sidebar #556 reads the status from outside the view.
  • Checked on macOS only. Windows is covered by CI.
  • Pre-PR review, two passes: the move holds line for line; the hook's header comment was wrong in several places and is rewritten; four findings are left as follow-ups.

Related

Follow-up to #554. Prepares #556, part of #542.


Review outcome (required — see AGENTS.md)

Run as the repository's review procedure, with the judgement pass in a fresh context that took no part in the change. First pass on the move alone; second pass on the fix-up. The branch was rebased onto trunk after #592 merged, and the checks below are on the rebased head.

First pass: one finding to fix here, four follow-ups. It diffed the hook's body against SiteRow's old lines and found two differences, both intended; checked that every returned name is read only after the hook's call and that the eight setters not returned were only ever used inside loadStatus; and found the one effect that changed place, the copy button's timer, sharing nothing with the status. To fix: the hook's header said a finished build sets "built" (it goes through loadStatus; the dev server's start is what sets it), that everything comes from one read (the handed-out setters mean it does not always), and that the status is read when a site's view is opened (every listed site's view mounts as the app opens). Rewritten. Follow-ups, all in Risks above: the silent catch, the missing journey for a discard with a patch applied, the report to the sites list being untested, and that report's decision living in a hook. The third is closed here by site-status.spec.js.

Second pass: four findings, one medium, all fixed. The medium one asked that the new journey be shown to go red, since it never sees the state it starts from: it does, three ways, as the table below records. The other three were sentences in the two headers that left a case out.

Checks, on macOS, on the head of this branch:

Check Result
npx eslint . --max-warnings=0 clean
npm test 1733 pass, 2 skipped
npm run test:electron 1734 pass, 1 skipped
npm run test:e2e (journeys) 57 of 57 on 62c5ab5; the head differs from it by comments, and site-status.spec.js was run again on it

That it is a move. Comparing the lines removed from index.jsx with the hook's, every removed line is in the hook except two dependency lists and a comment that said the trunk update was "below". No name the hook returns is read in SiteRow above the hook's call.

The wiring was audited by breaking it, one thing at a time, and running the journeys: 17 breaks, 11 caught.

Break Caught by
The status is not read when the view mounts build-watch
A legacy site is not told apart legacy-site
An unfinished merge is not seen merge-in-progress
The checked-out pull request is not known pr-checkout
An unfinished update is not known trunk-update-watch
The applied patch is not known patch-apply
The linked ticket is not read back store-persistence
Whether the site is built is not known build-watch
The dev server's start does not set "built" itself nothing: it decides from its own read, and the state only changes what is shown until the next status read
Skipping the checklist does not set it itself nothing: every journey starts with the checklist already skipped
Linking a ticket does not set it itself nothing: the link reads the status straight after
Discarding does not clear the applied patch itself nothing: no journey discards with a patch applied
The status never stops loading nothing: it only disables the first-run checklist's buttons, which no journey shows; setup-steps.cjs has unit tests for what it does with the flag
The status does not reach the sites list site-status
The hook is handed another ref to report through site-status
The trunk's date is left out of the report site-status
loadStatus returns nothing to its caller nothing: only the setup chain reads it, and only the opt-in real-setup suite runs that

🤖 Generated with Claude Code

zaerl and others added 3 commits October 2, 2026 09:41
What the main process says about a site: whether it is installed and
built, the ticket it is working on, what is applied to it, the age of
its trunk, and the two states the app reads and never writes over, a
site the old engine made and a merge left unfinished outside the app.
Thirteen pieces of state, the one function that reads them all, and the
effect that calls it when the site's view mounts.

It was the largest thing left in SiteRow after #554's eight domains, and
it is what nearly every other hook and card reads. The redesign's page
header and sites list (#556) need it from outside the site's view.

A move: the lines are SiteRow's own. Two dependency lists gain a value
that was already stable, the ref the status reports through and a state
setter that now comes from the hook. The effect that reads the status on
mount now runs before the one that clears the copy button's timer, which
shares nothing with it.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…ollows the status

The pre-PR review. The hook's header said a finished build sets
"built", that everything comes from one read, and that the status is
read when a site's view is opened. A finished build goes through
`loadStatus`; it is the dev server's start that sets "built". The five
setters handed out mean a value can be newer than the rest until the
next read. And every listed site's view mounts as the app opens, so
that is when each status is first read.

The report a site's status makes to the sites list is the one wiring
this move reshaped, into an argument, and no journey read it: the
update journeys read the store, which the main process writes itself.
`site-status.spec.js` seeds the store with an old trunk for a checkout
whose trunk is recent, and reads the entry's name.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Deleting a ticket's work reads the status too, when it leaves the
checkout on trunk; a site's view mounts when the site joins the list,
which is at launch only for the sites already there; and the window does
read the store again, after a site is created or deleted.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Oct 2, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository: WordPress/contributor-toolkit/.coderabbit.yaml

Review profile: CHILL

Plan: Advanced

Run ID: 5f8acb00-28ee-42d4-a589-cf276eb36f72

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
  • Autopilot · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Autopilot is currently an internal CodeRabbit preview.


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.

@zaerl zaerl self-assigned this Oct 2, 2026
@zaerl
zaerl merged commit 522b6ea into trunk Oct 2, 2026
8 checks passed
@zaerl
zaerl deleted the update/site-status-hook branch October 2, 2026 07:55
zaerl added a commit that referenced this pull request Oct 2, 2026
Brings in the site-status hook (#593): what the main process says about
a site leaves SiteRow for useSiteStatus, with a journey for the sites
list following it.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@zaerl zaerl added this to the v2.0.0 milestone Oct 7, 2026
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