Skip to content

Commit 21140f6

Browse files
authored
Merge pull request #3095 from element-hq/robin/berry
Upgrade to Yarn v4 (Berry)
2 parents a4f8649 + 6927a92 commit 21140f6

18 files changed

+13841
-9279
lines changed

.githooks/post-commit

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
#!/usr/bin/sh
2+
3+
FILE=.links.disabled.yaml
4+
if test -f "$FILE"; then
5+
# echo "$FILE exists. -> moving to .links.disabled.yaml"
6+
mv .links.disabled.yaml .links.yaml
7+
# echo "running yarn"
8+
yarnLog=$(yarn)
9+
echo "[yarn-linker] The post-commit hook has re-enabled .links.yaml."
10+
exit 1
11+
fi

.githooks/pre-commit

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
#!/usr/bin/sh
2+
3+
FILE=".links.yaml"
4+
if test -f "$FILE"; then
5+
# echo "$FILE exists. -> moving to .links.disabled.yaml"
6+
mv .links.yaml .links.disabled.yaml
7+
# echo "running yarn"
8+
x=$(yarn)
9+
y=$(git add yarn.lock)
10+
echo "[yarn-linker] The pre-commit hook has disabled .links.yaml and MODIFIED the yarn.lock file. Review the staged changes (the hook added yarn.lock, was this desired?) and run \`git commit \` again if they look okay. The post-commit hook will re-enable your links."
11+
exit 1
12+
fi

.github/workflows/build-element-call.yaml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,13 +28,15 @@ jobs:
2828
steps:
2929
- name: Checkout code
3030
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
31+
- name: Enable Corepack
32+
run: corepack enable
3133
- name: Yarn cache
3234
uses: actions/setup-node@1d0ff469b7ec7b3cb9d8673fde0c81c44821de2a # v4
3335
with:
3436
cache: "yarn"
3537
node-version-file: ".node-version"
3638
- name: Install dependencies
37-
run: "yarn install --frozen-lockfile"
39+
run: "yarn install --immutable"
3840
- name: Build full version
3941
if: ${{ inputs.package == 'full' }}
4042
run: "yarn run build:full"

.github/workflows/lint.yaml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,15 @@ jobs:
88
steps:
99
- name: Checkout code
1010
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
11+
- name: Enable Corepack
12+
run: corepack enable
1113
- name: Yarn cache
1214
uses: actions/setup-node@1d0ff469b7ec7b3cb9d8673fde0c81c44821de2a # v4
1315
with:
1416
cache: "yarn"
1517
node-version-file: ".node-version"
1618
- name: Install dependencies
17-
run: "yarn install --frozen-lockfile"
19+
run: "yarn install --immutable"
1820
- name: Prettier
1921
run: "yarn run prettier:check"
2022
- name: i18n

.github/workflows/publish-embedded-packages.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@ jobs:
8080
name: build-output-embedded
8181
path: embedded/web/dist
8282

83+
# n.b. We don't enable corepack here because we are using plain npm
8384
- name: Setup node
8485
uses: actions/setup-node@1d0ff469b7ec7b3cb9d8673fde0c81c44821de2a # v4
8586
with:

.github/workflows/test.yaml

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,15 @@ jobs:
1010
steps:
1111
- name: Checkout code
1212
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
13+
- name: Enable Corepack
14+
run: corepack enable
1315
- name: Yarn cache
1416
uses: actions/setup-node@1d0ff469b7ec7b3cb9d8673fde0c81c44821de2a # v4
1517
with:
1618
cache: "yarn"
1719
node-version-file: ".node-version"
1820
- name: Install dependencies
19-
run: "yarn install --frozen-lockfile"
21+
run: "yarn install --immutable"
2022
- name: Vitest
2123
run: "yarn run test:coverage"
2224
- name: Upload to codecov
@@ -32,12 +34,14 @@ jobs:
3234
runs-on: ubuntu-latest
3335
steps:
3436
- uses: actions/checkout@v4
37+
- name: Enable Corepack
38+
run: corepack enable
3539
- uses: actions/setup-node@v4
3640
with:
3741
cache: "yarn"
3842
node-version-file: ".node-version"
3943
- name: Install dependencies
40-
run: yarn install --frozen-lockfile
44+
run: yarn install --immutable
4145
- name: Install Playwright Browsers
4246
run: yarn playwright install --with-deps
4347
- name: Run backend components

.github/workflows/translations-download.yaml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,16 @@ jobs:
1515
- name: Checkout the code
1616
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
1717

18+
- name: Enable Corepack
19+
run: corepack enable
20+
1821
- uses: actions/setup-node@1d0ff469b7ec7b3cb9d8673fde0c81c44821de2a # v4
1922
with:
2023
cache: "yarn"
2124
node-version-file: ".node-version"
2225

2326
- name: Install Deps
24-
run: "yarn install --frozen-lockfile"
27+
run: "yarn install --immutable"
2528

2629
- name: Prune i18n
2730
run: "rm -R locales"

.gitignore

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,18 @@ dist-ssr
99
public/config.json
1010
backend/synapse_tmp/*
1111
/coverage
12+
13+
# Yarn
1214
yarn-error.log
15+
/.pnp.*
16+
/.yarn/*
17+
!/.yarn/patches
18+
!/.yarn/plugins
19+
!/.yarn/releases
20+
!/.yarn/sdks
21+
!/.yarn/versions
22+
/.links.yaml
23+
/.links.disabled.yaml
1324

1425
# Playwright
1526
/test-results/

.yarn/plugins/linker.cjs

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
/*
2+
Copyright 2025 New Vector Ltd.
3+
4+
SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial
5+
Please see LICENSE in the repository root for full details.
6+
*/
7+
8+
module.exports = {
9+
name: "linker",
10+
factory: (require) => ({
11+
hooks: {
12+
// Yarn's plugin system is very light on documentation. The best we have
13+
// for this hook is simply the type definition in
14+
// https://github.com/yarnpkg/berry/blob/master/packages/yarnpkg-core/sources/Plugin.ts
15+
registerPackageExtensions: async (config, registerPackageExtension) => {
16+
const { structUtils } = require("@yarnpkg/core");
17+
const { parseSyml } = require("@yarnpkg/parsers");
18+
const path = require("path");
19+
const fs = require("fs");
20+
const process = require("process");
21+
22+
// Create a descriptor that we can use to target our direct dependencies
23+
const projectPath = config.projectCwd
24+
.replace(/\\/g, "/")
25+
.replace("/C:/", "C:/");
26+
const manifestPath = path.join(projectPath, "package.json");
27+
const manifest = JSON.parse(fs.readFileSync(manifestPath, "utf8"));
28+
const selfDescriptor = structUtils.parseDescriptor(
29+
`${manifest.name}@*`,
30+
true,
31+
);
32+
33+
// Load the list of linked packages
34+
const linksPath = path.join(projectPath, ".links.yaml");
35+
let linksFile;
36+
try {
37+
linksFile = fs.readFileSync(linksPath, "utf8");
38+
} catch (e) {
39+
return; // File doesn't exist, there's nothing to link
40+
}
41+
let links;
42+
try {
43+
links = parseSyml(linksFile);
44+
} catch (e) {
45+
console.error(".links.yaml has invalid syntax", e);
46+
process.exit(1);
47+
}
48+
49+
// Resolve paths and turn them into a Yarn package extension
50+
const overrides = Object.fromEntries(
51+
Object.entries(links).map(([name, link]) => [
52+
name,
53+
`portal:${path.resolve(config.projectCwd, link)}`,
54+
]),
55+
);
56+
const overrideIdentHashes = new Set();
57+
for (const name of Object.keys(overrides))
58+
overrideIdentHashes.add(
59+
structUtils.parseDescriptor(`${name}@*`, true).identHash,
60+
);
61+
62+
// Extend our own package's dependencies with these local overrides
63+
registerPackageExtension(selfDescriptor, { dependencies: overrides });
64+
65+
// Filter out the original dependencies from the package spec so Yarn
66+
// actually respects the overrides
67+
const filterDependencies = (original) => {
68+
const pkg = structUtils.copyPackage(original);
69+
pkg.dependencies = new Map(
70+
Array.from(pkg.dependencies.entries()).filter(
71+
([, value]) => !overrideIdentHashes.has(value.identHash),
72+
),
73+
);
74+
return pkg;
75+
};
76+
77+
// Patch Yarn's own normalizePackage method to use the above filter
78+
const originalNormalizePackage = config.normalizePackage;
79+
config.normalizePackage = function (pkg, extensions) {
80+
return originalNormalizePackage.call(
81+
this,
82+
pkg.identHash === selfDescriptor.identHash
83+
? filterDependencies(pkg)
84+
: pkg,
85+
extensions,
86+
);
87+
};
88+
},
89+
},
90+
}),
91+
};

