-
Notifications
You must be signed in to change notification settings - Fork 434
feat: migration guide updates #2315
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from 4 commits
Commits
Show all changes
33 commits
Select commit
Hold shift + click to select a range
a350ae8
chore: migration guide updates
unatasha8 c1cc94d
chore: migration guide updates
unatasha8 67f2ad3
chore: migration guide updates
unatasha8 0ecca7d
chore: edits to migration guide
unatasha8 a0ef5d1
docs: updated migration strategies and identity schema content
unatasha8 6f448c2
Update docs/migrate-to-ory/migrate/create-project.mdx
unatasha8 b80511d
docs: final review comments
unatasha8 e1650cf
chore: format
unatasha8 3275ee3
Merge branch 'master' into una-MigGuideUpdate
unatasha8 364d7cc
chore: formatting fixes
unatasha8 e1fba13
chore: fixed tabs again
unatasha8 1466d44
chore: formatting fixes
unatasha8 da5ed2e
chore: fix formating
unatasha8 3a28186
chore: fix formatting
unatasha8 52a4874
chore: fix formating again
unatasha8 103a313
Update docs/migrate-to-ory/migrate/migrate-strategies.mdx
unatasha8 c690685
docs: switch to calendar-based unified versioning (#2326)
adamwalach 329399e
docs: add device flow documentation (#2026)
nsklikas be44bcd
fix: high-perf pooling doc (#2332)
vinckr bcd03b3
chore(docs): update of OEL images (#2337)
ory-bot ed75f81
autogen(docs): generate cli docs
ory-bot a04e06a
autogen(docs): generate cli docs
ory-bot f6ab4ff
autogen(docs): generate cli docs
ory-bot 1af52f5
chore: added oel configuration schemas (#2279)
deepakprabhakara e62c260
docs: bump to 99e1d24edde1c46372cb61a1839961fde59dba8b
aeneasr f703129
chore: clarify webhook config update (#2339)
vinckr c623f51
fix: organizations docs (#2334)
vinckr cb07e32
feat: flutter quickstart (#2241)
pi1814 40b9b3f
feat: add kratos webhook header allowlist config details (#2100)
K3das 10ad7ef
chore: migration guide updates
unatasha8 41044fc
chore: migration updates
unatasha8 6c55a36
chore: migration guide updates
unatasha8 206cd77
chore: update migration guide
unatasha8 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Some comments aren't visible on the classic Files Changed page.
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,16 @@ | ||
| --- | ||
| id: create-project | ||
| title: Create an Ory Network project | ||
| sidebar_label: Create an Ory Network project | ||
| sidebar_position: 3 | ||
| --- | ||
|
|
||
| Now that you have chosen your migration strategy, you can begin the actual migration process by setting up your Ory Network | ||
| projects in a development, staging, and production environment. | ||
|
|
||
| You can create a new Ory Network project using the Ory CLI. The command ory create project allows you to specify the environment | ||
| of the project, the output format, the name of the project, and the workspace to use. More details about creating a project can be | ||
| found [here](../../cli/ory-create-project). | ||
|
|
||
| Before migrating to your production environment, perform the migration in a development or staging environment. This allows you to | ||
| test and refine the process without affecting your live data or users. | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,18 @@ | ||
| --- | ||
| id: design-id-schema | ||
| title: Design your identity schema | ||
| sidebar_label: Design your identity schema | ||
| sidebar_position: 3 | ||
| --- | ||
|
|
||
| To match identities from your current system with the new Ory system, you can customize the identity schema in Ory to meet your | ||
| specific requirements. This schema defines the types of data that the system can store for users, including names, email | ||
| addresses, phone numbers, and other authentication-related information. Additionally, you can specify extra metadata fields to be | ||
| included in user profiles. Ory offers default presets to assist you in creating and managing identity schemas. More details about | ||
| identity schemas can be found [here](../../kratos/manage-identities/identity-schema). | ||
|
|
||
| - Do store profile data in your identity that is used across your system. This includes the usernames, email addresses, phone | ||
| numbers, first names, and last names. | ||
| - Do not store business logic in your identity, store this information in other systems, such as your application database. This | ||
| includes for example credit card information, shipping addresses, shopping cart items, or user preferences. See also the | ||
| following section on backend integration. |
vinckr marked this conversation as resolved.
Show resolved
Hide resolved
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,8 @@ | ||
| --- | ||
| id: faq-migrate | ||
| title: Migration FAQ | ||
| sidebar_label: Migration FAQ | ||
| sidebar_position: 1 | ||
| --- | ||
|
|
||
| TODO: Living section for specific questions/answers that Sales get asked but which don't neatly fit within the migration process. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,24 @@ | ||
| --- | ||
| id: go-live | ||
| title: Go live | ||
| sidebar_label: Go live | ||
| sidebar_position: 2 | ||
| --- | ||
|
|
||
| After successfully migrating your data and testing the integration in your development or staging environment, it's time to go | ||
| live with Ory in your production environment. | ||
|
|
||
| 1. Final testing: Before switching over to Ory in production, conduct thorough testing of all user authentication flows, identity | ||
| management features, and access controls. This includes testing edge cases, error handling, and load testing to ensure the | ||
| system can handle your user base. | ||
| 1. Prepare a rollback plan: In case any issues arise during the go-live process, have a rollback plan in place. This may involve | ||
| reverting to your previous authentication system or restoring data from backups. | ||
| 1. Schedule the go-live: Choose a time for the go-live that minimizes the impact on your users, such as during low-traffic | ||
| periods. Communicate the planned migration to your users in advance, including any expected downtime or changes they should be | ||
| aware of. | ||
| 1. Monitor the transition: As you switch over to Ory, closely monitor the system for any issues, such as failed authentications, | ||
| performance bottlenecks, or user complaints. Use live events to monitor the system under | ||
| <ConsoleLink route="project.activity.events" />. | ||
| 1. Optimize and refine: After the go-live, continue to monitor the system and gather user feedback. | ||
|
|
||
| Once your Ory integration is stable and users are successfully authenticating with the new system, your migration is complete. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,36 @@ | ||
| --- | ||
| id: index | ||
| title: Migrate to Ory Network | ||
| sidebar_label: Migrate to Ory Network | ||
| sidebar_position: 1 | ||
| --- | ||
|
|
||
| # Migrate to Ory Network | ||
|
|
||
| Before you can migrate smoothly, you need a complete picture of how your identity management system works today. This step ensures | ||
| nothing gets missed — from everyday login flows to rare edge cases — and sets the foundation for mapping existing functionality to | ||
unatasha8 marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| Ory Network's equivalent capabilities. | ||
|
|
||
| :::info Why it matters | ||
|
|
||
| Not understanding your existing system’s behavior is the #1 cause of unexpected regressions during cutover. | ||
|
|
||
| ::: | ||
|
|
||
| With Ory Network, you gain full control, and with it, the ability to shape your system’s flows exactly to your needs. | ||
|
|
||
| 1. [Understand your current identity management system](migrate-to-ory) | ||
| 1. [Choose your migration strategy](migrate-strategies) | ||
| 1. [Create an Ory Network project](create-project) | ||
| 1. [Design your identity schema](design-id-schema) | ||
| 1. [Integrate your frontend](integrate-frontend) | ||
| 1. [Integrate your backend](integrate-backend) | ||
| 1. [Migrate your existing identities](migrate-identities) | ||
| 1. [Test and validate your integration](test-validate) | ||
| 1. [Go live](go-live) | ||
|
|
||
| ```mdx-code-block | ||
| import Help from '@site/docs/_common/need-help.mdx' | ||
|
|
||
| <Help/> | ||
| ``` | ||
unatasha8 marked this conversation as resolved.
Show resolved
Hide resolved
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,28 @@ | ||
| --- | ||
| id: integrate-backend | ||
| title: Integrate your backend | ||
| sidebar_label: Integrate your backend | ||
| sidebar_position: 1 | ||
| --- | ||
|
|
||
| When the frontend makes an API call to your backend, it will include the necessary cookies. Your backend must then forward these | ||
| cookies when calling the Ory API to validate the session. For example in a Go backend, you could use a | ||
| [middleware](../../getting-started/integrate-auth/go#validate-and-login) to intercept API requests and validate the session by | ||
| calling Ory’s toSession() method. Ensure that the cookies received from the front end are forwarded in this call. Since backend | ||
| calls to Ory’s API won’t automatically include cookies, you must manually attach the relevant cookies to these requests. This is | ||
| important for the backend to be able to check the session. | ||
|
|
||
| When using Ory to manage identities, it is best practice to store business logic in your application database and keep only | ||
| authentication-relevant data in Ory. Here’s a general approach: | ||
|
|
||
| 1. Configure [Ory Actions](../../kratos/hooks/configure-hooks) to send webhooks to your server after user registration or other | ||
| identity-related events. The webhook payload will include the data of the newly created identity. | ||
| 1. Upon receiving the webhook, your server can create a corresponding user record in your database. This allows your system to | ||
| link Ory-managed identities with your business logic. | ||
| 1. Establish a connection between the Ory identity and the user record in your database by storing the `user.id` in | ||
| `identity.metadata_public.id`. This ensures that subsequent API calls can easily map the Ory identity to the correct internal | ||
| user. More about metadata in the [Identity metadata & traits ](../../kratos/manage-identities/managing-users-identities-metadata) | ||
| documentation. | ||
| 1. Now when the frontend makes API calls containing the Ory cookie or token, the backend should verify the session using the | ||
| whoami API endpoint. This endpoint returns the session details, including the identity, allowing the backend to authenticate | ||
| the request and link it to the internal user record. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,31 @@ | ||
| --- | ||
| id: integrate-frontend | ||
| title: Integrate your frontend | ||
| sidebar_label: Integrate your frontend | ||
| sidebar_position: 1 | ||
| --- | ||
|
|
||
| To make authenticated API calls using Ory, start by properly configuring your domain and subdomains. By default the cookie domain | ||
| is set to the root domain (e.g., example.org) when you add a custom domain. This ensures that cookies can be shared across all | ||
| subdomains. | ||
|
|
||
| - Example subdomain structure: | ||
| - Run Ory at auth.example.org. | ||
| - Host your backend API at api.example.org. | ||
| - Serve your frontend UI at www.example.org or another designated subdomain. | ||
|
|
||
| This setup allows both your front end and back end to access the authentication session cookies managed by Ory. | ||
|
|
||
| To begin integrating Ory into your frontend, it's helpful to start with the | ||
| ["protect a page with login" guides](../../getting-started/overview) that cover the basics of developing with Ory for various | ||
| programming languages and frameworks, including SDK usage and essential setup steps. | ||
|
|
||
| Ory Network has two types of user interfaces. We recommend starting with the built-in | ||
| [Account Experience](../../account-experience/index.mdx), which offers a standard user interface, covering all self-service flows | ||
| with the option to style branding to get you up and running. If you prefer a custom user interface that matches your current | ||
| design 1:1, Ory allows you to create and style a custom UI that integrates seamlessly with your existing setup. You can do this | ||
| using the API directly, the SDK for your language, or - if you are working in the React ecosystem - Ory Elements. Ory Elements is | ||
| a component library designed to make building login, registration, and account pages for Ory easy. It is modular and customizable, | ||
| allowing you to use only the components you need while tailoring them to fit your implementation's design. The UI created with Ory | ||
| Elements changes dynamically to adapt to your Ory Network configuration. More details about customizing the user interface with | ||
| Ory Elements can be found [here](../../elements/index.mdx). |
unatasha8 marked this conversation as resolved.
Show resolved
Hide resolved
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,20 @@ | ||
| --- | ||
| id: map-to-orycap | ||
| title: Map your existing functionality to Ory Network capabilities | ||
| sidebar_label: Map your existing functionality to Ory Network capabilities | ||
| sidebar_position: 1 | ||
| --- | ||
|
|
||
| Using your list of identity-related flows, create a side-by-side table to map existing functionality to Ory Network’s equivalent | ||
| capabilities. While the majority of the time you'll find your existing functionality neatly maps to Ory's capabilities, now is the best time to | ||
| identify when it does not. Some examples: | ||
|
|
||
| - Not all vendors strickly comply with standards, whereas Ory does, so you might discover you need to | ||
| change how you implement functionality to be compliant. | ||
| - You might have a unique use case to solve that requires additional help from our support. | ||
|
|
||
| Table 1: An example of mapping functionality | ||
|
|
||
| | Existing Functionality | Ory Capabilities | | ||
| |---|---| | ||
| | JSON Web Tokens | [Ory Session cookies/tokens](https://www.ory.sh/docs/identities/session-to-jwt-cors)| |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,43 @@ | ||
| --- | ||
| id: migrate-identities | ||
| title: Migrate your existing identities | ||
| sidebar_label: Migrate your existing identities | ||
| sidebar_position: 3 | ||
| --- | ||
| With authentication now set up on your front end and back end, the next step is to prepare your existing user identities for | ||
| migration. | ||
|
|
||
| ## Get existing user identities ready for migration | ||
| If you're using a managed identity solution, it’s a good idea to start the export process early, especially if there's | ||
| no straightforward way to export the identities and you might need to go through a support process. | ||
|
|
||
| Export user data from your existing authentication solution or database and find out the hashing algorithm used to hash their | ||
| credentials. If your passwords are not hashed, you can bypass this step, as Ory will handle password hashing automatically during | ||
| the import process. Ory supports a range of hashing algorithms; if yours is supported, use the | ||
| [create identity API](../../reference/api#tag/identity/operation/createIdentity) to import your users. If the hashing algorithm isn't | ||
| supported or if you can't get the hashed passwords from your current authentication system, you may want to do a "graceful" | ||
| migration and use the password migration hook to migrate your existing users. You can find more details in the | ||
| [Import identities ](../../kratos/manage-identities/25_import-user-accounts-identities.mdx) documentation. | ||
|
|
||
| - For migrating from Auth0s, see [Migrate user identities from Auth0 to Ory](../migrate-from-auth0) | ||
|
|
||
| ## Import user identities | ||
|
|
||
| You can use the [create identity API] (../../reference/api#tag/identity/operation/batchPatchIdentities) to bulk import identities into | ||
| Ory. A maximum of 2000 identities can be created in a single request. If you need to import more identities, you need to split the | ||
unatasha8 marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| import into multiple requests. The endpoint accepts a JSON array of identities, each of which must have a create property that | ||
| holds the identity that should be created. You can find more details in the | ||
| [Import identities ](../../kratos/manage-identities/25_import-user-accounts-identities.mdx) documentation. | ||
|
|
||
| ### Phased migration for active sessions | ||
|
|
||
| Ory does not support the direct import of active sessions from your existing system. To ensure that users with active sessions | ||
| from the old system can continue accessing your services without needing to reauthenticate immediately, implement a transition | ||
| period during which both the old and new systems operate concurrently. During this period, all user authentication flows—including | ||
| login, registration, password recovery, and settings management—should be managed by Ory. However, your backend must be configured | ||
| to recognize and accept sessions from both the old system and Ory. | ||
|
|
||
| As the transition progresses, gradually phase out the old system. Once most or all active sessions from the old system have | ||
| expired or been replaced by new sessions in Ory, you can complete the migration to Ory exclusively. This gradual approach | ||
| minimizes user disruption and provides your development team with the time needed to resolve any potential issues that may arise | ||
| during the migration. | ||
unatasha8 marked this conversation as resolved.
Show resolved
Hide resolved
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,106 @@ | ||
| --- | ||
| id: migrate-strategies | ||
| title: Choose your migration strategy | ||
| sidebar_label: Choose your migration strategy | ||
| sidebar_position: 2 | ||
| --- | ||
|
|
||
| When migrating user data, there are two main steps in the migration process; the first is a backfill, in which existing data | ||
| is transferred from the old system to the new system, and the second is a cutover or "go-live event", in which users authenticate with the new | ||
| system for the first time. There are three main migration strategies that consider these steps as well as when you turn-off your old system. | ||
|
|
||
| The three main migration strategies are: | ||
|
|
||
| - **Big bang** - Migrate all users at once. | ||
| - **Stepped** - Migrate your applications or user segments individually. _This is the most common choice_. | ||
| - **Graceful** - Migrate when a user authenticates, running both solutions in parallel. | ||
|
|
||
| Each migration strategy has its strengths and challenges. Which migration strategy you choose depends on factors such as the | ||
| complexity of your system, the number of users, and your organization's tolerance for risk and downtime. | ||
|
|
||
| :::info | ||
|
|
||
| While your choice of migration strategy is mostly influenced by user data, if you have a complex system or are risk adverse, you might | ||
| choose your migration strategy based on its ability to breakdown the migration into a series of migrations. This lets you test your | ||
| processes in production by migrating less critical, sets of users or applications first and learning lessons to improve the migration process. | ||
|
|
||
| ::: | ||
|
|
||
| ### Big bang migration | ||
|
|
||
| In a big bang migration, also known as "offline migration", all user data is transferred at once, and a single "go-live" event is | ||
| scheduled, where all users start using the new system simultaneously. | ||
|
|
||
| #### Recommendation | ||
| A big bang migration is often not the best choice due to the risk and downtime, but it is recommended when: | ||
|
|
||
| - The number of users is low / app is simple | ||
| - Downtime isn't a problem | ||
| - You need to retire the current solution yesterday | ||
|
|
||
| #### Advantages of big bang migration | ||
|
|
||
| - Simplicity: Since there is only one "go-live", the migration process is easier to manage and plan. | ||
| - Time efficiency: The migration process happens in one go, reducing the time needed for the transition. | ||
| - Less complexity: There is no need to run two systems in parallel and you can retire the previous solution immediately. | ||
|
|
||
| #### Drawbacks of big bang migration | ||
|
|
||
| - High risk: If any issues occur during the cutover, the impact can be significant, affecting all users. | ||
| - Downtime: This approach may require planned system downtime to ensure data consistency, which can disrupt users. | ||
| - Increased preparation: Requires extensive planning and testing to mitigate risks, making it more resource-intensive during that | ||
| phase. | ||
|
|
||
| ### Stepwise migration | ||
|
|
||
| Stepwise migration, also called "application-based migration", involves transferring user data in phases, focusing on specific | ||
| applications, services, or user segments at a time. This approach results in multiple "go-lives", each affecting a defined group | ||
| of users. | ||
|
|
||
| #### Recommendation | ||
| A stepwise migration is the best choice in most cases, especially when: | ||
|
|
||
| - You manage multiple apps/segments of users with different underlying auth systems | ||
| - You need to keep active sessions live during the migration | ||
| - Downtime should be mostly avoided | ||
| - You have some time to migrate | ||
|
|
||
| #### Advantages of stepwise migration | ||
|
|
||
| - Reduced risk: By migrating in phases, issues are isolated to specific apps or user segments. | ||
| - Flexibility: Allows for adjustments and optimizations between phases based on lessons learned. | ||
| - Minimized/no downtime: Since the migration occurs in stages, downtime can be limited to smaller user groups or avoided | ||
| completely. | ||
|
|
||
| #### Drawbacks of stepwise migration | ||
|
|
||
| - Complex management: Multiple "go-lives" require more coordination and detailed planning, increasing operational complexity. | ||
| - Extended timeline: The migration process takes longer as it is broken down into phases. | ||
| - Resource demands: Running both systems in parallel during the transition can strain resources. | ||
|
|
||
| ### Graceful migration | ||
|
|
||
| Graceful migration - also called "slow migration", "rolling migration", or "online migration" - involves running both the old and | ||
| new systems in parallel, gradually migrating users as they authenticate. This approach features two "go-lives": the initial | ||
| application "go-live" and subsequent user-specific cutovers during login. | ||
|
|
||
| #### Recommendation | ||
| A graceful migration is a good choice when: | ||
|
|
||
| - You don't have access to hashed credentials or they are hashed with a proprietary algorithm | ||
| - Absolutely no downtime is acceptable | ||
| - Running the current solution until the end of migration isn't a problem | ||
|
|
||
| #### Advantages of graceful migration | ||
|
|
||
| - Low risk: The gradual transition reduces the risk of widespread issues, as only a few users are affected at any given time. | ||
| - No hashed credentials needed: Users are migrated during their "normal" authentication process, so you don't need to import | ||
| credentials. Great if you don't have access to the hashed credentials. | ||
| - No downtime: Both systems operate simultaneously until the migration is completed. | ||
|
|
||
| #### Drawbacks of graceful migration | ||
|
|
||
| - Extended migration period: The process takes longer as users are migrated individually over time. | ||
| - Increased complexity: Maintaining synchronization between two systems adds complexity to the migration process. | ||
| - Potential for data inconsistencies: If not carefully managed, there may be discrepancies between the two systems during the | ||
| transition period. |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.