When the TypeScript migration dashboard is updated, it is built and
deployed in another repo, which is then deployed via GitHub Pages. To
push to this repo we have to set a Git username and email. This is
missing from the CircleCI config, so this commit uses the metamaskbot
GitHub account to do that.
As we convert parts of the codebase to TypeScript, we will want a way to
track progress. This commit adds a dashboard which displays all of the
files that we wish to convert to TypeScript and which files we've
already converted.
The list of all possible files to convert is predetermined by walking
the dependency graph of each entrypoint the build system uses to compile
the extension (the files that the entrypoint imports, the files that the
imports import, etc). The list should not need to be regenerated, but
you can do it by running:
yarn ts-migration:enumerate
The dashboard is implemented as a separate React app. The CircleCI
configuration has been updated so that when a new commit is pushed, the
React app is built and stored in the CircleCI artifacts. When a PR is
merged, the built files will be pushed to a separate repo whose sole
purpose is to serve the dashboard via GitHub Pages (this is the same
way that the Storybook works). All of the app code and script to build
the app are self-contained under
`development/ts-migration-dashboard`. To build this app yourself, you
can run:
yarn ts-migration:dashboard:build
or if you want to build automatically as you change files, run:
yarn ts-migration:dashboard:watch
Then open the following file in your browser (there is no server
component):
development/ts-migration-dashboard/build/index.html
Finally, although you shouldn't have to do this, to manually deploy the
dashboard once built, you can run:
git remote add ts-migration-dashboard git@github.com:MetaMask/metamask-extension-ts-migration-dashboard.git
yarn ts-migration:dashboard:deploy
* Automate the Flask release
A Flask release will now be published alongside each main extension
release. The version of each Flask release will be the same as the
extension version except it will have the suffix `-flask.0`.
* Programmatically remove build prefix
The create GH release Bash script derives the Flask version from the
Flask build filename by removing the build prefix, leaving just the
version. Rather than hard-coding the prefix size to remove, it is now
calculated programmatically so that it is easier to read and update.
* Fix tag publishing
The tab publishing step used the wrong credentials, and didn't properly
identify the commit author. This has now been fixed.
* Changed registryUrl for snaps only in firefox
Fixed getPlatform to only be imported into metamask-controller in flask
Removed snaps specific testrunner script and use run-all with a cli option
* Fixed flakey tests
* Removed unneeded await
* Added delay
* Fixed linting
# Permission System 2.0
## Background
This PR migrates the extension permission system to [the new `PermissionController`](https://github.com/MetaMask/snaps-skunkworks/tree/main/packages/controllers/src/permissions).
The original permission system, based on [`rpc-cap`](https://github.com/MetaMask/rpc-cap), introduced [`ZCAP-LD`](https://w3c-ccg.github.io/zcap-ld/)-like permissions to our JSON-RPC stack.
We used it to [implement](https://github.com/MetaMask/metamask-extension/pull/7004) what we called "LoginPerSite" in [version 7.7.0](https://github.com/MetaMask/metamask-extension/releases/tag/v7.7.0) of the extension, which enabled the user to choose which accounts, if any, should be exposed to each dapp.
While that was a worthwhile feature in and of itself, we wanted a permission _system_ in order to enable everything we are going to with Snaps.
Unfortunately, the original permission system was difficult to use, and necessitated the creation of the original `PermissionsController` (note the "s"), which was more or less a wrapper for `rpc-cap`.
With this PR, we shake off the yoke of the original permission system, in favor of the modular, self-contained, ergonomic, and more mature permission system 2.0.
Note that [the `PermissionController` readme](https://github.com/MetaMask/snaps-skunkworks/tree/main/packages/controllers/src/permissions/README.md) explains how the new permission system works.
The `PermissionController` and `SubjectMetadataController` are currently shipped via `@metamask/snap-controllers`. This is a temporary state of affairs, and we'll move them to `@metamask/controllers` once they've landed in prod.
## Changes in Detail
First, the changes in this PR are not as big as they seem. Roughly half of the additions in this PR are fixtures in the test for the new migration (number 68), and a significant portion of the remaining ~2500 lines are due to find-and-replace changes in other test fixtures and UI files.
- The extension `PermissionsController` has been deleted, and completely replaced with the new `PermissionController` from [`@metamask/snap-controllers`](https://www.npmjs.com/package/@metamask/snap-controllers).
- The original `PermissionsController` "domain metadata" functionality is now managed by the new `SubjectMetadataController`, also from [`@metamask/snap-controllers`](https://www.npmjs.com/package/@metamask/snap-controllers).
- The permission activity and history log controller has been renamed `PermissionLogController` and has its own top-level state key, but is otherwise functionally equivalent to the existing implementation.
- Migration number 68 has been added to account for the new state changes.
- The tests in `app/scripts/controllers/permissions` have been migrated from `mocha` to `jest`.
Reviewers should focus their attention on the following files:
- `app/scripts/`
- `metamask-controller.js`
- This is where most of the integration work for the new `PermissionController` occurs.
Some functions that were internal to the original controller were moved here.
- `controllers/permissions/`
- `selectors.js`
- These selectors are for `ControllerMessenger` selector subscriptions. The actual subscriptions occur in `metamask-controller.js`. See the `ControllerMessenger` implementation for details.
- `specifications.js`
- The caveat and permission specifications are required by the new `PermissionController`, and are used to specify the `eth_accounts` permission and its JSON-RPC method implementation.
See the `PermissionController` readme for details.
- `migrations/068.js`
- The new state should be cross-referenced with the controllers that manage it.
The accompanying tests should also be thoroughly reviewed.
Some files may appear new but have just moved and/or been renamed:
- `app/scripts/lib/rpc-method-middleware/handlers/request-accounts.js`
- This was previously implemented in `controllers/permissions/permissionsMethodMiddleware.js`.
- `test/mocks/permissions.js`
- A truncated version of `test/mocks/permission-controller.js`.
Co-authored-by: Mark Stacey <markjstacey@gmail.com>
* add storybook unit tests with CI integration
* fix command and fix casing for test
* change ci ordering for storybook tasks
* fix syntax error
* fix jest
* lint
* Add transaction-total-banner render test to Storybook (#12517)
* transaction-total-banner
* lint
* confirm to spec
* lint
* fix jest ocnfig for snapshot test failure
The beta and Flask builds are now built on CI and included in the
metamask bot comment alongside the main builds. The same sourcemap
linter and mozilla linter used for the prod builds is also run on the
beta and Flask builds.
Closes#12426
The benchmark script can now be set to retry upon failure, like the E2E
tests do. The default is zero, just as with the E2E tests. A retry of 2
has been set in CI to match the E2E tests as well.
The `retry` module had to be adjusted to throw an error in the case of
failure. Previously it just set the exit code, but that only worked
because it was the last thing called before the process ended. That is
no longer the case.
This script makes it easier to run an individual E2E test. In the past
I've run individual scripts by editing `run-all.sh` manually, but now
that can be done more easily with this script. It also allows setting
the number of retries to use and the browser to use from the CLI.
This script has been added as an npm script as well, called
'test:e2e:single'.
The `run-all.sh` script was rewritten in JavaScript to make it easier
to pass through a `--retries` argument.
The default number of retries has been set to zero to make local
testing easier. It has been set to 2 on CI.
This was mainly done to consolidate the code used to run an E2E test in
one place, to make later improvements easier.
Sentry is now configured with environment variables, rather than with
hard-coded values. This makes it easier to test Sentry functionality
using a different Sentry account, as we did recently during QA of
v9.5.1.
The only change for the normal build process is the introduction of the
`SENTRY_DSN_DEV` variable, which can be set via `.metamaskrc` or via an
environment variable. This determines where error reports are sent. It
still defaults to our team Sentry account's `metamask-testing` project.
The `sentry:publish` script now requires SENTRY_ORG and SENTRY_PROJECT
to be set in order to publish release artifacts. The CircleCI
configuration has been updated with these values, so it should act the
same as it did before. Previously we had used a CLI flag to specify the
organization and project, but Sentry already natively supports these
environment variables [1].
[1]: https://docs.sentry.io/product/cli/configuration/#configuration-values
Add changelog validation to CI, ensuring that the changelog follows the
KeepAChangelog format. Additionally, this will also ensure that all of
the auto-generated "Uncategorized" changelog entries on release
branches get categorized.
The SSH key used for Storybook deployments to `metamask-storybook` has
been updated. This new key is associated with `metamaskbot` rather than
a specific team member.
* Setup jest config
* Adjust test for jest.
* Adjust lint config
* Omit swaps ui folder for unit testing
* Omit swaps from test:unit:lax
* Add jest.config.js to script files
* Restore mocks rather than clearing them.
* Update jest config and adjust lint to include subdirs
* Convert view-quote-price-difference test to jest
* Add jest ci and ci coverage scripts. Add jest unit test to general test command
* Add test coverage to ci
* Use --ignore flag
* Fixup
* Add @metamask/eslint-config-jest
* Update .eslintrc.js
Co-authored-by: Mark Stacey <markjstacey@gmail.com>
* Adds jest-coverage/
Co-authored-by: Mark Stacey <markjstacey@gmail.com>
The changelog script now accepts an `--rc` flag to tell it whether to
add new changes to `Unreleased` or to the header for the current
version.
Previously this was inferred from whether the current version matched
the most recent tag. However this method only works for the first
update. Using a flag simplifies this logic, and makes it possible to
manually re-run this for further updates to a release candidate.
The changelog will now be automatically updated when a release branch
is created. A new release header along with changelog entries for any
new commits will be added.
Note that this changelog will still need to be manually cleaned up, but
it's one less manual step at least.
The old Bash script for adding a new release header to the changelog
has been removed, as that functionality is now built into the changelog
update script.
A new script has been added to commit any changes made to the manifest
and changelog. This step used to happen at the end of the bump manifest
version script, but now the changelog update relies upon the manifest
version bump happening first, so it needed to be re-ordered. The
changes should only be committed on the first run of the branch, as
it's contingent upon the manifest changing (due to the version bump).
Further changelog updates won't trigger new automatic commits.
The script responsible for creating the "Sync `master` with `develop`"
PR has been removed. We will soon be eliminating the need for a
`master` branch altogether, so we don't need this anymore. Also, this
script hasn't been running correctly in a long time. We've been
creating this PR manually.
A CI job has been added to ensure the `allow-scripts` config and the
LavaMoat auto-generated policy is up-to-date. This will only run on
release branches and the `master` branch, because it's too difficult a
requirement to meet for each PR for contributors on macOS, due to
differences in the dependency graph caused by optional dependencies.
The `allow-scripts` and LavaMoat policy have both been updated using
`yarn allow-scripts auto` and `yarn lavamoat:auto`.
The `.sh` file extension is now used for all Bash scripts. This ensures
the files are recognized as Bash scripts by the ShellCheck CI job, and
by editors/IDEs for improved syntax highlighting.
* ci - run storybook and add to build-artifacts
* ci/storybook - rename storybook build path and fix artifact upload
* ci/storybook - rename link text
* clean - remove accidently committed storybook build dir
* storybook - fix image path to relative (#10364)
Dependencies are now cached between builds, using a checksum of the
`yarn.lock` file as the cache key. The `node_modules` directory and the
`.har` file from the install are cached and restored, so that we ensure
the record of the install is always preserved alongside the
dependencies.
The consolidation of the `collect-har-artifact` script was to make it
easier to cache the `.har` file along with the dependencies.
We don't look at coveralls very much. We might occasionally consult it
to see a report on our code coverage, but that report is already
generated entirely locally, and has been added to the MetaMask bot
comment in #10061.
The CI config has been updated to use CircleCI executors. This allows
us to define the container environments used in one place, and reuse
these environment definitions between jobs.
This should result in no functional changes.
The Firefox e2e tests now use the `.zip` file for testing the
extension. We've found this to produce more similar results to
production, compared to the old method of loading the unzipped
directory.
Passing in a `.zip` file to the Chrome driver didn't seem to work. I
didn't investigate this further to see if it was possible, but I'm not
sure it makes a difference on Chrome anyway.
An e2e test has been added that uses the new mock Segment server to
verify that the three initial page metric events are sent correctly.
Using the mock Segment server requires a special build with this mock
Segment server hostname embedded, so a distinct job for building and
running this test was required. As such, it was left out of the
`run-all.sh` script.
The sesify viz step of the build was broken in #9838 when
`eth-rpc-errors@4` was introduced to the project. `eth-rpc-errors@4`
uses inline sourcemaps without including the full source in the
sourcemap, which breaks `sesify`.
`sesify` has been fixed[1] (under its new name, `lavamoat-browserify`),
but it has been disabled temporarily until this fix is included in a
new release, and until we can update to use it.
[1]: https://github.com/LavaMoat/LavaMoat/pull/121
This reduces the footprint of each Node process in an attempt to try
and lower the failure rate.
> Expected behavior with –max-old-space-size within container constraints
>
> By default, Node.js (up to 11.x) uses a maximum heap size of 700MB and 1400MB
> on 32-bit and 64-bit platforms, respectively. For current defaults, see the
> reference mentioned at the end of blog.
[1]:https://developer.ibm.com/languages/node-js/articles/nodejs-memory-management-in-container-environments/
The remaining integration tests are all covered by e2e tests, so
they're no longer needed.
All associated scripts, fixtures, and dependencies have also been
removed.
Our JSDoc documentation has not been updated in a very long time, and
we don't use JSDoc in enough places for the docs to have been
especially useful. The tools and scripts used to generate and publish
these docs have been removed.
References to this documentation have also been removed from the
README.
Hopefully once the TypeScript migration has made substantial progress,
we can generate more useful documentation using something like TypeDoc.
The Storybook deploy step is currently broken because it's using the
wrong source branch (`master` instead of `develop`), and because the
key that CircleCI is setup with doesn't have write access to the repo.
While I expect we'll get these two problems fixed soon, this ensures
that we at least have passing builds on `develop` in the meantime.
* Minimum changes to get storybook working
Undo path changes
* Add build:storybook scripts to package.json
* Add storybook deployer
* Add storybook:deploy to package.json
* Update circle ci config
* Update yarn.lock
* Remove addon-info
* Update yarn.lock file to reflect removing of addon-info
Co-authored-by: Dan J Miller <danjm.com@gmail.com>
* Add benchmark to CI
The page load benchmark for Chrome is now run during CI, and the
results are collected and summarized in the `metamaskbot` comment.
Closes#6881
* Double default number of samples
The number of default samples was changed from 10 to 20. The results
from 10 samples would show statistically significant changes in page
load times between builds, so weren't a sufficiently useful metric.
This reverts commit 4b4c00e94f. The
original change was a possible optimization of CI, though it ended up
not having a huge impact. It was thought that it may have broken source
maps, because the test build overwrote the `dist` directory that the
source maps were written to. However this turned out not to be the
case, as the changes to `dist` are never persisted to the workspace.
This is being re-introduced because the test build is needed for an
additional job (the page load benchmark), and sharing the same build
for all three jobs would surely be faster than building it separately
three times.
* Add shellcheck lint script
* Add to build
* Add shellcheck lint to main lint task
* Put shellcheck in the right place, hopefully?
* Fix declared multiple executor types
* Add sudo
* Address shellcheck warnings
* Add test-lint-shellcheck
* Add test-lint-shellcheck to workflow
* Use correct lint task
* output version which could be helpful for debugging
* Address PR feedback
* consistency++
* ci - install deps - limit install scripts to those needed for build
* Update .circleci/scripts/deps-install.sh
Co-Authored-By: Mark Stacey <markjstacey@gmail.com>
* ci - install deps - expand install scripts needed for tests
* ci - install deps - expand install scripts needed for integration tests
* ci - install deps - fix node-sass script ref
* github - set codeowners for scripts/deps-install
* development - add utility to show deps with install scripts
* lint fix
* deps - move read-installed to devDeps
* Use common test build during CI
Previously both e2e test jobs were running `test:build`. Now there is a
separate job that runs `test:build` that runs before each e2e test job,
so that `test:build` is only run once instead of twice.
* Move test builds to separate directory
This prevents the test build from conflicting with the production build
in later jobs.
* Add '--quiet' flag to verify locales script
The `--quiet` flag reduces the console output to just the essential
information for running in a CI environment. For each locale, it will
print the number of unused messages (if any).
* Add `verify-locales` script to lint CI job
The locales are now verified as part of the lint CI job. Any unused
messages detected will result in the job failing.
* ci - install deps with "--har" flag to capture network activity
* ci - add yarn install HAR logs to build-artifacts
* ci - yarn har - fix typo
* Update .circleci/scripts/collect-har-artifact.sh
Co-Authored-By: Mark Stacey <markjstacey@gmail.com>
* ci - create source-map-explorer build-artifacts
* ci - add source-map-explorer builds to metamaskbot comment
* lint fix
* ci - source-map-explorer - include all bundles
* Publish GitHub release from master branch
This ensures that changes made on `develop` since branching for the
release are not included. It also ensures that the final release
sourcemaps line-up correctly (they were always build on master)`.
* Consolidate publish jobs
The jobs `job-publish-release` and `create_github_release` both handle
different parts of publishing a release. They have been consolidated
into a single `job-publish-release` job.
* Update release script to expect a merge commit
The release script was originally written to be run on `develop`, so it
expected the current commit to be a result of `Squash & Merge`. Now
that it's run on `master`, it will generally be run against a merge
commit.
The version is now extracted from the commit message using a regular
expression that should work on all version of Bash v3+, and should be
tolerant of both merge commits and `Squash & Merge` commits.
* Target `master` with release PR
`master` is now targeted by the release PR instead of `develop`, as
the release has to be created from the master branch.
The update to `develop` is handled after the release by a PR from
`master` to `develop`, which is created automatically after the
release.
As a solution to the constant lockfile churn issues we've had with
`npm`, the project now uses `yarn` to manage dependencies.
The `package-lock.json` file has been replaced with `yarn.lock`, which
was created using `yarn import`. It should approximate the contents of
`package-lock.json` fairly well, though there may be some changes due to
deduplication. The codeowners file has been updated to reference this
new lockfile.
All documentation and npm scripts have been updated to reference `yarn`
rather than `npm`. Note that running scripts using `npm run` still works
fine, but it seemed better to switch those to `yarn` as well to avoid
confusion.
The `npm-audit` Bash script has been replaced with `yarn-audit`. The
output of `yarn audit` is a bit different than `npm audit` in that it
returns a bitmask to describe which severity issues were found. This
made it simpler to check the results directly from the Bash script, so
the associated `npm-audit-check.js` script was no longer required. The
output should be exactly the same, and the information is still sourced
from the same place (the npm registry).
The new `yarn-audit` script does have an external dependency: `jq`.
However, `jq` is already assumed to be present by another CI script, and
is present on all CI images we use. `jq` was not added to `package.json`
as a dependency because there is no official package on the npm
registry, just wrapper scripts. We don't need it anywhere exept on CI
anyway.
The section in `CONTRIBUTING` about how to develop inside the
`node_modules` folder was removed, as the advice was a bit dated, and
wasn't specific to this project anyway.
The npm audit script was auditing all dependencies, then filtering the
results to just the advisories concerning production dependencies. This
was done by checking the boolean `dev` and `optional` properties of each
`findings` entry in each advisory.
The `dev` and `optional` properties are now missing, which is resulting
in dev advisories being mistakenly identified as affecting production.
This check has been removed, and instead the `--production` flag is used
when calling `npm audit`. This accomplishes the same goal without
relying as much upon the audit output format.
The `--production` flag was added in `npm` `v6.10.0`, so `npm` has been
updated to the current latest stable (`v6.10.2`) for the `test-deps`
job. It was also updated on the `prep-deps-npm` job to ensure
consistency in behaviour. The other jobs only use `npm run` which hasn't
changed substantially in some time, so compatibility isn't really a
concern for those.
`audit.json` has also been added to `.gitignore`. It was accidentally
checked in once while working on this branch.
* ci: Rename full_test to test_and_release
* ci: Add scripts to automate GH releases
* Add .bak files to .gitignore
* ci: Add reviewer to the auto version PR
The Drizzle tests have not been used for some time. They were used to
ensure compatibility with newer versions of `web3` v1. If we want to
re-add tests to ensure compatibility with newer `web3` versions, we
should find some way of doing that more reliably than was done here -
these tests were somewhat flaky and unreliable.
`addons-linter` will occasionally run out of heap space. This provides 3
GB of heap for that script rather than the default ~1.5 GB. The CircleCI
containers have 4GB of memory, so this should leave plenty of extra
space for non-heap memory.
The MetaMask bot is currently failing to publish docs updates, and it is
[blocking our ability to release new
versions](https://github.com/MetaMask/metamask-extension/pull/6765).
While we should pursue a proper fix, I think it's worth disabling in the
meanwhile so this glitch doesn't interfere with our regular release
cadence further.