Skip to content

Conversation

@sam-lord
Copy link
Contributor

@sam-lord sam-lord commented Nov 3, 2025

closes GVA-583
closes GVA-587

These migrations are both required for the feature. I ran an experimental spike to see what data we'd need to get domain warmup working, and these two came out:

  • A count of the messages that were sent by the CSD for each email => this lets us ramp up the number of emails that we send from the CSD on each subsequent send
  • A boolean flag that says whether an email batch was sent by the fallback domain (a back-up domain configured for if we're going to exceed the CSD's budget)

Note

Adds DB migrations and schema/model/test updates for emails.csd_email_count and email_batches.fallback_sending_domain.

  • Database/Migrations
    • Add emails.csd_email_count (nullable integer, unsigned) via versions/6.7/2025-11-03-15-17-05-add-csd-email-count.js.
    • Add email_batches.fallback_sending_domain (boolean, default false) via versions/6.7/2025-11-03-15-18-04-add-email-batch-fallback-domain.js.
    • Update core/server/data/schema/schema.js to include both columns.
  • Models
    • Update core/server/models/email-batch.js defaults to include fallback_sending_domain: false.
  • Tests/Fixtures
    • Update fixtures in test/utils/fixtures/data-generator.js to populate fallback_sending_domain and reflect new schema.
    • Refresh schema hash in test/unit/server/data/schema/integrity.test.js.
    • Adjust E2E/API snapshots to include csd_email_count and changed content-lengths.
    • Fix link HTML in test/e2e-server/click-tracking.test.js (adds missing quotes).

Written by Cursor Bugbot for commit ecb9bec. This will update automatically on new commits. Configure here.

@sam-lord sam-lord requested a review from aileen November 3, 2025 15:41
@github-actions github-actions bot added the migration [pull request] Includes migration for review label Nov 3, 2025
@github-actions
Copy link
Contributor

github-actions bot commented Nov 3, 2025

It looks like this PR contains a migration 👀
Here's the checklist for reviewing migrations:

General requirements

  • ⚠️ Tested performance on staging database servers, as performance on local machines is not comparable to a production environment
  • Satisfies idempotency requirement (both up() and down())
  • Does not reference models
  • Filename is in the correct format (and correctly ordered)
  • Targets the next minor version
  • All code paths have appropriate log messages
  • Uses the correct utils
  • Contains a minimal changeset
  • Does not mix DDL/DML operations
  • Tested in MySQL and SQLite

Schema changes

  • Both schema change and related migration have been implemented
  • For index changes: has been performance tested for large tables
  • For new tables/columns: fields use the appropriate predefined field lengths
  • For new tables/columns: field names follow the appropriate conventions
  • Does not drop a non-alpha table outside of a major version

Data changes

  • Mass updates/inserts are batched appropriately
  • Does not loop over large tables/datasets
  • Defends against missing or invalid data
  • For settings updates: follows the appropriate guidelines

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Nov 3, 2025

Note

Other AI code review bot(s) detected

CodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review.

Walkthrough

This PR adds two migrations and corresponding schema changes: a nullable integer column csd_email_count on emails and a non-nullable boolean fallback_sending_domain (default false) on email_batches. It adds two migration files, updates schema.js, sets EmailBatch.defaults.fallback_sending_domain = false, updates fixtures (data-generator), adjusts an e2e HTML link quoting, and updates the schema-integrity test expected hash.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

  • Verify the two migration files create columns with the exact attributes (type, nullable, unsigned/default).
  • Confirm schema.js entries match the migrations.
  • Inspect core/server/models/email-batch.js defaults change for side effects (serialization, validation).
  • Check test/utils/fixtures/data-generator.js and e2e HTML change for consistency with the new schema.
  • Validate the updated schema-integrity test hash was recomputed from the modified schema.

Pre-merge checks and finishing touches

✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title 'Migrations for domain warmup feature' clearly and directly summarizes the main change in this PR, which is adding database migrations and schema updates required for a domain warmup feature.
Description check ✅ Passed The description is highly detailed and directly related to the changeset, clearly explaining the purpose of both migrations, the feature they enable, and references the closed Linear issues.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch domain-warmup-migrations

📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 8732a18 and ecb9bec.

⛔ Files ignored due to path filters (2)
  • ghost/core/test/e2e-api/admin/__snapshots__/activity-feed.test.js.snap is excluded by !**/*.snap
  • ghost/core/test/e2e-api/admin/__snapshots__/emails.test.js.snap is excluded by !**/*.snap
📒 Files selected for processing (7)
  • ghost/core/core/server/data/migrations/versions/6.7/2025-11-03-15-17-05-add-csd-email-count.js (1 hunks)
  • ghost/core/core/server/data/migrations/versions/6.7/2025-11-03-15-18-04-add-email-batch-fallback-domain.js (1 hunks)
  • ghost/core/core/server/data/schema/schema.js (2 hunks)
  • ghost/core/core/server/models/email-batch.js (1 hunks)
  • ghost/core/test/e2e-server/click-tracking.test.js (1 hunks)
  • ghost/core/test/unit/server/data/schema/integrity.test.js (1 hunks)
  • ghost/core/test/utils/fixtures/data-generator.js (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (6)
  • ghost/core/core/server/data/schema/schema.js
  • ghost/core/test/e2e-server/click-tracking.test.js
  • ghost/core/test/utils/fixtures/data-generator.js
  • ghost/core/core/server/data/migrations/versions/6.7/2025-11-03-15-17-05-add-csd-email-count.js
  • ghost/core/core/server/models/email-batch.js
  • ghost/core/core/server/data/migrations/versions/6.7/2025-11-03-15-18-04-add-email-batch-fallback-domain.js
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-10-09T17:25:12.439Z
Learnt from: CR
Repo: TryGhost/Ghost PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-10-09T17:25:12.439Z
Learning: Applies to ghost/core/core/server/data/schema/** : Database schema changes must be placed under ghost/core/core/server/data/schema/

Applied to files:

  • ghost/core/test/unit/server/data/schema/integrity.test.js
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (8)
  • GitHub Check: Ghost-CLI tests
  • GitHub Check: Unit tests (Node 22.13.1)
  • GitHub Check: Acceptance tests (Node 22.13.1, sqlite3)
  • GitHub Check: Legacy tests (Node 22.13.1, mysql8)
  • GitHub Check: Acceptance tests (Node 22.13.1, mysql8)
  • GitHub Check: Legacy tests (Node 22.13.1, sqlite3)
  • GitHub Check: Lint
  • GitHub Check: Build & Push
🔇 Additional comments (1)
ghost/core/test/unit/server/data/schema/integrity.test.js (1)

38-38: Schema hash bump looks correct.

Hash update matches the new emails.csd_email_count and email_batches.fallback_sending_domain columns introduced in the schema, so this expectation adjustment makes sense.


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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

cursor[bot]

This comment was marked as outdated.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between b941f98 and 14a793a.

📒 Files selected for processing (4)
  • ghost/core/core/server/data/migrations/versions/6.7/2025-11-03-15-17-05-add-csd-email-count.js (1 hunks)
  • ghost/core/core/server/data/migrations/versions/6.7/2025-11-03-15-18-04-add-email-batch-fallback-domain.js (1 hunks)
  • ghost/core/core/server/data/schema/schema.js (2 hunks)
  • ghost/core/test/unit/server/data/schema/integrity.test.js (1 hunks)
🧰 Additional context used
📓 Path-based instructions (2)
ghost/core/core/server/**

📄 CodeRabbit inference engine (AGENTS.md)

Backend core logic should reside under ghost/core/core/server/

Files:

  • ghost/core/core/server/data/schema/schema.js
  • ghost/core/core/server/data/migrations/versions/6.7/2025-11-03-15-17-05-add-csd-email-count.js
  • ghost/core/core/server/data/migrations/versions/6.7/2025-11-03-15-18-04-add-email-batch-fallback-domain.js
ghost/core/core/server/data/schema/**

📄 CodeRabbit inference engine (AGENTS.md)

Database schema changes must be placed under ghost/core/core/server/data/schema/

Files:

  • ghost/core/core/server/data/schema/schema.js
🧠 Learnings (1)
📚 Learning: 2025-10-09T17:25:12.439Z
Learnt from: CR
Repo: TryGhost/Ghost PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-10-09T17:25:12.439Z
Learning: Applies to ghost/core/core/server/data/schema/** : Database schema changes must be placed under ghost/core/core/server/data/schema/

Applied to files:

  • ghost/core/test/unit/server/data/schema/integrity.test.js
  • ghost/core/core/server/data/schema/schema.js
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (6)
  • GitHub Check: Ghost-CLI tests
  • GitHub Check: Legacy tests (Node 22.13.1, mysql8)
  • GitHub Check: Legacy tests (Node 22.13.1, sqlite3)
  • GitHub Check: Lint
  • GitHub Check: Unit tests (Node 22.13.1)
  • GitHub Check: Build & Push
🔇 Additional comments (3)
ghost/core/core/server/data/migrations/versions/6.7/2025-11-03-15-18-04-add-email-batch-fallback-domain.js (1)

1-7: LGTM! Migration correctly adds fallback_sending_domain column.

The migration properly uses the createAddColumnMigration utility and the column definition matches the schema definition in schema.js (line 870).

ghost/core/test/unit/server/data/schema/integrity.test.js (1)

38-38: LGTM! Schema hash correctly updated.

The updated MD5 hash reflects the schema changes (addition of csd_email_count and fallback_sending_domain columns).

ghost/core/core/server/data/schema/schema.js (1)

870-870: LGTM! Schema definition matches migration.

The fallback_sending_domain column definition correctly matches the migration in ghost/core/core/server/data/migrations/versions/6.7/2025-11-03-15-18-04-add-email-batch-fallback-domain.js.

@sam-lord sam-lord force-pushed the domain-warmup-migrations branch from 14a793a to a321b87 Compare November 3, 2025 16:31
cursor[bot]

This comment was marked as outdated.

Copy link
Member

@aileen aileen left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the acceptance tests need some care. Other than that, I think this migration is good. The naming of the new columns makes sense to me as well. I also agree with omitting the defaultTo: 0, so we have another indicator if the feature is used at all. I would expect that - when we turn the feature on and the user has a custom sending domain, but not send anything yet, we'd set it to 0?

@sam-lord sam-lord force-pushed the domain-warmup-migrations branch from f27c617 to 8732a18 Compare November 4, 2025 10:31
posts: [{
title: 'My Newsletter',
html: `<p>External link <a href="https://example.com/a">https://example.com/a</a>; Internal link <a href=${siteUrl.href}/about">${siteUrl.href}/about</a>;Ghost homepage <a href="https://ghost.org">https://ghost.org</a></p>`
html: `<p>External link <a href="https://example.com/a">https://example.com/a</a>; Internal link <a href="${siteUrl.href}/about">${siteUrl.href}/about</a>;Ghost homepage <a href="https://ghost.org">https://ghost.org</a></p>`
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't understand why I'm having to fix this 🤔

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That is strange indeed. Maybe something to flag up in our development channel?

@sam-lord sam-lord requested a review from aileen November 4, 2025 11:11
closes
[GVA-583](https://linear.app/ghost/issue/GVA-583/create-migration-in-ghost-to-add-csd-member-count-to-emails)

We need to know how many emails were sent using the CSD from the
previous email in order to ramp up the sending from the CSD.

See [spike PR](#25303) for our
test implementation of domain warmup using this field.
closes
[GVA-587](https://linear.app/ghost/issue/GVA-587/create-a-migration-for-the-email-batches-table-to-say-whether-its-sent)

We need to know whether an email batch should be sent from the fallback
domain or the primary configured domain.

See [spike PR](#25303) for our
test implementation.
@sam-lord sam-lord force-pushed the domain-warmup-migrations branch from 330a7ed to ecb9bec Compare November 4, 2025 11:12
Copy link
Member

@aileen aileen left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

migration [pull request] Includes migration for review

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants