CI
CI platforms
Run rn-doctor on Azure DevOps, GitLab CI, Bitbucket Pipelines or GitHub Actions - platform detection, the --ci flag, and a copy-paste pipeline file for each.
rn-doctor is a plain Node CLI with a stable exit-code contract, so it gates a build on any CI
that can run npx. On top of that it speaks each major platform's own inline-feedback
mechanism, so findings land where reviewers already look instead of being buried in a log.
Detection
The platform is detected from the environment. Nothing to configure in the common case.
| Platform | Detected via | Inline feedback |
|---|---|---|
| GitHub Actions | GITHUB_ACTIONS=true | Workflow-command annotations on the PR diff |
| Azure Pipelines | TF_BUILD=True | ##vso[task.logissue] entries in the run's Issues pane |
| GitLab CI | GITLAB_CI=true | Code Quality report artifact (see below) |
| Bitbucket Pipelines | BITBUCKET_BUILD_NUMBER | Code Insights report + PR annotations |
Override detection with --ci <auto|github|azure|bitbucket|gitlab|none>. --no-annotations
silences inline feedback on every platform; --ci none does the same by selecting no platform.
Everything else - pretty output, --json, --sarif, exit codes - is identical everywhere.
Azure Pipelines
Annotations are emitted automatically; policy errors fail the job through exit code 1.
steps:
- checkout: self
fetchDepth: 0 # --changed-only needs the merge-base with the target branch
- task: UseNode@1
inputs:
version: "22.x"
- script: npx --yes --package react-native-doctor-ci rn-doctor --changed-only --base "origin/$(System.PullRequest.TargetBranchName)"
displayName: rn-doctorAzure has no notice-level issue type, and warnings count toward the run's issue total, so notes and allowlisted findings stay in the pretty log rather than being inflated into warnings. Paths are repo-relative, so run rn-doctor from the repository root.
GitLab CI
GitLab surfaces findings through a Code Quality report artifact. Write it with
--gitlab-codequality <path> and declare it under artifacts: reports: codequality:
rn-doctor:
image: node:22
variables:
GIT_DEPTH: 0
script:
- npx --yes --package react-native-doctor-ci rn-doctor --changed-only --base "origin/$CI_DEFAULT_BRANCH" --gitlab-codequality gl-code-quality-report.json
artifacts:
when: always # upload the report even when the gate fails
reports:
codequality: gl-code-quality-report.json
rules:
- if: $CI_PIPELINE_SOURCE == "merge_request_event"Severities map to major (policy errors), minor (warnings) and info (notes and allowlisted
findings). Each finding's fingerprint is hashed from the rule, package and manifest path - never
the line number or message - so reordering a package.json or rewording a message doesn't make
GitLab treat an old finding as new. Writing the file alone isn't enough: without the artifacts
declaration the merge-request widget stays empty.
Bitbucket Pipelines
A Code Insights report plus per-finding PR annotations are published automatically, through the pipeline's local auth proxy - no token, no setup:
image: node:22
clone:
depth: full
pipelines:
pull-requests:
"**":
- step:
name: rn-doctor
script:
- npx --yes --package react-native-doctor-ci rn-doctor --changed-only --base "origin/$BITBUCKET_PR_DESTINATION_BRANCH"The report is published on clean runs too, so a green check is visible evidence the gate ran. That proxy only exists inside a running pipeline: run the same command locally and rn-doctor prints a warning and carries on. An upload failure never changes the exit code - the policy verdict is always decided locally.
GitHub Actions
Covered in depth on the GitHub Action page: the composite action wraps the same CLI, and annotations plus SARIF upload are the native path there.
Anywhere else
On a CI with no native integration, the exit code is the gate and --json or --sarif is the
record:
npx --yes --package react-native-doctor-ci rn-doctor --json > rn-doctor.jsonExit 0 is clean, 1 means policy errors, 2 means the tool itself failed (bad flags,
unreadable manifest, invalid policy). Many platforms - including Azure DevOps via the SARIF SAST
scans extension - can also ingest the SARIF file directly.