Skip to content

fix(repo): add copy-assets plugin and migrate all packages from legacy-post-build#34994

Merged
FrozenPandaz merged 42 commits intomasterfrom
fix/sandboxing-config-native-node
Mar 27, 2026
Merged

fix(repo): add copy-assets plugin and migrate all packages from legacy-post-build#34994
FrozenPandaz merged 42 commits intomasterfrom
fix/sandboxing-config-native-node

Conversation

@FrozenPandaz
Copy link
Copy Markdown
Contributor

@FrozenPandaz FrozenPandaz commented Mar 24, 2026

Current Behavior

Each package defines a legacy-post-build target in project.json with inline asset copy configuration. Inputs are not accurately declared, leading to sandbox violations in CI. The asset globs, ignores, and outputs must be manually kept in sync across 37 packages.

Expected Behavior

A copy-assets createNodesV2 plugin reads assets.json from each package and automatically generates the target with:

  • Inputs derived from asset globs (positive patterns first, then negations)
  • Outputs derived using the same dest logic as CopyAssetsHandler
  • dependentTasksOutputFiles for gitignored build artifacts (jars, native binaries)
  • Automatic outDir exclusion from asset copies

Changes

New infrastructure:

  • Add copy-assets createNodesV2 plugin in tools/workspace-plugin
  • Add copy-assets executor (simplified from legacy-post-build — just copies assets, no package.json field manipulation)
  • Extract normalizeAssets and getAssetOutputPath into reusable module in packages/js
  • Add copyReadme namedInput for copy-readme build targets

Migration (all 37 packages):

  • Create assets.json for every package defining what to copy
  • Remove all legacy-post-build targets from project.json files
  • Remove legacy-post-build target defaults from nx.json
  • Remove redundant copy-local-native target (replaced by .node/.wasm in asset glob)

Cleanup:

  • Remove dead config: creator-files globs, non-existent template files, typo'd directory names
  • Use root-level tsconfig*.json ignore instead of recursive (so template tsconfigs in files/ dirs are still copied)
  • Replace !(*.ts) extglob patterns with explicit globs (extglobs don't work correctly in Nx inputs)
  • Fix gradle lint: add buildTargets: ["build-base"] and tslib dependency
  • Add jar outputs to maven _package target for correct dependentTasksOutputFiles resolution

Other fixes:

  • Exclude .swc directories from sandbox write checks
  • Enable typecheck for angular-rspack packages (remove addTypecheckTarget: false)
  • Pin workspace-plugin deps to explicit versions, add @nx/plugin to root package.json

@FrozenPandaz FrozenPandaz requested a review from a team as a code owner March 24, 2026 17:52
@FrozenPandaz FrozenPandaz requested a review from MaxKless March 24, 2026 17:52
@netlify
Copy link
Copy Markdown

netlify bot commented Mar 24, 2026

Deploy Preview for nx-docs ready!

Name Link
🔨 Latest commit 90d2206
🔍 Latest deploy log https://app.netlify.com/projects/nx-docs/deploys/69c5b5a448bc100008d29bea
😎 Deploy Preview https://deploy-preview-34994--nx-docs.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

@netlify
Copy link
Copy Markdown

netlify bot commented Mar 24, 2026

Deploy Preview for nx-dev ready!

Name Link
🔨 Latest commit 90d2206
🔍 Latest deploy log https://app.netlify.com/projects/nx-dev/deploys/69c5b5a42386c20008fe5191
😎 Deploy Preview https://deploy-preview-34994--nx-dev.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

@nx-cloud
Copy link
Copy Markdown
Contributor

nx-cloud bot commented Mar 24, 2026

View your CI Pipeline Execution ↗ for commit 90d2206

Command Status Duration Result
nx affected --targets=lint,test,build,e2e,e2e-c... ✅ Succeeded 45m 13s View ↗
nx run-many -t check-imports check-lock-files c... ✅ Succeeded 7s View ↗
nx-cloud record -- pnpm nx conformance:check ✅ Succeeded 7s View ↗
nx-cloud record -- nx format:check ✅ Succeeded 3s View ↗
nx build workspace-plugin ✅ Succeeded <1s View ↗
nx-cloud record -- nx sync:check ✅ Succeeded <1s View ↗
nx affected -t e2e-macos-local --parallel=1 --b... ✅ Succeeded 31m 51s View ↗

☁️ Nx Cloud last updated this comment at 2026-03-26 23:28:44 UTC

@FrozenPandaz FrozenPandaz force-pushed the fix/sandboxing-config-native-node branch from 7eddc97 to fa911c7 Compare March 24, 2026 19:48
nx-cloud[bot]

This comment was marked as outdated.

@FrozenPandaz FrozenPandaz force-pushed the fix/sandboxing-config-native-node branch 2 times, most recently from 776b85f to f3dd1c3 Compare March 25, 2026 14:35
nx-cloud[bot]

This comment was marked as outdated.

@FrozenPandaz FrozenPandaz force-pushed the fix/sandboxing-config-native-node branch 4 times, most recently from c5db95e to e7c15ca Compare March 25, 2026 23:15
nx-cloud[bot]

This comment was marked as outdated.

nx-cloud[bot]

This comment was marked as outdated.

Comment on lines +60 to +61
? [
`${relative(projectRoot, assetsJson.outDir)}/**`,
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The relative() call will fail when assetsJson.outDir is an absolute path. The code assumes assetsJson.outDir is always relative to projectRoot, but several assets.json files use absolute-style paths (e.g., packages/nx/dist, packages/dotnet/dist). When assetsJson.outDir doesn't start with projectRoot, relative() produces paths with .. segments that should not be in the ignore pattern.

const ignore =
  input === projectRoot && !path.isAbsolute(assetsJson.outDir)
    ? [
        `${relative(projectRoot, assetsJson.outDir)}/**`,
        ...(asset.ignore ?? []),
      ]
    : asset.ignore;
Suggested change
? [
`${relative(projectRoot, assetsJson.outDir)}/**`,
input === projectRoot && !path.isAbsolute(assetsJson.outDir)
? [
`${relative(projectRoot, assetsJson.outDir)}/**`,

Spotted by Graphite

Fix in Graphite


Is this helpful? React 👍 or 👎 to let us know.

@FrozenPandaz FrozenPandaz force-pushed the fix/sandboxing-config-native-node branch 4 times, most recently from a3a8def to 4571187 Compare March 26, 2026 14:55
@FrozenPandaz FrozenPandaz changed the title fix(repo): restore sandboxing config for native .node files fix(repo): add copy-assets plugin and migrate all packages from legacy-post-build Mar 26, 2026
Comment on lines +124 to +130
const outputs = normalized.map((entry) => {
const outputPath = getAssetOutputPath(entry.pattern, entry);
if (outputPath.startsWith(projectRoot + '/')) {
return `{projectRoot}/${outputPath.slice(projectRoot.length + 1)}`;
}
return `{workspaceRoot}/${outputPath}`;
});
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The getAssetOutputPath function is being called with entry.pattern (a glob pattern like packages/angular/**/files/**) but it expects an actual file path as its first argument. This will produce incorrect output patterns.

The function computes path.relative(entry.input, src) where src is expected to be a file path, not a glob pattern. For glob patterns, this will produce unpredictable results.

To fix, the outputs should be constructed directly from entry.output without trying to compute them from patterns:

const outputs = normalized.map((entry) => {
  if (entry.output.startsWith(projectRoot + '/')) {
    return `{projectRoot}/${entry.output.slice(projectRoot.length + 1)}/**`;
  }
  return `{workspaceRoot}/${entry.output}/**`;
});
Suggested change
const outputs = normalized.map((entry) => {
const outputPath = getAssetOutputPath(entry.pattern, entry);
if (outputPath.startsWith(projectRoot + '/')) {
return `{projectRoot}/${outputPath.slice(projectRoot.length + 1)}`;
}
return `{workspaceRoot}/${outputPath}`;
});
const outputs = normalized.map((entry) => {
if (entry.output.startsWith(projectRoot + '/')) {
return `{projectRoot}/${entry.output.slice(projectRoot.length + 1)}/**`;
}
return `{workspaceRoot}/${entry.output}/**`;
});

Spotted by Graphite

Fix in Graphite


Is this helpful? React 👍 or 👎 to let us know.

nx-cloud[bot]

This comment was marked as outdated.

@FrozenPandaz FrozenPandaz force-pushed the fix/sandboxing-config-native-node branch 5 times, most recently from c2e1ab8 to 8024262 Compare March 26, 2026 18:40
nx-cloud[bot]

This comment was marked as outdated.

…puts

Add outputs to maven-batch-runner _package target so
dependentTasksOutputFiles can resolve the jar files. Narrow
workspace-plugin input to just the executor files.
The !(*.ts) extglob doesn't work correctly in Nx inputs, causing
.d.ts files to be excluded. Replace with explicit globs matching
the standard pattern used by other packages.
Change **/tsconfig*.json to tsconfig*.json in asset ignores so
template tsconfig files inside files/ directories are still copied.
Remove tsConfig, main, types, packageRoot, and addPackageJsonFields
options. The executor now only needs assets and outputPath since the
plugin always provides both.
The old legacy-post-build executor copied typings to types at build
time. Now that the executor is simplified, set types directly in
source package.json and remove the deprecated typings field.
…-specific cache

Split .node files into separate asset entry with includeIgnoredFiles
so they are tracked via dependentTasksOutputFiles. Add build-native
to copy-assets dependsOn so the cache key includes the platform.
@FrozenPandaz FrozenPandaz force-pushed the fix/sandboxing-config-native-node branch from e164c3f to 8309fd7 Compare March 26, 2026 20:07
nx-cloud[bot]

This comment was marked as outdated.

nx-cloud[bot]

This comment was marked as outdated.

nx-cloud[bot]

This comment was marked as outdated.

Copy link
Copy Markdown
Contributor

@nx-cloud nx-cloud bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nx Cloud has identified a flaky task in your failed CI:

🔂 Since the failure was identified as flaky, we triggered a CI rerun by adding an empty commit to this branch.

Nx Cloud View detailed reasoning in Nx Cloud ↗

🔔 Heads up, your workspace has pending recommendations ↗ to auto-apply fixes for similar failures.


🎓 Learn more about Self-Healing CI on nx.dev

@FrozenPandaz FrozenPandaz force-pushed the fix/sandboxing-config-native-node branch from b440466 to 90d2206 Compare March 26, 2026 22:39
try {
await assetHandler.processAllAssetsOnce();
} catch (error) {
logger.error(`Error processing assets: ${error.message || error}`);
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: if error: unknown then you'd to check instanceof Error or that message is a property because using. We don't have strict mode on so it's passing typechecks.

@FrozenPandaz FrozenPandaz merged commit a040a93 into master Mar 27, 2026
25 checks passed
@FrozenPandaz FrozenPandaz deleted the fix/sandboxing-config-native-node branch March 27, 2026 15:49
FrozenPandaz added a commit that referenced this pull request Mar 27, 2026
## Current Behavior

- The copy-assets plugin copies `assets.json` into the output directory
(it doesn't exclude itself)
- The copy-assets executor catches errors with `error.message` but
`error` is typed as `unknown`, which can fail at runtime
- No way to skip e2e cleanup when debugging locally

## Expected Behavior

- `assets.json` is excluded from being copied into the output directory
- Error handling properly checks `instanceof Error` before accessing
`.message`
- Setting `NX_E2E_SKIP_CLEANUP=true` preserves the test project
directory for debugging

## Related Issue(s)

Follow-up to #34994 — addresses review comments from that PR.

---------

Co-authored-by: nx-cloud[bot] <71083854+nx-cloud[bot]@users.noreply.github.com>
@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Apr 2, 2026

This pull request has already been merged/closed. If you experience issues related to these changes, please open a new issue referencing this pull request.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Apr 2, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants