|
| 1 | +# Snap migration process guide |
| 2 | + |
| 3 | +This document outlines the process for migrating a MetaMask first-party Snap into the `internal-snaps` monorepo. The migration target is assumed to be based off template-snap-monorepo. |
| 4 | + |
| 5 | +> Prerequisites: `internal-snaps` has been created and prepared to host snaps, its CI is green, and the host repo grants merge access for the migration PRs. The migration target must be in a clean state with all in-flight work merged or rebased. Install `git-filter-repo`. |
| 6 | +
|
| 7 | +--- |
| 8 | + |
| 9 | +## Phase A: Preparation in the original repository |
| 10 | + |
| 11 | +### [PR#1] Add the migration notice to the README |
| 12 | + |
| 13 | +Add this banner to the top of `README.md`: |
| 14 | + |
| 15 | +```markdown |
| 16 | +<table><tr><td><p align="center"><b>⚠️ PLEASE READ ⚠️</b></p><p align="center">This package is currently being migrated to our <a href="<https://github.com/MetaMask/internal-snaps>"><code>internal-snaps</code></a> monorepo. Please do not make any commits to this repository while this migration is taking place, as they will not be transferred over. Also, please re-open PRs that are under active development in the <code>internal-snaps</code> repo.</p></td></tr></table> |
| 17 | +``` |
| 18 | + |
| 19 | +### [PR#2] Align dependency versions and TypeScript / ESLint / Prettier / Oxfmt configurations with `internal-snaps` |
| 20 | + |
| 21 | +- If the snap's dependency versions are ahead of `internal-snaps`, update the monorepo root first; otherwise, bump the snap to match. |
| 22 | +- Copy the relevant tooling configs (`tsconfig.base.json` compiler flags, `.prettierrc.js`, `.oxfmtrc.json`, the shared ESLint config) so the snap satisfies them on the monorepo's tooling. |
| 23 | +- Preserve any TypeScript compiler flags enabled in the snap but not in the monorepo. |
| 24 | +- **Yarn version**: if the source repo (or the `packages/snap/package.json`) pins `yarn@3.x`, upgrade to Yarn 4 (`yarn set version berry && yarn set version stable`) and re-resolve `yarn.lock` before merging. The monorepo runs Yarn 4; a yarn-3 lockfile will be re-generated on first install in the monorepo regardless, but bumping in the source repo first avoids surprise dependency-resolution diffs at integration time. |
| 25 | +- Resolve any errors that result from the alignment. |
| 26 | + |
| 27 | +### [PR#3] Reconcile with `template-snap-monorepo` |
| 28 | + |
| 29 | +Compare `<original-repo>/packages/snap` against the current sample-snap from `internal-snaps` and add anything missing: eslint, jest config, `LICENSE`, etc. |
| 30 | + |
| 31 | +### [PR#4] Cut a final release from the source repo |
| 32 | + |
| 33 | +Cut and publish a final release of the package from the original repository. All subsequent releases happen from `internal-snaps`. Keep the release tag for the changelog link in PR#7. |
| 34 | + |
| 35 | +--- |
| 36 | + |
| 37 | +## Phase B: Staging from `internal-snaps`'s `merged-packages/` |
| 38 | + |
| 39 | +### [PR#5] Migrate the source repo's git history into `merged-packages/` |
| 40 | + |
| 41 | +> [!WARNING] |
| 42 | +> |
| 43 | +> - **Do not rebase** the migration branch: it will disrupt the imported history. |
| 44 | +> - **Merge the PR without squashing.** Contact a maintainer to temporarily enable merge commits into `main`. |
| 45 | +> - Coordinate with the team to minimise the time the PR stays open; superfluous merge commits to `main` will pollute the migrated git history. If history pollution occurs, replay the migration on a fresh branch before merging. |
| 46 | +
|
| 47 | +1. Navigate to a temporary directory: `cd /tmp`. |
| 48 | +2. Clone a fresh copy of the source repo: `git clone <https://github.com/MetaMask/snap-tron-wallet`>. **Do not** reuse an existing clone: the next step rewrites history irreversibly. |
| 49 | +3. `cd snap-tron-wallet`. |
| 50 | +4. Rewrite history so the snap package lives at the staging path: |
| 51 | + This both isolates the snap package (drops the `packages/site/` test-dapp and any other top-level files) and moves it into the staging directory in a single rewrite. If the source repo is **not** itself a monorepo (i.e. the snap lives at the repo root), use `-path-rename :merged-packages/<name>-snap/` instead. |
| 52 | + `bash |
| 53 | +git filter-repo \\ |
| 54 | + --path packages/snap/ \\ |
| 55 | + --path-rename packages/snap/:merged-packages/tron-wallet-snap/ |
| 56 | +` |
| 57 | +5. `cd` into your local checkout of `internal-snaps`. |
| 58 | +6. Add the rewritten repo as a remote: `git remote add tron-wallet-snap /tmp/snap-tron-wallet`. |
| 59 | +7. Fetch history without tags: `git fetch tron-wallet-snap --no-tags`. |
| 60 | +8. Create the migration branch: `git checkout -b migrate-tron-wallet-snap`. |
| 61 | +9. Merge the snap into the monorepo: `git merge --allow-unrelated-histories tron-wallet-snap/main`. |
| 62 | +10. Open a pull request in `internal-snaps` that reflects the above changes. |
| 63 | + |
| 64 | +### [PR#6] Reset the CHANGELOG, linking back to the old repository |
| 65 | + |
| 66 | +In `merged-packages/tron-wallet-snap/CHANGELOG.md`: |
| 67 | + |
| 68 | +- Replace the file with a fresh CHANGELOG that contains only an empty `## [Unreleased]` section (no historical releases). |
| 69 | +- Add a `### Changed` entry under `## [Unreleased]` explaining that the package was migrated, and include a link to the old changelog: |
| 70 | + > This package was migrated from `MetaMask/snap-tron-wallet`. See the source repository for the original changelog. |
| 71 | +
|
| 72 | +do **not** try to rewrite the old tag-diff links to point at `internal-snaps`. The old tags do not exist in the new repo, so the links would 404. |
| 73 | + |
| 74 | +### [PR#7] Remove files and directories replaced by the monorepo root |
| 75 | + |
| 76 | +Inside `merged-packages/tron-wallet-snap/`: |
| 77 | + |
| 78 | +- **Remove**: `.github/`, `.git*`, `.depcheckrc.{json,yml}`, `.yarn/`, `.yarnrc.yml`, `yarn.lock`, `.editorconfig`, `.eslint*`, `.prettier*`, `.oxfmtrc*`, `.nvm*`, `lavamoat/`, `simple-git-hooks` config, `node_modules/`, `dist/`, `coverage/`, real `.env` files (keep `.env.example` / `.env.sample`), and top-level `LICENSE` if present alongside `LICENSE.MIT0` / `LICENSE.APACHE2`. |
| 79 | +- **Keep**: `src/`, `tests/`, `integration-test/` (if present), `docs/` (snap-internal docs), `scripts/` (snap-internal helpers like `build-preinstalled-snap.js`, `populate-en-locale.js` / `populate-locale.js`, `update-manifest-local.js`), `CHANGELOG.md`, `package.json`, `README.md`, `jest.config.js`, `jest.integration.config.js`, `jest.setup.ts` (if present), custom jest transformers (e.g. `svg-transformer.js`), `babel.config.js` (if jest uses babel), `tsconfig*.json`, `snap.manifest.json`, `snap.config.ts`, `messages.json`, `openrpc.json`, `keyring.openrpc.json`, `images/`, `locales/`, `crowdin.yml`, `.env.example` / `.env.sample`, `LICENSE.MIT0`, `LICENSE.APACHE2`. |
| 80 | + |
| 81 | +Carry over any snap-specific Yarn patches into the monorepo root `.yarn/patches/`. For Tron, this means `tronweb-npm-6.1.0-771b242b6a.patch`. (e.g., Solana and Bitcoin have no patches; this step is no-op for them.) |
| 82 | + |
| 83 | +### [PR#8] Replace config files |
| 84 | + |
| 85 | +- `tsconfig.json`: See sample-snap config. |
| 86 | +- `jest.config.js`: keep the snap's existing config (it already does what `@metamask/snaps-jest` expects). Verify its `preset` / `transform` / custom `setupFilesAfterEnv` / custom transformer references (e.g. `<rootDir>/svg-transformer.js`) still resolve under the monorepo's hoisted dependencies. Preserve any `coverageThreshold`, `collectCoverageFrom`, `coveragePathIgnorePatterns`, and `testMatch` overrides. |
| 87 | +- If `jest.integration.config.js` (or any other config file) uses ESM `export default` while the rest of the snap is CommonJS, convert it to `module.exports` (or rename to `.mjs`); ESLint in the monorepo rejects the mismatch. |
| 88 | +- Keep `babel.config.js` if jest uses babel for transformation. |
| 89 | +- Add tsconfig reference paths for upstream dependencies: snaps in `internal-snaps` are leaf packages and do not consume monorepo workspaces, but this may change in the future. |
| 90 | + |
| 91 | +### [PR#9] Align dependencies and build scripts with the monorepo |
| 92 | + |
| 93 | +- Remove redundant build scripts already provided by the monorepo root. |
| 94 | +- Remove redundant dev dependencies already listed at the monorepo root. **Exception**: do not remove `typescript`. |
| 95 | +- Align dependency versions with the monorepo: |
| 96 | + - If the snap version is ahead, decrement to match the monorepo (or bump the monorepo in a preceding PR). |
| 97 | + - If behind, bump only when there are no resulting breaking changes to resolve. |
| 98 | +- **Migrate root-level `resolutions`**: copy any entries from the source repo's root `package.json#resolutions` into the monorepo root `package.json#resolutions`, merging with the existing set. Common offenders: `@metamask/snaps-sdk` (Solana, Bitcoin), `@types/react` / `@types/react-dom` (Solana). If snaps in the monorepo disagree on a pinned version, raise it to a coordination decision before merging. |
| 99 | +- **Migrate LavaMoat allow-list entries**: Run `yarn allow-scripts auto` to |
| 100 | +- **Move `crowdin.yml`** from the source repo root (or `packages/snap/`) into the package directory so the monorepo's per-package Crowdin tooling treats it independently. |
| 101 | +- **Snap-specific**: keep `scripts.build` starting with `mm-snap build` (the monorepo constraint only requires the prefix; chaining `&& yarn locale:build && yarn build-preinstalled-snap`: or `build:locale`, depending on the snap: is supported). Add `scripts.prepublishOnly: mm-snap manifest` so the manifest shasum stays in sync at publish time. |
| 102 | +- Edit `package.json` metadata: |
| 103 | + - `repository.url` → `https://github.com/MetaMask/internal-snaps.git`. |
| 104 | + - `homepage` → `https://github.com/MetaMask/internal-snaps/tree/main/packages/tron-wallet-snap#readme`. |
| 105 | + - `bugs.url` → `https://github.com/MetaMask/internal-snaps/issues`. |
| 106 | + - `license` → `(MIT-0 OR Apache-2.0)`. |
| 107 | + - `files`: includes `dist/`, `snap.manifest.json`, `images/`, `locales/`. |
| 108 | + - Add `scripts.changelog:update`: `../../scripts/update-changelog.sh @metamask/tron-wallet-snap`. |
| 109 | + - Add `scripts.changelog:validate`: `../../scripts/validate-changelog.sh @metamask/tron-wallet-snap`. |
| 110 | + - Add `scripts.since-latest-release`: `../../scripts/since-latest-release.sh`. |
| 111 | + |
| 112 | +### [PR#10] Update the README to reflect non-root-package status |
| 113 | + |
| 114 | +- Preserve the opening sentence/paragraph that introduces the snap. |
| 115 | +- Add or modify an "Installation" section (see other snap READMEs once they exist, or model after a core non-root package). |
| 116 | +- Preserve the "Usage" section. |
| 117 | +- Remove "Test", "Build" and other instructions for common development tasks (these now live in the monorepo's `docs/processes/`). |
| 118 | +- Add a "Contributing" section that links to the monorepo's `docs/processes/`. |
| 119 | + |
| 120 | +--- |
| 121 | + |
| 122 | +## [PR#11] Phase C: Integration into `packages/` |
| 123 | + |
| 124 | +All Phase C steps go in a **single** PR. Coordinate with the team to minimise the time it stays open. |
| 125 | + |
| 126 | +### 1. Move the package from `merged-packages/` to `packages/` |
| 127 | + |
| 128 | +```bash |
| 129 | +git mv merged-packages/tron-wallet-snap packages/tron-wallet-snap |
| 130 | +yarn install |
| 131 | +``` |
| 132 | + |
| 133 | +Check the snap's tests pass: `yarn workspace @metamask/tron-wallet-snap run test`. |
| 134 | + |
| 135 | +### 2. Linter and constraints fixes |
| 136 | + |
| 137 | +- `yarn constraints --fix` then `yarn constraints` until clean. |
| 138 | +- Verify `scripts.changelog:validate` is present in `package.json` (added in PR#10). |
| 139 | +- `yarn allow-scripts auto` if the snap brought new lifecycle scripts. Commit the LavaMoat policy update. |
| 140 | +- `yarn lint:eslint --fix --suppress-all` to absorb existing snap-side findings into `eslint-suppressions.json`, then `yarn lint` to confirm clean. |
| 141 | +- Update `teams.json`: add `"metamask/tron-wallet-snap": "@MetaMask/networks"` (or the owning team). |
| 142 | +- Update `.github/CODEOWNERS`: append `/packages/tron-wallet-snap/ @MetaMask/networks`. |
| 143 | + |
| 144 | +### 4. Resolve or TODO downstream errors |
| 145 | + |
| 146 | +If the migration breaks anything inside the monorepo (rare, since snaps are leaf packages): |
| 147 | + |
| 148 | +- Resolve simple errors in this PR. |
| 149 | +- Mark complex/blocked errors with `@ts-expect-error TODO:` and file a follow-up issue. |
| 150 | + |
| 151 | +### 5. Record changes in CHANGELOG `[Unreleased]` |
| 152 | + |
| 153 | +In `packages/tron-wallet-snap/CHANGELOG.md` under `## [Unreleased]`, e.g.: |
| 154 | + |
| 155 | +- `### Changed` |
| 156 | + - Migrated package from `MetaMask/snap-tron-wallet` to `MetaMask/internal-snaps` (no consumer-visible behaviour change). |
| 157 | + - Re-licensed split into `LICENSE.MIT0` + `LICENSE.APACHE2` files (SPDX expression unchanged). |
| 158 | + |
| 159 | +### 6. Finalize merge |
| 160 | + |
| 161 | +- Confirm all tests pass for the snap and for the rest of the monorepo (CI must be green). |
| 162 | +- Double-check that any changes that landed on `main` while the PR was open are correctly merged in. |
| 163 | + |
| 164 | +--- |
| 165 | + |
| 166 | +## Phase D: Clean-up and release |
| 167 | + |
| 168 | +### Source repo (`snap-tron-wallet`) |
| 169 | + |
| 170 | +1. **Transfer open issues** from the source repo into `internal-snaps` using GitHub's _Transfer issue_ feature. Prepend the title with `[tron-wallet-snap]`. |
| 171 | +2. **Lock open PRs** (do not provide a reason). Leave this comment: |
| 172 | + |
| 173 | + ```markdown |
| 174 | + This library has now been migrated into the internal-snaps monorepo. This PR has been locked and this repo will be archived shortly. Going forward, releases of this library will only include changes made in the internal-snaps repo. |
| 175 | + |
| 176 | + - Please push this branch to internal-snaps and open a new PR there. |
| 177 | + - Optionally, add a link pointing to the discussion in this PR to provide context. |
| 178 | + ``` |
| 179 | + |
| 180 | + For important PRs, manually migrate them into `internal-snaps` or create follow-up tickets. |
| 181 | + |
| 182 | +3. **[PR#12] Replace the migration notice in `snap-tron-wallet/README.md`** with the archive notice (this replaces the banner added in PR#1): |
| 183 | + |
| 184 | + ```html |
| 185 | + <table> |
| 186 | + <tr> |
| 187 | + <td> |
| 188 | + <p align="center"><b>⚠️ PLEASE READ ⚠️</b></p> |
| 189 | + <p align="center"> |
| 190 | + This package has been migrated to our |
| 191 | + <a href="<https://github.com/MetaMask/internal-snaps>" |
| 192 | + ><code>internal-snaps</code></a |
| 193 | + > |
| 194 | + monorepo, and this repository has been archived. Please note that all |
| 195 | + future development and feature releases will take place in the |
| 196 | + <a href="<https://github.com/MetaMask/internal-snaps>" |
| 197 | + ><code>internal-snaps</code></a |
| 198 | + > |
| 199 | + repository. |
| 200 | + </p> |
| 201 | + </td> |
| 202 | + </tr> |
| 203 | + </table> |
| 204 | + ``` |
| 205 | + |
| 206 | +4. **Archive the source repository**. Contact a maintainer to perform this step. Keep tags and the final release intact for npm-package history continuity. |
| 207 | + |
| 208 | +### `internal-snaps` |
| 209 | + |
| 210 | +1. **Fix any `@ts-expect-error TODO:` annotations** added during PR#12. Do this before the first post-migration release if possible. |
| 211 | +2. **[PR#13] Cut the first post-migration release** with `yarn create-release-branch -i`. |
| 212 | +3. **Verify the preview-build workflow** by opening a no-op PR against the new package and confirming the preview-publish job posts. |
0 commit comments