Repository navigation
[Fix] Keep the install step in progress until npm ci has exited - #496
Conversation
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Repository: WordPress/contributor-toolkit/.coderabbit.yaml Review profile: CHILL Plan: Advanced Run ID: 📒 Files selected for processing (2)
Included review availability: Your plan provides up to 1 included review per hour; 0 remain after this review. 📝 WalkthroughWalkthrough
Assessment against linked issues
Priority: ➖ Normal Severity of issue fixed: Medium 🚥 Pre-merge checks | ✅ 1✅ Passed checks (1 passed)
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. Comment |
The step read as completed, with the build unlocked, whenever a status refresh ran mid-install and found a half-written node_modules. An install still running now overrides existence, the same way a failed one already did. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
44570f4 to
2b6634c
Compare
|
@coderabbitai review |
✅ Action performedReview finished.
|
…504) ## Why On a Gutenberg site the wizard's **Run full build** step flipped to **COMPLETED** ("Build complete") and **Start dev server & finish wizard** to **READY** while `npm run build` was still running: banner on *step 3 of 3*, terminal in phase 4 (widgets). Seen on 20 Sep 2026 on Windows (UTM VM, trunk artifact `ffbdb3c`), right after #496 fixed the same thing for the install step. Since #500 a click there starts Playground at once on that half-written `build/` (#502). ## What changes **Root cause.** `computeSetupStepState` took the build step as done when the status's `hasBuilt` was true. That is one marker file, `build/scripts/block-library/index.min.js`, which Gutenberg's build writes mid-way (phase 2), with routes, widgets and the PHP registries still to come. Any status refresh during the build (switching windows is enough) read the site as built. The `building` flag was ignored, exactly as `installing` was in #495. **The fix.** The step is built only when the marker is there **and** no build is running **and** the last build did not fail: `builtOk = hasBuilt && !building && !buildFailed`. It drives the build step's done state and the dev step's ready state; the step's label and the button's variant follow the step state instead of the raw flag. The failed-build half comes from the self-review: a build stopped or failed late leaves the marker on disk, and within a session `buildFailed` is never stale (every build path clears it on success), so a flag still set outranks the marker. ## How to test this Platforms: either; Windows is where the build is slow enough to catch. Build: the Buildkite artifact for the current head, or `npm start` from the repository root. **Starting state:** no site, or a Gutenberg site at the download step. 1. Create a Gutenberg site and let the wizard reach *step 3 of 3*. 2. While the terminal is past *Transpiled …* and into *Built route …*, switch to another window and back, two or three times. Expected: **Run full build** stays **IN PROGRESS** with its button busy, **Start dev server & finish wizard** stays **LOCKED**. 3. Let the build finish. Expected: the step turns **COMPLETED**, "Build complete", the dev step **READY**; click it and the site opens. 4. New site, same steps, but press Ctrl+C in the terminal during *Built route …*. Expected: the build step reads **FAILED** with "Retry the build", the dev step stays **LOCKED**; retry, let it finish, and the step completes. 5. Open an existing, fully built site. Expected: the step reads **COMPLETED** as before. **What must not have happened:** the dev server enabled while `npm run build` runs; a build stopped mid-way reading "Build complete"; a built site's step reading anything but complete. Tests: `tests/unit/setup-steps.test.cjs`, *a marker written mid-build does not complete the build step* and *a build still running reads in progress, whatever the marker says* fail on trunk (`build.done` was the raw marker) and pass here; *a build that failed over an existing marker reads failed, not complete* replaces the earlier test that had the opposite premise, with the reason in its comment. Lint clean, 1596 unit tests pass. ## Risks and limitations - `buildFailed` is session-local: after an app restart a build that failed late over an existing marker reads complete again, as on trunk. Persisting it like the install outcome is in #503. - Outside the wizard, **Start dev server** and **Start build watch** are still reachable while a build runs from the terminal or an apply; pre-existing, #503. ## Related Fixes #502. Same rule as #496 (#495). Follow-up #503. Part of the v1.2.0-beta.1 pass. --- <details> <summary>Review outcome (required — see AGENTS.md)</summary> 2 [fix here] · 1 [follow-up] on `e5b762d` — both fix-here fixed in `f1ed783`. - Fixed: a build that failed or was stopped over an existing marker read complete and unlocked the dev server (`builtOk` now requires `!buildFailed`; `build.failed` no longer tests the raw marker; the colliding test's premise revisited and rewritten). - Fixed: the "In progress" status string had no ladder assertion; added. - Fixed (style): the build button's variant keyed off the raw marker while its label followed the step state. - Deferred to #503: the skip-wizard path (action bar reachable while a build runs) and persisting the build outcome across restarts; both pre-existing. - **Review:** completed — `/self-review` (Explore subagent, judgement pass; lint and unit inline); reviewed head `e5b762d` / base `ffbdb3c` (trunk); evidence: findings above; outcome: 2 fixed, 1 deferred. - **Since review:** `e5b762d → f1ed783` checked: the fixes above plus their tests; lint clean, 1596 unit tests pass on the new head. </details> <details> <summary>Screenshots or recording</summary> No new surface: the same checklist, now honest about a running build. The Windows screenshot of the bug is on #502. </details> 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
## Why `v1.1.0` shipped on 16 September. Sixteen commits since then reach trunk, and this beta is the first build that carries the Gutenberg contribution target (#251): a site can now be a checkout of `WordPress/gutenberg`, served through Playground as a plugin in a stock WordPress, with a GitHub issue as its work item, pull request checkout from that issue, and a pull request opened against `WordPress/gutenberg` from the app. The manual pass of that work ran on macOS and on Windows over 18 to 20 September and found six issues; the four that affected the first-run path are fixed on trunk (#489, #493, #496, #500, #504, and #491 for the hint), the rest are on the `v1.2.0-beta.2` milestone. `electron-builder` derives artifact names from `package.json`, so the version has to move before the tag and the artifacts exist. A beta is a pre-release, so `releases/latest` stays on `v1.1.0`. ## What changes Only the version. All three package-version fields in `package.json` and `package-lock.json` move together from `1.1.0` to `1.2.0-beta.1`. No dependency versions change, and there is no application behaviour change in this PR. ## How to test this Platforms: any for the suite; macOS and Windows for the artifact checks that follow the merge. 1. `npm run lint` is clean and `npm test` passes. 2. `node -e "console.log(require('./package.json').version)"` prints `1.2.0-beta.1`. 3. `python3 -c "import json;d=json.load(open('package-lock.json'));print(d['version'], d['packages']['']['version'])"` prints `1.2.0-beta.1 1.2.0-beta.1`. **What must not have happened:** no dependency version may change. `git diff` must show exactly three changed lines, all of them the root package version. After merge, the release build must produce artifacts named `wordpress-contributor-toolkit-1.2.0-beta.1-*`; the asar root must be exactly `node_modules`, `package.json`, `src`, with npm 11 under `node_modules/npm` and no `.codesigning` directory; on macOS `CFBundleShortVersionString` reads `1.2.0-beta.1`. ## Risks and limitations No UI change. The risk is a mis-scoped edit in `package-lock.json`, where dependencies also carry version fields; the replacement was confined to the first 2000 bytes of the file, which hold the two root entries and nothing else, and both files were re-parsed as JSON afterwards. Verified locally on this branch: lint clean, `npm test` 1596 pass / 0 fail. ## Related Part of #251. Release notes follow on the pre-release; docs publish for the tag per #487. --- <details> <summary>Review outcome (required — see AGENTS.md)</summary> 0 [fix here] · 0 [follow-up]. Deterministic layer only: lint clean, 1596 tests pass, both files valid JSON, diff confined to the three root version fields. No judgement pass was run: this change has no logic to review. - **Review:** completed — deterministic layer, in session; head is the single bump commit / base `b5ca272` (trunk); evidence above; outcome: nothing to fix. - **Since review:** none. </details> 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
Why
While the setup wizard is still installing (banner step 2 of 3, Installing dependencies,
npm cistreaming in the terminal), the Install npm dependencies step flipped to COMPLETED and Run full build to READY with its button enabled. A click there starts a build over a half-writtennode_modules. Seen on Windows during the v1.2.0-beta.1 pass on a Gutenberg site, whose install is long enough to switch windows during; the rule is shared by every site (#495).What changes
Root cause.
computeSetupStepStatetook the step as done whennode_modulesexists and is non-empty and the last install did not fail. It ignoredinstalling. Any status refresh mid-install (switching back to the window triggers one) reads the partial directory as done.The fix. An install still running overrides existence, exactly as a failed one already did (#42):
installOkalso requires!installing. One line. Whennpm ciexits 0 the flag clears, the next status read sees the full directory, and the step completes as before.How to test this
Platforms: either. Build: the Buildkite artifact for the current head, or
npm startfrom the repository root.Starting state: no site yet, or a site whose wizard is at the download step.
npm http fetchlines. Expected: Install npm dependencies keeps its in-progress state and Run full build stays locked.What must not have happened: Run full build enabled while
npm ciis running; a completed site's install step reading as not done.Test:
tests/unit/setup-steps.test.cjs, a half-written node_modules during an install does not complete the step. Fails on trunk, checked in a trunk worktree.Risks and limitations
None beyond the one-line rule. The
installingflag is set by the renderer for the wizard's install and for a manualnpm installfrom the terminal alike, so both paths get the same hold.Related
Fixes #495. Part of the v1.2.0-beta.1 pass, follows #489, #491, #493.
Review outcome (required — see AGENTS.md)
npm test1589 pass, 33 journeys. Judgement: the change is one predicate in a pure module with a test that fails on trunk; the only question checked was whetherinstallingis set on every install path (it is, for the wizard's chain and for a terminalnpm install), so the hold applies to both; no security, performance or platform surface.44570f4 → 2b6634cchecked: rebase onto trunk5167e88([Change] Start a built Gutenberg site's dev server without the build watch #500) only, no conflict, same diff; eslint clean,npm test1594 pass on the new head. Reproduced again on 19 Sep 2026 on Windows with the trunk artifact, see The install step reads as completed while npm ci is still running #495.🤖 Generated with Claude Code