Skip to content

Released comments threading and pinned comments#28125

Merged
jonatansberg merged 3 commits into
mainfrom
ber-3685-ga-threading-and-pinned-comments
May 26, 2026
Merged

Released comments threading and pinned comments#28125
jonatansberg merged 3 commits into
mainfrom
ber-3685-ga-threading-and-pinned-comments

Conversation

@jonatansberg
Copy link
Copy Markdown
Member

@jonatansberg jonatansberg commented May 26, 2026

Summary

  • Released commentsThreads by moving it from private labs to GA and removing it from the private Labs admin UI.
  • Released commentsPinning by moving it from private labs to GA and removing it from the private Labs admin UI.
  • Updated the Admin Settings API header snapshot affected by the labs payload change.

Why

These comment features are ready to go out to everyone in the next release.

ref https://linear.app/ghost/issue/BER-3685/ga-threading-and-pinned-comments

Testing

  • pnpm --dir ghost/core exec eslint --cache -- core/shared/labs.js
  • pnpm --dir apps/admin-x-settings exec eslint --cache -- src/components/settings/advanced/labs/private-features.tsx
  • pnpm test:single test/e2e-api/admin/settings.test.js (29 passing)
  • pnpm test:single test/unit/shared/labs.test.js (9 passing)

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 26, 2026

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: c3a9bc7a-61ba-47a5-b8ef-00e5303718d7

📥 Commits

Reviewing files that changed from the base of the PR and between ed9b482 and 94d2b29.

📒 Files selected for processing (1)
  • e2e/tests/public/comment-replies.test.ts

Walkthrough

This PR moves the comment-related flags commentsThreads and commentsPinning from PRIVATE_FEATURES into GA_FEATURES (so they are forced true by labs.getAll and included in GA_KEYS) and removes them from the writable private feature allowlist. The admin labs UI is updated to remove those two private feature entries and add a new smarterCounts private feature. Related e2e tests are renamed and an assertion about a “Replied to” label in threaded layout was removed.

Possibly related PRs

  • TryGhost/Ghost#27914: Removes commentsThreads/commentsPinning from the private labs feature list and updates the same UI and core labs files that this PR changes.
  • TryGhost/Ghost#27847: Adds threaded replies UI gated by commentsThreads; this PR promotes commentsThreads to GA and adjusts e2e expectations accordingly.
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and accurately summarizes the main change: releasing two comment features (threading and pinning) from private labs to GA.
Description check ✅ Passed The description is directly related to the changeset, providing clear context about what was released, why, and testing performed.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch ber-3685-ga-threading-and-pinned-comments

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.

@nx-cloud
Copy link
Copy Markdown

nx-cloud Bot commented May 26, 2026

🤖 Nx Cloud AI Fix

Ensure the fix-ci command is configured to always run in your CI pipeline to get automatic fixes in future runs. For more information, please see https://nx.dev/ci/features/self-healing-ci


View your CI Pipeline Execution ↗ for commit 94d2b29

Command Status Duration Result
nx run ghost:test:ci:integration ✅ Succeeded 1m 56s View ↗
nx run @tryghost/admin-x-settings:test:acceptance ✅ Succeeded 8m 51s View ↗
nx run ghost:test:ci:e2e ✅ Succeeded 7m 23s View ↗
nx run ghost:test:ci:legacy ✅ Succeeded 3m 6s View ↗
nx build @tryghost/sodo-search ✅ Succeeded <1s View ↗
nx build @tryghost/activitypub ✅ Succeeded 2s View ↗
nx build @tryghost/announcement-bar ✅ Succeeded <1s View ↗
nx build @tryghost/portal ✅ Succeeded <1s View ↗
Additional runs (8) ✅ Succeeded ... View ↗

☁️ Nx Cloud last updated this comment at 2026-05-26 14:20:41 UTC

@jonatansberg jonatansberg force-pushed the ber-3685-ga-threading-and-pinned-comments branch 3 times, most recently from ad6f664 to 17bb20b Compare May 26, 2026 10:15
@jonatansberg jonatansberg marked this pull request as ready for review May 26, 2026 10:18
@jonatansberg jonatansberg requested a review from ErisDS May 26, 2026 10:23
@jonatansberg jonatansberg enabled auto-merge (rebase) May 26, 2026 12:07
@jonatansberg jonatansberg force-pushed the ber-3685-ga-threading-and-pinned-comments branch from 17bb20b to 8daf285 Compare May 26, 2026 13:02
Copy link
Copy Markdown
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.

🧹 Nitpick comments (1)
ghost/core/core/shared/labs.js (1)

27-28: 🏗️ Heavy lift

Update on GA flag promotion cleanup for commentsThreads / commentsPinning

No migration/backfill was found to remove these keys from existing settings.labs JSON. However, the settings write paths filter labs payloads to WRITABLE_KEYS_ALLOWLIST before SettingsModel validation, so existing DB values containing commentsThreads/commentsPinning shouldn’t cause ValidationError on subsequent labs updates. (ghost/core/core/server/api/endpoints/utils/serializers/input/settings.js and ghost/core/core/server/data/importer/importers/data/settings-importer.js both drop non-allowlisted lab keys.)

