Skip to content

Fix Node restore/build regressions from the Rush-aware targets - #103

Open
zekelinAlex wants to merge 5 commits into
TALXIS:masterfrom
zekelinAlex:develop
Open

Fix Node restore/build regressions from the Rush-aware targets#103
zekelinAlex wants to merge 5 commits into
TALXIS:masterfrom
zekelinAlex:develop

Conversation

@zekelinAlex

Copy link
Copy Markdown
Collaborator

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.

Copilot AI 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.

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.exe invocation for Node/Rush commands and harden restore flows (Rush bootstrap repair, correct restore project directory timing).
  • Make Node restore incrementality reliable after node_modules deletion 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.

Comment thread src/Dataverse/Tasks/Tasks/ExecWithRetry.cs
@TomProkop
TomProkop self-requested a review July 31, 2026 08:00
@TomProkop

TomProkop commented Jul 31, 2026

Copy link
Copy Markdown
Member

@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 -c --environment BUILD:development

rollup.config.js:

import terser from '@rollup/plugin-terser';

const isProduction = process.env.BUILD === 'production';

export default {
  input: 'src/main.js',
  output: {
    file: 'dist/bundle.js',
    format: 'cjs',
    sourcemap: !isProduction 
  },
  plugins: [
    // Minify code only in production mode
    isProduction && terser()
  ].filter(Boolean)
};

@TomProkop

Copy link
Copy Markdown
Member

By default ScriptLibrary projects should not nest under the TS folder. That should be optional prop similar to SolutionRootPath in Solution projects.

@TomProkop

Copy link
Copy Markdown
Member

BTW pcf-scripts use webpack or esbuild. This is how they handle it:

esbuild:
image

for webpack they pass the buildMode variable directly to webpack.

@zekelinAlex

Copy link
Copy Markdown
Collaborator Author

By default ScriptLibrary projects should not nest under the TS folder. That should be optional prop similar to SolutionRootPath in Solution projects.

done

@zekelinAlex

zekelinAlex commented Jul 31, 2026

Copy link
Copy Markdown
Collaborator Author

@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 -c --environment BUILD:development

rollup.config.js:

import terser from '@rollup/plugin-terser';

const isProduction = process.env.BUILD === 'production';

export default {
  input: 'src/main.js',
  output: {
    file: 'dist/bundle.js',
    format: 'cjs',
    sourcemap: !isProduction 
  },
  plugins: [
    // Minify code only in production mode
    isProduction && terser()
  ].filter(Boolean)
};

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
image
image

@zekelinAlex

Copy link
Copy Markdown
Collaborator Author

BTW pcf-scripts use webpack or esbuild. This is how they handle it:

esbuild: image

for webpack they pass the buildMode variable directly to webpack.

that's exactly the contract we're feeding.

@TomProkop

Copy link
Copy Markdown
Member

that's exactly the contract we're feeding.

Are we? are those projects listening to this env variable? I dont think so.

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.

4 participants