diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index 4aea508d..4ee95152 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -27,5 +27,5 @@ For example: - [ ] I've updated the test suite for new or updated code as appropriate - [ ] I've updated documentation (JSDoc, Markdown, etc.) for new or updated code as appropriate -- [ ] I've communicated my changes to consumers by [updating changelogs for packages I've changed](https://github.com/MetaMask/core/tree/main/docs/processes/updating-changelogs.md) -- [ ] I've introduced [breaking changes](https://github.com/MetaMask/core/tree/main/docs/processes/breaking-changes.md) in this PR and have prepared draft pull requests for clients and consumer packages to resolve them +- [ ] I've communicated my changes to consumers by [updating changelogs for packages I've changed](https://github.com/MetaMask/internal-snaps/tree/main/docs/processes/updating-changelogs.md) +- [ ] I've introduced [breaking changes](https://github.com/MetaMask/internal-snaps/tree/main/docs/processes/breaking-changes.md) in this PR and have prepared draft pull requests for clients and consumer packages to resolve them diff --git a/README.md b/README.md index 50dafbd4..ca2aea75 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,16 @@ This monorepo hosts MetaMask's first-party Snaps along with shared tooling and infrastructure for building, testing, and releasing them. +## Contributing + +See the [Contributor Documentation](./docs/README.md) for help on: + +- Setting up your development environment +- Working with the monorepo +- Testing changes in clients +- Issuing new releases +- Creating a new package + ## Installation/Usage Each snap in this repository has its own README with installation and usage instructions. See `packages/` for more. diff --git a/docs/README.md b/docs/README.md new file mode 100644 index 00000000..f177787c --- /dev/null +++ b/docs/README.md @@ -0,0 +1,26 @@ +# Contributor Documentation + +Hi! Welcome to the contributor documentation for the `internal-snaps` monorepo. + +## Getting started + +- [Setting up your development environment](./getting-started/setting-up-your-environment.md) +- [Codeownership](./getting-started/codeownership.md) + +## Processes + +- [Performing operations across the monorepo](./processes/general-monorepo-operations.md) +- [Writing and running tests](./processes/testing.md) +- [Linting and formatting](./processes/linting-and-formatting.md) +- [Updating changelogs](./processes/updating-changelogs.md) +- [Creating pull requests](./processes/creating-pull-requests.md) +- [Releasing changes](./processes/releasing.md) + - [Preparing and releasing breaking changes](./processes/breaking-changes.md) +- [Testing changes to packages in other projects](./processes/testing-changes-in-other-projects.md) +- [Building packages](./processes/building.md) +- [Adding new packages to the monorepo](./processes/adding-new-packages.md) +- [Migrating external snaps to the monorepo](./processes/snap-migration-process-guide.md) + +## Code guidelines + +- [General MetaMask code guidelines](https://github.com/MetaMask/contributor-docs) diff --git a/docs/getting-started/codeownership.md b/docs/getting-started/codeownership.md new file mode 100644 index 00000000..274143be --- /dev/null +++ b/docs/getting-started/codeownership.md @@ -0,0 +1,5 @@ +# Understanding codeowners + +Although maintenance of this repository is superintended by the Networks team, the responsibility of maintenance is expected to be shared among multiple teams at MetaMask. The exact allocation is governed by the [`CODEOWNERS`](../../.github/CODEOWNERS) file. + +\*\*If your team is listed as a codeowner for a package, you may change, approve pull requests, and create releases. Alternatively, if you feel that your team should be granted codeownership over a specific package, you can submit a pull request to change `CODEOWNERS`. diff --git a/docs/getting-started/setting-up-your-environment.md b/docs/getting-started/setting-up-your-environment.md new file mode 100644 index 00000000..28fd99d1 --- /dev/null +++ b/docs/getting-started/setting-up-your-environment.md @@ -0,0 +1,7 @@ +# Setting up your development environment + +1. Install the current LTS version of [Node](https://nodejs.org). + - If you are using [NVM](https://github.com/creationix/nvm#installation) (recommended), running `nvm install` will install the latest version, and running `nvm use` will automatically choose the right Node version for you. +2. Run `corepack enable` to install [Yarn](https://yarnpkg.com) via [Corepack](https://github.com/nodejs/corepack?tab=readme-ov-file#how-to-install). + - If you have Yarn installed globally via Homebrew or NPM, you'll need to uninstall it before running this command. +3. Run `yarn install` to install dependencies and run any required post-install scripts. diff --git a/docs/processes/adding-new-packages.md b/docs/processes/adding-new-packages.md new file mode 100644 index 00000000..45bec7fc --- /dev/null +++ b/docs/processes/adding-new-packages.md @@ -0,0 +1,29 @@ +# Adding new packages to the monorepo + +> [!NOTE] +> If you're migrating an existing package to the monorepo, please see [the package migration documentation](./package-migration-process-guide.md). You may be able to make use of `create-package` when migrating your package, but there's a lot more to it. + +Manually creating a new monorepo package can be a tedious, even frustrating process. To alleviate that problem, we have created a CLI that automates most of the job for us, creatively titled [`create-package`](../../scripts/create-package/). To create a new monorepo package, follow these steps: + +1. Create a new package using `yarn create-package`. + - Use the `--help` flag for usage information. + - Once this is done, you can find a package with your chosen name in `/packages`. +2. Make sure your license is correct. + - By default, `create-package` gives your package an MIT license. + - If your desired license is _not_ MIT, then you must update your `LICENSE` file and the `license` field of `package.json`. +3. Update `.github/CODEOWNERS` to assign a team as the owner of the new package. +4. Add your dependencies. + - Do this as normal using `yarn`. + - Remember, if you are adding other monorepo packages as dependents, don't forget to add them to the `references` array in your package's `tsconfig.json` and `tsconfig.build.json`. + +And that's it! + +### Contributing to `create-package` + +Along with this documentation, `create-package` is intended to be the source of truth for the process of adding new packages to the monorepo. Consequently, to change that process, you will want to change `create-package`. + +The `create-package` directory contains a [template package](../../scripts/create-package/package-template/). The CLI is not aware of the contents of the template, only that its files have [placeholder values](../../scripts/create-package/constants.ts). When a new package is created, the template files are read from disk, the placeholder values are replaced with real ones, and the updated files are added to a new directory in `/packages`. To modify the template package: + +- If you need to add or modify any files or folders, just go ahead and make your changes in [`/scripts/create-package/package-template`](../../scripts/create-package/package-template/). The CLI will read whatever's in that directory and write it to disk. +- If you need to add or modify any placeholders, make sure that your desired values are added to both the relevant file(s) and [`/scripts/create-package/constants.ts`](../../scripts/create-package/constants.ts). Then, update the implementation of the CLI accordingly. +- As with placeholders, updating the monorepo files that the CLI interacts with begins by updating [`/scripts/create-package/constants.ts`](../../scripts/create-package/constants.ts). diff --git a/docs/processes/breaking-changes.md b/docs/processes/breaking-changes.md new file mode 100644 index 00000000..ae134a70 --- /dev/null +++ b/docs/processes/breaking-changes.md @@ -0,0 +1,76 @@ +# Preparing and releasing breaking changes + +When developing packages, it is always important to be intentional about the impact that changes have on projects which use those packages. However, special consideration must be given to breaking changes. + +This guide provides best practices for documenting, preparing, releasing, and adapting to breaking changes within `internal-snaps` and in other projects. + +## What is a breaking change? + +A change to a package is "breaking" if upgrading a project to a version containing the change would require modifications to source code or configuration in order to avoid user- or developer-facing problems (an inability to use or build the project, a loss of functionality, etc.). + +There are many kinds of breaking changes. Here are some examples: + +- Removals + - Removing a method from a class + - Removing an export from a package (including a type export) +- Functional changes that require code changes or change expectations + - Changing the number of required arguments for a function or method + - Throwing a new error in a function or method + - Changing a function or method so that it no longer fires an event +- Breaking changes to types + - Adding external actions or events to a messenger type + - Narrowing the type of an argument in a function or method + - Changing the number of required properties in an object type + - Narrowing the type of a property in an object type + - Changing the number of type parameters for a type + - Making any other change listed [here](https://www.semver-ts.org/formal-spec/2-breaking-changes.html) +- Bumping the minimum supported Node.js version of a package +- Upgrading a dependency referenced in published code to a version that causes any of the above + +## Introducing breaking changes safely + +Before merging a PR that introduces breaking changes, it is important to ensure that they are accounted for among projects. + +### 1. Document breaking changes + +To inform other maintainers now and in the future, make sure that breaking changes are documented in the changelog: + +1. Be explicit in your changelog entries about which classes, functions, types, etc. are affected. +2. Prefix entries with `**BREAKING:**`. +3. If relevant, provide details on how consuming code can adapt to the changes safely. +4. Move entries for breaking changes above all other kinds of changes within the same section. + + + + + +### 2. Audit dependents + +When you release your changes, which codebases will be affected? + +Using the changelog as a guide, locate all of the places across MetaMask that use the affected classes, functions, types, etc.: + +- To find dependents of your package within `internal-snaps`, look in the package's `package.json`, or simply search across the repo. +- To find dependents of your package across MetaMask, do a search on GitHub for import statements or, better, usages of the affected symbols. + +### 3. Prepare upgrade PRs for dependents + +Finally, how will dependent projects need to adapt to your breaking changes? + +For dependent packages located in `internal-snaps`, you may get type errors immediately that you will have to fix in the same PR that introduces the breaking changes. Otherwise, create new PRs to migrate existing code. + +For other projects that live outside of `internal-snaps`, you can use the following process to verify the effects: + +1. Create a [preview build](./preview-builds.md) for your package. +2. Open draft PRs in the dependent projects. +3. In each draft PR, upgrade your package to the preview build. +4. Test the project, particularly the functionality that makes use of your package. +5. If you see compile-time or runtime errors, make changes to the project as necessary. +6. If you discover new breaking changes in your package that you haven't yet listed in the changelog, go back and [document them](#1-document-breaking-changes). +7. Once you've done this for all projects, check off the "I've followed the process for releasing breaking changes" item in the checklist at the bottom of your PR. + +This process serves as a check to help you understand the full impact of your changes. It will also save you time after you make a new release, because you can reuse the draft PRs later to complete upgrades. diff --git a/docs/processes/building.md b/docs/processes/building.md new file mode 100644 index 00000000..6618b6fe --- /dev/null +++ b/docs/processes/building.md @@ -0,0 +1,6 @@ +# Building packages + +Built files show up in the `dist/` directory in each package. These are the files which will ultimately be published to NPM. + +- Run `yarn build` to build all packages in the monorepo. +- Run `yarn workspace run build` to build a single package. diff --git a/docs/processes/creating-pull-requests.md b/docs/processes/creating-pull-requests.md new file mode 100644 index 00000000..0e3f3d54 --- /dev/null +++ b/docs/processes/creating-pull-requests.md @@ -0,0 +1,8 @@ +# Creating pull requests + +When submitting a pull request for this repo, take some a bit of extra time to fill out its description. Use the provided template as a guide, paying particular attention to the **Explanation** section. This section is intended for you to explain the purpose and scope of your changes and share knowledge that other engineers might not be able to see from reading the PR alone. Some questions you should seek to answer are: + +- What is the motivator for these changes? What need are the changes satisfying? Is there a ticket you can share or can you provide some more context for people who might not be familiar with the domain? +- Are there any changes in particular whose purpose might not be obvious or whose implementation might be difficult to decipher? How do they work? +- If your primary goal was to update one package but you found you had to update another one along the way, why did you do so? +- If you had to upgrade a dependency, why did you do so? diff --git a/docs/processes/general-monorepo-operations.md b/docs/processes/general-monorepo-operations.md new file mode 100644 index 00000000..dc9a13fb --- /dev/null +++ b/docs/processes/general-monorepo-operations.md @@ -0,0 +1,11 @@ +# Performing operations across the monorepo + +This repository relies on Yarn's [workspaces feature](https://yarnpkg.com/features/workspaces) to provide a way to work with packages individually and collectively. Refer to the documentation for the following Yarn commands for usage instructions: + +- [`yarn workspace`](https://yarnpkg.com/cli/workspace) +- [`yarn workspaces foreach`](https://yarnpkg.com/cli/workspaces/foreach) + +> **Note** +> +> - `workspaceName` in the Yarn documentation is the `name` field within a package's `package.json`, e.g., `@metamask/bitcoin-wallet-snap`. +> - `commandName` in the Yarn documentation is any sub-command that the `yarn` executable would usually take. Pay special attention to the difference between `run` vs `exec`. If you want to run a package script, you would use `run`, e.g., `yarn workspace @metamask/bitcoin-wallet-snap run changelog:validate`; but if you want to run _any_ shell command, you'd use `exec`, e.g. `yarn workspace @metamask/bitcoin-wallet-snap exec cat package.json | jq '.version'`. diff --git a/docs/processes/linting-and-formatting.md b/docs/processes/linting-and-formatting.md new file mode 100644 index 00000000..5d120753 --- /dev/null +++ b/docs/processes/linting-and-formatting.md @@ -0,0 +1,8 @@ +# Linting and formatting code + +[ESLint](https://eslint.org) v9 (via [MetaMask's shared ESLint configurations](https://github.com/MetaMask/eslint-config)) is used to check for code quality issues, and [Oxfmt](https://oxc.rs/docs/guide/usage/formatter.html) is used to format files. + +If you need to customize the behavior of ESLint, see `eslint.config.mjs` in the root. + +- Run `yarn lint` to lint all files and show possible violations across the monorepo. +- Run `yarn lint:fix` to fix any automatically fixable violations. diff --git a/docs/processes/local-builds.md b/docs/processes/local-builds.md new file mode 100644 index 00000000..1c32b1a4 --- /dev/null +++ b/docs/processes/local-builds.md @@ -0,0 +1,40 @@ +# Using local builds + +If you are unable to use [preview builds](./preview-builds.md) for testing, you can always build a package locally and link it to a project. + +1. First, build the monorepo by running `yarn build`. + +2. In the project, open `package.json` and locate the entry in `dependencies` for the package you want to test. + +3. Replace the version range in the right-hand side of the entry to point to the local build: + + ```json + "@metamask/@": "file:/packages/" + ``` + + where: + - `PACKAGE_NAME` is the name of your package + - `VERSION_RANGE` is the version range of your package being used in production, usually starting with `^` + - `PATH_TO_MONOREPO` is the local path to the clone of this monorepo + +4. Run `yarn install`. (Note that due to the use of Yarn's `file:` protocol, you'll need to repeat this step each time you update the package in the monorepo.) + +> **Example:** +> +> Given: +> +> - You have changes to `@metamask/bitcoin-wallet-snap` you want to test +> - `@metamask/bitcoin-wallet-snap` is listed at `^1.15.2` +> - You've cloned this repo next to the project +> +> In this case, you would go to `dependencies` and replace the line: +> +> ```json +> "@metamask/bitcoin-wallet-snap": "^1.15.2" +> ``` +> +> with: +> +> ```json +> "@metamask/bitcoin-wallet-snap@^1.15.2": "file:../internal-snaps/packages/bitcoin-wallet-snap" +> ``` diff --git a/docs/processes/preview-builds.md b/docs/processes/preview-builds.md new file mode 100644 index 00000000..4fa51c85 --- /dev/null +++ b/docs/processes/preview-builds.md @@ -0,0 +1,191 @@ +# Publishing and using preview builds + +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. + +Generally, when working with preview builds, you will follow this process: + +1. Create a branch in your clone of this repo +2. Work on changes to your package(s) +3. [Publish preview builds](#publishing-preview-builds) +4. Switch to the project and [configure it to use the new preview builds](#using-preview-builds) +5. Repeat steps 2-4 as necessary + +## Publishing preview builds + +To publish preview builds: + +1. Create a pull request with the changes to your package(s). +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. +3. After a few minutes, you will see a new comment that lists the newly published packages along with their versions. + +
Publishing preview builds as an independent contributor +
+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: + +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). +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. +3. Run the following command to create and publish preview builds for all packages in the monorepo (replacing `NPM_ORG` as appropriate): + + ```bash + yarn prepare-preview-builds "@" "$(git rev-parse --short HEAD)" + yarn build + yarn publish-previews + ``` + + You will see a list of the newly published packages along with their versions. +
+ +## Using preview builds + +To simulate production as best as possible, there are two different paths to take depending on whether you anticipate making breaking or non-breaking changes to the package you want to test. + +### Testing non-breaking changes to a package + +If you're in a MetaMask client repo (e.g. `metamask-extension` or `metamask-mobile`): + +1. Open `package.json` and locate the `previewBuilds` section. If it doesn't exist, then add it (it should be an object). +2. Within `previewBuilds`, add an entry that looks like this: + + ``` + "": { + "type": "non-breaking", + "previewVersion": "" + } + ``` + + For example: + + ``` + "@metamask/permission-controller": { + "type": "non-breaking", + "previewVersion": "13.0.2-preview-940c934" + } + ``` + +3. Run `yarn install`. You're now using the preview build. + +
+Manual steps + +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. + - Note that the dependency may be patched. Patched dependencies look like this: + + ```json + "@metamask/": "patch:@metamask/@npm:#~/.yarn/patches/.patch" + ``` + + where: + - `PACKAGE_NAME` is the name of the package. + - `ESCAPED_VERSION_RANGE` is the version range, but where characters like `^` are escaped (for instance, `^` will appear as `%3A`). + - `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. + + In this case the major version you are targeting will come from `ESCAPED_VERSION_RANGE`. + +2. Run `yarn why @metamask/`, replacing `PACKAGE_NAME` as appropriate. You will see output like this: + + ``` + ├─ @metamask/parent-controller-1@npm:93.1.0 + │ └─ @metamask/my-controller@npm:12.1.1 (via npm:^12.1.1) + │ + ├─ @metamask/parent-controller-2@npm:94.1.0 + │ └─ @metamask/my-controller@npm:12.1.1 (via npm:^12.1.1) + │ + ├─ @metamask/parent-controller-3@npm:94.1.0 [abc9d] + │ └─ @metamask/my-controller@npm:12.1.1 [57677] (via npm:^12.1.1 [15228]) + ... + │ + └─ metamask@workspace:. + └─ @metamask/my-controller@npm:12.1.1 [57677] (via npm:^12.1.0 [abc9d]) + ``` + + 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`). + +3. Back in `package.json`, locate the `resolutions` section. If it doesn't exist, then add it (it should be an object). + +4. For each version range, add a new entry that looks like this: + + ```json + "@metamask/@": "npm:@/@" + ``` + + where: + - `PACKAGE_NAME` is the name of your package + - `VERSION_RANGE` is one of the version ranges you noted in step 2 + - `NPM_ORG` is the NPM scope that the preview build is published under (note: this is _not_ `@metamask`) + - `PREVIEW_VERSION` is the version string of the preview build (note: this should _not_ start with `^`) + + Note that if the dependency was patched as in step 1, you may have a resolution already. You'll want to replace the existing resolution while keeping the existing patch. Your entry will look more like: + + ```json + "@metamask/@": "patch:@/@npm:#~/.yarn/patches/.patch" + ``` + +5. Run `yarn install` to apply the changes. + +6. Run `yarn why @metamask/` 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. + +
+ +### Testing breaking changes to a package + +If you're in a MetaMask client repo (e.g. `metamask-extension` or `metamask-mobile`), run: + +1. Open `package.json` and locate the `previewBuilds` section. If it doesn't exist, then add it (it should be an object). +2. Within `previewBuilds`, add an entry that looks like this: + + ``` + "": { + "type": "breaking", + "previewVersion": "" + } + ``` + + For example: + + ``` + "@metamask/permission-controller": { + "type": "breaking", + "previewVersion": "13.0.2-preview-940c934" + } + ``` + +3. Run `yarn install`. You're now using the preview build. + +
+Manual steps + +1. In the project, open `package.json`, and: + - Note the name of the package. + - Locate the `resolutions` section. If it doesn't exist, then add it (it should be an object). + - Check to see if the dependency you're testing is patched. Patched dependencies look like this: + + ```json + "@metamask/": "patch:@metamask/@npm:#~/.yarn/patches/.patch" + ``` + + where: + - `PACKAGE_NAME` is the name of the package. + - `ESCAPED_VERSION_RANGE` is the version range, but where characters like `^` are escaped (for instance, `^` will appear as `%3A`). + - `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. + +2. Add a new entry to `resolutions` that looks like this: + + ```json + "@workspace:./@metamask/": "npm:@/@" + ``` + + where: + - `ROOT_PACKAGE_NAME` is the value of the `name` field at the top of `package.json` + - `NPM_ORG` is the NPM scope that the preview build is published under (note: this is _not_ `@metamask`) + - `PACKAGE_NAME` is the name of your package + - `PREVIEW_VERSION` is the version string of the preview build (note: this should _not_ start with `^`) + + Note that if the dependency was patched as in step 1, you may have a resolution already. You'll want to replace the existing resolution while keeping the existing patch. Your entry will look more like: + + ```json + "@metamask/@": "patch:@/@npm:#~/.yarn/patches/.patch" + ``` + +3. Run `yarn install` to apply the changes. + +
diff --git a/docs/processes/releasing.md b/docs/processes/releasing.md new file mode 100644 index 00000000..e472f9db --- /dev/null +++ b/docs/processes/releasing.md @@ -0,0 +1,148 @@ +# Releasing changes + +Have changes that you need to release? There are a few things to understand: + +- The responsibility of maintenance is not the only thing shared among multiple teams at MetaMask; releases are as well. That means **if you work on a team that has codeownership over a package, you are free to create a new release without needing the Wallet Framework team to do so.** +- Unlike clients, releases are not issued on a schedule; **anyone may create a release at any time**. Because of this, you may wish to review the Pull Requests tab on GitHub and ensure that no one else has a release candidate already in progress. If not, then you are free to start the process. +- The release process is a work in progress. Further improvements to simplify the process are planned, but in the meantime, if you encounter any issues, please reach out to the Wallet Framework team. +- Breaking changes take special consideration. [Read the guide](./breaking-changes.md) on how to prepare and handle them effectively. + +Now for the process itself, you have two options: using our interactive UI (recommended for most users) or manual specification. + +### Option A: Interactive Mode (Recommended) + +This option provides a visual interface to streamline the release process: + +1. **Start the interactive release tool.** + + On the `main` branch, run: + + ``` + yarn create-release-branch -i + ``` + + This will start a local web server (default port 3000) and open a browser interface. + +2. **Select packages to release.** + + The UI will show all packages with changes since their last release. For each package: + - Choose whether to include it in the release + - Select an appropriate version bump (patch, minor, or major) following SemVer rules + - The UI will automatically validate your selections and identify dependencies that need to be included + +3. **Review and resolve dependency requirements.** + + The UI automatically analyzes your selections and identifies potential dependency issues that need to be addressed before proceeding. You'll need to review and resolve these issues by either: + - Including the suggested additional packages + - Confirming that you want to skip certain packages (if you're certain they don't need to be updated) + + Common types of dependency issues you might encounter: + - **Missing dependencies**: If you're releasing Package A that depends on Package B, the UI will prompt you to include Package B + - **Breaking change impacts**: If you're releasing Package B with breaking changes, the UI will identify packages that have peer dependencies on Package B that need to be updated + - **Version incompatibilities**: The UI will flag if your selected version bumps don't follow semantic versioning rules relative to dependent packages + + Unlike the manual workflow where you need to repeatedly edit a YAML file, in the interactive mode you can quickly resolve these issues by checking boxes and selecting version bumps directly in the UI. + +4. **Confirm your selections.** + + Once you're satisfied with your package selections and version bumps, confirm them in the UI. This will: + - Create a new branch named `release/` + - Update the version in each package's `package.json` + - Add a new section to each package's `CHANGELOG.md` for the new version + +5. **Review and update changelogs.** + + Each selected package will have a new changelog section. Review these entries to ensure they are helpful for consumers: + - Categorize entries appropriately following the ["Keep a Changelog"](https://keepachangelog.com/en/1.0.0/) guidelines. Ensure that no changes are listed under "Uncategorized". + - Remove changelog entries that don't affect consumers of the package (e.g. lockfile changes or development environment changes). Exceptions may be made for changes that might be of interest despite not having an effect upon the published package (e.g. major test improvements, security improvements, improved documentation, etc.). + - Reword changelog entries to explain changes in terms that users of the package will understand (e.g., avoid referencing internal variables/concepts). + - Consolidate related changes into single entries where appropriate. + + Run `yarn changelog:validate` when you're done to ensure all changelogs are correctly formatted. + +6. **Push and submit a pull request.** + + Create a PR for the release branch so that it can be reviewed and tested. + Release PRs can be approved by codeowners of affected packages, so as long as the above guidelines have been followed, there is no need to reach out to the Wallet Framework team for approval. + +7. **Incorporate any new changes from `main`.** + + If you see the "Update branch" button on your release PR, stop and look over the most recent commits made to `main`. If there are new changes to packages you are releasing, make sure they are reflected in the appropriate changelogs. + +8. **Merge the release PR and wait for approval.** + + "Squash & Merge" the release PR when it's approved. + + Merging triggers the [`publish-release` GitHub action](https://github.com/MetaMask/action-publish-release) workflow to tag the final release commit and publish the release on GitHub. Before packages are published to NPM, this action will automatically notify the [`npm-publishers`](https://github.com/orgs/MetaMask/teams/npm-publishers) team in Slack to review and approve the release. + +9. **Verify publication.** + + Once the `npm-publishers` team has approved the release, you can click on the link in the Slack message to monitor the remainder of the process. + + After the action has completed, [check NPM](https://npms.io/search?q=scope%3Ametamask) to verify that all relevant packages have been published. + +> **Tip:** You can specify a different port if needed: `yarn create-release-branch -i -p 3001` + +### Option B: Manual Release Specification + +If you prefer more direct control over the release process: + +1. **Start by creating the release branch.** + + On the `main` branch, run `yarn create-release-branch`. This command creates a branch named `release/` which will represent the new release. + +2. **Specify packages to release along with their versions.** + + Unless you've made a lot of breaking changes, you probably don't want to publish a new version of every single package in this repo. Fortunately, you can choose a subset of packages to include in the next release. You do this by modifying a YAML file called a "release spec", which the tool has generated and opened it in your editor. Follow the instructions at the top of the file for more information. + + In addition to selecting a list of packages, you'll also want to tell the tool which new versions they ought to receive. Since you'll want to follow SemVer, how you bump a package depends on the nature of the changes. You can understand these changes better by opening the changelog for each package in your editor. + + Once you save and close the release spec, the tool will proceed. + +3. **Review and resolve dependency requirements.** + + The tool automatically analyzes your selections and identifies potential dependency issues that need to be addressed before proceeding. You'll need to review and resolve these issues by either: + - Including the suggested additional packages + - Confirming that you want to skip certain packages (if you're certain they don't need to be updated) + + Common types of dependency issues you might encounter: + - **Missing dependencies**: If you're releasing Package A that depends on Package B, the UI will prompt you to include Package B + - **Breaking change impacts**: If you're releasing Package B with breaking changes, the UI will identify packages that have peer dependencies on Package B that need to be updated + - **Version incompatibilities**: The UI will flag if your selected version bumps don't follow semantic versioning rules relative to dependent packages + + To address these issues, you will need to reopen the YAML file, modify it by either adding more packages to the release or omitting packages from the release you think are safe, and then re-running `yarn create-release-branch`. You may need to repeat this step multiple times until you don't see any more errors. + +4. **Review and update changelogs for relevant packages.** + + Once the tool proceeds without issue, you will be on the new release branch. In addition, each package you intend to release has been updated in two ways: + - The version in `package.json` has been bumped. + - A new section has been added at the top of `CHANGELOG` for the new version. + + At this point, you need to review the changelog entries and ensure that they are helpful for consumers: + - Categorize entries appropriately following the ["Keep a Changelog"](https://keepachangelog.com/en/1.0.0/) guidelines. Ensure that no changes are listed under "Uncategorized". + - Remove changelog entries that don't affect consumers of the package (e.g. lockfile changes or development environment changes). Exceptions may be made for changes that might be of interest despite not having an effect upon the published package (e.g. major test improvements, security improvements, improved documentation, etc.). + - Reword changelog entries to explain changes in terms that users of the package will understand (e.g., avoid referencing internal variables/concepts). + - Consolidate related changes into single entries where appropriate. + + Make sure to run `yarn changelog:validate` once you're done to ensure all changelogs are correctly formatted. + +5. **Push and submit a pull request.** + + Create a PR for the release branch so that it can be reviewed and tested. + Release PRs can be approved by codeowners of affected packages, so as long as the above guidelines have been followed, there is no need to reach out to the Wallet Framework team for approval. + +6. **Incorporate any new changes from `main`.** + + If you see the "Update branch" button on your release PR, stop and look over the most recent commits made to `main`. If there are new changes to packages you are releasing, make sure they are reflected in the appropriate changelogs. + +7. **Merge the release PR and wait for approval.** + + "Squash & Merge" the release PR when it's approved. + + Merging triggers the [`publish-release` GitHub action](https://github.com/MetaMask/action-publish-release) workflow to tag the final release commit and publish the release on GitHub. Before packages are published to NPM, this action will automatically notify the [`npm-publishers`](https://github.com/orgs/MetaMask/teams/npm-publishers) team in Slack to review and approve the release. + +8. **Verify publication.** + + Once the `npm-publishers` team has approved the release, you can click on the link in the Slack message to monitor the remainder of the process. + + After the action has completed, [check NPM](https://npms.io/search?q=scope%3Ametamask) to verify that all relevant packages have been published. diff --git a/docs/processes/testing-changes-in-other-projects.md b/docs/processes/testing-changes-in-other-projects.md new file mode 100644 index 00000000..e456b33b --- /dev/null +++ b/docs/processes/testing-changes-in-other-projects.md @@ -0,0 +1,8 @@ +# Testing changes to packages in other projects + +Often it is useful to test in-progress changes to one or more packages in the context of a project before releasing them (particularly when making [breaking changes](./breaking-changes.md)). + +There are two ways to do this: + +- [Preview builds](./preview-builds.md) _(recommended)_ +- [Local builds](./local-builds.md) diff --git a/docs/processes/testing.md b/docs/processes/testing.md new file mode 100644 index 00000000..0454c009 --- /dev/null +++ b/docs/processes/testing.md @@ -0,0 +1,15 @@ +# Writing and running tests + +[Jest](https://jestjs.io/) is used to ensure that code is working as expected. Ideally, all packages should have 100% test coverage. + +Please follow the [MetaMask unit testing guidelines](https://github.com/MetaMask/contributor-docs/blob/main/docs/testing/unit-testing.md) when writing tests. + +If you need to customize the behavior of Jest for a package, see `jest.config.js` within that package. + +- Run `yarn workspace run test` to run all tests for a package. +- Run `yarn workspace run jest --no-coverage ` to run a test file within the context of a package. +- Run `yarn test` to run tests for all packages. + +> **Note** +> +> `workspaceName` in these commands is the `name` field within a package's `package.json`, e.g., `@metamask/bitcoin-wallet-snap`. diff --git a/docs/processes/updating-changelogs.md b/docs/processes/updating-changelogs.md new file mode 100644 index 00000000..4d01939d --- /dev/null +++ b/docs/processes/updating-changelogs.md @@ -0,0 +1,18 @@ +# Updating changelogs + +Each package in this repo has a file called `CHANGELOG.md` which is used to record consumer-facing changes that have been published over time. This file is useful for other engineers who are upgrading to new versions of packages so that they know how to use new features they are expecting, they know when bugs have been addressed, and they understand how to adapt to breaking changes (if any). All changelogs follow the ["Keep a Changelog"](https://keepachangelog.com/) specification (enforced by `@metamask/auto-changelog`). + +As you make changes to packages, make sure to update their changelogs in the same branch. + +We will offer more guidance here in the future, but in general: + +- Place new entries under the "Unreleased" section. +- Place changes into categories. Consult the ["Keep a Changelog"](https://keepachangelog.com/en/1.1.0/#how) specification for the list. +- Highlight breaking changes by prefixing them with `**BREAKING:**`. +- Omit non-consumer facing changes from the changelog. +- Do not simply reuse the commit message, but describe exact changes to the API or usable surface area of the project. +- Use a list nested under a changelog entry to enumerate more details about a change if need be. +- Include links to pull request(s) that introduced each change. (Most likely, this is the very same pull request in which you are updating the changelog.) +- Combine like changes from multiple pull requests into a single changelog entry if necessary. +- Split disparate changes from the same pull request into multiple entries if necessary. +- Omit reverted changes from the changelog. diff --git a/merged-packages/tron-wallet-snap/README.md b/merged-packages/tron-wallet-snap/README.md index 9582ba73..a311bda4 100644 --- a/merged-packages/tron-wallet-snap/README.md +++ b/merged-packages/tron-wallet-snap/README.md @@ -1,11 +1,20 @@ # Tron Snap +The Tron Snap allows MetaMask and dapps to support all Tron-related networks and address types. + +## Installation + +```bash +npm install @metamask/tron-wallet-snap +# or +yarn add @metamask/tron-wallet-snap +``` + ## Configuration -Rename `.env.example` to `.env` -Configurations are setup though `.env`, +Copy `.env.example` to `.env` and configure it as needed. -## API: +## Usage ### `keyring_createAccount` @@ -83,3 +92,7 @@ provider.request({ }, }); ``` + +## Contributing + +This package is part of the Internal Snaps monorepo. See the [contribution processes](../../docs/processes/) for development, testing, building, and release instructions. diff --git a/packages/bitcoin-wallet-snap/README.md b/packages/bitcoin-wallet-snap/README.md index dc926e71..226381c5 100644 --- a/packages/bitcoin-wallet-snap/README.md +++ b/packages/bitcoin-wallet-snap/README.md @@ -22,8 +22,6 @@ yarn start > [!WARNING] > When snap updates you will need to still reconnect from the dapp to see changes -## Building +## Contributing -```bash -yarn build:snap -``` +This package is part of the Internal Snaps monorepo. See the [contribution processes](../../docs/processes/) for development, testing, building, and release instructions.