|
| 1 | +# Publishing and using preview builds |
| 2 | + |
| 3 | +Preview builds are pre-production versions of packages. Unlike [local builds](./local-builds.md), they are published to NPM (albeit under a separate NPM namespace) and can therefore be treated the same way as production releases in CI. Because of this, we recommend using preview builds for testing. |
| 4 | + |
| 5 | +Generally, when working with preview builds, you will follow this process: |
| 6 | + |
| 7 | +1. Create a branch in your clone of this repo |
| 8 | +2. Work on changes to your package(s) |
| 9 | +3. [Publish preview builds](#publishing-preview-builds) |
| 10 | +4. Switch to the project and [configure it to use the new preview builds](#using-preview-builds) |
| 11 | +5. Repeat steps 2-4 as necessary |
| 12 | + |
| 13 | +## Publishing preview builds |
| 14 | + |
| 15 | +To publish preview builds: |
| 16 | + |
| 17 | +1. Create a pull request with the changes to your package(s). |
| 18 | +2. Post a comment on the pull request with the text `@metamaskbot publish-previews`. The `publish-preview` GitHub action will kick off to generate and publish preview builds for all packages in the monorepo. |
| 19 | +3. After a few minutes, you will see a new comment that lists the newly published packages along with their versions. |
| 20 | + |
| 21 | +<details><summary><b>Publishing preview builds as an independent contributor</b></summary> |
| 22 | +<br/> |
| 23 | +Note that the steps above will only work if you are a member of the MetaMask engineering team on GitHub. If you are not, you'll need to follow some different steps: |
| 24 | + |
| 25 | +1. First, you'll need access to an NPM organization under which the preview builds will be published. If you have not already done so, you can either [create a new organization](https://www.npmjs.com/org/create) or [convert your existing username into an organization](https://www.npmjs.com/org/upgrade). |
| 26 | +2. Open the `package.json` for each package that you want to publish, and change the NPM scope in the package's name from `@metamask` to reflect your NPM organization. |
| 27 | +3. Run the following command to create and publish preview builds for all packages in the monorepo (replacing `NPM_ORG` as appropriate): |
| 28 | + |
| 29 | + ```bash |
| 30 | + yarn prepare-preview-builds "@<NPM_ORG>" "$(git rev-parse --short HEAD)" |
| 31 | + yarn build |
| 32 | + yarn publish-previews |
| 33 | + ``` |
| 34 | + |
| 35 | + You will see a list of the newly published packages along with their versions. |
| 36 | + </details> |
| 37 | + |
| 38 | +## Using preview builds |
| 39 | + |
| 40 | +To simulate production as best as possible, there are different instructions for using preview builds depending on whether the changes to a package you are testing are breaking or non-breaking. |
| 41 | + |
| 42 | +### Testing non-breaking changes to a package |
| 43 | + |
| 44 | +If you have made non-breaking changes to the package you want to test, and therefore plan on bumping the _minor_ or _patch_ part of that package's version, follow these steps: |
| 45 | + |
| 46 | +1. In the project, open `package.json` and locate the entry in `dependencies` for the package. Take note of the major part of the version. |
| 47 | + |
| 48 | +2. Run `yarn why @metamask/<PACKAGE_NAME>`, replacing `PACKAGE_NAME` as appropriate. You will see output like this: |
| 49 | + |
| 50 | + ``` |
| 51 | + ├─ @metamask/parent-controller-1@npm:93.1.0 |
| 52 | + │ └─ @metamask/my-controller@npm:12.1.1 (via npm:^12.1.1) |
| 53 | + │ |
| 54 | + ├─ @metamask/parent-controller-2@npm:94.1.0 |
| 55 | + │ └─ @metamask/my-controller@npm:12.1.1 (via npm:^12.1.1) |
| 56 | + │ |
| 57 | + ├─ @metamask/parent-controller-3@npm:94.1.0 [abc9d] |
| 58 | + │ └─ @metamask/my-controller@npm:12.1.1 [57677] (via npm:^12.1.1 [15228]) |
| 59 | + ... |
| 60 | + │ |
| 61 | + └─ metamask@workspace:. |
| 62 | + └─ @metamask/my-controller@npm:12.1.1 [57677] (via npm:^12.1.0 [abc9d]) |
| 63 | + ``` |
| 64 | + |
| 65 | + Take note of all the version ranges that match the major version you saw earlier (here, we are looking for all version ranges that start with `^12`). |
| 66 | + |
| 67 | +3. Back in `package.json`, locate the section responsible for resolution overrides (or create one if it doesn't exist). If you're using Yarn, this is `resolutions`; if you're using NPM or any other package manager, this is `overrides`. |
| 68 | + |
| 69 | +4. For each version range, add a new entry that looks like this: |
| 70 | + |
| 71 | + ```json |
| 72 | + "@metamask/<PACKAGE_NAME>@<VERSION_RANGE>": "npm:@<NPM_ORG>/<PACKAGE_NAME>@<PREVIEW_VERSION>" |
| 73 | + ``` |
| 74 | + |
| 75 | + where: |
| 76 | + |
| 77 | + - `PACKAGE_NAME` is the name of your package |
| 78 | + - `VERSION_RANGE` is one of the version ranges you noted in step 2 |
| 79 | + - `NPM_ORG` is the NPM scope that the preview build is published under (note: this is _not_ `@metamask`) |
| 80 | + - `PREVIEW_VERSION` is the version string of the preview build (note: this should _not_ start with `^`) |
| 81 | + |
| 82 | +5. Run `yarn install` to apply the changes. |
| 83 | + |
| 84 | +6. Run `yarn why @metamask/<PACKAGE_NAME>` again to confirm that all of the instances of the package you saw when you ran this command earlier are now using your preview build. |
| 85 | + |
| 86 | +> **Example:** |
| 87 | +> |
| 88 | +> - You have non-breaking changes to `@metamask/controller-utils` you want to test |
| 89 | +> - You're in a MetaMask client repo |
| 90 | +> - `@metamask/controller-utils` is listed at `^1.1.4`, and `yarn why` reveals that `^1.0.1` and `^1.1.3` are also being used as version ranges in the dependency tree |
| 91 | +> - You want to use the preview version `1.1.4-preview-e2df9b4` |
| 92 | +> |
| 93 | +> In this case, you would go to `resolutions` and add these lines: |
| 94 | +> |
| 95 | +> ```json |
| 96 | +> "@metamask/controller-utils@^1.0.1": "npm:@metamask-previews/[email protected]", |
| 97 | +> "@metamask/controller-utils@^1.1.3": "npm:@metamask-previews/[email protected]", |
| 98 | +> "@metamask/controller-utils@^1.1.4": "npm:@metamask-previews/[email protected]", |
| 99 | +> ``` |
| 100 | +
|
| 101 | +### Testing breaking changes to a package |
| 102 | +
|
| 103 | +If you have made breaking changes to the package you want to test, and therefore plan on bumping the _major_ part of that package's version, follow these steps: |
| 104 | +
|
| 105 | +1. In the project, open `package.json`, and: |
| 106 | +
|
| 107 | + - Note the name of the package. |
| 108 | + - Locate the section responsible for resolution overrides (or create one if it doesn't exist). If you're using Yarn, this is `resolutions`; if you're using NPM or any other package manager, this is `overrides`. |
| 109 | +
|
| 110 | +2. Add a new entry that looks like this: |
| 111 | +
|
| 112 | + ```json |
| 113 | + "<ROOT_PACKAGE_NAME>@workspace:./@metamask/<PACKAGE_NAME>": "npm:@<NPM_ORG>/<PACKAGE_NAME>@<PREVIEW_VERSION>" |
| 114 | + ``` |
| 115 | +
|
| 116 | + where: |
| 117 | + |
| 118 | + - `ROOT_PACKAGE_NAME` is the value of the `name` field at the top of `package.json` |
| 119 | + - `NPM_ORG` is the NPM scope that the preview build is published under (note: this is _not_ `@metamask`) |
| 120 | + - `PACKAGE_NAME` is the name of your package |
| 121 | + - `PREVIEW_VERSION` is the version string of the preview build (note: this should _not_ start with `^`) |
| 122 | + |
| 123 | +3. Run `yarn install` to apply the changes. |
| 124 | + |
| 125 | +> **Example:** |
| 126 | +> |
| 127 | +> - You have breaking changes to `@metamask/network-controller` you want to test |
| 128 | +> - You're in a MetaMask client repo |
| 129 | +> - The `name` in `package.json` is "metamask" |
| 130 | +> - `@metamask/network-controller` is listed at `^12.4.9` |
| 131 | +> - You want to use the preview version `12.4.9-preview-e2df9b4` |
| 132 | +> |
| 133 | +> In this case, you would go to `resolutions` and add this line: |
| 134 | +> |
| 135 | +> ```json |
| 136 | +> "metamask@workspace:./@metamask/network-controller@^12.4.9": "npm:@metamask-previews/[email protected]", |
| 137 | +> ``` |
| 138 | +
|
| 139 | +### Using a preview build for a patched package |
| 140 | +
|
| 141 | +When you go to add a resolution for a package you want to test following steps in either of the sections above, you may find that the package is patched. An entry for a patched dependency looks like this: |
| 142 | +
|
| 143 | +```json |
| 144 | +"@metamask/<PACKAGE_NAME>": "patch:@metamask/<PACKAGE_NAME>@npm:<ESCAPED_VERSION_RANGE>#~/.yarn/patches/<PATCH_NAME>.patch" |
| 145 | +``` |
| 146 | +
|
| 147 | +where: |
| 148 | + |
| 149 | +- `PACKAGE_NAME` is the name of the package. |
| 150 | +- `ESCAPED_VERSION_RANGE` is the version range, but where characters like `^` are escaped (for instance, `^` will appear as `%3A`). |
| 151 | +- `PATCH_NAME` is the filename for a patch. It is usually dash-separated, starts with the package name, and ends with the commit ID from which the patch was created. |
| 152 | + |
| 153 | +You will need to ensure that you keep the patch when you use a preview build for the package. To do this: |
| 154 | + |
| 155 | +1. Look for the escaped version range on the right-hand side of the dependency entry and mentally parse it to determine the underlying version range that the patch is being applied to. |
| 156 | + |
| 157 | +2. When you add a resolution, target that version range on the left-hand side as if the patch were not there, and reuse the same `patch:` identifier on the right side, but replace the package name and version string accordingly. |
| 158 | + |
| 159 | + - Note: Sometimes, for a patched dependency, the patch is present in not only as a dependency entry but also a resolution entry. If a resolution entry already exists, you'll want to replace it (but _only_ if you are making non-breaking changes, otherwise you'll want to add a new resolution). |
| 160 | + |
| 161 | +> **Example 1 (non-breaking changes):** |
| 162 | +> |
| 163 | +> - You have non-breaking changes to `@metamask/controller-utils` you want to test |
| 164 | +> - You're in a MetaMask client repo |
| 165 | +> - `@metamask/controller-utils` is listed at `^1.1.4`, and `yarn why` reveals that `^1.0.1` and `^1.1.3` are also being used as version ranges in the dependency tree |
| 166 | +> - The dependency entry looks like this: |
| 167 | +> ```json |
| 168 | +> "@metamask/controller-utils": "patch:@metamask/controller-utils@npm%3A1.1.4#~/.yarn/patches/@metamask-controller-utils-npm-1.1.4-cccac388c7.patch" |
| 169 | +> ``` |
| 170 | +> - A resolution entry also exists which looks like this: |
| 171 | +> ```json |
| 172 | +> "@metamask/controller-utils@npm:^1.1.4": "patch:@metamask/controller-utils@npm%3A1.1.4#~/.yarn/patches/@metamask-controller-utils-npm-1.1.4-cccac388c7.patch" |
| 173 | +> ``` |
| 174 | +> - You want to use the preview version `1.1.4-preview-e2df9b4` |
| 175 | +> |
| 176 | +> In this case, you would go to `resolutions`, _remove_ the existing entry, and add these new entries: |
| 177 | +> |
| 178 | +> ```json |
| 179 | +> "@metamask/controller-utils@^1.0.1": "patch:@metamask-previews/controller-utils@npm%3A1.1.4-preview-e2df9b4#~/.yarn/patches/@metamask-controller-utils-npm-1.1.4-cccac388c7.patch" |
| 180 | +> "@metamask/controller-utils@^1.1.3": "patch:@metamask-previews/controller-utils@npm%3A1.1.4-preview-e2df9b4#~/.yarn/patches/@metamask-controller-utils-npm-1.1.4-cccac388c7.patch" |
| 181 | +> "@metamask/controller-utils@^1.1.4": "patch:@metamask-previews/controller-utils@npm%3A1.1.4-preview-e2df9b4#~/.yarn/patches/@metamask-controller-utils-npm-1.1.4-cccac388c7.patch" |
| 182 | +> ``` |
| 183 | +
|
| 184 | +> **Example 2 (breaking changes):** |
| 185 | +> |
| 186 | +> - You have breaking changes to `@metamask/network-controller` you want to test |
| 187 | +> - You're in a MetaMask client repo |
| 188 | +> - The `name` in `package.json` is "metamask" |
| 189 | +> - `@metamask/network-controller` is listed at `^12.4.9` |
| 190 | +> - The dependency entry looks like this: |
| 191 | +> ```json |
| 192 | +> "@metamask/network-controller": "patch:@metamask/network-controller@npm%3A12.4.9#~/.yarn/patches/@metamask-network-controller-npm-12.4.9-cccac388c7.patch" |
| 193 | +> ``` |
| 194 | +> - A resolution entry also exists which looks like this: |
| 195 | +> ```json |
| 196 | +> "@metamask/network-controller@npm:^12.4.9": "patch:@metamask/network-controller@npm%3A12.4.9#~/.yarn/patches/@metamask-network-controller-npm-12.4.9-cccac388c7.patch" |
| 197 | +> ``` |
| 198 | +> - You want to use the preview version `12.4.9-preview-e2df9b4` |
| 199 | +> |
| 200 | +> In this case, you would go to `resolutions` and leave the existing one there, but _add_ a new one: |
| 201 | +> |
| 202 | +> ```json |
| 203 | +> "metamask@workspace:./@metamask/network-controller@^12.4.9": "patch:@metamask-previews/network-controller@npm%3A12.4.9-preview-e2df9b4#~/.yarn/patches/@metamask-network-controller-npm-12.4.9-cccac388c7.patch" |
| 204 | +> ``` |
0 commit comments