Scheduled, watch & webhook triggers
Run a lane automatically on a cron schedule, when files change, or from a signed webhook — and watch runs flow through the run queue. Triggers fire while AppRelay is open.
Last updated 2026-07-25
Triggers run a lane automatically so you don't have to click Run yourself. A trigger pairs one of your lanes with an event — a clock, a file change, or an incoming webhook — and an action to take when it fires. Open them from the Triggers tab in the sidebar.
What a trigger does
Every trigger names one lane and one action to take on it:
- Build
- Run the lane's build recipe.
- Run
- Run the lane's run recipe (e.g. launch on a simulator).
- Ship
- Build, then publish — to a specific distribution channel, or to all of the lane's channels.
The event only selects the lane and action you configured in advance. A trigger never carries a command of its own, so an incoming webhook or a file change can't make AppRelay run anything you didn't already set up.
The three kinds
Schedule
Fire on a clock, using a standard 5-field cron expression (minute hour day-of-month month day-of-week). Schedules are evaluated locally — there's no external scheduling service. Pick a preset (Every 15 minutes, Hourly, Daily at 9am, Weekdays at 9am, Weekly) or write your own; the editor validates the expression and previews the next fire time.
| Expression | Fires |
|---|---|
0 9 * * * | Every day at 9:00am |
0 9 * * 1-5 | Weekdays at 9:00am |
*/15 * * * * | Every 15 minutes |
Running when AppRelay is closed
By default a schedule only fires while AppRelay is open. Turn on Run schedules when AppRelay is closed — the toggle appears on the Triggers tab once you have a schedule — to install a small per-user background helper that fires your scheduled runs even when the app isn't running. On macOS that's a launchd agent in ~/Library/LaunchAgents; on Windows it's a Task Scheduler task. Either way it needs no administrator password, and turning the toggle off removes it.
- Catches up on wake. If a scheduled time passes while your computer is asleep, the run fires the moment it wakes — a nightly build you'd otherwise miss still runs when you open the lid in the morning.
- It won't power on a sleeping machine by itself. The helper runs while the computer is awake, or as it wakes — it doesn't wake it at 3am. For that, schedule a system wake at the OS level (
pmseton macOS, a wake timer on Windows) or use external CI that calls an AppRelay webhook. - Same guardrails. A background run goes through the exact same path as clicking Run — including the explicit opt-in a schedule needs before it may ship to an irreversible channel — so nothing publishes silently, and it can still alert you on failure (see below). Automation is part of AppRelay Studio.
Watch
Fire when files change. You give it one or more repo-relative paths to watch (e.g. src, package.json); when something under them changes, the trigger fires. A configurable debounce (default 1 second) coalesces a burst of saves into a single run.
.git/, build/, .build/, DerivedData/, node_modules/, .gradle/, Pods/, and similar, so a build writing into your working tree won't kick off an endless loop.Webhook
Fire from an outside system — your CI, a Git host, a deploy hook. AppRelay gives each webhook trigger a URL of the form /webhook/<id>, served by the same local companion server used by AppRelay Mobile. The URL and a copy button appear on the trigger once you save it.
- Signed requests only. The sender signs the raw request body with HMAC-SHA256 and sends the digest in an
X-Hub-Signature-256: sha256=<hex>header. The shared secret is stored in your operating system's credential store — the Keychain on macOS, an encrypted vault on Windows — never in the trigger file. Unsigned or wrongly-signed requests get a401, and repeated bad signatures from one address are rate-limited. - Optional ref filter. You can restrict a webhook to a single git ref (e.g.
refs/heads/main) so a push to any other branch is ignored.
apprelay serve from a terminal.From the command line
Triggers and run history are fully scriptable through the built-in apprelay CLI, so you can drive AppRelay from inside CI, not just beside it:
| Command | Does |
|---|---|
apprelay trigger list | List triggers (JSON). |
apprelay trigger run <id> | Fire a trigger now (id or unique prefix). |
apprelay trigger add / rm | Create or delete a trigger (add --env <name> to run it against a deployment environment). |
apprelay runs | Recent run records (JSON). |
apprelay serve | Headless host: run schedules/watches and receive webhooks with no GUI. |
Adding a trigger
- Open the Triggers tab and choose Add Trigger.
- Pick the lane and the action (Build, Run, or Ship — and which channel, for Ship).
- Choose the kind — Schedule, Watch, or Webhook — and fill in its details (a cron expression, the paths to watch, or the signing secret and optional ref).
- Save. Use the toggle to enable or disable a trigger without deleting it, and Run now to fire it once by hand.
The run queue
Triggers, the desktop Run button, the phone, and the CLI can all ask for runs at once. AppRelay funnels them through a single run queue so they don't collide:
- One at a time per working directory. A second run against the same folder waits for the first to finish — you never get two builds writing the same tree.
- Several at once across folders. Runs in different working directories proceed in parallel, up to a small concurrency cap (3 by default) so parallel Xcode/Gradle builds don't thrash the machine.
- Visible and cancelable. When anything is queued, a run queue bar appears at the bottom of the window listing active and waiting runs, each with a cancel button.
Failure notifications
Automation you can't trust to tell you when it breaks isn't much use — so AppRelay can alert you when a run finishes. Set it up in Settings → Notifications & Alerts.
- Desktop notifications. A native notification when a run fails (on by default) — and, if you want, when one succeeds too. It names the project, lane, source, and outcome.
- A push to your phone. If you've paired the mobile companion, a finished run can push a notification to it — even when the app is closed — that opens straight to the run. It carries the same run details and no code or secrets (see Security & privacy).
- Slack, Discord, or any webhook. Optionally POST the same details to a Slack or Discord incoming webhook, or a plain URL, on failures only or on every run. The webhook URL is kept in your operating system's credential store, never in the settings file, and the sink only ever sends — it can't run anything.
Notifications cover every run, but they matter most for unattended ones: pair them with schedules (and with running while closed, above) so a 3am failure reaches you instead of sitting silent until morning.
Commit status on your pull requests
When a webhook (or schedule) build runs, AppRelay can report its outcome back to your git host as a commit status, so the pull request that triggered it turns green or red. Turn it on per project in Project Settings → CI Status.
- GitHub and GitLab, including Enterprise and self-managed instances (set the API base). Click Detect from git remote to auto-fill the provider and
owner/repofrom yourorigin. - Pending → success/failure. AppRelay posts a pending status when the build starts and success or failure when it finishes, on the commit checked out (HEAD) at run start — so a build that must report the pushed commit should check it out first.
- Token in the credential store. The API token (GitHub
repo:statusscope, or a GitLabapitoken) is stored in your operating system's credential store, never in the project file. You choose which lanes report, and only trigger runs report — never a manual desktop build.
Where triggers live
Triggers are machine-local. They're saved on this computer (in AppRelay's app-data folder), survive quitting and relaunching, and re-arm — catching up any run missed while the machine slept — on wake. They are deliberately not part of a .relay archive — schedules, watched paths, and webhook URLs are specific to one machine, so importing a project elsewhere doesn't carry its triggers along. Every fire is recorded in run history with its source (for example trigger:schedule).
Next steps
- Run history, deployments & rollback — see what your triggers did
- Lanes, toolchains & version sources — what a trigger runs
- The Relay Monitor & AppRelay Mobile — the companion server webhooks ride on