feat(core): add parallelism to target configuration (#26820)
<!-- 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 --> ## Related Issue(s) <!-- Please link the issue being fixed so it gets closed when this is merged. --> Fixes #
This commit is contained in:
parent
37f0ccaa20
commit
39e104b6c3
@ -22,6 +22,7 @@ Target's configuration
|
||||
- [metadata](../../devkit/documents/TargetConfiguration#metadata): TargetMetadata
|
||||
- [options](../../devkit/documents/TargetConfiguration#options): T
|
||||
- [outputs](../../devkit/documents/TargetConfiguration#outputs): string[]
|
||||
- [parallelism](../../devkit/documents/TargetConfiguration#parallelism): boolean
|
||||
|
||||
## Properties
|
||||
|
||||
@ -109,3 +110,12 @@ Target's options. They are passed in to the executor.
|
||||
|
||||
List of the target's outputs. The outputs will be cached by the Nx computation
|
||||
caching engine.
|
||||
|
||||
---
|
||||
|
||||
### parallelism
|
||||
|
||||
• `Optional` **parallelism**: `boolean`
|
||||
|
||||
Whether this target can be run in parallel with other tasks
|
||||
Default is true
|
||||
|
||||
@ -13,6 +13,7 @@ A representation of the invocation of an Executor
|
||||
- [id](../../devkit/documents/Task#id): string
|
||||
- [outputs](../../devkit/documents/Task#outputs): string[]
|
||||
- [overrides](../../devkit/documents/Task#overrides): any
|
||||
- [parallelism](../../devkit/documents/Task#parallelism): boolean
|
||||
- [projectRoot](../../devkit/documents/Task#projectroot): string
|
||||
- [startTime](../../devkit/documents/Task#starttime): number
|
||||
- [target](../../devkit/documents/Task#target): Object
|
||||
@ -84,6 +85,14 @@ Overrides for the configured options of the target
|
||||
|
||||
---
|
||||
|
||||
### parallelism
|
||||
|
||||
• **parallelism**: `boolean`
|
||||
|
||||
Determines if a given task should be parallelizable.
|
||||
|
||||
---
|
||||
|
||||
### projectRoot
|
||||
|
||||
• `Optional` **projectRoot**: `string`
|
||||
|
||||
@ -121,6 +121,7 @@ describe('@nx/cypress/plugin', () => {
|
||||
"{projectRoot}/dist/videos",
|
||||
"{projectRoot}/dist/screenshots",
|
||||
],
|
||||
"parallelism": false,
|
||||
},
|
||||
"open-cypress": {
|
||||
"command": "cypress open",
|
||||
@ -329,6 +330,7 @@ describe('@nx/cypress/plugin', () => {
|
||||
"{projectRoot}/dist/videos",
|
||||
"{projectRoot}/dist/screenshots",
|
||||
],
|
||||
"parallelism": false,
|
||||
},
|
||||
"e2e-ci": {
|
||||
"cache": true,
|
||||
@ -369,6 +371,7 @@ describe('@nx/cypress/plugin', () => {
|
||||
"{projectRoot}/dist/videos",
|
||||
"{projectRoot}/dist/screenshots",
|
||||
],
|
||||
"parallelism": false,
|
||||
},
|
||||
"e2e-ci--src/test.cy.ts": {
|
||||
"cache": true,
|
||||
@ -404,6 +407,7 @@ describe('@nx/cypress/plugin', () => {
|
||||
"{projectRoot}/dist/videos",
|
||||
"{projectRoot}/dist/screenshots",
|
||||
],
|
||||
"parallelism": false,
|
||||
},
|
||||
"open-cypress": {
|
||||
"command": "cypress open",
|
||||
|
||||
@ -211,6 +211,7 @@ async function buildCypressTargets(
|
||||
cache: true,
|
||||
inputs: getInputs(namedInputs),
|
||||
outputs: getOutputs(projectRoot, cypressConfig, 'e2e'),
|
||||
parallelism: false,
|
||||
metadata: {
|
||||
technologies: ['cypress'],
|
||||
description: 'Runs Cypress Tests',
|
||||
@ -276,6 +277,7 @@ async function buildCypressTargets(
|
||||
options: {
|
||||
cwd: projectRoot,
|
||||
},
|
||||
parallelism: false,
|
||||
metadata: {
|
||||
technologies: ['cypress'],
|
||||
description: `Runs Cypress Tests in ${relativeSpecFilePath} in CI`,
|
||||
@ -300,6 +302,7 @@ async function buildCypressTargets(
|
||||
inputs,
|
||||
outputs,
|
||||
dependsOn,
|
||||
parallelism: false,
|
||||
metadata: {
|
||||
technologies: ['cypress'],
|
||||
description: 'Runs Cypress Tests in CI',
|
||||
|
||||
@ -389,30 +389,35 @@ describe('calculateDependenciesFromTaskGraph', () => {
|
||||
overrides: {},
|
||||
target: { project: 'lib1', target: 'build' },
|
||||
outputs: [],
|
||||
parallelism: true,
|
||||
},
|
||||
'lib2:build': {
|
||||
id: 'lib2:build',
|
||||
overrides: {},
|
||||
target: { project: 'lib2', target: 'build' },
|
||||
outputs: [],
|
||||
parallelism: true,
|
||||
},
|
||||
'lib2:build-base': {
|
||||
id: 'lib2:build-base',
|
||||
overrides: {},
|
||||
target: { project: 'lib2', target: 'build-base' },
|
||||
outputs: [],
|
||||
parallelism: true,
|
||||
},
|
||||
'lib3:build': {
|
||||
id: 'lib3:build',
|
||||
overrides: {},
|
||||
target: { project: 'lib3', target: 'build' },
|
||||
outputs: [],
|
||||
parallelism: true,
|
||||
},
|
||||
'lib4:build': {
|
||||
id: 'lib4:build',
|
||||
overrides: {},
|
||||
target: { project: 'lib4', target: 'build' },
|
||||
outputs: [],
|
||||
parallelism: true,
|
||||
},
|
||||
},
|
||||
};
|
||||
@ -559,48 +564,56 @@ describe('calculateDependenciesFromTaskGraph', () => {
|
||||
overrides: {},
|
||||
target: { project: 'lib1', target: 'build' },
|
||||
outputs: [],
|
||||
parallelism: true,
|
||||
},
|
||||
'lib1:build-base': {
|
||||
id: 'lib1:build-base',
|
||||
overrides: {},
|
||||
target: { project: 'lib1', target: 'build-base' },
|
||||
outputs: [],
|
||||
parallelism: true,
|
||||
},
|
||||
'lib2:build': {
|
||||
id: 'lib2:build',
|
||||
overrides: {},
|
||||
target: { project: 'lib2', target: 'build' },
|
||||
outputs: [],
|
||||
parallelism: true,
|
||||
},
|
||||
'lib2:build-base': {
|
||||
id: 'lib2:build-base',
|
||||
overrides: {},
|
||||
target: { project: 'lib2', target: 'build-base' },
|
||||
outputs: [],
|
||||
parallelism: true,
|
||||
},
|
||||
'lib3:build': {
|
||||
id: 'lib3:build',
|
||||
overrides: {},
|
||||
target: { project: 'lib3', target: 'build' },
|
||||
outputs: [],
|
||||
parallelism: true,
|
||||
},
|
||||
'lib3:build-base': {
|
||||
id: 'lib3:build-base',
|
||||
overrides: {},
|
||||
target: { project: 'lib3', target: 'build-base' },
|
||||
outputs: [],
|
||||
parallelism: true,
|
||||
},
|
||||
'lib4:build': {
|
||||
id: 'lib4:build',
|
||||
overrides: {},
|
||||
target: { project: 'lib4', target: 'build' },
|
||||
outputs: [],
|
||||
parallelism: true,
|
||||
},
|
||||
'lib4:build-base': {
|
||||
id: 'lib4:build-base',
|
||||
overrides: {},
|
||||
target: { project: 'lib4', target: 'build-base' },
|
||||
outputs: [],
|
||||
parallelism: true,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
@ -4,6 +4,27 @@
|
||||
"title": "JSON schema for Nx projects",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"name": {
|
||||
"type": "string",
|
||||
"description": "Project's name. Optional if specified in workspace.json"
|
||||
},
|
||||
"root": {
|
||||
"type": "string",
|
||||
"description": "Project's location relative to the root of the workspace"
|
||||
},
|
||||
"sourceRoot": {
|
||||
"type": "string",
|
||||
"description": "The location of project's sources relative to the root of the workspace"
|
||||
},
|
||||
"projectType": {
|
||||
"type": "string",
|
||||
"description": "Type of project supported",
|
||||
"enum": ["library", "application"]
|
||||
},
|
||||
"generators": {
|
||||
"type": "object",
|
||||
"description": "List of default values used by generators"
|
||||
},
|
||||
"namedInputs": {
|
||||
"type": "object",
|
||||
"description": "Named inputs used by inputs defined in targets",
|
||||
@ -112,6 +133,11 @@
|
||||
"cache": {
|
||||
"type": "boolean",
|
||||
"description": "Specifies if the given target should be cacheable"
|
||||
},
|
||||
"parallelism": {
|
||||
"type": "boolean",
|
||||
"default": true,
|
||||
"description": "Whether this target can be run in parallel with other tasks"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -76,6 +76,11 @@ export interface Task {
|
||||
* Determines if a given task should be cacheable.
|
||||
*/
|
||||
cache?: boolean;
|
||||
|
||||
/**
|
||||
* Determines if a given task should be parallelizable.
|
||||
*/
|
||||
parallelism: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -73,6 +73,7 @@ describe('Workspaces', () => {
|
||||
],
|
||||
"executor": "@nx/js:release-publish",
|
||||
"options": {},
|
||||
"parallelism": true,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
@ -230,4 +230,10 @@ export interface TargetConfiguration<T = any> {
|
||||
* Metadata about the target
|
||||
*/
|
||||
metadata?: TargetMetadata;
|
||||
|
||||
/**
|
||||
* Whether this target can be run in parallel with other tasks
|
||||
* Default is true
|
||||
*/
|
||||
parallelism?: boolean;
|
||||
}
|
||||
|
||||
@ -155,21 +155,21 @@ describe('native task hasher', () => {
|
||||
"AllExternalDependencies": "3244421341483603138",
|
||||
"env:NONEXISTENTENV": "3244421341483603138",
|
||||
"env:TESTENV": "11441948532827618368",
|
||||
"parent:ProjectConfiguration": "4131510303084753861",
|
||||
"parent:ProjectConfiguration": "3608670998275221195",
|
||||
"parent:TsConfig": "2264969541778889434",
|
||||
"parent:{projectRoot}/**/*": "15295586939211629225",
|
||||
"runtime:echo runtime123": "29846575039086708",
|
||||
"tagged:ProjectConfiguration": "1604492097835699503",
|
||||
"tagged:ProjectConfiguration": "8596726088057301092",
|
||||
"tagged:TsConfig": "2264969541778889434",
|
||||
"tagged:{projectRoot}/**/*": "112200405683630828",
|
||||
"unrelated:ProjectConfiguration": "439515135357674343",
|
||||
"unrelated:ProjectConfiguration": "11133337791644294114",
|
||||
"unrelated:TsConfig": "2264969541778889434",
|
||||
"unrelated:{projectRoot}/**/*": "10505120368757496776",
|
||||
"{workspaceRoot}/.gitignore": "3244421341483603138",
|
||||
"{workspaceRoot}/.nxignore": "3244421341483603138",
|
||||
"{workspaceRoot}/nx.json": "5219582320960288192",
|
||||
},
|
||||
"value": "6332317845632665670",
|
||||
"value": "17193008237392864712",
|
||||
},
|
||||
]
|
||||
`);
|
||||
@ -226,17 +226,17 @@ describe('native task hasher', () => {
|
||||
{
|
||||
"details": {
|
||||
"AllExternalDependencies": "3244421341483603138",
|
||||
"child:ProjectConfiguration": "7051130583729928229",
|
||||
"child:ProjectConfiguration": "710102491746666394",
|
||||
"child:TsConfig": "2264969541778889434",
|
||||
"child:{projectRoot}/**/*": "7694964870822928111",
|
||||
"parent:ProjectConfiguration": "7704699416930647320",
|
||||
"parent:ProjectConfiguration": "8031122597231773116",
|
||||
"parent:TsConfig": "2264969541778889434",
|
||||
"parent:{projectRoot}/**/*": "15295586939211629225",
|
||||
"{workspaceRoot}/.gitignore": "3244421341483603138",
|
||||
"{workspaceRoot}/.nxignore": "3244421341483603138",
|
||||
"{workspaceRoot}/nx.json": "5219582320960288192",
|
||||
},
|
||||
"value": "18412450685244791672",
|
||||
"value": "4141725338792606519",
|
||||
}
|
||||
`);
|
||||
});
|
||||
@ -307,17 +307,17 @@ describe('native task hasher', () => {
|
||||
{
|
||||
"details": {
|
||||
"AllExternalDependencies": "3244421341483603138",
|
||||
"child:ProjectConfiguration": "2562552455862160288",
|
||||
"child:ProjectConfiguration": "13051054958929525761",
|
||||
"child:TsConfig": "2264969541778889434",
|
||||
"child:{projectRoot}/**/*": "7694964870822928111",
|
||||
"parent:!{projectRoot}/**/*.spec.ts": "7663204892242899157",
|
||||
"parent:ProjectConfiguration": "4131510303084753861",
|
||||
"parent:ProjectConfiguration": "3608670998275221195",
|
||||
"parent:TsConfig": "2264969541778889434",
|
||||
"{workspaceRoot}/.gitignore": "3244421341483603138",
|
||||
"{workspaceRoot}/.nxignore": "3244421341483603138",
|
||||
"{workspaceRoot}/nx.json": "4641558175996703359",
|
||||
},
|
||||
"value": "5825507912633865657",
|
||||
"value": "12061654175538209437",
|
||||
}
|
||||
`);
|
||||
});
|
||||
@ -379,25 +379,25 @@ describe('native task hasher', () => {
|
||||
"details": {
|
||||
"AllExternalDependencies": "3244421341483603138",
|
||||
"parent:!{projectRoot}/**/*.spec.ts": "7663204892242899157",
|
||||
"parent:ProjectConfiguration": "8008830016795210968",
|
||||
"parent:ProjectConfiguration": "16402137858974842465",
|
||||
"parent:TsConfig": "2264969541778889434",
|
||||
"{workspaceRoot}/.gitignore": "3244421341483603138",
|
||||
"{workspaceRoot}/.nxignore": "3244421341483603138",
|
||||
"{workspaceRoot}/nx.json": "4641558175996703359",
|
||||
},
|
||||
"value": "16919987205625802616",
|
||||
"value": "1683972350273460485",
|
||||
},
|
||||
{
|
||||
"details": {
|
||||
"AllExternalDependencies": "3244421341483603138",
|
||||
"parent:ProjectConfiguration": "8008830016795210968",
|
||||
"parent:ProjectConfiguration": "16402137858974842465",
|
||||
"parent:TsConfig": "2264969541778889434",
|
||||
"parent:{projectRoot}/**/*": "15295586939211629225",
|
||||
"{workspaceRoot}/.gitignore": "3244421341483603138",
|
||||
"{workspaceRoot}/.nxignore": "3244421341483603138",
|
||||
"{workspaceRoot}/nx.json": "4641558175996703359",
|
||||
},
|
||||
"value": "2732213649703581334",
|
||||
"value": "2469956415584213984",
|
||||
},
|
||||
]
|
||||
`);
|
||||
@ -478,10 +478,10 @@ describe('native task hasher', () => {
|
||||
"details": {
|
||||
"AllExternalDependencies": "3244421341483603138",
|
||||
"child:!{projectRoot}/**/*.spec.ts": "13790135045935437026",
|
||||
"child:ProjectConfiguration": "11541456798478268276",
|
||||
"child:ProjectConfiguration": "10085593111011845427",
|
||||
"child:TsConfig": "2264969541778889434",
|
||||
"env:MY_TEST_HASH_ENV": "17357374746554314488",
|
||||
"parent:ProjectConfiguration": "2287392686890337925",
|
||||
"parent:ProjectConfiguration": "14398811678394411425",
|
||||
"parent:TsConfig": "2264969541778889434",
|
||||
"parent:{projectRoot}/**/*": "15295586939211629225",
|
||||
"{workspaceRoot}/.gitignore": "3244421341483603138",
|
||||
@ -490,7 +490,7 @@ describe('native task hasher', () => {
|
||||
"{workspaceRoot}/global2": "13625885481717016690",
|
||||
"{workspaceRoot}/nx.json": "10897751101872977225",
|
||||
},
|
||||
"value": "1217581064022758580",
|
||||
"value": "12563443797830627612",
|
||||
},
|
||||
]
|
||||
`);
|
||||
@ -539,14 +539,14 @@ describe('native task hasher', () => {
|
||||
{
|
||||
"details": {
|
||||
"AllExternalDependencies": "3244421341483603138",
|
||||
"parent:ProjectConfiguration": "4131510303084753861",
|
||||
"parent:ProjectConfiguration": "3608670998275221195",
|
||||
"parent:TsConfig": "8661678577354855152",
|
||||
"parent:{projectRoot}/**/*": "15295586939211629225",
|
||||
"{workspaceRoot}/.gitignore": "3244421341483603138",
|
||||
"{workspaceRoot}/.nxignore": "3244421341483603138",
|
||||
"{workspaceRoot}/nx.json": "5219582320960288192",
|
||||
},
|
||||
"value": "9574395623667735815",
|
||||
"value": "192468752006013407",
|
||||
}
|
||||
`);
|
||||
});
|
||||
@ -616,17 +616,17 @@ describe('native task hasher', () => {
|
||||
{
|
||||
"details": {
|
||||
"AllExternalDependencies": "3244421341483603138",
|
||||
"child:ProjectConfiguration": "3898391056798628885",
|
||||
"child:ProjectConfiguration": "13748859057138736105",
|
||||
"child:TsConfig": "2264969541778889434",
|
||||
"child:{projectRoot}/**/*": "7694964870822928111",
|
||||
"parent:ProjectConfiguration": "4131510303084753861",
|
||||
"parent:ProjectConfiguration": "3608670998275221195",
|
||||
"parent:TsConfig": "2264969541778889434",
|
||||
"parent:{projectRoot}/**/*": "15295586939211629225",
|
||||
"{workspaceRoot}/.gitignore": "3244421341483603138",
|
||||
"{workspaceRoot}/.nxignore": "3244421341483603138",
|
||||
"{workspaceRoot}/nx.json": "5219582320960288192",
|
||||
},
|
||||
"value": "3140483997697830788",
|
||||
"value": "571545311225175014",
|
||||
}
|
||||
`);
|
||||
|
||||
@ -640,17 +640,17 @@ describe('native task hasher', () => {
|
||||
{
|
||||
"details": {
|
||||
"AllExternalDependencies": "3244421341483603138",
|
||||
"child:ProjectConfiguration": "3898391056798628885",
|
||||
"child:ProjectConfiguration": "13748859057138736105",
|
||||
"child:TsConfig": "2264969541778889434",
|
||||
"child:{projectRoot}/**/*": "7694964870822928111",
|
||||
"parent:ProjectConfiguration": "4131510303084753861",
|
||||
"parent:ProjectConfiguration": "3608670998275221195",
|
||||
"parent:TsConfig": "2264969541778889434",
|
||||
"parent:{projectRoot}/**/*": "15295586939211629225",
|
||||
"{workspaceRoot}/.gitignore": "3244421341483603138",
|
||||
"{workspaceRoot}/.nxignore": "3244421341483603138",
|
||||
"{workspaceRoot}/nx.json": "5219582320960288192",
|
||||
},
|
||||
"value": "3140483997697830788",
|
||||
"value": "571545311225175014",
|
||||
}
|
||||
`);
|
||||
});
|
||||
|
||||
@ -121,6 +121,7 @@ describe('TaskHasher', () => {
|
||||
id: 'parent-build',
|
||||
overrides: { prop: 'prop-value' },
|
||||
outputs: [],
|
||||
parallelism: true,
|
||||
},
|
||||
{
|
||||
roots: ['parent-build'],
|
||||
@ -130,6 +131,7 @@ describe('TaskHasher', () => {
|
||||
target: { project: 'parent', target: 'build' },
|
||||
overrides: {},
|
||||
outputs: [],
|
||||
parallelism: true,
|
||||
},
|
||||
},
|
||||
dependencies: {},
|
||||
@ -188,6 +190,7 @@ describe('TaskHasher', () => {
|
||||
id: 'parent-build',
|
||||
overrides: { prop: 'prop-value' },
|
||||
outputs: [],
|
||||
parallelism: true,
|
||||
},
|
||||
{
|
||||
roots: ['child-build'],
|
||||
@ -197,12 +200,14 @@ describe('TaskHasher', () => {
|
||||
target: { project: 'parent', target: 'build' },
|
||||
overrides: {},
|
||||
outputs: [],
|
||||
parallelism: true,
|
||||
},
|
||||
'child-build': {
|
||||
id: 'child-build',
|
||||
target: { project: 'child', target: 'build' },
|
||||
overrides: {},
|
||||
outputs: [],
|
||||
parallelism: true,
|
||||
},
|
||||
},
|
||||
dependencies: {
|
||||
@ -275,6 +280,7 @@ describe('TaskHasher', () => {
|
||||
id: 'parent-build',
|
||||
overrides: { prop: 'prop-value' },
|
||||
outputs: [],
|
||||
parallelism: true,
|
||||
},
|
||||
{
|
||||
roots: ['child-build'],
|
||||
@ -284,12 +290,14 @@ describe('TaskHasher', () => {
|
||||
target: { project: 'parent', target: 'build' },
|
||||
overrides: {},
|
||||
outputs: [],
|
||||
parallelism: true,
|
||||
},
|
||||
'child-build': {
|
||||
id: 'child-build',
|
||||
target: { project: 'child', target: 'build' },
|
||||
overrides: {},
|
||||
outputs: [],
|
||||
parallelism: true,
|
||||
},
|
||||
},
|
||||
dependencies: {
|
||||
@ -354,6 +362,7 @@ describe('TaskHasher', () => {
|
||||
target: { project: 'parent', target: 'test' },
|
||||
overrides: {},
|
||||
outputs: [],
|
||||
parallelism: true,
|
||||
},
|
||||
},
|
||||
dependencies: {},
|
||||
@ -365,6 +374,7 @@ describe('TaskHasher', () => {
|
||||
id: 'parent-test',
|
||||
overrides: { prop: 'prop-value' },
|
||||
outputs: [],
|
||||
parallelism: true,
|
||||
},
|
||||
taskGraph,
|
||||
{}
|
||||
@ -378,6 +388,7 @@ describe('TaskHasher', () => {
|
||||
id: 'parent-build',
|
||||
overrides: { prop: 'prop-value' },
|
||||
outputs: [],
|
||||
parallelism: true,
|
||||
},
|
||||
taskGraph,
|
||||
{}
|
||||
@ -459,12 +470,14 @@ describe('TaskHasher', () => {
|
||||
target: { project: 'parent', target: 'test' },
|
||||
overrides: {},
|
||||
outputs: [],
|
||||
parallelism: true,
|
||||
},
|
||||
'child-test': {
|
||||
id: 'child-test',
|
||||
target: { project: 'child', target: 'test' },
|
||||
overrides: {},
|
||||
outputs: [],
|
||||
parallelism: true,
|
||||
},
|
||||
},
|
||||
dependencies: {
|
||||
@ -478,6 +491,7 @@ describe('TaskHasher', () => {
|
||||
id: 'parent-test',
|
||||
overrides: { prop: 'prop-value' },
|
||||
outputs: [],
|
||||
parallelism: true,
|
||||
},
|
||||
taskGraph,
|
||||
{ MY_TEST_HASH_ENV: 'MY_TEST_HASH_ENV_VALUE' }
|
||||
@ -491,6 +505,7 @@ describe('TaskHasher', () => {
|
||||
id: 'child-test',
|
||||
overrides: { prop: 'prop-value' },
|
||||
outputs: [],
|
||||
parallelism: true,
|
||||
},
|
||||
taskGraph,
|
||||
{ MY_TEST_HASH_ENV: 'MY_TEST_HASH_ENV_VALUE' }
|
||||
@ -559,6 +574,7 @@ describe('TaskHasher', () => {
|
||||
id: 'parent-build',
|
||||
overrides: { prop: 'prop-value' },
|
||||
outputs: [],
|
||||
parallelism: true,
|
||||
},
|
||||
{
|
||||
roots: ['child-build'],
|
||||
@ -568,12 +584,14 @@ describe('TaskHasher', () => {
|
||||
target: { project: 'parent', target: 'build' },
|
||||
overrides: {},
|
||||
outputs: [],
|
||||
parallelism: true,
|
||||
},
|
||||
'child-build': {
|
||||
id: 'child-build',
|
||||
target: { project: 'child', target: 'build' },
|
||||
overrides: {},
|
||||
outputs: [],
|
||||
parallelism: true,
|
||||
},
|
||||
},
|
||||
dependencies: {
|
||||
@ -622,6 +640,7 @@ describe('TaskHasher', () => {
|
||||
id: 'parent-build',
|
||||
overrides: { prop: 'prop-value' },
|
||||
outputs: [],
|
||||
parallelism: true,
|
||||
},
|
||||
{
|
||||
roots: ['parent:build'],
|
||||
@ -631,6 +650,7 @@ describe('TaskHasher', () => {
|
||||
target: { project: 'parent', target: 'build' },
|
||||
overrides: {},
|
||||
outputs: [],
|
||||
parallelism: true,
|
||||
},
|
||||
},
|
||||
dependencies: {},
|
||||
@ -687,12 +707,14 @@ describe('TaskHasher', () => {
|
||||
target: { project: 'parent', target: 'build' },
|
||||
overrides: {},
|
||||
outputs: [],
|
||||
parallelism: true,
|
||||
},
|
||||
'child-build': {
|
||||
id: 'child-build',
|
||||
target: { project: 'child', target: 'build' },
|
||||
overrides: {},
|
||||
outputs: [],
|
||||
parallelism: true,
|
||||
},
|
||||
},
|
||||
dependencies: {
|
||||
@ -706,6 +728,7 @@ describe('TaskHasher', () => {
|
||||
id: 'parent-build',
|
||||
overrides: { prop: 'prop-value' },
|
||||
outputs: [],
|
||||
parallelism: true,
|
||||
},
|
||||
taskGraph,
|
||||
{}
|
||||
@ -719,6 +742,7 @@ describe('TaskHasher', () => {
|
||||
id: 'child-build',
|
||||
overrides: { prop: 'prop-value' },
|
||||
outputs: [],
|
||||
parallelism: true,
|
||||
},
|
||||
taskGraph,
|
||||
{}
|
||||
@ -763,6 +787,7 @@ describe('TaskHasher', () => {
|
||||
id: 'parent-build',
|
||||
overrides: {},
|
||||
outputs: [],
|
||||
parallelism: true,
|
||||
},
|
||||
{
|
||||
roots: ['parent:build'],
|
||||
@ -772,6 +797,7 @@ describe('TaskHasher', () => {
|
||||
target: { project: 'parent', target: 'build' },
|
||||
overrides: {},
|
||||
outputs: [],
|
||||
parallelism: true,
|
||||
},
|
||||
},
|
||||
dependencies: {},
|
||||
@ -834,6 +860,7 @@ describe('TaskHasher', () => {
|
||||
id: 'app-build',
|
||||
overrides: { prop: 'prop-value' },
|
||||
outputs: [],
|
||||
parallelism: true,
|
||||
},
|
||||
{
|
||||
roots: ['app-build'],
|
||||
@ -843,6 +870,7 @@ describe('TaskHasher', () => {
|
||||
target: { project: 'app', target: 'build' },
|
||||
overrides: {},
|
||||
outputs: [],
|
||||
parallelism: true,
|
||||
},
|
||||
},
|
||||
dependencies: {},
|
||||
@ -902,6 +930,7 @@ describe('TaskHasher', () => {
|
||||
id: 'app-build',
|
||||
overrides: { prop: 'prop-value' },
|
||||
outputs: [],
|
||||
parallelism: true,
|
||||
},
|
||||
{
|
||||
roots: ['app-build'],
|
||||
@ -911,6 +940,7 @@ describe('TaskHasher', () => {
|
||||
target: { project: 'app', target: 'build' },
|
||||
overrides: {},
|
||||
outputs: [],
|
||||
parallelism: true,
|
||||
},
|
||||
},
|
||||
dependencies: {},
|
||||
@ -961,6 +991,7 @@ describe('TaskHasher', () => {
|
||||
id: 'app-build',
|
||||
overrides: { prop: 'prop-value' },
|
||||
outputs: [],
|
||||
parallelism: true,
|
||||
},
|
||||
{
|
||||
roots: ['app-build'],
|
||||
@ -970,6 +1001,7 @@ describe('TaskHasher', () => {
|
||||
target: { project: 'app', target: 'build' },
|
||||
overrides: {},
|
||||
outputs: [],
|
||||
parallelism: true,
|
||||
},
|
||||
},
|
||||
dependencies: {},
|
||||
@ -1051,12 +1083,14 @@ describe('TaskHasher', () => {
|
||||
target: { project: 'a', target: 'build' },
|
||||
overrides: {},
|
||||
outputs: [],
|
||||
parallelism: true,
|
||||
},
|
||||
'b-build': {
|
||||
id: 'b-build',
|
||||
target: { project: 'b', target: 'build' },
|
||||
overrides: {},
|
||||
outputs: [],
|
||||
parallelism: true,
|
||||
},
|
||||
},
|
||||
dependencies: {},
|
||||
@ -1071,6 +1105,7 @@ describe('TaskHasher', () => {
|
||||
target: { project: 'a', target: 'build' },
|
||||
overrides: {},
|
||||
outputs: [],
|
||||
parallelism: true,
|
||||
},
|
||||
taskGraph,
|
||||
{}
|
||||
@ -1081,6 +1116,7 @@ describe('TaskHasher', () => {
|
||||
target: { project: 'b', target: 'build' },
|
||||
overrides: {},
|
||||
outputs: [],
|
||||
parallelism: true,
|
||||
},
|
||||
taskGraph,
|
||||
{}
|
||||
@ -1092,6 +1128,7 @@ describe('TaskHasher', () => {
|
||||
target: { project: 'b', target: 'build' },
|
||||
overrides: {},
|
||||
outputs: [],
|
||||
parallelism: true,
|
||||
},
|
||||
taskGraph,
|
||||
{}
|
||||
@ -1102,6 +1139,7 @@ describe('TaskHasher', () => {
|
||||
target: { project: 'a', target: 'build' },
|
||||
overrides: {},
|
||||
outputs: [],
|
||||
parallelism: true,
|
||||
},
|
||||
taskGraph,
|
||||
{}
|
||||
@ -1201,6 +1239,7 @@ describe('TaskHasher', () => {
|
||||
id: 'app-build',
|
||||
overrides: { prop: 'prop-value' },
|
||||
outputs: [],
|
||||
parallelism: true,
|
||||
},
|
||||
{
|
||||
roots: ['app-build'],
|
||||
@ -1210,6 +1249,7 @@ describe('TaskHasher', () => {
|
||||
target: { project: 'app', target: 'build' },
|
||||
overrides: {},
|
||||
outputs: [],
|
||||
parallelism: true,
|
||||
},
|
||||
},
|
||||
dependencies: {},
|
||||
@ -1418,6 +1458,7 @@ describe('TaskHasher', () => {
|
||||
id: 'app-build',
|
||||
overrides: { prop: 'prop-value' },
|
||||
outputs: [],
|
||||
parallelism: true,
|
||||
},
|
||||
{
|
||||
roots: ['app-build'],
|
||||
@ -1427,6 +1468,7 @@ describe('TaskHasher', () => {
|
||||
target: { project: 'app', target: 'build' },
|
||||
overrides: {},
|
||||
outputs: [],
|
||||
parallelism: true,
|
||||
},
|
||||
},
|
||||
dependencies: {},
|
||||
@ -1502,6 +1544,7 @@ describe('TaskHasher', () => {
|
||||
id: 'app-build',
|
||||
overrides: { prop: 'prop-value' },
|
||||
outputs: [],
|
||||
parallelism: true,
|
||||
},
|
||||
{
|
||||
roots: ['app-build'],
|
||||
@ -1511,6 +1554,7 @@ describe('TaskHasher', () => {
|
||||
target: { project: 'app', target: 'build' },
|
||||
overrides: {},
|
||||
outputs: [],
|
||||
parallelism: true,
|
||||
},
|
||||
},
|
||||
dependencies: {},
|
||||
@ -1584,6 +1628,7 @@ describe('TaskHasher', () => {
|
||||
id: 'app-build',
|
||||
overrides: { prop: 'prop-value' },
|
||||
outputs: [],
|
||||
parallelism: true,
|
||||
},
|
||||
{
|
||||
roots: ['app-build'],
|
||||
@ -1593,6 +1638,7 @@ describe('TaskHasher', () => {
|
||||
target: { project: 'app', target: 'build' },
|
||||
overrides: {},
|
||||
outputs: [],
|
||||
parallelism: true,
|
||||
},
|
||||
},
|
||||
dependencies: {},
|
||||
@ -1710,6 +1756,7 @@ describe('TaskHasher', () => {
|
||||
id: 'parent-build',
|
||||
overrides: { prop: 'prop-value' },
|
||||
outputs: [],
|
||||
parallelism: true,
|
||||
},
|
||||
{
|
||||
roots: ['grandchild-build'],
|
||||
@ -1719,18 +1766,21 @@ describe('TaskHasher', () => {
|
||||
target: { project: 'parent', target: 'build' },
|
||||
overrides: {},
|
||||
outputs: ['dist/libs/libs/parent'],
|
||||
parallelism: true,
|
||||
},
|
||||
'child-build': {
|
||||
id: 'child-build',
|
||||
target: { project: 'child', target: 'build' },
|
||||
overrides: {},
|
||||
outputs: ['dist/libs/libs/child'],
|
||||
parallelism: true,
|
||||
},
|
||||
'grandchild-build': {
|
||||
id: 'grandchild-build',
|
||||
target: { project: 'grandchild', target: 'build' },
|
||||
overrides: {},
|
||||
outputs: ['dist/libs/libs/grandchild'],
|
||||
parallelism: true,
|
||||
},
|
||||
},
|
||||
dependencies: {
|
||||
@ -1850,6 +1900,7 @@ describe('TaskHasher', () => {
|
||||
id: 'parent-build',
|
||||
overrides: { prop: 'prop-value' },
|
||||
outputs: [],
|
||||
parallelism: true,
|
||||
},
|
||||
{
|
||||
roots: ['grandchild-build'],
|
||||
@ -1859,18 +1910,21 @@ describe('TaskHasher', () => {
|
||||
target: { project: 'parent', target: 'build' },
|
||||
overrides: {},
|
||||
outputs: [],
|
||||
parallelism: true,
|
||||
},
|
||||
'child-build': {
|
||||
id: 'child-build',
|
||||
target: { project: 'child', target: 'build' },
|
||||
overrides: {},
|
||||
outputs: [],
|
||||
parallelism: true,
|
||||
},
|
||||
'grandchild-build': {
|
||||
id: 'grandchild-build',
|
||||
target: { project: 'grandchild', target: 'build' },
|
||||
overrides: {},
|
||||
outputs: [],
|
||||
parallelism: true,
|
||||
},
|
||||
},
|
||||
dependencies: {
|
||||
|
||||
1
packages/nx/src/native/index.d.ts
vendored
1
packages/nx/src/native/index.d.ts
vendored
@ -185,6 +185,7 @@ export interface Target {
|
||||
outputs?: Array<string>
|
||||
options?: string
|
||||
configurations?: string
|
||||
parallelism?: boolean
|
||||
}
|
||||
|
||||
export interface Task {
|
||||
|
||||
@ -16,6 +16,7 @@ pub struct Target {
|
||||
pub outputs: Option<Vec<String>>,
|
||||
pub options: Option<String>,
|
||||
pub configurations: Option<String>,
|
||||
pub parallelism: Option<bool>,
|
||||
}
|
||||
|
||||
#[napi(object)]
|
||||
|
||||
@ -21,12 +21,13 @@ pub fn hash_project_config(
|
||||
.sorted_by(|a, b| a.0.cmp(b.0))
|
||||
.map(|(k, v)| {
|
||||
format!(
|
||||
"{}{}{}{}{}",
|
||||
"{}{}{}{}{}{}",
|
||||
k,
|
||||
v.executor.as_deref().unwrap_or_default(),
|
||||
v.outputs.as_deref().unwrap_or_default().concat(),
|
||||
v.options.as_deref().unwrap_or_default(),
|
||||
v.configurations.as_deref().unwrap_or_default(),
|
||||
v.parallelism.unwrap_or_default()
|
||||
)
|
||||
})
|
||||
.collect::<Vec<_>>()
|
||||
@ -144,7 +145,7 @@ mod tests {
|
||||
assert_eq!(nx_project_hash.unwrap(), "3244421341483603138");
|
||||
|
||||
let js_project_hash = hash_project_config("js", &projects).unwrap();
|
||||
assert_eq!(js_project_hash, "18342193044952101577");
|
||||
assert_eq!(js_project_hash, "13565578942842640362");
|
||||
|
||||
let js_unsorted = hash_project_config("js-unsorted", &projects);
|
||||
assert_eq!(js_unsorted.unwrap(), js_project_hash);
|
||||
|
||||
@ -23,6 +23,7 @@ export function transformProjectGraphForRust(
|
||||
outputs: targetConfig.outputs,
|
||||
options: JSON.stringify(targetConfig.options),
|
||||
configurations: JSON.stringify(targetConfig.configurations),
|
||||
parallelism: targetConfig.parallelism,
|
||||
};
|
||||
}
|
||||
nodes[projectName] = {
|
||||
|
||||
@ -1520,6 +1520,7 @@ describe('project-configuration-utils', () => {
|
||||
"options": {
|
||||
"command": "echo libs/project",
|
||||
},
|
||||
"parallelism": true,
|
||||
}
|
||||
`);
|
||||
});
|
||||
@ -1676,6 +1677,7 @@ describe('project-configuration-utils', () => {
|
||||
"options": {
|
||||
"command": "echo a @ libs/a",
|
||||
},
|
||||
"parallelism": true,
|
||||
}
|
||||
`);
|
||||
});
|
||||
|
||||
@ -1122,5 +1122,7 @@ export function normalizeTarget(
|
||||
);
|
||||
}
|
||||
|
||||
target.parallelism ??= true;
|
||||
|
||||
return target;
|
||||
}
|
||||
|
||||
@ -107,6 +107,7 @@ describe('createTaskGraph', () => {
|
||||
outputs: [],
|
||||
overrides: { a: 123 },
|
||||
projectRoot: 'app1-root',
|
||||
parallelism: true,
|
||||
},
|
||||
},
|
||||
dependencies: {
|
||||
@ -137,6 +138,7 @@ describe('createTaskGraph', () => {
|
||||
outputs: [],
|
||||
overrides: { a: 123 },
|
||||
projectRoot: 'app1-root',
|
||||
parallelism: true,
|
||||
},
|
||||
'lib1:test': {
|
||||
id: 'lib1:test',
|
||||
@ -147,6 +149,7 @@ describe('createTaskGraph', () => {
|
||||
outputs: [],
|
||||
overrides: { a: 123 },
|
||||
projectRoot: 'lib1-root',
|
||||
parallelism: true,
|
||||
},
|
||||
},
|
||||
dependencies: {
|
||||
@ -286,6 +289,7 @@ describe('createTaskGraph', () => {
|
||||
outputs: [],
|
||||
overrides: {},
|
||||
projectRoot: 'lib1-root',
|
||||
parallelism: true,
|
||||
},
|
||||
'lib2:compile': {
|
||||
id: 'lib2:compile',
|
||||
@ -298,6 +302,7 @@ describe('createTaskGraph', () => {
|
||||
__overrides_unparsed__: [],
|
||||
},
|
||||
projectRoot: 'lib2-root',
|
||||
parallelism: true,
|
||||
},
|
||||
},
|
||||
dependencies: {
|
||||
@ -328,6 +333,7 @@ describe('createTaskGraph', () => {
|
||||
outputs: [],
|
||||
overrides: {},
|
||||
projectRoot: 'app1-root',
|
||||
parallelism: true,
|
||||
},
|
||||
'lib1:compile:libDefault': {
|
||||
id: 'lib1:compile:libDefault',
|
||||
@ -341,6 +347,7 @@ describe('createTaskGraph', () => {
|
||||
__overrides_unparsed__: [],
|
||||
},
|
||||
projectRoot: 'lib1-root',
|
||||
parallelism: true,
|
||||
},
|
||||
'lib2:compile:ci': {
|
||||
id: 'lib2:compile:ci',
|
||||
@ -354,6 +361,7 @@ describe('createTaskGraph', () => {
|
||||
__overrides_unparsed__: [],
|
||||
},
|
||||
projectRoot: 'lib2-root',
|
||||
parallelism: true,
|
||||
},
|
||||
},
|
||||
dependencies: {
|
||||
@ -454,6 +462,7 @@ describe('createTaskGraph', () => {
|
||||
project: 'app1',
|
||||
target: 'compile',
|
||||
},
|
||||
parallelism: true,
|
||||
},
|
||||
'lib3:compile': {
|
||||
id: 'lib3:compile',
|
||||
@ -466,6 +475,7 @@ describe('createTaskGraph', () => {
|
||||
project: 'lib3',
|
||||
target: 'compile',
|
||||
},
|
||||
parallelism: true,
|
||||
},
|
||||
},
|
||||
});
|
||||
@ -494,6 +504,7 @@ describe('createTaskGraph', () => {
|
||||
outputs: [],
|
||||
overrides: { a: '--value=app1-root' },
|
||||
projectRoot: 'app1-root',
|
||||
parallelism: true,
|
||||
},
|
||||
},
|
||||
dependencies: {
|
||||
@ -525,6 +536,7 @@ describe('createTaskGraph', () => {
|
||||
outputs: [],
|
||||
overrides: { a: '--base-href=/app1-root${deploymentId}' },
|
||||
projectRoot: 'app1-root',
|
||||
parallelism: true,
|
||||
},
|
||||
},
|
||||
dependencies: {
|
||||
@ -639,6 +651,7 @@ describe('createTaskGraph', () => {
|
||||
outputs: [],
|
||||
overrides: { myFlag: 'flag value' },
|
||||
projectRoot: 'app1-root',
|
||||
parallelism: true,
|
||||
},
|
||||
'app1:precompile': {
|
||||
id: 'app1:precompile',
|
||||
@ -649,6 +662,7 @@ describe('createTaskGraph', () => {
|
||||
outputs: [],
|
||||
overrides: { myFlag: 'flag value' },
|
||||
projectRoot: 'app1-root',
|
||||
parallelism: true,
|
||||
},
|
||||
'lib1:compile': {
|
||||
id: 'lib1:compile',
|
||||
@ -659,6 +673,7 @@ describe('createTaskGraph', () => {
|
||||
outputs: [],
|
||||
overrides: { myFlag: 'flag value' },
|
||||
projectRoot: 'lib1-root',
|
||||
parallelism: true,
|
||||
},
|
||||
'lib2:compile': {
|
||||
id: 'lib2:compile',
|
||||
@ -669,6 +684,7 @@ describe('createTaskGraph', () => {
|
||||
outputs: [],
|
||||
overrides: { __overrides_unparsed__: [] },
|
||||
projectRoot: 'lib2-root',
|
||||
parallelism: true,
|
||||
},
|
||||
},
|
||||
dependencies: {
|
||||
@ -706,6 +722,7 @@ describe('createTaskGraph', () => {
|
||||
__overrides_unparsed__: [],
|
||||
},
|
||||
projectRoot: 'app1-root',
|
||||
parallelism: true,
|
||||
},
|
||||
'app1:precompile': {
|
||||
id: 'app1:precompile',
|
||||
@ -718,6 +735,7 @@ describe('createTaskGraph', () => {
|
||||
__overrides_unparsed__: [],
|
||||
},
|
||||
projectRoot: 'app1-root',
|
||||
parallelism: true,
|
||||
},
|
||||
'app1:precompile2': {
|
||||
id: 'app1:precompile2',
|
||||
@ -730,6 +748,7 @@ describe('createTaskGraph', () => {
|
||||
__overrides_unparsed__: [],
|
||||
},
|
||||
projectRoot: 'app1-root',
|
||||
parallelism: true,
|
||||
},
|
||||
'lib1:compile': {
|
||||
id: 'lib1:compile',
|
||||
@ -742,6 +761,7 @@ describe('createTaskGraph', () => {
|
||||
__overrides_unparsed__: [],
|
||||
},
|
||||
projectRoot: 'lib1-root',
|
||||
parallelism: true,
|
||||
},
|
||||
},
|
||||
dependencies: {
|
||||
@ -779,6 +799,7 @@ describe('createTaskGraph', () => {
|
||||
__overrides_unparsed__: [],
|
||||
},
|
||||
projectRoot: 'app1-root',
|
||||
parallelism: true,
|
||||
},
|
||||
'app1:precompile': {
|
||||
id: 'app1:precompile',
|
||||
@ -791,6 +812,7 @@ describe('createTaskGraph', () => {
|
||||
__overrides_unparsed__: [],
|
||||
},
|
||||
projectRoot: 'app1-root',
|
||||
parallelism: true,
|
||||
},
|
||||
'app1:precompile2': {
|
||||
id: 'app1:precompile2',
|
||||
@ -803,6 +825,7 @@ describe('createTaskGraph', () => {
|
||||
__overrides_unparsed__: [],
|
||||
},
|
||||
projectRoot: 'app1-root',
|
||||
parallelism: true,
|
||||
},
|
||||
'lib1:compile': {
|
||||
id: 'lib1:compile',
|
||||
@ -815,6 +838,7 @@ describe('createTaskGraph', () => {
|
||||
__overrides_unparsed__: [],
|
||||
},
|
||||
projectRoot: 'lib1-root',
|
||||
parallelism: true,
|
||||
},
|
||||
},
|
||||
dependencies: {
|
||||
@ -921,6 +945,7 @@ describe('createTaskGraph', () => {
|
||||
__overrides_unparsed__: [],
|
||||
},
|
||||
projectRoot: 'app1-root',
|
||||
parallelism: true,
|
||||
},
|
||||
'lib1:compile': {
|
||||
id: 'lib1:compile',
|
||||
@ -933,6 +958,7 @@ describe('createTaskGraph', () => {
|
||||
__overrides_unparsed__: [],
|
||||
},
|
||||
projectRoot: 'lib1-root',
|
||||
parallelism: true,
|
||||
},
|
||||
'lib2:compile': {
|
||||
id: 'lib2:compile',
|
||||
@ -945,6 +971,7 @@ describe('createTaskGraph', () => {
|
||||
__overrides_unparsed__: [],
|
||||
},
|
||||
projectRoot: 'lib2-root',
|
||||
parallelism: true,
|
||||
},
|
||||
'lib3:compile': {
|
||||
id: 'lib3:compile',
|
||||
@ -957,6 +984,7 @@ describe('createTaskGraph', () => {
|
||||
__overrides_unparsed__: [],
|
||||
},
|
||||
projectRoot: 'lib3-root',
|
||||
parallelism: true,
|
||||
},
|
||||
},
|
||||
dependencies: {
|
||||
@ -1080,6 +1108,7 @@ describe('createTaskGraph', () => {
|
||||
projectRoot: 'infra1-root',
|
||||
outputs: [],
|
||||
overrides: { myFlag: 'flag value' },
|
||||
parallelism: true,
|
||||
},
|
||||
'app2:compile': {
|
||||
id: 'app2:compile',
|
||||
@ -1087,6 +1116,7 @@ describe('createTaskGraph', () => {
|
||||
projectRoot: 'app2-root',
|
||||
outputs: [],
|
||||
overrides: { __overrides_unparsed__: [] },
|
||||
parallelism: true,
|
||||
},
|
||||
'coreInfra:apply': {
|
||||
id: 'coreInfra:apply',
|
||||
@ -1094,6 +1124,7 @@ describe('createTaskGraph', () => {
|
||||
projectRoot: 'infra3-root',
|
||||
outputs: [],
|
||||
overrides: { myFlag: 'flag value' },
|
||||
parallelism: true,
|
||||
},
|
||||
'app1:compile': {
|
||||
id: 'app1:compile',
|
||||
@ -1101,6 +1132,7 @@ describe('createTaskGraph', () => {
|
||||
projectRoot: 'app1-root',
|
||||
outputs: [],
|
||||
overrides: { __overrides_unparsed__: [] },
|
||||
parallelism: true,
|
||||
},
|
||||
'infra2:apply': {
|
||||
id: 'infra2:apply',
|
||||
@ -1108,6 +1140,7 @@ describe('createTaskGraph', () => {
|
||||
projectRoot: 'infra2-root',
|
||||
outputs: [],
|
||||
overrides: { myFlag: 'flag value' },
|
||||
parallelism: true,
|
||||
},
|
||||
},
|
||||
dependencies: {
|
||||
@ -1174,6 +1207,7 @@ describe('createTaskGraph', () => {
|
||||
__overrides_unparsed__: [],
|
||||
},
|
||||
projectRoot: 'app1-root',
|
||||
parallelism: true,
|
||||
},
|
||||
'app1:test': {
|
||||
id: 'app1:test',
|
||||
@ -1186,6 +1220,7 @@ describe('createTaskGraph', () => {
|
||||
__overrides_unparsed__: [],
|
||||
},
|
||||
projectRoot: 'app1-root',
|
||||
parallelism: true,
|
||||
},
|
||||
},
|
||||
dependencies: {
|
||||
@ -1267,6 +1302,7 @@ describe('createTaskGraph', () => {
|
||||
__overrides_unparsed__: [],
|
||||
},
|
||||
projectRoot: 'app1-root',
|
||||
parallelism: true,
|
||||
},
|
||||
'app3:compile': {
|
||||
id: 'app3:compile',
|
||||
@ -1279,6 +1315,7 @@ describe('createTaskGraph', () => {
|
||||
__overrides_unparsed__: [],
|
||||
},
|
||||
projectRoot: 'app3-root',
|
||||
parallelism: true,
|
||||
},
|
||||
},
|
||||
dependencies: {
|
||||
@ -1357,6 +1394,7 @@ describe('createTaskGraph', () => {
|
||||
__overrides_unparsed__: [],
|
||||
},
|
||||
projectRoot: 'app1-root',
|
||||
parallelism: true,
|
||||
},
|
||||
'app3:compile': {
|
||||
id: 'app3:compile',
|
||||
@ -1369,6 +1407,7 @@ describe('createTaskGraph', () => {
|
||||
__overrides_unparsed__: [],
|
||||
},
|
||||
projectRoot: 'app3-root',
|
||||
parallelism: true,
|
||||
},
|
||||
},
|
||||
dependencies: {
|
||||
@ -1445,6 +1484,7 @@ describe('createTaskGraph', () => {
|
||||
__overrides_unparsed__: [],
|
||||
},
|
||||
projectRoot: 'app1-root',
|
||||
parallelism: true,
|
||||
},
|
||||
},
|
||||
dependencies: {
|
||||
@ -1478,6 +1518,7 @@ describe('createTaskGraph', () => {
|
||||
__overrides_unparsed__: [],
|
||||
},
|
||||
projectRoot: 'app1-root',
|
||||
parallelism: true,
|
||||
},
|
||||
'app2:compile': {
|
||||
id: 'app2:compile',
|
||||
@ -1490,6 +1531,7 @@ describe('createTaskGraph', () => {
|
||||
__overrides_unparsed__: [],
|
||||
},
|
||||
projectRoot: 'app2-root',
|
||||
parallelism: true,
|
||||
},
|
||||
},
|
||||
dependencies: {
|
||||
|
||||
@ -35,7 +35,7 @@ export class ProcessTasks {
|
||||
configuration: string,
|
||||
overrides: Object,
|
||||
excludeTaskDependencies: boolean
|
||||
) {
|
||||
): string[] {
|
||||
for (const projectName of projectNames) {
|
||||
for (const target of targets) {
|
||||
const project = this.projectGraph.nodes[projectName];
|
||||
@ -319,6 +319,7 @@ export class ProcessTasks {
|
||||
interpolatedOverrides
|
||||
),
|
||||
cache: project.data.targets[target].cache,
|
||||
parallelism: project.data.targets[target].parallelism ?? true,
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@ -5,7 +5,7 @@ import { DependencyType, ProjectGraph } from '../config/project-graph';
|
||||
import * as nxJsonUtils from '../config/nx-json';
|
||||
import * as executorUtils from '../command-line/run/executor-utils';
|
||||
|
||||
function createMockTask(id: string): Task {
|
||||
function createMockTask(id: string, parallelism: boolean = true): Task {
|
||||
const [project, target] = id.split(':');
|
||||
return {
|
||||
id,
|
||||
@ -15,6 +15,7 @@ function createMockTask(id: string): Task {
|
||||
},
|
||||
outputs: [],
|
||||
overrides: {},
|
||||
parallelism,
|
||||
};
|
||||
}
|
||||
|
||||
@ -411,4 +412,367 @@ describe('TasksSchedule', () => {
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('tasks with parallelism false', () => {
|
||||
describe('dependent tasks', () => {
|
||||
let taskSchedule: TasksSchedule;
|
||||
let taskGraph: TaskGraph;
|
||||
let app1Build: Task;
|
||||
let app2Build: Task;
|
||||
let lib1Build: Task;
|
||||
let lifeCycle: any;
|
||||
beforeEach(() => {
|
||||
// app1 depends on lib1
|
||||
// app2 does not depend on anything
|
||||
// lib1 does not depend on anything
|
||||
// all tasks have parallelism set to false
|
||||
app1Build = createMockTask('app1:build', false);
|
||||
app2Build = createMockTask('app2:build', false);
|
||||
lib1Build = createMockTask('lib1:build', false);
|
||||
|
||||
taskGraph = {
|
||||
tasks: {
|
||||
'app1:build': app1Build,
|
||||
'app2:build': app2Build,
|
||||
'lib1:build': lib1Build,
|
||||
},
|
||||
dependencies: {
|
||||
'app1:build': ['lib1:build'],
|
||||
'app2:build': [],
|
||||
'lib1:build': [],
|
||||
},
|
||||
roots: ['lib1:build', 'app2:build'],
|
||||
};
|
||||
jest.spyOn(nxJsonUtils, 'readNxJson').mockReturnValue({});
|
||||
jest.spyOn(executorUtils, 'getExecutorInformation').mockReturnValue({
|
||||
schema: {
|
||||
version: 2,
|
||||
properties: {},
|
||||
},
|
||||
implementationFactory: jest.fn(),
|
||||
batchImplementationFactory: jest.fn(),
|
||||
isNgCompat: true,
|
||||
isNxExecutor: true,
|
||||
});
|
||||
|
||||
const projectGraph: ProjectGraph = {
|
||||
nodes: {
|
||||
app1: {
|
||||
data: {
|
||||
root: 'app1',
|
||||
targets: {
|
||||
build: {
|
||||
executor: 'awesome-executors:build',
|
||||
},
|
||||
},
|
||||
},
|
||||
name: 'app1',
|
||||
type: 'app',
|
||||
},
|
||||
app2: {
|
||||
name: 'app2',
|
||||
type: 'app',
|
||||
data: {
|
||||
root: 'app2',
|
||||
targets: {
|
||||
build: {
|
||||
executor: 'awesome-executors:app2-build',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
lib1: {
|
||||
name: 'lib1',
|
||||
type: 'lib',
|
||||
data: {
|
||||
root: 'lib1',
|
||||
targets: {
|
||||
build: {
|
||||
executor: 'awesome-executors:build',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
} as any,
|
||||
dependencies: {
|
||||
app1: [
|
||||
{
|
||||
source: 'app1',
|
||||
target: 'lib1',
|
||||
type: DependencyType.static,
|
||||
},
|
||||
],
|
||||
app2: [
|
||||
{
|
||||
source: 'app2',
|
||||
target: 'lib1',
|
||||
type: DependencyType.static,
|
||||
},
|
||||
],
|
||||
},
|
||||
externalNodes: {},
|
||||
version: '5',
|
||||
};
|
||||
|
||||
lifeCycle = {
|
||||
startTask: jest.fn(),
|
||||
endTask: jest.fn(),
|
||||
scheduleTask: jest.fn(),
|
||||
};
|
||||
taskSchedule = new TasksSchedule(projectGraph, taskGraph, {
|
||||
lifeCycle,
|
||||
});
|
||||
});
|
||||
|
||||
describe('Without Batch Mode', () => {
|
||||
let original;
|
||||
beforeEach(() => {
|
||||
original = process.env['NX_BATCH_MODE'];
|
||||
process.env['NX_BATCH_MODE'] = 'false';
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
process.env['NX_BATCH_MODE'] = original;
|
||||
});
|
||||
|
||||
it('should begin with no scheduled tasks', () => {
|
||||
expect(taskSchedule.nextBatch()).toBeNull();
|
||||
expect(taskSchedule.nextTask()).toBeNull();
|
||||
});
|
||||
|
||||
it('should schedule root tasks first', async () => {
|
||||
// app1 depends on lib1, app2 has no dependencies
|
||||
await taskSchedule.scheduleNextTasks();
|
||||
expect(taskSchedule.nextTask()).toEqual(lib1Build);
|
||||
// since lib1 is not parallel, app2 should not be scheduled even though it has no dependencies
|
||||
expect(taskSchedule.nextTask()).toBeNull();
|
||||
taskSchedule.complete([lib1Build.id]);
|
||||
await taskSchedule.scheduleNextTasks();
|
||||
expect(taskSchedule.nextTask()).toEqual(app1Build);
|
||||
expect(taskSchedule.nextTask()).toBeNull(); // app2 should not be scheduled since app1 is not parallel and not completed
|
||||
taskSchedule.complete([app1Build.id]);
|
||||
await taskSchedule.scheduleNextTasks();
|
||||
expect(taskSchedule.nextTask()).toEqual(app2Build);
|
||||
taskSchedule.complete([app2Build.id]);
|
||||
expect(taskSchedule.hasTasks()).toEqual(false);
|
||||
});
|
||||
|
||||
it('should not schedule batches', async () => {
|
||||
await taskSchedule.scheduleNextTasks();
|
||||
|
||||
expect(taskSchedule.nextTask()).not.toBeNull();
|
||||
|
||||
expect(taskSchedule.nextBatch()).toBeNull();
|
||||
});
|
||||
});
|
||||
|
||||
describe('With Batch Mode', () => {
|
||||
let original;
|
||||
beforeEach(() => {
|
||||
original = process.env['NX_BATCH_MODE'];
|
||||
process.env['NX_BATCH_MODE'] = 'true';
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
process.env['NX_BATCH_MODE'] = original;
|
||||
});
|
||||
|
||||
it('should not schedule batches of tasks by different executors if task has parallelism false', async () => {
|
||||
await taskSchedule.scheduleNextTasks();
|
||||
|
||||
// since all tasks have parallelism false, they should not be batched
|
||||
expect(taskSchedule.nextTask()).toEqual(lib1Build);
|
||||
|
||||
expect(taskSchedule.nextBatch()).toBeNull();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('non-dependent tasks', () => {
|
||||
let taskSchedule: TasksSchedule;
|
||||
let taskGraph: TaskGraph;
|
||||
let app1Test: Task;
|
||||
let app2Test: Task;
|
||||
let lib1Test: Task;
|
||||
let lifeCycle: any;
|
||||
beforeEach(() => {
|
||||
// app1, app2, and lib1 do not depend on each other
|
||||
// all tasks have parallelism set to false
|
||||
app1Test = createMockTask('app1:test', false);
|
||||
app2Test = createMockTask('app2:test', false);
|
||||
lib1Test = createMockTask('lib1:test', false);
|
||||
|
||||
taskGraph = {
|
||||
tasks: {
|
||||
'app1:test': app1Test,
|
||||
'app2:test': app2Test,
|
||||
'lib1:test': lib1Test,
|
||||
},
|
||||
dependencies: {
|
||||
'app1:test': [],
|
||||
'app2:test': [],
|
||||
'lib1:test': [],
|
||||
},
|
||||
roots: ['app1:test', 'app2:test', 'lib1:test'],
|
||||
};
|
||||
jest.spyOn(nxJsonUtils, 'readNxJson').mockReturnValue({});
|
||||
jest.spyOn(executorUtils, 'getExecutorInformation').mockReturnValue({
|
||||
schema: {
|
||||
version: 2,
|
||||
properties: {},
|
||||
},
|
||||
implementationFactory: jest.fn(),
|
||||
batchImplementationFactory: jest.fn(),
|
||||
isNgCompat: true,
|
||||
isNxExecutor: true,
|
||||
});
|
||||
|
||||
const projectGraph: ProjectGraph = {
|
||||
nodes: {
|
||||
app1: {
|
||||
data: {
|
||||
root: 'app1',
|
||||
targets: {
|
||||
test: {
|
||||
executor: 'awesome-executors:test',
|
||||
parallelism: false,
|
||||
},
|
||||
},
|
||||
},
|
||||
name: 'app1',
|
||||
type: 'app',
|
||||
},
|
||||
app2: {
|
||||
name: 'app2',
|
||||
type: 'app',
|
||||
data: {
|
||||
root: 'app2',
|
||||
targets: {
|
||||
test: {
|
||||
executor: 'awesome-executors:app2-test',
|
||||
parallelism: false,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
lib1: {
|
||||
name: 'lib1',
|
||||
type: 'lib',
|
||||
data: {
|
||||
root: 'lib1',
|
||||
targets: {
|
||||
test: {
|
||||
executor: 'awesome-executors:test',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
} as any,
|
||||
dependencies: {
|
||||
app1: [
|
||||
{
|
||||
source: 'app1',
|
||||
target: 'lib1',
|
||||
type: DependencyType.static,
|
||||
},
|
||||
],
|
||||
app2: [
|
||||
{
|
||||
source: 'app2',
|
||||
target: 'lib1',
|
||||
type: DependencyType.static,
|
||||
},
|
||||
],
|
||||
},
|
||||
externalNodes: {},
|
||||
version: '5',
|
||||
};
|
||||
|
||||
lifeCycle = {
|
||||
startTask: jest.fn(),
|
||||
endTask: jest.fn(),
|
||||
scheduleTask: jest.fn(),
|
||||
};
|
||||
taskSchedule = new TasksSchedule(projectGraph, taskGraph, {
|
||||
lifeCycle,
|
||||
});
|
||||
});
|
||||
|
||||
describe('Without Batch Mode', () => {
|
||||
let original;
|
||||
beforeEach(() => {
|
||||
original = process.env['NX_BATCH_MODE'];
|
||||
process.env['NX_BATCH_MODE'] = 'false';
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
process.env['NX_BATCH_MODE'] = original;
|
||||
});
|
||||
|
||||
it('should begin with no scheduled tasks', () => {
|
||||
expect(taskSchedule.nextBatch()).toBeNull();
|
||||
expect(taskSchedule.nextTask()).toBeNull();
|
||||
});
|
||||
|
||||
it('should schedule root tasks in topological order', async () => {
|
||||
await taskSchedule.scheduleNextTasks();
|
||||
expect(taskSchedule.nextTask()).toEqual(app1Test);
|
||||
let nextTask = taskSchedule.nextTask();
|
||||
expect(nextTask).not.toEqual(app2Test); // app2 should not be scheduled since app1 is not parallel and not completed
|
||||
expect(nextTask).not.toEqual(lib1Test); // lib1 should not be scheduled since app1 is not parallel and not completed
|
||||
expect(nextTask).toBeNull();
|
||||
|
||||
taskSchedule.complete([app1Test.id]);
|
||||
await taskSchedule.scheduleNextTasks();
|
||||
nextTask = taskSchedule.nextTask();
|
||||
expect(nextTask).toEqual(app2Test); // app2 should be scheduled since app1 is completed now
|
||||
|
||||
nextTask = taskSchedule.nextTask();
|
||||
expect(nextTask).not.toEqual(lib1Test); // lib1 should not be scheduled since app2 is not parallel and not completed
|
||||
expect(nextTask).toBeNull();
|
||||
|
||||
taskSchedule.complete([app1Test.id]); // this should not do anything since app1 is already completed
|
||||
await taskSchedule.scheduleNextTasks();
|
||||
nextTask = taskSchedule.nextTask();
|
||||
expect(nextTask).not.toEqual(lib1Test); // lib1 should not be scheduled since app2 is not parallel and not completed
|
||||
expect(nextTask).toBeNull();
|
||||
|
||||
taskSchedule.complete([app2Test.id]);
|
||||
await taskSchedule.scheduleNextTasks();
|
||||
expect(taskSchedule.nextTask()).toEqual(lib1Test); // lib1 should be scheduled since app2 is completed now
|
||||
taskSchedule.complete([lib1Test.id]);
|
||||
expect(taskSchedule.hasTasks()).toEqual(false);
|
||||
});
|
||||
|
||||
it('should not schedule batches', async () => {
|
||||
await taskSchedule.scheduleNextTasks();
|
||||
|
||||
expect(taskSchedule.nextTask()).not.toBeNull();
|
||||
|
||||
expect(taskSchedule.nextBatch()).toBeNull();
|
||||
});
|
||||
});
|
||||
|
||||
describe('With Batch Mode', () => {
|
||||
let original;
|
||||
beforeEach(() => {
|
||||
original = process.env['NX_BATCH_MODE'];
|
||||
process.env['NX_BATCH_MODE'] = 'true';
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
process.env['NX_BATCH_MODE'] = original;
|
||||
});
|
||||
|
||||
it('should not schedule batches of tasks by different executors if task have parallelism false', async () => {
|
||||
await taskSchedule.scheduleNextTasks();
|
||||
|
||||
// app1, app2, and lib1 are not parallel, so they should not be batched
|
||||
expect(taskSchedule.nextTask()).toEqual(app1Test);
|
||||
|
||||
expect(taskSchedule.nextBatch()).toBeNull();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@ -21,6 +21,7 @@ export class TasksSchedule {
|
||||
private reverseProjectGraph = reverse(this.projectGraph);
|
||||
private scheduledBatches: Batch[] = [];
|
||||
private scheduledTasks: string[] = [];
|
||||
private runningTasks = new Set<string>();
|
||||
private completedTasks = new Set<string>();
|
||||
private scheduleRequestsExecutionChain = Promise.resolve();
|
||||
|
||||
@ -48,6 +49,7 @@ export class TasksSchedule {
|
||||
public complete(taskIds: string[]) {
|
||||
for (const taskId of taskIds) {
|
||||
this.completedTasks.add(taskId);
|
||||
this.runningTasks.delete(taskId);
|
||||
}
|
||||
this.notScheduledTaskGraph = removeTasksFromTaskGraph(
|
||||
this.notScheduledTaskGraph,
|
||||
@ -117,6 +119,7 @@ export class TasksSchedule {
|
||||
.length
|
||||
);
|
||||
});
|
||||
this.runningTasks.add(taskId);
|
||||
}
|
||||
|
||||
private async scheduleBatches() {
|
||||
@ -146,8 +149,8 @@ export class TasksSchedule {
|
||||
task: Task,
|
||||
rootExecutorName: string,
|
||||
isRoot: boolean
|
||||
) {
|
||||
if (!this.canBatchTaskBeScheduled(task.id, batches[rootExecutorName])) {
|
||||
): Promise<void> {
|
||||
if (!this.canBatchTaskBeScheduled(task, batches[rootExecutorName])) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -191,18 +194,45 @@ export class TasksSchedule {
|
||||
}
|
||||
|
||||
private canBatchTaskBeScheduled(
|
||||
taskId: string,
|
||||
task: Task,
|
||||
batchTaskGraph: TaskGraph | undefined
|
||||
): boolean {
|
||||
// task self needs to have parallelism true
|
||||
// all deps have either completed or belong to the same batch
|
||||
return this.taskGraph.dependencies[taskId].every(
|
||||
return (
|
||||
task.parallelism === true &&
|
||||
this.taskGraph.dependencies[task.id].every(
|
||||
(id) => this.completedTasks.has(id) || !!batchTaskGraph?.tasks[id]
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
private canBeScheduled(taskId: string) {
|
||||
return this.taskGraph.dependencies[taskId].every((id) =>
|
||||
this.completedTasks.has(id)
|
||||
private canBeScheduled(taskId: string): boolean {
|
||||
const hasDependenciesCompleted = this.taskGraph.dependencies[taskId].every(
|
||||
(id) => this.completedTasks.has(id)
|
||||
);
|
||||
|
||||
// if dependencies have not completed, cannot schedule
|
||||
if (!hasDependenciesCompleted) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// if there are no running tasks, can schedule anything
|
||||
if (this.runningTasks.size === 0) {
|
||||
return true;
|
||||
}
|
||||
|
||||
const runningTasksNotSupportParallelism = Array.from(
|
||||
this.runningTasks
|
||||
).some((taskId) => {
|
||||
return this.taskGraph.tasks[taskId].parallelism === false;
|
||||
});
|
||||
if (runningTasksNotSupportParallelism) {
|
||||
// if any running tasks do not support parallelism, no other tasks can be scheduled
|
||||
return false;
|
||||
} else {
|
||||
// if all running tasks support parallelism, can only schedule task with parallelism
|
||||
return this.taskGraph.tasks[taskId].parallelism === true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -91,6 +91,7 @@ describe('@nx/playwright/plugin', () => {
|
||||
"outputs": [
|
||||
"{projectRoot}/test-results",
|
||||
],
|
||||
"parallelism": false,
|
||||
},
|
||||
"e2e-ci": {
|
||||
"cache": true,
|
||||
@ -123,6 +124,7 @@ describe('@nx/playwright/plugin', () => {
|
||||
"outputs": [
|
||||
"{projectRoot}/test-results",
|
||||
],
|
||||
"parallelism": false,
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -200,6 +202,7 @@ describe('@nx/playwright/plugin', () => {
|
||||
"{projectRoot}/test-results/html",
|
||||
"{projectRoot}/test-results",
|
||||
],
|
||||
"parallelism": false,
|
||||
},
|
||||
"e2e-ci": {
|
||||
"cache": true,
|
||||
@ -235,6 +238,7 @@ describe('@nx/playwright/plugin', () => {
|
||||
"{projectRoot}/test-results/html",
|
||||
"{projectRoot}/test-results",
|
||||
],
|
||||
"parallelism": false,
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -323,6 +327,7 @@ describe('@nx/playwright/plugin', () => {
|
||||
"outputs": [
|
||||
"{projectRoot}/test-results",
|
||||
],
|
||||
"parallelism": false,
|
||||
}
|
||||
`);
|
||||
expect(targets['e2e-ci--tests/run-me.spec.ts']).toMatchInlineSnapshot(`
|
||||
@ -358,6 +363,7 @@ describe('@nx/playwright/plugin', () => {
|
||||
"outputs": [
|
||||
"{projectRoot}/test-results",
|
||||
],
|
||||
"parallelism": false,
|
||||
}
|
||||
`);
|
||||
expect(targets['e2e-ci--tests/run-me-2.spec.ts']).toMatchInlineSnapshot(`
|
||||
@ -393,6 +399,7 @@ describe('@nx/playwright/plugin', () => {
|
||||
"outputs": [
|
||||
"{projectRoot}/test-results",
|
||||
],
|
||||
"parallelism": false,
|
||||
}
|
||||
`);
|
||||
expect(targets['e2e-ci--tests/skip-me.spec.ts']).not.toBeDefined();
|
||||
|
||||
@ -162,6 +162,7 @@ async function buildPlaywrightTargets(
|
||||
options: {
|
||||
cwd: '{projectRoot}',
|
||||
},
|
||||
parallelism: false,
|
||||
metadata: {
|
||||
technologies: ['playwright'],
|
||||
description: 'Runs Playwright Tests',
|
||||
@ -257,6 +258,7 @@ async function buildPlaywrightTargets(
|
||||
inputs: ciBaseTargetConfig.inputs,
|
||||
outputs: ciBaseTargetConfig.outputs,
|
||||
dependsOn,
|
||||
parallelism: false,
|
||||
metadata: {
|
||||
technologies: ['playwright'],
|
||||
description: 'Runs Playwright Tests in CI',
|
||||
|
||||
@ -14,7 +14,8 @@ describe('<%=propertyName%>Hasher', () => {
|
||||
target: 'target'
|
||||
},
|
||||
overrides: {},
|
||||
outputs: []
|
||||
outputs: [],
|
||||
parallelism: true
|
||||
}, {
|
||||
hasher: mockHasher
|
||||
} as unknown as HasherContext)
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user