Skip to content

Workflow

This is the GitHub Actions layer, not warden.toml. warden.toml controls which skills run and how findings are reported. The workflow controls when GitHub starts Warden, which credentials are available, and which action inputs are passed.

warden init generates a split analyze/report starter workflow. Add a GitHub App token step immediately before reporting when you want branded comments.

.github/workflows/warden.yml
name: Warden
permissions:
contents: write
pull-requests: write
checks: write
on:
pull_request:
types: [opened, synchronize, reopened, labeled]
env:
WARDEN_MODEL: ${{ secrets.WARDEN_MODEL }}
WARDEN_OPENAI_API_KEY: ${{ secrets.WARDEN_OPENAI_API_KEY }}
WARDEN_ANTHROPIC_API_KEY: ${{ secrets.WARDEN_ANTHROPIC_API_KEY }}
jobs:
warden:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
ref: ${{ github.event.pull_request.head.sha }}
- name: Analyze
id: warden-analyze
uses: getsentry/warden@v0
with:
mode: analyze
- name: Report
uses: getsentry/warden@v0
with:
mode: report
findings-file: ${{ steps.warden-analyze.outputs.findings-file }}

Put the workflow file in your org .github repository to run Warden everywhere with one mandatory workflow definition. Add the second checkout when you want a shared base warden.toml.

.github/workflows/warden.yml
name: Warden
permissions:
contents: write
pull-requests: write
checks: write
on:
pull_request:
types: [opened, synchronize, reopened, labeled]
env:
WARDEN_MODEL: ${{ secrets.WARDEN_MODEL }}
WARDEN_OPENAI_API_KEY: ${{ secrets.WARDEN_OPENAI_API_KEY }}
WARDEN_ANTHROPIC_API_KEY: ${{ secrets.WARDEN_ANTHROPIC_API_KEY }}
jobs:
warden:
runs-on: ubuntu-latest
steps:
- name: Checkout target repository
uses: actions/checkout@v4
with:
ref: ${{ github.event.pull_request.head.sha }}
- name: Checkout org GitHub repo
uses: actions/checkout@v4
with:
repository: ${{ github.repository_owner }}/.github
path: .warden-org
- name: Analyze
id: warden-analyze
uses: getsentry/warden@v0
with:
mode: analyze
base-config-path: .warden-org/warden.toml
base-skill-root: .warden-org
- name: Report
uses: getsentry/warden@v0
with:
mode: report
findings-file: ${{ steps.warden-analyze.outputs.findings-file }}
base-config-path: .warden-org/warden.toml
base-skill-root: .warden-org

The first checkout is the repository being reviewed. The second checkout provides the org-wide base config and local shared skills.

If the target repo also has a root warden.toml, Warden loads it in the same run. Repo-local config can add skills and repo-local defaults, but it does not weaken org-enforced base skills.

The recommended workflow runs analysis and reporting as separate action steps. This keeps long analysis runs from holding GitHub write credentials. GitHub App installation tokens expire after 1 hour, and a long analysis run can outlive a token that was created before Warden starts.

Use mode: analyze first. It runs skills and writes a structured findings file without creating checks, posting comments, or resolving stale comments. Then create the GitHub App token and run mode: report against that findings file. Split modes are only supported for pull request workflows. Report mode reloads warden.toml, applies the report step’s current reporting settings, creates completed checks, and posts comments.

.github/workflows/warden.yml
jobs:
warden:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
ref: ${{ github.event.pull_request.head.sha }}
- name: Analyze
id: warden-analyze
uses: getsentry/warden@v0
with:
mode: analyze
- name: Create Warden app token
id: warden-token
uses: actions/create-github-app-token@v3
with:
app-id: ${{ secrets.WARDEN_APP_ID }}
private-key: ${{ secrets.WARDEN_PRIVATE_KEY }}
- name: Report
uses: getsentry/warden@v0
with:
mode: report
findings-file: ${{ steps.warden-analyze.outputs.findings-file }}
github-token: ${{ steps.warden-token.outputs.token }}

If you use config-path, base-config-path, base-skill-root, or action-level reporting inputs such as fail-on, report-on, request-changes, fail-check, or max-findings, pass the intended values to the report step. Report mode reads config again from the checkout and applies the report step’s inputs; the findings file does not store a copy of warden.toml.

By default, every push re-reviews every hunk in the pull request. Set incremental = true in warden.toml to have a skill review only hunks that changed since its last clean run on the same pull request. Like failCheck, it can be set in [defaults], per skill, or per trigger, so each skill picks its own mode.

warden.toml
[defaults]
incremental = true
incrementalApp = "github-actions"
[[skills]]
name = "code-review"
[[skills]]
name = "security-review"
# Re-review every hunk on every push.
incremental = false

Set incrementalApp to the slug of the GitHub App that writes Warden’s checks: github-actions when the report or run step uses the default GITHUB_TOKEN, or your app’s slug when it uses a GitHub App token. Warden only trusts baselines from that app, so look-alike checks from other apps cannot make it skip hunks. Without incrementalApp, Warden warns and reviews the full PR. With a base config, repo-defined skills inherit the base incrementalApp, and the repo config cannot change the mode of skills the base config defines.

The analysis step needs checks: read:

permissions:
contents: read
pull-requests: read
checks: read

When a skill check completes without failing and its findings have been posted to the pull request, Warden tags it with a fingerprint of the skill prompt, Warden version, and the settings that affect analysis and reporting. On the next push, Warden looks for the newest earlier commit on the pull request with a matching check, rebuilds the pull request diff at that commit, and skips any current hunk with the same file and content. Line numbers are ignored, so merging the base branch or rebasing does not re-review code the pull request did not change. Skipped hunks do not count against scan limits.

Warden falls back to a full review when:

  • no earlier commit has a matching check, for example on the first push, after a force push drops the old commits, after a config or skill change, or after the pull request is retargeted to another base branch
  • the earlier run failed its check, had hunk failures, skipped files because of scan limits or because they looked generated, or was cut short by a provider failure
  • some of the earlier run’s findings never reached the pull request, for example because the review failed to post, the head moved first, or findings were over maxFindings
  • the checks or the earlier diff cannot be read

Comments on skipped hunks stay open. Warden does not run fix evaluation or the stale-comment pass on them until their hunk changes, and it does not dismiss an earlier blocking review while any of them are unresolved. GitHub cannot place an outdated comment on the current diff, so Warden treats it as being on a skipped hunk whenever its skill skipped any hunk in that file. A skipped hunk is not re-checked against changes elsewhere in the pull request.

Baselines come from per-skill check runs, so incremental review has no effect with post-checks: false. The CLI ignores incremental.

If Warden is a required status check, require the core warden check or a per-skill check like warden: security-review.

Keep workflow-level paths and paths-ignore filters off required Warden workflows. Let Warden start, then let warden.toml decide which triggers match. For each configured pull request trigger, Warden creates a check run. Triggers that do not actually run for the current event complete as neutral.

Do not set post-checks: false on a repo where warden or a per-skill check is a required status check — Warden stops creating that check entirely, so it never reports and the required check blocks every PR indefinitely.

moderun | analyze | report
Action mode. Default: run for compatibility. New pull request workflows should use analyze and report to split analysis from GitHub write reporting.
findings-filepath
Structured findings file to read in mode: report. Usually the findings-file output from the analyze step.
github-tokenstring
GitHub token for posting comments. Default: GITHUB_TOKEN.
anthropic-api-keystring
Anthropic API key input. Prefer WARDEN_ANTHROPIC_API_KEY env for new workflows.
base-config-pathoptional
Path to a base warden.toml loaded before repo config.
base-skill-rootoptional
Repo root containing local shared skills used by the base config.
config-pathstring
Path to the repo-local config. Default: warden.toml.
fail-onseverity
Minimum severity to fail the check.
report-onseverity
Minimum severity to post comments.
max-findingsnumber
Maximum findings to report. Default: 50.
request-changesboolean
Whether to request changes on PR reviews. Default: false.
fail-checkboolean
Whether to fail the check run. Default: false.
post-checksboolean
Whether to create/update the core warden check and per-skill checks. Set to false to post only PR review comments. Default: true. See Required Status Checks before disabling this on a repo with a required Warden check.
parallelnumber
Maximum concurrent matched trigger executions and hunk analyses unless runner.concurrency is set. Default: 5.