Skip to content

Commit

Permalink
docs(core): add more realistic graph example and some other improvements
Browse files Browse the repository at this point in the history
  • Loading branch information
juristr committed Nov 30, 2023
1 parent 434dee2 commit 1f4346f
Showing 1 changed file with 151 additions and 56 deletions.
207 changes: 151 additions & 56 deletions docs/shared/using-nx/affected.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,9 @@ When you run `nx affected -t test`, Nx uses Git to determine the files you chang
change (what exactly did you update in those files), and it uses this to determine the list of projects in the workspace
that can be affected by this change. It then runs the `run-many` command with that list.

For instance, if my PR changes `lib`, and I then run `nx affected -t test`, Nx figures out that `app1` and `app2`
depend on `lib`, so it will invoke `nx run-many -t test -p app1 app2 lib`.
For instance, if my PR changes `lib10`, and we then run `nx affected -t test`, Nx leverages the project graph to determine all the projects that depend on `lib10`, marks them as "affected" and runs `test` on just that subset of projects.

{% side-by-side %}
{% graph title="Changing app1 can only affect app1" height="250px" %}
{% graph title="Making a change in lib10 only affects a sub-part of the project graph" height="400px" %}

```json
{
Expand All @@ -31,56 +29,62 @@ depend on `lib`, so it will invoke `nx run-many -t test -p app1 app2 lib`.
},
{
"type": "lib",
"name": "lib",
"name": "lib1",
"data": {}
}
],
"groupByFolder": false,
"workspaceLayout": {
"appsDir": "apps",
"libsDir": "libs"
},
"dependencies": {
"app1": [
{
"target": "lib",
"source": "app1",
"type": "direct"
}
],
"app2": [
{
"target": "lib",
"source": "app2",
"type": "direct"
}
],
"lib": []
},
"affectedProjectIds": ["app1"]
}
```

{% /graph %}

{% graph title="Changing lib can affect lib, app1 and app2" height="250px" %}

```json
{
"projects": [
},
{
"type": "app",
"name": "app1",
"type": "lib",
"name": "lib2",
"data": {}
},
{
"type": "app",
"name": "app2",
"type": "lib",
"name": "lib3",
"data": {}
},
{
"type": "lib",
"name": "lib",
"name": "lib4",
"data": {}
},
{
"type": "lib",
"name": "lib5",
"data": {}
},
{
"type": "lib",
"name": "lib6",
"data": {}
},
{
"type": "lib",
"name": "lib7",
"data": {}
},
{
"type": "lib",
"name": "lib8",
"data": {}
},
{
"type": "lib",
"name": "lib9",
"data": {}
},
{
"type": "lib",
"name": "lib10",
"data": {}
},
{
"type": "lib",
"name": "lib11",
"data": {}
},
{
"type": "lib",
"name": "lib12",
"data": {}
}
],
Expand All @@ -92,41 +96,126 @@ depend on `lib`, so it will invoke `nx run-many -t test -p app1 app2 lib`.
"dependencies": {
"app1": [
{
"target": "lib",
"target": "lib1",
"source": "app1",
"type": "direct"
},
{
"target": "lib2",
"source": "app1",
"type": "direct"
}
],
"app2": [
{
"target": "lib",
"target": "lib4",
"source": "app2",
"type": "direct"
},
{
"target": "lib5",
"source": "app2",
"type": "direct"
},
{
"target": "lib6",
"source": "app2",
"type": "direct"
}
],
"lib1": [
{
"target": "lib7",
"source": "lib1",
"type": "direct"
},
{
"target": "lib8",
"source": "lib1",
"type": "direct"
}
],
"lib": []
"lib2": [
{
"target": "lib3",
"source": "lib2",
"type": "direct"
}
],
"lib3": [
{
"target": "lib8",
"source": "lib3",
"type": "direct"
}
],
"lib4": [
{
"target": "lib3",
"source": "lib4",
"type": "direct"
},
{
"target": "lib9",
"source": "lib4",
"type": "direct"
},
{
"target": "lib10",
"source": "lib4",
"type": "direct"
}
],
"lib5": [
{
"target": "lib10",
"source": "lib5",
"type": "direct"
},
{
"target": "lib11",
"source": "lib5",
"type": "direct"
},
{
"target": "lib12",
"source": "lib5",
"type": "direct"
}
],
"lib6": [
{
"target": "lib12",
"source": "lib6",
"type": "direct"
}
],
"lib7": [],
"lib8": [],
"lib9": [],
"lib10": [],
"lib11": [],
"lib12": []
},
"affectedProjectIds": ["app1", "app2", "lib"]
"affectedProjectIds": ["lib10", "lib4", "lib5", "app2"]
}
```

{% /graph %}
{% /side-by-side %}

Nx analyzes the nature of the changes. For example, if you change the version of Next.js in the package.json, Nx knows
that `app2` cannot be affected by it, so it only retests `app1`.

## Visualize Affected Projects

To visualize what is affected, run:
You can also visualize the affected projects using the [Nx graph](/core-features/explore-graph). Simply run:

```shell
nx affected:graph
```

## Specify Which SHAs to Use to Calculate Affected Code

The SHAs you pass must be defined in the git repository. The `main` and `HEAD` SHAs are what you normally use while developing. Most likely you will want to provision other SHAs in your CI environment.
To understand which projects are affected, Nx uses the Git history and the [project graph](/core-features/explore-graph). Git knows which files changed, and the Nx project graph knows which projects those files belong to.

The affected command takes a `base` and `head` commit. The default `base` is your `main` branch and the default `head` is your current file system. This is generally what you want when developing locally, but in CI, you need to customize these values.

```shell
nx affected:build --base=origin/main --head=$PR_BRANCH_NAME # where PR_BRANCH_NAME is defined by your CI system
Expand All @@ -140,7 +229,13 @@ NX_BASE=origin/main~1
NX_HEAD=origin/main
```

Typically, you want to set the base SHA not the the most recent commit on the `main` branch, but rather that latest commit that successfully passed in CI. In other words, in order to be certain that the repo is in a good state, we need to check all the changes that have happened since the last time the repo was in a good state. See the setup guide for your CI provider to learn how to calculate the last successful commit.
Typically, you want to set the base SHA not the most recent commit on the `main` branch, but rather that latest commit that successfully passed in CI. In other words, in order to be certain that the repo is in a good state, we need to check all the changes that have happened since the last time the repo was in a good state. Depending on your CI provider this might differ:

- [Get last successful commit for Azure Pipelines](/nx-cloud/recipes/set-up/monorepo-ci-azure#get-the-commit-of-the-last-successful-build)
- [Get last successful commit for GitHub Actions](/nx-cloud/recipes/set-up/monorepo-ci-github-actions#get-the-commit-of-the-last-successful-build)
- [Get last successful commit for CircleCI](/nx-cloud/recipes/set-up/monorepo-ci-circle-ci#get-the-commit-of-the-last-successful-build)
- [Get last successful commit for GitLab](/nx-cloud/recipes/set-up/monorepo-ci-gitlab#process-only-affected-projects-with-one-job-on-gitlab)
- [Get last successful commit for Jenkins](/nx-cloud/recipes/set-up/monorepo-ci-jenkins#get-the-commit-of-the-last-successful-build)

## Ignoring Files from Affected Commands

Expand Down

1 comment on commit 1f4346f

@vercel
Copy link

@vercel vercel bot commented on 1f4346f Nov 30, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Successfully deployed to the following URLs:

nx-dev – ./

nx-five.vercel.app
nx-dev-nrwl.vercel.app
nx.dev
nx-dev-git-master-nrwl.vercel.app

Please sign in to comment.