import { DocsActionButton } from "@/components/docs/docs-github-action-button";

# GitHub Actions

Add React Doctor to GitHub Actions to catch security risks and performance regressions on every pull request.

## Install with the CLI

Run the CI installer from the project root:

```bash
npx react-doctor@latest ci install
```

React Doctor detects GitHub Actions, asks how the check should report findings, and writes `.github/workflows/react-doctor.yml`. Pass `--yes` to accept the advisory defaults.

## Add the workflow manually

If you want a CI-only setup, create `.github/workflows/react-doctor.yml`:

```yaml
name: React Doctor

on:
  # Scans the PR's changed files and posts a sticky summary comment listing only the new issues introduced relative to the merge base of the target branch.
  pull_request:
    types: [opened, synchronize, reopened, ready_for_review]
  # Scans `main` on every push to track the health-score trend and catch regressions that slipped past PR review.
  push:
    branches: [main]

permissions:
  contents: read
  pull-requests: write
  issues: write
  statuses: write

# Cancels any in-flight scan for the same PR (or branch, on push) the moment a new commit arrives, so reviewers only ever see the latest run.
concurrency:
  group: react-doctor-${{ github.event.pull_request.number || github.ref }}
  cancel-in-progress: true

jobs:
  react-doctor:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v5
        with:
          fetch-depth: 0
      - uses: millionco/react-doctor@v2
```

Create a pull request against `main` to start the check. The default workflow reports findings without failing the check.

### Configure the first scan

React Doctor starts in advisory mode and reports only issues introduced by the pull request. To map the entire project before you enforce a gate, run a full scan:

```yaml
- uses: millionco/react-doctor@v2
  with:
    blocking: none
    scope: full
```

`blocking: none` reports issues without failing the check. `scope: full` scans the whole project. The other scopes are `changed`, `files`, and `lines`.

Keep the advisory gate until the team trusts the signal. Then set `blocking: error` to fail on new errors or `blocking: warning` to fail on any new finding. You can edit the workflow through the CLI:

```bash
npx react-doctor@latest ci config --blocking error
```

For more configuration options, see the [Action reference](/docs/reference/github-action-reference).

#### Monorepos and subdirectories

Point the Action at an app in a subfolder with `directory`:

```yaml
- uses: millionco/react-doctor@v2
  with:
    directory: apps/web
```

By default, `project: "*"` finds and scans every React project. To scan only some projects, list them:

```yaml
- uses: millionco/react-doctor@v2
  with:
    project: "web,admin"
```

## What happens on a pull request

On a pull request, React Doctor reports findings in the PR conversation, inline review comments, and CI logs.

{/* TODO: put a screenshot of the CI here */}

For example, [CDCgov/cdc-open-viz#2868](https://github.com/CDCgov/cdc-open-viz/pull/2868) changed `3` files on `fix/nonnumeric-circles` against `dev`. React Doctor posted `No React Doctor issues found in this scan` with a `100/100 (Great)` score for that pull request scope.

That scope matters. The check passed because the changed files had no findings. When React Doctor finds a new issue on a changed line, it leaves an inline review comment, updates the same summary comment, and reports a failing commit status for branch protection.

Pushes to `main` only record the score, with no comment and no failure, so `main` never goes red over old issues.

### Pull request feedback

The Action creates or updates one sticky summary comment instead of stacking new comments. The comment shows issue counts, the score, links each error to its `file:line`, groups warnings by file, and notes what your change added or fixed.

Inline review comments appear on changed lines that triggered a diagnostic. Each comment includes a suggested fix and a link to the relevant docs. React Doctor caps inline comments so the summary stays the complete record.

Every run also includes full terminal output in the CI logs. Reviewers can use the logs when PR comments are disabled or unavailable.

### Feedback controls

Use Action inputs to control where feedback appears:

```yaml
- uses: millionco/react-doctor@v2
  with:
    comment: false
    review-comments: false
    commit-status: false
```

`comment` needs `issues: write`, `review-comments` needs `pull-requests: write`, and `commit-status` needs `statuses: write`. To control what reaches the pull request comment, use `surfaces.prComment` in your React Doctor config.

## Use another CI provider

The scanner is a plain CLI, so it runs on GitLab CI, CircleCI, Jenkins, and Buildkite. See [Other CI providers](/docs/ci-and-prs/other-ci-providers).

## Troubleshooting

### It reported existing issues on a pull request

The checkout couldn't find where your PR started. Add `fetch-depth: 0` to the `actions/checkout` step.

### No comment showed up

Check the workflow has `pull-requests: write` and `issues: write`, and that `comment` isn't `false`. Comments never appear on `push` runs, only pull requests.

### The status or score isn't showing

That needs `statuses: write` (unless you set `commit-status: false`). The Action warns in the run log when the permission is missing.

### It's failing PRs before the team is ready

Set `blocking: none` to report findings without failing the workflow, then tighten later.

### A failing check doesn't block the merge

Add the React Doctor check as required under **Settings → Branches → Branch protection rules**. Without that, a red check shows but the merge button still works.

### PRs from forks don't get comments

GitHub blocks write access on fork PRs for security. The scan still runs and still passes or fails; it can't post a comment.
