Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Add support for yarn berry #229

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 18 additions & 3 deletions dist/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@ const install = (opts = {}) => {
}

const shouldUseYarn = opts.useYarn
const shouldUseYarnV1 = opts.useYarnV1 ?? true
const shouldUsePackageLock = opts.usePackageLock
const npmCacheFolder = opts.npmCacheFolder
if (!npmCacheFolder) {
Expand All @@ -134,7 +135,9 @@ const install = (opts = {}) => {
return io.which('yarn', true).then(yarnPath => {
console.log('yarn at "%s"', yarnPath)

const args = shouldUsePackageLock ? ['--frozen-lockfile'] : []
const args = shouldUsePackageLock
? [shouldUseYarnV1 ? '--frozen-lockfile' : '--immutable']
: []
core.debug(
`yarn command: "${yarnPath}" ${args} ${JSON.stringify(options)}`
)
Expand Down Expand Up @@ -189,6 +192,7 @@ const getLockFilename = usePackageLock => workingDirectory => {

const getCacheParams = ({
useYarn,
useYarnV1,
useRollingCache,
homeDirectory,
npmCacheFolder,
Expand All @@ -206,7 +210,9 @@ const getCacheParams = ({
let inputPaths, restoreKeys

if (useYarn) {
inputPaths = [path.join(homeDirectory, '.cache', 'yarn')]
inputPaths = useYarnV1
? [path.join(homeDirectory, '.cache', 'yarn')]
: [path.join(homeDirectory, '.yarn', 'berry', 'cache')]
primaryKeySegments.unshift('yarn')
} else {
inputPaths = [npmCacheFolder]
Expand All @@ -232,7 +238,7 @@ const getCacheParams = ({
return { primaryKey: primaryKeySegments.join('-'), inputPaths, restoreKeys }
}

const installInOneFolder = ({
const installInOneFolder = async ({
usePackageLock,
workingDirectory,
useRollingCache,
Expand All @@ -259,13 +265,21 @@ const installInOneFolder = ({
core.debug('using NPM command, not using Yarn cache paths')
useYarn = false
}
let useYarnV1 = true
if (useYarn) {
const { stdout: yarnVersion } = await exec.getExecOutput('yarn', [
'--version'
])
useYarnV1 = /^1/.test(yarnVersion)
}

// enforce the same NPM cache folder across different operating systems
const homeDirectory = os.homedir()
const NPM_CACHE_FOLDER = path.join(homeDirectory, '.npm')

const NPM_CACHE = getCacheParams({
useYarn,
useYarnV1,
homeDirectory,
useRollingCache,
npmCacheFolder: NPM_CACHE_FOLDER,
Expand All @@ -275,6 +289,7 @@ const installInOneFolder = ({

const opts = {
useYarn,
useYarnV1,
usePackageLock,
workingDirectory,
npmCacheFolder: NPM_CACHE_FOLDER,
Expand Down
21 changes: 18 additions & 3 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@ const install = (opts = {}) => {
}

const shouldUseYarn = opts.useYarn
const shouldUseYarnV1 = opts.useYarnV1 ?? true
const shouldUsePackageLock = opts.usePackageLock
const npmCacheFolder = opts.npmCacheFolder
if (!npmCacheFolder) {
Expand All @@ -127,7 +128,9 @@ const install = (opts = {}) => {
return io.which('yarn', true).then(yarnPath => {
console.log('yarn at "%s"', yarnPath)

const args = shouldUsePackageLock ? ['--frozen-lockfile'] : []
const args = shouldUsePackageLock
? [shouldUseYarnV1 ? '--frozen-lockfile' : '--immutable']
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

--frozen-lockfile is for v1 and --immutable is for v2 and more.

: []
core.debug(
`yarn command: "${yarnPath}" ${args} ${JSON.stringify(options)}`
)
Expand Down Expand Up @@ -182,6 +185,7 @@ const getLockFilename = usePackageLock => workingDirectory => {

const getCacheParams = ({
useYarn,
useYarnV1,
useRollingCache,
homeDirectory,
npmCacheFolder,
Expand All @@ -199,7 +203,9 @@ const getCacheParams = ({
let inputPaths, restoreKeys

if (useYarn) {
inputPaths = [path.join(homeDirectory, '.cache', 'yarn')]
inputPaths = useYarnV1
? [path.join(homeDirectory, '.cache', 'yarn')]
: [path.join(homeDirectory, '.yarn', 'berry', 'cache')]
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I ran yarn info --cache in repository which using yarn v4 and it says that the cache is in "$HOME/.yarn/berry/cache".

primaryKeySegments.unshift('yarn')
} else {
inputPaths = [npmCacheFolder]
Expand All @@ -225,7 +231,7 @@ const getCacheParams = ({
return { primaryKey: primaryKeySegments.join('-'), inputPaths, restoreKeys }
}

const installInOneFolder = ({
const installInOneFolder = async ({
usePackageLock,
workingDirectory,
useRollingCache,
Expand All @@ -252,13 +258,21 @@ const installInOneFolder = ({
core.debug('using NPM command, not using Yarn cache paths')
useYarn = false
}
let useYarnV1 = true
if (useYarn) {
const { stdout: yarnVersion } = await exec.getExecOutput('yarn', [
'--version'
])
useYarnV1 = /^1/.test(yarnVersion)
}

// enforce the same NPM cache folder across different operating systems
const homeDirectory = os.homedir()
const NPM_CACHE_FOLDER = path.join(homeDirectory, '.npm')

const NPM_CACHE = getCacheParams({
useYarn,
useYarnV1,
homeDirectory,
useRollingCache,
npmCacheFolder: NPM_CACHE_FOLDER,
Expand All @@ -268,6 +282,7 @@ const installInOneFolder = ({

const opts = {
useYarn,
useYarnV1,
usePackageLock,
workingDirectory,
npmCacheFolder: NPM_CACHE_FOLDER,
Expand Down
72 changes: 72 additions & 0 deletions test/action-spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,11 @@ describe('action', () => {
.withArgs(yarnFilename)
.returns('hash-from-yarn-lock-file')

sandbox
.stub(exec, 'getExecOutput')
.withArgs('yarn', ['--version'])
.resolves({ stdout: '1.22.19' })

const cacheHit = false
this.restoreCache = sandbox.stub(cache, 'restoreCache').resolves(cacheHit)
this.saveCache = sandbox.stub(cache, 'saveCache').resolves()
Expand All @@ -80,6 +85,63 @@ describe('action', () => {
})
})

context('finds Yarn berry', function() {
const pathToYarn = '/path/to/yarn'
const yarnFilename = path.join(cwd, 'yarn.lock')
const yarnCachePaths = [path.join(homedir, '.yarn', 'berry', 'cache')]
const cacheKey = 'yarn-platform-arch-hash-from-yarn-lock-file'

beforeEach(function() {
sandbox
.stub(core, 'getInput')
.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')

sandbox
.stub(exec, 'getExecOutput')
.withArgs('yarn', ['--version'])
.resolves({ stdout: '4.2.1' })

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

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

expect(this.restoreCache).to.be.calledOnceWithExactly(
yarnCachePaths,
cacheKey,
[cacheKey]
)
expect(this.exec).to.be.calledOnceWithExactly(
quote(pathToYarn),
['--immutable'],
{ cwd }
)
expect(this.saveCache).to.be.calledOnceWithExactly(
yarnCachePaths,
cacheKey
)
})
})

context('does not find Yarn and uses NPM', function() {
const yarnFilename = path.join(cwd, 'yarn.lock')
const npmShrinkwrapFilename = path.join(cwd, 'npm-shrinkwrap.json')
Expand Down Expand Up @@ -316,6 +378,11 @@ describe('action', () => {
.withArgs(yarnFilename)
.returns('hash-from-yarn-lock-file')

sandbox
.stub(exec, 'getExecOutput')
.withArgs('yarn', ['--version'])
.resolves({ stdout: '1.22.19' })

const cacheHit = false
this.restoreCache = sandbox.stub(cache, 'restoreCache').resolves(cacheHit)
this.saveCache = sandbox.stub(cache, 'saveCache').resolves()
Expand Down Expand Up @@ -449,6 +516,11 @@ describe('action', () => {
.withArgs(yarnFilename)
.returns('hash-from-yarn-lock-file')

sandbox
.stub(exec, 'getExecOutput')
.withArgs('yarn', ['--version'])
.resolves({ stdout: '1.22.19' })

const cacheHit = false
this.restoreCache = sandbox.stub(cache, 'restoreCache').resolves(cacheHit)
this.saveCache = sandbox.stub(cache, 'saveCache').resolves()
Expand Down
27 changes: 27 additions & 0 deletions test/install-spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ describe('install command', () => {
it('uses absolute working directory', async function() {
const opts = {
useYarn: true,
useYarnV1: true,
usePackageLock: true,
// only use relative path
workingDirectory: 'directory',
Expand Down Expand Up @@ -54,6 +55,7 @@ describe('install command', () => {
it('and lock file', async function() {
const opts = {
useYarn: true,
useYarnV1: true,
usePackageLock: true,
workingDirectory,
npmCacheFolder
Expand All @@ -73,6 +75,7 @@ describe('install command', () => {
it('without lock file', async function() {
const opts = {
useYarn: true,
useYarnV1: true,
usePackageLock: false,
workingDirectory,
npmCacheFolder
Expand All @@ -88,6 +91,26 @@ describe('install command', () => {
{ cwd: workingDirectory }
)
})

it('uses Yarn berry', async function() {
const opts = {
useYarn: true,
useYarnV1: false,
usePackageLock: true,
workingDirectory,
npmCacheFolder
}
sandbox
.stub(io, 'which')
.withArgs('yarn')
.resolves(pathToYarn)
await action.utils.install(opts)
expect(this.exec).to.have.been.calledOnceWithExactly(
quote(pathToYarn),
['--immutable'],
{ cwd: workingDirectory }
)
})
})

context('using NPM', () => {
Expand All @@ -100,6 +123,7 @@ describe('install command', () => {
it('uses absolute working directory', async function() {
const opts = {
useYarn: false,
useYarnV1: false,
usePackageLock: true,
// only use relative path
workingDirectory: 'directory',
Expand Down Expand Up @@ -127,6 +151,7 @@ describe('install command', () => {
it('installs using lock file', async function() {
const opts = {
useYarn: false,
useYarnV1: false,
usePackageLock: true,
workingDirectory,
npmCacheFolder
Expand All @@ -151,6 +176,7 @@ describe('install command', () => {
it('installs without a lock file', async function() {
const opts = {
useYarn: false,
useYarnV1: false,
usePackageLock: false,
workingDirectory,
npmCacheFolder
Expand All @@ -177,6 +203,7 @@ describe('install command', () => {
it('calls exec directly', async function() {
const opts = {
useYarn: true,
useYarnV1: false,
usePackageLock: true,
// only use relative path
workingDirectory: 'directory',
Expand Down
Loading