.yarnrc.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
nodeLinker: node-modules
2+
plugins:
3+
- .yarn/plugins/linker.cjs

README.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,7 @@ To get started clone and set up this project:
149149
```sh
150150
git clone https://github.com/element-hq/element-call.git
151151
cd element-call
152+
corepack enable
152153
yarn
153154
```
154155

@@ -168,6 +169,10 @@ You're now ready to launch the development server:
168169
yarn dev
169170
```
170171

172+
See also:
173+
174+
- [Developing with linked packages](./linking.md)
175+
171176
### Backend
172177

173178
A docker compose file `dev-backend-docker-compose.yml` is provided to start the

docs/README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
## Element Call Docs
22

3-
This folder contains documentation for Element Call setup and usage.
3+
This folder contains documentation for setup, usage, and development of Element Call.
44

55
- [Embedded vs standalone mode](./embedded-standalone.md)
66
- [Url format and parameters](./url-params.md)
77
- [Global JS controls](./controls.md)
88
- [Self-Hosting](./self-hosting.md)
9+
- [Developing with linked packages](./linking.md)

docs/linking.md

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
# Developing with linked packages
2+
3+
If you want to make changes to a package that Element Call depends on and see those changes applied in real time, you can create a link to a local copy of the package. Yarn has a command for this (`yarn link`), but it's not recommended to use it as it ends up modifying package.json with details specific to your development environment.
4+
5+
Instead, you can use our little 'linker' plugin. Create a file named `.links.yaml` in the Element Call project directory, listing the names and paths of any dependencies you want to link. For example:
6+
7+
```yaml
8+
matrix-js-sdk: ../path/to/matrix-js-sdk
9+
"@vector-im/compound-web": /home/alice/path/to/compound-web
10+
```
11+
12+
Then run `yarn install`.
13+
14+
## Hooks
15+
16+
Changes in `.links.yaml` will also update `yarn.lock` when `yarn` is executed. The lockfile will then contain the local
17+
version of the package which would not work on others dev setups or the github CI.
18+
One always needs to run:
19+
20+
```bash
21+
mv .links.yaml .links.disabled.yaml
22+
yarn
23+
```
24+
25+
before committing a change.
26+
27+
To make it more convenient to work with this linking system we added git hooks for your conviniece.
28+
A `pre-commit` hook will run `mv .links.yaml .links.disabled.yaml`, `yarn` and `git add yarn.lock` if it detects
29+
a `.links.yaml` file and abort the commit.
30+
You will than need to check if the resulting changes are appropriate and commit again.
31+
32+
A `post-commit` hook will setup the linking as it was
33+
before if a `.links.disabled.yaml` is present. It runs `mv .links.disabled.yaml .links.yaml` and `yarn`.
34+
35+
To activate the hooks automatically configure git with
36+
37+
```bash
38+
git config --local core.hooksPath .githooks/
39+
```

docs/self-hosting.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,7 @@ source. First, clone and install the package:
159159
```sh
160160
git clone https://github.com/element-hq/element-call.git
161161
cd element-call
162+
corepack enable
162163
yarn
163164
yarn build
164165
```

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -130,5 +130,6 @@
130130
"resolutions": {
131131
"@livekit/components-core/rxjs": "^7.8.1",
132132
"matrix-widget-api": "1.11.0"
133-
}
133+
},
134+
"packageManager": "yarn@4.7.0"
134135
}

scripts/dockerbuild.sh

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,6 @@ set -ex
44

55
export VITE_APP_VERSION=$(git describe --tags --abbrev=0)
66

7+
corepack enable
78
yarn install
89
yarn run build

src/analytics/PosthogAnalytics.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ import posthog, {
1212
} from "posthog-js";
1313
import { logger } from "matrix-js-sdk/src/logger";
1414
import { type MatrixClient } from "matrix-js-sdk/src/matrix";
15-
import { Buffer } from "buffer";
1615
import { type Subscription } from "rxjs";
1716

1817
import { widget } from "../widget";
@@ -296,7 +295,7 @@ export class PosthogAnalytics {
296295
const posthogIdMaterial = "ec" + accountAnalyticsId + client.getUserId();
297296
const bufferForPosthogId = await crypto.subtle.digest(
298297
"sha-256",
299-
Buffer.from(posthogIdMaterial, "utf-8"),
298+
new TextEncoder().encode(posthogIdMaterial),
300299
);
301300
const view = new Int32Array(bufferForPosthogId);
302301
return Array.from(view)

0 commit comments

Comments
 (0)