Fix Node restore/build regressions from the Rush-aware targets - #103
Fix Node restore/build regressions from the Rush-aware targets#103zekelinAlex wants to merge 5 commits into
Conversation
There was a problem hiding this comment.
Pull request overview
Fixes regressions introduced by the Rush-aware Node restore/build targets by correcting restore/build behavior across project types, improving incremental restore correctness, and aligning packaging behavior with PAC’s build pipeline.
Changes:
- Fix Windows
cmd.exeinvocation for Node/Rush commands and harden restore flows (Rush bootstrap repair, correct restore project directory timing). - Make Node restore incrementality reliable after
node_modulesdeletion by relocating the restore stamp (with Yarn Berry PnP exception + cleanup). - Make Node build mode flag forwarding opt-in per project type (avoids breaking
tsc/rollup), and disable redundant packaging on Plugin/WorkflowActivity builds.
Reviewed changes
Copilot reviewed 14 out of 14 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| src/Dataverse/WorkflowActivity/msbuild/tasks/TALXIS.DevKit.Build.Dataverse.WorkflowActivity.targets | Disables package generation on build to avoid PAC target conflicts. |
| src/Dataverse/Tasks/Tasks/ExecWithRetry.cs | Adjusts Windows shell invocation mechanics for command execution retries. |
| src/Dataverse/Tasks/msbuild/tasks/Targets/NodeRestore/Rush.targets | Detects/repairs broken Rush bootstrap state after partial cleanup. |
| src/Dataverse/Tasks/msbuild/tasks/Targets/NodeRestore/Generic.targets | Moves restore stamp into node_modules (except Yarn Berry PnP) and cleans stale root stamps. |
| src/Dataverse/Tasks/msbuild/tasks/Targets/NodeRestore/Detection.targets | Defers NodeRestoreProjectDirectory defaulting to target execution time for correct override precedence. |
| src/Dataverse/Tasks/msbuild/tasks/Targets/NodeRestore.targets | Removes earlier-evaluated defaulting of NodeRestoreProjectDirectory (now set in detection target). |
| src/Dataverse/Tasks/msbuild/tasks/Targets/NodeBuild/RushDelegation.targets | Makes Rush mode-flag forwarding conditional and updates required-parameter handling accordingly. |
| src/Dataverse/Tasks/msbuild/tasks/Targets/NodeBuild/Direct.targets | Makes direct build mode args conditional to avoid passing unknown flags to build tools. |
| src/Dataverse/Tasks/msbuild/tasks/Targets/NodeBuild.targets | Changes mode-flag behavior to opt-in per project type (NODE_ENV always set). |
| src/Dataverse/ScriptLibrary/README.md | Documents new TypeScriptDir auto-detection order and behavior. |
| src/Dataverse/ScriptLibrary/msbuild/tasks/TALXIS.DevKit.Build.Dataverse.ScriptLibrary.targets | Implements TypeScriptDir detection and narrows file discovery/excludes for output copying. |
| src/Dataverse/Plugin/msbuild/tasks/TALXIS.DevKit.Build.Dataverse.Plugin.targets | Disables package generation on build to avoid PAC target conflicts. |
| src/Dataverse/CodeApp/msbuild/tasks/TALXIS.DevKit.Build.Dataverse.CodeApp.targets | Opts CodeApp into --mode forwarding for Vite builds. |
| docs/NodeDependencies.md | Updates docs to match new mode-flag opt-in and stamp location behavior. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
|
@zekelinAlex how do we make rollup produce minified bundle on "dotnet build --configuration Release" for ScriptLibrary/CodeApp/GenPage? For PCF we must pass "npm run build --buildMode production". It looks like we will resort to something like this:
rollup.config.js: |
|
By default ScriptLibrary projects should not nest under the TS folder. That should be optional prop similar to SolutionRootPath in Solution projects. |
done |
SDK already sets NODE_ENV on every Node build invocation, for every project type, on both the direct and the Rush-delegated path. dotnet build gives you development, dotnet build -c Release gives you production |
Are we? are those projects listening to this env variable? I dont think so. |




The Node targets from #99 broke real builds in both TALXIS and INT0015, this fixes all the failure modes we found there plus one plugin packaging problem.
npm install ran in the ScriptLibrary project root instead of TS. The Tasks package defaults NodeRestoreProjectDirectory at evaluation time and imports before the ScriptLibrary targets, so their override never won. The default moved to execution time.
npm run build -- --mode development fails on plain tsc and rollup build scripts (TS5023). The mode flag is per project type now: pcf-scripts gets --build-mode, vite gets --mode, ScriptLibrary gets no flag and relies on NODE_ENV, which is set for everyone anyway.
deleting node_modules didn't retrigger the install: .node-restore.stamp sat next to it and survived, so the incremental gate skipped the restore. The stamp lives inside node_modules now (Yarn Berry PnP keeps the root path since it has no node_modules), stale root stamps get cleaned on the next restore.
every Rush invocation on Windows died with MODULE_NOT_FOUND. ExecWithRetry passed the command to cmd.exe through ArgumentList, which escapes quotes as ", and cmd doesn't parse that, so node received paths with literal quotes. cmd gets a raw /d /s /c "..." string now, same as MSBuild's own Exec.
wiping node_modules recursively also removes Rush's engine under common/temp/install-run but leaves its installed.flag, and install-run-rush then trusts the flag and launches a binary that isn't there. NodeRestore detects that half-deleted bootstrap and removes it so the engine reinstalls itself.
Also turned off GeneratePackageOnBuild for Plugin and WorkflowActivity projects, PAC's targets auto-pack them on build and that broke build and publish for both.