Assignment Rules

Assignment rules allow you to control which tasks can run on which agents. Save on agent costs by provisioning different sizes of agents to suite the individual needs of your tasks. Ensure resource intensive targets like e2e-ci and build have what they need by using larger agents and with a specified parallelism. Lighter tasks like lint and test can run on smaller agents.

Assignment rules are defined in yaml files within your workspace's .nx/workflows directory. You can use assignment rules with Manual Distributed Task Execution (DTE) or with dynamic Nx agents. Note that additional configuration is required when using Manual DTE.

How to Define an Assignment Rule

Each assignment rule has one of the following properties that it matches against tasks: projects, targets, and/or configurations. You can provide a list of globs to match against the tasks in your workspace. It also has a list of possible agent types that tasks with the matching properties can run on. Rules are defined in yaml like the following:

.nx/workflows/distribution-config.yaml
1distribute-on: 2 default: 5 linux-medium-js, 5 linux-large-js 3 4assignment-rules: 5 - projects: 6 - app1 7 targets: 8 - e2e-ci* 9 configurations: 10 - production 11 run-on: 12 - agent: linux-medium 13 parallelism: 5 14 15 - targets: 16 - lint 17 - build 18 run-on: 19 - agent: linux-large 20 parallelism: 10 21

The above rule will match any task that has a project named app1, any targets that begin with e2e-ci, and a configuration named production. Any tasks that match this rule will only be allowed to run on agents with linux-medium-js launch templates. Agents assigned these tasks will also be able to execute up to 5 tasks in parallel.

The second rule above will match any task that has a lint or build target. These tasks only run on linux-large agents and up to 10 tasks can be executed in parallel by agents of that type.

You can mix and match any of the criteria in an assignment rule provided that you follow the constraints:

  • At least one of the following properties is defined: projects, targets, configurations.
  • There is at least one agent type specified in the run-on field. If no parallelism is specified, the parallelism of the executed command will be used instead. If that is not specified, then the parallelism will default to 1
  • For assignment rules with Nx Agents, every changeset in your distribute-on field must include at least one agent that matches each agent type specified in the runs-on field across all assignment rules. For example, if your rules distribute tasks on linux-small-js, linux-medium-js, and linux-large-js, then at least one agent of each type must be available; otherwise, tasks associated with those rules cannot be executed.
If you are using Manual DTE, you must define your own agent types

You must define your own agent types and attach them to your agents using the NX_AGENT_LAUNCH_TEMPLATE environment variable. Ensure that for each runs-on field in your assignment rules, you have corresponding agents in your agent pool that have the same agent type. See below for an example of how to define your own agent types when using Manual DTE.

Assignment Rule Property Reference

projects

A list of string globs that matches against projects in your workspace.

targets

A list of string globs that matches against targets in your workspace.

configurations

A list of string globs that matches against configurations in your workspace.

run-on

Specification of which agent and how to run your tasks:

  • agent: the type of agent to run on (linux-medium, linux-large)
  • parallelism: the number of parallel executions allowed for agents of a given type

Glob Reference

You can use globs for better control over how to define your assignment rules.

* matches zero or more characters
  • lint* matches lint-js, linting-test
  • *test* matches business-test-2, test-12, 10-test
  • lint* does not match eslint, lin-test, lin
? matches exactly one character
  • app? matches app1, app3, apps
  • app? does not match app10, apps1, bus-app1
! at start negates the pattern
  • !prod matches development, staging
  • !prod does not match prod

List delimited globs

If you provide a list of globs to an individual rule property (projects, targets, configurations), it will match any of the patterns for that given property.

.nx/workflows/assignment-rules.yaml
1assignment-rules: 2 - targets: 3 - e2e-ci* 4 - lint* 5 run-on: 6 - agent: linux-medium 7 parallelism: 2 8

The following rule will match the following tasks:

  • starts with e2e-ci (i.e e2e-ci--playwright-button-test)
  • starts with lint (i.e lint-js)

Comma delimited globs

Within each list entry, you can define a comma delimited list of globs. This notation will match a given property only if all globs match.

.nx/workflows/assignment-rules.yaml
1assignment-rules: 2 - targets: 3 - 'e2e-ci*,*server-test' 4 - 'lint*' 5 run-on: 6 - agent: linux-large 7 parallelism: 5 8

The following rule will match the following tasks:

  • starts with e2e-ci and ends with server-test (i.e e2e-ci--playwright-server-test)
  • starts with lint (i.e lint-js)

Configuring Parallelism through Assignment Rules

You can specify how many tasks of a certain type can run in parallel on a particular agent. Each agent object within the run-on list can have the parallelism property. Configuring parallelism through your assignment rules will override the other parallelism configurations in your workspace. For a given command run with DTE, parallelism is determined by in the following order:

  1. Parallelism defined in the assignment rules
  2. Parallelism defined in the --parallel flag in your command
  3. Parallelism defined in your nx.json file (parallel: 3)

