diff --git a/docs/generated/manifests/ci.json b/docs/generated/manifests/ci.json index bc2539e604cae2..db1fa909753f06 100644 --- a/docs/generated/manifests/ci.json +++ b/docs/generated/manifests/ci.json @@ -176,7 +176,7 @@ }, { "id": "split-e2e-tasks", - "name": "Automatically Split E2E Tasks", + "name": "Automatically Split E2E Tasks (TestAtomizer)", "description": "", "mediaImage": "", "file": "nx-cloud/features/split-e2e-tasks", @@ -258,7 +258,7 @@ }, "/ci/features/split-e2e-tasks": { "id": "split-e2e-tasks", - "name": "Automatically Split E2E Tasks", + "name": "Automatically Split E2E Tasks (TestAtomizer)", "description": "", "mediaImage": "", "file": "nx-cloud/features/split-e2e-tasks", diff --git a/docs/generated/manifests/menus.json b/docs/generated/manifests/menus.json index 7668cfa3456f70..ffb28477f03cf6 100644 --- a/docs/generated/manifests/menus.json +++ b/docs/generated/manifests/menus.json @@ -5779,7 +5779,7 @@ "disableCollapsible": false }, { - "name": "Automatically Split E2E Tasks", + "name": "Automatically Split E2E Tasks (TestAtomizer)", "path": "/ci/features/split-e2e-tasks", "id": "split-e2e-tasks", "isExternal": false, @@ -5838,7 +5838,7 @@ "disableCollapsible": false }, { - "name": "Automatically Split E2E Tasks", + "name": "Automatically Split E2E Tasks (TestAtomizer)", "path": "/ci/features/split-e2e-tasks", "id": "split-e2e-tasks", "isExternal": false, diff --git a/docs/generated/packages/angular/executors/dev-server.json b/docs/generated/packages/angular/executors/dev-server.json index cc4e906d0a731a..308168e403f615 100644 --- a/docs/generated/packages/angular/executors/dev-server.json +++ b/docs/generated/packages/angular/executors/dev-server.json @@ -105,6 +105,11 @@ "type": "number", "description": "Enable and define the file watching poll time period in milliseconds." }, + "forceEsbuild": { + "type": "boolean", + "description": "Force the development server to use the 'browser-esbuild' builder when building. This is a developer preview option for the esbuild-based build system. _Note: this is only supported in Angular versions >= 16.1.0_.", + "default": false + }, "buildLibsFromSource": { "type": "boolean", "description": "Read buildable libraries from source instead of building them separately. If not set, it will take the value specified in the `browserTarget` options, or it will default to `true` if it's also not set in the `browserTarget` options.", diff --git a/docs/generated/packages/cypress/documents/overview.md b/docs/generated/packages/cypress/documents/overview.md index 3e2bbb4aa4c79e..7ddd5c569a242d 100644 --- a/docs/generated/packages/cypress/documents/overview.md +++ b/docs/generated/packages/cypress/documents/overview.md @@ -75,6 +75,30 @@ The `@nx/cypress/plugin` is configured in the `plugins` array in `nx.json`. The `@nx/cypress/plugin` will automatically split your e2e tasks by file. You can read more about this feature [here](/ci/features/split-e2e-tasks). +To enable e2e task splitting, make sure there is a `ciWebServerCommand` property set in your `cypress.config.ts` file. It will look something like this: + +```ts {% fileName="apps/my-project-e2e/cypress.config.ts" highlightLines=[13] %} +import { defineConfig } from 'cypress'; +import { nxE2EPreset } from '@nx/cypress/plugins/cypress-preset'; + +export default defineConfig({ + e2e: { + ...nxE2EPreset(__filename, { + cypressDir: 'src', + bundler: 'vite', + webServerCommands: { + default: 'nx run my-project:serve', + production: 'nx run my-project:preview', + }, + ciWebServerCommand: 'nx run my-project:serve-static', + }), + baseUrl: 'http://localhost:4200', + }, +}); +``` + +Note: The `nxE2EPreset` is a collection of default settings, but is not necessary for task splitting. + {% /tab %} {% tab label="Nx < 18" %} diff --git a/docs/map.json b/docs/map.json index 33a958d9d15a75..6e93ead9caa898 100644 --- a/docs/map.json +++ b/docs/map.json @@ -1712,7 +1712,7 @@ "file": "nx-cloud/features/dynamic-agents" }, { - "name": "Automatically Split E2E Tasks", + "name": "Automatically Split E2E Tasks (TestAtomizer)", "id": "split-e2e-tasks", "file": "nx-cloud/features/split-e2e-tasks" }, diff --git a/docs/nx-cloud/features/dynamic-agents.md b/docs/nx-cloud/features/dynamic-agents.md index cf81b0736ea942..2c73d39ad18304 100644 --- a/docs/nx-cloud/features/dynamic-agents.md +++ b/docs/nx-cloud/features/dynamic-agents.md @@ -10,7 +10,7 @@ The standard way to set up [Nx Agents](/ci/features/distribute-task-execution) i ```yaml {% fileName=".nx/workflows/dynamic-changesets.yaml" %} distribute-on: - small-changeset: 1 linux-medium-js + small-changeset: 3 linux-medium-js medium-changeset: 6 linux-medium-js large-changeset: 10 linux-medium-js ``` diff --git a/docs/nx-cloud/features/flaky-tasks-ci.png b/docs/nx-cloud/features/flaky-tasks-ci.png new file mode 100644 index 00000000000000..1ad77d3ba1051c Binary files /dev/null and b/docs/nx-cloud/features/flaky-tasks-ci.png differ diff --git a/docs/nx-cloud/features/flaky-tasks.md b/docs/nx-cloud/features/flaky-tasks.md index 9307845c8191df..b48193cd322ad9 100644 --- a/docs/nx-cloud/features/flaky-tasks.md +++ b/docs/nx-cloud/features/flaky-tasks.md @@ -8,14 +8,20 @@ Nx is perfectly positioned to detect which tasks are flaky and automatically re- Nx creates a hash of all the inputs for a task whenever it is run. If Nx ever encounters a task that fails with a particular set of inputs and then succeeds with those same inputs, Nx knows for a fact that the task is flaky. Nx can't know with certainty when the task has been fixed to no longer be flaky, so if a particular task has no flakiness incidents for 2 weeks, the `flaky` flag is removed for that task. -## Manually Mark a Task as Flaky or Not Flaky +![Flaky tasks in CI](/nx-cloud/features/flaky-tasks-ci.png) -If you need to manually mark a task as flaky or not flaky, you can do so from the run details screen. Flaky tasks will have a button that says `Mark task as no longer flaky` and failed tasks that are not flaky will have a button that says `Mark task as likely flaky`. Using these buttons, you can ensure that Nx Cloud treats tasks in the appropriate way. +In this image, the `e2e-ci--src/e2e/app.cy.ts` task is a flaky task that has been automatically retried once. There is a `1 retry` indicator to show that it has been retried and, once expanded, you can see tabs that contain the logs for `Attempt 1` and `Attempt 2`. With this UI, you can easily compare the output between a successful and unsuccessful run of a flaky task. -![Mark task as no longer flaky button](/nx-cloud/features/mark-task-as-no-longer-flaky.png) +## Manually Mark a Task as Flaky or Not Flaky + +If you suspect that a task is flaky, but Nx has not confirmed it yet, you can manually mark it as `likely flaky` from the run details screen. Failed tasks that are not flaky will have a button that says `Mark task as likely flaky`. ![Mark task as likely flaky button](/nx-cloud/features/mark-task-as-likely-flaky.png) +Once you've resolved the issue that caused a task to be flaky, you can immediately mark the task as not flaky by clicking on `Mark task as no longer flaky` on the same run details screen. + +![Mark task as no longer flaky button](/nx-cloud/features/mark-task-as-no-longer-flaky.png) + ## Re-run Flaky Tasks When a flaky task fails in CI with [distributed task execution](/ci/features/distribute-task-execution) enabled, Nx will automatically send that task to a different agent and run it again (up to 2 tries in total). Its important to run the task on a different agent to ensure that the agent itself or the other tasks that were run on that agent are not the reason for the flakiness. diff --git a/docs/nx-cloud/features/mark-task-as-no-longer-flaky.png b/docs/nx-cloud/features/mark-task-as-no-longer-flaky.png index 54047c921491bc..6aad234ac63002 100644 Binary files a/docs/nx-cloud/features/mark-task-as-no-longer-flaky.png and b/docs/nx-cloud/features/mark-task-as-no-longer-flaky.png differ diff --git a/docs/nx-cloud/features/split-e2e-tasks.md b/docs/nx-cloud/features/split-e2e-tasks.md index 18da173f45ee5f..758a073b26cf4d 100644 --- a/docs/nx-cloud/features/split-e2e-tasks.md +++ b/docs/nx-cloud/features/split-e2e-tasks.md @@ -33,15 +33,301 @@ If you are already using the `@nx/cypress` or `@nx/playwright` plugin, you need ## Usage -You can view the available tasks in the graph: +You can view the available tasks for your project in the project detail view: ```shell -nx graph +nx show project myproject-e2e --web ``` +{% project-details title="Project Details View" height="100px" %} + +```json +{ + "project": { + "name": "admin-e2e", + "data": { + "root": "apps/admin-e2e", + "projectType": "application", + "targets": { + "e2e": { + "cache": true, + "inputs": ["default", "^production"], + "outputs": [ + "{workspaceRoot}/dist/cypress/apps/admin-e2e/videos", + "{workspaceRoot}/dist/cypress/apps/admin-e2e/screenshots" + ], + "executor": "nx:run-commands", + "dependsOn": ["^build"], + "options": { + "cwd": "apps/admin-e2e", + "command": "cypress run" + }, + "configurations": { + "production": { + "command": "cypress run --env webServerCommand=\"nx run admin:preview\"" + } + } + }, + "e2e-ci--src/e2e/app.cy.ts": { + "outputs": [ + "{workspaceRoot}/dist/cypress/apps/admin-e2e/videos", + "{workspaceRoot}/dist/cypress/apps/admin-e2e/screenshots" + ], + "inputs": [ + "default", + "^production", + { + "externalDependencies": ["cypress"] + } + ], + "cache": true, + "options": { + "cwd": "apps/admin-e2e", + "command": "cypress run --env webServerCommand=\"nx run admin:serve-static\" --spec src/e2e/app.cy.ts" + }, + "executor": "nx:run-commands", + "configurations": {} + }, + "e2e-ci--src/e2e/login.cy.ts": { + "outputs": [ + "{workspaceRoot}/dist/cypress/apps/admin-e2e/videos", + "{workspaceRoot}/dist/cypress/apps/admin-e2e/screenshots" + ], + "inputs": [ + "default", + "^production", + { + "externalDependencies": ["cypress"] + } + ], + "cache": true, + "options": { + "cwd": "apps/admin-e2e", + "command": "cypress run --env webServerCommand=\"nx run admin:serve-static\" --spec src/e2e/login.cy.ts" + }, + "executor": "nx:run-commands", + "configurations": {} + }, + "e2e-ci": { + "executor": "nx:noop", + "cache": true, + "inputs": [ + "default", + "^production", + { + "externalDependencies": ["cypress"] + } + ], + "outputs": [ + "{workspaceRoot}/dist/cypress/apps/admin-e2e/videos", + "{workspaceRoot}/dist/cypress/apps/admin-e2e/screenshots" + ], + "dependsOn": [ + { + "target": "e2e-ci--src/e2e/app.cy.ts", + "projects": "self", + "params": "forward" + }, + { + "target": "e2e-ci--src/e2e/login.cy.ts", + "projects": "self", + "params": "forward" + } + ], + "options": {}, + "configurations": {} + }, + "lint": { + "executor": "@nx/eslint:lint", + "inputs": ["default", "{workspaceRoot}/.eslintrc.json"], + "cache": true, + "outputs": ["{options.outputFile}"], + "options": {}, + "configurations": {} + } + }, + "name": "admin-e2e", + "$schema": "../../node_modules/nx/schemas/project-schema.json", + "sourceRoot": "apps/admin-e2e/src", + "tags": [], + "implicitDependencies": ["admin"] + } + }, + "sourceMap": { + "root": ["apps/admin-e2e/project.json", "nx/core/project-json"], + "projectType": ["apps/admin-e2e/project.json", "nx/core/project-json"], + "targets": ["apps/admin-e2e/project.json", "nx/core/project-json"], + "targets.e2e": ["apps/admin-e2e/project.json", "nx/core/target-defaults"], + "targets.e2e.options": [ + "apps/admin-e2e/cypress.config.ts", + "@nx/cypress/plugin" + ], + "targets.e2e.cache": [ + "apps/admin-e2e/project.json", + "nx/core/target-defaults" + ], + "targets.e2e.inputs": [ + "apps/admin-e2e/project.json", + "nx/core/target-defaults" + ], + "targets.e2e.outputs": [ + "apps/admin-e2e/cypress.config.ts", + "@nx/cypress/plugin" + ], + "targets.e2e.configurations": [ + "apps/admin-e2e/cypress.config.ts", + "@nx/cypress/plugin" + ], + "targets.e2e.executor": [ + "apps/admin-e2e/cypress.config.ts", + "@nx/cypress/plugin" + ], + "targets.e2e.options.cwd": [ + "apps/admin-e2e/cypress.config.ts", + "@nx/cypress/plugin" + ], + "targets.e2e.options.command": [ + "apps/admin-e2e/cypress.config.ts", + "@nx/cypress/plugin" + ], + "targets.e2e.configurations.production": [ + "apps/admin-e2e/cypress.config.ts", + "@nx/cypress/plugin" + ], + "targets.e2e.configurations.production.command": [ + "apps/admin-e2e/cypress.config.ts", + "@nx/cypress/plugin" + ], + "targets.e2e-ci--src/e2e/app.cy.ts": [ + "apps/admin-e2e/cypress.config.ts", + "@nx/cypress/plugin" + ], + "targets.e2e-ci--src/e2e/app.cy.ts.outputs": [ + "apps/admin-e2e/cypress.config.ts", + "@nx/cypress/plugin" + ], + "targets.e2e-ci--src/e2e/app.cy.ts.inputs": [ + "apps/admin-e2e/cypress.config.ts", + "@nx/cypress/plugin" + ], + "targets.e2e-ci--src/e2e/app.cy.ts.cache": [ + "apps/admin-e2e/cypress.config.ts", + "@nx/cypress/plugin" + ], + "targets.e2e-ci--src/e2e/app.cy.ts.options": [ + "apps/admin-e2e/cypress.config.ts", + "@nx/cypress/plugin" + ], + "targets.e2e-ci--src/e2e/app.cy.ts.executor": [ + "apps/admin-e2e/cypress.config.ts", + "@nx/cypress/plugin" + ], + "targets.e2e-ci--src/e2e/app.cy.ts.options.cwd": [ + "apps/admin-e2e/cypress.config.ts", + "@nx/cypress/plugin" + ], + "targets.e2e-ci--src/e2e/app.cy.ts.options.command": [ + "apps/admin-e2e/cypress.config.ts", + "@nx/cypress/plugin" + ], + "targets.e2e-ci--src/e2e/login.cy.ts": [ + "apps/admin-e2e/cypress.config.ts", + "@nx/cypress/plugin" + ], + "targets.e2e-ci--src/e2e/login.cy.ts.outputs": [ + "apps/admin-e2e/cypress.config.ts", + "@nx/cypress/plugin" + ], + "targets.e2e-ci--src/e2e/login.cy.ts.inputs": [ + "apps/admin-e2e/cypress.config.ts", + "@nx/cypress/plugin" + ], + "targets.e2e-ci--src/e2e/login.cy.ts.cache": [ + "apps/admin-e2e/cypress.config.ts", + "@nx/cypress/plugin" + ], + "targets.e2e-ci--src/e2e/login.cy.ts.options": [ + "apps/admin-e2e/cypress.config.ts", + "@nx/cypress/plugin" + ], + "targets.e2e-ci--src/e2e/login.cy.ts.executor": [ + "apps/admin-e2e/cypress.config.ts", + "@nx/cypress/plugin" + ], + "targets.e2e-ci--src/e2e/login.cy.ts.options.cwd": [ + "apps/admin-e2e/cypress.config.ts", + "@nx/cypress/plugin" + ], + "targets.e2e-ci--src/e2e/login.cy.ts.options.command": [ + "apps/admin-e2e/cypress.config.ts", + "@nx/cypress/plugin" + ], + "targets.e2e-ci": [ + "apps/admin-e2e/cypress.config.ts", + "@nx/cypress/plugin" + ], + "targets.e2e-ci.executor": [ + "apps/admin-e2e/cypress.config.ts", + "@nx/cypress/plugin" + ], + "targets.e2e-ci.cache": [ + "apps/admin-e2e/cypress.config.ts", + "@nx/cypress/plugin" + ], + "targets.e2e-ci.inputs": [ + "apps/admin-e2e/cypress.config.ts", + "@nx/cypress/plugin" + ], + "targets.e2e-ci.outputs": [ + "apps/admin-e2e/cypress.config.ts", + "@nx/cypress/plugin" + ], + "targets.e2e-ci.dependsOn": [ + "apps/admin-e2e/cypress.config.ts", + "@nx/cypress/plugin" + ], + "targets.e2e.dependsOn": [ + "apps/admin-e2e/project.json", + "nx/core/target-defaults" + ], + "targets.lint": ["apps/admin-e2e/project.json", "nx/core/project-json"], + "targets.lint.executor": [ + "apps/admin-e2e/project.json", + "nx/core/project-json" + ], + "targets.lint.inputs": [ + "apps/admin-e2e/project.json", + "nx/core/target-defaults" + ], + "targets.lint.cache": [ + "apps/admin-e2e/project.json", + "nx/core/target-defaults" + ], + "name": ["apps/admin-e2e/project.json", "nx/core/project-json"], + "$schema": ["apps/admin-e2e/project.json", "nx/core/project-json"], + "sourceRoot": ["apps/admin-e2e/project.json", "nx/core/project-json"], + "tags": ["apps/admin-e2e/project.json", "nx/core/project-json"], + "implicitDependencies": [ + "apps/admin-e2e/project.json", + "nx/core/project-json" + ], + "implicitDependencies.admin": [ + "apps/admin-e2e/project.json", + "nx/core/project-json" + ], + "targets.lint.outputs": [ + "apps/admin-e2e/project.json", + "nx/core/project-json" + ] + } +} +``` + +{% /project-details %} + You'll see that there are tasks named `e2e`, `e2e-ci` and a task for each e2e test file. -Developers can run all e2e tests locally the same way as usual: +Developers can run all e2e tests locally with the `e2e` target: ```shell nx e2e my-project-e2e @@ -55,8 +341,16 @@ nx e2e-ci my-project-e2e ## Benefits -Smaller e2e tasks enable the following benefits: +With more granular e2e tasks, all the other features of Nx become more powerful. Let's imagine a scenario where there are 10 spec files in a single e2e project and each spec file takes 3 minutes to run. + +### Improved Caching + +[Nx's cache](/ci/features/remote-cache) can be used for all the individual e2e tasks that succeeded and only the failed tasks need to be re-run. Without e2e task splitting, a single spec file failing would force you to re-run all the e2e tests for the project, which would take 30 minutes. With e2e task splitting, a single spec file that fails can be re-run in 3 minutes and the other successful spec file results can be retrieved from the cache. + +### Better Distribution + +[Distributed task execution](/ci/features/distribute-task-execution) allows your e2e tests to be run on multiple machines simultaneously, which reduces the total time of the CI pipeline. Without e2e task splitting, the CI pipeline has to take at least 30 minutes to complete because the one e2e task needs that long to finish. With e2e task splitting, a fully distributed pipeline with 10 agents could finish in 3 minutes. + +### More Precise Flaky Task Identification -- Nx's cache can be used for all the e2e tasks that succeeded and only the failed tasks need to be re-run -- Distributed Task Execution allows your e2e tests to be run on multiple machines simultaneously, which reduces the total time of the CI pipeline -- Nx Agents can [automatically re-run failed flaky e2e tests](/ci/features/flaky-tasks) on a separate agent without a developer needing to manually re-run the CI pipeline +Nx Agents [automatically re-run failed flaky e2e tests](/ci/features/flaky-tasks) on a separate agent without a developer needing to manually re-run the CI pipeline. Leveraging e2e task splitting, Nx identifies the specific flaky test file - this way you can quickly fix the offending test file. Without e2e splitting, Nx identifies that at least one of the e2e tests are flaky - requiring you to find the flaky test on your own. diff --git a/docs/nx-cloud/reference/nx-cloud-cli.md b/docs/nx-cloud/reference/nx-cloud-cli.md index bc9d38445d0ee4..845f285e6b40f7 100644 --- a/docs/nx-cloud/reference/nx-cloud-cli.md +++ b/docs/nx-cloud/reference/nx-cloud-cli.md @@ -21,7 +21,7 @@ You can also define the configuration in a file and reference it as follows: ```yaml {% fileName=".nx/workflows/dynamic-changesets.yaml" %} distribute-on: - small-changeset: 1 linux-medium-js + small-changeset: 3 linux-medium-js medium-changeset: 6 linux-medium-js large-changeset: 10 linux-medium-js ``` diff --git a/docs/shared/packages/cypress/cypress-plugin.md b/docs/shared/packages/cypress/cypress-plugin.md index 3e2bbb4aa4c79e..7ddd5c569a242d 100644 --- a/docs/shared/packages/cypress/cypress-plugin.md +++ b/docs/shared/packages/cypress/cypress-plugin.md @@ -75,6 +75,30 @@ The `@nx/cypress/plugin` is configured in the `plugins` array in `nx.json`. The `@nx/cypress/plugin` will automatically split your e2e tasks by file. You can read more about this feature [here](/ci/features/split-e2e-tasks). +To enable e2e task splitting, make sure there is a `ciWebServerCommand` property set in your `cypress.config.ts` file. It will look something like this: + +```ts {% fileName="apps/my-project-e2e/cypress.config.ts" highlightLines=[13] %} +import { defineConfig } from 'cypress'; +import { nxE2EPreset } from '@nx/cypress/plugins/cypress-preset'; + +export default defineConfig({ + e2e: { + ...nxE2EPreset(__filename, { + cypressDir: 'src', + bundler: 'vite', + webServerCommands: { + default: 'nx run my-project:serve', + production: 'nx run my-project:preview', + }, + ciWebServerCommand: 'nx run my-project:serve-static', + }), + baseUrl: 'http://localhost:4200', + }, +}); +``` + +Note: The `nxE2EPreset` is a collection of default settings, but is not necessary for task splitting. + {% /tab %} {% tab label="Nx < 18" %} diff --git a/docs/shared/reference/sitemap.md b/docs/shared/reference/sitemap.md index a1ae8af9264071..571b7ec4a6da2d 100644 --- a/docs/shared/reference/sitemap.md +++ b/docs/shared/reference/sitemap.md @@ -271,7 +271,7 @@ - [Use Remote Caching (Nx Replay)](/ci/features/remote-cache) - [Distribute Task Execution (Nx Agents)](/ci/features/distribute-task-execution) - [Dynamically Allocate Agents](/ci/features/dynamic-agents) - - [Automatically Split E2E Tasks](/ci/features/split-e2e-tasks) + - [Automatically Split E2E Tasks (TestAtomizer)](/ci/features/split-e2e-tasks) - [Identify and Re-run Flaky Tasks](/ci/features/flaky-tasks) - [Set up Nx Cloud On-Premise](/ci/features/on-premise) - [Concepts](/ci/concepts) diff --git a/nx-dev/nx-dev/pages/tips.tsx b/nx-dev/nx-dev/pages/tips.tsx index e7697c833e40ab..703daf0b26b987 100644 --- a/nx-dev/nx-dev/pages/tips.tsx +++ b/nx-dev/nx-dev/pages/tips.tsx @@ -386,7 +386,7 @@ const tips: NewYearTip[] = [
Read more about using Nx to{' '} Automate Updating Dependencies diff --git a/nx-dev/nx-dev/public/images/launch-nx/nx-release.jpg b/nx-dev/nx-dev/public/images/launch-nx/nx-release.jpg new file mode 100644 index 00000000000000..9ff5ab0f36a2d2 Binary files /dev/null and b/nx-dev/nx-dev/public/images/launch-nx/nx-release.jpg differ diff --git a/nx-dev/ui-common/src/lib/header.tsx b/nx-dev/ui-common/src/lib/header.tsx index 222b9195b45940..78a2a514c58108 100644 --- a/nx-dev/ui-common/src/lib/header.tsx +++ b/nx-dev/ui-common/src/lib/header.tsx @@ -35,7 +35,7 @@ export function Header(): JSX.Element { name: 'Nx Replay', description: 'Built-in local and remote caching to speed up your tasks and save you time and money.', - href: '/core-features/cache-task-results', + href: '/features/cache-task-results', }, { name: 'Recipes', @@ -46,7 +46,7 @@ export function Header(): JSX.Element { name: 'Nx Agents', description: 'Executes tasks remotely on different agents in parallel. Enable remote cache in one command.', - href: '/ci/features/nx-agents', + href: '/ci/features/distribute-task-execution', }, { name: 'Nx Console', diff --git a/nx-dev/ui-conference/src/lib/launch-week/agenda.tsx b/nx-dev/ui-conference/src/lib/launch-week/agenda.tsx index b99536a6470c4f..99753e420554ed 100644 --- a/nx-dev/ui-conference/src/lib/launch-week/agenda.tsx +++ b/nx-dev/ui-conference/src/lib/launch-week/agenda.tsx @@ -85,7 +85,7 @@ export function LaunchWeekAgenda(): JSX.Element { className="font-input-mono group flex w-full items-center text-blue-500 dark:text-sky-500 sm:text-xl" > - Watch the live stream recording + Watch the conference recording