Nx: Exclude Apps in affected scripts by tags from nx.json

Created on 24 Jul 2019  路  16Comments  路  Source: nrwl/nx

Currently the only way to exclude apps and libs from being processed by the affected scripts, is by their names.
It would be useful, if we could exclude apps and libs in the affected scripts by their tags which can be defined in nx.json

For example having the following nx.json

....
    "booking": {
      "tags": ["booking"]
    },
    "error-page": {
      "tags": ["error-page"]
    },
    "my-nanosite": {
      "tags": ["my-nanosite", "nanosites"]
    },
    "my-other-nanosite": {
      "tags": ["my-other-nanosite", "nanosites"]
    },
...

and running npm run affected:apps -- --base=origin/develop --exclude="tags:nanosites" or something similar :) only apps should printed out, which are affected by changes and do not have the nanosites tag.
It should also be possible to pass a list of tags to be excluded.
This would save us a lot of headaches, because we have more than 50 nanosites and adding them by name in the exclude part is tedious and error prone.

I know the nx.json is used for linting, but could that purpose be extended?

core feature

Most helpful comment

Hi,

I saw there is a pullrequest for .nxignore --> PR #1585

However it only works for the workspace-lint command and not the affected commands

Can it be added in? I see that its added in the core/file-utils.ts in the function allFilesInDir

However thats only use in the workspace-lint as i observed.

Can we add the ignore machanism for the affected as well?

From what I observe there are several places this mechanism can be coded in, if someone would guide with me it would be great.

  1. We either add a project level check with tags/flags at these functions

    • getTouchedProjects,
    • getImplicitlyTouchedProjects,
    • getImplicitlyTouchedProjectsByJsonChanges,
    • getTouchedProjectsInNxJson,
    • getTouchedProjectsInWorkspaceJson
  2. Or we can go directly for the files using glob pattern in .nxignore

    • Either in shared.parseFiles after the git command are run
    • Or add directly into the file-utils.calculateFileChanges

I like the

add directly into the file-utils.calculateFileChanges

option the most. Please advise :D, If so can i work on it and open a PR?

All 16 comments

Hi @mehrad-rafigh, I am working on a new feature to have the ability to ignore glob patterns from the affected commands using either a .nxignore file or nx.json -> ignore property. Would this meet your needs?

PR #1585

Hi @wesleygrimes, I looked over your pull request. It doesn't add the feature I am looking for.
I want to be able to exclude entire apps by their tag names from affected:apps,test,lint and the such for example.

1274 somehow relates to my feature request

Yeah I was going to say this is a duplicate d:

I'm currently applying this patch using patch-package to achieve what I need in my project:

diff --git a/node_modules/@nrwl/workspace/src/command-line/affected.js b/node_modules/@nrwl/workspace/src/command-line/affected.js
index ac6c7d7..87927e6 100644
--- a/node_modules/@nrwl/workspace/src/command-line/affected.js
+++ b/node_modules/@nrwl/workspace/src/command-line/affected.js
@@ -117,8 +117,8 @@ function affected(parsedArgs) {
 exports.affected = affected;
 function getProjects(target, parsedArgs, workspaceResults, all) {
     var projects = all
-        ? shared_1.getAllProjectsWithTarget(target)
-        : shared_1.getAffectedProjectsWithTarget(target)(shared_1.parseFiles(parsedArgs).files);
+        ? shared_1.getAllProjectsWithTarget(target, parsedArgs.tags)
+        : shared_1.getAffectedProjectsWithTarget(target, parsedArgs.tags)(shared_1.parseFiles(parsedArgs).files);
     return projects
         .filter(function (project) { return !parsedArgs.exclude.includes(project); })
         .filter(function (project) { return !parsedArgs.onlyFailed || !workspaceResults.getResult(project); });
@@ -277,6 +277,7 @@ var dummyOptions = {
     head: 'head',
     exclude: ['exclude'],
     files: [''],
+    tags: [],
     verbose: false
 };
 var nxSpecificFlags = Object.keys(dummyOptions);
diff --git a/node_modules/@nrwl/workspace/src/command-line/nx-commands.js b/node_modules/@nrwl/workspace/src/command-line/nx-commands.js
index 200d5c9..ebfa4c0 100644
--- a/node_modules/@nrwl/workspace/src/command-line/nx-commands.js
+++ b/node_modules/@nrwl/workspace/src/command-line/nx-commands.js
@@ -134,6 +134,12 @@ function withAffectedOptions(yargs) {
         type: 'array',
         coerce: parseCSV,
         default: []
+    })
+        .option('tags', {
+        describe: 'Only process projects with the given tag',
+        type: 'array',
+        coerce: parseCSV,
+        default: []
     })
         .options('only-failed', {
         describe: 'Isolate projects which previously failed',
diff --git a/node_modules/@nrwl/workspace/src/command-line/shared.js b/node_modules/@nrwl/workspace/src/command-line/shared.js
index f354aff..883fdbb 100644
--- a/node_modules/@nrwl/workspace/src/command-line/shared.js
+++ b/node_modules/@nrwl/workspace/src/command-line/shared.js
@@ -274,18 +274,21 @@ function readNxJson() {
     return config;
 }
 exports.readNxJson = readNxJson;
-exports.getAffected = function (affectedNamesFetcher) { return function (touchedFiles) {
+exports.getAffected = function (affectedNamesFetcher, tags = []) { return function (touchedFiles) {
     var workspaceJson = readWorkspaceJson();
     var nxJson = readNxJson();
     var projects = getProjectNodes(workspaceJson, nxJson);
     var implicitDeps = getImplicitDependencies(projects, workspaceJson, nxJson);
     var dependencies = deps_calculator_1.readDependencies(nxJson.npmScope, projects);
     var sortedProjects = topologicallySortProjects(projects, dependencies);
+    if (tags.length) {
+      sortedProjects = sortedProjects.filter(p => p.tags.some(t => tags.includes(t)));
+    }
     var tp = touched_1.touchedProjects(implicitDeps, projects, touchedFiles);
     return affectedNamesFetcher(sortedProjects, dependencies, tp);
 }; };
-function getAffectedProjectsWithTarget(target) {
-    return exports.getAffected(affected_apps_1.affectedProjectNamesWithTarget(target));
+function getAffectedProjectsWithTarget(target, tags = []) {
+    return exports.getAffected(affected_apps_1.affectedProjectNamesWithTarget(target), tags);
 }
 exports.getAffectedProjectsWithTarget = getAffectedProjectsWithTarget;
 exports.getAffectedApps = exports.getAffected(affected_apps_1.affectedAppNames);
@@ -303,12 +306,15 @@ function getAllProjectNamesWithTarget(target) {
     return getProjectNames(function (p) { return p.architect[target]; });
 }
 exports.getAllProjectNamesWithTarget = getAllProjectNamesWithTarget;
-function getAllProjectsWithTarget(target) {
+function getAllProjectsWithTarget(target, tags = []) {
     var workspaceJson = readWorkspaceJson();
     var nxJson = readNxJson();
     var projects = getProjectNodes(workspaceJson, nxJson);
     var dependencies = deps_calculator_1.readDependencies(nxJson.npmScope, projects);
     var sortedProjects = topologicallySortProjects(projects, dependencies);
+    if (tags.length) {
+      sortedProjects = sortedProjects.filter(p => p.tags.some(t => tags.includes(t)));
+    }
     return sortedProjects.filter(function (p) { return p.architect[target]; }).map(function (p) { return p.name; });
 }
 exports.getAllProjectsWithTarget = getAllProjectsWithTarget;

@alfaproject @wesleygrimes This looks like a start to a solution, which I would love to see in NX!

@alfaproject @wesleygrimes This looks like a start to a solution, which I would love to see in NX!

I am adding this ability, although I think we will go a slightly different route. I will reference the PR when it is submitted.

@wesleygrimes how it going with the feature that you have been working on to allow custom NX to ignore files/directories when running affected commands? I am working on CI/CD stuff for our repo and wanted to ignore files from affected to redeploy apps, such as I don't want to redeploy if I just updated my tslint.json file on the project root folder

@hoang-innomizetech Yes, you can now create an .nxignore file. This has been merged to master and should be available if not now, definitely in the next release.

I am using NX 8.4.13 and the .nxignore file is created but it seems not to work.

Can you file an issue please and provide a small reproduction with example nxignore file?

@wesleygrimes I think we have an open issue #895, release 8.4.13 included that issue but it still open

@alfaproject @wesleygrimes This looks like a start to a solution, which I would love to see in NX!

I am adding this ability, although I think we will go a slightly different route. I will reference the PR when it is submitted.

Any update on this?

Hi,

I saw there is a pullrequest for .nxignore --> PR #1585

However it only works for the workspace-lint command and not the affected commands

Can it be added in? I see that its added in the core/file-utils.ts in the function allFilesInDir

However thats only use in the workspace-lint as i observed.

Can we add the ignore machanism for the affected as well?

From what I observe there are several places this mechanism can be coded in, if someone would guide with me it would be great.

  1. We either add a project level check with tags/flags at these functions

    • getTouchedProjects,
    • getImplicitlyTouchedProjects,
    • getImplicitlyTouchedProjectsByJsonChanges,
    • getTouchedProjectsInNxJson,
    • getTouchedProjectsInWorkspaceJson
  2. Or we can go directly for the files using glob pattern in .nxignore

    • Either in shared.parseFiles after the git command are run
    • Or add directly into the file-utils.calculateFileChanges

I like the

add directly into the file-utils.calculateFileChanges

option the most. Please advise :D, If so can i work on it and open a PR?

same here. I have the feeling, that the **/generated entry in my .nxignore file gets ignored (haha). In this case, the npm run affected:lint --fix --parallel --files=... command still tries to lint some auto-generated files (i.e., from a 3rd-party-codegen package). Obviously, this code is not lint-compliant and, therefore, cannot be committed properly :(

Does anyone have a solution for this?!

Hi, sorry about this.

This was mislabeled as stale. We are testing ways to mark _not reproducible_ issues as stale so that we can focus on actionable items but our initial experiment was too broad and unintentionally labeled this issue as stale.

Was this page helpful?
0 / 5 - 0 ratings