If none of these methods of configuring parallelism are used, the parallelism of executed tasks will default to 1.

Note that there are two special cases for parallelism with assignment rules where the behaviour may differ.

  1. All tasks that are marked as non-cacheable (they are configured with cache: false) will be run with a parallelism of 1 regardless of the parallelism defined in the assignment rules or execution. This is usually the case with tasks such as e2e-ci which may requires each process to have its own environment or resources to run.
  2. Assignment rules only apply to distributed executions (DTE). If you want to run multiple tasks in parallel without DTE (via the --no-dte flag), you will need to use the --parallel flag in your commands.

nx affected -t lint test built --no-dte --parallel=3

Assignment Rules Parallelism Example

nx affected -t lint test build --parallel=3

.nx/workflows/assignment-rules.yaml
1assignment-rules 2 - targets: 3 - lint 4 - test 5 run-on: 6 - agent: linux-medium 7 parallelism: 4 8 9 - target: 10 - build 11 run-on: 12 - agent: linux-large 13

In the above example, the lint and test targets will run on linux-medium agents with a parallelism of 4 as defined within the rules. The build target will run on linux-large agents, but note that there is no parallelism defined for that target. The parallelism for build tasks will then use the value provided by the --parallel flag, which is 3.

Setting Default Parallelism for Multiple Tasks

Putting globs and parallelism together, you can set a default parallelism for all tasks within your executions. Take the following statement:

Only e2e-ci tasks should run on large agents. All other tasks should run on medium agents with a parallelism of 5.

This can be represented as the following yaml config.

1assignment-rules: 2 # Since this rule was defined first and `targets` has a higher precedence order, 3 # e2e-ci tasks will use this rule 4 - targets: 5 - e2e-ci* 6 run-on: 7 - agent: linux-large 8 9 # This rule will match all projects in your workspace 10 - projects: 11 - '*' 12 run-on: 13 - agent: linux-medium 14 parallelism: 5 15

Assignment Rule Precedence

Having multiple assignment rules means that often rules may overlap or apply to the same tasks. For a given task, only one rule will ever be applied. To determine which rule take priority, a rule of thumb is that more specific rules take precedence over more general rules. You can consult our precedence chart for a full list of rule priorities. A checkmark indicates that a rule has a particular property defined.

If two rules have the same priority based on the below chart, the rule that appears first in the assignment-rules list will take precedence.

PriorityConfigurationTargetProject
1✅︎✅︎✅︎
2✅︎✅︎
3✅︎✅︎
4✅︎✅︎
5✅︎
6✅︎
7

Rule Precedence Example

In this example, the task defined below can match multiple assignment rules. However, since the second rule specifies all three properties (projects, targets, and configurations) rather than just two (projects and targets), it takes precedence, and we automatically apply the second rule when distributing the task.

A task from your workspace
1{ 2 "project": "app1", 3 "target": "build", 4 "configuration": "production" 5} 6
.nx/workflows/distribution-config.yaml
1assignment-rules: 2 # A task for app1:build:production will use this rule because it is more 3 # specific (matches all three properties instead of just two) 4 - projects: 5 - app1 6 targets: 7 - build 8 configurations: 9 - production 10 run-on: 11 - agent: linux-medium-js 12 parallelism: 5 13 14 - projects: 15 - app1 16 targets: 17 - build 18 run-on: 19 - agent: linux-large-js 20 parallelism: 3 21

Using Assignment Rules with Manual DTE

A typical assignment-rules.yaml file might look like this:

.nx/workflows/assignment-rules.yaml
1assignment-rules: 2 - projects: 3 - app1 4 targets: 5 - build 6 configurations: 7 - production 8 run-on: 9 - agent: linux-medium 10 parallelism: 5 11 - agent: linux-large 12 13 - targets: 14 - lint 15 runs-on: 16 - agent: linux-medium 17 18 - configurations: 19 - development 20 run-on: 21 - agent: linux-medium 22 - agent: linux-large 23

Note that the agent types supplied in the run-on property will be used to determine which agents will have rules applied to them. You can choose to name your agent types anything you want, but they must be set on your agents via the NX_AGENT_LAUNCH_TEMPLATE environment variable.

You can then reference your assignment rules file within your start-ci-run command:

npx nx-cloud start-ci-run --distribute-on="manual" --assignment-rules=".nx/workflows/assignment-rules.yaml"

The following is an example of what this looks like within a Github Actions pipeline:

