Implement native Yarn Modern support
This is a feature request for github-action.
What would you like
github-action should provide full native support for Yarn Modern (version 2 and later) usage.
Why is this needed
Yarn Classic (version 1) entered maintenance mode in January 2022, so github-action should provide full support for the follow-on version Yarn Modern (aka Yarn Berry - current version is ~~3.x~~ 4.x).
Due to the fact that Yarn Classic is still widely used, Yarn Classic and Yarn Modern both need to be supported. Yarn Classic has not declared any end-of-life status change and support cannot yet be dropped.
Yarn Modern is currently dealt with through the use of github-action options. These are workarounds because the action does not recognize Yarn Modern and therefore does not change the commands it calls internally. For workaround usage see:
Missing features and possible solutions
Module API call for Yarn Plug'n'Play (pnp)
The call to the Cypress Module API to invoke cypress run fails in a Yarn Plug'n'Play (pnp) environment. It does not find cypress.
For comparison: at the CLI level, for Yarn Classic and Yarn Modern, yarn node script.js works with all variations. In contrast node script.js works with only with Yarn Classic, Yarn Modern node-modules and Yarn Modern pnpm. It does not work with Yarn Modern pnp.
npx replacement by yarn
Internally github-action uses npx to execute cypress commands such as cypress cache list and cypress verify.
This does not work correctly with the Yarn Plug'n'Play default mode of Yarn Modern because there is no node_modules directory available in this configuration. npx will then separately download the arbitrary latest version of Cypress to work with, producing results which are not tied to the yarn.lock file.
With Yarn Modern configured for pnpm any npx commands fail completely. Since npx is currently hard-wired into github-action it is incompatible with this mode.
The Yarn Modern CLI run command offers the option --binaries-only so npx can be replaced by yarn run --binaries-only or yarn run -B in Yarn Modern environments. An equivalent option is not available for Yarn Classic, so npx should continue to be used in this case to avoid issues with Yarn Classic environments where cypress has been used as the name of a script in package.json. See issue https://github.com/cypress-io/github-action/issues/941 where this conflict became apparent.
yarn install command
Yarn Classic dependencies are correctly installed by github-action using yarn --frozen-lockfile, however the option --frozen-lockfile is deprecated in the Yarn Modern CLI install. For correct usage with Yarn Modern, the option --frozen-lockfile should be removed. (See also the detailed discussion in https://github.com/cypress-io/github-action/pull/611). This issue is currently worked around by using the custom install-command github-action option for Yarn Modern configurations.
Suggestion summary
| Yarn Version / Mode | Installation | npx | Module API |
|---|---|---|---|
| Yarn Classic | no change | no change | no change |
| Yarn Modern node-modules | yarn (drop --frozen-lockfile) |
yarn run -B |
yarn node |
| Yarn Modern pnp | ditto | ditto | ditto |
| Yarn Modern pnpm | ditto | ditto | ditto |
This means that the action needs to differentiate between Yarn Classic (version 1) and Yarn Modern (version 2 and later) and needs to change the logic correspondingly. Since the three nodeLinker variants of Yarn Modern (node-modules, pnp and pnpm) can be handled the same, there is no need to differentiate between them.
Currently the action checks for the presence of yarn.lock to recognize Yarn projects. yarn.lock is used by both Yarn Classic and Yarn Modern.
- There are multiple issues with Cypress compatibility with Yarn Plug'n'Play, especially for component testing - see https://github.com/cypress-io/cypress-documentation/issues/5394