From 0716a45b7ddd280b57156aa7e16979a2797ac0a1 Mon Sep 17 00:00:00 2001 From: Pierre Vanduynslager Date: Thu, 5 Dec 2019 01:09:09 -0500 Subject: [PATCH] feat: require Node.js >=10.13 BREAKING CHANGE: Require Node.js >= 10.13 --- .travis.yml | 3 +-- bin/semantic-release.js | 2 +- docs/recipes/github-actions.md | 2 +- docs/recipes/gitlab-ci.md | 2 +- docs/support/FAQ.md | 10 +++++----- docs/support/node-version.md | 6 +++--- lib/branches/index.js | 2 +- lib/get-git-auth-url.js | 3 ++- lib/git.js | 4 ++-- lib/utils.js | 6 ++++-- package.json | 2 +- test/helpers/git-utils.js | 2 +- 12 files changed, 23 insertions(+), 21 deletions(-) diff --git a/.travis.yml b/.travis.yml index f6aa5c3d..f0e66956 100644 --- a/.travis.yml +++ b/.travis.yml @@ -5,8 +5,7 @@ services: node_js: - 12 - - 10 - - 8.16 + - 10.13 # Trigger a push build on release and greenkeeper branches + PRs build on every branches # Avoid double build on PRs (See https://github.com/travis-ci/travis-ci/issues/1147) diff --git a/bin/semantic-release.js b/bin/semantic-release.js index 37fcf858..8cfbaada 100755 --- a/bin/semantic-release.js +++ b/bin/semantic-release.js @@ -35,7 +35,7 @@ execa('git', ['--version']) process.exit(1); }); -// Node 8+ from this point on +// Node 10+ from this point on require('../cli')() .then(exitCode => { process.exitCode = exitCode; diff --git a/docs/recipes/github-actions.md b/docs/recipes/github-actions.md index c448a6d9..ed84f774 100644 --- a/docs/recipes/github-actions.md +++ b/docs/recipes/github-actions.md @@ -10,7 +10,7 @@ In this example an [`NPM_TOKEN`](https://docs.npmjs.com/creating-and-viewing-aut [GitHub Actions](https://github.com/features/actions) support [Workflows](https://help.github.com/en/articles/configuring-workflows), allowing to run tests on multiple Node versions and publish a release only when all test pass. -**Note**: The publish pipeline must run on [Node version >= 8.16](../support/FAQ.md#why-does-semantic-release-require-node-version--816). +**Note**: The publish pipeline must run on [Node version >= 10.13](../support/FAQ.md#why-does-semantic-release-require-node-version--1013). ### `.github/workflows/release.yml` configuration for Node projects diff --git a/docs/recipes/gitlab-ci.md b/docs/recipes/gitlab-ci.md index 5df4b1b4..dd576730 100644 --- a/docs/recipes/gitlab-ci.md +++ b/docs/recipes/gitlab-ci.md @@ -10,7 +10,7 @@ The [Authentication](../usage/ci-configuration.md#authentication) environment va GitLab CI supports [Pipelines](https://docs.gitlab.com/ee/ci/pipelines.html) allowing to test on multiple Node versions and publishing a release only when all test pass. -**Note**: The publish pipeline must run a [Node >= 8.16 version](../support/FAQ.md#why-does-semantic-release-require-node-version--816). +**Note**: The publish pipeline must run a [Node >= 10.13 version](../support/FAQ.md#why-does-semantic-release-require-node-version--1013). ### `.gitlab-ci.yml` configuration for Node projects diff --git a/docs/support/FAQ.md b/docs/support/FAQ.md index cb9d6278..40ef3072 100644 --- a/docs/support/FAQ.md +++ b/docs/support/FAQ.md @@ -38,7 +38,7 @@ Yes with the [dry-run options](../usage/configuration.md#dryrun) which prints to ## Can I use semantic-release with Yarn? -If you are using a [local](../usage/installation.md#local-installation) **semantic-release** installation and run multiple CI jobs with different versions, the `yarn install` command will fail on jobs running with Node < 8 as **semantic-release** requires [Node >= 8.16](#why-does-semantic-release-require-node-version--816) and specifies it in its `package.json`s [`engines`](https://docs.npmjs.com/files/package.json#engines) key. +If you are using a [local](../usage/installation.md#local-installation) **semantic-release** installation and run multiple CI jobs with different versions, the `yarn install` command will fail on jobs running with Node < 8 as **semantic-release** requires [Node >= 10.13](#why-does-semantic-release-require-node-version--1013) and specifies it in its `package.json`s [`engines`](https://docs.npmjs.com/files/package.json#engines) key. The recommended solution is to use the [Yarn](https://yarnpkg.com) [--ignore-engines](https://yarnpkg.com/en/docs/cli/install#toc-yarn-install-ignore-engines) option to install the project dependencies on the CI environment, so Yarn will ignore the **semantic-release**'s `engines` key: @@ -48,7 +48,7 @@ $ yarn install --ignore-engines **Note**: Several CI services use Yarn by default if your repository contains a `yarn.lock` file. So you should override the install step to specify `yarn install --ignore-engines`. -Alternatively you can use a [global](../usage/installation.md#global-installation) **semantic-release** installation and make sure to install and run the `semantic-release` command only in a CI jobs running with Node >= 8.16. +Alternatively you can use a [global](../usage/installation.md#global-installation) **semantic-release** installation and make sure to install and run the `semantic-release` command only in a CI jobs running with Node >= 10.13. If your CI environment provides [nvm](https://github.com/creationix/nvm) you can switch to Node 8 before installing and running the `semantic-release` command: @@ -73,7 +73,7 @@ Yes, **semantic-release** is a Node CLI application but it can be used to publis To publish a non-Node package (without a `package.json`) you would need to: - Use a [global](../usage/installation.md#global-installation) **semantic-release** installation - Set **semantic-release** [options](../usage/configuration.md#options) via [CLI arguments or rc file](../usage/configuration.md#configuration) -- Make sure your CI job executing the `semantic-release` command has access to [Node >= 8.16](#why-does-semantic-release-require-node-version--816) to execute the `semantic-release` command +- Make sure your CI job executing the `semantic-release` command has access to [Node >= 10.13](#why-does-semantic-release-require-node-version--1013) to execute the `semantic-release` command See the [CI configuration recipes](../recipes/README.md#ci-configurations) for more details on specific CI environments. @@ -232,9 +232,9 @@ See [“Introduction to SemVer” - Irina Gebauer](https://blog.greenkeeper.io/i In addition the [verify conditions step](../../README.md#release-steps) verifies that all necessary conditions for proceeding with a release are met, and a new release will be performed [only if all your tests pass](../usage/ci-configuration.md#run-semantic-release-only-after-all-tests-succeeded). -## Why does semantic-release require Node version >= 8.16? +## Why does semantic-release require Node version >= 10.13? -**semantic-release** is written using the latest [ECMAScript 2017](https://www.ecma-international.org/publications/standards/Ecma-262.htm) features, without transpilation which **requires Node version 8.16 or higher**. +**semantic-release** is written using the latest [ECMAScript 2017](https://www.ecma-international.org/publications/standards/Ecma-262.htm) features, without transpilation which **requires Node version 10.13 or higher**. See [Node version requirement](./node-version.md#node-version-requirement) for more details and solutions. diff --git a/docs/support/node-version.md b/docs/support/node-version.md index 633a8c72..8a6266a5 100644 --- a/docs/support/node-version.md +++ b/docs/support/node-version.md @@ -1,6 +1,6 @@ # Node version requirement -**semantic-release** is written using the latest [ECMAScript 2017](https://www.ecma-international.org/publications/standards/Ecma-262.htm) features, without transpilation which requires **requires Node version 8.16 or higher**. +**semantic-release** is written using the latest [ECMAScript 2017](https://www.ecma-international.org/publications/standards/Ecma-262.htm) features, without transpilation which requires **requires Node version 10 or higher**. **semantic-release** is meant to be used in a CI environment as a development support tool, not as a production dependency. Therefore the only constraint is to run the `semantic-release` in a CI environment providing Node 8 or higher. @@ -8,9 +8,9 @@ See our [Node Support Policy](node-support-policy.md) for our long-term promise ## Recommended solution -### Run at least one CI job with Node >= 8.16 +### Run at least one CI job with Node >= 10.13 -The recommended approach is to run the `semantic-release` command from a CI job running on Node 8.16 or higher. This can either be a job used by your project to test on Node >= 8.16 or a dedicated job for the release steps. +The recommended approach is to run the `semantic-release` command from a CI job running on Node 10.13 or higher. This can either be a job used by your project to test on Node >= 10.13 or a dedicated job for the release steps. See [CI configuration](../usage/ci-configuration.md) and [CI configuration recipes](../recipes/README.md#ci-configurations) for more details. diff --git a/lib/branches/index.js b/lib/branches/index.js index b94e76f2..8bedfe69 100644 --- a/lib/branches/index.js +++ b/lib/branches/index.js @@ -50,7 +50,7 @@ module.exports = async (repositoryUrl, ciBranch, context) => { const duplicates = [...branches] .map(branch => branch.name) .sort() - .filter((val, idx, arr) => arr[idx] === arr[idx + 1] && arr[idx] !== arr[idx - 1]); + .filter((_, idx, arr) => arr[idx] === arr[idx + 1] && arr[idx] !== arr[idx - 1]); if (duplicates.length > 0) { errors.push(getError('EDUPLICATEBRANCHES', {duplicates})); diff --git a/lib/get-git-auth-url.js b/lib/get-git-auth-url.js index d02b0cc6..88d63a72 100644 --- a/lib/get-git-auth-url.js +++ b/lib/get-git-auth-url.js @@ -47,7 +47,8 @@ module.exports = async ({cwd, env, branch, options: {repositoryUrl}}) => { if (gitCredentials) { // If credentials are set via environment variables, convert the URL to http/https and add basic auth, otherwise return `repositoryUrl` as is - const [match, auth, host, path] = /^(?!.+:\/\/)(?:(.*)@)?(.*?):(.*)$/.exec(repositoryUrl) || []; + const [match, auth, host, path] = + /^(?!.+:\/\/)(?:(?.*)@)?(?.*?):(?.*)$/.exec(repositoryUrl) || []; const {port, hostname, ...parsed} = parse( match ? `ssh://${auth ? `${auth}@` : ''}${host}/${path}` : repositoryUrl ); diff --git a/lib/git.js b/lib/git.js index efaecadb..563b4774 100644 --- a/lib/git.js +++ b/lib/git.js @@ -65,7 +65,7 @@ async function getCommits(from, to, execaOpts) { async function getBranches(repositoryUrl, execaOpts) { return (await execa('git', ['ls-remote', '--heads', repositoryUrl], execaOpts)).stdout .split('\n') - .map(branch => branch.match(/^.+refs\/heads\/(.+)$/)[1]) + .map(branch => branch.match(/^.+refs\/heads\/(?.+)$/)[1]) .filter(Boolean); } @@ -312,7 +312,7 @@ async function verifyBranchName(branch, execaOpts) { async function isBranchUpToDate(repositoryUrl, branch, execaOpts) { const {stdout: remoteHead} = await execa('git', ['ls-remote', '--heads', repositoryUrl, branch], execaOpts); try { - return await isRefInHistory(remoteHead.match(/^(\w+)?/)[1], branch, execaOpts); + return await isRefInHistory(remoteHead.match(/^(?\w+)?/)[1], branch, execaOpts); } catch (error) { debug(error); } diff --git a/lib/utils.js b/lib/utils.js index e40c5d19..14d9d028 100644 --- a/lib/utils.js +++ b/lib/utils.js @@ -31,11 +31,13 @@ function isMaintenanceRange(range) { } function getUpperBound(range) { - return semver.valid(range) ? range : ((semver.validRange(range) || '').match(/<(\d+\.\d+\.\d+)$/) || [])[1]; + return semver.valid(range) + ? range + : ((semver.validRange(range) || '').match(/<(?\d+\.\d+\.\d+)$/) || [])[1]; } function getLowerBound(range) { - return ((semver.validRange(range) || '').match(/(\d+\.\d+\.\d+)/) || [])[1]; + return ((semver.validRange(range) || '').match(/(?\d+\.\d+\.\d+)/) || [])[1]; } function highest(version1, version2) { diff --git a/package.json b/package.json index d2538fcb..01bf4aa4 100644 --- a/package.json +++ b/package.json @@ -72,7 +72,7 @@ "xo": "^0.25.0" }, "engines": { - "node": ">=8.16" + "node": ">=10.13" }, "files": [ "bin", diff --git a/test/helpers/git-utils.js b/test/helpers/git-utils.js index 2dfa4ba2..c474801b 100644 --- a/test/helpers/git-utils.js +++ b/test/helpers/git-utils.js @@ -213,7 +213,7 @@ export async function gitRemoteTagHead(repositoryUrl, tagName, execaOpts) { return (await execa('git', ['ls-remote', '--tags', repositoryUrl, tagName], execaOpts)).stdout .split('\n') .filter(tag => Boolean(tag)) - .map(tag => tag.match(/^(\S+)/)[1])[0]; + .map(tag => tag.match(/^(?\S+)/)[1])[0]; } /**