mirror of
https://github.com/Novaloop-AG/healthchat-web.git
synced 2026-11-11 02:38:39 +00:00
Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| d5672ff388 |
@@ -0,0 +1,12 @@
|
||||
# Exclude a bunch of stuff which can make the build context a larger than it needs to be
|
||||
test/
|
||||
webapp/
|
||||
lib/
|
||||
node_modules/
|
||||
karma-reports/
|
||||
.idea/
|
||||
.tmp/
|
||||
config.json*
|
||||
# Exclude the playwright directory as much as we can as the snapshots are huge and we bind mount it in
|
||||
playwright/
|
||||
!playwright/docker-entrypoint.sh
|
||||
@@ -0,0 +1,9 @@
|
||||
src/vector/modernizr.js
|
||||
test/end-to-end-tests/node_modules/
|
||||
test/end-to-end-tests/element/
|
||||
test/end-to-end-tests/synapse/
|
||||
test/end-to-end-tests/lib/
|
||||
# Legacy skinning file that some people might still have
|
||||
src/component-index.js
|
||||
# Auto-generated file
|
||||
src/modules.ts
|
||||
@@ -0,0 +1,60 @@
|
||||
module.exports = {
|
||||
plugins: ["matrix-org"],
|
||||
extends: ["./.eslintrc.js"],
|
||||
parserOptions: {
|
||||
project: ["./tsconfig.module_system.json"],
|
||||
},
|
||||
overrides: [
|
||||
{
|
||||
files: ["module_system/**/*.{ts,tsx}"],
|
||||
extends: ["plugin:matrix-org/typescript", "plugin:matrix-org/react"],
|
||||
// NOTE: These rules are frozen and new rules should not be added here.
|
||||
// New changes belong in https://github.com/matrix-org/eslint-plugin-matrix-org/
|
||||
rules: {
|
||||
// Things we do that break the ideal style
|
||||
"prefer-promise-reject-errors": "off",
|
||||
"quotes": "off",
|
||||
|
||||
// We disable this while we're transitioning
|
||||
"@typescript-eslint/no-explicit-any": "off",
|
||||
// We're okay with assertion errors when we ask for them
|
||||
"@typescript-eslint/no-non-null-assertion": "off",
|
||||
|
||||
// Ban matrix-js-sdk/src imports in favour of matrix-js-sdk/src/matrix imports to prevent unleashing hell.
|
||||
"no-restricted-imports": [
|
||||
"error",
|
||||
{
|
||||
paths: [
|
||||
{
|
||||
name: "matrix-js-sdk",
|
||||
message: "Please use matrix-js-sdk/src/matrix instead",
|
||||
},
|
||||
{
|
||||
name: "matrix-js-sdk/",
|
||||
message: "Please use matrix-js-sdk/src/matrix instead",
|
||||
},
|
||||
{
|
||||
name: "matrix-js-sdk/src",
|
||||
message: "Please use matrix-js-sdk/src/matrix instead",
|
||||
},
|
||||
{
|
||||
name: "matrix-js-sdk/src/",
|
||||
message: "Please use matrix-js-sdk/src/matrix instead",
|
||||
},
|
||||
{
|
||||
name: "matrix-js-sdk/src/index",
|
||||
message: "Please use matrix-js-sdk/src/matrix instead",
|
||||
},
|
||||
],
|
||||
patterns: [
|
||||
{
|
||||
group: ["matrix-js-sdk/lib", "matrix-js-sdk/lib/", "matrix-js-sdk/lib/**"],
|
||||
message: "Please use matrix-js-sdk/src/* instead",
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
+290
@@ -0,0 +1,290 @@
|
||||
module.exports = {
|
||||
plugins: ["matrix-org"],
|
||||
extends: ["plugin:matrix-org/babel", "plugin:matrix-org/react", "plugin:matrix-org/a11y"],
|
||||
parserOptions: {
|
||||
project: ["./tsconfig.json"],
|
||||
},
|
||||
env: {
|
||||
browser: true,
|
||||
node: true,
|
||||
},
|
||||
globals: {
|
||||
LANGUAGES_FILE: "readonly",
|
||||
},
|
||||
rules: {
|
||||
// Things we do that break the ideal style
|
||||
"no-constant-condition": "off",
|
||||
"prefer-promise-reject-errors": "off",
|
||||
"no-async-promise-executor": "off",
|
||||
"no-extra-boolean-cast": "off",
|
||||
|
||||
// Bind or arrow functions in props causes performance issues (but we
|
||||
// currently use them in some places).
|
||||
// It's disabled here, but we should using it sparingly.
|
||||
"react/jsx-no-bind": "off",
|
||||
"react/jsx-key": ["error"],
|
||||
|
||||
"no-restricted-properties": [
|
||||
"error",
|
||||
...buildRestrictedPropertiesOptions(
|
||||
["window.innerHeight", "window.innerWidth", "window.visualViewport"],
|
||||
"Use UIStore to access window dimensions instead.",
|
||||
),
|
||||
...buildRestrictedPropertiesOptions(
|
||||
["*.mxcUrlToHttp", "*.getHttpUriForMxc"],
|
||||
"Use Media helper instead to centralise access for customisation.",
|
||||
),
|
||||
...buildRestrictedPropertiesOptions(["window.setImmediate"], "Use setTimeout instead."),
|
||||
],
|
||||
"no-restricted-globals": [
|
||||
"error",
|
||||
{
|
||||
name: "setImmediate",
|
||||
message: "Use setTimeout instead.",
|
||||
},
|
||||
],
|
||||
|
||||
"import/no-duplicates": ["error"],
|
||||
// Ban matrix-js-sdk/src imports in favour of matrix-js-sdk/src/matrix imports to prevent unleashing hell.
|
||||
// Ban compound-design-tokens raw svg imports in favour of their React component counterparts
|
||||
"no-restricted-imports": [
|
||||
"error",
|
||||
{
|
||||
paths: [
|
||||
{
|
||||
name: "@testing-library/react",
|
||||
message: "Please use jest-matrix-react instead",
|
||||
},
|
||||
{
|
||||
name: "matrix-js-sdk",
|
||||
message: "Please use matrix-js-sdk/src/matrix instead",
|
||||
},
|
||||
{
|
||||
name: "matrix-js-sdk/",
|
||||
message: "Please use matrix-js-sdk/src/matrix instead",
|
||||
},
|
||||
{
|
||||
name: "matrix-js-sdk/src",
|
||||
message: "Please use matrix-js-sdk/src/matrix instead",
|
||||
},
|
||||
{
|
||||
name: "matrix-js-sdk/src/",
|
||||
message: "Please use matrix-js-sdk/src/matrix instead",
|
||||
},
|
||||
{
|
||||
name: "matrix-js-sdk/src/index",
|
||||
message: "Please use matrix-js-sdk/src/matrix instead",
|
||||
},
|
||||
{
|
||||
name: "emojibase-regex",
|
||||
message:
|
||||
"This regex doesn't actually test for emoji. See the docs at https://emojibase.dev/docs/regex/ and prefer our own EMOJI_REGEX from HtmlUtils.",
|
||||
},
|
||||
],
|
||||
patterns: [
|
||||
{
|
||||
group: [
|
||||
"matrix-js-sdk/src/**",
|
||||
"!matrix-js-sdk/src/matrix",
|
||||
"!matrix-js-sdk/src/crypto-api",
|
||||
"!matrix-js-sdk/src/types",
|
||||
"!matrix-js-sdk/src/testing",
|
||||
"!matrix-js-sdk/src/utils/**",
|
||||
"matrix-js-sdk/src/utils/internal/**",
|
||||
"matrix-js-sdk/lib",
|
||||
"matrix-js-sdk/lib/",
|
||||
"matrix-js-sdk/lib/**",
|
||||
// XXX: Temporarily allow these as they are not available via the main export
|
||||
"!matrix-js-sdk/src/logger",
|
||||
"!matrix-js-sdk/src/errors",
|
||||
"!matrix-js-sdk/src/utils",
|
||||
"!matrix-js-sdk/src/version-support",
|
||||
"!matrix-js-sdk/src/randomstring",
|
||||
"!matrix-js-sdk/src/sliding-sync",
|
||||
"!matrix-js-sdk/src/browser-index",
|
||||
"!matrix-js-sdk/src/feature",
|
||||
"!matrix-js-sdk/src/NamespacedValue",
|
||||
"!matrix-js-sdk/src/ReEmitter",
|
||||
"!matrix-js-sdk/src/event-mapper",
|
||||
"!matrix-js-sdk/src/interactive-auth",
|
||||
"!matrix-js-sdk/src/secret-storage",
|
||||
"!matrix-js-sdk/src/room-hierarchy",
|
||||
"!matrix-js-sdk/src/rendezvous",
|
||||
"!matrix-js-sdk/src/indexeddb-worker",
|
||||
"!matrix-js-sdk/src/pushprocessor",
|
||||
"!matrix-js-sdk/src/extensible_events_v1",
|
||||
"!matrix-js-sdk/src/extensible_events_v1/PollStartEvent",
|
||||
"!matrix-js-sdk/src/extensible_events_v1/PollResponseEvent",
|
||||
"!matrix-js-sdk/src/extensible_events_v1/PollEndEvent",
|
||||
"!matrix-js-sdk/src/extensible_events_v1/InvalidEventError",
|
||||
"!matrix-js-sdk/src/crypto",
|
||||
"!matrix-js-sdk/src/crypto/keybackup",
|
||||
"!matrix-js-sdk/src/crypto/deviceinfo",
|
||||
"!matrix-js-sdk/src/crypto/dehydration",
|
||||
"!matrix-js-sdk/src/oidc",
|
||||
"!matrix-js-sdk/src/oidc/discovery",
|
||||
"!matrix-js-sdk/src/oidc/authorize",
|
||||
"!matrix-js-sdk/src/oidc/validate",
|
||||
"!matrix-js-sdk/src/oidc/error",
|
||||
"!matrix-js-sdk/src/oidc/register",
|
||||
"!matrix-js-sdk/src/webrtc",
|
||||
"!matrix-js-sdk/src/webrtc/call",
|
||||
"!matrix-js-sdk/src/webrtc/callFeed",
|
||||
"!matrix-js-sdk/src/webrtc/mediaHandler",
|
||||
"!matrix-js-sdk/src/webrtc/callEventTypes",
|
||||
"!matrix-js-sdk/src/webrtc/callEventHandler",
|
||||
"!matrix-js-sdk/src/webrtc/groupCallEventHandler",
|
||||
"!matrix-js-sdk/src/models",
|
||||
"!matrix-js-sdk/src/models/read-receipt",
|
||||
"!matrix-js-sdk/src/models/relations-container",
|
||||
"!matrix-js-sdk/src/models/related-relations",
|
||||
"!matrix-js-sdk/src/matrixrtc",
|
||||
],
|
||||
message: "Please use matrix-js-sdk/src/matrix instead",
|
||||
},
|
||||
{
|
||||
group: ["emojibase-regex/emoji*"],
|
||||
message:
|
||||
"This regex doesn't actually test for emoji. See the docs at https://emojibase.dev/docs/regex/ and prefer our own EMOJI_REGEX from HtmlUtils.",
|
||||
},
|
||||
{
|
||||
group: ["@vector-im/compound-design-tokens/icons/*"],
|
||||
message: "Please use @vector-im/compound-design-tokens/assets/web/icons/* instead",
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
|
||||
// There are too many a11y violations to fix at once
|
||||
// Turn violated rules off until they are fixed
|
||||
"jsx-a11y/aria-activedescendant-has-tabindex": "off",
|
||||
"jsx-a11y/click-events-have-key-events": "off",
|
||||
"jsx-a11y/interactive-supports-focus": "off",
|
||||
"jsx-a11y/media-has-caption": "off",
|
||||
"jsx-a11y/mouse-events-have-key-events": "off",
|
||||
"jsx-a11y/no-autofocus": "off",
|
||||
"jsx-a11y/no-noninteractive-element-interactions": "off",
|
||||
"jsx-a11y/no-noninteractive-element-to-interactive-role": "off",
|
||||
"jsx-a11y/no-noninteractive-tabindex": "off",
|
||||
"jsx-a11y/no-static-element-interactions": "off",
|
||||
"jsx-a11y/role-supports-aria-props": "off",
|
||||
|
||||
"matrix-org/require-copyright-header": "error",
|
||||
},
|
||||
overrides: [
|
||||
{
|
||||
files: ["src/**/*.{ts,tsx}", "test/**/*.{ts,tsx}", "playwright/**/*.ts"],
|
||||
extends: ["plugin:matrix-org/typescript", "plugin:matrix-org/react"],
|
||||
rules: {
|
||||
"@typescript-eslint/explicit-function-return-type": [
|
||||
"error",
|
||||
{
|
||||
allowExpressions: true,
|
||||
},
|
||||
],
|
||||
|
||||
// Things we do that break the ideal style
|
||||
"prefer-promise-reject-errors": "off",
|
||||
"no-extra-boolean-cast": "off",
|
||||
|
||||
// Remove Babel things manually due to override limitations
|
||||
"@babel/no-invalid-this": ["off"],
|
||||
|
||||
// We're okay being explicit at the moment
|
||||
"@typescript-eslint/no-empty-interface": "off",
|
||||
// We disable this while we're transitioning
|
||||
"@typescript-eslint/no-explicit-any": "off",
|
||||
// We'd rather not do this but we do
|
||||
"@typescript-eslint/ban-ts-comment": "off",
|
||||
// We're okay with assertion errors when we ask for them
|
||||
"@typescript-eslint/no-non-null-assertion": "off",
|
||||
// We do this sometimes to brand interfaces
|
||||
"@typescript-eslint/no-empty-object-type": "off",
|
||||
},
|
||||
},
|
||||
// temporary override for offending icon require files
|
||||
{
|
||||
files: [
|
||||
"src/SdkConfig.ts",
|
||||
"src/components/structures/FileDropTarget.tsx",
|
||||
"src/components/structures/RoomStatusBar.tsx",
|
||||
"src/components/structures/UserMenu.tsx",
|
||||
"src/components/views/avatars/WidgetAvatar.tsx",
|
||||
"src/components/views/dialogs/AddExistingToSpaceDialog.tsx",
|
||||
"src/components/views/dialogs/ForwardDialog.tsx",
|
||||
"src/components/views/dialogs/InviteDialog.tsx",
|
||||
"src/components/views/dialogs/ModalWidgetDialog.tsx",
|
||||
"src/components/views/dialogs/UploadConfirmDialog.tsx",
|
||||
"src/components/views/dialogs/security/SetupEncryptionDialog.tsx",
|
||||
"src/components/views/elements/AddressTile.tsx",
|
||||
"src/components/views/elements/AppWarning.tsx",
|
||||
"src/components/views/elements/SSOButtons.tsx",
|
||||
"src/components/views/messages/MAudioBody.tsx",
|
||||
"src/components/views/messages/MImageBody.tsx",
|
||||
"src/components/views/messages/MFileBody.tsx",
|
||||
"src/components/views/messages/MStickerBody.tsx",
|
||||
"src/components/views/messages/MVideoBody.tsx",
|
||||
"src/components/views/messages/MVoiceMessageBody.tsx",
|
||||
"src/components/views/right_panel/EncryptionPanel.tsx",
|
||||
"src/components/views/rooms/EntityTile.tsx",
|
||||
"src/components/views/rooms/LinkPreviewGroup.tsx",
|
||||
"src/components/views/rooms/MemberList.tsx",
|
||||
"src/components/views/rooms/MessageComposer.tsx",
|
||||
"src/components/views/rooms/ReplyPreview.tsx",
|
||||
"src/components/views/settings/tabs/room/SecurityRoomSettingsTab.tsx",
|
||||
"src/components/views/settings/tabs/user/GeneralUserSettingsTab.tsx",
|
||||
],
|
||||
rules: {
|
||||
"@typescript-eslint/no-var-requires": "off",
|
||||
},
|
||||
},
|
||||
{
|
||||
files: ["test/**/*.{ts,tsx}", "playwright/**/*.ts"],
|
||||
extends: ["plugin:matrix-org/jest"],
|
||||
rules: {
|
||||
// We don't need super strict typing in test utilities
|
||||
"@typescript-eslint/explicit-function-return-type": "off",
|
||||
"@typescript-eslint/explicit-member-accessibility": "off",
|
||||
|
||||
// Jest/Playwright specific
|
||||
|
||||
// Disabled tests are a reality for now but as soon as all of the xits are
|
||||
// eliminated, we should enforce this.
|
||||
"jest/no-disabled-tests": "off",
|
||||
// Also treat "oldBackendOnly" as a test function.
|
||||
// Used in some crypto tests.
|
||||
"jest/no-standalone-expect": [
|
||||
"error",
|
||||
{
|
||||
additionalTestBlockFunctions: ["beforeAll", "beforeEach", "oldBackendOnly"],
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
{
|
||||
files: ["playwright/**/*.ts"],
|
||||
parserOptions: {
|
||||
project: ["./playwright/tsconfig.json"],
|
||||
},
|
||||
},
|
||||
],
|
||||
settings: {
|
||||
react: {
|
||||
version: "detect",
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
function buildRestrictedPropertiesOptions(properties, message) {
|
||||
return properties.map((prop) => {
|
||||
let [object, property] = prop.split(".");
|
||||
if (object === "*") {
|
||||
object = undefined;
|
||||
}
|
||||
return {
|
||||
object,
|
||||
property,
|
||||
message,
|
||||
};
|
||||
});
|
||||
}
|
||||
+12
-39
@@ -1,45 +1,18 @@
|
||||
* @element-hq/element-web-reviewers
|
||||
/.github/workflows/** @element-hq/element-web-team
|
||||
**/package.json @element-hq/element-web-team
|
||||
/pnpm-lock.yaml @element-hq/element-web-team
|
||||
/package.json @element-hq/element-web-team
|
||||
/yarn.lock @element-hq/element-web-team
|
||||
|
||||
/apps/web/src/SecurityManager.ts @element-hq/element-crypto-web-reviewers
|
||||
/apps/web/test/unit-tests/SecurityManager-test.ts @element-hq/element-crypto-web-reviewers
|
||||
/apps/web/src/async-components/views/dialogs/security/ @element-hq/element-crypto-web-reviewers
|
||||
/apps/web/test/unit-tests/async-components/dialogs/security/ @element-hq/element-crypto-web-reviewers
|
||||
/apps/web/src/components/views/dialogs/security/ @element-hq/element-crypto-web-reviewers
|
||||
/apps/web/test/unit-tests/components/views/dialogs/security/ @element-hq/element-crypto-web-reviewers
|
||||
/apps/web/src/stores/SetupEncryptionStore.ts @element-hq/element-crypto-web-reviewers
|
||||
/apps/web/test/unit-tests/stores/SetupEncryptionStore-test.ts @element-hq/element-crypto-web-reviewers
|
||||
/apps/web/src/components/views/settings/tabs/user/EncryptionUserSettingsTab.tsx @element-hq/element-crypto-web-reviewers
|
||||
/apps/web/src/components/views/settings/encryption/ @element-hq/element-crypto-web-reviewers
|
||||
/apps/web/test/unit-tests/components/views/settings/encryption/ @element-hq/element-crypto-web-reviewers
|
||||
/apps/web/src/components/views/dialogs/devtools/Crypto.tsx @element-hq/element-crypto-web-reviewers
|
||||
/apps/web/playwright/e2e/crypto/ @element-hq/element-crypto-web-reviewers
|
||||
/apps/web/playwright/e2e/settings/encryption-user-tab/ @element-hq/element-crypto-web-reviewers
|
||||
/packages/shared-components/src/crypto/ @element-hq/element-crypto-web-reviewers
|
||||
|
||||
|
||||
/apps/web/src/models/Call.ts @element-hq/element-call-reviewers
|
||||
/apps/web/test/unit-tests/models/Call-test.ts @element-hq/element-call-reviewers
|
||||
/apps/web/src/stores/CallStore.ts @element-hq/element-call-reviewers
|
||||
/apps/web/test/unit-tests/stores/CallStore-test.ts @element-hq/element-call-reviewers
|
||||
/apps/web/src/call-types.ts @element-hq/element-call-reviewers
|
||||
/apps/web/src/components/views/voip @element-hq/element-call-reviewers
|
||||
/apps/web/res/css/views/voip @element-hq/element-call-reviewers
|
||||
/apps/web/playwright/e2e/voip @element-hq/element-call-reviewers
|
||||
/apps/web/playwright/snapshots/voip @element-hq/element-call-reviewers
|
||||
/apps/web/test/test-utils/call.ts @element-hq/element-call-reviewers
|
||||
/src/SecurityManager.ts @element-hq/element-crypto-web-reviewers
|
||||
/test/SecurityManager-test.ts @element-hq/element-crypto-web-reviewers
|
||||
/src/async-components/views/dialogs/security/ @element-hq/element-crypto-web-reviewers
|
||||
/src/components/views/dialogs/security/ @element-hq/element-crypto-web-reviewers
|
||||
/test/components/views/dialogs/security/ @element-hq/element-crypto-web-reviewers
|
||||
/src/stores/SetupEncryptionStore.ts @element-hq/element-crypto-web-reviewers
|
||||
/test/stores/SetupEncryptionStore-test.ts @element-hq/element-crypto-web-reviewers
|
||||
|
||||
# Ignore translations as those will be updated by GHA for Localazy download
|
||||
/apps/web/src/i18n/strings
|
||||
/apps/desktop/src/i18n/strings
|
||||
/packages/shared-components/src/i18n/strings
|
||||
/apps/web/src/i18n/strings/en_EN.json @element-hq/element-web-reviewers
|
||||
/apps/desktop/src/i18n/strings/en_EN.json @element-hq/element-web-reviewers
|
||||
/packages/shared-components/src/i18n/strings/en_EN.json @element-hq/element-web-reviewers
|
||||
|
||||
# Ignore the synapse & mas plugins as this is updated by GHA for docker image updating
|
||||
/apps/web/playwright/testcontainers/synapse.ts
|
||||
/apps/web/playwright/testcontainers/mas.ts
|
||||
/src/i18n/strings
|
||||
# Ignore the synapse plugin as this is updated by GHA for docker image updating
|
||||
/playwright/plugins/homeserver/synapse/index.ts
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
name: Bug report for the Element desktop app (not in a browser)
|
||||
description: File a bug report if you are using the desktop Element application.
|
||||
labels: [T-Defect, A-Electron]
|
||||
labels: [T-Defect]
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
|
||||
@@ -3,6 +3,3 @@ contact_links:
|
||||
- name: Questions & support
|
||||
url: https://matrix.to/#/#element-web:matrix.org
|
||||
about: Please ask and answer questions here.
|
||||
- name: Bug report for the Element flatpak app
|
||||
url: https://github.com/flathub/im.riot.Riot/issues
|
||||
about: Please file bugs with the Flatpak application on the respective repository.
|
||||
|
||||
@@ -2,8 +2,7 @@
|
||||
|
||||
## Checklist
|
||||
|
||||
- [ ] I have read through [review guidelines](https://github.com/element-hq/element-web/blob/develop/docs/review.md) and [CONTRIBUTING.md](https://github.com/element-hq/element-web/blob/develop/CONTRIBUTING.md).
|
||||
- [ ] Tests written for new code (and old code if feasible).
|
||||
- [ ] New or updated `public`/`exported` symbols have accurate [TSDoc](https://tsdoc.org/) documentation.
|
||||
- [ ] Linter and other CI checks pass.
|
||||
- [ ] I have licensed the changes to Element by completing the [Contributor License Agreement (CLA)](https://cla-assistant.io/element-hq/element-web)
|
||||
- [ ] Tests written for new code (and old code if feasible).
|
||||
- [ ] New or updated `public`/`exported` symbols have accurate [TSDoc](https://tsdoc.org/) documentation.
|
||||
- [ ] Linter and other CI checks pass.
|
||||
- [ ] I have licensed the changes to Element by completing the [Contributor License Agreement (CLA)](https://cla-assistant.io/element-hq/element-web)
|
||||
|
||||
@@ -1,35 +0,0 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIGBzCCA++gAwIBAgIIaI6ivggL++4wDQYJKoZIhvcNAQELBQAwgZAxCzAJBgNV
|
||||
BAYTAlVTMQ4wDAYDVQQIDAVUZXhhczEQMA4GA1UEBwwHSG91c3RvbjEYMBYGA1UE
|
||||
CgwPU1NMIENvcnBvcmF0aW9uMUUwQwYDVQQDDDxTU0wuY29tIEVWIFJvb3QgQ2Vy
|
||||
dGlmaWNhdGlvbiBBdXRob3JpdHkgUlNBIFIyIC0gRGV2ZWxvcG1lbnQwHhcNMTgw
|
||||
MTE2MTIxNjM2WhcNNDMwMTE1MTIxNjM2WjCBkDELMAkGA1UEBhMCVVMxDjAMBgNV
|
||||
BAgMBVRleGFzMRAwDgYDVQQHDAdIb3VzdG9uMRgwFgYDVQQKDA9TU0wgQ29ycG9y
|
||||
YXRpb24xRTBDBgNVBAMMPFNTTC5jb20gRVYgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1
|
||||
dGhvcml0eSBSU0EgUjIgLSBEZXZlbG9wbWVudDCCAiIwDQYJKoZIhvcNAQEBBQAD
|
||||
ggIPADCCAgoCggIBAK/qcD65JCkueKp0+KXG2kAw8euDHuraLR3lJoUFz4ilGK1M
|
||||
t+RjSuY6dHQw8ku7TnW9ejWoSFjCBSDx7tP/fzOwOxmBW6+F1NDuV/IaUtn3G2lk
|
||||
CZglVk9z3n1HuWDN10xNiLoo5nzeIlvNAoDbXDGhI4Y6Z0qouAIS607JpJMWHOqZ
|
||||
OUiiOuM11gI5Kz9GtVttXCjRmwlkU8WiJVIUuVedQAQt2FChrzNQewGFFi0uIau/
|
||||
wFRclx6hd4JRIImC6VMJd9lcitWsqMcM94pD3fX2ozNgWX+MVlmcDYFSN9Sv8tG4
|
||||
yCj4ONS8HZGzbxeyQXJhEJSi2FnBi0j6MD/d4DNFj0hCg9wz3fgVLDGCO0pNMO0Y
|
||||
oXdrzfoj1/zEv0Ibgh7zKG2JHkPfapn3ExFI5d6xi66u5tPVI8cvLxqrgybRPs7Z
|
||||
y1dQA7ew3LyTPAHoGtbTMvewtx1TkTtRxxhRRm0l58owqSVbSYrixFtosNobCERo
|
||||
uiknaQqoY1ZDsdKsaqFoZDbntNRYhN3Ea4OPWVqDUU5ZPz9MTIRAi3MIq854yyQo
|
||||
BjX9nv+kYa+Esr19pxUW0z7BWFhbXsMVpt0QMVyhwgzXvEreaZHFwHHaGb9d5x5P
|
||||
VBDhsigMmtzBk9NlbCsy+uGXWHgZA/DVefueEq0sv38VoU30uYa5Tj0FLm09AgMB
|
||||
AAGjYzBhMA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAUI9PCucv3G9fRoTDu
|
||||
ZQ4Hw6g4PkIwHQYDVR0OBBYEFCPTwrnL9xvX0aEw7mUOB8OoOD5CMA4GA1UdDwEB
|
||||
/wQEAwIBhjANBgkqhkiG9w0BAQsFAAOCAgEAk43CCrC0Zbvi7YUsSePKi+KzvyQ9
|
||||
mjKa5NBU/A5/sLeZS3R+wqCX7l5euYVDsUuNgNVD/QL9jNIonuHBrvKaxkmqxE1r
|
||||
IcDEaUdjy2lQ0uqD7UDoS3ctrjGkPpUahrTdr3gaKcQBtUhn9v4Y2OBm6J1hDVwI
|
||||
CIKcxIzRv6AUpApOtk+++m5tzDU48t8+GzrVl1hkspSYcumA+zuHllbPDL1ADdo5
|
||||
kK/bBQtZrGqzPqKzeqaB1A5Wm0Igwf++7nyzdKNdjxtv907D9vg8EB4Swavuv/Ne
|
||||
5/jbpI32pz0NIzzSl5ARAHuFhILsO/cEAlloDoTHzibHqFDIeU9/59HMUsJYMOtD
|
||||
Ii0/LmQ6dBE4TeukCCLJwtkFYZ2eBgDjF/LHBB+z/UBs4milRgwx+Pe5UDUEjtGe
|
||||
G/XMVnTSKZTy9jMaXJD5EmfP+Cfh8EEgFgjg4AmLUbEo9gXzPxyXSLgd8JGSsjg8
|
||||
EV/Ri4Mmmt4XUwlSVvEOezxxDGd17gwbottCIC+rqPHonHkGmKpLMH80Bk0uOOCs
|
||||
ui1oVwSifMyIcudgCcOfRLUf/f2j2NW7N7E7Vw/Zqfn+pqp/EG0KCqOM2vfJAc0s
|
||||
u3rSrOJZGtB6txgtmTjoadxApWf4U/FCi3uArt6gS5MJqZjuiRNXs/K3SlSAqLGl
|
||||
5UiG52ew+VdBHzE=
|
||||
-----END CERTIFICATE-----
|
||||
@@ -1,40 +0,0 @@
|
||||
name: Upload release assets
|
||||
description: Uploads assets to an existing release and optionally signs them
|
||||
inputs:
|
||||
tag:
|
||||
description: GitHub release tag to fetch assets from.
|
||||
required: true
|
||||
out-file-path:
|
||||
description: Path to where the webapp should be extracted to.
|
||||
required: true
|
||||
runs:
|
||||
using: composite
|
||||
steps:
|
||||
- name: Download release tarball
|
||||
uses: robinraju/release-downloader@28fc21f50d76778e7023361aa1f863e717d3d56f # v1
|
||||
with:
|
||||
tag: ${{ inputs.tag }}
|
||||
fileName: element-*.tar.gz*
|
||||
out-file-path: ${{ runner.temp }}/download-verify-element-tarball
|
||||
|
||||
- name: Verify tarball
|
||||
shell: bash
|
||||
run: gpg --verify element-*.tar.gz.asc element-*.tar.gz
|
||||
working-directory: ${{ runner.temp }}/download-verify-element-tarball
|
||||
|
||||
- name: Extract tarball
|
||||
shell: bash
|
||||
run: |
|
||||
mkdir webapp
|
||||
tar xvzf element-*.tar.gz -C webapp --strip-components=1
|
||||
working-directory: ${{ runner.temp }}/download-verify-element-tarball
|
||||
|
||||
- name: Move webapp to out-file-path
|
||||
shell: bash
|
||||
run: mv ${{ runner.temp }}/download-verify-element-tarball/webapp "$OUT_PATH"
|
||||
env:
|
||||
OUT_PATH: ${{ inputs.out-file-path }}
|
||||
|
||||
- name: Clean up temp directory
|
||||
shell: bash
|
||||
run: rm -R ${{ runner.temp }}/download-verify-element-tarball
|
||||
@@ -1,49 +0,0 @@
|
||||
name: Setup playwright
|
||||
description: Installs playwright browsers and sets up a cache
|
||||
inputs:
|
||||
needs-webkit:
|
||||
description: Whether to install the additional dependencies for webkit
|
||||
required: false
|
||||
default: "false"
|
||||
write-cache:
|
||||
description: Whether to write the cache back
|
||||
required: true
|
||||
runs:
|
||||
using: composite
|
||||
steps:
|
||||
- name: Calculate cache key
|
||||
id: key
|
||||
run: |
|
||||
PW_VERSION=$(pnpm --silent -- playwright --version | awk '{print $2}')
|
||||
echo "key=${PREFIX}-playwright-${PW_VERSION}" >> $GITHUB_OUTPUT
|
||||
shell: bash
|
||||
env:
|
||||
PREFIX: ${{ runner.os }}-${{ runner.arch }}
|
||||
|
||||
- name: Cache playwright binaries
|
||||
uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5
|
||||
if: inputs.write-cache == 'true'
|
||||
id: cache
|
||||
with:
|
||||
path: ~/.cache/ms-playwright
|
||||
key: ${{ steps.key.outputs.key }}
|
||||
|
||||
# When running in merge queue only restore the cache, never write it
|
||||
- name: Restore playwright binaries cache
|
||||
uses: actions/cache/restore@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5
|
||||
if: inputs.write-cache != 'true'
|
||||
id: cache-restore
|
||||
with:
|
||||
path: ~/.cache/ms-playwright
|
||||
key: ${{ steps.key.outputs.key }}
|
||||
|
||||
- name: Install Playwright browsers
|
||||
if: (steps.cache.outputs.cache-hit || steps.cache-restore.outputs.cache-hit) != 'true'
|
||||
shell: bash
|
||||
run: pnpm playwright install --with-deps
|
||||
|
||||
# Some WebKit dependencies seem to lay outside the cache and will need to be installed separately
|
||||
- name: Install system dependencies for WebKit
|
||||
if: inputs.needs-webkit == 'true' && (steps.cache.outputs.cache-hit || steps.cache-restore.outputs.cache-hit) == 'true'
|
||||
shell: bash
|
||||
run: pnpm playwright install-deps webkit
|
||||
+3
-44
@@ -91,6 +91,9 @@
|
||||
- name: "A-Modules"
|
||||
description: "Module system related"
|
||||
color: "bfd4f2"
|
||||
- name: "A-New-Search-Experience"
|
||||
description: "The new search dialog available in Labs"
|
||||
color: "bfd4f2"
|
||||
- name: "A-Packaging"
|
||||
description: "Packaging, signing, releasing"
|
||||
color: "bfd4f2"
|
||||
@@ -170,12 +173,6 @@
|
||||
color: "bfd4f2"
|
||||
- name: "A-Welcome-Page"
|
||||
color: "bfd4f2"
|
||||
- name: "A-Install"
|
||||
color: "72A447"
|
||||
- name: "A-Seshat"
|
||||
color: "8262BE"
|
||||
- name: "A-Update"
|
||||
color: "17BE67"
|
||||
- name: "backport staging"
|
||||
description: "Label to automatically backport PR to staging branch"
|
||||
color: "B60205"
|
||||
@@ -213,9 +210,6 @@
|
||||
- name: "X-Upcoming-Release-Blocker"
|
||||
description: "This does not affect the current release cycle but will affect the next one"
|
||||
color: "e99695"
|
||||
- name: "X-Run-All-Tests"
|
||||
description: "When applied to PRs, it'll run the full gamut of end-to-end tests on the PR"
|
||||
color: "ff7979"
|
||||
- name: "Z-Actions"
|
||||
color: "ededed"
|
||||
- name: "Z-Cache-Confusion"
|
||||
@@ -238,18 +232,6 @@
|
||||
- name: "Z-Flaky-Test"
|
||||
description: "A test is raising false alarms"
|
||||
color: "ededed"
|
||||
- name: "Z-Flaky-Test-Chrome"
|
||||
description: "Flaky playwright test in Chrome"
|
||||
color: "ededed"
|
||||
- name: "Z-Flaky-Test-Firefox"
|
||||
description: "Flaky playwright test in Firefox"
|
||||
color: "ededed"
|
||||
- name: "Z-Flaky-Test-Webkit"
|
||||
description: "Flaky playwright test in Webkit"
|
||||
color: "ededed"
|
||||
- name: "Z-Flaky-Jest-Test"
|
||||
description: "A Jest test is raising false alarms"
|
||||
color: "ededed"
|
||||
- name: "Z-FOSDEM"
|
||||
description: "Issues in chat.fosdem.org"
|
||||
color: "ededed"
|
||||
@@ -282,26 +264,3 @@
|
||||
- name: "Z-Flaky-Test-Disabled"
|
||||
description: "The flaking test has been disabled"
|
||||
color: "ededed"
|
||||
- name: "Z-Skip-Coverage"
|
||||
description: "Skip SonarQube coverage for this PR"
|
||||
color: "ededed"
|
||||
- name: "Z-Arch"
|
||||
color: "D601BE"
|
||||
- name: "Z-ARM"
|
||||
color: "5DEC5B"
|
||||
- name: "Z-Flatpak"
|
||||
color: "0CA856"
|
||||
- name: "Z-Linux"
|
||||
color: "7B4A9C"
|
||||
- name: "Z-macOS"
|
||||
color: "500605"
|
||||
- name: "Z-Official"
|
||||
color: "1D2B20"
|
||||
- name: "Z-Snap"
|
||||
color: "29CD95"
|
||||
- name: "Z-Suse"
|
||||
color: "79D07B"
|
||||
- name: "Z-Wayland"
|
||||
color: "94C519"
|
||||
- name: "Z-Windows"
|
||||
color: "0632DE"
|
||||
|
||||
+1
-47
@@ -1,50 +1,4 @@
|
||||
{
|
||||
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
|
||||
"extends": ["github>matrix-org/renovate-config-element-web"],
|
||||
"postUpdateOptions": ["pnpmDedupe"],
|
||||
"stopUpdatingLabel": "X-Blocked",
|
||||
"packageRules": [
|
||||
{
|
||||
"description": "Group all testcontainers docker digests",
|
||||
"groupName": "testcontainers docker digests",
|
||||
"groupSlug": "testcontainers-docker",
|
||||
"matchDepTypes": ["testcontainers-docker"],
|
||||
"matchPackageNames": ["*"]
|
||||
},
|
||||
{
|
||||
"description": "Separate updates to overrides from other groups",
|
||||
"matchManagers": ["npm"],
|
||||
"matchFileNames": ["pnpm-workspace.yaml"],
|
||||
"matchDepTypes": ["pnpm-workspace.overrides"],
|
||||
"groupSlug": null
|
||||
},
|
||||
{
|
||||
"description": "Disable any major updates to overrides as this almost always is wrong",
|
||||
"matchUpdateTypes": ["major"],
|
||||
"matchManagers": ["npm"],
|
||||
"matchFileNames": ["pnpm-workspace.yaml"],
|
||||
"matchDepTypes": ["pnpm-workspace.overrides"],
|
||||
"enabled": false
|
||||
}
|
||||
],
|
||||
"customManagers": [
|
||||
{
|
||||
"description": "Update testcontainers docker digests",
|
||||
"customType": "regex",
|
||||
"datasourceTemplate": "docker",
|
||||
"versioningTemplate": "loose",
|
||||
"managerFilePatterns": ["**/testcontainers/*.ts"],
|
||||
"matchStrings": ["\\s+\"(?<depName>[^@]+):(?<currentValue>[^@]+)@(?<currentDigest>sha256:[a-f0-9]+)\""],
|
||||
"depTypeTemplate": "testcontainers-docker"
|
||||
},
|
||||
{
|
||||
"description": "Update element-desktop hakDependencies",
|
||||
"customType": "jsonata",
|
||||
"managerFilePatterns": ["/(^|/)package\\.json$/"],
|
||||
"fileFormat": "json",
|
||||
"matchStrings": ["hakDependencies.$each(function($v, $k) { { 'packageName': $k, 'currentValue': $v } })"],
|
||||
"datasourceTemplate": "npm",
|
||||
"depTypeTemplate": "hak"
|
||||
}
|
||||
]
|
||||
"extends": ["github>matrix-org/renovate-config-element-web"]
|
||||
}
|
||||
|
||||
@@ -1,16 +1,12 @@
|
||||
name: Backport
|
||||
on:
|
||||
# Privilege escalation necessary to enable backporting PRs from forks
|
||||
# 🚨 We must not execute any checked out code here.
|
||||
pull_request_target: # zizmor: ignore[dangerous-triggers]
|
||||
pull_request_target:
|
||||
types:
|
||||
- closed
|
||||
- labeled
|
||||
branches:
|
||||
- develop
|
||||
|
||||
permissions: {} # We use ELEMENT_BOT_TOKEN instead
|
||||
|
||||
jobs:
|
||||
backport:
|
||||
name: Backport
|
||||
|
||||
@@ -1,48 +0,0 @@
|
||||
# Triggers after the playwright tests have finished,
|
||||
# taking the artifact and uploading it to Netlify for easier viewing
|
||||
name: Upload End to End Test report to Netlify
|
||||
on:
|
||||
# Privilege escalation necessary to publish to Netlify
|
||||
# 🚨 We must not execute any checked out code here.
|
||||
workflow_run: # zizmor: ignore[dangerous-triggers]
|
||||
workflows: ["Build & Test"]
|
||||
types:
|
||||
- completed
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.event.workflow_run.head_branch || github.run_id }}
|
||||
cancel-in-progress: ${{ github.event.workflow_run.event == 'pull_request' }}
|
||||
|
||||
permissions: {}
|
||||
|
||||
jobs:
|
||||
report:
|
||||
if: github.event.workflow_run.conclusion != 'cancelled'
|
||||
name: Report results
|
||||
runs-on: ubuntu-24.04
|
||||
environment: Netlify
|
||||
permissions:
|
||||
statuses: write
|
||||
deployments: write
|
||||
actions: read
|
||||
steps:
|
||||
- name: Download HTML report
|
||||
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8
|
||||
with:
|
||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
run-id: ${{ github.event.workflow_run.id }}
|
||||
name: html-report
|
||||
path: playwright-report
|
||||
|
||||
- name: 📤 Deploy to Netlify
|
||||
uses: matrix-org/netlify-pr-preview@9805cd123fc9a7e421e35340a05e1ebc5dee46b5 # v3
|
||||
with:
|
||||
path: playwright-report
|
||||
owner: ${{ github.event.workflow_run.head_repository.owner.login }}
|
||||
branch: ${{ github.event.workflow_run.head_branch }}
|
||||
revision: ${{ github.event.workflow_run.head_sha }}
|
||||
token: ${{ secrets.NETLIFY_AUTH_TOKEN }}
|
||||
site_id: ${{ vars.NETLIFY_SITE_ID }}
|
||||
desc: Playwright Report
|
||||
deployment_env: EndToEndTests
|
||||
prefix: "e2e-"
|
||||
@@ -1,311 +0,0 @@
|
||||
# builds Element Web
|
||||
# runs Playwright tests against the built Element Web
|
||||
# builds Element Desktop using the built Element Web
|
||||
#
|
||||
# Tries to use a matching js-sdk branch for the build.
|
||||
#
|
||||
# Produces a `webapp` artifact
|
||||
# Produces multiple Desktop artifacts
|
||||
# Produces multiple Playwright report artifacts
|
||||
name: Build & Test
|
||||
on:
|
||||
# CRON to run all Projects at 6am UTC
|
||||
schedule:
|
||||
- cron: "0 6 * * *"
|
||||
pull_request: {}
|
||||
merge_group:
|
||||
types: [checks_requested]
|
||||
push:
|
||||
# We do not build on push to develop as the merge_group check handles that
|
||||
branches: [staging, master]
|
||||
|
||||
# support triggering from other workflows
|
||||
workflow_call:
|
||||
inputs:
|
||||
skip:
|
||||
type: boolean
|
||||
required: false
|
||||
default: false
|
||||
description: "A boolean to skip the playwright check itself while still creating the passing check. Useful when only running in Merge Queues."
|
||||
|
||||
matrix-js-sdk-sha:
|
||||
type: string
|
||||
required: false
|
||||
description: "The Git SHA of matrix-js-sdk to build against. By default, will use a matching branch name if it exists, or develop."
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}-${{ github.event_name }}
|
||||
cancel-in-progress: true
|
||||
|
||||
env:
|
||||
# fetchdep.sh needs to know our PR number
|
||||
PR_NUMBER: ${{ github.event.pull_request.number }}
|
||||
# Use 4 runners in the default case, but only 1 when running on a schedule where we run all 5 projects
|
||||
NUM_RUNNERS: ${{ github.event_name == 'schedule' && 1 || 4 }}
|
||||
NX_DEFAULT_OUTPUT_STYLE: stream-without-prefixes
|
||||
|
||||
permissions: {} # No permissions required
|
||||
|
||||
jobs:
|
||||
build_ew:
|
||||
name: "Build Element Web"
|
||||
runs-on: ubuntu-24.04
|
||||
if: inputs.skip != true
|
||||
outputs:
|
||||
num-runners: ${{ env.NUM_RUNNERS }}
|
||||
runners-matrix: ${{ steps.runner-vars.outputs.matrix }}
|
||||
# Skip pull_request runs on renovate PRs to speed up CI time, delegating to the full run in merge queue
|
||||
skip: ${{ inputs.skip || (github.event_name == 'pull_request' && startsWith(github.head_ref, 'renovate/')) }}
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
|
||||
with:
|
||||
repository: element-hq/element-web
|
||||
persist-credentials: false
|
||||
|
||||
- uses: pnpm/action-setup@0e279bb959325dab635dd2c09392533439d90093 # v6.0.8
|
||||
- uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6
|
||||
with:
|
||||
cache: "pnpm"
|
||||
node-version: "lts/*"
|
||||
|
||||
- name: Fetch layered build
|
||||
env:
|
||||
# tell layered.sh to check out the right sha of the JS-SDK & EW, if they were given one
|
||||
JS_SDK_GITHUB_BASE_REF: ${{ inputs.matrix-js-sdk-sha }}
|
||||
run: scripts/layered.sh
|
||||
|
||||
- name: Copy config
|
||||
working-directory: apps/web
|
||||
run: cp element.io/develop/config.json config.json
|
||||
|
||||
- name: Build
|
||||
env:
|
||||
CI_PACKAGE: true
|
||||
working-directory: apps/web
|
||||
run: VERSION=$(scripts/get-version-from-git.sh) pnpm run build
|
||||
|
||||
- name: Upload Artifact
|
||||
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
|
||||
with:
|
||||
name: webapp
|
||||
path: apps/web/webapp
|
||||
retention-days: 1
|
||||
|
||||
- name: Calculate runner variables
|
||||
id: runner-vars
|
||||
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9
|
||||
with:
|
||||
script: |
|
||||
const numRunners = parseInt(process.env.NUM_RUNNERS, 10);
|
||||
const matrix = Array.from({ length: numRunners }, (_, i) => i + 1);
|
||||
core.setOutput("matrix", JSON.stringify(matrix));
|
||||
|
||||
playwright_ew:
|
||||
name: "Run Tests [${{ matrix.project }}] ${{ matrix.runner }}/${{ needs.build_ew.outputs.num-runners }}"
|
||||
needs: build_ew
|
||||
if: needs.build_ew.outputs.skip == 'false'
|
||||
runs-on: ubuntu-24.04
|
||||
permissions:
|
||||
actions: read
|
||||
issues: read
|
||||
pull-requests: read
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
# Run multiple instances in parallel to speed up the tests
|
||||
runner: ${{ fromJSON(needs.build_ew.outputs.runners-matrix) }}
|
||||
project:
|
||||
- Chrome
|
||||
- Firefox
|
||||
- WebKit
|
||||
- Dendrite
|
||||
- Pinecone
|
||||
runAllTests:
|
||||
- ${{ github.event_name == 'schedule' || contains(github.event.pull_request.labels.*.name, 'X-Run-All-Tests') }}
|
||||
# Skip the Firefox & Safari runs unless this was a cron trigger or PR has X-Run-All-Tests label
|
||||
exclude:
|
||||
- runAllTests: false
|
||||
project: Firefox
|
||||
- runAllTests: false
|
||||
project: WebKit
|
||||
- runAllTests: false
|
||||
project: Dendrite
|
||||
- runAllTests: false
|
||||
project: Pinecone
|
||||
steps:
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
|
||||
with:
|
||||
persist-credentials: false
|
||||
repository: element-hq/element-web
|
||||
|
||||
- name: 📥 Download artifact
|
||||
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8
|
||||
with:
|
||||
name: webapp
|
||||
path: apps/web/webapp
|
||||
|
||||
- uses: pnpm/action-setup@0e279bb959325dab635dd2c09392533439d90093 # v6.0.8
|
||||
- uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6
|
||||
with:
|
||||
cache: "pnpm"
|
||||
cache-dependency-path: pnpm-lock.yaml
|
||||
node-version: "lts/*"
|
||||
|
||||
- name: Install dependencies
|
||||
run: pnpm install --frozen-lockfile
|
||||
|
||||
- name: Setup playwright
|
||||
uses: ./.github/actions/setup-playwright
|
||||
with:
|
||||
needs-webkit: ${{ matrix.project == 'WebKit' }}
|
||||
write-cache: ${{ github.event_name != 'merge_group' }}
|
||||
|
||||
# We skip tests tagged with @mergequeue when running on PRs, but run them in MQ and everywhere else
|
||||
- name: Run Playwright tests
|
||||
working-directory: apps/web
|
||||
run: |
|
||||
pnpm test:playwright \
|
||||
--shard "$SHARD" \
|
||||
--project="${{ matrix.project }}" \
|
||||
${{ (github.event_name == 'pull_request' && matrix.runAllTests == false ) && '--grep-invert @mergequeue' || '' }}
|
||||
env:
|
||||
SHARD: ${{ format('{0}/{1}', matrix.runner, needs.build_ew.outputs.num-runners) }}
|
||||
|
||||
- name: Upload blob report to GitHub Actions Artifacts
|
||||
if: always()
|
||||
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
|
||||
with:
|
||||
name: blob-report-${{ matrix.project }}-${{ matrix.runner }}
|
||||
path: apps/web/blob-report
|
||||
retention-days: 1
|
||||
if-no-files-found: error
|
||||
|
||||
downstream-modules:
|
||||
name: Downstream Playwright tests [element-modules]
|
||||
needs: build_ew
|
||||
if: needs.build_ew.outputs.skip == 'false' && github.event_name == 'merge_group'
|
||||
uses: element-hq/element-modules/.github/workflows/reusable-playwright-tests.yml@main # zizmor: ignore[unpinned-uses]
|
||||
with:
|
||||
webapp-artifact: webapp
|
||||
reporter: blob
|
||||
|
||||
prepare_ed:
|
||||
name: "Prepare Element Desktop"
|
||||
uses: ./.github/workflows/build_desktop_prepare.yaml
|
||||
needs: build_ew
|
||||
if: needs.build_ew.outputs.skip == 'false'
|
||||
permissions:
|
||||
contents: read
|
||||
with:
|
||||
config: ${{ (github.event.pull_request.base.ref || github.ref_name) == 'develop' && 'element.io/nightly' || 'element.io/release' }}
|
||||
version: ${{ case((github.event.pull_request.base.ref || github.ref_name) == 'develop' || github.event_name == 'merge_group', 'develop', '') }}
|
||||
webapp-artifact: webapp
|
||||
|
||||
build_ed_windows:
|
||||
needs: prepare_ed
|
||||
name: "Desktop Windows"
|
||||
uses: ./.github/workflows/build_desktop_windows.yaml
|
||||
# Skip Windows builds on PRs, as the Linux amd64 build is enough of a smoke test and includes the screenshot tests
|
||||
if: github.event_name != 'pull_request' || contains(github.event.pull_request.labels.*.name, 'X-Run-All-Tests')
|
||||
strategy:
|
||||
matrix:
|
||||
arch: [x64, ia32, arm64]
|
||||
with:
|
||||
arch: ${{ matrix.arch }}
|
||||
blob_report: true
|
||||
|
||||
build_ed_linux:
|
||||
needs: prepare_ed
|
||||
name: "Desktop Linux"
|
||||
uses: ./.github/workflows/build_desktop_linux.yaml
|
||||
strategy:
|
||||
matrix:
|
||||
sqlcipher: [system, static]
|
||||
arch: [amd64, arm64]
|
||||
runAllTests:
|
||||
- ${{ github.event_name != 'pull_request' || contains(github.event.pull_request.labels.*.name, 'X-Run-All-Tests') }}
|
||||
exclude:
|
||||
# We ship static sqlcipher builds, so delegate testing the system builds to the merge queue
|
||||
- runAllTests: false
|
||||
sqlcipher: system
|
||||
# Additionally skip arm64 system builds on PRs, as the amd64 test is enough for a smoke test and includes the screenshot tests
|
||||
- runAllTests: false
|
||||
arch: arm64
|
||||
with:
|
||||
sqlcipher: ${{ matrix.sqlcipher }}
|
||||
arch: ${{ matrix.arch }}
|
||||
blob_report: true
|
||||
|
||||
build_ed_macos:
|
||||
needs: prepare_ed
|
||||
name: "Desktop macOS"
|
||||
uses: ./.github/workflows/build_desktop_macos.yaml
|
||||
# Skip macOS builds on PRs, as the Linux amd64 build is enough of a smoke test and includes the screenshot tests
|
||||
# and we have a very low limit of concurrent macos runners (5) across the Github org.
|
||||
if: github.event_name != 'pull_request' || contains(github.event.pull_request.labels.*.name, 'X-Run-All-Tests')
|
||||
with:
|
||||
blob_report: true
|
||||
|
||||
complete:
|
||||
name: end-to-end-tests
|
||||
needs:
|
||||
- build_ew
|
||||
- playwright_ew
|
||||
- downstream-modules
|
||||
- prepare_ed
|
||||
- build_ed_windows
|
||||
- build_ed_linux
|
||||
- build_ed_macos
|
||||
if: always()
|
||||
runs-on: ubuntu-24.04
|
||||
steps:
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
|
||||
if: needs.build_ew.outputs.skip == 'false'
|
||||
with:
|
||||
persist-credentials: false
|
||||
repository: element-hq/element-web
|
||||
|
||||
- uses: pnpm/action-setup@0e279bb959325dab635dd2c09392533439d90093 # v6.0.8
|
||||
if: needs.build_ew.outputs.skip == 'false'
|
||||
- uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6
|
||||
if: needs.build_ew.outputs.skip == 'false'
|
||||
with:
|
||||
cache: "pnpm"
|
||||
node-version: "lts/*"
|
||||
|
||||
- name: Install dependencies
|
||||
if: needs.build_ew.outputs.skip == 'false'
|
||||
run: pnpm install --frozen-lockfile
|
||||
|
||||
- name: Download blob reports from GitHub Actions Artifacts
|
||||
if: needs.build_ew.outputs.skip == 'false'
|
||||
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8
|
||||
with:
|
||||
pattern: blob-report-*
|
||||
path: all-blob-reports
|
||||
merge-multiple: true
|
||||
|
||||
- name: Merge into HTML Report
|
||||
if: needs.build_ew.outputs.skip == 'false'
|
||||
run: |
|
||||
pnpm playwright merge-reports \
|
||||
--config=playwright-merge.config.ts \
|
||||
./all-blob-reports
|
||||
env:
|
||||
# Only pass creds to the flaky-reporter on main branch runs
|
||||
GITHUB_TOKEN: ${{ github.ref_name == 'develop' && secrets.ELEMENT_BOT_TOKEN || '' }}
|
||||
PLAYWRIGHT_HTML_TITLE: ${{ case(github.event_name == 'pull_request', format('Playwright Report PR-{0}', env.PR_NUMBER), 'Playwright Report') }}
|
||||
|
||||
# Upload the HTML report even if one of our reporters fails, this can happen when stale screenshots are detected
|
||||
- name: Upload HTML report
|
||||
if: always() && needs.build_ew.outputs.skip == 'false'
|
||||
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
|
||||
with:
|
||||
name: html-report
|
||||
path: playwright-report
|
||||
retention-days: 14
|
||||
if-no-files-found: error
|
||||
|
||||
- if: contains(needs.*.result, 'failure') || contains(needs.*.result, 'cancelled')
|
||||
run: exit 1
|
||||
+10
-37
@@ -5,15 +5,11 @@ on:
|
||||
branches: [develop, master]
|
||||
merge_group:
|
||||
types: [checks_requested]
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.head_ref || github.sha }}
|
||||
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
|
||||
# develop pushes and repository_dispatch handled in build_develop.yaml
|
||||
env:
|
||||
# This must be set for fetchdep.sh to get the right branch
|
||||
# These must be set for fetchdep.sh to get the right branch
|
||||
REPOSITORY: ${{ github.repository }}
|
||||
PR_NUMBER: ${{ github.event.pull_request.number }}
|
||||
NX_DEFAULT_OUTPUT_STYLE: stream-without-prefixes
|
||||
permissions: {} # No permissions required
|
||||
jobs:
|
||||
build:
|
||||
name: "Build on ${{ matrix.image }}"
|
||||
@@ -27,50 +23,27 @@ jobs:
|
||||
- macos-14
|
||||
isDevelop:
|
||||
- ${{ github.event_name == 'push' && github.ref_name == 'develop' }}
|
||||
isPullRequest:
|
||||
- ${{ github.event_name == 'pull_request' }}
|
||||
# Skip the ubuntu-24.04 build for the develop branch as the dedicated CD build_develop workflow handles that
|
||||
# Skip the non-linux builds for pull requests as Windows is awfully slow, so run in merge queue only
|
||||
exclude:
|
||||
- isDevelop: true
|
||||
image: ubuntu-24.04
|
||||
- isPullRequest: true
|
||||
image: windows-2022
|
||||
- isPullRequest: true
|
||||
image: macos-14
|
||||
runs-on: ${{ matrix.image }}
|
||||
defaults:
|
||||
run:
|
||||
shell: bash
|
||||
steps:
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
|
||||
with:
|
||||
persist-credentials: false
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- uses: pnpm/action-setup@0e279bb959325dab635dd2c09392533439d90093 # v6.0.8
|
||||
- uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6
|
||||
- uses: actions/setup-node@v4
|
||||
with:
|
||||
# Disable cache on Windows as it is slower than not caching
|
||||
# https://github.com/actions/setup-node/issues/975
|
||||
cache: ${{ runner.os != 'Windows' && 'pnpm' || '' }}
|
||||
cache: "yarn"
|
||||
node-version: "lts/*"
|
||||
|
||||
- name: Fetch layered build
|
||||
run: ./scripts/layered.sh
|
||||
# Workaround for yarn install timeouts, especially on Windows
|
||||
- run: yarn config set network-timeout 300000
|
||||
|
||||
- name: Copy config
|
||||
working-directory: apps/web
|
||||
run: cp element.io/develop/config.json config.json
|
||||
- name: Install Dependencies
|
||||
run: "./scripts/layered.sh"
|
||||
|
||||
- name: Build
|
||||
working-directory: apps/web
|
||||
env:
|
||||
CI_PACKAGE: true
|
||||
run: VERSION=$(scripts/get-version-from-git.sh) pnpm run build
|
||||
|
||||
- name: Upload Artifact
|
||||
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
|
||||
with:
|
||||
name: webapp-${{ matrix.image }}
|
||||
path: apps/web/webapp
|
||||
retention-days: 1
|
||||
run: "yarn build"
|
||||
|
||||
@@ -3,7 +3,6 @@ on:
|
||||
release:
|
||||
types: [published]
|
||||
concurrency: ${{ github.workflow }}
|
||||
permissions: {} # We use ELEMENT_BOT_TOKEN instead
|
||||
jobs:
|
||||
build:
|
||||
name: Build package
|
||||
@@ -14,18 +13,14 @@ jobs:
|
||||
R2_URL: ${{ vars.CF_R2_S3_API }}
|
||||
VERSION: ${{ github.ref_name }}
|
||||
steps:
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
|
||||
with:
|
||||
persist-credentials: false
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Download package
|
||||
working-directory: apps/web
|
||||
run: |
|
||||
wget "https://github.com/element-hq/element-web/releases/download/$VERSION/element-$VERSION.tar.gz"
|
||||
wget "https://github.com/element-hq/element-web/releases/download/$VERSION/element-$VERSION.tar.gz.asc"
|
||||
|
||||
- name: Check GPG signature
|
||||
working-directory: apps/web
|
||||
run: |
|
||||
wget "https://packages.element.io/element-release-key.gpg"
|
||||
gpg --import element-release-key.gpg
|
||||
@@ -35,7 +30,6 @@ jobs:
|
||||
FINGERPRINT: ${{ vars.GPG_FINGERPRINT }}
|
||||
|
||||
- name: Prepare
|
||||
working-directory: apps/web
|
||||
run: |
|
||||
mkdir -p debian/tmp/DEBIAN
|
||||
find debian -maxdepth 1 -type f -exec cp "{}" debian/tmp/DEBIAN/ \;
|
||||
@@ -46,7 +40,6 @@ jobs:
|
||||
ln -s /etc/element-web/config.json debian/tmp/usr/share/element-web/config.json
|
||||
|
||||
- name: Write changelog
|
||||
working-directory: apps/web
|
||||
run: |
|
||||
VERSION=$(cat package.json | jq -r .version)
|
||||
TIME=$(date -d "$PUBLISHED_AT" -R)
|
||||
@@ -63,23 +56,22 @@ jobs:
|
||||
PUBLISHED_AT: ${{ github.event.release.published_at }}
|
||||
|
||||
- name: Build deb package
|
||||
working-directory: apps/web
|
||||
run: |
|
||||
VERSION=$(cat package.json | jq -r .version)
|
||||
dpkg-gencontrol -v"$VERSION" -ldebian/tmp/DEBIAN/changelog
|
||||
dpkg-deb -Zxz --root-owner-group --build debian/tmp element-web.deb
|
||||
|
||||
- uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
|
||||
- uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: element-web.deb
|
||||
path: apps/web/element-web.deb
|
||||
path: element-web.deb
|
||||
retention-days: 14
|
||||
|
||||
- name: Publish to packages.element.io
|
||||
if: github.event.release.prerelease == false
|
||||
uses: element-hq/packages.element.io@master # zizmor: ignore[unpinned-uses]
|
||||
uses: element-hq/packages.element.io@master
|
||||
with:
|
||||
file: apps/web/element-web.deb
|
||||
file: element-web.deb
|
||||
github-token: ${{ secrets.ELEMENT_BOT_TOKEN }}
|
||||
bucket-api: ${{ vars.CF_R2_S3_API }}
|
||||
bucket-key-id: ${{ secrets.CF_R2_ACCESS_KEY_ID }}
|
||||
|
||||
@@ -1,313 +0,0 @@
|
||||
name: Build and Deploy
|
||||
on:
|
||||
# Nightly build
|
||||
schedule:
|
||||
- cron: "0 9 * * *"
|
||||
# Release build
|
||||
release:
|
||||
types: [published]
|
||||
# Manual nightly & release
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
mode:
|
||||
description: What type of build to trigger. Release builds MUST be ran from the `master` branch.
|
||||
required: true
|
||||
default: nightly
|
||||
type: choice
|
||||
options:
|
||||
- nightly
|
||||
- release
|
||||
macos:
|
||||
description: Build macOS
|
||||
required: true
|
||||
type: boolean
|
||||
default: true
|
||||
windows:
|
||||
description: Build Windows
|
||||
required: true
|
||||
type: boolean
|
||||
default: true
|
||||
linux:
|
||||
description: Build Linux
|
||||
required: true
|
||||
type: boolean
|
||||
default: true
|
||||
deploy:
|
||||
description: Deploy artifacts
|
||||
required: true
|
||||
type: boolean
|
||||
default: true
|
||||
run-name: Element ${{ inputs.mode != 'release' && github.event_name != 'release' && 'Nightly' || 'Desktop' }}
|
||||
concurrency: ${{ github.workflow }}
|
||||
env:
|
||||
R2_BUCKET: ${{ vars.R2_BUCKET }}
|
||||
permissions: {} # Uses ELEMENT_BOT_TOKEN
|
||||
jobs:
|
||||
prepare:
|
||||
uses: ./.github/workflows/build_desktop_prepare.yaml
|
||||
permissions:
|
||||
contents: read
|
||||
with:
|
||||
config: element.io/${{ inputs.mode || (github.event_name == 'release' && 'release') || 'nightly' }}
|
||||
version: ${{ (inputs.mode != 'release' && github.event_name != 'release') && 'develop' || '' }}
|
||||
nightly: ${{ inputs.mode != 'release' && github.event_name != 'release' }}
|
||||
deploy: ${{ inputs.deploy || (github.event_name != 'workflow_dispatch' && github.event.release.prerelease != true) }}
|
||||
secrets:
|
||||
CF_R2_ACCESS_KEY_ID: ${{ secrets.CF_R2_ACCESS_KEY_ID }}
|
||||
CF_R2_TOKEN: ${{ secrets.CF_R2_TOKEN }}
|
||||
|
||||
trigger-pro-pipeline:
|
||||
name: Trigger Pro pipeline
|
||||
needs: prepare
|
||||
runs-on: ubuntu-24.04
|
||||
steps:
|
||||
- uses: peter-evans/repository-dispatch@28959ce8df70de7be546dd1250a005dd32156697 # v4
|
||||
with:
|
||||
repository: element-hq/element-web-pro
|
||||
token: ${{ secrets.ELEMENT_BOT_TOKEN }}
|
||||
event-type: trigger-pipeline
|
||||
client-payload: |-
|
||||
{
|
||||
"base-ref": "${{ github.ref_name }}"
|
||||
}
|
||||
|
||||
windows:
|
||||
if: github.event_name != 'workflow_dispatch' || inputs.windows
|
||||
needs: prepare
|
||||
name: Windows ${{ matrix.arch }}
|
||||
strategy:
|
||||
matrix:
|
||||
arch: [x64, arm64]
|
||||
uses: ./.github/workflows/build_desktop_windows.yaml
|
||||
secrets: inherit # zizmor: ignore[secrets-inherit]
|
||||
with:
|
||||
sign: true
|
||||
arch: ${{ matrix.arch }}
|
||||
version: ${{ needs.prepare.outputs.nightly-version }}
|
||||
|
||||
macos:
|
||||
if: github.event_name != 'workflow_dispatch' || inputs.macos
|
||||
needs: prepare
|
||||
name: macOS
|
||||
uses: ./.github/workflows/build_desktop_macos.yaml
|
||||
secrets: inherit # zizmor: ignore[secrets-inherit]
|
||||
with:
|
||||
sign: true
|
||||
base-url: https://packages.element.io/${{ needs.prepare.outputs.packages-dir }}
|
||||
version: ${{ needs.prepare.outputs.nightly-version }}
|
||||
|
||||
linux:
|
||||
if: github.event_name != 'workflow_dispatch' || inputs.linux
|
||||
needs: prepare
|
||||
name: Linux ${{ matrix.arch }} (sqlcipher ${{ matrix.sqlcipher }})
|
||||
strategy:
|
||||
matrix:
|
||||
arch: [amd64, arm64]
|
||||
sqlcipher: [static]
|
||||
uses: ./.github/workflows/build_desktop_linux.yaml
|
||||
with:
|
||||
arch: ${{ matrix.arch }}
|
||||
sqlcipher: ${{ matrix.sqlcipher }}
|
||||
version: ${{ needs.prepare.outputs.nightly-version }}
|
||||
|
||||
deploy:
|
||||
needs:
|
||||
- prepare
|
||||
- macos
|
||||
- linux
|
||||
- windows
|
||||
runs-on: ubuntu-24.04
|
||||
name: ${{ needs.prepare.outputs.deploy == 'true' && 'Deploy' || 'Deploy (dry-run)' }}
|
||||
if: always() && !contains(needs.*.result, 'failure') && !contains(needs.*.result, 'cancelled')
|
||||
environment: ${{ needs.prepare.outputs.deploy == 'true' && 'packages.element.io' || '' }}
|
||||
steps:
|
||||
- name: Download artifacts
|
||||
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8
|
||||
|
||||
- name: Prepare artifacts for deployment
|
||||
run: |
|
||||
set -ex
|
||||
|
||||
# Windows
|
||||
for arch in x64 arm64
|
||||
do
|
||||
if [ -d "win-$arch" ]; then
|
||||
mkdir -p packages.element.io/{install,update}/win32/$arch
|
||||
mv win-$arch/squirrel-windows*/*.exe "packages.element.io/install/win32/$arch/"
|
||||
mv win-$arch/squirrel-windows*/*.nupkg "packages.element.io/update/win32/$arch/"
|
||||
mv win-$arch/squirrel-windows*/RELEASES "packages.element.io/update/win32/$arch/"
|
||||
fi
|
||||
done
|
||||
|
||||
# macOS
|
||||
if [ -d macos ]; then
|
||||
mkdir -p packages.element.io/{install,update}/macos
|
||||
mv macos/*.dmg packages.element.io/install/macos/
|
||||
mv macos/*-mac.zip packages.element.io/update/macos/
|
||||
mv macos/*.json packages.element.io/update/macos/
|
||||
fi
|
||||
|
||||
# Linux
|
||||
if [ -d linux-amd64-sqlcipher-static ]; then
|
||||
mkdir -p packages.element.io/install/linux/glibc-x86-64
|
||||
mv linux-amd64-sqlcipher-static/*.tar.gz packages.element.io/install/linux/glibc-x86-64
|
||||
fi
|
||||
if [ -d linux-arm64-sqlcipher-static ]; then
|
||||
mkdir -p packages.element.io/install/linux/glibc-aarch64
|
||||
mv linux-arm64-sqlcipher-static/*.tar.gz packages.element.io/install/linux/glibc-aarch64
|
||||
fi
|
||||
|
||||
# We don't wish to store the installer for every nightly ever, so we only keep the latest
|
||||
- name: "[Nightly] Strip version from installer file"
|
||||
if: needs.prepare.outputs.nightly-version != ''
|
||||
run: |
|
||||
set -ex
|
||||
|
||||
# Windows
|
||||
for arch in x64 arm64
|
||||
do
|
||||
if [ -d "win-$arch" ]; then mv packages.element.io/install/win32/$arch/{*,"Element Nightly Setup"}.exe; fi
|
||||
done
|
||||
|
||||
# macOS
|
||||
if [ -d macos ]; then mv packages.element.io/install/macos/{*,"Element Nightly"}.dmg; fi
|
||||
|
||||
# Linux
|
||||
if [ -d linux-amd64-sqlcipher-static ]; then mv packages.element.io/install/linux/glibc-x86-64/{*,element-desktop-nightly}.tar.gz; fi
|
||||
if [ -d linux-arm64-sqlcipher-static ]; then mv packages.element.io/install/linux/glibc-aarch64/{*,element-desktop-nightly}.tar.gz; fi
|
||||
|
||||
- name: "[Release] Prepare release latest symlink"
|
||||
if: needs.prepare.outputs.nightly-version == ''
|
||||
run: |
|
||||
set -ex
|
||||
|
||||
# Windows
|
||||
for arch in x64 arm64
|
||||
do
|
||||
if [ -d "win-$arch" ]; then
|
||||
pushd packages.element.io/install/win32/$arch
|
||||
ln -s "$(find . -type f -iname "*.exe" | xargs -0 -n1 -- basename)" "Element Setup.exe"
|
||||
popd
|
||||
fi
|
||||
done
|
||||
|
||||
# macOS
|
||||
if [ -d macos ]; then
|
||||
pushd packages.element.io/install/macos
|
||||
ln -s "$(find . -type f -iname "*.dmg" | xargs -0 -n1 -- basename)" "Element.dmg"
|
||||
popd
|
||||
fi
|
||||
|
||||
# Linux
|
||||
if [ -d linux-amd64-sqlcipher-static ]; then
|
||||
pushd packages.element.io/install/linux/glibc-x86-64
|
||||
ln -s "$(find . -type f -iname "*.tar.gz" | xargs -0 -n1 -- basename)" "element-desktop.tar.gz"
|
||||
popd
|
||||
fi
|
||||
if [ -d linux-arm64-sqlcipher-static ]; then
|
||||
pushd packages.element.io/install/linux/glibc-aarch64
|
||||
ln -s "$(find . -type f -iname "*.tar.gz" | xargs -0 -n1 -- basename)" "element-desktop.tar.gz"
|
||||
popd
|
||||
fi
|
||||
|
||||
- name: Stash packages.element.io
|
||||
if: needs.prepare.outputs.deploy == 'false'
|
||||
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
|
||||
with:
|
||||
name: packages.element.io
|
||||
path: packages.element.io
|
||||
|
||||
# Checksum algorithm specified as per https://developers.cloudflare.com/r2/examples/aws/aws-cli/
|
||||
- name: Deploy artifacts
|
||||
if: needs.prepare.outputs.deploy == 'true'
|
||||
run: |
|
||||
set -x
|
||||
aws s3 cp --recursive packages.element.io/ s3://$R2_BUCKET/$DEPLOYMENT_DIR --endpoint-url $R2_URL --region auto --checksum-algorithm CRC32
|
||||
env:
|
||||
AWS_ACCESS_KEY_ID: ${{ secrets.CF_R2_ACCESS_KEY_ID }}
|
||||
AWS_SECRET_ACCESS_KEY: ${{ secrets.CF_R2_TOKEN }}
|
||||
R2_URL: ${{ vars.CF_R2_S3_API }}
|
||||
DEPLOYMENT_DIR: ${{ needs.prepare.outputs.packages-dir }}
|
||||
|
||||
- name: Notify packages.element.io of new files
|
||||
if: needs.prepare.outputs.deploy == 'true'
|
||||
uses: peter-evans/repository-dispatch@28959ce8df70de7be546dd1250a005dd32156697 # v4
|
||||
with:
|
||||
token: ${{ secrets.ELEMENT_BOT_TOKEN }}
|
||||
repository: element-hq/packages.element.io
|
||||
event-type: packages-index
|
||||
|
||||
- name: Find debs
|
||||
id: deb
|
||||
if: needs.linux.result == 'success'
|
||||
run: |
|
||||
set -x
|
||||
|
||||
for arch in amd64 arm64
|
||||
do
|
||||
echo "$arch=$(ls linux-$arch-sqlcipher-static/*.deb | tail -n1)" >> $GITHUB_OUTPUT
|
||||
done
|
||||
|
||||
- name: Stash debs
|
||||
if: needs.prepare.outputs.deploy == 'false' && needs.linux.result == 'success'
|
||||
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
|
||||
with:
|
||||
name: debs
|
||||
path: |
|
||||
${{ steps.deb.outputs.amd64 }}
|
||||
${{ steps.deb.outputs.arm64 }}
|
||||
|
||||
- name: Publish amd64 deb to packages.element.io
|
||||
uses: element-hq/packages.element.io@master # zizmor: ignore[unpinned-uses]
|
||||
if: needs.prepare.outputs.deploy == 'true' && needs.linux.result == 'success'
|
||||
with:
|
||||
file: ${{ steps.deb.outputs.amd64 }}
|
||||
github-token: ${{ secrets.ELEMENT_BOT_TOKEN }}
|
||||
bucket-api: ${{ vars.CF_R2_S3_API }}
|
||||
bucket-key-id: ${{ secrets.CF_R2_ACCESS_KEY_ID }}
|
||||
bucket-access-key: ${{ secrets.CF_R2_TOKEN }}
|
||||
|
||||
- name: Publish arm64 deb to packages.element.io
|
||||
uses: element-hq/packages.element.io@master # zizmor: ignore[unpinned-uses]
|
||||
if: needs.prepare.outputs.deploy == 'true' && needs.linux.result == 'success'
|
||||
with:
|
||||
file: ${{ steps.deb.outputs.arm64 }}
|
||||
github-token: ${{ secrets.ELEMENT_BOT_TOKEN }}
|
||||
bucket-api: ${{ vars.CF_R2_S3_API }}
|
||||
bucket-key-id: ${{ secrets.CF_R2_ACCESS_KEY_ID }}
|
||||
bucket-access-key: ${{ secrets.CF_R2_TOKEN }}
|
||||
|
||||
deploy-ess:
|
||||
needs: deploy
|
||||
runs-on: ubuntu-24.04
|
||||
name: Deploy builds to ESS
|
||||
if: needs.prepare.outputs.deploy == 'true' && github.event_name == 'release'
|
||||
env:
|
||||
BUCKET_NAME: "element-desktop-msi.onprem.element.io"
|
||||
AWS_REGION: "eu-central-1"
|
||||
permissions:
|
||||
id-token: write # This is required for requesting the JWT
|
||||
steps:
|
||||
- name: Configure AWS credentials
|
||||
uses: aws-actions/configure-aws-credentials@99214aa6889fcddfa57764031d71add364327e59 # v6
|
||||
with:
|
||||
role-to-assume: arn:aws:iam::264135176173:role/Push-ElementDesktop-MSI
|
||||
role-session-name: githubaction-run-${{ github.run_id }}
|
||||
aws-region: ${{ env.AWS_REGION }}
|
||||
|
||||
- name: Download artifacts
|
||||
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8
|
||||
with:
|
||||
pattern: win-*
|
||||
|
||||
- name: Copy files to S3
|
||||
run: |
|
||||
set -x
|
||||
|
||||
PREFIX="${VERSION%.*}"
|
||||
for file in win-*/*.msi; do
|
||||
filename=$(basename "$file")
|
||||
aws s3 cp "$file" "s3://${{ env.BUCKET_NAME }}/$PREFIX/$filename"
|
||||
done
|
||||
env:
|
||||
VERSION: ${{ github.event.release.tag_name }}
|
||||
@@ -1,267 +0,0 @@
|
||||
# This workflow relies on actions/cache to store the hak dependency artifacts as they take a long time to build
|
||||
# Due to this extra care must be taken to only ever run all build_* scripts against the same branch to ensure
|
||||
# the correct cache scoping, and additional care must be taken to not run untrusted actions on the develop branch.
|
||||
on:
|
||||
workflow_call:
|
||||
inputs:
|
||||
ref:
|
||||
type: string
|
||||
required: false
|
||||
description: "The git ref to checkout, defaults to the default branch"
|
||||
arch:
|
||||
type: string
|
||||
required: true
|
||||
description: "The architecture to build for, one of 'amd64' | 'arm64'"
|
||||
version:
|
||||
type: string
|
||||
required: false
|
||||
description: "Version string to override the one in package.json, used for non-release builds"
|
||||
sqlcipher:
|
||||
type: string
|
||||
required: true
|
||||
description: "How to link sqlcipher, one of 'system' | 'static'"
|
||||
blob_report:
|
||||
type: boolean
|
||||
required: false
|
||||
description: "Whether to run the blob report"
|
||||
prepare-artifact-name:
|
||||
type: string
|
||||
required: false
|
||||
description: |
|
||||
The name of the prepare artifact to use, defaults to 'desktop-prepare'.
|
||||
The artifact must contain the following:
|
||||
+ webapp.asar - the asar archive of the webapp to embed in the desktop app
|
||||
+ electronVersion - the version of electron to use for cache keying
|
||||
+ hakHash - the hash of the .hak directory to use for cache keying
|
||||
+ changelog.Debian - the changelog file to embed in the Debian package
|
||||
+ variant.json - the variant configuration to use for the build
|
||||
|
||||
The artifact can also contain any additional files which will be applied as overrides to the checkout root before building,
|
||||
for example icons in the `build/` directory to override the app icons.
|
||||
default: "desktop-prepare"
|
||||
test:
|
||||
type: boolean
|
||||
required: false
|
||||
default: true
|
||||
description: "Whether to run the test stage after building"
|
||||
test-args:
|
||||
type: string
|
||||
required: false
|
||||
description: "Additional arguments to pass to playwright"
|
||||
runs-on:
|
||||
type: string
|
||||
required: false
|
||||
description: "The runner image to use, normally set for you, may be needed for running in private repos."
|
||||
artifact-prefix:
|
||||
type: string
|
||||
required: false
|
||||
description: "An optional prefix to add to the artifact name, useful for distinguishing builds in private repos."
|
||||
default: ""
|
||||
targets:
|
||||
type: string
|
||||
required: false
|
||||
description: "List of targets to build"
|
||||
default: "tar.gz deb"
|
||||
env:
|
||||
SQLCIPHER_BUNDLED: ${{ inputs.sqlcipher == 'static' && '1' || '' }}
|
||||
MAX_GLIBC: 2.31 # bullseye-era glibc, used by glibc-check.sh
|
||||
permissions: {} # No permissions required
|
||||
jobs:
|
||||
build:
|
||||
name: Build Linux ${{ inputs.arch }} SQLCipher ${{ inputs.sqlcipher }}
|
||||
# We build on native infrastructure as matrix-seshat fails to cross-compile properly
|
||||
# https://github.com/matrix-org/seshat/issues/135
|
||||
runs-on: ${{ inputs.runs-on || (inputs.arch == 'arm64' && 'ubuntu-22.04-arm' || 'ubuntu-22.04') }}
|
||||
env:
|
||||
HAK_DOCKER_IMAGE: ghcr.io/element-hq/element-web/desktop-build-env:${{ case(github.event_name == 'push', inputs.ref || github.ref_name, github.event_name == 'release', 'staging', 'develop') }}
|
||||
steps:
|
||||
- uses: nbucic/variable-mapper@0673f6891a0619ba7c002ecfed0f9f4f39017b6f
|
||||
id: config
|
||||
with:
|
||||
key: "${{ inputs.arch }}"
|
||||
export_to: output
|
||||
map: |
|
||||
{
|
||||
"amd64": {
|
||||
"arch": "x86-64"
|
||||
},
|
||||
"arm64": {
|
||||
"arch": "aarch64",
|
||||
"build-args": "--arm64"
|
||||
}
|
||||
}
|
||||
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
|
||||
with:
|
||||
repository: element-hq/element-web
|
||||
ref: ${{ inputs.ref }}
|
||||
persist-credentials: false
|
||||
|
||||
- uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8
|
||||
with:
|
||||
name: ${{ inputs.prepare-artifact-name }}
|
||||
path: apps/desktop
|
||||
|
||||
- name: Cache .hak
|
||||
id: cache
|
||||
uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5
|
||||
with:
|
||||
key: ${{ runner.os }}-${{ github.ref_name }}-${{ inputs.sqlcipher }}-${{ inputs.arch }}-${{ hashFiles('apps/desktop/hakHash', 'apps/desktop/electronVersion', 'apps/desktop/dockerbuild/*') }}
|
||||
path: |
|
||||
apps/desktop/.hak
|
||||
|
||||
- uses: pnpm/action-setup@0e279bb959325dab635dd2c09392533439d90093 # v6.0.8
|
||||
- uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6
|
||||
with:
|
||||
node-version-file: apps/desktop/.node-version
|
||||
cache: "pnpm"
|
||||
env:
|
||||
# Workaround for https://github.com/actions/setup-node/issues/317
|
||||
FORCE_COLOR: 0
|
||||
|
||||
- name: Install Deps
|
||||
working-directory: apps/desktop
|
||||
run: "pnpm install --frozen-lockfile --filter element-desktop"
|
||||
|
||||
- name: "Get modified files"
|
||||
id: changed_files
|
||||
if: steps.cache.outputs.cache-hit != 'true' && github.event_name == 'pull_request' && github.repository == 'element-hq/element-web'
|
||||
uses: tj-actions/changed-files@9426d40962ed5378910ee2e21d5f8c6fcbf2dd96 # v47
|
||||
with:
|
||||
files: |
|
||||
apps/desktop/dockerbuild/**
|
||||
|
||||
# This allows contributors to test changes to the dockerbuild image within a pull request
|
||||
- name: Build docker image
|
||||
uses: docker/build-push-action@bcafcacb16a39f128d818304e6c9c0c18556b85f # v7
|
||||
if: steps.changed_files.outputs.any_modified == 'true'
|
||||
with:
|
||||
file: apps/desktop/dockerbuild/Dockerfile
|
||||
context: apps/desktop
|
||||
load: true
|
||||
platforms: linux/${{ inputs.arch }}
|
||||
tags: ${{ env.HAK_DOCKER_IMAGE }}
|
||||
|
||||
- name: Build Natives
|
||||
if: steps.cache.outputs.cache-hit != 'true'
|
||||
run: |
|
||||
docker run \
|
||||
-v ${{ github.workspace }}:/work -w /work \
|
||||
-e SQLCIPHER_BUNDLED \
|
||||
-e CI=1 \
|
||||
$HAK_DOCKER_IMAGE \
|
||||
pnpm -C apps/desktop run build:native
|
||||
|
||||
- name: Fix permissions
|
||||
run: |
|
||||
shopt -s globstar
|
||||
|
||||
# For .hak
|
||||
sudo chown -R $USER:$USER apps/desktop/.hak
|
||||
# For node_modules
|
||||
sudo chown -R $USER:$USER **/node_modules
|
||||
|
||||
- name: Check native libraries in hak dependencies
|
||||
working-directory: apps/desktop
|
||||
run: |
|
||||
shopt -s globstar
|
||||
|
||||
for filename in ./.hak/hakModules/**/*.node; do
|
||||
./scripts/glibc-check.sh $filename
|
||||
done
|
||||
|
||||
- name: Generate debian files and arguments
|
||||
working-directory: apps/desktop
|
||||
run: |
|
||||
if [ -f changelog.Debian ]; then
|
||||
echo "ED_DEBIAN_CHANGELOG=changelog.Debian" >> $GITHUB_ENV
|
||||
fi
|
||||
|
||||
- name: Build App
|
||||
working-directory: apps/desktop
|
||||
run: pnpm run build --publish never $BUILD_ARGS -l $TARGETS
|
||||
env:
|
||||
VARIANT_PATH: variant.json
|
||||
# Only set for Nightly builds
|
||||
VERSION: ${{ inputs.version }}
|
||||
# Workaround for https://github.com/electron-userland/electron-builder/issues/5721
|
||||
USE_HARD_LINKS: false
|
||||
BUILD_ARGS: ${{ steps.config.outputs.build-args }}
|
||||
TARGETS: ${{ inputs.targets }}
|
||||
|
||||
- name: Check native libraries
|
||||
working-directory: apps/desktop
|
||||
run: |
|
||||
set -x
|
||||
shopt -s globstar
|
||||
|
||||
FILES=$(file dist/**/*.node)
|
||||
echo $FILES
|
||||
|
||||
! echo "$FILES" | grep -v "$ARCH"
|
||||
|
||||
LIBS=$(readelf -d dist/**/*.node | grep NEEDED)
|
||||
echo "$LIBS"
|
||||
|
||||
set +x
|
||||
assert_contains_string() { [[ "$1" == *"$2"* ]]; }
|
||||
! assert_contains_string "$LIBS" "libcrypto.so.1.1"
|
||||
if [ "$SQLCIPHER_BUNDLED" == "1" ]; then
|
||||
! assert_contains_string "$LIBS" "libsqlcipher.so.0"
|
||||
else
|
||||
assert_contains_string "$LIBS" "libsqlcipher.so.0"
|
||||
fi
|
||||
|
||||
./scripts/glibc-check.sh dist/linux-*unpacked/element-desktop*
|
||||
env:
|
||||
ARCH: ${{ steps.config.outputs.arch }}
|
||||
|
||||
# We exclude *-unpacked as it loses permissions and the tarball contains it with correct permissions
|
||||
- name: Upload Artifacts
|
||||
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
|
||||
with:
|
||||
name: ${{ inputs.artifact-prefix }}linux-${{ inputs.arch }}-sqlcipher-${{ inputs.sqlcipher }}
|
||||
path: |
|
||||
apps/desktop/dist
|
||||
!apps/desktop/dist/*-unpacked/**
|
||||
retention-days: 1
|
||||
|
||||
- name: Assert deb is present and valid
|
||||
if: contains(inputs.targets, 'deb')
|
||||
working-directory: apps/desktop
|
||||
run: |
|
||||
test -f ./dist/element-desktop*$ARCH.deb
|
||||
|
||||
DEB_LISTING=$(dpkg-deb --fsys-tarfile ./dist/element-desktop*.deb | tar -tv)
|
||||
echo "deb listing: "
|
||||
echo "$DEB_LISTING"
|
||||
! echo "$DEB_LISTING" | grep '^h'
|
||||
env:
|
||||
ARCH: ${{ inputs.arch }}
|
||||
|
||||
- name: Assert tar.gz is present
|
||||
if: contains(inputs.targets, 'tar.gz')
|
||||
working-directory: apps/desktop
|
||||
run: |
|
||||
test -f ./dist/element-desktop*.tar.gz
|
||||
|
||||
TAR_GZ_LISTING=$(tar -tvf ./dist/element-desktop*.tar.gz)
|
||||
echo "tar.gz listing: "
|
||||
echo "$TAR_GZ_LISTING"
|
||||
! echo "$TAR_GZ_LISTING" | grep '^h'
|
||||
|
||||
test:
|
||||
name: Test Linux ${{ inputs.arch }} SQLCipher ${{ inputs.sqlcipher }}
|
||||
needs: build
|
||||
if: inputs.test && contains(inputs.targets, 'deb')
|
||||
uses: ./.github/workflows/build_desktop_test.yaml
|
||||
with:
|
||||
project: linux-${{ inputs.arch }}-sqlcipher-${{ inputs.sqlcipher }}
|
||||
artifact: ${{ inputs.artifact-prefix }}linux-${{ inputs.arch }}-sqlcipher-${{ inputs.sqlcipher }}
|
||||
runs-on: ${{ inputs.runs-on || (inputs.arch == 'arm64' && 'ubuntu-22.04-arm' || 'ubuntu-22.04') }}
|
||||
executable: /opt/Element*/element-desktop*
|
||||
prepare_cmd: |
|
||||
sudo apt-get -qq update
|
||||
sudo apt install ./dist/*.deb
|
||||
blob_report: ${{ inputs.blob_report }}
|
||||
args: ${{ inputs.test-args }}
|
||||
@@ -1,234 +0,0 @@
|
||||
# This workflow relies on actions/cache to store the hak dependency artifacts as they take a long time to build
|
||||
# Due to this extra care must be taken to only ever run all build_* scripts against the same branch to ensure
|
||||
# the correct cache scoping, and additional care must be taken to not run untrusted actions on the develop branch.
|
||||
on:
|
||||
workflow_call:
|
||||
secrets:
|
||||
APPLE_ID:
|
||||
required: false
|
||||
APPLE_ID_PASSWORD:
|
||||
required: false
|
||||
APPLE_CSC_KEY_PASSWORD:
|
||||
required: false
|
||||
APPLE_CSC_LINK:
|
||||
required: false
|
||||
inputs:
|
||||
ref:
|
||||
type: string
|
||||
required: false
|
||||
description: "The git ref to checkout, defaults to the default branch"
|
||||
version:
|
||||
type: string
|
||||
required: false
|
||||
description: "Version string to override the one in package.json, used for non-release builds"
|
||||
sign:
|
||||
type: string
|
||||
required: false
|
||||
description: "Whether to sign & notarise the build, requires 'Desktop Apple' environment"
|
||||
base-url:
|
||||
type: string
|
||||
required: false
|
||||
description: "The URL to which the output will be deployed."
|
||||
blob_report:
|
||||
type: boolean
|
||||
required: false
|
||||
description: "Whether to run the blob report"
|
||||
prepare-artifact-name:
|
||||
type: string
|
||||
required: false
|
||||
description: |
|
||||
The name of the prepare artifact to use, defaults to 'desktop-prepare'.
|
||||
The artifact must contain the following:
|
||||
+ webapp.asar - the asar archive of the webapp to embed in the desktop app
|
||||
+ electronVersion - the version of electron to use for cache keying
|
||||
+ hakHash - the hash of the .hak directory to use for cache keying
|
||||
+ variant.json - the variant configuration to use for the build
|
||||
|
||||
The artifact can also contain any additional files which will be applied as overrides to the checkout root before building,
|
||||
for example icons in the `build/` directory to override the app icons.
|
||||
default: "desktop-prepare"
|
||||
test:
|
||||
type: boolean
|
||||
required: false
|
||||
default: true
|
||||
description: "Whether to run the test stage after building"
|
||||
test-args:
|
||||
type: string
|
||||
required: false
|
||||
description: "Additional arguments to pass to playwright"
|
||||
artifact-prefix:
|
||||
type: string
|
||||
required: false
|
||||
description: "An optional prefix to add to the artifact name, useful for distinguishing builds in private repos."
|
||||
default: ""
|
||||
targets:
|
||||
type: string
|
||||
required: false
|
||||
description: "List of targets to build"
|
||||
default: "dmg zip"
|
||||
permissions: {} # No permissions required
|
||||
jobs:
|
||||
build:
|
||||
name: Build macOS Universal
|
||||
runs-on: macos-26 # M1
|
||||
environment: ${{ inputs.sign && 'Desktop Apple' || '' }}
|
||||
steps:
|
||||
- uses: maxim-lobanov/setup-xcode@ed7a3b1fda3918c0306d1b724322adc0b8cc0a90 # v1
|
||||
with:
|
||||
xcode-version: latest-stable
|
||||
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
|
||||
with:
|
||||
repository: element-hq/element-web
|
||||
ref: ${{ inputs.ref }}
|
||||
persist-credentials: false
|
||||
|
||||
- uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8
|
||||
with:
|
||||
name: ${{ inputs.prepare-artifact-name }}
|
||||
path: apps/desktop
|
||||
|
||||
- name: Cache .hak
|
||||
id: cache
|
||||
uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5
|
||||
with:
|
||||
key: ${{ runner.os }}-${{ hashFiles('apps/desktop/hakHash', 'apps/desktop/electronVersion') }}
|
||||
path: |
|
||||
apps/desktop/.hak
|
||||
|
||||
- name: Install Rust
|
||||
if: steps.cache.outputs.cache-hit != 'true'
|
||||
run: |
|
||||
rustup toolchain install stable --profile minimal --no-self-update
|
||||
rustup default stable
|
||||
rustup target add aarch64-apple-darwin
|
||||
rustup target add x86_64-apple-darwin
|
||||
|
||||
# M1 macos-14 comes without Python preinstalled
|
||||
- uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6
|
||||
with:
|
||||
python-version: "3.13"
|
||||
|
||||
# Install Quartz for DMG badges
|
||||
# https://github.com/electron-userland/electron-builder/issues/9511#issuecomment-3774092888
|
||||
- run: sudo pip3 install pyobjc-framework-Quartz
|
||||
|
||||
- uses: pnpm/action-setup@0e279bb959325dab635dd2c09392533439d90093 # v6.0.8
|
||||
- uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6
|
||||
with:
|
||||
node-version-file: apps/desktop/.node-version
|
||||
cache: "pnpm"
|
||||
|
||||
- name: Install Deps
|
||||
working-directory: apps/desktop
|
||||
run: "pnpm install --frozen-lockfile --filter element-desktop"
|
||||
|
||||
- name: Build Natives
|
||||
if: steps.cache.outputs.cache-hit != 'true'
|
||||
working-directory: apps/desktop
|
||||
run: pnpm run build:native:universal
|
||||
|
||||
# We split these because electron-builder gets upset if we set CSC_LINK even to an empty string
|
||||
- name: "[Signed] Build App"
|
||||
if: inputs.sign != ''
|
||||
working-directory: apps/desktop
|
||||
run: |
|
||||
pnpm run build:universal --publish never -m ${TARGETS}
|
||||
env:
|
||||
APPLE_TEAM_ID: ${{ vars.APPLE_TEAM_ID }}
|
||||
APPLE_ID: ${{ secrets.APPLE_ID }}
|
||||
APPLE_APP_SPECIFIC_PASSWORD: ${{ secrets.APPLE_ID_PASSWORD }}
|
||||
CSC_KEY_PASSWORD: ${{ secrets.APPLE_CSC_KEY_PASSWORD }}
|
||||
CSC_LINK: ${{ secrets.APPLE_CSC_LINK }}
|
||||
VARIANT_PATH: variant.json
|
||||
# Only set for Nightly builds
|
||||
VERSION: ${{ inputs.version }}
|
||||
TARGETS: ${{ inputs.targets }}
|
||||
|
||||
- name: Check app was signed & notarised successfully
|
||||
if: inputs.sign != ''
|
||||
working-directory: apps/desktop
|
||||
run: |
|
||||
hdiutil attach dist/*.dmg -mountpoint /Volumes/Element
|
||||
codesign -dv --verbose=4 /Volumes/Element/*.app
|
||||
spctl -a -vvv -t install /Volumes/Element/*.app
|
||||
hdiutil detach /Volumes/Element
|
||||
|
||||
- name: "[Unsigned] Build App"
|
||||
if: inputs.sign == ''
|
||||
working-directory: apps/desktop
|
||||
run: |
|
||||
pnpm run build:universal --publish never -m ${TARGETS}
|
||||
env:
|
||||
CSC_IDENTITY_AUTO_DISCOVERY: false
|
||||
VARIANT_PATH: variant.json
|
||||
TARGETS: ${{ inputs.targets }}
|
||||
|
||||
- name: Generate releases.json
|
||||
if: inputs.base-url
|
||||
working-directory: apps/desktop
|
||||
run: |
|
||||
PKG_JSON_VERSION=$(cat package.json | jq -r .version)
|
||||
LATEST=$(find dist -type f -iname "*-mac.zip" | xargs -0 -n1 -- basename)
|
||||
# Encode spaces in the URL as Squirrel.Mac complains about bad JSON otherwise
|
||||
URL="${BASE_URL}/update/macos/${LATEST// /%20}"
|
||||
|
||||
jq -n --arg version "${VERSION:-$PKG_JSON_VERSION}" --arg url "$URL" '
|
||||
{
|
||||
currentRelease: $version,
|
||||
releases: [{
|
||||
version: $version,
|
||||
updateTo: {
|
||||
version: $version,
|
||||
url: $url,
|
||||
},
|
||||
}],
|
||||
}
|
||||
' > dist/releases.json
|
||||
jq -n --arg url "$URL" '
|
||||
{ url: $url }
|
||||
' > dist/releases-legacy.json
|
||||
env:
|
||||
VERSION: ${{ inputs.version }}
|
||||
BASE_URL: ${{ inputs.base-url }}
|
||||
|
||||
# We exclude mac-universal as the unpacked app takes forever to upload and zip and dmg already contains it
|
||||
- name: Upload Artifacts
|
||||
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
|
||||
with:
|
||||
name: ${{ inputs.artifact-prefix }}macos
|
||||
path: |
|
||||
apps/desktop/dist
|
||||
!apps/desktop/dist/mac-universal/**
|
||||
retention-days: 1
|
||||
|
||||
- name: Assert zip is present
|
||||
if: contains(inputs.targets, 'zip')
|
||||
working-directory: apps/desktop
|
||||
run: |
|
||||
test -f ./dist/Element*-mac.zip
|
||||
|
||||
- name: Assert dmg is present
|
||||
if: contains(inputs.targets, 'dmg')
|
||||
working-directory: apps/desktop
|
||||
run: |
|
||||
test -f ./dist/Element*.dmg
|
||||
|
||||
test:
|
||||
name: Test macOS Universal
|
||||
needs: build
|
||||
if: inputs.test && contains(inputs.targets, 'dmg')
|
||||
uses: ./.github/workflows/build_desktop_test.yaml
|
||||
with:
|
||||
project: macos
|
||||
artifact: ${{ inputs.artifact-prefix }}macos
|
||||
runs-on: macos-14
|
||||
executable: /Users/runner/Applications/Element*.app/Contents/MacOS/Element*
|
||||
# We need to mount the DMG and copy the app to the Applications folder as a mounted DMG is
|
||||
# read-only and thus would not allow us to override the fuses as is required for Playwright.
|
||||
prepare_cmd: |
|
||||
hdiutil attach ./dist/*.dmg -mountpoint /Volumes/Element &&
|
||||
rsync -a /Volumes/Element/Element*.app ~/Applications/ &&
|
||||
hdiutil detach /Volumes/Element
|
||||
blob_report: ${{ inputs.blob_report }}
|
||||
args: ${{ inputs.test-args }}
|
||||
@@ -1,197 +0,0 @@
|
||||
# This action helps perform common actions before the build_* actions are started in parallel.
|
||||
on:
|
||||
workflow_call:
|
||||
inputs:
|
||||
config:
|
||||
type: string
|
||||
required: true
|
||||
description: "The config directory to use"
|
||||
version:
|
||||
type: string
|
||||
required: false
|
||||
description: "The version tag to fetch, or 'develop', will pick automatically if not passed"
|
||||
nightly:
|
||||
type: boolean
|
||||
required: false
|
||||
default: false
|
||||
description: "Whether the build is a Nightly and to calculate the version strings new builds should use"
|
||||
deploy:
|
||||
type: boolean
|
||||
required: false
|
||||
default: false
|
||||
description: "Whether the build should be deployed to production"
|
||||
webapp-artifact:
|
||||
type: string
|
||||
required: false
|
||||
description: "Name of the webapp artifact that should be used, will fetch a relevant build if omitted"
|
||||
secrets:
|
||||
# Required if `nightly` is set
|
||||
CF_R2_ACCESS_KEY_ID:
|
||||
required: false
|
||||
# Required if `nightly` is set
|
||||
CF_R2_TOKEN:
|
||||
required: false
|
||||
outputs:
|
||||
nightly-version:
|
||||
description: "The version string the next Nightly should use, only output for nightly"
|
||||
value: ${{ jobs.prepare.outputs.nightly-version }}
|
||||
packages-dir:
|
||||
description: "The directory non-deb packages for this run should live in within packages.element.io"
|
||||
value: ${{ inputs.nightly && 'nightly' || 'desktop' }}
|
||||
# This is just a simple pass-through of the input to simplify reuse of complex inline conditions
|
||||
deploy:
|
||||
description: "Whether the build should be deployed to production"
|
||||
value: ${{ inputs.deploy }}
|
||||
permissions: {}
|
||||
jobs:
|
||||
prepare:
|
||||
name: Prepare
|
||||
environment: ${{ inputs.nightly && 'packages.element.io' || '' }}
|
||||
runs-on: ubuntu-24.04
|
||||
permissions:
|
||||
contents: read
|
||||
outputs:
|
||||
nightly-version: ${{ steps.versions.outputs.nightly }}
|
||||
steps:
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
|
||||
with:
|
||||
persist-credentials: false
|
||||
repository: element-hq/element-web
|
||||
|
||||
- uses: pnpm/action-setup@0e279bb959325dab635dd2c09392533439d90093 # v6.0.8
|
||||
- uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6
|
||||
with:
|
||||
node-version-file: apps/desktop/.node-version
|
||||
cache: "pnpm"
|
||||
|
||||
- name: Install Deps
|
||||
working-directory: apps/desktop
|
||||
run: "pnpm install --frozen-lockfile --filter element-desktop"
|
||||
|
||||
- name: Fetch Element Web (from artifact)
|
||||
if: inputs.webapp-artifact != ''
|
||||
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8
|
||||
with:
|
||||
name: ${{ inputs.webapp-artifact }}
|
||||
path: apps/desktop/webapp
|
||||
|
||||
- name: Build webapp.asar (from artifact)
|
||||
if: inputs.webapp-artifact != ''
|
||||
working-directory: apps/desktop
|
||||
run: |
|
||||
cp -f "$CONFIG_DIR/config.json" webapp/config.json
|
||||
pnpm run asar-webapp
|
||||
env:
|
||||
CONFIG_DIR: ${{ inputs.config }}
|
||||
|
||||
- name: Fetch Element Web (${{ inputs.version }})
|
||||
if: inputs.webapp-artifact == ''
|
||||
working-directory: apps/desktop
|
||||
run: pnpm run fetch --noverify -d ${CONFIG} ${VERSION}
|
||||
env:
|
||||
CONFIG: ${{ inputs.config }}
|
||||
VERSION: ${{ inputs.version }}
|
||||
|
||||
- name: Copy variant config
|
||||
working-directory: apps/desktop
|
||||
run: cp "$CONFIG_DIR/build.json" variant.json
|
||||
env:
|
||||
CONFIG_DIR: ${{ inputs.config }}
|
||||
|
||||
# We split this out to save the build_* scripts having to do it to make use of `hashFiles` in the cache action
|
||||
- name: Generate cache hash files
|
||||
working-directory: apps/desktop
|
||||
run: |
|
||||
set -ex
|
||||
# Add --no-sandbox as otherwise it fails because the helper isn't setuid root. It's only getting the version.
|
||||
pnpm --silent electron --no-sandbox --version > electronVersion
|
||||
cat package.json | jq -c .hakDependencies | sha1sum > hakHash
|
||||
find hak -type f -print0 | xargs -0 sha1sum >> hakHash
|
||||
find scripts/hak -type f -print0 | xargs -0 sha1sum >> hakHash
|
||||
|
||||
- name: "[Nightly] Calculate version"
|
||||
id: versions
|
||||
if: inputs.nightly
|
||||
working-directory: apps/desktop
|
||||
run: |
|
||||
set -e
|
||||
|
||||
# Find all latest Nightly versions
|
||||
aws s3 cp s3://$R2_BUCKET/nightly/update/macos/releases.json - --endpoint-url $R2_URL --region auto | jq -r .currentRelease >> VERSIONS
|
||||
aws s3 cp s3://$R2_BUCKET/debian/dists/default/main/binary-amd64/Packages - --endpoint-url $R2_URL --region auto | grep "Package: element-nightly" -A 50 | grep Version -m1 | sed -n 's/Version: //p' >> VERSIONS
|
||||
aws s3 cp s3://$R2_BUCKET/debian/dists/default/main/binary-arm64/Packages - --endpoint-url $R2_URL --region auto | grep "Package: element-nightly" -A 50 | grep Version -m1 | sed -n 's/Version: //p' >> VERSIONS
|
||||
aws s3 cp s3://$R2_BUCKET/nightly/update/win32/x64/RELEASES - --endpoint-url $R2_URL --region auto | awk '{print $2}' | cut -d "-" -f 5 | cut -c 8- >> VERSIONS
|
||||
aws s3 cp s3://$R2_BUCKET/nightly/update/win32/arm64/RELEASES - --endpoint-url $R2_URL --region auto | awk '{print $2}' | cut -d "-" -f 5 | cut -c 8- >> VERSIONS
|
||||
|
||||
# Pick the greatest one
|
||||
VERSION=$(cat VERSIONS | sort -uf | tail -n1)
|
||||
echo "Found latest nightly version $VERSION"
|
||||
# Increment it
|
||||
echo "nightly=$(scripts/generate-nightly-version.ts --latest $VERSION)" >> $GITHUB_OUTPUT
|
||||
env:
|
||||
AWS_ACCESS_KEY_ID: ${{ secrets.CF_R2_ACCESS_KEY_ID }}
|
||||
AWS_SECRET_ACCESS_KEY: ${{ secrets.CF_R2_TOKEN }}
|
||||
R2_BUCKET: ${{ vars.R2_BUCKET }}
|
||||
R2_URL: ${{ vars.CF_R2_S3_API }}
|
||||
|
||||
- name: Check version
|
||||
id: package
|
||||
working-directory: apps/desktop
|
||||
run: |
|
||||
echo "version=$(cat package.json | jq -r .version)" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: "[Release] Fetch release"
|
||||
id: release
|
||||
if: ${{ !inputs.nightly && inputs.version != 'develop' }}
|
||||
uses: cardinalby/git-get-release-action@5172c3a026600b1d459b117738c605fabc9e4e44 # 1.2.5
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ github.token }}
|
||||
with:
|
||||
tag: v${{ steps.package.outputs.version }}
|
||||
|
||||
- name: "[Release] Write changelog"
|
||||
if: ${{ !inputs.nightly && inputs.version != 'develop' }}
|
||||
working-directory: apps/desktop
|
||||
run: |
|
||||
TIME=$(date -d "$PUBLISHED_AT" -R)
|
||||
echo "element-desktop ($VERSION) default; urgency=medium" >> changelog.Debian
|
||||
echo "$BODY" | sed 's/^##/\n */g;s/^\*/ */g' | perl -pe 's/\[.+?]\((.+?)\)/\1/g' >> changelog.Debian
|
||||
echo "" >> changelog.Debian
|
||||
echo " -- $ACTOR <support@element.io> $TIME" >> changelog.Debian
|
||||
env:
|
||||
ACTOR: ${{ github.actor }}
|
||||
VERSION: v${{ steps.package.outputs.version }}
|
||||
BODY: ${{ steps.release.outputs.body }}
|
||||
PUBLISHED_AT: ${{ steps.release.outputs.published_at }}
|
||||
|
||||
- name: "[Nightly] Write summary"
|
||||
if: inputs.nightly
|
||||
working-directory: apps/desktop
|
||||
run: |
|
||||
set -e
|
||||
|
||||
BUNDLE_HASH=$(pnpm exec asar l webapp.asar | grep /bundles/ | head -n 1 | sed 's|.*/||')
|
||||
WEBAPP_VERSION=$(./scripts/get-version.ts)
|
||||
WEB_VERSION=${WEBAPP_VERSION:0:12}
|
||||
JS_VERSION=${WEBAPP_VERSION:16:12}
|
||||
|
||||
echo "### Nightly build ${NIGHTLY_VERSION}" >> $GITHUB_STEP_SUMMARY
|
||||
echo "" >> $GITHUB_STEP_SUMMARY
|
||||
echo "| Component | Version |" >> $GITHUB_STEP_SUMMARY
|
||||
echo "| ----------- | ------- |" >> $GITHUB_STEP_SUMMARY
|
||||
echo "| Bundle Hash | $BUNDLE_HASH |" >> $GITHUB_STEP_SUMMARY
|
||||
echo "| Element Web | [$WEB_VERSION](https://github.com/element-hq/element-web/commit/$WEB_VERSION) |" >> $GITHUB_STEP_SUMMARY
|
||||
echo "| JS SDK | [$JS_VERSION](https://github.com/matrix-org/matrix-js-sdk/commit/$JS_VERSION) |" >> $GITHUB_STEP_SUMMARY
|
||||
env:
|
||||
NIGHTLY_VERSION: ${{ steps.versions.outputs.nightly }}
|
||||
|
||||
- uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
|
||||
with:
|
||||
name: desktop-prepare
|
||||
retention-days: 1
|
||||
path: |
|
||||
apps/desktop/webapp.asar
|
||||
apps/desktop/electronVersion
|
||||
apps/desktop/hakHash
|
||||
apps/desktop/changelog.Debian
|
||||
apps/desktop/variant.json
|
||||
@@ -1,120 +0,0 @@
|
||||
# This action helps run Playwright tests within one of the build_* stages.
|
||||
on:
|
||||
workflow_call:
|
||||
inputs:
|
||||
runs-on:
|
||||
type: string
|
||||
required: true
|
||||
description: "The runner image to use"
|
||||
artifact:
|
||||
type: string
|
||||
required: true
|
||||
description: "The name of the artifact to download"
|
||||
project:
|
||||
type: string
|
||||
required: true
|
||||
description: "The Playwright project to use for testing"
|
||||
executable:
|
||||
type: string
|
||||
required: true
|
||||
description: "Path to the executable to test"
|
||||
prepare_cmd:
|
||||
type: string
|
||||
required: false
|
||||
description: "Command to run to prepare the executable or environment for testing"
|
||||
blob_report:
|
||||
type: boolean
|
||||
default: false
|
||||
description: "Whether to upload a blob report instead of the HTML report"
|
||||
args:
|
||||
type: string
|
||||
required: false
|
||||
description: "Additional arguments to pass to playwright, for e.g. skipping specific tests"
|
||||
permissions: {}
|
||||
jobs:
|
||||
test:
|
||||
name: Test ${{ inputs.project }}
|
||||
runs-on: ${{ inputs.runs-on }}
|
||||
steps:
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
|
||||
with:
|
||||
repository: element-hq/element-web
|
||||
persist-credentials: false
|
||||
|
||||
- uses: pnpm/action-setup@0e279bb959325dab635dd2c09392533439d90093 # v6.0.8
|
||||
id: pnpm
|
||||
- uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6
|
||||
with:
|
||||
node-version-file: apps/desktop/.node-version
|
||||
cache: "pnpm"
|
||||
|
||||
- name: Install Deps
|
||||
run: "pnpm install --frozen-lockfile --filter element-desktop"
|
||||
|
||||
- uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8
|
||||
with:
|
||||
name: ${{ inputs.artifact }}
|
||||
path: apps/desktop/dist
|
||||
|
||||
- name: Prepare for tests
|
||||
working-directory: apps/desktop
|
||||
# This is set by the caller of the reusable workflow, they have the ability to run the command they specify
|
||||
# directly without our help so this is fine.
|
||||
run: ${{ inputs.prepare_cmd }} # zizmor: ignore[template-injection]
|
||||
if: inputs.prepare_cmd
|
||||
|
||||
- name: Expand executable path
|
||||
id: executable
|
||||
working-directory: apps/desktop
|
||||
shell: bash
|
||||
env:
|
||||
EXECUTABLE: ${{ inputs.executable }}
|
||||
run: |
|
||||
FILES=($EXECUTABLE)
|
||||
echo "path=${FILES[0]}" >> $GITHUB_OUTPUT
|
||||
|
||||
# We previously disabled the `EnableNodeCliInspectArguments` fuse, but Playwright requires
|
||||
# it to be enabled to test Electron apps, so turn it back on.
|
||||
- name: Set EnableNodeCliInspectArguments fuse enabled
|
||||
run: $RUN_AS $PNPM_PATH/pnpm exec electron-fuses write --app "$EXECUTABLE" EnableNodeCliInspectArguments=on
|
||||
working-directory: apps/desktop
|
||||
shell: bash
|
||||
env:
|
||||
# We need sudo on Linux as it is installed in /opt/
|
||||
RUN_AS: ${{ runner.os == 'Linux' && 'sudo' || '' }}
|
||||
PNPM_PATH: ${{ steps.pnpm.outputs.bin_dest }}
|
||||
EXECUTABLE: ${{ steps.executable.outputs.path }}
|
||||
|
||||
- name: Run tests
|
||||
timeout-minutes: 20
|
||||
shell: bash
|
||||
working-directory: apps/desktop
|
||||
run: |
|
||||
$PREFIX pnpm playwright test \
|
||||
${{ runner.os != 'Linux' && '--ignore-snapshots' || '' }} \
|
||||
${{ inputs.blob_report == false && '--reporter=html' || '' }} \
|
||||
$ARGS
|
||||
env:
|
||||
PREFIX: ${{ runner.os == 'Linux' && 'xvfb-run' || '' }}
|
||||
PW_TAG: ${{ inputs.project }}
|
||||
ELEMENT_DESKTOP_EXECUTABLE: ${{ steps.executable.outputs.path }}
|
||||
ARGS: ${{ inputs.args }}
|
||||
DEBUG: pw:browser
|
||||
|
||||
- name: Upload blob report
|
||||
if: always() && inputs.blob_report
|
||||
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
|
||||
with:
|
||||
name: blob-report-${{ inputs.artifact }}
|
||||
path: apps/desktop/blob-report
|
||||
retention-days: 1
|
||||
if-no-files-found: error
|
||||
|
||||
- name: Upload HTML report
|
||||
if: always() && inputs.blob_report == false
|
||||
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
|
||||
with:
|
||||
name: ${{ inputs.artifact }}-test
|
||||
path: apps/desktop/playwright-report
|
||||
retention-days: 14
|
||||
if-no-files-found: error
|
||||
@@ -1,320 +0,0 @@
|
||||
# This workflow relies on actions/cache to store the hak dependency artifacts as they take a long time to build
|
||||
# Due to this extra care must be taken to only ever run all build_* scripts against the same branch to ensure
|
||||
# the correct cache scoping, and additional care must be taken to not run untrusted actions on the develop branch.
|
||||
|
||||
# Windows GHA runner by default uses the pwsh shell which breaks codeSigningCert in the workflow
|
||||
# We always sign using eSignerCKA to ensure it keeps working, but aside from release & nightlies we use demo credentials
|
||||
# which do not yield trusted signatures.
|
||||
defaults:
|
||||
run:
|
||||
shell: powershell
|
||||
on:
|
||||
workflow_call:
|
||||
secrets:
|
||||
ESIGNER_USER_NAME:
|
||||
required: false
|
||||
ESIGNER_USER_PASSWORD:
|
||||
required: false
|
||||
ESIGNER_USER_TOTP:
|
||||
required: false
|
||||
inputs:
|
||||
ref:
|
||||
type: string
|
||||
required: false
|
||||
description: "The git ref to checkout, defaults to the default branch"
|
||||
arch:
|
||||
type: string
|
||||
required: true
|
||||
description: "The architecture to build for, one of 'x64' | 'ia32' | 'arm64'"
|
||||
version:
|
||||
type: string
|
||||
required: false
|
||||
description: "Version string to override the one in package.json, used for non-release builds"
|
||||
sign:
|
||||
type: string
|
||||
required: false
|
||||
description: "Whether to sign & notarise the build, requires 'Desktop eSigner' environment"
|
||||
blob_report:
|
||||
type: boolean
|
||||
required: false
|
||||
description: "Whether to run the blob report"
|
||||
prepare-artifact-name:
|
||||
type: string
|
||||
required: false
|
||||
description: |
|
||||
The name of the prepare artifact to use, defaults to 'desktop-prepare'.
|
||||
The artifact must contain the following:
|
||||
+ webapp.asar - the asar archive of the webapp to embed in the desktop app
|
||||
+ electronVersion - the version of electron to use for cache keying
|
||||
+ hakHash - the hash of the .hak directory to use for cache keying
|
||||
+ variant.json - the variant configuration to use for the build
|
||||
|
||||
|
||||
The artifact can also contain any additional files which will be applied as overrides to the checkout root before building,
|
||||
for example icons in the `build/` directory to override the app icons.
|
||||
default: "desktop-prepare"
|
||||
test:
|
||||
type: boolean
|
||||
required: false
|
||||
default: true
|
||||
description: "Whether to run the test stage after building"
|
||||
test-runs-on:
|
||||
type: string
|
||||
required: false
|
||||
description: "The runner image to use for testing, normally set for you, may be needed for running in private repos."
|
||||
test-args:
|
||||
type: string
|
||||
required: false
|
||||
description: "Additional arguments to pass to playwright"
|
||||
artifact-prefix:
|
||||
type: string
|
||||
required: false
|
||||
description: "An optional prefix to add to the artifact name, useful for distinguishing builds in private repos."
|
||||
default: ""
|
||||
targets:
|
||||
type: string
|
||||
required: false
|
||||
description: "List of targets to build"
|
||||
default: "squirrel msi"
|
||||
permissions: {} # No permissions required
|
||||
jobs:
|
||||
build:
|
||||
name: Build Windows ${{ inputs.arch }}
|
||||
runs-on: windows-2025
|
||||
environment: ${{ inputs.sign && 'Desktop eSigner' || '' }}
|
||||
env:
|
||||
SIGNTOOL_PATH: "C:/Program Files (x86)/Windows Kits/10/bin/10.0.26100.0/x86/signtool.exe"
|
||||
steps:
|
||||
- uses: nbucic/variable-mapper@0673f6891a0619ba7c002ecfed0f9f4f39017b6f
|
||||
id: config
|
||||
with:
|
||||
key: "${{ inputs.arch }}"
|
||||
export_to: output
|
||||
map: |
|
||||
{
|
||||
"x64": {
|
||||
"target": "x86_64-pc-windows-msvc"
|
||||
},
|
||||
"arm64": {
|
||||
"target": "aarch64-pc-windows-msvc",
|
||||
"build-args": "--arm64",
|
||||
"arch": "amd64_arm64"
|
||||
},
|
||||
"ia32": {
|
||||
"target": "i686-pc-windows-msvc",
|
||||
"build-args": "--ia32",
|
||||
"arch": "x86",
|
||||
"extra_config": "{\"user_notice\": {\"title\": \"Your desktop environment is unsupported.\",\"description\": \"Support for 32-bit Windows installations has ended. Transition to the web or mobile app for continued access.\"}}"
|
||||
}
|
||||
}
|
||||
|
||||
# Tweak line endings to make nx happy, workaround for https://github.com/nrwl/nx/issues/35828
|
||||
- name: Configure git line endings
|
||||
run: |
|
||||
git config --system core.autocrlf false
|
||||
git config --system core.eol lf
|
||||
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
|
||||
with:
|
||||
repository: element-hq/element-web
|
||||
ref: ${{ inputs.ref }}
|
||||
persist-credentials: false
|
||||
|
||||
- uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8
|
||||
with:
|
||||
name: ${{ inputs.prepare-artifact-name }}
|
||||
path: apps/desktop/
|
||||
|
||||
- name: Cache .hak
|
||||
id: cache
|
||||
uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5
|
||||
with:
|
||||
key: ${{ runner.os }}-${{ inputs.arch }}-${{ hashFiles('apps/desktop/hakHash', 'apps/desktop/electronVersion') }}
|
||||
path: |
|
||||
apps/desktop/.hak
|
||||
|
||||
# ActiveTCL package on choco is from 2015,
|
||||
# this one is newer but includes more than we need
|
||||
- name: Choco install tclsh
|
||||
if: steps.cache.outputs.cache-hit != 'true'
|
||||
shell: pwsh
|
||||
run: |
|
||||
choco install -y magicsplat-tcl-tk --no-progress
|
||||
echo "${HOME}/AppData/Local/Apps/Tcl86/bin" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append
|
||||
|
||||
- name: Choco install NetWide Assembler
|
||||
if: steps.cache.outputs.cache-hit != 'true'
|
||||
shell: pwsh
|
||||
run: |
|
||||
choco install -y nasm --no-progress
|
||||
echo "C:/Program Files/NASM" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append
|
||||
|
||||
- name: Install Rust
|
||||
if: steps.cache.outputs.cache-hit != 'true'
|
||||
run: |
|
||||
rustup toolchain install stable --profile minimal --no-self-update
|
||||
rustup default stable
|
||||
rustup target add $env:TARGET
|
||||
env:
|
||||
TARGET: ${{ steps.config.outputs.target }}
|
||||
|
||||
- uses: pnpm/action-setup@0e279bb959325dab635dd2c09392533439d90093 # v6.0.8
|
||||
- uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6
|
||||
with:
|
||||
node-version-file: apps/desktop/.node-version
|
||||
cache: "pnpm"
|
||||
|
||||
- name: Install Deps
|
||||
working-directory: apps/desktop
|
||||
run: "pnpm install --frozen-lockfile --filter element-desktop"
|
||||
|
||||
- name: Insert config snippet
|
||||
if: steps.config.outputs.extra_config != ''
|
||||
working-directory: apps/desktop
|
||||
shell: bash
|
||||
run: |
|
||||
mkdir config-edit
|
||||
pnpm asar extract webapp.asar config-edit
|
||||
cd config-edit
|
||||
mv config.json old-config.json
|
||||
echo '${{ steps.config.outputs.extra_config }}' | jq -s '.[0] * .[1]' old-config.json - > config.json
|
||||
rm old-config.json
|
||||
cd ..
|
||||
rm webapp.asar
|
||||
pnpm asar pack config-edit/ webapp.asar
|
||||
|
||||
- name: Set up sqlcipher macros
|
||||
if: steps.cache.outputs.cache-hit != 'true' && contains(inputs.arch, 'arm')
|
||||
shell: pwsh
|
||||
run: |
|
||||
echo "NCC=${{ github.workspace }}\scripts\cl.bat" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append
|
||||
|
||||
- name: Set up build tools
|
||||
if: steps.cache.outputs.cache-hit != 'true'
|
||||
uses: ilammy/msvc-dev-cmd@0b201ec74fa43914dc39ae48a89fd1d8cb592756 # v1.13.0
|
||||
with:
|
||||
arch: ${{ steps.config.outputs.arch || inputs.arch }}
|
||||
|
||||
- name: Build Natives
|
||||
if: steps.cache.outputs.cache-hit != 'true'
|
||||
working-directory: apps/desktop
|
||||
run: |
|
||||
refreshenv
|
||||
pnpm run build:native --target $env:TARGET
|
||||
env:
|
||||
TARGET: ${{ steps.config.outputs.target }}
|
||||
|
||||
- name: Install and configure eSigner CKA
|
||||
run: |
|
||||
Set-StrictMode -Version 'Latest'
|
||||
|
||||
# Download, extract, and rename
|
||||
Invoke-WebRequest -OutFile eSigner_CKA.zip "$env:ESIGNER_URL"
|
||||
Expand-Archive -Path eSigner_CKA.zip -DestinationPath .
|
||||
Get-ChildItem -Path * -Include "*_build_*.exe" | Rename-Item -NewName eSigner_CKA.exe
|
||||
|
||||
# Install
|
||||
New-Item -ItemType Directory -Force -Path "$env:INSTALL_DIR"
|
||||
./eSigner_CKA.exe /CURRENTUSER /VERYSILENT /SUPPRESSMSGBOXES /DIR="${{ env.INSTALL_DIR }}" | Out-Null
|
||||
|
||||
# Disable logger
|
||||
$LogConfig = Get-Content -Path ${{ env.INSTALL_DIR }}/log4net.config
|
||||
$LogConfig[0] = '<log4net threshold="OFF">'
|
||||
$LogConfig | Set-Content -Path ${{ env.INSTALL_DIR }}/log4net.config
|
||||
|
||||
# Configure - default credentials from https://www.ssl.com/guide/esigner-demo-credentials-and-certificates/
|
||||
${{ env.INSTALL_DIR }}/eSignerCKATool.exe config `
|
||||
-mode "$env:ESIGNER_MODE" `
|
||||
-user "${{ secrets.ESIGNER_USER_NAME || 'esigner_demo' }}" `
|
||||
-pass "${{ secrets.ESIGNER_USER_PASSWORD || 'esignerDemo#1' }}" `
|
||||
-totp "${{ secrets.ESIGNER_USER_TOTP || 'RDXYgV9qju+6/7GnMf1vCbKexXVJmUVr+86Wq/8aIGg=' }}" `
|
||||
-key "${{ env.MASTER_KEY_FILE }}" -r
|
||||
${{ env.INSTALL_DIR }}/eSignerCKATool.exe unload
|
||||
${{ env.INSTALL_DIR }}/eSignerCKATool.exe load
|
||||
|
||||
# Find certificate
|
||||
$CodeSigningCert = Get-ChildItem Cert:\CurrentUser\My -CodeSigningCert | Select-Object -First 1
|
||||
echo Certificate: $CodeSigningCert
|
||||
|
||||
# Extract thumbprint and subject name
|
||||
$Thumbprint = $CodeSigningCert.Thumbprint
|
||||
$SubjectName = ($CodeSigningCert.Subject -replace ", ?", "`n" | ConvertFrom-StringData).CN
|
||||
|
||||
echo "ED_SIGNTOOL_THUMBPRINT=$Thumbprint" >> $env:GITHUB_ENV
|
||||
echo "ED_SIGNTOOL_SUBJECT_NAME=$SubjectName" >> $env:GITHUB_ENV
|
||||
env:
|
||||
ESIGNER_MODE: ${{ vars.ESIGNER_MODE || 'sandbox' }}
|
||||
ESIGNER_URL: https://github.com/SSLcom/eSignerCKA/releases/download/v1.0.6/SSL.COM-eSigner-CKA_1.0.6.zip
|
||||
INSTALL_DIR: C:\Users\runneradmin\eSignerCKA
|
||||
MASTER_KEY_FILE: C:\Users\runneradmin\eSignerCKA\master.key
|
||||
|
||||
- name: Build App
|
||||
working-directory: apps/desktop
|
||||
run: pnpm run build --publish never $BUILD_ARGS -w $TARGETS
|
||||
shell: bash
|
||||
env:
|
||||
VARIANT_PATH: variant.json
|
||||
# Only set for Nightly builds
|
||||
# The windows packager relies on parsing this as semver, so we have to make it look like one.
|
||||
# This will give our update packages really stupid names, but we probably can't change that either
|
||||
# because squirrel windows parses them for the version too. We don't really care: nobody sees them.
|
||||
# We just give the installer a static name, so you'll just see this in the 'about' dialog.
|
||||
# Turns out if you use 0.0.0 here it makes Squirrel windows crash, so we use 0.0.1.
|
||||
VERSION: ${{ inputs.version && format('0.0.1-nightly.{0}', inputs.version) || '' }}
|
||||
BUILD_ARGS: ${{ steps.config.outputs.build-args }}
|
||||
TARGETS: ${{ inputs.targets }}
|
||||
|
||||
- name: Trust eSigner sandbox cert
|
||||
if: inputs.sign == ''
|
||||
run: |
|
||||
Set-StrictMode -Version 'Latest'
|
||||
Import-Certificate -CertStoreLocation Cert:\LocalMachine\Root -FilePath .github/SSLcom-sandbox.crt
|
||||
|
||||
- name: Check app was signed successfully
|
||||
working-directory: apps/desktop
|
||||
run: |
|
||||
Set-StrictMode -Version 'Latest'
|
||||
Get-ChildItem `
|
||||
-Recurse dist `
|
||||
-Include *.exe, *.msi `
|
||||
| ForEach-Object -Process {. $env:SIGNTOOL_PATH verify /pa $_.FullName; if(!$?) { throw }}
|
||||
|
||||
- name: Upload Artifacts
|
||||
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
|
||||
with:
|
||||
name: ${{ inputs.artifact-prefix }}win-${{ inputs.arch }}
|
||||
path: |
|
||||
apps/desktop/dist
|
||||
retention-days: 1
|
||||
|
||||
- name: Assert executable is present
|
||||
working-directory: apps/desktop
|
||||
run: |
|
||||
Test-Path './dist/win-*unpacked/Element*.exe'
|
||||
|
||||
- name: Assert all Squirrel files are present
|
||||
if: contains(inputs.targets, 'squirrel')
|
||||
working-directory: apps/desktop
|
||||
run: |
|
||||
Test-Path './dist/squirrel-windows*/Element Setup*.exe'
|
||||
Test-Path './dist/squirrel-windows*/element-desktop-*-full.nupkg'
|
||||
Test-Path './dist/squirrel-windows*/RELEASES'
|
||||
|
||||
- name: Assert MSI is present
|
||||
if: contains(inputs.targets, 'msi')
|
||||
working-directory: apps/desktop
|
||||
run: |
|
||||
Test-Path './dist/Element*.msi'
|
||||
|
||||
test:
|
||||
name: Test Windows ${{ inputs.arch }}
|
||||
needs: build
|
||||
if: inputs.test
|
||||
uses: ./.github/workflows/build_desktop_test.yaml
|
||||
with:
|
||||
project: win-${{ inputs.arch }}
|
||||
artifact: ${{ inputs.artifact-prefix }}win-${{ inputs.arch }}
|
||||
runs-on: ${{ inputs.test-runs-on || (inputs.arch == 'arm64' && 'windows-11-arm' || 'windows-2022') }}
|
||||
executable: ./dist/win*-unpacked/Element*.exe
|
||||
blob_report: ${{ inputs.blob_report }}
|
||||
args: ${{ inputs.test-args }}
|
||||
@@ -9,9 +9,6 @@ on:
|
||||
concurrency:
|
||||
group: ${{ github.repository_owner }}-${{ github.workflow }}-${{ github.ref_name }}
|
||||
cancel-in-progress: true
|
||||
env:
|
||||
NX_DEFAULT_OUTPUT_STYLE: stream-without-prefixes
|
||||
permissions: {}
|
||||
jobs:
|
||||
build:
|
||||
name: "Build & Deploy develop.element.io"
|
||||
@@ -19,30 +16,22 @@ jobs:
|
||||
if: github.repository == 'element-hq/element-web'
|
||||
runs-on: ubuntu-24.04
|
||||
environment: develop
|
||||
permissions:
|
||||
checks: read
|
||||
pages: write
|
||||
deployments: write
|
||||
env:
|
||||
R2_BUCKET: "element-web-develop"
|
||||
R2_URL: ${{ vars.CF_R2_S3_API }}
|
||||
R2_PUBLIC_URL: "https://element-web-develop.element.io"
|
||||
steps:
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
|
||||
with:
|
||||
persist-credentials: false
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- uses: pnpm/action-setup@0e279bb959325dab635dd2c09392533439d90093 # v6.0.8
|
||||
- uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6
|
||||
- uses: actions/setup-node@v4
|
||||
with:
|
||||
cache: "pnpm"
|
||||
cache: "yarn"
|
||||
node-version: "lts/*"
|
||||
|
||||
- name: Install Dependencies
|
||||
run: "./scripts/layered.sh"
|
||||
|
||||
- name: Build, Package & Upload sourcemaps
|
||||
working-directory: apps/web
|
||||
run: "./scripts/ci_package.sh"
|
||||
env:
|
||||
SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }}
|
||||
@@ -58,21 +47,20 @@ jobs:
|
||||
CSP_EXTRA_SOURCE: ${{ env.R2_PUBLIC_URL }}
|
||||
|
||||
- run: mv dist/element-*.tar.gz dist/develop.tar.gz
|
||||
working-directory: apps/web
|
||||
|
||||
- uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
|
||||
- uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: webapp
|
||||
path: apps/web/dist/develop.tar.gz
|
||||
path: dist/develop.tar.gz
|
||||
retention-days: 1
|
||||
|
||||
- name: Extract webapp
|
||||
run: |
|
||||
mkdir _deploy
|
||||
tar xf apps/web/dist/develop.tar.gz -C _deploy --strip-components=1
|
||||
tar xf dist/develop.tar.gz -C _deploy --strip-components=1
|
||||
|
||||
- name: Copy config
|
||||
run: cp apps/web/element.io/develop/config.json _deploy/config.json
|
||||
run: cp element.io/develop/config.json _deploy/config.json
|
||||
|
||||
- name: Populate 404.html
|
||||
run: echo "404 Not Found" > _deploy/404.html
|
||||
@@ -111,30 +99,28 @@ jobs:
|
||||
running-workflow-name: "Build & Deploy develop.element.io"
|
||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
wait-interval: 10
|
||||
check-regexp: ^((?!SonarCloud|SonarQube|issue|board|label|Release|prepare|GitHub Pages|Upload|Netlify|Report|deploy).)*$
|
||||
check-regexp: ^((?!SonarCloud|SonarQube|issue|board|label|Release|prepare|GitHub Pages).)*$
|
||||
|
||||
# We keep the latest develop.tar.gz on R2 instead of relying on the github artifact uploaded earlier
|
||||
# as the expires after 24h and requires auth to download.
|
||||
# Element Desktop's fetch script uses this tarball to fetch latest develop to build Nightlies.
|
||||
# Checksum algorithm specified as per https://developers.cloudflare.com/r2/examples/aws/aws-cli/
|
||||
- name: Deploy to R2
|
||||
run: |
|
||||
aws s3 cp apps/web/dist/develop.tar.gz s3://$R2_BUCKET/develop.tar.gz --endpoint-url $R2_URL --region=auto --checksum-algorithm CRC32
|
||||
aws s3 cp _deploy/ s3://$R2_BUCKET/ --recursive --endpoint-url $R2_URL --region=auto --checksum-algorithm CRC32
|
||||
aws s3 cp dist/develop.tar.gz s3://$R2_BUCKET/develop.tar.gz --endpoint-url $R2_URL --region=auto
|
||||
aws s3 cp _deploy/ s3://$R2_BUCKET/ --recursive --endpoint-url $R2_URL --region=auto
|
||||
env:
|
||||
AWS_ACCESS_KEY_ID: ${{ secrets.CF_R2_ACCESS_KEY_ID }}
|
||||
AWS_SECRET_ACCESS_KEY: ${{ secrets.CF_R2_TOKEN }}
|
||||
|
||||
- name: Deploy to Cloudflare Pages
|
||||
id: cfp
|
||||
uses: cloudflare/wrangler-action@ebbaa1584979971c8614a24965b4405ff95890e0 # v4.0.0
|
||||
uses: cloudflare/pages-action@f0a1cd58cd66095dee69bfa18fa5efd1dde93bca # v1
|
||||
with:
|
||||
apiToken: ${{ secrets.CF_PAGES_TOKEN }}
|
||||
accountId: ${{ secrets.CF_PAGES_ACCOUNT_ID }}
|
||||
command: pages deploy _deploy --project-name element-web-develop
|
||||
projectName: element-web-develop
|
||||
directory: _deploy
|
||||
gitHubToken: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- run: |
|
||||
echo "Deployed to ${STEPS_CFP_OUTPUTS_URL}" >> $GITHUB_STEP_SUMMARY
|
||||
env:
|
||||
STEPS_CFP_OUTPUTS_URL: ${{ steps.cfp.outputs.deployment-url }}
|
||||
echo "Deployed to ${{ steps.cfp.outputs.url }}" >> $GITHUB_STEP_SUMMARY
|
||||
|
||||
@@ -1,82 +0,0 @@
|
||||
name: CD # Continuous Delivery
|
||||
on:
|
||||
push:
|
||||
branches: [master, staging, develop]
|
||||
paths:
|
||||
- "**/Dockerfile"
|
||||
- "**/dockerbuild"
|
||||
- "**/docker"
|
||||
- "**/docker-*"
|
||||
- "pnpm-lock.yaml"
|
||||
|
||||
concurrency: ${{ github.workflow }}-${{ github.ref_name }}
|
||||
|
||||
permissions: {}
|
||||
env:
|
||||
NX_DEFAULT_OUTPUT_STYLE: stream-without-prefixes
|
||||
|
||||
jobs:
|
||||
docker:
|
||||
name: Docker Bake
|
||||
runs-on: ubuntu-24.04
|
||||
permissions:
|
||||
id-token: write # needed for signing the images with GitHub OIDC Token
|
||||
packages: write # needed for publishing packages to GHCR
|
||||
# Needed for nx-set-shas
|
||||
contents: read
|
||||
actions: read
|
||||
steps:
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
- name: Install Cosign
|
||||
uses: sigstore/cosign-installer@6f9f17788090df1f26f669e9d70d6ae9567deba6 # v4.1.2
|
||||
|
||||
- name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@ce360397dd3f832beb865e1373c09c0e9f86d70a # v4
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
id: builder
|
||||
uses: docker/setup-buildx-action@4d04d5d9486b7bd6fa91e7baf45bbb4f8b9deedd # v4
|
||||
|
||||
- uses: pnpm/action-setup@0e279bb959325dab635dd2c09392533439d90093 # v6.0.8
|
||||
- uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6
|
||||
with:
|
||||
node-version-file: package.json
|
||||
cache: "pnpm"
|
||||
|
||||
- name: Install Deps
|
||||
run: "pnpm install --frozen-lockfile"
|
||||
|
||||
- name: Login to GitHub Container Registry
|
||||
uses: docker/login-action@4907a6ddec9925e35a0a9e82d7399ccc52663121 # v4
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: ${{ github.repository_owner }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
# Fudge and run this separately rather than relying on the dependency,
|
||||
# otherwise nx does not appear to pick up the .env file that playwright
|
||||
# common's prebuild step creates.
|
||||
- run: pnpm nx run-many --nxBail -t docker:prebuild
|
||||
env:
|
||||
INPUT_BUILDER: ${{ steps.builder.outputs.name }}
|
||||
|
||||
- run: pnpm nx run-many --nxBail -t docker:build
|
||||
id: build
|
||||
env:
|
||||
INPUT_PUSH: true
|
||||
INPUT_LOAD: false
|
||||
INPUT_GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
INPUT_BUILDER: ${{ steps.builder.outputs.name }}
|
||||
|
||||
- name: Sign the images with GitHub OIDC token
|
||||
run: |
|
||||
shopt -s globstar
|
||||
|
||||
for FILE in ./node_modules/.cache/nx-container/**/metadata; do
|
||||
TARGET=$(jq -r '(.["image.name"] | split(",") | last) + "@" + .["containerimage.digest"]' "$FILE")
|
||||
echo "Signing $TARGET..."
|
||||
cosign sign --yes "$TARGET"
|
||||
done
|
||||
@@ -1,105 +0,0 @@
|
||||
# Manual deploy workflow for deploying to app.element.io & staging.element.io
|
||||
# Runs automatically for staging.element.io when an RC or Release is published
|
||||
# Note: Does *NOT* run automatically for app.element.io so that it gets tested on staging.element.io beforehand
|
||||
name: Deploy release
|
||||
run-name: Deploy ${{ github.ref_name }} to ${{ inputs.site || 'staging.element.io' }}
|
||||
on:
|
||||
release:
|
||||
types: [published]
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
site:
|
||||
description: Which site to deploy to
|
||||
required: true
|
||||
default: staging.element.io
|
||||
type: choice
|
||||
options:
|
||||
- staging.element.io
|
||||
- app.element.io
|
||||
skip-checks:
|
||||
description: Skip CI on the tagged commit
|
||||
required: true
|
||||
default: false
|
||||
type: boolean
|
||||
concurrency: ${{ inputs.site || 'staging.element.io' }}
|
||||
permissions: {}
|
||||
jobs:
|
||||
deploy:
|
||||
name: "Deploy to Cloudflare Pages"
|
||||
runs-on: ubuntu-24.04
|
||||
environment: ${{ inputs.site || 'staging.element.io' }}
|
||||
permissions:
|
||||
checks: read
|
||||
deployments: write
|
||||
env:
|
||||
SITE: ${{ inputs.site || 'staging.element.io' }}
|
||||
steps:
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
- uses: pnpm/action-setup@0e279bb959325dab635dd2c09392533439d90093 # v6.0.8
|
||||
- uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6
|
||||
with:
|
||||
cache: "pnpm"
|
||||
node-version-file: package.json
|
||||
|
||||
- name: Load GPG key
|
||||
run: |
|
||||
curl https://packages.element.io/element-release-key.gpg | gpg --import
|
||||
gpg -k "$GPG_FINGERPRINT"
|
||||
env:
|
||||
GPG_FINGERPRINT: ${{ vars.GPG_FINGERPRINT }}
|
||||
|
||||
- name: Check current version on deployment
|
||||
id: current_version
|
||||
run: |
|
||||
version=$(curl -s https://$SITE/version)
|
||||
echo "version=${version#v}" >> $GITHUB_OUTPUT
|
||||
|
||||
# The current version bundle melding dance is skipped if the version we're deploying is the same
|
||||
# as then we're just doing a re-deploy of the same version with potentially different configs.
|
||||
- name: Download current version for its old bundles
|
||||
id: current_download
|
||||
if: steps.current_version.outputs.version != github.ref_name
|
||||
uses: ./.github/actions/download-verify-element-tarball
|
||||
with:
|
||||
tag: v${{ steps.current_version.outputs.version }}
|
||||
out-file-path: _current_version
|
||||
|
||||
- name: Download target version
|
||||
uses: ./.github/actions/download-verify-element-tarball
|
||||
with:
|
||||
tag: ${{ github.ref_name }}
|
||||
out-file-path: _deploy
|
||||
|
||||
- name: Merge current bundles into target
|
||||
if: steps.current_download.outcome == 'success'
|
||||
run: cp -vnpr _current_version/bundles/* _deploy/bundles/
|
||||
|
||||
- name: Copy config
|
||||
run: cp apps/web/element.io/app/config.json _deploy/config.json
|
||||
|
||||
- name: Populate 404.html
|
||||
run: echo "404 Not Found" > _deploy/404.html
|
||||
|
||||
- name: Populate _headers
|
||||
run: cp .github/cfp_headers _deploy/_headers
|
||||
|
||||
- name: Wait for other steps to succeed
|
||||
uses: t3chguy/wait-on-check-action@18541021811b56544d90e0f073401c2b99e249d6 # fork
|
||||
if: inputs.skip-checks != true
|
||||
with:
|
||||
ref: ${{ github.sha }}
|
||||
running-workflow-name: "Deploy to Cloudflare Pages"
|
||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
wait-interval: 10
|
||||
check-regexp: ^((?!SonarCloud|SonarQube|issue|board|label|Release|prepare|GitHub Pages).)*$
|
||||
|
||||
- name: Deploy to Cloudflare Pages
|
||||
uses: cloudflare/wrangler-action@ebbaa1584979971c8614a24965b4405ff95890e0 # v4.0.0
|
||||
with:
|
||||
apiToken: ${{ secrets.CF_PAGES_TOKEN }}
|
||||
accountId: ${{ secrets.CF_PAGES_ACCOUNT_ID }}
|
||||
command: pages deploy _deploy --project-name ${{ env.SITE == 'staging.element.io' && 'element-web-staging' || 'element-web' }} --branch main
|
||||
gitHubToken: ${{ secrets.GITHUB_TOKEN }}
|
||||
@@ -1,181 +0,0 @@
|
||||
name: Docker
|
||||
on:
|
||||
workflow_dispatch: {}
|
||||
push:
|
||||
tags: [v*]
|
||||
pull_request: {}
|
||||
schedule:
|
||||
# This job can take a while, and we have usage limits, so just publish develop only twice a day
|
||||
- cron: "0 7/12 * * *"
|
||||
concurrency: ${{ github.workflow }}-${{ github.ref_name }}
|
||||
permissions: {}
|
||||
jobs:
|
||||
buildx:
|
||||
name: Docker Buildx
|
||||
runs-on: ubuntu-24.04
|
||||
environment: ${{ github.event_name != 'pull_request' && 'dockerhub' || '' }}
|
||||
permissions:
|
||||
id-token: write # needed for signing the images with GitHub OIDC Token
|
||||
packages: write # needed for publishing packages to GHCR
|
||||
env:
|
||||
TEST_TAG: vectorim/element-web:test
|
||||
steps:
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
|
||||
with:
|
||||
fetch-depth: 0 # needed for docker-package to be able to calculate the version
|
||||
persist-credentials: false
|
||||
|
||||
- name: Install Cosign
|
||||
uses: sigstore/cosign-installer@6f9f17788090df1f26f669e9d70d6ae9567deba6 # v4.1.2
|
||||
if: github.event_name != 'pull_request'
|
||||
|
||||
- name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@ce360397dd3f832beb865e1373c09c0e9f86d70a # v4
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@4d04d5d9486b7bd6fa91e7baf45bbb4f8b9deedd # v4
|
||||
with:
|
||||
install: true
|
||||
|
||||
- name: Build and load
|
||||
id: test-build
|
||||
uses: docker/build-push-action@bcafcacb16a39f128d818304e6c9c0c18556b85f # v7
|
||||
with:
|
||||
context: .
|
||||
file: apps/web/Dockerfile
|
||||
load: true
|
||||
|
||||
- name: Test the image
|
||||
env:
|
||||
IMAGEID: ${{ steps.test-build.outputs.imageid }}
|
||||
timeout-minutes: 2
|
||||
run: |
|
||||
set -x
|
||||
|
||||
# Make a fake module to test the image
|
||||
MODULE_PATH="modules/module_name/index.js"
|
||||
mkdir -p $(dirname $MODULE_PATH)
|
||||
echo 'alert("Testing");' > $MODULE_PATH
|
||||
|
||||
# Spin up a container of the image
|
||||
ELEMENT_WEB_PORT=8181
|
||||
CONTAINER_ID=$(
|
||||
docker run \
|
||||
--rm \
|
||||
-e "ELEMENT_WEB_PORT=$ELEMENT_WEB_PORT" \
|
||||
-dp "$ELEMENT_WEB_PORT:$ELEMENT_WEB_PORT" \
|
||||
-v $(pwd)/modules:/modules \
|
||||
"$IMAGEID" \
|
||||
)
|
||||
|
||||
# Run some smoke tests
|
||||
wget --retry-connrefused --tries=5 -q --wait=3 --spider "http://localhost:$ELEMENT_WEB_PORT/modules/module_name/index.js"
|
||||
MODULE_0=$(curl "http://localhost:$ELEMENT_WEB_PORT/config.json" | jq -r .modules[0])
|
||||
test "$MODULE_0" = "/${MODULE_PATH}"
|
||||
|
||||
# Check healthcheck
|
||||
until test "$(docker inspect -f {{.State.Health.Status}} $CONTAINER_ID)" == "healthy"; do
|
||||
sleep 1
|
||||
done
|
||||
|
||||
# Clean up
|
||||
docker stop "$CONTAINER_ID"
|
||||
|
||||
- name: Docker meta
|
||||
id: meta
|
||||
uses: docker/metadata-action@030e881283bb7a6894de51c315a6bfe6a94e05cf # v6
|
||||
if: github.event_name != 'pull_request'
|
||||
with:
|
||||
images: |
|
||||
vectorim/element-web
|
||||
ghcr.io/element-hq/element-web
|
||||
oci-push.vpn.infra.element.io/element-web
|
||||
tags: |
|
||||
type=ref,event=branch
|
||||
type=ref,event=tag
|
||||
flavor: |
|
||||
latest=${{ contains(github.ref_name, '-rc.') && 'false' || 'auto' }}
|
||||
|
||||
- name: Login to Docker Hub
|
||||
uses: docker/login-action@4907a6ddec9925e35a0a9e82d7399ccc52663121 # v4
|
||||
if: github.event_name != 'pull_request'
|
||||
with:
|
||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||
|
||||
- name: Login to GitHub Container Registry
|
||||
uses: docker/login-action@4907a6ddec9925e35a0a9e82d7399ccc52663121 # v4
|
||||
if: github.event_name != 'pull_request'
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: ${{ github.repository_owner }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Connect to Tailscale
|
||||
uses: tailscale/github-action@306e68a486fd2350f2bfc3b19fcd143891a4a2d8 # v4
|
||||
if: github.event_name != 'pull_request'
|
||||
with:
|
||||
oauth-client-id: ${{ secrets.TS_OAUTH_CLIENT_ID }}
|
||||
audience: ${{ secrets.TS_AUDIENCE }}
|
||||
tags: tag:github-actions
|
||||
|
||||
- name: Compute vault jwt role name
|
||||
id: vault-jwt-role
|
||||
if: github.event_name != 'pull_request'
|
||||
run: |
|
||||
echo "role_name=github_service_management_$( echo "${{ github.repository }}" | sed -r 's|[/-]|_|g')" | tee -a "$GITHUB_OUTPUT"
|
||||
|
||||
- name: Get team registry token
|
||||
id: import-secrets
|
||||
uses: hashicorp/vault-action@892a26828f195e65540a40b4768ae4571f51ebfc # v4
|
||||
if: github.event_name != 'pull_request'
|
||||
with:
|
||||
url: https://vault.infra.ci.i.element.dev
|
||||
role: ${{ steps.vault-jwt-role.outputs.role_name }}
|
||||
path: service-management/github-actions
|
||||
jwtGithubAudience: https://vault.infra.ci.i.element.dev
|
||||
method: jwt
|
||||
secrets: |
|
||||
services/web-repositories/secret/data/oci.element.io username | OCI_USERNAME ;
|
||||
services/web-repositories/secret/data/oci.element.io password | OCI_PASSWORD ;
|
||||
|
||||
- name: Login to oci.element.io Registry
|
||||
uses: docker/login-action@4907a6ddec9925e35a0a9e82d7399ccc52663121 # v4
|
||||
if: github.event_name != 'pull_request'
|
||||
with:
|
||||
registry: oci-push.vpn.infra.element.io
|
||||
username: ${{ steps.import-secrets.outputs.OCI_USERNAME }}
|
||||
password: ${{ steps.import-secrets.outputs.OCI_PASSWORD }}
|
||||
|
||||
- name: Build and push
|
||||
id: build-and-push
|
||||
uses: docker/build-push-action@bcafcacb16a39f128d818304e6c9c0c18556b85f # v7
|
||||
if: github.event_name != 'pull_request'
|
||||
with:
|
||||
context: .
|
||||
file: apps/web/Dockerfile
|
||||
push: true
|
||||
platforms: linux/amd64,linux/arm64
|
||||
tags: ${{ steps.meta.outputs.tags }}
|
||||
labels: ${{ steps.meta.outputs.labels }}
|
||||
|
||||
- name: Sign the images with GitHub OIDC Token
|
||||
env:
|
||||
DIGEST: ${{ steps.build-and-push.outputs.digest }}
|
||||
TAGS: ${{ steps.meta.outputs.tags }}
|
||||
if: github.event_name != 'pull_request'
|
||||
run: |
|
||||
images=""
|
||||
for tag in ${TAGS}; do
|
||||
images+="${tag}@${DIGEST} "
|
||||
done
|
||||
cosign sign --yes ${images}
|
||||
|
||||
- name: Update repo description
|
||||
uses: peter-evans/dockerhub-description@1b9a80c056b620d92cedb9d9b5a223409c68ddfa # v5
|
||||
if: github.event_name != 'pull_request'
|
||||
continue-on-error: true
|
||||
with:
|
||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||
repository: vectorim/element-web
|
||||
@@ -0,0 +1,79 @@
|
||||
name: Dockerhub
|
||||
on:
|
||||
workflow_dispatch: {}
|
||||
push:
|
||||
tags: [v*]
|
||||
schedule:
|
||||
# This job can take a while, and we have usage limits, so just publish develop only twice a day
|
||||
- cron: "0 7/12 * * *"
|
||||
concurrency: ${{ github.workflow }}-${{ github.ref_name }}
|
||||
|
||||
permissions:
|
||||
id-token: write # needed for signing the images with GitHub OIDC Token
|
||||
jobs:
|
||||
buildx:
|
||||
name: Docker Buildx
|
||||
runs-on: ubuntu-24.04
|
||||
environment: dockerhub
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0 # needed for docker-package to be able to calculate the version
|
||||
|
||||
- name: Install Cosign
|
||||
uses: sigstore/cosign-installer@4959ce089c160fddf62f7b42464195ba1a56d382 # v3
|
||||
|
||||
- name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@49b3bc8e6bdd4a60e6116a5414239cba5943d3cf # v3
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@988b5a0280414f521da01fcc63a27aeeb4b104db # v3
|
||||
with:
|
||||
install: true
|
||||
|
||||
- name: Login to Docker Hub
|
||||
uses: docker/login-action@9780b0c442fbb1117ed29e0efdff1e18412f7567 # v3
|
||||
with:
|
||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||
|
||||
- name: Docker meta
|
||||
id: meta
|
||||
uses: docker/metadata-action@8e5442c4ef9f78752691e2d8f8d19755c6f78e81 # v5
|
||||
with:
|
||||
images: |
|
||||
vectorim/element-web
|
||||
tags: |
|
||||
type=ref,event=branch
|
||||
type=ref,event=tag
|
||||
flavor: |
|
||||
latest=${{ contains(github.ref_name, '-rc.') && 'false' || 'auto' }}
|
||||
|
||||
- name: Build and push
|
||||
id: build-and-push
|
||||
uses: docker/build-push-action@4f58ea79222b3b9dc2c8bbdd6debcef730109a75 # v6
|
||||
with:
|
||||
context: .
|
||||
push: true
|
||||
platforms: linux/amd64,linux/arm64
|
||||
tags: ${{ steps.meta.outputs.tags }}
|
||||
labels: ${{ steps.meta.outputs.labels }}
|
||||
|
||||
- name: Sign the images with GitHub OIDC Token
|
||||
env:
|
||||
DIGEST: ${{ steps.build-and-push.outputs.digest }}
|
||||
TAGS: ${{ steps.meta.outputs.tags }}
|
||||
run: |
|
||||
images=""
|
||||
for tag in ${TAGS}; do
|
||||
images+="${tag}@${DIGEST} "
|
||||
done
|
||||
cosign sign --yes ${images}
|
||||
|
||||
- name: Update repo description
|
||||
uses: peter-evans/dockerhub-description@e98e4d1628a5f3be2be7c231e50981aee98723ae # v4
|
||||
continue-on-error: true
|
||||
with:
|
||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||
repository: vectorim/element-web
|
||||
+69
-17
@@ -5,7 +5,10 @@ on:
|
||||
branches: [develop]
|
||||
workflow_dispatch: {}
|
||||
|
||||
permissions: {}
|
||||
permissions:
|
||||
contents: read
|
||||
pages: write
|
||||
id-token: write
|
||||
|
||||
concurrency:
|
||||
group: "pages"
|
||||
@@ -16,40 +19,89 @@ jobs:
|
||||
name: GitHub Pages
|
||||
runs-on: ubuntu-24.04
|
||||
steps:
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
|
||||
- name: Fetch element-desktop
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
persist-credentials: false
|
||||
repository: element-hq/element-desktop
|
||||
path: element-desktop
|
||||
|
||||
- uses: pnpm/action-setup@0e279bb959325dab635dd2c09392533439d90093 # v6.0.8
|
||||
- name: Fetch element-web
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
package_json_file: package.json
|
||||
- uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6
|
||||
path: element-web
|
||||
|
||||
- name: Fetch matrix-js-sdk
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
cache: "pnpm"
|
||||
cache-dependency-path: pnpm-lock.yaml
|
||||
repository: matrix-org/matrix-js-sdk
|
||||
path: matrix-js-sdk
|
||||
|
||||
- uses: actions/setup-node@v4
|
||||
with:
|
||||
cache: "yarn"
|
||||
cache-dependency-path: element-web/yarn.lock
|
||||
node-version: "lts/*"
|
||||
|
||||
- name: Fetch layered build
|
||||
run: ./scripts/layered.sh
|
||||
- name: Generate automations docs
|
||||
working-directory: element-web
|
||||
run: |
|
||||
yarn install --frozen-lockfile
|
||||
yarn ts-node ./scripts/gen-workflow-mermaid.ts ../element-desktop ../element-web ../matrix-js-sdk > docs/automations.md
|
||||
echo "- [Automations](automations.md)" >> docs/SUMMARY.md
|
||||
|
||||
- name: Setup mdBook
|
||||
uses: peaceiris/actions-mdbook@v2
|
||||
with:
|
||||
mdbook-version: "0.4.10"
|
||||
|
||||
- name: Install mdbook extensions
|
||||
run: cargo install mdbook-combiner mdbook-mermaid
|
||||
|
||||
- name: Prepare docs
|
||||
run: |
|
||||
mkdir docs
|
||||
|
||||
mv element-desktop/README.md element-desktop/docs/
|
||||
mv element-desktop/docs "docs/Element Desktop"
|
||||
|
||||
mv element-web/README.md element-web/docs/
|
||||
mv element-web/docs/lib docs/
|
||||
mv element-web/docs "docs/Element Web"
|
||||
|
||||
mv matrix-js-sdk/README.md matrix-js-sdk/docs/
|
||||
mv matrix-js-sdk/docs "docs/Matrix JS SDK"
|
||||
|
||||
sed -i -e 's/\.\.\/README.md/README.md/' docs/**/SUMMARY.md
|
||||
|
||||
mdbook-combiner -m docs
|
||||
sed -i -E 's/^\t# (.+)$/- [\1]()/gm;t' SUMMARY.md
|
||||
sed -i -E 's/^- \[(.+)]\(<>\)$/---\n# \1/gm;t' SUMMARY.md
|
||||
sed -i -E 's/\t- \[Introduction]/- [Introduction]/gm;t' SUMMARY.md
|
||||
|
||||
cat <<EOF > docs/SUMMARY.md
|
||||
# Summary
|
||||
- [Introduction](<Element Web/README.md>)
|
||||
|
||||
EOF
|
||||
cat SUMMARY.md >> docs/SUMMARY.md
|
||||
|
||||
mv element-web/book.toml .
|
||||
|
||||
- name: Build docs
|
||||
run: pnpm run docs:build
|
||||
run: mdbook build
|
||||
|
||||
- name: Upload artifact
|
||||
uses: actions/upload-pages-artifact@fc324d3547104276b827a68afc52ff2a11cc49c9 # v5
|
||||
uses: actions/upload-pages-artifact@v3
|
||||
with:
|
||||
path: ./docs/.vitepress/dist
|
||||
path: ./book
|
||||
|
||||
deploy:
|
||||
environment:
|
||||
name: github-pages
|
||||
url: ${{ steps.deployment.outputs.page_url }}
|
||||
runs-on: ubuntu-24.04
|
||||
permissions:
|
||||
pages: write
|
||||
id-token: write
|
||||
needs: build
|
||||
steps:
|
||||
- name: Deploy to GitHub Pages
|
||||
id: deployment
|
||||
uses: actions/deploy-pages@cd2ce8fcbc39b97be8ca5fce6e763baed58fa128 # v5
|
||||
uses: actions/deploy-pages@v4
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
# Triggers after the playwright tests have finished,
|
||||
# taking the artifact and uploading it to Netlify for easier viewing
|
||||
name: Upload End to End Test report to Netlify
|
||||
on:
|
||||
workflow_run:
|
||||
workflows: ["End to End Tests"]
|
||||
types:
|
||||
- completed
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.event.workflow_run.head_branch || github.run_id }}
|
||||
cancel-in-progress: ${{ github.event.workflow_run.event == 'pull_request' }}
|
||||
|
||||
jobs:
|
||||
report:
|
||||
if: github.event.workflow_run.conclusion != 'cancelled'
|
||||
name: Report results
|
||||
runs-on: ubuntu-22.04
|
||||
environment: Netlify
|
||||
permissions:
|
||||
statuses: write
|
||||
deployments: write
|
||||
steps:
|
||||
- name: Download HTML report
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
github-token: ${{ secrets.ELEMENT_BOT_TOKEN }}
|
||||
run-id: ${{ github.event.workflow_run.id }}
|
||||
name: html-report
|
||||
path: playwright-report
|
||||
|
||||
- name: 📤 Deploy to Netlify
|
||||
uses: matrix-org/netlify-pr-preview@v3
|
||||
with:
|
||||
path: playwright-report
|
||||
owner: ${{ github.event.workflow_run.head_repository.owner.login }}
|
||||
branch: ${{ github.event.workflow_run.head_branch }}
|
||||
revision: ${{ github.event.workflow_run.head_sha }}
|
||||
token: ${{ secrets.NETLIFY_AUTH_TOKEN }}
|
||||
site_id: ${{ vars.NETLIFY_SITE_ID }}
|
||||
desc: Playwright Report
|
||||
deployment_env: EndToEndTests
|
||||
prefix: "e2e-"
|
||||
@@ -0,0 +1,190 @@
|
||||
# Produce a build of element-web with this version of react-sdk
|
||||
# and any matching branches of element-web and js-sdk, output it
|
||||
# as an artifact and run end-to-end tests.
|
||||
name: End to End Tests
|
||||
on:
|
||||
pull_request: {}
|
||||
merge_group:
|
||||
types: [checks_requested]
|
||||
push:
|
||||
branches: [develop, master]
|
||||
repository_dispatch:
|
||||
types: [element-web-notify]
|
||||
|
||||
# support triggering from other workflows
|
||||
workflow_call:
|
||||
inputs:
|
||||
skip:
|
||||
type: boolean
|
||||
required: false
|
||||
default: false
|
||||
description: "A boolean to skip the playwright check itself while still creating the passing check. Useful when only running in Merge Queues."
|
||||
|
||||
matrix-js-sdk-sha:
|
||||
type: string
|
||||
required: false
|
||||
description: "The Git SHA of matrix-js-sdk to build against. By default, will use a matching branch name if it exists, or develop."
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}-${{ github.event_name }}
|
||||
cancel-in-progress: true
|
||||
|
||||
env:
|
||||
# fetchdep.sh needs to know our PR number
|
||||
PR_NUMBER: ${{ github.event.pull_request.number }}
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: "Build Element-Web"
|
||||
runs-on: ubuntu-22.04
|
||||
if: inputs.skip != true
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
repository: element-hq/element-web
|
||||
|
||||
- uses: actions/setup-node@v4
|
||||
with:
|
||||
cache: "yarn"
|
||||
node-version: "lts/*"
|
||||
|
||||
- name: Fetch layered build
|
||||
id: layered_build
|
||||
env:
|
||||
# tell layered.sh to check out the right sha of the JS-SDK & EW, if they were given one
|
||||
JS_SDK_GITHUB_BASE_REF: ${{ inputs.matrix-js-sdk-sha }}
|
||||
run: |
|
||||
scripts/layered.sh
|
||||
JSSDK_SHA=$(git -C matrix-js-sdk rev-parse --short=12 HEAD)
|
||||
VECTOR_SHA=$(git rev-parse --short=12 HEAD)
|
||||
echo "VERSION=$VECTOR_SHA--js-$JSSDK_SHA" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Copy config
|
||||
run: cp element.io/develop/config.json config.json
|
||||
|
||||
- name: Build
|
||||
env:
|
||||
CI_PACKAGE: true
|
||||
VERSION: "${{ steps.layered_build.outputs.VERSION }}"
|
||||
run: |
|
||||
yarn build
|
||||
echo $VERSION > webapp/version
|
||||
|
||||
- name: Upload Artifact
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: webapp
|
||||
path: webapp
|
||||
retention-days: 1
|
||||
|
||||
playwright:
|
||||
name: "Run Tests ${{ matrix.runner }}/${{ strategy.job-total }}"
|
||||
needs: build
|
||||
if: inputs.skip != true
|
||||
runs-on: ubuntu-22.04
|
||||
permissions:
|
||||
actions: read
|
||||
issues: read
|
||||
pull-requests: read
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
# Run multiple instances in parallel to speed up the tests
|
||||
runner: [1, 2, 3, 4, 5, 6]
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
persist-credentials: false
|
||||
repository: element-hq/element-web
|
||||
|
||||
- name: 📥 Download artifact
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: webapp
|
||||
path: webapp
|
||||
|
||||
- uses: actions/setup-node@v4
|
||||
with:
|
||||
cache: "yarn"
|
||||
cache-dependency-path: yarn.lock
|
||||
node-version: "lts/*"
|
||||
|
||||
- name: Install dependencies
|
||||
run: yarn install --frozen-lockfile
|
||||
|
||||
- name: Get installed Playwright version
|
||||
id: playwright
|
||||
run: echo "version=$(yarn list --pattern @playwright/test --depth=0 --json --non-interactive --no-progress | jq -r '.data.trees[].name')" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Cache playwright binaries
|
||||
uses: actions/cache@v4
|
||||
id: playwright-cache
|
||||
with:
|
||||
path: |
|
||||
~/.cache/ms-playwright
|
||||
key: ${{ runner.os }}-playwright-${{ steps.playwright.outputs.version }}
|
||||
|
||||
- name: Install Playwright browsers
|
||||
if: steps.playwright-cache.outputs.cache-hit != 'true'
|
||||
run: yarn playwright install --with-deps
|
||||
|
||||
- name: Run Playwright tests
|
||||
run: yarn playwright test --shard ${{ matrix.runner }}/${{ strategy.job-total }}
|
||||
|
||||
- name: Upload blob report to GitHub Actions Artifacts
|
||||
if: always()
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: all-blob-reports-${{ matrix.runner }}
|
||||
path: blob-report
|
||||
retention-days: 1
|
||||
|
||||
complete:
|
||||
name: end-to-end-tests
|
||||
needs: playwright
|
||||
if: always()
|
||||
runs-on: ubuntu-22.04
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
if: inputs.skip != true
|
||||
with:
|
||||
persist-credentials: false
|
||||
repository: element-hq/element-web
|
||||
|
||||
- uses: actions/setup-node@v4
|
||||
if: inputs.skip != true
|
||||
with:
|
||||
cache: "yarn"
|
||||
node-version: "lts/*"
|
||||
|
||||
- name: Install dependencies
|
||||
if: inputs.skip != true
|
||||
run: yarn install --frozen-lockfile
|
||||
|
||||
- name: Download blob reports from GitHub Actions Artifacts
|
||||
if: inputs.skip != true
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
pattern: all-blob-reports-*
|
||||
path: all-blob-reports
|
||||
merge-multiple: true
|
||||
|
||||
- name: Merge into HTML Report
|
||||
if: inputs.skip != true
|
||||
run: yarn playwright merge-reports --reporter=html,./playwright/flaky-reporter.ts,./playwright/stale-screenshot-reporter.ts ./all-blob-reports
|
||||
env:
|
||||
# Only pass creds to the flaky-reporter on main branch runs
|
||||
GITHUB_TOKEN: ${{ github.ref_name == 'develop' && secrets.ELEMENT_BOT_TOKEN || '' }}
|
||||
|
||||
# Upload the HTML report even if one of our reporters fails, this can happen when stale screenshots are detected
|
||||
- name: Upload HTML report
|
||||
if: always() && inputs.skip != true
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: html-report
|
||||
path: playwright-report
|
||||
retention-days: 14
|
||||
|
||||
- if: needs.playwright.result != 'skipped' && needs.playwright.result != 'success'
|
||||
run: exit 1
|
||||
@@ -4,13 +4,12 @@
|
||||
on:
|
||||
issues:
|
||||
types: [closed]
|
||||
permissions: {} # We use ELEMENT_BOT_TOKEN instead
|
||||
jobs:
|
||||
tidy:
|
||||
name: Tidy closed issues
|
||||
runs-on: ubuntu-24.04
|
||||
steps:
|
||||
- uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9
|
||||
- uses: actions/github-script@v7
|
||||
id: main
|
||||
with:
|
||||
# PAT needed as the GITHUB_TOKEN won't be able to see cross-references from other orgs (matrix-org)
|
||||
@@ -142,7 +141,7 @@ jobs:
|
||||
});
|
||||
}
|
||||
}
|
||||
- uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9
|
||||
- uses: actions/github-script@v7
|
||||
name: Close duplicate as Not Planned
|
||||
if: steps.main.outputs.closeAsNotPlanned
|
||||
with:
|
||||
|
||||
@@ -3,12 +3,8 @@ on:
|
||||
workflow_dispatch: {}
|
||||
schedule:
|
||||
- cron: "0 6 * * 1,3,5" # Every Monday, Wednesday and Friday at 6am UTC
|
||||
permissions:
|
||||
pull-requests: write # needed to auto-approve PRs
|
||||
jobs:
|
||||
download:
|
||||
uses: matrix-org/matrix-web-i18n/.github/workflows/localazy_download.yaml@6eda3835118f3bc3fb658a1a3c20b7da9d16ae42
|
||||
with:
|
||||
packageManager: pnpm
|
||||
uses: matrix-org/matrix-web-i18n/.github/workflows/localazy_download.yaml@main
|
||||
secrets:
|
||||
ELEMENT_BOT_TOKEN: ${{ secrets.ELEMENT_BOT_TOKEN }}
|
||||
|
||||
@@ -1,14 +1,11 @@
|
||||
name: Localazy Upload
|
||||
on:
|
||||
workflow_dispatch: {}
|
||||
push:
|
||||
branches: [develop]
|
||||
paths:
|
||||
- "apps/web/src/i18n/strings/en_EN.json"
|
||||
- "packages/shared-components/src/i18n/strings/en_EN.json"
|
||||
permissions: {} # No permissions needed
|
||||
- "src/i18n/strings/en_EN.json"
|
||||
jobs:
|
||||
upload:
|
||||
uses: matrix-org/matrix-web-i18n/.github/workflows/localazy_upload.yaml@6eda3835118f3bc3fb658a1a3c20b7da9d16ae42
|
||||
uses: matrix-org/matrix-web-i18n/.github/workflows/localazy_upload.yaml@main
|
||||
secrets:
|
||||
LOCALAZY_WRITE_KEY: ${{ secrets.LOCALAZY_WRITE_KEY }}
|
||||
|
||||
@@ -1,29 +0,0 @@
|
||||
# Tweaks the behaviour of Merge Queue to skip certain checks
|
||||
name: Merge Queue tweaks
|
||||
on:
|
||||
merge_group:
|
||||
types: [checks_requested]
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}-${{ github.event_name }}
|
||||
cancel-in-progress: true
|
||||
|
||||
permissions: {}
|
||||
|
||||
jobs:
|
||||
run:
|
||||
runs-on: ubuntu-24.04
|
||||
permissions:
|
||||
statuses: write
|
||||
steps:
|
||||
# This is only needed as license/cla at time of writing seems to be extraordinarily flaky
|
||||
# and Github doesn't support conditional checks between PR & merge queue.
|
||||
# This is fine to do as a PR won't make it to merge queue until it has license/cla passing.
|
||||
- name: Skip license/cla on merge queues
|
||||
uses: guibranco/github-status-action-v2@9bfa8773cdbdc6c185747fd43cd7faa9d7c32f09
|
||||
with:
|
||||
authToken: ${{ secrets.GITHUB_TOKEN }}
|
||||
state: success
|
||||
context: license/cla
|
||||
sha: ${{ github.sha }}
|
||||
target_url: https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}
|
||||
@@ -2,20 +2,15 @@
|
||||
# and uploading it to netlify
|
||||
name: Upload Preview Build to Netlify
|
||||
on:
|
||||
# Privilege escalation necessary to publish to Netlify
|
||||
# 🚨 We must not execute any checked out code here.
|
||||
workflow_run: # zizmor: ignore[dangerous-triggers]
|
||||
workflows: ["Build"]
|
||||
workflow_run:
|
||||
workflows: ["End to End Tests"]
|
||||
types:
|
||||
- completed
|
||||
jobs:
|
||||
deploy:
|
||||
if: github.event.workflow_run.conclusion != 'cancelled' && github.event.workflow_run.event == 'pull_request'
|
||||
runs-on: ubuntu-24.04
|
||||
runs-on: ubuntu-22.04
|
||||
environment: Netlify
|
||||
permissions:
|
||||
actions: read
|
||||
deployments: write
|
||||
steps:
|
||||
- name: 📝 Create Deployment
|
||||
uses: bobheadxi/deployments@648679e8e4915b27893bd7dbc35cb504dc915bc8 # v1
|
||||
@@ -30,15 +25,15 @@ jobs:
|
||||
Exercise caution. Use test accounts.
|
||||
|
||||
- name: 📥 Download artifact
|
||||
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
github-token: ${{ secrets.ELEMENT_BOT_TOKEN }}
|
||||
run-id: ${{ github.event.workflow_run.id }}
|
||||
name: webapp-ubuntu-24.04
|
||||
name: webapp
|
||||
path: webapp
|
||||
|
||||
- name: 📤 Deploy to Netlify
|
||||
uses: matrix-org/netlify-pr-preview@9805cd123fc9a7e421e35340a05e1ebc5dee46b5 # v3
|
||||
uses: matrix-org/netlify-pr-preview@v3
|
||||
with:
|
||||
path: webapp
|
||||
owner: ${{ github.event.workflow_run.head_repository.owner.login }}
|
||||
|
||||
@@ -1,43 +0,0 @@
|
||||
name: Publish npm package
|
||||
run-name: Publish ${{ inputs.package }}
|
||||
on:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
package:
|
||||
description: Which package to release
|
||||
required: true
|
||||
type: choice
|
||||
options:
|
||||
- playwright-common
|
||||
- shared-components
|
||||
- module-api
|
||||
|
||||
concurrency: release
|
||||
jobs:
|
||||
publish:
|
||||
name: "Publish"
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: write
|
||||
id-token: write
|
||||
|
||||
steps:
|
||||
- name: 🧮 Checkout code
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
- uses: pnpm/action-setup@0e279bb959325dab635dd2c09392533439d90093 # v6.0.8
|
||||
- name: 🔧 Set up node environment
|
||||
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6
|
||||
with:
|
||||
cache: "pnpm"
|
||||
node-version-file: ".node-version"
|
||||
registry-url: "https://registry.npmjs.org"
|
||||
|
||||
- name: 🛠️ Install dependencies
|
||||
run: pnpm install --frozen-lockfile
|
||||
|
||||
- name: 🚀 Publish to npm
|
||||
working-directory: packages/${{ inputs.package }}
|
||||
run: npm publish --access public --provenance
|
||||
@@ -0,0 +1,91 @@
|
||||
name: Pending reviews automation
|
||||
on:
|
||||
# The bot exceeded its API rate limit. Disabling for now (adding workflow dispatch so the workflow file stays valid & we can test to see if it starts working again)
|
||||
workflow_dispatch: {}
|
||||
# We run it on a schedule instead of on pull_request_* events to not create confusing messaging in the PR
|
||||
#schedule:
|
||||
# - cron: "*/10 * * * *"
|
||||
concurrency: ${{ github.workflow }}
|
||||
jobs:
|
||||
bot:
|
||||
name: Pending reviews bot
|
||||
runs-on: ubuntu-24.04
|
||||
environment: Matrix
|
||||
env:
|
||||
URL: "https://github.com/pulls?q=is%3Apr+is%3Aopen+repo%3Amatrix-org%2Fmatrix-js-sdk+repo%3Amatrix-org%2Fmatrix-react-sdk+repo%3Aelement-hq%2Felement-web+repo%3Aelement-hq%2Felement-desktop+review-requested%3A%40me+sort%3Aupdated-desc+"
|
||||
RELEASE_BLOCKERS_URL: "https://github.com/pulls?q=is%3Aopen+repo%3Amatrix-org%2Fmatrix-js-sdk+repo%3Amatrix-org%2Fmatrix-react-sdk+repo%3Aelement-hq%2Felement-web+repo%3Aelement-hq%2Felement-desktop+sort%3Aupdated-desc+label%3AX-Release-Blocker+"
|
||||
steps:
|
||||
- uses: actions/github-script@v7
|
||||
env:
|
||||
HS_URL: ${{ secrets.BETABOT_HS_URL }}
|
||||
ROOM_ID: ${{ secrets.ROOM_ID }}
|
||||
TOKEN: ${{ secrets.BETABOT_ACCESS_TOKEN }}
|
||||
with:
|
||||
# PAT needed as the GITHUB_TOKEN won't be able to see cross-references from other orgs (matrix-org)
|
||||
github-token: ${{ secrets.ELEMENT_BOT_TOKEN }}
|
||||
script: |
|
||||
const { HS_URL, ROOM_ID, TOKEN, URL, RELEASE_BLOCKERS_URL } = process.env;
|
||||
|
||||
async function updateCounter(counter, link, severity, title, value, clearOnZero) {
|
||||
const apiUrl = `${HS_URL}/_matrix/client/v3/rooms/${ROOM_ID}/state/re.jki.counter/${counter}`;
|
||||
const headers = {
|
||||
"Content-Type": "application/json",
|
||||
"Authorization": `Bearer ${TOKEN}`,
|
||||
};
|
||||
const res = await fetch(apiUrl, {
|
||||
method: "GET",
|
||||
headers,
|
||||
});
|
||||
|
||||
const data = await res.json();
|
||||
|
||||
if (data.value === issueCount) {
|
||||
console.log("Pending review count already correct");
|
||||
return;
|
||||
}
|
||||
|
||||
let body = {};
|
||||
if (issueCount || !clearOnZero) {
|
||||
body = JSON.stringify({
|
||||
link,
|
||||
severity,
|
||||
title,
|
||||
value,
|
||||
});
|
||||
}
|
||||
|
||||
await fetch(apiUrl, {
|
||||
method: "PUT",
|
||||
body,
|
||||
headers,
|
||||
});
|
||||
}
|
||||
|
||||
const repos = [
|
||||
"element-hq/element-desktop",
|
||||
"element-hq/element-web",
|
||||
"matrix-org/matrix-js-sdk",
|
||||
];
|
||||
const teams = [
|
||||
"matrix-org/element-web-team",
|
||||
"matrix-org/element-web-reviewers",
|
||||
"element-hq/element-web-team",
|
||||
"element-hq/element-web-reviewers",
|
||||
];
|
||||
|
||||
let issueCount = 0;
|
||||
for (const team of teams) {
|
||||
const org = team.split("/", 2)[0];
|
||||
const reposInOrg = repos.filter(repo => repo.startsWith(org + "/"));
|
||||
const { data } = await github.rest.search.issuesAndPullRequests({
|
||||
q: `is:pr is:open review:required ${reposInOrg.map(r => `repo:${r}`).join(" ")} team-review-requested:${team}`,
|
||||
});
|
||||
issueCount += data.total_count;
|
||||
}
|
||||
await updateCounter("gh_reviews", URL, "warning", "Pending reviews", issueCount);
|
||||
|
||||
const { data } = await github.rest.search.issuesAndPullRequests({
|
||||
q: `is:open ${repos.map(repo => `repo:${repo}`).join(" ")} label:X-Release-Blocker`,
|
||||
});
|
||||
const blockerCount = data.total_count;
|
||||
await updateCounter("release_blockers", RELEASE_BLOCKERS_URL, "alert", "Release Blockers", blockerCount, true);
|
||||
@@ -0,0 +1,45 @@
|
||||
name: Update Playwright docker images
|
||||
on:
|
||||
workflow_dispatch: {}
|
||||
schedule:
|
||||
- cron: "0 6 * * *" # Every day at 6am UTC
|
||||
jobs:
|
||||
update:
|
||||
runs-on: ubuntu-22.04
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Update synapse image
|
||||
run: |
|
||||
docker pull "$IMAGE"
|
||||
INSPECT=$(docker inspect --format='{{index .RepoDigests 0}}' "$IMAGE")
|
||||
DIGEST=${INSPECT#*@}
|
||||
sed -i "s/const DOCKER_TAG.*/const DOCKER_TAG = \"develop@$DIGEST\";/" playwright/plugins/homeserver/synapse/index.ts
|
||||
env:
|
||||
IMAGE: ghcr.io/element-hq/synapse:develop
|
||||
|
||||
- name: Create Pull Request
|
||||
id: cpr
|
||||
uses: peter-evans/create-pull-request@5e914681df9dc83aa4e4905692ca88beb2f9e91f # v7
|
||||
with:
|
||||
token: ${{ secrets.ELEMENT_BOT_TOKEN }}
|
||||
branch: actions/playwright-image-updates
|
||||
delete-branch: true
|
||||
title: Playwright Docker image updates
|
||||
labels: |
|
||||
T-Task
|
||||
|
||||
- name: Enable automerge
|
||||
run: gh pr merge --merge --auto "$PR_NUMBER"
|
||||
if: steps.cpr.outputs.pull-request-operation == 'created'
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.ELEMENT_BOT_TOKEN }}
|
||||
PR_NUMBER: ${{ steps.cpr.outputs.pull-request-number }}
|
||||
|
||||
- name: Enable autoapprove
|
||||
run: |
|
||||
gh pr review --approve "$PR_NUMBER"
|
||||
if: steps.cpr.outputs.pull-request-operation == 'created'
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
PR_NUMBER: ${{ steps.cpr.outputs.pull-request-number }}
|
||||
@@ -1,16 +1,11 @@
|
||||
name: Pull Request
|
||||
on:
|
||||
# Privilege escalation necessary access members of the review teams
|
||||
# 🚨 We must not execute any checked out code here, and be careful around use of user-controlled inputs.
|
||||
pull_request_target: # zizmor: ignore[dangerous-triggers]
|
||||
pull_request_target:
|
||||
types: [opened, edited, labeled, unlabeled, synchronize]
|
||||
merge_group:
|
||||
types: [checks_requested]
|
||||
permissions: {}
|
||||
jobs:
|
||||
action:
|
||||
uses: matrix-org/matrix-js-sdk/.github/workflows/pull_request.yaml@develop # zizmor: ignore[unpinned-uses]
|
||||
permissions:
|
||||
pull-requests: write
|
||||
uses: matrix-org/matrix-js-sdk/.github/workflows/pull_request.yaml@develop
|
||||
secrets:
|
||||
ELEMENT_BOT_TOKEN: ${{ secrets.ELEMENT_BOT_TOKEN }}
|
||||
|
||||
@@ -2,13 +2,12 @@ name: Pull Request Base Branch
|
||||
on:
|
||||
pull_request:
|
||||
types: [opened, edited, synchronize]
|
||||
permissions: {} # No permissions required
|
||||
jobs:
|
||||
check_base_branch:
|
||||
name: Check PR base branch
|
||||
runs-on: ubuntu-24.04
|
||||
runs-on: ubuntu-22.04
|
||||
steps:
|
||||
- uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9
|
||||
- uses: actions/github-script@v7
|
||||
with:
|
||||
script: |
|
||||
const baseBranch = context.payload.pull_request.base.ref;
|
||||
|
||||
@@ -4,9 +4,6 @@ on:
|
||||
branches: [staging]
|
||||
workflow_dispatch: {}
|
||||
concurrency: ${{ github.workflow }}
|
||||
permissions: {}
|
||||
jobs:
|
||||
draft:
|
||||
permissions:
|
||||
contents: write
|
||||
uses: matrix-org/matrix-js-sdk/.github/workflows/release-drafter-workflow.yml@develop # zizmor: ignore[unpinned-uses]
|
||||
uses: matrix-org/matrix-js-sdk/.github/workflows/release-drafter-workflow.yml@develop
|
||||
|
||||
@@ -4,14 +4,11 @@ on:
|
||||
push:
|
||||
branches: [master]
|
||||
concurrency: ${{ github.repository }}-${{ github.workflow }}
|
||||
permissions: {} # We use ELEMENT_BOT_TOKEN instead
|
||||
jobs:
|
||||
merge:
|
||||
uses: matrix-org/matrix-js-sdk/.github/workflows/release-gitflow.yml@develop # zizmor: ignore[unpinned-uses]
|
||||
uses: matrix-org/matrix-js-sdk/.github/workflows/release-gitflow.yml@develop
|
||||
secrets:
|
||||
ELEMENT_BOT_TOKEN: ${{ secrets.ELEMENT_BOT_TOKEN }}
|
||||
with:
|
||||
# This relates to the directory in which to reset dependencies, only web needs this
|
||||
dir: apps/web
|
||||
dependencies: |
|
||||
matrix-js-sdk
|
||||
|
||||
@@ -11,15 +11,9 @@ on:
|
||||
- rc
|
||||
- final
|
||||
concurrency: ${{ github.workflow }}
|
||||
permissions: {}
|
||||
jobs:
|
||||
release:
|
||||
uses: matrix-org/matrix-js-sdk/.github/workflows/release-make.yml@develop # zizmor: ignore[unpinned-uses]
|
||||
permissions:
|
||||
contents: write
|
||||
issues: write
|
||||
pull-requests: read
|
||||
id-token: write
|
||||
uses: matrix-org/matrix-js-sdk/.github/workflows/release-make.yml@develop
|
||||
secrets:
|
||||
ELEMENT_BOT_TOKEN: ${{ secrets.ELEMENT_BOT_TOKEN }}
|
||||
GPG_PRIVATE_KEY: ${{ secrets.GPG_PRIVATE_KEY }}
|
||||
@@ -29,24 +23,33 @@ jobs:
|
||||
gpg-fingerprint: ${{ vars.GPG_FINGERPRINT }}
|
||||
asset-path: dist/*.tar.gz
|
||||
expected-asset-count: 3
|
||||
# Desktop has no dist script so we only target web here
|
||||
dist-dir: apps/web
|
||||
version-dirs: apps/web apps/desktop
|
||||
|
||||
notify-downstream:
|
||||
name: Trigger release drafter downstream
|
||||
needs: release
|
||||
runs-on: ubuntu-24.04
|
||||
steps:
|
||||
- name: Notify element-desktop repo that element-web release has completed to re-trigger release-drafter
|
||||
uses: benc-uk/workflow-dispatch@e2e5e9a103e331dad343f381a29e654aea3cf8fc # v1
|
||||
with:
|
||||
workflow: release-drafter.yml
|
||||
repo: element-hq/element-desktop
|
||||
ref: staging
|
||||
# Required when using the `repo` option. Either a PAT or a token generated from the GitHub app or CLI
|
||||
token: "${{ secrets.ELEMENT_BOT_TOKEN }}"
|
||||
|
||||
check:
|
||||
name: Post release checks
|
||||
needs: release
|
||||
runs-on: ubuntu-24.04
|
||||
permissions:
|
||||
checks: read
|
||||
steps:
|
||||
- name: Wait for docker build
|
||||
- name: Wait for dockerhub
|
||||
uses: t3chguy/wait-on-check-action@18541021811b56544d90e0f073401c2b99e249d6 # fork
|
||||
with:
|
||||
ref: master
|
||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
wait-interval: 10
|
||||
check-name: "Docker Buildx"
|
||||
check-name: "Docker Buildx (vanilla)"
|
||||
allowed-conclusions: success
|
||||
|
||||
- name: Wait for debian package
|
||||
@@ -57,12 +60,3 @@ jobs:
|
||||
wait-interval: 10
|
||||
check-name: Build package
|
||||
allowed-conclusions: success
|
||||
|
||||
- name: Wait for desktop packaging
|
||||
uses: t3chguy/wait-on-check-action@18541021811b56544d90e0f073401c2b99e249d6 # fork
|
||||
with:
|
||||
ref: master
|
||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
wait-interval: 10
|
||||
check-regexp: Prepare|Linux|macOS|Windows|Deploy|deploy
|
||||
allowed-conclusions: success
|
||||
|
||||
@@ -2,6 +2,11 @@ name: Cut branches
|
||||
on:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
element-desktop:
|
||||
description: Prepare element-desktop
|
||||
required: true
|
||||
type: boolean
|
||||
default: true
|
||||
element-web:
|
||||
description: Prepare element-web
|
||||
required: true
|
||||
@@ -12,30 +17,22 @@ on:
|
||||
required: true
|
||||
type: boolean
|
||||
default: true
|
||||
permissions: {} # Uses ELEMENT_BOT_TOKEN instead
|
||||
jobs:
|
||||
checks:
|
||||
name: Sanity checks
|
||||
strategy:
|
||||
matrix:
|
||||
repo:
|
||||
- matrix-org/matrix-js-sdk
|
||||
- element-hq/element-web
|
||||
uses: matrix-org/matrix-js-sdk/.github/workflows/release-checks.yml@develop # zizmor: ignore[unpinned-uses]
|
||||
secrets:
|
||||
ELEMENT_BOT_TOKEN: ${{ secrets.ELEMENT_BOT_TOKEN }}
|
||||
with:
|
||||
repository: ${{ matrix.repo }}
|
||||
|
||||
prepare:
|
||||
runs-on: ubuntu-24.04
|
||||
needs: checks
|
||||
env:
|
||||
# The order is specified bottom-up to avoid any races for allchange
|
||||
REPOS: matrix-js-sdk element-web
|
||||
steps:
|
||||
- name: Checkout Element Desktop
|
||||
uses: actions/checkout@v4
|
||||
if: inputs.element-desktop
|
||||
with:
|
||||
repository: element-hq/element-desktop
|
||||
path: element-desktop
|
||||
ref: staging
|
||||
fetch-depth: 0
|
||||
fetch-tags: true
|
||||
token: ${{ secrets.ELEMENT_BOT_TOKEN }}
|
||||
- name: Checkout Element Web
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
|
||||
uses: actions/checkout@v4
|
||||
if: inputs.element-web
|
||||
with:
|
||||
repository: element-hq/element-web
|
||||
@@ -44,9 +41,8 @@ jobs:
|
||||
fetch-depth: 0
|
||||
fetch-tags: true
|
||||
token: ${{ secrets.ELEMENT_BOT_TOKEN }}
|
||||
persist-credentials: true
|
||||
- name: Checkout Matrix JS SDK
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
|
||||
uses: actions/checkout@v4
|
||||
if: inputs.matrix-js-sdk
|
||||
with:
|
||||
repository: matrix-org/matrix-js-sdk
|
||||
@@ -55,13 +51,16 @@ jobs:
|
||||
fetch-depth: 0
|
||||
fetch-tags: true
|
||||
token: ${{ secrets.ELEMENT_BOT_TOKEN }}
|
||||
persist-credentials: true
|
||||
|
||||
- name: Prepare Git
|
||||
run: |
|
||||
git config --global user.email "releases@riot.im"
|
||||
git config --global user.name "RiotRobot"
|
||||
|
||||
- name: Merge Element Desktop
|
||||
if: inputs.element-desktop
|
||||
run: |
|
||||
git -C "element-desktop" merge origin/develop
|
||||
- name: Merge Element Web
|
||||
if: inputs.element-web
|
||||
run: |
|
||||
@@ -82,7 +81,7 @@ jobs:
|
||||
repo: matrix-org/matrix-js-sdk
|
||||
repo-token: ${{ secrets.ELEMENT_BOT_TOKEN }}
|
||||
wait-interval: 10
|
||||
check-name: "draft / draft"
|
||||
check-name: draft
|
||||
allowed-conclusions: success
|
||||
|
||||
- name: Wait for element-web draft
|
||||
@@ -93,5 +92,16 @@ jobs:
|
||||
repo: element-hq/element-web
|
||||
repo-token: ${{ secrets.ELEMENT_BOT_TOKEN }}
|
||||
wait-interval: 10
|
||||
check-name: "draft / draft"
|
||||
check-name: draft
|
||||
allowed-conclusions: success
|
||||
|
||||
- name: Wait for element-desktop draft
|
||||
if: inputs.element-desktop
|
||||
uses: t3chguy/wait-on-check-action@18541021811b56544d90e0f073401c2b99e249d6 # fork
|
||||
with:
|
||||
ref: staging
|
||||
repo: element-hq/element-desktop
|
||||
repo-token: ${{ secrets.ELEMENT_BOT_TOKEN }}
|
||||
wait-interval: 10
|
||||
check-name: draft
|
||||
allowed-conclusions: success
|
||||
|
||||
@@ -1,38 +0,0 @@
|
||||
name: Build shared component storybook
|
||||
on:
|
||||
merge_group: {}
|
||||
pull_request: {}
|
||||
workflow_call: {}
|
||||
|
||||
permissions: {}
|
||||
|
||||
jobs:
|
||||
doc:
|
||||
name: Build storybook
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: 🧮 Checkout code
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
- uses: pnpm/action-setup@0e279bb959325dab635dd2c09392533439d90093 # v6.0.8
|
||||
- name: 🔧 Pnpm cache
|
||||
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6
|
||||
with:
|
||||
cache: "pnpm"
|
||||
node-version-file: package.json
|
||||
|
||||
- name: 🔨 Install dependencies
|
||||
working-directory: packages/shared-components
|
||||
run: "pnpm install --frozen-lockfile"
|
||||
|
||||
- name: 📖 Build Storybook
|
||||
working-directory: packages/shared-components
|
||||
run: pnpm build:storybook
|
||||
|
||||
- uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
|
||||
with:
|
||||
name: shared-components-storybook
|
||||
path: packages/shared-components/storybook-static
|
||||
retention-days: 1
|
||||
@@ -1,33 +0,0 @@
|
||||
name: Publish shared component storybook
|
||||
on:
|
||||
workflow_dispatch: {}
|
||||
push:
|
||||
branches:
|
||||
- "develop"
|
||||
paths:
|
||||
- "packages/shared-components/**/*"
|
||||
|
||||
permissions: {}
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: Build storybook
|
||||
uses: ./.github/workflows/shared-component-storybook-build.yml
|
||||
|
||||
publish:
|
||||
name: Publish storybook
|
||||
runs-on: ubuntu-latest
|
||||
needs: build
|
||||
environment: SharedComponents
|
||||
steps:
|
||||
- uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8
|
||||
with:
|
||||
name: shared-components-storybook
|
||||
path: storybook-static
|
||||
|
||||
- name: 🚀 Deploy to Cloudflare Pages
|
||||
uses: cloudflare/wrangler-action@ebbaa1584979971c8614a24965b4405ff95890e0 # v4
|
||||
with:
|
||||
apiToken: ${{ secrets.CF_PAGES_TOKEN }}
|
||||
accountId: ${{ secrets.CF_PAGES_ACCOUNT_ID }}
|
||||
command: pages deploy storybook-static --project-name=shared-components-storybook
|
||||
@@ -1,50 +0,0 @@
|
||||
# Triggers after the shared component tests have finished,
|
||||
# It uploads the received images and diffs to netlify, printing the URLs to the console
|
||||
name: Upload Shared Component Visual Test Diffs
|
||||
on:
|
||||
# Privilege escalation necessary to deploy to Netlify
|
||||
# 🚨 We must not execute any checked out code here.
|
||||
workflow_run: # zizmor: ignore[dangerous-triggers]
|
||||
workflows: ["Shared Component Visual Tests"]
|
||||
types:
|
||||
- completed
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.event.workflow_run.head_branch || github.run_id }}
|
||||
cancel-in-progress: ${{ github.event.workflow_run.event == 'pull_request' }}
|
||||
|
||||
permissions: {}
|
||||
|
||||
jobs:
|
||||
report:
|
||||
if: github.event.workflow_run.conclusion == 'failure'
|
||||
name: Upload Diffs
|
||||
runs-on: ubuntu-24.04
|
||||
environment: Netlify
|
||||
permissions:
|
||||
actions: read
|
||||
deployments: write
|
||||
steps:
|
||||
- name: Download Diffs
|
||||
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8
|
||||
with:
|
||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
run-id: ${{ github.event.workflow_run.id }}
|
||||
name: received-images
|
||||
path: received-images
|
||||
|
||||
- name: Generate Index
|
||||
run: "cd received-images && tree -L 1 --noreport -H '' -o index.html ."
|
||||
|
||||
- name: 📤 Deploy to Netlify
|
||||
uses: matrix-org/netlify-pr-preview@9805cd123fc9a7e421e35340a05e1ebc5dee46b5 # v3
|
||||
with:
|
||||
path: received-images
|
||||
owner: ${{ github.event.workflow_run.head_repository.owner.login }}
|
||||
branch: ${{ github.event.workflow_run.head_branch }}
|
||||
revision: ${{ github.event.workflow_run.head_sha }}
|
||||
token: ${{ secrets.NETLIFY_AUTH_TOKEN }}
|
||||
site_id: ${{ vars.NETLIFY_SITE_ID }}
|
||||
desc: Shared Component Visual Diffs
|
||||
deployment_env: SharedComponentDiffs
|
||||
prefix: "diffs-"
|
||||
@@ -1,60 +0,0 @@
|
||||
name: Shared Component Visual Tests
|
||||
on:
|
||||
pull_request: {}
|
||||
merge_group:
|
||||
types: [checks_requested]
|
||||
push:
|
||||
branches: [develop, master]
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}-${{ github.event_name }}
|
||||
cancel-in-progress: true
|
||||
|
||||
permissions: {} # No permissions required
|
||||
|
||||
jobs:
|
||||
testStorybook:
|
||||
name: "Run Visual Tests"
|
||||
runs-on: ubuntu-24.04
|
||||
permissions:
|
||||
actions: read
|
||||
issues: read
|
||||
pull-requests: read
|
||||
steps:
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
|
||||
with:
|
||||
persist-credentials: false
|
||||
repository: element-hq/element-web
|
||||
|
||||
- uses: pnpm/action-setup@0e279bb959325dab635dd2c09392533439d90093 # v6.0.8
|
||||
- uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6
|
||||
with:
|
||||
cache: "pnpm"
|
||||
node-version: "lts/*"
|
||||
|
||||
- name: Install dependencies
|
||||
working-directory: packages/shared-components
|
||||
run: pnpm install --frozen-lockfile
|
||||
|
||||
- name: Setup playwright
|
||||
uses: ./.github/actions/setup-playwright
|
||||
with:
|
||||
write-cache: ${{ github.event_name != 'merge_group' }}
|
||||
|
||||
- name: Run Visual tests
|
||||
working-directory: packages/shared-components
|
||||
run: "pnpm test:storybook --run"
|
||||
|
||||
- name: Detect stale screenshots
|
||||
run: |
|
||||
if diff -rq __baselines__ __results__ | grep "^Only in __baselines__"; then
|
||||
exit 1
|
||||
fi
|
||||
working-directory: packages/shared-components/__vis__/linux
|
||||
|
||||
- name: Upload received images & diffs
|
||||
if: always()
|
||||
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
|
||||
with:
|
||||
name: received-images
|
||||
path: packages/shared-components/__vis__/linux
|
||||
@@ -0,0 +1,19 @@
|
||||
name: SonarQube
|
||||
on:
|
||||
workflow_run:
|
||||
workflows: ["Tests"]
|
||||
types:
|
||||
- completed
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.event.workflow_run.head_branch }}
|
||||
cancel-in-progress: true
|
||||
jobs:
|
||||
sonarqube:
|
||||
name: 🩻 SonarQube
|
||||
if: github.event.workflow_run.conclusion == 'success' && github.event.workflow_run.event != 'merge_group'
|
||||
uses: matrix-org/matrix-js-sdk/.github/workflows/sonarcloud.yml@develop
|
||||
secrets:
|
||||
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
|
||||
ELEMENT_BOT_TOKEN: ${{ secrets.ELEMENT_BOT_TOKEN }}
|
||||
with:
|
||||
sharded: true
|
||||
@@ -5,129 +5,147 @@ on:
|
||||
branches: [develop, master]
|
||||
merge_group:
|
||||
types: [checks_requested]
|
||||
repository_dispatch:
|
||||
types: [element-web-notify]
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}-${{ github.event_name }}
|
||||
cancel-in-progress: true
|
||||
|
||||
env:
|
||||
# This must be set for fetchdep.sh to get the right branch
|
||||
# These must be set for fetchdep.sh to get the right branch
|
||||
REPOSITORY: ${{ github.repository }}
|
||||
PR_NUMBER: ${{ github.event.pull_request.number }}
|
||||
NX_DEFAULT_OUTPUT_STYLE: stream-without-prefixes
|
||||
|
||||
permissions: {} # No permissions required
|
||||
|
||||
jobs:
|
||||
lint:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- name: Typescript Syntax Check
|
||||
install: layered
|
||||
command: "lint:types"
|
||||
- name: Prettier
|
||||
install: normal
|
||||
command: "lint:prettier"
|
||||
- name: ESLint
|
||||
install: normal
|
||||
command: "lint:js"
|
||||
- name: Style Lint
|
||||
install: normal
|
||||
command: "lint:style"
|
||||
- name: Workflow Lint
|
||||
install: normal
|
||||
command: "lint:workflows"
|
||||
- name: Analyse Dead Code
|
||||
install: normal
|
||||
command: "lint:knip"
|
||||
- name: Rethemendex Check
|
||||
command: "rethemendex"
|
||||
assert-diff: true
|
||||
- name: Docs
|
||||
install: layered
|
||||
command: "docs:build"
|
||||
name: ${{ matrix.name }}
|
||||
ts_lint:
|
||||
name: "Typescript Syntax Check"
|
||||
runs-on: ubuntu-24.04
|
||||
steps:
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
|
||||
with:
|
||||
persist-credentials: false
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- uses: pnpm/action-setup@0e279bb959325dab635dd2c09392533439d90093 # v6.0.8
|
||||
- uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6
|
||||
if: matrix.install != ''
|
||||
- uses: actions/setup-node@v4
|
||||
with:
|
||||
cache: "pnpm"
|
||||
cache: "yarn"
|
||||
node-version: "lts/*"
|
||||
|
||||
- name: Install Dependencies (layered)
|
||||
if: matrix.install == 'layered'
|
||||
- name: Install Dependencies
|
||||
run: "./scripts/layered.sh"
|
||||
- name: Install Dependencies (normal)
|
||||
if: matrix.install == 'normal'
|
||||
run: "pnpm install --frozen-lockfile"
|
||||
|
||||
- name: Run ${{ matrix.command }}
|
||||
run: pnpm --if-present run "$CMD" && pnpm -r --if-present run "$CMD"
|
||||
env:
|
||||
CMD: ${{ matrix.command }}
|
||||
- name: Typecheck
|
||||
run: "yarn run lint:types"
|
||||
|
||||
- name: Assert no changes
|
||||
run: git diff --exit-code
|
||||
if: matrix.assert-diff
|
||||
- name: Switch js-sdk to release mode
|
||||
working-directory: node_modules/matrix-js-sdk
|
||||
run: |
|
||||
scripts/switch_package_to_release.cjs
|
||||
yarn install
|
||||
yarn run build:compile
|
||||
yarn run build:types
|
||||
|
||||
zizmor:
|
||||
name: Zizmor Github Actions lint
|
||||
runs-on: ubuntu-24.04
|
||||
permissions:
|
||||
security-events: write
|
||||
steps:
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
|
||||
with:
|
||||
persist-credentials: false
|
||||
- name: Typecheck (release mode)
|
||||
run: "yarn run lint:types"
|
||||
|
||||
- name: Run zizmor
|
||||
uses: zizmorcore/zizmor-action@5f14fd08f7cf1cb1609c1e344975f152c7ee938d # v0.5.6
|
||||
# Temporary while we directly import matrix-js-sdk/src/* which means we need
|
||||
# certain @types/* packages to make sense of matrix-js-sdk types.
|
||||
#- name: Typecheck (release mode; no yarn link)
|
||||
# if: github.event_name != 'pull_request' && github.ref_name != 'master'
|
||||
# run: |
|
||||
# yarn unlink matrix-js-sdk
|
||||
# yarn add github:matrix-org/matrix-js-sdk#develop
|
||||
# yarn install --force
|
||||
# yarn run lint:types
|
||||
|
||||
i18n:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- name: Element Web
|
||||
path: "apps/web"
|
||||
allowed-hardcoded-keys: |
|
||||
console_dev_note
|
||||
labs|element_call_video_rooms
|
||||
labs|feature_disable_call_per_sender_encryption
|
||||
voip|element_call
|
||||
error|invalid_json
|
||||
error|misconfigured
|
||||
welcome|title_element
|
||||
devtools|settings|elementCallUrl
|
||||
labs|sliding_sync_description
|
||||
settings|voip|noise_suppression_description
|
||||
settings|voip|echo_cancellation_description
|
||||
- name: Element Desktop
|
||||
path: "apps/desktop"
|
||||
- name: Shared Components
|
||||
path: "packages/shared-components"
|
||||
name: "i18n Check (${{ matrix.name }})"
|
||||
uses: matrix-org/matrix-web-i18n/.github/workflows/i18n_check.yml@6eda3835118f3bc3fb658a1a3c20b7da9d16ae42
|
||||
permissions:
|
||||
pull-requests: read
|
||||
i18n_lint:
|
||||
name: "i18n Check"
|
||||
uses: matrix-org/matrix-web-i18n/.github/workflows/i18n_check.yml@main
|
||||
with:
|
||||
hardcoded-words: "Element"
|
||||
packageManager: pnpm
|
||||
path: ${{ matrix.path }}
|
||||
allowed-hardcoded-keys: ${{ matrix.allowed-hardcoded-keys }}
|
||||
allowed-hardcoded-keys: |
|
||||
console_dev_note
|
||||
labs|element_call_video_rooms
|
||||
labs|feature_disable_call_per_sender_encryption
|
||||
voip|element_call
|
||||
error|invalid_json
|
||||
error|misconfigured
|
||||
welcome_to_element
|
||||
|
||||
# Dummy job to simplify branch protections
|
||||
ci:
|
||||
name: Static Analysis
|
||||
needs: [lint, i18n, zizmor]
|
||||
if: always()
|
||||
rethemendex_lint:
|
||||
name: "Rethemendex Check"
|
||||
runs-on: ubuntu-22.04
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- run: ./res/css/rethemendex.sh
|
||||
|
||||
- run: git diff --exit-code
|
||||
|
||||
js_lint:
|
||||
name: "ESLint"
|
||||
runs-on: ubuntu-24.04
|
||||
steps:
|
||||
- if: contains(needs.*.result, 'failure') || contains(needs.*.result, 'cancelled')
|
||||
run: exit 1
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- uses: actions/setup-node@v4
|
||||
with:
|
||||
cache: "yarn"
|
||||
node-version: "lts/*"
|
||||
|
||||
# Does not need branch matching as only analyses this layer
|
||||
- name: Install Deps
|
||||
run: "yarn install --frozen-lockfile"
|
||||
|
||||
- name: Run Linter
|
||||
run: "yarn run lint:js"
|
||||
|
||||
style_lint:
|
||||
name: "Style Lint"
|
||||
runs-on: ubuntu-24.04
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- uses: actions/setup-node@v4
|
||||
with:
|
||||
cache: "yarn"
|
||||
node-version: "lts/*"
|
||||
|
||||
# Does not need branch matching as only analyses this layer
|
||||
- name: Install Deps
|
||||
run: "yarn install"
|
||||
|
||||
- name: Run Linter
|
||||
run: "yarn run lint:style"
|
||||
|
||||
workflow_lint:
|
||||
name: "Workflow Lint"
|
||||
runs-on: ubuntu-24.04
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- uses: actions/setup-node@v4
|
||||
with:
|
||||
cache: "yarn"
|
||||
node-version: "lts/*"
|
||||
|
||||
# Does not need branch matching as only analyses this layer
|
||||
- name: Install Deps
|
||||
run: "yarn install --frozen-lockfile"
|
||||
|
||||
- name: Run Linter
|
||||
run: "yarn lint:workflows"
|
||||
|
||||
analyse_dead_code:
|
||||
name: "Analyse Dead Code"
|
||||
runs-on: ubuntu-24.04
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- uses: actions/setup-node@v4
|
||||
with:
|
||||
cache: "yarn"
|
||||
node-version: "lts/*"
|
||||
|
||||
- name: Install Deps
|
||||
run: "scripts/layered.sh"
|
||||
|
||||
- name: Dead Code Analysis
|
||||
run: "yarn run analyse:unused-exports"
|
||||
|
||||
@@ -8,12 +8,9 @@ on:
|
||||
- develop
|
||||
paths:
|
||||
- .github/labels.yml
|
||||
|
||||
permissions: {} # We use ELEMENT_BOT_TOKEN instead
|
||||
|
||||
jobs:
|
||||
sync-labels:
|
||||
uses: element-hq/element-meta/.github/workflows/sync-labels.yml@7f2f93fb9b52ece7a0998f60e64862aa203c1746
|
||||
uses: element-hq/element-meta/.github/workflows/sync-labels.yml@develop
|
||||
with:
|
||||
LABELS: |
|
||||
element-hq/element-meta
|
||||
|
||||
+30
-147
@@ -5,6 +5,8 @@ on:
|
||||
types: [checks_requested]
|
||||
push:
|
||||
branches: [develop, master]
|
||||
repository_dispatch:
|
||||
types: [element-web-notify]
|
||||
workflow_call:
|
||||
inputs:
|
||||
disable_coverage:
|
||||
@@ -23,37 +25,27 @@ env:
|
||||
ENABLE_COVERAGE: ${{ github.event_name != 'merge_group' && inputs.disable_coverage != 'true' }}
|
||||
# fetchdep.sh needs to know our PR number
|
||||
PR_NUMBER: ${{ github.event.pull_request.number }}
|
||||
NX_DEFAULT_OUTPUT_STYLE: stream-without-prefixes
|
||||
|
||||
permissions: {}
|
||||
|
||||
jobs:
|
||||
jest_ew:
|
||||
name: Jest (Element Web)
|
||||
runs-on: ubuntu-24.04
|
||||
jest:
|
||||
name: Jest
|
||||
runs-on: ubuntu-22.04
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
# Run multiple instances in parallel to speed up the tests
|
||||
runner: [1, 2]
|
||||
steps:
|
||||
# Dump the disk usage before we start: this job frequently flakes with "No space left on device"
|
||||
# so, with the one at the end too, this will let us work out how much disk has been used.
|
||||
- name: dfbefore
|
||||
run: df -h && df -i
|
||||
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
repository: ${{ inputs.matrix-js-sdk-sha && 'element-hq/element-web' || github.repository }}
|
||||
persist-credentials: false
|
||||
|
||||
- uses: pnpm/action-setup@0e279bb959325dab635dd2c09392533439d90093 # v6.0.8
|
||||
- name: pnpm cache
|
||||
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6
|
||||
- name: Yarn cache
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: "lts/*"
|
||||
cache: "pnpm"
|
||||
cache: "yarn"
|
||||
|
||||
- name: Install Deps
|
||||
run: "./scripts/layered.sh"
|
||||
@@ -61,129 +53,54 @@ jobs:
|
||||
JS_SDK_GITHUB_BASE_REF: ${{ inputs.matrix-js-sdk-sha }}
|
||||
|
||||
- name: Jest Cache
|
||||
uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: /tmp/jest_cache
|
||||
key: ${{ hashFiles('**/pnpm-lock.yaml') }}
|
||||
key: ${{ hashFiles('**/yarn.lock') }}
|
||||
|
||||
- name: Get number of CPU cores
|
||||
id: cpu-cores
|
||||
uses: SimenB/github-actions-cpu-cores@97330871fe1b7d3529392ea000e3d2c4b357e403 # v3
|
||||
uses: SimenB/github-actions-cpu-cores@97ba232459a8e02ff6121db9362b09661c875ab8 # v2
|
||||
|
||||
- name: Run tests
|
||||
working-directory: apps/web
|
||||
run: |
|
||||
pnpm test \
|
||||
--coverage=$ENABLE_COVERAGE \
|
||||
yarn test \
|
||||
--coverage=${{ env.ENABLE_COVERAGE }} \
|
||||
--ci \
|
||||
--max-workers $MAX_WORKERS \
|
||||
--shard "$SHARD" \
|
||||
--max-workers ${{ steps.cpu-cores.outputs.count }} \
|
||||
--shard ${{ matrix.runner }}/${{ strategy.job-total }} \
|
||||
--cacheDirectory /tmp/jest_cache
|
||||
env:
|
||||
JEST_SONAR_UNIQUE_OUTPUT_NAME: true
|
||||
|
||||
# tell jest to use coloured output
|
||||
FORCE_COLOR: true
|
||||
MAX_WORKERS: ${{ steps.cpu-cores.outputs.count }}
|
||||
SHARD: ${{ format('{0}/{1}', matrix.runner, strategy.job-total) }}
|
||||
|
||||
- name: Move coverage files into place
|
||||
if: env.ENABLE_COVERAGE == 'true'
|
||||
working-directory: apps/web
|
||||
run: mv coverage/lcov.info coverage/$NODE_VERSION-${{ matrix.runner }}.lcov.info
|
||||
env:
|
||||
NODE_VERSION: ${{ steps.setupNode.outputs.node-version }}
|
||||
run: mv coverage/lcov.info coverage/${{ steps.setupNode.outputs.node-version }}-${{ matrix.runner }}.lcov.info
|
||||
|
||||
- name: Upload Artifact
|
||||
if: env.ENABLE_COVERAGE == 'true'
|
||||
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: coverage-jest-${{ matrix.runner }}
|
||||
name: coverage-${{ matrix.runner }}
|
||||
path: |
|
||||
apps/web/coverage
|
||||
!apps/web/coverage/lcov-report
|
||||
|
||||
vitest:
|
||||
name: Vitest
|
||||
strategy:
|
||||
matrix:
|
||||
path:
|
||||
- apps/desktop
|
||||
- packages/shared-components
|
||||
- packages/module-api
|
||||
runs-on: ubuntu-24.04
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
|
||||
with:
|
||||
repository: ${{ inputs.matrix-js-sdk-sha && 'element-hq/element-web' || github.repository }}
|
||||
persist-credentials: false
|
||||
|
||||
- uses: pnpm/action-setup@0e279bb959325dab635dd2c09392533439d90093 # v6.0.8
|
||||
- name: pnpm cache
|
||||
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6
|
||||
with:
|
||||
node-version: "lts/*"
|
||||
cache: "pnpm"
|
||||
|
||||
- name: Install Deps
|
||||
run: "pnpm install"
|
||||
|
||||
- name: Cache storybook & vitest
|
||||
uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5
|
||||
with:
|
||||
path: |
|
||||
${{ matrix.path }}/node_modules/.cache
|
||||
${{ matrix.path }}/node_modules/.vite/vitest
|
||||
key: ${{ matrix.path }}-${{ hashFiles('pnpm-lock.yaml') }}
|
||||
|
||||
- name: Setup playwright
|
||||
uses: ./.github/actions/setup-playwright
|
||||
if: matrix.path == 'packages/shared-components'
|
||||
with:
|
||||
write-cache: ${{ github.event_name != 'merge_group' }}
|
||||
|
||||
- name: Run tests
|
||||
working-directory: ${{ matrix.path }}
|
||||
run: pnpm test:unit --coverage=$ENABLE_COVERAGE
|
||||
|
||||
# Dump the disk usage on failure, because this job seems to fail with disk fills sometimes
|
||||
- name: df
|
||||
run: df -h && df -i
|
||||
if: ${{ failure() }}
|
||||
|
||||
- name: Calculate artifact name
|
||||
if: env.ENABLE_COVERAGE == 'true'
|
||||
id: artifact
|
||||
run: |
|
||||
NAME=$(basename "$MATRIX_PATH")
|
||||
echo "name=$NAME" >> $GITHUB_OUTPUT
|
||||
env:
|
||||
MATRIX_PATH: ${{ matrix.path }}
|
||||
|
||||
- name: Upload Artifact
|
||||
if: env.ENABLE_COVERAGE == 'true'
|
||||
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
|
||||
with:
|
||||
name: coverage-${{ steps.artifact.outputs.name }}
|
||||
path: |
|
||||
${{ matrix.path }}/coverage
|
||||
!${{ matrix.path }}/coverage/lcov-report
|
||||
coverage
|
||||
!coverage/lcov-report
|
||||
|
||||
complete:
|
||||
name: Tests
|
||||
needs:
|
||||
- jest_ew
|
||||
- vitest
|
||||
name: jest-tests
|
||||
needs: jest
|
||||
if: always()
|
||||
runs-on: ubuntu-24.04
|
||||
permissions:
|
||||
contents: read
|
||||
pull-requests: read
|
||||
checks: write
|
||||
statuses: write
|
||||
runs-on: ubuntu-22.04
|
||||
steps:
|
||||
- if: needs.jest.result != 'skipped' && needs.jest.result != 'success'
|
||||
run: exit 1
|
||||
|
||||
- name: Skip SonarCloud in merge queue
|
||||
if: github.event_name == 'merge_group' || inputs.disable_coverage == 'true'
|
||||
uses: guibranco/github-status-action-v2@9bfa8773cdbdc6c185747fd43cd7faa9d7c32f09
|
||||
uses: Sibz/github-status-action@faaa4d96fecf273bd762985e0e7f9f933c774918 # v1
|
||||
with:
|
||||
authToken: ${{ secrets.GITHUB_TOKEN }}
|
||||
state: success
|
||||
@@ -191,37 +108,3 @@ jobs:
|
||||
context: SonarCloud Code Analysis
|
||||
sha: ${{ github.sha }}
|
||||
target_url: https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}
|
||||
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
|
||||
if: needs.test.result == 'success' && env.ENABLE_COVERAGE == 'true'
|
||||
with:
|
||||
persist-credentials: false
|
||||
fetch-depth: 0 # Full history, fastest for diff-cover
|
||||
|
||||
- name: Download coverage artifacts
|
||||
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8
|
||||
if: needs.test.result == 'success' && env.ENABLE_COVERAGE == 'true'
|
||||
with:
|
||||
pattern: coverage-*
|
||||
path: coverage
|
||||
|
||||
- name: Diff Coverage
|
||||
id: coverage
|
||||
if: needs.test.result == 'success' && env.ENABLE_COVERAGE == 'true'
|
||||
uses: Affanmir/diff-cover-action@0d8c98f613bbd2428df50b3109b1e3b1d5ab59d3 # v2.1.0
|
||||
with:
|
||||
compare-branch: origin/${{ github.base_ref || 'develop' }}
|
||||
mode: coverage
|
||||
coverage-files: coverage/*/*lcov.info
|
||||
ignore-whitespace: true
|
||||
show-uncovered: true
|
||||
post-comment: false
|
||||
create-annotations: true
|
||||
annotation-type: warning
|
||||
fail-on-threshold: ${{ contains(github.event.pull_request.labels.*.name, 'Z-Skip-Coverage') && 'false' || 'true' }}
|
||||
fail-under: 80
|
||||
|
||||
- name: Check status of tests
|
||||
if: contains(needs.*.result, 'failure') || contains(needs.*.result, 'cancelled')
|
||||
run: exit 1
|
||||
|
||||
@@ -4,18 +4,15 @@ on:
|
||||
issues:
|
||||
types: [assigned]
|
||||
|
||||
permissions: {} # We use ELEMENT_BOT_TOKEN instead
|
||||
|
||||
jobs:
|
||||
web-app-team:
|
||||
runs-on: ubuntu-24.04
|
||||
if: |
|
||||
contains(github.event.issue.assignees.*.login, 't3chguy') ||
|
||||
contains(github.event.issue.assignees.*.login, 'florianduros') ||
|
||||
contains(github.event.issue.assignees.*.login, 'dbkr') ||
|
||||
contains(github.event.issue.assignees.*.login, 'andybalaam') ||
|
||||
contains(github.event.issue.assignees.*.login, 'MidhunSureshR')
|
||||
steps:
|
||||
- uses: actions/add-to-project@5afcf98fcd03f1c2f92c3c83f58ae24323cc57fd # v2.0.0
|
||||
- uses: actions/add-to-project@main
|
||||
with:
|
||||
project-url: https://github.com/orgs/element-hq/projects/67
|
||||
github-token: ${{ secrets.ELEMENT_BOT_TOKEN }}
|
||||
|
||||
@@ -4,13 +4,11 @@ on:
|
||||
issues:
|
||||
types: [opened]
|
||||
|
||||
permissions: {} # We use ELEMENT_BOT_TOKEN instead
|
||||
|
||||
jobs:
|
||||
automate-project-columns:
|
||||
runs-on: ubuntu-24.04
|
||||
steps:
|
||||
- uses: actions/add-to-project@5afcf98fcd03f1c2f92c3c83f58ae24323cc57fd # v2.0.0
|
||||
- uses: actions/add-to-project@main
|
||||
with:
|
||||
project-url: https://github.com/orgs/element-hq/projects/120
|
||||
github-token: ${{ secrets.ELEMENT_BOT_TOKEN }}
|
||||
|
||||
@@ -8,8 +8,6 @@ on:
|
||||
ELEMENT_BOT_TOKEN:
|
||||
required: true
|
||||
|
||||
permissions: {} # We use ELEMENT_BOT_TOKEN instead
|
||||
|
||||
jobs:
|
||||
apply_Z-Labs_label:
|
||||
name: Add Z-Labs label for features behind labs flags
|
||||
@@ -27,7 +25,7 @@ jobs:
|
||||
contains(github.event.issue.labels.*.name, 'A-Rich-Text-Editor') ||
|
||||
contains(github.event.issue.labels.*.name, 'A-Element-Call')
|
||||
steps:
|
||||
- uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9
|
||||
- uses: actions/github-script@v7
|
||||
with:
|
||||
script: |
|
||||
github.rest.issues.addLabels({
|
||||
@@ -44,7 +42,7 @@ jobs:
|
||||
contains(github.event.issue.labels.*.name, 'good first issue') ||
|
||||
contains(github.event.issue.labels.*.name, 'Hacktoberfest')
|
||||
steps:
|
||||
- uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9
|
||||
- uses: actions/github-script@v7
|
||||
with:
|
||||
script: |
|
||||
github.rest.issues.addLabels({
|
||||
@@ -61,7 +59,7 @@ jobs:
|
||||
contains(github.event.issue.labels.*.name, 'X-Needs-Info')
|
||||
steps:
|
||||
- id: add_to_project
|
||||
uses: actions/add-to-project@5afcf98fcd03f1c2f92c3c83f58ae24323cc57fd # v2.0.0
|
||||
uses: actions/add-to-project@v1.0.2
|
||||
with:
|
||||
project-url: ${{ env.PROJECT_URL }}
|
||||
github-token: ${{ secrets.ELEMENT_BOT_TOKEN }}
|
||||
@@ -84,7 +82,7 @@ jobs:
|
||||
contains(github.event.issue.labels.*.name, 'Z-Flaky-Test')
|
||||
steps:
|
||||
- id: add_to_project
|
||||
uses: actions/add-to-project@5afcf98fcd03f1c2f92c3c83f58ae24323cc57fd # v2.0.0
|
||||
uses: actions/add-to-project@v1.0.2
|
||||
with:
|
||||
project-url: ${{ env.PROJECT_URL }}
|
||||
github-token: ${{ secrets.ELEMENT_BOT_TOKEN }}
|
||||
@@ -112,7 +110,7 @@ jobs:
|
||||
contains(github.event.issue.labels.*.name, 'O-Frequent') ||
|
||||
contains(github.event.issue.labels.*.name, 'A11y'))
|
||||
steps:
|
||||
- uses: actions/add-to-project@5afcf98fcd03f1c2f92c3c83f58ae24323cc57fd # v2.0.0
|
||||
- uses: actions/add-to-project@main
|
||||
with:
|
||||
project-url: https://github.com/orgs/element-hq/projects/18
|
||||
github-token: ${{ secrets.ELEMENT_BOT_TOKEN }}
|
||||
@@ -123,7 +121,7 @@ jobs:
|
||||
if: >
|
||||
contains(github.event.issue.labels.*.name, 'X-Needs-Product')
|
||||
steps:
|
||||
- uses: actions/add-to-project@5afcf98fcd03f1c2f92c3c83f58ae24323cc57fd # v2.0.0
|
||||
- uses: actions/add-to-project@main
|
||||
with:
|
||||
project-url: https://github.com/orgs/element-hq/projects/28
|
||||
github-token: ${{ secrets.ELEMENT_BOT_TOKEN }}
|
||||
@@ -134,7 +132,7 @@ jobs:
|
||||
if: >
|
||||
contains(github.event.issue.labels.*.name, 'A-New-Search-Experience')
|
||||
steps:
|
||||
- uses: actions/add-to-project@5afcf98fcd03f1c2f92c3c83f58ae24323cc57fd # v2.0.0
|
||||
- uses: actions/add-to-project@main
|
||||
with:
|
||||
project-url: https://github.com/orgs/element-hq/projects/48
|
||||
github-token: ${{ secrets.ELEMENT_BOT_TOKEN }}
|
||||
@@ -145,20 +143,20 @@ jobs:
|
||||
if: >
|
||||
contains(github.event.issue.labels.*.name, 'Team: VoIP')
|
||||
steps:
|
||||
- uses: actions/add-to-project@5afcf98fcd03f1c2f92c3c83f58ae24323cc57fd # v2.0.0
|
||||
- uses: actions/add-to-project@main
|
||||
with:
|
||||
project-url: https://github.com/orgs/element-hq/projects/41
|
||||
github-token: ${{ secrets.ELEMENT_BOT_TOKEN }}
|
||||
|
||||
crypto:
|
||||
name: Add labelled issues to Crypto project
|
||||
verticals_feature:
|
||||
name: Add labelled issues to Verticals Feature project
|
||||
runs-on: ubuntu-24.04
|
||||
if: >
|
||||
contains(github.event.issue.labels.*.name, 'Team: Crypto')
|
||||
contains(github.event.issue.labels.*.name, 'Team: Verticals Feature')
|
||||
steps:
|
||||
- uses: actions/add-to-project@5afcf98fcd03f1c2f92c3c83f58ae24323cc57fd # v2.0.0
|
||||
- uses: actions/add-to-project@main
|
||||
with:
|
||||
project-url: https://github.com/orgs/element-hq/projects/76
|
||||
project-url: https://github.com/orgs/element-hq/projects/57
|
||||
github-token: ${{ secrets.ELEMENT_BOT_TOKEN }}
|
||||
|
||||
tech_debt:
|
||||
@@ -172,7 +170,7 @@ jobs:
|
||||
contains(github.event.issue.labels.*.name, 'A-Testing') ||
|
||||
contains(github.event.issue.labels.*.name, 'Z-Flaky-Test')
|
||||
steps:
|
||||
- uses: actions/add-to-project@5afcf98fcd03f1c2f92c3c83f58ae24323cc57fd # v2.0.0
|
||||
- uses: actions/add-to-project@main
|
||||
with:
|
||||
project-url: https://github.com/orgs/element-hq/projects/101
|
||||
github-token: ${{ secrets.ELEMENT_BOT_TOKEN }}
|
||||
|
||||
@@ -3,13 +3,12 @@ on:
|
||||
pull_request_target:
|
||||
types: [review_requested]
|
||||
|
||||
permissions: {} # Uses ELEMENT_BOT_TOKEN instead
|
||||
jobs:
|
||||
add_design_pr_to_project:
|
||||
name: Move PRs asking for design review to the design board
|
||||
runs-on: ubuntu-24.04
|
||||
steps:
|
||||
- uses: octokit/graphql-action@ddde8ebb2493e79f390e6449c725c21663a67505 # v3.0.2
|
||||
- uses: octokit/graphql-action@v2.x
|
||||
id: find_team_members
|
||||
with:
|
||||
headers: '{"GraphQL-Features": "projects_next_graphql"}'
|
||||
@@ -52,7 +51,7 @@ jobs:
|
||||
fi
|
||||
env:
|
||||
TEAM: "design"
|
||||
- uses: octokit/graphql-action@ddde8ebb2493e79f390e6449c725c21663a67505 # v3.0.2
|
||||
- uses: octokit/graphql-action@v2.x
|
||||
id: add_to_project
|
||||
if: steps.any_matching_reviewers.outputs.match == 'true'
|
||||
with:
|
||||
@@ -76,7 +75,7 @@ jobs:
|
||||
name: Move PRs asking for design review to the design board
|
||||
runs-on: ubuntu-24.04
|
||||
steps:
|
||||
- uses: octokit/graphql-action@ddde8ebb2493e79f390e6449c725c21663a67505 # v3.0.2
|
||||
- uses: octokit/graphql-action@v2.x
|
||||
id: find_team_members
|
||||
with:
|
||||
headers: '{"GraphQL-Features": "projects_next_graphql"}'
|
||||
@@ -119,7 +118,7 @@ jobs:
|
||||
fi
|
||||
env:
|
||||
TEAM: "product"
|
||||
- uses: octokit/graphql-action@ddde8ebb2493e79f390e6449c725c21663a67505 # v3.0.2
|
||||
- uses: octokit/graphql-action@v2.x
|
||||
id: add_to_project
|
||||
if: steps.any_matching_reviewers.outputs.match == 'true'
|
||||
with:
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
name: Close stale flaky issues
|
||||
on:
|
||||
schedule:
|
||||
- cron: "30 1 * * *"
|
||||
jobs:
|
||||
close:
|
||||
runs-on: ubuntu-24.04
|
||||
permissions:
|
||||
actions: write
|
||||
issues: write
|
||||
steps:
|
||||
- uses: actions/stale@v9
|
||||
with:
|
||||
only-labels: "Z-Flaky-Test"
|
||||
days-before-stale: 14
|
||||
days-before-close: 0
|
||||
close-issue-message: "This flaky test issue has not been updated in 14 days. It is being closed as presumed resolved."
|
||||
exempt-issue-labels: "Z-Flaky-Test-Disabled"
|
||||
@@ -1,29 +0,0 @@
|
||||
name: Close stale issues & PRs
|
||||
on:
|
||||
workflow_dispatch: {}
|
||||
schedule:
|
||||
- cron: "30 1 * * *"
|
||||
permissions: {}
|
||||
jobs:
|
||||
close:
|
||||
runs-on: ubuntu-24.04
|
||||
permissions:
|
||||
actions: write
|
||||
issues: write
|
||||
pull-requests: write
|
||||
steps:
|
||||
- uses: actions/stale@eb5cf3af3ac0a1aa4c9c45633dd1ae542a27a899 # v10
|
||||
with:
|
||||
operations-per-run: 100
|
||||
|
||||
# Flaky test issue closing
|
||||
any-of-issue-labels: "Z-Flaky-Test-Chrome,Z-Flaky-Test-Firefox,Z-Flaky-Test-Webkit"
|
||||
days-before-issue-stale: 14
|
||||
days-before-issue-close: 0
|
||||
close-issue-message: "This flaky test issue has not been updated in 14 days. It is being closed as presumed resolved."
|
||||
exempt-issue-labels: "Z-Flaky-Test-Disabled"
|
||||
|
||||
# Stale PR closing
|
||||
days-before-pr-stale: 180
|
||||
days-before-pr-close: 0
|
||||
close-pr-message: "This PR has been automatically closed because it has been stale for 180 days. If you wish to continue working on this PR, please ping a maintainer to reopen it."
|
||||
@@ -3,27 +3,44 @@ name: Move unlabelled from needs info columns to triaged
|
||||
on:
|
||||
issues:
|
||||
types: [unlabeled]
|
||||
permissions: {}
|
||||
|
||||
jobs:
|
||||
move_no_longer_needs_info_issues:
|
||||
Move_Unabeled_Issue_On_Project_Board:
|
||||
name: Move no longer X-Needs-Info issues to Triaged
|
||||
runs-on: ubuntu-24.04
|
||||
if: >
|
||||
!contains(github.event.issue.labels.*.name, 'X-Needs-Info')
|
||||
steps:
|
||||
- id: set_fields
|
||||
uses: nipe0324/update-project-v2-item-field@c4af58452d1c5a788c1ea4f20e073fa722ec4a6b #v2.0.2
|
||||
with:
|
||||
project-url: ${{ env.PROJECT_URL }}
|
||||
github-token: ${{ secrets.ELEMENT_BOT_TOKEN }}
|
||||
skip-update-script: |
|
||||
const isIssue = item.type === 'ISSUE'
|
||||
const status = item.fieldValues['Status']
|
||||
return !isIssue || status !== 'Needs info'
|
||||
field-name: Status
|
||||
field-value: "Triaged"
|
||||
${{
|
||||
!contains(github.event.issue.labels.*.name, 'X-Needs-Info') }}
|
||||
env:
|
||||
PROJECT_URL: https://github.com/orgs/element-hq/projects/120
|
||||
BOARD_NAME: "Issue triage"
|
||||
OWNER: ${{ github.repository_owner }}
|
||||
REPO: ${{ github.event.repository.name }}
|
||||
ISSUE: ${{ github.event.issue.number }}
|
||||
steps:
|
||||
- name: Check if issue is already in "${{ env.BOARD_NAME }}"
|
||||
run: |
|
||||
json=$(curl -s -H 'Content-Type: application/json' -H "Authorization: bearer ${{ secrets.GITHUB_TOKEN }}" -X POST -d '{"query": "query($issue: Int!, $owner: String!, $repo: String!) { repository(owner: $owner, name: $repo) { issue(number: $issue) { projectCards { nodes { project { name } isArchived } } } } } ", "variables" : "{ \"issue\": '${ISSUE}', \"owner\": \"'${OWNER}'\", \"repo\": \"'${REPO}'\" }" }' https://api.github.com/graphql)
|
||||
if echo $json | jq '.data.repository.issue.projectCards.nodes | length'; then
|
||||
if [[ $(echo $json | jq '.data.repository.issue.projectCards.nodes[0].project.name') =~ "${BOARD_NAME}" ]]; then
|
||||
if [[ $(echo $json | jq '.data.repository.issue.projectCards.nodes[0].isArchived') == 'true' ]]; then
|
||||
echo "Issue is already in Project '$BOARD_NAME', but is archived - skipping workflow";
|
||||
echo "SKIP_ACTION=true" >> $GITHUB_ENV
|
||||
else
|
||||
echo "Issue is already in Project '$BOARD_NAME', proceeding";
|
||||
echo "ALREADY_IN_BOARD=true" >> $GITHUB_ENV
|
||||
fi
|
||||
else
|
||||
echo "Issue is not in project '$BOARD_NAME', cancelling this workflow"
|
||||
echo "ALREADY_IN_BOARD=false" >> $GITHUB_ENV
|
||||
fi
|
||||
fi
|
||||
- name: Move issue
|
||||
uses: alex-page/github-project-automation-plus@303f24a24c67ce7adf565a07e96720faf126fe36
|
||||
if: ${{ env.ALREADY_IN_BOARD == 'true' && env.SKIP_ACTION != 'true' }}
|
||||
with:
|
||||
project: Issue triage
|
||||
column: Triaged
|
||||
repo-token: ${{ secrets.ELEMENT_BOT_TOKEN }}
|
||||
|
||||
remove_Z-Labs_label:
|
||||
name: Remove Z-Labs label when features behind labs flags are removed
|
||||
@@ -43,7 +60,7 @@ jobs:
|
||||
contains(github.event.issue.labels.*.name, 'A-Element-Call')) &&
|
||||
contains(github.event.issue.labels.*.name, 'Z-Labs')
|
||||
steps:
|
||||
- uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9
|
||||
- uses: actions/github-script@v7
|
||||
with:
|
||||
script: |
|
||||
github.rest.issues.removeLabel({
|
||||
|
||||
@@ -4,30 +4,25 @@ on:
|
||||
workflow_dispatch: {}
|
||||
schedule:
|
||||
- cron: "0 3 * * 0" # 3am every Sunday
|
||||
permissions: {} # We use ELEMENT_BOT_TOKEN instead
|
||||
jobs:
|
||||
update:
|
||||
runs-on: ubuntu-24.04
|
||||
steps:
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
|
||||
with:
|
||||
persist-credentials: false
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- uses: pnpm/action-setup@0e279bb959325dab635dd2c09392533439d90093 # v6.0.8
|
||||
- uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6
|
||||
- uses: actions/setup-node@v4
|
||||
with:
|
||||
cache: "pnpm"
|
||||
cache: "yarn"
|
||||
node-version: "lts/*"
|
||||
|
||||
- name: Install Deps
|
||||
run: "pnpm install --frozen-lockfile"
|
||||
run: "yarn install --frozen-lockfile"
|
||||
|
||||
- name: Fetch Jitsi
|
||||
working-directory: apps/web
|
||||
run: "pnpm vendor:jitsi"
|
||||
run: "yarn update:jitsi"
|
||||
|
||||
- name: Create Pull Request
|
||||
uses: peter-evans/create-pull-request@5f6978faf089d4d20b00c7766989d076bb2fc7f1 # v8
|
||||
uses: peter-evans/create-pull-request@5e914681df9dc83aa4e4905692ca88beb2f9e91f # v7
|
||||
with:
|
||||
token: ${{ secrets.ELEMENT_BOT_TOKEN }}
|
||||
branch: actions/jitsi-update
|
||||
|
||||
@@ -15,24 +15,23 @@ on:
|
||||
required: true
|
||||
type: string
|
||||
concurrency: ${{ github.workflow }}
|
||||
permissions: {} # No permissions required
|
||||
jobs:
|
||||
bot:
|
||||
name: Release topic update
|
||||
runs-on: ubuntu-24.04
|
||||
environment: Matrix
|
||||
steps:
|
||||
- uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9
|
||||
- uses: actions/github-script@v7
|
||||
env:
|
||||
HS_URL: ${{ secrets.BETABOT_HS_URL }}
|
||||
LOBBY_ROOM_ID: ${{ secrets.ROOM_ID }}
|
||||
PUBLIC_DISCUSSION_ROOM_ID: "!xUW4PpAe1CmThA3r2wI8IrgwwsK006-zqWdJCljpd10"
|
||||
ANNOUNCEMENT_ROOM_ID: "!ars5ndgI6IIYZXECiJ-u8YljHNzShJn3nHdB-3rYI2M"
|
||||
PUBLIC_ROOM_ID: "!YTvKGNlinIzlkMTVRl:matrix.org"
|
||||
ANNOUNCEMENT_ROOM_ID: "!bijaLdadorKgNGtHdA:matrix.org"
|
||||
TOKEN: ${{ secrets.BETABOT_ACCESS_TOKEN }}
|
||||
RELEASE_STATUS: "Release status: ${{ inputs.expected_status }} expected ${{ inputs.expected_date }}"
|
||||
with:
|
||||
script: |
|
||||
const { HS_URL, TOKEN, RELEASE_STATUS, LOBBY_ROOM_ID, PUBLIC_DISCUSSION_ROOM_ID, ANNOUNCEMENT_ROOM_ID } = process.env;
|
||||
const { HS_URL, TOKEN, RELEASE_STATUS, LOBBY_ROOM_ID, PUBLIC_ROOM_ID, ANNOUNCEMENT_ROOM_ID } = process.env;
|
||||
|
||||
const repo = context.repo;
|
||||
const { data } = await github.rest.repos.getLatestRelease({
|
||||
@@ -71,23 +70,13 @@ jobs:
|
||||
const data = await res.json();
|
||||
console.log(roomId, "got event", data);
|
||||
|
||||
if (!regex.test(data.topic)) {
|
||||
core.setFailed("Topic format is incorrect for room " + roomId);
|
||||
return;
|
||||
}
|
||||
|
||||
const topic = data.topic.replace(regex, releaseTopic);
|
||||
if (topic === data.topic) {
|
||||
console.log(roomId, "nothing to do");
|
||||
return;
|
||||
}
|
||||
if (data["org.matrix.msc3765.topic"]) {
|
||||
data["org.matrix.msc3765.topic"]?.["m.text"].forEach(d => {
|
||||
d.body = d.body.replace(regex, releaseTopic);
|
||||
});
|
||||
}
|
||||
if (data["m.topic"]) {
|
||||
data["m.topic"]?.["m.text"].forEach(d => {
|
||||
data["org.matrix.msc3765.topic"].forEach(d => {
|
||||
d.body = d.body.replace(regex, releaseTopic);
|
||||
});
|
||||
}
|
||||
@@ -102,18 +91,12 @@ jobs:
|
||||
});
|
||||
|
||||
if (res.ok) {
|
||||
const resJson = res.json();
|
||||
if (resJson.errcode) {
|
||||
core.setFailed(`Error updating ${roomId}: ${resJson.error}`);
|
||||
} else {
|
||||
console.log(roomId, "topic updated:", topic);
|
||||
}
|
||||
console.log(roomId, "topic updated:", topic);
|
||||
} else {
|
||||
const errText = await res.text();
|
||||
core.setFailed(`Error updating ${roomId}: ${errText}`);
|
||||
console.log(roomId, await res.text());
|
||||
}
|
||||
}
|
||||
|
||||
await updateReleaseInTopic(LOBBY_ROOM_ID);
|
||||
await updateReleaseInTopic(PUBLIC_DISCUSSION_ROOM_ID);
|
||||
await updateReleaseInTopic(PUBLIC_ROOM_ID);
|
||||
await updateReleaseInTopic(ANNOUNCEMENT_ROOM_ID);
|
||||
|
||||
+16
-27
@@ -3,42 +3,31 @@
|
||||
/dist
|
||||
/key.pem
|
||||
/lib
|
||||
node_modules
|
||||
/node_modules
|
||||
/packages/
|
||||
/webapp
|
||||
/.npmrc
|
||||
/*.log
|
||||
package-lock.json
|
||||
.DS_Store
|
||||
electron/dist
|
||||
electron/pub
|
||||
**/.idea
|
||||
/webpack-stats.json
|
||||
/config.json
|
||||
/config.json.*
|
||||
/config.local*.json
|
||||
# Legacy skinning file that some people might still have
|
||||
/src/component-index.js
|
||||
/.tmp
|
||||
/webpack-stats.json
|
||||
.vscode
|
||||
.vscode/
|
||||
.env
|
||||
.env.*
|
||||
coverage
|
||||
/coverage
|
||||
# Auto-generated file
|
||||
/src/modules.ts
|
||||
/build_config.yaml
|
||||
/book
|
||||
/index.html
|
||||
# version file and tarball created by `npm pack` / `yarn pack`
|
||||
/git-revision.txt
|
||||
jest-sonar.xml
|
||||
|
||||
*storybook.log
|
||||
storybook-static
|
||||
|
||||
/packages/shared-components/node_modules
|
||||
/packages/shared-components/dist
|
||||
/packages/shared-components/src/i18nKeys.d.ts
|
||||
/packages/shared-components/.vitest-attachments
|
||||
|
||||
# TSC incremental compilation information
|
||||
*.tsbuildinfo
|
||||
|
||||
/.link-config
|
||||
|
||||
.nx/cache
|
||||
.nx/workspace-data
|
||||
|
||||
.pnpm-store
|
||||
|
||||
# vitepress
|
||||
/docs/.vitepress/dist
|
||||
/docs/.vitepress/cache
|
||||
|
||||
+4
-1
@@ -1 +1,4 @@
|
||||
pnpm exec lint-staged --concurrent false
|
||||
#!/usr/bin/env sh
|
||||
. "$(dirname "$0")/_/husky.sh"
|
||||
|
||||
npx lint-staged --concurrent false
|
||||
|
||||
+5
-1
@@ -1,3 +1,7 @@
|
||||
{
|
||||
"*": "prettier --write --ignore-unknown"
|
||||
"*": "prettier --write",
|
||||
"src/**/*.(ts|tsx)": ["eslint --fix"],
|
||||
"scripts/**/*.(ts|tsx)": ["eslint --fix"],
|
||||
"module_system/**/*.(ts|tsx)": ["eslint --fix --config .eslintrc-module_system.js module_system"],
|
||||
"*.pcss": ["stylelint --fix"]
|
||||
}
|
||||
|
||||
+1
-1
@@ -1 +1 @@
|
||||
24
|
||||
20
|
||||
|
||||
+21
-46
@@ -1,71 +1,46 @@
|
||||
/build
|
||||
/dist
|
||||
/lib
|
||||
node_modules
|
||||
/apps/web/webapp
|
||||
/node_modules
|
||||
/packages/
|
||||
/webapp
|
||||
/*.log
|
||||
pnpm-lock.yaml
|
||||
yarn.lock
|
||||
electron/dist
|
||||
electron/pub
|
||||
**/.idea
|
||||
/.tmp
|
||||
webpack-stats.json
|
||||
/webpack-stats.json
|
||||
.vscode
|
||||
.vscode/
|
||||
.env
|
||||
coverage
|
||||
# Auto-generated files
|
||||
*.api.md
|
||||
/apps/web/src/modules.ts
|
||||
/apps/web/src/modules.js
|
||||
src/i18n/strings
|
||||
/apps/web/build_config.yaml
|
||||
/coverage
|
||||
# Auto-generated file
|
||||
/src/modules.ts
|
||||
/src/i18n/strings
|
||||
/build_config.yaml
|
||||
# Raises an error because it contains a template var breaking the script tag
|
||||
/apps/web/src/vector/index.html
|
||||
/apps/web/src/vector/modernizr.cjs
|
||||
src/vector/index.html
|
||||
src/vector/modernizr.js
|
||||
/docs/lib
|
||||
/book
|
||||
debian/tmp
|
||||
/debian/tmp
|
||||
/.npmrc
|
||||
package-lock.json
|
||||
|
||||
# This file is owned, parsed, and generated by allchange, which doesn't comply with prettier
|
||||
CHANGELOG.md
|
||||
/CHANGELOG.md
|
||||
/docs/changelogs
|
||||
|
||||
# Legacy skinning file that some people might still have
|
||||
/apps/web/src/component-index.js
|
||||
/src/component-index.js
|
||||
|
||||
# Downloaded and already minified
|
||||
/apps/web/res/jitsi_external_api.min.js
|
||||
res/jitsi_external_api.min.js
|
||||
|
||||
# This file is also machine-generated
|
||||
/apps/web/playwright/e2e/crypto/test_indexeddb_cryptostore_dump/dump.json
|
||||
/apps/web/playwright/test-results/
|
||||
/apps/web/playwright/html-report/
|
||||
/apps/web/playwright/logs/
|
||||
/apps/web/playwright/snapshots/
|
||||
|
||||
/apps/desktop/.hak/
|
||||
/apps/desktop/dist/
|
||||
/apps/desktop/build/
|
||||
/apps/desktop/dockerbuild/
|
||||
/apps/desktop/deploys/
|
||||
/apps/desktop/lib/
|
||||
/apps/desktop/webapp
|
||||
/apps/desktop/playwright/html-report
|
||||
/apps/desktop/playwright/test-results
|
||||
|
||||
# Shared components generated files
|
||||
/packages/shared-components/dist/
|
||||
/packages/shared-components/src/i18n/i18nKeys.d.ts
|
||||
/packages/shared-components/typedoc/
|
||||
/packages/shared-components/storybook-static/
|
||||
|
||||
# These files are generated by running `pnpm -r lint:types` and do not adhere to prettier's requirements.
|
||||
# All of them are .gitignored within their parent directory.
|
||||
/packages/playwright-common/lib/
|
||||
/packages/module-api/lib/
|
||||
/packages/module-api/temp/
|
||||
|
||||
/.nx/
|
||||
/playwright/e2e/crypto/test_indexeddb_cryptostore_dump/dump.json
|
||||
/playwright/test-results/
|
||||
/playwright/html-report/
|
||||
/playwright/logs/
|
||||
/playwright/snapshots/
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
module.exports = {
|
||||
extends: ["stylelint-config-standard"],
|
||||
customSyntax: require("postcss-scss"),
|
||||
plugins: ["stylelint-scss"],
|
||||
rules: {
|
||||
"comment-empty-line-before": null,
|
||||
"declaration-empty-line-before": null,
|
||||
"length-zero-no-unit": null,
|
||||
"rule-empty-line-before": null,
|
||||
"color-hex-length": null,
|
||||
"at-rule-no-unknown": null,
|
||||
"no-descending-specificity": null,
|
||||
"scss/at-rule-no-unknown": [
|
||||
true,
|
||||
{
|
||||
// https://github.com/vector-im/element-web/issues/10544
|
||||
ignoreAtRules: ["define-mixin"],
|
||||
},
|
||||
],
|
||||
// Disable `&_kind`-style selectors while our unused CSS approach is "Find & Replace All"
|
||||
// rather than a CI thing. Shorthand selectors are harder to detect when searching for a
|
||||
// class name. This regex is trying to *allow* anything except `&words`, such as `&::before`,
|
||||
// `&.mx_Class`, etc.
|
||||
"selector-nested-pattern": "^((&[ :.\\[,])|([^&]))",
|
||||
// Disable some defaults
|
||||
"selector-class-pattern": null,
|
||||
"custom-property-pattern": null,
|
||||
"selector-id-pattern": null,
|
||||
"keyframes-name-pattern": null,
|
||||
"alpha-value-notation": null,
|
||||
"color-function-notation": null,
|
||||
"selector-not-notation": null,
|
||||
"import-notation": null,
|
||||
"value-keyword-case": null,
|
||||
"declaration-block-no-redundant-longhand-properties": null,
|
||||
"declaration-block-no-duplicate-properties": [
|
||||
true,
|
||||
// useful for fallbacks
|
||||
{ ignore: ["consecutive-duplicates-with-different-values"] },
|
||||
],
|
||||
"shorthand-property-no-redundant-values": null,
|
||||
"property-no-vendor-prefix": null,
|
||||
"value-no-vendor-prefix": null,
|
||||
"selector-no-vendor-prefix": null,
|
||||
"media-feature-name-no-vendor-prefix": null,
|
||||
"number-max-precision": null,
|
||||
"no-invalid-double-slash-comments": true,
|
||||
"media-feature-range-notation": null,
|
||||
},
|
||||
};
|
||||
@@ -19,6 +19,3 @@ include:
|
||||
|
||||
* Thom Cleary (https://github.com/thomcatdotrocks)
|
||||
Small update for tarball deployment
|
||||
|
||||
* Alexander (https://github.com/ioalexander)
|
||||
Save image on CTRL + S shortcut
|
||||
|
||||
-1255
File diff suppressed because it is too large
Load Diff
+126
-61
@@ -2,11 +2,6 @@
|
||||
|
||||
Everyone is welcome to contribute code to Element Web, provided that they are willing to license their contributions to Element under a [Contributor License Agreement](https://cla-assistant.io/element-hq/element-web) (CLA). This ensures that their contribution will be made available under an OSI-approved open-source license, currently licensed under Affero General Public License v3 (AGPLv3) or General Public License v3 (GPLv3) at your choice.
|
||||
|
||||
If you're contributing, or thinking about contributing, please come & chat to
|
||||
us in our development room, [#element-dev](https://matrix.to/#/#element-dev:matrix.org).
|
||||
This is the best place to ask questions about the code, how to work on the project
|
||||
or whether a change is likely to be accepted.
|
||||
|
||||
## How to contribute
|
||||
|
||||
The preferred and easiest way to contribute changes to the project is to fork
|
||||
@@ -25,44 +20,26 @@ Definitely don't use the GitHub default of "Update file.ts".
|
||||
|
||||
As for your PR description, it should include these things:
|
||||
|
||||
- References to any bugs fixed by the change (in GitHub's `Fixes` notation)
|
||||
- Describe the why and what is changing in the PR description so it's easy for
|
||||
onlookers and reviewers to onboard and context switch. This information is
|
||||
also helpful when we come back to look at this in 6 months and ask "why did
|
||||
we do it like that?" we have a chance of finding out.
|
||||
- Why didn't it work before? Why does it work now? What use cases does it
|
||||
unlock?
|
||||
- If you find yourself adding information on how the code works or why you
|
||||
chose to do it the way you did, make sure this information is instead
|
||||
written as comments in the code itself.
|
||||
- Sometimes a PR can change considerably as it is developed. In this case,
|
||||
the description should be updated to reflect the most recent state of
|
||||
the PR. (It can be helpful to retain the old content under a suitable
|
||||
heading, for additional context.)
|
||||
- Include both **before** and **after** screenshots to easily compare and discuss
|
||||
what's changing.
|
||||
- Include a step-by-step testing strategy so that a reviewer can check out the
|
||||
code locally and easily get to the point of testing your change.
|
||||
- Add comments to the diff for the reviewer that might help them to understand
|
||||
why the change is necessary or how they might better understand and review it.
|
||||
|
||||
Please **_do not use force push_** in your PRs. Doing so means we can't see what
|
||||
has changed. We use squash merge to get a "clean" git history.
|
||||
|
||||
### Adding a new feature or enhancement
|
||||
|
||||
To make a great product with a great user experience, all the small efforts need to go in the same direction and be aligned and consistent with each other.
|
||||
|
||||
Before making your contribution, please consider the following:
|
||||
|
||||
- One product can’t do everything well. Element is focusing on private end-to-end encrypted messaging and voice - this can either be for consumers (e.g. friends and family) or for professional teams and organizations. Public forums and other types of chats without E2EE remain supported but are not the primary use case in case UX compromises need to be made.
|
||||
- There are 3 platforms - Web/Desktop, [Android](https://github.com/element-hq/element-x-android) and [iOS](https://github.com/element-hq/element-x-ios). These platforms need to have feature parity and design consistency. For some features, supporting all platforms is a must have, in some cases exceptions can be made to have it on one platform only.
|
||||
- To make sure your idea fits both from a design/solution and use case perspective, please open a new issue (or find an existing issue) in [element-meta](https://github.com/element-hq/element-meta/issues) repository describing the use case and how you plan to tackle it. Do not just describe what feature is missing, explain why the users need it with a couple of real life examples from the field.
|
||||
- In case of an existing issue, please comment that you're planning to contribute. If you create a new issue, please specify that in the issue. In such a case we will try to review the issue ASAP and provide you with initial feedback so you can be confident if and at which conditions your contributions will be accepted.
|
||||
|
||||
Once we know that you want to contribute and have confirmed that the new feature is overall aligned with the product direction, the designers of the core team will help you with the designs and any other type of guidance when it comes to the user experience. We will try to unblock you as quickly as we can, but it may not be instant. Having a clear understanding of the use case and the impact of the feature will help us with the prioritization and faster responses.
|
||||
|
||||
Only once all of the above is met should you open a PR with your proposed changes.
|
||||
- References to any bugs fixed by the change (in GitHub's `Fixes` notation)
|
||||
- Describe the why and what is changing in the PR description so it's easy for
|
||||
onlookers and reviewers to onboard and context switch. This information is
|
||||
also helpful when we come back to look at this in 6 months and ask "why did
|
||||
we do it like that?" we have a chance of finding out.
|
||||
- Why didn't it work before? Why does it work now? What use cases does it
|
||||
unlock?
|
||||
- If you find yourself adding information on how the code works or why you
|
||||
chose to do it the way you did, make sure this information is instead
|
||||
written as comments in the code itself.
|
||||
- Sometimes a PR can change considerably as it is developed. In this case,
|
||||
the description should be updated to reflect the most recent state of
|
||||
the PR. (It can be helpful to retain the old content under a suitable
|
||||
heading, for additional context.)
|
||||
- Include both **before** and **after** screenshots to easily compare and discuss
|
||||
what's changing.
|
||||
- Include a step-by-step testing strategy so that a reviewer can check out the
|
||||
code locally and easily get to the point of testing your change.
|
||||
- Add comments to the diff for the reviewer that might help them to understand
|
||||
why the change is necessary or how they might better understand and review it.
|
||||
|
||||
### Changelogs
|
||||
|
||||
@@ -86,6 +63,25 @@ the default for PRs labelled with `T-Task`):
|
||||
|
||||
_Remove outdated comment from `Ungulates.ts`_
|
||||
|
||||
```
|
||||
Notes: none
|
||||
```
|
||||
|
||||
Sometimes, you're fixing a bug in a downstream project, in which case you want
|
||||
an entry in that project's changelog. You can do that too:
|
||||
|
||||
_Fix another herding bug_
|
||||
|
||||
```
|
||||
Notes: Fix a bug where the `herd()` function would only work on Tuesdays
|
||||
element-web notes: Fix a bug where the 'Herd' button only worked on Tuesdays
|
||||
```
|
||||
|
||||
This example is for Element Web. You can specify:
|
||||
|
||||
- element-web
|
||||
- element-desktop
|
||||
|
||||
If your PR introduces a breaking change, use the `Notes` section in the same
|
||||
way, additionally adding the `X-Breaking-Change` label (see below). There's no need
|
||||
to specify in the notes that it's a breaking change - this will be added
|
||||
@@ -100,10 +96,10 @@ Notes: Remove legacy `Camelopard` class. `Giraffe` should be used instead.
|
||||
|
||||
Other metadata can be added using labels.
|
||||
|
||||
- `X-Breaking-Change`: A breaking change - adding this label will mean the change causes a _major_ version bump.
|
||||
- `T-Enhancement`: A new feature - adding this label will mean the change causes a _minor_ version bump.
|
||||
- `T-Defect`: A bug fix (in either code or docs).
|
||||
- `T-Task`: No user-facing changes, eg. code comments, CI fixes, refactors or tests. Won't have a changelog entry unless you specify one.
|
||||
- `X-Breaking-Change`: A breaking change - adding this label will mean the change causes a _major_ version bump.
|
||||
- `T-Enhancement`: A new feature - adding this label will mean the change causes a _minor_ version bump.
|
||||
- `T-Defect`: A bug fix (in either code or docs).
|
||||
- `T-Task`: No user-facing changes, eg. code comments, CI fixes, refactors or tests. Won't have a changelog entry unless you specify one.
|
||||
|
||||
If you don't have permission to add labels, your PR reviewer(s) can work with you
|
||||
to add them: ask in the PR description or comments.
|
||||
@@ -140,10 +136,6 @@ These are located in `/spec/` in `matrix-js-sdk` or `/test/` in `element-web`.
|
||||
When writing unit tests, please aim for a high level of test coverage
|
||||
for new code - 80% or greater. If you cannot achieve that, please document
|
||||
why it's not possible in your PR.
|
||||
CI will validate that the coverage reached on your change is sufficient,
|
||||
you can also assert this locally by installing https://github.com/Bachmann1234/diff_cover,
|
||||
running the entire test suite in coverage mode `pnpm coverage` then running
|
||||
`pnpm coverage:diff` to see the coverage of the diff between your HEAD and `develop`.
|
||||
|
||||
Some sections of code are not sensible to add coverage for, such as those
|
||||
which explicitly inhibit noisy logging for tests. Which can be hidden using
|
||||
@@ -187,16 +179,6 @@ Please ensure your changes match the cosmetic style of the existing project,
|
||||
and **_never_** mix cosmetic and functional changes in the same commit, as it
|
||||
makes it horribly hard to review otherwise.
|
||||
|
||||
## Shared Components
|
||||
|
||||
When creating new UI components, consider whether they should be added to the shared components package (`packages/shared-components`) rather than directly in the main `src/` directory. Components should be placed in shared components if they:
|
||||
|
||||
- Are reusable across different parts of the application
|
||||
- Could potentially be used by other Element projects (Element Desktop, Aurora, Element modules...)
|
||||
- Follow established patterns and don't have tight coupling to specific application logic
|
||||
|
||||
For more details, see the [shared components README](./packages/shared-components/README.md).
|
||||
|
||||
## Attribution
|
||||
|
||||
Everyone who contributes anything to Matrix is welcome to be listed in the
|
||||
@@ -207,6 +189,89 @@ give away to contributors - if you feel that Matrix-branded apparel is missing
|
||||
from your life, please mail us your shipping address to matrix at matrix.org
|
||||
and we'll try to fix it :)
|
||||
|
||||
## Sign off
|
||||
|
||||
In order to have a concrete record that your contribution is intentional
|
||||
and you agree to license it under the same terms as the project's license, we've
|
||||
adopted the same lightweight approach that the Linux Kernel
|
||||
(https://www.kernel.org/doc/html/latest/process/submitting-patches.html), Docker
|
||||
(https://github.com/docker/docker/blob/master/CONTRIBUTING.md), and many other
|
||||
projects use: the DCO (Developer Certificate of Origin:
|
||||
http://developercertificate.org/). This is a simple declaration that you wrote
|
||||
the contribution or otherwise have the right to contribute it to Matrix:
|
||||
|
||||
```
|
||||
Developer Certificate of Origin
|
||||
Version 1.1
|
||||
|
||||
Copyright (C) 2004, 2006 The Linux Foundation and its contributors.
|
||||
660 York Street, Suite 102,
|
||||
San Francisco, CA 94110 USA
|
||||
|
||||
Everyone is permitted to copy and distribute verbatim copies of this
|
||||
license document, but changing it is not allowed.
|
||||
|
||||
Developer's Certificate of Origin 1.1
|
||||
|
||||
By making a contribution to this project, I certify that:
|
||||
|
||||
(a) The contribution was created in whole or in part by me and I
|
||||
have the right to submit it under the open source license
|
||||
indicated in the file; or
|
||||
|
||||
(b) The contribution is based upon previous work that, to the best
|
||||
of my knowledge, is covered under an appropriate open source
|
||||
license and I have the right under that license to submit that
|
||||
work with modifications, whether created in whole or in part
|
||||
by me, under the same open source license (unless I am
|
||||
permitted to submit under a different license), as indicated
|
||||
in the file; or
|
||||
|
||||
(c) The contribution was provided directly to me by some other
|
||||
person who certified (a), (b) or (c) and I have not modified
|
||||
it.
|
||||
|
||||
(d) I understand and agree that this project and the contribution
|
||||
are public and that a record of the contribution (including all
|
||||
personal information I submit with it, including my sign-off) is
|
||||
maintained indefinitely and may be redistributed consistent with
|
||||
this project or the open source license(s) involved.
|
||||
```
|
||||
|
||||
If you agree to this for your contribution, then all that's needed is to
|
||||
include the line in your commit or pull request comment:
|
||||
|
||||
```
|
||||
Signed-off-by: Your Name <your@email.example.org>
|
||||
```
|
||||
|
||||
We accept contributions under a legally identifiable name, such as your name on
|
||||
government documentation or common-law names (names claimed by legitimate usage
|
||||
or repute). Unfortunately, we cannot accept anonymous contributions at this
|
||||
time.
|
||||
|
||||
Git allows you to add this signoff automatically when using the `-s` flag to
|
||||
`git commit`, which uses the name and email set in your `user.name` and
|
||||
`user.email` git configs.
|
||||
|
||||
If you forgot to sign off your commits before making your pull request and are
|
||||
on Git 2.17+ you can mass signoff using rebase:
|
||||
|
||||
```
|
||||
git rebase --signoff origin/develop
|
||||
```
|
||||
|
||||
## Private sign off
|
||||
|
||||
If you would like to provide your legal name privately to the Matrix.org
|
||||
Foundation (instead of in a public commit or comment), you can do so by emailing
|
||||
your legal name and a link to the pull request to dco@matrix.org. It helps to
|
||||
include "sign off" or similar in the subject line. You will then be instructed
|
||||
further.
|
||||
|
||||
Once private sign off is complete, doing so for future contributions will not
|
||||
be required.
|
||||
|
||||
# Review expectations
|
||||
|
||||
See https://github.com/element-hq/element-meta/wiki/Review-process
|
||||
|
||||
+31
@@ -0,0 +1,31 @@
|
||||
# Builder
|
||||
FROM --platform=$BUILDPLATFORM node:20-bullseye as builder
|
||||
|
||||
# Support custom branch of the js-sdk. This also helps us build images of element-web develop.
|
||||
ARG USE_CUSTOM_SDKS=false
|
||||
ARG JS_SDK_REPO="https://github.com/matrix-org/matrix-js-sdk.git"
|
||||
ARG JS_SDK_BRANCH="master"
|
||||
|
||||
RUN apt-get update && apt-get install -y git dos2unix
|
||||
|
||||
WORKDIR /src
|
||||
|
||||
COPY . /src
|
||||
RUN dos2unix /src/scripts/docker-link-repos.sh && bash /src/scripts/docker-link-repos.sh
|
||||
RUN yarn --network-timeout=200000 install
|
||||
|
||||
RUN dos2unix /src/scripts/docker-package.sh /src/scripts/get-version-from-git.sh /src/scripts/normalize-version.sh && bash /src/scripts/docker-package.sh
|
||||
|
||||
# Copy the config now so that we don't create another layer in the app image
|
||||
RUN cp /src/config.sample.json /src/webapp/config.json
|
||||
|
||||
# App
|
||||
FROM nginx:alpine-slim
|
||||
|
||||
COPY --from=builder /src/webapp /app
|
||||
|
||||
# Override default nginx config
|
||||
COPY /nginx/conf.d/default.conf /etc/nginx/conf.d/default.conf
|
||||
|
||||
RUN rm -rf /usr/share/nginx/html \
|
||||
&& ln -s /app /usr/share/nginx/html
|
||||
@@ -1,6 +0,0 @@
|
||||
Licensees holding a valid commercial license with Element may use this
|
||||
software in accordance with the terms contained in a written agreement
|
||||
between you and Element.
|
||||
|
||||
To purchase a commercial license please contact our sales team at
|
||||
licensing@element.io
|
||||
@@ -9,41 +9,41 @@
|
||||
|
||||
# Element
|
||||
|
||||
Element (formerly known as Vector and Riot) is a Matrix web & desktop client built using the [Matrix
|
||||
Element (formerly known as Vector and Riot) is a Matrix web client built using the [Matrix
|
||||
JS SDK](https://github.com/matrix-org/matrix-js-sdk).
|
||||
|
||||
# Supported Environments
|
||||
|
||||
Element has several tiers of support for different environments:
|
||||
|
||||
- Supported
|
||||
- Definition:
|
||||
- Issues **actively triaged**, regressions **block** the release
|
||||
- Last 2 major versions of Chrome, Firefox, and Edge on desktop OSes
|
||||
- Last 2 versions of Safari
|
||||
- Latest release of official Element Desktop app on desktop OSes
|
||||
- Desktop OSes means macOS, Windows, and Linux versions for desktop devices
|
||||
that are actively supported by the OS vendor and receive security updates
|
||||
- Best effort
|
||||
- Definition:
|
||||
- Issues **accepted**, regressions **do not block** the release
|
||||
- The wider Element Products (including Element Call and the Enterprise Server Suite) do still not officially support these browsers.
|
||||
- The element web project and its contributors should keep the client functioning and gracefully degrade where other sibling features (E.g. Element Call) may not function.
|
||||
- Last major release of Firefox ESR and Chrome/Edge Extended Stable
|
||||
- Community Supported
|
||||
- Definition:
|
||||
- Issues **accepted**, regressions **do not block** the release
|
||||
- Community contributions are welcome to support these issues
|
||||
- Mobile web for current stable version of Chrome, Firefox, and Safari on Android, iOS, and iPadOS
|
||||
- Not supported
|
||||
- Definition: Issues only affecting unsupported environments are **closed**
|
||||
- Everything else
|
||||
- Supported
|
||||
- Definition:
|
||||
- Issues **actively triaged**, regressions **block** the release
|
||||
- Last 2 major versions of Chrome, Firefox, and Edge on desktop OSes
|
||||
- Last 2 versions of Safari
|
||||
- Latest release of official Element Desktop app on desktop OSes
|
||||
- Desktop OSes means macOS, Windows, and Linux versions for desktop devices
|
||||
that are actively supported by the OS vendor and receive security updates
|
||||
- Best effort
|
||||
- Definition:
|
||||
- Issues **accepted**, regressions **do not block** the release
|
||||
- The wider Element Products(including Element Call and the Enterprise Server Suite) do still not officially support these browsers.
|
||||
- The element web project and its contributors should keep the client functioning and gracefully degrade where other sibling features (E.g. Element Call) may not function.
|
||||
- Last major release of Firefox ESR and Chrome/Edge Extended Stable
|
||||
- Community Supported
|
||||
- Definition:
|
||||
- Issues **accepted**, regressions **do not block** the release
|
||||
- Community contributions are welcome to support these issues
|
||||
- Mobile web for current stable version of Chrome, Firefox, and Safari on Android, iOS, and iPadOS
|
||||
- Not supported
|
||||
- Definition: Issues only affecting unsupported environments are **closed**
|
||||
- Everything else
|
||||
|
||||
The period of support for these tiers should last until the releases specified above, plus 1 app release cycle(2 weeks). In the case of Firefox ESR this is extended further to allow it land in Debian Stable.
|
||||
|
||||
For accessing Element on an Android or iOS device, we currently recommend the
|
||||
native apps [element-x-android](https://github.com/element-hq/element-x-android)
|
||||
and [element-x-ios](https://github.com/element-hq/element-x-ios).
|
||||
native apps [element-android](https://github.com/element-hq/element-android)
|
||||
and [element-ios](https://github.com/element-hq/element-ios).
|
||||
|
||||
# Getting Started
|
||||
|
||||
@@ -55,16 +55,91 @@ To host your own instance of Element see [Installing Element Web](docs/install.m
|
||||
|
||||
To install Element as a desktop application, see [Running as a desktop app](#running-as-a-desktop-app) below.
|
||||
|
||||
---
|
||||
# Important Security Notes
|
||||
|
||||
# Monorepo
|
||||
## Separate domains
|
||||
|
||||
This repository is a monorepo hosting Element Web and other related projects in various subdirectories.
|
||||
You can read more about the structure [here](docs/monorepo.md).
|
||||
We do not recommend running Element from the same domain name as your Matrix
|
||||
homeserver. The reason is the risk of XSS (cross-site-scripting)
|
||||
vulnerabilities that could occur if someone caused Element to load and render
|
||||
malicious user generated content from a Matrix API which then had trusted
|
||||
access to Element (or other apps) due to sharing the same domain.
|
||||
|
||||
# Element Web
|
||||
We have put some coarse mitigations into place to try to protect against this
|
||||
situation, but it's still not good practice to do it in the first place. See
|
||||
<https://github.com/element-hq/element-web/issues/1977> for more details.
|
||||
|
||||
To learn more about Element Web [click here](apps/web/README.md)
|
||||
## Configuration best practices
|
||||
|
||||
Unless you have special requirements, you will want to add the following to
|
||||
your web server configuration when hosting Element Web:
|
||||
|
||||
- The `X-Frame-Options: SAMEORIGIN` header, to prevent Element Web from being
|
||||
framed and protect from [clickjacking][owasp-clickjacking].
|
||||
- The `frame-ancestors 'self'` directive to your `Content-Security-Policy`
|
||||
header, as the modern replacement for `X-Frame-Options` (though both should be
|
||||
included since not all browsers support it yet, see
|
||||
[this][owasp-clickjacking-csp]).
|
||||
- The `X-Content-Type-Options: nosniff` header, to [disable MIME
|
||||
sniffing][mime-sniffing].
|
||||
- The `X-XSS-Protection: 1; mode=block;` header, for basic XSS protection in
|
||||
legacy browsers.
|
||||
|
||||
[mime-sniffing]: https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types#mime_sniffing
|
||||
[owasp-clickjacking-csp]: https://cheatsheetseries.owasp.org/cheatsheets/Clickjacking_Defense_Cheat_Sheet.html#content-security-policy-frame-ancestors-examples
|
||||
[owasp-clickjacking]: https://cheatsheetseries.owasp.org/cheatsheets/Clickjacking_Defense_Cheat_Sheet.html
|
||||
|
||||
If you are using nginx, this would look something like the following:
|
||||
|
||||
```
|
||||
add_header X-Frame-Options SAMEORIGIN;
|
||||
add_header X-Content-Type-Options nosniff;
|
||||
add_header X-XSS-Protection "1; mode=block";
|
||||
add_header Content-Security-Policy "frame-ancestors 'self'";
|
||||
```
|
||||
|
||||
For Apache, the configuration looks like:
|
||||
|
||||
```
|
||||
Header set X-Frame-Options SAMEORIGIN
|
||||
Header set X-Content-Type-Options nosniff
|
||||
Header set X-XSS-Protection "1; mode=block"
|
||||
Header set Content-Security-Policy "frame-ancestors 'self'"
|
||||
```
|
||||
|
||||
Note: In case you are already setting a `Content-Security-Policy` header
|
||||
elsewhere, you should modify it to include the `frame-ancestors` directive
|
||||
instead of adding that last line.
|
||||
|
||||
# Building From Source
|
||||
|
||||
Element is a modular webapp built with modern ES6 and uses a Node.js build system.
|
||||
Ensure you have the latest LTS version of Node.js installed.
|
||||
|
||||
Using `yarn` instead of `npm` is recommended. Please see the Yarn [install
|
||||
guide](https://classic.yarnpkg.com/en/docs/install) if you do not have it already.
|
||||
|
||||
1. Install or update `node.js` so that your `node` is at least the current recommended LTS.
|
||||
1. Install `yarn` if not present already.
|
||||
1. Clone the repo: `git clone https://github.com/element-hq/element-web.git`.
|
||||
1. Switch to the element-web directory: `cd element-web`.
|
||||
1. Install the prerequisites: `yarn install`.
|
||||
- If you're using the `develop` branch, then it is recommended to set up a
|
||||
proper development environment (see [Setting up a dev
|
||||
environment](#setting-up-a-dev-environment) below). Alternatively, you
|
||||
can use <https://develop.element.io> - the continuous integration release of
|
||||
the develop branch.
|
||||
1. Configure the app by copying `config.sample.json` to `config.json` and
|
||||
modifying it. See the [configuration docs](docs/config.md) for details.
|
||||
1. `yarn dist` to build a tarball to deploy. Untaring this file will give
|
||||
a version-specific directory containing all the files that need to go on your
|
||||
web server.
|
||||
|
||||
Note that `yarn dist` is not supported on Windows, so Windows users can run `yarn build`,
|
||||
which will build all the necessary files into the `webapp` directory. The version of Element
|
||||
will not appear in Settings without using the dist script. You can then mount the
|
||||
`webapp` directory on your web server to actually serve up the app, which is
|
||||
entirely static content.
|
||||
|
||||
# Running as a Desktop app
|
||||
|
||||
@@ -72,19 +147,158 @@ Element can also be run as a desktop app, wrapped in Electron. You can download
|
||||
pre-built version from <https://element.io/get-started> or, if you prefer,
|
||||
build it yourself.
|
||||
|
||||
To build it yourself, follow the instructions at <https://github.com/element-hq/element-web/tree/develop/apps/desktop>.
|
||||
To build it yourself, follow the instructions at <https://github.com/element-hq/element-desktop>.
|
||||
|
||||
Many thanks to @aviraldg for the initial work on the Electron integration.
|
||||
|
||||
The [configuration docs](docs/config.md#desktop-app-configuration) show how to override the desktop app's default settings if desired.
|
||||
|
||||
# config.json
|
||||
|
||||
Element supports a variety of settings to configure default servers, behaviour, themes, etc.
|
||||
See the [configuration docs](docs/config.md) for more details.
|
||||
|
||||
# Labs Features
|
||||
|
||||
Some features of Element may be enabled by flags in the `Labs` section of the settings.
|
||||
Some of these features are described in [labs.md](https://github.com/element-hq/element-web/blob/develop/docs/labs.md).
|
||||
|
||||
# Caching requirements
|
||||
|
||||
Element requires the following URLs not to be cached, when/if you are serving Element from your own webserver:
|
||||
|
||||
```
|
||||
/config.*.json
|
||||
/i18n
|
||||
/home
|
||||
/sites
|
||||
/index.html
|
||||
```
|
||||
|
||||
We also recommend that you force browsers to re-validate any cached copy of Element on page load by configuring your
|
||||
webserver to return `Cache-Control: no-cache` for `/`. This ensures the browser will fetch a new version of Element on
|
||||
the next page load after it's been deployed. Note that this is already configured for you in the nginx config of our
|
||||
Dockerfile.
|
||||
|
||||
# Development
|
||||
|
||||
Please read through the following:
|
||||
Before attempting to develop on Element you **must** read the [developer guide
|
||||
for `matrix-react-sdk`](https://github.com/matrix-org/matrix-react-sdk#developer-guide), which
|
||||
also defines the design, architecture and style for Element too.
|
||||
|
||||
1. [Developer guide](./developer_guide.md)
|
||||
2. [Code style](./code_style.md)
|
||||
3. [Contribution guide](./CONTRIBUTING.md)
|
||||
Read the [Choosing an issue](docs/choosing-an-issue.md) page for some guidance
|
||||
about where to start. Before starting work on a feature, it's best to ensure
|
||||
your plan aligns well with our vision for Element. Please chat with the team in
|
||||
[#element-dev:matrix.org](https://matrix.to/#/#element-dev:matrix.org) before
|
||||
you start so we can ensure it's something we'd be willing to merge.
|
||||
|
||||
You should also familiarise yourself with the ["Here be Dragons" guide
|
||||
](https://docs.google.com/document/d/12jYzvkidrp1h7liEuLIe6BMdU0NUjndUYI971O06ooM)
|
||||
to the tame & not-so-tame dragons (gotchas) which exist in the codebase.
|
||||
|
||||
The idea of Element is to be a relatively lightweight "skin" of customisations on
|
||||
top of the underlying `matrix-react-sdk`. `matrix-react-sdk` provides both the
|
||||
higher and lower level React components useful for building Matrix communication
|
||||
apps using React.
|
||||
|
||||
Please note that Element is intended to run correctly without access to the public
|
||||
internet. So please don't depend on resources (JS libs, CSS, images, fonts)
|
||||
hosted by external CDNs or servers but instead please package all dependencies
|
||||
into Element itself.
|
||||
|
||||
# Setting up a dev environment
|
||||
|
||||
Much of the functionality in Element is actually in the `matrix-js-sdk` module.
|
||||
It is possible to set these up in a way that makes it easy to track the `develop` branches
|
||||
in git and to make local changes without having to manually rebuild each time.
|
||||
|
||||
First clone and build `matrix-js-sdk`:
|
||||
|
||||
```bash
|
||||
git clone https://github.com/matrix-org/matrix-js-sdk.git
|
||||
pushd matrix-js-sdk
|
||||
yarn link
|
||||
yarn install
|
||||
popd
|
||||
```
|
||||
|
||||
Clone the repo and switch to the `element-web` directory:
|
||||
|
||||
```bash
|
||||
git clone https://github.com/element-hq/element-web.git
|
||||
cd element-web
|
||||
```
|
||||
|
||||
Configure the app by copying `config.sample.json` to `config.json` and
|
||||
modifying it. See the [configuration docs](docs/config.md) for details.
|
||||
|
||||
Finally, build and start Element itself:
|
||||
|
||||
```bash
|
||||
yarn link matrix-js-sdk
|
||||
yarn install
|
||||
yarn start
|
||||
```
|
||||
|
||||
Wait a few seconds for the initial build to finish; you should see something like:
|
||||
|
||||
```
|
||||
[element-js] <s> [webpack.Progress] 100%
|
||||
[element-js]
|
||||
[element-js] ℹ 「wdm」: 1840 modules
|
||||
[element-js] ℹ 「wdm」: Compiled successfully.
|
||||
```
|
||||
|
||||
Remember, the command will not terminate since it runs the web server
|
||||
and rebuilds source files when they change. This development server also
|
||||
disables caching, so do NOT use it in production.
|
||||
|
||||
Open <http://127.0.0.1:8080/> in your browser to see your newly built Element.
|
||||
|
||||
**Note**: The build script uses inotify by default on Linux to monitor directories
|
||||
for changes. If the inotify limits are too low your build will fail silently or with
|
||||
`Error: EMFILE: too many open files`. To avoid these issues, we recommend a watch limit
|
||||
of at least `128M` and instance limit around `512`.
|
||||
|
||||
You may be interested in issues [#15750](https://github.com/element-hq/element-web/issues/15750) and
|
||||
[#15774](https://github.com/element-hq/element-web/issues/15774) for further details.
|
||||
|
||||
To set a new inotify watch and instance limit, execute:
|
||||
|
||||
```
|
||||
sudo sysctl fs.inotify.max_user_watches=131072
|
||||
sudo sysctl fs.inotify.max_user_instances=512
|
||||
sudo sysctl -p
|
||||
```
|
||||
|
||||
If you wish, you can make the new limits permanent, by executing:
|
||||
|
||||
```
|
||||
echo fs.inotify.max_user_watches=131072 | sudo tee -a /etc/sysctl.conf
|
||||
echo fs.inotify.max_user_instances=512 | sudo tee -a /etc/sysctl.conf
|
||||
sudo sysctl -p
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
When you make changes to `matrix-js-sdk` they should be automatically picked up by webpack and built.
|
||||
|
||||
If any of these steps error with, `file table overflow`, you are probably on a mac
|
||||
which has a very low limit on max open files. Run `ulimit -Sn 1024` and try again.
|
||||
You'll need to do this in each new terminal you open before building Element.
|
||||
|
||||
## Running the tests
|
||||
|
||||
There are a number of application-level tests in the `tests` directory; these
|
||||
are designed to run with Jest and JSDOM. To run them
|
||||
|
||||
```
|
||||
yarn test
|
||||
```
|
||||
|
||||
### End-to-End tests
|
||||
|
||||
See [matrix-react-sdk](https://github.com/matrix-org/matrix-react-sdk/#end-to-end-tests) for how to run the end-to-end tests.
|
||||
|
||||
# Translations
|
||||
|
||||
@@ -97,21 +311,3 @@ For a developer guide, see the [translating dev doc](docs/translating-dev.md).
|
||||
Issues are triaged by community members and the Web App Team, following the [triage process](https://github.com/element-hq/element-meta/wiki/Triage-process).
|
||||
|
||||
We use [issue labels](https://github.com/element-hq/element-meta/wiki/Issue-labelling) to sort all incoming issues.
|
||||
|
||||
## Copyright & License
|
||||
|
||||
Copyright (c) 2014-2017 OpenMarket Ltd
|
||||
Copyright (c) 2017 Vector Creations Ltd
|
||||
Copyright (c) 2017-2025 New Vector Ltd
|
||||
|
||||
This software is multi licensed by New Vector Ltd (Element). It can be used either:
|
||||
|
||||
(1) for free under the terms of the GNU Affero General Public License (as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version); OR
|
||||
|
||||
(2) for free under the terms of the GNU General Public License (as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version); OR
|
||||
|
||||
(3) under the terms of a paid-for Element Commercial License agreement between you and Element (the terms of which may vary depending on what you and Element have agreed to).
|
||||
Unless required by applicable law or agreed to in writing, software distributed under the Licenses is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the Licenses for the specific language governing permissions and limitations under the Licenses.
|
||||
|
||||
Please contact [licensing@element.io](mailto:licensing@element.io) to purchase
|
||||
an Element commercial license for this software.
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
// Stub out FontManager for tests as it doesn't validate anything we don't already know given
|
||||
// our fixed test environment and it requires the installation of node-canvas.
|
||||
|
||||
module.exports = {
|
||||
fixupColorFonts: () => Promise.resolve(),
|
||||
};
|
||||
@@ -2,7 +2,7 @@
|
||||
Copyright 2024 New Vector Ltd.
|
||||
Copyright 2022 The Matrix.org Foundation C.I.C.
|
||||
|
||||
SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Commercial
|
||||
SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only
|
||||
Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
@@ -17,7 +17,6 @@ class MockMap extends EventEmitter {
|
||||
setCenter = jest.fn();
|
||||
setStyle = jest.fn();
|
||||
fitBounds = jest.fn();
|
||||
remove = jest.fn();
|
||||
}
|
||||
const MockMapInstance = new MockMap();
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
/*
|
||||
Copyright 2024 New Vector Ltd.
|
||||
Copyright 2023 The Matrix.org Foundation C.I.C.
|
||||
|
||||
SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only
|
||||
Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
export default function workerFactory(options) {
|
||||
return jest.fn;
|
||||
}
|
||||
@@ -1,97 +0,0 @@
|
||||
module.exports = {
|
||||
plugins: ["matrix-org", "n"],
|
||||
extends: ["plugin:matrix-org/javascript"],
|
||||
parserOptions: {
|
||||
ecmaVersion: 2021,
|
||||
project: ["tsconfig.json"],
|
||||
},
|
||||
env: {
|
||||
es6: true,
|
||||
node: true,
|
||||
// we also have some browser code (ie. the preload script)
|
||||
browser: true,
|
||||
},
|
||||
// NOTE: These rules are frozen and new rules should not be added here.
|
||||
// New changes belong in https://github.com/matrix-org/eslint-plugin-matrix-org/
|
||||
rules: {
|
||||
"quotes": "off",
|
||||
"indent": "off",
|
||||
"prefer-promise-reject-errors": "off",
|
||||
"no-async-promise-executor": "off",
|
||||
|
||||
"n/file-extension-in-import": ["error", "always"],
|
||||
"unicorn/prefer-node-protocol": ["error"],
|
||||
},
|
||||
overrides: [
|
||||
{
|
||||
files: ["src/**/*.ts"],
|
||||
extends: ["plugin:matrix-org/typescript"],
|
||||
rules: {
|
||||
// Things we do that break the ideal style
|
||||
"prefer-promise-reject-errors": "off",
|
||||
"quotes": "off",
|
||||
|
||||
"@typescript-eslint/no-explicit-any": "off",
|
||||
// We're okay with assertion errors when we ask for them
|
||||
"@typescript-eslint/no-non-null-assertion": "off",
|
||||
},
|
||||
},
|
||||
{
|
||||
files: ["hak/**/*.ts"],
|
||||
extends: ["plugin:matrix-org/typescript"],
|
||||
parserOptions: {
|
||||
project: ["hak/tsconfig.json"],
|
||||
},
|
||||
rules: {
|
||||
// Things we do that break the ideal style
|
||||
"prefer-promise-reject-errors": "off",
|
||||
"quotes": "off",
|
||||
"n/file-extension-in-import": "off",
|
||||
|
||||
"@typescript-eslint/no-explicit-any": "off",
|
||||
// We're okay with assertion errors when we ask for them
|
||||
"@typescript-eslint/no-non-null-assertion": "off",
|
||||
},
|
||||
},
|
||||
{
|
||||
files: ["scripts/**/*.ts"],
|
||||
extends: ["plugin:matrix-org/typescript"],
|
||||
parserOptions: {
|
||||
project: ["scripts/tsconfig.json"],
|
||||
},
|
||||
rules: {
|
||||
// Things we do that break the ideal style
|
||||
"prefer-promise-reject-errors": "off",
|
||||
"quotes": "off",
|
||||
"n/file-extension-in-import": "off",
|
||||
|
||||
"@typescript-eslint/no-explicit-any": "off",
|
||||
// We're okay with assertion errors when we ask for them
|
||||
"@typescript-eslint/no-non-null-assertion": "off",
|
||||
},
|
||||
},
|
||||
{
|
||||
files: ["playwright/**/*.ts"],
|
||||
extends: ["plugin:matrix-org/typescript"],
|
||||
parserOptions: {
|
||||
project: ["playwright/tsconfig.json"],
|
||||
},
|
||||
rules: {
|
||||
// Things we do that break the ideal style
|
||||
"prefer-promise-reject-errors": "off",
|
||||
"quotes": "off",
|
||||
|
||||
"@typescript-eslint/no-explicit-any": "off",
|
||||
// We're okay with assertion errors when we ask for them
|
||||
"@typescript-eslint/no-non-null-assertion": "off",
|
||||
},
|
||||
},
|
||||
{
|
||||
files: ["src/**/*.test.ts", "electron-builder.ts", "vitest.config.ts"],
|
||||
extends: ["plugin:matrix-org/typescript"],
|
||||
parserOptions: {
|
||||
project: ["tsconfig.node.json"],
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
@@ -1,22 +0,0 @@
|
||||
/dist
|
||||
/lib
|
||||
/webapp
|
||||
/webapp.asar
|
||||
/packages
|
||||
/deploys
|
||||
node_modules/
|
||||
/pkg/control
|
||||
/.hak
|
||||
/.yarnrc
|
||||
/docker
|
||||
/.npmrc
|
||||
.vscode
|
||||
.vscode/
|
||||
/test_artifacts/
|
||||
/coverage/
|
||||
yarn-error.log
|
||||
/hak/**/*.js
|
||||
/scripts/hak/**/*.js
|
||||
.DS_Store
|
||||
/playwright-report
|
||||
.pnpm-store
|
||||
@@ -1,4 +0,0 @@
|
||||
{
|
||||
"*": "prettier --write --ignore-unknown",
|
||||
"*.(ts|tsx)": ["eslint --fix"]
|
||||
}
|
||||
@@ -1 +0,0 @@
|
||||
24.15.0
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,173 +0,0 @@
|
||||

|
||||

|
||||
[](https://localazy.com/p/element-web)
|
||||
[](https://sonarcloud.io/summary/new_code?id=element-desktop)
|
||||
[](https://sonarcloud.io/summary/new_code?id=element-desktop)
|
||||
[](https://sonarcloud.io/summary/new_code?id=element-desktop)
|
||||
|
||||
# Element Desktop
|
||||
|
||||
Element Desktop is a Matrix client for desktop platforms with Element Web at its core.
|
||||
|
||||
# First Steps
|
||||
|
||||
Before you do anything else, fetch the dependencies:
|
||||
|
||||
```
|
||||
pnpm install
|
||||
```
|
||||
|
||||
# Fetching Element
|
||||
|
||||
Since this package is just the Electron wrapper for Element Web, it doesn't contain any of the Element Web code,
|
||||
so the first step is to get a working copy of Element Web. There are a few ways of doing this:
|
||||
|
||||
```
|
||||
# Fetch the prebuilt release Element package from the element-web GitHub releases page. The version
|
||||
# fetched will be the same as the local element-desktop package.
|
||||
# We're explicitly asking for no config, so the packaged Element will have no config.json.
|
||||
pnpm run fetch --noverify --cfgdir ""
|
||||
```
|
||||
|
||||
...or if you'd like to use GPG to verify the downloaded package:
|
||||
|
||||
```
|
||||
# Fetch the Element public key from the element.io web server over a secure connection and import
|
||||
# it into your local GPG keychain (you'll need GPG installed). You only need to to do this
|
||||
# once.
|
||||
pnpm run fetch --importkey
|
||||
# Fetch the package and verify the signature
|
||||
pnpm run fetch --cfgdir ""
|
||||
```
|
||||
|
||||
...or either of the above, but fetching a specific version of Element:
|
||||
|
||||
```
|
||||
# Fetch the prebuilt release Element package from the element-web GitHub releases page. The version
|
||||
# fetched will be the same as the local element-desktop package.
|
||||
pnpm run fetch --noverify --cfgdir "" v1.5.6
|
||||
```
|
||||
|
||||
If you only want to run the app locally and don't need to build packages, you can
|
||||
provide the `webapp` directory directly:
|
||||
|
||||
```
|
||||
ln -s ../web/webapp ./
|
||||
```
|
||||
|
||||
[TODO: add support for fetching develop builds, arbitrary URLs and arbitrary paths]
|
||||
|
||||
# Building
|
||||
|
||||
## Native Build
|
||||
|
||||
TODO: List native pre-requisites
|
||||
|
||||
Optionally, [build the native modules](https://github.com/vector-im/element-desktop/blob/develop/docs/native-node-modules.md),
|
||||
which include support for searching in encrypted rooms and secure storage. Skipping this step is fine, you just won't have those features.
|
||||
|
||||
Then, run
|
||||
|
||||
```
|
||||
pnpm run build
|
||||
```
|
||||
|
||||
This will do a couple of things:
|
||||
|
||||
- Run the `setversion` script to set the local package version to match whatever
|
||||
version of Element you installed above.
|
||||
- Run electron-builder to build a package. The package built will match the operating system
|
||||
you're running the build process on.
|
||||
|
||||
## Docker
|
||||
|
||||
Alternatively, you can also build using docker, which will always produce the linux package:
|
||||
|
||||
```
|
||||
# Run this once to make the docker image
|
||||
pnpm run docker:setup
|
||||
|
||||
pnpm run docker:install
|
||||
# if you want to build the native modules (this will take a while)
|
||||
pnpm run docker:build:native
|
||||
pnpm run docker:build
|
||||
```
|
||||
|
||||
After running, the packages should be in `dist/`.
|
||||
|
||||
# Starting
|
||||
|
||||
If you'd just like to run the electron app locally for development:
|
||||
|
||||
```
|
||||
pnpm start
|
||||
```
|
||||
|
||||
# Config
|
||||
|
||||
If you'd like the packaged Element to have a configuration file, you can create a
|
||||
config directory and place `config.json` in there, then specify this directory
|
||||
with the `--cfgdir` option to `pnpm run fetch`, eg:
|
||||
|
||||
```
|
||||
mkdir myconfig
|
||||
cp /path/to/my/config.json myconfig/
|
||||
pnpm run fetch --cfgdir myconfig
|
||||
```
|
||||
|
||||
The config dir for the official Element app is in `element.io`. If you use this,
|
||||
your app will auto-update itself using builds from element.io.
|
||||
|
||||
# Profiles
|
||||
|
||||
To run multiple instances of the desktop app for different accounts, you can
|
||||
launch the executable with the `--profile` argument followed by a unique
|
||||
identifier, e.g `element-desktop --profile Work` for it to run a separate profile and
|
||||
not interfere with the default one.
|
||||
|
||||
Alternatively, a custom location for the profile data can be specified using the
|
||||
`--profile-dir` flag followed by the desired path.
|
||||
|
||||
# User-specified config.json
|
||||
|
||||
- `%APPDATA%\$NAME\config.json` on Windows
|
||||
- `$XDG_CONFIG_HOME/$NAME/config.json` or `~/.config/$NAME/config.json` on Linux
|
||||
- `~/Library/Application Support/$NAME/config.json` on macOS
|
||||
|
||||
In the paths above, `$NAME` is typically `Element`, unless you use `--profile
|
||||
$PROFILE` in which case it becomes `Element-$PROFILE`, or it is using one of
|
||||
the above created by a pre-1.7 install, in which case it will be `Riot` or
|
||||
`Riot-$PROFILE`.
|
||||
|
||||
You may also specify a different path entirely for the `config.json` file by
|
||||
providing the `--config $YOUR_CONFIG_JSON_FILE` to the process, or via the
|
||||
`ELEMENT_DESKTOP_CONFIG_JSON` environment variable.
|
||||
|
||||
# Translations
|
||||
|
||||
To add a new translation, head to the [translating doc](https://github.com/vector-im/element-web/blob/develop/docs/translating.md).
|
||||
|
||||
For a developer guide, see the [translating dev doc](https://github.com/vector-im/element-web/blob/develop/docs/translating-dev.md).
|
||||
|
||||
# Report bugs & give feedback
|
||||
|
||||
If you run into any bugs or have feedback you'd like to share, please let us know on GitHub.
|
||||
|
||||
To help avoid duplicate issues, please [view existing issues](https://github.com/vector-im/element-web/issues?q=is%3Aopen+is%3Aissue+sort%3Areactions-%2B1-desc) first (and add a +1) or [create a new issue](https://github.com/vector-im/element-web/issues/new/choose) if you can't find it. Please note that this issue tracker is associated with the [element-web](https://github.com/vector-im/element-web) repo, but is also applied to the code in this repo as well.
|
||||
|
||||
## Copyright & License
|
||||
|
||||
Copyright (c) 2016-2017 OpenMarket Ltd
|
||||
|
||||
Copyright (c) 2017 Vector Creations Ltd
|
||||
|
||||
Copyright (c) 2017-2025 New Vector Ltd
|
||||
|
||||
This software is multi licensed by New Vector Ltd (Element). It can be used either:
|
||||
|
||||
(1) for free under the terms of the GNU Affero General Public License (as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version); OR
|
||||
|
||||
(2) for free under the terms of the GNU General Public License (as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version); OR
|
||||
|
||||
(3) under the terms of a paid-for Element Commercial License agreement between you and Element (the terms of which may vary depending on what you and Element have agreed to).
|
||||
Unless required by applicable law or agreed to in writing, software distributed under the Licenses is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the Licenses for the specific language governing permissions and limitations under the Licenses.
|
||||
@@ -1,3 +0,0 @@
|
||||
module.exports = {
|
||||
presets: [["@babel/preset-env", { targets: { node: "current" } }], "@babel/preset-typescript"],
|
||||
};
|
||||
@@ -1,28 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<!-- Entitlements from electron-builder's defaults
|
||||
(https://github.com/electron-userland/electron-builder/blob/master/packages/app-builder-lib/templates/entitlements.mac.plist)
|
||||
nb. This does *not* include the app sandbox: at the time of adding this file,
|
||||
we were using electron-builder 21.2.0 which does not have the sandbox entitlement.
|
||||
Latest electron-builder does, but it appears to be causing issues:
|
||||
(https://github.com/electron-userland/electron-builder/issues/4390)
|
||||
-->
|
||||
|
||||
<!-- https://github.com/electron/electron-notarize#prerequisites -->
|
||||
<key>com.apple.security.cs.allow-jit</key>
|
||||
<true/>
|
||||
|
||||
<!-- https://github.com/electron-userland/electron-builder/issues/3940 -->
|
||||
<key>com.apple.security.cs.disable-library-validation</key>
|
||||
<true/>
|
||||
|
||||
<!-- Our own additional entitlements (we need to access the camera and
|
||||
mic for VoIP calls -->
|
||||
<key>com.apple.security.device.camera</key>
|
||||
<true/>
|
||||
<key>com.apple.security.device.audio-input</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</plist>
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 34 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 315 KiB |
@@ -1,27 +0,0 @@
|
||||
{
|
||||
"fill": "automatic",
|
||||
"groups": [
|
||||
{
|
||||
"layers": [
|
||||
{
|
||||
"glass": false,
|
||||
"image-name": "element.png",
|
||||
"name": "element"
|
||||
}
|
||||
],
|
||||
"name": "Figma",
|
||||
"shadow": {
|
||||
"kind": "none",
|
||||
"opacity": 0.5
|
||||
},
|
||||
"specular": false,
|
||||
"translucency": {
|
||||
"enabled": false,
|
||||
"value": 0.5
|
||||
}
|
||||
}
|
||||
],
|
||||
"supported-platforms": {
|
||||
"squares": ["macOS"]
|
||||
}
|
||||
}
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 35 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 256 KiB |
@@ -1,26 +0,0 @@
|
||||
# Docker image to facilitate building Element Desktop's native bits using a glibc version (2.31)
|
||||
# with broader compatibility, down to Debian bullseye & Ubuntu focal.
|
||||
|
||||
FROM rust:bullseye@sha256:28afaeb8445f2a2e7d878bd34ed39ba02bb517efb29986188cbd59b7cf4f2fdf
|
||||
|
||||
ENV DEBIAN_FRONTEND=noninteractive
|
||||
|
||||
RUN apt-get -qq update && apt-get -y -qq dist-upgrade && \
|
||||
apt-get -y -qq install --no-install-recommends \
|
||||
# tclsh is required for building SQLite as part of SQLCipher
|
||||
tcl \
|
||||
# Used by seshat (when not SQLCIPHER_STATIC) \
|
||||
libsqlcipher-dev && \
|
||||
apt-get purge -y --auto-remove && rm -rf /var/lib/apt/lists/*
|
||||
RUN ln -s /usr/bin/python3 /usr/bin/python & ln -s /usr/bin/pip3 /usr/bin/pip
|
||||
|
||||
ENV DEBUG_COLORS=true
|
||||
ENV FORCE_COLOR=true
|
||||
ENV COREPACK_ENABLE_DOWNLOAD_PROMPT=0
|
||||
|
||||
WORKDIR /project/apps/desktop
|
||||
|
||||
ARG TARGETOS
|
||||
ARG TARGETARCH
|
||||
COPY .node-version dockerbuild/setup.sh /
|
||||
RUN /setup.sh
|
||||
@@ -1,12 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -x
|
||||
declare -A archMap=(["amd64"]="x64" ["arm64"]="arm64")
|
||||
ARCH="${archMap["$TARGETARCH"]}"
|
||||
# The .node-version file generally doesn't have the 'v' (renovate does not put the 'v' and will
|
||||
# strip it on upgrade if it's there) but the 'v' is also widely supported so we probably ought
|
||||
# to just work either way.
|
||||
NODE_VERSION=$(cat /.node-version | sed -e 's/^v//')
|
||||
curl --proto "=https" -L "https://nodejs.org/dist/v$NODE_VERSION/node-v$NODE_VERSION-$TARGETOS-$ARCH.tar.gz" | tar xz -C /usr/local --strip-components=1 && \
|
||||
unlink /usr/local/CHANGELOG.md && unlink /usr/local/LICENSE && unlink /usr/local/README.md
|
||||
corepack enable
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user