Skip to content

Commit 75f48d0

Browse files
committed
feat: add Yarn Modern yarn install --immutable
Detect Yarn Modern and install with yarn install --immutable
1 parent 15caff4 commit 75f48d0

6 files changed

Lines changed: 65 additions & 31 deletions

File tree

.github/workflows/example-yarn-modern-pnp.yml

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,10 +28,8 @@ jobs:
2828
run: |
2929
npm install -g corepack
3030
corepack enable yarn
31-
- name: Custom Yarn command
31+
- name: Custom Yarn Modern command
3232
uses: ./ # if copying, replace with cypress-io/github-action@v7
3333
with:
3434
working-directory: examples/yarn-modern-pnp
35-
# https://yarnpkg.com/cli/install
36-
install-command: yarn install
3735
command: yarn run --binaries-only cypress run

.github/workflows/example-yarn-modern.yml

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,7 @@ jobs:
2828
run: |
2929
npm install -g corepack
3030
corepack enable yarn
31-
- name: Custom Yarn command
31+
- name: Test with Yarn Modern
3232
uses: ./ # if copying, replace with cypress-io/github-action@v7
3333
with:
3434
working-directory: examples/yarn-modern
35-
# https://yarnpkg.com/cli/install
36-
install-command: yarn install

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ See [Releases](https://github.com/cypress-io/github-action/releases) for full de
66

77
| Version | Changes |
88
| ------- | ------------------------------------------------------------------------------------------------------------ |
9+
| v7.5.0 | Add Yarn Modern `yarn install --immutable` |
910
| v7.4.0 | Examples remove Node.js 25. End of support for Node.js 25. |
1011
| v7.3.0 | Add parameter `expose` for [`Cypress.expose()`](https://docs.cypress.io/api/cypress-api/expose) support |
1112
| v7.2.0 | Examples remove Node.js 20. End of support for Node.js 20. |

README.md

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1262,7 +1262,7 @@ See the example project [start-and-pnpm-workspaces](examples/start-and-pnpm-work
12621262

12631263
### Yarn Classic
12641264

1265-
If a `yarn.lock` file is found, the action uses the [Yarn 1 (Classic)](https://classic.yarnpkg.com/) command `yarn --frozen-lockfile` by default to install dependencies.
1265+
If a `yarn.lock` file is found, the action uses the [Yarn 1 (Classic)](https://classic.yarnpkg.com/) command `yarn --frozen-lockfile` by default to install dependencies, unless [Yarn Modern](#yarn-modern) is detected.
12661266

12671267
```yaml
12681268
name: example-yarn-classic
@@ -1283,7 +1283,7 @@ jobs:
12831283

12841284
### Yarn Modern
12851285

1286-
To install dependencies using a `yarn.lock` file from [Yarn Modern](https://yarnpkg.com/) (Yarn 2 and later) you need to override the default [Yarn 1 (Classic)](https://classic.yarnpkg.com/) installation command `yarn --frozen-lockfile`. You can do this by using the `install-command` parameter and specifying `yarn install` as in the example below.
1286+
If a `yarn.lock` file is found with a Yarn Modern format, the [Yarn Modern install](https://yarnpkg.com/cli/install) command, `yarn install --immutable`, is used to install dependencies.
12871287

12881288
The action supports built-in caching of Yarn Classic dependencies only. To cache Yarn Modern dependencies additionally use [actions/setup-node](https://github.com/actions/setup-node) and specify `cache: yarn`.
12891289

@@ -1307,7 +1307,6 @@ jobs:
13071307
uses: cypress-io/github-action@v7
13081308
with:
13091309
working-directory: examples/yarn-modern
1310-
install-command: yarn install
13111310
```
13121311

13131312
This example covers the [`.yarnrc.yml`](https://yarnpkg.com/configuration/yarnrc#nodeLinker) configuration `nodeLinker: node-modules` which Yarn uses by default for projects updated from Yarn Classic. For `nodeLinker: pnp` see [Yarn Plug'n'Play](#yarn-plugnplay) below.
@@ -1325,7 +1324,7 @@ See the above [Yarn Modern](#yarn-modern) section for information on caching Yar
13251324
name: example-yarn-modern-pnp
13261325
on: push
13271326
jobs:
1328-
yarn-classic:
1327+
yarn-modern-pnp:
13291328
runs-on: ubuntu-24.04
13301329
steps:
13311330
- name: Checkout
@@ -1334,7 +1333,6 @@ jobs:
13341333
uses: cypress-io/github-action@v7
13351334
with:
13361335
working-directory: examples/yarn-modern-pnp
1337-
install-command: yarn install
13381336
command: yarn run --binaries-only cypress run
13391337
```
13401338

@@ -1668,8 +1666,7 @@ This action installs local dependencies using lock files. Ensure that exactly on
16681666
| `package-lock.json` | [npm](https://docs.npmjs.com/cli/v9/commands/npm-ci) | `npm ci` |
16691667
| `pnpm-lock.yaml` | [pnpm](https://pnpm.io/cli/install#--frozen-lockfile) | `pnpm install --frozen-lockfile` |
16701668
| `yarn.lock` | [Yarn Classic](https://classic.yarnpkg.com/en/docs/cli/install#toc-yarn-install-frozen-lockfile) | `yarn --frozen-lockfile` |
1671-
1672-
See section [Yarn Modern](#yarn-modern) for information about using Yarn version 2 and later.
1669+
| `yarn.lock` | [Yarn Modern](https://yarnpkg.com/cli/install) | `yarn install --immutable` |
16731670

16741671
### Caching
16751672

dist/index.js

Lines changed: 29 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -101888,6 +101888,14 @@ const packageLockFilename = path.join(
101888101888
)
101889101889

101890101890
const useYarn = () => fs.existsSync(yarnFilename)
101891+
const isYarnModern = () => {
101892+
if (!useYarn()) return false
101893+
const fd = fs.openSync(yarnFilename, 'r')
101894+
const buffer = Buffer.alloc(256)
101895+
fs.readSync(fd, buffer, 0, 256, 0)
101896+
fs.closeSync(fd)
101897+
return buffer.toString('utf8').includes('__metadata:')
101898+
}
101891101899
const usePnpm = () => fs.existsSync(pnpmLockFilename)
101892101900
const useNpm = () => fs.existsSync(packageLockFilename)
101893101901

@@ -102030,15 +102038,27 @@ const install = () => {
102030102038
}
102031102039

102032102040
if (useYarn()) {
102033-
debug('installing npm dependencies using Yarn')
102034-
return io.which('yarn', true).then((yarnPath) => {
102035-
debug(`yarn at "${yarnPath}"`)
102036-
return exec.exec(
102037-
quote(yarnPath),
102038-
['--frozen-lockfile'],
102039-
cypressCommandOptions
102040-
)
102041-
})
102041+
if (isYarnModern()) {
102042+
debug('installing npm dependencies using Yarn Modern')
102043+
return io.which('yarn', true).then((yarnPath) => {
102044+
debug(`yarn at "${yarnPath}"`)
102045+
return exec.exec(
102046+
quote(yarnPath),
102047+
['install', '--immutable'],
102048+
cypressCommandOptions
102049+
)
102050+
})
102051+
} else {
102052+
debug('installing npm dependencies using Yarn Classic')
102053+
return io.which('yarn', true).then((yarnPath) => {
102054+
debug(`yarn at "${yarnPath}"`)
102055+
return exec.exec(
102056+
quote(yarnPath),
102057+
['--frozen-lockfile'],
102058+
cypressCommandOptions
102059+
)
102060+
})
102061+
}
102042102062
} else if (usePnpm()) {
102043102063
debug('installing npm dependencies using pnpm')
102044102064
return io.which('pnpm', true).then((pnpmPath) => {

index.js

Lines changed: 29 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,14 @@ const packageLockFilename = path.join(
103103
)
104104

105105
const useYarn = () => fs.existsSync(yarnFilename)
106+
const isYarnModern = () => {
107+
if (!useYarn()) return false
108+
const fd = fs.openSync(yarnFilename, 'r')
109+
const buffer = Buffer.alloc(256)
110+
fs.readSync(fd, buffer, 0, 256, 0)
111+
fs.closeSync(fd)
112+
return buffer.toString('utf8').includes('__metadata:')
113+
}
106114
const usePnpm = () => fs.existsSync(pnpmLockFilename)
107115
const useNpm = () => fs.existsSync(packageLockFilename)
108116

@@ -245,15 +253,27 @@ const install = () => {
245253
}
246254

247255
if (useYarn()) {
248-
debug('installing npm dependencies using Yarn')
249-
return io.which('yarn', true).then((yarnPath) => {
250-
debug(`yarn at "${yarnPath}"`)
251-
return exec.exec(
252-
quote(yarnPath),
253-
['--frozen-lockfile'],
254-
cypressCommandOptions
255-
)
256-
})
256+
if (isYarnModern()) {
257+
debug('installing npm dependencies using Yarn Modern')
258+
return io.which('yarn', true).then((yarnPath) => {
259+
debug(`yarn at "${yarnPath}"`)
260+
return exec.exec(
261+
quote(yarnPath),
262+
['install', '--immutable'],
263+
cypressCommandOptions
264+
)
265+
})
266+
} else {
267+
debug('installing npm dependencies using Yarn Classic')
268+
return io.which('yarn', true).then((yarnPath) => {
269+
debug(`yarn at "${yarnPath}"`)
270+
return exec.exec(
271+
quote(yarnPath),
272+
['--frozen-lockfile'],
273+
cypressCommandOptions
274+
)
275+
})
276+
}
257277
} else if (usePnpm()) {
258278
debug('installing npm dependencies using pnpm')
259279
return io.which('pnpm', true).then((pnpmPath) => {

0 commit comments

Comments
 (0)