Run in CI with the GitHub Action
The Doc Detective GitHub Action runs your tests inside a GitHub Actions workflow. It’s the recommended way to run Doc Detective in CI. It installs Doc Detective for you, and it fails the job when tests fail if you set exit_on_fail to true. It can also open a pull request or file an issue when a run finds a problem. This guide covers adding the action to a workflow, failing the build on test failures, and wiring up the pull request and issue features.
For the full list of inputs and outputs, see the action’s README.
Before you begin
- A GitHub repository with documentation tests. That’s either a spec you can run, or docs with inline or detected tests.
- Permission to add a workflow file under
.github/workflows/in that repository.
Step 1: Add the action to a workflow
Create a workflow file in .github/workflows/. Check out the repository first so the action can read your tests, then add the Doc Detective step:
This runs Doc Detective on every pull request. Pin to the major version (@v1) to pick up fixes automatically, or pin to a full version such as @v1.4.1 for a fixed release.
Step 2: Point the action at your tests
By default, the action runs from the repository root and uses the config file Doc Detective discovers there. To override either one, set the corresponding input:
Leave version empty to skip the registry install and run whatever doc-detective is already resolvable in the working directory. One example is a local build you exposed with npm link in an earlier step. This lets a repository test the action against its own build under review rather than the published package.
Step 3: Fail the build when tests fail
By default, the action doesn’t fail the job when tests fail. It reports the results and exits cleanly. To make a failing test fail the workflow and block the pull request, set exit_on_fail to true:
This is the action’s main advantage over running the CLI directly in a workflow. The standalone doc-detective CLI exits non-zero only when it crashes or your config is invalid, never because a test failed. A script that relies on its exit code therefore reports success even when documentation tests failed. The action reads the results and exits non-zero for you. See Reporters and artifacts for the CLI behavior in detail.
Step 4: Open a pull request when files change
Doc Detective sometimes updates files during a run, refreshing screenshots or recording new command output. The action can commit those changes to a new branch and open a pull request for review. To enable this, set create_pr_on_change to true and grant the job permission to write contents and pull requests:
You must allow GitHub Actions to create pull requests for the repository. Go to Settings > Actions > General and select Allow GitHub Actions to create and approve pull requests.
A created pull request means files changed, not that tests passed or failed. Review the diff before merging.
Step 5: File an issue when tests fail
When a run has failing tests, the action can open a GitHub issue to track the failure and mention an AI integration to investigate it. To enable this, set create_issue_on_fail to true and grant the job permission to write issues:
The integrations input mentions an AI assistant in the issue so it can investigate the failure and suggest a fix. Options include claude, copilot, cursor, and promptless. For the full list, see Integrations.
Step 6: Use the results in later steps
The action exposes the run’s results so later steps can act on them. Give the step an id, then read its outputs:
Browser modes
On Ubuntu runners, the action runs browsers headless. Chrome and Firefox contexts fall back to headless mode automatically.
Some tests need a display, such as recording video with the ffmpeg engine. Run those jobs on a macOS or Windows runner instead:
See Docker and headless for how headless environments affect a run.
Speed up iOS tests on macOS
Tests against the ios platform run on macOS runners, where the first XCUITest session compiles the WebDriverAgent (WDA) with xcodebuild. On a cold, ephemeral runner that compile takes around 10 minutes and dominates the run. To avoid paying that cost every time, the action caches the WDA build products and restores them on later runs. The build then becomes near-instant.
The ios input controls this behavior:
The first run compiles WDA cold and saves the build to the cache. Later runs restore it and finish with a quick incremental build. The cache key covers the runner OS, the Xcode version, and the XCUITest driver version. A change to the runner OS or Xcode starts a fresh, cold build. A driver-version bump is gentler. The exact key misses, but the action falls back to the most recent build for the same OS and Xcode. It warms an incremental rebuild from that, then re-caches the result under the new driver version. A driver upgrade therefore repairs the cache on the next run instead of leaving it stale.
Caching only affects build speed. Doc Detective still bootstraps the XCUITest driver and simulator it needs at test time. Leave ios at auto for most workflows. Set it to true when your ios platform lives outside the scanned specs and config, or false to turn caching off.
iOS simulators run only on macOS, so this input has no effect on Linux or Windows runners.
Alternative: prebuild WebDriverAgent into a persisted cache
Your workflow might already persist Doc Detective’s cache directory between runs, for example with actions/cache. You can then skip the action’s WDA cache and let Doc Detective manage the build itself. Run doc-detective install ios --yes in your setup steps. It compiles WebDriverAgent once into the cache, keyed by your Xcode and XCUITest driver versions. Test sessions consume the products automatically and read-only, which is safe to share across parallel jobs. Set ios: 'false' on the action in that case. The two mechanisms overlap, and the action’s cache takes precedence when both are active, so you’d pay for both.
Runtime caching
Doc Detective installs heavy runtime assets on first use, including browsers, drivers, and npm packages. To speed up CI, cache them between runs.
Cache the runtime directory
Point DOC_DETECTIVE_CACHE_DIR at a path under the workspace, then use GitHub’s cache action to persist it between runs:
Because DOC_DETECTIVE_CACHE_DIR points to a path under ${{ github.workspace }}, the cache action can store and restore those assets across runs.
Pre-install assets
To control exactly when assets download, install them before the action runs:
Setting env at the job level makes DOC_DETECTIVE_CACHE_DIR visible to every step, so the pre-install step and the action share the same cached directory.
Verify it works
Open a pull request that touches a documented command, screenshot, or API response, then confirm:
- The
doc-detectivejob runs and its log shows the terminal summary. - With
exit_on_fail: true, a failing test fails the job and blocks the pull request. - With
create_pr_on_change: true, a run that changes files opens a pull request. - With
create_issue_on_fail: true, a run with failing tests opens an issue.
Troubleshooting
The job passes even though a test failed
Cause: exit_on_fail defaults to false, so the action reports failures without failing the job.
Solution: Set exit_on_fail to true so failing tests fail the workflow. See Step 3.
The action can’t create a pull request or issue
Cause: The job lacks the required permissions, or the repository doesn’t allow Actions to create pull requests.
Solution: Add permissions: { contents: write, pull-requests: write } for pull requests or permissions: { issues: write } for issues. For pull requests, also enable Allow GitHub Actions to create and approve pull requests under Settings > Actions > General.
Runs are slow because assets download every time
Cause: The runtime cache isn’t persisted between runs.
Solution: Set DOC_DETECTIVE_CACHE_DIR to a cached workspace path and pre-install assets. See Runtime caching.
What’s next
- Consume results and fail the build correctly with reporters and artifacts.
- Run in Docker and headless for containerized or non-GitHub pipelines.
- Troubleshoot a failing or flaky test when a run isn’t green.