Compare commits

...

71 Commits

Author SHA1 Message Date
FrozenPandaz 2c9ed8fc67 fix(repo): use GITHUB_ACTIONS env var for CI detection in nx-release
CI / main-linux (push) Has been cancelled
CI / main-macos (push) Has been cancelled
2026-02-11 15:16:03 -05:00
Jason Jean 5eedb37285 chore(repo): patch nx js 2026-02-11 14:00:01 -05:00
FrozenPandaz 508d91e4dc fix(repo): use sudo for global npm install in publish workflow 2026-02-11 12:18:21 -05:00
FrozenPandaz 8eed5808bc chore(repo): update publish.yml with the latest from master 2026-02-11 10:38:48 -05:00
FrozenPandaz db7ef37596 chore(repo): fix build 2026-02-10 17:47:49 -05:00
Leosvel Pérez Espinosa cd7f2ba224 fix(core): track all task outputs regardless of path depth (#34321)
## Current Behavior

When a task has outputs at different path depths, some outputs may not
be tracked. This causes:

- Deleted output files not being detected
- Cache restoration being skipped with message "existing outputs match
the cache, left as is"
- Files not being restored even though they exist in cache

## Expected Behavior

All task outputs are tracked regardless of their path depth, ensuring:

- Deleted outputs are correctly detected
- Cache restoration happens when outputs are missing
2026-02-10 14:35:21 -05:00
Jack Hsu 7992b7aa8f chore(misc): fix type errors 2025-08-01 14:52:13 -04:00
Jack Hsu 684a357f65 chore(misc): update stale snapshot on patch branch 2025-08-01 14:48:22 -04:00
Rodrigo Yokota 6337e5423b fix(module-federation): re-add support for mf aliases (#31347)
## Current Behavior
At some point in time, we had support for Module Federation aliases, and
I noticed some of our examples broke in the latest versions of Nx.


![image](https://github.com/user-attachments/assets/c9130d0c-3694-4650-8c26-96ff62c7ccad)

This is an attempt to regain that support with some normalization of
Module Federation project names.

## Expected Behavior
We need to have the mapping back of aliases in the format:
```typescript
const mfConfig = {
  // ...
  "@nx-mf/remote": "_nx_mf_remote@http://localhost:3001",
  // ...
}
```

## Related Issue(s)
https://github.com/nrwl/nx/issues/31346

Fixes #
Add a function specific to parse Federated names into resolvable
JavaScript vars.
Use this function in every place a `str.replace(/-/, '_')` is being
used.

---------

Co-authored-by: Colum Ferry <cferry09@gmail.com>
2025-08-01 13:22:58 -04:00
Leosvel Pérez Espinosa b8bf803963 fix(angular): add missing config properties to adapter whitelist (#32186)
## Current Behavior

Running tasks for Angular projects that use Angular CLI builders can
result in validation errors when the project or workspace configurations
contain Nx-specific properties.

## Expected Behavior

Running tasks for Angular projects that use Angular CLI builders
shouldn't result in validation errors when the project or workspace
configurations contain Nx-specific properties.
2025-08-01 13:22:58 -04:00
Jack Hsu 3f0b2dc716 docs(docker): fix config for releaseTagPattern to be valid (#32179)
This PR fixes an invalid config for Docker release that didn't end up
being implemented.
2025-08-01 13:22:58 -04:00
Nicholas Cunningham e966be7545 fix(testing): add NODE_OPTIONS flag for Node.js 24 compatibility (#32177)
## Current Behavior

Jest fails to parse TypeScript config files with ES module syntax on
Node.js 24 with error:
```
Error: Jest: Failed to parse the TypeScript config file
SyntaxError: Unexpected token 'export'
```

## Expected Behavior

Jest should successfully parse TypeScript config files on Node.js 24.

## Related Issue(s)

This occurs because Jest 30 + Node.js 24 can't parse TS configs with
imports without the `--no-experimental-strip-types` flag.

Related to: https://github.com/jestjs/jest/issues/15682
2025-08-01 13:22:58 -04:00
Jack Hsu f4892c5c58 docs(docker): add documentation for @nx/docker and supporting release pages (#32130)
See:
https://nx-dev-git-docs-node-docker-nrwl.vercel.app/features/manage-releases
<!-- Please make sure you have read the submission guidelines before
posting an PR -->
<!--
https://github.com/nrwl/nx/blob/master/CONTRIBUTING.md#-submitting-a-pr
-->

<!-- Please make sure that your commit message follows our format -->
<!-- Example: `fix(nx): must begin with lowercase` -->

<!-- If this is a particularly complex change or feature addition, you
can request a dedicated Nx release for this pull request branch. Mention
someone from the Nx team or the `@nrwl/nx-pipelines-reviewers` and they
will confirm if the PR warrants its own release for testing purposes,
and generate it for you if appropriate. -->

## Current Behavior
<!-- This is the behavior we have today -->

## Expected Behavior
<!-- This is the behavior we should expect with the changes in this PR
-->

## Related Issue(s)
<!-- Please link the issue being fixed so it gets closed when this is
merged. -->

Fixes #

---------

Co-authored-by: Colum Ferry <cferry09@gmail.com>
2025-08-01 13:17:19 -04:00
Mike Hartington 5d6a2dd669 docs(misc): add docker release blog post (#32170)
<!-- Please make sure you have read the submission guidelines before
posting an PR -->
<!--
https://github.com/nrwl/nx/blob/master/CONTRIBUTING.md#-submitting-a-pr
-->

<!-- Please make sure that your commit message follows our format -->
<!-- Example: `fix(nx): must begin with lowercase` -->

<!-- If this is a particularly complex change or feature addition, you
can request a dedicated Nx release for this pull request branch. Mention
someone from the Nx team or the `@nrwl/nx-pipelines-reviewers` and they
will confirm if the PR warrants its own release for testing purposes,
and generate it for you if appropriate. -->

## Current Behavior
<!-- This is the behavior we have today -->

## Expected Behavior
<!-- This is the behavior we should expect with the changes in this PR
-->

## Related Issue(s)
<!-- Please link the issue being fixed so it gets closed when this is
merged. -->

Fixes #
2025-08-01 13:17:19 -04:00
Emily Xiong c29dc0a67a fix(gradle): fix bootJar, add excludeDependsOn to false (#32157)
<!-- Please make sure you have read the submission guidelines before
posting an PR -->
<!--
https://github.com/nrwl/nx/blob/master/CONTRIBUTING.md#-submitting-a-pr
-->

<!-- Please make sure that your commit message follows our format -->
<!-- Example: `fix(nx): must begin with lowercase` -->

<!-- If this is a particularly complex change or feature addition, you
can request a dedicated Nx release for this pull request branch. Mention
someone from the Nx team or the `@nrwl/nx-pipelines-reviewers` and they
will confirm if the PR warrants its own release for testing purposes,
and generate it for you if appropriate. -->

## Current Behavior
<!-- This is the behavior we have today -->

when run bootJar and bootRun, i got this error:
```
> Querying the mapped value of task ':application:resolveMainClassName' property 'outputFile' before task ':application:resolveMainClassName' has completed is not supported
```

both bootJar and bootRun dependsOn resolveMainClassName. however, when
it runs with excludeDependsOn, the gradlew command will be `./gradlew
:app:bootRun --exclude-task :app:resolveMainClassName`. when running the
command like that, it will cause an issue

## Expected Behavior
<!-- This is the behavior we should expect with the changes in this PR
-->
for bootJar and bootRun, hardcode excludeDependsOn to false

## Related Issue(s)
<!-- Please link the issue being fixed so it gets closed when this is
merged. -->

Fixes #
2025-08-01 13:17:19 -04:00
Colum Ferry a10a4201b8 fix(core): only traverse workspace node when it exists (#32165)
## Current Behavior
There is a runtime issue in project graph pruning where we attempt to
eagerly traverse workspace nodes when they may not exist.

## Expected Behavior
Ensure the workspace node exists before traversing it.
2025-08-01 13:17:19 -04:00
Jack Hsu 8808cb7c1f fix(release): use top-level releaseTagPattern as the default for release groups (#32154)
## Current Behavior

When using `nx release` with Docker projects, the
`release.releaseTagPattern` defined at the root level is not inherited
by release groups. Users must explicitly specify the `releaseTagPattern`
at both the root level AND within
`release.groups.<group>.releaseTagPattern` for it to work correctly when
using 'independent' releases.

Example configuration that doesn't work as expected:
```json
{
  "release": {
    "releaseTagPattern": "release/{projectName}/{version}",
    "groups": {
      "apps": {
          "projectsRelationship": "independent",
          // releaseTagPattern is not inherited here
      }
    }
  }
}
```

## Expected Behavior

The `release.releaseTagPattern` should be automatically inherited by
group configurations, following the same inheritance pattern as other
release configuration properties. Users should only need to specify the
pattern once at the root level unless they want to override it for
specific groups.

With this fix, the above configuration will work correctly, and the
docker releases will use the `release/{projectName}/{version}` pattern
for git tags.

## Related Issue(s)

Fixes #
2025-08-01 13:17:19 -04:00
Nicholas Cunningham 6ce05845d0 fix(rspack): update installed version of rspack to be same as @nx/rspack (#32152)
We should match the version which we install of `@rspack/core` to be the
same as `@nx/rspack` as the mismatch can cause errors:
https://staging.nx.app/runs/McxmSeecWa/task/e2e-rspack%3Ae2e-local
```
> rspack build --node-env=production

●  ━━━━━━━━━━━━━━━━━━━━━━━━━ (10%) building builtin:swc-loader??ruleSet[1].rules[2].use[0]!/../my-rspack-react/apps/my-rspack-react/src/../repos/my-rspack-react/node_modules/@nx/rspack/node_modules/@rspack/core/dist/cssExtractLoader.js:141
            }) : result, dependencies.length > 0 && this.__internal__setParseMeta(PLUGIN_NAME, JSON.stringify(dependencies)), callback(null, resultSource, void 0, data);
                                                         ^

TypeError: this.__internal__setParseMeta is not a function
    at /../my-rspack-react/node_modules/@nx/rspack/node_modules/@rspack/core/dist/cssExtractLoader.js:141:58
    at ../my-rspack-react/node_modules/@nx/rspack/node_modules/@rspack/core/dist/cssExtractLoader.js:142:11
    at /../my-rspack-react/node_modules/@rspack/core/dist/index.js:3435:255
    at /../my-rspack-react/node_modules/@rspack/core/dist/index.js:3431:120

Node.js v22.16.0
```

This version is also the same as in our migrations for `@nx/rspack`.

References:
https://github.com/nrwl/nx/blob/master/packages/rspack/package.json#L32

https://github.com/nrwl/nx/blob/master/packages/rspack/migrations.json#L81
2025-08-01 13:17:19 -04:00
Caleb Ukle f0a5c2f728 docs(misc): update gradle tutorial (#32137)
before:
gradle tutorial didn't match with other tutorials format

after:
gradle tutorial fits format of other tutorials

---------

Co-authored-by: Jack Hsu <jack.hsu@gmail.com>
Co-authored-by: nx-cloud[bot] <71083854+nx-cloud[bot]@users.noreply.github.com>
2025-08-01 13:17:19 -04:00
Jack Hsu 3012dba2d0 fix(release): provide a link to Manage Release page when "nx release"fails (#32153)
Currently users running `nx release` without a correct setup will see an
unhelpful message:

```
NX   Release group "__default__" matches no projects. Please ensure all release groups match at least one project:

The relevant config is defined here: nx.json
```

This change provides a link to https://nx.dev/features/manage-releases
so users can find the correct information to fix their setup.

This is particular useful when users are curious or checking out `nx
release` for the first time, and may not realize that there are set up
steps.

<!-- Please make sure you have read the submission guidelines before
posting an PR -->
<!--
https://github.com/nrwl/nx/blob/master/CONTRIBUTING.md#-submitting-a-pr
-->

<!-- Please make sure that your commit message follows our format -->
<!-- Example: `fix(nx): must begin with lowercase` -->

<!-- If this is a particularly complex change or feature addition, you
can request a dedicated Nx release for this pull request branch. Mention
someone from the Nx team or the `@nrwl/nx-pipelines-reviewers` and they
will confirm if the PR warrants its own release for testing purposes,
and generate it for you if appropriate. -->

## Current Behavior
Error message is not helpful

## Expected Behavior
Provide a link for users to find the info they need

## Related Issue(s)
<!-- Please link the issue being fixed so it gets closed when this is
merged. -->

Fixes #
2025-08-01 13:17:19 -04:00
Mike Hartington f834ffe9a7 docs(misc): add android blog post for java week (#32146)
<!-- Please make sure you have read the submission guidelines before
posting an PR -->
<!--
https://github.com/nrwl/nx/blob/master/CONTRIBUTING.md#-submitting-a-pr
-->

<!-- Please make sure that your commit message follows our format -->
<!-- Example: `fix(nx): must begin with lowercase` -->

<!-- If this is a particularly complex change or feature addition, you
can request a dedicated Nx release for this pull request branch. Mention
someone from the Nx team or the `@nrwl/nx-pipelines-reviewers` and they
will confirm if the PR warrants its own release for testing purposes,
and generate it for you if appropriate. -->

## Current Behavior
<!-- This is the behavior we have today -->

## Expected Behavior
<!-- This is the behavior we should expect with the changes in this PR
-->

## Related Issue(s)
<!-- Please link the issue being fixed so it gets closed when this is
merged. -->

Fixes #

---------

Co-authored-by: graphite-app[bot] <96075541+graphite-app[bot]@users.noreply.github.com>
2025-07-30 15:30:06 -04:00
Mike Hartington 7cc121c010 docs(misc): add spring boot blog post (#32123)
<!-- Please make sure you have read the submission guidelines before
posting an PR -->
<!--
https://github.com/nrwl/nx/blob/master/CONTRIBUTING.md#-submitting-a-pr
-->

<!-- Please make sure that your commit message follows our format -->
<!-- Example: `fix(nx): must begin with lowercase` -->

<!-- If this is a particularly complex change or feature addition, you
can request a dedicated Nx release for this pull request branch. Mention
someone from the Nx team or the `@nrwl/nx-pipelines-reviewers` and they
will confirm if the PR warrants its own release for testing purposes,
and generate it for you if appropriate. -->

## Current Behavior
<!-- This is the behavior we have today -->

## Expected Behavior
<!-- This is the behavior we should expect with the changes in this PR
-->

## Related Issue(s)
<!-- Please link the issue being fixed so it gets closed when this is
merged. -->

Fixes #
2025-07-30 15:28:18 -04:00
Victor Savkin 53e07ca01a fix(misc): small tweaks in messaging (#32131)
<!-- Please make sure you have read the submission guidelines before
posting an PR -->
<!--
https://github.com/nrwl/nx/blob/master/CONTRIBUTING.md#-submitting-a-pr
-->

<!-- Please make sure that your commit message follows our format -->
<!-- Example: `fix(nx): must begin with lowercase` -->

<!-- If this is a particularly complex change or feature addition, you
can request a dedicated Nx release for this pull request branch. Mention
someone from the Nx team or the `@nrwl/nx-pipelines-reviewers` and they
will confirm if the PR warrants its own release for testing purposes,
and generate it for you if appropriate. -->

## Current Behavior
<!-- This is the behavior we have today -->

## Expected Behavior
<!-- This is the behavior we should expect with the changes in this PR
-->

## Related Issue(s)
<!-- Please link the issue being fixed so it gets closed when this is
merged. -->

Fixes #
2025-07-30 15:26:45 -04:00
Juri 859c082e06 docs(core): new what is Nx video 2025-07-30 15:25:52 -04:00
Juri 5991bf5df9 docs(nx-dev): remove webinar notifier for workshop 2025-07-30 15:25:48 -04:00
Jack Hsu 9b0fb37eb6 docs(misc): make sure "npx nx@latest" is used when calling init or coonnect (#32128)
Documentation instructs users to run `npx nx init` and `npx nx connect`,
which may use cached outdated versions of
Nx.

## Expected Behavior

Documentation now uses `npx nx@latest` to ensure users always get the
latest version, preventing issues from outdated
cached versions.

Updated 27 command occurrences across 23 documentation files:
- `npx nx init` → `npx nx@latest init`
- `npx nx connect` → `npx nx@latest connect`
- `npx nx connect-to-nx-cloud` → `npx nx@latest connect-to-nx-cloud`

## Related Issue(s)

Fixes #
2025-07-29 14:15:26 -04:00
Mike Hartington 46848b9b8d docs(misc): add nx gradle blog post (#32106)
<!-- Please make sure you have read the submission guidelines before
posting an PR -->
<!--
https://github.com/nrwl/nx/blob/master/CONTRIBUTING.md#-submitting-a-pr
-->

<!-- Please make sure that your commit message follows our format -->
<!-- Example: `fix(nx): must begin with lowercase` -->

<!-- If this is a particularly complex change or feature addition, you
can request a dedicated Nx release for this pull request branch. Mention
someone from the Nx team or the `@nrwl/nx-pipelines-reviewers` and they
will confirm if the PR warrants its own release for testing purposes,
and generate it for you if appropriate. -->

## Current Behavior
<!-- This is the behavior we have today -->

## Expected Behavior
<!-- This is the behavior we should expect with the changes in this PR
-->

## Related Issue(s)
<!-- Please link the issue being fixed so it gets closed when this is
merged. -->

Fixes #
2025-07-29 11:47:13 -04:00
Victor Savkin b8ee55b1cc chore(misc): temporarily hide social card (#32080)
<!-- Please make sure you have read the submission guidelines before
posting an PR -->
<!--
https://github.com/nrwl/nx/blob/master/CONTRIBUTING.md#-submitting-a-pr
-->

<!-- Please make sure that your commit message follows our format -->
<!-- Example: `fix(nx): must begin with lowercase` -->

<!-- If this is a particularly complex change or feature addition, you
can request a dedicated Nx release for this pull request branch. Mention
someone from the Nx team or the `@nrwl/nx-pipelines-reviewers` and they
will confirm if the PR warrants its own release for testing purposes,
and generate it for you if appropriate. -->

## Current Behavior
<!-- This is the behavior we have today -->

## Expected Behavior
<!-- This is the behavior we should expect with the changes in this PR
-->

## Related Issue(s)
<!-- Please link the issue being fixed so it gets closed when this is
merged. -->

Fixes #
2025-07-29 09:34:00 -04:00
Nicholas Cunningham 42c2d0dc45 fix(misc): critical severity for form-data package (#32108)
### Currently
The `form-data` version we are using contains a critical issue which can
be reproduce by running.
```
pnpm dlx audit-ci --critical --report-type summary
```
https://github.com/advisories/GHSA-fjxv-7rqg-78g4

We should update our `form-data` version that contains the patch to
address the vulnerability.

### Misc
This also addresses our nightly audit failures:
https://github.com/nrwl/nx/actions/runs/16545241633/job/46791870646
2025-07-29 09:33:08 -04:00
Victor Savkin d53e008d5f cleanup(core): clean up onboarding url generation (#32101)
<!-- Please make sure you have read the submission guidelines before
posting an PR -->
<!--
https://github.com/nrwl/nx/blob/master/CONTRIBUTING.md#-submitting-a-pr
-->

<!-- Please make sure that your commit message follows our format -->
<!-- Example: `fix(nx): must begin with lowercase` -->

<!-- If this is a particularly complex change or feature addition, you
can request a dedicated Nx release for this pull request branch. Mention
someone from the Nx team or the `@nrwl/nx-pipelines-reviewers` and they
will confirm if the PR warrants its own release for testing purposes,
and generate it for you if appropriate. -->

## Current Behavior
<!-- This is the behavior we have today -->

## Expected Behavior
<!-- This is the behavior we should expect with the changes in this PR
-->

## Related Issue(s)
<!-- Please link the issue being fixed so it gets closed when this is
merged. -->

Fixes #
2025-07-29 09:32:59 -04:00
Emily Xiong e2a6b3e551 fix(react-native): add release option to publisable react-native library (#29817) 2025-07-28 11:04:09 -04:00
Craigory Coppola b9be698f13 fix(core): remove graph creation from postinstall hook (#32027)
## Current Behavior
The post install hook creates the project graph... which contains quite
a bit of work and appears to be hanging at times.

## Expected Behavior
The post install hook is slimmer, and has a hard timeout of 30s to avoid
hanging.

## Related Issue(s)
<!-- Please link the issue being fixed so it gets closed when this is
merged. -->

Fixes #31694
2025-07-28 11:04:06 -04:00
Caleb Ukle 5df65700b9 docs(misc): change tutorial CTA copy (#32094) 2025-07-28 11:03:59 -04:00
Victor Savkin ad01165391 fix(core): cloud commands should be handled before loading local (#32090)
<!-- Please make sure you have read the submission guidelines before
posting an PR -->
<!--
https://github.com/nrwl/nx/blob/master/CONTRIBUTING.md#-submitting-a-pr
-->

<!-- Please make sure that your commit message follows our format -->
<!-- Example: `fix(nx): must begin with lowercase` -->

<!-- If this is a particularly complex change or feature addition, you
can request a dedicated Nx release for this pull request branch. Mention
someone from the Nx team or the `@nrwl/nx-pipelines-reviewers` and they
will confirm if the PR warrants its own release for testing purposes,
and generate it for you if appropriate. -->

<!-- This is the behavior we have today -->

<!-- This is the behavior we should expect with the changes in this PR
-->

<!-- Please link the issue being fixed so it gets closed when this is
merged. -->

Fixes #
2025-07-25 13:50:05 -04:00
Jack Hsu 1cf850f964 fix(core): prevent --skipInstall from being passed from create-nx-workspace to new generator (#32086)
<!-- Please make sure you have read the submission guidelines before
posting an PR -->
<!--
https://github.com/nrwl/nx/blob/master/CONTRIBUTING.md#-submitting-a-pr
-->

<!-- Please make sure that your commit message follows our format -->
<!-- Example: `fix(nx): must begin with lowercase` -->

<!-- If this is a particularly complex change or feature addition, you
can request a dedicated Nx release for this pull request branch. Mention
someone from the Nx team or the `@nrwl/nx-pipelines-reviewers` and they
will confirm if the PR warrants its own release for testing purposes,
and generate it for you if appropriate. -->

## Current Behavior
When you run `npx -y create-nx-workspace@latest nameofmyrepo-monorepo
--preset=apps --nxCloud=skip --skip-install --skip-prettier --verbose`
it fails because `--skip-install` is passed to the `new` generator (even
though it's not an CNW option), which means no `node_modules` to resolve
`nx/bin/nx`.

## Expected Behavior
Running CNW should not skip install ever.

## Related Issue(s)
<!-- Please link the issue being fixed so it gets closed when this is
merged. -->

Fixes #31834
2025-07-25 13:49:13 -04:00
Leosvel Pérez Espinosa 11ba75f4e4 fix(misc): allow scoped package names in application generators (#31957)
Allow application names starting with @ symbol to support scoped
packages like @myorg/myapp.

Updated the validation pattern to match the library generator pattern
that already supports this.

Fixes #31229

Generated with [Claude Code](https://claude.ai/code)

---------

Co-authored-by: claude[bot] <209825114+claude[bot]@users.noreply.github.com>
Co-authored-by: Leosvel Pérez Espinosa <leosvelperez@users.noreply.github.com>
2025-07-25 13:48:47 -04:00
Leosvel Pérez Espinosa b001a4529b fix(core): derive graph node type correctly when projectType is not set (#32018)
## Current Behavior

When building the project graph nodes, the node `type` is always
inferred as `lib` when `projectType` is not set.

## Expected Behavior

When building the project graph nodes, the node `type` should be derived
correctly using the same logic used by generators when `projectType` is
not set.

## Related Issue(s)

Fixes #31983
2025-07-25 09:04:54 -04:00
Juri 8c7edfb431 docs(nx-dev): update payfit blog post 2025-07-25 09:04:46 -04:00
Rares Matei 758c5a6f13 docs(nx-cloud): update release notes (#32054)
<!-- Please make sure you have read the submission guidelines before
posting an PR -->
<!--
https://github.com/nrwl/nx/blob/master/CONTRIBUTING.md#-submitting-a-pr
-->

<!-- Please make sure that your commit message follows our format -->
<!-- Example: `fix(nx): must begin with lowercase` -->

<!-- If this is a particularly complex change or feature addition, you
can request a dedicated Nx release for this pull request branch. Mention
someone from the Nx team or the `@nrwl/nx-pipelines-reviewers` and they
will confirm if the PR warrants its own release for testing purposes,
and generate it for you if appropriate. -->

## Current Behavior
<!-- This is the behavior we have today -->

## Expected Behavior
<!-- This is the behavior we should expect with the changes in this PR
-->

## Related Issue(s)
<!-- Please link the issue being fixed so it gets closed when this is
merged. -->

Fixes #

---------

Co-authored-by: Caleb Ukle <caleb.ukle+github@pm.me>
2025-07-25 09:04:40 -04:00
Jason Jean be3e3dc3d9 fix(core): disable TUI on ai agents (#31480)
## Current Behavior

The TUI (Terminal User Interface) is enabled for all environments,
including AI agents like Claude Code, which can cause issues with
AI-driven development workflows.

## Expected Behavior

When an AI agent is detected through environment variables, the TUI
should be automatically disabled to prevent interference with AI-driven
interactions.

## Related Issue(s)

This change improves the developer experience when using AI agents by
automatically detecting their presence and adjusting the interface
accordingly.

---------

Co-authored-by: claude[bot] <209825114+claude[bot]@users.noreply.github.com>
Co-authored-by: FrozenPandaz <FrozenPandaz@users.noreply.github.com>
Co-authored-by: Claude <noreply@anthropic.com>
2025-07-25 09:04:35 -04:00
Jason Jean 0b143a7306 fix(core): prevent thread leaks in nx_walker and logger (#32061)
## Current Behavior

The native Rust code in nx_walker and logger components was creating
threads that weren't being properly cleaned up, leading to resource
leaks over time.

## Expected Behavior

With these changes, threads are properly managed and cleaned up to
prevent resource leaks, improving the overall stability and performance
of Nx operations.

## Related Issue(s)

This addresses native thread leak issues discovered during development.

Fixes thread leaks in native components
2025-07-25 09:04:29 -04:00
Jason Jean 3aaedd3d57 fix(core): improve arrow key detection for interactive programs (#32075)
## Current Behavior

The TUI's arrow key handling uses only alternate screen mode detection
to determine whether to send arrow key sequences to programs or handle
scrolling locally. This works for programs like vim, less, and git log,
but fails for enquirer-style prompts that use cursor positioning without
alternate screen mode.

## Expected Behavior

Arrow key handling should properly detect when interactive programs like
enquirer are running and send arrow key sequences to them for
navigation, while maintaining TUI scrolling for regular command output.

## Related Issue(s)

This improves the TUI's interaction with enquirer prompts and similar
interactive programs that don't use alternate screen mode but still need
to receive arrow key input.

## Changes Made

- **Enhanced Detection Logic**: Added `handles_arrow_keys()` method that
detects interactive programs using:
  - Alternate screen mode detection (vim, less, git log, htop)
  - Cursor movement sequence detection (enquirer-style programs)
- **Refactored Arrow Key Handling**: Updated `handle_arrow_keys()` to
use improved detection
- **Consistent Mouse Event Handling**: Updated `send_mouse_event()` to
use same detection logic
- **Comprehensive Tests**: Added tests for interactive program detection
patterns

## Technical Details

The new `handles_arrow_keys()` method checks for:
1. **Alternate screen mode** - Strong indicator for programs like vim,
less
2. **Cursor control sequences** - Detects enquirer-style programs that
use:
   - `\x1b[?25l` / `\x1b[?25h` (hide/show cursor)
   - `\x1b[H` (cursor positioning)
   - `\x1b[A/B/C/D` (cursor movement)

This ensures enquirer prompts receive proper arrow key navigation while
maintaining backward compatibility with existing TUI scrolling behavior.

Fixes arrow key navigation in enquirer prompts and similar interactive
programs.

Co-authored-by: Claude <noreply@anthropic.com>
2025-07-25 09:04:24 -04:00
Juri f0779ee7bd docs(nx-dev): customer success story about payfit 2025-07-25 09:04:18 -04:00
Leosvel Pérez Espinosa b6abd81bc5 fix(core): make tasks list columns in the tui more compact (#32074)
## Current Behavior

The Tasks List pane in the TUI is not too compact. It has some wide
spaces and long texts that do not allow for a better use of the
available space.

<img width="1079" height="450" alt="image"
src="https://github.com/user-attachments/assets/f814df3c-0623-413b-9473-48e16f752e0f"
/>

<img width="1368" height="455" alt="image"
src="https://github.com/user-attachments/assets/2436da03-3812-4cfc-8152-756eb99607d2"
/>

## Expected Behavior

The Tasks List pane in the TUI should be more compact:

- `Kept Existing` value in the Cache column should be renamed to `Match`
- The Duration column should not reserve as much space as it does
currently

<img width="1077" height="455" alt="image"
src="https://github.com/user-attachments/assets/bfe6ee33-09c3-4cd7-bd36-15c4b673c9e9"
/>
2025-07-25 09:04:12 -04:00
Jason Jean 3781cfeaec fix(js): resolve relative imports correctly in nested projects (#31978)
## Current Behavior

When resolving "./" imports from a nested project, the target project
locator incorrectly resolves to the parent project instead of the
current project.

For example, given:
- `parent-project` at `libs/parent-path`
- `child-project` at `libs/parent-path/child-path` (nested 1 level under
parent)

When importing "./" from `libs/parent-path/child-path/module.ts`, it
incorrectly resolves to `parent-project` instead of `child-project`.

## Expected Behavior

"./" imports from within a nested project should resolve to that
project, not its parent.

## Related Issue(s)

Fixes #31980
2025-07-25 09:04:06 -04:00
Leosvel Pérez Espinosa d5b829e62f fix(core): improve tui minimal view display and prevent flashing scrollbar (#32045)
## Current Behavior

- When the minimal view in the TUI is shown, some borders are initially
shown for a fraction of a second.
- When rendering terminal panes, the scrollbar can be wrongly shown for
a fraction of a second when the PTY dimensions are stale. This looks
like the scrollbar flashes.

## Expected Behavior

- When the minimal view in the TUI is shown, no borders should ever be
shown.
- The scrollbar should only be shown when rendering terminal panes when
needed.
2025-07-25 09:03:48 -04:00
Juri b848dd47f5 docs(misc): update nx-mcp install instructions 2025-07-25 09:03:42 -04:00
Mike Hartington 3e88dcecca docs(misc): add nx workshop promo blog post (#32055)
<!-- Please make sure you have read the submission guidelines before
posting an PR -->
<!--
https://github.com/nrwl/nx/blob/master/CONTRIBUTING.md#-submitting-a-pr
-->

<!-- Please make sure that your commit message follows our format -->
<!-- Example: `fix(nx): must begin with lowercase` -->

<!-- If this is a particularly complex change or feature addition, you
can request a dedicated Nx release for this pull request branch. Mention
someone from the Nx team or the `@nrwl/nx-pipelines-reviewers` and they
will confirm if the PR warrants its own release for testing purposes,
and generate it for you if appropriate. -->

## Current Behavior
<!-- This is the behavior we have today -->

## Expected Behavior
<!-- This is the behavior we should expect with the changes in this PR
-->

## Related Issue(s)
<!-- Please link the issue being fixed so it gets closed when this is
merged. -->

Fixes #
2025-07-25 09:03:22 -04:00
Leosvel Pérez Espinosa 63465ad044 fix(angular): update migration target version for jest-preset-angular v15 package update (#32051)
Update the migration target version for `jest-preset-angular` v15
package update.
2025-07-25 09:02:58 -04:00
FrozenPandaz 2b371eabc4 chore(repo): fix react-native build 2025-07-23 13:23:25 -04:00
Jason Jean 7c6cbbf339 chore(repo): remove stylus res (#32052)
<!-- Please make sure you have read the submission guidelines before
posting an PR -->
<!--
https://github.com/nrwl/nx/blob/master/CONTRIBUTING.md#-submitting-a-pr
-->

<!-- Please make sure that your commit message follows our format -->
<!-- Example: `fix(nx): must begin with lowercase` -->

<!-- If this is a particularly complex change or feature addition, you
can request a dedicated Nx release for this pull request branch. Mention
someone from the Nx team or the `@nrwl/nx-pipelines-reviewers` and they
will confirm if the PR warrants its own release for testing purposes,
and generate it for you if appropriate. -->

<!-- This is the behavior we have today -->

Security package is removed. This resolution fails.

<!-- This is the behavior we should expect with the changes in this PR
-->

Remove the resolution.

<!-- Please link the issue being fixed so it gets closed when this is
merged. -->

Fixes #

(cherry picked from commit 713f86a64d)
2025-07-23 12:32:20 -04:00
Leosvel Pérez Espinosa 2953a17906 fix(angular): update jest-preset-angular to v15 (#32050)
## Current Behavior

Angular projects use `jest-preset-angular` v14, which doesn't support
Jest v30.

Note: When support for Jest v30 was added, `jest-preset-angular` didn't
have a version explicitly supporting it.

## Expected Behavior

Angular projects should use `jest-preset-angular` v15, which supports
Jest v30.

## Related Issue(s)

Fixes #32024

(cherry picked from commit 3419b329a3)
2025-07-23 12:31:23 -04:00
MaxKless 9bcb39364f chore(misc): change cursor mcp.json to use streamable http instead of sse (#31994)
(cherry picked from commit b879e7e0d2)
2025-07-23 12:30:48 -04:00
Leosvel Pérez Espinosa ae7de55920 fix(core): render the correct output in the tui terminal pane when pinning task (#31975)
## Current Behavior

In the TUI, opening the Terminal Pane for a task with the space bar,
navigating to another task, and pressing "1" to pin it, results in the
terminal pane displaying the output of the task for which the space bar
was pressed initially instead of the pinned task.

## Expected Behavior

Pinning tasks in the TUI should work correctly and always display the
output of the pinned task.

(cherry picked from commit dd57e0faf0)
2025-07-23 12:30:47 -04:00
Victor Savkin afab5299d0 cleanup(misc): point to the guide with next steps (#32026)
<!-- Please make sure you have read the submission guidelines before
posting an PR -->
<!--
https://github.com/nrwl/nx/blob/master/CONTRIBUTING.md#-submitting-a-pr
-->

<!-- Please make sure that your commit message follows our format -->
<!-- Example: `fix(nx): must begin with lowercase` -->

<!-- If this is a particularly complex change or feature addition, you
can request a dedicated Nx release for this pull request branch. Mention
someone from the Nx team or the `@nrwl/nx-pipelines-reviewers` and they
will confirm if the PR warrants its own release for testing purposes,
and generate it for you if appropriate. -->

## Current Behavior
<!-- This is the behavior we have today -->

## Expected Behavior
<!-- This is the behavior we should expect with the changes in this PR
-->

## Related Issue(s)
<!-- Please link the issue being fixed so it gets closed when this is
merged. -->

Fixes #

(cherry picked from commit 51b702e67f)
2025-07-23 12:30:46 -04:00
Caleb Ukle 2f1d887032 docs(core): add "next steps" for nx init docs (#32025)
improve doc page where people land after running `nx init`
- clarify how to use nx after setup
- make sure to update CI configs
- how to finish nx cloud setup if opted-in for cloud

(cherry picked from commit eb2392a515)
2025-07-23 12:30:46 -04:00
Emily Xiong c4eff655c4 chore(gradle): document build-ci target (#31660)
<!-- Please make sure you have read the submission guidelines before
posting an PR -->
<!--
https://github.com/nrwl/nx/blob/master/CONTRIBUTING.md#-submitting-a-pr
-->

<!-- Please make sure that your commit message follows our format -->
<!-- Example: `fix(nx): must begin with lowercase` -->

<!-- If this is a particularly complex change or feature addition, you
can request a dedicated Nx release for this pull request branch. Mention
someone from the Nx team or the `@nrwl/nx-pipelines-reviewers` and they
will confirm if the PR warrants its own release for testing purposes,
and generate it for you if appropriate. -->

## Current Behavior
<!-- This is the behavior we have today -->
add documentation for build-ci target for gradle

## Expected Behavior
<!-- This is the behavior we should expect with the changes in this PR
-->
currently there is no build-ci target documented

## Related Issue(s)
<!-- Please link the issue being fixed so it gets closed when this is
merged. -->

Fixes #

(cherry picked from commit 862bc4bbb0)
2025-07-23 12:30:37 -04:00
Caleb Ukle 2abc3c6d7a docs(core): update intro language for tutorials (#32005)
<!-- Please make sure you have read the submission guidelines before
posting an PR -->
<!--
https://github.com/nrwl/nx/blob/master/CONTRIBUTING.md#-submitting-a-pr
-->

<!-- Please make sure that your commit message follows our format -->
<!-- Example: `fix(nx): must begin with lowercase` -->

<!-- If this is a particularly complex change or feature addition, you
can request a dedicated Nx release for this pull request branch. Mention
someone from the Nx team or the `@nrwl/nx-pipelines-reviewers` and they
will confirm if the PR warrants its own release for testing purposes,
and generate it for you if appropriate. -->

## Current Behavior
<!-- This is the behavior we have today -->
tutorial intro language is subpar
## Expected Behavior
<!-- This is the behavior we should expect with the changes in this PR
-->
improve tutorial intro language

## Related Issue(s)
<!-- Please link the issue being fixed so it gets closed when this is
merged. -->

Fixes #

(cherry picked from commit 0348faa7c5)
2025-07-23 12:30:36 -04:00
Leosvel Pérez Espinosa 8b64caaaa5 fix(testing): add missing package updates for ts-jest and jest-util for jest v30 migrations (#32017)
## Current Behavior

The migration for Jest v30 is missing package updates for `ts-jest` and
`jest-util`.

## Expected Behavior

The migration for Jest v30 should have package updates for `ts-jest` and
`jest-util`.

(cherry picked from commit 0bbb473f4f)
2025-07-23 12:30:35 -04:00
Leosvel Pérez Espinosa 91aa699b00 fix(testing): normalize spec files correctly in jest replace-removed-matcher-aliases migration (#31995)
## Current Behavior

When running the Jest `replace-removed-matcher-aliases` migration on
Windows, it resolves the spec files incorrectly and fails.

## Expected Behavior

Running the Jest `replace-removed-matcher-aliases` migration should work
correctly regardless the OS.

## Related Issue(s)

Fixes #31991

(cherry picked from commit a64af8b59b)
2025-07-23 12:30:34 -04:00
Leosvel Pérez Espinosa c5ba63f976 fix(nextjs): infer relevant tasks with the typescript sync generator when using ts project references (#31996)
## Current Behavior

When using the TS solution setup, tasks inferred by the
`@nx/next/plugin` do not have the `@nx/js:typescript-sync` generator
set.

## Expected Behavior

When using the TS solution setup, tasks inferred by the
`@nx/next/plugin` should have the `@nx/js:typescript-sync` generator
set.

## Related Issue(s)

Fixes #31983

(cherry picked from commit aad2e81eaa)
2025-07-23 12:30:33 -04:00
Jack Hsu 89523f9e8a docs(misc): remove CI tutorials and redirect to their setup guides (#32004)
This PR removes the two CI tutorials (GitHub Actions and CircleCI) and
redirect them to the setup guides:
- https://nx.dev/ci/recipes/set-up/monorepo-ci-github-actions
- https://nx.dev/ci/recipes/set-up/monorepo-ci-circle-ci

There's not much value in having separate CI tutorials now that CI is a
central part of the main tutorials, rather than an optional step. e.g.
https://nx.dev/getting-started/tutorials/typescript-packages-tutorial

The guides are sufficient for users that want to learn how to set up
their CI with Nx Cloud.

(cherry picked from commit 5163bcddfd)
2025-07-23 12:30:31 -04:00
Mike Hartington 14130ad0ea docs(nx-dev): add 21.3 changelog (#32000)
<!-- Please make sure you have read the submission guidelines before
posting an PR -->
<!--
https://github.com/nrwl/nx/blob/master/CONTRIBUTING.md#-submitting-a-pr
-->

<!-- Please make sure that your commit message follows our format -->
<!-- Example: `fix(nx): must begin with lowercase` -->

<!-- If this is a particularly complex change or feature addition, you
can request a dedicated Nx release for this pull request branch. Mention
someone from the Nx team or the `@nrwl/nx-pipelines-reviewers` and they
will confirm if the PR warrants its own release for testing purposes,
and generate it for you if appropriate. -->

## Current Behavior
<!-- This is the behavior we have today -->

## Expected Behavior
<!-- This is the behavior we should expect with the changes in this PR
-->

## Related Issue(s)
<!-- Please link the issue being fixed so it gets closed when this is
merged. -->

Fixes #

(cherry picked from commit 105ce6af06)
2025-07-23 12:30:30 -04:00
Leosvel Pérez Espinosa a5b1ec330b fix(linter): update lint executor to correctly handle --fix and --quiet (#31970)
## Current Behavior

When running ESLint using the `@nx/eslint:lint` executor with `--quiet`
and `--fix`, and there are errors, no fix is made, and the task
incorrectly succeeds.

This is a regression introduced by
https://github.com/nrwl/nx/commit/9406d2bfdb15e33ad85345533f96f6136130e817,
which updated the executor to not fix warnings when `--quiet` is used,
but the solution was incorrect.

## Expected Behavior

When running ESLint using the `@nx/eslint:lint` executor with `--quiet`
and `--fix`, and there are errors, fixes should be applied, and the task
should succeed if there are no remaining errors. It should not fix
warnings.

## Related Issue(s)

Fixes #31868

(cherry picked from commit 59496ed446)
2025-07-23 12:30:29 -04:00
Nicholas Cunningham 4ded9bdd00 feat(bundling)!: remove stylus support (#32035)
BREAKING CHANGE: Stylus (.styl) files are no longer supported.

Stylus has been deprecated and was slated to be removed in Nx 20.
Now we are removing it.

- Remove `stylus` and `stylus-loader` dependencies
- Remove `deprecated-stylus-loader` file
- Remove `stylus` configuration from `webpack` and `rspack` plugins
- Remove `'styl'` option from `rspack` generator schemas and TypeScript
definitions
- Remove `.styl`/`.stylus` extensions from executor schema file
completion globs

MISC
Even though we removed stylus from our repo as a dependency other
projects in the workspace still have stylus as an optional dependency:
  - Vite
  - Astro

So we add a placeholder for it since on npm registry there is a
_security_ placeholder.

---------

Co-authored-by: Leosvel Pérez Espinosa <leosvel.perez.espinosa@gmail.com>
2025-07-23 11:52:50 -04:00
JamesHenry d1a32b034f chore: fix lockfile 2025-07-23 16:30:35 +04:00
Nicholas Cunningham d387b064d3 fix(bundling): fix stylus installation error due to npm security (#32036)
The stylus npm registry has been compromised.
So can resolve `stylus` with `npm:ignore@*` it tells the package manager
to replace the dependency with the ignore package from npm registry.

Until we can merge: https://github.com/nrwl/nx/pull/32035
2025-07-23 15:04:24 +04:00
Victor Savkin e6476528b1 fix(misc): fix setup selection (#31997)
<!-- Please make sure you have read the submission guidelines before
posting an PR -->
<!--
https://github.com/nrwl/nx/blob/master/CONTRIBUTING.md#-submitting-a-pr
-->

<!-- Please make sure that your commit message follows our format -->
<!-- Example: `fix(nx): must begin with lowercase` -->

<!-- If this is a particularly complex change or feature addition, you
can request a dedicated Nx release for this pull request branch. Mention
someone from the Nx team or the `@nrwl/nx-pipelines-reviewers` and they
will confirm if the PR warrants its own release for testing purposes,
and generate it for you if appropriate. -->

## Current Behavior
<!-- This is the behavior we have today -->

## Expected Behavior
<!-- This is the behavior we should expect with the changes in this PR
-->

## Related Issue(s)
<!-- Please link the issue being fixed so it gets closed when this is
merged. -->

Fixes #

---------

Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Jason Jean <FrozenPandaz@users.noreply.github.com>
(cherry picked from commit 84a6f9da35)
2025-07-21 12:06:17 -04:00
James Henry d6dedaba42 docs(core): update self-healing-ci.md (#31993)
(cherry picked from commit 27330b53bd)
2025-07-21 12:06:16 -04:00
Jason Jean 0347c1daed chore(repo): update nx to 21.4.0-beta.0 (#31985)
Updating Nx from 21.3.0-rc.0 to 21.4.0-beta.0

(cherry picked from commit 4720175b1e)
2025-07-21 12:06:03 -04:00
Victor Savkin 6fcb011935 cleanup(misc): small tweaks to cnw and init (#31986)
<!-- Please make sure you have read the submission guidelines before
posting an PR -->
<!--
https://github.com/nrwl/nx/blob/master/CONTRIBUTING.md#-submitting-a-pr
-->

<!-- Please make sure that your commit message follows our format -->
<!-- Example: `fix(nx): must begin with lowercase` -->

<!-- If this is a particularly complex change or feature addition, you
can request a dedicated Nx release for this pull request branch. Mention
someone from the Nx team or the `@nrwl/nx-pipelines-reviewers` and they
will confirm if the PR warrants its own release for testing purposes,
and generate it for you if appropriate. -->

## Current Behavior
<!-- This is the behavior we have today -->

## Expected Behavior
<!-- This is the behavior we should expect with the changes in this PR
-->

## Related Issue(s)
<!-- Please link the issue being fixed so it gets closed when this is
merged. -->

Fixes #
2025-07-20 10:08:27 -04:00
312 changed files with 17346 additions and 12015 deletions
+1 -1
View File
@@ -1,7 +1,7 @@
{
"mcpServers": {
"nx-mcp": {
"url": "http://localhost:9470/sse"
"url": "http://localhost:9470/mcp"
}
}
}
+235 -107
View File
@@ -3,7 +3,7 @@ name: publish
on:
# Automated schedule - canary releases from master
schedule:
- cron: "0 3 * * 2-6" # Tuesdays - Saturdays, at 3am UTC
- cron: "0 19 * * 1-5" # Monday - Friday, at 19:00 UTC (7pm UTC)
# Manual trigger - PR releases or dry-runs (based on workflow inputs)
workflow_dispatch:
inputs:
@@ -22,7 +22,7 @@ env:
NX_RUN_GROUP: ${{ github.run_id }}-${{ github.run_attempt }}
CYPRESS_INSTALL_BINARY: 0
NODE_VERSION: 22.16.0
PNPM_VERSION: 10.11.1 # Aligned with root package.json (pnpm/action-setup will helpfully error if out of sync)
PNPM_VERSION: 10.28.2 # Aligned with root package.json (pnpm/action-setup will helpfully error if out of sync)
jobs:
# We first need to determine the version we are releasing, and if we need a custom repo or ref to use for the git checkout in subsequent steps.
@@ -37,7 +37,7 @@ jobs:
# ref resolution in actions/checkout. The exact version will be generated within scripts/nx-release.ts.
#
# - workflow_dispatch:
# - We are either running a dry-run on the current branch, in which case the version will be statica and we can use
# - We are either running a dry-run on the current branch, in which case the version will be static and we can use
# default ref resolution in actions/checkout, or we are creating a PR release for the given PR number, in which case
# we should generate an applicable version number within publish-resolve-data.js and use a custom ref of the PR branch name.
resolve-required-data:
@@ -51,31 +51,23 @@ jobs:
publish_branch: ${{ steps.script.outputs.publish_branch }}
ref: ${{ steps.script.outputs.ref }}
repo: ${{ steps.script.outputs.repo }}
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
pr_number: ${{ steps.script.outputs.pr_number }}
pr_author: ${{ steps.script.outputs.pr_author }}
steps:
# Default checkout on the triggering branch so that the latest publish-resolve-data.js script is available
- uses: actions/checkout@v4
# Set up pnpm and node so that we can verify our setup and that the NPM_TOKEN secret will work later
- uses: pnpm/action-setup@v4
with:
version: ${{ env.PNPM_VERSION }}
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
- name: Setup node
uses: actions/setup-node@v4
uses: actions/setup-node@a0853c24544627f65ddf259abe73b1d18a591444 # v5.0.0
with:
node-version: ${{ env.NODE_VERSION }}
registry-url: 'https://registry.npmjs.org'
check-latest: true
# Ensure that the NPM_TOKEN secret is still valid before wasting any time deriving data or building projects
- name: Check NPM Credentials
run: npm whoami && echo "NPM credentials are valid" || (echo "NPM credentials are invalid or have expired." && exit 1)
package-manager-cache: false
- name: Resolve and set checkout and version data to use for release
id: script
uses: actions/github-script@v7
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0
env:
PR_NUMBER: ${{ github.event.inputs.pr }}
with:
@@ -86,7 +78,7 @@ jobs:
- name: (PR Release Only) Check out latest master
if: ${{ steps.script.outputs.ref != '' }}
uses: actions/checkout@v4
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
with:
# Check out the latest master branch to get its copy of nx-release.ts
repository: nrwl/nx
@@ -95,24 +87,31 @@ jobs:
- name: (PR Release Only) Check out PR branch
if: ${{ steps.script.outputs.ref != '' }}
uses: actions/checkout@v4
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
with:
# Check out the PR branch to get its copy of nx-release.ts
repository: ${{ steps.script.outputs.repo }}
ref: ${{ steps.script.outputs.ref }}
path: pr-branch-checkout
- name: (PR Release Only) Ensure that nx-release.ts has not changed in the PR being released
- name: (PR Release Only) Ensure that release scripts have not changed in the PR being released
if: ${{ steps.script.outputs.ref != '' }}
env:
FILE_TO_COMPARE: "scripts/nx-release.ts"
run: |
if ! cmp -s "latest-master-checkout/${{ env.FILE_TO_COMPARE }}" "pr-branch-checkout/${{ env.FILE_TO_COMPARE }}"; then
echo "🛑 Error: The file ${{ env.FILE_TO_COMPARE }} is different on the ${{ steps.script.outputs.ref }} branch on ${{ steps.script.outputs.repo }} vs latest master on nrwl/nx, cancelling workflow. If you did not modify the file, then you likely just need to rebase/merge latest master."
exit 1
else
echo "✅ The file ${{ env.FILE_TO_COMPARE }} is identical between the ${{ steps.script.outputs.ref }} branch on ${{ steps.script.outputs.repo }} and latest master on nrwl/nx."
fi
# List of files that must not change in PR releases
FILES_TO_CHECK=(
"scripts/nx-release.ts"
"scripts/publish-resolve-data.js"
)
for FILE in "${FILES_TO_CHECK[@]}"; do
if ! cmp -s "latest-master-checkout/$FILE" "pr-branch-checkout/$FILE"; then
echo "🛑 Error: The file $FILE is different on the ${{ steps.script.outputs.ref }} branch on ${{ steps.script.outputs.repo }} vs latest master on nrwl/nx, cancelling workflow."
echo "If you did not modify the file, then you likely just need to rebase/merge latest master."
exit 1
else
echo "✅ The file $FILE is identical between the ${{ steps.script.outputs.ref }} branch on ${{ steps.script.outputs.repo }} and latest master on nrwl/nx."
fi
done
build:
needs: [ resolve-required-data ]
@@ -121,16 +120,21 @@ jobs:
fail-fast: false
matrix:
settings:
- host: macos-13
- host: macos-latest
target: x86_64-apple-darwin
setup: |-
rustup target add aarch64-apple-darwin
rustup target add x86_64-apple-darwin
build: |
pnpm nx run-many --target=build-native -- --target=x86_64-apple-darwin
- host: windows-latest
setup: |-
choco install openjdk --version=21.0.0 -y
rustup target add aarch64-pc-windows-msvc
build: pnpm nx run-many --target=build-native -- --target=x86_64-pc-windows-msvc
build: |
export JAVA_HOME="C:\Program Files\OpenJDK\jdk-21"
export PATH="$JAVA_HOME\bin:$PATH"
java -version
pnpm nx run-many --target=build-native -- --target=x86_64-pc-windows-msvc
target: x86_64-pc-windows-msvc
# Windows 32bit (not needed)
# - host: windows-latest
@@ -144,16 +148,22 @@ jobs:
set -e
apt-get update
# Install Java 21
apt-get install -y openjdk-21-jdk
export JAVA_HOME=/usr/lib/jvm/java-21-openjdk-amd64
export PATH="$JAVA_HOME/bin:$PATH"
java --version
curl -fsSL https://deb.nodesource.com/setup_22.x | bash -
apt-get install -y nodejs=22.16.0-1nodesource1
export PATH="/usr/local/bin:$PATH"
node --version
npm --version
npm i -g pnpm@${PNPM_VERSION} --force
pnpm --version
pnpm install --frozen-lockfile
rustup target add x86_64-unknown-linux-gnu
pnpm nx run-many --verbose --target=build-native -- --target=x86_64-unknown-linux-gnu
@@ -164,27 +174,32 @@ jobs:
bash -c "
set -e
echo 'https://dl-cdn.alpinelinux.org/alpine/edge/community' >> /etc/apk/repositories
apk add --no-cache curl xz
apk add --no-cache curl xz openjdk21
# Set up Java 21
export JAVA_HOME=/usr/lib/jvm/java-21-openjdk
export PATH=\"\$JAVA_HOME/bin:\$PATH\"
java --version
curl -fsSL https://unofficial-builds.nodejs.org/download/release/v22.16.0/node-v22.16.0-linux-x64-musl.tar.xz -o node.tar.xz
tar -xJf node.tar.xz
mv node-v22.16.0-linux-x64-musl /usr/local/node
export PATH=\"/usr/local/node/bin:\$PATH\"
echo Node: \$(node -v)
echo NPM: \$(npm -v)
# Install PNPM
npm i -g pnpm@${PNPM_VERSION} --force
pnpm --version
# Install deps and run native build
pnpm install --frozen-lockfile
rustup target add x86_64-unknown-linux-musl
pnpm nx run-many --verbose --target=build-native -- --target=x86_64-unknown-linux-musl
"
- host: macos-13
- host: macos-latest
target: aarch64-apple-darwin
setup: |-
rustup target add aarch64-apple-darwin
@@ -201,17 +216,23 @@ jobs:
build: |
set -e
apt-get update
# Install Java 21
apt-get install -y openjdk-21-jdk
export JAVA_HOME=/usr/lib/jvm/java-21-openjdk-amd64
export PATH="$JAVA_HOME/bin:$PATH"
java --version
curl -fsSL https://deb.nodesource.com/setup_22.x | bash -
apt-get install -y nodejs=22.16.0-1nodesource1
export PATH="/usr/local/bin:$PATH"
node --version
npm --version
npm i -g pnpm@${PNPM_VERSION} --force
pnpm --version
pnpm install --frozen-lockfile
rustup target add aarch64-unknown-linux-gnu
pnpm nx run-many --verbose --target=build-native -- --target=aarch64-unknown-linux-gnu
@@ -239,59 +260,61 @@ jobs:
bash -c "
set -e
echo 'https://dl-cdn.alpinelinux.org/alpine/edge/community' >> /etc/apk/repositories
apk add --no-cache curl xz
apk add --no-cache curl xz openjdk21
# Set up Java 21
export JAVA_HOME=/usr/lib/jvm/java-21-openjdk
export PATH=\"\$JAVA_HOME/bin:\$PATH\"
java --version
curl -fsSL https://unofficial-builds.nodejs.org/download/release/v22.16.0/node-v22.16.0-linux-x64-musl.tar.xz -o node.tar.xz
tar -xJf node.tar.xz
mv node-v22.16.0-linux-x64-musl /usr/local/node
export PATH=\"/usr/local/node/bin:\$PATH\"
echo Node: \$(node -v)
echo NPM: \$(npm -v)
# Install PNPM
npm i -g pnpm@${PNPM_VERSION} --force
pnpm --version
# Install deps and run native build
pnpm install --frozen-lockfile
rustup target add aarch64-unknown-linux-musl
pnpm nx run-many --verbose --target=build-native -- --target=aarch64-unknown-linux-musl
rustup target add aarch64-unknown-linux-musl
pnpm nx run-many --verbose --target=build-native -- --target=aarch64-unknown-linux-musl
"
- host: windows-latest
target: aarch64-pc-windows-msvc
setup: |-
choco install openjdk --version=21.0.0 -y
rustup target add aarch64-pc-windows-msvc
build: pnpm nx run-many --target=build-native -- --target=aarch64-pc-windows-msvc
build: |
export JAVA_HOME="C:\Program Files\OpenJDK\jdk-21"
export PATH="$JAVA_HOME\bin:$PATH"
java -version
pnpm nx run-many --target=build-native -- --target=aarch64-pc-windows-msvc
name: stable - ${{ matrix.settings.target }} - node@22.16.0
runs-on: ${{ matrix.settings.host }}
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
with:
repository: ${{ needs.resolve-required-data.outputs.repo }}
ref: ${{ needs.resolve-required-data.outputs.ref }}
repository: ${{ needs.resolve-required-data.outputs.repo || github.repository }}
ref: ${{ needs.resolve-required-data.outputs.ref || github.ref }}
- uses: pnpm/action-setup@v4
with:
version: ${{ env.PNPM_VERSION }}
- name: Setup node
uses: actions/setup-node@v4
- name: Setup dev tools with mise
uses: jdx/mise-action@146a28175021df8ca24f8ee1828cc2a60f980bd5 # v3
if: ${{ !matrix.settings.docker }}
with:
node-version: ${{ env.NODE_VERSION }}
check-latest: true
cache: 'pnpm'
- name: Install
uses: dtolnay/rust-toolchain@stable
- name: Enable corepack and install pnpm
if: ${{ !matrix.settings.docker }}
with:
targets: ${{ matrix.settings.target }}
run: |
corepack enable
corepack prepare --activate
- name: Cache cargo
uses: actions/cache@v4
uses: actions/cache@0400d5f644dc74513175e3cd8d07132dd4860809 # v4.2.4
with:
path: |
~/.cargo/registry/index/
@@ -301,7 +324,7 @@ jobs:
target/
key: ${{ matrix.settings.target }}-cargo-registry
- uses: goto-bus-stop/setup-zig@v2
- uses: goto-bus-stop/setup-zig@abea47f85e598557f500fa1fd2ab7464fcb39406 # v2.2.1
if: ${{ matrix.settings.target == 'armv7-unknown-linux-gnueabihf' }}
with:
version: 0.10.0
@@ -322,7 +345,7 @@ jobs:
timeout-minutes: 30
- name: Setup node x86
uses: actions/setup-node@v4
uses: actions/setup-node@a0853c24544627f65ddf259abe73b1d18a591444 # v5.0.0
if: matrix.settings.target == 'i686-pc-windows-msvc'
with:
node-version: ${{ env.NODE_VERSION }}
@@ -331,7 +354,7 @@ jobs:
architecture: x86
- name: Build in docker
uses: addnab/docker-run-action@v3
uses: addnab/docker-run-action@4f65fabd2431ebc8d299f8e5a018d79a769ae185 # v3
if: ${{ matrix.settings.docker }}
with:
image: ${{ matrix.settings.docker }}
@@ -344,12 +367,12 @@ jobs:
shell: bash
- name: Upload artifact
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
with:
name: bindings-${{ matrix.settings.target }}
path: |
packages/**/*.node
packages/**/*.wasm
packages/nx/src/native/*.node
packages/nx/src/native/*.wasm
if-no-files-found: error
build-freebsd:
@@ -359,14 +382,14 @@ jobs:
name: Build FreeBSD
timeout-minutes: 45
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
with:
repository: ${{ needs.resolve-required-data.outputs.repo }}
ref: ${{ needs.resolve-required-data.outputs.ref }}
repository: ${{ needs.resolve-required-data.outputs.repo || github.repository }}
ref: ${{ needs.resolve-required-data.outputs.ref || github.ref }}
- name: Build
id: build
uses: cross-platform-actions/action@v0.25.0
uses: cross-platform-actions/action@462ed697694d2ac9aa49e1225f395f7bb6dd49fe # v0.29.0
env:
DEBUG: napi:*
RUSTUP_IO_THREADS: 1
@@ -382,8 +405,12 @@ jobs:
run: |
env
whoami
sudo pkg install -y -f node libnghttp2 www/npm git
sudo npm install --location=global --ignore-scripts pnpm@10.11.1
sudo pkg install -y -f node libnghttp2 www/npm git openjdk17
sudo npm install --location=global --ignore-scripts pnpm@10.28.2
# Set up Java 17
export JAVA_HOME=/usr/local/openjdk17
export PATH="$JAVA_HOME/bin:$PATH"
java --version
curl https://sh.rustup.rs -sSf --output rustup.sh
sh rustup.sh -y --profile minimal --default-toolchain stable
source "$HOME/.cargo/env"
@@ -398,8 +425,75 @@ jobs:
whoami
env
freebsd-version
echo "Installing dependencies"
pnpm install --frozen-lockfile --ignore-scripts
pnpm nx run-many --verbose --outputStyle stream --target=build-native -- --target=x86_64-unknown-freebsd
echo "Checking disk space before cleanup"
df -h
echo "Removing unnecessary preinstalled packages"
# List all packages first to see what's installed
sudo pkg info -a
echo "Cleaning up to free disk space"
# Clean package caches
sudo pkg clean -a -y
sudo pkg autoremove -y
# Remove unnecessary system files
sudo rm -rf /usr/local/lib/*.a
sudo rm -rf /usr/local/share/doc/*
sudo rm -rf /usr/local/share/man/*
sudo rm -rf /usr/local/share/examples/*
sudo rm -rf /usr/local/share/locale/*
sudo rm -rf /usr/local/share/gtk-doc/*
sudo rm -rf /usr/local/share/info/*
sudo rm -rf /usr/src/*
sudo rm -rf /usr/obj/*
sudo rm -rf /usr/tests/*
sudo rm -rf /usr/lib/debug/*
# Clean var directories
sudo rm -rf /var/cache/pkg/*
sudo rm -rf /var/db/pkg/*.tbz
sudo rm -rf /var/log/*.log
sudo rm -rf /var/log/*.old
# Clean temporary files
sudo rm -rf /tmp/*
sudo rm -rf /var/tmp/*
# Remove Python cache if present
sudo find /usr/local -type d -name "__pycache__" -exec rm -rf {} + 2>/dev/null || true
sudo find /usr/local -name "*.pyc" -delete 2>/dev/null || true
sudo find /usr/local -name "*.pyo" -delete 2>/dev/null || true
# Clean npm/pnpm caches
npm cache clean --force || true
pnpm store prune || true
rm -rf ~/.npm || true
rm -rf ~/.pnpm-store || true
# Remove Rust build artifacts if any
rm -rf ~/.cargo/registry || true
rm -rf ~/.cargo/git || true
rm -rf ~/.rustup/toolchains/*/share || true
# Remove other development tool caches
rm -rf ~/.cache/* || true
# Remove unnecessary workspace directories
rm -rf docs astro-docs nx-dev || true
echo "Checking disk space after cleanup"
df -h
echo "Building FreeBSD bindings"
BUILD_EXIT=0
pnpm nx run-many --verbose --outputStyle stream --target=build-native -- --target=x86_64-unknown-freebsd || BUILD_EXIT=$?
echo "=== Disk usage after build ==="
df -h
if [ "$BUILD_EXIT" -ne 0 ]; then
echo "Build failed with exit code $BUILD_EXIT"
exit $BUILD_EXIT
fi
echo "Build succeeded"
echo "Cleaning up"
pnpm nx reset
rm -rf node_modules
rm -rf dist
@@ -408,16 +502,18 @@ jobs:
echo "COMPLETE"
- name: Upload artifact
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
with:
name: bindings-freebsd
path: packages/**/*.node
path: |
packages/nx/src/native/*.node
if-no-files-found: error
publish:
if: ${{ github.repository_owner == 'nrwl' }}
name: Publish
runs-on: ubuntu-latest
environment: npm-registry
permissions:
id-token: write
contents: write
@@ -428,31 +524,28 @@ jobs:
- build
env:
GH_TOKEN: ${{ github.token }}
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
NPM_CONFIG_PROVENANCE: true
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
with:
repository: ${{ needs.resolve-required-data.outputs.repo }}
ref: ${{ needs.resolve-required-data.outputs.ref }}
repository: ${{ needs.resolve-required-data.outputs.repo || github.repository }}
ref: ${{ needs.resolve-required-data.outputs.ref || github.ref }}
- uses: pnpm/action-setup@v4
with:
version: ${{ env.PNPM_VERSION }}
- name: Setup dev tools with mise
uses: jdx/mise-action@146a28175021df8ca24f8ee1828cc2a60f980bd5 # v3
- name: Setup node
uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
registry-url: 'https://registry.npmjs.org'
check-latest: true
cache: 'pnpm'
- name: Enable corepack and install pnpm
run: |
corepack enable
corepack prepare --activate
- name: Use npm 11.5.2
run: sudo npm install -g npm@11.5.2
- name: Install dependencies
run: pnpm install --frozen-lockfile
- name: Download all artifacts
uses: actions/download-artifact@v4
uses: actions/download-artifact@634f93cb2916e3fdff6788551b99b062d0335ce0 # v5.0.0
with:
path: artifacts
@@ -464,6 +557,7 @@ jobs:
run: |
wget https://github.com/WebAssembly/wasi-sdk/releases/download/wasi-sdk-23/wasi-sdk-23.0-x86_64-linux.tar.gz
tar -xvf wasi-sdk-23.0-x86_64-linux.tar.gz
rustup toolchain install nightly-2025-05-09
pnpm build:wasm
- name: Publish
env:
@@ -488,11 +582,11 @@ jobs:
- name: (PR Release Only) Create comment for successful PR release
if: success() && github.event.inputs.pr
uses: actions/github-script@v7
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0
env:
SUCCESS_COMMENT: ${{ needs.resolve-required-data.outputs.success_comment }}
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
# github-token defaults to ${{ github.token }} so we don't need to specify it
script: |
const successComment = JSON.parse(process.env.SUCCESS_COMMENT);
await github.rest.issues.createComment({
@@ -502,22 +596,55 @@ jobs:
body: successComment
});
report-pending-publish:
name: Report Pending Publish to Slack
if: ${{ github.repository_owner == 'nrwl' }}
needs:
- resolve-required-data
- build-freebsd
- build
runs-on: ubuntu-latest
timeout-minutes: 10
continue-on-error: true # Don't fail the workflow if notification fails
steps:
- name: Send Slack notification
uses: ravsamhq/notify-slack-action@be814b201e233b2dc673608aa46e5447c8ab13f2 # v11
with:
status: ${{ job.status }}
notification_title: >-
${{ needs.resolve-required-data.outputs.pr_number &&
format('📦 PR #{0} Publish Pending Review', needs.resolve-required-data.outputs.pr_number) ||
'📦 Publish Pending Review' }}
message_format: >-
${{ needs.resolve-required-data.outputs.pr_number &&
format('Version {0} from PR #{1} by @{2} is being published to NPM - manual review is required',
needs.resolve-required-data.outputs.version,
needs.resolve-required-data.outputs.pr_number,
needs.resolve-required-data.outputs.pr_author) ||
format('Version {0} is being published to NPM - manual review is required',
needs.resolve-required-data.outputs.version) }}
footer: '<{run_url}|View Workflow Run>'
mention_users: 'U9NPA6C90' # Jason
env:
SLACK_WEBHOOK_URL: ${{ secrets.ACTION_MONITORING_SLACK }}
pr_failure_comment:
# Run this job if it is a PR release, running on the nrwl origin, and any of the required jobs failed
if: ${{ github.repository_owner == 'nrwl' && github.event.inputs.pr && always() && contains(needs.*.result, 'failure') }}
needs: [ resolve-required-data, build, build-freebsd, publish ]
name: (PR Release Failure Only) Create comment for failed PR release
runs-on: ubuntu-latest
permissions:
pull-requests: write
steps:
- name: Create comment for failed PR release
uses: actions/github-script@v7
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
# This script is intentionally kept inline (and e.g. not generated in publish-resolve-data.js)
# to ensure that an error within the data generation itself is not missed.
script: |
const message = `
Failed to publish a PR release of this pull request, triggered by @${{ github.triggering_actor }}.
Failed to publish a PR release of this pull request, triggered by @${{ github.triggering_actor }}.
See the failed workflow run at: https://github.com/nrwl/nx/actions/runs/${{ github.run_id }}
`;
await github.rest.issues.createComment({
@@ -526,3 +653,4 @@ jobs:
issue_number: ${{ github.event.inputs.pr }},
body: message
});
+1
View File
@@ -344,6 +344,7 @@ The scope must be one of the following:
- express - anything Express specific
- js - anything related to @nx/js package or general js/ts support
- linter - anything Linter specific
- module-federation - anything Nx Module Federation specific
- nest - anything Nest specific
- nextjs - anything Next specific
- node - anything Node specific
@@ -53,7 +53,7 @@ Finally, add the following to your `lerna.json`.
That's mostly it. You can continue using the usual Lerna commands, but at this point Lerna would delegate its operations to Nx underneath.
To get more out of it, you might want to create a small `nx.json` file (or run `npx nx init` to generate one) for going into some more details on configuring the cacheable operations:
To get more out of it, you might want to create a small `nx.json` file (or run `npx nx@latest init` to generate one) for going into some more details on configuring the cacheable operations:
```json5 {% fileName="nx.json" %}
{
@@ -88,7 +88,7 @@ By having Nx integrated, you not just get faster builds but also some other Nx's
**Distributed caching** — Right now when you enable `useNx` in your existing Lerna repo, you will get local caching, meaning the cache sits in a local folder on your machine. You get much more value out of it when you start distributing and sharing it with your teammates but especially in CI. This can be done by adding Nx Cloud, which comes with a no-credit card, 500 hours free / month offer which is more than what most workspaces need. Adding that is easy and can be done by adding `@nrwl/nx-cloud` to your root-level `package.json` and then by running:
```shell
npx nx connect-to-nx-cloud
npx nx@latest connect-to-nx-cloud
```
**Distributed task execution** — Distribution of the cache is one thing, but the real speed improvements come from also [distributing the task execution](/ci/features/distribute-task-execution) to speed up your CI. Having the Nx project graph and as well as the cache and historical data about previous runs, Nx Cloud DTE is able to maximize the CI agent utilization by evenly distributing tasks based on their (historical) duration as well as based on their topological order. In addition, the DTE process makes sure to properly move cached assets between the agents. Setting up DTE is straightforward, read more on our [Nx Cloud docs](/ci/features/distribute-task-execution). Hint: we also have a CI generator in Nx (you need the `@nrwl/workspace` package) that allows you to generate your CI setup using a single command: `npx nx generate @nrwl/workspace:ci-workflow --ci=github`
@@ -75,7 +75,7 @@ In v14 we already simplified Nx (we have a whole section in [our release blog po
Whenever you need to fine-tune the default settings you can run the following command to get a `nx.json` generated or you can obviously create it by hand:
```shell
npx nx init
npx nx@latest init
```
## Run Nx graph on any monorepo!
@@ -509,7 +509,7 @@ If you're currently on a [CRA](https://create-react-app.dev/) setup, you can eas
{% youtube src="https://youtu.be/zvYb7XCLQzU" /%}
```shell
npx nx init
npx nx@latest init
```
Read more on the Nx docs: [/recipes/adopting-nx/adding-to-existing-project](/recipes/adopting-nx/adding-to-existing-project)
@@ -65,7 +65,7 @@ When you run `nx init` in your existing Nuxt.js project, Nx does the following:
To begin the integration process, simply navigate to the root of your existing Nuxt.js project and run:
```shell
npx nx init
npx nx@latest init
```
This approach offers several key benefits for teams looking to adopt Nx:
+1 -1
View File
@@ -120,7 +120,7 @@ Versioning and publishing packages is always a bit tricky. Mix in the added comp
For a long time, Nx has been purposefully versioning and publishing agnostic, but given our time spent as [stewards of Lerna](/blog/lerna-is-dead-long-live-lerna) (the OG Javascript monorepo tool), we've been able to take alot of that experience and finally feel confident creating our own versioning and publishing implementation.
Therefore, we've been working on a new command to the Nx CLI: [nx release](/recipes/nx-release/get-started-with-nx-release#get-started-with-nx-release). We launched this on Friday of our Launch Nx week!
Therefore, we've been working on a new command to the Nx CLI: [nx release](/recipes/nx-release/release-npm-packages). We launched this on Friday of our Launch Nx week!
Juri goes into [full details in this blog post](/blog/versioning-and-releasing-packages-in-a-monorepo), and James Henry — our Director of Engineering and the primary engineer responsible for both maintaining Lerna and creating Nx Release — expands further in his conference talk:
+1 -1
View File
@@ -169,7 +169,7 @@ nx affected --targets=lint,test,build,e2e-ci
In CI, Nx Agents will allow all tasks to run in parallel on the same machine, except for the atomized end-to-end tasks, which will only run in isolation.
Learn more about how you can [Parallelize Tasks Across Multiple Machines Using Nx Agents](/ci/intro/tutorials/github-actions#parallelize-tasks-across-multiple-machines-using-nx-agents):
Learn more about how you can [Parallelize Tasks Across Multiple Machines Using Nx Agents](/ci/features/split-e2e-tasks):
{% youtube
src="https://youtu.be/0YxcxIR7QU0"
@@ -33,7 +33,7 @@ If you prefer the previous log view in your CI, you can opt-out of the new table
If you're not on Nx Cloud yet, you can **connect your Nx workspace** by running:
```shell
npx nx connect
npx nx@latest connect
```
This command will guide you through the setup. We recently introduced a [new Hobby plan](/pricing), which lets you experiment with all the Nx Cloud features for free. This is a great way to see if it's a good fit for your team.
@@ -94,7 +94,7 @@ The routes exist as projects which are then imported by the application. We can
Adopting a monorepo powered by Nx on its own does not solve build speeds or CI pipeline times. But adopting a monorepo and taking the time to reevaluate your architecture can lead to a significant improvement in build times when best practices are applied. If you're curious to know more, reach out to us to see how Nx can improve your monorepo experience and ship faster!
{% call-to-action title="Explore Nx Cloud for Enterprises" url="/enterprise" icon="nxcloud" description="Learn more about our offerings for enterprises and contact our team" %} Explore Nx Cloud for Enterprises {% /call-to-action %}
{% call-to-action title="Reach out to our team!" url="/contact/sales" icon="nxcloud" description="Looking to transform your teams velocity? Reach out to learn more about Nx Enterprise and see how we can help your team achieve similar results." /%}
## Further reading
@@ -86,4 +86,4 @@ Consolidating projects into a single repository **eliminated the complexity of m
Hetzner Cloud continues to **work closely with the Nx Developer Productivity Engineering (DPE) team** to monitor and refine their setup. By actively collaborating, they ensure that their monorepo remains optimized and that their CI is continuously improved. This ongoing partnership allows Hetzner Cloud to adapt to new challenges, fine-tune configurations, and further push the boundaries of efficiency in their development workflow.
{% call-to-action title="Want to achieve similar results?" url="/enterprise" icon="nxcloud" description="Learn more about Nx Enterprise or get started with a free trial." /%}
{% call-to-action title="Reach out to our team!" url="/contact/sales" icon="nxcloud" description="Looking to transform your teams velocity? Reach out to learn more about Nx Enterprise and see how we can help your team achieve similar results." /%}
@@ -73,6 +73,4 @@ Other engineers in other business units are seeing the advantage of Nx, and thei
What's blocking you from getting your products to market fast? Let our team figure it out for you! With Nx Enterprise, you receive expert guidance from day one, ensuring your setup is optimized for maximum efficiency. Whether you're starting fresh, migrating, or scaling your developer platform, we'll work with you to tailor the perfect solution for your team.
{% call-to-action title="Get a Free Trial of Nx Enterprise" url="/enterprise" icon="nxcloud" description="Learn more about our enterprise offerings or request a free trial of Nx Enterprise" %}
{% /call-to-action %}
{% call-to-action title="Reach out to our team!" url="/contact/sales" icon="nxcloud" description="Looking to transform your teams velocity? Reach out to learn more about Nx Enterprise and see how we can help your team achieve similar results." /%}
@@ -106,10 +106,10 @@ If you view the `my-app-e2e` project (`npx nx show project my-app-e2e`), you wil
When run on a single machine, `e2e-ci` will be slower because it starts multiple Playwright processes, which is why we only allow it to run through distribution. To [enable distribution](/ci/features/split-e2e-tasks#enable-automated-e2e-task-splitting), you must connect your workspace to [Nx Cloud](/nx-cloud). This is easily done with the `connect` command.
```shell
npx nx connect
npx nx@latest connect
```
Follow the onboarding steps and you should be connected within five minutes. For more information, check out our [GitHub Actions Tutorial](/ci/intro/tutorials/github-actions) or our [guides](/ci/recipes/set-up) for all supported CI providers (GitHub, GitLab, Azure, etc.).
Follow the onboarding steps and you should be connected within five minutes. For more information, check out our [setup guides](/ci/recipes/set-up) for all supported CI providers (GitHub, GitLab, Azure, etc.).
Now, let's take a look at a concrete example to get an idea of how much time-saving you can unlock with Nx Atomizer. I created [this repo](https://github.com/jaysoo/angular-testing-demo) that contains a simple Angular application and a UI package. It also has 40 Playwright test files.
@@ -161,7 +161,7 @@ It uses Nx for running and building your project. Nx relies on the Angular Devki
If you have an existing Angular CLI project, you can also [add Nx support to it](/technologies/angular/migration/angular) by running:
```shell
npx nx init
npx nx@latest init
```
If you already know you want to go straight to an Nx monorepo, you can add the `--integrated` flag to the `nx init` command.
@@ -72,7 +72,7 @@ The steps are very simple:
2. Run `nx g @nx/angular:convert-to-rspack` to migrate your Angular application to Rspack.
There is also a [guide in our documentation](/technologies/angular/angular-rspack/recipes/migrate-from-webpack) that walks you through the process step-by-step.
Even if you're currently using the Angular CLI, it's as simple as first running `npx nx init` in your workspace and then running `npx nx g convert-to-rspack`.
Even if you're currently using the Angular CLI, it's as simple as first running `npx nx@latest init` in your workspace and then running `npx nx g convert-to-rspack`.
## Using Angular Rspack
+2 -2
View File
@@ -99,7 +99,7 @@ To enable Self-Healing CI on your workspace:
If you haven't already connected to Nx Cloud:
```shell
npx nx connect
npx nx@latest connect
```
You can [start with the free Hobby plan](/pricing) and play around with the new AI features.
@@ -179,7 +179,7 @@ Self-Healing CI completes Nx Cloud's comprehensive approach to eliminating CI fr
- **Built on proven infrastructure**: Uses the same robust Nx Cloud infrastructure that powers distributed task execution
- **Part of a broader vision**: Continues our mission to optimize "time to green" and eliminate developer workflow friction
**Ready to try it?** Self-Healing CI is rolling out as an early access feature and is available to everyone right now—no special approval or signup required. If you don't have an Nx Cloud account yet, you can quickly [start with the Hobby plan](/pricing), connect your workspace with `npx nx connect`, and get going immediately.
**Ready to try it?** Self-Healing CI is rolling out as an early access feature and is available to everyone right now—no special approval or signup required. If you don't have an Nx Cloud account yet, you can quickly [start with the Hobby plan](/pricing), connect your workspace with `npx nx@latest connect`, and get going immediately.
**For enterprise teams:** If you're already using Nx Cloud and want to learn more about how AI features like Self-Healing CI can enhance your existing setup, [reach out to us](/contact). We'd love to help you leverage these capabilities in your organization.
@@ -125,7 +125,7 @@ Then update the JSON configuration as follows, making sure the `cwd` points to t
If you haven't already connected your Nx workspace to Nx Cloud, run:
```shell
npx nx connect
npx nx@latest connect
```
This command will walk you through connecting your existing Nx workspace to a new Nx Cloud account. **There's a [free hobby plan](/pricing)**. Run it for a couple of weeks and then try out these conversational analytics features.
+38
View File
@@ -0,0 +1,38 @@
---
title: 'The More the Merrier - Groups Save 50% on Nx Essentials Workshop'
slug: nx-essentials-workshop
authors: []
tags: ['workshop']
cover_image: /blog/images/2025-07-23/header.avif
description: 'Join us for a 2-day deep dive into all things Nx! Instructors from Nx and Push-Based will team up to cover the breadth of tools and techniques needed for any tech lead or individual contributor to be successful setting up and navigating an Nx workspace.'
---
You may have missed the Early Bird discount, but its not too late to get an amazing price on our [Nx Essentials online workshop](https://bit.ly/3IYOILt). **Groups of 3 or more can use the promo code NXGROUP at checkout to save 50% on everyones registration.**
## About the Workshop
**Dates:** July 29th-30th
**Time:** 12pm - 5pm ET/9am-2pm PT
This is a 2-day deep dive into all things Nx! Instructors from Nx and Push-Based will team up to cover the breadth of tools and techniques needed for any tech lead or individual contributor to be successful optimizing your development workflow with Nx.
We believe that the most effective way to learn is often to get in there and start trying things out yourself, so topics will be presented via short presentations followed by hands-on code labs. Our instructors will work with attendees, offering help to anyone who gets stuck and engaging discussion topics for anyone blazing ahead.
While the course starts with the very basics of Nx, it quickly moves into advanced topics, so attendees of any experience level should come away with new insights.
Well cover…
- **Using Nx ** Run Tasks, Task Pipelines, Affected, Caching, Generate Code
- **Enforcing Organizational Decisions ** Configure Module Boundaries, Create a Custom Plugin to Manage Docker Configs
- **Boosting Performance ** Module Federation, Remote Caching, Nx Agents, Optimize Cache Settings, Atomizer, Flaky Tasks
And more! **Every exercise will also include clear action steps for you to try out in your own repository.**
## Need help justifying the expense?
Weve drafted a [sample justification letter](https://bit.ly/44pNuzX) you can use.
And if you think your team might be a good fit for Nx Enterprise, your workshop fees can also be applied as a discount towards new contracts signed within 6 months of the workshop date.
[Check out the full details and save your spot for the Nx Essentials workshop!](https://bit.ly/3IYOILt)
@@ -0,0 +1,105 @@
---
title: 'From 5 Days to 20 Minutes: How PayFit Accelerated Time to Market with Strategic Nx Implementation'
slug: payfit-success-story
authors: [Juri Strumpflohner]
tags: ['customer story']
description: Discover how a 4-person platform team at Payfit turned monorepo abandonment into a competitive advantage using strategic Nx implementation.
cover_image: /blog/images/articles/bg-payfit-customer-success.avif
youtubeUrl: https://youtu.be/Vdk-tza4PCs
metrics:
- value: '5 days→20 min'
label: 'feature deployment time'
- value: '75% faster'
label: 'coding time'
- value: '4 engineers'
label: 'platform team managing entire frontend ecosystem'
- value: '100%'
label: 'teams wanting to migrate back to monorepo'
---
PayFit is a leading European HR and payroll platform serving thousands of businesses across the continent with their innovative SaaS solutions. As one of Europe's fastest-growing HR tech companies, PayFit continues to expand rapidly across multiple markets. Their engineering organization faced a classic scale challenge: maintaining development velocity while managing an increasingly complex codebase distributed across multiple repositories.
With a lean but highly strategic platform team of just four engineers responsible for frontend tooling, design systems, monorepo health, and CI/CD infrastructure, PayFit needed maximum efficiency to compete in the demanding startup landscape. When deployment cycles stretched from 2-5 days per feature and teams abandoned their shared monorepo due to poor initial implementation, the company was at a critical inflection point that threatened their competitive advantage in the fast-moving European HR tech market.
## Challenge
Payfit's journey with Nx began with a top-down mandate that didn't include the necessary knowledge transfer or support systems. This led to a predictable outcome: teams abandoned the monorepo entirely. At a critical tipping point, engineering teams extracted themselves from the shared workspace, prioritizing autonomy over the collaborative benefits that a well-managed monorepo could provide.
The consequences of this fragmentation were severe:
- **Deployment complexity** Deploying a single feature required navigating multiple repositories and systems sequentially, taking between **2 and 5 days** to complete.
- **Lost development velocity** Teams accepted slower development pace as the cost of independence.
- **Fragmented ownership** No clear ownership or maintenance of shared tooling and infrastructure.
- **CI/CD inefficiencies** Each repository required its own CI setup and optimization, leading to duplicated effort and inconsistent performance.
In a startup environment where speed to market is crucial, these delays were becoming a significant competitive disadvantage.
## Solution
Nicolas Beaussart joined Payfit as a staff engineer with a clear mission: revive the monorepo and restore development velocity. Rather than forcing teams back immediately, the platform team took a strategic approach focused on proving value through execution.
The team focused on making the monorepo a compelling choice rather than a mandate:
- **Invested in monorepo health** Properly configured Nx with task inference to ensure everything worked smoothly out of the box.
- **Leveraged Nx Cloud** Implemented Nx Cloud to dramatically speed up CI performance and eliminate the manual optimization burden.
- **Pilot program approach** Started with a few pilot teams to migrate back and demonstrate the benefits in practice.
- **Created social proof** Early positive feedback from pilot teams served as validation for other teams considering the migration.
### Offloading Complexity with Nx Cloud
One of the most significant improvements came from adopting [Nx Cloud](https://nx.app) to handle CI optimization. This shift from manual CI optimization to automated intelligence freed the platform team to focus on higher-value work while ensuring optimal performance.
{% testimonial
name="Nicolas Beaussart"
title="Staff Engineer, Payfit"
image="https://avatars.githubusercontent.com/u/7281023?v=4" %}
The number of hours we spent optimizing CI before, trying to load balance in CircleCI, the different number of agents that we run ourselves by hand... it was painful and we spent hours and days trying to do that. The main thing with Nx Cloud is that we don't have to think about that.
{% /testimonial %}
The strategic approach paid off. Positive feedback from pilot teams created a snowball effect:
> "Slowly but surely it went into a snowball effect where now teams want to migrate themselves back into the monorepo directly themselves."
This organic adoption was far more sustainable than the original top-down mandate, as teams could see the concrete benefits in their daily work.
## Results
### Dramatic Reduction in Deployment Time
The most striking improvement was in feature deployment speed:
- **From 2-5 days to 20 minutes maximum** The initial optimization achieved in the October 2024 interview reduced deployment time to 2 hours (a 97% reduction). Since then, the PayFit team has continued optimizing their deployment pipeline, achieving just _20 minutes from branch push to full production deployment across all environments—including merge, dev, staging, e2e, and production_.
- **75% faster coding** Features that previously took much longer to code can now be developed in a quarter of the time
{% testimonial
name="Nicolas Beaussart"
title="Staff Engineer, Payfit"
image="/documentation/blog/images/articles/nicolas-beaussart.avif" %}
A year ago to deploy a feature it took between 2 and 5 days because you had to go through all of the monorepos, all of the systems one by one to be able to deploy that. Today the same feature can be coded in like a quarter of the time and deploying like 2 hours tops (now even down to only 20 min).
{% /testimonial %}
### Restored Team Confidence in Monorepo Architecture
The platform team successfully reversed the initial exodus from the monorepo:
- Teams now **actively request to migrate back** to the main monorepo
- **100% positive feedback** from teams that have migrated back
- Strong **social proof** driving organic adoption across the organization
### Operational Efficiency Through Automation
By leveraging Nx Cloud's intelligent CI optimization, the platform team eliminated a major operational burden:
- **Zero time spent** on manual CI optimization and load balancing
- **Predictable performance** without manual intervention
- **Direct support channel** with Nx team for any optimization needs
### Competitive Advantage in Startup Environment
For a startup where speed to market is crucial, these improvements translated directly to business impact:
> "This is critical in a startup world where things need to move fast, and a big part of this answer is Nx and Nx Cloud. Without those pieces, I don't think we could have the same velocity that we have right now."
The transformation enabled Payfit to maintain their competitive edge while scaling their engineering organization efficiently.
{% call-to-action title="Reach out to our team!" url="/contact/sales" icon="nxcloud" description="Looking to transform your teams velocity? Reach out to learn more about Nx Enterprise and see how we can help your team achieve similar results." /%}
@@ -0,0 +1,69 @@
---
title: 'The Journey of Nx Gradle: From Prototype to Production'
slug: journey-of-nx-gradle
authors: [Jason Jean, Mike Hartington]
tags: ['java', 'gradle']
description: Nxs Gradle plugin evolved from a prototype into a robust solution for integrating Java projects in monorepos, offering deep Gradle insights, faster CI, and upcoming Maven support.
cover_image: /blog/images/2025-07-28/header.avif
---
{% callout type="deepdive" title="Java Week Series" expanded=true %}
This article is part of the Java Week series:
- **The Journey of Nx Gradle**
- [Polyglot Projects Made Easy](/blog/spring-boot-with-nx)
- [Getting Mobile Into Your Monorepo](/blog/android-and-nx)
- [Seamless Deploys With Docker](/blog/seamless-deploys-with-docker)
{% /callout %}
When Nx first dipped its toes into the world of Java, no one could have predicted the ride ahead. From an accidental prototype to enterprise-level adoption, the path of Java support at Nx, particularly through the `@nx/gradle` plugin, has been one of exploration, iteration, and growing maturity.
## Humble Beginnings: An Accidental Start
In February 2020, the Nx team attended their first Java conference, DevNexus. At the time, there was no Java solution from Nx, so we spent the next couple of days thinking about what Nx for Java would look like and what kind of technical challenges would need to be addressed. At the time, Nx was still very much tied to Angular, and while it was technically possible to target Gradle projects this way, it was very rough and never went past the point of being a prototype. Shortly after the conference, Covid lock downs went into place and we put development on pause.
## Laying the Foundations with Crystal
Fast forward to 2024, and we made a major change to Nx. Code name **Project Crystal** was a shift in how Nx worked under the hood. Instead of configuring Nx separately to work with a particular tool, most tools have their own configuration that Nx would reference to get even better configuration programmatically. We started using this inferred approach for all of our core supported tools (like Vite) and would read the config from the associated config file (`vite.config.js`). **Project Crystal made Nx more transparent, simplified how Nx was configured, optimized the configuration, made running tools through Nx even faster, and reduced maintenance required all in one fell swoop.** Even during Project Crystal, Gradle was at the forefront of our considerations during this re-architecture. This new architecture set the stage for how Java/Gradle support could be implemented. Nx would get information from Gradle itself for how Nx should run Gradle and Nx would transparently invoke Gradle.
## The Birth of Nx Gradle
Shortly after inferred projects shipped, we had a reworked version of that early prototype that was ready for some real world testing as `@nx/gradle`. We [announced the plugin](/blog/manage-your-gradle-project-using-nx) and started to use it internally in our closed-source monorepo. We even had interest from some clients who had Java projects that they wanted to consolidate with their existing Nx monorepo.
However, after its initial usage, we had started to notice some limitations with this approach. The main limitation was our usage of Gradle's built-in `project-report` feature which didn't provide Nx with enough detail for accurate configuration. We went back to the drawing board and reimagined how to add support for more complex setups that we saw in the real world.
## A Smarter, Deeper Integration: v2 of Nx Gradle
By November 2024, the team began experimenting with a **v2** of Gradle plugin that aimed to extract richer and more granular data from Gradle itself. This involved building a dedicated **Gradle plugin for Nx (`dev.nx.gradle`)**. The new approach could detect:
- Available tasks
- Task inputs and outputs
- Dependency chains (`dependsOn`)
- And more!
At the start of 2025 we started testing this against a much larger and more complex Java codebase, the [Spring Boot repository](https://github.com/xiongemi/spring-boot).
## Benchmarking Nx in Spring Boot
Even though we had learned a lot from the initial adoption of `@nx/gradle`, if we can get Nx working here, we can better support other projects with ease. The Spring Boot repo ran more than 8000 tasks for its CI pipeline taking up to 1 hour 40 minutes for the worst case scenario without caching. Integrating Nx into this pipeline required us to make even more improvements to Nx to get things running smoothly. We introduced Batch mode support for running `@nx/gradle` tasks which allowed Nx to run multiple tasks within a single invocation of Gradle greatly reducing the overhead that Nx would incur running Gradle. We also introduced atomization for running Gradle tests. Today, Nx is able to run the same 8000+ tasks in a worst case scenario with no caching in 50 minutes.
## Looking Ahead
As of now, the Nx Gradle plugin is in a much better state than when we started last year. We can now handle multi-module Gradle projects, as well as polyglot monorepos with existing JavaScript projects. This week, we're going to take a refreshed look at `@nx/gradle` and what you can expect in the future. We have more plans for Nxs Java Support (like Maven support) so we're not done yet. In fact, we are actively prototyping a Maven plugin against the [Quarkus repository](https://github.com/quarkusio/quarkus)!
What began as an off-the-cuff prototype at a conference has matured into a serious offering for Java developers working in monorepos. Nx Gradle has evolved from a limited tool into a reliable, insightful, and enterprise-friendly integration—bringing the Nx developer experience to Java and teams. And with Maven support on the horizon, the journey is far from over.
**Stay tuned—because the future of Java at Nx is only just getting started.**
---
Learn more:
- 🌌 [Nx Gradle Tutorial](/getting-started/tutorials/gradle-tutorial)
- 📖 [Nx Gradle API](/technologies/java/api)
- 👩‍💻 [Nx GitHub](https://github.com/nrwl/nx)
- 👩‍💻 [Nx Console GitHub](https://github.com/nrwl/nx-console)
- 💬 [Nx Official Discord Server](https://go.nx.dev/community)
- 📹 [Nx Youtube Channel](https://www.youtube.com/@nxdevtools)
+150
View File
@@ -0,0 +1,150 @@
---
title: 'Polyglot Projects Made Easy: Integrating Spring Boot into an Nx Workspace'
slug: spring-boot-with-nx
authors: ['Mike Hartington']
tags: ['nx', 'java', 'springboot']
cover_image: /blog/images/2025-07-29/header.avif
description: 'Learn how to seamlessly integrate a Spring Boot Java backend into an existing Nx monorepo with a React frontend—streamlining development, simplifying workflows, and enabling powerful fullstack coordination.'
youtubeUrl: https://youtu.be/FM2kAw-NNsQ
---
{% callout type="deepdive" title="Java Week Series" expanded=true %}
This article is part of the Java Week series:
- [The Journey of Nx Gradle](/blog/journey-of-nx-gradle)
- **Polyglot Projects Made Easy**
- [Getting Mobile Into Your Monorepo](/blog/android-and-nx)
- [Seamless Deploys With Docker](/blog/seamless-deploys-with-docker)
{% /callout %}
Behind every modern JavaScript app lies a powerful backend, and for many enterprises, that backend is powered by Java. At Nx, we believe Java is just as much a first-class citizen as JavaScript. While Nx has a proven history of streamlining JavaScript development, we also offer seamless integration for Java projects. With the `@nx/gradle` plugin, you can bring your Java services built with Gradle into your Nx monorepo, creating a unified environment where both frontend and backend thrive together. Lets dive into how Nx bridges these worlds effortlessly.
## Spring into Java
For starters, let's look at our Java backend. It's just a simple app built using the Spring Boot framework. With this, we can set up various rest endpoints for interacting with some data. There's some endpoints for user management, authentication, and session storage for logged in users. For Java developers, running and testing this app is as simple as pressing the "play" button in IntelliJ.
![](/blog/images/2025-07-29/intellij.png)
Spring has [a project generator](https://start.spring.io/index.html) that can help get you up and running, and you can check out this project on GitHub if you want to follow along.
Now if I want to interact with this backend, I would need to create a frontend app that I can make request from. But in a real world situation, the frontend and backend are probably maintained by different teams. This is the typical problem space that Nx works in, so we can reduce and simplify the development of this app.
## You got your Java In my JavaScript
Our frontend project is just your standard React app. It already exists in a Nx workspace, so I have all of my usual Nx feature available to me. It interacts with the backend by making requests to it, but I need to start the two projects separately, which can just be cumbersome to manage.
![](/blog/images/2025-07-29/vscode.png)
To actually make these two projects work together, we can utilize the `nx import` command to start migrating the backend into the existing workspace. `import` can take a relative path or a git URL, and it will handle all of the necessary work of maintaining the git history, detecting the project type, and suggesting additional plugins you might want to include.
For our Java project, it's going to suggest that we include the `@nx/gradle` plugin as we are using [Gradle as our build system](https://gradle.org/). Once installed, we can run `nx graph` or `nx show project java-backend` to inspect.
![](/blog/images/2025-07-29/java-tasks.png)
Here we can see all of the available tasks from Gradle that we could run for our Java project. But how does Nx know about these tasks? We actually include a Gradle plugin for Nx that we use under the hood to inspect the Java project. When we call any `nx` command for our java project, we actually invoke Gradle in the background to get all of tasks that Gradle could run directly.
```groovy
plugins {
id 'java'
id 'org.springframework.boot' version '3.4.5'
id 'io.spring.dependency-management' version '1.1.7'
// Added by Nx
id "dev.nx.gradle.project-graph" version "0.1.0"
}
java {...}
configurations {...}
repositories {...}
dependencies {...}
allprojects {
apply {
plugin("dev.nx.gradle.project-graph")
}
}
```
This project-graph is added to our `build.gradle` file and is doing the real heavy lifting for us.
From here, we can start running the Java project
```bash
nx run java-backend:bootRun
```
And our API is up and running:
![](/blog/images/2025-07-29/backend-response.png)
## Connecting Two Tasks
With the project imported, we can now coordinate the frontend and backend processes so we can easily run them together. This is actually pretty easy to do thanks to `dependsOn`. In the `package.json` for our React app, let's configure the `dev` task and make it start the Java backend.
```json
{
"name": "@mono-app/react-frontend",
"version": "0.0.1",
"private": true,
"nx": {
"targets": {
"dev": {
"dependsOn": ["java-backend:bootRun"]
}
}
}
}
```
Now we can run `react-frontend:dev` and we'll automatically get our Java backend up and running
![](/blog/images/2025-07-29/react-java.png)
But we can take this one step further. Let's consider that we have a bug in our Java backend. A bad response from an endpoint, incorrect structure, or something similar. Since our code is all in one place, we could fix this easily, but to get the changes applied, we'll need to stop and restart our server. That's not ideal, and is super slow. So we can expand on that `dependsOn` approach from earlier within our Java backend project.
If we create a simple `project.json` in the java-backend directory, we'll be able to customize the `bootRun` task. For starters, we want `bootRun` to depend on the `build` task we have:
```json
{
"targets": {
"bootRun": {
"dependsOn": ["build"]
}
}
}
```
Now for the build task, we want to pass in an argument to our underlying Gradle command:
```json
"build": {
"continuous": true,
"options": {
"args": ["--continuous"]
}
}
```
So we have the `options.args` passing in a `--continuous` flag and setting `"continuous": true`. Now, these look similar, but are doing two different things. The `"continuous": true` is telling Nx that this task is long-lived and will not end. The `options.args` part is getting passed to Gradle directly and telling Gradle to watch for file changes.
> For demo purposes, we're going to target the build task directly, but for more production ready example, create your own task so you do not impact any CI runs.
Now if we change one of our Java files, Gradle will rebuild our project, and the `bootRun` will refresh with the new changes applied.
![](/blog/images/2025-07-29/java-rebuilds.png)
## A Polyglot Future
With this, we have the beginnings of a great polyglot experience for teams that have a mix of languages. We can start to incorporate more Java related projects into Nx and bring all of the features that Nx has to offer. Be sure to stop by tomorrow to see what else we have in store for Java developers.
---
Learn more:
- 🌌 [Nx Gradle Tutorial](/getting-started/tutorials/gradle-tutorial)
- 📖 [Nx Gradle API](/technologies/java/api)
- 👩‍💻 [Nx GitHub](https://github.com/nrwl/nx)
- 👩‍💻 [Nx Console GitHub](https://github.com/nrwl/nx-console)
- 💬 [Nx Official Discord Server](https://go.nx.dev/community)
- 📹 [Nx Youtube Channel](https://www.youtube.com/@nxdevtools)
+129
View File
@@ -0,0 +1,129 @@
---
title: 'Getting Mobile Into Your Monorepo: Android + Nx'
slug: android-and-nx
authors: ['Mike Hartington']
tags: ['nx', 'java', 'android']
cover_image: /blog/images/2025-07-30/header.avif
description: 'Learn how to integrate an Android app using Kotlin and Jetpack Compose into an Nx monorepo, enabling full-stack builds and emulator deployment—all from the Nx CLI.'
---
{% callout type="deepdive" title="Java Week Series" expanded=true %}
This article is part of the Java Week series:
- [The Journey of Nx Gradle](/blog/journey-of-nx-gradle)
- [Polyglot Projects Made Easy](/blog/spring-boot-with-nx)
- **Getting Mobile Into Your Monorepo**
- [Seamless Deploys With Docker](/blog/seamless-deploys-with-docker)
{% /callout %}
Ok, so we now have a Java project in our monorepo, sitting along side of our React frontend app. We can run each of these from the Nx CLI and have a really good experience. But we can take this further. Java isn't only just used for backend apps. You can use Java to build things like Android apps, and Android apps can be built via Gradle. So in theory you could have frontend, backend, and mobile all coming from one monorepo. Now, I'm going out on my own here. Nx doesn't have an official Nx plugin for native Android, but in a attempt to see what is possible, let's try it!
## Android Setup
Ok, we aren't going to be using Java completely, instead we're going to use Kotlin which runs on the JVM. Kotlin's major feature is Jetpack Compose, a declarative approach to building interfaces for Android apps. We can then use Gradle to manage our dependencies and build the final `apk` for installation. But to get started, we do need the IDE of choice for Android development, [Android Studio](https://developer.android.com/studio). Android Studio is built on top of IntelliJ so if you've that before, you should feel at home. The major changes here are to add some needed features to managing your Android SDK and virtual devices.
Once installed, we'll go through some setup which installs the Android SDK for us. When setup, we'll create a new project based on an Empty Activity template. A word of caution, there are several templates that are based on the older "Views" approach, which is an XML-based approach of building your UI. While this is still a valid way of building Android apps, Google has recommended folks use Jetpack Compose over the XML approach. Be sure to chose the templates that do no include "Views".
![](/blog/images/2025-07-30/template-picker.png)
From here, we do have a bit of work to prepare our project. Out of the box, Android Studio creates what is called a "multi-module" project. This is similar to a monorepo, as we could have multiple Java/Kotlin based apps or libraries in one repo. However, since our goal is to incorporate this into our previous monorepo, we need to consolidate this into a single module project. To do this, we're going to move some files around and merge our Gradle files for the project and for the `app` module.
> You really shouldn't need to do this, but for simplicity sake, we're doing it so we're not having to deal with Gradle's Composite Build.
Once built, let's just test a build inside of Android Studio to validate our app still builds and that Gradle has all the dependencies installed.
![](/blog/images/2025-07-30/android-studio.png)
## Bringing in Nx
From here, we can follow the same process we used when bringing our Spring Boot app over to an existing Nx workspace.
```shell
$ nx import ../mhartington/MyApplication
✔ Which branch do you want to import? · main
✔ Which directory do you want to import into this workspace? ·
? Where in this workspace should the code be imported into? apps/android-frontend
```
Once imported, we do need to help Nx know about this project a bit more. For starter, we need a `project.json` in the root of the app:
```json {% fileName="project.json" %}
{
"name": "android-frontend",
"root": "apps/android-frontend",
"projectType": "application"
}
```
Then we need to modify the `build.gradle.kt` to include the Nx Gradle plugin. This is currently a bug in the import process, so this is temporary. Remember, this isn't technically fully supported, so there be dragons:
```diff {% fileName="build.gralde.kt" %}
plugins {
+ id("dev.nx.gradle.project-graph") version "0.1.0"
alias(libs.plugins.android.application)
alias(libs.plugins.kotlin.android)
alias(libs.plugins.kotlin.compose)
}
android {...}
dependencies {...}
+ allprojects {
+ apply {
+ plugin("dev.nx.gradle.project-graph")
+ }
+ }
```
Then one last thing is to cd into the project and run a Gradle build:
```shell
cd apps/android-frontend
./gradlew build
cd ../../
```
This just let's Gradle install the Nx plugin and sync all the dependencies.
## We Got Android, Now What?
Ok, that was a bit of work, but we're getting closer. From here we want to be able to deploy to an emulator from `nx`, so let's see what tasks we have available to use:
```shell
nx show project android-frontend
```
![](/blog/images/2025-07-30/android-tasks.png)
There are a lot of tasks in here, and most of them are not too relevant for us. How ever, I do know that there is a task we can run, and specifically an `installDebug` task.
![](/blog/images/2025-07-30/android-installdebug.png)
Behind the scenes, `installDebug` will build our app, and deploy it to any device or emulator we have running.
```shell
nx run android-frontend:installDebug
```
We do need to have an emulator open, so we can start one from Android Studio or if you have the Android SDK available from the command line, you can start it that way. With `installDebug` running, we should be able to see the app get installed to the emulator. We'll need to manually open it up, but it does install.
![](/blog/images/2025-07-30/nx-android.png)
## Whats Next
And that's it! It might seem not that impressive, but in the future, there could hypothetically be a dedicated Nx Android plugin that could handle starting your emulator and deploying your app. This could build on the Nx Gradle plugin and really help Android developers work more closely with their colleagues on the web team. We got one last blog post this week for our Java developers, so be sure to check back tomorrow and we'll get our app shipped 🚀.
---
Learn more:
- 🌌 [Nx Gradle Tutorial](/getting-started/tutorials/gradle-tutorial)
- 📖 [Nx Gradle API](/technologies/java/api)
- 👩‍💻 [Nx GitHub](https://github.com/nrwl/nx)
- 👩‍💻 [Nx Console GitHub](https://github.com/nrwl/nx-console)
- 💬 [Nx Official Discord Server](https://go.nx.dev/community)
- 📹 [Nx Youtube Channel](https://www.youtube.com/@nxdevtools)
@@ -0,0 +1,158 @@
---
title: 'Seamless Java Deployment in Nx Using Docker'
slug: seamless-deploys-with-docker
authors: ['Mike Hartington']
tags: ['nx', 'java', 'docker']
cover_image: /blog/images/2025-07-31/header.avif
description: 'Learn how to package, run, and deploy a Java backend from an Nx monorepo using the new Nx Docker plugin—automating builds, streamlining releases, and shipping production-ready containers.'
youtubeUrl: https://youtu.be/TOPxKJXUaqw
---
{% callout type="deepdive" title="Java Week Series" expanded=true %}
This article is part of the Java Week series:
- [The Journey of Nx Gradle](/blog/journey-of-nx-gradle)
- [Polyglot Projects Made Easy](/blog/spring-boot-with-nx)
- [Getting Mobile Into Your Monorepo](/blog/android-and-nx)
- **Seamless Deploys With Docker**
{% /callout %}
We've explored how you can add a Java app to an existing Nx workspace, but just getting the code in the same place doesn't really help _ship_ our code. With JavaScript apps, you simply need to have a static hosting provider or have a platform that can run node. But Java? Where do you even begin? Let's look at how we can get our Java backend deployed and automate it using Nx. We'll also get a sneak peek at a new plugin we've been working on.
## The Challenge: From Monorepo to Production
Running both the front-end and back-end within an Nx workspace is straightforward. But when it comes time to deploy your backend to a live URL, questions arise:
- How do we package and deploy a Java application from the monorepo?
- Do we need a hosting provider that supports Java by default?
- How do we ensure consistent environments across different platforms?
The solution: Docker.
Docker allows us to encapsulate our backend into an image, ensuring that it will run consistently across AWS, GCP, or any other provider. By combining Docker with `nx release`, we can:
- Automate the creation of Docker images for the backend.
- Ensure builds are consistent and reproducible.
- Push images directly to registries like Docker Hub for deployment.
The upcoming `@nx/docker` plugin takes this a step further, letting you define Docker workflows natively within Nx.
## Setting Up a Dockerfile for the Backend
To get started, we create a `Dockerfile` inside the Java backend directory of the Nx workspace. This file tells Docker how to build and run our application:
```
FROM openjdk:26-slim-bullseye
MAINTAINER baeldung.com
EXPOSE 3000
COPY build/libs/java-backend-0.0.1-SNAPSHOT.jar app.jar
ENTRYPOINT ["java","-jar","/app.jar"]
```
1. **Base Image:** Use `openjdk:26` as the starting point.
2. **Expose Ports:** Our backend runs on port `3000`, so we expose this port for the container.
3. **Copy the Build Artifact:** Copy the generated `.jar` file into the container as `app.jar`.
4. **Set the Entry Point:** Run the app with `java -jar app.jar`.
This simple setup ensures that the container will spin up our backend just like we would run it locally. Now, we can manually run Docker ourselves from the command line, but we have Nx here, and it can do that for us. Let's add the new Nx Docker plugin:
```bash
nx add @nx/docker
```
In my project, I need to setup some port forwarding, so that the port my Java app runs on, can be exposed when the Docker image is started.
```json
{
"name": "java-backend",
"root": "apps/java-backend",
"projectType": "application",
"targets": {
"docker:run": {
"options": {
"args": ["-p", "3000:3000"]
}
}
}
}
```
With this, `localhost:3000` will serve your API endpoints as if they were running directly on your machine.
Now with this new plugin, you can incorporate various Docker tasks in other parts of your Nx workflow, or as stand alone tasks. We can harness Nxs task orchestration to build out a task pipeline. We can set `docker:build` to `dependsOn: ["build"]` and the `@nx/docker` plugin will already infer that `docker:run` `dependsOn: ["docker:build"]` ensuring that the docker image is available locally to run.
```bash
nx docker:run java-backend
```
All this from a simple command!
## Integrating Docker with Nx Release
Now creating and running a docker image is fine, but we want to coordinate this as part of a release so everything we built can be shipped together. This is where `nx release` comes in. Let's add a new `release` configuration in our `nx.json`:
```json
{
"release": {
"projects": ["java-backend"],
"projectsRelationship": "independent",
"releaseTagPattern": "release/{projectName}/{version}",
"docker": {
"skipVersionActions": true
},
"changelog": {
"projectChangelogs": true
}
}
}
```
This is fairly standard release config, but the `docker` entry is new. The `skipVersionActions` tells Nx to not attempt to version any of the packages were releasing. Typically, this means bumping the version to the next major/minor/patch depending on your commits. Since this is just a demo, we don't really need worry about versioning any packages, just versioning the Docker image.
Then, we need to include some release configuration to tell `nx release` about where we want our `java-backend` released to. Let's open the `project.json` and add a new release setup:
```json
{
"name": "java-backend",
"root": "apps/java-backend",
"projectType": "application",
"targets": {...},
"release": {
"docker": {
"repositoryName": "nrwlmike/java-app"
}
}
}
```
The `repositoryName` is how `nx release` will know where it should upload the image to after it's ready. By default, this will publish to Docker Hub, but you can also set a `registryURL` to point it to your own private Docker registry if needed.
Now, it's time to ship it!
```bash
nx release --first-release
```
Nx will build, version, and publish your Docker image to Docker Hub.
## Deploying Anywhere
With the Docker image published, deployment becomes as simple as pointing any provider—AWS, GCP, or others—to your image. Your backend will spin up in a consistent, production-ready environment.
The Docker plugin is still experimental, but its integration into Nxs existing build and release workflows makes deploying backends seamless. It takes care of the tedious steps, allowing you to focus on building features rather than managing deployment scripts.
If you're interested in knowing more, let us know! Join our community Discord and be on the look out for the official release of the Docker plugin.
---
Learn more:
- 🌌 [Nx Gradle Tutorial](/getting-started/tutorials/gradle-tutorial)
- 📖 [Nx Gradle API](/technologies/java/api)
- 📦 [Nx Release](/features/manage-releases)
- 👩‍💻 [Nx GitHub](https://github.com/nrwl/nx)
- 👩‍💻 [Nx Console GitHub](https://github.com/nrwl/nx-console)
- 💬 [Nx Official Discord Server](https://go.nx.dev/community)
- 📹 [Nx Youtube Channel](https://www.youtube.com/@nxdevtools)
Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 333 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 761 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 556 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 52 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 440 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 606 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 643 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 433 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 897 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 480 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 716 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 415 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 707 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 503 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 327 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 704 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 972 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

+19
View File
@@ -0,0 +1,19 @@
# Nx 21.3
## Features
{% cards cols="2" %}
{% card title="Angular 20.1 Support" type="document" url="/technologies/angular/introduction" /%}
{% card title="Jest 30 Support" type="document" url="/technologies/test-tools/jest/introduction" /%}
{% card title="Enhanced TUI with Live Task Durations" type="external" url="https://github.com/nrwl/nx/pull/31897" /%}
{% card title="CI Workflow Enhancements" type="external" url="https://github.com/nrwl/nx/pull/31833" /%}
{% /cards %}
## Bug Fixes
{% cards cols="2" %}
{% card title="Improved TUI Terminal Output for Skipped Tasks" type="external" url="https://github.com/nrwl/nx/pull/31559" /%}
{% card title="Better Error Handling in Daemon Server" type="external" url="https://github.com/nrwl/nx/pull/31728" /%}
{% card title="Fix Angular NgRx Facade Spec Generation" type="external" url="https://github.com/nrwl/nx/pull/31850" /%}
{% card title="Improved Parent Gitignore Handling for Nested Workspaces" type="external" url="https://github.com/nrwl/nx/pull/31911" /%}
{% /cards %}
@@ -17,4 +17,4 @@ Well also take a quick detour to discuss `namedInputs` in `nx.json`, ensuring
## Relevant Links
- [Run Only Tasks Affected by a PR](/ci/features/affected)
- [Tutorial: Github Actions with Nx](/ci/intro/tutorials/github-actions#create-a-ci-workflow)
- [Guide: Github Actions with Nx](/ci/recipes/set-up/monorepo-ci-github-actions)
-90
View File
@@ -38,40 +38,6 @@
"isExternal": false,
"path": "/ci/intro/connect-to-nx-cloud",
"tags": []
},
{
"id": "tutorials",
"name": "Tutorials",
"description": "Tutorials setting up CI with Nx",
"mediaImage": "",
"file": "",
"itemList": [
{
"id": "circle",
"name": "Circle CI with Nx",
"description": "",
"mediaImage": "",
"file": "nx-cloud/tutorial/circle",
"itemList": [],
"isExternal": false,
"path": "/ci/intro/tutorials/circle",
"tags": []
},
{
"id": "github-actions",
"name": "GitHub Actions with Nx",
"description": "",
"mediaImage": "",
"file": "nx-cloud/tutorial/github-actions",
"itemList": [],
"isExternal": false,
"path": "/ci/intro/tutorials/github-actions",
"tags": []
}
],
"isExternal": false,
"path": "/ci/intro/tutorials",
"tags": []
}
],
"isExternal": false,
@@ -111,62 +77,6 @@
"path": "/ci/intro/connect-to-nx-cloud",
"tags": []
},
"/ci/intro/tutorials": {
"id": "tutorials",
"name": "Tutorials",
"description": "Tutorials setting up CI with Nx",
"mediaImage": "",
"file": "",
"itemList": [
{
"id": "circle",
"name": "Circle CI with Nx",
"description": "",
"mediaImage": "",
"file": "nx-cloud/tutorial/circle",
"itemList": [],
"isExternal": false,
"path": "/ci/intro/tutorials/circle",
"tags": []
},
{
"id": "github-actions",
"name": "GitHub Actions with Nx",
"description": "",
"mediaImage": "",
"file": "nx-cloud/tutorial/github-actions",
"itemList": [],
"isExternal": false,
"path": "/ci/intro/tutorials/github-actions",
"tags": []
}
],
"isExternal": false,
"path": "/ci/intro/tutorials",
"tags": []
},
"/ci/intro/tutorials/circle": {
"id": "circle",
"name": "Circle CI with Nx",
"description": "",
"mediaImage": "",
"file": "nx-cloud/tutorial/circle",
"itemList": [],
"isExternal": false,
"path": "/ci/intro/tutorials/circle",
"tags": []
},
"/ci/intro/tutorials/github-actions": {
"id": "github-actions",
"name": "GitHub Actions with Nx",
"description": "",
"mediaImage": "",
"file": "nx-cloud/tutorial/github-actions",
"itemList": [],
"isExternal": false,
"path": "/ci/intro/tutorials/github-actions",
"tags": []
},
"/ci/features": {
"id": "features",
"name": "Features",
+19 -36
View File
@@ -462,9 +462,25 @@
"isExternal": false,
"children": [
{
"name": "Get Started with Nx Release",
"path": "/recipes/nx-release/get-started-with-nx-release",
"id": "get-started-with-nx-release",
"name": "Release TypeScript/JavaScript Packages to NPM",
"path": "/recipes/nx-release/release-npm-packages",
"id": "release-npm-packages",
"isExternal": false,
"children": [],
"disableCollapsible": false
},
{
"name": "Release Docker Images",
"path": "/recipes/nx-release/release-docker-images",
"id": "release-docker-images",
"isExternal": false,
"children": [],
"disableCollapsible": false
},
{
"name": "Release Rust Crates",
"path": "/recipes/nx-release/publish-rust-crates",
"id": "publish-rust-crates",
"isExternal": false,
"children": [],
"disableCollapsible": false
@@ -541,14 +557,6 @@
"children": [],
"disableCollapsible": false
},
{
"name": "Publish Rust Crates",
"path": "/recipes/nx-release/publish-rust-crates",
"id": "publish-rust-crates",
"isExternal": false,
"children": [],
"disableCollapsible": false
},
{
"name": "Update Your Local Registry Setup to use Nx Release",
"path": "/recipes/nx-release/update-local-registry-setup",
@@ -6802,31 +6810,6 @@
"isExternal": false,
"children": [],
"disableCollapsible": false
},
{
"name": "Tutorials",
"path": "/ci/intro/tutorials",
"id": "tutorials",
"isExternal": false,
"children": [
{
"name": "Circle CI with Nx",
"path": "/ci/intro/tutorials/circle",
"id": "circle",
"isExternal": false,
"children": [],
"disableCollapsible": false
},
{
"name": "GitHub Actions with Nx",
"path": "/ci/intro/tutorials/github-actions",
"id": "github-actions",
"isExternal": false,
"children": [],
"disableCollapsible": false
}
],
"disableCollapsible": false
}
],
"disableCollapsible": false
+30
View File
@@ -399,6 +399,16 @@
}
},
"migrations": {
"/technologies/angular/api/migrations/21.3.5-jest-package-updates": {
"description": "",
"file": "generated/packages/angular/migrations/21.3.5-jest-package-updates.json",
"hidden": false,
"name": "21.3.5-jest-package-updates",
"version": "21.3.5-beta.0",
"originalFilePath": "/packages/angular",
"path": "/technologies/angular/api/migrations/21.3.5-jest-package-updates",
"type": "migration"
},
"/technologies/angular/api/migrations/update-angular-cli-version-20-1-0": {
"description": "Update the @angular/cli package version to ~20.1.0.",
"file": "generated/packages/angular/migrations/update-angular-cli-version-20-1-0.json",
@@ -2218,6 +2228,26 @@
}
},
"migrations": {
"/technologies/test-tools/jest/api/migrations/21.3.3-jest-util-package-updates": {
"description": "",
"file": "generated/packages/jest/migrations/21.3.3-jest-util-package-updates.json",
"hidden": false,
"name": "21.3.3-jest-util-package-updates",
"version": "21.3.3-beta.3",
"originalFilePath": "/packages/jest",
"path": "/technologies/test-tools/jest/api/migrations/21.3.3-jest-util-package-updates",
"type": "migration"
},
"/technologies/test-tools/jest/api/migrations/21.3.3-package-updates": {
"description": "",
"file": "generated/packages/jest/migrations/21.3.3-package-updates.json",
"hidden": false,
"name": "21.3.3-package-updates",
"version": "21.3.3-beta.0",
"originalFilePath": "/packages/jest",
"path": "/technologies/test-tools/jest/api/migrations/21.3.3-package-updates",
"type": "migration"
},
"/technologies/test-tools/jest/api/migrations/rename-test-path-pattern": {
"description": "Rename the CLI option `testPathPattern` to `testPathPatterns`.",
"file": "generated/packages/jest/migrations/rename-test-path-pattern.json",
+79 -46
View File
@@ -1057,14 +1057,36 @@
"file": "",
"itemList": [
{
"id": "get-started-with-nx-release",
"name": "Get Started with Nx Release",
"id": "release-npm-packages",
"name": "Release TypeScript/JavaScript Packages to NPM",
"description": "",
"mediaImage": "",
"file": "shared/recipes/nx-release/get-started-with-nx-release",
"file": "shared/recipes/nx-release/release-typescript-packages-to-npm",
"itemList": [],
"isExternal": false,
"path": "/recipes/nx-release/get-started-with-nx-release",
"path": "/recipes/nx-release/release-npm-packages",
"tags": ["nx-release"]
},
{
"id": "release-docker-images",
"name": "Release Docker Images",
"description": "",
"mediaImage": "",
"file": "shared/recipes/nx-release/release-docker-images",
"itemList": [],
"isExternal": false,
"path": "/recipes/nx-release/release-docker-images",
"tags": ["nx-release"]
},
{
"id": "publish-rust-crates",
"name": "Release Rust Crates",
"description": "",
"mediaImage": "",
"file": "shared/recipes/nx-release/publish-rust-crates",
"itemList": [],
"isExternal": false,
"path": "/recipes/nx-release/publish-rust-crates",
"tags": ["nx-release"]
},
{
@@ -1166,17 +1188,6 @@
"path": "/recipes/nx-release/automate-gitlab-releases",
"tags": ["nx-release"]
},
{
"id": "publish-rust-crates",
"name": "Publish Rust Crates",
"description": "",
"mediaImage": "",
"file": "shared/recipes/nx-release/publish-rust-crates",
"itemList": [],
"isExternal": false,
"path": "/recipes/nx-release/publish-rust-crates",
"tags": ["nx-release"]
},
{
"id": "update-local-registry-setup",
"name": "Update Your Local Registry Setup to use Nx Release",
@@ -2026,14 +2037,36 @@
"file": "",
"itemList": [
{
"id": "get-started-with-nx-release",
"name": "Get Started with Nx Release",
"id": "release-npm-packages",
"name": "Release TypeScript/JavaScript Packages to NPM",
"description": "",
"mediaImage": "",
"file": "shared/recipes/nx-release/get-started-with-nx-release",
"file": "shared/recipes/nx-release/release-typescript-packages-to-npm",
"itemList": [],
"isExternal": false,
"path": "/recipes/nx-release/get-started-with-nx-release",
"path": "/recipes/nx-release/release-npm-packages",
"tags": ["nx-release"]
},
{
"id": "release-docker-images",
"name": "Release Docker Images",
"description": "",
"mediaImage": "",
"file": "shared/recipes/nx-release/release-docker-images",
"itemList": [],
"isExternal": false,
"path": "/recipes/nx-release/release-docker-images",
"tags": ["nx-release"]
},
{
"id": "publish-rust-crates",
"name": "Release Rust Crates",
"description": "",
"mediaImage": "",
"file": "shared/recipes/nx-release/publish-rust-crates",
"itemList": [],
"isExternal": false,
"path": "/recipes/nx-release/publish-rust-crates",
"tags": ["nx-release"]
},
{
@@ -2135,17 +2168,6 @@
"path": "/recipes/nx-release/automate-gitlab-releases",
"tags": ["nx-release"]
},
{
"id": "publish-rust-crates",
"name": "Publish Rust Crates",
"description": "",
"mediaImage": "",
"file": "shared/recipes/nx-release/publish-rust-crates",
"itemList": [],
"isExternal": false,
"path": "/recipes/nx-release/publish-rust-crates",
"tags": ["nx-release"]
},
{
"id": "update-local-registry-setup",
"name": "Update Your Local Registry Setup to use Nx Release",
@@ -2195,15 +2217,37 @@
"path": "/recipes/nx-release",
"tags": []
},
"/recipes/nx-release/get-started-with-nx-release": {
"id": "get-started-with-nx-release",
"name": "Get Started with Nx Release",
"/recipes/nx-release/release-npm-packages": {
"id": "release-npm-packages",
"name": "Release TypeScript/JavaScript Packages to NPM",
"description": "",
"mediaImage": "",
"file": "shared/recipes/nx-release/get-started-with-nx-release",
"file": "shared/recipes/nx-release/release-typescript-packages-to-npm",
"itemList": [],
"isExternal": false,
"path": "/recipes/nx-release/get-started-with-nx-release",
"path": "/recipes/nx-release/release-npm-packages",
"tags": ["nx-release"]
},
"/recipes/nx-release/release-docker-images": {
"id": "release-docker-images",
"name": "Release Docker Images",
"description": "",
"mediaImage": "",
"file": "shared/recipes/nx-release/release-docker-images",
"itemList": [],
"isExternal": false,
"path": "/recipes/nx-release/release-docker-images",
"tags": ["nx-release"]
},
"/recipes/nx-release/publish-rust-crates": {
"id": "publish-rust-crates",
"name": "Release Rust Crates",
"description": "",
"mediaImage": "",
"file": "shared/recipes/nx-release/publish-rust-crates",
"itemList": [],
"isExternal": false,
"path": "/recipes/nx-release/publish-rust-crates",
"tags": ["nx-release"]
},
"/recipes/nx-release/release-projects-independently": {
@@ -2305,17 +2349,6 @@
"path": "/recipes/nx-release/automate-gitlab-releases",
"tags": ["nx-release"]
},
"/recipes/nx-release/publish-rust-crates": {
"id": "publish-rust-crates",
"name": "Publish Rust Crates",
"description": "",
"mediaImage": "",
"file": "shared/recipes/nx-release/publish-rust-crates",
"itemList": [],
"isExternal": false,
"path": "/recipes/nx-release/publish-rust-crates",
"tags": ["nx-release"]
},
"/recipes/nx-release/update-local-registry-setup": {
"id": "update-local-registry-setup",
"name": "Update Your Local Registry Setup to use Nx Release",
+18 -11
View File
@@ -672,10 +672,24 @@
},
{
"description": "",
"file": "shared/recipes/nx-release/get-started-with-nx-release",
"id": "get-started-with-nx-release",
"name": "Get Started with Nx Release",
"path": "/recipes/nx-release/get-started-with-nx-release"
"file": "shared/recipes/nx-release/release-typescript-packages-to-npm",
"id": "release-npm-packages",
"name": "Release TypeScript/JavaScript Packages to NPM",
"path": "/recipes/nx-release/release-npm-packages"
},
{
"description": "",
"file": "shared/recipes/nx-release/release-docker-images",
"id": "release-docker-images",
"name": "Release Docker Images",
"path": "/recipes/nx-release/release-docker-images"
},
{
"description": "",
"file": "shared/recipes/nx-release/publish-rust-crates",
"id": "publish-rust-crates",
"name": "Release Rust Crates",
"path": "/recipes/nx-release/publish-rust-crates"
},
{
"description": "",
@@ -740,13 +754,6 @@
"name": "Automate GitLab Releases",
"path": "/recipes/nx-release/automate-gitlab-releases"
},
{
"description": "",
"file": "shared/recipes/nx-release/publish-rust-crates",
"id": "publish-rust-crates",
"name": "Publish Rust Crates",
"path": "/recipes/nx-release/publish-rust-crates"
},
{
"description": "",
"file": "shared/recipes/nx-release/update-local-registry-setup",
+30
View File
@@ -439,6 +439,16 @@
}
],
"migrations": [
{
"description": "",
"file": "generated/packages/angular/migrations/21.3.5-jest-package-updates.json",
"hidden": false,
"name": "21.3.5-jest-package-updates",
"version": "21.3.5-beta.0",
"originalFilePath": "/packages/angular",
"path": "angular/migrations/21.3.5-jest-package-updates",
"type": "migration"
},
{
"description": "Update the @angular/cli package version to ~20.1.0.",
"file": "generated/packages/angular/migrations/update-angular-cli-version-20-1-0.json",
@@ -2402,6 +2412,26 @@
}
],
"migrations": [
{
"description": "",
"file": "generated/packages/jest/migrations/21.3.3-jest-util-package-updates.json",
"hidden": false,
"name": "21.3.3-jest-util-package-updates",
"version": "21.3.3-beta.3",
"originalFilePath": "/packages/jest",
"path": "jest/migrations/21.3.3-jest-util-package-updates",
"type": "migration"
},
{
"description": "",
"file": "generated/packages/jest/migrations/21.3.3-package-updates.json",
"hidden": false,
"name": "21.3.3-package-updates",
"version": "21.3.3-beta.0",
"originalFilePath": "/packages/jest",
"path": "jest/migrations/21.3.3-package-updates",
"type": "migration"
},
{
"description": "Rename the CLI option `testPathPattern` to `testPathPatterns`.",
"file": "generated/packages/jest/migrations/rename-test-path-pattern.json",
@@ -18,7 +18,7 @@
"name": {
"description": "The name of the application.",
"type": "string",
"pattern": "^[a-zA-Z][^:]*$",
"pattern": "(?:^@[a-zA-Z0-9-*~][a-zA-Z0-9-*._~]*\\/[a-zA-Z0-9-~][a-zA-Z0-9-._~]*|^[a-zA-Z][^:]*)$",
"x-priority": "important"
},
"style": {
@@ -0,0 +1,23 @@
{
"name": "21.3.5-jest-package-updates",
"version": "21.3.5-beta.0",
"requires": {
"@angular/compiler-cli": ">=18.0.0 <21.0.0",
"@angular/core": ">=18.0.0 <21.0.0",
"@angular/platform-browser-dynamic": ">=18.0.0 <21.0.0",
"jest": "^30.0.0"
},
"packages": {
"jest-preset-angular": {
"version": "~15.0.0",
"alwaysAddToPackageJson": false
}
},
"aliases": [],
"description": "",
"hidden": false,
"implementation": "",
"path": "/packages/angular",
"schema": null,
"type": "migration"
}
@@ -27,7 +27,7 @@
"name": {
"description": "The name of the application.",
"type": "string",
"pattern": "^[a-zA-Z][^:]*$",
"pattern": "(?:^@[a-zA-Z0-9-*~][a-zA-Z0-9-*._~]*\\/[a-zA-Z0-9-~][a-zA-Z0-9-._~]*|^[a-zA-Z][^:]*)$",
"x-priority": "important"
},
"displayName": {
@@ -17,7 +17,7 @@
},
"name": {
"description": "The name of the application.",
"pattern": "^[a-zA-Z][^:]*$",
"pattern": "(?:^@[a-zA-Z0-9-*~][a-zA-Z0-9-*._~]*\\/[a-zA-Z0-9-~][a-zA-Z0-9-._~]*|^[a-zA-Z][^:]*)$",
"type": "string"
},
"skipFormat": {
@@ -152,7 +152,8 @@ The `@nx/gradle` is configured in the `plugins` array in `nx.json`.
"testTargetName": "test",
"classesTargetName": "classes",
"buildTargetName": "build",
"ciTestTargetName": "test-ci"
"ciTestTargetName": "test-ci",
"ciIntTestTargetName": "intTest-ci"
}
}
]
@@ -161,23 +162,101 @@ The `@nx/gradle` is configured in the `plugins` array in `nx.json`.
Once a Gradle configuration file has been identified, the targets are created with the name you specify under `testTargetName`, `classesTargetName` or `buildTargetName` in the `nx.json` `plugins` array. The default names for the inferred targets are `test`, `classes` and `build`.
### Splitting Tests
### Test Distribution
The `@nx/gradle` plugin will automatically split your testing tasks by test class if you provide a `ciTestTargetName`. You can read more about the Atomizer feature [here](/ci/features/split-e2e-tasks). Nx will create a task with the name that you specify which can be used in CI to run the tests for each test class in a distributed fashion.
Nx provides powerful features for distributing tasks in CI, including test splitting (also known as atomization) and optimized build targets. For Gradle projects, this is facilitated by the `@nx/gradle` plugin, allowing you to run your tests and builds more efficiently in your Continuous Integration (CI) environment.
```json {% fileName="nx.json" highlightLines=[6] %}
#### How to Set Up Test Distribution (Atomizer) in CI
To enable test distribution for your Gradle projects in CI, follow these steps:
1. **Generate CI Workflow**: Run the `ci-workflow` generator to set up the necessary CI configurations. This generator creates a GitHub Actions workflow file that integrates with Nx's distributed task execution capabilities.
```shell
nx g @nx/gradle:ci-workflow
```
This command will generate a workflow file (e.g., `.github/workflows/ci.yml`) tailored for your Nx workspace with Gradle projects.
2. **Configure `nx.json` for Atomizer**: Add or ensure the presence of `ciTestTargetName` or `ciIntTestTargetName` in the `@nx/gradle` plugin options within your `nx.json`.
```json {% fileName="nx.json" highlightLines=[6,7] %}
{
"plugins": [
{
"plugin": "@nx/gradle",
"options": {
"ciTestTargetName": "test-ci",
"ciIntTestTargetName": "intTest-ci"
}
}
]
}
```
Setting these options turns on the atomizer feature in CI. Nx will automatically split your testing tasks (unit and integration tests, respectively) by test class, allowing them to be run in a distributed fashion across your CI agents.
3. **Update CI Workflow Command**: In your generated CI workflow file, modify the command used to run affected tasks. Instead of using a generic `build` target, leverage the `build-ci` target provided by the `@nx/gradle` plugin:
```shell
# Before:
# ./nx affected --base=$NX_BASE --head=$NX_HEAD -t build
# After:
./nx affected --base=$NX_BASE --head=$NX_HEAD -t build-ci
```
This ensures that your CI pipeline utilizes the optimized `build-ci` target, which is designed to integrate seamlessly with Nx's test distribution and caching mechanisms.
#### The `ci-workflow` Generator
The `@nx/gradle:ci-workflow` generator is a utility that automates the setup of a CI workflow for your Nx workspace containing Gradle projects. It creates a `.github/workflows` file (or equivalent for other CI providers) that includes steps for checking out code, setting up Java and Gradle, restoring caches, and running affected Nx tasks. Its primary purpose is to streamline the integration of Nx's CI features, such as distributed task execution and caching, into your existing CI pipeline.
#### The `build-ci` Target
The `@nx/gradle` plugin can create a `build-ci` target that is specifically designed for use in CI environments. This target allows for a more optimized and consistent build process by ensuring that the `check` task is rewired to its CI counterpart (`check-ci`), which also implies that test tasks (`test` and `intTest`) are rewired to their atomized `test-ci` and `intTest-ci` counterparts respectively.
##### What is it?
The `build-ci` target is a synthetic Nx target that acts as a placeholder for your Gradle `build` task in a CI context. Instead of directly running the `build` task, the `build-ci` target ensures that the `check` task (a dependency of `build`) first executes its CI-optimized version (`check-ci`), which in turn uses the split/atomized test tasks (`test-ci`, `intTest-ci`). This allows for distributed execution of tests and efficient caching in CI.
##### How to Enable?
To enable the `build-ci` target, you need to configure `ciTestTargetName` or `ciIntTestTargetName` in the `@nx/gradle` plugin options in your `nx.json`.
For example:
```json {% fileName="nx.json" %}
{
"plugins": [
{
"plugin": "@nx/gradle",
"options": {
"ciTestTargetName": "test-ci"
"ciTestTargetName": "test-ci",
"ciBuildTargetName": "build-ci"
}
}
]
}
```
When `ciTestTargetName` (or `ciIntTestTargetName`) is set, the `build-ci` target is automatically created if the `build` task exists for a given Gradle project.
##### Expected Behavior
When you run `nx build-ci <your-gradle-project>`, Nx will:
1. Execute the `check-ci` task (if defined) instead of the standard `check` task.
2. The `check-ci` task will, in turn, trigger the atomized test tasks (`test-ci` and `intTest-ci`) if they are configured.
3. The `build-ci` target itself will use the `nx:noop` executor, meaning it doesn't execute a direct Gradle command, but rather relies on its dependencies (`check-ci`) to orchestrate the build process in a CI-friendly manner.
4. The `build-ci` target is cacheable.
This setup ensures that your build process in CI leverages Nx's caching and distribution capabilities effectively.
##### How to Turn it Off?
To disable the `build-ci` target, simply remove the `ciBuildTargetName` option from the `@nx/gradle` plugin configuration in your `nx.json` file. If `ciTestTargetName` and `ciIntTestTargetName` are also removed, then the special CI targets for tests and check will also be turned off.
### Continuous Tasks
Gradle doesn't have a standard way to identify tasks which are [continuous](/reference/project-configuration#continuous), like `bootRun` for serving a Spring Boot project. To ensure Nx handles these continuous tasks correctly, you can explicitly mark them as continuous.
@@ -0,0 +1,15 @@
{
"name": "21.3.3-jest-util-package-updates",
"version": "21.3.3-beta.3",
"requires": { "jest": ">=30.0.0 <31.0.0", "ts-jest": ">=29.4.0" },
"packages": {
"jest-util": { "version": "~30.0.0", "addToPackageJson": "devDependencies" }
},
"aliases": [],
"description": "",
"hidden": false,
"implementation": "",
"path": "/packages/jest",
"schema": null,
"type": "migration"
}
@@ -0,0 +1,14 @@
{
"name": "21.3.3-package-updates",
"version": "21.3.3-beta.0",
"packages": {
"ts-jest": { "version": "~29.4.0", "alwaysAddToPackageJson": false }
},
"aliases": [],
"description": "",
"hidden": false,
"implementation": "",
"path": "/packages/jest",
"schema": null,
"type": "migration"
}
@@ -18,7 +18,7 @@
"name": {
"description": "The name of the application.",
"type": "string",
"pattern": "^[a-zA-Z][^:]*$",
"pattern": "(?:^@[a-zA-Z0-9-*~][a-zA-Z0-9-*._~]*\\/[a-zA-Z0-9-~][a-zA-Z0-9-._~]*|^[a-zA-Z][^:]*)$",
"x-priority": "important"
},
"skipFormat": {
@@ -19,7 +19,7 @@
"name": {
"description": "The name of the application.",
"type": "string",
"pattern": "^[a-zA-Z][^:]*$",
"pattern": "(?:^@[a-zA-Z0-9-*~][a-zA-Z0-9-*._~]*\\/[a-zA-Z0-9-~][a-zA-Z0-9-._~]*|^[a-zA-Z][^:]*)$",
"x-priority": "important"
},
"style": {
@@ -18,7 +18,7 @@
"name": {
"description": "The name of the application.",
"type": "string",
"pattern": "^[a-zA-Z][^:]*$",
"pattern": "(?:^@[a-zA-Z0-9-*~][a-zA-Z0-9-*._~]*\\/[a-zA-Z0-9-~][a-zA-Z0-9-._~]*|^[a-zA-Z][^:]*)$",
"x-priority": "important"
},
"skipFormat": {
@@ -19,7 +19,7 @@
"name": {
"description": "The name of the application.",
"type": "string",
"pattern": "^[a-zA-Z][^:]*$",
"pattern": "(?:^@[a-zA-Z0-9-*~][a-zA-Z0-9-*._~]*\\/[a-zA-Z0-9-~][a-zA-Z0-9-._~]*|^[a-zA-Z][^:]*)$",
"x-priority": "important"
},
"skipFormat": {
@@ -27,7 +27,7 @@
},
"name": {
"description": "The name of the application.",
"pattern": "^[a-zA-Z][^:]*$",
"pattern": "(?:^@[a-zA-Z0-9-*~][a-zA-Z0-9-*._~]*\\/[a-zA-Z0-9-~][a-zA-Z0-9-._~]*|^[a-zA-Z][^:]*)$",
"type": "string"
},
"displayName": {
@@ -37,7 +37,7 @@
"name": {
"description": "The name of the application.",
"type": "string",
"pattern": "^[a-zA-Z][^:]*$",
"pattern": "(?:^@[a-zA-Z0-9-*~][a-zA-Z0-9-*._~]*\\/[a-zA-Z0-9-~][a-zA-Z0-9-._~]*|^[a-zA-Z][^:]*)$",
"x-priority": "important"
},
"style": {
@@ -245,7 +245,7 @@
"type": "string",
"description": "The file to include.",
"x-completion-type": "file",
"x-completion-glob": "**/*@(.css|.scss|.less|.sass|.styl|.stylus)"
"x-completion-glob": "**/*@(.css|.scss|.less|.sass)"
},
"bundleName": {
"type": "string",
@@ -264,7 +264,7 @@
"type": "string",
"description": "The file to include.",
"x-completion-type": "file",
"x-completion-glob": "**/*@(.css|.scss|.less|.sass|.styl|.stylus)"
"x-completion-glob": "**/*@(.css|.scss|.less|.sass)"
}
]
}
@@ -316,7 +316,7 @@
"type": "string",
"description": "The file to include.",
"x-completion-type": "file",
"x-completion-glob": "**/*@(.css|.scss|.less|.sass|.styl|.stylus)"
"x-completion-glob": "**/*@(.css|.scss|.less|.sass)"
},
"bundleName": {
"type": "string",
@@ -335,7 +335,7 @@
"type": "string",
"description": "The file to include.",
"x-completion-type": "file",
"x-completion-glob": "**/*@(.css|.scss|.less|.sass|.styl|.stylus)"
"x-completion-glob": "**/*@(.css|.scss|.less|.sass)"
}
]
}
@@ -409,7 +409,7 @@
"type": "string",
"description": "The file to include.",
"x-completion-type": "file",
"x-completion-glob": "**/*@(.css|.scss|.less|.sass|.styl|.stylus)"
"x-completion-glob": "**/*@(.css|.scss|.less|.sass)"
},
"bundleName": {
"type": "string",
@@ -428,7 +428,7 @@
"type": "string",
"description": "The file to include.",
"x-completion-type": "file",
"x-completion-glob": "**/*@(.css|.scss|.less|.sass|.styl|.stylus)"
"x-completion-glob": "**/*@(.css|.scss|.less|.sass)"
}
]
},
@@ -24,7 +24,7 @@
"name": {
"description": "The name of the application.",
"type": "string",
"pattern": "^[a-zA-Z].*$"
"pattern": "(?:^@[a-zA-Z0-9-*~][a-zA-Z0-9-*._~]*\\/[a-zA-Z0-9-~][a-zA-Z0-9-._~]*|^[a-zA-Z][^:]*)$"
},
"framework": {
"type": "string",
@@ -49,10 +49,6 @@
"value": "scss",
"label": "SASS(.scss) [ http://sass-lang.com ]"
},
{
"value": "styl",
"label": "Stylus(.styl) [ http://stylus-lang.com ]"
},
{
"value": "less",
"label": "LESS [ http://lesscss.org ]"
@@ -17,7 +17,7 @@
"style": {
"type": "string",
"description": "The style solution to use.",
"enum": ["none", "css", "scss", "less", "styl"]
"enum": ["none", "css", "scss", "less"]
},
"rootProject": { "type": "boolean", "x-priority": "internal" },
"keepExistingVersions": {
@@ -24,7 +24,6 @@
},
"less": { "type": "boolean", "description": "Use less for styling." },
"sass": { "type": "boolean", "description": "Use sass for styling." },
"stylus": { "type": "boolean", "description": "Use stylus for styling." },
"unitTestRunner": {
"type": "string",
"description": "The unit test runner to use.",
@@ -29,7 +29,7 @@
"name": {
"description": "The name of the application.",
"type": "string",
"pattern": "^[a-zA-Z][^:]*$",
"pattern": "(?:^@[a-zA-Z0-9-*~][a-zA-Z0-9-*._~]*\\/[a-zA-Z0-9-~][a-zA-Z0-9-._~]*|^[a-zA-Z][^:]*)$",
"x-priority": "important"
},
"style": {
@@ -18,7 +18,7 @@
"name": {
"description": "The name of the application.",
"type": "string",
"pattern": "^[a-zA-Z][^:]*$",
"pattern": "(?:^@[a-zA-Z0-9-*~][a-zA-Z0-9-*._~]*\\/[a-zA-Z0-9-~][a-zA-Z0-9-._~]*|^[a-zA-Z][^:]*)$",
"x-priority": "important"
},
"style": {
@@ -141,7 +141,7 @@
"type": "string",
"description": "The file to include.",
"x-completion-type": "file",
"x-completion-glob": "**/*@(.css|.scss|.less|.sass|.styl|.stylus)"
"x-completion-glob": "**/*@(.css|.scss|.less|.sass)"
},
"bundleName": {
"type": "string",
@@ -160,7 +160,7 @@
"type": "string",
"description": "The file to include.",
"x-completion-type": "file",
"x-completion-glob": "**/*@(.css|.scss|.less|.sass|.styl|.stylus)"
"x-completion-glob": "**/*@(.css|.scss|.less|.sass)"
}
]
}
@@ -177,7 +177,7 @@
"type": "string",
"description": "The file to include.",
"x-completion-type": "file",
"x-completion-glob": "**/*@(.css|.scss|.less|.sass|.styl|.stylus)"
"x-completion-glob": "**/*@(.css|.scss|.less|.sass)"
},
"bundleName": {
"type": "string",
@@ -196,7 +196,7 @@
"type": "string",
"description": "The file to include.",
"x-completion-type": "file",
"x-completion-glob": "**/*@(.css|.scss|.less|.sass|.styl|.stylus)"
"x-completion-glob": "**/*@(.css|.scss|.less|.sass)"
}
]
}
@@ -442,7 +442,7 @@
"type": "string",
"description": "The file to include.",
"x-completion-type": "file",
"x-completion-glob": "**/*@(.css|.scss|.less|.sass|.styl|.stylus)"
"x-completion-glob": "**/*@(.css|.scss|.less|.sass)"
},
"bundleName": {
"type": "string",
@@ -461,7 +461,7 @@
"type": "string",
"description": "The file to include.",
"x-completion-type": "file",
"x-completion-glob": "**/*@(.css|.scss|.less|.sass|.styl|.stylus)"
"x-completion-glob": "**/*@(.css|.scss|.less|.sass)"
}
]
},
+15 -26
View File
@@ -363,10 +363,22 @@
"description": "Recipes for releasing with Nx release.",
"itemList": [
{
"name": "Get Started with Nx Release",
"id": "get-started-with-nx-release",
"name": "Release TypeScript/JavaScript Packages to NPM",
"id": "release-npm-packages",
"tags": ["nx-release"],
"file": "shared/recipes/nx-release/get-started-with-nx-release"
"file": "shared/recipes/nx-release/release-typescript-packages-to-npm"
},
{
"name": "Release Docker Images",
"id": "release-docker-images",
"tags": ["nx-release"],
"file": "shared/recipes/nx-release/release-docker-images"
},
{
"name": "Release Rust Crates",
"id": "publish-rust-crates",
"tags": ["nx-release"],
"file": "shared/recipes/nx-release/publish-rust-crates"
},
{
"name": "Release Projects Independently",
@@ -422,12 +434,6 @@
"tags": ["nx-release"],
"file": "shared/recipes/nx-release/automate-gitlab-releases"
},
{
"name": "Publish Rust Crates",
"id": "publish-rust-crates",
"tags": ["nx-release"],
"file": "shared/recipes/nx-release/publish-rust-crates"
},
{
"name": "Update Your Local Registry Setup to use Nx Release",
"id": "update-local-registry-setup",
@@ -2525,23 +2531,6 @@
"name": "Connect to Nx Cloud",
"id": "connect-to-nx-cloud",
"file": "nx-cloud/intro/connect-to-cloud"
},
{
"name": "Tutorials",
"id": "tutorials",
"description": "Tutorials setting up CI with Nx",
"itemList": [
{
"name": "Circle CI with Nx",
"id": "circle",
"file": "nx-cloud/tutorial/circle"
},
{
"name": "GitHub Actions with Nx",
"id": "github-actions",
"file": "nx-cloud/tutorial/github-actions"
}
]
}
]
},
+1 -1
View File
@@ -11,7 +11,7 @@ Flaky Task Detection is enabled by default if your workspace is connected to Nx
To connect your workspace to Nx Cloud run:
```shell
npx nx connect
npx nx@latest connect
```
See the [connect to Nx Cloud recipe](/ci/intro/connect-to-nx-cloud) for all the details.
+1 -1
View File
@@ -23,7 +23,7 @@ Manually splitting large e2e test projects can be complex and require ongoing ma
To use **automated e2e task splitting**, you need to connect your workspace to Nx Cloud (if you haven't already).
```shell
npx nx connect
npx nx@latest connect
```
See the [connect to Nx Cloud recipe](/ci/intro/connect-to-nx-cloud) for all the details.
+3 -3
View File
@@ -19,7 +19,7 @@ Your CI pipeline with Nx can:
[Create an account on Nx Cloud](https://cloud.nx.app) and connect your repository.
```shell
npx nx connect
npx nx@latest connect
```
## Learn about Nx on CI
@@ -30,9 +30,9 @@ npx nx connect
{% link-card title="E2E Test Auto-Splitting and Distribution" type="video" url="https://youtu.be/0YxcxIR7QU0" icon="nxagents" /%}
{% link-card title="Circle CI with Nx" type="tutorial" url="/ci/intro/tutorials/circle" icon="circleci" /%}
{% link-card title="Circle CI with Nx" type="tutorial" url="/ci/recipes/set-up/monorepo-ci-circle-ci" icon="circleci" /%}
{% link-card title="GitHub Actions with Nx" type="tutorial" url="/ci/intro/tutorials/github-actions" icon="github" /%}
{% link-card title="GitHub Actions with Nx" type="tutorial" url="/ci/recipes/set-up/monorepo-ci-github-actions" icon="github" /%}
{% /cards %}
+1 -1
View File
@@ -11,7 +11,7 @@ Here's how you get set up.
To connect your workspace, **push it to GitHub** (or your respective source control provider) and then run:
```shell
npx nx connect
npx nx@latest connect
```
## Step 2: Configure your CI script
+61
View File
@@ -1,5 +1,66 @@
# Enterprise Release Notes
### 2025.07.1
- Fix: auth redirect loop when using admin login
- Fix: improvement to the flaky task retry mechanism
### 2025.07
##### Breaking Change
This upgrade includes a breaking change to the `nx-cloud` cluster: instead of a message queue, the `nx-api` pod needs a valid Valkey (Redis) connection string.
1. Install Valkey:
1. You can either use the Bitnami chart: https://github.com/bitnami/charts/tree/main/bitnami/valkey
2. Or for a simpler deployment, you can use the Valkey docker image directly: https://hub.docker.com/r/valkey/valkey/
3. Or you can install it as a system service: https://valkey.io/topics/installation/
2. Upgrade to the latest Helm chart `0.16.3`
3. Apply the following values
```yaml
enableMessageQueue: false
nxApi:
# add these env vars to the nx-api
deployment:
env:
- name: VALKEY_CLIENT_PROVIDER
value: 'redisson'
- name: VALKEY_PASSWORD
valueFrom:
# remember to apply this secret to your cluster
secretKeyRef:
name: valkey-secrets
key: VALKEY_PASSWORD
- name: VALKEY_PORT
value: '6379'
- name: VALKEY_PRIMARY_ADDRESS
value: 'valkey'
- name: VALKEY_USE_SENTINEL
value: 'false'
- name: VALKEY_USERNAME
value: 'default'
- name: NX_CLOUD_CONFORMANCE_RULES_BUCKET
value:
local-cluster-file-server # use this exact value if you are using the file server, otherwise point it to an S3/Azure/Google bucket
# it will use the same role-based auth mechanism you already configured for the NxCloud cache
# you can also use the same bucket name that you use for the cache (rules will just be stored in a sub-folder)
```
##### Updates
- Feat: [Polygraph availability](/ci/recipes/enterprise/polygraph) (Conformance, Workspace Graph, Custom Workflows)
- Feat: Nx 21 [continuous tasks](/blog/nx-21-continuous-tasks) support
- Feat: Download artifacts button
- When you view a task that just ran in CI on the NxCloud UI, there is now a button to download any artifacts that task produced directly from your browser
- This is especially useful if you want to view screenshots/videos of failed e2e tests
- Feat: [Self-healing CI](/ci/features/self-healing-ci)
- Speak to your assigned DPE about testing this
- You will need an Anthropic API key and access to Claude's servers
- Feat: Dark Mode UI setting
- Various fixes and stability improvements to DTE, agent visualization, and other areas of the app
### 2025.06.3
- Fix: add timeouts to GitLab requests
Binary file not shown.

Before

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 136 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 97 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 70 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 240 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 84 KiB

-300
View File
@@ -1,300 +0,0 @@
---
title: 'Circle CI Tutorial with Nx'
description: In this tutorial you'll set up continuous integration with Circle CI and Nx
---
# Circle CI with Nx
In this tutorial we're going to learn how to leverage Nx to setup a scalable CI pipeline on Circle CI. As repositories get bigger, making sure that the CI is fast, reliable and maintainable can get very challenging. Nx provides a solution.
- Nx reduces wasted time in CI with the [`affected` command](/ci/features/affected).
- Nx Replay's [remote caching](/ci/features/remote-cache) will reuse task artifacts from different CI executions making sure you will never run the same computation twice.
- Nx Agents [efficiently distribute tasks across machines](/ci/concepts/parallelization-distribution) ensuring constant CI time regardless of the repository size. The right number of machines is allocated for each PR to ensure good performance without wasting compute.
- Nx Atomizer [automatically splits](/ci/features/split-e2e-tasks) large e2e tests to distribute them across machines. Nx can also automatically [identify and rerun flaky e2e tests](/ci/features/flaky-tasks).
## Example Repository
To follow along with this tutorial, we recommend using the [nx-shops sample repository](https://github.com/nrwl/nx-shops).
{% github-repository url="https://github.com/nrwl/nx-shops" /%}
The `nx-shops` repo is useful to demonstrate the value of the CI pipeline because it has the following characteristics:
- Multiple Nx projects with interdependencies
- Defined lint, test, build and e2e tasks
- Running all the tasks takes more than a minute to finish
To get started:
1. [Fork the nx-shop repo](https://github.com/nrwl/nx-shops/fork) and then clone it to your local machine
```shell
git clone https://github.com/<your-username>/nx-shops.git
```
2. Install dependencies (this repo uses [PNPM](https://pnpm.io/) but you should be able to also use any other package manager)
```shell
pnpm i
```
3. Make sure all tasks are working on your machine, by running lint, test, build and e2e on all projects of the workspace
```shell
pnpm nx run-many -t lint test build
```
## Connect to Circle CI
In order to use Circle CI, you need to [sign up and create an organization](https://circleci.com/docs/first-steps/#sign-up-and-create-an-org). Follow the steps in the Circle CI documentation to connect to your GitHub repository to a project.
![](/nx-cloud/tutorial/circle-setup-project.avif)
The easiest way is to create a branch and PR in your GitHub repository. Note that a sample pipeline workflow file will be created, which we will overwrite in the next step.
![](/nx-cloud/tutorial/circle-create-pr.avif)
Once the PR is created, merge it into your main branch.
![](/nx-cloud/tutorial/circle-pr.avif)
And pull the changes locally:
```shell
git pull
```
## Create a CI Workflow
First, we'll create a new branch to start adding a CI workflow.
```shell
git checkout -b setup-ci
```
Now we can use an Nx generator to create a default CI workflow file.
```shell
pnpm nx generate ci-workflow --ci=circleci
```
This generator will overwrite Circle CI's default `.circleci/config.yml` file to create a CI pipeline that will run the `lint`, `test`, `build` and `e2e` tasks for projects that are affected by any given PR.
The key lines in the CI pipeline are:
```yml {% fileName=".circleci/config.yml" highlightLines=["27-29"] %}
version: 2.1
orbs:
nx: nrwl/nx@1.6.2
jobs:
main:
docker:
- image: cimg/node:lts-browsers
steps:
- checkout
- run:
name: Install PNPM
command: npm install --prefix=$HOME/.local -g pnpm@8
# This enables task distribution via Nx Cloud
# Run this command as early as possible, before dependencies are installed
# Learn more at https://nx.dev/ci/reference/nx-cloud-cli#npx-nxcloud-startcirun
# Connect your workspace by running "nx connect" and uncomment this line to enable task distribution
# - run: pnpm dlx nx-cloud start-ci-run --distribute-on="3 linux-medium-js" --stop-agents-after="e2e-ci"
- run: pnpm install --frozen-lockfile
- nx/set-shas:
main-branch-name: 'main'
# Prepend any command with "nx-cloud record --" to record its logs to Nx Cloud
# - run: pnpm exec nx-cloud record -- echo Hello World
- run: pnpm exec nx affected --base=$NX_BASE --head=$NX_HEAD -t lint test build e2e-ci
workflows:
version: 2
ci:
jobs:
- main
```
The [`nx affected` command](/ci/features/affected) will run the specified tasks only for projects that have been affected by a particular PR, which can save a lot of time as repositories grow larger.
Commit your changes and push your branch:
```shell
git add .
git commit -am "basic ci workflow"
git push -u origin HEAD
```
Open up a new PR to see the run on CircleCI. If you see a message about the `nrwl/nx` orb not being loaded, you need to enable third-party CircleCI orbs in your organization settings. In the Circle CI project dashboard, go to `Organization Settings -> Security` and select `Yes` under Orb Security Settings: Allow Uncertified Orbs.
![](/nx-cloud/tutorial/circle-orb-security.png)
{% callout type="warning" title="Create Your PR on Your Own Repository" %}
Make sure that the PR you create is against your own repository's `main` branch - not the `nrwl/nx-shops` repository.
{% /callout %}
![](/nx-cloud/tutorial/circle-new-run.avif)
Once CI is green, merge the PR.
![](/nx-cloud/tutorial/github-pr-workflow.avif)
And make sure to pull the changes locally:
```shell
git checkout main
git pull origin main
```
The rest of the tutorial covers remote caching and distribution across multiple machines, which need Nx Cloud to be enabled. Let's set that up next.
## Connect to Nx Cloud
Nx Cloud is a companion app for your CI system that provides remote caching, task distribution, e2e test deflaking, better DX and more.
Let's connect your repository to Nx Cloud with the following command:
```shell
pnpm nx connect
```
A browser window will open to register your repository in your [Nx Cloud](https://cloud.nx.app) account. The link is also printed to the terminal if the windows does not open, or you closed it before finishing the steps. The app will guide you to create a PR to enable Nx Cloud on your repository.
![](/nx-cloud/tutorial/nx-cloud-setup.avif)
Nx Cloud will create a comment on your PR that gives you a summary of the CI run and a link to dig into logs and understand everything that happened during the CI run.
![Nx Cloud report comment](/nx-cloud/tutorial/nx-cloud-report-comment.png)
Once the PR is green, merge it into your main branch.
![](/nx-cloud/tutorial/github-cloud-pr.avif)
And make sure you pull the latest changes locally:
```shell
git pull
```
You should now have an `nxCloudId` property specified in the `nx.json` file.
## Understand Remote Caching
[Nx Cloud](https://nx.app) provides [Nx Replay](/ci/features/remote-cache), which is a powerful, scalable and, very importantly, secure way to share task artifacts across machines. It lets you configure permissions and guarantees the cached artifacts cannot be tempered with.
[Nx Replay](/ci/features/remote-cache) is enabled by default. We can see it in action by running a few commands locally. First, let's build every project in the repository:
```shell
pnpm nx run-many -t build
```
Nx will store the output of those tasks locally in the `.nx/cache` folder and remotely in Nx Cloud. If someone else in the organization were to run the same `build` command on the same source code, they would receive the remotely cached outputs instead of re-running the `build` task themselves. We can simulate this by deleting the `.nx/cache` folder and re-running the `build` command.
```shell
rm -rf .nx/cache
pnpm nx run-many -t build
```
The `build` tasks complete almost instantly, and you can see in the logs that Nx has pulled the outputs from the remote cache:
```
nx run-many -t build
✔ nx run shared-product-types:build [remote cache]
✔ nx run shared-product-ui:build [remote cache]
✔ nx run shared-header:build [remote cache]
✔ nx run landing-page:build:production [remote cache]
✔ nx run admin:build:production [remote cache]
✔ nx run cart:build:production [remote cache]
```
This remote cache is useful to speed up tasks when developing on a local machine, but it is incredibly useful for CI to be able share task results across different CI pipeline executions. When a small commit is added to a large PR, the CI is able to download the results for most of the tasks instead of recomputing everything from scratch.
You might also want to learn more about [how to fine-tune caching](/recipes/running-tasks/configure-inputs) to get even better results.
## Parallelize Tasks Across Multiple Machines Using Nx Agents
The affected command and Nx Replay help speed up the average CI time, but there will be some PRs that affect everything in the repository. The only way to speed up that worst case scenario is through efficient parallelization. The best way to parallelize CI with Nx is to use [Nx Agents](/ci/features/distribute-task-execution).
The Nx Agents feature
- takes a command (e.g. `nx affected -t build lint test e2e-ci`) and splits it into individual tasks which it then distributes across multiple agents
- distributes tasks by considering the dependencies between them; e.g. if `e2e-ci` depends on `build`, Nx Cloud will make sure that `build` is executed before `e2e-ci`; it does this across machines
- distributes tasks to optimize for CPU processing time and reduce idle time by taking into account historical data about how long each task takes to run
- collects the results and logs of all the tasks and presents them in a single view
- automatically shuts down agents when they are no longer needed
To enable Nx Agents, make sure the `nx-cloud start-ci-run` line is uncommented in the `.circleci/config.yml` file and the `nx affected` line runs the `e2e-ci` task instead of `e2e`.
```yml {% fileName=".circleci/config.yml" highlightLines=["21","29"] %}
version: 2.1
orbs:
nx: nrwl/nx@1.6.2
jobs:
main:
docker:
- image: cimg/node:lts-browsers
steps:
- checkout
- run:
name: Install PNPM
command: npm install --prefix=$HOME/.local -g pnpm@8
# This enables task distribution via Nx Cloud
# Run this command as early as possible, before dependencies are installed
# Learn more at https://nx.dev/ci/reference/nx-cloud-cli#npx-nxcloud-startcirun
# Connect your workspace by running "nx connect" and uncomment this line to enable task distribution
- run: pnpm dlx nx-cloud start-ci-run --distribute-on="3 linux-medium-js" --stop-agents-after="e2e-ci"
- run: pnpm install --frozen-lockfile
- nx/set-shas:
main-branch-name: 'main'
# Prepend any command with "nx-cloud record --" to record its logs to Nx Cloud
# - run: pnpm exec nx-cloud record -- echo Hello World
- run: pnpm exec nx affected --base=$NX_BASE --head=$NX_HEAD -t lint test build e2e-ci
workflows:
version: 2
ci:
jobs:
- main
```
We recommend you add this line right after you check out the repo, before installing node modules.
- `nx-cloud start-ci-run --distribute-on="3 linux-medium-js` lets Nx know that all the tasks after this line should use Nx Agents and that Nx Cloud should use three instances of the `linux-medium-js` launch template. See the separate reference on how to [configure a custom launch template](/ci/reference/launch-templates).
- `--stop-agents-after="e2e-ci"` lets Nx Cloud know which line is the last command in this pipeline. Once there are no more e2e tasks for an agent to run, Nx Cloud will automatically shut them down. This way you're not wasting money on idle agents while a particularly long e2e task is running on a single agent.
Try it out by creating a new PR with the above changes.
```shell
git checkout -b enable-distribution
git commit -am 'enable task distribution'
```
![](/nx-cloud/tutorial/github-pr-distribution.avif)
Once Circle CI starts, you can click on the Nx Cloud report to see what tasks agents are executing in real time.
![](/nx-cloud/tutorial/nx-cloud-distribution.avif)
With this pipeline configuration in place, no matter how large the repository scales, Nx Cloud will adjust and distribute tasks across agents in the optimal way. If CI pipelines start to slow down, just add some agents. One of the main advantages is that this pipeline definition is declarative. We tell Nx what commands to run, but not how to distribute them. That way even if our monorepo structure changes and evolves over time, the distribution will be taken care of by Nx Cloud.
## Next Steps
You now have a highly optimized CI configuration that will scale as your repository scales. See what else you can do with Nx Cloud.
- Configure [dynamic agent allocation](/ci/features/dynamic-agents)
- Learn about [automatically splitting e2e tasks](/ci/features/split-e2e-tasks)
- Identify and re-run [flaky tasks](/ci/features/flaky-tasks)
Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 120 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 98 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 64 KiB

Some files were not shown because too many files have changed in this diff Show More