product
Automation Rules
Automation Rules

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 logged

You 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": 60

Approval workflow:

  1. Rule fires → run is created with status pending_approval
  2. A team member reviews and approves or rejects from the run detail view
  3. Approved → action executes; Rejected → run stops
  4. 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
}
SettingDefaultRangeWhat it retries
build_max_attempts20–5Docker image build failures
container_start_max_attempts20–5Container start failures
health_check_max_attempts51–20Odoo 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": 10

Valid 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.

TemplateTriggerActionBest for
Deploy staging on push to mainPush → mainDeploy stagingContinuous integration
Quick-update dev on feature pushPush → feature/*Quick Update devFast inner loop
Deploy staging on PR mergePR merge → mainDeploy stagingReview-gated deploys
Production release on version tagTag push v*Deploy prodVersioned releases
Promote staging to productionTag push release/*PromoteTested build promotion
Refresh staging from productionManualClone + neutralizeFresh data for QA
Refresh UAT (no filestore)ManualClone (fast)~80% faster refresh
Deploy PR to staging for reviewPR openDeploy stagingPR preview deploys
Quick-update staging on PR re-pushPush → PR branchQuick UpdateFast re-test after fixes
Manual production deploy (approval)ManualDeploy prodSafety-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

StatusMeaning
pendingQueued, waiting to be processed
runningAction is executing
completedAction finished successfully
failedAction encountered an unrecoverable error
skippedConditions were not met (shows skip reason)
pending_approvalWaiting for a team member to approve
approvedApproved, action is executing
rejectedA team member rejected the run
approval_expiredApproval 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"