Automation Rules
Automation rules let you define when and what oec.sh should do automatically — deploy staging when code is pushed to main, refresh UAT from production on demand, promote a tested build to production after human approval. Each rule pairs a trigger with an action, plus optional conditions to keep things running safely.
How It Works
A rule watches for a git event or waits to be called manually. When the trigger fires, the rule evaluates its conditions (branch patterns, cooldowns, file filters). If conditions pass — and an approval gate is not blocking — the action executes in the background and the result is logged.
Git push → trigger matches → conditions evaluated → [approval?] → action runs → run loggedYou can see all rules on the Automation tab inside a project. Each rule shows its trigger type, last run status, and the notification channels subscribed to its events.
Triggers
A trigger defines what event starts the rule.
Push (push)
Fires when code is pushed to a branch. Use branch patterns to scope it.
"trigger_config": {
"branch_patterns": ["main", "staging", "release/*"]
}Glob patterns are supported: main matches exactly, feature/* matches any branch starting with feature/, * matches everything.
Pull Request Opened (pr_open)
Fires when a pull request is opened. Useful for spinning up a testing deploy when a developer raises a PR.
"trigger_config": {
"target_branch_patterns": ["main"],
"source_branch_patterns": ["feature/*", "fix/*"]
}Both target_branch_patterns (the branch the PR targets) and source_branch_patterns (the PR's own branch) are optional — omit either to match all.
Pull Request Merged (pr_merge)
Fires when a pull request is merged. Avoids mid-review deploys — code only ships after the PR is approved and merged.
"trigger_config": {
"target_branch_patterns": ["main"]
}Tag Push (tag_push)
Fires when a git tag is pushed. Commonly used for release pipelines.
"trigger_config": {
"tag_pattern": "v*"
}The tag_pattern is a glob: v* matches v1.0.0, v2.3.1, etc. Omit it to fire on any tag.
Manual (manual)
No git event is required. The rule runs when explicitly triggered from the Automation tab or via API. Use this for operations that require a deliberate human decision — staging refreshes, UAT resets, on-demand deploys.
Manual rules can still have an approval gate (see Approval Gates).
Actions
The action is what oec.sh does when a rule fires.
Deploy (deploy)
Performs a full deployment of the target environment from its configured git branch. Rebuilds containers, runs migrations, restarts Odoo.
"action_config": {
"action_type": "deploy",
"target_env_id": "ENV_UUID",
"force": false
}Set force: true to redeploy even if the environment is already on the latest commit.
Quick Update (quick_update)
Runs a lightweight git pull + container restart without rebuilding Docker images. Much faster than a full deploy (~30 seconds vs minutes), useful for code-only changes with no dependency or migration changes.
"action_config": {
"action_type": "quick_update",
"target_env_id": "ENV_UUID"
}Quick Update skips migrations and Docker image rebuilds. Only use it for changes that don't add new Python dependencies or database schema changes.
Promote (promote)
Deploys the exact git SHA and module state from a source environment to a target environment — no rebuild from scratch. The target ends up running precisely what QA tested on the source.
"action_config": {
"action_type": "promote",
"source_env_id": "STAGING_ENV_UUID",
"target_env_id": "PROD_ENV_UUID"
}This is the safest way to move a tested build to production — there are no "build surprises" since the exact same artifact is promoted.
Clone, Neutralize & Deploy (clone_neutralize_deploy)
Clones a source environment's database (and optionally filestore) into a target environment, runs Odoo's native neutralize command to make it safe for non-production use, then deploys. Perfect for keeping staging in sync with production data.
"action_config": {
"action_type": "clone_neutralize_deploy",
"source_env_id": "PROD_ENV_UUID",
"target_env_id": "STAGING_ENV_UUID",
"neutralize": true,
"include_filestore": false,
"git_branch_override": null
}Neutralize disables outgoing emails, payment providers, crons, OAuth, webhooks, and external integrations so the cloned environment cannot accidentally contact real systems.
Set include_filestore: false to skip copying uploaded files — this makes the refresh ~80% faster and is sufficient for most development and QA scenarios.
Use git_branch_override to deploy a different branch after the clone (e.g. deploy develop branch onto the freshly-cloned data).
Neutralize uses Odoo's built-in odoo-bin neutralize command. It handles disabling correctly for all versions (Odoo 16, 17, 18, 19).
Destroy Environment (destroy_env)
Permanently destroys an environment — stops containers, removes database, releases resources. Use with care.
"action_config": {
"action_type": "destroy_env",
"target_env_id": "ENV_UUID"
}This action is irreversible. Always pair it with an approval gate for anything other than ephemeral test environments.
Conditions
Conditions are checked after the trigger fires but before the action runs. If any condition fails, the run is recorded as skipped with a reason.
Branch Patterns
Set in trigger_config.branch_patterns — the rule only fires if the pushed branch matches one of the patterns.
Cooldown
Prevents the rule from firing more than once within a time window.
"conditions": {
"cooldown_minutes": 5
}If the rule last ran less than cooldown_minutes ago, the run is skipped. Set to 0 (default) to allow unlimited frequency.
File Path Filters
Only fire if the commit changed files matching certain patterns — or skip if only excluded paths changed.
"conditions": {
"include_paths": ["requirements.txt", "manifest.json", "*.py"],
"exclude_paths": ["docs/*", "README.md", "*.mdx"]
}include_paths: At least one changed file must match one of these patterns. If none match, the run is skipped.exclude_paths: If all changed files match these patterns, the run is skipped. Useful for ignoring documentation-only commits.
Environment Status Requirement
Only run the action if the target environment is in a particular state.
"conditions": {
"require_env_status": "running"
}Options: "running", "stopped", or null (any status — the default).
Approval Gates
Add a human sign-off step before the action executes. Useful for production deployments where an unreviewed deploy could cause downtime.
"require_approval": true,
"approval_expires_minutes": 60Approval workflow:
- Rule fires → run is created with status
pending_approval - A team member reviews and approves or rejects from the run detail view
- Approved → action executes; Rejected → run stops
- If no action is taken within
approval_expires_minutes, the run expires automatically
Approval windows range from 5 to 1440 minutes (24 hours).
Circuit Breaker
The circuit breaker automatically disables a rule after a run of consecutive failures, preventing a broken rule from hammering your infrastructure.
"circuit_breaker": {
"enabled": true,
"max_consecutive_failures": 3,
"window_minutes": 60
}When max_consecutive_failures is reached, the rule is paused (is_active set to false) and must be manually re-enabled from the Automation tab. Successful runs reset the failure counter.
Recommended settings:
- Development/staging rules:
max_consecutive_failures: 3— allows a few transient failures - Production rules:
max_consecutive_failures: 1— fail fast, get a human involved immediately
Retry Policy
Control how many times individual deployment steps are retried before a run is marked as failed.
"retry_policy": {
"build_max_attempts": 2,
"container_start_max_attempts": 2,
"health_check_max_attempts": 5
}| Setting | Default | Range | What it retries |
|---|---|---|---|
build_max_attempts | 2 | 0–5 | Docker image build failures |
container_start_max_attempts | 2 | 0–5 | Container start failures |
health_check_max_attempts | 5 | 1–20 | Odoo health check failures |
Database migrations are never retried automatically (migration_retry is always false). This prevents double-migration data corruption.
Rule Priority
When multiple rules can fire on the same event, they execute in priority order. Lower numbers run first.
"priority": 10Valid range: 1–9999 (default: 100). Reorder rules from the Automation tab by dragging, or bulk-update priorities via the API.
Templates
The Automation tab includes a template gallery with 10 pre-built rule configurations for common workflows. Templates auto-resolve environment slots by matching environment names — select a template, confirm the environment mappings, and the rule is ready.
| Template | Trigger | Action | Best for |
|---|---|---|---|
| Deploy staging on push to main | Push → main | Deploy staging | Continuous integration |
| Quick-update dev on feature push | Push → feature/* | Quick Update dev | Fast inner loop |
| Deploy staging on PR merge | PR merge → main | Deploy staging | Review-gated deploys |
| Production release on version tag | Tag push v* | Deploy prod | Versioned releases |
| Promote staging to production | Tag push release/* | Promote | Tested build promotion |
| Refresh staging from production | Manual | Clone + neutralize | Fresh data for QA |
| Refresh UAT (no filestore) | Manual | Clone (fast) | ~80% faster refresh |
| Deploy PR to staging for review | PR open | Deploy staging | PR preview deploys |
| Quick-update staging on PR re-push | Push → PR branch | Quick Update | Fast re-test after fixes |
| Manual production deploy (approval) | Manual | Deploy prod | Safety-gated prod deploys |
Run History
Every time a rule fires, a run is created — whether it executed, was skipped, or is waiting for approval.
Go to Automation tab → select a rule → Run History to see per-rule runs, or view all project runs across all rules from the project-level automation log.
Run Statuses
| Status | Meaning |
|---|---|
pending | Queued, waiting to be processed |
running | Action is executing |
completed | Action finished successfully |
failed | Action encountered an unrecoverable error |
skipped | Conditions were not met (shows skip reason) |
pending_approval | Waiting for a team member to approve |
approved | Approved, action is executing |
rejected | A team member rejected the run |
approval_expired | Approval window closed with no response |
What's in a Run
Each run record includes:
- The trigger that fired (event type, branch, commit SHA, actor)
- Start and end time
- Per-step timing breakdown
- Error message for failed runs
- Link to the deployment created by the run (for deploy/promote/quick-update actions)
Notifications
When a rule completes or fails, oec.sh fires automation_rule.completed or automation_rule.failed events. Subscribe to these with an outgoing webhook or email notification channel to alert your team.
The Automation tab shows small indicator pills on each rule row — green for webhooks, blue for email channels — so you can see at a glance which rules have notifications configured.
To set up notifications: go to Settings → Webhooks or Settings → Email Alerts and subscribe to automation_rule.completed and/or automation_rule.failed. You can scope a channel to the specific project if you only want events from one project.
See Notifications for setup instructions.
Permissions
Creating, editing, and deleting automation rules requires the Developer role or higher on the project.
Approving or rejecting pending runs requires the Admin role or higher.
Viewing rules and run history is available to all project members.
API
All automation rule operations are available via the REST API for CI/CD integration and programmatic management.
curl "https://api.oec.sh/api/v1/projects/PROJECT_ID/automation-rules" \
-H "Authorization: Bearer YOUR_TOKEN"