Skip to content

Commit 0704312

Browse files
mcmireGudahttMrtenz
authored
Convert to monorepo (#831)
Currently, this repo and everything within it is published as a single package. Using and maintaining this package, however, is problematic for a few reasons: 1. Even if your library uses a couple of controllers, you must add the entire package and all of its dependencies to your library's dependency tree. 2. Because this package is used by many teams, when we make a new release, even if that release contains changes to one controller, we must coordinate with all teams to ensure that nothing has broken. In addition, we want to be able to maintain our existing libraries more easily, as right now it is difficult due to code being split across multiple repositories. To solve this problem, this commit converts the existing structure to a monorepo structure, assigning controllers to packages which we can then publish individually. (A full list of packages is contained in the README.) Along with a monorepo structure comes with a litany of changes: * **TypeScript:** We have a "master" TypeScript config file, which is used by developers' code editors, but each package also has its own TypeScript config files. We are also using TypeScript project references, which allows us to inform TypeScript how all packages are connected to each other dependency-wise; this allows TypeScript to know which packages to build first. * **Jest:** Each package has its own Jest config file, and we use Yarn workspaces to run the tests for each package in parallel. * **ESLint:** We are able to lint the monorepo in the same way as we linted before. * **TypeDoc:** We've added TypeDoc to each package and use Yarn workspaces to generate docs for each package in parallel. * **Yarn:** A bunch of Yarn constraints have been added that verify that both the root package and each package has a well-formed `package.json`. * **Other notes:** * Some packages depend on other packages within the monorepo. In other words, we might have an import for `@metamask/base-controller` within a controller file. Out of the box both TypeScript and Jest won't know what to do with this. Although Yarn will add a symlink in `node_modules` to the proper directory in `packages` for the package in question, TypeScript expects the code for the package to be compiled (i.e. for `dist/` to be populated), and Jest, as it has custom resolver logic, doesn't know what to do at all. To make this possible we have to add a custom mapping for both TypeScript and Jest that will tell them what to do when it sees a `@metamask/*` import. * The GitHub Action workflow files have been standardized against the newest changes to the module template. Co-authored-by: Mark Stacey <[email protected]> Co-authored-by: Maarten Zuidhoorn <[email protected]>
1 parent 3a003ea commit 0704312

File tree

315 files changed

+8061
-4034
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

315 files changed

+8061
-4034
lines changed

.github/workflows/create-release-pr.yml

Lines changed: 0 additions & 43 deletions
This file was deleted.

.github/workflows/lint-build-test.yml

Lines changed: 74 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,12 @@
11
name: Lint, Build, and Test
22

33
on:
4-
push:
5-
branches: [main]
6-
pull_request:
4+
workflow_call:
75

86
jobs:
9-
lint-build-test:
10-
name: Lint, Build, and Test
11-
runs-on: ubuntu-20.04
7+
prepare:
8+
name: Prepare
9+
runs-on: ubuntu-latest
1210
strategy:
1311
matrix:
1412
node-version: [14.x, 16.x]
@@ -18,31 +16,78 @@ jobs:
1816
uses: actions/setup-node@v3
1917
with:
2018
node-version: ${{ matrix.node-version }}
21-
- name: Get Yarn cache directory
22-
run: echo "YARN_CACHE_DIR=$(yarn config get cacheFolder)" >> $GITHUB_OUTPUT
23-
id: yarn-cache-dir
24-
- name: Get Yarn version
25-
run: echo "YARN_VERSION=$(yarn --version)" >> $GITHUB_OUTPUT
26-
id: yarn-version
27-
- name: Cache yarn dependencies
28-
uses: actions/cache@v3
19+
cache: yarn
20+
- run: yarn --immutable
21+
22+
lint:
23+
name: Lint
24+
runs-on: ubuntu-latest
25+
needs: prepare
26+
strategy:
27+
matrix:
28+
node-version: [14.x, 16.x]
29+
steps:
30+
- uses: actions/checkout@v3
31+
- name: Use Node.js ${{ matrix.node-version }}
32+
uses: actions/setup-node@v3
2933
with:
30-
path: ${{ steps.yarn-cache-dir.outputs.YARN_CACHE_DIR }}
31-
key: yarn-cache-${{ runner.os }}-${{ steps.yarn-version.outputs.YARN_VERSION }}-${{ hashFiles('yarn.lock') }}
34+
node-version: ${{ matrix.node-version }}
35+
cache: yarn
3236
- run: yarn --immutable
3337
- run: yarn lint
34-
- name: Validate RC changelog
35-
if: ${{ startsWith(github.ref, 'release/') }}
36-
run: yarn auto-changelog validate --rc
37-
- name: Validate changelog
38-
if: ${{ !startsWith(github.ref, 'release/') }}
39-
run: yarn auto-changelog validate
38+
- run: yarn changelog:validate
39+
- name: Require clean working directory
40+
shell: bash
41+
run: |
42+
if ! git diff --exit-code; then
43+
echo "Working tree dirty at end of job"
44+
exit 1
45+
fi
46+
47+
build:
48+
name: Build
49+
runs-on: ubuntu-latest
50+
needs: prepare
51+
strategy:
52+
matrix:
53+
node-version: [14.x, 16.x]
54+
steps:
55+
- uses: actions/checkout@v3
56+
- name: Use Node.js ${{ matrix.node-version }}
57+
uses: actions/setup-node@v3
58+
with:
59+
node-version: ${{ matrix.node-version }}
60+
cache: yarn
61+
- run: yarn --immutable
4062
- run: yarn build
41-
- run: yarn test --maxWorkers=1
42-
all-jobs-pass:
43-
name: All jobs pass
44-
runs-on: ubuntu-20.04
45-
needs:
46-
- lint-build-test
63+
- name: Require clean working directory
64+
shell: bash
65+
run: |
66+
if ! git diff --exit-code; then
67+
echo "Working tree dirty at end of job"
68+
exit 1
69+
fi
70+
71+
test:
72+
name: Test
73+
runs-on: ubuntu-latest
74+
needs: prepare
75+
strategy:
76+
matrix:
77+
node-version: [14.x, 16.x]
4778
steps:
48-
- run: echo "Great success!"
79+
- uses: actions/checkout@v3
80+
- name: Use Node.js ${{ matrix.node-version }}
81+
uses: actions/setup-node@v3
82+
with:
83+
node-version: ${{ matrix.node-version }}
84+
cache: yarn
85+
- run: yarn --immutable
86+
- run: yarn test
87+
- name: Require clean working directory
88+
shell: bash
89+
run: |
90+
if ! git diff --exit-code; then
91+
echo "Working tree dirty at end of job"
92+
exit 1
93+
fi

.github/workflows/main.yml

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
name: Main
2+
3+
on:
4+
push:
5+
branches: [main]
6+
pull_request:
7+
8+
jobs:
9+
check-workflows:
10+
name: Check workflows
11+
runs-on: ubuntu-latest
12+
steps:
13+
- uses: actions/checkout@v3
14+
- name: Download actionlint
15+
id: download-actionlint
16+
run: bash <(curl https://raw.githubusercontent.com/rhysd/actionlint/7fdc9630cc360ea1a469eed64ac6d78caeda1234/scripts/download-actionlint.bash) 1.6.22
17+
shell: bash
18+
- name: Check workflow files
19+
run: ${{ steps.download-actionlint.outputs.executable }} -color
20+
shell: bash
21+
22+
lint-build-test:
23+
name: Lint, build, and test
24+
needs: check-workflows
25+
uses: ./.github/workflows/lint-build-test.yml
26+
27+
is-release:
28+
name: Determine whether this is a release merge commit
29+
needs: lint-build-test
30+
if: startsWith(github.event.commits[0].author.name, 'github-actions')
31+
runs-on: ubuntu-latest
32+
outputs:
33+
IS_RELEASE: ${{ steps.is-release.outputs.IS_RELEASE }}
34+
steps:
35+
- uses: MetaMask/action-is-release@v1
36+
id: is-release
37+
38+
publish-release:
39+
name: Publish release
40+
needs: is-release
41+
if: needs.is-release.outputs.IS_RELEASE == 'true'
42+
permissions:
43+
contents: write
44+
uses: ./.github/workflows/publish-release.yml
45+
46+
all-jobs-pass:
47+
name: All jobs pass
48+
runs-on: ubuntu-latest
49+
needs: lint-build-test
50+
steps:
51+
- run: echo "Great success!"

.github/workflows/publish-release.yml

Lines changed: 17 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -1,58 +1,33 @@
11
name: Publish Release
22

33
on:
4-
push:
5-
branches: [main]
4+
workflow_call:
65

76
jobs:
8-
is-release:
9-
# release merge commits come from github-actions
10-
if: startsWith(github.event.commits[0].author.name, 'github-actions')
11-
outputs:
12-
IS_RELEASE: ${{ steps.is-release.outputs.IS_RELEASE }}
13-
runs-on: ubuntu-latest
14-
steps:
15-
- uses: MetaMask/action-is-release@v1
16-
id: is-release
17-
187
publish-release:
198
permissions:
209
contents: write
21-
if: needs.is-release.outputs.IS_RELEASE == 'true'
2210
runs-on: ubuntu-latest
23-
needs: is-release
2411
steps:
2512
- uses: actions/checkout@v3
2613
with:
2714
ref: ${{ github.sha }}
28-
- name: Get Node.js version
29-
id: nvm
30-
run: echo "NODE_VERSION=$(cat .nvmrc)" >> $GITHUB_OUTPUT
3115
- name: Setup Node
3216
uses: actions/setup-node@v3
3317
with:
34-
node-version: ${{ steps.nvm.outputs.NODE_VERSION }}
18+
node-version-file: '.nvmrc'
19+
cache: yarn
20+
- uses: actions/cache@v3
21+
with:
22+
path: |
23+
./packages/**/dist
24+
./node_modules/.yarn-state.yml
25+
key: ${{ github.sha }}
3526
- uses: MetaMask/action-publish-release@v2
3627
env:
3728
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
38-
- name: Get Yarn cache directory
39-
run: echo "YARN_CACHE_DIR=$(yarn config get cacheFolder)" >> $GITHUB_OUTPUT
40-
id: yarn-cache-dir
41-
- name: Get Yarn version
42-
run: echo "YARN_VERSION=$(yarn --version)" >> $GITHUB_OUTPUT
43-
id: yarn-version
44-
- name: Cache yarn dependencies
45-
uses: actions/cache@v3
46-
with:
47-
path: ${{ steps.yarn-cache-dir.outputs.YARN_CACHE_DIR }}
48-
key: yarn-cache-${{ runner.os }}-${{ steps.yarn-version.outputs.YARN_VERSION }}-${{ hashFiles('yarn.lock') }}
4929
- run: yarn --immutable
5030
- run: yarn build
51-
- uses: actions/cache@v3
52-
id: restore-build
53-
with:
54-
path: ./dist
55-
key: ${{ github.sha }}
5631

5732
publish-npm-dry-run:
5833
runs-on: ubuntu-latest
@@ -62,15 +37,14 @@ jobs:
6237
with:
6338
ref: ${{ github.sha }}
6439
- uses: actions/cache@v3
65-
id: restore-build
6640
with:
67-
path: ./dist
41+
path: |
42+
./packages/**/dist
43+
./node_modules/.yarn-state.yml
6844
key: ${{ github.sha }}
69-
# Set `ignore-scripts` to skip `prepublishOnly` because the release was built already in the previous job
70-
- run: npm config set ignore-scripts true
7145
- name: Dry Run Publish
7246
# omit npm-token token to perform dry run publish
73-
uses: MetaMask/action-npm-publish@v1
47+
uses: MetaMask/action-npm-publish@v2
7448
env:
7549
SKIP_PREPACK: true
7650

@@ -83,14 +57,13 @@ jobs:
8357
with:
8458
ref: ${{ github.sha }}
8559
- uses: actions/cache@v3
86-
id: restore-build
8760
with:
88-
path: ./dist
61+
path: |
62+
./packages/**/dist
63+
./node_modules/.yarn-state.yml
8964
key: ${{ github.sha }}
90-
# Set `ignore-scripts` to skip `prepublishOnly` because the release was built already in the previous job
91-
- run: npm config set ignore-scripts true
9265
- name: Publish
93-
uses: MetaMask/action-npm-publish@v1
66+
uses: MetaMask/action-npm-publish@v2
9467
with:
9568
npm-token: ${{ secrets.NPM_TOKEN }}
9669
env:

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,3 +24,6 @@ docs
2424
!.yarn/releases
2525
!.yarn/sdks
2626
!.yarn/versions
27+
28+
# typescript
29+
*.tsbuildinfo

.yarn/plugins/@yarnpkg/plugin-constraints.cjs

Lines changed: 52 additions & 0 deletions
Large diffs are not rendered by default.

0 commit comments

Comments
 (0)