Skip to content

fix(react-native): include migration docs in the built package - #36378

Merged
leosvelperez merged 7 commits into
masterfrom
fix-react-native-migration-docs
Jul 22, 2026
Merged

fix(react-native): include migration docs in the built package#36378
leosvelperez merged 7 commits into
masterfrom
fix-react-native-migration-docs

Conversation

@leosvelperez

@leosvelperez leosvelperez commented Jul 16, 2026

Copy link
Copy Markdown
Member

Note

#36377 makes the migrations reference pages read the documentation key, which is what surfaces this package's missing file on the page. The two PRs are independent and can merge in any order.

Current Behavior

@nx/react-native declares a documentation file for update-23-0-0-migrate-create-nodes-v2-import, but its assets config never copies src/migrations/**/*.md into dist. Since the published package ships its built output from dist, it points at a file it does not contain:

  • nx migrate --run-migrations --agentic warns that the documentation file could not be resolved and drops it as agent context.
  • The migrations reference page renders the entry with only its one-line description, while the identical migration in sibling plugins renders its docs.

Nothing caught this. assertValidMigrationPaths maps the published ./dist/... path back to the source tree and asserts the source file exists, which it does, so the spec passes while the built package stays broken.

Expected Behavior

The markdown is copied into the built package, so the published tarball contains the file it references and both consumers read it.

The migration-markdown-assets conformance rule closes the gap the spec leaves open, for every package rather than the 27 with a migrations.spec.ts. It checks each prompt and documentation reference against the files the assets config actually produces, catching a file that is never copied, one copied somewhere other than the declared path, and a reference resolving outside the built output. Rather than reimplementing the glob and output semantics, it drives the copy-assets pipeline with a collecting callback in place of the copying one, so the paths it compares against are the ones a build produces; it needs no dist. toExecutorAssets moves out of the copy-assets plugin so the rule and the plugin expand an assets.json the same way. The generated copy-assets targets are unchanged.

Relative imports need a .js specifier under nodenext, which jest resolves back to the TypeScript sources through the added moduleNameMapper.

Related Issue(s)

Fixes NXC-4713


View session information ↗

@netlify

netlify Bot commented Jul 16, 2026

Copy link
Copy Markdown

Deploy Preview for nx-dev ready!

Name Link
🔨 Latest commit 26f9f93
🔍 Latest deploy log https://app.netlify.com/projects/nx-dev/deploys/6a60eadc57a3ce0008fe27d1
😎 Deploy Preview https://deploy-preview-36378--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.

@netlify

netlify Bot commented Jul 16, 2026

Copy link
Copy Markdown

Deploy Preview for nx-docs ready!

Name Link
🔨 Latest commit 26f9f93
🔍 Latest deploy log https://app.netlify.com/projects/nx-docs/deploys/6a60eadc7d2d310008028633
😎 Deploy Preview https://deploy-preview-36378--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.

@nx-cloud

nx-cloud Bot commented Jul 16, 2026

Copy link
Copy Markdown
Contributor

View your CI Pipeline Execution ↗ for commit 26f9f93

Command Status Duration Result
nx affected --targets=lint,test,build,e2e,e2e-c... ✅ Succeeded 47m 6s View ↗
nx run-many -t check-imports check-lock-files c... ✅ Succeeded 3s View ↗
nx-cloud record -- pnpm nx-cloud conformance:check ✅ Succeeded 1m 5s View ↗
nx build workspace-plugin ✅ Succeeded 4m 6s View ↗
nx-cloud record -- nx sync:check ✅ Succeeded 18s View ↗
nx-cloud record -- nx format:check ✅ Succeeded 5s View ↗
nx affected -t e2e-macos-local --parallel=2 --b... ✅ Succeeded 36m 16s View ↗

☁️ Nx Cloud last updated this comment at 2026-07-22 17:03:37 UTC

@leosvelperez leosvelperez self-assigned this Jul 16, 2026
@leosvelperez
leosvelperez marked this pull request as ready for review July 16, 2026 13:29
@leosvelperez
leosvelperez requested a review from a team as a code owner July 16, 2026 13:29
@leosvelperez
leosvelperez requested a review from lourw July 16, 2026 13:29

@nx-cloud nx-cloud Bot left a comment

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.

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

leosvelperez and others added 7 commits July 22, 2026 18:01
`@nx/react-native` declares a `documentation` file for `update-23-0-0-migrate-create-nodes-v2-import`, but the assets config never copied `src/migrations/**/*.md` into `dist`. The published package therefore points at a file it does not contain: the migrations reference page renders the entry without its docs, and `nx migrate --run-migrations --agentic` warns that the documentation file could not be resolved and drops it as agent context.

Copy the migration markdown into the built package, matching the other plugins.
`migrations.json` resolves `prompt` and `documentation` against the built `./dist`, but nothing checked that the assets config copies those markdown files there. `assertValidMigrationPaths` maps the published path back to the source tree and asserts the source file exists, so a package could reference a file its build never ships and every test still passed. That is how `@nx/react-native` came to publish a `documentation` path pointing at a file absent from the tarball.

The migration-markdown-assets conformance rule drives the copy-assets pipeline with a collecting callback in place of the copying one, so the paths it compares against are the ones a build produces. `toExecutorAssets` moves out of the copy-assets plugin so the rule and the plugin expand an assets.json the same way.

Relative imports need a `.js` specifier under `nodenext`, which jest resolves back to the TypeScript sources through the added `moduleNameMapper`.
…he built output

References resolving outside a package's built output were skipped, on the
premise that they are checked into the package and published through
`package.json#files`. No package publishes anything but its built output, so the
skip was fail-open: dropping the `dist/` prefix, the most plausible typo for
these paths, produced no violation and the rule missed the bug it exists to
catch. Such a reference is now a violation carrying its own message.

The message for a file that is not copied asserted a missing glob, but the file
can just as well be absent from the source tree or copied to a different path.
It now states what is known and leaves the cause open.

`collectCopiedFiles` claimed not to touch the file system. It reads
`.gitignore`/`.nxignore` and globs the working tree, which is what makes the
collected paths reflect a real build.

`generators` and `schematics` entries are now merged in the same precedence nx
itself applies, so a `generators` entry wins.
The rule merges `schematics` and `generators` entries in the precedence nx
itself applies, but nothing exercised it: no spec declared a `schematics` key,
so inverting the merge went unnoticed. Pin it with an entry declared under both
names, where only the `generators` file is copied into the built output.
…le message

The violation for a reference resolving outside the built output claimed that
only that directory is published and that the reference therefore cannot
resolve in the installed package. Neither holds: no package declaring
migrations publishes only its build output, and migration references are
resolved with `require.resolve` relative to the installed package's
`migrations.json` directory, so a reference outside the built output can
resolve. Requiring references to point inside the built output is a
deliberate requirement rather than a physical constraint, so the message now
states it as one.
…assets rule

The rule vouched for the `prompt` and `documentation` files a migrations.json
references, but not for the implementation each entry actually runs, so an
entry pointing at a file the build never emits still passed.

Implementations are tsc outputs rather than copied assets, so the assets
pipeline cannot answer for them. The published path maps back through the
package's own `rootDir`/`outDir` instead, and the source file it comes from has
to exist. A package whose tsconfig declares neither is left unchecked rather
than checked against a guessed layout.
@leosvelperez
leosvelperez force-pushed the fix-react-native-migration-docs branch from ee61351 to 26f9f93 Compare July 22, 2026 16:07
@leosvelperez
leosvelperez enabled auto-merge (squash) July 22, 2026 16:12
@leosvelperez
leosvelperez merged commit c8f67bb into master Jul 22, 2026
26 checks passed
@leosvelperez
leosvelperez deleted the fix-react-native-migration-docs branch July 22, 2026 17:04
leosvelperez added a commit that referenced this pull request Jul 23, 2026
> [!NOTE]
> `@nx/react-native` declares a `documentation` file that its build
never copies into the published package. That is a packaging bug rather
than a rendering one, and it is fixed separately in #36378. The two PRs
are independent and can merge in any order.

