Ghost icon indicating copy to clipboard operation
Ghost copied to clipboard

Unified members/paid-members enabled checks in Admin

Open kevinansfield opened this issue 8 months ago • 1 comments

no issue

  • we had a confusing mix of manual underlying access setting checks, direct settings.membersEnabled/paidMembersEnabled checks, and membersUtils.membersEnabled/paidMembersEnabled checks
    • the membersUtils.xEnabled checks were originally in place to remove the repeated direct checks of settings.membersSignupAccess !== 'none' type checks that were spread around the codebase but the refactor to switch to those utils was never fully completed
    • we've later added API-level membersEnabled and paidMembersEnabled settings which membersUtils.xEnabled checks were switched to but we also started using the underlying settings directly in different parts of the codebase meaning we ended up with three different approaches
    • the confusion around and slightly different behaviour between these different methods meant our tests were also difficult to determine as setup helpers were doing different things that meant code paths using each different approach were not necessarily doing what was intended
  • unified to always use settings.membersEnabled and settings.paidMembersEnabled
    • removed the duplicate properties from membersUtils
    • switched all uses of membersUtils and manual checks over to settings checks
    • updated test utils to update all impacted settings when enabling/disabling members
  • fixed tests that were incorrectly testing against members disabled
  • added missing /api/admin/stats/mrr/ mocked endpoint that was causing dashboard tests to fail now that we are correctly testing against the members enabled state

kevinansfield avatar Mar 31 '25 16:03 kevinansfield

Walkthrough

The changes refactor the handling of member-related functionality throughout the Ghost admin interface. References to the membersUtils service have been removed and replaced with direct accesses to properties from the settings service. This affects conditional logic in multiple Handlebars templates, JavaScript components, controllers, helpers, models, and services related to the display of membership features, email analytics, and paid member configurations. Updates include revisions to service injections, computed properties, and conditional checks to reflect the use of new settings properties such as membersEnabled and paidMembersEnabled. Additional modifications update Mirage fixtures and endpoints, as well as test configurations, to load the corresponding settings properly.

Possibly related PRs

  • TryGhost/Ghost#22172: Refactors involving the removal of the membersUtils service and associated methods align closely with this PR’s adjustments to member-related functionality.

Suggested labels

migration, browser-tests

[!WARNING] There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 ESLint

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

ghost/admin/app/components/gh-member-settings-form.js

