- Install Node.js version 16.
- If you're using NVM (recommended),
nvm usewill ensure that the right version is installed.
- If you're using NVM (recommended),
- Install Yarn v3.
- Run
yarn installto install dependencies and run any required post-install scripts. - Run
yarn simple-git-hooksto add a Git hook to your local development environment which will ensure that all files pass linting before you push a branch.
- Run
yarn workspace <workspaceName> run testto run all tests for a package. - Run
yarn workspace <workspaceName> run jest --no-coverage <file>to run a test file within the context of a package. - Run
yarn testto run tests for all packages.
Note
workspaceNamein these commands is thenamefield within a package'spackage.json, e.g.,@metamask/address-book-controller, not the directory where it is located, e.g.,packages/address-book-controller.
Run yarn lint to lint all files and show possible violations.
Run yarn lint:fix to fix any automatically fixable violations.
This repository relies on Yarn's workspaces feature to provide a way to work with packages individually and collectively. Refer to the documentation for the following Yarn commands for usage instructions:
Note
workspaceNamein the Yarn documentation is thenamefield within a package'spackage.json, e.g.,@metamask/address-book-controller, not the directory where it is located, e.g.,packages/address-book-controller.commandNamein the Yarn documentation is any sub-command that theyarnexecutable would usually take. Pay special attention to the difference betweenrunvsexec. If you want to run a package script, you would userun, e.g.,yarn workspace @metamask/address-book-controller run changelog:validate; but if you want to run any shell command, you'd useexec, e.g.yarn workspace @metamask/address-book-controller exec cat package.json | jq '.version'.
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 two sections:
- Explanation: This section is targeted toward maintainers and is intended for you to explain the purpose and scope of your changes and share knowledge that they 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?
- Changelog: This section is targeted toward consumers — internal developers of the extension or mobile app in addition to external dapp developers — and is intended to be a list of your changes from the perspective of each package in the monorepo. Questions you should seek to answer are:
- Which packages are being updated?
- What are the exact changes to the API (types, interfaces, functions, methods) that are being changed?
- What are the anticipated effects to whichever platform might want to make use of these changes?
- If there are breaking changes to the API, what do consumers need to do in order to adapt to those changes upon upgrading to them?
When developing changes to packages within this repository that a different project depends upon, you may wish to load those changes into the project and test them locally or in CI before publishing proper releases of those packages. To solve that problem, this repository provides a mechanism to publish "preview" versions of packages to GitHub Package Registry. These versions can then be used in the project like any other version, provided the project is configured to use that registry.
If you are a member of the MetaMask organization, you can create branches directly on this repository rather than using a fork. This allows you to use our preview build GitHub Action.
Post a comment on the PR with the text @metamaskbot publish-preview (This triggers the publish-preview GitHub action). After a few minutes, you will see a new comment indicating that all packages have been published with the format <package name>-<commit id>.
If you're a contributor and you've forked this repository, you can create preview versions for a branch by following these steps:
- Open the
package.jsonfor each package that you want to publish and change the scope in the name from@metamaskto@<your GitHub username>. - From your local fork of the repository, run
yarn prepare-preview-builds "$(git rev-parse --short HEAD)" && yarn build && yarn publish-previewsto generate preview versions for all packages based on the current branch and publish them to GitHub Package Registry.- Take note of the version that is published; it should look like
1.2.3-e2df9b4instead of1.2.3.
- Take note of the version that is published; it should look like
Warning
There is a known problem with the preview build workflow. It relies upon you having a local cache of any non-preview
@metamask/-scoped packages.If you encounter problems installing non-preview
@metamask/-scoped packages when using this workflow, you can work around the problem by first installing dependencies without preview builds enabled (e.g. by temporarily removing the.npmrcor unsetting the required environment variables) to install the missing packages. Once they are installed, preview build installations should work (the non-preview@metamask/-scoped packages will be found in your local cache).See issue #1075 for more details.
Preview builds should automatically work in CI on the MetaMask extension and MetaMask mobile repositories, as long as the PR is in draft.
To use preview builds locally, follow these steps:
-
Navigate to your settings within GitHub and create a classic access token. Make sure to give this token the
read:packagesscope. -
Follow these steps in the project using the preview builds:
-
Yarn 1 (classic) or NPM
Add the following in
.npmrc@metamask:registry=https://npm.pkg.github.com //npm.pkg.github.com/:_authToken=<your personal access token> -
Yarn >= 2 (berry):
Ensure that the project
.yarnrc.ymlfile has the following contents:npmRegistries: "https://npm.pkg.github.com": npmAlwaysAuth: true npmAuthToken: "${GITHUB_NPM_TOKEN-}" npmScopes: metamask: npmRegistryServer: "${METAMASK_NPM_REGISTRY:-https://registry.yarnpkg.com}"The
METAMASK_NPM_REGISTRYenvironment variable lets you control which registry is used for@metamask-scoped packages. Set this environment variable tohttps://npm.pkg.github.comto use preview builds. TheGITHUB_NPM_TOKENenvironment variable is where your token is set (the one created in step 1).For example, in Bash or ZSH, you can set both of these environment variables when installing dependencies:
GITHUB_NPM_TOKEN=<your personal access token> METAMASK_NPM_REGISTRY=https://npm.pkg.github.com yarn install
- It's recommended to use your machine's local keychain to store the token, and retrieve it from there. For example on macOS, you can use:
GITHUB_NPM_TOKEN=$(security find-generic-password -s 'GitHub NPM Token' -w) METAMASK_NPM_REGISTRY=https://npm.pkg.github.com yarn install
- It's recommended to use your machine's local keychain to store the token, and retrieve it from there. For example on macOS, you can use:
-
-
Update
package.jsonwith the new preview build versions- Each preview build package should have a version matching (e.g.
1.2.3-e2df9b4instead of~1.2.3), then runyarn install.
- Each preview build package should have a version matching (e.g.
-
Repeat step 3 each time you publish new preview builds.
The create-release-branch tool and action-publish-release GitHub action are used to automate the release process.
-
Create a release branch.
Run
yarn create-release-branch. This tool generates a file and opens it in your editor, where you can specify which packages you want to include in the next release and which versions they should receive. Instructions are provided for you at the top; read them and update the file accordingly.When you're ready to continue, save and close the file.
-
Update changelogs for relevant packages.
At this point you will be on a new release branch, and a new section will have been added to the changelog of each package you specified in the previous step.
For each changelog, review the new section and make the appropriate changes:
- Move each entry into the appropriate category (review the "Keep a Changelog" spec for the full list of categories and the correct ordering of all categories).
- Remove any 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 one change entry if it makes it easier to comprehend.
Run
yarn changelog:validateto check that all changelogs are correctly formatted.Commit and push the branch.
-
Submit a pull request for the release branch so that it can be reviewed and tested.
Make sure the title of the pull request follows the pattern "Release <new version>".
If changes are made to the base branch, the release branch will need to be updated with these changes and review/QA will need to restart again. As such, it's probably best to avoid merging other PRs into the base branch while review is underway.
-
"Squash & Merge" the release.
This step triggers the
publish-releaseGitHub action workflow to tag the final release commit and publish the release on GitHub.Pay attention to the box you see when you press the green button and ensure that the final name of the commit follows the pattern "Release <new version>".
-
Publish the release on NPM.
The
publish-releaseGitHub Action workflow runs thepublish-npmjob, which publishes relevant packages to NPM. It requires approval from thenpm-publishersteam to complete. If you're not on the team, ask a member to approve it for you; otherwise, approve the job.Once the
publish-npmjob has finished, check NPM to verify that all relevant packages has been published.