## Current Behavior

The migrations reference pages inline `<implementation>.md` whenever a
file with that name happens to sit next to a migration's implementation,
instead of reading the `documentation` key the entry declares.

Two things fall out of that guess:

- The eslint `update-23-1-0-convert-to-flat-config` migration ships a
`prompt` file whose basename matches its implementation, so its LLM
runbook ("ESLint v9 Flat Config Migration Instructions for LLM") renders
as public documentation on the eslint migrations page.
- Prompt-only migrations never match the guess, since it keys off the
implementation path. The docs declared by
`update-23-1-0-create-ai-instructions-for-next-15` and
`update-23-1-0-create-ai-instructions-for-react-19` therefore never
render, even though both entries separate their agent `prompt` from a
user-facing `documentation` file.

## Expected Behavior

The pages read the `documentation` key and no longer guess from the
implementation basename. The runbook is gone from the eslint page, and
the two prompt-only migrations render the docs they declare.

The two jest setup-file migrations relied on the guess to render their
docs, so they now declare `documentation` explicitly. Every other
migration that rendered through the guess declares the key, so the
runbook is the only content any page loses.

## Related Issue(s)

Fixes NXC-4712

<!-- polygraph-session-start -->
---
[View session information
↗](https://app.trypolygraph.com/orgs/6a061dcb561c062131116eca/sessions/fix-migration-docs-3961141b)
<!-- polygraph-session-end -->

---------

Co-authored-by: nx-cloud[bot] <71083854+nx-cloud[bot]@users.noreply.github.com>
jaysoo pushed a commit that referenced this pull request Jul 23, 2026
> [!NOTE]
> `@nx/react-native` declares a `documentation` file that its build
never copies into the published package. That is a packaging bug rather
than a rendering one, and it is fixed separately in #36378. The two PRs
are independent and can merge in any order.

The migrations reference pages inline `<implementation>.md` whenever a
file with that name happens to sit next to a migration's implementation,
instead of reading the `documentation` key the entry declares.

Two things fall out of that guess:

- The eslint `update-23-1-0-convert-to-flat-config` migration ships a
`prompt` file whose basename matches its implementation, so its LLM
runbook ("ESLint v9 Flat Config Migration Instructions for LLM") renders
as public documentation on the eslint migrations page.
- Prompt-only migrations never match the guess, since it keys off the
implementation path. The docs declared by
`update-23-1-0-create-ai-instructions-for-next-15` and
`update-23-1-0-create-ai-instructions-for-react-19` therefore never
render, even though both entries separate their agent `prompt` from a
user-facing `documentation` file.

The pages read the `documentation` key and no longer guess from the
implementation basename. The runbook is gone from the eslint page, and
the two prompt-only migrations render the docs they declare.

The two jest setup-file migrations relied on the guess to render their
docs, so they now declare `documentation` explicitly. Every other
migration that rendered through the guess declares the key, so the
runbook is the only content any page loses.

Fixes NXC-4712

<!-- polygraph-session-start -->
---
[View session information
↗](https://app.trypolygraph.com/orgs/6a061dcb561c062131116eca/sessions/fix-migration-docs-3961141b)
<!-- polygraph-session-end -->

---------

Co-authored-by: nx-cloud[bot] <71083854+nx-cloud[bot]@users.noreply.github.com>
(cherry picked from commit 1ad2f96)
FrozenPandaz pushed a commit that referenced this pull request Jul 29, 2026
> [!NOTE]
> #36377 makes the migrations reference pages read the `documentation`
key, which is what surfaces this package's missing file on the page. The
two PRs are independent and can merge in any order.

## Current Behavior

`@nx/react-native` declares a `documentation` file for
`update-23-0-0-migrate-create-nodes-v2-import`, but its assets config
never copies `src/migrations/**/*.md` into `dist`. Since the published
package ships its built output from `dist`, it points at a file it does
not contain:

- `nx migrate --run-migrations --agentic` warns that the documentation
file could not be resolved and drops it as agent context.
- The migrations reference page renders the entry with only its one-line
description, while the identical migration in sibling plugins renders
its docs.

Nothing caught this. `assertValidMigrationPaths` maps the published
`./dist/...` path back to the source tree and asserts the source file
exists, which it does, so the spec passes while the built package stays
broken.

## Expected Behavior

The markdown is copied into the built package, so the published tarball
contains the file it references and both consumers read it.

The `migration-markdown-assets` conformance rule closes the gap the spec
leaves open, for every package rather than the 27 with a
`migrations.spec.ts`. It checks each `prompt` and `documentation`
reference against the files the assets config actually produces,
catching a file that is never copied, one copied somewhere other than
the declared path, and a reference resolving outside the built output.
Rather than reimplementing the glob and output semantics, it drives the
copy-assets pipeline with a collecting callback in place of the copying
one, so the paths it compares against are the ones a build produces; it
needs no `dist`. `toExecutorAssets` moves out of the copy-assets plugin
so the rule and the plugin expand an `assets.json` the same way. The
generated `copy-assets` targets are unchanged.

Relative imports need a `.js` specifier under `nodenext`, which jest
resolves back to the TypeScript sources through the added
`moduleNameMapper`.

## Related Issue(s)

Fixes NXC-4713

<!-- polygraph-session-start -->
---
[View session information
↗](https://app.trypolygraph.com/orgs/6a061dcb561c062131116eca/sessions/fix-migration-docs-3961141b)
<!-- polygraph-session-end -->

---------

Co-authored-by: nx-cloud[bot] <71083854+nx-cloud[bot]@users.noreply.github.com>
(cherry picked from commit c8f67bb)
FrozenPandaz pushed a commit that referenced this pull request Jul 29, 2026
> [!NOTE]
> `@nx/react-native` declares a `documentation` file that its build
never copies into the published package. That is a packaging bug rather
than a rendering one, and it is fixed separately in #36378. The two PRs
are independent and can merge in any order.

## Current Behavior

The migrations reference pages inline `<implementation>.md` whenever a
file with that name happens to sit next to a migration's implementation,
instead of reading the `documentation` key the entry declares.

Two things fall out of that guess:

- The eslint `update-23-1-0-convert-to-flat-config` migration ships a
`prompt` file whose basename matches its implementation, so its LLM
runbook ("ESLint v9 Flat Config Migration Instructions for LLM") renders
as public documentation on the eslint migrations page.
- Prompt-only migrations never match the guess, since it keys off the
implementation path. The docs declared by
`update-23-1-0-create-ai-instructions-for-next-15` and
`update-23-1-0-create-ai-instructions-for-react-19` therefore never
render, even though both entries separate their agent `prompt` from a
user-facing `documentation` file.

## Expected Behavior

The pages read the `documentation` key and no longer guess from the
implementation basename. The runbook is gone from the eslint page, and
the two prompt-only migrations render the docs they declare.

The two jest setup-file migrations relied on the guess to render their
docs, so they now declare `documentation` explicitly. Every other
migration that rendered through the guess declares the key, so the
runbook is the only content any page loses.

## Related Issue(s)

Fixes NXC-4712

<!-- polygraph-session-start -->
---
[View session information
↗](https://app.trypolygraph.com/orgs/6a061dcb561c062131116eca/sessions/fix-migration-docs-3961141b)
<!-- polygraph-session-end -->

---------

Co-authored-by: nx-cloud[bot] <71083854+nx-cloud[bot]@users.noreply.github.com>
(cherry picked from commit 1ad2f96)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants