Skip to content

feat(node-version-file): support parsing devEngines field #1283

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

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
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
15 changes: 15 additions & 0 deletions .github/workflows/versions.yml
Original file line number Diff line number Diff line change
@@ -168,6 +168,21 @@ jobs:
- name: Verify node
run: __tests__/verify-node.sh 20

version-file-dev-engines:
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, windows-latest, macos-latest, macos-13]
steps:
- uses: actions/checkout@v4
- name: Setup node from node version file
uses: ./
with:
node-version-file: '__tests__/data/package-dev-engines.json'
- name: Verify node
run: __tests__/verify-node.sh 20

version-file-volta:
runs-on: ${{ matrix.os }}
strategy:
11 changes: 11 additions & 0 deletions __tests__/data/package-dev-engines.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"engines": {
"node": "^20 || ^22"
},
"devEngines": {
"runtime": {
"name": "node",
"version": "^20"
}
}
}
33 changes: 17 additions & 16 deletions __tests__/main.test.ts
Original file line number Diff line number Diff line change
@@ -91,22 +91,23 @@ describe('main tests', () => {

describe('getNodeVersionFromFile', () => {
each`
contents | expected
${'12'} | ${'12'}
${'12.3'} | ${'12.3'}
${'12.3.4'} | ${'12.3.4'}
${'v12.3.4'} | ${'12.3.4'}
${'lts/erbium'} | ${'lts/erbium'}
${'lts/*'} | ${'lts/*'}
${'nodejs 12.3.4'} | ${'12.3.4'}
${'ruby 2.3.4\nnodejs 12.3.4\npython 3.4.5'} | ${'12.3.4'}
${''} | ${''}
${'unknown format'} | ${'unknown format'}
${' 14.1.0 '} | ${'14.1.0'}
${'{"volta": {"node": ">=14.0.0 <=17.0.0"}}'}| ${'>=14.0.0 <=17.0.0'}
${'{"volta": {"extends": "./package.json"}}'}| ${'18.0.0'}
${'{"engines": {"node": "17.0.0"}}'} | ${'17.0.0'}
${'{}'} | ${null}
contents | expected
${'12'} | ${'12'}
${'12.3'} | ${'12.3'}
${'12.3.4'} | ${'12.3.4'}
${'v12.3.4'} | ${'12.3.4'}
${'lts/erbium'} | ${'lts/erbium'}
${'lts/*'} | ${'lts/*'}
${'nodejs 12.3.4'} | ${'12.3.4'}
${'ruby 2.3.4\nnodejs 12.3.4\npython 3.4.5'} | ${'12.3.4'}
${''} | ${''}
${'unknown format'} | ${'unknown format'}
${' 14.1.0 '} | ${'14.1.0'}
${'{"volta": {"node": ">=14.0.0 <=17.0.0"}}'} | ${'>=14.0.0 <=17.0.0'}
${'{"volta": {"extends": "./package.json"}}'} | ${'18.0.0'}
${'{"engines": {"node": "17.0.0"}}'} | ${'17.0.0'}
${'{"devEngines": {"runtime": {"name": "node", "version": "22.0.0"}}}'} | ${'22.0.0'}
${'{}'} | ${null}
`.it('parses "$contents"', ({contents, expected}) => {
const existsSpy = jest.spyOn(fs, 'existsSync');
existsSpy.mockImplementation(() => true);
32 changes: 29 additions & 3 deletions docs/advanced-usage.md
Original file line number Diff line number Diff line change
@@ -71,7 +71,35 @@ steps:
- run: npm test
```

When using the `package.json` input, the action will look for `volta.node` first. If `volta.node` isn't defined, then it will look for `engines.node`.
When using the `package.json` input, the action will look in following field for a specified Node version:
1. It checks `volta.node` first.
2. Then it checks `devEngines.runtime`.
3. Then it will look for `engines.node`.
4. Otherwise it tries to resolve the file defined by [`volta.extends`](https://docs.volta.sh/advanced/workspaces)
and look for `volta.node` or `engines.node` recursively.

### Example with `devEngines`

When a runtime engine (`engines.node`) is defined but also a development engine (`devEngines.runtime`) then the `devEngine` runtime version is used.
This example will install a Node version based on the `^20.10` pattern.

```json
{
"engines": {
"node": "^20 || ^22"
},
"devEngines": {
"runtime": {
"name": "node",
"version": "^20.10"
}
}
}
```

### Example with volta pinned Node version

When both `engines.node` and `volta.node` is defined the value in `volta.node` is used.

```json
{
@@ -84,8 +112,6 @@ When using the `package.json` input, the action will look for `volta.node` first
}
```

Otherwise, when [`volta.extends`](https://docs.volta.sh/advanced/workspaces) is defined, then it will resolve the corresponding file and look for `volta.node` or `engines.node` recursively.

## Architecture

You can use any of the [supported operating systems](https://docs.github.com/en/actions/using-github-hosted-runners/about-github-hosted-runners), and the compatible `architecture` can be selected using `architecture`. Values are `x86`, `x64`, `arm64`, `armv6l`, `armv7l`, `ppc64le`, `s390x` (not all of the architectures are available on all platforms).
8 changes: 8 additions & 0 deletions src/util.ts
Original file line number Diff line number Diff line change
@@ -26,6 +26,14 @@ export function getNodeVersionFromFile(versionFilePath: string): string | null {
return manifest.volta.node;
}

// support devEngines from npm 11
if (
manifest.devEngines?.runtime?.name === 'node' &&
manifest.devEngines.runtime.version
) {
return manifest.devEngines.runtime.version;
}

if (manifest.engines?.node) {
return manifest.engines.node;
}