Skip to content

Commit 7c0de0d

Browse files
Add node 20 support to task-lib for testing and pick highest node version for tests (#1039)
* Add node 20 support to task-lib for testing and pick highest node version for tests - Added node 20 support - Changed the logic to pick highest handler instead of first one - Added tests for node20 - Changed tests for node6, node10, node16 to use highest handler * rename fake node20 task * Add node 20 support to task-lib for testing and pick highest node version for tests - Bumped node version * Add node 20 support to task-lib for testing and pick highest node version for tests - Fix test for node20 * Add node 20 support to task-lib for testing and pick highest node version for tests - code review feedback
1 parent 79bc298 commit 7c0de0d

File tree

7 files changed

+63
-35
lines changed

7 files changed

+63
-35
lines changed

node/mock-test.ts

+24-33
Original file line numberDiff line numberDiff line change
@@ -165,21 +165,17 @@ export class MockTestRunner {
165165
// Returns a path to node.exe with the correct version for this task (based on if its node10 or node)
166166
private async getNodePath(nodeVersion?: number): Promise<string> {
167167
const version: number = nodeVersion || this.getNodeVersion();
168-
169-
let downloadVersion: string;
170-
switch (version) {
171-
case 6:
172-
downloadVersion = 'v6.17.1';
173-
break;
174-
case 10:
175-
downloadVersion = 'v10.21.0';
176-
break;
177-
case 16:
178-
downloadVersion = 'v16.13.0';
179-
break;
180-
default:
181-
throw new Error('Invalid node version, must be 6, 10, or 16 (received ' + version + ')');
182-
}
168+
const versions = {
169+
20: 'v20.13.1',
170+
16: 'v16.20.2',
171+
10: 'v10.24.1',
172+
6: 'v6.17.1',
173+
};
174+
175+
const downloadVersion: string = versions[version];
176+
if (!downloadVersion) {
177+
throw new Error('Invalid node version, must be 6, 10, 16 or 20 (received ' + version + ')');
178+
}
183179

184180
// Install node in home directory if it isn't already there.
185181
const downloadDestination: string = path.join(downloadDirectory, 'node' + version);
@@ -203,31 +199,26 @@ export class MockTestRunner {
203199
const taskJsonContents = fs.readFileSync(taskJsonPath, { encoding: 'utf-8' });
204200
const taskJson: object = JSON.parse(taskJsonContents);
205201

206-
let nodeVersionFound = false;
207-
const execution: object = (
208-
taskJson['execution']
209-
|| taskJson['prejobexecution']
210-
|| taskJson['postjobexecution']
211-
);
212-
const keys = Object.keys(execution);
213-
for (let i = 0; i < keys.length; i++) {
214-
if (keys[i].toLowerCase() == 'node16') {
215-
// Prefer node 16 and return immediately.
216-
return 16;
217-
} else if (keys[i].toLowerCase() == 'node10') {
218-
// Prefer node 10 and return immediately.
219-
return 10;
220-
} else if (keys[i].toLowerCase() == 'node') {
221-
nodeVersionFound = true;
202+
let nodeVersion = 0;
203+
const executors = ['execution', 'prejobexecution', 'postjobexecution'];
204+
for (const executor of executors) {
205+
if (!taskJson[executor]) continue;
206+
207+
for (const key of Object.keys(taskJson[executor])) {
208+
const currExecutor = key.toLocaleLowerCase();
209+
if (!currExecutor.startsWith('node')) continue;
210+
const version = currExecutor.replace('node', '');
211+
const intVersion = parseInt(version) || 6; // node handler is node v6 by default
212+
nodeVersion = Math.max(intVersion, nodeVersion);
222213
}
223214
}
224215

225-
if (!nodeVersionFound) {
216+
if (nodeVersion === 0) {
226217
console.warn('Unable to determine execution type from task.json, defaulting to use Node 16');
227218
return 16;
228219
}
229220

230-
return 6;
221+
return nodeVersion;
231222
}
232223

233224
// Returns the path to the task.json for the task being tested. Returns null if unable to find it.

node/package-lock.json

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

node/package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "azure-pipelines-task-lib",
3-
"version": "4.12.1",
3+
"version": "4.13.0",
44
"description": "Azure Pipelines Task SDK",
55
"main": "./task.js",
66
"typings": "./task.d.ts",

node/test/fakeTasks/node10task/task.json

+3
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@
22
"id": "id",
33
"name": "Node10Task",
44
"execution": {
5+
"Node": {
6+
"target": "usedotnet.js"
7+
},
58
"Node10": {
69
"target": "usedotnet.js"
710
}

node/test/fakeTasks/node16task/task.json

+6
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,12 @@
22
"id": "id",
33
"name": "Node16Task",
44
"execution": {
5+
"Node": {
6+
"target": "usedotnet.js"
7+
},
8+
"Node10": {
9+
"target": "usedotnet.js"
10+
},
511
"Node16": {
612
"target": "usedotnet.js"
713
}
+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
{
2+
"id": "id",
3+
"name": "Node20Task",
4+
"execution": {
5+
"Node": {
6+
"target": "usedotnet.js"
7+
},
8+
"Node10": {
9+
"target": "usedotnet.js"
10+
},
11+
"Node16": {
12+
"target": "usedotnet.js"
13+
},
14+
"Node20": {
15+
"target": "usedotnet.js"
16+
}
17+
}
18+
}

node/test/mocktests.ts

+10
Original file line numberDiff line numberDiff line change
@@ -338,6 +338,16 @@ describe('Mock Tests', function () {
338338
await Promise.resolve()
339339
})
340340

341+
it('MockTest handles node 20 tasks correctly', async function () {
342+
this.timeout(30000);
343+
const runner = await (new mtm.MockTestRunner).LoadAsync(path.join(__dirname, 'fakeTasks', 'node20task', 'entry.js'));
344+
const nodePath = runner.nodePath;
345+
assert(nodePath, 'node path should have been correctly set');
346+
const version = ncp.execSync(nodePath + ' -v').toString().trim();
347+
assert(semver.satisfies(version, '20.x'), 'Downloaded node version should be Node 20 instead of ' + version);
348+
await Promise.resolve()
349+
})
350+
341351
it('MockTest handles node tasks correctly by async call', async () => {
342352
this.timeout(30000);
343353
const runner = await (new mtm.MockTestRunner).LoadAsync(path.join(__dirname, 'fakeTasks', 'node16task', 'entry.js'));

0 commit comments

Comments
 (0)