Oops! Something went wrong! :(

ESLint: 8.57.1

Error: Failed to load parser '@babel/eslint-parser' declared in 'ghost/admin/.eslintrc.js': Cannot find module '@babel/eslint-parser' Require stack:

  • /ghost/admin/.eslintrc.js at Module._resolveFilename (node:internal/modules/cjs/loader:1248:15) at Function.resolve (node:internal/modules/helpers:145:19) at Object.resolve (/node_modules/@eslint/eslintrc/dist/eslintrc.cjs:2346:46) at ConfigArrayFactory._loadParser (/node_modules/@eslint/eslintrc/dist/eslintrc.cjs:3325:39) at ConfigArrayFactory._normalizeObjectConfigDataBody (/node_modules/@eslint/eslintrc/dist/eslintrc.cjs:3099:43) at _normalizeObjectConfigDataBody.next () at ConfigArrayFactory._normalizeObjectConfigData (/node_modules/@eslint/eslintrc/dist/eslintrc.cjs:3040:20) at _normalizeObjectConfigData.next () at ConfigArrayFactory.loadInDirectory (/node_modules/@eslint/eslintrc/dist/eslintrc.cjs:2886:28) at CascadingConfigArrayFactory._loadConfigInAncestors (/node_modules/@eslint/eslintrc/dist/eslintrc.cjs:3871:46)
ghost/admin/app/components/gh-members-recipient-select.js

Oops! Something went wrong! :(

ESLint: 8.57.1

Error: Failed to load parser '@babel/eslint-parser' declared in 'ghost/admin/.eslintrc.js': Cannot find module '@babel/eslint-parser' Require stack:

  • /ghost/admin/.eslintrc.js at Module._resolveFilename (node:internal/modules/cjs/loader:1248:15) at Function.resolve (node:internal/modules/helpers:145:19) at Object.resolve (/node_modules/@eslint/eslintrc/dist/eslintrc.cjs:2346:46) at ConfigArrayFactory._loadParser (/node_modules/@eslint/eslintrc/dist/eslintrc.cjs:3325:39) at ConfigArrayFactory._normalizeObjectConfigDataBody (/node_modules/@eslint/eslintrc/dist/eslintrc.cjs:3099:43) at _normalizeObjectConfigDataBody.next () at ConfigArrayFactory._normalizeObjectConfigData (/node_modules/@eslint/eslintrc/dist/eslintrc.cjs:3040:20) at _normalizeObjectConfigData.next () at ConfigArrayFactory.loadInDirectory (/node_modules/@eslint/eslintrc/dist/eslintrc.cjs:2886:28) at CascadingConfigArrayFactory._loadConfigInAncestors (/node_modules/@eslint/eslintrc/dist/eslintrc.cjs:3871:46)
ghost/admin/app/components/koenig-lexical-editor.js

Oops! Something went wrong! :(

ESLint: 8.57.1

Error: Failed to load parser '@babel/eslint-parser' declared in 'ghost/admin/.eslintrc.js': Cannot find module '@babel/eslint-parser' Require stack:

  • /ghost/admin/.eslintrc.js at Module._resolveFilename (node:internal/modules/cjs/loader:1248:15) at Function.resolve (node:internal/modules/helpers:145:19) at Object.resolve (/node_modules/@eslint/eslintrc/dist/eslintrc.cjs:2346:46) at ConfigArrayFactory._loadParser (/node_modules/@eslint/eslintrc/dist/eslintrc.cjs:3325:39) at ConfigArrayFactory._normalizeObjectConfigDataBody (/node_modules/@eslint/eslintrc/dist/eslintrc.cjs:3099:43) at _normalizeObjectConfigDataBody.next () at ConfigArrayFactory._normalizeObjectConfigData (/node_modules/@eslint/eslintrc/dist/eslintrc.cjs:3040:20) at _normalizeObjectConfigData.next () at ConfigArrayFactory.loadInDirectory (/node_modules/@eslint/eslintrc/dist/eslintrc.cjs:2886:28) at CascadingConfigArrayFactory._loadConfigInAncestors (/node_modules/@eslint/eslintrc/dist/eslintrc.cjs:3871:46)
  • 16 others

📜 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 d8a47162d4498f96be24bbf71e3b26a80a3dc959 and 92b3fef892057e15ae2bd7923641aa65c536c521.

📒 Files selected for processing (30)
  • ghost/admin/app/components/editor/modals/preview.hbs (1 hunks)
  • ghost/admin/app/components/gh-member-details.hbs (1 hunks)
  • ghost/admin/app/components/gh-member-settings-form.hbs (1 hunks)
  • ghost/admin/app/components/gh-member-settings-form.js (1 hunks)
  • ghost/admin/app/components/gh-members-no-members.hbs (1 hunks)
  • ghost/admin/app/components/gh-members-recipient-select.js (2 hunks)
  • ghost/admin/app/components/koenig-lexical-editor.js (2 hunks)
  • ghost/admin/app/components/member-attribution/modals/all-sources.hbs (2 hunks)
  • ghost/admin/app/components/member-attribution/modals/all-sources.js (1 hunks)
  • ghost/admin/app/components/member-attribution/source-attribution-table.hbs (3 hunks)
  • ghost/admin/app/components/member-attribution/source-attribution-table.js (1 hunks)
  • ghost/admin/app/components/posts-list/context-menu.hbs (1 hunks)
  • ghost/admin/app/components/posts-list/context-menu.js (1 hunks)
  • ghost/admin/app/controllers/dashboard.js (1 hunks)
  • ghost/admin/app/helpers/parse-member-event.js (2 hunks)
  • ghost/admin/app/models/post.js (1 hunks)
  • ghost/admin/app/services/dashboard-stats.js (1 hunks)
  • ghost/admin/app/services/member-import-validator.js (0 hunks)
  • ghost/admin/app/services/members-utils.js (2 hunks)
  • ghost/admin/app/templates/dashboard.hbs (1 hunks)
  • ghost/admin/app/templates/members.hbs (3 hunks)
  • ghost/admin/app/utils/publish-options.js (1 hunks)
  • ghost/admin/mirage/config/stats.js (1 hunks)
  • ghost/admin/mirage/fixtures/settings.js (1 hunks)
  • ghost/admin/mirage/routes-test.js (1 hunks)
  • ghost/admin/tests/acceptance/content-test.js (5 hunks)
  • ghost/admin/tests/acceptance/editor/post-email-preview-test.js (3 hunks)
  • ghost/admin/tests/acceptance/members/filter-test.js (1 hunks)
  • ghost/admin/tests/helpers/members.js (1 hunks)
  • ghost/admin/tests/integration/services/member-import-validator-test.js (0 hunks)
💤 Files with no reviewable changes (2)
  • ghost/admin/app/services/member-import-validator.js
  • ghost/admin/tests/integration/services/member-import-validator-test.js
⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: Admin tests - Chrome
🔇 Additional comments (49)
ghost/admin/app/templates/dashboard.hbs (1)

105-105: Consistent property access pattern applied.

This change replaces membersUtils.membersInviteOnly with settings.membersInviteOnly, aligning with the PR objective to standardize member-related checks through the settings service directly.

ghost/admin/app/controllers/dashboard.js (1)

24-24: Service dependency updated correctly.

Replacing membersUtils with settings service follows the PR objective to standardize member-related checks by accessing settings properties directly instead of going through the membersUtils service.

ghost/admin/app/templates/members.hbs (3)

66-66: Standardized conditional check.

Changed from checking membersSignupAccess being "none" to using settings.membersEnabled directly, which aligns with the PR objective to standardize member checks. This ensures consistent behavior across the codebase.


100-100: Standardized conditional check.

Similar to the previous change, this replaces a check against membersSignupAccess with the more direct settings.membersEnabled property, maintaining consistent patterns throughout the application.


118-118: Standardized conditional check.

The third instance of replacing a membersSignupAccess comparison with the cleaner settings.membersEnabled check maintains consistency for when the "New member" button should be displayed.

ghost/admin/app/services/dashboard-stats.js (3)

364-364: Standardized service reference.

Changed from membersUtils.paidMembersEnabled to settings.paidMembersEnabled, removing the dependency on the membersUtils service and using settings properties directly.


368-368: Standardized service reference in hasPaidTiers definition.

Correctly updated the reference to use settings.paidMembersEnabled instead of membersUtils.paidMembersEnabled, maintaining consistent access patterns.


374-374: Standardized service reference in membersEnabled assignment.

Changed from membersUtils.isMembersEnabled to settings.membersEnabled, completing the consistent pattern of using the settings service directly for all member-related properties.

ghost/admin/app/services/members-utils.js (3)

19-19: Updated to use direct settings reference.

The change correctly replaces the former use of this.paidMembersEnabled getter with direct access to this.settings.paidMembersEnabled, aligning with the PR's objective to standardize member settings checks.


23-23: Updated to use direct settings reference.

The change correctly replaces the use of this.paidMembersEnabled getter with direct access to this.settings.paidMembersEnabled, consistent with the standardization approach.


49-49: Improved comment documentation.

The comment has been correctly updated to guide developers to use settings.paidMembersEnabled directly, which is consistent with the code changes and helps prevent future confusion.

ghost/admin/app/helpers/parse-member-event.js (2)

10-10: Added settings service injection.

The change correctly adds the settings service injection to replace membersUtils.


296-296: Updated to use direct settings reference.

The change correctly replaces the former use of this.membersUtils.paidMembersEnabled with direct access to this.settings.paidMembersEnabled.

ghost/admin/mirage/routes-test.js (1)

35-35:

❓ Verification inconclusive

Enabled Mirage logging.

Changing logging to true will provide more visibility into Mirage routes during tests, which may be helpful for debugging the updated member settings behavior. However, this could potentially make test output more verbose.

Consider whether this change is intentional or if it was meant to be temporary for debugging. If temporary, it should be reverted before merging.


🏁 Script executed:

#!/bin/bash
# Check if there are any test files that might be affected by this change
rg -l "mirage" --type js ghost/admin/tests

Length of output: 1973


Verify Mirage logging intention in tests

  • In ghost/admin/mirage/routes-test.js (line 35), the property this.logging is set to true, which will enable verbose logging during tests.
  • The tests within ghost/admin/tests/ reference Mirage across multiple files, but there is no clear indication that verbose logging was meant to persist.
  • Please confirm whether enabling logging was an intentional permanent change to aid debugging, or if it was a temporary measure meant to be reverted before merging. If it was for temporary debugging only, kindly revert this change or add an inline comment clarifying the intent.
ghost/admin/app/components/posts-list/context-menu.hbs (1)

54-54: Updated to use direct settings reference.

The change correctly replaces the use of this.membersUtils.isMembersEnabled with direct access to this.settings.membersEnabled, which aligns with the PR's objective to standardize member settings checks.

ghost/admin/app/components/gh-member-settings-form.hbs (1)

82-82: Updated conditional logic to use settings service

The conditional check has been changed from using this.membersUtils.paidMembersEnabled to this.settings.paidMembersEnabled, which aligns with the PR objective of unifying member-related checks to use the settings service directly.

ghost/admin/app/components/member-attribution/modals/all-sources.js (1)

5-5: Service injection updated from membersUtils to settings

The component now injects the settings service instead of the membersUtils service, which aligns with the PR objective of unifying member-related checks to use settings directly.

ghost/admin/mirage/config/stats.js (1)

74-112: Added mock endpoint for MRR statistics

Added a new mock endpoint for /stats/mrr/ that provides structured test data for Monthly Recurring Revenue. This allows dashboard tests to work correctly with the updated member-enabled checks.

The mock data includes dates from 2025, which is appropriate for testing future projections, and provides a good variety of MRR values to test different scenarios.

ghost/admin/app/components/gh-member-settings-form.js (1)

26-26: Updated conditional logic to use settings service

The condition has been changed from if (!this.membersUtils.paidMembersEnabled) to if (!this.settings.paidMembersEnabled), aligning with the PR objective of unifying member-related checks to use settings directly.

ghost/admin/app/utils/publish-options.js (1)

124-127: Looks good - Unified membership checks.

The change from checking this.settings.membersSignupAccess === 'none' to !this.settings.membersEnabled aligns with the PR objective of standardizing member settings checks.

ghost/admin/app/components/member-attribution/source-attribution-table.hbs (1)

9-9: Properly standardized paid members settings checks.

All conditional checks now reference this.settings.paidMembersEnabled directly instead of using the membersUtils service, consistent with the PR's objective to unify member-related setting checks.

Also applies to: 11-11, 40-40, 72-72

ghost/admin/app/components/posts-list/context-menu.js (1)

68-68: Successfully migrated from membersUtils to settings service.

The change from @service membersUtils to @service settings supports the PR objective of removing duplicate properties from membersUtils and transitioning all checks to rely solely on the settings object.

ghost/admin/tests/acceptance/editor/post-email-preview-test.js (3)

4-4: Great addition of the disablePaidMembers helper.

Adding the helper and calling it appropriately ensures tests correctly simulate the disabled paid members state, aligning with the PR's goal of improving test accuracy.

Also applies to: 20-21


31-32: Improved test readability with descriptive assertion messages.

Adding descriptive messages ('newsletter select' and 'segment select') to the assertions makes test failures more informative and easier to debug.

Also applies to: 55-56


37-38: Properly configured test environment for accurate testing.

Including the call to disablePaidMembers(this.server) ensures the test environment correctly simulates the disabled paid members state, which is crucial for validating the expected behavior.

ghost/admin/mirage/fixtures/settings.js (1)

60-61: Good addition of member settings fixtures

These two new settings align with the PR objective of standardizing checks for member and paid member settings. Setting both to true by default is appropriate for test fixtures, as most tests will want to test with members enabled.

ghost/admin/app/components/member-attribution/source-attribution-table.js (1)

8-8:

✅ Verification successful

Service dependency change in line with PR objectives

This change replaces the membersUtils service with the settings service, aligning with the PR goal of standardizing member-related checks to use settings properties directly.

Run the following script to verify that all references to membersUtils.paidMembersEnabled have been replaced with settings.paidMembersEnabled in the template:


🏁 Script executed:

#!/bin/bash
# Check for any remaining references to membersUtils.paidMembersEnabled in the template
rg "membersUtils\.paidMembersEnabled" "ghost/admin/app/components/member-attribution/source-attribution-table.hbs" || echo "No references found - good!"

Length of output: 179


Service Dependency Update Verified

  • The change in ghost/admin/app/components/member-attribution/source-attribution-table.js (Line 8) to use @service settings instead of membersUtils aligns with the PR goals.
  • The verification script confirms that all references to membersUtils.paidMembersEnabled in the template have been successfully replaced with settings.paidMembersEnabled.
ghost/admin/tests/acceptance/members/filter-test.js (1)

24-24:

✅ Verification successful

Added theme fixtures loading

This adds the loading of theme fixtures to the test setup. While not directly mentioned in the PR objectives, this might be necessary since the member settings are now standardized and tests may rely on proper theme fixtures.

Let's verify if there are any dependencies between themes and member settings that would make this addition necessary:


🏁 Script executed:

#!/bin/bash
# Look for any relationships between themes and member settings
rg -A 5 -B 5 "themes.*members" "ghost/admin" || echo "No direct relationship found in code"

Length of output: 127


Dependency Check Complete – Approved Theme Fixture Loading

The executed script did not reveal any direct dependencies between themes and member settings in the code. The addition of the fixture loading:

this.server.loadFixtures('themes');

remains valid for ensuring that tests have the necessary theme data for the standardized member settings. No further action is needed.

ghost/admin/app/components/editor/modals/preview.hbs (1)

12-12: Updated conditional check for email preview

This change replaces checking membersSignupAccess with checking settings.membersEnabled, which aligns with the PR objective of standardizing member-related checks to use settings properties directly.

The condition is now clearer and more straightforward: if members are enabled AND email recipients are not disabled, show the email preview option.

ghost/admin/app/components/member-attribution/modals/all-sources.hbs (2)

12-12: Correct usage of standardized settings check.

This change aligns with the PR objective to unify member-related checks through the settings service instead of using membersUtils.


32-32: Consistent approach to member settings check.

Good consistency with the earlier check in the same file, both now use this.settings.paidMembersEnabled.

ghost/admin/app/components/gh-members-no-members.hbs (1)

4-4: Simplified member-enabled check.

The change improves clarity by using the direct this.settings.membersEnabled property rather than checking against membership access values, which aligns with the PR objectives to standardize these checks.

ghost/admin/app/components/gh-member-details.hbs (1)

75-75: Standardized member-enabled check.

The condition has been simplified to use this.settings.membersEnabled directly while preserving the additional check for email recipients. This is consistent with the PR's objective to streamline member-related feature checks.

ghost/admin/tests/acceptance/content-test.js (4)

148-149: Added settings fixtures for editor tests.

Good addition of the settings fixtures loading, which is necessary since the editor tests now depend on member-related settings for the context menu functionality.


172-178: Updated context menu button expectations.

The test has been correctly updated to account for the added "Change access" button in the context menu, which is now visible based on the standardized member settings check.


339-346: Updated context menu button expectations for admin user.

The test expectations have been properly adjusted to include the additional "Change access" button in the admin context menu, keeping tests aligned with the implementation changes.


349-349: Updated button index for duplicate action.

The action index has been correctly updated to reflect the new position of the "Duplicate" button after the addition of the "Change access" button.

ghost/admin/app/components/gh-members-recipient-select.js (2)

12-12: Service dependency updated to match unified approach.

The component now relies on settings service instead of membersUtils, aligning with the PR objective to standardize member-related checks through the settings service.


43-43: Unified paid members check.

Changed from using this.membersUtils.isStripeEnabled to this.settings.paidMembersEnabled, ensuring consistent checks for paid members functionality throughout the application.

ghost/admin/app/components/koenig-lexical-editor.js (2)

285-285: Standardized paid members check.

Updated to use this.settings.paidMembersEnabled instead of this.membersUtils.paidMembersEnabled, ensuring consistency with other components that check for paid member availability.


449-449: Simplified members enabled check.

Changed from the indirect check this.settings.membersSignupAccess === 'all' to the more straightforward this.settings.membersEnabled, improving readability while maintaining the same functionality.

ghost/admin/app/models/post.js (4)

197-197: Standardized members enabled check in analytics.

Updated to use this.settings.membersEnabled instead of checking this.settings.membersSignupAccess !== 'none', making the code more readable and consistent.


205-205: Unified members enabled check in email click analytics.

Same change as in the email open analytics property, standardizing on this.settings.membersEnabled for consistency across the codebase.


211-215: Simplified invite-only members check.

Changed from using this.membersUtils.isMembersInviteOnly to directly checking !this.settings.membersInviteOnly, making the dependency hierarchy clearer and code more maintainable.


219-219: Standardized paid members check in analytics.

Using settings.paidMembersEnabled directly instead of going through membersUtils.paidMembersEnabled, creating a more consistent approach to checking paid member status.

ghost/admin/tests/helpers/members.js (4)

1-10: Enhanced test helper with parameterized members enabling.

The enableMembers function now accepts a boolean parameter to control both members_signup_access and the new members_enabled setting, making tests more flexible and aligned with the application's unified approach.


13-15: Simplified members disabling implementation.

Refactored to leverage the parameterized enableMembers function, making the code more DRY while maintaining the same functionality.


17-21: Enhanced paid members test helper with parameterization.

Similar to the enableMembers update, the paid members helper now accepts a boolean parameter for more flexible test setup.


23-25: Added missing paid members disabling helper.

Implemented the previously missing disablePaidMembers function to complement enablePaidMembers, completing the set of test utilities needed for proper test setup.

✨ Finishing Touches
  • [ ] 📝 Generate Docstrings

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
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai plan to trigger planning for file edits and PR creation.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

coderabbitai[bot] avatar Mar 31 '25 16:03 coderabbitai[bot]

Cleaning up older PRs 💅

ErisDS avatar Aug 04 '25 09:08 ErisDS