Solvedcache Can this module be used from other JavaScript actions?

I am trying to write a JavaScript action that runs npm ci and caches ~/.npm and ~/.cache/Cypress folders. I can use this action from YML file like this

# https://github.com/actions/cache
- name: Cache node modules
  uses: actions/cache@v1
  with:
    path: ~/.npm
    key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
    restore-keys: |
      ${{ runner.os }}-node-

- name: Cache Cypress binary
  uses: actions/cache@v1
  with:
    path: ~/.cache/Cypress
    key: cypress-${{ runner.os }}-node-${{ hashFiles('**/package.json') }}
    restore-keys: |
      cypress-${{ runner.os }}-node-

- name: install dependencies
  env:
    # make sure every Cypress install prints minimal information
    CI: 1
  run: npm ci

But I would like to have our own Cypress action that does the caching and NPM install for the user, something like

- name: Install NPM and Cypress
  uses: @cypress/github-action

This means from Cypress GH action JS code I need to call restore and save files in this action. I have tried but without success, for example

// after executing `npm ci` successfully
const homeDirectory = os.homedir()
const npmCacheDirectory = path.join(homeDirectory, '.npm')

core.saveState('path', npmCacheDirectory)
core.saveState('key', 'abc123')
core.saveState('restore-keys', 'abc123')

console.log('loading cache dist restore')
require('cache/dist/restore')

which gives me

done installing NPM modules
loading cache dist restore
##[error]Input required and not supplied: path
##[error]Node run failed with exit code 1

I think this particular error is due to a different core singleton between "regular" npm module and ncc- bundled actions/cache one. But in general, do you have by any chance a plan to document how to use this module from JavaScript? I could write TypeScript and bundle it as a top level action, which should bundle actions/cache code I think.

29 Answers

✔️Accepted Answer

@actions/cache@0.1.0 is released. Please try it out and file issues under the toolkit repo if you encountered any issue. Feedback is welcomed!

Code is here.

Cache action v2 (which we are releasing later this month) will be using the cache node package #313

Other Answers:

@Cyberbeni Yes that's an option.

We're working on moving the core cache logic into a package (@actions/cache) that will live in the actions toolkit

I do understand the concerns, but actions could easily provide a flag to let users enable/disable the cache. It's not in action authors interests to build something that works sub-optimally, since people won't use their actions.

The problem with the example above, is that if you have multiple things to set up, you'll very quickly end up with tens of lines of junk just to get a (potentially very small) benefit of caching. Most likely you just won't bother. One of my workflow files already has like 47 lines) of "setup bloat" in it.

Of course, I could wrap some of that up into an action that's stored in the same repo - but then we're back to the same request - how do I implement the caching in the action instead of the workflow file?

When coding, if a function gets too big or complex, we might extract parts of it into smaller functions. It feels like the same should be possible here - if my workflow file gets large and complex, I should be able to extract a chunk of it into an action. It's hard to do that if some features only work embedded directly in the workflow file.

@chrispat @ethomson Could you prioritize this?
In the current state the manual caching with this action is so verbose (10 lines vs 1-2 lines) that many people don't use it.
This seems to notably result in excessive requests to RubyGems.org: rubygems/rubygems#3463

If there was a actions/cache package, we could automatically enable caching for ruby/setup-ruby and many other actions.

I don't think states are accessible from other actions, as you can see here. Also, it's kind of hard to use this repository's code as npm dependency due to the ncc bundled code, like you mentioned. However, I'm also interested if we can implement the caching mechanism in 3rd party actions.

Right now, I'm trying to implement the necessary API calls based on actions/cache, and I don't see any reason why it wouldn't work. We have the same security tokens, and access to the API doesn't seem to be limited to 1st party apps only. But, it does require some additional work actions/cache is doing here already.

Wouldn't it make sense to create a toolkit package that handles most of the cache code?