From 162ddf7c40a5ef49459ceb64575b09d8f89e2b34 Mon Sep 17 00:00:00 2001
From: Jacob Gillespie <jacobwgillespie@gmail.com>
Date: Wed, 30 Jun 2021 16:44:51 +0100
Subject: [PATCH 01/12] Add pnpm caching support

---
 .github/workflows/e2e-cache.yml |  33 +++
 README.md                       |  19 +-
 __tests__/cache-restore.test.ts |  16 +-
 __tests__/cache-save.test.ts    |  46 ++++
 __tests__/cache-utils.test.ts   |   5 +
 __tests__/data/pnpm-lock.yaml   | 360 ++++++++++++++++++++++++++++++++
 action.yml                      |   2 +-
 dist/cache-save/index.js        |  20 +-
 dist/setup/index.js             |  20 +-
 src/cache-utils.ts              |  23 +-
 src/constants.ts                |   1 +
 11 files changed, 531 insertions(+), 14 deletions(-)
 create mode 100644 __tests__/data/pnpm-lock.yaml

diff --git a/.github/workflows/e2e-cache.yml b/.github/workflows/e2e-cache.yml
index fd0d4046..7e0fd247 100644
--- a/.github/workflows/e2e-cache.yml
+++ b/.github/workflows/e2e-cache.yml
@@ -35,6 +35,39 @@ jobs:
         run: __tests__/verify-node.sh "${{ matrix.node-version }}"
         shell: bash
 
+  node-pnpm-depencies-caching:
+    name: Test pnpm (Node ${{ matrix.node-version}}, ${{ matrix.os }})
+    runs-on: ${{ matrix.os }}
+    strategy:
+      fail-fast: false
+      matrix:
+        os: [ubuntu-latest, windows-latest, macos-latest]
+        node-version: [12, 14, 16]
+    steps:
+      - uses: actions/checkout@v2
+      - name: Install pnpm
+        uses: pnpm/action-setup@v2
+        with:
+          version: 6.9.0
+      - name: Generate pnpm file
+        run: pnpm install
+      - name: Remove dependencies
+        shell: pwsh
+        run: Remove-Item node_modules -Force -Recurse
+      - name: Clean global cache
+        run: rm -rf ~/.pnpm-store
+        shell: bash
+      - name: Setup Node
+        uses: ./
+        with:
+          node-version: ${{ matrix.node-version }}
+          cache: 'pnpm'
+      - name: Install dependencies
+        run: pnpm install
+      - name: Verify node and pnpm
+        run: __tests__/verify-node.sh "${{ matrix.node-version }}"
+        shell: bash
+
   node-yarn1-depencies-caching:
     name: Test yarn 1 (Node ${{ matrix.node-version}}, ${{ matrix.os }})
     runs-on: ${{ matrix.os }}
diff --git a/README.md b/README.md
index aa243c2e..d813bb8c 100644
--- a/README.md
+++ b/README.md
@@ -7,7 +7,7 @@
 This action provides the following functionality for GitHub Actions users:
 
 - Optionally downloading and caching distribution of the requested Node.js version, and adding it to the PATH
-- Optionally caching npm/yarn dependencies
+- Optionally caching npm/pnpm/yarn dependencies
 - Registering problem matchers for error output
 - Configuring authentication for GPR or npm
 
@@ -41,7 +41,7 @@ nvm lts syntax: `lts/erbium`, `lts/fermium`, `lts/*`
 
 ### Caching packages dependencies
 
-The action has a built-in functionality for caching and restoring npm/yarn dependencies. Supported package managers are `npm`, `yarn`. The `cache` input is optional, and caching is turned off by default.
+The action has a built-in functionality for caching and restoring npm/yarn dependencies. Supported package managers are `npm`, `pnpm`, `yarn`. The `cache` input is optional, and caching is turned off by default.
 
 **Caching npm dependencies:**
 ```yaml
@@ -55,6 +55,21 @@ steps:
 - run: npm test
 ```
 
+**Caching pnpm dependencies:**
+```yaml
+steps:
+- uses: actions/checkout@v2
+- uses: pnpm/action-setup@v2
+  with:
+    version: 6.9.0
+- uses: actions/setup-node@v2
+  with:
+    node-version: '14'
+    cache: 'pnpm'
+- run: pnpm install
+- run: pnpm test
+```
+
 **Caching yarn dependencies:**
 ```yaml
 steps:
diff --git a/__tests__/cache-restore.test.ts b/__tests__/cache-restore.test.ts
index 18962e57..483f8eb6 100644
--- a/__tests__/cache-restore.test.ts
+++ b/__tests__/cache-restore.test.ts
@@ -14,14 +14,18 @@ describe('cache-restore', () => {
   const platform = process.env.RUNNER_OS;
   const commonPath = '/some/random/path';
   const npmCachePath = `${commonPath}/npm`;
+  const pnpmCachePath = `${commonPath}/pnpm`;
   const yarn1CachePath = `${commonPath}/yarn1`;
   const yarn2CachePath = `${commonPath}/yarn2`;
   const yarnFileHash =
     'b8a0bae5243251f7c07dd52d1f78ff78281dfefaded700a176261b6b54fa245b';
   const npmFileHash =
     'abf7c9b306a3149dcfba4673e2362755503bcceaab46f0e4e6fee0ade493e20c';
+  const pnpmFileHash =
+    '26309058093e84713f38869c50cf1cee9b08155ede874ec1b44ce3fca8c68c70';
   const cachesObject = {
     [npmCachePath]: npmFileHash,
+    [pnpmCachePath]: pnpmFileHash,
     [yarn1CachePath]: yarnFileHash,
     [yarn2CachePath]: yarnFileHash
   };
@@ -30,6 +34,8 @@ describe('cache-restore', () => {
     switch (command) {
       case utils.supportedPackageManagers.npm.getCacheFolderCommand:
         return npmCachePath;
+      case utils.supportedPackageManagers.pnpm.getCacheFolderCommand:
+        return pnpmCachePath;
       case utils.supportedPackageManagers.yarn1.getCacheFolderCommand:
         return yarn1CachePath;
       case utils.supportedPackageManagers.yarn2.getCacheFolderCommand:
@@ -66,6 +72,8 @@ describe('cache-restore', () => {
     hashFilesSpy.mockImplementation((pattern: string) => {
       if (pattern.includes('package-lock.json')) {
         return npmFileHash;
+      } else if (pattern.includes('pnpm-lock.yaml')) {
+        return pnpmFileHash;
       } else if (pattern.includes('yarn.lock')) {
         return yarnFileHash;
       } else {
@@ -97,7 +105,7 @@ describe('cache-restore', () => {
   });
 
   describe('Validate provided package manager', () => {
-    it.each([['npm7'], ['npm6'], ['yarn1'], ['yarn2'], ['random']])(
+    it.each([['npm7'], ['npm6'], ['pnpm6'], ['yarn1'], ['yarn2'], ['random']])(
       'Throw an error because %s is not supported',
       async packageManager => {
         await expect(restoreCache(packageManager)).rejects.toThrowError(
@@ -111,7 +119,8 @@ describe('cache-restore', () => {
     it.each([
       ['yarn', '2.1.2', yarnFileHash],
       ['yarn', '1.2.3', yarnFileHash],
-      ['npm', '', npmFileHash]
+      ['npm', '', npmFileHash],
+      ['pnpm', '', pnpmFileHash]
     ])(
       'restored dependencies for %s',
       async (packageManager, toolVersion, fileHash) => {
@@ -139,7 +148,8 @@ describe('cache-restore', () => {
     it.each([
       ['yarn', '2.1.2', yarnFileHash],
       ['yarn', '1.2.3', yarnFileHash],
-      ['npm', '', npmFileHash]
+      ['npm', '', npmFileHash],
+      ['pnpm', '', pnpmFileHash]
     ])(
       'dependencies are changed %s',
       async (packageManager, toolVersion, fileHash) => {
diff --git a/__tests__/cache-save.test.ts b/__tests__/cache-save.test.ts
index 099a6119..64ef942c 100644
--- a/__tests__/cache-save.test.ts
+++ b/__tests__/cache-save.test.ts
@@ -12,6 +12,8 @@ describe('run', () => {
     'b8a0bae5243251f7c07dd52d1f78ff78281dfefaded700a176261b6b54fa245b';
   const npmFileHash =
     'abf7c9b306a3149dcfba4673e2362755503bcceaab46f0e4e6fee0ade493e20c';
+  const pnpmFileHash =
+    '26309058093e84713f38869c50cf1cee9b08155ede874ec1b44ce3fca8c68c70';
   const commonPath = '/some/random/path';
   process.env['GITHUB_WORKSPACE'] = path.join(__dirname, 'data');
 
@@ -150,6 +152,23 @@ describe('run', () => {
       );
       expect(setFailedSpy).not.toHaveBeenCalled();
     });
+
+    it('should not save cache for npm', async () => {
+      inputs['cache'] = 'pnpm';
+      getStateSpy.mockImplementation(() => pnpmFileHash);
+      getCommandOutputSpy.mockImplementationOnce(() => `${commonPath}/pnpm`);
+
+      await run();
+
+      expect(getInputSpy).toHaveBeenCalled();
+      expect(getStateSpy).toHaveBeenCalledTimes(2);
+      expect(getCommandOutputSpy).toHaveBeenCalledTimes(1);
+      expect(debugSpy).toHaveBeenCalledWith(`pnpm path is ${commonPath}/pnpm`);
+      expect(infoSpy).toHaveBeenCalledWith(
+        `Cache hit occurred on the primary key ${pnpmFileHash}, not saving cache.`
+      );
+      expect(setFailedSpy).not.toHaveBeenCalled();
+    });
   });
 
   describe('action saves the cache', () => {
@@ -239,6 +258,33 @@ describe('run', () => {
       );
       expect(setFailedSpy).not.toHaveBeenCalled();
     });
+
+    it('saves cache from pnpm', async () => {
+      inputs['cache'] = 'pnpm';
+      getStateSpy.mockImplementation((name: string) => {
+        if (name === State.CacheMatchedKey) {
+          return pnpmFileHash;
+        } else {
+          return npmFileHash;
+        }
+      });
+      getCommandOutputSpy.mockImplementationOnce(() => `${commonPath}/pnpm`);
+
+      await run();
+
+      expect(getInputSpy).toHaveBeenCalled();
+      expect(getStateSpy).toHaveBeenCalledTimes(2);
+      expect(getCommandOutputSpy).toHaveBeenCalledTimes(1);
+      expect(debugSpy).toHaveBeenCalledWith(`pnpm path is ${commonPath}/pnpm`);
+      expect(infoSpy).not.toHaveBeenCalledWith(
+        `Cache hit occurred on the primary key ${pnpmFileHash}, not saving cache.`
+      );
+      expect(saveCacheSpy).toHaveBeenCalled();
+      expect(infoSpy).toHaveBeenLastCalledWith(
+        `Cache saved with the key: ${npmFileHash}`
+      );
+      expect(setFailedSpy).not.toHaveBeenCalled();
+    });
   });
 
   afterEach(() => {
diff --git a/__tests__/cache-utils.test.ts b/__tests__/cache-utils.test.ts
index 0be153ba..0ceabeb0 100644
--- a/__tests__/cache-utils.test.ts
+++ b/__tests__/cache-utils.test.ts
@@ -14,6 +14,10 @@ describe('cache-utils', () => {
   function getPackagePath(name: string) {
     if (name === utils.supportedPackageManagers.npm.getCacheFolderCommand) {
       return `${commonPath}/npm`;
+    } else if (
+      name === utils.supportedPackageManagers.pnpm.getCacheFolderCommand
+    ) {
+      return `${commonPath}/pnpm`;
     } else {
       if (name === utils.supportedPackageManagers.yarn1.getCacheFolderCommand) {
         return `${commonPath}/yarn1`;
@@ -34,6 +38,7 @@ describe('cache-utils', () => {
   describe('getPackageManagerInfo', () => {
     it.each<[string, PackageManagerInfo | null]>([
       ['npm', utils.supportedPackageManagers.npm],
+      ['pnpm', utils.supportedPackageManagers.pnpm],
       ['yarn', utils.supportedPackageManagers.yarn1],
       ['yarn1', null],
       ['yarn2', null],
diff --git a/__tests__/data/pnpm-lock.yaml b/__tests__/data/pnpm-lock.yaml
new file mode 100644
index 00000000..f4c3963e
--- /dev/null
+++ b/__tests__/data/pnpm-lock.yaml
@@ -0,0 +1,360 @@
+lockfileVersion: 5.3
+
+specifiers:
+  express: ^4.17.1
+
+dependencies:
+  express: 4.17.1
+
+packages:
+
+  /accepts/1.3.7:
+    resolution: {integrity: sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==}
+    engines: {node: '>= 0.6'}
+    dependencies:
+      mime-types: 2.1.31
+      negotiator: 0.6.2
+    dev: false
+
+  /array-flatten/1.1.1:
+    resolution: {integrity: sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=}
+    dev: false
+
+  /body-parser/1.19.0:
+    resolution: {integrity: sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw==}
+    engines: {node: '>= 0.8'}
+    dependencies:
+      bytes: 3.1.0
+      content-type: 1.0.4
+      debug: 2.6.9
+      depd: 1.1.2
+      http-errors: 1.7.2
+      iconv-lite: 0.4.24
+      on-finished: 2.3.0
+      qs: 6.7.0
+      raw-body: 2.4.0
+      type-is: 1.6.18
+    dev: false
+
+  /bytes/3.1.0:
+    resolution: {integrity: sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==}
+    engines: {node: '>= 0.8'}
+    dev: false
+
+  /content-disposition/0.5.3:
+    resolution: {integrity: sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g==}
+    engines: {node: '>= 0.6'}
+    dependencies:
+      safe-buffer: 5.1.2
+    dev: false
+
+  /content-type/1.0.4:
+    resolution: {integrity: sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==}
+    engines: {node: '>= 0.6'}
+    dev: false
+
+  /cookie-signature/1.0.6:
+    resolution: {integrity: sha1-4wOogrNCzD7oylE6eZmXNNqzriw=}
+    dev: false
+
+  /cookie/0.4.0:
+    resolution: {integrity: sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg==}
+    engines: {node: '>= 0.6'}
+    dev: false
+
+  /debug/2.6.9:
+    resolution: {integrity: sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==}
+    dependencies:
+      ms: 2.0.0
+    dev: false
+
+  /depd/1.1.2:
+    resolution: {integrity: sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=}
+    engines: {node: '>= 0.6'}
+    dev: false
+
+  /destroy/1.0.4:
+    resolution: {integrity: sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=}
+    dev: false
+
+  /ee-first/1.1.1:
+    resolution: {integrity: sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=}
+    dev: false
+
+  /encodeurl/1.0.2:
+    resolution: {integrity: sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=}
+    engines: {node: '>= 0.8'}
+    dev: false
+
+  /escape-html/1.0.3:
+    resolution: {integrity: sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=}
+    dev: false
+
+  /etag/1.8.1:
+    resolution: {integrity: sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=}
+    engines: {node: '>= 0.6'}
+    dev: false
+
+  /express/4.17.1:
+    resolution: {integrity: sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g==}
+    engines: {node: '>= 0.10.0'}
+    dependencies:
+      accepts: 1.3.7
+      array-flatten: 1.1.1
+      body-parser: 1.19.0
+      content-disposition: 0.5.3
+      content-type: 1.0.4
+      cookie: 0.4.0
+      cookie-signature: 1.0.6
+      debug: 2.6.9
+      depd: 1.1.2
+      encodeurl: 1.0.2
+      escape-html: 1.0.3
+      etag: 1.8.1
+      finalhandler: 1.1.2
+      fresh: 0.5.2
+      merge-descriptors: 1.0.1
+      methods: 1.1.2
+      on-finished: 2.3.0
+      parseurl: 1.3.3
+      path-to-regexp: 0.1.7
+      proxy-addr: 2.0.7
+      qs: 6.7.0
+      range-parser: 1.2.1
+      safe-buffer: 5.1.2
+      send: 0.17.1
+      serve-static: 1.14.1
+      setprototypeof: 1.1.1
+      statuses: 1.5.0
+      type-is: 1.6.18
+      utils-merge: 1.0.1
+      vary: 1.1.2
+    dev: false
+
+  /finalhandler/1.1.2:
+    resolution: {integrity: sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==}
+    engines: {node: '>= 0.8'}
+    dependencies:
+      debug: 2.6.9
+      encodeurl: 1.0.2
+      escape-html: 1.0.3
+      on-finished: 2.3.0
+      parseurl: 1.3.3
+      statuses: 1.5.0
+      unpipe: 1.0.0
+    dev: false
+
+  /forwarded/0.2.0:
+    resolution: {integrity: sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==}
+    engines: {node: '>= 0.6'}
+    dev: false
+
+  /fresh/0.5.2:
+    resolution: {integrity: sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=}
+    engines: {node: '>= 0.6'}
+    dev: false
+
+  /http-errors/1.7.2:
+    resolution: {integrity: sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg==}
+    engines: {node: '>= 0.6'}
+    dependencies:
+      depd: 1.1.2
+      inherits: 2.0.3
+      setprototypeof: 1.1.1
+      statuses: 1.5.0
+      toidentifier: 1.0.0
+    dev: false
+
+  /http-errors/1.7.3:
+    resolution: {integrity: sha512-ZTTX0MWrsQ2ZAhA1cejAwDLycFsd7I7nVtnkT3Ol0aqodaKW+0CTZDQ1uBv5whptCnc8e8HeRRJxRs0kmm/Qfw==}
+    engines: {node: '>= 0.6'}
+    dependencies:
+      depd: 1.1.2
+      inherits: 2.0.4
+      setprototypeof: 1.1.1
+      statuses: 1.5.0
+      toidentifier: 1.0.0
+    dev: false
+
+  /iconv-lite/0.4.24:
+    resolution: {integrity: sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==}
+    engines: {node: '>=0.10.0'}
+    dependencies:
+      safer-buffer: 2.1.2
+    dev: false
+
+  /inherits/2.0.3:
+    resolution: {integrity: sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=}
+    dev: false
+
+  /inherits/2.0.4:
+    resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==}
+    dev: false
+
+  /ipaddr.js/1.9.1:
+    resolution: {integrity: sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==}
+    engines: {node: '>= 0.10'}
+    dev: false
+
+  /media-typer/0.3.0:
+    resolution: {integrity: sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=}
+    engines: {node: '>= 0.6'}
+    dev: false
+
+  /merge-descriptors/1.0.1:
+    resolution: {integrity: sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=}
+    dev: false
+
+  /methods/1.1.2:
+    resolution: {integrity: sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=}
+    engines: {node: '>= 0.6'}
+    dev: false
+
+  /mime-db/1.48.0:
+    resolution: {integrity: sha512-FM3QwxV+TnZYQ2aRqhlKBMHxk10lTbMt3bBkMAp54ddrNeVSfcQYOOKuGuy3Ddrm38I04If834fOUSq1yzslJQ==}
+    engines: {node: '>= 0.6'}
+    dev: false
+
+  /mime-types/2.1.31:
+    resolution: {integrity: sha512-XGZnNzm3QvgKxa8dpzyhFTHmpP3l5YNusmne07VUOXxou9CqUqYa/HBy124RqtVh/O2pECas/MOcsDgpilPOPg==}
+    engines: {node: '>= 0.6'}
+    dependencies:
+      mime-db: 1.48.0
+    dev: false
+
+  /mime/1.6.0:
+    resolution: {integrity: sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==}
+    engines: {node: '>=4'}
+    hasBin: true
+    dev: false
+
+  /ms/2.0.0:
+    resolution: {integrity: sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=}
+    dev: false
+
+  /ms/2.1.1:
+    resolution: {integrity: sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==}
+    dev: false
+
+  /negotiator/0.6.2:
+    resolution: {integrity: sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==}
+    engines: {node: '>= 0.6'}
+    dev: false
+
+  /on-finished/2.3.0:
+    resolution: {integrity: sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=}
+    engines: {node: '>= 0.8'}
+    dependencies:
+      ee-first: 1.1.1
+    dev: false
+
+  /parseurl/1.3.3:
+    resolution: {integrity: sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==}
+    engines: {node: '>= 0.8'}
+    dev: false
+
+  /path-to-regexp/0.1.7:
+    resolution: {integrity: sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=}
+    dev: false
+
+  /proxy-addr/2.0.7:
+    resolution: {integrity: sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==}
+    engines: {node: '>= 0.10'}
+    dependencies:
+      forwarded: 0.2.0
+      ipaddr.js: 1.9.1
+    dev: false
+
+  /qs/6.7.0:
+    resolution: {integrity: sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==}
+    engines: {node: '>=0.6'}
+    dev: false
+
+  /range-parser/1.2.1:
+    resolution: {integrity: sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==}
+    engines: {node: '>= 0.6'}
+    dev: false
+
+  /raw-body/2.4.0:
+    resolution: {integrity: sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q==}
+    engines: {node: '>= 0.8'}
+    dependencies:
+      bytes: 3.1.0
+      http-errors: 1.7.2
+      iconv-lite: 0.4.24
+      unpipe: 1.0.0
+    dev: false
+
+  /safe-buffer/5.1.2:
+    resolution: {integrity: sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==}
+    dev: false
+
+  /safer-buffer/2.1.2:
+    resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==}
+    dev: false
+
+  /send/0.17.1:
+    resolution: {integrity: sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg==}
+    engines: {node: '>= 0.8.0'}
+    dependencies:
+      debug: 2.6.9
+      depd: 1.1.2
+      destroy: 1.0.4
+      encodeurl: 1.0.2
+      escape-html: 1.0.3
+      etag: 1.8.1
+      fresh: 0.5.2
+      http-errors: 1.7.3
+      mime: 1.6.0
+      ms: 2.1.1
+      on-finished: 2.3.0
+      range-parser: 1.2.1
+      statuses: 1.5.0
+    dev: false
+
+  /serve-static/1.14.1:
+    resolution: {integrity: sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg==}
+    engines: {node: '>= 0.8.0'}
+    dependencies:
+      encodeurl: 1.0.2
+      escape-html: 1.0.3
+      parseurl: 1.3.3
+      send: 0.17.1
+    dev: false
+
+  /setprototypeof/1.1.1:
+    resolution: {integrity: sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==}
+    dev: false
+
+  /statuses/1.5.0:
+    resolution: {integrity: sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=}
+    engines: {node: '>= 0.6'}
+    dev: false
+
+  /toidentifier/1.0.0:
+    resolution: {integrity: sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==}
+    engines: {node: '>=0.6'}
+    dev: false
+
+  /type-is/1.6.18:
+    resolution: {integrity: sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==}
+    engines: {node: '>= 0.6'}
+    dependencies:
+      media-typer: 0.3.0
+      mime-types: 2.1.31
+    dev: false
+
+  /unpipe/1.0.0:
+    resolution: {integrity: sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=}
+    engines: {node: '>= 0.8'}
+    dev: false
+
+  /utils-merge/1.0.1:
+    resolution: {integrity: sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=}
+    engines: {node: '>= 0.4.0'}
+    dev: false
+
+  /vary/1.1.2:
+    resolution: {integrity: sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=}
+    engines: {node: '>= 0.8'}
+    dev: false
diff --git a/action.yml b/action.yml
index 213dc9d2..2552b8d5 100644
--- a/action.yml
+++ b/action.yml
@@ -20,7 +20,7 @@ inputs:
     description: Used to pull node distributions from node-versions.  Since there's a default, this is typically not supplied by the user.
     default: ${{ github.token }}
   cache:
-    description: 'Used to specify a package manager for caching in the default directory. Supported values: npm, yarn'
+    description: 'Used to specify a package manager for caching in the default directory. Supported values: npm, pnpm, yarn'
 # TODO: add input to control forcing to pull from cloud or dist. 
 #       escape valve for someone having issues or needing the absolute latest which isn't cached yet
 # Deprecated option, do not use. Will not be supported after October 1, 2019
diff --git a/dist/cache-save/index.js b/dist/cache-save/index.js
index f470ef5b..fdc89282 100644
--- a/dist/cache-save/index.js
+++ b/dist/cache-save/index.js
@@ -4290,6 +4290,11 @@ exports.supportedPackageManagers = {
         lockFilePatterns: ['package-lock.json', 'yarn.lock'],
         getCacheFolderCommand: 'npm config get cache'
     },
+    pnpm: {
+        lockFilePatterns: ['pnpm-lock.yaml'],
+        getCacheFolderCommand: 'pnpm get store',
+        defaultCacheFolder: '~/.pnpm-store'
+    },
     yarn1: {
         lockFilePatterns: ['yarn.lock'],
         getCacheFolderCommand: 'yarn cache dir'
@@ -4304,7 +4309,7 @@ exports.getCommandOutput = (toolCommand) => __awaiter(void 0, void 0, void 0, fu
     if (stderr) {
         throw new Error(stderr);
     }
-    return stdout;
+    return stdout.trim();
 });
 const getPackageManagerVersion = (packageManager, command) => __awaiter(void 0, void 0, void 0, function* () {
     const stdOut = yield exports.getCommandOutput(`${packageManager} ${command}`);
@@ -4317,6 +4322,9 @@ exports.getPackageManagerInfo = (packageManager) => __awaiter(void 0, void 0, vo
     if (packageManager === 'npm') {
         return exports.supportedPackageManagers.npm;
     }
+    else if (packageManager === 'pnpm') {
+        return exports.supportedPackageManagers.pnpm;
+    }
     else if (packageManager === 'yarn') {
         const yarnVersion = yield getPackageManagerVersion('yarn', '--version');
         core.debug(`Consumed yarn version is ${yarnVersion}`);
@@ -4332,7 +4340,14 @@ exports.getPackageManagerInfo = (packageManager) => __awaiter(void 0, void 0, vo
     }
 });
 exports.getCacheDirectoryPath = (packageManagerInfo, packageManager) => __awaiter(void 0, void 0, void 0, function* () {
-    const stdOut = yield exports.getCommandOutput(packageManagerInfo.getCacheFolderCommand);
+    let stdOut = yield exports.getCommandOutput(packageManagerInfo.getCacheFolderCommand);
+    // pnpm returns 'undefined' if no custom store path is set
+    if (stdOut === 'undefined') {
+        stdOut = '';
+    }
+    if (!stdOut && packageManagerInfo.defaultCacheFolder) {
+        stdOut = packageManagerInfo.defaultCacheFolder;
+    }
     if (!stdOut) {
         throw new Error(`Could not get cache folder path for ${packageManager}`);
     }
@@ -5270,6 +5285,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
 var LockType;
 (function (LockType) {
     LockType["Npm"] = "npm";
+    LockType["Pnpm"] = "pnpm";
     LockType["Yarn"] = "yarn";
 })(LockType = exports.LockType || (exports.LockType = {}));
 var State;
diff --git a/dist/setup/index.js b/dist/setup/index.js
index ab46cecf..69ec4c9c 100644
--- a/dist/setup/index.js
+++ b/dist/setup/index.js
@@ -8652,6 +8652,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
 var LockType;
 (function (LockType) {
     LockType["Npm"] = "npm";
+    LockType["Pnpm"] = "pnpm";
     LockType["Yarn"] = "yarn";
 })(LockType = exports.LockType || (exports.LockType = {}));
 var State;
@@ -51587,6 +51588,11 @@ exports.supportedPackageManagers = {
         lockFilePatterns: ['package-lock.json', 'yarn.lock'],
         getCacheFolderCommand: 'npm config get cache'
     },
+    pnpm: {
+        lockFilePatterns: ['pnpm-lock.yaml'],
+        getCacheFolderCommand: 'pnpm get store',
+        defaultCacheFolder: '~/.pnpm-store'
+    },
     yarn1: {
         lockFilePatterns: ['yarn.lock'],
         getCacheFolderCommand: 'yarn cache dir'
@@ -51601,7 +51607,7 @@ exports.getCommandOutput = (toolCommand) => __awaiter(void 0, void 0, void 0, fu
     if (stderr) {
         throw new Error(stderr);
     }
-    return stdout;
+    return stdout.trim();
 });
 const getPackageManagerVersion = (packageManager, command) => __awaiter(void 0, void 0, void 0, function* () {
     const stdOut = yield exports.getCommandOutput(`${packageManager} ${command}`);
@@ -51614,6 +51620,9 @@ exports.getPackageManagerInfo = (packageManager) => __awaiter(void 0, void 0, vo
     if (packageManager === 'npm') {
         return exports.supportedPackageManagers.npm;
     }
+    else if (packageManager === 'pnpm') {
+        return exports.supportedPackageManagers.pnpm;
+    }
     else if (packageManager === 'yarn') {
         const yarnVersion = yield getPackageManagerVersion('yarn', '--version');
         core.debug(`Consumed yarn version is ${yarnVersion}`);
@@ -51629,7 +51638,14 @@ exports.getPackageManagerInfo = (packageManager) => __awaiter(void 0, void 0, vo
     }
 });
 exports.getCacheDirectoryPath = (packageManagerInfo, packageManager) => __awaiter(void 0, void 0, void 0, function* () {
-    const stdOut = yield exports.getCommandOutput(packageManagerInfo.getCacheFolderCommand);
+    let stdOut = yield exports.getCommandOutput(packageManagerInfo.getCacheFolderCommand);
+    // pnpm returns 'undefined' if no custom store path is set
+    if (stdOut === 'undefined') {
+        stdOut = '';
+    }
+    if (!stdOut && packageManagerInfo.defaultCacheFolder) {
+        stdOut = packageManagerInfo.defaultCacheFolder;
+    }
     if (!stdOut) {
         throw new Error(`Could not get cache folder path for ${packageManager}`);
     }
diff --git a/src/cache-utils.ts b/src/cache-utils.ts
index ced58c6c..e8f68951 100644
--- a/src/cache-utils.ts
+++ b/src/cache-utils.ts
@@ -8,6 +8,7 @@ type SupportedPackageManagers = {
 export interface PackageManagerInfo {
   lockFilePatterns: Array<string>;
   getCacheFolderCommand: string;
+  defaultCacheFolder?: string;
 }
 
 export const supportedPackageManagers: SupportedPackageManagers = {
@@ -15,6 +16,11 @@ export const supportedPackageManagers: SupportedPackageManagers = {
     lockFilePatterns: ['package-lock.json', 'yarn.lock'],
     getCacheFolderCommand: 'npm config get cache'
   },
+  pnpm: {
+    lockFilePatterns: ['pnpm-lock.yaml'],
+    getCacheFolderCommand: 'pnpm get store',
+    defaultCacheFolder: '~/.pnpm-store'
+  },
   yarn1: {
     lockFilePatterns: ['yarn.lock'],
     getCacheFolderCommand: 'yarn cache dir'
@@ -32,7 +38,7 @@ export const getCommandOutput = async (toolCommand: string) => {
     throw new Error(stderr);
   }
 
-  return stdout;
+  return stdout.trim();
 };
 
 const getPackageManagerVersion = async (
@@ -51,6 +57,8 @@ const getPackageManagerVersion = async (
 export const getPackageManagerInfo = async (packageManager: string) => {
   if (packageManager === 'npm') {
     return supportedPackageManagers.npm;
+  } else if (packageManager === 'pnpm') {
+    return supportedPackageManagers.pnpm;
   } else if (packageManager === 'yarn') {
     const yarnVersion = await getPackageManagerVersion('yarn', '--version');
 
@@ -70,9 +78,16 @@ export const getCacheDirectoryPath = async (
   packageManagerInfo: PackageManagerInfo,
   packageManager: string
 ) => {
-  const stdOut = await getCommandOutput(
-    packageManagerInfo.getCacheFolderCommand
-  );
+  let stdOut = await getCommandOutput(packageManagerInfo.getCacheFolderCommand);
+
+  // pnpm returns 'undefined' if no custom store path is set
+  if (stdOut === 'undefined') {
+    stdOut = '';
+  }
+
+  if (!stdOut && packageManagerInfo.defaultCacheFolder) {
+    stdOut = packageManagerInfo.defaultCacheFolder;
+  }
 
   if (!stdOut) {
     throw new Error(`Could not get cache folder path for ${packageManager}`);
diff --git a/src/constants.ts b/src/constants.ts
index b7c45de6..021418c2 100644
--- a/src/constants.ts
+++ b/src/constants.ts
@@ -1,5 +1,6 @@
 export enum LockType {
   Npm = 'npm',
+  Pnpm = 'pnpm',
   Yarn = 'yarn'
 }
 

From f24e78e0f6461d5f307b67ef629bcb2d60daf667 Mon Sep 17 00:00:00 2001
From: Jacob Gillespie <jacobwgillespie@gmail.com>
Date: Wed, 14 Jul 2021 13:01:18 +0100
Subject: [PATCH 02/12] Update __tests__/cache-save.test.ts

Co-authored-by: Konrad Pabjan <konradpabjan@github.com>
---
 __tests__/cache-save.test.ts | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/__tests__/cache-save.test.ts b/__tests__/cache-save.test.ts
index 64ef942c..4e678945 100644
--- a/__tests__/cache-save.test.ts
+++ b/__tests__/cache-save.test.ts
@@ -153,7 +153,7 @@ describe('run', () => {
       expect(setFailedSpy).not.toHaveBeenCalled();
     });
 
-    it('should not save cache for npm', async () => {
+    it('should not save cache for pnpm', async () => {
       inputs['cache'] = 'pnpm';
       getStateSpy.mockImplementation(() => pnpmFileHash);
       getCommandOutputSpy.mockImplementationOnce(() => `${commonPath}/pnpm`);

From fdbc93ea6e81822965c11808ddbb4a7d6d7dd1cd Mon Sep 17 00:00:00 2001
From: Jacob Gillespie <jacobwgillespie@gmail.com>
Date: Wed, 14 Jul 2021 13:03:28 +0100
Subject: [PATCH 03/12] Add disclaimer to pnpm action example, pin action

---
 README.md | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/README.md b/README.md
index d813bb8c..847fff84 100644
--- a/README.md
+++ b/README.md
@@ -57,9 +57,14 @@ steps:
 
 **Caching pnpm dependencies:**
 ```yaml
+# This workflow uses actions that are not certified by GitHub.
+# They are provided by a third-party and are governed by
+# separate terms of service, privacy policy, and support
+# documentation.
+
 steps:
 - uses: actions/checkout@v2
-- uses: pnpm/action-setup@v2
+- uses: pnpm/action-setup@646cdf48217256a3d0b80361c5a50727664284f2
   with:
     version: 6.9.0
 - uses: actions/setup-node@v2

From d278e78bddf957771f319214444100b4032fb7aa Mon Sep 17 00:00:00 2001
From: Jacob Gillespie <jacobwgillespie@gmail.com>
Date: Wed, 14 Jul 2021 13:06:33 +0100
Subject: [PATCH 04/12] Add logic to check that cache folder exists

---
 src/cache-utils.ts | 11 ++++++++++-
 1 file changed, 10 insertions(+), 1 deletion(-)

diff --git a/src/cache-utils.ts b/src/cache-utils.ts
index e8f68951..cfe8c5b0 100644
--- a/src/cache-utils.ts
+++ b/src/cache-utils.ts
@@ -1,5 +1,8 @@
 import * as core from '@actions/core';
 import * as exec from '@actions/exec';
+import fs from 'fs';
+import os from 'os';
+import path from 'path';
 
 type SupportedPackageManagers = {
   [prop: string]: PackageManagerInfo;
@@ -19,7 +22,7 @@ export const supportedPackageManagers: SupportedPackageManagers = {
   pnpm: {
     lockFilePatterns: ['pnpm-lock.yaml'],
     getCacheFolderCommand: 'pnpm get store',
-    defaultCacheFolder: '~/.pnpm-store'
+    defaultCacheFolder: path.join(os.homedir(), '.pnpm-store')
   },
   yarn1: {
     lockFilePatterns: ['yarn.lock'],
@@ -95,5 +98,11 @@ export const getCacheDirectoryPath = async (
 
   core.debug(`${packageManager} path is ${stdOut}`);
 
+  if (!fs.existsSync(stdOut)) {
+    throw new Error(
+      `Cache folder path is retrieved for ${packageManager} but doesn't exist on disk: ${stdOut}`
+    );
+  }
+
   return stdOut;
 };

From 399982b36805ac9d772a419dc9f95fb5a8eb5c55 Mon Sep 17 00:00:00 2001
From: Jacob Gillespie <jacobwgillespie@gmail.com>
Date: Wed, 14 Jul 2021 15:25:45 +0100
Subject: [PATCH 05/12] Move existence check to cache-save

---
 src/cache-save.ts  | 8 ++++++++
 src/cache-utils.ts | 7 -------
 2 files changed, 8 insertions(+), 7 deletions(-)

diff --git a/src/cache-save.ts b/src/cache-save.ts
index 11f830b8..9fb0b29d 100644
--- a/src/cache-save.ts
+++ b/src/cache-save.ts
@@ -1,5 +1,6 @@
 import * as core from '@actions/core';
 import * as cache from '@actions/cache';
+import fs from 'fs';
 import {State} from './constants';
 import {getCacheDirectoryPath, getPackageManagerInfo} from './cache-utils';
 
@@ -26,6 +27,13 @@ const cachePackages = async (packageManager: string) => {
     packageManagerInfo,
     packageManager
   );
+
+  if (!fs.existsSync(cachePath)) {
+    throw new Error(
+      `Cache folder path is retrieved for ${packageManager} but doesn't exist on disk: ${cachePath}`
+    );
+  }
+
   if (primaryKey === state) {
     core.info(
       `Cache hit occurred on the primary key ${primaryKey}, not saving cache.`
diff --git a/src/cache-utils.ts b/src/cache-utils.ts
index cfe8c5b0..f39fe8a2 100644
--- a/src/cache-utils.ts
+++ b/src/cache-utils.ts
@@ -1,6 +1,5 @@
 import * as core from '@actions/core';
 import * as exec from '@actions/exec';
-import fs from 'fs';
 import os from 'os';
 import path from 'path';
 
@@ -98,11 +97,5 @@ export const getCacheDirectoryPath = async (
 
   core.debug(`${packageManager} path is ${stdOut}`);
 
-  if (!fs.existsSync(stdOut)) {
-    throw new Error(
-      `Cache folder path is retrieved for ${packageManager} but doesn't exist on disk: ${stdOut}`
-    );
-  }
-
   return stdOut;
 };

From 0453e516eb2a16fb262fa8f9db51405c7089b869 Mon Sep 17 00:00:00 2001
From: Jacob Gillespie <jacobwgillespie@gmail.com>
Date: Wed, 14 Jul 2021 15:25:55 +0100
Subject: [PATCH 06/12] Regenerate compiled files

---
 dist/cache-save/index.js | 14 +++++++++++++-
 dist/setup/index.js      |  7 ++++++-
 2 files changed, 19 insertions(+), 2 deletions(-)

diff --git a/dist/cache-save/index.js b/dist/cache-save/index.js
index fdc89282..02e4fefb 100644
--- a/dist/cache-save/index.js
+++ b/dist/cache-save/index.js
@@ -4282,9 +4282,14 @@ var __importStar = (this && this.__importStar) || function (mod) {
     result["default"] = mod;
     return result;
 };
+var __importDefault = (this && this.__importDefault) || function (mod) {
+    return (mod && mod.__esModule) ? mod : { "default": mod };
+};
 Object.defineProperty(exports, "__esModule", { value: true });
 const core = __importStar(__webpack_require__(470));
 const exec = __importStar(__webpack_require__(986));
+const os_1 = __importDefault(__webpack_require__(87));
+const path_1 = __importDefault(__webpack_require__(622));
 exports.supportedPackageManagers = {
     npm: {
         lockFilePatterns: ['package-lock.json', 'yarn.lock'],
@@ -4293,7 +4298,7 @@ exports.supportedPackageManagers = {
     pnpm: {
         lockFilePatterns: ['pnpm-lock.yaml'],
         getCacheFolderCommand: 'pnpm get store',
-        defaultCacheFolder: '~/.pnpm-store'
+        defaultCacheFolder: path_1.default.join(os_1.default.homedir(), '.pnpm-store')
     },
     yarn1: {
         lockFilePatterns: ['yarn.lock'],
@@ -50613,9 +50618,13 @@ var __importStar = (this && this.__importStar) || function (mod) {
     result["default"] = mod;
     return result;
 };
+var __importDefault = (this && this.__importDefault) || function (mod) {
+    return (mod && mod.__esModule) ? mod : { "default": mod };
+};
 Object.defineProperty(exports, "__esModule", { value: true });
 const core = __importStar(__webpack_require__(470));
 const cache = __importStar(__webpack_require__(692));
+const fs_1 = __importDefault(__webpack_require__(747));
 const constants_1 = __webpack_require__(196);
 const cache_utils_1 = __webpack_require__(143);
 function run() {
@@ -50639,6 +50648,9 @@ const cachePackages = (packageManager) => __awaiter(void 0, void 0, void 0, func
         return;
     }
     const cachePath = yield cache_utils_1.getCacheDirectoryPath(packageManagerInfo, packageManager);
+    if (!fs_1.default.existsSync(cachePath)) {
+        throw new Error(`Cache folder path is retrieved for ${packageManager} but doesn't exist on disk: ${cachePath}`);
+    }
     if (primaryKey === state) {
         core.info(`Cache hit occurred on the primary key ${primaryKey}, not saving cache.`);
         return;
diff --git a/dist/setup/index.js b/dist/setup/index.js
index 69ec4c9c..07e6781f 100644
--- a/dist/setup/index.js
+++ b/dist/setup/index.js
@@ -51580,9 +51580,14 @@ var __importStar = (this && this.__importStar) || function (mod) {
     result["default"] = mod;
     return result;
 };
+var __importDefault = (this && this.__importDefault) || function (mod) {
+    return (mod && mod.__esModule) ? mod : { "default": mod };
+};
 Object.defineProperty(exports, "__esModule", { value: true });
 const core = __importStar(__webpack_require__(470));
 const exec = __importStar(__webpack_require__(986));
+const os_1 = __importDefault(__webpack_require__(87));
+const path_1 = __importDefault(__webpack_require__(622));
 exports.supportedPackageManagers = {
     npm: {
         lockFilePatterns: ['package-lock.json', 'yarn.lock'],
@@ -51591,7 +51596,7 @@ exports.supportedPackageManagers = {
     pnpm: {
         lockFilePatterns: ['pnpm-lock.yaml'],
         getCacheFolderCommand: 'pnpm get store',
-        defaultCacheFolder: '~/.pnpm-store'
+        defaultCacheFolder: path_1.default.join(os_1.default.homedir(), '.pnpm-store')
     },
     yarn1: {
         lockFilePatterns: ['yarn.lock'],

From e93556ca6645851a427f77742aeb1b22a95b4700 Mon Sep 17 00:00:00 2001
From: Jacob Gillespie <jacobwgillespie@gmail.com>
Date: Wed, 14 Jul 2021 20:11:07 +0100
Subject: [PATCH 07/12] Mock fs.existsSync in tests

---
 __tests__/cache-save.test.ts | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/__tests__/cache-save.test.ts b/__tests__/cache-save.test.ts
index 4e678945..90c29ab2 100644
--- a/__tests__/cache-save.test.ts
+++ b/__tests__/cache-save.test.ts
@@ -1,6 +1,7 @@
 import * as core from '@actions/core';
 import * as cache from '@actions/cache';
 import * as glob from '@actions/glob';
+import fs from 'fs';
 import path from 'path';
 
 import * as utils from '../src/cache-utils';
@@ -28,6 +29,7 @@ describe('run', () => {
   let saveCacheSpy: jest.SpyInstance;
   let getCommandOutputSpy: jest.SpyInstance;
   let hashFilesSpy: jest.SpyInstance;
+  let existsSpy: jest.SpyInstance;
 
   beforeEach(() => {
     getInputSpy = jest.spyOn(core, 'getInput');
@@ -63,6 +65,9 @@ describe('run', () => {
       }
     });
 
+    existsSpy = jest.spyOn(fs, 'existsSync');
+    existsSpy.mockImplementation(() => true);
+
     // utils
     getCommandOutputSpy = jest.spyOn(utils, 'getCommandOutput');
   });

From f452812b440ff2d1b0ee9d300a037464407004e5 Mon Sep 17 00:00:00 2001
From: Jacob Gillespie <jacobwgillespie@gmail.com>
Date: Thu, 15 Jul 2021 12:40:08 +0100
Subject: [PATCH 08/12] Unmock fs.existsSync after tests

---
 __tests__/cache-save.test.ts | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/__tests__/cache-save.test.ts b/__tests__/cache-save.test.ts
index 90c29ab2..82db2195 100644
--- a/__tests__/cache-save.test.ts
+++ b/__tests__/cache-save.test.ts
@@ -72,6 +72,10 @@ describe('run', () => {
     getCommandOutputSpy = jest.spyOn(utils, 'getCommandOutput');
   });
 
+  afterEach(() => {
+    existsSpy.mockRestore();
+  });
+
   describe('Package manager validation', () => {
     it('Package manager is not provided, skip caching', async () => {
       inputs['cache'] = '';

From 3af302a4f220de9ff48cd21cc1ab8e9c54382600 Mon Sep 17 00:00:00 2001
From: Jacob Gillespie <jacobwgillespie@gmail.com>
Date: Thu, 15 Jul 2021 12:43:19 +0100
Subject: [PATCH 09/12] Switch to pnpm store path command

---
 README.md                |  6 ++++--
 dist/cache-save/index.js | 17 ++---------------
 dist/setup/index.js      | 17 ++---------------
 src/cache-utils.ts       | 17 ++++-------------
 4 files changed, 12 insertions(+), 45 deletions(-)

diff --git a/README.md b/README.md
index 847fff84..58997afc 100644
--- a/README.md
+++ b/README.md
@@ -55,18 +55,20 @@ steps:
 - run: npm test
 ```
 
-**Caching pnpm dependencies:**
+**Caching pnpm (v6.10+) dependencies:**
 ```yaml
 # This workflow uses actions that are not certified by GitHub.
 # They are provided by a third-party and are governed by
 # separate terms of service, privacy policy, and support
 # documentation.
 
+# NOTE: pnpm caching support requires pnpm version >= 6.10.0
+
 steps:
 - uses: actions/checkout@v2
 - uses: pnpm/action-setup@646cdf48217256a3d0b80361c5a50727664284f2
   with:
-    version: 6.9.0
+    version: 6.10.0
 - uses: actions/setup-node@v2
   with:
     node-version: '14'
diff --git a/dist/cache-save/index.js b/dist/cache-save/index.js
index 02e4fefb..2a0dfa54 100644
--- a/dist/cache-save/index.js
+++ b/dist/cache-save/index.js
@@ -4282,14 +4282,9 @@ var __importStar = (this && this.__importStar) || function (mod) {
     result["default"] = mod;
     return result;
 };
-var __importDefault = (this && this.__importDefault) || function (mod) {
-    return (mod && mod.__esModule) ? mod : { "default": mod };
-};
 Object.defineProperty(exports, "__esModule", { value: true });
 const core = __importStar(__webpack_require__(470));
 const exec = __importStar(__webpack_require__(986));
-const os_1 = __importDefault(__webpack_require__(87));
-const path_1 = __importDefault(__webpack_require__(622));
 exports.supportedPackageManagers = {
     npm: {
         lockFilePatterns: ['package-lock.json', 'yarn.lock'],
@@ -4297,8 +4292,7 @@ exports.supportedPackageManagers = {
     },
     pnpm: {
         lockFilePatterns: ['pnpm-lock.yaml'],
-        getCacheFolderCommand: 'pnpm get store',
-        defaultCacheFolder: path_1.default.join(os_1.default.homedir(), '.pnpm-store')
+        getCacheFolderCommand: 'pnpm store path'
     },
     yarn1: {
         lockFilePatterns: ['yarn.lock'],
@@ -4345,14 +4339,7 @@ exports.getPackageManagerInfo = (packageManager) => __awaiter(void 0, void 0, vo
     }
 });
 exports.getCacheDirectoryPath = (packageManagerInfo, packageManager) => __awaiter(void 0, void 0, void 0, function* () {
-    let stdOut = yield exports.getCommandOutput(packageManagerInfo.getCacheFolderCommand);
-    // pnpm returns 'undefined' if no custom store path is set
-    if (stdOut === 'undefined') {
-        stdOut = '';
-    }
-    if (!stdOut && packageManagerInfo.defaultCacheFolder) {
-        stdOut = packageManagerInfo.defaultCacheFolder;
-    }
+    const stdOut = yield exports.getCommandOutput(packageManagerInfo.getCacheFolderCommand);
     if (!stdOut) {
         throw new Error(`Could not get cache folder path for ${packageManager}`);
     }
diff --git a/dist/setup/index.js b/dist/setup/index.js
index 07e6781f..1a213700 100644
--- a/dist/setup/index.js
+++ b/dist/setup/index.js
@@ -51580,14 +51580,9 @@ var __importStar = (this && this.__importStar) || function (mod) {
     result["default"] = mod;
     return result;
 };
-var __importDefault = (this && this.__importDefault) || function (mod) {
-    return (mod && mod.__esModule) ? mod : { "default": mod };
-};
 Object.defineProperty(exports, "__esModule", { value: true });
 const core = __importStar(__webpack_require__(470));
 const exec = __importStar(__webpack_require__(986));
-const os_1 = __importDefault(__webpack_require__(87));
-const path_1 = __importDefault(__webpack_require__(622));
 exports.supportedPackageManagers = {
     npm: {
         lockFilePatterns: ['package-lock.json', 'yarn.lock'],
@@ -51595,8 +51590,7 @@ exports.supportedPackageManagers = {
     },
     pnpm: {
         lockFilePatterns: ['pnpm-lock.yaml'],
-        getCacheFolderCommand: 'pnpm get store',
-        defaultCacheFolder: path_1.default.join(os_1.default.homedir(), '.pnpm-store')
+        getCacheFolderCommand: 'pnpm store path'
     },
     yarn1: {
         lockFilePatterns: ['yarn.lock'],
@@ -51643,14 +51637,7 @@ exports.getPackageManagerInfo = (packageManager) => __awaiter(void 0, void 0, vo
     }
 });
 exports.getCacheDirectoryPath = (packageManagerInfo, packageManager) => __awaiter(void 0, void 0, void 0, function* () {
-    let stdOut = yield exports.getCommandOutput(packageManagerInfo.getCacheFolderCommand);
-    // pnpm returns 'undefined' if no custom store path is set
-    if (stdOut === 'undefined') {
-        stdOut = '';
-    }
-    if (!stdOut && packageManagerInfo.defaultCacheFolder) {
-        stdOut = packageManagerInfo.defaultCacheFolder;
-    }
+    const stdOut = yield exports.getCommandOutput(packageManagerInfo.getCacheFolderCommand);
     if (!stdOut) {
         throw new Error(`Could not get cache folder path for ${packageManager}`);
     }
diff --git a/src/cache-utils.ts b/src/cache-utils.ts
index f39fe8a2..774e87b3 100644
--- a/src/cache-utils.ts
+++ b/src/cache-utils.ts
@@ -10,7 +10,6 @@ type SupportedPackageManagers = {
 export interface PackageManagerInfo {
   lockFilePatterns: Array<string>;
   getCacheFolderCommand: string;
-  defaultCacheFolder?: string;
 }
 
 export const supportedPackageManagers: SupportedPackageManagers = {
@@ -20,8 +19,7 @@ export const supportedPackageManagers: SupportedPackageManagers = {
   },
   pnpm: {
     lockFilePatterns: ['pnpm-lock.yaml'],
-    getCacheFolderCommand: 'pnpm get store',
-    defaultCacheFolder: path.join(os.homedir(), '.pnpm-store')
+    getCacheFolderCommand: 'pnpm store path'
   },
   yarn1: {
     lockFilePatterns: ['yarn.lock'],
@@ -80,16 +78,9 @@ export const getCacheDirectoryPath = async (
   packageManagerInfo: PackageManagerInfo,
   packageManager: string
 ) => {
-  let stdOut = await getCommandOutput(packageManagerInfo.getCacheFolderCommand);
-
-  // pnpm returns 'undefined' if no custom store path is set
-  if (stdOut === 'undefined') {
-    stdOut = '';
-  }
-
-  if (!stdOut && packageManagerInfo.defaultCacheFolder) {
-    stdOut = packageManagerInfo.defaultCacheFolder;
-  }
+  const stdOut = await getCommandOutput(
+    packageManagerInfo.getCacheFolderCommand
+  );
 
   if (!stdOut) {
     throw new Error(`Could not get cache folder path for ${packageManager}`);

From b96348a4e97e0510304e475e5cec7a7a05518c5d Mon Sep 17 00:00:00 2001
From: Jacob Gillespie <jacobwgillespie@gmail.com>
Date: Thu, 15 Jul 2021 12:46:07 +0100
Subject: [PATCH 10/12] Remove unused imports

---
 src/cache-utils.ts | 2 --
 1 file changed, 2 deletions(-)

diff --git a/src/cache-utils.ts b/src/cache-utils.ts
index 774e87b3..ebea9a75 100644
--- a/src/cache-utils.ts
+++ b/src/cache-utils.ts
@@ -1,7 +1,5 @@
 import * as core from '@actions/core';
 import * as exec from '@actions/exec';
-import os from 'os';
-import path from 'path';
 
 type SupportedPackageManagers = {
   [prop: string]: PackageManagerInfo;

From 4bc87b8e10a7f0f76173ad410d874a0b1f984af0 Mon Sep 17 00:00:00 2001
From: Maxim Lobanov <maxim-lobanov@github.com>
Date: Thu, 15 Jul 2021 14:51:41 +0300
Subject: [PATCH 11/12] Bump e2e tests to 6.10.0

---
 .github/workflows/e2e-cache.yml | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/.github/workflows/e2e-cache.yml b/.github/workflows/e2e-cache.yml
index 7e0fd247..9c294f16 100644
--- a/.github/workflows/e2e-cache.yml
+++ b/.github/workflows/e2e-cache.yml
@@ -48,7 +48,7 @@ jobs:
       - name: Install pnpm
         uses: pnpm/action-setup@v2
         with:
-          version: 6.9.0
+          version: 6.10.0
       - name: Generate pnpm file
         run: pnpm install
       - name: Remove dependencies
@@ -131,4 +131,4 @@ jobs:
         run: yarn install
       - name: Verify node and yarn
         run: __tests__/verify-node.sh "${{ matrix.node-version }}"
-        shell: bash
\ No newline at end of file
+        shell: bash

From 0ae03de2b799ae88b378c51b87476d242b3d8ef0 Mon Sep 17 00:00:00 2001
From: Jacob Gillespie <jacobwgillespie@gmail.com>
Date: Thu, 15 Jul 2021 20:14:30 +0100
Subject: [PATCH 12/12] Reorder to npm, yarn, pnpm

---
 README.md  | 30 +++++++++++++++---------------
 action.yml |  2 +-
 2 files changed, 16 insertions(+), 16 deletions(-)

diff --git a/README.md b/README.md
index 58997afc..1b66c7b1 100644
--- a/README.md
+++ b/README.md
@@ -7,7 +7,7 @@
 This action provides the following functionality for GitHub Actions users:
 
 - Optionally downloading and caching distribution of the requested Node.js version, and adding it to the PATH
-- Optionally caching npm/pnpm/yarn dependencies
+- Optionally caching npm/yarn/pnpm dependencies
 - Registering problem matchers for error output
 - Configuring authentication for GPR or npm
 
@@ -41,7 +41,7 @@ nvm lts syntax: `lts/erbium`, `lts/fermium`, `lts/*`
 
 ### Caching packages dependencies
 
-The action has a built-in functionality for caching and restoring npm/yarn dependencies. Supported package managers are `npm`, `pnpm`, `yarn`. The `cache` input is optional, and caching is turned off by default.
+The action has a built-in functionality for caching and restoring npm/yarn dependencies. Supported package managers are `npm`, `yarn`, `pnpm`. The `cache` input is optional, and caching is turned off by default.
 
 **Caching npm dependencies:**
 ```yaml
@@ -55,6 +55,19 @@ steps:
 - run: npm test
 ```
 
+**Caching yarn dependencies:**
+```yaml
+steps:
+- uses: actions/checkout@v2
+- uses: actions/setup-node@v2
+  with:
+    node-version: '14'
+    cache: 'yarn'
+- run: yarn install
+- run: yarn test
+```
+Yarn caching handles both yarn versions: 1 or 2.
+
 **Caching pnpm (v6.10+) dependencies:**
 ```yaml
 # This workflow uses actions that are not certified by GitHub.
@@ -77,19 +90,6 @@ steps:
 - run: pnpm test
 ```
 
-**Caching yarn dependencies:**
-```yaml
-steps:
-- uses: actions/checkout@v2
-- uses: actions/setup-node@v2
-  with:
-    node-version: '14'
-    cache: 'yarn'
-- run: yarn install
-- run: yarn test
-```
-Yarn caching handles both yarn versions: 1 or 2. 
-
 > At the moment, only `lock` files in the project root are supported.
 
 ### Matrix Testing:
diff --git a/action.yml b/action.yml
index 2552b8d5..943d5310 100644
--- a/action.yml
+++ b/action.yml
@@ -20,7 +20,7 @@ inputs:
     description: Used to pull node distributions from node-versions.  Since there's a default, this is typically not supplied by the user.
     default: ${{ github.token }}
   cache:
-    description: 'Used to specify a package manager for caching in the default directory. Supported values: npm, pnpm, yarn'
+    description: 'Used to specify a package manager for caching in the default directory. Supported values: npm, yarn, pnpm'
 # TODO: add input to control forcing to pull from cloud or dist. 
 #       escape valve for someone having issues or needing the absolute latest which isn't cached yet
 # Deprecated option, do not use. Will not be supported after October 1, 2019