Use the Codex Plugin Doctor GitHub Action when a plugin repository should fail pull requests before broken packaging, unsafe MCP config, or runtime protocol issues reach users.
The action installs codex-plugin-doctor from npm, then runs the same CLI used locally.
Remote MCP checks are off by default. Set runtime: "true" and give explicit network consent only for endpoints you trust. Use allow-local-network: "true" for loopback endpoints only (localhost, 127.0.0.0/8, or ::1). Private, link-local, multicast, unspecified, reserved, and NAT64 ranges remain blocked.
- uses: ./
with:
path: .
runtime: "true"
allow-network: "true"
allow-local-network: "true" # Remove for public endpoints.
require-remote-reliability: "true" # Fails unless every attempted reliability scorecard passes.The Action transfers these boolean inputs through environment-backed shell variables and a Bash argument array. require-remote-reliability is a strict result gate, not network consent: it fails unless every attempted remote reliability scorecard passes. Local-only runs are unaffected. Keep allow-session-lifecycle: "false" (the default) unless the workflow explicitly authorizes one bounded, state-changing session DELETE after a valid session is issued. Remote probes redact diagnostics and retain no raw remote content; see Remote MCP Readiness and Remote MCP Transport Reliability for SSRF, OAuth metadata-discovery, SSE, and lifecycle boundaries.
Use local Registry metadata gating when the repository contains a server.json intended for publication:
- uses: Esquetta/CodexPluginDoctor@v1.57.0
with:
version: "1.57.0"
path: .
registry-metadata: ./server.json
require-registry-readiness: "true"The Action writes mcp-registry-readiness.json and exposes registry-report-path. This path is checked locally; the Action does not inspect the live Registry and does not grant network access. require-registry-readiness requires registry-metadata and blocks warnings as well as failures.
name: Validate Codex plugin
on:
pull_request:
push:
branches:
- main
jobs:
doctor:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
- uses: Esquetta/CodexPluginDoctor@v1.57.0
with:
version: "1.57.0"
path: .
runtime: "true"
policy: codex-publish
corpus: "true"
contract: "true"
upload-artifact: "true"
artifact-name: codex-plugin-doctor-reports
output-dir: codex-plugin-doctor-reportsBy default the action writes:
codex-plugin-doctor-summary.mdcodex-plugin-doctor-report.json
The Markdown report is appended to the GitHub Actions step summary, and the output directory is uploaded as a workflow artifact. The action preserves the real validation exit code after report generation, so failed checks still fail the job after artifacts are available.
Set corpus: "true" to add validation-corpus.json and contract: "true" to add output-contract.json to the same artifact directory. These reports are useful when a release workflow needs bundled validation evidence and the current public JSON contract without adding separate CLI steps.
Every action run also writes codex-plugin-doctor-action-manifest.json. The manifest records the installed CLI version, final action status, report directory, artifact name, target mode, and enabled report paths so follow-up workflow steps can discover generated files without hard-coded path assumptions.
Use SARIF when repository security tooling should ingest validation findings.
- uses: Esquetta/CodexPluginDoctor@v1.57.0
with:
version: "1.57.0"
path: .
sarif: "true"The action writes codex-plugin-doctor.sarif into output-dir. Uploading it to GitHub Code Scanning should be handled by the consuming workflow after the action runs.
Use artifact and summary controls when the workflow needs custom retention or wants to disable generated report uploads.
- uses: Esquetta/CodexPluginDoctor@v1.57.0
with:
version: "1.57.0"
path: .
output-dir: doctor-ci-reports
artifact-name: codex-plugin-doctor-reports
upload-artifact: "true"
step-summary: "true"
json: "true"
markdown: "true"
sarif: "true"
corpus: "true"
contract: "true"Set upload-artifact: "false" when a consuming workflow wants to upload files itself. Set step-summary: "false" when the Markdown report should only be retained as an artifact.
The action also exposes these workflow outputs for follow-up steps:
statusreport-dirsummary-pathjson-pathsarif-pathvalidation-corpus-pathcorpus-metrics-pathcorpus-metrics-diff-pathoutput-contract-pathaction-manifest-pathregistry-report-pathreview-bundle-pathreview-bundle-verification-path
Use review bundle artifacts when a pull request or release workflow should preserve signed runtime approval, runtime policy, attestation, and release evidence handoff files.
- uses: Esquetta/CodexPluginDoctor@v1.57.0
env:
CODEX_PLUGIN_DOCTOR_SIGNING_KEY: ${{ secrets.CODEX_PLUGIN_DOCTOR_SIGNING_KEY }}
with:
version: "1.57.0"
path: .
review-bundle: "true"
review-bundle-verify: "true"
signing-key-env: CODEX_PLUGIN_DOCTOR_SIGNING_KEY
review-bundle-allow-untagged: "true"The action writes the bundle under output-dir/review-bundle by default and includes it in the uploaded artifact directory. review-bundle-verify: "true" also writes review-bundle-verification.json.
review-bundle-allow-untagged defaults to "true" because pull request and branch workflows are usually not running on exact release tags. Set it to "false" in strict release jobs that should require tagged release evidence.
The CLI can produce badge output for release notes, README automation, or a static artifact served by the consuming repository.
- name: Generate Doctor badge JSON
run: codex-plugin-doctor check . --badge-json --output doctor-badge.json
- name: Generate Doctor badge Markdown
run: codex-plugin-doctor check . --badge-markdown --output doctor-badge.md--badge-json follows the Shields endpoint schema with schemaVersion, label, message, and color. --badge-markdown emits a static shields.io Markdown image link.
Use a private corpus metrics manifest to measure reviewed precision, recall, and false-positive share in CI. The action writes only the public-safe metrics report into its artifact directory; snapshots, manifest contents, local paths, and review notes are not copied.
- uses: Esquetta/CodexPluginDoctor@v1.57.0
with:
version: "1.57.0"
path: .
corpus-metrics-manifest: ../private-corpus/metrics.jsonThis writes corpus-metrics.json. To compare the result with a retained report and fail the job on regression:
- uses: Esquetta/CodexPluginDoctor@v1.57.0
with:
version: "1.57.0"
path: .
corpus-metrics-manifest: ../private-corpus/metrics.json
corpus-metrics-baseline: .doctor-baselines/corpus-metrics.json
corpus-metrics-fail-on-regression: "true"The comparison writes corpus-metrics-diff.json. Reports must have the same corpusDigest; changed corpus composition is rejected as non-comparable rather than reported as a validator regression. corpus-metrics-fail-on-regression requires both a manifest and baseline.
Use history output when a workflow should preserve validation trend data between runs.
- name: Append Doctor history
run: codex-plugin-doctor check . --history validation-history.jsonl
- name: Summarize Doctor history
run: codex-plugin-doctor history validation-history.jsonl
- name: Fail on Doctor regression
run: codex-plugin-doctor history validation-history.jsonl --fail-on-regressionThe history file is newline-delimited JSON. Store it as an artifact, cache, or repository-managed file depending on the consuming workflow's retention model. Use codex-plugin-doctor history validation-history.jsonl --json when another CI step needs machine-readable latest, previous, delta, and regression fields.
The composite action can also append history directly:
- uses: Esquetta/CodexPluginDoctor@v1.57.0
with:
version: "1.57.0"
path: .
runtime: "true"
history: validation-history.jsonlUse profiles when a consuming workflow needs a named validation policy instead of custom flags.
- name: Publish-grade Doctor check
run: codex-plugin-doctor check . --profile publish --json --output doctor-report.jsonci keeps the default behavior, strict fails on warnings, and publish fails on warnings while enabling runtime probing by default.
The composite action can pass profiles directly:
- uses: Esquetta/CodexPluginDoctor@v1.57.0
with:
version: "1.57.0"
path: .
profile: publishUse policy presets when a workflow should apply one of the opinionated release gates without adding a local .codex-doctor.json.
- uses: Esquetta/CodexPluginDoctor@v1.57.0
with:
version: "1.57.0"
path: .
policy: codex-publishSupported policy values are codex-publish, mcp-strict, and security. The CLI validates unsupported values and fails the workflow with a clear error.
Use installed-cache mode only in environments where Codex plugins are already available on the runner.
- uses: Esquetta/CodexPluginDoctor@v1.57.0
with:
version: "1.57.0"
installed: "true"
filter: github
runtime: "false"Pin both the action ref and npm package version for reproducible CI:
- uses: Esquetta/CodexPluginDoctor@v1.57.0
with:
version: "1.57.0"Use version: "latest" only when the consuming repository intentionally wants automatic CLI upgrades.