Skip to main content

GitHub Actions

Basic Setup

Add React Doctor to your workflow:
.github/workflows/react-doctor.yml
name: React Doctor

on:
  pull_request:
  push:
    branches: [main]

jobs:
  analyze:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v5
        with:
          fetch-depth: 0 # Required for --diff mode

      - uses: millionco/react-doctor@main
        with:
          verbose: true
          fail-on: error

Diff Mode (PR Only)

Scan only changed files in pull requests:
.github/workflows/react-doctor.yml
name: React Doctor

on:
  pull_request:

jobs:
  analyze:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v5
        with:
          fetch-depth: 0

      - uses: millionco/react-doctor@main
        with:
          diff: main
          github-token: ${{ secrets.GITHUB_TOKEN }}
          fail-on: error
Setting github-token automatically posts scan results as a PR comment

Monorepo Workflow

Scan specific workspace projects:
.github/workflows/react-doctor.yml
name: React Doctor

on:
  pull_request:
  push:
    branches: [main]

jobs:
  analyze:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v5
        with:
          fetch-depth: 0

      - uses: millionco/react-doctor@main
        with:
          project: web,admin,mobile
          verbose: true
          fail-on: warning

Use Score in Next Steps

Access the health score in subsequent workflow steps:
.github/workflows/react-doctor.yml
name: React Doctor

on:
  pull_request:

jobs:
  analyze:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v5
        with:
          fetch-depth: 0

      - uses: millionco/react-doctor@main
        id: doctor
        with:
          verbose: true

      - name: Check Score
        run: |
          echo "Health Score: ${{ steps.doctor.outputs.score }}"
          if [ "${{ steps.doctor.outputs.score }}" -lt 70 ]; then
            echo "::warning::Health score is below 70"
          fi

      - name: Post to Slack
        if: always()
        run: |
          curl -X POST ${{ secrets.SLACK_WEBHOOK }} \
            -H 'Content-Type: application/json' \
            -d '{"text":"React Doctor Score: ${{ steps.doctor.outputs.score }}"}'

Matrix Strategy for Multiple Projects

Run parallel jobs for different workspace projects:
.github/workflows/react-doctor.yml
name: React Doctor

on:
  pull_request:

jobs:
  analyze:
    runs-on: ubuntu-latest
    strategy:
      matrix:
        project: [web, admin, mobile]
    steps:
      - uses: actions/checkout@v5
        with:
          fetch-depth: 0

      - uses: millionco/react-doctor@main
        with:
          project: ${{ matrix.project }}
          verbose: true
          fail-on: error

GitLab CI

Basic Pipeline

.gitlab-ci.yml
react-doctor:
  image: node:20
  stage: test
  script:
    - npx -y react-doctor@latest . --verbose --fail-on error
  only:
    - merge_requests
    - main

With Diff Mode

.gitlab-ci.yml
react-doctor:
  image: node:20
  stage: test
  script:
    - git fetch origin main
    - npx -y react-doctor@latest . --diff origin/main --verbose --fail-on error
  only:
    - merge_requests

Store Score as Artifact

.gitlab-ci.yml
react-doctor:
  image: node:20
  stage: test
  script:
    - npx -y react-doctor@latest . --score > score.txt
    - cat score.txt
    - npx -y react-doctor@latest . --verbose --fail-on warning
  artifacts:
    reports:
      metrics: score.txt
    paths:
      - score.txt
    expire_in: 30 days
  only:
    - merge_requests
    - main

CircleCI

Basic Config

.circleci/config.yml
version: 2.1

jobs:
  react-doctor:
    docker:
      - image: cimg/node:20.0
    steps:
      - checkout
      - run:
          name: Run React Doctor
          command: npx -y react-doctor@latest . --verbose --fail-on error

workflows:
  analyze:
    jobs:
      - react-doctor

With Caching

.circleci/config.yml
version: 2.1

jobs:
  react-doctor:
    docker:
      - image: cimg/node:20.0
    steps:
      - checkout
      - restore_cache:
          keys:
            - v1-deps-{{ checksum "package-lock.json" }}
      - run:
          name: Install dependencies
          command: npm ci
      - save_cache:
          key: v1-deps-{{ checksum "package-lock.json" }}
          paths:
            - node_modules
      - run:
          name: Run React Doctor
          command: npx -y react-doctor@latest . --verbose --fail-on error

workflows:
  version: 2
  analyze:
    jobs:
      - react-doctor

Jenkins

Declarative Pipeline

Jenkinsfile
pipeline {
  agent {
    docker {
      image 'node:20'
    }
  }
  
  stages {
    stage('React Doctor') {
      steps {
        sh 'npx -y react-doctor@latest . --verbose --fail-on error'
      }
    }
  }
}

With Diff Mode

Jenkinsfile
pipeline {
  agent {
    docker {
      image 'node:20'
    }
  }
  
  stages {
    stage('React Doctor') {
      steps {
        script {
          if (env.CHANGE_ID) {
            // Pull request - scan only changed files
            sh 'npx -y react-doctor@latest . --diff origin/main --verbose --fail-on error'
          } else {
            // Main branch - full scan
            sh 'npx -y react-doctor@latest . --verbose --fail-on error'
          }
        }
      }
    }
  }
}

Bitbucket Pipelines

bitbucket-pipelines.yml
image: node:20

pipelines:
  pull-requests:
    '**':
      - step:
          name: React Doctor
          script:
            - npx -y react-doctor@latest . --verbose --fail-on error
  
  branches:
    main:
      - step:
          name: React Doctor
          script:
            - npx -y react-doctor@latest . --score > score.txt
            - cat score.txt
            - npx -y react-doctor@latest . --verbose --fail-on warning
          artifacts:
            - score.txt

Fail-On Levels

Control when CI should fail based on diagnostic severity:
- uses: millionco/react-doctor@main
  with:
    fail-on: error  # Default in CI

Action Inputs Reference

InputDefaultDescription
directory.Project directory to scan
verbosetrueShow file details per rule
projectWorkspace project(s) to scan (comma-separated)
diffBase branch for diff mode. Only changed files are scanned
github-tokenWhen set on pull_request events, posts findings as a PR comment
fail-onerrorExit with error code on diagnostics: error, warning, none
node-version20Node.js version to use

Tips

Use fail-on: warning for stricter quality gates on main branches
Use fail-on: none during initial adoption to avoid blocking PRs
Always use fetch-depth: 0 with --diff mode to access full git history

Build docs developers (and LLMs) love