.github/workflows/ci.yaml
1--- 2jobs: 3 main: 4 name: Main Job 5 runs-on: ubuntu-latest 6 steps: 7 - ... # setup steps for your main job 8 9 - run: npx nx-cloud start-ci-run --distribute-on="manual" --assignment-rules=".nx/workflows/assignment-rules.yaml" --stop-agents-after="e2e-ci" 10 11 - ... # Nx commands you want to distribute 12 13 medium-agents: 14 name: Agents ${{ matrix.agent }} 15 runs-on: 16 group: medium-agents 17 strategy: 18 matrix: 19 agent: [1, 2, 3] 20 steps: 21 - name: Checkout 22 uses: actions/checkout@v4 23 24 - uses: actions/setup-node@v4 25 with: 26 node-version: 20 27 cache: 'npm' 28 29 - ... # other setup steps you may need 30 31 - name: Install dependencies 32 run: npm ci --legacy-peer-deps 33 34 - name: Start Agent ${{ matrix.agent }} 35 run: npx nx-cloud start-agent 36 env: 37 NX_AGENT_NAME: ${{ matrix.agent }} 38 NX_AGENT_LAUNCH_TEMPLATE: 'linux-medium' # This value needs to match one of the 'runs-on' values defined in the assignment rules 39 40 large-agents: 41 name: Agents ${{ matrix.agent }} 42 runs-on: 43 group: large-agents 44 strategy: 45 matrix: 46 agent: [1, 2, 3] 47 48 steps: 49 - name: Checkout 50 uses: actions/checkout@v4 51 52 - uses: actions/setup-node@v4 53 with: 54 node-version: 20 55 cache: 'npm' 56 57 - ... # other setup steps you may need 58 59 - name: Install dependencies 60 run: npm ci --legacy-peer-deps 61 62 - name: Start Agent ${{ matrix.agent }} 63 run: npx nx-cloud start-agent 64 env: 65 NX_AGENT_NAME: ${{ matrix.agent }} 66 NX_AGENT_LAUNCH_TEMPLATE: 'linux-large' # This value needs to match one of the 'runs-on' values defined in the assignment rules 67

Using Assignment Rules with Dynamic Nx Agents

A typical distribution-config.yaml file might look like this:

.nx/workflows/distribution-config.yaml
1distribute-on: 2 default: 5 linux-medium-js, 5 linux-large-js 3 4assignment-rules: 5 - projects: 6 - app1 7 targets: 8 - build 9 configurations: 10 - production 11 run-on: 12 - agent: linux-large-js 13 14 - targets: 15 - lint 16 run-on: 17 - agent: linux-medium-js 18 parallelism: 3 19 20 - configurations: 21 - development 22 run-on: 23 - agent: linux-medium-js 24 - agent: linux-large-js 25

You can then reference your distribution configuration in your CI pipeline configuration:

.github/workflows/main.yaml
1... 2jobs: 3 - job: main 4 name: Main Job 5 ... 6 steps: 7 ... 8 - run: npx nx-cloud start-ci-run --distribute-on=".nx/workflows/distribution-config.yaml" --stop-agents-after="e2e-ci" 9 - .. 10

More Examples of Assignment Rules with Dynamic Agents

Invalid Assignment Rules Example

.nx/workflows/distribution-config.yaml
1distribute-on: 2 # Invalid changeset that is missing `linux-large-js`. Tasks assigned to large agents won't be able to execute. 3 small-changeset: 1 linux-small-js, 2 linux-medium-js 4 medium-changeset: 2 linux-small-js, 2 linux-medium-js, 3 linux-large-js 5 large-changeset: 3 linux-small-js, 3 linux-medium-js, 4 linux-large-js 6 7assignment-rules: 8 # Missing one of `projects`, `targets`, `configurations` 9 - run-on: 10 - agent: linux-medium-js 11 parallelism: 1 12 - agent: linux-large-js 13 parallelism: 3 14 15 # Missing `runs-on` 16 - targets: 17 - lint 18 configurations: 19 - production 20 21 # Agent type not found in any of the `distribute-on` changesets 22 - projects: 23 - lib1 24 targets: 25 - test 26 run-on: 27 - agent: linux-extra-large-js 28

Valid Assignment Rules Example

.nx/workflows/distribution-config.yaml
1distribute-on: 2 default: 3 linux-small-js, 2 linux-medium-js, 1 linux-large-js 3 4# All rules below are valid assignment rules 5assignment-rules: 6 - projects: 7 - app1 8 run-on: 9 - agent: linux-medium-js 10 - agent: linux-large-js 11 12 - targets: 13 - lint 14 configurations: 15 - production 16 run-on: 17 - agent: linux-large-js 18 parallelism: 10 19 20 - projects: 21 - lib1 22 targets: 23 - test 24 run-on: 25 - agent: linux-medium-js 26

Deprecated Assignment Rules

Assignment rules used to be defined with the following schema. However, this schema did not support multi-glob matching, nor parallelism. Rules defined in this format will still work, but we recommend updating them to the new schema.

.nx/workflows/distribution-config.yaml
1# We recommend updating your assignment rules to the most recent schema 2assignment-rules: 3 - project: app1 # replaced by `projects` 4 target: e2e-ci* # replaced by `targets` 5 configuration: production # replaced by `configurations` 6 runs-on: # replaced by `run-on` 7 - linux-medium-js 8 - linux-large-js 9