From 2a5ca2de696eeb8b40a38de90580441c4c6c96e0 Mon Sep 17 00:00:00 2001 From: Sonishi Izuka Date: Mon, 27 Feb 2023 02:17:56 +0900 Subject: [PATCH] chore(package manager): introduce Corepack (#674) * chore(package manager): introduce Corepack From now on, we will use Corepack to manage pnpm versions. see https://nodejs.org/api/corepack.html see https://github.com/nodejs/corepack * ci(github actions): setup Corepack instead of pnpm Corepack automatically prepares the pnpm. Thus, all we have to do is execute the `corepack enable` command. * ci(corepack): should not use the latest Corepack for old Node.js * ci(corepack): override Corepack if version range is specified * ci(corepack): show installed Corepack versions * ci: use the `npm install --global ...` command instead of the `npm install -g ...` command * ci(debug): try to use pnpm without running the `corepack enable` command Surprisingly, Corepack seems to work with all versions of Node.js on GitHub Actions. Perhaps there is no need to run the `corepack enable` command. * revert: ci(debug): try to use pnpm without running the `corepack enable` command The following error occurred on each job: pnpm: command not found It seems that the `corepack enable` command must be executed. This reverts commit 8cb0f488922011c79a143df297590399b7220cd5. * docs: add setup instructions using Corepack in `CONTRIBUTING.md` file * ci(github actions): fix the name of steps for enable Corepack to be more understandable The step name "Setup Corepack" indicates that it is setting up Corepack. However, this step name does not clearly indicate that pnpm will be available automatically. Contributors who are not familiar with Node.js will not be able to grasp what is possible by enabling Corepack. So we fix the step names and clarify what we are enabling Corepack for. --- .github/workflows/ci.yaml | 53 ++++++++++++++++++----- .github/workflows/release.yaml | 12 +++--- CONTRIBUTING.md | 11 ++++- actions/setup-pnpm/action.yaml | 15 ------- actions/setup-pnpm/get-pnpm-data.js | 67 ----------------------------- package.json | 1 + 6 files changed, 60 insertions(+), 99 deletions(-) delete mode 100644 actions/setup-pnpm/action.yaml delete mode 100644 actions/setup-pnpm/get-pnpm-data.js diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index d1508cd3f..6e013e1f2 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -73,6 +73,8 @@ jobs: uses: actions/setup-node@v3 with: node-version: ${{ matrix.node-version }} + - name: Enable Corepack (Automatically setup a package manager for Node.js) + run: corepack enable - name: Cache .pnpm-store uses: actions/cache@v3 with: @@ -82,8 +84,6 @@ jobs: ${{ runner.os }}-node-${{ matrix.node-version }}- ${{ runner.os }}-node- ${{ runner.os }}- - - name: Setup pnpm - uses: ./actions/setup-pnpm - name: Install Dependencies run: pnpm install - name: Build packages @@ -145,6 +145,8 @@ jobs: uses: actions/setup-node@v3 with: node-version: ${{ matrix.node-version }} + - name: Enable Corepack (Automatically setup a package manager for Node.js) + run: corepack enable - name: Cache actionlint uses: actions/cache@v3 with: @@ -154,8 +156,6 @@ jobs: ./scripts/actionlint/download-actionlint.bash ./scripts/actionlint/download-actionlint.bash.http-cache-metadata.json key: actionlint-${{ runner.os }} - - name: Setup pnpm - uses: ./actions/setup-pnpm - run: pnpm run lint format: needs: pre-build @@ -184,8 +184,8 @@ jobs: uses: actions/setup-node@v3 with: node-version: ${{ matrix.node-version }} - - name: Setup pnpm - uses: ./actions/setup-pnpm + - name: Enable Corepack (Automatically setup a package manager for Node.js) + run: corepack enable - name: Setup dprint # The dprint command may fail to deserialize the wasm module. # This only happens on CI, and in some cases no error occurs. @@ -303,8 +303,8 @@ jobs: uses: actions/setup-node@v3 with: node-version: ${{ matrix.node-version }} - - name: Setup pnpm - uses: ./actions/setup-pnpm + - name: Enable Corepack (Automatically setup a package manager for Node.js) + run: corepack enable - name: Install flatbuffers # https://snapcraft.io/flatbuffers run: | @@ -401,6 +401,21 @@ jobs: - 17.x - 18.0.0 - 18.x + include: + # Corepack 0.11.0 and later only supports Node.js 14.14.0 and later + # see https://github.com/nodejs/corepack/pull/227 + - node-version: 12.17.0 + corepack-version-range: "<0.11" + - node-version: 12.20.0 + corepack-version-range: "<0.11" + - node-version: 12.x + corepack-version-range: "<0.11" + - node-version: 14.1.0 + corepack-version-range: "<0.11" + - node-version: 14.13.0 + corepack-version-range: "<0.11" + - node-version: 14.13.1 + corepack-version-range: "<0.11" steps: - uses: actions/checkout@v3 - name: Download installed dependencies @@ -430,6 +445,26 @@ jobs: uses: actions/setup-node@v3 with: node-version: ${{ matrix.node-version }} + - name: Enable Corepack (Automatically setup a package manager for Node.js) + shell: bash + # If Corepack does not exist or a Corepack version range is specified, install Corepack + run: | + readonly COREPACK_VERSION_RANGE='${{ matrix.corepack-version-range }}' + if { type corepack >/dev/null 2>&1; } && [ -z "${COREPACK_VERSION_RANGE}" ]; then + echo Corepack "$(corepack --version)" is already installed + else + readonly corepack_package_spec="corepack${COREPACK_VERSION_RANGE:+"@${COREPACK_VERSION_RANGE}"}" + if type corepack >/dev/null 2>&1; then + echo '::group::Override corepack' "(install ${corepack_package_spec})" + else + echo '::group::Install' "${corepack_package_spec}" + fi + npm install --global "${corepack_package_spec}" + echo '::endgroup::' + fi + echo '::group::$' corepack enable + corepack enable + echo '::endgroup::' - name: Cache .pnpm-store uses: actions/cache@v3 with: @@ -440,8 +475,6 @@ jobs: ${{ runner.os }}-node- ${{ runner.os }}- if: ${{ ! steps.restore-deps-and-build.outputs.node_modules }} - - name: Setup pnpm - uses: ./actions/setup-pnpm - name: Install Dependencies run: pnpm install if: ${{ ! steps.restore-deps-and-build.outputs.node_modules }} diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index 1bada95c4..50a1b7649 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -124,6 +124,9 @@ jobs: with: node-version: 16.x if: ${{ steps.release-pr.outputs.ref }} + - name: Commit to Release PR / Enable Corepack (Automatically setup a package manager for Node.js) + run: corepack enable + if: ${{ steps.release-pr.outputs.ref }} - name: Commit to Release PR / Cache .pnpm-store uses: actions/cache@v3 with: @@ -134,9 +137,6 @@ jobs: ${{ runner.os }}-node- ${{ runner.os }}- if: ${{ steps.release-pr.outputs.ref }} - - name: Commit to Release PR / Setup pnpm - uses: ./actions/setup-pnpm - if: ${{ steps.release-pr.outputs.ref }} - name: Commit to Release PR / Install Dependencies run: pnpm install if: ${{ steps.release-pr.outputs.ref }} @@ -215,6 +215,9 @@ jobs: # Note: The `registry-url` option is required. # If this option is not set, the "npm publish" command will not detect the environment variable NODE_AUTH_TOKEN. if: ${{ steps.release.outputs.releases_created }} + - name: Publish / Enable Corepack (Automatically setup a package manager for Node.js) + run: corepack enable + if: ${{ steps.release.outputs.releases_created }} - name: Publish / Cache .pnpm-store uses: actions/cache@v3 with: @@ -225,9 +228,6 @@ jobs: ${{ runner.os }}-node- ${{ runner.os }}- if: ${{ steps.release.outputs.releases_created }} - - name: Publish / Setup pnpm - uses: ./actions/setup-pnpm - if: ${{ steps.release.outputs.releases_created }} - name: Publish / Install Dependencies run: pnpm install if: ${{ steps.release.outputs.releases_created }} diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 9f9f33ade..2f296785f 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -25,10 +25,19 @@ We use [Semantic Versioning](https://semver.org/). - [Git](https://git-scm.com/) - [Node.js](https://nodejs.org/) -- [pnpm](https://pnpm.js.org/) +- [pnpm](https://pnpm.js.org/) (If [Corepack] is available, you do not need to install pnpm) + +[Corepack]: https://nodejs.org/api/corepack.html ### Setup +> **Note** +> If [Corepack] is available in your development environment, do not forget to [enable Corepack](https://nodejs.org/docs/latest-v16.x/api/corepack.html#enabling-the-feature) before running the `pnpm` command. +> +> ```sh +> $ corepack enable +> ``` + ```sh $ git clone https://github.com/sounisi5011/npm-packages.git $ cd ./npm-packages/ diff --git a/actions/setup-pnpm/action.yaml b/actions/setup-pnpm/action.yaml deleted file mode 100644 index e88d43129..000000000 --- a/actions/setup-pnpm/action.yaml +++ /dev/null @@ -1,15 +0,0 @@ -name: Setup pnpm environment -author: sounisi5011 -description: Install and set up pnpm, the version of pnpm will be automatically detected from the `engines` field in the `package.json` file in the project root -runs: - using: composite - steps: - - id: get-pnpm-data - shell: bash - run: node ${{ github.action_path }}/get-pnpm-data.js - - shell: bash - run: | - echo '::group::$' npm i -g pnpm@${{ steps.get-pnpm-data.outputs.pnpm-version-range }} - npm i -g pnpm@${{ steps.get-pnpm-data.outputs.pnpm-version-range }} - echo '::endgroup::' - echo Installed pnpm version: $(pnpm --version) diff --git a/actions/setup-pnpm/get-pnpm-data.js b/actions/setup-pnpm/get-pnpm-data.js deleted file mode 100644 index 9795ece9f..000000000 --- a/actions/setup-pnpm/get-pnpm-data.js +++ /dev/null @@ -1,67 +0,0 @@ -// @ts-check - -const fs = require('fs'); -const os = require('os'); -const path = require('path'); - -/** - * @param {string} name - * @param {string} value - * @returns {void} - * @see https://github.blog/changelog/2022-10-11-github-actions-deprecating-save-state-and-set-output-commands/ - */ -function setOutput(name, value) { - // eslint-disable-next-line dot-notation - const outputFilepath = process.env['GITHUB_OUTPUT']; - if (outputFilepath) { - /** @type {number|null} */ - let fd = null; - try { - /** - * Open file for appending. An exception occurs if the file does not exist. - * @see https://github.com/nodejs/node/issues/1592#issuecomment-223819785 - */ - fd = fs.openSync(outputFilepath, fs.constants.O_APPEND | fs.constants.O_WRONLY); - /** - * Note: With the `flag` option, there is no need to use the `fs.openSync()` function in the above line. - * However, it is not documented that the `flag` option can be passed a number. - * We use the `fs.openSync()` function to ensure that it will work in future Node.js. - */ - fs.writeFileSync(fd, `${name}=${value}${os.EOL}`); - return; - } finally { - if (typeof fd === 'number') { - fs.closeSync(fd); - } - } - } - - /** - * If writing to the "GITHUB_OUTPUT" file fails, try the old approach. - */ - console.log(`::set-output name=${name}::${value}`); -} - -function main() { - const pkgJsonPath = path.resolve('package.json'); - const pkg = require(pkgJsonPath); - console.log(`Loaded ${pkgJsonPath}`); - - const { engines } = pkg; - if (!engines) throw new Error('`engines` field is not defined'); - if (typeof engines !== 'object') throw new Error('`engines` field is not object value'); - - const pnpmVersionRange = engines.pnpm; - if (!pnpmVersionRange) throw new Error('`engines.pnpm` field is not defined'); - if (typeof pnpmVersionRange !== 'string') throw new Error('`engines.pnpm` field is not string value'); - - console.log(`Detect pnpm version: ${pnpmVersionRange}`); - setOutput('pnpm-version-range', pnpmVersionRange || ''); -} - -try { - main(); -} catch (error) { - process.exitCode = 1; - console.error(error.message); -} diff --git a/package.json b/package.json index 83059c203..9cfcee577 100644 --- a/package.json +++ b/package.json @@ -77,6 +77,7 @@ "typescript": "4.9.4", "ultra-runner": "3.10.5" }, + "packageManager": "pnpm@6.32.25", "engines": { "node": "^12.17.x || 14.x || 15.x || 16.x || 17.x || >=18.x", "npm": "use pnpm please!",