Started executing automations (in development)#28120
Conversation
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Run ID: ⛔ Files ignored due to path filters (1)
📒 Files selected for processing (12)
✅ Files skipped from review due to trivial changes (1)
🚧 Files skipped from review as they are similar to previous changes (11)
WalkthroughThis PR implements an automation step polling and execution system: it defines step types and constants, extends the repository API for locking/transition operations, implements those operations in the fake-database repository (locking, finish+enqueue, retry, terminal), provides a poll runner that fetches/locks steps, executes wait and send_email steps with retries and terminal logic, refactors the member-welcome-emails service to send automation emails, wires automationsApi into the service, and adds unit and e2e tests covering these flows. Possibly related PRs
Suggested labels
Suggested reviewers
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
| Command | Status | Duration | Result |
|---|---|---|---|
nx run ghost:build:tsc |
❌ Failed | 5s | View ↗ |
nx run-many -t lint -p ghost |
❌ Failed | 11s | View ↗ |
nx run ghost:test:ci:integration |
✅ Succeeded | 1m 57s | View ↗ |
nx run ghost:test:ci:e2e |
✅ Succeeded | 7m 53s | View ↗ |
nx run ghost:test:ci:legacy |
✅ Succeeded | 3m 3s | View ↗ |
nx run-many -t test:unit -p ghost |
✅ Succeeded | 31s | View ↗ |
nx run-many --target=build --projects=@tryghost... |
✅ Succeeded | <1s | View ↗ |
☁️ Nx Cloud last updated this comment at 2026-05-25 21:05:13 UTC
f349d29 to
595810d
Compare
towards https://linear.app/ghost/issue/NY-1286 ref #28120 We can use `export foo` instead of `module.exports`. This change should have no user impact, but makes an upcoming change easier.
towards https://linear.app/ghost/issue/NY-1286 ref #28120 **I recommend [reviewing this with whitespace changes disabled](https://github.com/TryGhost/Ghost/pull/28263/changes?w=1).** When a member signs up, we should trigger an automation run and possibly insert a new row. Nothing happens yet when these rows are inserted. That will be done in a future change. This is development-only; triggering is a no-op in production. I tested this by: - Adding automated tests. - Verified that the old member welcome email is still sent on member signup. - Creating this temporary endpoint and verifying that the results looked expected after member signup: ```js router.get('/automations/database-dump', (_req, res) => { const db = getTemporaryFakeAutomationsDatabase(); res.json({ automation_runs: db.prepare('SELECT * FROM automation_runs').all(), automation_run_steps: db.prepare('SELECT * FROM automation_run_steps').all() }); }); ```
towards https://linear.app/ghost/issue/NY-1286 ref #28120 This change should have no impact on functionality. We have [a lint rule that limits the length of `index.js` files][0]. In [an upcoming change][1], the automations service will cross that limit. This patch moves it into a separate file. Doing so also makes it a little easier to test. [0]: https://github.com/TryGhost/eslint-plugin-ghost/blob/22d154a8e3807e4e30219fb8449e7aa9b90a110b/lib/config/node.js#L32-L37 [1]: #28120
towards https://linear.app/ghost/issue/NY-1286 ref #28120 This change should have no impact on functionality. We have [a lint rule that limits the length of `index.js` files][0]. In [an upcoming change][1], the automations service will cross that limit. This patch moves it into a separate file. Doing so also makes it a little easier to test. [0]: https://github.com/TryGhost/eslint-plugin-ghost/blob/22d154a8e3807e4e30219fb8449e7aa9b90a110b/lib/config/node.js#L32-L37 [1]: #28120
towards https://linear.app/ghost/issue/NY-1286 ref #28120 This change should have no impact on functionality. We have [a lint rule that limits the length of `index.js` files][0]. In [an upcoming change][1], the automations service will cross that limit. This patch moves it into a separate file. Doing so also makes it a little easier to test. [0]: https://github.com/TryGhost/eslint-plugin-ghost/blob/22d154a8e3807e4e30219fb8449e7aa9b90a110b/lib/config/node.js#L32-L37 [1]: #28120
towards https://linear.app/ghost/issue/NY-1286 ref #28120 This change should have no impact on functionality. We have [a lint rule that limits the length of `index.js` files][0]. In [an upcoming change][1], the automations service will cross that limit. This patch moves it into a separate file. Doing so also makes it a little easier to test. [0]: https://github.com/TryGhost/eslint-plugin-ghost/blob/22d154a8e3807e4e30219fb8449e7aa9b90a110b/lib/config/node.js#L32-L37 [1]: #28120 (cherry picked from commit 2eb8a65)
towards https://linear.app/ghost/issue/NY-1286 ref #28120 To run an automation, we will: 1. Fetch (and lock) up to 100 steps. 2. If no steps are found, enqueue another poll for later, and stop. 3. Run all the steps. 4. Possibly enqueue another poll for later. This patch implements the first of those procedures. (If you want to see more fully how it will be used, see [this PR][0].) [0]: #28120
towards https://linear.app/ghost/issue/NY-1286 ref #28120 This is a test-only change that just makes things a little easier to read. I think it's useful on its own, but it'll also be useful for [an upcoming change](#28120).
towards https://linear.app/ghost/issue/NY-1286 ref #28120 To run an automation, we will: 1. Fetch (and lock) up to 100 steps. 2. If no steps are found, enqueue another poll for later, and stop. 3. Run all the steps. 4. Possibly enqueue another poll for later. This patch implements the first of those procedures. (If you want to see more fully how it will be used, see [this PR][0].) [0]: #28120
towards https://linear.app/ghost/issue/NY-1286 ref #28120 *I recommend reviewing this with whitespace changes disabled.* **What:** We want to trigger automations after members are inserted. **Why:** If we don't do this, automations could run before the member exists in the database.
towards https://linear.app/ghost/issue/NY-1286 ref #28120 *I recommend reviewing this with whitespace changes disabled.* **What:** We want to trigger automations after members are inserted. **Why:** If we don't do this, automations could run before the member exists in the database.
towards https://linear.app/ghost/issue/NY-1286 ref #28120 *I recommend reviewing this with whitespace changes disabled.* **What:** We want to trigger automations after members are inserted. **Why:** If we don't do this, automations could run before the member exists in the database. (cherry picked from commit e04da95)
cbc2db3 to
8b0cf45
Compare
towards https://linear.app/ghost/issue/NY-1286 ref #28120 *I recommend reviewing this with whitespace changes disabled.* **What:** We want to trigger automations after members are inserted. **Why:** If we don't do this, automations could run before the member exists in the database. (cherry picked from commit e04da95)
8b0cf45 to
b7f0a05
Compare
b7f0a05 to
d46b3ac
Compare
d46b3ac to
183d864
Compare
…8376) towards https://linear.app/ghost/issue/NY-1286 ref #28120 *I recommend [reviewing this with whitespace changes disabled][0].* **What:** We want to trigger automations after members are inserted. **Why:** If we don't do this, automations could run before the member exists in the database. [0]: https://github.com/TryGhost/Ghost/pull/28376/changes?w=1
There was a problem hiding this comment.
Pull request overview
This PR starts executing member welcome-email automations by implementing a polling/execution loop (dev + test environments only), including step locking/retries, and wiring the poller into the automations service. It also extends the fake automations database/schema to include sender fields and adds unit/e2e coverage for step execution.
Changes:
- Implemented automations step polling/execution with locking, retry, and terminal status handling.
- Extended the fake automations repository + temporary schema to support fetching/locking/running steps (including sender metadata).
- Added unit + e2e tests (and updated snapshots) validating step locking, progression, and email sending.
Reviewed changes
Copilot reviewed 12 out of 12 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| ghost/core/core/server/services/automations/poll.ts | Implements the poll loop that fetches/locks steps, executes them, retries/fails, and schedules the next poll. |
| ghost/core/core/server/services/automations/fake-database-automations-repository.ts | Adds step locking/fetching and step lifecycle operations (finish/terminal/retry) to the fake repository. |
| ghost/core/core/server/services/automations/automations-repository.ts | Introduces step-to-run and terminal-status types + repository methods for polling/execution. |
| ghost/core/core/server/services/automations/constants.ts | Defines shared constants for locking, attempt limits, batching, and retry delays. |
| ghost/core/core/server/services/automations/automations-api.ts | Exposes new repository operations (fetch/lock/finish/terminal/retry) via the automations API layer. |
| ghost/core/core/server/services/automations/service.js | Wires poll() into the service by injecting automationsApi + memberWelcomeEmailService. |
| ghost/core/core/server/services/automations/temporary-fake-database.ts | Updates fake automations schema + seed data to include sender fields for email actions. |
| ghost/core/core/server/services/member-welcome-emails/service.js | Refactors sending to allow automation-driven email sends (including sender fields + design setting lookup). |
| ghost/core/test/unit/server/services/automations/poll.test.ts | Adds unit coverage for poll behavior (env gating, batching, retrying, terminal statuses, scheduling). |
| ghost/core/test/unit/server/services/automations/automations-repository.test.ts | Adds unit tests for step locking and lifecycle operations in the repository. |
| ghost/core/test/e2e-api/members/automations.test.js | Adds e2e test to run the full free-member automation and assert resulting outgoing emails. |
| ghost/core/test/e2e-api/admin/snapshots/automations.test.js.snap | Updates snapshots to reflect sender fields coming from automation action revisions. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

closes https://linear.app/ghost/issue/NY-1286
ref #28239
ref #28263
ref #28343
ref #28375
ref #28376
I recommend reviewing this commit-by-commit.
This change starts executing automations (only in development and test).