Skip to navigation

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:

.github/workflows/doc-detective.yml
name: doc-detective
on: [pull_request]
jobs:
runTests:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: doc-detective/github-action@v1

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:

- uses: doc-detective/github-action@v1
with:
version: latest
config: .doc-detective.json
input: ./docs
InputDefaultDescription
versionlatestDoc Detective version to run, as a version number or an npm tag such as latest. Leave it empty ("") to run a locally resolvable build instead of installing from the registry.
working_directory.Directory to run in, relative to the repository root.
iosautoCache the WebDriverAgent build on macOS runners so ios-platform tests skip the slow cold compile. auto caches only when your specs use an ios platform, true always caches, and false never does. No effect off macOS. See Speed up iOS tests on macOS.
configNonePath to a configuration file.
inputNonePath to an input file or directory. Overrides the input field in the config file.

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:

- uses: doc-detective/github-action@v1
with:
exit_on_fail: 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:

name: doc-detective
on:
schedule:
- cron: '0 0 * * *' # Run daily at midnight
jobs:
runTests:
runs-on: ubuntu-latest
permissions:
contents: write
pull-requests: write
steps:
- uses: actions/checkout@v4
- uses: doc-detective/github-action@v1
with:
create_pr_on_change: true
pr_title: Doc Detective found changes
pr_labels: doc-detective,for-review

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.

InputDefaultDescription
create_pr_on_changefalseOpen a pull request if any files change during the run.
pr_branchdoc-detective-{DATE}Branch name for the pull request.
pr_titleDoc Detective ChangesPull request title.
pr_bodySee READMEPull request body. $RUN_URL inserts the workflow run URL.
pr_labelsdoc-detectiveComma-separated labels.
pr_assigneesNoneComma-separated usernames to assign.
pr_reviewersNoneComma-separated usernames to request reviews from.

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:

name: doc-detective
on: [pull_request]
jobs:
runTests:
runs-on: ubuntu-latest
permissions:
contents: read
issues: write
steps:
- uses: actions/checkout@v4
- uses: doc-detective/github-action@v1
with:
create_issue_on_fail: true
issue_title: Doc Detective found documentation issues
integrations: claude
InputDefaultDescription
create_issue_on_failfalseOpen an issue if one or more tests fail.
issue_titleDoc Detective FailureIssue title.
issue_bodySee READMEIssue body. $RESULTS inserts the results, $RUN_URL the workflow run URL, and $PROMPT the prompt text.
issue_labelsdoc-detectiveComma-separated labels.
issue_assigneesNoneComma-separated usernames to assign.
integrationsNoneComma-separated integrations to mention in the issue (see Integrations).
promptSee READMEPrompt text passed to integrations.

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:

- uses: doc-detective/github-action@v1
id: doc-detective
- run: echo "Results: ${{ steps.doc-detective.outputs.results }}"
OutputDescription
resultsJSON-formatted test results.
pull_request_urlURL of the created pull request, when create_pr_on_change opens one.
issue_urlURL of the created issue, when create_issue_on_fail opens one.

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:

jobs:
runTests:
runs-on: macos-latest # or windows-latest
steps:
- uses: actions/checkout@v4
- uses: doc-detective/github-action@v1

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.

jobs:
runTests:
runs-on: macos-latest
steps:
- uses: actions/checkout@v4
- uses: doc-detective/github-action@v1
# ios: auto is the default—nothing else is needed on macOS.

The ios input controls this behavior:

InputDefaultDescription
iosautoCache the WebDriverAgent build on macOS runners. auto scans your resolved specs and config and caches only when it finds an ios platform, true always caches, and false never does.

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.

jobs:
runTests:
runs-on: macos-latest
env:
DOC_DETECTIVE_CACHE_DIR: ${{ github.workspace }}/.dd-cache
steps:
- uses: actions/checkout@v4
- uses: actions/cache@v4
with:
path: .dd-cache
key: dd-cache-${{ runner.os }}
- run: npx doc-detective install ios --yes
- uses: doc-detective/github-action@v1
with:
ios: 'false'

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:

jobs:
runTests:
runs-on: ubuntu-latest
env:
DOC_DETECTIVE_CACHE_DIR: ${{ github.workspace }}/.doc-detective-cache
steps:
- uses: actions/checkout@v4
- uses: actions/cache@v4
with:
path: .doc-detective-cache
key: doc-detective-${{ runner.os }}-${{ hashFiles('**/package-lock.json') }}
restore-keys: |
doc-detective-${{ runner.os }}-
- uses: doc-detective/github-action@v1

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:

jobs:
runTests:
runs-on: ubuntu-latest
env:
DOC_DETECTIVE_CACHE_DIR: ${{ github.workspace }}/.doc-detective-cache
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 22
- uses: actions/cache@v4
with:
path: .doc-detective-cache
key: doc-detective-${{ runner.os }}-${{ hashFiles('**/package-lock.json') }}
restore-keys: |
doc-detective-${{ runner.os }}-
- run: npm install -g doc-detective
- run: doc-detective install all --yes
- uses: doc-detective/github-action@v1

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-detective job 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