From baefa18f283f7786b9e6545dd51dd4f54afcb171 Mon Sep 17 00:00:00 2001 From: Emily Rohrbough Date: Fri, 21 Jan 2022 11:01:13 -0600 Subject: [PATCH 1/7] this might be a better solution. --- .husky/pre-commit | 2 +- cli/lib/exec/spawn.js | 1 + cli/lib/util.js | 28 ++++++++++++++++++++++------ packages/server/lib/plugins/index.js | 15 --------------- 4 files changed, 24 insertions(+), 22 deletions(-) diff --git a/.husky/pre-commit b/.husky/pre-commit index 36af219892fd..9f5c7d244218 100755 --- a/.husky/pre-commit +++ b/.husky/pre-commit @@ -1,4 +1,4 @@ #!/bin/sh . "$(dirname "$0")/_/husky.sh" -npx lint-staged +# npx lint-staged diff --git a/cli/lib/exec/spawn.js b/cli/lib/exec/spawn.js index 9286f1ad7d71..2712872b106b 100644 --- a/cli/lib/exec/spawn.js +++ b/cli/lib/exec/spawn.js @@ -88,6 +88,7 @@ module.exports = { env: process.env, detached: false, stdio: getStdio(needsXvfb), + processVersions: process.versions, }) const spawn = (overrides = {}) => { diff --git a/cli/lib/util.js b/cli/lib/util.js index 3028c5e0cfc1..a8c911d50cb6 100644 --- a/cli/lib/util.js +++ b/cli/lib/util.js @@ -18,10 +18,12 @@ const executable = require('executable') const { stripIndent } = require('common-tags') const supportsColor = require('supports-color') const isInstalledGlobally = require('is-installed-globally') -const pkg = require(path.join(__dirname, '..', 'package.json')) const logger = require('./logger') const debug = require('debug')('cypress:cli') const fs = require('./fs') +const semver = require('semver') + +const pkg = require(path.join(__dirname, '..', 'package.json')) const issuesUrl = 'https://github.com/cypress-io/cypress/issues' @@ -286,14 +288,28 @@ const util = { .value() }, - getOriginalNodeOptions (options) { + getOriginalNodeOptions ({ processVersions }) { + const opts = {} + if (process.env.NODE_OPTIONS) { - return { - ORIGINAL_NODE_OPTIONS: process.env.NODE_OPTIONS, - } + opts.ORIGINAL_NODE_OPTIONS = process.env.NODE_OPTIONS + } + + // https://github.com/cypress-io/cypress/issues/18914 + // Node 17+ ships with OpenSSL 3 by default, so we may need the option + // --openssl-legacy-provider so that webpack@4 can use the legacy MD4 hash + // function. This option doesn't exist on Node <17 or when it is built + // against OpenSSL 1, so we have to detect Node's major version and check + // which version of OpenSSL it was built against before spawning the plugins + // process. + + // To be removed on update to webpack >= 5.61, which no longer relies on + // Node's builtin crypto.hash function. + if (processVersions && semver.satisfies(processVersions.node, '>=17.0.0') && processVersions.openssl.startsWith('3.')) { + opts.ORIGINAL_NODE_OPTIONS += ' --openssl-legacy-provider' } - return {} + return opts }, getForceTty () { diff --git a/packages/server/lib/plugins/index.js b/packages/server/lib/plugins/index.js index da0e05540945..1ef403e73813 100644 --- a/packages/server/lib/plugins/index.js +++ b/packages/server/lib/plugins/index.js @@ -52,21 +52,6 @@ const getChildOptions = (config) => { childOptions.execPath = config.resolvedNodePath } - // https://github.com/cypress-io/cypress/issues/18914 - // Node 17+ ships with OpenSSL 3 by default, so we may need the option - // --openssl-legacy-provider so that webpack@4 can use the legacy MD4 hash - // function. This option doesn't exist on Node <17 or when it is built - // against OpenSSL 1, so we have to detect Node's major version and check - // which version of OpenSSL it was built against before spawning the plugins - // process. - - // To be removed on update to webpack >= 5.61, which no longer relies on - // Node's builtin crypto.hash function. - if (semver.satisfies(config.resolvedNodeVersion, '>=17.0.0') && - !process.versions.openssl.startsWith('1.')) { - childOptions.env.NODE_OPTIONS += ' --openssl-legacy-provider' - } - if (inspector.url()) { childOptions.execArgv = _.chain(process.execArgv.slice(0)) .remove('--inspect-brk') From 6a73bd21344e19bdcb6b93ff3e4cebfed77e98f0 Mon Sep 17 00:00:00 2001 From: Emily Rohrbough Date: Fri, 28 Jan 2022 15:17:48 -0600 Subject: [PATCH 2/7] update tests --- circle.yml | 2 +- cli/lib/util.js | 5 +- cli/package.json | 1 + cli/test/lib/util_spec.js | 68 +++++++++++++++++++ packages/server/lib/plugins/index.js | 1 - .../server/test/unit/plugins/index_spec.js | 39 ----------- 6 files changed, 73 insertions(+), 43 deletions(-) diff --git a/circle.yml b/circle.yml index 4f8b02cd804a..eeac4a383b9c 100644 --- a/circle.yml +++ b/circle.yml @@ -29,7 +29,7 @@ mainBuildFilters: &mainBuildFilters only: - develop - 10.0-release - - test-binary-downstream-windows + - node-17-maybe # usually we don't build Mac app - it takes a long time # but sometimes we want to really confirm we are doing the right thing diff --git a/cli/lib/util.js b/cli/lib/util.js index a8c911d50cb6..f67e599126bb 100644 --- a/cli/lib/util.js +++ b/cli/lib/util.js @@ -303,10 +303,11 @@ const util = { // which version of OpenSSL it was built against before spawning the plugins // process. - // To be removed on update to webpack >= 5.61, which no longer relies on + // To be removed when the Cypress binary pulls in the @cypress/webpack-batteries-included-preprocessor + // version that has been updated to webpack >= 5.61, which no longer relies on // Node's builtin crypto.hash function. if (processVersions && semver.satisfies(processVersions.node, '>=17.0.0') && processVersions.openssl.startsWith('3.')) { - opts.ORIGINAL_NODE_OPTIONS += ' --openssl-legacy-provider' + opts.ORIGINAL_NODE_OPTIONS = `${opts.ORIGINAL_NODE_OPTIONS || ''} --openssl-legacy-provider` } return opts diff --git a/cli/package.json b/cli/package.json index 1cbf5623efdf..2a9089f6c572 100644 --- a/cli/package.json +++ b/cli/package.json @@ -58,6 +58,7 @@ "pretty-bytes": "^5.6.0", "proxy-from-env": "1.0.0", "request-progress": "^3.0.0", + "semver": "^7.3.2", "supports-color": "^8.1.1", "tmp": "~0.2.1", "untildify": "^4.0.0", diff --git a/cli/test/lib/util_spec.js b/cli/test/lib/util_spec.js index b325ccab31a0..39b8e7aa5c91 100644 --- a/cli/test/lib/util_spec.js +++ b/cli/test/lib/util_spec.js @@ -274,6 +274,74 @@ describe('util', () => { ORIGINAL_NODE_OPTIONS: '--require foo.js', }) }) + + // https://github.com/cypress-io/cypress/issues/18914 + it('includes --openssl-legacy-provider in Node 17+ w/ OpenSSL 3', () => { + const processVersions = { + node: 'v17.1.0', + openssl: '3.0.0-quic', + } + + restoreEnv = mockedEnv({ + NODE_OPTIONS: '--require foo.js', + }) + + let childOptions = util.getOriginalNodeOptions({ processVersions }) + + expect(childOptions.ORIGINAL_NODE_OPTIONS).to.eq('--require foo.js --openssl-legacy-provider') + + restoreEnv() + restoreEnv = mockedEnv({}) + childOptions = util.getOriginalNodeOptions({ processVersions }) + + expect(childOptions.ORIGINAL_NODE_OPTIONS).to.eq(' --openssl-legacy-provider') + }) + + // https://github.com/cypress-io/cypress/issues/19320 + it('does not include --openssl-legacy-provider in Node 17+ w/ OpenSSL 1', () => { + const processVersions = { + node: 'v17.1.0', + openssl: '1.0.0', + } + + restoreEnv = mockedEnv({ + NODE_OPTIONS: '--require foo.js', + }) + + let childOptions = util.getOriginalNodeOptions({ processVersions }) + + expect(childOptions.ORIGINAL_NODE_OPTIONS).to.eq('--require foo.js') + expect(childOptions.ORIGINAL_NODE_OPTIONS).not.to.contain('--openssl-legacy-provider') + + restoreEnv() + restoreEnv = mockedEnv({}) + childOptions = util.getOriginalNodeOptions({ processVersions }) + + expect(childOptions.ORIGINAL_NODE_OPTIONS).to.be.undefined + }) + + // https://github.com/cypress-io/cypress/issues/18914 + it('does not include --openssl-legacy-provider in Node <=16', () => { + const processVersions = { + node: 'v16.31.0', + openssl: '1.0.0', + } + + restoreEnv = mockedEnv({}) + + let childOptions = util.getOriginalNodeOptions({ processVersions }) + + expect(childOptions.ORIGINAL_NODE_OPTIONS).to.be.undefined + + restoreEnv = mockedEnv({ + NODE_OPTIONS: '--require foo.js', + }) + + childOptions = util.getOriginalNodeOptions({ processVersions }) + + expect(childOptions.ORIGINAL_NODE_OPTIONS).to.eq('--require foo.js') + expect(childOptions.ORIGINAL_NODE_OPTIONS).not.to.contain('--openssl-legacy-provider') + }) }) context('.exit', () => { diff --git a/packages/server/lib/plugins/index.js b/packages/server/lib/plugins/index.js index 1ef403e73813..c34ddad44c6f 100644 --- a/packages/server/lib/plugins/index.js +++ b/packages/server/lib/plugins/index.js @@ -8,7 +8,6 @@ const inspector = require('inspector') const errors = require('../errors') const util = require('./util') const pkg = require('@packages/root') -const semver = require('semver') let pluginsProcess = null let registeredEvents = {} diff --git a/packages/server/test/unit/plugins/index_spec.js b/packages/server/test/unit/plugins/index_spec.js index 81397112e8e1..8af2124a8a0e 100644 --- a/packages/server/test/unit/plugins/index_spec.js +++ b/packages/server/test/unit/plugins/index_spec.js @@ -64,45 +64,6 @@ describe('lib/plugins/index', () => { expect(childOptions.execPath).to.eq(undefined) }) - - // https://github.com/cypress-io/cypress/issues/18914 - it('includes --openssl-legacy-provider in Node 17+ w/ OpenSSL 3', () => { - const sandbox = sinon.createSandbox() - - sandbox.stub(process.versions, 'openssl').value('3.0.0-quic') - - const childOptions = plugins.getChildOptions({ - resolvedNodeVersion: 'v17.1.0', - }) - - expect(childOptions.env.NODE_OPTIONS).to.contain('--openssl-legacy-provider') - - sandbox.restore() - }) - - // https://github.com/cypress-io/cypress/issues/19320 - it('does not include --openssl-legacy-provider in Node 17+ w/ OpenSSL 1', () => { - const sandbox = sinon.createSandbox() - - sandbox.stub(process.versions, 'openssl').value('1.1.1m') - - const childOptions = plugins.getChildOptions({ - resolvedNodeVersion: 'v17.3.0', - }) - - expect(childOptions.env.NODE_OPTIONS).not.to.contain('--openssl-legacy-provider') - - sandbox.restore() - }) - - // https://github.com/cypress-io/cypress/issues/18914 - it('does not include --openssl-legacy-provider in Node <=16', () => { - const childOptions = plugins.getChildOptions({ - resolvedNodeVersion: 'v16.31.0', - }) - - expect(childOptions.env.NODE_OPTIONS).not.to.contain('--openssl-legacy-provider') - }) }) context('#init', () => { From ef609e7df909e652e6fd6eb86e0957eec9b96984 Mon Sep 17 00:00:00 2001 From: Emily Rohrbough Date: Fri, 28 Jan 2022 17:12:27 -0600 Subject: [PATCH 3/7] lets see if this references the branch --- scripts/binary/bump.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/binary/bump.js b/scripts/binary/bump.js index d8a28866040b..0a0587cceee6 100644 --- a/scripts/binary/bump.js +++ b/scripts/binary/bump.js @@ -18,7 +18,7 @@ const _PROVIDERS = { linux: [ 'cypress-io/cypress-test-tiny', 'cypress-io/cypress-test-module-api', - 'cypress-io/cypress-test-node-versions', + 'cypress-io/cypress-test-node-versions/tree/add-small-cypress-test', 'cypress-io/cypress-test-nested-projects', 'cypress-io/cypress-test-ci-environments', 'cypress-io/cypress-test-example-repos', From f2ca0203ba272756083b03486b99e767b3e1386b Mon Sep 17 00:00:00 2001 From: Emily Rohrbough Date: Fri, 28 Jan 2022 17:25:53 -0600 Subject: [PATCH 4/7] upload binary & url --- circle.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/circle.yml b/circle.yml index eeac4a383b9c..2cbffc852f30 100644 --- a/circle.yml +++ b/circle.yml @@ -1587,7 +1587,7 @@ jobs: - run: name: Check current branch to persist artifacts command: | - if [[ "$CIRCLE_BRANCH" != "develop" && "$CIRCLE_BRANCH" != "test-binary-downstream-windows" ]]; then + if [[ "$CIRCLE_BRANCH" != "develop" && "$CIRCLE_BRANCH" != "node-17-maybe" ]]; then echo "Not uploading artifacts or posting install comment for this branch." circleci-agent step halt fi From a940ced36c3aaa12a17eec1d3397251e99da689e Mon Sep 17 00:00:00 2001 From: Emily Rohrbough Date: Mon, 31 Jan 2022 09:06:51 -0600 Subject: [PATCH 5/7] . --- scripts/binary/bump.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/binary/bump.js b/scripts/binary/bump.js index 0a0587cceee6..d8a28866040b 100644 --- a/scripts/binary/bump.js +++ b/scripts/binary/bump.js @@ -18,7 +18,7 @@ const _PROVIDERS = { linux: [ 'cypress-io/cypress-test-tiny', 'cypress-io/cypress-test-module-api', - 'cypress-io/cypress-test-node-versions/tree/add-small-cypress-test', + 'cypress-io/cypress-test-node-versions', 'cypress-io/cypress-test-nested-projects', 'cypress-io/cypress-test-ci-environments', 'cypress-io/cypress-test-example-repos', From 1d75c775083f46de48747e831b87a978c0f641b1 Mon Sep 17 00:00:00 2001 From: Emily Rohrbough Date: Mon, 31 Jan 2022 09:24:04 -0600 Subject: [PATCH 6/7] pass token --- scripts/binary/bump.js | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/scripts/binary/bump.js b/scripts/binary/bump.js index d8a28866040b..b7cc4dd8dd40 100644 --- a/scripts/binary/bump.js +++ b/scripts/binary/bump.js @@ -268,15 +268,7 @@ Testing new Cypress version ${version} } // first try to commit to branch for next upcoming version - const specificBranchOptions = { - owner, - repo, - token: creds.githubToken, - message, - branch: version, - } - - return makeEmptyGithubCommit(specificBranchOptions) + return makeEmptyGithubCommit({ ...defaultOptions, branch: version }) .catch(() => { // maybe there is no branch for next version // try default branch From 3c013e86151e349ff6716f7497ec06f782c881b6 Mon Sep 17 00:00:00 2001 From: Emily Rohrbough Date: Mon, 31 Jan 2022 10:51:21 -0600 Subject: [PATCH 7/7] PR feedback - use process.versions directly. --- .husky/pre-commit | 2 +- cli/lib/exec/spawn.js | 1 - cli/lib/util.js | 6 +++--- cli/test/lib/util_spec.js | 34 ++++++++++++++++------------------ 4 files changed, 20 insertions(+), 23 deletions(-) diff --git a/.husky/pre-commit b/.husky/pre-commit index 9f5c7d244218..36af219892fd 100755 --- a/.husky/pre-commit +++ b/.husky/pre-commit @@ -1,4 +1,4 @@ #!/bin/sh . "$(dirname "$0")/_/husky.sh" -# npx lint-staged +npx lint-staged diff --git a/cli/lib/exec/spawn.js b/cli/lib/exec/spawn.js index 2712872b106b..9286f1ad7d71 100644 --- a/cli/lib/exec/spawn.js +++ b/cli/lib/exec/spawn.js @@ -88,7 +88,6 @@ module.exports = { env: process.env, detached: false, stdio: getStdio(needsXvfb), - processVersions: process.versions, }) const spawn = (overrides = {}) => { diff --git a/cli/lib/util.js b/cli/lib/util.js index f67e599126bb..36dbb788d915 100644 --- a/cli/lib/util.js +++ b/cli/lib/util.js @@ -284,11 +284,11 @@ const util = { .mapValues((value) => { // stringify to 1 or 0 return value ? '1' : '0' }) - .extend(util.getOriginalNodeOptions(options)) + .extend(util.getOriginalNodeOptions()) .value() }, - getOriginalNodeOptions ({ processVersions }) { + getOriginalNodeOptions () { const opts = {} if (process.env.NODE_OPTIONS) { @@ -306,7 +306,7 @@ const util = { // To be removed when the Cypress binary pulls in the @cypress/webpack-batteries-included-preprocessor // version that has been updated to webpack >= 5.61, which no longer relies on // Node's builtin crypto.hash function. - if (processVersions && semver.satisfies(processVersions.node, '>=17.0.0') && processVersions.openssl.startsWith('3.')) { + if (process.versions && semver.satisfies(process.versions.node, '>=17.0.0') && process.versions.openssl.startsWith('3.')) { opts.ORIGINAL_NODE_OPTIONS = `${opts.ORIGINAL_NODE_OPTIONS || ''} --openssl-legacy-provider` } diff --git a/cli/test/lib/util_spec.js b/cli/test/lib/util_spec.js index 39b8e7aa5c91..8412933170f6 100644 --- a/cli/test/lib/util_spec.js +++ b/cli/test/lib/util_spec.js @@ -257,6 +257,7 @@ describe('util', () => { context('.getOriginalNodeOptions', () => { let restoreEnv + const sandbox = sinon.createSandbox() afterEach(() => { if (restoreEnv) { @@ -266,6 +267,9 @@ describe('util', () => { }) it('copy NODE_OPTIONS to ORIGINAL_NODE_OPTIONS', () => { + sandbox.stub(process.versions, 'node').value('v16.5.0') + sandbox.stub(process.versions, 'openssl').value('1.0.0') + restoreEnv = mockedEnv({ NODE_OPTIONS: '--require foo.js', }) @@ -277,59 +281,53 @@ describe('util', () => { // https://github.com/cypress-io/cypress/issues/18914 it('includes --openssl-legacy-provider in Node 17+ w/ OpenSSL 3', () => { - const processVersions = { - node: 'v17.1.0', - openssl: '3.0.0-quic', - } + sandbox.stub(process.versions, 'node').value('v17.1.0') + sandbox.stub(process.versions, 'openssl').value('3.0.0-quic') restoreEnv = mockedEnv({ NODE_OPTIONS: '--require foo.js', }) - let childOptions = util.getOriginalNodeOptions({ processVersions }) + let childOptions = util.getOriginalNodeOptions() expect(childOptions.ORIGINAL_NODE_OPTIONS).to.eq('--require foo.js --openssl-legacy-provider') restoreEnv() restoreEnv = mockedEnv({}) - childOptions = util.getOriginalNodeOptions({ processVersions }) + childOptions = util.getOriginalNodeOptions() expect(childOptions.ORIGINAL_NODE_OPTIONS).to.eq(' --openssl-legacy-provider') }) // https://github.com/cypress-io/cypress/issues/19320 it('does not include --openssl-legacy-provider in Node 17+ w/ OpenSSL 1', () => { - const processVersions = { - node: 'v17.1.0', - openssl: '1.0.0', - } + sandbox.stub(process.versions, 'node').value('v17.1.0') + sandbox.stub(process.versions, 'openssl').value('1.0.0') restoreEnv = mockedEnv({ NODE_OPTIONS: '--require foo.js', }) - let childOptions = util.getOriginalNodeOptions({ processVersions }) + let childOptions = util.getOriginalNodeOptions() expect(childOptions.ORIGINAL_NODE_OPTIONS).to.eq('--require foo.js') expect(childOptions.ORIGINAL_NODE_OPTIONS).not.to.contain('--openssl-legacy-provider') restoreEnv() restoreEnv = mockedEnv({}) - childOptions = util.getOriginalNodeOptions({ processVersions }) + childOptions = util.getOriginalNodeOptions() expect(childOptions.ORIGINAL_NODE_OPTIONS).to.be.undefined }) // https://github.com/cypress-io/cypress/issues/18914 it('does not include --openssl-legacy-provider in Node <=16', () => { - const processVersions = { - node: 'v16.31.0', - openssl: '1.0.0', - } + sandbox.stub(process.versions, 'node').value('v16.5.0') + sandbox.stub(process.versions, 'openssl').value('1.0.0') restoreEnv = mockedEnv({}) - let childOptions = util.getOriginalNodeOptions({ processVersions }) + let childOptions = util.getOriginalNodeOptions() expect(childOptions.ORIGINAL_NODE_OPTIONS).to.be.undefined @@ -337,7 +335,7 @@ describe('util', () => { NODE_OPTIONS: '--require foo.js', }) - childOptions = util.getOriginalNodeOptions({ processVersions }) + childOptions = util.getOriginalNodeOptions() expect(childOptions.ORIGINAL_NODE_OPTIONS).to.eq('--require foo.js') expect(childOptions.ORIGINAL_NODE_OPTIONS).not.to.contain('--openssl-legacy-provider')