docs(nx-cloud): add docs for assignment rules (#28855)
<!-- 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 --> Add documentation for how assignment rules feature works with Nx Cloud. ## Related Issue(s) <!-- Please link the issue being fixed so it gets closed when this is merged. --> Fixes # --------- Co-authored-by: Isaac Mann <isaacplmann@users.noreply.github.com> Co-authored-by: Isaac Mann <isaacplmann@gmail.com>
This commit is contained in:
parent
432d9d3b17
commit
9526560fa0
@ -1854,6 +1854,17 @@
|
|||||||
"path": "/ci/reference/launch-templates",
|
"path": "/ci/reference/launch-templates",
|
||||||
"tags": []
|
"tags": []
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"id": "assignment-rules",
|
||||||
|
"name": "Assignment Rules",
|
||||||
|
"description": "",
|
||||||
|
"mediaImage": "",
|
||||||
|
"file": "nx-cloud/reference/assignment-rules",
|
||||||
|
"itemList": [],
|
||||||
|
"isExternal": false,
|
||||||
|
"path": "/ci/reference/assignment-rules",
|
||||||
|
"tags": []
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"id": "custom-steps",
|
"id": "custom-steps",
|
||||||
"name": "Custom Steps",
|
"name": "Custom Steps",
|
||||||
@ -1925,6 +1936,17 @@
|
|||||||
"path": "/ci/reference/launch-templates",
|
"path": "/ci/reference/launch-templates",
|
||||||
"tags": []
|
"tags": []
|
||||||
},
|
},
|
||||||
|
"/ci/reference/assignment-rules": {
|
||||||
|
"id": "assignment-rules",
|
||||||
|
"name": "Assignment Rules",
|
||||||
|
"description": "",
|
||||||
|
"mediaImage": "",
|
||||||
|
"file": "nx-cloud/reference/assignment-rules",
|
||||||
|
"itemList": [],
|
||||||
|
"isExternal": false,
|
||||||
|
"path": "/ci/reference/assignment-rules",
|
||||||
|
"tags": []
|
||||||
|
},
|
||||||
"/ci/reference/custom-steps": {
|
"/ci/reference/custom-steps": {
|
||||||
"id": "custom-steps",
|
"id": "custom-steps",
|
||||||
"name": "Custom Steps",
|
"name": "Custom Steps",
|
||||||
|
|||||||
@ -6776,6 +6776,14 @@
|
|||||||
"children": [],
|
"children": [],
|
||||||
"disableCollapsible": false
|
"disableCollapsible": false
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "Assignment Rules",
|
||||||
|
"path": "/ci/reference/assignment-rules",
|
||||||
|
"id": "assignment-rules",
|
||||||
|
"isExternal": false,
|
||||||
|
"children": [],
|
||||||
|
"disableCollapsible": false
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "Custom Steps",
|
"name": "Custom Steps",
|
||||||
"path": "/ci/reference/custom-steps",
|
"path": "/ci/reference/custom-steps",
|
||||||
@ -6827,6 +6835,14 @@
|
|||||||
"children": [],
|
"children": [],
|
||||||
"disableCollapsible": false
|
"disableCollapsible": false
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "Assignment Rules",
|
||||||
|
"path": "/ci/reference/assignment-rules",
|
||||||
|
"id": "assignment-rules",
|
||||||
|
"isExternal": false,
|
||||||
|
"children": [],
|
||||||
|
"disableCollapsible": false
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "Custom Steps",
|
"name": "Custom Steps",
|
||||||
"path": "/ci/reference/custom-steps",
|
"path": "/ci/reference/custom-steps",
|
||||||
|
|||||||
@ -2001,6 +2001,11 @@
|
|||||||
"id": "launch-templates",
|
"id": "launch-templates",
|
||||||
"file": "nx-cloud/reference/launch-templates"
|
"file": "nx-cloud/reference/launch-templates"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "Assignment Rules",
|
||||||
|
"id": "assignment-rules",
|
||||||
|
"file": "nx-cloud/reference/assignment-rules"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "Custom Steps",
|
"name": "Custom Steps",
|
||||||
"id": "custom-steps",
|
"id": "custom-steps",
|
||||||
|
|||||||
@ -18,26 +18,51 @@ jobs:
|
|||||||
- ...
|
- ...
|
||||||
```
|
```
|
||||||
|
|
||||||
This works great but may not be the most cost-effective way to run your tasks. The goal is to **balance cost and speed**. For example, you might want to run a small PR on a few agents to save costs, but use many agents for a large PR to get the fastest possible build time.
|
This works great, but may not be the most cost-effective way to run your tasks. The goal is to **balance cost and speed**. For example, you might want to run a small PR on a few agents to save costs, but use many agents for a large PR to get the fastest possible build time.
|
||||||
|
|
||||||
## Configure Dynamic Agents based on PR size
|
## Configure Dynamic Agents based on PR size
|
||||||
|
|
||||||
Instead of using a static configuration of agents (like the one shown above), you can also configure to use a different number and type of agents based on the size of your PR.
|
You can configure Nx Cloud to execute a different number of agents based on the size of your PR's affected changes. Define any number of **changesets** (the number of agents and types of agents) to use for different sized PRs and pass them in a configuration file to your `start-ci-run` command.
|
||||||
|
|
||||||
Create a file called `dynamic-changesets.yaml` in the `.nx/workflows` directory of your repo.
|
Start by creating a file called `distribution-config.yaml` in the `.nx/workflows` directory of your repo. This file will contain a `distribute-on` property that will be used to define the changesets to use for your PR. You can name your changesets anything you want.
|
||||||
|
|
||||||
```yaml {% fileName=".nx/workflows/dynamic-changesets.yaml" %}
|
{% callout type="warning" title="The order of your changesets matters!" %}
|
||||||
|
Define your changesets in order of increasing size (i.e. smallest changesets are defined before larger changesets). Nx Cloud uses the position of your changesets as part of its calculations to dynamically determine the correct changeset to use for your PR.
|
||||||
|
{% /callout %}
|
||||||
|
|
||||||
|
```yaml {% fileName=".nx/workflows/distribution-config.yaml" %}
|
||||||
distribute-on:
|
distribute-on:
|
||||||
small-changeset: 3 linux-medium-js
|
small-changeset: 3 linux-medium-js
|
||||||
medium-changeset: 6 linux-medium-js
|
medium-changeset: 6 linux-medium-js
|
||||||
large-changeset: 10 linux-medium-js
|
large-changeset: 10 linux-medium-js
|
||||||
```
|
```
|
||||||
|
|
||||||
|
You can also specify a `default` changeset if you only want one changeset to be used for all PRs. Note that `default` is a reserved keyword so do not use it if you would like to define multiple changesets.
|
||||||
|
|
||||||
|
```yaml {% fileName=".nx/workflows/distribution-config.yaml" %}
|
||||||
|
distribute-on:
|
||||||
|
default: 3 linux-medium-js
|
||||||
|
```
|
||||||
|
|
||||||
|
You can have as many changesets as you want. Based on the number of changesets specified, each changeset is assigned an equal percentage out of 100. Nx Cloud can determine the percentage of affected projects in your PR and use that value to evaluate which changeset to use.
|
||||||
|
|
||||||
{% callout type="deepdive" title="How is the size of the PR determined?" %}
|
{% callout type="deepdive" title="How is the size of the PR determined?" %}
|
||||||
To determine the size of the PR, Nx Cloud calculates the relationship between the number of [affected projects](/ci/features/affected) and the total number of projects in the workspace. It then assigns it to one of the three categories: small, medium, or large.
|
Nx Cloud calculates the relationship between the number of [affected projects](/ci/features/affected) and the total number of projects in the workspace to determine the size of a PR.
|
||||||
{% /callout %}
|
{% /callout %}
|
||||||
|
|
||||||
You can then reference it in your CI pipeline configuration:
|
## Setting up Dynamic Agents in your CI Pipeline
|
||||||
|
|
||||||
|
In the example below, each changeset would be assigned an equal percentage range out of 100%. If Nx Cloud determines that 30% of your projects have been affected, then it will use the medium changeset to distribute the workload on. If Nx Cloud determines that 55% of your projects have been affected, it will use the large changeset.
|
||||||
|
|
||||||
|
```yaml {% fileName=".nx/workflows/distribution-config.yaml" %}
|
||||||
|
distribute-on:
|
||||||
|
small-changeset: 3 linux-medium-js # Distribute on small if 1-25% of projects affected in PR
|
||||||
|
medium-changeset: 6 linux-medium-js # Distribute on medium if 26-50% of projects affected in PR
|
||||||
|
large-changeset: 10 linux-medium-js # Distribute on large if 51-75% of projects affected in PR
|
||||||
|
extra-large-changeset: 15 linux-medium-js # Distribute on extra-large if 76-100% of projects affected in PR
|
||||||
|
```
|
||||||
|
|
||||||
|
You can then reference your distribution configuration in your CI pipeline configuration:
|
||||||
|
|
||||||
```yaml {% fileName=".github/workflows/main.yaml" highlightLines=[8] %}
|
```yaml {% fileName=".github/workflows/main.yaml" highlightLines=[8] %}
|
||||||
...
|
...
|
||||||
@ -47,8 +72,9 @@ jobs:
|
|||||||
...
|
...
|
||||||
steps:
|
steps:
|
||||||
...
|
...
|
||||||
- run: npx nx-cloud start-ci-run --distribute-on=".nx/workflows/dynamic-changesets.yaml" --stop-agents-after="e2e-ci"
|
- run: npx nx-cloud start-ci-run --distribute-on=".nx/workflows/distribution-config.yaml" --stop-agents-after="e2e-ci"
|
||||||
- ...
|
- ...
|
||||||
```
|
```
|
||||||
|
|
||||||
Now, PRs that affect a small percentage of the repo will run on 3 agents, mid-size PRs will use 6 agents, and large PRs will use 10 agents. This feature helps save costs on smaller PRs while maintaining the high performance necessary for large PRs.
|
Now your agents will distribute your tasks dynamically—scaling and adapting to your PR sizes.
|
||||||
|
This feature helps save costs on smaller PRs while maintaining the high performance necessary for large PRs.
|
||||||
|
|||||||
164
docs/nx-cloud/reference/assignment-rules.md
Normal file
164
docs/nx-cloud/reference/assignment-rules.md
Normal file
@ -0,0 +1,164 @@
|
|||||||
|
# Assignment Rules (beta)
|
||||||
|
|
||||||
|
Assignment rules allow you to control which tasks can run on which agents. Save on agent costs by provisioning different sizes of agents all with the confidence that your tasks will be run on the agents that are best suited for them. You can ensure resource intensive targets like `e2e-ci` and `build` have what they need by using larger agents. Lighter tasks like `lint` and `test` can run on smaller agents.
|
||||||
|
|
||||||
|
Assignment rules are defined in your workspaces `distribution-config.yaml` file. This file should be created in the `.nx/workflows` directory of your repository. Note that this means that you must have [dynamic agents](/ci/features/dynamic-agents) also configured in your `distribution-config.yaml` file.
|
||||||
|
|
||||||
|
## How to Define an Assignment Rule
|
||||||
|
|
||||||
|
Each assignment rule has one of the following properties that it matches against tasks: `project`, `target`, and/or `configuration`. It also has a list of possible [agent types](/ci/reference/launch-templates) that tasks with the matching properties can run on. Rules are defined in yaml like the following:
|
||||||
|
|
||||||
|
```yaml {% fileName=".nx/workflows/distribution-config.yaml" %}
|
||||||
|
distribute-on:
|
||||||
|
default: 3 linux-small-js, 2 linux-medium-js, 1 linux-large-js
|
||||||
|
|
||||||
|
assignment-rules:
|
||||||
|
- project: app1
|
||||||
|
target: build
|
||||||
|
configuration: production
|
||||||
|
runs-on:
|
||||||
|
- linux-large-js
|
||||||
|
- linux-medium-js
|
||||||
|
```
|
||||||
|
|
||||||
|
The above rule will match any task that has a project named `app1`, a target named `build`, and a configuration named `production`. Any tasks that match this rule will only be allowed to run on agents with the `linux-large-js` and `linux-medium-js` launch templates.
|
||||||
|
|
||||||
|
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: `project`, `target`, `configuration`.
|
||||||
|
- There is at least one [agent type](/ci/reference/launch-templates) specified in the `run-on` field.
|
||||||
|
- Every changeset in your `distribute-on` field must include at **least one agent** that matches each agent type specified in the run-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.
|
||||||
|
|
||||||
|
### Invalid Assignment Rules Example
|
||||||
|
|
||||||
|
```yaml {% fileName=".nx/workflows/distribution-config.yaml" %}
|
||||||
|
distribute-on:
|
||||||
|
# Invalid changeset that is missing `linux-large-js`. Tasks assigned to large agents won't be able to execute.
|
||||||
|
small-changeset: 1 linux-small-js, 2 linux-medium-js
|
||||||
|
medium-changeset: 2 linux-small-js, 2 linux-medium-js, 3 linux-large-js
|
||||||
|
large-changeset: 3 linux-small-js, 3 linux-medium-js, 4 linux-large-js
|
||||||
|
|
||||||
|
assignment-rules:
|
||||||
|
# Missing one of `project`, `target`, `configuration`
|
||||||
|
- runs-on:
|
||||||
|
- linux-medium-js
|
||||||
|
- linux-large-js
|
||||||
|
|
||||||
|
# Missing `runs-on`
|
||||||
|
- target: lint
|
||||||
|
configuration: production
|
||||||
|
|
||||||
|
# Agent type not found in any of the `distribute-on` changesets
|
||||||
|
- project: lib1
|
||||||
|
target: test
|
||||||
|
runs-on:
|
||||||
|
- linux-extra-large-js
|
||||||
|
```
|
||||||
|
|
||||||
|
### Valid Assignment Rules Example
|
||||||
|
|
||||||
|
```yaml {% fileName=".nx/workflows/distribution-config.yaml" %}
|
||||||
|
distribute-on:
|
||||||
|
default: 3 linux-small-js, 2 linux-medium-js, 1 linux-large-js
|
||||||
|
|
||||||
|
# All rules below are valid assignment rules
|
||||||
|
assignment-rules:
|
||||||
|
- project: app1
|
||||||
|
runs-on:
|
||||||
|
- linux-medium-js
|
||||||
|
- linux-large-js
|
||||||
|
|
||||||
|
- target: lint
|
||||||
|
configuration: production
|
||||||
|
runs-on:
|
||||||
|
- linux-large-js
|
||||||
|
|
||||||
|
- project: lib1
|
||||||
|
target: test
|
||||||
|
runs-on:
|
||||||
|
- linux-medium-js
|
||||||
|
```
|
||||||
|
|
||||||
|
## Assignment Rule Precedence
|
||||||
|
|
||||||
|
Having multiple assignment rules means that often rules may overlap or apply to the same tasks. 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.
|
||||||
|
|
||||||
|
| Priority | Configuration | Target | Project |
|
||||||
|
| :------: | :-----------: | :----: | :-----: |
|
||||||
|
| 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 (`project`, `target`, and `configuration`) rather than just two (`project` and `target`), it takes precedence, and we apply the second rule when distributing the task.
|
||||||
|
|
||||||
|
```json {% fileName="A task from your workspace" %}
|
||||||
|
{
|
||||||
|
"project": "app1",
|
||||||
|
"target": "build",
|
||||||
|
"configuration": "production"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
```yaml {% fileName=".nx/workflows/distribution-config.yaml" %}
|
||||||
|
distribute-on:
|
||||||
|
default: 10 linux-medium-js, 8 linux-large-js
|
||||||
|
|
||||||
|
assignment-rules:
|
||||||
|
- project: app1
|
||||||
|
target: build
|
||||||
|
configuration: production
|
||||||
|
runs-on:
|
||||||
|
- linux-medium-js
|
||||||
|
|
||||||
|
- project: app1
|
||||||
|
target: build
|
||||||
|
runs-on:
|
||||||
|
- linux-large-js
|
||||||
|
```
|
||||||
|
|
||||||
|
## Using Assignment Rules in your CI Pipeline
|
||||||
|
|
||||||
|
A typical `distribution-config.yaml` file might look like this:
|
||||||
|
|
||||||
|
```yaml {% fileName=".nx/workflows/distribution-config.yaml" %}
|
||||||
|
distribute-on:
|
||||||
|
small-changeset: 3 linux-medium-js, 2 linux-large-js
|
||||||
|
medium-changeset: 6 linux-medium-js, 4 linux-large-js
|
||||||
|
large-changeset: 10 linux-medium-js, 8 linux-large-js
|
||||||
|
|
||||||
|
assignment-rules:
|
||||||
|
- project: app1
|
||||||
|
target: build
|
||||||
|
configuration: production
|
||||||
|
runs-on:
|
||||||
|
- linux-large-js
|
||||||
|
|
||||||
|
- target: lint
|
||||||
|
runs-on:
|
||||||
|
- linux-medium-js
|
||||||
|
|
||||||
|
- configuration: development
|
||||||
|
runs-on:
|
||||||
|
- linux-medium-js
|
||||||
|
- linux-large-js
|
||||||
|
```
|
||||||
|
|
||||||
|
You can then reference your distribution configuration in your CI pipeline configuration:
|
||||||
|
|
||||||
|
```yaml {% fileName=".github/workflows/main.yaml" highlightLines=[8] %}
|
||||||
|
...
|
||||||
|
jobs:
|
||||||
|
- job: main
|
||||||
|
displayName: Main Job
|
||||||
|
...
|
||||||
|
steps:
|
||||||
|
...
|
||||||
|
- run: npx nx-cloud start-ci-run --distribute-on=".nx/workflows/distribution-config.yaml" --stop-agents-after="e2e-ci"
|
||||||
|
- ..
|
||||||
|
```
|
||||||
@ -322,6 +322,7 @@
|
|||||||
- [Configuration Options](/ci/reference/config)
|
- [Configuration Options](/ci/reference/config)
|
||||||
- [nx-cloud CLI](/ci/reference/nx-cloud-cli)
|
- [nx-cloud CLI](/ci/reference/nx-cloud-cli)
|
||||||
- [Launch Templates](/ci/reference/launch-templates)
|
- [Launch Templates](/ci/reference/launch-templates)
|
||||||
|
- [Assignment Rules](/ci/reference/assignment-rules)
|
||||||
- [Custom Steps](/ci/reference/custom-steps)
|
- [Custom Steps](/ci/reference/custom-steps)
|
||||||
- [Environment Variables](/ci/reference/env-vars)
|
- [Environment Variables](/ci/reference/env-vars)
|
||||||
- [Release Notes](/ci/reference/release-notes)
|
- [Release Notes](/ci/reference/release-notes)
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user