diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index ed051367..2e8d0be6 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -12,6 +12,7 @@ defaults: env: NODE_OPTIONS: "--unhandled-rejections=strict" + VOLTA_FEATURE_PNPM: 1 concurrency: group: ci-${{ github.head_ref || github.ref }} @@ -59,9 +60,10 @@ jobs: - run: ./action/tests/log-info.sh - run: ./action/tests/check-version.sh 'volta' ${{ matrix.volta-version }} - - run: volta install node@10.17.0 yarn@1.19.0 + - run: volta install node@10.17.0 yarn@1.19.0 pnpm@9.0.0 - run: ./action/tests/check-version.sh 'node' 'v10.17.0' - run: ./action/tests/check-version.sh 'yarn' '1.19.0' + - run: ./action/tests/check-version.sh 'pnpm' '9.0.0' test-no-options: runs-on: "${{ matrix.os }}-latest" @@ -83,10 +85,11 @@ jobs: - run: ./action/tests/log-info.sh - run: ./action/tests/check-version.sh 'volta' 'current' - - run: volta install node@12.16.1 npm@7.5.2 yarn@1.19.1 + - run: volta install node@12.16.1 npm@7.5.2 yarn@1.19.1 pnpm@9.0.0 - run: ./action/tests/check-version.sh 'node' 'v12.16.1' - run: ./action/tests/check-version.sh 'npm' '7.5.2' - run: ./action/tests/check-version.sh 'yarn' '1.19.1' + - run: ./action/tests/check-version.sh 'pnpm' '9.0.0' test-specified-node-npm-yarn-overrides-pinned-versions: runs-on: "${{ matrix.os }}-latest" @@ -114,11 +117,13 @@ jobs: node-version: 12.14.0 npm-version: 7.5.2 yarn-version: 1.22.0 + pnpm-version: 9.0.0 - run: ./action/tests/log-info.sh - run: ./action/tests/check-version.sh 'node' 'v12.14.0' - run: ./action/tests/check-version.sh 'npm' '7.5.2' - run: ./action/tests/check-version.sh 'yarn' '1.22.0' + - run: ./action/tests/check-version.sh 'pnpm' '9.0.0' test-specific-volta-node-npm-yarn: runs-on: "${{ matrix.os }}-latest" @@ -141,12 +146,14 @@ jobs: node-version: 12.0.0 npm-version: 7.5.2 yarn-version: 1.22.0 + pnpm-version: 9.0.0 - run: ./action/tests/log-info.sh - run: ./action/tests/check-version.sh 'volta' '1.0.8' - run: ./action/tests/check-version.sh 'node' 'v12.0.0' - run: ./action/tests/check-version.sh 'npm' '7.5.2' - run: ./action/tests/check-version.sh 'yarn' '1.22.0' + - run: ./action/tests/check-version.sh 'pnpm' '9.0.0' test-specified-registry-url: runs-on: "${{ matrix.os }}-latest" @@ -171,9 +178,10 @@ jobs: - run: ./action/tests/log-info.sh - run: ./action/tests/check-version.sh 'volta' 'current' - - run: volta install node@10.17.0 yarn@1.19.0 + - run: volta install node@10.17.0 yarn@1.19.0 pnpm@9.0.0 - run: ./action/tests/check-version.sh 'node' 'v10.17.0' - run: ./action/tests/check-version.sh 'yarn' '1.19.0' + - run: ./action/tests/check-version.sh 'pnpm' '9.0.0' - run: ./action/tests/check-registry.sh 'https://some.path.here.com/lol/' test-specific-variant: @@ -194,10 +202,11 @@ jobs: - run: ./action/tests/log-info.sh - run: ./action/tests/check-version.sh 'volta' 'current' - - run: volta install node@12.16.1 npm@7.5.2 yarn@1.19.1 + - run: volta install node@12.16.1 npm@7.5.2 yarn@1.19.1 pnpm@9.0.0 - run: ./action/tests/check-version.sh 'node' 'v12.16.1' - run: ./action/tests/check-version.sh 'npm' '7.5.2' - run: ./action/tests/check-version.sh 'yarn' '1.19.1' + - run: ./action/tests/check-version.sh 'pnpm' '9.0.0' test-js-project-in-subdir-no-options: runs-on: "ubuntu-latest" diff --git a/README.md b/README.md index 46d19404..478786a8 100644 --- a/README.md +++ b/README.md @@ -18,6 +18,7 @@ This action installs [volta](https://volta.sh) by: | `node-version` |

Version Spec of the node version to use. Examples: 10.6.x, 10.15.1, >=10.15.0

| `false` | `""` | | `npm-version` |

Version Spec of the npm version to use. Examples: 7.5.x, 7.5.3, >=7.5.3

| `false` | `""` | | `yarn-version` |

Version Spec of the yarn version to use. Examples: 1.6.x, 10.15.1, >=10.15.0

| `false` | `""` | +| `pnpm-version` |

experimental. Version Spec of the pnpm version to use. Examples: ^8, 8.15.9, >=9. To enable it, ensure that the environment variable [VOLTA_FEATURE_PNPM](https://docs.volta.sh/advanced/pnpm) is set to 1

| `false` | `""` | | `package-json-path` |

The path to the package.json to update when using an explicit node-version | yarn-version | npm-version override. By default, we will use package.json in the checkout root.

| `false` | `""` | | `variant` |

Specific variant to install. Example: providing the variant "linux-openssl-rhel", which will target installing the volta-${version}-linux-openssl-rhel.tar.gz tarball

| `false` | `""` | | `registry-url` |

Optional registry to set up for auth. Will set the registry in a project level .npmrc file, and set up auth to read in from env.NODEAUTHTOKEN

| `false` | `""` | diff --git a/action.yml b/action.yml index e366f3f2..54c2cb3d 100644 --- a/action.yml +++ b/action.yml @@ -14,6 +14,9 @@ inputs: yarn-version: description: 'Version Spec of the yarn version to use. Examples: 1.6.x, 10.15.1, >=10.15.0' default: '' + pnpm-version: + description: 'Version Spec of the pnpm version to use. Examples: ^8, 8.15.9, >=9. ensure that the environment variable VOLTA_FEATURE_PNPM is set to 1' + default: '' package-json-path: description: 'The path to the package.json to update when using an explicit `node-version` | `yarn-version` | `npm-version` override. By default, we will use `package.json` in the checkout root.' default: '' diff --git a/src/index.ts b/src/index.ts index 0440a5c2..a5636ab2 100644 --- a/src/index.ts +++ b/src/index.ts @@ -63,6 +63,17 @@ async function run(): Promise { } } + const pnpmVersion = core.getInput('pnpm-version', { required: false }); + if (pnpmVersion !== '') { + core.info(`installing Pnpm ${pnpmVersion.toUpperCase() === 'TRUE' ? '' : pnpmVersion}`); + await installer.installPnpm(pnpmVersion); + + // cannot pin `yarn` when `node` is not pinned as well + if (nodeVersion !== '' && hasPackageJSON) { + await installer.pinPnpm(workingDirectory, pnpmVersion); + } + } + const registryUrl = core.getInput('registry-url', { required: false }); const alwaysAuth = core.getInput('always-auth', { required: false }); if (registryUrl !== '') { diff --git a/src/installer.test.ts b/src/installer.test.ts index 1e0bef6e..92b700fe 100644 --- a/src/installer.test.ts +++ b/src/installer.test.ts @@ -186,6 +186,7 @@ describe('buildLayout', () => { "node": "shim-file-here", "npm": "shim-file-here", "npx": "shim-file-here", + "pnpm": "shim-file-here", "shim": "shim-file-here", "yarn": "shim-file-here", }, @@ -198,11 +199,13 @@ describe('buildLayout', () => { "image": { "node": {}, "packages": {}, + "pnpm": {}, "yarn": {}, }, "inventory": { "node": {}, "packages": {}, + "pnpm": {}, "yarn": {}, }, "user": {}, diff --git a/src/installer.ts b/src/installer.ts index 5b9122fa..a7990d1c 100644 --- a/src/installer.ts +++ b/src/installer.ts @@ -236,6 +236,7 @@ async function setupShims(voltaHome: string): Promise { setupShim(voltaHome, 'yarn'); setupShim(voltaHome, 'npm'); setupShim(voltaHome, 'npx'); + setupShim(voltaHome, 'pnpm'); } /* @@ -253,9 +254,11 @@ export async function buildLayout(voltaHome: string): Promise { await io.mkdirP(path.join(voltaHome, 'tools/image/node')); await io.mkdirP(path.join(voltaHome, 'tools/image/packages')); await io.mkdirP(path.join(voltaHome, 'tools/image/yarn')); + await io.mkdirP(path.join(voltaHome, 'tools/image/pnpm')); await io.mkdirP(path.join(voltaHome, 'tools/inventory/node')); await io.mkdirP(path.join(voltaHome, 'tools/inventory/packages')); await io.mkdirP(path.join(voltaHome, 'tools/inventory/yarn')); + await io.mkdirP(path.join(voltaHome, 'tools/inventory/pnpm')); await io.mkdirP(path.join(voltaHome, 'tools/user')); await setupShims(voltaHome); } @@ -364,6 +367,11 @@ export async function installYarn(version: string): Promise { await execVolta('.', ['install', `yarn${version === 'true' ? '' : `@${version}`}`]); } +export async function installPnpm(version: string): Promise { + // using `.` here because `volta install` doesn't care about the working directory at all + await execVolta('.', ['install', `pnpm${version === 'true' ? '' : `@${version}`}`]); +} + export async function pinNode(workingDirectory: string, version: string): Promise { await execVolta(workingDirectory, ['pin', `node${version === 'true' ? '' : `@${version}`}`]); } @@ -376,6 +384,10 @@ export async function pinYarn(workingDirectory: string, version: string): Promis await execVolta(workingDirectory, ['pin', `yarn${version === 'true' ? '' : `@${version}`}`]); } +export async function pinPnpm(workingDirectory: string, version: string): Promise { + await execVolta(workingDirectory, ['pin', `pnpm${version === 'true' ? '' : `@${version}`}`]); +} + export async function getVoltaVersion(versionSpec: string, authToken: string): Promise { let version = semver.clean(versionSpec) || ''; const validVersionProvided = semver.valid(version) !== null; diff --git a/tests/log-info.sh b/tests/log-info.sh index 39a4fd0c..a5b01753 100755 --- a/tests/log-info.sh +++ b/tests/log-info.sh @@ -11,3 +11,4 @@ echo "Current contents of $VOLTA_HOME\n$voltaBinContents" echo "Path to volta: $(which volta)" echo "Path to node: $(which node)" echo "Path to yarn: $(which yarn)" +echo "Path to pnpm: $(which pnpm)"