Skip to content
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

refactor: [M3-8712] - Tanstack Reat Router rollout setup + betas routes migration #11049

Merged
merged 33 commits into from
Oct 16, 2024

Conversation

abailly-akamai
Copy link
Contributor

@abailly-akamai abailly-akamai commented Oct 5, 2024

Description 📝

This PR offers a safe pattern to be able to slowly roll out the new Tanstack routing migration.
The worry was to have to replace all of the routes and routing internals at once, resulting in a very large, hard to manage feature branch. Fortunately, this is not the case! The way we can incrementally implement the new routing is to accept to have the two routers cohabitating, and implement a cascading routing approach:

  • react-router-dom:
    • serve non-migrated routes
    • route not found: defer to migrationRouter (Tanstack)
  • tanstack-react-router
    • server migrated routes
    • route not found: render <NotFound />

The deferring logic lives in <MainContent /> where a wildcard catch-all will defer all unhandled routes to the tanstack <RouterProvider />. The POC is showing that there's no conflict resulting in this approach.

The <Link /> components will be replaced last to avoid any potential conflict and keep things simple (already confirmed that the current behavior is not causing any problem navigating to the new routes 🎆

Lastly, the PR introduces development tools to make out task easier and safer (linting, testing, inspecting)

Changes 🔄

  • Implement router deferring logic
  • Migrate /betas paths to the new routing
    • remove react-router-dom handling of Betas paths
    • replace utils
    • switch from using state navigation to params navigation for betas/<detail>
      • improve betas/{id} query to be able to be disabled
    • update tests
  • Add a new e2e smoke test for beta
  • Update mockServiceWorker declaration
  • Enable routes migration test
  • Improve path utils
  • Add missing lazy imports in a few files to remove build error messages

How to test 🧪

Verification steps

  • Pull code locally and update dependencies
  • Confirm the /betas feature has no regression
  • Confirm application routing behaves well everywhere else
  • Confirm tests are passing
  • Confirm being able to use the routing debugging tools in our DevTools

As an Author I have considered 🤔

Check all that apply

  • 👀 Doing a self review
  • ❔ Our contribution guidelines
  • 🤏 Splitting feature into small PRs
  • ➕ Adding a changeset
  • 🧪 Providing/Improving test coverage
  • 🔐 Removing all sensitive information from the code and PR description
  • 🚩 Using a feature flag to protect the release
  • 👣 Providing comprehensive reproduction steps
  • 📑 Providing or updating our documentation
  • 🕛 Scheduling a pair reviewing session
  • 📱 Providing mobile support
  • ♿ Providing accessibility support

packages/manager/.eslintrc.cjs Show resolved Hide resolved
packages/manager/public/mockServiceWorker.js Outdated Show resolved Hide resolved
*/}
<Route path="*">
<RouterProvider router={migrationRouter} />
</Route>
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the primary deferring change described in the PR summary.

const { data: beta, isError, isLoading } = useBetaQuery(betaId);
const navigate = useNavigate();
const { betaId } = useParams({ from: '/betas/signup/$betaId' });
const { data: beta, isError, isLoading } = useBetaQuery(betaId, !!betaId);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using params rather than state seems to me like an always better pattern - i don't see any drawback of doing so, hopefully i did not miss anything

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I had the same thought back when this was implemented #9544 (comment)

Should be fine

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With this migration we will see most feature/index.tsx deleted since the routing is now centralized

useQuery({
...betaQueries.beta(id),
enabled,
});
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just adding the enabled parameter since we now have a URL param to check if we want to run the query or not

return (
<React.Suspense fallback={<SuspenseLoader />}>
<Outlet />
{selfServeBetas ? <Outlet /> : <NotFound />}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

moving the <MainContent /> flag logic here, which is where it belongs now

@@ -8,5 +8,4 @@ export type RouterContext = {
isACLPEnabled?: boolean;
isDatabasesEnabled?: boolean;
isPlacementGroupsEnabled?: boolean;
selfServeBetas?: boolean;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not part of the context anymore since we're check this at the betas root route now

})
);
.filter((path) => path !== '/')
.filter(Boolean);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

just simplifying this util by using tanstack internals

Copy link
Contributor

@jaalah-akamai jaalah-akamai Oct 11, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice file cleanup 🧹

packages/manager/src/types/index.ts Outdated Show resolved Hide resolved
@abailly-akamai abailly-akamai marked this pull request as ready for review October 7, 2024 19:36
@abailly-akamai abailly-akamai requested a review from a team as a code owner October 7, 2024 19:36
@abailly-akamai abailly-akamai requested review from hana-akamai and cpathipa and removed request for a team October 7, 2024 19:36
Copy link

github-actions bot commented Oct 7, 2024

Coverage Report:
Base Coverage: 86.96%
Current Coverage: 87.06%

@bnussman-akamai bnussman-akamai requested a review from a team as a code owner October 8, 2024 16:46
@bnussman-akamai bnussman-akamai requested review from cliu-akamai and removed request for a team October 8, 2024 16:46
packages/manager/src/routes/index.tsx Outdated Show resolved Hide resolved
packages/manager/src/routes/index.tsx Outdated Show resolved Hide resolved
@abailly-akamai abailly-akamai force-pushed the M3-8712 branch 3 times, most recently from 433a136 to 01fb10a Compare October 10, 2024 13:31
cy.url().should('include', '/betas');
cy.url().should('not.include', 'signup');
});
});
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jdamore-linode! just wanted to mention you in here to take a quick look at the smoke test here. The feature's e2e coverage wasn't too exhaustive so that should add a lil' bit of confidence

@@ -53,6 +63,7 @@ describe('BetaDetails', () => {
const errorBetasList = renderWithTheme(
<BetaDetailsList
betas={[]}
dataQA="betas"
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

prop drilling a bit for testing purposes

<Typography>No betas found</Typography>
)}
</Stack>
)}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sorry, this was just an ugly loading experience. just a bit nicer with this update

packages/manager/.eslintrc.cjs Show resolved Hide resolved
packages/manager/src/routes/root.ts Outdated Show resolved Hide resolved
packages/manager/src/routes/routes.test.tsx Show resolved Hide resolved
packages/manager/src/routes/routes.test.tsx Show resolved Hide resolved
})
);
.filter((path) => path !== '/')
.filter(Boolean);
Copy link
Contributor

@jaalah-akamai jaalah-akamai Oct 11, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice file cleanup 🧹

@abailly-akamai abailly-akamai force-pushed the M3-8712 branch 2 times, most recently from 18004bd to b8b8a93 Compare October 11, 2024 20:40
Copy link
Member

@bnussman-akamai bnussman-akamai left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good! 🎉

I was trying to get some "transitionary" type-safety by doing this in our Link component:
Screenshot 2024-10-15 at 10 41 22 AM

But that lead me to find out that that the router's global module override doesn't seem to be working as expected. (See comment in packages/manager/src/routes/index.tsx)

packages/manager/src/routes/routes.test.tsx Outdated Show resolved Hide resolved
packages/manager/src/routes/routes.test.tsx Outdated Show resolved Hide resolved
@@ -70,6 +70,26 @@ export const router = createRouter({
declare module '@tanstack/react-router' {
interface Register {
// This infers the type of our router and registers it across the entire project
router: typeof router;
// router: typeof router;
migrationRouter: MigrationRouter;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe this is essentially making the router untyped / any.

I tried updating it restore the type-safety:

Suggested change
migrationRouter: MigrationRouter;
router: MigrationRouter;

but this introduces many TypeScript errors because of all of the work we've done for routes that are not yet in the migrationRouter.

Any thoughts here? Will we just have to proceed with an untyped router until the end of this migration?

Maybe we could do something hacky like this, but it might cause us more trouble than we want

Suggested change
migrationRouter: MigrationRouter;
router: typeof router | MigrationRouter;

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@bnussman of course! 🤦 thx for catching.

So look at 75b20f0

I reintroduced the main router type for the applciation, which also forced me to cast AnyRouter in a few places. Still much better! and allowed to get <Link /> to show path suggestion which is a good idea.

We still have good typing but will not narrow to the migrationRouter routes which I was hoping to be able to do. We're half way there and get at least stronger rail guards and working suggestions 👍

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice. Sounds good to me! 🚀

@bnussman-akamai bnussman-akamai added the Approved Multiple approvals and ready to merge! label Oct 15, 2024
@abailly-akamai abailly-akamai merged commit ed30c6e into linode:develop Oct 16, 2024
21 of 23 checks passed
Copy link

cypress bot commented Oct 16, 2024

Cloud Manager E2E    Run #6684

Run Properties:  status check failed Failed #6684  •  git commit ed30c6e1bb: refactor: [M3-8712] - Tanstack Reat Router rollout setup + betas routes migratio...
Project Cloud Manager E2E
Run status status check failed Failed #6684
Run duration 34m 32s
Commit git commit ed30c6e1bb: refactor: [M3-8712] - Tanstack Reat Router rollout setup + betas routes migratio...
Committer Alban Bailly
View all properties for this run ↗︎

Test results
Tests that failed  Failures 4
Tests that were flaky  Flaky 8
Tests that did not run due to a developer annotating a test with .skip  Pending 2
Tests that did not run due to a failure in a mocha hook  Skipped 0
Tests that passed  Passing 433

Tests for review

Failed  oneClickApps/one-click-apps.spec.ts • 1 failed test

View Output Video

Test Artifacts
OneClick Apps (OCA) > Lists all the OneClick Apps Screenshots Video
Failed  placementGroups/delete-placement-groups.spec.ts • 1 failed test

View Output Video

Test Artifacts
Placement Group deletion > can delete with Linodes assigned when unexpected error show up and retry Screenshots Video
Failed  kubernetes/lke-update.spec.ts • 2 failed tests

View Output Video

Test Artifacts
LKE cluster updates > can upgrade to high availability Screenshots Video
LKE cluster updates > can upgrade kubernetes version from the details page Screenshots Video
Flakiness  linodes/clone-linode.spec.ts • 1 flaky test

View Output Video

Test Artifacts
clone linode > can clone a Linode from Linode details page Screenshots Video
Flakiness  objectStorageGen2/bucket-create-gen2.spec.ts • 3 flaky tests

View Output Video

Test Artifacts
Object Storage Gen2 create bucket tests > can create a bucket with E1 endpoint type Screenshots Video
Object Storage Gen2 create bucket tests > can create a bucket with E2 endpoint type Screenshots Video
Object Storage Gen2 create bucket tests > can create a bucket with E3 endpoint type Screenshots Video
Flakiness  linodes/rebuild-linode.spec.ts • 1 flaky test

View Output Video

Test Artifacts
rebuild linode > cannot rebuild a provisioning linode Screenshots Video
Flakiness  nodebalancers/smoke-create-nodebal.spec.ts • 1 flaky test

View Output Video

Test Artifacts
create NodeBalancer > displays API errors for NodeBalancer Create form fields Screenshots Video
Flakiness  account/account-logout.spec.ts • 1 flaky test

View Output Video

Test Artifacts
Logout Test > can logout the account and redirect to login endpoint Screenshots Video

The first 5 flaky specs are shown, see all 6 specs in Cypress Cloud.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Approved Multiple approvals and ready to merge! Routing Refactor
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants