Skip to content

Commit

Permalink
feat: add custom cache prefix (#218)
Browse files Browse the repository at this point in the history
* feat: add cache prefix input

* feat: add custom cache key prefix
  • Loading branch information
bahmutov authored Feb 14, 2024
1 parent cfc4184 commit 99e7d72
Show file tree
Hide file tree
Showing 5 changed files with 117 additions and 10 deletions.
24 changes: 24 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,30 @@ You can use your own install command

See [example-install-command.yml](./.github/workflows/example-install-command.yml)

### Add cache prefix

If you are installing different individual tools, you might want to have different caches. You can insert custom cache prefix strings into the cache keys. For example, let's install two different tools, each cache will be separate.

```yml
- name: Install tool A
uses: bahmutov/npm-install@v1
with:
# use just package.json checksum
useLockFile: false
install-command: 'npm install tool-a'
cache-key-prefix: tool-a
- name: Install tool B
uses: bahmutov/npm-install@v1
with:
# use just package.json checksum
useLockFile: false
install-command: 'npm install tool-b'
cache-key-prefix: tool-b
```

The first cache will have key `npm-tool-a-...` and the second cache will have key `npm-tool-b-...`

### Node version

If you need to use a specific Node version, use the [actions/setup-node](https://github.com/actions/setup-node) before installing the dependencies.
Expand Down
3 changes: 3 additions & 0 deletions action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,6 @@ inputs:
install-command:
description: 'Custom install command to use'
required: false
cache-key-prefix:
description: 'Prefix the cache name with this string'
required: false
19 changes: 15 additions & 4 deletions dist/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -183,11 +183,17 @@ const getCacheParams = ({
useRollingCache,
homeDirectory,
npmCacheFolder,
lockHash
lockHash,
cachePrefix
}) => {
const platformAndArch = api.utils.getPlatformAndArch()
core.debug(`platform and arch ${platformAndArch}`)
const primaryKeySegments = [platformAndArch]

if (cachePrefix) {
primaryKeySegments.unshift(cachePrefix)
}

let inputPaths, restoreKeys

if (useYarn) {
Expand Down Expand Up @@ -221,7 +227,8 @@ const installInOneFolder = ({
usePackageLock,
workingDirectory,
useRollingCache,
installCommand
installCommand,
cachePrefix
}) => {
core.debug(`usePackageLock? ${usePackageLock}`)
core.debug(`working directory ${workingDirectory}`)
Expand Down Expand Up @@ -253,7 +260,8 @@ const installInOneFolder = ({
homeDirectory,
useRollingCache,
npmCacheFolder: NPM_CACHE_FOLDER,
lockHash
lockHash,
cachePrefix
})

const opts = {
Expand All @@ -278,8 +286,10 @@ const installInOneFolder = ({
const npmInstallAction = async () => {
const usePackageLock = getInputBool('useLockFile', true)
const useRollingCache = getInputBool('useRollingCache', false)
const cachePrefix = core.getInput('cache-key-prefix') || ''
core.debug(`usePackageLock? ${usePackageLock}`)
core.debug(`useRollingCache? ${useRollingCache}`)
core.debug(`cache prefix "${cachePrefix}"`)

// Note: working directory for "actions/exec" should be absolute

Expand All @@ -299,7 +309,8 @@ const npmInstallAction = async () => {
usePackageLock,
useRollingCache,
workingDirectory,
installCommand
installCommand,
cachePrefix
})
}
}
Expand Down
19 changes: 15 additions & 4 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -176,11 +176,17 @@ const getCacheParams = ({
useRollingCache,
homeDirectory,
npmCacheFolder,
lockHash
lockHash,
cachePrefix
}) => {
const platformAndArch = api.utils.getPlatformAndArch()
core.debug(`platform and arch ${platformAndArch}`)
const primaryKeySegments = [platformAndArch]

if (cachePrefix) {
primaryKeySegments.unshift(cachePrefix)
}

let inputPaths, restoreKeys

if (useYarn) {
Expand Down Expand Up @@ -214,7 +220,8 @@ const installInOneFolder = ({
usePackageLock,
workingDirectory,
useRollingCache,
installCommand
installCommand,
cachePrefix
}) => {
core.debug(`usePackageLock? ${usePackageLock}`)
core.debug(`working directory ${workingDirectory}`)
Expand Down Expand Up @@ -246,7 +253,8 @@ const installInOneFolder = ({
homeDirectory,
useRollingCache,
npmCacheFolder: NPM_CACHE_FOLDER,
lockHash
lockHash,
cachePrefix
})

const opts = {
Expand All @@ -271,8 +279,10 @@ const installInOneFolder = ({
const npmInstallAction = async () => {
const usePackageLock = getInputBool('useLockFile', true)
const useRollingCache = getInputBool('useRollingCache', false)
const cachePrefix = core.getInput('cache-key-prefix') || ''
core.debug(`usePackageLock? ${usePackageLock}`)
core.debug(`useRollingCache? ${useRollingCache}`)
core.debug(`cache prefix "${cachePrefix}"`)

// Note: working directory for "actions/exec" should be absolute

Expand All @@ -292,7 +302,8 @@ const npmInstallAction = async () => {
usePackageLock,
useRollingCache,
workingDirectory,
installCommand
installCommand,
cachePrefix
})
}
}
Expand Down
62 changes: 60 additions & 2 deletions test/action-spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ describe('action', () => {
sandbox.stub(os, 'homedir').returns(homedir)
sandbox.stub(process, 'cwd').returns(cwd)
sandbox.stub(utils, 'getPlatformAndArch').returns('platform-arch')
sandbox.stub(utils, 'getNow').returns(new Date(2020, 01, 01))
sandbox.stub(utils, 'getNow').returns(new Date(2020, 0o1, 0o1))
// always stub "core.exportVariable" to avoid polluting actual workflow
sandbox.stub(core, 'exportVariable').returns()
})
Expand Down Expand Up @@ -80,7 +80,7 @@ describe('action', () => {
})
})

context('does not find Yarn', function() {
context('does not find Yarn and uses NPM', function() {
const yarnFilename = path.join(cwd, 'yarn.lock')
const npmShrinkwrapFilename = path.join(cwd, 'npm-shrinkwrap.json')
const packageLockFilename = path.join(cwd, 'package-lock.json')
Expand Down Expand Up @@ -268,18 +268,21 @@ describe('action', () => {
await action.npmInstallAction()
expect(installInOneFolder).to.be.calledThrice
expect(installInOneFolder).to.be.calledWithExactly({
cachePrefix: '',
installCommand: undefined,
usePackageLock: true,
useRollingCache: false,
workingDirectory: 'subfolder/foo'
})
expect(installInOneFolder).to.be.calledWithExactly({
cachePrefix: '',
installCommand: undefined,
usePackageLock: true,
useRollingCache: false,
workingDirectory: 'subfolder/bar'
})
expect(installInOneFolder).to.be.calledWithExactly({
cachePrefix: '',
installCommand: undefined,
usePackageLock: true,
useRollingCache: false,
Expand Down Expand Up @@ -418,4 +421,59 @@ describe('action', () => {
)
})
})

context('with cachePrefix', function() {
const pathToYarn = '/path/to/yarn'
const yarnFilename = path.join(cwd, 'yarn.lock')
const yarnCachePaths = [path.join(homedir, '.cache', 'yarn')]
const cacheKey =
'yarn-my-cache-prefix-platform-arch-2020-1-hash-from-yarn-lock-file'

beforeEach(function() {
const stub = sandbox.stub(core, 'getInput')
stub.withArgs('cache-key-prefix').returns('my-cache-prefix')
stub.withArgs('useRollingCache').returns('1')
stub.withArgs('useLockFile').returns()
sandbox
.stub(fs, 'existsSync')
.withArgs(yarnFilename)
.returns(true)

sandbox
.stub(io, 'which')
.withArgs('yarn')
.resolves(pathToYarn)

sandbox
.stub(hasha, 'fromFileSync')
.withArgs(yarnFilename)
.returns('hash-from-yarn-lock-file')

const cacheHit = false
this.restoreCache = sandbox.stub(cache, 'restoreCache').resolves(cacheHit)
this.saveCache = sandbox.stub(cache, 'saveCache').resolves()
})

it('finds yarn and uses lock file', async function() {
await action.npmInstallAction()

expect(this.restoreCache).to.be.calledOnceWithExactly(
yarnCachePaths,
cacheKey,
[
'yarn-my-cache-prefix-platform-arch-2020-1-hash-from-yarn-lock-file',
'yarn-my-cache-prefix-platform-arch-2020-1'
]
)
expect(this.exec).to.be.calledOnceWithExactly(
quote(pathToYarn),
['--frozen-lockfile'],
{ cwd }
)
expect(this.saveCache).to.be.calledOnceWithExactly(
yarnCachePaths,
cacheKey
)
})
})
})

0 comments on commit 99e7d72

Please sign in to comment.