diff --git a/.github/workflows/example-basic-pnpm.yml b/.github/workflows/example-basic-pnpm.yml index 2ecc8c9f7..bf0be9a02 100644 --- a/.github/workflows/example-basic-pnpm.yml +++ b/.github/workflows/example-basic-pnpm.yml @@ -11,7 +11,10 @@ jobs: strategy: fail-fast: false matrix: - os: [ubuntu-24.04, windows-2025, macos-15] + os: + - ubuntu-24.04 + - windows-2025 + - macos-15 runs-on: ${{ matrix.os }} steps: - name: Checkout @@ -28,12 +31,13 @@ jobs: uses: actions/setup-node@v6 with: node-version-file: '.node-version' - cache: 'pnpm' + cache: pnpm cache-dependency-path: examples/basic-pnpm/pnpm-lock.yaml - name: Cypress tests uses: ./ # if copying, replace with cypress-io/github-action@v7 with: + package-manager-cache: false working-directory: examples/basic-pnpm # print information about detected browsers, etc # see https://on.cypress.io/command-line#cypress-info diff --git a/.github/workflows/example-basic.yml b/.github/workflows/example-basic.yml index bd3215570..e3608a248 100644 --- a/.github/workflows/example-basic.yml +++ b/.github/workflows/example-basic.yml @@ -1,5 +1,11 @@ name: example-basic # This workflow represents a set of basic End-to-End tests +# +# In the example jobs, the action is called with +# uses: ./ +# which runs the action code from the current branch. +# If you copy this workflow to another repo, replace the line with +# uses: cypress-io/github-action@v7 on: push: branches: @@ -12,14 +18,18 @@ jobs: strategy: fail-fast: false matrix: - os: [ubuntu-22.04, ubuntu-24.04, windows-2025, macos-15] + os: + - ubuntu-22.04 + - ubuntu-24.04 + - windows-2025 + - macos-15 runs-on: ${{ matrix.os }} steps: - name: Checkout uses: actions/checkout@v6 - name: Cypress tests - uses: ./ # if copying, replace with cypress-io/github-action@v7 + uses: ./ # the parameters below are only necessary # because we are running these examples in a monorepo with: @@ -28,3 +38,31 @@ jobs: # print information about detected browsers, etc # see https://on.cypress.io/command-line#cypress-info build: npx cypress info + + basic-npm-cache: + # Use setup-node to cache npm dependencies + strategy: + fail-fast: false + matrix: + os: + - ubuntu-22.04 + - ubuntu-24.04 + - windows-2025 + - macos-15 + runs-on: ${{ matrix.os }} + steps: + - name: Checkout + uses: actions/checkout@v6 + - name: Setup Node.js + uses: actions/setup-node@v6 + with: + node-version-file: .node-version + cache: npm + cache-dependency-path: examples/basic/package-lock.json + + - name: Cypress tests + uses: ./ + with: + package-manager-cache: false + working-directory: examples/basic + build: npx cypress info diff --git a/.github/workflows/example-node-versions.yml b/.github/workflows/example-node-versions.yml index eaf097b4b..9547848ce 100644 --- a/.github/workflows/example-node-versions.yml +++ b/.github/workflows/example-node-versions.yml @@ -20,6 +20,8 @@ jobs: - 25 name: Cypress E2E on Node v${{ matrix.node }} steps: + - name: Checkout + uses: actions/checkout@v6 - name: Install Node.js uses: actions/setup-node@v6 with: @@ -27,9 +29,6 @@ jobs: - run: node -v - run: npm -v - - name: Checkout - uses: actions/checkout@v6 - - name: Cypress tests uses: ./ # if copying, replace with cypress-io/github-action@v7 with: diff --git a/.github/workflows/example-start-and-pnpm-workspaces.yml b/.github/workflows/example-start-and-pnpm-workspaces.yml index ccf5bd139..b4accc6cc 100644 --- a/.github/workflows/example-start-and-pnpm-workspaces.yml +++ b/.github/workflows/example-start-and-pnpm-workspaces.yml @@ -26,14 +26,27 @@ jobs: - name: Checkout repository uses: actions/checkout@v6 - # pnpm is not installed by default on GitHub runners + # See https://github.com/pnpm/action-setup - name: Install pnpm - run: npm install -g pnpm@10 + uses: pnpm/action-setup@v4 + with: + version: 10 + + # See https://github.com/actions/setup-node + - name: Install Node.js + uses: actions/setup-node@v6 + with: + node-version-file: '.node-version' + cache: pnpm + cache-dependency-path: examples/start-and-pnpm-workspaces/pnpm-lock.yaml - name: Install dependencies # All dependencies including workspaces are installed - run: pnpm install --frozen-lockfile - working-directory: examples/start-and-pnpm-workspaces + uses: ./ + with: + package-manager-cache: false + runTests: false + working-directory: examples/start-and-pnpm-workspaces - name: Cypress test Single # Run Cypress in examples/start-and-pnpm-workspaces/packages/workspace-1 only @@ -66,11 +79,23 @@ jobs: uses: actions/checkout@v6 - name: Install pnpm - run: npm install -g pnpm@10 + uses: pnpm/action-setup@v4 + with: + version: 10 + + - name: Install Node.js + uses: actions/setup-node@v6 + with: + node-version-file: '.node-version' + cache: pnpm + cache-dependency-path: examples/start-and-pnpm-workspaces/pnpm-lock.yaml - name: Install dependencies - run: pnpm install --frozen-lockfile - working-directory: examples/start-and-pnpm-workspaces + uses: ./ + with: + package-manager-cache: false + runTests: false + working-directory: examples/start-and-pnpm-workspaces - name: Cypress test Multiple # Run Cypress in diff --git a/.github/workflows/example-yarn-classic.yml b/.github/workflows/example-yarn-classic.yml index dcc0a75ab..6ecf4d6b6 100644 --- a/.github/workflows/example-yarn-classic.yml +++ b/.github/workflows/example-yarn-classic.yml @@ -1,4 +1,9 @@ name: example-yarn-classic +# In the example jobs, the action is called with +# uses: ./ +# which runs the action code from the current branch. +# If you copy this workflow to another repo, replace the line with +# uses: cypress-io/github-action@v7 on: push: branches: @@ -14,6 +19,25 @@ jobs: uses: actions/checkout@v6 - name: Test with Yarn Classic - uses: ./ # if copying, replace with cypress-io/github-action@v7 + uses: ./ with: working-directory: examples/yarn-classic + + yarn-classic-cache: + # Use setup-node to cache Yarn dependencies + runs-on: ubuntu-24.04 + steps: + - name: Checkout + uses: actions/checkout@v6 + - name: Setup Node.js + uses: actions/setup-node@v6 + with: + node-version-file: .node-version + cache: yarn + cache-dependency-path: examples/yarn-classic/yarn.lock + + - name: Test with Yarn Classic + uses: ./ + with: + package-manager-cache: false + working-directory: examples/yarn-classic diff --git a/README.md b/README.md index 0ade221c4..e903babeb 100644 --- a/README.md +++ b/README.md @@ -68,6 +68,7 @@ The following examples demonstrate the actions' functions. - Use [Yarn Modern](#yarn-modern) - Use [Yarn Plug'n'Play](#yarn-plugnplay) - Use [Yarn workspaces](#yarn-workspaces) +- Disable [package manager cache](#package-manager-cache-disable) - Use [custom cache key](#custom-cache-key) - Run tests on multiple [Node versions](#node-versions) - Split [install and tests](#split-install-and-tests) into separate jobs @@ -100,7 +101,7 @@ jobs: steps: - name: Checkout uses: actions/checkout@v6 - # Install npm dependencies, cache them correctly + # Install dependencies with caching # and run all Cypress tests - name: Cypress run uses: cypress-io/github-action@v7 @@ -566,15 +567,14 @@ jobs: node: [20, 22, 24, 25] name: E2E on Node v${{ matrix.node }} steps: + - name: Checkout + uses: actions/checkout@v6 - name: Install Node.js uses: actions/setup-node@v6 with: node-version: ${{ matrix.node }} - run: node -v - - name: Checkout - uses: actions/checkout@v6 - - name: Cypress run uses: cypress-io/github-action@v7 with: @@ -663,7 +663,7 @@ jobs: steps: - name: Checkout uses: actions/checkout@v6 - # Install npm dependencies, cache them correctly + # Install dependencies with caching # and run all Cypress tests with `quiet` parameter - name: Cypress run uses: cypress-io/github-action@v7 @@ -1167,9 +1167,14 @@ jobs: ### pnpm -The package manager `pnpm` is not pre-installed in [GitHub Actions runner images](https://github.com/actions/runner-images) (unlike `npm` and `yarn`) and so it must be installed in a separate workflow step (see below). If the action finds a `pnpm-lock.yaml` file, it uses the [pnpm](https://pnpm.io/cli/install) command `pnpm install --frozen-lockfile` by default to install dependencies. +The package manager `pnpm` is not pre-installed in [GitHub Actions runner images](https://github.com/actions/runner-images) +(unlike npm and Yarn Classic) and so it must be installed in a separate workflow step (see below). +If the action finds a `pnpm-lock.yaml` file, it uses the [pnpm](https://pnpm.io/cli/install) command `pnpm install --frozen-lockfile` by default to install dependencies. -The example below follows [pnpm recommendations](https://pnpm.io/continuous-integration#github-actions) for installing pnpm and caching the [pnpm store](https://pnpm.io/cli/store). Follow the [Cypress pnpm configuration instructions](https://docs.cypress.io/app/get-started/install-cypress#pnpm-configuration) and apply them to your project, to enable pnpm to install the Cypress binary. +The example below follows [pnpm recommendations](https://pnpm.io/continuous-integration#github-actions) for installing pnpm and caching the +[pnpm store](https://pnpm.io/cli/store). +Follow the [Cypress pnpm configuration instructions](https://docs.cypress.io/app/get-started/install-cypress#pnpm-configuration) +and apply them to your project, to enable pnpm to install the Cypress binary. ```yaml name: example-basic-pnpm @@ -1193,6 +1198,7 @@ jobs: - name: Cypress run uses: cypress-io/github-action@v7 with: + package-manager-cache: false working-directory: examples/basic-pnpm ``` @@ -1200,13 +1206,19 @@ jobs: ### pnpm workspaces -The action does not directly support using [pnpm workspaces](https://pnpm.io/workspaces) (see feature request [#1144](https://github.com/cypress-io/github-action/issues/1144)). As a workaround, you can install dependencies and run Cypress tests in a workspace in separate steps. The snippet below shows this principle. +The action does not directly support using [pnpm workspaces](https://pnpm.io/workspaces) +(see feature request [#1144](https://github.com/cypress-io/github-action/issues/1144)). +As a workaround, you can install dependencies and run Cypress tests in a workspace in separate steps. +The snippet below shows this principle. ```yml ... - name: Install dependencies - run: pnpm install --frozen-lockfile - working-directory: examples/start-and-pnpm-workspaces + uses: cypress-io/github-action@v7 + with: + package-manager-cache: false + runTests: false + working-directory: examples/start-and-pnpm-workspaces - name: Cypress test uses: cypress-io/github-action@v7 @@ -1329,6 +1341,38 @@ jobs: [![Yarn workspaces example](https://github.com/cypress-io/github-action/actions/workflows/example-start-and-yarn-workspaces.yml/badge.svg)](.github/workflows/example-start-and-yarn-workspaces.yml) +### Package manager cache disable + +When the action installs dependencies, +it caches the package manager cache from npm or from Yarn 1 (Classic) by default, +based on the [lockfile](#package-manager-cache) it discovers. +If package manager caching is implemented separately from the action, +for example to work with Yarn Modern or pnpm, +then disable the actions' package manager caching by setting the parameter +`package-manager-cache` to `false`. + +GitHub's [actions/setup-node](https://github.com/actions/setup-node/blob/main/README.md) offers a convenient way to install a chosen version of Node.js +and to set up caching of package manager caches in one step. + +```yml +name: Package manager caching +on: push +jobs: + cypress-run: + runs-on: ubuntu-24.04 + name: + steps: + - uses: actions/checkout@v6 + - uses: actions/setup-node@v6 + with: + node-version: lts + cache: 'pnpm' + cache-dependency-path: pnpm-lock.yaml + - uses: cypress-io/github-action@v7 + with: + package-manager-cache: false +``` + ### Custom cache key Sometimes the default cache key does not work. For example, if you cannot share the Node modules across Node versions due to native extensions. In that case pass your own `cache-key` parameter. @@ -1345,12 +1389,12 @@ jobs: node: [20, 22, 24, 25] name: E2E on Node v${{ matrix.node }} steps: + - name: Checkout + uses: actions/checkout@v6 - name: Install Node.js uses: actions/setup-node@v6 with: node-version: ${{ matrix.node }} - - name: Checkout - uses: actions/checkout@v6 # run Cypress tests and record them under the same run # associated with commit SHA and just give a different group name - name: Cypress run @@ -1379,10 +1423,10 @@ jobs: node: [20, 22, 24, 25] name: E2E on Node v${{ matrix.node }} steps: + - uses: actions/checkout@v6 - uses: actions/setup-node@v6 with: node-version: ${{ matrix.node }} - - uses: actions/checkout@v6 - uses: cypress-io/github-action@v7 ``` diff --git a/action.yml b/action.yml index bfcc50968..ab6b0cea4 100644 --- a/action.yml +++ b/action.yml @@ -83,6 +83,10 @@ inputs: install-command: description: 'Custom install command to use' required: false + package-manager-cache: + description: 'Set to false to disable automatic package manager caching. By default, package manager caching is enabled.' + required: false + default: true publish-summary: description: 'Whether or not to publish a job summary' required: false diff --git a/dist/index.js b/dist/index.js index ac9f94ace..62a3abb56 100644 --- a/dist/index.js +++ b/dist/index.js @@ -102775,8 +102775,16 @@ const installMaybe = () => { return Promise.resolve() } + const packageManagerCacheEnabled = getInputBool( + 'package-manager-cache', + true + ) + const npmCachePromise = packageManagerCacheEnabled + ? restoreCachedNpm() + : Promise.resolve(false) + return Promise.all([ - restoreCachedNpm(), + npmCachePromise, restoreCachedCypressBinary() ]).then(([npmCacheHit, cypressCacheHit]) => { debug(`npm cache hit ${npmCacheHit}`) @@ -102791,8 +102799,11 @@ const installMaybe = () => { } debug('verifying Cypress binary') + const saveNpmPromise = packageManagerCacheEnabled + ? saveCachedNpm() + : Promise.resolve(undefined) return verifyCypressBinary() - .then(saveCachedNpm) + .then(() => saveNpmPromise) .then(saveCachedCypressBinary) }) }) diff --git a/index.js b/index.js index de026c3f5..4c0dd242e 100644 --- a/index.js +++ b/index.js @@ -977,8 +977,16 @@ const installMaybe = () => { return Promise.resolve() } + const packageManagerCacheEnabled = getInputBool( + 'package-manager-cache', + true + ) + const npmCachePromise = packageManagerCacheEnabled + ? restoreCachedNpm() + : Promise.resolve(false) + return Promise.all([ - restoreCachedNpm(), + npmCachePromise, restoreCachedCypressBinary() ]).then(([npmCacheHit, cypressCacheHit]) => { debug(`npm cache hit ${npmCacheHit}`) @@ -993,8 +1001,11 @@ const installMaybe = () => { } debug('verifying Cypress binary') + const saveNpmPromise = packageManagerCacheEnabled + ? saveCachedNpm() + : Promise.resolve(undefined) return verifyCypressBinary() - .then(saveCachedNpm) + .then(() => saveNpmPromise) .then(saveCachedCypressBinary) }) })