Create Your First Rule
Every TinyOps rule follows the same pattern: trigger → condition → action. Let’s build one from scratch.
Choose your approach
Use a template
Navigate to Rules → Create Rule → Templates. Pick a template that matches your use case:
| Template | What it does |
|---|---|
| Stale PR alert | Notify Slack when PRs are open too long |
| Vercel cost spike | Alert when monthly costs exceed a threshold |
| Large PR warning | Comment on PRs with 500+ lines changed |
| Weekly repo summary | Email a weekly digest of open PRs/issues |
| Deploy rollback | Auto-rollback Vercel on failed CI |
| Release notification | Slack message on new releases |
Click a template, customize the values, and save.
Building a rule step by step
Let’s create a “Stale PR alert” rule that checks every weekday morning for PRs older than 3 days and sends a Slack notification.
Define the trigger
The trigger determines when the rule runs. For a daily check, use a cron schedule:
name: stale-pr-alert
trigger:
type: schedule
cron: "0 9 * * 1-5"This runs at 9:00 AM UTC, Monday through Friday. See the full triggers reference for all trigger types.
Add a condition
The condition determines whether the rule should act. We check if any PR has been open longer than 3 days:
condition:
provider: github
check: pr.age
operator: gt
value: 3The provider field tells TinyOps which integration to query. The check field specifies what to measure. See all available conditions and operators.
Conditions are optional. If you skip the condition, the action fires every time the trigger activates.
Define the action
The action determines what happens when the condition is met:
action:
provider: slack
method: send_message
params:
channel: "#engineering"
message: "Stale PR alert: {{condition.result}} days old"The {{condition.result}} template variable is replaced with the actual value from the condition check. See all template variables.
Complete rule
Here’s the full rule:
name: stale-pr-alert
trigger:
type: schedule
cron: "0 9 * * 1-5"
condition:
provider: github
check: pr.age
operator: gt
value: 3
action:
provider: slack
method: send_message
params:
channel: "#engineering"
message: "Stale PR alert: {{condition.result}} days old"Test it
Click Test Run to execute the rule against live data. You’ll see:
- Whether the trigger would fire
- The condition result (the actual PR age value)
- What action would be taken
Choose a mode
TinyOps rules have three modes:
| Mode | Behavior |
|---|---|
| Disabled | Rule does nothing |
| Shadow | Rule evaluates but does not execute actions. Builds confidence score over time. |
| Live | Rule evaluates and executes actions for real |
Start in Shadow mode to verify behavior, then promote to Live when ready.
More examples
name: vercel-cost-spike
trigger:
type: schedule
cron: "0 */6 * * *"
condition:
provider: vercel
check: billing.mtd
operator: gt
value: 50
action:
provider: slack
method: send_message
params:
channel: "#engineering"
message: "Vercel cost alert: ${{condition.result}} MTD"name: large-pr-warning
trigger:
type: webhook
source: github
event: github.pull_request.opened
condition:
provider: github
check: pr.lines_changed
operator: gt
value: 500
action:
provider: github
method: pr_comment
params:
body: "This PR has {{condition.result}} lines changed. Consider splitting it."What’s next
- YAML syntax reference for the complete schema
- Integration guides for provider-specific checks and actions
- Simulation mode to learn about shadow mode and confidence scoring