🐛 Fix Admin API Post update method to not save a revision when save_revision=false#26678
🐛 Fix Admin API Post update method to not save a revision when save_revision=false#26678markstos wants to merge 1 commit intoTryGhost:mainfrom
Conversation
fixes TryGhost#26677 Reversing the sort here does not adversely impact anything else.
WalkthroughThe changes fix a revision ordering bug in the post model. The code now reverses the revision records array before processing revisions, correcting the order in which they are handled. Additionally, a new end-to-end test is added to verify that when editing a post without the save_revision flag within the revision interval, no additional PostRevision records are created. Together, these changes ensure the revision timestamp comparison works correctly and unnecessary revisions are not generated. 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 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 |
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
Bugbot Free Tier Details
Your team is on the Bugbot Free tier. On this plan, Bugbot will review limited PRs each billing cycle for each member of your team.
To receive Bugbot reviews on all of your PRs, visit the Cursor dashboard to activate Pro and start your 14-day free trial.
Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
| .where('post_id', postResponse.id) | ||
| .fetchAll(); | ||
| assert.equal(revisionsAfter.length, 2, 'No new revision should be created within the interval without save_revision'); | ||
| }); |
There was a problem hiding this comment.
Test doesn't actually validate the sort-order fix
Medium Severity
The new test claims to verify that no revision is created within the interval without save_revision, but it passes regardless of whether the .reverse() fix is applied. All revisions are created within milliseconds of each other in the test, so even when the sort-order bug causes latestRevision to point to the oldest revision, that revision is still well within the 10-minute POST_REVISIONS_INTERVAL_MS. To actually catch a regression of the sort-order bug, the oldest revision's created_at_ts would need to be more than 10 minutes in the past.
There was a problem hiding this comment.
🧹 Nitpick comments (1)
ghost/core/core/server/models/post.js (1)
926-926: Document the revision-ordering contract at Line 926.This reverse is correct, but it encodes a non-obvious dependency (
PostRevisiondefault DESC order +PostRevisionsexpecting oldest→newest). A brief inline comment here would make the intent explicit and reduce future regressions.💡 Minimal clarity diff
- const revisions = revisionModels.toJSON().reverse(); + // PostRevision is fetched newest-first by default; PostRevisions expects oldest->newest. + const revisions = revisionModels.toJSON().reverse();🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@ghost/core/core/server/models/post.js` at line 926, Add a short inline comment next to the const revisions = revisionModels.toJSON().reverse(); line documenting the ordering contract: state that PostRevision model is returned in default DESC (newest→oldest) order and PostRevisions consumer expects oldest→newest, so we reverse the array here; reference the revisionModels variable and the PostRevision model name in the comment so future readers understand the dependency and won't remove the reverse unintentionally.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Nitpick comments:
In `@ghost/core/core/server/models/post.js`:
- Line 926: Add a short inline comment next to the const revisions =
revisionModels.toJSON().reverse(); line documenting the ordering contract: state
that PostRevision model is returned in default DESC (newest→oldest) order and
PostRevisions consumer expects oldest→newest, so we reverse the array here;
reference the revisionModels variable and the PostRevision model name in the
comment so future readers understand the dependency and won't remove the reverse
unintentionally.
ℹ️ Review info
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: 70a1d003-fe0a-4fca-9a8c-8a35f9869eb2
📒 Files selected for processing (2)
ghost/core/core/server/models/post.jsghost/core/test/e2e-api/admin/posts.test.js


fixes #26677
There's a sort order bug in Ghost's revision logic. Here's the chain:
So latestRevision is actually the oldest revision, not the newest. The time check on line 84 compares Date.now() against the oldest revision's timestamp — which is almost always >10 minutes old. This means the background_save condition passes every time content has changed, regardless of how recently the last revision was created.
This bug is masked in the Ghost Admin UI because it always sends save_revision=true and there was no test coverage in the test suite for the condition.
The flag is not documented in the Admin API docs, helping the issue to go undetected.
Steps to Reproduce
Revision count should not be increasing, but it is.
Note
Cursor Bugbot is generating a summary for commit fc10425. Configure here.