In the previous blog post Run Changed Traced Specs On GitHub Actions I have explained how you can determine the Cypress specs that changed in the current pull request. In this post, I will show how to run them even quicker using GitHub Actions.
🎁 You can find the source code for this blog post in the repo bahmutov/changed-specs-quickly-example.
Precompute spec dependencies
If you have multiple specs plus utilities, it makes sense to precompute their import graph and store it in a JSON file in the repo. We will use my tool spec-change to compute dependencies among spec files.
1 | { |
We can run the npm run trace-deps
command locally. Here is its partial outut
1 | $ npm run trace-deps |
The file cypress/e2e/utils.ts
is popular. Several specs depend on it. If this file changes, we would consider e2e/adding-spec.ts
, e2e/clear-completed-spec.ts
and others changed too.
We can periodically update the deps.json
file on CI using a job like this:
1 | # this workflow computes the dependencies between Cypress spec |
The install step installs only the spec-change
NPM dependency and caches it by caching the ~/.npm
folder. We don't want to install all dependencies, and we don't want to download the Cypress binary.
1 | - name: Install spec-change 📦 |
Run changed specs first
When a user opens a pull request, they probably have modified some specs. We want to run the modified specs first, and if they pass, we would like to run all specs. We can find the changed between the current branch and the main branch using the find-cypress-specs utility. We can use either simple Git file change or trace dependencies.
1 | { |
I prefer using the trace so that any change to the utils.ts
forces the spec files that import it to run. Here is our workflow to determine the changed spec files.
1 | name: PR checks |
Notice the last job "Trace changed specs" has an id "trace". This job produces outputs, like the list of changed specs, the number of changed specs, and even the recommended number of machines to use to run the changed specs in parallel. We expose these outputs from the job find-changed-specs
:
1 | jobs: |
Let's pretend we modified the utils.ts
file and opened a pull request. The workflow runs and detects all the specs that rely on utils.ts
file
The workflow
After finding the changed specs, we should quickly run them. First, we run all changed specs across the N recommended machines. Then we want ti run the other specs, also in parallel. Here is how we can do it using bahmutov/cypress-workflows reusable GitHub workflows. This is the rest of the PR workflow shown above; two jobs are after the "find-changed-specs" job.
1 | # run all changed specs in parallel |
We take the find-changed-specs
job's outputs and make two jobs, both using the split
workflow from bahmutov/cypress-workflows
. I used just two machines to run the rest of the specs. In the future I hope to compute a good number of machines based on the specs.
You can find the full workflow and source code in the repo bahmutov/changed-specs-quickly-example.
See more
- 📝 blog post Run Changed Traced Specs On GitHub Actions
- 💻 utility spec-change
- 💻 utility find-cypress-specs
- 🧩 plugin cypress-split
- 🏗️ GH action bahmutov/npm-install
- 🏗️ GH workflows cypress-workflows