Re-run The Tests By Clicking A Checkbox

How to run the tests simply by clicking on a checkbox in the pull request.

I am heavy user of Renovate App that keeps all my repos up-to-date. One thing that is really nice and useful is a checkbox in the Renovate master GitHub issue that I can click to re-run the dependency check.

A checkbox click in the GitHub issue triggers Renovate run

If I click on that checkbox, the Renovate app runs and checks the dependencies. How does it do it? Can I use the same approach to re-run the tests when changing the tests I want to run via Pull Request? Turns out, it is pretty simple to set up using GitHub Actions.

🎁 You can find the example project in the repo bahmutov/todomvc-tests-circleci. Specifically, see the GitHub Workflow file .github/workflows/pr.yml and the file .github/PULL_REQUEST_TEMPLATE.md.

The pull request template

We can add a checkbox to the pull request file like this

1
2
3
To re-run the tests, pick the tags above then click the checkbox below

- [ ] re-run the tests

By default the checkbox is unfilled. The user can fill it by editing the pull request text or by clicking on the checkbox in the GitHub UI (assuming the user has the edit permission). Let's open a pull request and click on the checkbox.

Clicking on the checkbox

We need to detect the click and run the tests.

GitHub Actions

The easiest way to detect the change in the checkbox is to run a GitHub workflow on pull request edit. You can run a workflow on different pull request events: opened, synchronized, closed, edited. We only are interested in the "edited" events.

.github/workflows/pr.yml
1
2
3
4
5
6
7
8
9
10
11
12
name: pr
on:
pull_request:
types:
- edited
jobs:
trigger-tests:
runs-on: ubuntu-20.04
steps:

# inspect the event, see if the user
# has filled the checkbox "re-run the tests"

To detect if the user clicked the previously empty checkbox, we need to inspect the github.event object provided to the GitHub action.

1
2
3
4
- name: Dump GitHub event
env:
GITHUB_CONTEXT: ${{ toJson(github.event) }}
run: echo "$GITHUB_CONTEXT"

The dumped JSON object shows the change and the current body text of the pull request.

The body of the pull request before the edit

The current body of the pull request

Thus we can compare the event.changes.body.from and the event.pull_request.body text to see if the checkbox flipped from empty to filled. I have written this check in the bahmutov/should-run-github-action and created a reusable GitHub action everyone can use to determine if the user has filled the checkbox. In our project we use by providing an id and passing the GH event as an environment variable GITHUB_EVENT.

1
2
3
4
5
6
- name: Check the PR
# https://github.com/bahmutov/should-run-github-action
uses: bahmutov/should-run-github-action@v1
id: check-pr
env:
GITHUB_EVENT: ${{ toJson(github.event) }}

After that we can look at the check-pr step and the output variable it sets called shouldRun to decide if we need to run the tests.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
- name: Check the PR
# https://github.com/bahmutov/should-run-github-action
uses: bahmutov/should-run-github-action@v1
id: check-pr
env:
GITHUB_EVENT: ${{ toJson(github.event) }}

# we could trigger the tests to run on CircleCI
# or we can just run them here using the action
# https://github.com/cypress-io/github-action
- name: Run tests if the user filled the checkbox
if: ${{ steps.check-pr.outputs.shouldRun }}
uses: cypress-io/github-action@v2
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

This is how we can run the tests only when the user filled the checkbox. Of course, if the box is filled already and we click it the first time, it is emptied. The workflow runs, but immediately skips the test step. Then we click the checkbox and the tests run.

All edits trigger the workflow, but it quickly finishes

See also