Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Migrate to Node 20 #962

Open
wants to merge 6 commits into
base: releases/5.x
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion azure-pipelines.yml
Expand Up @@ -6,7 +6,7 @@ trigger:
variables:
- group: npm-tokens
- name: nodeVersion
value: '16.13.0'
value: '20.3.1'

jobs:
#################################################
Expand Down
3 changes: 3 additions & 0 deletions node/CHANGELOG.md
Expand Up @@ -48,3 +48,6 @@ Backported from ver.`3.4.0`:
## 4.4.0

- Add `getBoolFeatureFlag` [#936](https://github.com/microsoft/azure-pipelines-task-lib/pull/936)

## 5.x
- Introduced support for node20 task handler and added node20 to task.schema.json [#962](https://github.com/microsoft/azure-pipelines-task-lib/pull/962)
2 changes: 1 addition & 1 deletion node/buildutils.js
Expand Up @@ -35,7 +35,7 @@ exports.getExternals = function () {
// and add node to the PATH
var nodeUrl = process.env['TASK_NODE_URL'] || 'https://nodejs.org/dist';
nodeUrl = nodeUrl.replace(/\/$/, ''); // ensure there is no trailing slash on the base URL
var nodeVersion = 'v16.13.0';
var nodeVersion = 'v20.3.1';
switch (platform) {
case 'darwin':
var nodeArchivePath = downloadArchive(nodeUrl + '/' + nodeVersion + '/node-' + nodeVersion + '-darwin-x64.tar.gz');
Expand Down
2 changes: 2 additions & 0 deletions node/docs/minagent.md
Expand Up @@ -30,6 +30,8 @@ Use the details below to determine when specific agent features were added:
- Added in 2.144.0. Used node v10.x
* `node16` handler
- Added in 2.206.1. Used node v16.x
* `node20` handler
- Added in 3.225.0. Used node v20.x
Copy link
Author

@qianz2 qianz2 Aug 18, 2023

Choose a reason for hiding this comment

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

We supported node20 handler in this PR, and it's published in release 3.224.0, not sure if here we will require minimum agent version to be >= 3.224.0 to enable node20 support.
cc: @DmitriiBobreshev

* `powershell3` handler
- Added in 1.95.1
- Updated in 1.97 to propagate `Data` property for endpoints
Expand Down
9 changes: 9 additions & 0 deletions node/docs/nodeEnvironment.md
Expand Up @@ -22,6 +22,15 @@ With agent version 2.206.1 Node 16 can be used.
},
```

With agent version 3.225.0 Node 20 can be used.

```
"execution": {
"Node20": {
"target": "path/to/entry"
}
},
```
Existing `Node` execution targets will still resolve to a Node 6 environment for now to maintain back-compat.

### Testing your task
Expand Down
4 changes: 2 additions & 2 deletions node/docs/nodeVersioning.md
Expand Up @@ -2,9 +2,9 @@

## Agent Node Handler

The agent currently has 3 different node handlers that it can use to execute node tasks: Node 6, Node 10, Node 16.
The agent currently has 4 different node handlers that it can use to execute node tasks: Node 6, Node 10, Node 16, and Node20.
The handler used depends on the `execution` property specified in the tasks `task.json`.
If the `execution` property is specified to be `Node`, the task will run on the Node 6 handler, for `Node10` it will run on the Node 10 handler, for `Node16` it will run on the Node 16 handler.
If the `execution` property is specified to be `Node`, the task will run on the Node 6 handler, for `Node10` it will run on the Node 10 handler, for `Node16` it will run on the Node 16 handler, for `Node20` it will run on the Node 20 handler.

## Mock-test Node Handler

Expand Down
7 changes: 6 additions & 1 deletion node/internal.ts
Expand Up @@ -507,7 +507,12 @@ function _tryGetExecutablePath(filePath: string, extensions: string[]): string {
// R W X R W X R W X
// 256 128 64 32 16 8 4 2 1
function isUnixExecutable(stats: fs.Stats) {
return (stats.mode & 1) > 0 || ((stats.mode & 8) > 0 && stats.gid === process.getgid()) || ((stats.mode & 64) > 0 && stats.uid === process.getuid());
const uid = process.getuid?.(); // Use optional chaining here
const gid = process.getgid?.();

return (stats.mode & 1) > 0 ||
((stats.mode & 8) > 0 && gid !== undefined && stats.gid === gid) ||
((stats.mode & 64) > 0 && uid !== undefined && stats.uid === uid);
}

export function _legacyFindFiles_convertPatternToRegExp(pattern: string): RegExp {
Expand Down
10 changes: 8 additions & 2 deletions node/mock-test.ts
Expand Up @@ -152,8 +152,11 @@ export class MockTestRunner {
case 16:
downloadVersion = 'v16.13.0';
break;
case 20:
downloadVersion = 'v20.3.1';
break;
default:
throw new Error('Invalid node version, must be 6, 10, or 16 (received ' + version + ')');
throw new Error('Invalid node version, must be 6, 10, 16, or 20 (received ' + version + ')');
}

// Install node in home directory if it isn't already there.
Expand Down Expand Up @@ -185,7 +188,10 @@ export class MockTestRunner {
);
const keys = Object.keys(execution);
for (let i = 0; i < keys.length; i++) {
if (keys[i].toLowerCase() == 'node16') {
if (keys[i].toLowerCase() == 'node20') {
// Prefer node 20 and return immediately.
return 20;
} else if (keys[i].toLowerCase() == 'node16') {
// Prefer node 16 and return immediately.
return 16;
} else if (keys[i].toLowerCase() == 'node10') {
Expand Down