Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 23 additions & 8 deletions node/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,17 +17,32 @@ Documentation: [TypeScript API](https://github.com/microsoft/azure-pipelines-tas

Guidance: [Finding Files](https://github.com/microsoft/azure-pipelines-task-lib/blob/master/node/docs/findingfiles.md), [Minimum agent version](https://github.com/microsoft/azure-pipelines-task-lib/blob/master/node/docs/minagent.md), [Proxy](https://github.com/microsoft/azure-pipelines-task-lib/blob/master/node/docs/proxy.md), [Certificate](https://github.com/microsoft/azure-pipelines-task-lib/blob/master/node/docs/cert.md)

## Node 10 Upgrade Notice
## Node Runtime Support

Azure DevOps is currently working to establish Node 10 as the new preferred runtime for tasks, upgrading from Node 6.
Relevant work is happening in the `master` branch and the major version should be used with Node 10 is 3.
Previous major version is stored in the `releases/2.x`
Azure Pipelines supports multiple Node.js runtimes for task execution:

### Upgrading to Node 10
* **Node 6** - Supported
* **Node 10** - Supported
* **Node 16** - Supported
* **Node 20** - Current recommended version
* **Node 24** - Latest version with modern JavaScript features

Upgrading your tasks from Node 6 should be relatively painless, however there are some things to note:
* Typescript has been upgraded to TS 4. Older versions of TS may or may not work with Node 14 or the 3.x branch. We recommend upgrading to TS 4 when upgrading to task-lib 3.x.
* Node has made some changes to `fs` between Node 6 and Node 10. It is worth reviewing and testing your tasks thoroughly before publishing updates to Node 10.
### Node Version Selection

The Node runtime used depends on the `execution` handler specified in your task's `task.json`:
* `Node` - Uses Node 6
* `Node10` - Uses Node 10
* `Node16` - Uses Node 16
* `Node20_1` - Uses Node 20 (Note: handler name includes _1 suffix)
* `Node24` - Uses Node 24

### Upgrading to Newer Node Versions

When upgrading your tasks to newer Node versions:
* **TypeScript**: Ensure you're using a compatible TypeScript version (TS 4.0+ for Node 10+, TS 5.0+ for Node 20+, TS 5.7+ for Node 24)
* **Dependencies**: Review and update npm dependencies for compatibility with the target Node version
* **Testing**: Thoroughly test your tasks with the new Node runtime before publishing
* **Breaking Changes**: Review Node.js release notes for breaking changes between versions (especially `fs` module changes)

## Reference Examples

Expand Down
4 changes: 4 additions & 0 deletions node/docs/minagent.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,10 @@ 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 2.214.1. Used node v20.x
* `node24` handler
- Added in 3.250.0. Uses node v24.x
* `powershell3` handler
- Added in 1.95.1
- Updated in 1.97 to propagate `Data` property for endpoints
Expand Down
6 changes: 3 additions & 3 deletions node/docs/nodeVersioning.md
Original file line number Diff line number Diff line change
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 multiple node handlers that it can use to execute node tasks: Node 6, Node 10, Node 16, Node 20, and Node 24.
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_1` it will run on the Node 20 handler, and for `Node24` it will run on the Node 24 handler.

## Mock-test Node Handler

Expand All @@ -16,5 +16,5 @@ If this version of node is not found on the path, the library downloads the appr

### Behavior overrides

To specify a specific version of node to use, set the `nodeVersion` optional parameter in the `run` function of the `MockTestRunner` to the integer major version (e.g. `mtr.run(5)`).
To specify a specific version of node to use, set the `nodeVersion` optional parameter in the `run` function of the `MockTestRunner` to the integer major version (e.g. `mtr.run(20)` for Node 20, `mtr.run(24)` for Node 24).
To specify the location of a `task.json` file, set the `taskJsonPath` optional parameter in the `MockTestRunner` constructor to the path of the file (e.g. `let mtr = new mt.MockTaskRunner('<pathToTest>', '<pathToTask.json>'`).
3 changes: 2 additions & 1 deletion node/mock-test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,7 @@ export class MockTestRunner {
private async getNodePath(nodeVersion?: number): Promise<string> {
const version: number = nodeVersion || this.getNodeVersion();
const versions = {
24: 'v24.10.0',
20: 'v20.13.1',
16: 'v16.20.2',
10: 'v10.24.1',
Expand All @@ -174,7 +175,7 @@ export class MockTestRunner {

const downloadVersion: string = versions[version];
if (!downloadVersion) {
throw new Error('Invalid node version, must be 6, 10, 16 or 20 (received ' + version + ')');
throw new Error('Invalid node version, must be 6, 10, 16, 20 or 24 (received ' + version + ')');
}

// Install node in home directory if it isn't already there.
Expand Down
4 changes: 2 additions & 2 deletions node/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion node/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "azure-pipelines-task-lib",
"version": "5.2.1",
"version": "5.2.2",
"description": "Azure Pipelines Task SDK",
"main": "./task.js",
"typings": "./task.d.ts",
Expand Down
2 changes: 2 additions & 0 deletions node/test/fakeTasks/node24task/entry.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
// Minimal entry point for Node 24 task testing
console.log('Node 24 task entry point');
21 changes: 21 additions & 0 deletions node/test/fakeTasks/node24task/task.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{
"id": "id",
"name": "Node24Task",
"execution": {
"Node": {
"target": "usedotnet.js"
},
"Node10": {
"target": "usedotnet.js"
},
"Node16": {
"target": "usedotnet.js"
},
"Node20_1": {
"target": "usedotnet.js"
},
"Node24": {
"target": "usedotnet.js"
}
}
}
10 changes: 10 additions & 0 deletions node/test/mocktests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -348,6 +348,16 @@ describe('Mock Tests', function () {
await Promise.resolve()
})

it('MockTest handles node 24 tasks correctly', async function () {
this.timeout(30000);
const runner = await (new mtm.MockTestRunner).LoadAsync(path.join(__dirname, 'fakeTasks', 'node24task', 'entry.js'));
const nodePath = runner.nodePath;
assert(nodePath, 'node path should have been correctly set');
const version = ncp.execSync(nodePath + ' -v').toString().trim();
assert(semver.satisfies(version, '24.x'), 'Downloaded node version should be Node 24 instead of ' + version);
await Promise.resolve()
})

it('MockTest handles node tasks correctly by async call', async () => {
this.timeout(30000);
const runner = await (new mtm.MockTestRunner).LoadAsync(path.join(__dirname, 'fakeTasks', 'node16task', 'entry.js'));
Expand Down
9 changes: 9 additions & 0 deletions tasks.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -394,6 +394,9 @@
"additionalProperties": false,
"description": "Execution options for this task (on Pre-Job stage)",
"properties": {
"Node24": {
"$ref": "#/definitions/executionObject"
},
"Node20_1": {
"$ref": "#/definitions/executionObject"
},
Expand All @@ -419,6 +422,9 @@
"additionalProperties": false,
"description": "Execution options for this task",
"properties": {
"Node24": {
"$ref": "#/definitions/executionObject"
},
"Node20_1": {
"$ref": "#/definitions/executionObject"
},
Expand All @@ -444,6 +450,9 @@
"additionalProperties": false,
"description": "Execution options for this task (on Post-Job stage)",
"properties": {
"Node24": {
"$ref": "#/definitions/executionObject"
},
"Node20_1": {
"$ref": "#/definitions/executionObject"
},
Expand Down