nrwl / nx

Smart Monorepos · Fast CI
https://nx.dev
MIT License
23.52k stars 2.34k forks source link

readyWhen option of run-commands executor silently ending tasks #27986

Open GrayedFox opened 1 month ago

GrayedFox commented 1 month ago

Current Behavior

I have some core tasks that need to be run before running specs. I am using the dependsOn and readyWhen options with the aim of:

  1. running 2 backend tasks in parallel (serverless and mock api)
  2. running 2 front end tasks in parallel (FE packages)

Here's the config:

{
    "name": "e2e",
    "$schema": "../../../node_modules/nx/schemas/project-schema.json",
    "targets": {
        "dev": {
            "executor": "@nx/playwright:playwright",
            "options": {
                "config": "packages/specs/e2e/playwright.config.ts",
                "ui": true
            }
        },
        "lint": {
            "executor": "@nx/linter:eslint",
            "outputs": ["{options.outputFile}"],
            "options": {
                "lintFilePatterns": ["packages/specs/e2e/**/*.{js,ts}"]
            }
        },
        "local": {
            "executor": "nx:run-commands",
            "options": {
                "command": "nx run-many --parallel=2 -t serve -p dev-tools-local-api,common-serverless-application",
                "readyWhen": "Starting Offline SQS"
            }
        },
        "test": {
            "executor": "@nx/playwright:playwright",
            "outputs": ["{workspaceRoot}/dist/.playwright/packages/specs/e2e"],
            "options": {
                "config": "packages/specs/e2e/playwright.config.ts"
            }
        },
        "serve": {
            "executor": "nx:run-commands",
            "dependsOn": ["local"],
            "configurations": {
                "holiday-letting": {
                    "command": "nx run-many --parallel=2 -t serve -p holiday-letting-agent-app,holiday-letting-nsw-signing-experience"
                },
                "sales": {
                    "command": "nx run-many --parallel=2 -t serve -p sales-agent-app,sales-nsw-signing-experience"
                },
                "property-management": {
                    "command": "nx run-many --parallel=2 -t serve -p property-management-agent-app,property-management-nsw-signing-experience"
                }
            }
        }
    }
}

The nx pipeline correctly waits for the "Starting Offline SQS" string to appear, but then it seemingly just kills both the SQS and API when the serve task begins.

Expected Behavior

When I run the needed tasks in a single command like so:

{
  "holiday-letting": {
      "command": "nx run-many --nxBail --parallel=4 -t serve -p holiday-letting-agent-app,holiday-letting-nsw-signing-experience,dev-tools-local-api,common-serverless-application"
  },
}

Then it works fine and I can continue to run tests. Am I missing something obvious here? Is readyWhen designed to end a child process when it matches on the string? If so that is a bit unexpected (still learning the NX way of things, apologies if I'm out of step here).

The behaviour I'm looking for is to always run the 1st task (local which serves the backend and API) and then execute the 2nd configurable task (serve:sales or serve:holiday-letting).

Bonus Qs:

  1. is it possible to get NX to run the commands in parallel but still output to different shells i.e. I see 4 terminals from within the VS Code terminal tab?
  2. is it possible to get NX to share the depended upon task? What I mean is, if run serve:holiday-letting from the NX console and also run serve:sales in another terminal, will the 2nd task see that there is already a running backend and API and know not to spin up an extra one?

Thanks for your time and patience in this matter peeps, so far love the work 🚀

GitHub Repo

No response

Steps to Reproduce

Provided config demonstrates how to reproduce issue.

Nx Report

Node   : 20.15.1
OS     : darwin-arm64
npm    : 10.7.0

nx                 : 16.10.0
@nx/js             : 16.10.0
@nx/jest           : 16.10.0
@nx/linter         : 16.10.0
@nx/workspace      : 16.10.0
@nx/cypress        : 16.10.0
@nx/devkit         : 16.10.0
@nx/esbuild        : 16.10.0
@nx/eslint-plugin  : 16.10.0
@nx/node           : 16.10.0
@nx/playwright     : 16.10.0
@nx/react          : 16.10.0
@nx/storybook      : 16.10.0
@nrwl/tao          : 16.10.0
@nx/vite           : 16.10.0
@nx/web            : 16.10.0
typescript         : 5.1.6

Failure Logs

No response

Package Manager Version

No response

Operating System

Additional Information

No response

xiongemi commented 2 days ago

for the local target, "command": "nx run-many --parallel=2 -t serve -p dev-tools-local-api,common-serverless-application" is considered to be one command, so when readyWhen got hit, it will kill entire command. I think you can change to something like:

 "local": {
      "executor": "nx:run-commands",
      "options": {
        "commands": ["nx run dev-tools-local-api:serve", "nx run common-serverless-application:serve"],
        "parallel": true,
        "readyWhen": "Starting Offline SQS"
      }
    },

the commands are now an array of commands. so if one command hits the readyWhen condition, it will be resolved; if the other one does not meet the condition, it will keep running.

if you want both commands to be resolved, you can change readyWhen to be an array:

 "local": {
      "executor": "nx:run-commands",
      "options": {
        "commands": ["nx run dev-tools-local-api:serve", "nx run common-serverless-application:serve"],
        "parallel": true,
        "readyWhen": ["Starting Offline SQS", "Staring another server or something"]
      }
    },

when the output of each command meets ANY readyWhen condition, it will be resolved.

Bonus Qs:

  1. is it possible to get NX to run the commands in parallel but still output to different shells i.e. I see 4 terminals from within the VS Code terminal tab?

i don't think so, but I think you can specify the --output-style option: https://nx.dev/nx-api/nx/documents/run-many#options.

maybe try to run nx run-many --output-style=stream

  1. is it possible to get NX to share the depended upon task? What I mean is, if run serve:holiday-letting from the NX console and also run serve:sales in another terminal, will the 2nd task see that there is already a running backend and API and know not to spin up an extra one?

I don't think it is possible.

                "holiday-letting": {
                    "command": "nx run-many --parallel=2 -t serve -p holiday-letting-agent-app,holiday-letting-nsw-signing-experience"
                },
                "sales": {
                    "command": "nx run-many --parallel=2 -t serve -p sales-agent-app,sales-nsw-signing-experience"
                },

Because the commands are independent of each other, serve command is not cached, so I don't think Nx knows which app is being served and which is not.