diff --git a/.github/workflows/ci-cd.yml b/.github/workflows/ci-cd.yml index ec70347f5a8e1..3273d4f7dd4a7 100644 --- a/.github/workflows/ci-cd.yml +++ b/.github/workflows/ci-cd.yml @@ -20,10 +20,10 @@ jobs: - name: Checkout uses: actions/checkout@v3 - - name: Use Node.js 16.x + - name: Use Node.js 18.x uses: actions/setup-node@v3 with: - node-version: 16.x + node-version: 18.x registry-url: 'https://registry.npmjs.org' - name: Use Python 3.x @@ -34,6 +34,7 @@ jobs: - name: Install and Build shell: bash run: | + yarn global add node-gyp yarn --skip-integrity-check --network-timeout 100000 ./scripts/check_git_status.sh env: @@ -51,7 +52,7 @@ jobs: fail-fast: false matrix: os: [windows-2019, ubuntu-latest, macos-11] - node: [16.x] + node: [16.x, 18.x, 20.x] runs-on: ${{ matrix.os }} timeout-minutes: 60 @@ -74,6 +75,7 @@ jobs: - name: Install shell: bash run: | + yarn global add node-gyp yarn --skip-integrity-check --network-timeout 100000 ./scripts/check_git_status.sh env: diff --git a/.github/workflows/license-check.yml b/.github/workflows/license-check.yml index b130974e52550..82a562fa2adeb 100644 --- a/.github/workflows/license-check.yml +++ b/.github/workflows/license-check.yml @@ -20,7 +20,7 @@ jobs: fail-fast: false matrix: os: [ubuntu-latest] - node: ['16.x'] + node: ['18.x'] java: ['11'] runs-on: ${{ matrix.os }} diff --git a/.github/workflows/performance-tests.yml b/.github/workflows/performance-tests.yml index 1ac5e5742e4e7..065de46991490 100644 --- a/.github/workflows/performance-tests.yml +++ b/.github/workflows/performance-tests.yml @@ -6,7 +6,7 @@ on: jobs: build-and-test-performance: name: Performance Tests - + runs-on: ubuntu-latest timeout-minutes: 30 @@ -14,10 +14,10 @@ jobs: - name: Checkout uses: actions/checkout@v3 - - name: Use Node.js 16.x + - name: Use Node.js 18.x uses: actions/setup-node@v3 with: - node-version: "16.x" + node-version: "18.x" registry-url: "https://registry.npmjs.org" - name: Use Python 3.x @@ -28,6 +28,7 @@ jobs: - name: Build shell: bash run: | + yarn global add node-gyp yarn --skip-integrity-check --network-timeout 100000 --ignore-engines yarn build:examples env: diff --git a/.github/workflows/playwright.yml b/.github/workflows/playwright.yml index dce1bde8f6678..7746e7a2e251f 100644 --- a/.github/workflows/playwright.yml +++ b/.github/workflows/playwright.yml @@ -13,7 +13,7 @@ on: jobs: build-and-test-playwright: - name: Playwright Tests (ubuntu-latest, Node.js 16.x) + name: Playwright Tests (ubuntu-latest, Node.js 18.x) runs-on: ubuntu-latest timeout-minutes: 60 @@ -22,10 +22,10 @@ jobs: - name: Checkout uses: actions/checkout@v3 - - name: Use Node.js "16.x" + - name: Use Node.js "18.x" uses: actions/setup-node@v3 with: - node-version: "16.x" + node-version: "18.x" registry-url: "https://registry.npmjs.org" - name: Use Python 3.x @@ -36,6 +36,7 @@ jobs: - name: Build Browser shell: bash run: | + yarn global add node-gyp yarn --skip-integrity-check --network-timeout 100000 yarn browser build env: diff --git a/.github/workflows/publish-gh-pages.yml b/.github/workflows/publish-gh-pages.yml index 1d524d4857e9a..68e5311ca3004 100644 --- a/.github/workflows/publish-gh-pages.yml +++ b/.github/workflows/publish-gh-pages.yml @@ -19,10 +19,10 @@ jobs: with: fetch-depth: 0 # To fetch all history for all branches and tags. (Will be required for caching with lerna: https://github.com/markuplint/markuplint/pull/111) - - name: Use Node.js 16.x + - name: Use Node.js 18.x uses: actions/setup-node@v3 with: - node-version: '16.x' + node-version: '18.x' registry-url: 'https://registry.npmjs.org' - name: Use Python 3.x @@ -32,6 +32,7 @@ jobs: - name: Pre-npm-Publish run: | + yarn global add node-gyp yarn --skip-integrity-check --network-timeout 100000 env: NODE_OPTIONS: --max_old_space_size=4096 diff --git a/.github/workflows/translation.yml b/.github/workflows/translation.yml index cf7b792940cfc..c341e4637e830 100644 --- a/.github/workflows/translation.yml +++ b/.github/workflows/translation.yml @@ -12,10 +12,10 @@ jobs: - name: Checkout uses: actions/checkout@v3 - - name: Use Node.js 16.x + - name: Use Node.js 18.x uses: actions/setup-node@v3 with: - node-version: 16.x + node-version: 18.x registry-url: "https://registry.npmjs.org" - name: Use Python 3.x @@ -26,6 +26,7 @@ jobs: - name: Install and Build shell: bash run: | + yarn global add node-gyp yarn --skip-integrity-check --network-timeout 100000 env: NODE_OPTIONS: --max_old_space_size=4096 diff --git a/.gitpod.dockerfile b/.gitpod.dockerfile index 156d7aa676e31..4ca3b09bb0137 100644 --- a/.gitpod.dockerfile +++ b/.gitpod.dockerfile @@ -17,7 +17,7 @@ RUN sudo apt-get update \ ENV SHELL=/bin/bash -ENV NODE_VERSION="16.14.0" +ENV NODE_VERSION="18.17.0" RUN bash -c ". .nvm/nvm.sh \ && nvm install $NODE_VERSION \ && nvm use $NODE_VERSION \ diff --git a/CHANGELOG.md b/CHANGELOG.md index 33cad2171f03b..9aa2b61c9c882 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,9 +3,17 @@ ## History - [Previous Changelogs](https://github.com/eclipse-theia/theia/tree/master/doc/changelogs/) -## v1.41.0 - + +## v1.41.0 + - [application-package] Quit Electron app when back end fails to start [#12778](https://github.com/eclipse-theia/theia/pull/12778) - Contributed on behalf of STMicroelectronics. - [vscode] added support for tree checkbox api [#12836](https://github.com/eclipse-theia/theia/pull/12836) - Contributed on behalf of STMicroelectronics +- [core] Add `--dnsDefaultResultOrder ` CLI argument where `value` is one of `ipv4first`, `verbatim` or `nodeDefault`. It controls how domain names are resolved. + +[Breaking Changes:](#breaking_changes_1.41.0) + +- [deps] Bumped supported Node.js version from 16.x to >=18, you may need to update your environments. + ## v1.40.0 - 07/27/2023 - [application-package] bumped the default supported VS Code API from `1.78.0` to `1.79.0` [#12764](https://github.com/eclipse-theia/theia/pull/12764) - Contributed on behalf of STMicroelectronics. diff --git a/dev-packages/application-manager/src/generator/backend-generator.ts b/dev-packages/application-manager/src/generator/backend-generator.ts index d48e9484aa669..0a4a9f36edd17 100644 --- a/dev-packages/application-manager/src/generator/backend-generator.ts +++ b/dev-packages/application-manager/src/generator/backend-generator.ts @@ -161,9 +161,9 @@ BackendApplicationConfigProvider.set(${this.prettyStringify(this.pck.props.backe const serverModule = require('./server'); const serverAddress = main.start(serverModule()); -serverAddress.then(({ port, address }) => { +serverAddress.then(({ port, address, family }) => { if (process && process.send) { - process.send({ port, address }); + process.send({ port, address, family }); } }); diff --git a/dev-packages/cli/src/run-test.ts b/dev-packages/cli/src/run-test.ts index eab504cd5190e..2895d63481fae 100644 --- a/dev-packages/cli/src/run-test.ts +++ b/dev-packages/cli/src/run-test.ts @@ -79,7 +79,9 @@ export default async function runTest(options: TestOptions): Promise { } } }); - - const server = await start(); - await testPage.goto(`http://${server.address}:${server.port}`); + const { address, port } = await start(); + const url = net.isIPv6(address) + ? `http://[${address}]:${port}` + : `http://${address}:${port}`; + await testPage.goto(url); } diff --git a/doc/Developing.md b/doc/Developing.md index aa2f458af821d..cc19249bc041d 100644 --- a/doc/Developing.md +++ b/doc/Developing.md @@ -52,7 +52,7 @@ For Windows instructions [click here](#building-on-windows). ## Prerequisites - - Node.js `>= 16.14.0` and `< 17`. + - Node.js `>= 18.17.0` and `< 21`. - If you are interested in Theia's VS Code Extension support then you should use a Node version at least compatible with the one included in the version of Electron used by [VS Code](https://github.com/microsoft/vscode). - [Yarn package manager](https://yarnpkg.com/en/docs/install) `>= 1.7.0` **AND** `< 2.x.x`. - git (If you would like to use the Git-extension too, you will need to have git version 2.11.0 or higher.) @@ -508,7 +508,7 @@ etc.) by opening `packages//coverage/index.html`. - Install [`scoop`](https://github.com/lukesampson/scoop#installation). - Install [`nvm`](https://github.com/coreybutler/nvm-windows) with scoop: `scoop install nvm`. - - Install Node.js with `nvm`: `nvm install 16.15.1`, then use it: `nvm use 16.15.1`. You can list all available Node.js versions with `nvm list available` if you want to pick another version. + - Install Node.js with `nvm`: `nvm install 18.17.0`, then use it: `nvm use 18.17.0`. You can list all available Node.js versions with `nvm list available` if you want to pick another version. - Install `yarn`: `scoop install yarn`. - If you need to install `windows-build-tools`, see [`Installing Windows Build Tools`](#installing-windows-build-tools). - If you run into problems with installing the required build tools, the `node-gyp` documentation offers a useful [guide](https://github.com/nodejs/node-gyp#on-windows) how to install the dependencies manually. The versions required for building Theia are: diff --git a/doc/runtime-policy.md b/doc/runtime-policy.md index 2357b262486fe..551b1513c4b04 100644 --- a/doc/runtime-policy.md +++ b/doc/runtime-policy.md @@ -2,7 +2,7 @@ ## Version Support Policy -We try to support Node.js versions from 12 up to the current _Active LTS_ version. +We aim to support Node.js current _Active LTS_ version. See https://nodejs.org/en/about/releases/ to see the status of Node.js versions. @@ -15,6 +15,7 @@ Note that the Node.js version you should use depends on your own project's depen - Follow Node.js LTS cadence and initiate the update when a new Node.js version becomes _Active LTS_. - Use `@types/node` for the oldest supported Node version (backward compatibility). - Update the CI matrix to include the new Node.js versions to support. +- Update the documentation referencing recommended Node versions. - Update the CHANGELOG. # Electron diff --git a/package.json b/package.json index 1b0aa68d29fbc..ff123fe48011f 100644 --- a/package.json +++ b/package.json @@ -4,17 +4,17 @@ "version": "0.0.0", "engines": { "yarn": ">=1.7.0 <2", - "node": ">=16.14.0 <17" + "node": ">=16" }, "resolutions": { - "**/@types/node": "16" + "**/@types/node": "18" }, "devDependencies": { "@types/chai": "4.3.0", "@types/chai-spies": "1.0.3", "@types/chai-string": "^1.4.0", "@types/jsdom": "^21.1.1", - "@types/node": "16", + "@types/node": "18", "@types/sinon": "^10.0.6", "@types/temp": "^0.9.1", "@types/uuid": "^7.0.3", diff --git a/packages/core/src/node/backend-application.ts b/packages/core/src/node/backend-application.ts index 1f68370959219..92ec60c1e8c71 100644 --- a/packages/core/src/node/backend-application.ts +++ b/packages/core/src/node/backend-application.ts @@ -14,6 +14,7 @@ // SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0 // ***************************************************************************** +import * as dns from 'dns'; import * as path from 'path'; import * as http from 'http'; import * as https from 'https'; @@ -29,6 +30,8 @@ import { AddressInfo } from 'net'; import { ApplicationPackage } from '@theia/application-package'; import { ProcessUtils } from './process-utils'; +export type DnsResultOrder = 'ipv4first' | 'verbatim' | 'nodeDefault'; + const APP_PROJECT_PATH = 'app-project-path'; const TIMER_WARNING_THRESHOLD = 50; @@ -36,6 +39,7 @@ const TIMER_WARNING_THRESHOLD = 50; const DEFAULT_PORT = environment.electron.is() ? 0 : 3000; const DEFAULT_HOST = 'localhost'; const DEFAULT_SSL = false; +const DEFAULT_DNS_DEFAULT_RESULT_ORDER: DnsResultOrder = 'ipv4first'; export const BackendApplicationServer = Symbol('BackendApplicationServer'); /** @@ -107,6 +111,7 @@ export class BackendApplicationCliContribution implements CliContribution { port: number; hostname: string | undefined; + dnsDefaultResultOrder: DnsResultOrder = DEFAULT_DNS_DEFAULT_RESULT_ORDER; ssl: boolean | undefined; cert: string | undefined; certkey: string | undefined; @@ -119,6 +124,12 @@ export class BackendApplicationCliContribution implements CliContribution { conf.option('cert', { description: 'Path to SSL certificate.', type: 'string' }); conf.option('certkey', { description: 'Path to SSL certificate key.', type: 'string' }); conf.option(APP_PROJECT_PATH, { description: 'Sets the application project directory', default: this.appProjectPath() }); + conf.option('dnsDefaultResultOrder', { + type: 'string', + description: 'Configure Node\'s DNS resolver default behavior, see https://nodejs.org/docs/latest-v18.x/api/dns.html#dnssetdefaultresultorderorder', + choices: ['ipv4first', 'verbatim', 'nodeDefault'], + default: DEFAULT_DNS_DEFAULT_RESULT_ORDER + }); } setArguments(args: yargs.Arguments): void { @@ -128,6 +139,7 @@ export class BackendApplicationCliContribution implements CliContribution { this.cert = args.cert as string; this.certkey = args.certkey as string; this.projectPath = args[APP_PROJECT_PATH] as string; + this.dnsDefaultResultOrder = args.dnsDefaultResultOrder as DnsResultOrder; } protected appProjectPath(): string { @@ -234,9 +246,13 @@ export class BackendApplication { this.app.use(...handlers); } - async start(aPort?: number, aHostname?: string): Promise { - const hostname = aHostname !== undefined ? aHostname : this.cliParams.hostname; - const port = aPort !== undefined ? aPort : this.cliParams.port; + async start(port?: number, hostname?: string): Promise { + hostname ??= this.cliParams.hostname; + port ??= this.cliParams.port; + + if (this.cliParams.dnsDefaultResultOrder !== 'nodeDefault') { + dns.setDefaultResultOrder(this.cliParams.dnsDefaultResultOrder); + } const deferred = new Deferred(); let server: http.Server | https.Server; @@ -279,8 +295,10 @@ export class BackendApplication { }); server.listen(port, hostname, () => { - const scheme = this.cliParams.ssl ? 'https' : 'http'; - console.info(`Theia app listening on ${scheme}://${hostname || 'localhost'}:${(server.address() as AddressInfo).port}.`); + // address should be defined at this point + const address = server.address()!; + const url = typeof address === 'string' ? address : this.getHttpUrl(address, this.cliParams.ssl); + console.info(`Theia app listening on ${url}.`); deferred.resolve(server); }); @@ -301,6 +319,13 @@ export class BackendApplication { return this.stopwatch.startAsync('server', 'Finished starting backend application', () => deferred.promise); } + protected getHttpUrl({ address, port, family }: AddressInfo, ssl?: boolean): string { + const scheme = ssl ? 'https' : 'http'; + return family.toLowerCase() === 'ipv6' + ? `${scheme}://[${address}]:${port}` + : `${scheme}://${address}:${port}`; + } + protected onStop(): void { console.info('>>> Stopping backend contributions...'); for (const contrib of this.contributionsProvider.getContributions()) { diff --git a/packages/core/src/node/logger-cli-contribution.spec.ts b/packages/core/src/node/logger-cli-contribution.spec.ts index 204bd51104ef2..bc9c0a419a489 100644 --- a/packages/core/src/node/logger-cli-contribution.spec.ts +++ b/packages/core/src/node/logger-cli-contribution.spec.ts @@ -137,7 +137,7 @@ describe('log-level-cli-contribution', () => { const args: yargs.Arguments = yargs.parse(['--log-config', file.path]); await cli.setArguments(args); - sinon.assert.calledWithMatch(consoleErrorSpy, 'Unexpected token { in JSON at position 1'); + sinon.assert.calledWithMatch(consoleErrorSpy, 'Error reading log config file'); }); // Skip this test because it is flaky, sometimes we don't receive the event. diff --git a/packages/core/src/node/main.ts b/packages/core/src/node/main.ts index 4201405592221..6fc72783ce6b9 100644 --- a/packages/core/src/node/main.ts +++ b/packages/core/src/node/main.ts @@ -26,12 +26,7 @@ process.on('unhandledRejection', (reason, promise) => { throw reason; }); -export interface Address { - readonly port: number; - readonly address: string; -} - -export async function start(serverModule: MaybePromise): Promise
{ +export async function start(serverModule: MaybePromise): Promise { const server = await serverModule; return server.address() as AddressInfo; } diff --git a/packages/plugin-ext/package.json b/packages/plugin-ext/package.json index c34ce9a3abdc2..f2e7160f14885 100644 --- a/packages/plugin-ext/package.json +++ b/packages/plugin-ext/package.json @@ -39,7 +39,7 @@ "is-electron": "^2.2.0", "jsonc-parser": "^2.2.0", "lodash.clonedeep": "^4.5.0", - "macaddress": "^0.2.9", + "macaddress": "^0.5.3", "mime": "^2.4.4", "ps-tree": "^1.2.0", "semver": "^7.5.4", diff --git a/packages/plugin-ext/src/typings/index.d.ts b/packages/plugin-ext/src/typings/index.d.ts deleted file mode 100644 index 79f281800eab5..0000000000000 --- a/packages/plugin-ext/src/typings/index.d.ts +++ /dev/null @@ -1,25 +0,0 @@ -// ***************************************************************************** -// Copyright (C) 2019 Red Hat, Inc. and others. -// -// This program and the accompanying materials are made available under the -// terms of the Eclipse Public License v. 2.0 which is available at -// http://www.eclipse.org/legal/epl-2.0. -// -// This Source Code may also be made available under the following Secondary -// Licenses when the conditions for such availability set forth in the Eclipse -// Public License v. 2.0 are satisfied: GNU General Public License, version 2 -// with the GNU Classpath Exception which is available at -// https://www.gnu.org/software/classpath/license.html. -// -// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0 -// ***************************************************************************** - -/* eslint-disable @typescript-eslint/no-explicit-any */ - -declare module 'macaddress' { - export type MacAddresCallback = (err: any, data: any) => void; - export type MacAddressOneCallback = (err: any, mac: string) => void; - export function one(ifaceOrCallback: string | MacAddressOneCallback, callback?: MacAddressOneCallback): void; - export function all(callback: MacAddresCallback): void; - export function networkInterfaces(): any; -} diff --git a/yarn.lock b/yarn.lock index c89541b2757fd..ee3f8d062c298 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2029,10 +2029,10 @@ "@types/node" "*" form-data "^3.0.0" -"@types/node@*", "@types/node@16", "@types/node@>=10.0.0", "@types/node@^10.14.22", "@types/node@^16.11.26": - version "16.18.38" - resolved "https://registry.yarnpkg.com/@types/node/-/node-16.18.38.tgz#1dcdb6c54d02b323f621213745f2e44af30c73e6" - integrity sha512-6sfo1qTulpVbkxECP+AVrHV9OoJqhzCsfTNp5NIG+enM4HyM3HvZCO798WShIXBN0+QtDIcutJCjsVYnQP5rIQ== +"@types/node@*", "@types/node@18", "@types/node@>=10.0.0", "@types/node@^10.14.22", "@types/node@^16.11.26": + version "18.16.19" + resolved "https://registry.yarnpkg.com/@types/node/-/node-18.16.19.tgz#cb03fca8910fdeb7595b755126a8a78144714eea" + integrity sha512-IXl7o+R9iti9eBW4Wg2hx1xQDig183jj7YLn8F7udNceyfkbn1ZxmzZXuak20gR40D7pIkIY1kYGx5VIGbaHKA== "@types/normalize-package-data@^2.4.0": version "2.4.1" @@ -7355,10 +7355,10 @@ lzma-native@^8.0.5: node-gyp-build "^4.2.1" readable-stream "^3.6.0" -macaddress@^0.2.9: - version "0.2.9" - resolved "https://registry.yarnpkg.com/macaddress/-/macaddress-0.2.9.tgz#3579b8b9acd5b96b4553abf0f394185a86813cb3" - integrity sha512-k4F1JUof6cQXxNFzx3thLby4oJzXTXQueAOOts944Vqizn+Rjc2QNFenT9FJSLU1CH3PmrHRSyZs2E+Cqw+P2w== +macaddress@^0.5.3: + version "0.5.3" + resolved "https://registry.yarnpkg.com/macaddress/-/macaddress-0.5.3.tgz#2b9d6832be934cb775749f30f57d6537184a2bda" + integrity sha512-vGBKTA+jwM4KgjGZ+S/8/Mkj9rWzePyGY6jManXPGhiWu63RYwW8dKPyk5koP+8qNVhPhHgFa1y/MJ4wrjsNrg== make-dir@3.1.0, make-dir@^3.0.0, make-dir@^3.0.2, make-dir@^3.1.0: version "3.1.0"