Skip to content

Commit c21de06

Browse files
authored
Merge branch 'main' into bump-node-version-14.21.3
2 parents 26d2f87 + f5ee06d commit c21de06

13 files changed

+72
-47
lines changed

CHANGELOG.md

+2
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ Inspired from [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
6262
- [Data] Update `createAggConfig` so that newly created configs can be added to beginning of `aggConfig` array ([#3160](https://github.com/opensearch-project/OpenSearch-Dashboards/pull/3160))
6363
- Add disablePrototypePoisoningProtection configuration to prevent JS client from erroring when cluster utilizes JS reserved words ([#2992](https://github.com/opensearch-project/OpenSearch-Dashboards/pull/2992))
6464
- [Multiple DataSource] Add support for SigV4 authentication ([#3058](https://github.com/opensearch-project/OpenSearch-Dashboards/issues/3058))
65+
- Make build scripts find and use the latest version of Node.js that satisfies `engines.node` ([#3467](https://github.com/opensearch-project/OpenSearch-Dashboards/issues/3467))
6566

6667
### 🐛 Bug Fixes
6768

@@ -110,6 +111,7 @@ Inspired from [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
110111
- Add recording of functional test artifacts if they fail ([#3190](https://github.com/opensearch-project/OpenSearch-Dashboards/pull/3190))
111112
- Improve yarn's performance in workflows by caching yarn's cache folder ([#3194](https://github.com/opensearch-project/OpenSearch-Dashboards/pull/3194))
112113
- Fix detection of Chrome's version on Darwin during CI ([#3296](https://github.com/opensearch-project/OpenSearch-Dashboards/pull/3296))
114+
- Upgrade yarn version to be compatible with @openearch-project/opensearch ([#3443](https://github.com/opensearch-project/OpenSearch-Dashboards/pull/3443))
113115

114116
### 📝 Documentation
115117

package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -467,6 +467,6 @@
467467
},
468468
"engines": {
469469
"node": "^14.20.1",
470-
"yarn": "^1.21.1"
470+
"yarn": "^1.22.10"
471471
}
472472
}

src/dev/build/lib/config.test.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -79,10 +79,10 @@ describe('#getOpenSearchDashboardsPkg()', () => {
7979
});
8080
});
8181

82-
describe('#getNodeVersion()', () => {
83-
it('returns the node version from the OpenSearch Dashboards package.json', async () => {
82+
describe('#getNodeRange()', () => {
83+
it('returns the node version range from the OpenSearch Dashboards package.json', async () => {
8484
const config = await setup();
85-
expect(config.getNodeVersion()).toEqual(pkg.engines.node);
85+
expect(config.getNodeRange()).toEqual(pkg.engines.node);
8686
});
8787
});
8888

src/dev/build/lib/config.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ export class Config {
8686
private readonly targetAllPlatforms: boolean,
8787
private readonly targetPlatforms: TargetPlatforms,
8888
private readonly pkg: Package,
89-
private readonly nodeVersion: string,
89+
private readonly nodeRange: string,
9090
private readonly repoRoot: string,
9191
private readonly versionInfo: VersionInfo,
9292
public readonly isRelease: boolean
@@ -102,8 +102,8 @@ export class Config {
102102
/**
103103
* Get the node version required by OpenSearch Dashboards
104104
*/
105-
getNodeVersion() {
106-
return this.nodeVersion;
105+
getNodeRange() {
106+
return this.nodeRange;
107107
}
108108

109109
/**

src/dev/build/tasks/create_archives_sources_task.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ export const CreateArchivesSources: Task = {
5050

5151
// copy node.js install
5252
await scanCopy({
53-
source: getNodeDownloadInfo(config, platform).extractDir,
53+
source: (await getNodeDownloadInfo(config, platform)).extractDir,
5454
destination: build.resolvePathForPlatform(platform, 'node'),
5555
});
5656

src/dev/build/tasks/nodejs/download_node_builds_task.ts

+4-3
Original file line numberDiff line numberDiff line change
@@ -30,16 +30,17 @@
3030

3131
import { download, GlobalTask } from '../../lib';
3232
import { getNodeShasums } from './node_shasums';
33-
import { getNodeDownloadInfo } from './node_download_info';
33+
import { getLatestNodeVersion, getNodeDownloadInfo } from './node_download_info';
3434

3535
export const DownloadNodeBuilds: GlobalTask = {
3636
global: true,
3737
description: 'Downloading node.js builds for all platforms',
3838
async run(config, log) {
39-
const shasums = await getNodeShasums(log, config.getNodeVersion());
39+
const latestNodeVersion = await getLatestNodeVersion(config);
40+
const shasums = await getNodeShasums(log, latestNodeVersion);
4041
await Promise.all(
4142
config.getTargetPlatforms().map(async (platform) => {
42-
const { url, downloadPath, downloadName } = getNodeDownloadInfo(config, platform);
43+
const { url, downloadPath, downloadName } = await getNodeDownloadInfo(config, platform);
4344
await download({
4445
log,
4546
url,

src/dev/build/tasks/nodejs/extract_node_builds_task.test.ts

+11-12
Original file line numberDiff line numberDiff line change
@@ -28,10 +28,6 @@
2828
* under the License.
2929
*/
3030

31-
import { readFileSync } from 'fs';
32-
import Path from 'path';
33-
34-
import { REPO_ROOT } from '@osd/utils';
3531
import {
3632
ToolingLog,
3733
ToolingLogCollectingWriter,
@@ -41,6 +37,7 @@ import {
4137

4238
import { Config } from '../../lib';
4339
import { ExtractNodeBuilds } from './extract_node_builds_task';
40+
import { getLatestNodeVersion } from './node_download_info';
4441

4542
jest.mock('../../lib/fs');
4643
jest.mock('../../lib/get_build_number');
@@ -53,14 +50,6 @@ log.setWriters([testWriter]);
5350

5451
expect.addSnapshotSerializer(createAbsolutePathSerializer());
5552

56-
const nodeVersion = readFileSync(Path.resolve(REPO_ROOT, '.node-version'), 'utf8').trim();
57-
expect.addSnapshotSerializer(
58-
createRecursiveSerializer(
59-
(s) => typeof s === 'string' && s.includes(nodeVersion),
60-
(s) => s.split(nodeVersion).join('<node version>')
61-
)
62-
);
63-
6453
async function setup() {
6554
const config = await Config.create({
6655
isRelease: true,
@@ -73,6 +62,16 @@ async function setup() {
7362
},
7463
});
7564

65+
const realNodeVersion = await getLatestNodeVersion(config);
66+
if (realNodeVersion) {
67+
expect.addSnapshotSerializer(
68+
createRecursiveSerializer(
69+
(s) => typeof s === 'string' && s.includes(realNodeVersion),
70+
(s) => s.split(realNodeVersion).join('<node version>')
71+
)
72+
);
73+
}
74+
7675
return { config };
7776
}
7877

src/dev/build/tasks/nodejs/extract_node_builds_task.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ export const ExtractNodeBuilds: GlobalTask = {
3737
async run(config) {
3838
await Promise.all(
3939
config.getTargetPlatforms().map(async (platform) => {
40-
const { downloadPath, extractDir } = getNodeDownloadInfo(config, platform);
40+
const { downloadPath, extractDir } = await getNodeDownloadInfo(config, platform);
4141
if (platform.isWindows()) {
4242
await unzip(downloadPath, extractDir, { strip: 1 });
4343
} else {

src/dev/build/tasks/nodejs/node_download_info.ts

+26-2
Original file line numberDiff line numberDiff line change
@@ -29,11 +29,15 @@
2929
*/
3030

3131
import { basename } from 'path';
32+
import fetch from 'node-fetch';
33+
import semver from 'semver';
3234

3335
import { Config, Platform } from '../../lib';
3436

35-
export function getNodeDownloadInfo(config: Config, platform: Platform) {
36-
const version = config.getNodeVersion();
37+
const NODE_RANGE_CACHE: { [key: string]: string } = {};
38+
39+
export async function getNodeDownloadInfo(config: Config, platform: Platform) {
40+
const version = await getLatestNodeVersion(config);
3741
const arch = platform.getNodeArch();
3842

3943
const downloadName = platform.isWindows()
@@ -52,3 +56,23 @@ export function getNodeDownloadInfo(config: Config, platform: Platform) {
5256
version,
5357
};
5458
}
59+
60+
export async function getLatestNodeVersion(config: Config) {
61+
const range = config.getNodeRange();
62+
// Check cache and return if known
63+
if (NODE_RANGE_CACHE[range]) return NODE_RANGE_CACHE[range];
64+
65+
const releaseDoc = await fetch('https://nodejs.org/dist/index.json');
66+
const releaseList: [{ version: string }] = await releaseDoc.json();
67+
const releases = releaseList.map(({ version }) => version.replace(/^v/, ''));
68+
const maxVersion = semver.maxSatisfying(releases, range);
69+
70+
if (!maxVersion) {
71+
throw new Error(`Cannot find a version of Node.js that satisfies ${range}.`);
72+
}
73+
74+
// Cache it
75+
NODE_RANGE_CACHE[range] = maxVersion;
76+
77+
return maxVersion;
78+
}

src/dev/build/tasks/nodejs/verify_existing_node_builds_task.test.ts

+9-14
Original file line numberDiff line numberDiff line change
@@ -28,15 +28,10 @@
2828
* under the License.
2929
*/
3030

31-
import Path from 'path';
32-
import Fs from 'fs';
33-
34-
import { REPO_ROOT } from '@osd/utils';
3531
import {
3632
ToolingLog,
3733
ToolingLogCollectingWriter,
3834
createAnyInstanceSerializer,
39-
createRecursiveSerializer,
4035
} from '@osd/dev-utils';
4136

4237
import { Config, Platform } from '../../lib';
@@ -48,7 +43,7 @@ jest.mock('../../lib/fs');
4843
jest.mock('../../lib/get_build_number');
4944

5045
const { getNodeShasums } = jest.requireMock('./node_shasums');
51-
const { getNodeDownloadInfo } = jest.requireMock('./node_download_info');
46+
const { getNodeDownloadInfo, getLatestNodeVersion } = jest.requireMock('./node_download_info');
5247
const { getFileHash } = jest.requireMock('../../lib/fs');
5348

5449
const log = new ToolingLog();
@@ -58,14 +53,6 @@ log.setWriters([testWriter]);
5853
expect.addSnapshotSerializer(createAnyInstanceSerializer(Config));
5954
expect.addSnapshotSerializer(createAnyInstanceSerializer(ToolingLog));
6055

61-
const nodeVersion = Fs.readFileSync(Path.resolve(REPO_ROOT, '.node-version'), 'utf8').trim();
62-
expect.addSnapshotSerializer(
63-
createRecursiveSerializer(
64-
(s) => typeof s === 'string' && s.includes(nodeVersion),
65-
(s) => s.split(nodeVersion).join('<node version>')
66-
)
67-
);
68-
6956
async function setup(actualShaSums?: Record<string, string>) {
7057
const config = await Config.create({
7158
isRelease: true,
@@ -74,6 +61,7 @@ async function setup(actualShaSums?: Record<string, string>) {
7461
linux: false,
7562
linuxArm: false,
7663
darwin: false,
64+
windows: false,
7765
},
7866
});
7967

@@ -89,9 +77,12 @@ async function setup(actualShaSums?: Record<string, string>) {
8977
return {
9078
downloadPath: `${platform.getName()}:${platform.getNodeArch()}:downloadPath`,
9179
downloadName: `${platform.getName()}:${platform.getNodeArch()}:downloadName`,
80+
version: '<node version>',
9281
};
9382
});
9483

84+
getLatestNodeVersion.mockReturnValue('<node version>');
85+
9586
getFileHash.mockImplementation((downloadPath: string) => {
9687
if (actualShaSums?.[downloadPath]) {
9788
return actualShaSums[downloadPath];
@@ -176,27 +167,31 @@ it('checks shasums for each downloaded node build', async () => {
176167
"value": Object {
177168
"downloadName": "linux:linux-x64:downloadName",
178169
"downloadPath": "linux:linux-x64:downloadPath",
170+
"version": "<node version>",
179171
},
180172
},
181173
Object {
182174
"type": "return",
183175
"value": Object {
184176
"downloadName": "linux:linux-arm64:downloadName",
185177
"downloadPath": "linux:linux-arm64:downloadPath",
178+
"version": "<node version>",
186179
},
187180
},
188181
Object {
189182
"type": "return",
190183
"value": Object {
191184
"downloadName": "darwin:darwin-x64:downloadName",
192185
"downloadPath": "darwin:darwin-x64:downloadPath",
186+
"version": "<node version>",
193187
},
194188
},
195189
Object {
196190
"type": "return",
197191
"value": Object {
198192
"downloadName": "win32:win32-x64:downloadName",
199193
"downloadPath": "win32:win32-x64:downloadPath",
194+
"version": "<node version>",
200195
},
201196
},
202197
],

src/dev/build/tasks/nodejs/verify_existing_node_builds_task.ts

+4-3
Original file line numberDiff line numberDiff line change
@@ -29,18 +29,19 @@
2929
*/
3030

3131
import { getFileHash, GlobalTask } from '../../lib';
32-
import { getNodeDownloadInfo } from './node_download_info';
32+
import { getNodeDownloadInfo, getLatestNodeVersion } from './node_download_info';
3333
import { getNodeShasums } from './node_shasums';
3434

3535
export const VerifyExistingNodeBuilds: GlobalTask = {
3636
global: true,
3737
description: 'Verifying previously downloaded node.js build for all platforms',
3838
async run(config, log) {
39-
const shasums = await getNodeShasums(log, config.getNodeVersion());
39+
const latestNodeVersion = await getLatestNodeVersion(config);
40+
const shasums = await getNodeShasums(log, latestNodeVersion);
4041

4142
await Promise.all(
4243
config.getTargetPlatforms().map(async (platform) => {
43-
const { downloadPath, downloadName } = getNodeDownloadInfo(config, platform);
44+
const { downloadPath, downloadName } = await getNodeDownloadInfo(config, platform);
4445

4546
const sha256 = await getFileHash(downloadPath, 'sha256');
4647
if (sha256 !== shasums[downloadName]) {

src/dev/build/tasks/notice_file_task.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ export const CreateNoticeFile: Task = {
5757

5858
log.info('Generating build notice');
5959

60-
const { extractDir: nodeDir, version: nodeVersion } = getNodeDownloadInfo(
60+
const { extractDir: nodeDir, version: nodeVersion } = await getNodeDownloadInfo(
6161
config,
6262
config.hasSpecifiedPlatform()
6363
? config.getPlatform(

src/dev/build/tasks/verify_env_task.ts

+6-3
Original file line numberDiff line numberDiff line change
@@ -28,17 +28,20 @@
2828
* under the License.
2929
*/
3030

31+
import semver from 'semver';
3132
import { GlobalTask } from '../lib';
3233

3334
export const VerifyEnv: GlobalTask = {
3435
global: true,
3536
description: 'Verifying environment meets requirements',
3637

3738
async run(config, log) {
38-
const version = `v${config.getNodeVersion()}`;
39+
const range = config.getNodeRange();
3940

40-
if (version !== process.version) {
41-
throw new Error(`Invalid nodejs version, please use ${version}`);
41+
if (!semver.satisfies(process.version, range)) {
42+
throw new Error(
43+
`Invalid Node.js version (${process.version}); please use a version that satisfies ${range}.`
44+
);
4245
}
4346

4447
log.success('Node.js version verified');

0 commit comments

Comments
 (0)