Skip to content

[pull] main from TryGhost:main#1070

Merged
pull[bot] merged 3 commits into
code:mainfrom
TryGhost:main
Apr 16, 2026
Merged

[pull] main from TryGhost:main#1070
pull[bot] merged 3 commits into
code:mainfrom
TryGhost:main

Conversation

@pull
Copy link
Copy Markdown

@pull pull Bot commented Apr 16, 2026

See Commits and Changes for more details.


Created by pull[bot] (v2.0.0-alpha.4)

Can you help keep this open source service alive? 💖 Please sponsor : )

EvanHahn and others added 3 commits April 16, 2026 16:56
no ref

This is a test-only change.

I think Claude Opus 4.7's explanation is reasonably good:

> The test at `comments.test.js:1362` uses `dbFns.addCommentWithReplies`
to create a parent comment and a reply back-to-back without explicit
`created_at` values. Both rows rely on the model's default timestamp
(`new Date()` at save time).
>
> The admin browseAll controller at `comments-controller.js:166` sorts
by `created_at desc` and the SQL has no secondary tiebreak. When the two
inserts land in the same millisecond, MySQL happens to return rows in
insertion order (parent first, reply second), which matches the stored
snapshot `[commentMatcher, commentMatcherWithParent]`. When the reply
spills into a newer millisecond, `desc` puts the reply first — the
snapshot then sees `parent` (reply's parent object) missing from index 1
and the assertion fails exactly as in the CI log.
no issue

- Merged gift subscription tests from three scattered files into
`ghost/core/test/e2e-api/members/gift-subscriptions.test.js`
- Deleted `ghost/core/test/e2e-api/members/gifts.test.js` (all tests
moved)
- Removed 2 gift-related tests from
`ghost/core/test/e2e-api/members/signin.test.js`
- Organized tests into clear describe blocks: Purchase, Refund, Check
redeemability, and Redeem (logged-in + magic link flows)
- Added new tests for redeemability checks (already redeemed, expired,
refunded) and magic link edge cases (existing member redemption,
second-attempt failure)
no ref
- Persists the scheduled/backfill email analytics fetch to the database
so it survives Ghost restarts. Uses the existing `metadata` column on
the `jobs` table to store the begin/end time window as JSON;
`finished_at` continues to track progress within that window (same as
other fetch types), but since the scheduled job has a fixed time window
— not computed relative to now — both the start and end times need
explicit persistence.
- On startup, `restoreScheduled()` is called once (on the first
`startFetch()` cycle) to restore any in-progress schedule from the
database.
- Adds custom date range support to the debug UI
(`/posts/analytics/:id/debug`). A "Custom Date Range" option now appears
alongside the existing "Refetch Analytics" button, with datetime inputs
for arbitrary begin/end dates. The API endpoint accepts optional
`begin`/`end` parameters, falling back to the existing computed
defaults.

The scheduled/backfill job in Ghost was previously held only in memory. For very large data sets, it was often the case that Ghost would get restarted before the backfill job ever finished, making it of limited value.

This adds persistence to that job, just like our other email analytics jobs/tasks, and expands the `/debug` route to allow us to set a custom datetime from the frontend so we're not stuck with the defaults (post publish + 7d).
@pull pull Bot locked and limited conversation to collaborators Apr 16, 2026
@pull pull Bot added the ⤵️ pull label Apr 16, 2026
@pull pull Bot merged commit c66e552 into code:main Apr 16, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants