Using action/cache to cache puppeteer (which downloads a Chrome executable outside of the ~/.npm folder)

I have an action that uses the puppeteer-cli package from npm, which downloads a copy of Chrome as part of its installation process.

Right now it’s downloading Chrome on every run, which makes me sad. I’d like to use https://github.com/actions/cache to avoid this, but I can’t figure out how to do that.

Anyone got any tips? Here’s my action: https://github.com/simonw/til/blob/1e29c3fe5e90c29b0e71d87dba805484ceb4393c/.github/workflows/build.yml

I ended up having to install puppeteer-cli like this:

sudo npm install -g puppeteer-cli --unsafe-perm=true

Hi @simonw,

Typically the usage is to create npm package.json and add ‘puppeteer-cli’ as dependency.

  "dependencies": {
    "@actions/core": "^1.2.3",
    "@actions/github": "^3.0.0",
    "puppeteer-cli": "^1.5.0"
  }

And in workflow, use actions/cache:

  cachecheck:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v2
      - name: Cache node modules
        uses: actions/cache@v2
        with:
          path: ~/.npm
          key: ${{ runner.os }}-${{ hashFiles('**/package.json') }}
      - name: Install Dependencies
        run: npm install    # install puppeteer-cli via 'npm install'

I’m not familar with puppeteer-cli, could you please have a try?

Thanks

I don’t think that will solve the Puppeteer case because it works by downloading Chromium into a folder nested inside node_modules - which means that caching just ~/.npm won’t cache that downloaded file.

If I run npm install puppeteer-cli I get the following in node_modules:

node_modules/puppeteer/.local-chromium

This is a big directory because the Chromium zip file is decompressed there.

The actions/cache docs warn against caching the node_modules folder, but maybe I should be doing that?

As a separate issue : I’d like to understand if there’s a way to use actions/cache for NPM-distributed command-line utilities without needing a package.json - because I don’t use Node.js directly but I do occasionally want to write actions that make use of a command-line tool that’s written in Node.

If I have to use package.json to install those in a way that lets them be correctly cached then I will, but it would be nice if there was a pattern that worked without me having to use package.json.

Hi @simonw,

Thanks for your reply!

You don’t have to use package.json. You can create a folder and install puppeteer-cli there, cache the folder. Add the bin folder to PATH then you can invoke puppeteer command. If cache hit, skip the installation to save time.

Code sample as below:

    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v2
      - name: create directory
        run: |
          mkdir -p ./installhere    # create a directory for installation
      - name: Cache node modules
        id: cachestep
        uses: actions/cache@v2
        with:
          path: installhere
          key: ${{ runner.os }}-check   # you can change the key if you don't want to cache.
      - name: install
        if: steps.cachestep.outputs.cache-hit != 'true'   # if cache hit, skip the installation
        run: |
          npm install -g --prefix ./installhere puppeteer-cli --unsafe-perm=true   # install in the desired folder      
      - name: add to PATH
        run: |
          echo "::add-path::${{github.workspace}}/installhere/bin"
      - name: check with puppeteer
        run: |
          puppeteer print https://github.com/JarvusInnovations/puppeteer-cli puppeteer-cli.pdf

Please check my workflow for your reference.

Thanks

Hi @simonw,

How is it going? Does the custom installation directory work for you? Let me know if you have any queries.

Thanks