Optional: add a migration to strip stale GA keys from stored settings.labs for cleanliness/hygiene.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@ghost/core/core/shared/labs.js` around lines 27 - 28, Add a migration that
cleans stale GA keys 'commentsThreads' and 'commentsPinning' from stored
settings.labs JSON: load rows where key === 'labs' from SettingsModel (or the
settings table), parse the JSON value, remove those keys if present, and write
the cleaned JSON back (ensuring the update goes through the same validation path
used by SettingsModel); reference WRITABLE_KEYS_ALLOWLIST behavior in comments
and ensure the migration is idempotent and reversible (or logged) so it can be
run safely during deploy.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@ghost/core/core/shared/labs.js`:
- Around line 27-28: Add a migration that cleans stale GA keys 'commentsThreads'
and 'commentsPinning' from stored settings.labs JSON: load rows where key ===
'labs' from SettingsModel (or the settings table), parse the JSON value, remove
those keys if present, and write the cleaned JSON back (ensuring the update goes
through the same validation path used by SettingsModel); reference
WRITABLE_KEYS_ALLOWLIST behavior in comments and ensure the migration is
idempotent and reversible (or logged) so it can be run safely during deploy.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 1c2ddb47-44f9-4dba-85e4-dae8b1601f38

📥 Commits

Reviewing files that changed from the base of the PR and between 17bb20b and 8daf285.

📒 Files selected for processing (2)
  • apps/admin-x-settings/src/components/settings/advanced/labs/private-features.tsx
  • ghost/core/core/shared/labs.js
💤 Files with no reviewable changes (1)
  • apps/admin-x-settings/src/components/settings/advanced/labs/private-features.tsx

ref https://linear.app/ghost/issue/BER-3685/ga-threading-and-pinned-comments

Readers can now follow deeper reply conversations with threaded comments available to everyone.
ref https://linear.app/ghost/issue/BER-3685/ga-threading-and-pinned-comments

Staff can now pin top-level comments so important discussion stays visible for readers.
@jonatansberg jonatansberg force-pushed the ber-3685-ga-threading-and-pinned-comments branch from 8daf285 to 9745d25 Compare May 26, 2026 13:28
@jonatansberg jonatansberg requested a review from 9larsons as a code owner May 26, 2026 13:48
Copy link
Copy Markdown
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.

🧹 Nitpick comments (2)
e2e/tests/public/comment-replies.test.ts (2)

64-64: ⚡ Quick win

Consider aligning test name with repository guideline.

The test name should follow the pattern: 'what is tested - expected outcome' in lowercase. As per coding guidelines, e2e test names in this repository should use this format for consistency.

Consider renaming to something like: 'nested reply in threaded layout - hides reply-to context label'

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@e2e/tests/public/comment-replies.test.ts` at line 64, Rename the test case
currently declared as test('reply to reply comment in threaded layout', async
({page}) => ...) to follow the repository convention "what is tested - expected
outcome" in lowercase; update the test name to a form like 'nested reply in
threaded layout - hides reply-to context label' (or similar) so it matches the
pattern and keep the rest of the test body unchanged.

64-96: ⚡ Quick win

Add assertion to verify threaded layout behavior.

The test name explicitly mentions "in threaded layout", but the test doesn't assert the key threaded-specific behavior. According to the relevant code snippets, threaded layout hides the "Replied to:" context label for direct children replies. The admin test suite explicitly verifies this with await expect(directReply.getByText('Replied to:')).toBeHidden().

Consider adding a similar assertion after line 95 to ensure the threaded layout is correctly hiding the "Replied to:" label:

🧪 Suggested assertion to validate threaded behavior
 await expect(postCommentsSection.comments.last()).toContainText('My reply');
+await expect(postCommentsSection.comments.last().getByText('Replied to:')).toBeHidden();

Note: Adjust the locator syntax based on your PostPage implementation.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@e2e/tests/public/comment-replies.test.ts` around lines 64 - 96, Add an
assertion that verifies the threaded layout hides the "Replied to:" context
label for direct child replies: after using
postCommentsSection.replyToComment(...) and before the final expectations,
locate the direct reply element (use the PostPage/postCommentsSection helpers
such as postCommentsSection.comments or a specific locator for the newly created
reply) and assert that the "Replied to:" text is hidden (similar to the admin
test's await expect(directReply.getByText('Replied to:')).toBeHidden()). This
ensures the test named "reply to reply comment in threaded layout" actually
validates the threaded-specific UI behavior.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@e2e/tests/public/comment-replies.test.ts`:
- Line 64: Rename the test case currently declared as test('reply to reply
comment in threaded layout', async ({page}) => ...) to follow the repository
convention "what is tested - expected outcome" in lowercase; update the test
name to a form like 'nested reply in threaded layout - hides reply-to context
label' (or similar) so it matches the pattern and keep the rest of the test body
unchanged.
- Around line 64-96: Add an assertion that verifies the threaded layout hides
the "Replied to:" context label for direct child replies: after using
postCommentsSection.replyToComment(...) and before the final expectations,
locate the direct reply element (use the PostPage/postCommentsSection helpers
such as postCommentsSection.comments or a specific locator for the newly created
reply) and assert that the "Replied to:" text is hidden (similar to the admin
test's await expect(directReply.getByText('Replied to:')).toBeHidden()). This
ensures the test named "reply to reply comment in threaded layout" actually
validates the threaded-specific UI behavior.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: fce400a4-c9d8-4b23-9b7b-a635574608da

📥 Commits

Reviewing files that changed from the base of the PR and between 9745d25 and ed9b482.

📒 Files selected for processing (1)
  • e2e/tests/public/comment-replies.test.ts

ref https://linear.app/ghost/issue/BER-3685/ga-threading-and-pinned-comments

Threaded comments now hide the reply-to-reply context label, so the public comments E2E should assert that layout instead of the legacy flat reply copy.
@jonatansberg jonatansberg force-pushed the ber-3685-ga-threading-and-pinned-comments branch from ed9b482 to 94d2b29 Compare May 26, 2026 14:08
@jonatansberg jonatansberg merged commit e4ccc30 into main May 26, 2026
47 checks passed
@jonatansberg jonatansberg deleted the ber-3685-ga-threading-and-pinned-comments branch May 26, 2026 14:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants