Skip to content

Commit 00ca767

Browse files
tommasiniNicolasMassartCal-L
authored
migrations guidelines (#96)
Co-authored-by: Nico MASSART <[email protected]> Co-authored-by: Cal Leung <[email protected]>
1 parent 8609fc7 commit 00ca767

File tree

2 files changed

+63
-0
lines changed

2 files changed

+63
-0
lines changed

README.md

+1
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ This is a living repository — nothing is set in stone! If you're member of Met
99
- [Contributor Code of Conduct](https://github.com/MetaMask/.github/blob/main/CODE_OF_CONDUCT.md)
1010
- [Engineering Principles](./docs/engineering-principles.md)
1111
- [JavaScript Guidelines](./docs/javascript.md)
12+
- [Migrations Best Practices](./docs/migrations-guidelines.md)
1213
- [Performance Tracing Guidelines](./docs/performance-tracing.md)
1314
- [Pull Requests Guide](./docs/pull-requests.md)
1415
- [React Guidelines](./docs/react.md)

docs/migrations-guidelines.md

+62
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
# Migration and Testing Guidelines
2+
3+
## Overview
4+
5+
This document outlines best practices and guidelines for writing migration scripts and their corresponding test cases.
6+
7+
The focus is on ensuring data integrity, handling errors gracefully, and maintaining consistency across our applications versions.
8+
9+
We always look for improvement, if you see anything that could be improved, please open a PR against this guidelines.
10+
11+
You can also check an example of a migration on MetaMask mobile app [here](https://github.com/MetaMask/metamask-mobile/blob/1855bd674e33bb0ece06fb6d8f09a4e5df46a108/app/store/migrations/044.ts#L1)
12+
13+
## Migration Guidelines
14+
15+
1. **State Integrity Checks**:
16+
17+
Validates the state's structure and types before migration, using specific functions to ensure data meets expectations. Halts migration if inconsistencies are detected, preventing data corruption.
18+
19+
- State's on migrations are type `unknown`, it's crucial to validate state integrity before proceeding, we only migrate when structure and types meets our expectations,
20+
- Validate the state and its nested properties using functions like `isObject` and `hasProperty` from `@metamask/utils`,
21+
- Prevent data corruption by halting the migration on any inconsistencies and logging errors.
22+
23+
2. **Error Handling**:
24+
25+
Logs detailed errors and halts the migration if potential data corruption is identified, ensuring issues are addressed before proceeding.
26+
27+
- Log errors with `captureException` from Sentry, which is crucial for diagnosing issues post-migration,
28+
- Ensure that error messages are descriptive: include the migration number and a clear description of the issue,
29+
- If an exception is detected, indicating potential data corruption, halt the migration process and return the intial state,
30+
31+
3. **Return State**:
32+
33+
Completes the migration by returning the state, modified or not, ensuring a seamless transition to subsequent migrations.
34+
35+
- Always return the state at the end of the migration function, whether it was modified or not,
36+
- Returning the state ensures that the migration process completes and the state is passed to the next migrations.
37+
38+
## Testing Guidelines
39+
40+
1. **Initial State Setup**:
41+
42+
- Create an initial state that reflects possible real-world scenarios, including edge cases,
43+
- if needed, create multiple initial states and use them each in a test for this specific case,
44+
45+
2. **Invalid State Scenarios**:
46+
47+
- Test how the migration handles invalid states, including null values, incorrect types, and missing properties,
48+
- Ensure that the migration logs the appropriate errors without modifying and corrupting the state.
49+
50+
3. **Error Assertions**:
51+
52+
- Verify that errors are logged correctly for invalid states or unexpected conditions,
53+
54+
4. **Ensure State Immutability**:
55+
56+
- Always use deep cloning on the old state before passing it to the migration function in tests. For example, use `cloneDeep` from `lodash`.
57+
- Deep cloning preserves the integrity of your test data across different test cases.
58+
- Ensures the original state object is not mutated during the migration process.
59+
- guarantees that each test case runs on an correct, clean copy of the state.
60+
- Never mutate the state directly as this can:
61+
- lead to hard-to-track bugs and false positives or negatives test results.
62+
- start subsequent tests with the original state as intended.

0 commit comments

Comments
 (0)