Trigger Conditions
Filter GitHub events with dot-notation field matching, operators, and contributor whitelisting.
Trigger conditions let you control exactly which GitHub events fire a workflow. Every condition is evaluated against the raw webhook payload using dot-notation field paths and comparison operators. When a trigger has multiple conditions, all must match (AND logic) for the trigger to fire.
Anatomy of a Condition
A condition has three parts:
| Part | Description | Example |
|---|---|---|
| field | Dot-notation path into the webhook payload | sender.login |
| operator | Comparison to perform | eq, in, not_empty |
| value | Expected value (omitted for unary operators) | alice |
Operators
| Operator | Description | Value | Example |
|---|---|---|---|
eq | Equals (exact match) | Required | sender.type eq User |
neq | Not equals | Required | action neq closed |
in | Value is in a comma-separated list | Required | sender.login in alice,bob |
not_in | Value is not in a list | Required | sender.login not_in dependabot[bot] |
contains | Field value contains substring | Required | comment.body contains /syn |
not_empty | Field exists and is truthy | None | check_run.pull_requests not_empty |
is_empty | Field is missing or resolves to a falsy value | None | pull_request.body is_empty |
is_empty uses Python truthiness: None, "", 0, false, and [] all
match. If you need to check specifically for null or missing fields, use
is_empty and be aware that other falsy values will also pass.
Boolean coercion is automatic -- when a condition value is supplied as a string
(e.g. "false" from a CLI flag or API request), it is converted to a native
boolean before comparison. This means pull_request.draft eq false works
whether the condition value was provided as a boolean or a string. Payload
values are compared as-is and are not coerced.
Dot-Notation Field Paths
Fields use dot notation to traverse nested objects in the GitHub webhook payload. Array indexing is also supported:
sender.login → payload["sender"]["login"]
review.user.login → payload["review"]["user"]["login"]
pull_request.head.ref → payload["pull_request"]["head"]["ref"]
check_run.pull_requests[0].number → first PR's numberIf any segment in the path is missing, the resolved value is None (no
exception is raised) and operators then evaluate that None value according to
their normal semantics. For example, is_empty passes for None while eq
does not.
Common Webhook Payload Fields
GitHub webhook payloads vary by event type. Here are the most commonly used fields for conditions:
Sender (available on all events)
| Field | Description | Example values |
|---|---|---|
sender.login | GitHub username of the actor | alice, dependabot[bot] |
sender.type | Account type | User, Bot, Organization |
Pull Request events
| Field | Description |
|---|---|
action | opened, synchronize, closed, reopened |
pull_request.draft | true / false |
pull_request.head.ref | Source branch name |
pull_request.base.ref | Target branch name |
pull_request.number | PR number |
pull_request.user.login | PR author |
Pull Request Review events
| Field | Description |
|---|---|
action | submitted, edited, dismissed |
review.state | approved, changes_requested, commented |
review.user.login | Reviewer username |
review.body | Review comment text |
Check Run events
| Field | Description |
|---|---|
action | created, completed, rerequested |
check_run.conclusion | success, failure, cancelled, timed_out |
check_run.name | Check name (e.g. CI / test) |
check_run.pull_requests | Array of associated PRs |
Issue Comment events
| Field | Description |
|---|---|
action | created, edited, deleted |
comment.body | Comment text |
comment.user.login | Comment author |
issue.pull_request | Present (truthy) if the comment is on a PR |
CLI Usage
Conditions are passed with the --condition / -c flag when registering a
trigger. The basic syntax is field=value which uses the eq operator.
The -c flag only supports field=value syntax (always the eq operator).
For advanced operators like in, contains, not_empty, etc., use the API
directly or built-in presets.
syn triggers register \
--repo owner/my-repo \
--event check_run.completed \
--workflow self-heal-pr \
-c "check_run.conclusion=failure"Multiple -c flags combine with AND logic -- all must match:
syn triggers register \
--repo owner/my-repo \
--event pull_request_review.submitted \
--workflow self-heal-pr \
-c "review.state=changes_requested" \
-c "pull_request.draft=false"Security: Contributor Whitelisting
Conditions are the primary mechanism for restricting which users can trigger workflows. This is important because trigger rules fire automatically from external events -- without filtering, any GitHub user who opens a PR or leaves a comment could trigger an expensive agent execution.
Whitelist Specific Contributors
Only fire for known, trusted contributors:
syn triggers register \
--repo owner/my-repo \
--event pull_request.opened \
--workflow pr-review-v1 \
-c "sender.login=alice"To allow multiple users, use the API directly with the in operator:
{
"conditions": [
{ "field": "sender.login", "operator": "in", "value": ["alice", "bob", "charlie"] }
]
}Exclude Bots
Prevent bot accounts from triggering workflows:
syn triggers register \
--repo owner/my-repo \
--event pull_request.opened \
--workflow pr-review-v1 \
-c "sender.type=User"This filters out dependabot[bot], renovate[bot], GitHub Actions, and any
other non-human sender.
Filter by Branch
Only trigger on PRs targeting a specific branch:
syn triggers register \
--repo owner/my-repo \
--event pull_request.opened \
--workflow pr-review-v1 \
-c "pull_request.base.ref=main"Skip Draft PRs
Avoid wasting agent time on work-in-progress:
syn triggers register \
--repo owner/my-repo \
--event pull_request.opened \
--workflow pr-review-v1 \
-c "pull_request.draft=false"Built-in Presets
Syntropic137 ships with preset trigger configurations for common patterns. These include conditions by default:
Self-Healing
Automatically fixes CI failures on pull requests.
- Event:
check_run.completed - Conditions:
check_run.conclusion eq failureANDcheck_run.pull_requests not_empty
syn triggers enable self-healing --repo owner/my-repoReview Fix
Responds to review comments requesting changes on PRs.
- Event:
pull_request_review.submitted - Conditions:
review.state in changes_requested,commentedANDpull_request.draft eq false
syn triggers enable review-fix --repo owner/my-repoComment Command
Dispatches a workflow when /syn appears in a PR comment.
- Event:
issue_comment.created - Conditions:
issue.pull_request not_empty(only PR comments) ANDcomment.body contains /syn
syn triggers enable comment-command --repo owner/my-repoHow Conditions Combine
All conditions on a trigger are evaluated with AND logic. Every condition must pass for the trigger to fire. There is no OR support within a single trigger -- if you need OR behavior, create separate triggers for each case.
Condition 1: sender.type eq User ← must match
Condition 2: pull_request.draft eq false ← must match
Condition 3: pull_request.base.ref eq main ← must match
─────────────
All three must passCombining with Safety Limits
Conditions work alongside the trigger safety limits (daily limit, cooldown, budget). The evaluation order is:
- Event type match -- does the webhook event match the trigger's event?
- Condition evaluation -- do all conditions pass against the payload?
- Safety limits -- has the trigger exceeded its daily limit, cooldown, or budget?
Only if all three gates pass does the trigger fire a workflow execution.
Syntropic137 Docs v0.25.4 · Last updated March 2026