mirror of
https://github.com/element-hq/element-web.git
synced 2025-12-09 01:30:57 +00:00
Compare commits
1 Commits
hs/user-pr
...
t3chguy/no
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a52d4aed9f |
@@ -7,6 +7,3 @@ 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
|
||||
|
||||
@@ -1,8 +1,16 @@
|
||||
# Copyright 2024 New Vector Ltd.
|
||||
# Copyright 2017 Aviral Dasgupta
|
||||
#
|
||||
# SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only
|
||||
# Please see LICENSE files in the repository root for full details.
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
root = true
|
||||
|
||||
@@ -15,10 +23,7 @@ indent_size = 4
|
||||
trim_trailing_whitespace = true
|
||||
|
||||
[*.{yml,yaml}]
|
||||
indent_size = 4
|
||||
indent_size = 2
|
||||
|
||||
[package.json]
|
||||
indent_size = 4
|
||||
|
||||
[*.tsx.snap]
|
||||
trim_trailing_whitespace = false
|
||||
indent_size = 2
|
||||
|
||||
16
.env.example
Normal file
16
.env.example
Normal file
@@ -0,0 +1,16 @@
|
||||
# To enable CSS hot-reload, set the following variable to 1.
|
||||
CSS_HOT_RELOAD=1
|
||||
# To use the full page error dialog, set this to 1. Please report false positives to
|
||||
# the issue tracker for handling.
|
||||
FULL_PAGE_ERRORS=0
|
||||
# To use a single theme, uncomment the line with the theme you want to hot-reload.
|
||||
MATRIX_THEMES='light'
|
||||
#MATRIX_THEMES='dark'
|
||||
#MATRIX_THEMES='legacy-light'
|
||||
#MATRIX_THEMES='legacy-dark'
|
||||
#MATRIX_THEMES='light-custom'
|
||||
#MATRIX_THEMES='dark-custom'
|
||||
# You can also enable multiple themes by using a comma-separated list.
|
||||
# When multiple themes are enabled, switching between them may require a full page reload.
|
||||
# Note that compilation times are proportional to the number of enabled themes.
|
||||
#MATRIX_THEMES='light,dark'
|
||||
@@ -1,13 +1,5 @@
|
||||
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
|
||||
src/modules.js
|
||||
# Test result files
|
||||
/playwright/test-results/
|
||||
/playwright/html-report/
|
||||
|
||||
416
.eslintrc.js
416
.eslintrc.js
@@ -1,374 +1,72 @@
|
||||
module.exports = {
|
||||
plugins: ["matrix-org", "eslint-plugin-react-compiler"],
|
||||
plugins: ["matrix-org"],
|
||||
extends: [
|
||||
"plugin:matrix-org/babel",
|
||||
"plugin:matrix-org/react",
|
||||
"plugin:matrix-org/a11y",
|
||||
"plugin:storybook/recommended",
|
||||
],
|
||||
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(
|
||||
["React.forwardRef", "*.forwardRef", "forwardRef"],
|
||||
"Use ref props 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.",
|
||||
},
|
||||
{
|
||||
name: "Buffer",
|
||||
message: "Buffer is not available in the web.",
|
||||
},
|
||||
],
|
||||
|
||||
"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: "react",
|
||||
importNames: ["forwardRef"],
|
||||
message: "Use ref props instead.",
|
||||
},
|
||||
{
|
||||
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/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",
|
||||
|
||||
"react-compiler/react-compiler": "error",
|
||||
"quotes": "off",
|
||||
},
|
||||
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",
|
||||
"@typescript-eslint/no-empty-object-type": [
|
||||
"error",
|
||||
{
|
||||
// We do this sometimes to brand interfaces
|
||||
allowInterfaces: "with-single-extends",
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
// 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",
|
||||
"@typescript-eslint/no-empty-object-type": "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"],
|
||||
},
|
||||
],
|
||||
|
||||
// These are fine in tests
|
||||
"no-restricted-globals": "off",
|
||||
"react-compiler/react-compiler": "off",
|
||||
},
|
||||
},
|
||||
{
|
||||
files: ["playwright/**/*.ts"],
|
||||
parserOptions: {
|
||||
project: ["./playwright/tsconfig.json"],
|
||||
},
|
||||
rules: {
|
||||
"react-hooks/rules-of-hooks": ["off"],
|
||||
"@typescript-eslint/no-floating-promises": ["error"],
|
||||
},
|
||||
},
|
||||
{
|
||||
files: ["module_system/**/*.{ts,tsx}"],
|
||||
parserOptions: {
|
||||
project: ["./tsconfig.module_system.json"],
|
||||
},
|
||||
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",
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
],
|
||||
settings: {
|
||||
react: {
|
||||
version: "detect",
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
function buildRestrictedPropertiesOptions(properties, message) {
|
||||
return properties.map((prop) => {
|
||||
let [object, property] = prop.split(".");
|
||||
if (object === "*") {
|
||||
object = undefined;
|
||||
version: 'detect'
|
||||
}
|
||||
return {
|
||||
object,
|
||||
property,
|
||||
message,
|
||||
};
|
||||
});
|
||||
}
|
||||
},
|
||||
overrides: [{
|
||||
files: ["src/**/*.{ts,tsx}", "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",
|
||||
}, {
|
||||
"name": "matrix-react-sdk",
|
||||
"message": "Please use matrix-react-sdk/src/index instead",
|
||||
}, {
|
||||
"name": "matrix-react-sdk/",
|
||||
"message": "Please use matrix-react-sdk/src/index instead",
|
||||
}],
|
||||
"patterns": [{
|
||||
"group": ["matrix-js-sdk/lib", "matrix-js-sdk/lib/", "matrix-js-sdk/lib/**"],
|
||||
"message": "Please use matrix-js-sdk/src/* instead",
|
||||
}, {
|
||||
"group": ["matrix-react-sdk/lib", "matrix-react-sdk/lib/", "matrix-react-sdk/lib/**"],
|
||||
"message": "Please use matrix-react-sdk/src/* instead",
|
||||
}],
|
||||
}],
|
||||
},
|
||||
}],
|
||||
};
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
# prettier
|
||||
526645c79160ab1ad4b4c3845de27d51263a405e
|
||||
7921a6cbf86b035d2b0c1daecb4c24beaf5a5abc
|
||||
27
.github/CODEOWNERS
vendored
27
.github/CODEOWNERS
vendored
@@ -1,26 +1 @@
|
||||
* @element-hq/element-web-reviewers
|
||||
/.github/workflows/** @element-hq/element-web-team
|
||||
/package.json @element-hq/element-web-team
|
||||
/yarn.lock @element-hq/element-web-team
|
||||
|
||||
/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
|
||||
/src/components/views/settings/tabs/user/EncryptionUserSettingsTab.tsx @element-hq/element-crypto-web-reviewers
|
||||
/src/components/views/settings/encryption/ @element-hq/element-crypto-web-reviewers
|
||||
/test/unit-tests/components/views/settings/encryption/ @element-hq/element-crypto-web-reviewers
|
||||
/src/components/views/dialogs/devtools/Crypto.tsx @element-hq/element-crypto-web-reviewers
|
||||
/playwright/e2e/crypto/ @element-hq/element-crypto-web-reviewers
|
||||
/playwright/e2e/settings/encryption-user-tab/ @element-hq/element-crypto-web-reviewers
|
||||
|
||||
# Ignore translations as those will be updated by GHA for Localazy download
|
||||
/src/i18n/strings
|
||||
/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
|
||||
/playwright/testcontainers/synapse.ts
|
||||
/playwright/testcontainers/mas.ts
|
||||
|
||||
* @vector-im/element-web
|
||||
|
||||
140
.github/ISSUE_TEMPLATE/bug-desktop.yml
vendored
140
.github/ISSUE_TEMPLATE/bug-desktop.yml
vendored
@@ -2,75 +2,75 @@ 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]
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
Thanks for taking the time to fill out this bug report!
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
Thanks for taking the time to fill out this bug report!
|
||||
|
||||
Please report security issues by email to security@matrix.org
|
||||
- type: textarea
|
||||
id: reproduction-steps
|
||||
attributes:
|
||||
label: Steps to reproduce
|
||||
description: Please attach screenshots, videos or logs if you can.
|
||||
placeholder: Tell us what you see!
|
||||
value: |
|
||||
1. Where are you starting? What can you see?
|
||||
2. What do you click?
|
||||
3. More steps…
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: result
|
||||
attributes:
|
||||
label: Outcome
|
||||
placeholder: Tell us what went wrong
|
||||
value: |
|
||||
#### What did you expect?
|
||||
Please report security issues by email to security@matrix.org
|
||||
- type: textarea
|
||||
id: reproduction-steps
|
||||
attributes:
|
||||
label: Steps to reproduce
|
||||
description: Please attach screenshots, videos or logs if you can.
|
||||
placeholder: Tell us what you see!
|
||||
value: |
|
||||
1. Where are you starting? What can you see?
|
||||
2. What do you click?
|
||||
3. More steps…
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: result
|
||||
attributes:
|
||||
label: Outcome
|
||||
placeholder: Tell us what went wrong
|
||||
value: |
|
||||
#### What did you expect?
|
||||
|
||||
#### What happened instead?
|
||||
validations:
|
||||
required: true
|
||||
- type: input
|
||||
id: os
|
||||
attributes:
|
||||
label: Operating system
|
||||
placeholder: Windows, macOS, Ubuntu, Arch Linux…
|
||||
validations:
|
||||
required: false
|
||||
- type: input
|
||||
id: version
|
||||
attributes:
|
||||
label: Application version
|
||||
description: You can find the version information in Settings -> Help & About.
|
||||
placeholder: e.g. Element version 1.7.34, olm version 3.2.3
|
||||
validations:
|
||||
required: false
|
||||
- type: input
|
||||
id: source
|
||||
attributes:
|
||||
label: How did you install the app?
|
||||
description: Where did you install the app from? Please give a link or a description.
|
||||
placeholder: e.g. From https://element.io/get-started
|
||||
validations:
|
||||
required: false
|
||||
- type: input
|
||||
id: homeserver
|
||||
attributes:
|
||||
label: Homeserver
|
||||
description: |
|
||||
Which server is your account registered on? If it is a local or non-public homeserver, please tell us what is the homeserver implementation (ex: Synapse/Dendrite/etc.) and the version.
|
||||
placeholder: e.g. matrix.org or Synapse 1.50.0rc1
|
||||
validations:
|
||||
required: false
|
||||
- type: dropdown
|
||||
id: rageshake
|
||||
attributes:
|
||||
label: Will you send logs?
|
||||
description: |
|
||||
Did you know that you can send a /rageshake command from your application to submit logs for this issue? Trigger the defect, then type `/rageshake` into the message input area followed by a description of the problem and send the command. You will be able to add a link to this defect report and submit anonymous logs to the developers.
|
||||
options:
|
||||
- "Yes"
|
||||
- "No"
|
||||
validations:
|
||||
required: true
|
||||
#### What happened instead?
|
||||
validations:
|
||||
required: true
|
||||
- type: input
|
||||
id: os
|
||||
attributes:
|
||||
label: Operating system
|
||||
placeholder: Windows, macOS, Ubuntu, Arch Linux…
|
||||
validations:
|
||||
required: false
|
||||
- type: input
|
||||
id: version
|
||||
attributes:
|
||||
label: Application version
|
||||
description: You can find the version information in Settings -> Help & About.
|
||||
placeholder: e.g. Element version 1.7.34, olm version 3.2.3
|
||||
validations:
|
||||
required: false
|
||||
- type: input
|
||||
id: source
|
||||
attributes:
|
||||
label: How did you install the app?
|
||||
description: Where did you install the app from? Please give a link or a description.
|
||||
placeholder: e.g. From https://element.io/get-started
|
||||
validations:
|
||||
required: false
|
||||
- type: input
|
||||
id: homeserver
|
||||
attributes:
|
||||
label: Homeserver
|
||||
description: |
|
||||
Which server is your account registered on? If it is a local or non-public homeserver, please tell us what is the homeserver implementation (ex: Synapse/Dendrite/etc.) and the version.
|
||||
placeholder: e.g. matrix.org or Synapse 1.50.0rc1
|
||||
validations:
|
||||
required: false
|
||||
- type: dropdown
|
||||
id: rageshake
|
||||
attributes:
|
||||
label: Will you send logs?
|
||||
description: |
|
||||
Did you know that you can send a /rageshake command from your application to submit logs for this issue? Trigger the defect, then type `/rageshake` into the message input area followed by a description of the problem and send the command. You will be able to add a link to this defect report and submit anonymous logs to the developers.
|
||||
options:
|
||||
- 'Yes'
|
||||
- 'No'
|
||||
validations:
|
||||
required: true
|
||||
|
||||
156
.github/ISSUE_TEMPLATE/bug-web.yml
vendored
156
.github/ISSUE_TEMPLATE/bug-web.yml
vendored
@@ -2,83 +2,83 @@ name: Bug report for Element Web (in browser)
|
||||
description: File a bug report if you are using Element in a web browser like Firefox, Chrome, Edge, and so on.
|
||||
labels: [T-Defect]
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
Thanks for taking the time to fill out this bug report!
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
Thanks for taking the time to fill out this bug report!
|
||||
|
||||
Please report security issues by email to security@matrix.org
|
||||
- type: textarea
|
||||
id: reproduction-steps
|
||||
attributes:
|
||||
label: Steps to reproduce
|
||||
description: Please attach screenshots, videos or logs if you can.
|
||||
placeholder: Tell us what you see!
|
||||
value: |
|
||||
1. Where are you starting? What can you see?
|
||||
2. What do you click?
|
||||
3. More steps…
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: result
|
||||
attributes:
|
||||
label: Outcome
|
||||
placeholder: Tell us what went wrong
|
||||
value: |
|
||||
#### What did you expect?
|
||||
Please report security issues by email to security@matrix.org
|
||||
- type: textarea
|
||||
id: reproduction-steps
|
||||
attributes:
|
||||
label: Steps to reproduce
|
||||
description: Please attach screenshots, videos or logs if you can.
|
||||
placeholder: Tell us what you see!
|
||||
value: |
|
||||
1. Where are you starting? What can you see?
|
||||
2. What do you click?
|
||||
3. More steps…
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: result
|
||||
attributes:
|
||||
label: Outcome
|
||||
placeholder: Tell us what went wrong
|
||||
value: |
|
||||
#### What did you expect?
|
||||
|
||||
#### What happened instead?
|
||||
validations:
|
||||
required: true
|
||||
- type: input
|
||||
id: os
|
||||
attributes:
|
||||
label: Operating system
|
||||
placeholder: Windows, macOS, Ubuntu, Arch Linux…
|
||||
validations:
|
||||
required: false
|
||||
- type: input
|
||||
id: browser
|
||||
attributes:
|
||||
label: Browser information
|
||||
description: Which browser are you using? Which version?
|
||||
placeholder: e.g. Chromium Version 92.0.4515.131
|
||||
validations:
|
||||
required: false
|
||||
- type: input
|
||||
id: webapp-url
|
||||
attributes:
|
||||
label: URL for webapp
|
||||
description: Which URL are you using to access the webapp? If a private server, tell us what version of Element Web you are using.
|
||||
placeholder: e.g. develop.element.io, app.element.io
|
||||
validations:
|
||||
required: false
|
||||
- type: input
|
||||
id: version
|
||||
attributes:
|
||||
label: Application version
|
||||
description: You can find the version information in Settings -> Help & About.
|
||||
placeholder: e.g. Element version 1.7.34, olm version 3.2.3
|
||||
validations:
|
||||
required: false
|
||||
- type: input
|
||||
id: homeserver
|
||||
attributes:
|
||||
label: Homeserver
|
||||
description: |
|
||||
Which server is your account registered on? If it is a local or non-public homeserver, please tell us what is the homeserver implementation (ex: Synapse/Dendrite/etc.) and the version.
|
||||
placeholder: e.g. matrix.org or Synapse 1.50.0rc1
|
||||
validations:
|
||||
required: false
|
||||
- type: dropdown
|
||||
id: rageshake
|
||||
attributes:
|
||||
label: Will you send logs?
|
||||
description: |
|
||||
Did you know that you can send a /rageshake command from the web application to submit logs for this issue? Trigger the defect, then type `/rageshake` into the message input area followed by a description of the problem and send the command. You will be able to add a link to this defect report and submit anonymous logs to the developers.
|
||||
options:
|
||||
- "Yes"
|
||||
- "No"
|
||||
validations:
|
||||
required: true
|
||||
#### What happened instead?
|
||||
validations:
|
||||
required: true
|
||||
- type: input
|
||||
id: os
|
||||
attributes:
|
||||
label: Operating system
|
||||
placeholder: Windows, macOS, Ubuntu, Arch Linux…
|
||||
validations:
|
||||
required: false
|
||||
- type: input
|
||||
id: browser
|
||||
attributes:
|
||||
label: Browser information
|
||||
description: Which browser are you using? Which version?
|
||||
placeholder: e.g. Chromium Version 92.0.4515.131
|
||||
validations:
|
||||
required: false
|
||||
- type: input
|
||||
id: webapp-url
|
||||
attributes:
|
||||
label: URL for webapp
|
||||
description: Which URL are you using to access the webapp? If a private server, tell us what version of Element Web you are using.
|
||||
placeholder: e.g. develop.element.io, app.element.io
|
||||
validations:
|
||||
required: false
|
||||
- type: input
|
||||
id: version
|
||||
attributes:
|
||||
label: Application version
|
||||
description: You can find the version information in Settings -> Help & About.
|
||||
placeholder: e.g. Element version 1.7.34, olm version 3.2.3
|
||||
validations:
|
||||
required: false
|
||||
- type: input
|
||||
id: homeserver
|
||||
attributes:
|
||||
label: Homeserver
|
||||
description: |
|
||||
Which server is your account registered on? If it is a local or non-public homeserver, please tell us what is the homeserver implementation (ex: Synapse/Dendrite/etc.) and the version.
|
||||
placeholder: e.g. matrix.org or Synapse 1.50.0rc1
|
||||
validations:
|
||||
required: false
|
||||
- type: dropdown
|
||||
id: rageshake
|
||||
attributes:
|
||||
label: Will you send logs?
|
||||
description: |
|
||||
Did you know that you can send a /rageshake command from the web application to submit logs for this issue? Trigger the defect, then type `/rageshake` into the message input area followed by a description of the problem and send the command. You will be able to add a link to this defect report and submit anonymous logs to the developers.
|
||||
options:
|
||||
- 'Yes'
|
||||
- 'No'
|
||||
validations:
|
||||
required: true
|
||||
|
||||
6
.github/ISSUE_TEMPLATE/config.yml
vendored
6
.github/ISSUE_TEMPLATE/config.yml
vendored
@@ -1,5 +1,5 @@
|
||||
blank_issues_enabled: false
|
||||
contact_links:
|
||||
- name: Questions & support
|
||||
url: https://matrix.to/#/#element-web:matrix.org
|
||||
about: Please ask and answer questions here.
|
||||
- name: Questions & support
|
||||
url: https://matrix.to/#/#element-web:matrix.org
|
||||
about: Please ask and answer questions here.
|
||||
|
||||
60
.github/ISSUE_TEMPLATE/enhancement.yml
vendored
60
.github/ISSUE_TEMPLATE/enhancement.yml
vendored
@@ -2,35 +2,35 @@ name: Enhancement request
|
||||
description: Do you have a suggestion or feature request?
|
||||
labels: [T-Enhancement]
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
Thank you for taking the time to propose an enhancement to an existing feature. If you would like to propose a new feature or a major cross-platform change, please [start a discussion here](https://github.com/element-hq/element-meta/discussions/new?category=ideas).
|
||||
- type: textarea
|
||||
id: usecase
|
||||
attributes:
|
||||
label: Your use case
|
||||
description: What would you like to be able to do? Please feel welcome to include screenshots or mock ups.
|
||||
placeholder: Tell us what you would like to do!
|
||||
value: |
|
||||
#### What would you like to do?
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
Thank you for taking the time to propose a new feature or make a suggestion.
|
||||
- type: textarea
|
||||
id: usecase
|
||||
attributes:
|
||||
label: Your use case
|
||||
description: What would you like to be able to do? Please feel welcome to include screenshots or mock ups.
|
||||
placeholder: Tell us what you would like to do!
|
||||
value: |
|
||||
#### What would you like to do?
|
||||
|
||||
#### Why would you like to do it?
|
||||
#### Why would you like to do it?
|
||||
|
||||
#### How would you like to achieve it?
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: alternative
|
||||
attributes:
|
||||
label: Have you considered any alternatives?
|
||||
placeholder: A clear and concise description of any alternative solutions or features you've considered.
|
||||
validations:
|
||||
required: false
|
||||
- type: textarea
|
||||
id: additional-context
|
||||
attributes:
|
||||
label: Additional context
|
||||
placeholder: Is there anything else you'd like to add?
|
||||
validations:
|
||||
required: false
|
||||
#### How would you like to achieve it?
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: alternative
|
||||
attributes:
|
||||
label: Have you considered any alternatives?
|
||||
placeholder: A clear and concise description of any alternative solutions or features you've considered.
|
||||
validations:
|
||||
required: false
|
||||
- type: textarea
|
||||
id: additional-context
|
||||
attributes:
|
||||
label: Additional context
|
||||
placeholder: Is there anything else you'd like to add?
|
||||
validations:
|
||||
required: false
|
||||
|
||||
18
.github/PULL_REQUEST_TEMPLATE.md
vendored
18
.github/PULL_REQUEST_TEMPLATE.md
vendored
@@ -2,7 +2,17 @@
|
||||
|
||||
## Checklist
|
||||
|
||||
- [ ] 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)
|
||||
* [ ] Linter and other CI checks pass
|
||||
* [ ] Sign-off given on the changes (see [CONTRIBUTING.md](https://github.com/vector-im/element-web/blob/develop/CONTRIBUTING.md))
|
||||
|
||||
<!--
|
||||
If you would like to specify text for the changelog entry other than your PR title, add the following:
|
||||
|
||||
Notes: Add super cool feature
|
||||
|
||||
For PRs which *only* affect the desktop version, please use:
|
||||
|
||||
Notes: none
|
||||
element-desktop notes: Add super cool feature
|
||||
-->
|
||||
|
||||
@@ -1,38 +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@daf26c55d821e836577a15f77d86ddc078948b05 # 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 ${{ inputs.out-file-path }}
|
||||
|
||||
- name: Clean up temp directory
|
||||
shell: bash
|
||||
run: rm -R ${{ runner.temp }}/download-verify-element-tarball
|
||||
16
.github/cfp_headers
vendored
16
.github/cfp_headers
vendored
@@ -1,16 +0,0 @@
|
||||
/*
|
||||
! Access-Control-Allow-Origin
|
||||
X-XSS-Protection: 1; mode=block
|
||||
X-Content-Type-Options: nosniff
|
||||
X-Frame-Options: SAMEORIGIN
|
||||
Content-Security-Policy: frame-ancestors 'self'
|
||||
Strict-Transport-Security: max-age=31536000; includeSubDomains; preload
|
||||
|
||||
/version
|
||||
Content-Type: text/plain
|
||||
|
||||
/apple-app-site-association
|
||||
Content-Type: application/json
|
||||
|
||||
/.well-known/assetlinks.json
|
||||
Content-Type: application/json
|
||||
281
.github/labels.yml
vendored
281
.github/labels.yml
vendored
@@ -1,281 +0,0 @@
|
||||
- name: "A-Aliases"
|
||||
color: "bfd4f2"
|
||||
- name: "A-Authentication"
|
||||
color: "bfd4f2"
|
||||
- name: "A-Autocomplete"
|
||||
color: "bfd4f2"
|
||||
- name: "A-Breadcrumbs"
|
||||
color: "bfd4f2"
|
||||
- name: "A-Bridge"
|
||||
color: "bfd4f2"
|
||||
- name: "A-Broadcast"
|
||||
description: "Broadcast-style voice messages"
|
||||
color: "bfd4f2"
|
||||
- name: "A-Create-Room"
|
||||
description: "Create room flow, user suggestions, etc."
|
||||
color: "bfd4f2"
|
||||
- name: "A-DevTools"
|
||||
description: "/devtools, show hidden events, etc."
|
||||
color: "bfd4f2"
|
||||
- name: "A-Dialogs"
|
||||
color: "bfd4f2"
|
||||
- name: "A-Disambiguation"
|
||||
color: "bfd4f2"
|
||||
- name: "A-DM-Start"
|
||||
description: "Creating a DM with another user"
|
||||
color: "bfd4f2"
|
||||
- name: "A-E2EE-Dehydration"
|
||||
color: "8CC59A"
|
||||
- name: "A-Electron"
|
||||
color: "bfd4f2"
|
||||
- name: "A-Element-Call"
|
||||
description: "Group calls via Element Call"
|
||||
color: "bfd4f2"
|
||||
- name: "A-Element-R"
|
||||
description: "Issues affecting the port of Element's crypto layer to Rust"
|
||||
color: "bfd4f2"
|
||||
- name: "A-ELS"
|
||||
description: "Event List Summary (and Membership ELS, MELS)"
|
||||
color: "bfd4f2"
|
||||
- name: "A-Emotes"
|
||||
color: "bfd4f2"
|
||||
- name: "A-EMS"
|
||||
description: "Issues related to EMS"
|
||||
color: "bfd4f2"
|
||||
- name: "A-Error-Message"
|
||||
color: "bfd4f2"
|
||||
- name: "A-Federation"
|
||||
color: "bfd4f2"
|
||||
- name: "A-Feedback-Reporting"
|
||||
description: "Reporting process for bugs, debug logs (rageshakes), suggestions"
|
||||
color: "bfd4f2"
|
||||
- name: "A-File-Download"
|
||||
color: "bfd4f2"
|
||||
- name: "A-File-Panel"
|
||||
color: "bfd4f2"
|
||||
- name: "A-Identity-Server"
|
||||
color: "bfd4f2"
|
||||
- name: "A-Indexing"
|
||||
description: "Indexing messages via Seshat"
|
||||
color: "bfd4f2"
|
||||
- name: "A-IRC-Layout"
|
||||
color: "bfd4f2"
|
||||
- name: "A-Jump-To-Date"
|
||||
description: "Jump to date headers or slash command"
|
||||
color: "bfd4f2"
|
||||
- name: "A-Lazy-Loading"
|
||||
color: "bfd4f2"
|
||||
- name: "A-Light-Box"
|
||||
description: "UI when viewing an image"
|
||||
color: "bfd4f2"
|
||||
- name: "A-Location-Sharing"
|
||||
color: "bfd4f2"
|
||||
- name: "A-Logout"
|
||||
description: "Logout, sign out, etc."
|
||||
color: "bfd4f2"
|
||||
- name: "A-Maths"
|
||||
description: "Render LaTeX maths in messages"
|
||||
color: "bfd4f2"
|
||||
- name: "A-Memory"
|
||||
description: "Memory leaks, leak hunting tools"
|
||||
color: "bfd4f2"
|
||||
- name: "A-Message-Forwarding"
|
||||
color: "bfd4f2"
|
||||
- name: "A-Message-Pinning"
|
||||
color: "bfd4f2"
|
||||
- name: "A-Message-Previews"
|
||||
color: "bfd4f2"
|
||||
- name: "A-Message-Starring"
|
||||
description: "Saving favourite messages for later"
|
||||
color: "bfd4f2"
|
||||
- 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"
|
||||
- name: "A-Peeking"
|
||||
color: "bfd4f2"
|
||||
- name: "A-Picture-in-Picture"
|
||||
color: "bfd4f2"
|
||||
- name: "A-Power-Levels"
|
||||
description: "The permissions that users have in rooms and spaces"
|
||||
color: "bfd4f2"
|
||||
- name: "A-Replies"
|
||||
description: "reply"
|
||||
color: "bfd4f2"
|
||||
- name: "A-Session-Mgmt"
|
||||
description: "Session / device names, management UI, etc."
|
||||
color: "bfd4f2"
|
||||
- name: "A-Share"
|
||||
color: "bfd4f2"
|
||||
- name: "A-Shortcuts"
|
||||
description: "Keyboard shortcuts"
|
||||
color: "bfd4f2"
|
||||
- name: "A-Sliding-Sync"
|
||||
description: "Also known as Sync v3 - https://github.com/matrix-org/sliding-sync"
|
||||
color: "bfd4f2"
|
||||
- name: "A-Soft-Logout"
|
||||
description: "https://github.com/element-hq/element-web/issues/10224"
|
||||
color: "bfd4f2"
|
||||
- name: "A-Spaces-Settings"
|
||||
color: "bfd4f2"
|
||||
- name: "A-SSO"
|
||||
color: "bfd4f2"
|
||||
- name: "A-Status-Bar"
|
||||
description: "Unsent messages warning and 'Connectivity to the server has been lost'"
|
||||
color: "bfd4f2"
|
||||
- name: "A-Storage"
|
||||
description: "Storage layer of the app, including IndexedDB, local storage, etc."
|
||||
color: "bfd4f2"
|
||||
- name: "A-Technical-Debt"
|
||||
color: "bfd4f2"
|
||||
- name: "A-Testing"
|
||||
description: "Testing, code coverage, etc."
|
||||
color: "bfd4f2"
|
||||
- name: "A-Themes-Custom"
|
||||
description: "Custom theme variables or support"
|
||||
color: "bfd4f2"
|
||||
- name: "A-Themes-Official"
|
||||
description: "Official themes (light, dark)"
|
||||
color: "bfd4f2"
|
||||
- name: "A-Theming"
|
||||
color: "bfd4f2"
|
||||
- name: "A-Timeline-Jumpy-Scroll"
|
||||
description: "Stable timeline dream ✨"
|
||||
color: "bfd4f2"
|
||||
- name: "A-Timesheet-1"
|
||||
description: "Log any time spent on this into the A-Timesheet-1 project"
|
||||
color: "5319E7"
|
||||
- name: "A-Toast"
|
||||
color: "bfd4f2"
|
||||
- name: "A-Tooltips"
|
||||
description: "Anything related to tooltips"
|
||||
color: "bfd4f2"
|
||||
- name: "A-UI-Customisation"
|
||||
description: "UIFeatures etc. for customising entire parts of the UI"
|
||||
color: "bfd4f2"
|
||||
- name: "A-URL-Previews"
|
||||
color: "bfd4f2"
|
||||
- name: "A-User-Menu"
|
||||
description: "The top left main menu with the user's name and avatar"
|
||||
color: "bfd4f2"
|
||||
- name: "A-User-Search"
|
||||
description: "The start DM or invite to room dialogs (things dealing with `/user_directory/search`)"
|
||||
color: "bfd4f2"
|
||||
- name: "A-Video-Rooms"
|
||||
description: "Persistent group calls"
|
||||
color: "bfd4f2"
|
||||
- name: "A-Voice-Messages"
|
||||
color: "bfd4f2"
|
||||
- name: "A-Welcome-Page"
|
||||
color: "bfd4f2"
|
||||
- name: "backport staging"
|
||||
description: "Label to automatically backport PR to staging branch"
|
||||
color: "B60205"
|
||||
- name: "Dependencies"
|
||||
description: "Pull requests that update a dependency file"
|
||||
color: "0366d6"
|
||||
- name: "Hacktoberfest"
|
||||
description: "Issues which are suitable for Hacktoberfest PRs: https://hacktoberfest.digitalocean.com/"
|
||||
color: "ff7518"
|
||||
- name: "P4"
|
||||
description: "[OBSOLETE LABEL] Interesting — Not yet scheduled, will accept patches"
|
||||
color: "d1e5f0"
|
||||
- name: "spam"
|
||||
color: "B60205"
|
||||
- name: "Sponsored"
|
||||
color: "ffc8f4"
|
||||
- name: "T-Deprecation"
|
||||
description: "A pull request that makes something deprecated"
|
||||
color: "98e6ae"
|
||||
- name: "T-Other"
|
||||
description: "Questions, user support, anything else"
|
||||
color: "98e6ae"
|
||||
- name: "Team: App"
|
||||
color: "FFA500"
|
||||
- name: "X-Blocked"
|
||||
color: "ff7979"
|
||||
- name: "X-Cannot-Reproduce"
|
||||
color: "ff7979"
|
||||
- name: "X-Command"
|
||||
description: "Created using the !github command"
|
||||
color: "ff7979"
|
||||
- name: "X-Community-Supported-Platform"
|
||||
description: "This issue occurs in a platform not directly supported by us, but by a community project elsewhere"
|
||||
color: "ff7979"
|
||||
- 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"
|
||||
description: "Related to internal cache (clearing helps / causes the issue)"
|
||||
color: "ededed"
|
||||
- name: "Z-Community-PR"
|
||||
description: "Issue is solved by a community member's PR"
|
||||
color: "ededed"
|
||||
- name: "Z-Element-R-Blocker"
|
||||
description: "A blocker for enabling Element R by default"
|
||||
color: "ededed"
|
||||
- name: "Z-Experimental"
|
||||
color: "ededed"
|
||||
- name: "Z-Fixed by Element Call"
|
||||
description: "Issues which can be closed when we move to Element Call"
|
||||
color: "ededed"
|
||||
- name: "Z-Fixed-By-OIDC"
|
||||
description: "Issues which can be closed when we move to OIDC"
|
||||
color: "ededed"
|
||||
- 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"
|
||||
- name: "Z-Gitter"
|
||||
description: "Issues relating to or coming out of the Gitter migration, feature parity, etc"
|
||||
color: "ededed"
|
||||
- name: "Z-Legacy-Crypto"
|
||||
description: "Issues affecting the legacy crypto stack"
|
||||
color: "EEEEEE"
|
||||
- name: "Z-Maximised-Widgets"
|
||||
color: "ededed"
|
||||
- name: "Z-Papercuts"
|
||||
description: "Visible. Impactful. Predictable to action."
|
||||
color: "ededed"
|
||||
- name: "Z-Power-Users"
|
||||
color: "ededed"
|
||||
- name: "Z-Rageshake"
|
||||
description: "Has attached rageshake (not for log submission process)"
|
||||
color: "ededed"
|
||||
- name: "Z-RICE"
|
||||
color: "ededed"
|
||||
- name: "Z-Soft-Crash"
|
||||
description: "React soft crash caught by an error boundary"
|
||||
color: "ededed"
|
||||
- name: "Z-Spec-Compliance"
|
||||
description: "An area where Element doesn't correctly implement the spec"
|
||||
color: "ededed"
|
||||
- name: "Z-t3chguy"
|
||||
color: "ededed"
|
||||
- name: "Z-Flaky-Test-Disabled"
|
||||
description: "The flaking test has been disabled"
|
||||
color: "ededed"
|
||||
3
.github/release-drafter.yml
vendored
3
.github/release-drafter.yml
vendored
@@ -1,3 +0,0 @@
|
||||
_extends: matrix-org/matrix-js-sdk
|
||||
version-resolver:
|
||||
default: patch
|
||||
6
.github/renovate.json
vendored
6
.github/renovate.json
vendored
@@ -1,4 +1,6 @@
|
||||
{
|
||||
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
|
||||
"extends": ["github>matrix-org/renovate-config-element-web"]
|
||||
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
|
||||
"extends": [
|
||||
"github>matrix-org/renovate-config-element-web"
|
||||
]
|
||||
}
|
||||
|
||||
54
.github/workflows/backport.yml
vendored
54
.github/workflows/backport.yml
vendored
@@ -1,32 +1,30 @@
|
||||
name: Backport
|
||||
on:
|
||||
pull_request_target:
|
||||
types:
|
||||
- closed
|
||||
- labeled
|
||||
branches:
|
||||
- develop
|
||||
|
||||
permissions: {} # We use ELEMENT_BOT_TOKEN instead
|
||||
pull_request_target:
|
||||
types:
|
||||
- closed
|
||||
- labeled
|
||||
branches:
|
||||
- develop
|
||||
|
||||
jobs:
|
||||
backport:
|
||||
name: Backport
|
||||
runs-on: ubuntu-24.04
|
||||
# Only react to merged PRs for security reasons.
|
||||
# See https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#pull_request_target.
|
||||
if: >
|
||||
github.event.pull_request.merged
|
||||
&& (
|
||||
github.event.action == 'closed'
|
||||
|| (
|
||||
github.event.action == 'labeled'
|
||||
&& contains(github.event.label.name, 'backport')
|
||||
)
|
||||
)
|
||||
steps:
|
||||
- uses: tibdex/backport@9565281eda0731b1d20c4025c43339fb0a23812e # v2
|
||||
with:
|
||||
labels_template: "<%= JSON.stringify([...labels, 'X-Release-Blocker']) %>"
|
||||
# We can't use GITHUB_TOKEN here or CI won't run on the new PR
|
||||
github_token: ${{ secrets.ELEMENT_BOT_TOKEN }}
|
||||
backport:
|
||||
name: Backport
|
||||
runs-on: ubuntu-latest
|
||||
# Only react to merged PRs for security reasons.
|
||||
# See https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#pull_request_target.
|
||||
if: >
|
||||
github.event.pull_request.merged
|
||||
&& (
|
||||
github.event.action == 'closed'
|
||||
|| (
|
||||
github.event.action == 'labeled'
|
||||
&& contains(github.event.label.name, 'backport')
|
||||
)
|
||||
)
|
||||
steps:
|
||||
- uses: tibdex/backport@v2
|
||||
with:
|
||||
labels_template: "<%= JSON.stringify([...labels, 'X-Release-Blocker']) %>"
|
||||
# We can't use GITHUB_TOKEN here or CI won't run on the new PR
|
||||
github_token: ${{ secrets.ELEMENT_BOT_TOKEN }}
|
||||
|
||||
95
.github/workflows/build.yml
vendored
95
.github/workflows/build.yml
vendored
@@ -1,84 +1,27 @@
|
||||
name: Build
|
||||
on:
|
||||
pull_request: {}
|
||||
push:
|
||||
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' }}
|
||||
pull_request: { }
|
||||
push:
|
||||
branches: [ master ]
|
||||
# develop pushes and repository_dispatch handled in build_develop.yaml
|
||||
env:
|
||||
# These must be set for fetchdep.sh to get the right branch
|
||||
REPOSITORY: ${{ github.repository }}
|
||||
PR_NUMBER: ${{ github.event.pull_request.number }}
|
||||
permissions: {} # No permissions required
|
||||
# These must be set for fetchdep.sh to get the right branch
|
||||
REPOSITORY: ${{ github.repository }}
|
||||
PR_NUMBER: ${{ github.event.pull_request.number }}
|
||||
jobs:
|
||||
build:
|
||||
name: "Build on ${{ matrix.image }}"
|
||||
# We build on all 3 platforms to ensure we don't have any OS-specific build incompatibilities
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
image:
|
||||
- ubuntu-24.04
|
||||
- windows-2022
|
||||
- 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@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5
|
||||
build:
|
||||
name: "Build"
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
|
||||
- uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # 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' && 'yarn' || '' }}
|
||||
node-version: "lts/*"
|
||||
- uses: actions/setup-node@v3
|
||||
with:
|
||||
cache: 'yarn'
|
||||
node-version: 16
|
||||
|
||||
# Workaround for yarn install timeouts, especially on Windows
|
||||
- run: yarn config set network-timeout 300000
|
||||
- name: Install Dependencies
|
||||
run: "./scripts/layered.sh"
|
||||
|
||||
- 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
|
||||
|
||||
- name: Upload Artifact
|
||||
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
|
||||
with:
|
||||
name: webapp-${{ matrix.image }}
|
||||
path: webapp
|
||||
retention-days: 1
|
||||
- name: Build
|
||||
run: "yarn build"
|
||||
|
||||
79
.github/workflows/build_debian.yaml
vendored
79
.github/workflows/build_debian.yaml
vendored
@@ -1,79 +0,0 @@
|
||||
name: Build Debian package
|
||||
on:
|
||||
release:
|
||||
types: [published]
|
||||
concurrency: ${{ github.workflow }}
|
||||
permissions: {} # We use ELEMENT_BOT_TOKEN instead
|
||||
jobs:
|
||||
build:
|
||||
name: Build package
|
||||
environment: packages.element.io
|
||||
runs-on: ubuntu-24.04
|
||||
env:
|
||||
R2_INCOMING_BUCKET: ${{ vars.R2_INCOMING_BUCKET }}
|
||||
R2_URL: ${{ vars.CF_R2_S3_API }}
|
||||
VERSION: ${{ github.ref_name }}
|
||||
steps:
|
||||
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5
|
||||
|
||||
- name: Download package
|
||||
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
|
||||
run: |
|
||||
wget "https://packages.element.io/element-release-key.gpg"
|
||||
gpg --import element-release-key.gpg
|
||||
gpg --fingerprint "$FINGERPRINT"
|
||||
gpg --verify "element-$VERSION.tar.gz.asc" "element-$VERSION.tar.gz"
|
||||
env:
|
||||
FINGERPRINT: ${{ vars.GPG_FINGERPRINT }}
|
||||
|
||||
- name: Prepare
|
||||
run: |
|
||||
mkdir -p debian/tmp/DEBIAN
|
||||
find debian -maxdepth 1 -type f -exec cp "{}" debian/tmp/DEBIAN/ \;
|
||||
mkdir -p debian/tmp/usr/share/element-web/ debian/tmp/etc/element-web/
|
||||
|
||||
tar -xf "element-$VERSION.tar.gz" -C debian/tmp/usr/share/element-web --strip-components=1 --no-same-owner --no-same-permissions
|
||||
mv debian/tmp/usr/share/element-web/config.sample.json debian/tmp/etc/element-web/config.json
|
||||
ln -s /etc/element-web/config.json debian/tmp/usr/share/element-web/config.json
|
||||
|
||||
- name: Write changelog
|
||||
run: |
|
||||
VERSION=$(cat package.json | jq -r .version)
|
||||
TIME=$(date -d "$PUBLISHED_AT" -R)
|
||||
{
|
||||
echo "element-web ($VERSION) default; urgency=medium"
|
||||
echo "$BODY" | sed 's/^##/\n */g;s/^\*/ */g' | perl -pe 's/\[.+?]\((.+?)\)/\1/g'
|
||||
echo ""
|
||||
echo " -- $ACTOR <support@element.io> $TIME"
|
||||
} > debian/tmp/DEBIAN/changelog
|
||||
env:
|
||||
ACTOR: ${{ github.actor }}
|
||||
VERSION: ${{ github.event.release.tag_name }}
|
||||
BODY: ${{ github.event.release.body }}
|
||||
PUBLISHED_AT: ${{ github.event.release.published_at }}
|
||||
|
||||
- name: Build deb package
|
||||
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@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
|
||||
with:
|
||||
name: 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
|
||||
with:
|
||||
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 }}
|
||||
bucket-access-key: ${{ secrets.CF_R2_TOKEN }}
|
||||
174
.github/workflows/build_develop.yml
vendored
174
.github/workflows/build_develop.yml
vendored
@@ -1,132 +1,62 @@
|
||||
# Separate to the main build workflow for access to develop
|
||||
# environment secrets, largely similar to build.yaml.
|
||||
name: Build and Deploy develop
|
||||
name: Build and Package develop
|
||||
on:
|
||||
push:
|
||||
branches: [develop]
|
||||
repository_dispatch:
|
||||
types: [element-web-notify]
|
||||
push:
|
||||
branches: [ develop ]
|
||||
repository_dispatch:
|
||||
types: [ element-web-notify ]
|
||||
concurrency:
|
||||
group: ${{ github.repository_owner }}-${{ github.workflow }}-${{ github.ref_name }}
|
||||
cancel-in-progress: true
|
||||
permissions: {}
|
||||
group: ${{ github.workflow }}-${{ github.event.workflow_run.head_branch }}
|
||||
cancel-in-progress: true
|
||||
jobs:
|
||||
build:
|
||||
name: "Build & Deploy develop.element.io"
|
||||
# Only respect triggers from our develop branch, ignore that of forks
|
||||
if: github.repository == 'element-hq/element-web'
|
||||
runs-on: ubuntu-24.04
|
||||
environment: develop
|
||||
permissions:
|
||||
checks: read
|
||||
pages: write
|
||||
deployments: write
|
||||
build:
|
||||
name: "Build & Upload source maps to Sentry"
|
||||
# Only respect triggers from our develop branch, ignore that of forks
|
||||
if: github.repository == 'vector-im/element-web'
|
||||
runs-on: ubuntu-latest
|
||||
environment: develop
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
|
||||
- uses: actions/setup-node@v3
|
||||
with:
|
||||
cache: 'yarn'
|
||||
node-version: 16
|
||||
|
||||
- name: Install Dependencies
|
||||
run: "./scripts/layered.sh"
|
||||
|
||||
- name: Build, Package & Upload sourcemaps
|
||||
run: "./scripts/ci_package.sh"
|
||||
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@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5
|
||||
SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }}
|
||||
SENTRY_DSN: ${{ secrets.SENTRY_DSN }}
|
||||
SENTRY_URL: ${{ secrets.SENTRY_URL }}
|
||||
SENTRY_ORG: element
|
||||
SENTRY_PROJECT: riot-web
|
||||
|
||||
- uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4
|
||||
with:
|
||||
cache: "yarn"
|
||||
node-version: "lts/*"
|
||||
- run: mv dist/element-*.tar.gz dist/develop.tar.gz
|
||||
|
||||
- name: Install Dependencies
|
||||
run: "./scripts/layered.sh"
|
||||
# We keep the latest develop.tar.gz as the artifact uploaded later expires after 24 and requires auth to download
|
||||
# Element Desktop's fetch script uses this tarball to fetch latest develop to build Nightlies.
|
||||
- name: Deploy develop.tar.gz to Github Pages
|
||||
uses: JamesIves/github-pages-deploy-action@v4
|
||||
with:
|
||||
folder: dist
|
||||
single-commit: true
|
||||
|
||||
- name: Build, Package & Upload sourcemaps
|
||||
run: "./scripts/ci_package.sh"
|
||||
env:
|
||||
SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }}
|
||||
SENTRY_DSN: ${{ secrets.SENTRY_DSN }}
|
||||
SENTRY_URL: ${{ secrets.SENTRY_URL }}
|
||||
SENTRY_ORG: element
|
||||
SENTRY_PROJECT: riot-web
|
||||
# We only deploy the latest bundles to Cloudflare Pages and use _redirects to fallback to R2 for
|
||||
# older ones. This redirect means that 'self' is insufficient in the CSP,
|
||||
# and we have to add the R2 URL.
|
||||
# Once Cloudflare redirects support proxying mode we will be able to ditch this.
|
||||
# See Proxying in support table at https://developers.cloudflare.com/pages/platform/redirects
|
||||
CSP_EXTRA_SOURCE: ${{ env.R2_PUBLIC_URL }}
|
||||
- uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: webapp
|
||||
path: dist/develop.tar.gz
|
||||
retention-days: 1
|
||||
|
||||
- run: mv dist/element-*.tar.gz dist/develop.tar.gz
|
||||
|
||||
- uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
|
||||
with:
|
||||
name: webapp
|
||||
path: dist/develop.tar.gz
|
||||
retention-days: 1
|
||||
|
||||
- name: Extract webapp
|
||||
run: |
|
||||
mkdir _deploy
|
||||
tar xf dist/develop.tar.gz -C _deploy --strip-components=1
|
||||
|
||||
- name: Copy config
|
||||
run: cp element.io/develop/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
|
||||
|
||||
# Redirect requests for the develop tarball and the historical bundles to R2
|
||||
# We find the latest 100 bundle.css files and add their bundles to the redirects file
|
||||
# S3 has no sane way to get the age of a directory as they don't really exist
|
||||
- name: Populate _redirects
|
||||
run: |
|
||||
{
|
||||
echo "/develop.tar.gz $R2_PUBLIC_URL/develop.tar.gz 301"
|
||||
aws s3api --region auto --endpoint-url $R2_URL list-objects-v2 --bucket $R2_BUCKET \
|
||||
--query "sort_by(Contents[?ends_with(Key, '/bundle.css')], &LastModified)[-100:].Key" \
|
||||
--prefix "bundles/" | jq -r '.[]' | grep -oE '[^\"].*\/\s*' | while read -r path ; do
|
||||
echo "/${path}* $R2_PUBLIC_URL/${path}:splat 301"
|
||||
done
|
||||
} | tee _deploy/_redirects
|
||||
env:
|
||||
AWS_ACCESS_KEY_ID: ${{ secrets.CF_R2_ACCESS_KEY_ID }}
|
||||
AWS_SECRET_ACCESS_KEY: ${{ secrets.CF_R2_TOKEN }}
|
||||
|
||||
# We may be trying to deploy the same webapp bundles again, we need to ensure that the live bundles
|
||||
# are not present in the _redirects file and instead accessed directly from Cloudflare Pages.
|
||||
- name: Trim _redirects
|
||||
working-directory: _deploy
|
||||
run: |
|
||||
find bundles -type d -mindepth 1 -maxdepth 1 -exec sed -i "\:{}:d" _redirects \;
|
||||
|
||||
- name: Wait for other steps to succeed
|
||||
uses: t3chguy/wait-on-check-action@18541021811b56544d90e0f073401c2b99e249d6 # fork
|
||||
with:
|
||||
ref: ${{ github.sha }}
|
||||
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).)*$
|
||||
|
||||
# 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 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
|
||||
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/pages-action@f0a1cd58cd66095dee69bfa18fa5efd1dde93bca # v1
|
||||
with:
|
||||
apiToken: ${{ secrets.CF_PAGES_TOKEN }}
|
||||
accountId: ${{ secrets.CF_PAGES_ACCOUNT_ID }}
|
||||
projectName: element-web-develop
|
||||
directory: _deploy
|
||||
gitHubToken: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- run: |
|
||||
echo "Deployed to ${{ steps.cfp.outputs.url }}" >> $GITHUB_STEP_SUMMARY
|
||||
- name: Wait for other steps to succeed
|
||||
uses: lewagon/wait-on-check-action@v1.1.2
|
||||
with:
|
||||
ref: ${{ github.ref }}
|
||||
running-workflow-name: 'Build & Upload source maps to Sentry'
|
||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
wait-interval: 10
|
||||
check-regexp: ^((?!SonarQube|issues|board).)*$
|
||||
|
||||
99
.github/workflows/deploy.yml
vendored
99
.github/workflows/deploy.yml
vendored
@@ -1,99 +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@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5
|
||||
|
||||
- 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 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/pages-action@f0a1cd58cd66095dee69bfa18fa5efd1dde93bca # v1
|
||||
with:
|
||||
apiToken: ${{ secrets.CF_PAGES_TOKEN }}
|
||||
accountId: ${{ secrets.CF_PAGES_ACCOUNT_ID }}
|
||||
projectName: ${{ env.SITE == 'staging.element.io' && 'element-web-staging' || 'element-web' }}
|
||||
directory: _deploy
|
||||
gitHubToken: ${{ secrets.GITHUB_TOKEN }}
|
||||
branch: main
|
||||
154
.github/workflows/docker.yaml
vendored
154
.github/workflows/docker.yaml
vendored
@@ -1,154 +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@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5
|
||||
with:
|
||||
fetch-depth: 0 # needed for docker-package to be able to calculate the version
|
||||
|
||||
- name: Install Cosign
|
||||
uses: sigstore/cosign-installer@398d4b0eeef1380460a10c8013a76f728fb906ac # v3
|
||||
if: github.event_name != 'pull_request'
|
||||
|
||||
- name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@29109295f81e9208d7d86ff1c6c12d2833863392 # v3
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 # v3
|
||||
with:
|
||||
install: true
|
||||
|
||||
- name: Login to Docker Hub
|
||||
uses: docker/login-action@184bdaa0721073962dff0199f1fb9940f07167d1 # v3
|
||||
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@184bdaa0721073962dff0199f1fb9940f07167d1 # v3
|
||||
if: github.event_name != 'pull_request'
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: ${{ github.repository_owner }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Build and load
|
||||
id: test-build
|
||||
uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 # v6
|
||||
with:
|
||||
context: .
|
||||
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@c1e51972afc2121e065aed6d45c65596fe445f3f # v5
|
||||
if: github.event_name != 'pull_request'
|
||||
with:
|
||||
images: |
|
||||
vectorim/element-web
|
||||
ghcr.io/element-hq/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@263435318d21b8e681c14492fe198d362a7d2c83 # v6
|
||||
if: github.event_name != 'pull_request'
|
||||
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 }}
|
||||
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@432a30c9e07499fd01da9f8a49f0faf9e0ca5b77 # v4
|
||||
if: github.event_name != 'pull_request'
|
||||
continue-on-error: true
|
||||
with:
|
||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||
repository: vectorim/element-web
|
||||
|
||||
- name: Repository Dispatch
|
||||
uses: peter-evans/repository-dispatch@ff45666b9427631e3450c54a1bcbee4d9ff4d7c0 # v3
|
||||
if: github.event_name != 'pull_request'
|
||||
with:
|
||||
repository: element-hq/element-web-pro
|
||||
token: ${{ secrets.ELEMENT_BOT_TOKEN }}
|
||||
event-type: image-built
|
||||
# Stable way to determine the :version
|
||||
client-payload: |-
|
||||
{
|
||||
"base-ref": "${{ fromJSON(steps.meta.outputs.json).labels['org.opencontainers.image.version'] }}"
|
||||
}
|
||||
61
.github/workflows/dockerhub.yaml
vendored
Normal file
61
.github/workflows/dockerhub.yaml
vendored
Normal file
@@ -0,0 +1,61 @@
|
||||
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.ref_name }}
|
||||
jobs:
|
||||
buildx:
|
||||
name: Docker Buildx
|
||||
runs-on: ubuntu-latest
|
||||
environment: dockerhub
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
fetch-depth: 0 # needed for docker-package to be able to calculate the version
|
||||
|
||||
- name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v1
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v2
|
||||
with:
|
||||
install: true
|
||||
|
||||
- name: Login to Docker Hub
|
||||
uses: docker/login-action@v1
|
||||
with:
|
||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||
|
||||
- name: Docker meta
|
||||
id: meta
|
||||
uses: docker/metadata-action@v3
|
||||
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
|
||||
uses: docker/build-push-action@v2
|
||||
with:
|
||||
context: .
|
||||
push: true
|
||||
platforms: linux/amd64,linux/arm64
|
||||
tags: ${{ steps.meta.outputs.tags }}
|
||||
labels: ${{ steps.meta.outputs.labels }}
|
||||
|
||||
- name: Update repo description
|
||||
uses: peter-evans/dockerhub-description@v2
|
||||
continue-on-error: true
|
||||
with:
|
||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||
repository: vectorim/element-web
|
||||
107
.github/workflows/docs.yml
vendored
107
.github/workflows/docs.yml
vendored
@@ -1,107 +0,0 @@
|
||||
name: Deploy documentation
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [develop]
|
||||
workflow_dispatch: {}
|
||||
|
||||
permissions: {}
|
||||
|
||||
concurrency:
|
||||
group: "pages"
|
||||
cancel-in-progress: false
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: GitHub Pages
|
||||
runs-on: ubuntu-24.04
|
||||
steps:
|
||||
- name: Fetch element-desktop
|
||||
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5
|
||||
with:
|
||||
repository: element-hq/element-desktop
|
||||
path: element-desktop
|
||||
|
||||
- name: Fetch element-web
|
||||
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5
|
||||
with:
|
||||
path: element-web
|
||||
|
||||
- name: Fetch matrix-js-sdk
|
||||
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5
|
||||
with:
|
||||
repository: matrix-org/matrix-js-sdk
|
||||
path: matrix-js-sdk
|
||||
|
||||
- uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4
|
||||
with:
|
||||
cache: "yarn"
|
||||
cache-dependency-path: element-web/yarn.lock
|
||||
node-version: "lts/*"
|
||||
|
||||
- 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@ee69d230fe19748b7abf22df32acaa93833fad08 # 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: mdbook build
|
||||
|
||||
- name: Upload artifact
|
||||
uses: actions/upload-pages-artifact@56afc609e74202658d3ffba0e8f6dda462b719fa # v3
|
||||
with:
|
||||
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@d6db90164ac5ed86f2b6aed7e0febac5b3c0c03e # v4
|
||||
46
.github/workflows/end-to-end-tests-netlify.yaml
vendored
46
.github/workflows/end-to-end-tests-netlify.yaml
vendored
@@ -1,46 +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:
|
||||
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' }}
|
||||
|
||||
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@634f93cb2916e3fdff6788551b99b062d0335ce0 # v5
|
||||
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-"
|
||||
245
.github/workflows/end-to-end-tests.yaml
vendored
245
.github/workflows/end-to-end-tests.yaml
vendored
@@ -1,245 +0,0 @@
|
||||
# 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:
|
||||
# CRON to run all Projects at 6am UTC
|
||||
schedule:
|
||||
- cron: "0 6 * * *"
|
||||
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 }}
|
||||
# Use 6 runners in the default case, but 4 when running on a schedule where we run all 5 projects (20 runners total)
|
||||
NUM_RUNNERS: ${{ github.event_name == 'schedule' && 4 || 6 }}
|
||||
|
||||
permissions: {} # No permissions required
|
||||
|
||||
jobs:
|
||||
build:
|
||||
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 }}
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5
|
||||
with:
|
||||
repository: element-hq/element-web
|
||||
|
||||
- uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # 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
|
||||
|
||||
- name: Upload Artifact
|
||||
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
|
||||
with:
|
||||
name: webapp
|
||||
path: webapp
|
||||
retention-days: 1
|
||||
|
||||
- name: Calculate runner variables
|
||||
id: runner-vars
|
||||
uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7
|
||||
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:
|
||||
name: "Run Tests [${{ matrix.project }}] ${{ matrix.runner }}/${{ needs.build.outputs.num-runners }}"
|
||||
needs: build
|
||||
if: inputs.skip != true
|
||||
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.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@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5
|
||||
with:
|
||||
persist-credentials: false
|
||||
repository: element-hq/element-web
|
||||
|
||||
- name: 📥 Download artifact
|
||||
uses: actions/download-artifact@634f93cb2916e3fdff6788551b99b062d0335ce0 # v5
|
||||
with:
|
||||
name: webapp
|
||||
path: webapp
|
||||
|
||||
- uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # 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@0400d5f644dc74513175e3cd8d07132dd4860809 # v4
|
||||
id: playwright-cache
|
||||
with:
|
||||
path: ~/.cache/ms-playwright
|
||||
key: ${{ runner.os }}-${{ runner.arch }}-playwright-${{ steps.playwright.outputs.version }}
|
||||
|
||||
- name: Install Playwright browsers
|
||||
if: steps.playwright-cache.outputs.cache-hit != 'true'
|
||||
run: yarn playwright install --with-deps --no-shell
|
||||
|
||||
- name: Install system dependencies for WebKit
|
||||
# Some WebKit dependencies seem to lay outside the cache and will need to be installed separately
|
||||
if: matrix.project == 'WebKit' && steps.playwright-cache.outputs.cache-hit == 'true'
|
||||
run: yarn playwright install-deps webkit
|
||||
|
||||
# We skip tests tagged with @mergequeue when running on PRs, but run them in MQ and everywhere else
|
||||
- name: Run Playwright tests
|
||||
run: |
|
||||
yarn playwright test \
|
||||
--shard "${{ matrix.runner }}/${{ needs.build.outputs.num-runners }}" \
|
||||
--project="${{ matrix.project }}" \
|
||||
${{ (github.event_name == 'pull_request' && matrix.runAllTests == false ) && '--grep-invert @mergequeue' || '' }}
|
||||
|
||||
- name: Upload blob report to GitHub Actions Artifacts
|
||||
if: always()
|
||||
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
|
||||
with:
|
||||
name: all-blob-reports-${{ matrix.project }}-${{ matrix.runner }}
|
||||
path: blob-report
|
||||
retention-days: 1
|
||||
|
||||
downstream-modules:
|
||||
name: Downstream Playwright tests [element-modules]
|
||||
needs: build
|
||||
if: inputs.skip != true && github.event_name == 'merge_group'
|
||||
uses: element-hq/element-modules/.github/workflows/reusable-playwright-tests.yml@main
|
||||
with:
|
||||
webapp-artifact: webapp
|
||||
|
||||
complete:
|
||||
name: end-to-end-tests
|
||||
needs:
|
||||
- playwright
|
||||
- downstream-modules
|
||||
if: always()
|
||||
runs-on: ubuntu-24.04
|
||||
steps:
|
||||
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5
|
||||
if: inputs.skip != true
|
||||
with:
|
||||
persist-credentials: false
|
||||
repository: element-hq/element-web
|
||||
|
||||
- uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # 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@634f93cb2916e3fdff6788551b99b062d0335ce0 # v5
|
||||
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,@element-hq/element-web-playwright-common/lib/stale-screenshot-reporter.js ./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@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
|
||||
with:
|
||||
name: html-report
|
||||
path: playwright-report
|
||||
retention-days: 14
|
||||
|
||||
- if: contains(needs.*.result, 'failure') || contains(needs.*.result, 'cancelled')
|
||||
run: exit 1
|
||||
279
.github/workflows/issue_closed.yml
vendored
279
.github/workflows/issue_closed.yml
vendored
@@ -2,156 +2,155 @@
|
||||
# For all closed (completed) issues, cascade the closure onto any referenced rageshakes
|
||||
# For all closed (not planned) issues, comment on rageshakes to move them into the canonical issue if one exists
|
||||
on:
|
||||
issues:
|
||||
types: [closed]
|
||||
permissions: {} # We use ELEMENT_BOT_TOKEN instead
|
||||
issues:
|
||||
types: [ closed ]
|
||||
jobs:
|
||||
tidy:
|
||||
name: Tidy closed issues
|
||||
runs-on: ubuntu-24.04
|
||||
steps:
|
||||
- uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7
|
||||
id: main
|
||||
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 variables = {
|
||||
owner: context.repo.owner,
|
||||
name: context.repo.repo,
|
||||
number: context.issue.number,
|
||||
};
|
||||
tidy:
|
||||
name: Tidy closed issues
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/github-script@v5
|
||||
id: main
|
||||
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 variables = {
|
||||
owner: context.repo.owner,
|
||||
name: context.repo.repo,
|
||||
number: context.issue.number,
|
||||
};
|
||||
|
||||
const query = `query($owner:String!, $name:String!, $number:Int!) {
|
||||
repository(owner: $owner, name: $name) {
|
||||
issue(number: $number) {
|
||||
stateReason,
|
||||
timelineItems(first: 100, itemTypes: [MARKED_AS_DUPLICATE_EVENT, UNMARKED_AS_DUPLICATE_EVENT, CROSS_REFERENCED_EVENT]) {
|
||||
edges {
|
||||
node {
|
||||
__typename
|
||||
... on MarkedAsDuplicateEvent {
|
||||
canonical {
|
||||
... on Issue {
|
||||
repository {
|
||||
nameWithOwner
|
||||
}
|
||||
number
|
||||
}
|
||||
... on PullRequest {
|
||||
repository {
|
||||
nameWithOwner
|
||||
}
|
||||
number
|
||||
}
|
||||
}
|
||||
}
|
||||
... on UnmarkedAsDuplicateEvent {
|
||||
canonical {
|
||||
... on Issue {
|
||||
repository {
|
||||
nameWithOwner
|
||||
}
|
||||
number
|
||||
}
|
||||
... on PullRequest {
|
||||
repository {
|
||||
nameWithOwner
|
||||
}
|
||||
number
|
||||
}
|
||||
}
|
||||
}
|
||||
... on CrossReferencedEvent {
|
||||
source {
|
||||
... on Issue {
|
||||
repository {
|
||||
nameWithOwner
|
||||
}
|
||||
number
|
||||
}
|
||||
... on PullRequest {
|
||||
repository {
|
||||
nameWithOwner
|
||||
}
|
||||
number
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
const query = `query($owner:String!, $name:String!, $number:Int!) {
|
||||
repository(owner: $owner, name: $name) {
|
||||
issue(number: $number) {
|
||||
stateReason,
|
||||
timelineItems(first: 100, itemTypes: [MARKED_AS_DUPLICATE_EVENT, UNMARKED_AS_DUPLICATE_EVENT, CROSS_REFERENCED_EVENT]) {
|
||||
edges {
|
||||
node {
|
||||
__typename
|
||||
... on MarkedAsDuplicateEvent {
|
||||
canonical {
|
||||
... on Issue {
|
||||
repository {
|
||||
nameWithOwner
|
||||
}
|
||||
number
|
||||
}
|
||||
... on PullRequest {
|
||||
repository {
|
||||
nameWithOwner
|
||||
}
|
||||
number
|
||||
}
|
||||
}
|
||||
}
|
||||
}`;
|
||||
|
||||
const result = await github.graphql(query, variables);
|
||||
const { stateReason, timelineItems: { edges } } = result.repository.issue;
|
||||
|
||||
const RAGESHAKE_OWNER = "matrix-org";
|
||||
const RAGESHAKE_REPO = "element-web-rageshakes";
|
||||
const rageshakes = new Set();
|
||||
const duplicateOf = new Set();
|
||||
|
||||
console.log("Edges: ", JSON.stringify(edges));
|
||||
|
||||
for (const { node } of edges) {
|
||||
switch(node.__typename) {
|
||||
case "MarkedAsDuplicateEvent":
|
||||
duplicateOf.add(node.canonical.repository.nameWithOwner + "#" + node.canonical.number);
|
||||
break;
|
||||
case "UnmarkedAsDuplicateEvent":
|
||||
duplicateOf.remove(node.canonical.repository.nameWithOwner + "#" + node.canonical.number);
|
||||
break;
|
||||
case "CrossReferencedEvent":
|
||||
if (node.source.repository.nameWithOwner === (RAGESHAKE_OWNER + "/" + RAGESHAKE_REPO)) {
|
||||
rageshakes.add(node.source.number);
|
||||
... on UnmarkedAsDuplicateEvent {
|
||||
canonical {
|
||||
... on Issue {
|
||||
repository {
|
||||
nameWithOwner
|
||||
}
|
||||
number
|
||||
}
|
||||
break;
|
||||
... on PullRequest {
|
||||
repository {
|
||||
nameWithOwner
|
||||
}
|
||||
number
|
||||
}
|
||||
}
|
||||
}
|
||||
... on CrossReferencedEvent {
|
||||
source {
|
||||
... on Issue {
|
||||
repository {
|
||||
nameWithOwner
|
||||
}
|
||||
number
|
||||
}
|
||||
... on PullRequest {
|
||||
repository {
|
||||
nameWithOwner
|
||||
}
|
||||
number
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}`;
|
||||
|
||||
console.log("Duplicate of: ", duplicateOf);
|
||||
console.log("Found rageshakes: ", rageshakes);
|
||||
const result = await github.graphql(query, variables);
|
||||
const { stateReason, timelineItems: { edges } } = result.repository.issue;
|
||||
|
||||
if (duplicateOf.size) {
|
||||
const body = Array.from(duplicateOf).join("\n");
|
||||
const RAGESHAKE_OWNER = "matrix-org";
|
||||
const RAGESHAKE_REPO = "element-web-rageshakes";
|
||||
const rageshakes = new Set();
|
||||
const duplicateOf = new Set();
|
||||
|
||||
// Comment on all rageshakes to create relationship to the issue this was closed as duplicate of
|
||||
for (const rageshake of rageshakes) {
|
||||
github.rest.issues.createComment({
|
||||
owner: RAGESHAKE_OWNER,
|
||||
repo: RAGESHAKE_REPO,
|
||||
issue_number: rageshake,
|
||||
body,
|
||||
});
|
||||
}
|
||||
console.log("Edges: ", JSON.stringify(edges));
|
||||
|
||||
// Duplicate was closed with wrong reason, fix it
|
||||
if (stateReason === "COMPLETED") {
|
||||
core.setOutput("closeAsNotPlanned", "true");
|
||||
}
|
||||
} else {
|
||||
// This issue was closed, close all related rageshakes
|
||||
for (const rageshake of rageshakes) {
|
||||
github.rest.issues.update({
|
||||
owner: RAGESHAKE_OWNER,
|
||||
repo: RAGESHAKE_REPO,
|
||||
issue_number: rageshake,
|
||||
state: "closed",
|
||||
});
|
||||
}
|
||||
}
|
||||
- uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7
|
||||
name: Close duplicate as Not Planned
|
||||
if: steps.main.outputs.closeAsNotPlanned
|
||||
with:
|
||||
# We do this step separately, and with the default token so as to not re-trigger this workflow when re-closing
|
||||
script: |
|
||||
await github.graphql(`mutation($id:ID!) {
|
||||
closeIssue(input: { issueId:$id, stateReason:NOT_PLANNED }) {
|
||||
clientMutationId
|
||||
}
|
||||
}`, {
|
||||
id: context.payload.issue.node_id,
|
||||
});
|
||||
for (const { node } of edges) {
|
||||
switch(node.__typename) {
|
||||
case "MarkedAsDuplicateEvent":
|
||||
duplicateOf.add(node.canonical.repository.nameWithOwner + "#" + node.canonical.number);
|
||||
break;
|
||||
case "UnmarkedAsDuplicateEvent":
|
||||
duplicateOf.remove(node.canonical.repository.nameWithOwner + "#" + node.canonical.number);
|
||||
break;
|
||||
case "CrossReferencedEvent":
|
||||
if (node.source.repository.nameWithOwner === (RAGESHAKE_OWNER + "/" + RAGESHAKE_REPO)) {
|
||||
rageshakes.add(node.source.number);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
console.log("Duplicate of: ", duplicateOf);
|
||||
console.log("Found rageshakes: ", rageshakes);
|
||||
|
||||
if (duplicateOf.size) {
|
||||
const body = Array.from(duplicateOf).join("\n");
|
||||
|
||||
// Comment on all rageshakes to create relationship to the issue this was closed as duplicate of
|
||||
for (const rageshake of rageshakes) {
|
||||
github.rest.issues.createComment({
|
||||
owner: RAGESHAKE_OWNER,
|
||||
repo: RAGESHAKE_REPO,
|
||||
issue_number: rageshake,
|
||||
body,
|
||||
});
|
||||
}
|
||||
|
||||
// Duplicate was closed with wrong reason, fix it
|
||||
if (stateReason === "COMPLETED") {
|
||||
core.setOutput("closeAsNotPlanned", "true");
|
||||
}
|
||||
} else {
|
||||
// This issue was closed, close all related rageshakes
|
||||
for (const rageshake of rageshakes) {
|
||||
github.rest.issues.update({
|
||||
owner: RAGESHAKE_OWNER,
|
||||
repo: RAGESHAKE_REPO,
|
||||
issue_number: rageshake,
|
||||
state: "closed",
|
||||
});
|
||||
}
|
||||
}
|
||||
- uses: actions/github-script@v5
|
||||
name: Close duplicate as Not Planned
|
||||
if: steps.main.outputs.closeAsNotPlanned
|
||||
with:
|
||||
# We do this step separately, and with the default token so as to not re-trigger this workflow when re-closing
|
||||
script: |
|
||||
await github.graphql(`mutation($id:ID!) {
|
||||
closeIssue(input: { issueId:$id, stateReason:NOT_PLANNED }) {
|
||||
clientMutationId
|
||||
}
|
||||
}`, {
|
||||
id: context.payload.issue.node_id,
|
||||
});
|
||||
|
||||
12
.github/workflows/localazy_download.yaml
vendored
12
.github/workflows/localazy_download.yaml
vendored
@@ -1,12 +0,0 @@
|
||||
name: Localazy Download
|
||||
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@main
|
||||
secrets:
|
||||
ELEMENT_BOT_TOKEN: ${{ secrets.ELEMENT_BOT_TOKEN }}
|
||||
12
.github/workflows/localazy_upload.yaml
vendored
12
.github/workflows/localazy_upload.yaml
vendored
@@ -1,12 +0,0 @@
|
||||
name: Localazy Upload
|
||||
on:
|
||||
push:
|
||||
branches: [develop]
|
||||
paths:
|
||||
- "src/i18n/strings/en_EN.json"
|
||||
permissions: {} # No permissions needed
|
||||
jobs:
|
||||
upload:
|
||||
uses: matrix-org/matrix-web-i18n/.github/workflows/localazy_upload.yaml@main
|
||||
secrets:
|
||||
LOCALAZY_WRITE_KEY: ${{ secrets.LOCALAZY_WRITE_KEY }}
|
||||
51
.github/workflows/netlify.yaml
vendored
51
.github/workflows/netlify.yaml
vendored
@@ -1,51 +0,0 @@
|
||||
# Triggers after the layered build has finished, taking the artifact
|
||||
# and uploading it to netlify
|
||||
name: Upload Preview Build to Netlify
|
||||
on:
|
||||
workflow_run:
|
||||
workflows: ["Build"]
|
||||
types:
|
||||
- completed
|
||||
jobs:
|
||||
deploy:
|
||||
if: github.event.workflow_run.conclusion != 'cancelled' && github.event.workflow_run.event == 'pull_request'
|
||||
runs-on: ubuntu-24.04
|
||||
environment: Netlify
|
||||
permissions:
|
||||
actions: read
|
||||
deployments: write
|
||||
steps:
|
||||
- name: 📝 Create Deployment
|
||||
uses: bobheadxi/deployments@648679e8e4915b27893bd7dbc35cb504dc915bc8 # v1
|
||||
id: deployment
|
||||
with:
|
||||
step: start
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
env: Netlify
|
||||
ref: ${{ github.event.workflow_run.head_sha }}
|
||||
desc: |
|
||||
Do you trust the author of this PR? Maybe this build will steal your keys or give you malware.
|
||||
Exercise caution. Use test accounts.
|
||||
|
||||
- name: 📥 Download artifact
|
||||
uses: actions/download-artifact@634f93cb2916e3fdff6788551b99b062d0335ce0 # v5
|
||||
with:
|
||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
run-id: ${{ github.event.workflow_run.id }}
|
||||
name: webapp-ubuntu-24.04
|
||||
path: webapp
|
||||
|
||||
- name: 📤 Deploy to Netlify
|
||||
uses: matrix-org/netlify-pr-preview@9805cd123fc9a7e421e35340a05e1ebc5dee46b5 # v3
|
||||
with:
|
||||
path: webapp
|
||||
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 }}
|
||||
deployment_env: ${{ steps.deployment.outputs.env }}
|
||||
deployment_id: ${{ steps.deployment.outputs.deployment_id }}
|
||||
desc: |
|
||||
Do you trust the author of this PR? Maybe this build will steal your keys or give you malware.
|
||||
Exercise caution. Use test accounts.
|
||||
92
.github/workflows/pending-reviews.yaml
vendored
92
.github/workflows/pending-reviews.yaml
vendored
@@ -1,92 +0,0 @@
|
||||
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 }}
|
||||
permissions: {} # We use ELEMENT_BOT_TOKEN instead
|
||||
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@60a0d83039c74a4aee543508d2ffcb1c3799cdea # 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);
|
||||
57
.github/workflows/playwright-image-updates.yaml
vendored
57
.github/workflows/playwright-image-updates.yaml
vendored
@@ -1,57 +0,0 @@
|
||||
name: Update Playwright docker images
|
||||
on:
|
||||
workflow_dispatch: {}
|
||||
schedule:
|
||||
- cron: "0 6 * * *" # Every day at 6am UTC
|
||||
permissions: {}
|
||||
jobs:
|
||||
update:
|
||||
runs-on: ubuntu-24.04
|
||||
permissions:
|
||||
pull-requests: write
|
||||
steps:
|
||||
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5
|
||||
|
||||
- name: Update synapse image
|
||||
run: |
|
||||
docker pull "$IMAGE"
|
||||
INSPECT=$(docker inspect --format='{{index .RepoDigests 0}}' "$IMAGE")
|
||||
DIGEST=${INSPECT#*@}
|
||||
sed -i "s/const TAG.*/const TAG = \"develop@$DIGEST\";/" playwright/testcontainers/synapse.ts
|
||||
env:
|
||||
IMAGE: ghcr.io/element-hq/synapse:develop
|
||||
|
||||
- name: Update MAS image
|
||||
run: |
|
||||
docker pull "$IMAGE"
|
||||
INSPECT=$(docker inspect --format='{{index .RepoDigests 0}}' "$IMAGE")
|
||||
DIGEST=${INSPECT#*@}
|
||||
sed -i "s/const TAG.*/const TAG = \"main@$DIGEST\";/" playwright/testcontainers/mas.ts
|
||||
env:
|
||||
IMAGE: ghcr.io/element-hq/matrix-authentication-service:main
|
||||
|
||||
- name: Create Pull Request
|
||||
id: cpr
|
||||
uses: peter-evans/create-pull-request@271a8d0340265f705b14b6d32b9829c1cb33d45e # 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 }}
|
||||
20
.github/workflows/pull_request.yaml
vendored
20
.github/workflows/pull_request.yaml
vendored
@@ -1,14 +1,12 @@
|
||||
name: Pull Request
|
||||
on:
|
||||
pull_request_target:
|
||||
types: [opened, edited, labeled, unlabeled, synchronize]
|
||||
merge_group:
|
||||
types: [checks_requested]
|
||||
permissions: {}
|
||||
pull_request_target:
|
||||
types: [ opened, edited, labeled, unlabeled, synchronize ]
|
||||
concurrency: ${{ github.workflow }}-${{ github.event.pull_request.head.ref }}
|
||||
jobs:
|
||||
action:
|
||||
uses: matrix-org/matrix-js-sdk/.github/workflows/pull_request.yaml@develop
|
||||
permissions:
|
||||
pull-requests: write
|
||||
secrets:
|
||||
ELEMENT_BOT_TOKEN: ${{ secrets.ELEMENT_BOT_TOKEN }}
|
||||
action:
|
||||
uses: matrix-org/matrix-js-sdk/.github/workflows/pull_request.yaml@develop
|
||||
with:
|
||||
labels: "T-Defect,T-Enhancement,T-Task"
|
||||
secrets:
|
||||
ELEMENT_BOT_TOKEN: ${{ secrets.ELEMENT_BOT_TOKEN }}
|
||||
|
||||
17
.github/workflows/pull_request_base_branch.yaml
vendored
17
.github/workflows/pull_request_base_branch.yaml
vendored
@@ -1,17 +0,0 @@
|
||||
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
|
||||
steps:
|
||||
- uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7
|
||||
with:
|
||||
script: |
|
||||
const baseBranch = context.payload.pull_request.base.ref;
|
||||
if (!['develop', 'staging'].includes(baseBranch) && !baseBranch.startsWith('feat/')) {
|
||||
core.setFailed(`Invalid base branch: ${baseBranch}`);
|
||||
}
|
||||
12
.github/workflows/release-drafter.yml
vendored
12
.github/workflows/release-drafter.yml
vendored
@@ -1,12 +0,0 @@
|
||||
name: Release Drafter
|
||||
on:
|
||||
push:
|
||||
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
|
||||
15
.github/workflows/release-gitflow.yml
vendored
15
.github/workflows/release-gitflow.yml
vendored
@@ -1,15 +0,0 @@
|
||||
# Gitflow merge-back master->develop
|
||||
name: Merge master -> develop
|
||||
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
|
||||
secrets:
|
||||
ELEMENT_BOT_TOKEN: ${{ secrets.ELEMENT_BOT_TOKEN }}
|
||||
with:
|
||||
dependencies: |
|
||||
matrix-js-sdk
|
||||
70
.github/workflows/release.yml
vendored
70
.github/workflows/release.yml
vendored
@@ -1,70 +0,0 @@
|
||||
name: Release Process
|
||||
on:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
mode:
|
||||
description: What type of release
|
||||
required: true
|
||||
default: rc
|
||||
type: choice
|
||||
options:
|
||||
- rc
|
||||
- final
|
||||
concurrency: ${{ github.workflow }}
|
||||
permissions: {}
|
||||
jobs:
|
||||
release:
|
||||
uses: matrix-org/matrix-js-sdk/.github/workflows/release-make.yml@develop
|
||||
permissions:
|
||||
contents: write
|
||||
issues: write
|
||||
pull-requests: read
|
||||
id-token: write
|
||||
secrets:
|
||||
ELEMENT_BOT_TOKEN: ${{ secrets.ELEMENT_BOT_TOKEN }}
|
||||
GPG_PRIVATE_KEY: ${{ secrets.GPG_PRIVATE_KEY }}
|
||||
GPG_PASSPHRASE: ${{ secrets.GPG_PASSPHRASE }}
|
||||
with:
|
||||
final: ${{ inputs.mode == 'final' }}
|
||||
gpg-fingerprint: ${{ vars.GPG_FINGERPRINT }}
|
||||
asset-path: dist/*.tar.gz
|
||||
expected-asset-count: 3
|
||||
|
||||
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
|
||||
uses: t3chguy/wait-on-check-action@18541021811b56544d90e0f073401c2b99e249d6 # fork
|
||||
with:
|
||||
ref: master
|
||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
wait-interval: 10
|
||||
check-name: "Docker Buildx"
|
||||
allowed-conclusions: success
|
||||
|
||||
- name: Wait for debian package
|
||||
uses: t3chguy/wait-on-check-action@18541021811b56544d90e0f073401c2b99e249d6 # fork
|
||||
with:
|
||||
ref: master
|
||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
wait-interval: 10
|
||||
check-name: Build package
|
||||
allowed-conclusions: success
|
||||
126
.github/workflows/release_prepare.yml
vendored
126
.github/workflows/release_prepare.yml
vendored
@@ -1,126 +0,0 @@
|
||||
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
|
||||
type: boolean
|
||||
default: true
|
||||
matrix-js-sdk:
|
||||
description: Prepare matrix-js-sdk
|
||||
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
|
||||
- element-hq/element-desktop
|
||||
uses: matrix-org/matrix-js-sdk/.github/workflows/release-checks.yml@develop
|
||||
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 element-desktop
|
||||
steps:
|
||||
- name: Checkout Element Desktop
|
||||
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5
|
||||
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@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5
|
||||
if: inputs.element-web
|
||||
with:
|
||||
repository: element-hq/element-web
|
||||
path: element-web
|
||||
ref: staging
|
||||
fetch-depth: 0
|
||||
fetch-tags: true
|
||||
token: ${{ secrets.ELEMENT_BOT_TOKEN }}
|
||||
- name: Checkout Matrix JS SDK
|
||||
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5
|
||||
if: inputs.matrix-js-sdk
|
||||
with:
|
||||
repository: matrix-org/matrix-js-sdk
|
||||
path: matrix-js-sdk
|
||||
ref: staging
|
||||
fetch-depth: 0
|
||||
fetch-tags: true
|
||||
token: ${{ secrets.ELEMENT_BOT_TOKEN }}
|
||||
|
||||
- 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: |
|
||||
git -C "element-web" merge origin/develop
|
||||
- name: Merge JS SDK
|
||||
if: inputs.matrix-js-sdk
|
||||
run: |
|
||||
git -C "matrix-js-sdk" merge origin/develop
|
||||
|
||||
- name: Push staging
|
||||
run: for REPO in $REPOS; do [ -d "$REPO" ] && git -C "$REPO" push origin staging; done
|
||||
|
||||
- name: Wait for matrix-js-sdk draft
|
||||
if: inputs.matrix-js-sdk
|
||||
uses: t3chguy/wait-on-check-action@18541021811b56544d90e0f073401c2b99e249d6 # fork
|
||||
with:
|
||||
ref: staging
|
||||
repo: matrix-org/matrix-js-sdk
|
||||
repo-token: ${{ secrets.ELEMENT_BOT_TOKEN }}
|
||||
wait-interval: 10
|
||||
check-name: "draft / draft"
|
||||
allowed-conclusions: success
|
||||
|
||||
- name: Wait for element-web draft
|
||||
if: inputs.element-web
|
||||
uses: t3chguy/wait-on-check-action@18541021811b56544d90e0f073401c2b99e249d6 # fork
|
||||
with:
|
||||
ref: staging
|
||||
repo: element-hq/element-web
|
||||
repo-token: ${{ secrets.ELEMENT_BOT_TOKEN }}
|
||||
wait-interval: 10
|
||||
check-name: "draft / 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 / draft"
|
||||
allowed-conclusions: success
|
||||
@@ -1,51 +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:
|
||||
workflow_run:
|
||||
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: Install tree
|
||||
run: "sudo apt-get install -y tree"
|
||||
|
||||
- name: Download Diffs
|
||||
uses: actions/download-artifact@634f93cb2916e3fdff6788551b99b062d0335ce0 # v5
|
||||
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,70 +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@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5
|
||||
with:
|
||||
persist-credentials: false
|
||||
repository: element-hq/element-web
|
||||
|
||||
- uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4
|
||||
with:
|
||||
cache: "yarn"
|
||||
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@0400d5f644dc74513175e3cd8d07132dd4860809 # v4
|
||||
id: playwright-cache
|
||||
with:
|
||||
path: ~/.cache/ms-playwright
|
||||
key: ${{ runner.os }}-${{ runner.arch }}-playwright-${{ steps.playwright.outputs.version }}-onlyshell
|
||||
|
||||
- name: Install Playwright browsers
|
||||
if: steps.playwright-cache.outputs.cache-hit != 'true'
|
||||
run: "yarn playwright install --with-deps --only-shell"
|
||||
|
||||
- name: Build Element Web resources
|
||||
# Needed to prepare language files
|
||||
run: "yarn build:res"
|
||||
|
||||
- name: Build storybook dependencies
|
||||
# When the first test is ran, it will fail because the dependencies are not yet built.
|
||||
# This step is to ensure that the dependencies are built before running the tests.
|
||||
run: "yarn test:storybook:ci"
|
||||
continue-on-error: true
|
||||
|
||||
- name: Run Visual tests
|
||||
run: "yarn test:storybook:ci"
|
||||
|
||||
- name: Upload received images & diffs
|
||||
if: always()
|
||||
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
|
||||
with:
|
||||
name: received-images
|
||||
path: playwright/shared-component-received
|
||||
31
.github/workflows/sonarqube.yml
vendored
31
.github/workflows/sonarqube.yml
vendored
@@ -1,24 +1,15 @@
|
||||
name: SonarQube
|
||||
on:
|
||||
workflow_run:
|
||||
workflows: ["Tests"]
|
||||
types:
|
||||
- completed
|
||||
workflow_run:
|
||||
workflows: [ "Tests" ]
|
||||
types:
|
||||
- completed
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.event.workflow_run.head_branch }}
|
||||
cancel-in-progress: true
|
||||
permissions: {}
|
||||
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
|
||||
permissions:
|
||||
actions: read
|
||||
statuses: write
|
||||
id-token: write # sonar
|
||||
secrets:
|
||||
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
|
||||
ELEMENT_BOT_TOKEN: ${{ secrets.ELEMENT_BOT_TOKEN }}
|
||||
with:
|
||||
sharded: true
|
||||
sonarqube:
|
||||
name: 🩻 SonarQube
|
||||
uses: matrix-org/matrix-js-sdk/.github/workflows/sonarcloud.yml@develop
|
||||
secrets:
|
||||
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
|
||||
|
||||
179
.github/workflows/static_analysis.yaml
vendored
179
.github/workflows/static_analysis.yaml
vendored
@@ -1,136 +1,85 @@
|
||||
name: Static Analysis
|
||||
on:
|
||||
pull_request: {}
|
||||
push:
|
||||
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
|
||||
|
||||
pull_request: { }
|
||||
push:
|
||||
branches: [ develop, master ]
|
||||
repository_dispatch:
|
||||
types: [ element-web-notify ]
|
||||
env:
|
||||
# These must be set for fetchdep.sh to get the right branch
|
||||
REPOSITORY: ${{ github.repository }}
|
||||
PR_NUMBER: ${{ github.event.pull_request.number }}
|
||||
|
||||
permissions: {} # No permissions required
|
||||
|
||||
# These must be set for fetchdep.sh to get the right branch
|
||||
REPOSITORY: ${{ github.repository }}
|
||||
PR_NUMBER: ${{ github.event.pull_request.number }}
|
||||
jobs:
|
||||
ts_lint:
|
||||
name: "Typescript Syntax Check"
|
||||
runs-on: ubuntu-24.04
|
||||
steps:
|
||||
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5
|
||||
ts_lint:
|
||||
name: "Typescript Syntax Check"
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
|
||||
- uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4
|
||||
with:
|
||||
cache: "yarn"
|
||||
node-version: "lts/*"
|
||||
|
||||
- name: Install Dependencies
|
||||
run: "./scripts/layered.sh"
|
||||
|
||||
- name: Typecheck
|
||||
run: "yarn run lint:types"
|
||||
|
||||
i18n_lint:
|
||||
name: "i18n Check"
|
||||
uses: matrix-org/matrix-web-i18n/.github/workflows/i18n_check.yml@main
|
||||
permissions:
|
||||
pull-requests: read
|
||||
- uses: actions/setup-node@v3
|
||||
with:
|
||||
hardcoded-words: "Element"
|
||||
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
|
||||
devtools|settings|elementCallUrl
|
||||
labs|sliding_sync_description
|
||||
cache: 'yarn'
|
||||
node-version: 16
|
||||
|
||||
rethemendex_lint:
|
||||
name: "Rethemendex Check"
|
||||
runs-on: ubuntu-24.04
|
||||
steps:
|
||||
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5
|
||||
- name: Install Dependencies
|
||||
run: "./scripts/layered.sh"
|
||||
|
||||
- run: ./res/css/rethemendex.sh
|
||||
- name: Typecheck
|
||||
run: "yarn run lint:types"
|
||||
|
||||
- run: git diff --exit-code
|
||||
i18n_lint:
|
||||
name: "i18n Check"
|
||||
uses: matrix-org/matrix-react-sdk/.github/workflows/i18n_check.yml@develop
|
||||
|
||||
js_lint:
|
||||
name: "ESLint"
|
||||
runs-on: ubuntu-24.04
|
||||
steps:
|
||||
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5
|
||||
js_lint:
|
||||
name: "ESLint"
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
|
||||
- uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4
|
||||
with:
|
||||
cache: "yarn"
|
||||
node-version: "lts/*"
|
||||
- uses: actions/setup-node@v3
|
||||
with:
|
||||
cache: 'yarn'
|
||||
node-version: 16
|
||||
|
||||
# Does not need branch matching as only analyses this layer
|
||||
- name: Install Deps
|
||||
run: "yarn install --frozen-lockfile"
|
||||
# Does not need branch matching as only analyses this layer
|
||||
- name: Install Deps
|
||||
run: "yarn install --pure-lockfile"
|
||||
|
||||
- name: Run Linter
|
||||
run: "yarn run lint:js"
|
||||
- name: Run Linter
|
||||
run: "yarn run lint:js"
|
||||
|
||||
style_lint:
|
||||
name: "Style Lint"
|
||||
runs-on: ubuntu-24.04
|
||||
steps:
|
||||
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5
|
||||
style_lint:
|
||||
name: "Style Lint"
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
|
||||
- uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4
|
||||
with:
|
||||
cache: "yarn"
|
||||
node-version: "lts/*"
|
||||
- uses: actions/setup-node@v3
|
||||
with:
|
||||
cache: 'yarn'
|
||||
node-version: 16
|
||||
|
||||
# Does not need branch matching as only analyses this layer
|
||||
- name: Install Deps
|
||||
run: "yarn install"
|
||||
# Needs branch matching as it inherits .stylelintrc.js from matrix-react-sdk
|
||||
- name: Install Dependencies
|
||||
run: "./scripts/layered.sh"
|
||||
|
||||
- name: Run Linter
|
||||
run: "yarn run lint:style"
|
||||
- name: Run Linter
|
||||
run: "yarn run lint:style"
|
||||
|
||||
workflow_lint:
|
||||
name: "Workflow Lint"
|
||||
runs-on: ubuntu-24.04
|
||||
steps:
|
||||
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5
|
||||
analyse_dead_code:
|
||||
name: "Analyse Dead Code"
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
|
||||
- uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4
|
||||
with:
|
||||
cache: "yarn"
|
||||
node-version: "lts/*"
|
||||
- uses: actions/setup-node@v3
|
||||
with:
|
||||
cache: 'yarn'
|
||||
node-version: 16
|
||||
|
||||
# Does not need branch matching as only analyses this layer
|
||||
- name: Install Deps
|
||||
run: "yarn install --frozen-lockfile"
|
||||
- name: Install Deps
|
||||
run: "scripts/layered.sh"
|
||||
|
||||
- name: Run Linter
|
||||
run: "yarn lint:workflows"
|
||||
|
||||
analyse_dead_code:
|
||||
name: "Analyse Dead Code"
|
||||
runs-on: ubuntu-24.04
|
||||
steps:
|
||||
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5
|
||||
|
||||
- uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4
|
||||
with:
|
||||
cache: "yarn"
|
||||
node-version: "lts/*"
|
||||
|
||||
- name: Install Deps
|
||||
run: "yarn install --frozen-lockfile"
|
||||
|
||||
- name: Run linter
|
||||
run: "yarn run lint:knip"
|
||||
- name: Dead Code Analysis
|
||||
run: "yarn run analyse:unused-exports"
|
||||
|
||||
24
.github/workflows/sync-labels.yml
vendored
24
.github/workflows/sync-labels.yml
vendored
@@ -1,24 +0,0 @@
|
||||
name: Sync labels
|
||||
on:
|
||||
workflow_dispatch: {}
|
||||
schedule:
|
||||
- cron: "0 1 * * *" # 1am every day
|
||||
push:
|
||||
branches:
|
||||
- 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@develop
|
||||
with:
|
||||
LABELS: |
|
||||
element-hq/element-meta
|
||||
.github/labels.yml
|
||||
DELETE: true
|
||||
WET: true
|
||||
secrets:
|
||||
ELEMENT_BOT_TOKEN: ${{ secrets.ELEMENT_BOT_TOKEN }}
|
||||
38
.github/workflows/tests.yaml
vendored
Normal file
38
.github/workflows/tests.yaml
vendored
Normal file
@@ -0,0 +1,38 @@
|
||||
name: Tests
|
||||
on:
|
||||
pull_request: { }
|
||||
push:
|
||||
branches: [ develop, master ]
|
||||
repository_dispatch:
|
||||
types: [ element-web-notify ]
|
||||
env:
|
||||
# These must be set for fetchdep.sh to get the right branch
|
||||
REPOSITORY: ${{ github.repository }}
|
||||
PR_NUMBER: ${{ github.event.pull_request.number }}
|
||||
jobs:
|
||||
jest:
|
||||
name: Jest
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Yarn cache
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
cache: 'yarn'
|
||||
node-version: 16
|
||||
|
||||
- name: Install Dependencies
|
||||
run: "./scripts/layered.sh"
|
||||
|
||||
- name: Run tests with coverage
|
||||
run: "yarn coverage --ci"
|
||||
|
||||
- name: Upload Artifact
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: coverage
|
||||
path: |
|
||||
coverage
|
||||
!coverage/lcov-report
|
||||
114
.github/workflows/tests.yml
vendored
114
.github/workflows/tests.yml
vendored
@@ -1,114 +0,0 @@
|
||||
name: Tests
|
||||
on:
|
||||
pull_request: {}
|
||||
merge_group:
|
||||
types: [checks_requested]
|
||||
push:
|
||||
branches: [develop, master]
|
||||
repository_dispatch:
|
||||
types: [element-web-notify]
|
||||
workflow_call:
|
||||
inputs:
|
||||
disable_coverage:
|
||||
type: boolean
|
||||
required: false
|
||||
description: "Specify true to skip generating and uploading coverage for tests"
|
||||
matrix-js-sdk-sha:
|
||||
type: string
|
||||
required: false
|
||||
description: "The matrix-js-sdk SHA to use"
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}-${{ github.event_name }}
|
||||
cancel-in-progress: true
|
||||
|
||||
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 }}
|
||||
|
||||
permissions: {}
|
||||
|
||||
jobs:
|
||||
jest:
|
||||
name: Jest
|
||||
runs-on: ubuntu-24.04
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
# Run multiple instances in parallel to speed up the tests
|
||||
runner: [1, 2]
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5
|
||||
with:
|
||||
repository: ${{ inputs.matrix-js-sdk-sha && 'element-hq/element-web' || github.repository }}
|
||||
|
||||
- name: Yarn cache
|
||||
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4
|
||||
with:
|
||||
node-version: "lts/*"
|
||||
cache: "yarn"
|
||||
|
||||
- name: Install Deps
|
||||
run: "./scripts/layered.sh"
|
||||
env:
|
||||
JS_SDK_GITHUB_BASE_REF: ${{ inputs.matrix-js-sdk-sha }}
|
||||
|
||||
- name: Jest Cache
|
||||
uses: actions/cache@0400d5f644dc74513175e3cd8d07132dd4860809 # v4
|
||||
with:
|
||||
path: /tmp/jest_cache
|
||||
key: ${{ hashFiles('**/yarn.lock') }}
|
||||
|
||||
- name: Get number of CPU cores
|
||||
id: cpu-cores
|
||||
uses: SimenB/github-actions-cpu-cores@97ba232459a8e02ff6121db9362b09661c875ab8 # v2
|
||||
|
||||
- name: Run tests
|
||||
run: |
|
||||
yarn test \
|
||||
--coverage=${{ env.ENABLE_COVERAGE }} \
|
||||
--ci \
|
||||
--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
|
||||
|
||||
- name: Move coverage files into place
|
||||
if: env.ENABLE_COVERAGE == 'true'
|
||||
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@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
|
||||
with:
|
||||
name: coverage-${{ matrix.runner }}
|
||||
path: |
|
||||
coverage
|
||||
!coverage/lcov-report
|
||||
|
||||
complete:
|
||||
name: jest-tests
|
||||
needs: jest
|
||||
if: always()
|
||||
runs-on: ubuntu-24.04
|
||||
permissions:
|
||||
statuses: write
|
||||
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@741ea90ba6c3ca76fe0d43ba11a90cda97d5e685
|
||||
with:
|
||||
authToken: ${{ secrets.GITHUB_TOKEN }}
|
||||
state: success
|
||||
description: SonarCloud skipped
|
||||
context: SonarCloud Code Analysis
|
||||
sha: ${{ github.sha }}
|
||||
target_url: https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}
|
||||
29
.github/workflows/triage-assigned.yml
vendored
29
.github/workflows/triage-assigned.yml
vendored
@@ -1,21 +1,18 @@
|
||||
name: Move issued assigned to specific team members to their boards
|
||||
|
||||
on:
|
||||
issues:
|
||||
types: [assigned]
|
||||
|
||||
permissions: {} # We use ELEMENT_BOT_TOKEN instead
|
||||
issues:
|
||||
types: [ assigned ]
|
||||
|
||||
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, 'MidhunSureshR')
|
||||
steps:
|
||||
- uses: actions/add-to-project@244f685bbc3b7adfa8466e08b698b5577571133e # v1.0.2
|
||||
with:
|
||||
project-url: https://github.com/orgs/element-hq/projects/67
|
||||
github-token: ${{ secrets.ELEMENT_BOT_TOKEN }}
|
||||
web-app-team:
|
||||
runs-on: ubuntu-latest
|
||||
if: |
|
||||
contains(github.event.issue.assignees.*.login, 't3chguy') ||
|
||||
contains(github.event.issue.assignees.*.login, 'turt2live')
|
||||
steps:
|
||||
- uses: alex-page/github-project-automation-plus@be108970955040d35dd6d053c3aff3faaf678026
|
||||
with:
|
||||
project: Web App Team
|
||||
column: "In Progress"
|
||||
repo-token: ${{ secrets.ELEMENT_BOT_TOKEN }}
|
||||
|
||||
21
.github/workflows/triage-incoming.yml
vendored
21
.github/workflows/triage-incoming.yml
vendored
@@ -1,16 +1,15 @@
|
||||
name: Move new issues into Issue triage board
|
||||
|
||||
on:
|
||||
issues:
|
||||
types: [opened]
|
||||
|
||||
permissions: {} # We use ELEMENT_BOT_TOKEN instead
|
||||
issues:
|
||||
types: [ opened ]
|
||||
|
||||
jobs:
|
||||
automate-project-columns:
|
||||
runs-on: ubuntu-24.04
|
||||
steps:
|
||||
- uses: actions/add-to-project@244f685bbc3b7adfa8466e08b698b5577571133e # v1.0.2
|
||||
with:
|
||||
project-url: https://github.com/orgs/element-hq/projects/120
|
||||
github-token: ${{ secrets.ELEMENT_BOT_TOKEN }}
|
||||
automate-project-columns:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: alex-page/github-project-automation-plus@be108970955040d35dd6d053c3aff3faaf678026
|
||||
with:
|
||||
project: Issue triage
|
||||
column: Incoming
|
||||
repo-token: ${{ secrets.ELEMENT_BOT_TOKEN }}
|
||||
|
||||
381
.github/workflows/triage-labelled.yml
vendored
381
.github/workflows/triage-labelled.yml
vendored
@@ -1,178 +1,231 @@
|
||||
name: Move labelled issues to correct projects
|
||||
|
||||
on:
|
||||
issues:
|
||||
types: [labeled]
|
||||
workflow_call:
|
||||
secrets:
|
||||
ELEMENT_BOT_TOKEN:
|
||||
required: true
|
||||
|
||||
permissions: {} # We use ELEMENT_BOT_TOKEN instead
|
||||
issues:
|
||||
types: [labeled]
|
||||
|
||||
jobs:
|
||||
apply_Z-Labs_label:
|
||||
name: Add Z-Labs label for features behind labs flags
|
||||
runs-on: ubuntu-24.04
|
||||
if: >
|
||||
contains(github.event.issue.labels.*.name, 'A-Maths') ||
|
||||
contains(github.event.issue.labels.*.name, 'A-Location-Sharing') ||
|
||||
contains(github.event.issue.labels.*.name, 'Z-IA') ||
|
||||
contains(github.event.issue.labels.*.name, 'A-Jump-To-Date ') ||
|
||||
contains(github.event.issue.labels.*.name, 'A-Themes-Custom') ||
|
||||
contains(github.event.issue.labels.*.name, 'A-E2EE-Dehydration') ||
|
||||
contains(github.event.issue.labels.*.name, 'A-Tags') ||
|
||||
contains(github.event.issue.labels.*.name, 'A-Video-Rooms') ||
|
||||
contains(github.event.issue.labels.*.name, 'A-Message-Starring') ||
|
||||
contains(github.event.issue.labels.*.name, 'A-Rich-Text-Editor') ||
|
||||
contains(github.event.issue.labels.*.name, 'A-Element-Call')
|
||||
steps:
|
||||
- uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7
|
||||
with:
|
||||
script: |
|
||||
github.rest.issues.addLabels({
|
||||
issue_number: context.issue.number,
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
labels: ['Z-Labs']
|
||||
})
|
||||
apply_Z-Labs_label:
|
||||
name: Add Z-Labs label for features behind labs flags
|
||||
runs-on: ubuntu-latest
|
||||
if: >
|
||||
contains(github.event.issue.labels.*.name, 'A-Maths') ||
|
||||
contains(github.event.issue.labels.*.name, 'A-Message-Pinning') ||
|
||||
contains(github.event.issue.labels.*.name, 'A-Location-Sharing') ||
|
||||
contains(github.event.issue.labels.*.name, 'Z-IA') ||
|
||||
contains(github.event.issue.labels.*.name, 'A-Themes-Custom') ||
|
||||
contains(github.event.issue.labels.*.name, 'A-E2EE-Dehydration') ||
|
||||
contains(github.event.issue.labels.*.name, 'A-Tags') ||
|
||||
contains(github.event.issue.labels.*.name, 'A-Video-Rooms') ||
|
||||
contains(github.event.issue.labels.*.name, 'A-Message-Starring')
|
||||
steps:
|
||||
- uses: actions/github-script@v5
|
||||
with:
|
||||
script: |
|
||||
github.rest.issues.addLabels({
|
||||
issue_number: context.issue.number,
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
labels: ['Z-Labs']
|
||||
})
|
||||
|
||||
apply_Help-Wanted_label:
|
||||
name: Add "Help Wanted" label to all "good first issue" and Hacktoberfest
|
||||
runs-on: ubuntu-24.04
|
||||
if: >
|
||||
contains(github.event.issue.labels.*.name, 'good first issue') ||
|
||||
contains(github.event.issue.labels.*.name, 'Hacktoberfest')
|
||||
steps:
|
||||
- uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7
|
||||
with:
|
||||
script: |
|
||||
github.rest.issues.addLabels({
|
||||
issue_number: context.issue.number,
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
labels: ['Help Wanted']
|
||||
})
|
||||
move_needs_info_issues:
|
||||
name: X-Needs-Info issues to Need info column on triage board
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: konradpabjan/move-labeled-or-milestoned-issue@190352295fe309fcb113b49193bc81d9aaa9cb01
|
||||
with:
|
||||
action-token: "${{ secrets.ELEMENT_BOT_TOKEN }}"
|
||||
project-url: "https://github.com/vector-im/element-web/projects/27"
|
||||
column-name: "Need info"
|
||||
label-name: "X-Needs-Info"
|
||||
|
||||
move_needs_info_issues:
|
||||
name: X-Needs-Info issues to Need info column on triage board
|
||||
runs-on: ubuntu-24.04
|
||||
if: >
|
||||
contains(github.event.issue.labels.*.name, 'X-Needs-Info')
|
||||
steps:
|
||||
- id: add_to_project
|
||||
uses: actions/add-to-project@244f685bbc3b7adfa8466e08b698b5577571133e # v1.0.2
|
||||
with:
|
||||
project-url: ${{ env.PROJECT_URL }}
|
||||
github-token: ${{ secrets.ELEMENT_BOT_TOKEN }}
|
||||
|
||||
- id: set_fields
|
||||
uses: titoportas/update-project-fields@421a54430b3cdc9eefd8f14f9ce0142ab7678751 # v0.1.0
|
||||
with:
|
||||
project-url: ${{ env.PROJECT_URL }}
|
||||
github-token: ${{ secrets.ELEMENT_BOT_TOKEN }}
|
||||
item-id: ${{ steps.add_to_project.outputs.itemId }} # Use the item-id output of the previous step
|
||||
field-keys: Status
|
||||
field-values: "Needs info"
|
||||
add_priority_design_issues_to_project:
|
||||
name: P1 X-Needs-Design to Design project board
|
||||
runs-on: ubuntu-latest
|
||||
if: >
|
||||
contains(github.event.issue.labels.*.name, 'X-Needs-Design')
|
||||
steps:
|
||||
- uses: octokit/graphql-action@v2.x
|
||||
id: add_to_project
|
||||
with:
|
||||
headers: '{"GraphQL-Features": "projects_next_graphql"}'
|
||||
query: |
|
||||
mutation add_to_project($projectid:ID!,$contentid:ID!) {
|
||||
addProjectNextItem(input:{projectId:$projectid contentId:$contentid}) {
|
||||
projectNextItem {
|
||||
id
|
||||
}
|
||||
}
|
||||
}
|
||||
projectid: ${{ env.PROJECT_ID }}
|
||||
contentid: ${{ github.event.issue.node_id }}
|
||||
env:
|
||||
PROJECT_URL: https://github.com/orgs/element-hq/projects/120
|
||||
PROJECT_ID: "PN_kwDOAM0swc0sUA"
|
||||
GITHUB_TOKEN: ${{ secrets.ELEMENT_BOT_TOKEN }}
|
||||
|
||||
move_flakey_test_issues:
|
||||
name: Z-Flaky-Test issues to Sized for maintainer column on triage board
|
||||
runs-on: ubuntu-24.04
|
||||
if: >
|
||||
contains(github.event.issue.labels.*.name, 'Z-Flaky-Test')
|
||||
steps:
|
||||
- id: add_to_project
|
||||
uses: actions/add-to-project@244f685bbc3b7adfa8466e08b698b5577571133e # v1.0.2
|
||||
with:
|
||||
project-url: ${{ env.PROJECT_URL }}
|
||||
github-token: ${{ secrets.ELEMENT_BOT_TOKEN }}
|
||||
|
||||
- id: set_fields
|
||||
uses: titoportas/update-project-fields@421a54430b3cdc9eefd8f14f9ce0142ab7678751 # v0.1.0
|
||||
with:
|
||||
project-url: ${{ env.PROJECT_URL }}
|
||||
github-token: ${{ secrets.ELEMENT_BOT_TOKEN }}
|
||||
item-id: ${{ steps.add_to_project.outputs.itemId }} # Use the item-id output of the previous step
|
||||
field-keys: Status
|
||||
field-values: "Sized for maintainer"
|
||||
add_product_issues:
|
||||
name: X-Needs-Product to Design project board
|
||||
runs-on: ubuntu-latest
|
||||
if: >
|
||||
contains(github.event.issue.labels.*.name, 'X-Needs-Product')
|
||||
steps:
|
||||
- uses: octokit/graphql-action@v2.x
|
||||
id: add_to_project
|
||||
with:
|
||||
headers: '{"GraphQL-Features": "projects_next_graphql"}'
|
||||
query: |
|
||||
mutation add_to_project($projectid:ID!,$contentid:ID!) {
|
||||
addProjectNextItem(input:{projectId:$projectid contentId:$contentid}) {
|
||||
projectNextItem {
|
||||
id
|
||||
}
|
||||
}
|
||||
}
|
||||
projectid: ${{ env.PROJECT_ID }}
|
||||
contentid: ${{ github.event.issue.node_id }}
|
||||
env:
|
||||
PROJECT_URL: https://github.com/orgs/element-hq/projects/120
|
||||
PROJECT_ID: "PN_kwDOAM0swc4AAg6N"
|
||||
GITHUB_TOKEN: ${{ secrets.ELEMENT_BOT_TOKEN }}
|
||||
|
||||
add_priority_design_issues_to_project:
|
||||
name: P1 X-Needs-Design to Design project board
|
||||
runs-on: ubuntu-24.04
|
||||
if: >
|
||||
contains(github.event.issue.labels.*.name, 'X-Needs-Design') &&
|
||||
(contains(github.event.issue.labels.*.name, 'S-Critical') &&
|
||||
(contains(github.event.issue.labels.*.name, 'O-Frequent') ||
|
||||
contains(github.event.issue.labels.*.name, 'O-Occasional')) ||
|
||||
contains(github.event.issue.labels.*.name, 'S-Major') &&
|
||||
contains(github.event.issue.labels.*.name, 'O-Frequent') ||
|
||||
contains(github.event.issue.labels.*.name, 'A11y'))
|
||||
steps:
|
||||
- uses: actions/add-to-project@244f685bbc3b7adfa8466e08b698b5577571133e # v1.0.2
|
||||
with:
|
||||
project-url: https://github.com/orgs/element-hq/projects/18
|
||||
github-token: ${{ secrets.ELEMENT_BOT_TOKEN }}
|
||||
Delight_issues_to_board:
|
||||
name: Delight issues to project board
|
||||
runs-on: ubuntu-latest
|
||||
if: >
|
||||
contains(github.event.issue.labels.*.name, 'A-New-Search-Experience') ||
|
||||
(contains(github.event.issue.labels.*.name, 'A-Threads') &&
|
||||
(contains(github.event.issue.labels.*.name, 'S-Major') ||
|
||||
contains(github.event.issue.labels.*.name, 'S-Critical'))) ||
|
||||
contains(github.event.issue.labels.*.name, 'Team: Delight') ||
|
||||
contains(github.event.issue.labels.*.name, 'Z-NewUserJourney')
|
||||
steps:
|
||||
- uses: octokit/graphql-action@v2.x
|
||||
with:
|
||||
headers: '{"GraphQL-Features": "projects_next_graphql"}'
|
||||
query: |
|
||||
mutation add_to_project($projectid:ID!,$contentid:ID!) {
|
||||
addProjectNextItem(input:{projectId:$projectid contentId:$contentid}) {
|
||||
projectNextItem {
|
||||
id
|
||||
}
|
||||
}
|
||||
}
|
||||
projectid: ${{ env.PROJECT_ID }}
|
||||
contentid: ${{ github.event.issue.node_id }}
|
||||
env:
|
||||
PROJECT_ID: "PN_kwDOAM0swc1HvQ"
|
||||
GITHUB_TOKEN: ${{ secrets.ELEMENT_BOT_TOKEN }}
|
||||
|
||||
Search_issues_to_board:
|
||||
name: Search issues to project board
|
||||
runs-on: ubuntu-latest
|
||||
if: >
|
||||
contains(github.event.issue.labels.*.name, 'A-New-Search-Experience')
|
||||
steps:
|
||||
- uses: octokit/graphql-action@v2.x
|
||||
with:
|
||||
headers: '{"GraphQL-Features": "projects_next_graphql"}'
|
||||
query: |
|
||||
mutation add_to_project($projectid:ID!,$contentid:ID!) {
|
||||
addProjectNextItem(input:{projectId:$projectid contentId:$contentid}) {
|
||||
projectNextItem {
|
||||
id
|
||||
}
|
||||
}
|
||||
}
|
||||
projectid: ${{ env.PROJECT_ID }}
|
||||
contentid: ${{ github.event.issue.node_id }}
|
||||
env:
|
||||
PROJECT_ID: "PN_kwDOAM0swc4ADtaO"
|
||||
GITHUB_TOKEN: ${{ secrets.ELEMENT_BOT_TOKEN }}
|
||||
|
||||
add_product_issues:
|
||||
name: X-Needs-Product to product project board
|
||||
runs-on: ubuntu-24.04
|
||||
if: >
|
||||
contains(github.event.issue.labels.*.name, 'X-Needs-Product')
|
||||
steps:
|
||||
- uses: actions/add-to-project@244f685bbc3b7adfa8466e08b698b5577571133e # v1.0.2
|
||||
with:
|
||||
project-url: https://github.com/orgs/element-hq/projects/28
|
||||
github-token: ${{ secrets.ELEMENT_BOT_TOKEN }}
|
||||
move_voice-message_issues:
|
||||
name: A-Voice Messages to voice message board
|
||||
runs-on: ubuntu-latest
|
||||
if: >
|
||||
contains(github.event.issue.labels.*.name, 'A-Voice Messages')
|
||||
steps:
|
||||
- uses: octokit/graphql-action@v2.x
|
||||
with:
|
||||
headers: '{"GraphQL-Features": "projects_next_graphql"}'
|
||||
query: |
|
||||
mutation add_to_project($projectid:ID!,$contentid:ID!) {
|
||||
addProjectNextItem(input:{projectId:$projectid contentId:$contentid}) {
|
||||
projectNextItem {
|
||||
id
|
||||
}
|
||||
}
|
||||
}
|
||||
projectid: ${{ env.PROJECT_ID }}
|
||||
contentid: ${{ github.event.issue.node_id }}
|
||||
env:
|
||||
PROJECT_ID: "PN_kwDOAM0swc2KCw"
|
||||
GITHUB_TOKEN: ${{ secrets.ELEMENT_BOT_TOKEN }}
|
||||
move_message_bubbles_issues:
|
||||
name: A-Message-Bubbles to Message bubbles board
|
||||
runs-on: ubuntu-latest
|
||||
if: >
|
||||
contains(github.event.issue.labels.*.name, 'A-Message-Bubbles')
|
||||
steps:
|
||||
- uses: octokit/graphql-action@v2.x
|
||||
with:
|
||||
headers: '{"GraphQL-Features": "projects_next_graphql"}'
|
||||
query: |
|
||||
mutation add_to_project($projectid:ID!,$contentid:ID!) {
|
||||
addProjectNextItem(input:{projectId:$projectid contentId:$contentid}) {
|
||||
projectNextItem {
|
||||
id
|
||||
}
|
||||
}
|
||||
}
|
||||
projectid: ${{ env.PROJECT_ID }}
|
||||
contentid: ${{ github.event.issue.node_id }}
|
||||
env:
|
||||
PROJECT_ID: "PN_kwDOAM0swc3m-g"
|
||||
GITHUB_TOKEN: ${{ secrets.ELEMENT_BOT_TOKEN }}
|
||||
|
||||
Search_issues_to_board:
|
||||
name: Search issues to project board
|
||||
runs-on: ubuntu-24.04
|
||||
if: >
|
||||
contains(github.event.issue.labels.*.name, 'A-New-Search-Experience')
|
||||
steps:
|
||||
- uses: actions/add-to-project@244f685bbc3b7adfa8466e08b698b5577571133e # v1.0.2
|
||||
with:
|
||||
project-url: https://github.com/orgs/element-hq/projects/48
|
||||
github-token: ${{ secrets.ELEMENT_BOT_TOKEN }}
|
||||
move_ftue_issues:
|
||||
name: Z-FTUE issues to the FTUE project board
|
||||
runs-on: ubuntu-latest
|
||||
if: >
|
||||
contains(github.event.issue.labels.*.name, 'Z-FTUE')
|
||||
steps:
|
||||
- uses: octokit/graphql-action@v2.x
|
||||
with:
|
||||
headers: '{"GraphQL-Features": "projects_next_graphql"}'
|
||||
query: |
|
||||
mutation add_to_project($projectid:ID!,$contentid:ID!) {
|
||||
addProjectNextItem(input:{projectId:$projectid contentId:$contentid}) {
|
||||
projectNextItem {
|
||||
id
|
||||
}
|
||||
}
|
||||
}
|
||||
projectid: ${{ env.PROJECT_ID }}
|
||||
contentid: ${{ github.event.issue.node_id }}
|
||||
env:
|
||||
PROJECT_ID: "PN_kwDOAM0swc4AAqVx"
|
||||
GITHUB_TOKEN: ${{ secrets.ELEMENT_BOT_TOKEN }}
|
||||
|
||||
voip:
|
||||
name: Add labelled issues to VoIP project board
|
||||
runs-on: ubuntu-24.04
|
||||
if: >
|
||||
contains(github.event.issue.labels.*.name, 'Team: VoIP')
|
||||
steps:
|
||||
- uses: actions/add-to-project@244f685bbc3b7adfa8466e08b698b5577571133e # v1.0.2
|
||||
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
|
||||
runs-on: ubuntu-24.04
|
||||
if: >
|
||||
contains(github.event.issue.labels.*.name, 'Team: Crypto')
|
||||
steps:
|
||||
- uses: actions/add-to-project@244f685bbc3b7adfa8466e08b698b5577571133e # v1.0.2
|
||||
with:
|
||||
project-url: https://github.com/orgs/element-hq/projects/76
|
||||
github-token: ${{ secrets.ELEMENT_BOT_TOKEN }}
|
||||
|
||||
tech_debt:
|
||||
name: Add labelled issues to tech debt project
|
||||
runs-on: ubuntu-24.04
|
||||
if: >
|
||||
contains(github.event.issue.labels.*.name, 'A-Developer-Experience') ||
|
||||
contains(github.event.issue.labels.*.name, 'A-Documentation') ||
|
||||
contains(github.event.issue.labels.*.name, 'A-Packaging') ||
|
||||
contains(github.event.issue.labels.*.name, 'A-Technical-Debt') ||
|
||||
contains(github.event.issue.labels.*.name, 'A-Testing') ||
|
||||
contains(github.event.issue.labels.*.name, 'Z-Flaky-Test')
|
||||
steps:
|
||||
- uses: actions/add-to-project@244f685bbc3b7adfa8466e08b698b5577571133e # v1.0.2
|
||||
with:
|
||||
project-url: https://github.com/orgs/element-hq/projects/101
|
||||
github-token: ${{ secrets.ELEMENT_BOT_TOKEN }}
|
||||
move_WTF_issues:
|
||||
name: Z-WTF issues to the WTF project board
|
||||
runs-on: ubuntu-latest
|
||||
if: >
|
||||
contains(github.event.issue.labels.*.name, 'Z-WTF')
|
||||
steps:
|
||||
- uses: octokit/graphql-action@v2.x
|
||||
with:
|
||||
headers: '{"GraphQL-Features": "projects_next_graphql"}'
|
||||
query: |
|
||||
mutation add_to_project($projectid:ID!,$contentid:ID!) {
|
||||
addProjectNextItem(input:{projectId:$projectid contentId:$contentid}) {
|
||||
projectNextItem {
|
||||
id
|
||||
}
|
||||
}
|
||||
}
|
||||
projectid: ${{ env.PROJECT_ID }}
|
||||
contentid: ${{ github.event.issue.node_id }}
|
||||
env:
|
||||
PROJECT_ID: "PN_kwDOAM0swc4AArk0"
|
||||
GITHUB_TOKEN: ${{ secrets.ELEMENT_BOT_TOKEN }}
|
||||
|
||||
261
.github/workflows/triage-move-review-requests.yml
vendored
261
.github/workflows/triage-move-review-requests.yml
vendored
@@ -1,140 +1,139 @@
|
||||
name: Move pull requests asking for review to the relevant project
|
||||
on:
|
||||
pull_request_target:
|
||||
types: [review_requested]
|
||||
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@8ad880e4d437783ea2ab17010324de1075228110 # v2.3.2
|
||||
id: find_team_members
|
||||
with:
|
||||
headers: '{"GraphQL-Features": "projects_next_graphql"}'
|
||||
query: |
|
||||
query find_team_members($team: String!) {
|
||||
organization(login: "element-hq") {
|
||||
team(slug: $team) {
|
||||
members {
|
||||
nodes {
|
||||
login
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
team: ${{ env.TEAM }}
|
||||
env:
|
||||
TEAM: "design"
|
||||
GITHUB_TOKEN: ${{ secrets.ELEMENT_BOT_TOKEN }}
|
||||
- id: any_matching_reviewers
|
||||
run: |
|
||||
# Fetch requested reviewers, and people who are on the team
|
||||
echo '${{ tojson(fromjson(steps.find_team_members.outputs.data).organization.team.members.nodes[*].login) }}' | tee /tmp/team_members.json
|
||||
echo '${{ tojson(github.event.pull_request.requested_reviewers[*].login) }}' | tee /tmp/reviewers.json
|
||||
jq --raw-output .[] < /tmp/team_members.json | sort | tee /tmp/team_members.txt
|
||||
jq --raw-output .[] < /tmp/reviewers.json | sort | tee /tmp/reviewers.txt
|
||||
add_design_pr_to_project:
|
||||
name: Move PRs asking for design review to the design board
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: octokit/graphql-action@v2.x
|
||||
id: find_team_members
|
||||
with:
|
||||
headers: '{"GraphQL-Features": "projects_next_graphql"}'
|
||||
query: |
|
||||
query find_team_members($team: String!) {
|
||||
organization(login: "vector-im") {
|
||||
team(slug: $team) {
|
||||
members {
|
||||
nodes {
|
||||
login
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
team: ${{ env.TEAM }}
|
||||
env:
|
||||
TEAM: "design"
|
||||
GITHUB_TOKEN: ${{ secrets.ELEMENT_BOT_TOKEN }}
|
||||
- id: any_matching_reviewers
|
||||
run: |
|
||||
# Fetch requested reviewers, and people who are on the team
|
||||
echo '${{ tojson(fromjson(steps.find_team_members.outputs.data).organization.team.members.nodes[*].login) }}' | tee /tmp/team_members.json
|
||||
echo '${{ tojson(github.event.pull_request.requested_reviewers[*].login) }}' | tee /tmp/reviewers.json
|
||||
jq --raw-output .[] < /tmp/team_members.json | sort | tee /tmp/team_members.txt
|
||||
jq --raw-output .[] < /tmp/reviewers.json | sort | tee /tmp/reviewers.txt
|
||||
|
||||
# Fetch requested team reviewers, and the name of the team
|
||||
echo '${{ tojson(github.event.pull_request.requested_teams[*].slug) }}' | tee /tmp/team_reviewers.json
|
||||
jq --raw-output .[] < /tmp/team_reviewers.json | sort | tee /tmp/team_reviewers.txt
|
||||
echo '${{ env.TEAM }}' | tee /tmp/team.txt
|
||||
# Fetch requested team reviewers, and the name of the team
|
||||
echo '${{ tojson(github.event.pull_request.requested_teams[*].slug) }}' | tee /tmp/team_reviewers.json
|
||||
jq --raw-output .[] < /tmp/team_reviewers.json | sort | tee /tmp/team_reviewers.txt
|
||||
echo '${{ env.TEAM }}' | tee /tmp/team.txt
|
||||
|
||||
# If either a reviewer matches a team member, or a team matches our team, say "true"
|
||||
if [ $(join /tmp/team_members.txt /tmp/reviewers.txt | wc -l) != 0 ]; then
|
||||
echo "match=true" >> $GITHUB_OUTPUT
|
||||
elif [ $(join /tmp/team.txt /tmp/team_reviewers.txt | wc -l) != 0 ]; then
|
||||
echo "match=true" >> $GITHUB_OUTPUT
|
||||
else
|
||||
echo "match=false" >> $GITHUB_OUTPUT
|
||||
fi
|
||||
env:
|
||||
TEAM: "design"
|
||||
- uses: octokit/graphql-action@8ad880e4d437783ea2ab17010324de1075228110 # v2.3.2
|
||||
id: add_to_project
|
||||
if: steps.any_matching_reviewers.outputs.match == 'true'
|
||||
with:
|
||||
headers: '{"GraphQL-Features": "projects_next_graphql"}'
|
||||
query: |
|
||||
mutation add_to_project($projectid:ID!, $contentid:ID!) {
|
||||
addProjectV2ItemById(input: {projectId: $projectid contentId: $contentid}) {
|
||||
item {
|
||||
id
|
||||
}
|
||||
}
|
||||
}
|
||||
projectid: ${{ env.PROJECT_ID }}
|
||||
contentid: ${{ github.event.pull_request.node_id }}
|
||||
env:
|
||||
PROJECT_ID: "PVT_kwDOAM0swc0sUA"
|
||||
TEAM: "design"
|
||||
GITHUB_TOKEN: ${{ secrets.ELEMENT_BOT_TOKEN }}
|
||||
# If either a reviewer matches a team member, or a team matches our team, say "true"
|
||||
if [ $(join /tmp/team_members.txt /tmp/reviewers.txt | wc -l) != 0 ]; then
|
||||
echo "::set-output name=match::true"
|
||||
elif [ $(join /tmp/team.txt /tmp/team_reviewers.txt | wc -l) != 0 ]; then
|
||||
echo "::set-output name=match::true"
|
||||
else
|
||||
echo "::set-output name=match::false"
|
||||
fi
|
||||
env:
|
||||
TEAM: "design"
|
||||
- uses: octokit/graphql-action@v2.x
|
||||
id: add_to_project
|
||||
if: steps.any_matching_reviewers.outputs.match == 'true'
|
||||
with:
|
||||
headers: '{"GraphQL-Features": "projects_next_graphql"}'
|
||||
query: |
|
||||
mutation add_to_project($projectid:ID!, $contentid:ID!) {
|
||||
addProjectNextItem(input:{projectId:$projectid contentId:$contentid}) {
|
||||
projectNextItem {
|
||||
id
|
||||
}
|
||||
}
|
||||
}
|
||||
projectid: ${{ env.PROJECT_ID }}
|
||||
contentid: ${{ github.event.pull_request.node_id }}
|
||||
env:
|
||||
PROJECT_ID: "PN_kwDOAM0swc0sUA"
|
||||
TEAM: "design"
|
||||
GITHUB_TOKEN: ${{ secrets.ELEMENT_BOT_TOKEN }}
|
||||
|
||||
add_product_pr_to_project:
|
||||
name: Move PRs asking for design review to the design board
|
||||
runs-on: ubuntu-24.04
|
||||
steps:
|
||||
- uses: octokit/graphql-action@8ad880e4d437783ea2ab17010324de1075228110 # v2.3.2
|
||||
id: find_team_members
|
||||
with:
|
||||
headers: '{"GraphQL-Features": "projects_next_graphql"}'
|
||||
query: |
|
||||
query find_team_members($team: String!) {
|
||||
organization(login: "element-hq") {
|
||||
team(slug: $team) {
|
||||
members {
|
||||
nodes {
|
||||
login
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
team: ${{ env.TEAM }}
|
||||
env:
|
||||
TEAM: "product"
|
||||
GITHUB_TOKEN: ${{ secrets.ELEMENT_BOT_TOKEN }}
|
||||
- id: any_matching_reviewers
|
||||
run: |
|
||||
# Fetch requested reviewers, and people who are on the team
|
||||
echo '${{ tojson(fromjson(steps.find_team_members.outputs.data).organization.team.members.nodes[*].login) }}' | tee /tmp/team_members.json
|
||||
echo '${{ tojson(github.event.pull_request.requested_reviewers[*].login) }}' | tee /tmp/reviewers.json
|
||||
jq --raw-output .[] < /tmp/team_members.json | sort | tee /tmp/team_members.txt
|
||||
jq --raw-output .[] < /tmp/reviewers.json | sort | tee /tmp/reviewers.txt
|
||||
add_product_pr_to_project:
|
||||
name: Move PRs asking for design review to the design board
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: octokit/graphql-action@v2.x
|
||||
id: find_team_members
|
||||
with:
|
||||
headers: '{"GraphQL-Features": "projects_next_graphql"}'
|
||||
query: |
|
||||
query find_team_members($team: String!) {
|
||||
organization(login: "vector-im") {
|
||||
team(slug: $team) {
|
||||
members {
|
||||
nodes {
|
||||
login
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
team: ${{ env.TEAM }}
|
||||
env:
|
||||
TEAM: "product"
|
||||
GITHUB_TOKEN: ${{ secrets.ELEMENT_BOT_TOKEN }}
|
||||
- id: any_matching_reviewers
|
||||
run: |
|
||||
# Fetch requested reviewers, and people who are on the team
|
||||
echo '${{ tojson(fromjson(steps.find_team_members.outputs.data).organization.team.members.nodes[*].login) }}' | tee /tmp/team_members.json
|
||||
echo '${{ tojson(github.event.pull_request.requested_reviewers[*].login) }}' | tee /tmp/reviewers.json
|
||||
jq --raw-output .[] < /tmp/team_members.json | sort | tee /tmp/team_members.txt
|
||||
jq --raw-output .[] < /tmp/reviewers.json | sort | tee /tmp/reviewers.txt
|
||||
|
||||
# Fetch requested team reviewers, and the name of the team
|
||||
echo '${{ tojson(github.event.pull_request.requested_teams[*].slug) }}' | tee /tmp/team_reviewers.json
|
||||
jq --raw-output .[] < /tmp/team_reviewers.json | sort | tee /tmp/team_reviewers.txt
|
||||
echo '${{ env.TEAM }}' | tee /tmp/team.txt
|
||||
# Fetch requested team reviewers, and the name of the team
|
||||
echo '${{ tojson(github.event.pull_request.requested_teams[*].slug) }}' | tee /tmp/team_reviewers.json
|
||||
jq --raw-output .[] < /tmp/team_reviewers.json | sort | tee /tmp/team_reviewers.txt
|
||||
echo '${{ env.TEAM }}' | tee /tmp/team.txt
|
||||
|
||||
# If either a reviewer matches a team member, or a team matches our team, say "true"
|
||||
if [ $(join /tmp/team_members.txt /tmp/reviewers.txt | wc -l) != 0 ]; then
|
||||
echo "match=true" >> $GITHUB_OUTPUT
|
||||
elif [ $(join /tmp/team.txt /tmp/team_reviewers.txt | wc -l) != 0 ]; then
|
||||
echo "match=true" >> $GITHUB_OUTPUT
|
||||
else
|
||||
echo "match=false" >> $GITHUB_OUTPUT
|
||||
fi
|
||||
env:
|
||||
TEAM: "product"
|
||||
- uses: octokit/graphql-action@8ad880e4d437783ea2ab17010324de1075228110 # v2.3.2
|
||||
id: add_to_project
|
||||
if: steps.any_matching_reviewers.outputs.match == 'true'
|
||||
with:
|
||||
headers: '{"GraphQL-Features": "projects_next_graphql"}'
|
||||
query: |
|
||||
mutation add_to_project($projectid:ID!, $contentid:ID!) {
|
||||
addProjectV2ItemById(input: {projectId: $projectid contentId: $contentid}) {
|
||||
item {
|
||||
id
|
||||
}
|
||||
}
|
||||
}
|
||||
projectid: ${{ env.PROJECT_ID }}
|
||||
contentid: ${{ github.event.pull_request.node_id }}
|
||||
env:
|
||||
PROJECT_ID: "PVT_kwDOAM0swc4AAg6N"
|
||||
TEAM: "product"
|
||||
GITHUB_TOKEN: ${{ secrets.ELEMENT_BOT_TOKEN }}
|
||||
# If either a reviewer matches a team member, or a team matches our team, say "true"
|
||||
if [ $(join /tmp/team_members.txt /tmp/reviewers.txt | wc -l) != 0 ]; then
|
||||
echo "::set-output name=match::true"
|
||||
elif [ $(join /tmp/team.txt /tmp/team_reviewers.txt | wc -l) != 0 ]; then
|
||||
echo "::set-output name=match::true"
|
||||
else
|
||||
echo "::set-output name=match::false"
|
||||
fi
|
||||
env:
|
||||
TEAM: "product"
|
||||
- uses: octokit/graphql-action@v2.x
|
||||
id: add_to_project
|
||||
if: steps.any_matching_reviewers.outputs.match == 'true'
|
||||
with:
|
||||
headers: '{"GraphQL-Features": "projects_next_graphql"}'
|
||||
query: |
|
||||
mutation add_to_project($projectid:ID!, $contentid:ID!) {
|
||||
addProjectNextItem(input:{projectId:$projectid contentId:$contentid}) {
|
||||
projectNextItem {
|
||||
id
|
||||
}
|
||||
}
|
||||
}
|
||||
projectid: ${{ env.PROJECT_ID }}
|
||||
contentid: ${{ github.event.pull_request.node_id }}
|
||||
env:
|
||||
PROJECT_ID: "PN_kwDOAM0swc4AAg6N"
|
||||
TEAM: "product"
|
||||
GITHUB_TOKEN: ${{ secrets.ELEMENT_BOT_TOKEN }}
|
||||
|
||||
30
.github/workflows/triage-priority-bugs.yml
vendored
Normal file
30
.github/workflows/triage-priority-bugs.yml
vendored
Normal file
@@ -0,0 +1,30 @@
|
||||
name: Move P1 bugs to boards
|
||||
|
||||
on:
|
||||
issues:
|
||||
types: [labeled, unlabeled]
|
||||
|
||||
jobs:
|
||||
P1_issues_to_crypto_team_workboard:
|
||||
runs-on: ubuntu-latest
|
||||
if: >
|
||||
contains(github.event.issue.labels.*.name, 'Z-UISI') ||
|
||||
(contains(github.event.issue.labels.*.name, 'A-E2EE') ||
|
||||
contains(github.event.issue.labels.*.name, 'A-E2EE-Cross-Signing') ||
|
||||
contains(github.event.issue.labels.*.name, 'A-E2EE-Dehydration') ||
|
||||
contains(github.event.issue.labels.*.name, 'A-E2EE-Key-Backup') ||
|
||||
contains(github.event.issue.labels.*.name, 'A-E2EE-SAS-Verification')) &&
|
||||
(contains(github.event.issue.labels.*.name, 'T-Defect') &&
|
||||
contains(github.event.issue.labels.*.name, 'S-Critical') &&
|
||||
(contains(github.event.issue.labels.*.name, 'O-Frequent') ||
|
||||
contains(github.event.issue.labels.*.name, 'O-Occasional')) ||
|
||||
contains(github.event.issue.labels.*.name, 'S-Major') &&
|
||||
contains(github.event.issue.labels.*.name, 'O-Frequent') ||
|
||||
contains(github.event.issue.labels.*.name, 'A11y') &&
|
||||
contains(github.event.issue.labels.*.name, 'O-Frequent'))
|
||||
steps:
|
||||
- uses: alex-page/github-project-automation-plus@be108970955040d35dd6d053c3aff3faaf678026
|
||||
with:
|
||||
project: Crypto Team
|
||||
column: Ready
|
||||
repo-token: ${{ secrets.ELEMENT_BOT_TOKEN }}
|
||||
29
.github/workflows/triage-stale.yml
vendored
29
.github/workflows/triage-stale.yml
vendored
@@ -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@5bef64f19d7facfb25b37b414482c7164d639639 # v9
|
||||
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."
|
||||
136
.github/workflows/triage-unlabelled.yml
vendored
136
.github/workflows/triage-unlabelled.yml
vendored
@@ -1,73 +1,71 @@
|
||||
name: Move unlabelled from needs info columns to triaged
|
||||
|
||||
on:
|
||||
issues:
|
||||
types: [unlabeled]
|
||||
permissions: {}
|
||||
jobs:
|
||||
Move_Unabeled_Issue_On_Project_Board:
|
||||
name: Move no longer X-Needs-Info issues to Triaged
|
||||
runs-on: ubuntu-24.04
|
||||
permissions:
|
||||
repository-projects: read
|
||||
if: >
|
||||
${{
|
||||
!contains(github.event.issue.labels.*.name, 'X-Needs-Info') }}
|
||||
env:
|
||||
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 }}
|
||||
issues:
|
||||
types: [ unlabeled ]
|
||||
|
||||
remove_Z-Labs_label:
|
||||
name: Remove Z-Labs label when features behind labs flags are removed
|
||||
runs-on: ubuntu-24.04
|
||||
if: >
|
||||
!(contains(github.event.issue.labels.*.name, 'A-Maths') ||
|
||||
contains(github.event.issue.labels.*.name, 'A-Message-Pinning') ||
|
||||
contains(github.event.issue.labels.*.name, 'A-Location-Sharing') ||
|
||||
contains(github.event.issue.labels.*.name, 'Z-IA') ||
|
||||
contains(github.event.issue.labels.*.name, 'A-Jump-To-Date') ||
|
||||
contains(github.event.issue.labels.*.name, 'A-Themes-Custom') ||
|
||||
contains(github.event.issue.labels.*.name, 'A-E2EE-Dehydration') ||
|
||||
contains(github.event.issue.labels.*.name, 'A-Tags') ||
|
||||
contains(github.event.issue.labels.*.name, 'A-Video-Rooms') ||
|
||||
contains(github.event.issue.labels.*.name, 'A-Message-Starring') ||
|
||||
contains(github.event.issue.labels.*.name, 'A-Rich-Text-Editor') ||
|
||||
contains(github.event.issue.labels.*.name, 'A-Element-Call')) &&
|
||||
contains(github.event.issue.labels.*.name, 'Z-Labs')
|
||||
steps:
|
||||
- uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7
|
||||
with:
|
||||
script: |
|
||||
github.rest.issues.removeLabel({
|
||||
issue_number: context.issue.number,
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
name: ['Z-Labs']
|
||||
})
|
||||
jobs:
|
||||
Move_Unabeled_Issue_On_Project_Board:
|
||||
name: Move no longer X-Needs-Info issues to Triaged
|
||||
runs-on: ubuntu-latest
|
||||
if: >
|
||||
${{
|
||||
!contains(github.event.issue.labels.*.name, 'X-Needs-Info') }}
|
||||
env:
|
||||
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@be108970955040d35dd6d053c3aff3faaf678026
|
||||
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
|
||||
runs-on: ubuntu-latest
|
||||
if: >
|
||||
!(contains(github.event.issue.labels.*.name, 'A-Maths') ||
|
||||
contains(github.event.issue.labels.*.name, 'A-Message-Pinning') ||
|
||||
contains(github.event.issue.labels.*.name, 'A-Threads') ||
|
||||
contains(github.event.issue.labels.*.name, 'A-Polls') ||
|
||||
contains(github.event.issue.labels.*.name, 'A-Location-Sharing') ||
|
||||
contains(github.event.issue.labels.*.name, 'A-Message-Bubbles') ||
|
||||
contains(github.event.issue.labels.*.name, 'Z-IA') ||
|
||||
contains(github.event.issue.labels.*.name, 'A-Themes-Custom') ||
|
||||
contains(github.event.issue.labels.*.name, 'A-E2EE-Dehydration') ||
|
||||
contains(github.event.issue.labels.*.name, 'A-Tags') ||
|
||||
contains(github.event.issue.labels.*.name, 'A-Video-Rooms') ||
|
||||
contains(github.event.issue.labels.*.name, 'A-Message-Starring')) &&
|
||||
contains(github.event.issue.labels.*.name, 'Z-Labs')
|
||||
steps:
|
||||
- uses: actions/github-script@v5
|
||||
with:
|
||||
script: |
|
||||
github.rest.issues.removeLabel({
|
||||
issue_number: context.issue.number,
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
name: ['Z-Labs']
|
||||
})
|
||||
|
||||
33
.github/workflows/update-jitsi.yml
vendored
33
.github/workflows/update-jitsi.yml
vendored
@@ -1,33 +0,0 @@
|
||||
# Re-fetches the Jitsi SDK and opens a PR to update it if it's different from what's in the repository
|
||||
name: Update Jitsi
|
||||
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@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5
|
||||
|
||||
- uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4
|
||||
with:
|
||||
cache: "yarn"
|
||||
node-version: "lts/*"
|
||||
|
||||
- name: Install Deps
|
||||
run: "yarn install --frozen-lockfile"
|
||||
|
||||
- name: Fetch Jitsi
|
||||
run: "yarn update:jitsi"
|
||||
|
||||
- name: Create Pull Request
|
||||
uses: peter-evans/create-pull-request@271a8d0340265f705b14b6d32b9829c1cb33d45e # v7
|
||||
with:
|
||||
token: ${{ secrets.ELEMENT_BOT_TOKEN }}
|
||||
branch: actions/jitsi-update
|
||||
delete-branch: true
|
||||
title: Jitsi Update
|
||||
labels: |
|
||||
T-Task
|
||||
108
.github/workflows/update-topics.yaml
vendored
108
.github/workflows/update-topics.yaml
vendored
@@ -1,108 +0,0 @@
|
||||
name: Update release topics
|
||||
on:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
expected_status:
|
||||
description: What type of release is the next expected release
|
||||
required: true
|
||||
default: RC
|
||||
type: choice
|
||||
options:
|
||||
- RC
|
||||
- Release
|
||||
expected_date:
|
||||
description: Expected release date e.g. July 11th
|
||||
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@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7
|
||||
env:
|
||||
HS_URL: ${{ secrets.BETABOT_HS_URL }}
|
||||
LOBBY_ROOM_ID: ${{ secrets.ROOM_ID }}
|
||||
PUBLIC_ROOM_ID: "!IemiTbwVankHTFiEoh: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_ROOM_ID, ANNOUNCEMENT_ROOM_ID } = process.env;
|
||||
|
||||
const repo = context.repo;
|
||||
const { data } = await github.rest.repos.getLatestRelease({
|
||||
owner: repo.owner,
|
||||
repo: repo.repo,
|
||||
});
|
||||
console.log("Found latest version: " + data.tag_name);
|
||||
|
||||
const releaseTopic = `Stable: ${data.tag_name} | ${RELEASE_STATUS}`;
|
||||
console.log("Release topic: " + releaseTopic);
|
||||
|
||||
const regex = /Stable: v(.+) \| Release status: (\w+) expected (\w+ \d+\w\w)/gm;
|
||||
|
||||
async function updateReleaseInTopic(roomId) {
|
||||
const apiUrl = `${HS_URL}/_matrix/client/v3/rooms/${roomId}/state/m.room.topic/`;
|
||||
const headers = {
|
||||
"Content-Type": "application/json",
|
||||
"Authorization": `Bearer ${TOKEN}`,
|
||||
};
|
||||
await fetch(`${HS_URL}/_matrix/client/v3/rooms/${roomId}/join`, {
|
||||
method: "POST",
|
||||
headers,
|
||||
body: "{}",
|
||||
});
|
||||
|
||||
let res = await fetch(apiUrl, {
|
||||
method: "GET",
|
||||
headers,
|
||||
});
|
||||
|
||||
if (!res.ok) {
|
||||
console.log(roomId, "failed to fetch", await res.text());
|
||||
return;
|
||||
}
|
||||
|
||||
const data = await res.json();
|
||||
console.log(roomId, "got event", data);
|
||||
|
||||
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"].forEach(d => {
|
||||
d.body = d.body.replace(regex, releaseTopic);
|
||||
});
|
||||
}
|
||||
if (data["m.topic"]) {
|
||||
data["m.topic"].forEach(d => {
|
||||
d.body = d.body.replace(regex, releaseTopic);
|
||||
});
|
||||
}
|
||||
|
||||
res = await fetch(apiUrl, {
|
||||
method: "PUT",
|
||||
body: JSON.stringify({
|
||||
...data,
|
||||
topic,
|
||||
}),
|
||||
headers,
|
||||
});
|
||||
|
||||
if (res.ok) {
|
||||
console.log(roomId, "topic updated:", topic);
|
||||
} else {
|
||||
console.log(roomId, await res.text());
|
||||
}
|
||||
}
|
||||
|
||||
await updateReleaseInTopic(LOBBY_ROOM_ID);
|
||||
await updateReleaseInTopic(PUBLIC_ROOM_ID);
|
||||
await updateReleaseInTopic(ANNOUNCEMENT_ROOM_ID);
|
||||
8
.github/workflows/upgrade_dependencies.yml
vendored
Normal file
8
.github/workflows/upgrade_dependencies.yml
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
name: Upgrade Dependencies
|
||||
on:
|
||||
workflow_dispatch: { }
|
||||
jobs:
|
||||
upgrade:
|
||||
uses: matrix-org/matrix-js-sdk/.github/workflows/upgrade_dependencies.yml@develop
|
||||
secrets:
|
||||
ELEMENT_BOT_TOKEN: ${{ secrets.ELEMENT_BOT_TOKEN }}
|
||||
9
.gitignore
vendored
9
.gitignore
vendored
@@ -25,12 +25,5 @@ electron/pub
|
||||
.env
|
||||
/coverage
|
||||
# Auto-generated file
|
||||
/src/modules.js
|
||||
/src/modules.ts
|
||||
/build_config.yaml
|
||||
/book
|
||||
/index.html
|
||||
# version file and tarball created by `npm pack` / `yarn pack`
|
||||
/git-revision.txt
|
||||
|
||||
*storybook.log
|
||||
storybook-static
|
||||
|
||||
@@ -1,4 +0,0 @@
|
||||
#!/usr/bin/env sh
|
||||
. "$(dirname "$0")/_/husky.sh"
|
||||
|
||||
npx lint-staged --concurrent false
|
||||
@@ -1,7 +0,0 @@
|
||||
{
|
||||
"*": "prettier --write",
|
||||
"src/**/*.(ts|tsx)": ["eslint --fix"],
|
||||
"scripts/**/*.(ts|tsx)": ["eslint --fix"],
|
||||
"module_system/**/*.(ts|tsx)": ["eslint --fix"],
|
||||
"*.pcss": ["stylelint --fix"]
|
||||
}
|
||||
@@ -1,37 +1,36 @@
|
||||
{
|
||||
"minify": false,
|
||||
"enableClasses": false,
|
||||
"feature-detects": [
|
||||
"test/css/animations",
|
||||
"test/css/displaytable",
|
||||
"test/css/filters",
|
||||
"test/css/flexbox",
|
||||
"test/css/objectfit",
|
||||
"minify": true,
|
||||
"enableClasses": false,
|
||||
"feature-detects": [
|
||||
"test/css/animations",
|
||||
"test/css/displaytable",
|
||||
"test/css/filters",
|
||||
"test/css/flexbox",
|
||||
"test/css/objectfit",
|
||||
|
||||
"test/es5/date",
|
||||
"test/es5/function",
|
||||
"test/es5/object",
|
||||
"test/es5/undefined",
|
||||
"test/es5/date",
|
||||
"test/es5/function",
|
||||
"test/es5/object",
|
||||
"test/es5/undefined",
|
||||
|
||||
"test/es6/array",
|
||||
"test/es6/collections",
|
||||
"test/es6/promises",
|
||||
"test/es6/string",
|
||||
"test/es6/array",
|
||||
"test/es6/collections",
|
||||
"test/es6/promises",
|
||||
"test/es6/string",
|
||||
|
||||
"test/svg",
|
||||
"test/svg/asimg",
|
||||
"test/svg/filters",
|
||||
"test/svg",
|
||||
"test/svg/asimg",
|
||||
"test/svg/filters",
|
||||
|
||||
"test/url/parser",
|
||||
"test/url/urlsearchparams",
|
||||
"test/url/parser",
|
||||
"test/url/urlsearchparams",
|
||||
|
||||
"test/cors",
|
||||
"test/crypto",
|
||||
"test/iframe/sandbox",
|
||||
"test/json",
|
||||
"test/network/fetch",
|
||||
"test/storage/localstorage",
|
||||
"test/window/resizeobserver",
|
||||
"test/audio/webaudio"
|
||||
]
|
||||
"test/cors",
|
||||
"test/crypto",
|
||||
"test/iframe/sandbox",
|
||||
"test/json",
|
||||
"test/network/fetch",
|
||||
"test/storage/localstorage",
|
||||
"test/window/resizeobserver"
|
||||
]
|
||||
}
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
22
|
||||
@@ -1,47 +0,0 @@
|
||||
/build
|
||||
/dist
|
||||
/lib
|
||||
/node_modules
|
||||
/packages/
|
||||
/webapp
|
||||
/*.log
|
||||
yarn.lock
|
||||
electron/dist
|
||||
electron/pub
|
||||
**/.idea
|
||||
/.tmp
|
||||
/webpack-stats.json
|
||||
.vscode
|
||||
.vscode/
|
||||
.env
|
||||
/coverage
|
||||
# Auto-generated file
|
||||
/src/modules.ts
|
||||
/src/modules.js
|
||||
/src/i18n/strings
|
||||
/build_config.yaml
|
||||
# Raises an error because it contains a template var breaking the script tag
|
||||
src/vector/index.html
|
||||
src/vector/modernizr.js
|
||||
/docs/lib
|
||||
/book
|
||||
/debian/tmp
|
||||
/.npmrc
|
||||
package-lock.json
|
||||
|
||||
# This file is owned, parsed, and generated by allchange, which doesn't comply with prettier
|
||||
/CHANGELOG.md
|
||||
/docs/changelogs
|
||||
|
||||
# Legacy skinning file that some people might still have
|
||||
/src/component-index.js
|
||||
|
||||
# Downloaded and already minified
|
||||
res/jitsi_external_api.min.js
|
||||
|
||||
# This file is also machine-generated
|
||||
/playwright/e2e/crypto/test_indexeddb_cryptostore_dump/dump.json
|
||||
/playwright/test-results/
|
||||
/playwright/html-report/
|
||||
/playwright/logs/
|
||||
/playwright/snapshots/
|
||||
@@ -1 +0,0 @@
|
||||
module.exports = require("eslint-plugin-matrix-org/.prettierrc.js");
|
||||
@@ -1 +0,0 @@
|
||||
module.exports = require("eslint-plugin-matrix-org/.prettierrc.js");
|
||||
@@ -1,28 +0,0 @@
|
||||
/*
|
||||
Copyright 2025 New Vector Ltd.
|
||||
|
||||
SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Commercial
|
||||
Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
import { create } from "storybook/theming";
|
||||
|
||||
export default create({
|
||||
base: "light",
|
||||
|
||||
// Colors
|
||||
textColor: "#1b1d22",
|
||||
colorSecondary: "#111111",
|
||||
|
||||
// UI
|
||||
appBg: "#ffffff",
|
||||
appContentBg: "#ffffff",
|
||||
|
||||
// Toolbar
|
||||
barBg: "#ffffff",
|
||||
|
||||
brandTitle: "Element Web",
|
||||
brandUrl: "https://github.com/element-hq/element-web",
|
||||
brandImage: "https://element.io/images/logo-ele-secondary.svg",
|
||||
brandTarget: "_self",
|
||||
});
|
||||
@@ -1,61 +0,0 @@
|
||||
/*
|
||||
* Copyright 2025 New Vector Ltd.
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Commercial
|
||||
* Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
import { Addon, types, useGlobals } from "storybook/manager-api";
|
||||
import { WithTooltip, IconButton, TooltipLinkList } from "storybook/internal/components";
|
||||
import React from "react";
|
||||
import { GlobeIcon } from "@storybook/icons";
|
||||
|
||||
// We can't import `shared/i18n.tsx` directly here.
|
||||
// The storybook addon doesn't seem to benefit the vite config of storybook and we can't resolve the alias in i18n.tsx.
|
||||
import json from "../webapp/i18n/languages.json";
|
||||
const languages = Object.keys(json).filter((lang) => lang !== "default");
|
||||
|
||||
/**
|
||||
* Returns the title of a language in the user's locale.
|
||||
*/
|
||||
function languageTitle(language: string): string {
|
||||
return new Intl.DisplayNames([language], { type: "language", style: "short" }).of(language) || language;
|
||||
}
|
||||
|
||||
export const languageAddon: Addon = {
|
||||
title: "Language Selector",
|
||||
type: types.TOOL,
|
||||
render: ({ active }) => {
|
||||
const [globals, updateGlobals] = useGlobals();
|
||||
const selectedLanguage = globals.language || "en";
|
||||
|
||||
return (
|
||||
<WithTooltip
|
||||
placement="top"
|
||||
trigger="click"
|
||||
closeOnOutsideClick
|
||||
tooltip={({ onHide }) => {
|
||||
return (
|
||||
<TooltipLinkList
|
||||
links={languages.map((language) => ({
|
||||
id: language,
|
||||
title: languageTitle(language),
|
||||
active: selectedLanguage === language,
|
||||
onClick: async () => {
|
||||
// Update the global state with the selected language
|
||||
updateGlobals({ language });
|
||||
onHide();
|
||||
},
|
||||
}))}
|
||||
/>
|
||||
);
|
||||
}}
|
||||
>
|
||||
<IconButton title="Language">
|
||||
<GlobeIcon />
|
||||
{languageTitle(selectedLanguage)}
|
||||
</IconButton>
|
||||
</WithTooltip>
|
||||
);
|
||||
},
|
||||
};
|
||||
@@ -1,40 +0,0 @@
|
||||
/*
|
||||
Copyright 2025 New Vector Ltd.
|
||||
|
||||
SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Commercial
|
||||
Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
import type { StorybookConfig } from "@storybook/react-vite";
|
||||
import path from "node:path";
|
||||
import { nodePolyfills } from "vite-plugin-node-polyfills";
|
||||
import { mergeConfig } from "vite";
|
||||
|
||||
const config: StorybookConfig = {
|
||||
stories: ["../src/shared-components/**/*.stories.@(js|jsx|mjs|ts|tsx)"],
|
||||
staticDirs: ["../webapp"],
|
||||
addons: ["@storybook/addon-docs", "@storybook/addon-designs"],
|
||||
framework: "@storybook/react-vite",
|
||||
core: {
|
||||
disableTelemetry: true,
|
||||
},
|
||||
typescript: {
|
||||
reactDocgen: "react-docgen-typescript",
|
||||
},
|
||||
async viteFinal(config) {
|
||||
return mergeConfig(config, {
|
||||
resolve: {
|
||||
alias: {
|
||||
// Alias used by i18n.tsx
|
||||
$webapp: path.resolve("webapp"),
|
||||
},
|
||||
},
|
||||
// Needed for counterpart to work
|
||||
plugins: [nodePolyfills({ include: ["process", "util"] })],
|
||||
server: {
|
||||
allowedHosts: ["localhost", ".docker.internal"],
|
||||
},
|
||||
});
|
||||
},
|
||||
};
|
||||
export default config;
|
||||
@@ -1,18 +0,0 @@
|
||||
/*
|
||||
Copyright 2025 New Vector Ltd.
|
||||
|
||||
SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Commercial
|
||||
Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
import React from "react";
|
||||
|
||||
import { addons } from "storybook/manager-api";
|
||||
import ElementTheme from "./ElementTheme";
|
||||
import { languageAddon } from "./languageAddon";
|
||||
|
||||
addons.setConfig({
|
||||
theme: ElementTheme,
|
||||
});
|
||||
|
||||
addons.register("elementhq/language", () => addons.add("language", languageAddon));
|
||||
@@ -1,10 +0,0 @@
|
||||
/*
|
||||
Copyright 2025 New Vector Ltd.
|
||||
|
||||
SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Commercial
|
||||
Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
.docs-story {
|
||||
background: var(--cpd-color-bg-canvas-default);
|
||||
}
|
||||
@@ -1,106 +0,0 @@
|
||||
import type { ArgTypes, Preview, Decorator } from "@storybook/react-vite";
|
||||
import { addons } from "storybook/preview-api";
|
||||
|
||||
import "../res/css/shared.pcss";
|
||||
import "./preview.css";
|
||||
import React, { useLayoutEffect } from "react";
|
||||
import { FORCE_RE_RENDER } from "storybook/internal/core-events";
|
||||
import { setLanguage } from "../src/shared-components/utils/i18n";
|
||||
import { TooltipProvider } from "@vector-im/compound-web";
|
||||
|
||||
export const globalTypes = {
|
||||
theme: {
|
||||
name: "Theme",
|
||||
description: "Global theme for components",
|
||||
toolbar: {
|
||||
icon: "circlehollow",
|
||||
title: "Theme",
|
||||
items: [
|
||||
{ title: "System", value: "system", icon: "browser" },
|
||||
{ title: "Light", value: "light", icon: "sun" },
|
||||
{ title: "Light (high contrast)", value: "light-hc", icon: "sun" },
|
||||
{ title: "Dark", value: "dark", icon: "moon" },
|
||||
{ title: "Dark (high contrast)", value: "dark-hc", icon: "moon" },
|
||||
],
|
||||
},
|
||||
},
|
||||
language: {
|
||||
name: "Language",
|
||||
description: "Global language for components",
|
||||
},
|
||||
initialGlobals: {
|
||||
theme: "system",
|
||||
language: "en",
|
||||
},
|
||||
} satisfies ArgTypes;
|
||||
|
||||
const allThemesClasses = globalTypes.theme.toolbar.items.map(({ value }) => `cpd-theme-${value}`);
|
||||
|
||||
const ThemeSwitcher: React.FC<{
|
||||
theme: string;
|
||||
}> = ({ theme }) => {
|
||||
useLayoutEffect(() => {
|
||||
document.documentElement.classList.remove(...allThemesClasses);
|
||||
if (theme !== "system") {
|
||||
document.documentElement.classList.add(`cpd-theme-${theme}`);
|
||||
}
|
||||
return () => document.documentElement.classList.remove(...allThemesClasses);
|
||||
}, [theme]);
|
||||
|
||||
return null;
|
||||
};
|
||||
|
||||
const withThemeProvider: Decorator = (Story, context) => {
|
||||
return (
|
||||
<>
|
||||
<ThemeSwitcher theme={context.globals.theme} />
|
||||
<Story />
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
const LanguageSwitcher: React.FC<{
|
||||
language: string;
|
||||
}> = ({ language }) => {
|
||||
useLayoutEffect(() => {
|
||||
const changeLanguage = async (language: string) => {
|
||||
await setLanguage(language);
|
||||
// Force the component to re-render to apply the new language
|
||||
addons.getChannel().emit(FORCE_RE_RENDER);
|
||||
};
|
||||
changeLanguage(language);
|
||||
}, [language]);
|
||||
|
||||
return null;
|
||||
};
|
||||
|
||||
export const withLanguageProvider: Decorator = (Story, context) => {
|
||||
return (
|
||||
<>
|
||||
<LanguageSwitcher language={context.globals.language} />
|
||||
<Story />
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
const withTooltipProvider: Decorator = (Story) => {
|
||||
return (
|
||||
<TooltipProvider>
|
||||
<Story />
|
||||
</TooltipProvider>
|
||||
);
|
||||
};
|
||||
|
||||
const preview: Preview = {
|
||||
tags: ["autodocs"],
|
||||
decorators: [withThemeProvider, withLanguageProvider, withTooltipProvider],
|
||||
parameters: {
|
||||
options: {
|
||||
storySort: {
|
||||
method: "alphabetical",
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
export default preview;
|
||||
@@ -1,37 +0,0 @@
|
||||
/*
|
||||
Copyright 2025 New Vector Ltd.
|
||||
|
||||
SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Commercial
|
||||
Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
import { waitForPageReady } from "@storybook/test-runner";
|
||||
import { toMatchImageSnapshot } from "jest-image-snapshot";
|
||||
|
||||
const customSnapshotsDir = `${process.cwd()}/playwright/shared-component-snapshots/`;
|
||||
const customReceivedDir = `${process.cwd()}/playwright/shared-component-received/`;
|
||||
|
||||
/**
|
||||
* @type {import('@storybook/test-runner').TestRunnerConfig}
|
||||
*/
|
||||
const config = {
|
||||
setup(page) {
|
||||
expect.extend({ toMatchImageSnapshot });
|
||||
},
|
||||
async postVisit(page, context) {
|
||||
await waitForPageReady(page);
|
||||
|
||||
// If you want to take screenshot of multiple browsers, use
|
||||
// page.context().browser().browserType().name() to get the browser name to prefix the file name
|
||||
const image = await page.screenshot();
|
||||
expect(image).toMatchImageSnapshot({
|
||||
customSnapshotsDir,
|
||||
customSnapshotIdentifier: `${context.id}-${process.platform}`,
|
||||
storeReceivedOnFailure: true,
|
||||
customReceivedDir,
|
||||
customDiffDir: customReceivedDir,
|
||||
});
|
||||
},
|
||||
};
|
||||
|
||||
export default config;
|
||||
@@ -1,82 +1,3 @@
|
||||
module.exports = {
|
||||
extends: ["stylelint-config-standard"],
|
||||
customSyntax: "postcss-scss",
|
||||
plugins: ["stylelint-scss", "stylelint-value-no-unknown-custom-properties"],
|
||||
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,
|
||||
"shorthand-property-no-redundant-values": null,
|
||||
"property-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,
|
||||
"declaration-property-value-no-unknown": null,
|
||||
"declaration-property-value-keyword-no-deprecated": null,
|
||||
"csstools/value-no-unknown-custom-properties": [
|
||||
true,
|
||||
{
|
||||
importFrom: [
|
||||
{ from: "res/css/_common.pcss", type: "css" },
|
||||
{ from: "res/themes/light/css/_light.pcss", type: "css" },
|
||||
// Right now our styles share vars all over the place, this is not ideal but acceptable for now
|
||||
{ from: "res/css/views/rooms/_EventTile.pcss", type: "css" },
|
||||
{ from: "res/css/views/rooms/_IRCLayout.pcss", type: "css" },
|
||||
{ from: "res/css/views/rooms/_EventBubbleTile.pcss", type: "css" },
|
||||
{ from: "res/css/views/rooms/_ReadReceiptGroup.pcss", type: "css" },
|
||||
{ from: "res/css/views/rooms/_EditMessageComposer.pcss", type: "css" },
|
||||
{ from: "res/css/views/right_panel/_BaseCard.pcss", type: "css" },
|
||||
{ from: "res/css/views/messages/_MessageTimestamp.pcss", type: "css" },
|
||||
{ from: "res/css/views/messages/_EventTileBubble.pcss", type: "css" },
|
||||
{ from: "res/css/views/messages/_MessageActionBar.pcss", type: "css" },
|
||||
{ from: "res/css/views/voip/LegacyCallView/_LegacyCallViewButtons.pcss", type: "css" },
|
||||
{ from: "res/css/views/elements/_ToggleSwitch.pcss", type: "css" },
|
||||
{ from: "res/css/views/settings/tabs/_SettingsTab.pcss", type: "css" },
|
||||
{ from: "res/css/structures/_RoomView.pcss", type: "css" },
|
||||
// Compound vars
|
||||
"node_modules/@vector-im/compound-design-tokens/assets/web/css/cpd-common-base.css",
|
||||
"node_modules/@vector-im/compound-design-tokens/assets/web/css/cpd-common-semantic.css",
|
||||
"node_modules/@vector-im/compound-design-tokens/assets/web/css/cpd-theme-light-base-mq.css",
|
||||
"node_modules/@vector-im/compound-design-tokens/assets/web/css/cpd-theme-light-semantic-mq.css",
|
||||
],
|
||||
},
|
||||
],
|
||||
"property-no-deprecated": [
|
||||
true,
|
||||
{
|
||||
ignoreProperties: ["-webkit-box-orient", "word-wrap"],
|
||||
},
|
||||
],
|
||||
"nesting-selector-no-missing-scoping-root": null,
|
||||
"no-invalid-position-declaration": null,
|
||||
},
|
||||
...require("matrix-react-sdk/.stylelintrc.js"),
|
||||
};
|
||||
|
||||
@@ -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
|
||||
|
||||
8850
CHANGELOG.md
8850
CHANGELOG.md
File diff suppressed because it is too large
Load Diff
221
CONTRIBUTING.md
221
CONTRIBUTING.md
@@ -1,8 +1,16 @@
|
||||
# Contributing code to Element Web
|
||||
Contributing code to Element Web
|
||||
================================
|
||||
|
||||
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.
|
||||
Everyone is welcome to contribute code to Element Web, provided that they are
|
||||
willing to license their contributions under the same license as the project
|
||||
itself. We follow a simple 'inbound=outbound' model for contributions: the act
|
||||
of submitting an 'inbound' contribution means that the contributor agrees to
|
||||
license the code under the same terms as the project's overall 'outbound'
|
||||
license - in this case, Apache Software License v2 (see
|
||||
[LICENSE](LICENSE)).
|
||||
|
||||
## How to contribute
|
||||
How to contribute
|
||||
-----------------
|
||||
|
||||
The preferred and easiest way to contribute changes to the project is to fork
|
||||
it on github, and then create a pull request to ask us to pull your changes
|
||||
@@ -11,48 +19,39 @@ into our repo (https://help.github.com/articles/using-pull-requests/)
|
||||
We use GitHub's pull request workflow to review the contribution, and either
|
||||
ask you to make any refinements needed or merge it and make them ourselves.
|
||||
|
||||
Your PR should have a title that describes what change is being made. This
|
||||
is used for the text in the Changelog entry by default (see below), so a good
|
||||
title will tell a user succinctly what change is being made. "Fix bug where
|
||||
cows had five legs" and, "Add support for miniature horses" are examples of good
|
||||
titles. Don't include an issue number here: that belongs in the description.
|
||||
Definitely don't use the GitHub default of "Update file.ts".
|
||||
Things that should go into your PR description:
|
||||
* A changelog entry in the `Notes` section (see below)
|
||||
* 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.
|
||||
|
||||
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.
|
||||
|
||||
### Changelogs
|
||||
|
||||
There's no need to manually add Changelog entries: we use information in the
|
||||
pull request to populate the information that goes into the changelogs our
|
||||
users see, both for Element Web itself and other projects on which it is based.
|
||||
This is picked up from both labels on the pull request and the `Notes:`
|
||||
annotation in the description. By default, the PR title will be used for the
|
||||
changelog entry, but you can specify more options, as follows.
|
||||
We rely on information in pull request to populate the information that goes into
|
||||
the changelogs our users see, both for Element Web itself and other projects on
|
||||
which it is based. This is picked up from both labels on the pull request and
|
||||
the `Notes:` annotation in the description. By default, the PR title will be
|
||||
used for the changelog entry, but you can specify more options, as follows.
|
||||
|
||||
To add a longer, more detailed description of the change for the changelog:
|
||||
|
||||
_Fix llama herding bug_
|
||||
|
||||
*Fix llama herding bug*
|
||||
|
||||
```
|
||||
Notes: Fix a bug (https://github.com/matrix-org/notaproject/issues/123) where the 'Herd' button would not herd more than 8 Llamas if the moon was in the waxing gibbous phase
|
||||
@@ -61,8 +60,7 @@ Notes: Fix a bug (https://github.com/matrix-org/notaproject/issues/123) where th
|
||||
For some PRs, it's not useful to have an entry in the user-facing changelog (this is
|
||||
the default for PRs labelled with `T-Task`):
|
||||
|
||||
_Remove outdated comment from `Ungulates.ts`_
|
||||
|
||||
*Remove outdated comment from `Ungulates.ts`*
|
||||
```
|
||||
Notes: none
|
||||
```
|
||||
@@ -70,17 +68,16 @@ 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_
|
||||
|
||||
*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
|
||||
* matrix-react-sdk
|
||||
* 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
|
||||
@@ -88,18 +85,17 @@ to specify in the notes that it's a breaking change - this will be added
|
||||
automatically based on the label - but remember to tell the developer how to
|
||||
migrate:
|
||||
|
||||
_Remove legacy class_
|
||||
*Remove legacy class*
|
||||
|
||||
```
|
||||
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.
|
||||
@@ -108,16 +104,18 @@ We use continuous integration, and all pull requests get automatically tested:
|
||||
if your change breaks the build, then the PR will show that there are failed
|
||||
checks, so please check back after a few minutes.
|
||||
|
||||
## Tests
|
||||
|
||||
Tests
|
||||
-----
|
||||
Your PR should include tests.
|
||||
|
||||
For new user facing features in `matrix-js-sdk` or `element-web`, you must include:
|
||||
For new user facing features in `matrix-js-sdk`, `matrix-react-sdk` or `element-web`, you
|
||||
must include:
|
||||
|
||||
1. Comprehensive unit tests written in Jest. These are located in `/test`.
|
||||
2. "happy path" end-to-end tests.
|
||||
These are located in `/playwright/e2e`, and are run using `element-web`.
|
||||
Ideally, you would also include tests for edge and error cases.
|
||||
These are located in `/cypress/e2e` in `matrix-react-sdk`, and
|
||||
are run using `element-web`. Ideally, you would also include tests for edge
|
||||
and error cases.
|
||||
|
||||
Unit tests are expected even when the feature is in labs. It's good practice
|
||||
to write tests alongside the code as it ensures the code is testable from
|
||||
@@ -131,7 +129,8 @@ end-to-end test; which is best depends on what sort of test most concisely
|
||||
exercises the area.
|
||||
|
||||
Changes to must be accompanied by unit tests written in Jest.
|
||||
These are located in `/spec/` in `matrix-js-sdk` or `/test/` in `element-web`.
|
||||
These are located in `/spec/` in `matrix-js-sdk` or `/test/` in `element-web`
|
||||
and `matrix-react-sdk`.
|
||||
|
||||
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
|
||||
@@ -140,7 +139,6 @@ why it's not possible in your PR.
|
||||
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
|
||||
an istanbul magic comment as [documented here][1]. See example:
|
||||
|
||||
```javascript
|
||||
/* istanbul ignore if */
|
||||
if (process.env.NODE_ENV !== "test") {
|
||||
@@ -162,8 +160,8 @@ tests later will become progressively more difficult.
|
||||
If you're not sure how to approach writing tests for your change, ask for help
|
||||
in [#element-dev](https://matrix.to/#/#element-dev:matrix.org).
|
||||
|
||||
## Code style
|
||||
|
||||
Code style
|
||||
----------
|
||||
Element Web aims to target TypeScript/ES6. All new files should be written in
|
||||
TypeScript and existing files should use ES6 principles where possible.
|
||||
|
||||
@@ -176,11 +174,11 @@ The remaining code style is documented in [code_style.md](./code_style.md).
|
||||
Contributors are encouraged to it and follow the principles set out there.
|
||||
|
||||
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
|
||||
and ***never*** mix cosmetic and functional changes in the same commit, as it
|
||||
makes it horribly hard to review otherwise.
|
||||
|
||||
## Attribution
|
||||
|
||||
Attribution
|
||||
-----------
|
||||
Everyone who contributes anything to Matrix is welcome to be listed in the
|
||||
AUTHORS.rst file for the project in question. Please feel free to include a
|
||||
change to AUTHORS.rst in your pull request to list yourself and a short
|
||||
@@ -189,16 +187,91 @@ 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 :)
|
||||
|
||||
# Review expectations
|
||||
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/Documentation/SubmittingPatches), 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:
|
||||
|
||||
See https://github.com/element-hq/element-meta/wiki/Review-process
|
||||
```
|
||||
Developer Certificate of Origin
|
||||
Version 1.1
|
||||
|
||||
# Merge Strategy
|
||||
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
|
||||
```
|
||||
|
||||
Review expectations
|
||||
===================
|
||||
|
||||
See https://github.com/vector-im/element-meta/wiki/Review-process
|
||||
|
||||
|
||||
Merge Strategy
|
||||
==============
|
||||
|
||||
The preferred method for merging pull requests is squash merging to keep the
|
||||
commit history trim, but it is up to the discretion of the team member merging
|
||||
the change. We do not support rebase merges due to `allchange` being unable to
|
||||
handle them. When merging make sure to leave the default commit title, or
|
||||
handle them. When merging make sure to leave the default commit title, or
|
||||
at least leave the PR number at the end in brackets like by default.
|
||||
When stacking pull requests, you may wish to do the following:
|
||||
|
||||
@@ -206,11 +279,5 @@ When stacking pull requests, you may wish to do the following:
|
||||
2. Branch from your base branch (branch1) to your work branch (branch2), push commits and open a pull request configuring the base to be branch1, saying in the description that it is based on your other PR.
|
||||
3. Merge the first PR using a merge commit otherwise your stacked PR will need a rebase. Github will automatically adjust the base branch of your other PR to be develop.
|
||||
|
||||
|
||||
[1]: https://github.com/gotwarlost/istanbul/blob/master/ignoring-code-for-coverage.md
|
||||
|
||||
# Decoding Stack Traces
|
||||
|
||||
Element Web has crashed and given you an obfuscated stack trace? Don't panic:
|
||||
use the [Decoder Ring](https://app.element.io/decoder-ring/) (or /decoder-ring/
|
||||
on any Element Web deploy). It is somewhat of a manual process, but it should
|
||||
tell you what lines the stack trace corresponds to from the source maps.
|
||||
|
||||
42
Dockerfile
42
Dockerfile
@@ -1,46 +1,34 @@
|
||||
# syntax=docker.io/docker/dockerfile:1.17-labs@sha256:9187104f31e3a002a8a6a3209ea1f937fb7486c093cbbde1e14b0fa0d7e4f1b5
|
||||
|
||||
# Builder
|
||||
FROM --platform=$BUILDPLATFORM node:22-bullseye@sha256:9e34ba52e1f3c31ed9bd4d0bcf784f5909db17cda61c220e29c8d7a8ebfb402e AS builder
|
||||
FROM node:14-buster as builder
|
||||
|
||||
# Support custom branch of the js-sdk. This also helps us build images of element-web develop.
|
||||
# Support custom branches of the react-sdk and js-sdk. This also helps us build
|
||||
# images of element-web develop.
|
||||
ARG USE_CUSTOM_SDKS=false
|
||||
ARG REACT_SDK_REPO="https://github.com/matrix-org/matrix-react-sdk.git"
|
||||
ARG REACT_SDK_BRANCH="master"
|
||||
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 --exclude=docker . /src
|
||||
RUN /src/scripts/docker-link-repos.sh
|
||||
RUN yarn --network-timeout=200000 install
|
||||
RUN /src/scripts/docker-package.sh
|
||||
COPY . /src
|
||||
RUN dos2unix /src/scripts/docker-link-repos.sh && bash /src/scripts/docker-link-repos.sh
|
||||
RUN yarn --network-timeout=100000 install
|
||||
|
||||
RUN dos2unix /src/scripts/docker-package.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 nginxinc/nginx-unprivileged:alpine-slim@sha256:ea6c4b8b568824ea94cd1fabd47e1c4e7c0c04744f344a3793f7e9c8ac3a3636
|
||||
|
||||
# Need root user to install packages & manipulate the usr directory
|
||||
USER root
|
||||
|
||||
# Install jq and moreutils for sponge, both used by our entrypoints
|
||||
RUN apk add jq moreutils
|
||||
FROM nginx:alpine
|
||||
|
||||
COPY --from=builder /src/webapp /app
|
||||
|
||||
# Override default nginx config. Templates in `/etc/nginx/templates` are passed
|
||||
# through `envsubst` by the nginx docker image entry point.
|
||||
COPY /docker/nginx-templates/* /etc/nginx/templates/
|
||||
COPY /docker/docker-entrypoint.d/* /docker-entrypoint.d/
|
||||
# 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
|
||||
|
||||
# Run as nginx user by default
|
||||
USER nginx
|
||||
|
||||
# HTTP listen port
|
||||
ENV ELEMENT_WEB_PORT=80
|
||||
|
||||
HEALTHCHECK --start-period=5s CMD wget -q --spider http://localhost:$ELEMENT_WEB_PORT/config.json
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
@@ -175,45 +175,3 @@
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
|
||||
|
||||
Note:
|
||||
|
||||
This project was originally contributed to the community under the MIT license and with the following notice:
|
||||
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2013 ESTOS GmbH
|
||||
Copyright (c) 2013 BlueJimp SARL
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
661
LICENSE-AGPL-3.0
661
LICENSE-AGPL-3.0
@@ -1,661 +0,0 @@
|
||||
GNU AFFERO GENERAL PUBLIC LICENSE
|
||||
Version 3, 19 November 2007
|
||||
|
||||
Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The GNU Affero General Public License is a free, copyleft license for
|
||||
software and other kinds of works, specifically designed to ensure
|
||||
cooperation with the community in the case of network server software.
|
||||
|
||||
The licenses for most software and other practical works are designed
|
||||
to take away your freedom to share and change the works. By contrast,
|
||||
our General Public Licenses are intended to guarantee your freedom to
|
||||
share and change all versions of a program--to make sure it remains free
|
||||
software for all its users.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
them if you wish), that you receive source code or can get it if you
|
||||
want it, that you can change the software or use pieces of it in new
|
||||
free programs, and that you know you can do these things.
|
||||
|
||||
Developers that use our General Public Licenses protect your rights
|
||||
with two steps: (1) assert copyright on the software, and (2) offer
|
||||
you this License which gives you legal permission to copy, distribute
|
||||
and/or modify the software.
|
||||
|
||||
A secondary benefit of defending all users' freedom is that
|
||||
improvements made in alternate versions of the program, if they
|
||||
receive widespread use, become available for other developers to
|
||||
incorporate. Many developers of free software are heartened and
|
||||
encouraged by the resulting cooperation. However, in the case of
|
||||
software used on network servers, this result may fail to come about.
|
||||
The GNU General Public License permits making a modified version and
|
||||
letting the public access it on a server without ever releasing its
|
||||
source code to the public.
|
||||
|
||||
The GNU Affero General Public License is designed specifically to
|
||||
ensure that, in such cases, the modified source code becomes available
|
||||
to the community. It requires the operator of a network server to
|
||||
provide the source code of the modified version running there to the
|
||||
users of that server. Therefore, public use of a modified version, on
|
||||
a publicly accessible server, gives the public access to the source
|
||||
code of the modified version.
|
||||
|
||||
An older license, called the Affero General Public License and
|
||||
published by Affero, was designed to accomplish similar goals. This is
|
||||
a different license, not a version of the Affero GPL, but Affero has
|
||||
released a new version of the Affero GPL which permits relicensing under
|
||||
this license.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
TERMS AND CONDITIONS
|
||||
|
||||
0. Definitions.
|
||||
|
||||
"This License" refers to version 3 of the GNU Affero General Public License.
|
||||
|
||||
"Copyright" also means copyright-like laws that apply to other kinds of
|
||||
works, such as semiconductor masks.
|
||||
|
||||
"The Program" refers to any copyrightable work licensed under this
|
||||
License. Each licensee is addressed as "you". "Licensees" and
|
||||
"recipients" may be individuals or organizations.
|
||||
|
||||
To "modify" a work means to copy from or adapt all or part of the work
|
||||
in a fashion requiring copyright permission, other than the making of an
|
||||
exact copy. The resulting work is called a "modified version" of the
|
||||
earlier work or a work "based on" the earlier work.
|
||||
|
||||
A "covered work" means either the unmodified Program or a work based
|
||||
on the Program.
|
||||
|
||||
To "propagate" a work means to do anything with it that, without
|
||||
permission, would make you directly or secondarily liable for
|
||||
infringement under applicable copyright law, except executing it on a
|
||||
computer or modifying a private copy. Propagation includes copying,
|
||||
distribution (with or without modification), making available to the
|
||||
public, and in some countries other activities as well.
|
||||
|
||||
To "convey" a work means any kind of propagation that enables other
|
||||
parties to make or receive copies. Mere interaction with a user through
|
||||
a computer network, with no transfer of a copy, is not conveying.
|
||||
|
||||
An interactive user interface displays "Appropriate Legal Notices"
|
||||
to the extent that it includes a convenient and prominently visible
|
||||
feature that (1) displays an appropriate copyright notice, and (2)
|
||||
tells the user that there is no warranty for the work (except to the
|
||||
extent that warranties are provided), that licensees may convey the
|
||||
work under this License, and how to view a copy of this License. If
|
||||
the interface presents a list of user commands or options, such as a
|
||||
menu, a prominent item in the list meets this criterion.
|
||||
|
||||
1. Source Code.
|
||||
|
||||
The "source code" for a work means the preferred form of the work
|
||||
for making modifications to it. "Object code" means any non-source
|
||||
form of a work.
|
||||
|
||||
A "Standard Interface" means an interface that either is an official
|
||||
standard defined by a recognized standards body, or, in the case of
|
||||
interfaces specified for a particular programming language, one that
|
||||
is widely used among developers working in that language.
|
||||
|
||||
The "System Libraries" of an executable work include anything, other
|
||||
than the work as a whole, that (a) is included in the normal form of
|
||||
packaging a Major Component, but which is not part of that Major
|
||||
Component, and (b) serves only to enable use of the work with that
|
||||
Major Component, or to implement a Standard Interface for which an
|
||||
implementation is available to the public in source code form. A
|
||||
"Major Component", in this context, means a major essential component
|
||||
(kernel, window system, and so on) of the specific operating system
|
||||
(if any) on which the executable work runs, or a compiler used to
|
||||
produce the work, or an object code interpreter used to run it.
|
||||
|
||||
The "Corresponding Source" for a work in object code form means all
|
||||
the source code needed to generate, install, and (for an executable
|
||||
work) run the object code and to modify the work, including scripts to
|
||||
control those activities. However, it does not include the work's
|
||||
System Libraries, or general-purpose tools or generally available free
|
||||
programs which are used unmodified in performing those activities but
|
||||
which are not part of the work. For example, Corresponding Source
|
||||
includes interface definition files associated with source files for
|
||||
the work, and the source code for shared libraries and dynamically
|
||||
linked subprograms that the work is specifically designed to require,
|
||||
such as by intimate data communication or control flow between those
|
||||
subprograms and other parts of the work.
|
||||
|
||||
The Corresponding Source need not include anything that users
|
||||
can regenerate automatically from other parts of the Corresponding
|
||||
Source.
|
||||
|
||||
The Corresponding Source for a work in source code form is that
|
||||
same work.
|
||||
|
||||
2. Basic Permissions.
|
||||
|
||||
All rights granted under this License are granted for the term of
|
||||
copyright on the Program, and are irrevocable provided the stated
|
||||
conditions are met. This License explicitly affirms your unlimited
|
||||
permission to run the unmodified Program. The output from running a
|
||||
covered work is covered by this License only if the output, given its
|
||||
content, constitutes a covered work. This License acknowledges your
|
||||
rights of fair use or other equivalent, as provided by copyright law.
|
||||
|
||||
You may make, run and propagate covered works that you do not
|
||||
convey, without conditions so long as your license otherwise remains
|
||||
in force. You may convey covered works to others for the sole purpose
|
||||
of having them make modifications exclusively for you, or provide you
|
||||
with facilities for running those works, provided that you comply with
|
||||
the terms of this License in conveying all material for which you do
|
||||
not control copyright. Those thus making or running the covered works
|
||||
for you must do so exclusively on your behalf, under your direction
|
||||
and control, on terms that prohibit them from making any copies of
|
||||
your copyrighted material outside their relationship with you.
|
||||
|
||||
Conveying under any other circumstances is permitted solely under
|
||||
the conditions stated below. Sublicensing is not allowed; section 10
|
||||
makes it unnecessary.
|
||||
|
||||
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
|
||||
|
||||
No covered work shall be deemed part of an effective technological
|
||||
measure under any applicable law fulfilling obligations under article
|
||||
11 of the WIPO copyright treaty adopted on 20 December 1996, or
|
||||
similar laws prohibiting or restricting circumvention of such
|
||||
measures.
|
||||
|
||||
When you convey a covered work, you waive any legal power to forbid
|
||||
circumvention of technological measures to the extent such circumvention
|
||||
is effected by exercising rights under this License with respect to
|
||||
the covered work, and you disclaim any intention to limit operation or
|
||||
modification of the work as a means of enforcing, against the work's
|
||||
users, your or third parties' legal rights to forbid circumvention of
|
||||
technological measures.
|
||||
|
||||
4. Conveying Verbatim Copies.
|
||||
|
||||
You may convey verbatim copies of the Program's source code as you
|
||||
receive it, in any medium, provided that you conspicuously and
|
||||
appropriately publish on each copy an appropriate copyright notice;
|
||||
keep intact all notices stating that this License and any
|
||||
non-permissive terms added in accord with section 7 apply to the code;
|
||||
keep intact all notices of the absence of any warranty; and give all
|
||||
recipients a copy of this License along with the Program.
|
||||
|
||||
You may charge any price or no price for each copy that you convey,
|
||||
and you may offer support or warranty protection for a fee.
|
||||
|
||||
5. Conveying Modified Source Versions.
|
||||
|
||||
You may convey a work based on the Program, or the modifications to
|
||||
produce it from the Program, in the form of source code under the
|
||||
terms of section 4, provided that you also meet all of these conditions:
|
||||
|
||||
a) The work must carry prominent notices stating that you modified
|
||||
it, and giving a relevant date.
|
||||
|
||||
b) The work must carry prominent notices stating that it is
|
||||
released under this License and any conditions added under section
|
||||
7. This requirement modifies the requirement in section 4 to
|
||||
"keep intact all notices".
|
||||
|
||||
c) You must license the entire work, as a whole, under this
|
||||
License to anyone who comes into possession of a copy. This
|
||||
License will therefore apply, along with any applicable section 7
|
||||
additional terms, to the whole of the work, and all its parts,
|
||||
regardless of how they are packaged. This License gives no
|
||||
permission to license the work in any other way, but it does not
|
||||
invalidate such permission if you have separately received it.
|
||||
|
||||
d) If the work has interactive user interfaces, each must display
|
||||
Appropriate Legal Notices; however, if the Program has interactive
|
||||
interfaces that do not display Appropriate Legal Notices, your
|
||||
work need not make them do so.
|
||||
|
||||
A compilation of a covered work with other separate and independent
|
||||
works, which are not by their nature extensions of the covered work,
|
||||
and which are not combined with it such as to form a larger program,
|
||||
in or on a volume of a storage or distribution medium, is called an
|
||||
"aggregate" if the compilation and its resulting copyright are not
|
||||
used to limit the access or legal rights of the compilation's users
|
||||
beyond what the individual works permit. Inclusion of a covered work
|
||||
in an aggregate does not cause this License to apply to the other
|
||||
parts of the aggregate.
|
||||
|
||||
6. Conveying Non-Source Forms.
|
||||
|
||||
You may convey a covered work in object code form under the terms
|
||||
of sections 4 and 5, provided that you also convey the
|
||||
machine-readable Corresponding Source under the terms of this License,
|
||||
in one of these ways:
|
||||
|
||||
a) Convey the object code in, or embodied in, a physical product
|
||||
(including a physical distribution medium), accompanied by the
|
||||
Corresponding Source fixed on a durable physical medium
|
||||
customarily used for software interchange.
|
||||
|
||||
b) Convey the object code in, or embodied in, a physical product
|
||||
(including a physical distribution medium), accompanied by a
|
||||
written offer, valid for at least three years and valid for as
|
||||
long as you offer spare parts or customer support for that product
|
||||
model, to give anyone who possesses the object code either (1) a
|
||||
copy of the Corresponding Source for all the software in the
|
||||
product that is covered by this License, on a durable physical
|
||||
medium customarily used for software interchange, for a price no
|
||||
more than your reasonable cost of physically performing this
|
||||
conveying of source, or (2) access to copy the
|
||||
Corresponding Source from a network server at no charge.
|
||||
|
||||
c) Convey individual copies of the object code with a copy of the
|
||||
written offer to provide the Corresponding Source. This
|
||||
alternative is allowed only occasionally and noncommercially, and
|
||||
only if you received the object code with such an offer, in accord
|
||||
with subsection 6b.
|
||||
|
||||
d) Convey the object code by offering access from a designated
|
||||
place (gratis or for a charge), and offer equivalent access to the
|
||||
Corresponding Source in the same way through the same place at no
|
||||
further charge. You need not require recipients to copy the
|
||||
Corresponding Source along with the object code. If the place to
|
||||
copy the object code is a network server, the Corresponding Source
|
||||
may be on a different server (operated by you or a third party)
|
||||
that supports equivalent copying facilities, provided you maintain
|
||||
clear directions next to the object code saying where to find the
|
||||
Corresponding Source. Regardless of what server hosts the
|
||||
Corresponding Source, you remain obligated to ensure that it is
|
||||
available for as long as needed to satisfy these requirements.
|
||||
|
||||
e) Convey the object code using peer-to-peer transmission, provided
|
||||
you inform other peers where the object code and Corresponding
|
||||
Source of the work are being offered to the general public at no
|
||||
charge under subsection 6d.
|
||||
|
||||
A separable portion of the object code, whose source code is excluded
|
||||
from the Corresponding Source as a System Library, need not be
|
||||
included in conveying the object code work.
|
||||
|
||||
A "User Product" is either (1) a "consumer product", which means any
|
||||
tangible personal property which is normally used for personal, family,
|
||||
or household purposes, or (2) anything designed or sold for incorporation
|
||||
into a dwelling. In determining whether a product is a consumer product,
|
||||
doubtful cases shall be resolved in favor of coverage. For a particular
|
||||
product received by a particular user, "normally used" refers to a
|
||||
typical or common use of that class of product, regardless of the status
|
||||
of the particular user or of the way in which the particular user
|
||||
actually uses, or expects or is expected to use, the product. A product
|
||||
is a consumer product regardless of whether the product has substantial
|
||||
commercial, industrial or non-consumer uses, unless such uses represent
|
||||
the only significant mode of use of the product.
|
||||
|
||||
"Installation Information" for a User Product means any methods,
|
||||
procedures, authorization keys, or other information required to install
|
||||
and execute modified versions of a covered work in that User Product from
|
||||
a modified version of its Corresponding Source. The information must
|
||||
suffice to ensure that the continued functioning of the modified object
|
||||
code is in no case prevented or interfered with solely because
|
||||
modification has been made.
|
||||
|
||||
If you convey an object code work under this section in, or with, or
|
||||
specifically for use in, a User Product, and the conveying occurs as
|
||||
part of a transaction in which the right of possession and use of the
|
||||
User Product is transferred to the recipient in perpetuity or for a
|
||||
fixed term (regardless of how the transaction is characterized), the
|
||||
Corresponding Source conveyed under this section must be accompanied
|
||||
by the Installation Information. But this requirement does not apply
|
||||
if neither you nor any third party retains the ability to install
|
||||
modified object code on the User Product (for example, the work has
|
||||
been installed in ROM).
|
||||
|
||||
The requirement to provide Installation Information does not include a
|
||||
requirement to continue to provide support service, warranty, or updates
|
||||
for a work that has been modified or installed by the recipient, or for
|
||||
the User Product in which it has been modified or installed. Access to a
|
||||
network may be denied when the modification itself materially and
|
||||
adversely affects the operation of the network or violates the rules and
|
||||
protocols for communication across the network.
|
||||
|
||||
Corresponding Source conveyed, and Installation Information provided,
|
||||
in accord with this section must be in a format that is publicly
|
||||
documented (and with an implementation available to the public in
|
||||
source code form), and must require no special password or key for
|
||||
unpacking, reading or copying.
|
||||
|
||||
7. Additional Terms.
|
||||
|
||||
"Additional permissions" are terms that supplement the terms of this
|
||||
License by making exceptions from one or more of its conditions.
|
||||
Additional permissions that are applicable to the entire Program shall
|
||||
be treated as though they were included in this License, to the extent
|
||||
that they are valid under applicable law. If additional permissions
|
||||
apply only to part of the Program, that part may be used separately
|
||||
under those permissions, but the entire Program remains governed by
|
||||
this License without regard to the additional permissions.
|
||||
|
||||
When you convey a copy of a covered work, you may at your option
|
||||
remove any additional permissions from that copy, or from any part of
|
||||
it. (Additional permissions may be written to require their own
|
||||
removal in certain cases when you modify the work.) You may place
|
||||
additional permissions on material, added by you to a covered work,
|
||||
for which you have or can give appropriate copyright permission.
|
||||
|
||||
Notwithstanding any other provision of this License, for material you
|
||||
add to a covered work, you may (if authorized by the copyright holders of
|
||||
that material) supplement the terms of this License with terms:
|
||||
|
||||
a) Disclaiming warranty or limiting liability differently from the
|
||||
terms of sections 15 and 16 of this License; or
|
||||
|
||||
b) Requiring preservation of specified reasonable legal notices or
|
||||
author attributions in that material or in the Appropriate Legal
|
||||
Notices displayed by works containing it; or
|
||||
|
||||
c) Prohibiting misrepresentation of the origin of that material, or
|
||||
requiring that modified versions of such material be marked in
|
||||
reasonable ways as different from the original version; or
|
||||
|
||||
d) Limiting the use for publicity purposes of names of licensors or
|
||||
authors of the material; or
|
||||
|
||||
e) Declining to grant rights under trademark law for use of some
|
||||
trade names, trademarks, or service marks; or
|
||||
|
||||
f) Requiring indemnification of licensors and authors of that
|
||||
material by anyone who conveys the material (or modified versions of
|
||||
it) with contractual assumptions of liability to the recipient, for
|
||||
any liability that these contractual assumptions directly impose on
|
||||
those licensors and authors.
|
||||
|
||||
All other non-permissive additional terms are considered "further
|
||||
restrictions" within the meaning of section 10. If the Program as you
|
||||
received it, or any part of it, contains a notice stating that it is
|
||||
governed by this License along with a term that is a further
|
||||
restriction, you may remove that term. If a license document contains
|
||||
a further restriction but permits relicensing or conveying under this
|
||||
License, you may add to a covered work material governed by the terms
|
||||
of that license document, provided that the further restriction does
|
||||
not survive such relicensing or conveying.
|
||||
|
||||
If you add terms to a covered work in accord with this section, you
|
||||
must place, in the relevant source files, a statement of the
|
||||
additional terms that apply to those files, or a notice indicating
|
||||
where to find the applicable terms.
|
||||
|
||||
Additional terms, permissive or non-permissive, may be stated in the
|
||||
form of a separately written license, or stated as exceptions;
|
||||
the above requirements apply either way.
|
||||
|
||||
8. Termination.
|
||||
|
||||
You may not propagate or modify a covered work except as expressly
|
||||
provided under this License. Any attempt otherwise to propagate or
|
||||
modify it is void, and will automatically terminate your rights under
|
||||
this License (including any patent licenses granted under the third
|
||||
paragraph of section 11).
|
||||
|
||||
However, if you cease all violation of this License, then your
|
||||
license from a particular copyright holder is reinstated (a)
|
||||
provisionally, unless and until the copyright holder explicitly and
|
||||
finally terminates your license, and (b) permanently, if the copyright
|
||||
holder fails to notify you of the violation by some reasonable means
|
||||
prior to 60 days after the cessation.
|
||||
|
||||
Moreover, your license from a particular copyright holder is
|
||||
reinstated permanently if the copyright holder notifies you of the
|
||||
violation by some reasonable means, this is the first time you have
|
||||
received notice of violation of this License (for any work) from that
|
||||
copyright holder, and you cure the violation prior to 30 days after
|
||||
your receipt of the notice.
|
||||
|
||||
Termination of your rights under this section does not terminate the
|
||||
licenses of parties who have received copies or rights from you under
|
||||
this License. If your rights have been terminated and not permanently
|
||||
reinstated, you do not qualify to receive new licenses for the same
|
||||
material under section 10.
|
||||
|
||||
9. Acceptance Not Required for Having Copies.
|
||||
|
||||
You are not required to accept this License in order to receive or
|
||||
run a copy of the Program. Ancillary propagation of a covered work
|
||||
occurring solely as a consequence of using peer-to-peer transmission
|
||||
to receive a copy likewise does not require acceptance. However,
|
||||
nothing other than this License grants you permission to propagate or
|
||||
modify any covered work. These actions infringe copyright if you do
|
||||
not accept this License. Therefore, by modifying or propagating a
|
||||
covered work, you indicate your acceptance of this License to do so.
|
||||
|
||||
10. Automatic Licensing of Downstream Recipients.
|
||||
|
||||
Each time you convey a covered work, the recipient automatically
|
||||
receives a license from the original licensors, to run, modify and
|
||||
propagate that work, subject to this License. You are not responsible
|
||||
for enforcing compliance by third parties with this License.
|
||||
|
||||
An "entity transaction" is a transaction transferring control of an
|
||||
organization, or substantially all assets of one, or subdividing an
|
||||
organization, or merging organizations. If propagation of a covered
|
||||
work results from an entity transaction, each party to that
|
||||
transaction who receives a copy of the work also receives whatever
|
||||
licenses to the work the party's predecessor in interest had or could
|
||||
give under the previous paragraph, plus a right to possession of the
|
||||
Corresponding Source of the work from the predecessor in interest, if
|
||||
the predecessor has it or can get it with reasonable efforts.
|
||||
|
||||
You may not impose any further restrictions on the exercise of the
|
||||
rights granted or affirmed under this License. For example, you may
|
||||
not impose a license fee, royalty, or other charge for exercise of
|
||||
rights granted under this License, and you may not initiate litigation
|
||||
(including a cross-claim or counterclaim in a lawsuit) alleging that
|
||||
any patent claim is infringed by making, using, selling, offering for
|
||||
sale, or importing the Program or any portion of it.
|
||||
|
||||
11. Patents.
|
||||
|
||||
A "contributor" is a copyright holder who authorizes use under this
|
||||
License of the Program or a work on which the Program is based. The
|
||||
work thus licensed is called the contributor's "contributor version".
|
||||
|
||||
A contributor's "essential patent claims" are all patent claims
|
||||
owned or controlled by the contributor, whether already acquired or
|
||||
hereafter acquired, that would be infringed by some manner, permitted
|
||||
by this License, of making, using, or selling its contributor version,
|
||||
but do not include claims that would be infringed only as a
|
||||
consequence of further modification of the contributor version. For
|
||||
purposes of this definition, "control" includes the right to grant
|
||||
patent sublicenses in a manner consistent with the requirements of
|
||||
this License.
|
||||
|
||||
Each contributor grants you a non-exclusive, worldwide, royalty-free
|
||||
patent license under the contributor's essential patent claims, to
|
||||
make, use, sell, offer for sale, import and otherwise run, modify and
|
||||
propagate the contents of its contributor version.
|
||||
|
||||
In the following three paragraphs, a "patent license" is any express
|
||||
agreement or commitment, however denominated, not to enforce a patent
|
||||
(such as an express permission to practice a patent or covenant not to
|
||||
sue for patent infringement). To "grant" such a patent license to a
|
||||
party means to make such an agreement or commitment not to enforce a
|
||||
patent against the party.
|
||||
|
||||
If you convey a covered work, knowingly relying on a patent license,
|
||||
and the Corresponding Source of the work is not available for anyone
|
||||
to copy, free of charge and under the terms of this License, through a
|
||||
publicly available network server or other readily accessible means,
|
||||
then you must either (1) cause the Corresponding Source to be so
|
||||
available, or (2) arrange to deprive yourself of the benefit of the
|
||||
patent license for this particular work, or (3) arrange, in a manner
|
||||
consistent with the requirements of this License, to extend the patent
|
||||
license to downstream recipients. "Knowingly relying" means you have
|
||||
actual knowledge that, but for the patent license, your conveying the
|
||||
covered work in a country, or your recipient's use of the covered work
|
||||
in a country, would infringe one or more identifiable patents in that
|
||||
country that you have reason to believe are valid.
|
||||
|
||||
If, pursuant to or in connection with a single transaction or
|
||||
arrangement, you convey, or propagate by procuring conveyance of, a
|
||||
covered work, and grant a patent license to some of the parties
|
||||
receiving the covered work authorizing them to use, propagate, modify
|
||||
or convey a specific copy of the covered work, then the patent license
|
||||
you grant is automatically extended to all recipients of the covered
|
||||
work and works based on it.
|
||||
|
||||
A patent license is "discriminatory" if it does not include within
|
||||
the scope of its coverage, prohibits the exercise of, or is
|
||||
conditioned on the non-exercise of one or more of the rights that are
|
||||
specifically granted under this License. You may not convey a covered
|
||||
work if you are a party to an arrangement with a third party that is
|
||||
in the business of distributing software, under which you make payment
|
||||
to the third party based on the extent of your activity of conveying
|
||||
the work, and under which the third party grants, to any of the
|
||||
parties who would receive the covered work from you, a discriminatory
|
||||
patent license (a) in connection with copies of the covered work
|
||||
conveyed by you (or copies made from those copies), or (b) primarily
|
||||
for and in connection with specific products or compilations that
|
||||
contain the covered work, unless you entered into that arrangement,
|
||||
or that patent license was granted, prior to 28 March 2007.
|
||||
|
||||
Nothing in this License shall be construed as excluding or limiting
|
||||
any implied license or other defenses to infringement that may
|
||||
otherwise be available to you under applicable patent law.
|
||||
|
||||
12. No Surrender of Others' Freedom.
|
||||
|
||||
If conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot convey a
|
||||
covered work so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you may
|
||||
not convey it at all. For example, if you agree to terms that obligate you
|
||||
to collect a royalty for further conveying from those to whom you convey
|
||||
the Program, the only way you could satisfy both those terms and this
|
||||
License would be to refrain entirely from conveying the Program.
|
||||
|
||||
13. Remote Network Interaction; Use with the GNU General Public License.
|
||||
|
||||
Notwithstanding any other provision of this License, if you modify the
|
||||
Program, your modified version must prominently offer all users
|
||||
interacting with it remotely through a computer network (if your version
|
||||
supports such interaction) an opportunity to receive the Corresponding
|
||||
Source of your version by providing access to the Corresponding Source
|
||||
from a network server at no charge, through some standard or customary
|
||||
means of facilitating copying of software. This Corresponding Source
|
||||
shall include the Corresponding Source for any work covered by version 3
|
||||
of the GNU General Public License that is incorporated pursuant to the
|
||||
following paragraph.
|
||||
|
||||
Notwithstanding any other provision of this License, you have
|
||||
permission to link or combine any covered work with a work licensed
|
||||
under version 3 of the GNU General Public License into a single
|
||||
combined work, and to convey the resulting work. The terms of this
|
||||
License will continue to apply to the part which is the covered work,
|
||||
but the work with which it is combined will remain governed by version
|
||||
3 of the GNU General Public License.
|
||||
|
||||
14. Revised Versions of this License.
|
||||
|
||||
The Free Software Foundation may publish revised and/or new versions of
|
||||
the GNU Affero General Public License from time to time. Such new versions
|
||||
will be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the
|
||||
Program specifies that a certain numbered version of the GNU Affero General
|
||||
Public License "or any later version" applies to it, you have the
|
||||
option of following the terms and conditions either of that numbered
|
||||
version or of any later version published by the Free Software
|
||||
Foundation. If the Program does not specify a version number of the
|
||||
GNU Affero General Public License, you may choose any version ever published
|
||||
by the Free Software Foundation.
|
||||
|
||||
If the Program specifies that a proxy can decide which future
|
||||
versions of the GNU Affero General Public License can be used, that proxy's
|
||||
public statement of acceptance of a version permanently authorizes you
|
||||
to choose that version for the Program.
|
||||
|
||||
Later license versions may give you additional or different
|
||||
permissions. However, no additional obligations are imposed on any
|
||||
author or copyright holder as a result of your choosing to follow a
|
||||
later version.
|
||||
|
||||
15. Disclaimer of Warranty.
|
||||
|
||||
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
|
||||
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
|
||||
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
|
||||
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
|
||||
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
|
||||
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
|
||||
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||
|
||||
16. Limitation of Liability.
|
||||
|
||||
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
|
||||
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
|
||||
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
|
||||
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
|
||||
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
|
||||
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
|
||||
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
|
||||
SUCH DAMAGES.
|
||||
|
||||
17. Interpretation of Sections 15 and 16.
|
||||
|
||||
If the disclaimer of warranty and limitation of liability provided
|
||||
above cannot be given local legal effect according to their terms,
|
||||
reviewing courts shall apply local law that most closely approximates
|
||||
an absolute waiver of all civil liability in connection with the
|
||||
Program, unless a warranty or assumption of liability accompanies a
|
||||
copy of the Program in return for a fee.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
state the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it 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.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If your software can interact with users remotely through a computer
|
||||
network, you should also make sure that it provides a way for users to
|
||||
get its source. For example, if your program is a web application, its
|
||||
interface could display a "Source" link that leads users to an archive
|
||||
of the code. There are many ways you could offer source, and different
|
||||
solutions will be better for different programs; see section 13 for the
|
||||
specific requirements.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or school,
|
||||
if any, to sign a "copyright disclaimer" for the program, if necessary.
|
||||
For more information on this, and how to apply and follow the GNU AGPL, see
|
||||
<https://www.gnu.org/licenses/>.
|
||||
@@ -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
|
||||
674
LICENSE-GPL-3.0
674
LICENSE-GPL-3.0
@@ -1,674 +0,0 @@
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 3, 29 June 2007
|
||||
|
||||
Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The GNU General Public License is a free, copyleft license for
|
||||
software and other kinds of works.
|
||||
|
||||
The licenses for most software and other practical works are designed
|
||||
to take away your freedom to share and change the works. By contrast,
|
||||
the GNU General Public License is intended to guarantee your freedom to
|
||||
share and change all versions of a program--to make sure it remains free
|
||||
software for all its users. We, the Free Software Foundation, use the
|
||||
GNU General Public License for most of our software; it applies also to
|
||||
any other work released this way by its authors. You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
them if you wish), that you receive source code or can get it if you
|
||||
want it, that you can change the software or use pieces of it in new
|
||||
free programs, and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to prevent others from denying you
|
||||
these rights or asking you to surrender the rights. Therefore, you have
|
||||
certain responsibilities if you distribute copies of the software, or if
|
||||
you modify it: responsibilities to respect the freedom of others.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must pass on to the recipients the same
|
||||
freedoms that you received. You must make sure that they, too, receive
|
||||
or can get the source code. And you must show them these terms so they
|
||||
know their rights.
|
||||
|
||||
Developers that use the GNU GPL protect your rights with two steps:
|
||||
(1) assert copyright on the software, and (2) offer you this License
|
||||
giving you legal permission to copy, distribute and/or modify it.
|
||||
|
||||
For the developers' and authors' protection, the GPL clearly explains
|
||||
that there is no warranty for this free software. For both users' and
|
||||
authors' sake, the GPL requires that modified versions be marked as
|
||||
changed, so that their problems will not be attributed erroneously to
|
||||
authors of previous versions.
|
||||
|
||||
Some devices are designed to deny users access to install or run
|
||||
modified versions of the software inside them, although the manufacturer
|
||||
can do so. This is fundamentally incompatible with the aim of
|
||||
protecting users' freedom to change the software. The systematic
|
||||
pattern of such abuse occurs in the area of products for individuals to
|
||||
use, which is precisely where it is most unacceptable. Therefore, we
|
||||
have designed this version of the GPL to prohibit the practice for those
|
||||
products. If such problems arise substantially in other domains, we
|
||||
stand ready to extend this provision to those domains in future versions
|
||||
of the GPL, as needed to protect the freedom of users.
|
||||
|
||||
Finally, every program is threatened constantly by software patents.
|
||||
States should not allow patents to restrict development and use of
|
||||
software on general-purpose computers, but in those that do, we wish to
|
||||
avoid the special danger that patents applied to a free program could
|
||||
make it effectively proprietary. To prevent this, the GPL assures that
|
||||
patents cannot be used to render the program non-free.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
TERMS AND CONDITIONS
|
||||
|
||||
0. Definitions.
|
||||
|
||||
"This License" refers to version 3 of the GNU General Public License.
|
||||
|
||||
"Copyright" also means copyright-like laws that apply to other kinds of
|
||||
works, such as semiconductor masks.
|
||||
|
||||
"The Program" refers to any copyrightable work licensed under this
|
||||
License. Each licensee is addressed as "you". "Licensees" and
|
||||
"recipients" may be individuals or organizations.
|
||||
|
||||
To "modify" a work means to copy from or adapt all or part of the work
|
||||
in a fashion requiring copyright permission, other than the making of an
|
||||
exact copy. The resulting work is called a "modified version" of the
|
||||
earlier work or a work "based on" the earlier work.
|
||||
|
||||
A "covered work" means either the unmodified Program or a work based
|
||||
on the Program.
|
||||
|
||||
To "propagate" a work means to do anything with it that, without
|
||||
permission, would make you directly or secondarily liable for
|
||||
infringement under applicable copyright law, except executing it on a
|
||||
computer or modifying a private copy. Propagation includes copying,
|
||||
distribution (with or without modification), making available to the
|
||||
public, and in some countries other activities as well.
|
||||
|
||||
To "convey" a work means any kind of propagation that enables other
|
||||
parties to make or receive copies. Mere interaction with a user through
|
||||
a computer network, with no transfer of a copy, is not conveying.
|
||||
|
||||
An interactive user interface displays "Appropriate Legal Notices"
|
||||
to the extent that it includes a convenient and prominently visible
|
||||
feature that (1) displays an appropriate copyright notice, and (2)
|
||||
tells the user that there is no warranty for the work (except to the
|
||||
extent that warranties are provided), that licensees may convey the
|
||||
work under this License, and how to view a copy of this License. If
|
||||
the interface presents a list of user commands or options, such as a
|
||||
menu, a prominent item in the list meets this criterion.
|
||||
|
||||
1. Source Code.
|
||||
|
||||
The "source code" for a work means the preferred form of the work
|
||||
for making modifications to it. "Object code" means any non-source
|
||||
form of a work.
|
||||
|
||||
A "Standard Interface" means an interface that either is an official
|
||||
standard defined by a recognized standards body, or, in the case of
|
||||
interfaces specified for a particular programming language, one that
|
||||
is widely used among developers working in that language.
|
||||
|
||||
The "System Libraries" of an executable work include anything, other
|
||||
than the work as a whole, that (a) is included in the normal form of
|
||||
packaging a Major Component, but which is not part of that Major
|
||||
Component, and (b) serves only to enable use of the work with that
|
||||
Major Component, or to implement a Standard Interface for which an
|
||||
implementation is available to the public in source code form. A
|
||||
"Major Component", in this context, means a major essential component
|
||||
(kernel, window system, and so on) of the specific operating system
|
||||
(if any) on which the executable work runs, or a compiler used to
|
||||
produce the work, or an object code interpreter used to run it.
|
||||
|
||||
The "Corresponding Source" for a work in object code form means all
|
||||
the source code needed to generate, install, and (for an executable
|
||||
work) run the object code and to modify the work, including scripts to
|
||||
control those activities. However, it does not include the work's
|
||||
System Libraries, or general-purpose tools or generally available free
|
||||
programs which are used unmodified in performing those activities but
|
||||
which are not part of the work. For example, Corresponding Source
|
||||
includes interface definition files associated with source files for
|
||||
the work, and the source code for shared libraries and dynamically
|
||||
linked subprograms that the work is specifically designed to require,
|
||||
such as by intimate data communication or control flow between those
|
||||
subprograms and other parts of the work.
|
||||
|
||||
The Corresponding Source need not include anything that users
|
||||
can regenerate automatically from other parts of the Corresponding
|
||||
Source.
|
||||
|
||||
The Corresponding Source for a work in source code form is that
|
||||
same work.
|
||||
|
||||
2. Basic Permissions.
|
||||
|
||||
All rights granted under this License are granted for the term of
|
||||
copyright on the Program, and are irrevocable provided the stated
|
||||
conditions are met. This License explicitly affirms your unlimited
|
||||
permission to run the unmodified Program. The output from running a
|
||||
covered work is covered by this License only if the output, given its
|
||||
content, constitutes a covered work. This License acknowledges your
|
||||
rights of fair use or other equivalent, as provided by copyright law.
|
||||
|
||||
You may make, run and propagate covered works that you do not
|
||||
convey, without conditions so long as your license otherwise remains
|
||||
in force. You may convey covered works to others for the sole purpose
|
||||
of having them make modifications exclusively for you, or provide you
|
||||
with facilities for running those works, provided that you comply with
|
||||
the terms of this License in conveying all material for which you do
|
||||
not control copyright. Those thus making or running the covered works
|
||||
for you must do so exclusively on your behalf, under your direction
|
||||
and control, on terms that prohibit them from making any copies of
|
||||
your copyrighted material outside their relationship with you.
|
||||
|
||||
Conveying under any other circumstances is permitted solely under
|
||||
the conditions stated below. Sublicensing is not allowed; section 10
|
||||
makes it unnecessary.
|
||||
|
||||
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
|
||||
|
||||
No covered work shall be deemed part of an effective technological
|
||||
measure under any applicable law fulfilling obligations under article
|
||||
11 of the WIPO copyright treaty adopted on 20 December 1996, or
|
||||
similar laws prohibiting or restricting circumvention of such
|
||||
measures.
|
||||
|
||||
When you convey a covered work, you waive any legal power to forbid
|
||||
circumvention of technological measures to the extent such circumvention
|
||||
is effected by exercising rights under this License with respect to
|
||||
the covered work, and you disclaim any intention to limit operation or
|
||||
modification of the work as a means of enforcing, against the work's
|
||||
users, your or third parties' legal rights to forbid circumvention of
|
||||
technological measures.
|
||||
|
||||
4. Conveying Verbatim Copies.
|
||||
|
||||
You may convey verbatim copies of the Program's source code as you
|
||||
receive it, in any medium, provided that you conspicuously and
|
||||
appropriately publish on each copy an appropriate copyright notice;
|
||||
keep intact all notices stating that this License and any
|
||||
non-permissive terms added in accord with section 7 apply to the code;
|
||||
keep intact all notices of the absence of any warranty; and give all
|
||||
recipients a copy of this License along with the Program.
|
||||
|
||||
You may charge any price or no price for each copy that you convey,
|
||||
and you may offer support or warranty protection for a fee.
|
||||
|
||||
5. Conveying Modified Source Versions.
|
||||
|
||||
You may convey a work based on the Program, or the modifications to
|
||||
produce it from the Program, in the form of source code under the
|
||||
terms of section 4, provided that you also meet all of these conditions:
|
||||
|
||||
a) The work must carry prominent notices stating that you modified
|
||||
it, and giving a relevant date.
|
||||
|
||||
b) The work must carry prominent notices stating that it is
|
||||
released under this License and any conditions added under section
|
||||
7. This requirement modifies the requirement in section 4 to
|
||||
"keep intact all notices".
|
||||
|
||||
c) You must license the entire work, as a whole, under this
|
||||
License to anyone who comes into possession of a copy. This
|
||||
License will therefore apply, along with any applicable section 7
|
||||
additional terms, to the whole of the work, and all its parts,
|
||||
regardless of how they are packaged. This License gives no
|
||||
permission to license the work in any other way, but it does not
|
||||
invalidate such permission if you have separately received it.
|
||||
|
||||
d) If the work has interactive user interfaces, each must display
|
||||
Appropriate Legal Notices; however, if the Program has interactive
|
||||
interfaces that do not display Appropriate Legal Notices, your
|
||||
work need not make them do so.
|
||||
|
||||
A compilation of a covered work with other separate and independent
|
||||
works, which are not by their nature extensions of the covered work,
|
||||
and which are not combined with it such as to form a larger program,
|
||||
in or on a volume of a storage or distribution medium, is called an
|
||||
"aggregate" if the compilation and its resulting copyright are not
|
||||
used to limit the access or legal rights of the compilation's users
|
||||
beyond what the individual works permit. Inclusion of a covered work
|
||||
in an aggregate does not cause this License to apply to the other
|
||||
parts of the aggregate.
|
||||
|
||||
6. Conveying Non-Source Forms.
|
||||
|
||||
You may convey a covered work in object code form under the terms
|
||||
of sections 4 and 5, provided that you also convey the
|
||||
machine-readable Corresponding Source under the terms of this License,
|
||||
in one of these ways:
|
||||
|
||||
a) Convey the object code in, or embodied in, a physical product
|
||||
(including a physical distribution medium), accompanied by the
|
||||
Corresponding Source fixed on a durable physical medium
|
||||
customarily used for software interchange.
|
||||
|
||||
b) Convey the object code in, or embodied in, a physical product
|
||||
(including a physical distribution medium), accompanied by a
|
||||
written offer, valid for at least three years and valid for as
|
||||
long as you offer spare parts or customer support for that product
|
||||
model, to give anyone who possesses the object code either (1) a
|
||||
copy of the Corresponding Source for all the software in the
|
||||
product that is covered by this License, on a durable physical
|
||||
medium customarily used for software interchange, for a price no
|
||||
more than your reasonable cost of physically performing this
|
||||
conveying of source, or (2) access to copy the
|
||||
Corresponding Source from a network server at no charge.
|
||||
|
||||
c) Convey individual copies of the object code with a copy of the
|
||||
written offer to provide the Corresponding Source. This
|
||||
alternative is allowed only occasionally and noncommercially, and
|
||||
only if you received the object code with such an offer, in accord
|
||||
with subsection 6b.
|
||||
|
||||
d) Convey the object code by offering access from a designated
|
||||
place (gratis or for a charge), and offer equivalent access to the
|
||||
Corresponding Source in the same way through the same place at no
|
||||
further charge. You need not require recipients to copy the
|
||||
Corresponding Source along with the object code. If the place to
|
||||
copy the object code is a network server, the Corresponding Source
|
||||
may be on a different server (operated by you or a third party)
|
||||
that supports equivalent copying facilities, provided you maintain
|
||||
clear directions next to the object code saying where to find the
|
||||
Corresponding Source. Regardless of what server hosts the
|
||||
Corresponding Source, you remain obligated to ensure that it is
|
||||
available for as long as needed to satisfy these requirements.
|
||||
|
||||
e) Convey the object code using peer-to-peer transmission, provided
|
||||
you inform other peers where the object code and Corresponding
|
||||
Source of the work are being offered to the general public at no
|
||||
charge under subsection 6d.
|
||||
|
||||
A separable portion of the object code, whose source code is excluded
|
||||
from the Corresponding Source as a System Library, need not be
|
||||
included in conveying the object code work.
|
||||
|
||||
A "User Product" is either (1) a "consumer product", which means any
|
||||
tangible personal property which is normally used for personal, family,
|
||||
or household purposes, or (2) anything designed or sold for incorporation
|
||||
into a dwelling. In determining whether a product is a consumer product,
|
||||
doubtful cases shall be resolved in favor of coverage. For a particular
|
||||
product received by a particular user, "normally used" refers to a
|
||||
typical or common use of that class of product, regardless of the status
|
||||
of the particular user or of the way in which the particular user
|
||||
actually uses, or expects or is expected to use, the product. A product
|
||||
is a consumer product regardless of whether the product has substantial
|
||||
commercial, industrial or non-consumer uses, unless such uses represent
|
||||
the only significant mode of use of the product.
|
||||
|
||||
"Installation Information" for a User Product means any methods,
|
||||
procedures, authorization keys, or other information required to install
|
||||
and execute modified versions of a covered work in that User Product from
|
||||
a modified version of its Corresponding Source. The information must
|
||||
suffice to ensure that the continued functioning of the modified object
|
||||
code is in no case prevented or interfered with solely because
|
||||
modification has been made.
|
||||
|
||||
If you convey an object code work under this section in, or with, or
|
||||
specifically for use in, a User Product, and the conveying occurs as
|
||||
part of a transaction in which the right of possession and use of the
|
||||
User Product is transferred to the recipient in perpetuity or for a
|
||||
fixed term (regardless of how the transaction is characterized), the
|
||||
Corresponding Source conveyed under this section must be accompanied
|
||||
by the Installation Information. But this requirement does not apply
|
||||
if neither you nor any third party retains the ability to install
|
||||
modified object code on the User Product (for example, the work has
|
||||
been installed in ROM).
|
||||
|
||||
The requirement to provide Installation Information does not include a
|
||||
requirement to continue to provide support service, warranty, or updates
|
||||
for a work that has been modified or installed by the recipient, or for
|
||||
the User Product in which it has been modified or installed. Access to a
|
||||
network may be denied when the modification itself materially and
|
||||
adversely affects the operation of the network or violates the rules and
|
||||
protocols for communication across the network.
|
||||
|
||||
Corresponding Source conveyed, and Installation Information provided,
|
||||
in accord with this section must be in a format that is publicly
|
||||
documented (and with an implementation available to the public in
|
||||
source code form), and must require no special password or key for
|
||||
unpacking, reading or copying.
|
||||
|
||||
7. Additional Terms.
|
||||
|
||||
"Additional permissions" are terms that supplement the terms of this
|
||||
License by making exceptions from one or more of its conditions.
|
||||
Additional permissions that are applicable to the entire Program shall
|
||||
be treated as though they were included in this License, to the extent
|
||||
that they are valid under applicable law. If additional permissions
|
||||
apply only to part of the Program, that part may be used separately
|
||||
under those permissions, but the entire Program remains governed by
|
||||
this License without regard to the additional permissions.
|
||||
|
||||
When you convey a copy of a covered work, you may at your option
|
||||
remove any additional permissions from that copy, or from any part of
|
||||
it. (Additional permissions may be written to require their own
|
||||
removal in certain cases when you modify the work.) You may place
|
||||
additional permissions on material, added by you to a covered work,
|
||||
for which you have or can give appropriate copyright permission.
|
||||
|
||||
Notwithstanding any other provision of this License, for material you
|
||||
add to a covered work, you may (if authorized by the copyright holders of
|
||||
that material) supplement the terms of this License with terms:
|
||||
|
||||
a) Disclaiming warranty or limiting liability differently from the
|
||||
terms of sections 15 and 16 of this License; or
|
||||
|
||||
b) Requiring preservation of specified reasonable legal notices or
|
||||
author attributions in that material or in the Appropriate Legal
|
||||
Notices displayed by works containing it; or
|
||||
|
||||
c) Prohibiting misrepresentation of the origin of that material, or
|
||||
requiring that modified versions of such material be marked in
|
||||
reasonable ways as different from the original version; or
|
||||
|
||||
d) Limiting the use for publicity purposes of names of licensors or
|
||||
authors of the material; or
|
||||
|
||||
e) Declining to grant rights under trademark law for use of some
|
||||
trade names, trademarks, or service marks; or
|
||||
|
||||
f) Requiring indemnification of licensors and authors of that
|
||||
material by anyone who conveys the material (or modified versions of
|
||||
it) with contractual assumptions of liability to the recipient, for
|
||||
any liability that these contractual assumptions directly impose on
|
||||
those licensors and authors.
|
||||
|
||||
All other non-permissive additional terms are considered "further
|
||||
restrictions" within the meaning of section 10. If the Program as you
|
||||
received it, or any part of it, contains a notice stating that it is
|
||||
governed by this License along with a term that is a further
|
||||
restriction, you may remove that term. If a license document contains
|
||||
a further restriction but permits relicensing or conveying under this
|
||||
License, you may add to a covered work material governed by the terms
|
||||
of that license document, provided that the further restriction does
|
||||
not survive such relicensing or conveying.
|
||||
|
||||
If you add terms to a covered work in accord with this section, you
|
||||
must place, in the relevant source files, a statement of the
|
||||
additional terms that apply to those files, or a notice indicating
|
||||
where to find the applicable terms.
|
||||
|
||||
Additional terms, permissive or non-permissive, may be stated in the
|
||||
form of a separately written license, or stated as exceptions;
|
||||
the above requirements apply either way.
|
||||
|
||||
8. Termination.
|
||||
|
||||
You may not propagate or modify a covered work except as expressly
|
||||
provided under this License. Any attempt otherwise to propagate or
|
||||
modify it is void, and will automatically terminate your rights under
|
||||
this License (including any patent licenses granted under the third
|
||||
paragraph of section 11).
|
||||
|
||||
However, if you cease all violation of this License, then your
|
||||
license from a particular copyright holder is reinstated (a)
|
||||
provisionally, unless and until the copyright holder explicitly and
|
||||
finally terminates your license, and (b) permanently, if the copyright
|
||||
holder fails to notify you of the violation by some reasonable means
|
||||
prior to 60 days after the cessation.
|
||||
|
||||
Moreover, your license from a particular copyright holder is
|
||||
reinstated permanently if the copyright holder notifies you of the
|
||||
violation by some reasonable means, this is the first time you have
|
||||
received notice of violation of this License (for any work) from that
|
||||
copyright holder, and you cure the violation prior to 30 days after
|
||||
your receipt of the notice.
|
||||
|
||||
Termination of your rights under this section does not terminate the
|
||||
licenses of parties who have received copies or rights from you under
|
||||
this License. If your rights have been terminated and not permanently
|
||||
reinstated, you do not qualify to receive new licenses for the same
|
||||
material under section 10.
|
||||
|
||||
9. Acceptance Not Required for Having Copies.
|
||||
|
||||
You are not required to accept this License in order to receive or
|
||||
run a copy of the Program. Ancillary propagation of a covered work
|
||||
occurring solely as a consequence of using peer-to-peer transmission
|
||||
to receive a copy likewise does not require acceptance. However,
|
||||
nothing other than this License grants you permission to propagate or
|
||||
modify any covered work. These actions infringe copyright if you do
|
||||
not accept this License. Therefore, by modifying or propagating a
|
||||
covered work, you indicate your acceptance of this License to do so.
|
||||
|
||||
10. Automatic Licensing of Downstream Recipients.
|
||||
|
||||
Each time you convey a covered work, the recipient automatically
|
||||
receives a license from the original licensors, to run, modify and
|
||||
propagate that work, subject to this License. You are not responsible
|
||||
for enforcing compliance by third parties with this License.
|
||||
|
||||
An "entity transaction" is a transaction transferring control of an
|
||||
organization, or substantially all assets of one, or subdividing an
|
||||
organization, or merging organizations. If propagation of a covered
|
||||
work results from an entity transaction, each party to that
|
||||
transaction who receives a copy of the work also receives whatever
|
||||
licenses to the work the party's predecessor in interest had or could
|
||||
give under the previous paragraph, plus a right to possession of the
|
||||
Corresponding Source of the work from the predecessor in interest, if
|
||||
the predecessor has it or can get it with reasonable efforts.
|
||||
|
||||
You may not impose any further restrictions on the exercise of the
|
||||
rights granted or affirmed under this License. For example, you may
|
||||
not impose a license fee, royalty, or other charge for exercise of
|
||||
rights granted under this License, and you may not initiate litigation
|
||||
(including a cross-claim or counterclaim in a lawsuit) alleging that
|
||||
any patent claim is infringed by making, using, selling, offering for
|
||||
sale, or importing the Program or any portion of it.
|
||||
|
||||
11. Patents.
|
||||
|
||||
A "contributor" is a copyright holder who authorizes use under this
|
||||
License of the Program or a work on which the Program is based. The
|
||||
work thus licensed is called the contributor's "contributor version".
|
||||
|
||||
A contributor's "essential patent claims" are all patent claims
|
||||
owned or controlled by the contributor, whether already acquired or
|
||||
hereafter acquired, that would be infringed by some manner, permitted
|
||||
by this License, of making, using, or selling its contributor version,
|
||||
but do not include claims that would be infringed only as a
|
||||
consequence of further modification of the contributor version. For
|
||||
purposes of this definition, "control" includes the right to grant
|
||||
patent sublicenses in a manner consistent with the requirements of
|
||||
this License.
|
||||
|
||||
Each contributor grants you a non-exclusive, worldwide, royalty-free
|
||||
patent license under the contributor's essential patent claims, to
|
||||
make, use, sell, offer for sale, import and otherwise run, modify and
|
||||
propagate the contents of its contributor version.
|
||||
|
||||
In the following three paragraphs, a "patent license" is any express
|
||||
agreement or commitment, however denominated, not to enforce a patent
|
||||
(such as an express permission to practice a patent or covenant not to
|
||||
sue for patent infringement). To "grant" such a patent license to a
|
||||
party means to make such an agreement or commitment not to enforce a
|
||||
patent against the party.
|
||||
|
||||
If you convey a covered work, knowingly relying on a patent license,
|
||||
and the Corresponding Source of the work is not available for anyone
|
||||
to copy, free of charge and under the terms of this License, through a
|
||||
publicly available network server or other readily accessible means,
|
||||
then you must either (1) cause the Corresponding Source to be so
|
||||
available, or (2) arrange to deprive yourself of the benefit of the
|
||||
patent license for this particular work, or (3) arrange, in a manner
|
||||
consistent with the requirements of this License, to extend the patent
|
||||
license to downstream recipients. "Knowingly relying" means you have
|
||||
actual knowledge that, but for the patent license, your conveying the
|
||||
covered work in a country, or your recipient's use of the covered work
|
||||
in a country, would infringe one or more identifiable patents in that
|
||||
country that you have reason to believe are valid.
|
||||
|
||||
If, pursuant to or in connection with a single transaction or
|
||||
arrangement, you convey, or propagate by procuring conveyance of, a
|
||||
covered work, and grant a patent license to some of the parties
|
||||
receiving the covered work authorizing them to use, propagate, modify
|
||||
or convey a specific copy of the covered work, then the patent license
|
||||
you grant is automatically extended to all recipients of the covered
|
||||
work and works based on it.
|
||||
|
||||
A patent license is "discriminatory" if it does not include within
|
||||
the scope of its coverage, prohibits the exercise of, or is
|
||||
conditioned on the non-exercise of one or more of the rights that are
|
||||
specifically granted under this License. You may not convey a covered
|
||||
work if you are a party to an arrangement with a third party that is
|
||||
in the business of distributing software, under which you make payment
|
||||
to the third party based on the extent of your activity of conveying
|
||||
the work, and under which the third party grants, to any of the
|
||||
parties who would receive the covered work from you, a discriminatory
|
||||
patent license (a) in connection with copies of the covered work
|
||||
conveyed by you (or copies made from those copies), or (b) primarily
|
||||
for and in connection with specific products or compilations that
|
||||
contain the covered work, unless you entered into that arrangement,
|
||||
or that patent license was granted, prior to 28 March 2007.
|
||||
|
||||
Nothing in this License shall be construed as excluding or limiting
|
||||
any implied license or other defenses to infringement that may
|
||||
otherwise be available to you under applicable patent law.
|
||||
|
||||
12. No Surrender of Others' Freedom.
|
||||
|
||||
If conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot convey a
|
||||
covered work so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you may
|
||||
not convey it at all. For example, if you agree to terms that obligate you
|
||||
to collect a royalty for further conveying from those to whom you convey
|
||||
the Program, the only way you could satisfy both those terms and this
|
||||
License would be to refrain entirely from conveying the Program.
|
||||
|
||||
13. Use with the GNU Affero General Public License.
|
||||
|
||||
Notwithstanding any other provision of this License, you have
|
||||
permission to link or combine any covered work with a work licensed
|
||||
under version 3 of the GNU Affero General Public License into a single
|
||||
combined work, and to convey the resulting work. The terms of this
|
||||
License will continue to apply to the part which is the covered work,
|
||||
but the special requirements of the GNU Affero General Public License,
|
||||
section 13, concerning interaction through a network will apply to the
|
||||
combination as such.
|
||||
|
||||
14. Revised Versions of this License.
|
||||
|
||||
The Free Software Foundation may publish revised and/or new versions of
|
||||
the GNU General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the
|
||||
Program specifies that a certain numbered version of the GNU General
|
||||
Public License "or any later version" applies to it, you have the
|
||||
option of following the terms and conditions either of that numbered
|
||||
version or of any later version published by the Free Software
|
||||
Foundation. If the Program does not specify a version number of the
|
||||
GNU General Public License, you may choose any version ever published
|
||||
by the Free Software Foundation.
|
||||
|
||||
If the Program specifies that a proxy can decide which future
|
||||
versions of the GNU General Public License can be used, that proxy's
|
||||
public statement of acceptance of a version permanently authorizes you
|
||||
to choose that version for the Program.
|
||||
|
||||
Later license versions may give you additional or different
|
||||
permissions. However, no additional obligations are imposed on any
|
||||
author or copyright holder as a result of your choosing to follow a
|
||||
later version.
|
||||
|
||||
15. Disclaimer of Warranty.
|
||||
|
||||
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
|
||||
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
|
||||
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
|
||||
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
|
||||
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
|
||||
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
|
||||
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||
|
||||
16. Limitation of Liability.
|
||||
|
||||
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
|
||||
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
|
||||
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
|
||||
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
|
||||
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
|
||||
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
|
||||
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
|
||||
SUCH DAMAGES.
|
||||
|
||||
17. Interpretation of Sections 15 and 16.
|
||||
|
||||
If the disclaimer of warranty and limitation of liability provided
|
||||
above cannot be given local legal effect according to their terms,
|
||||
reviewing courts shall apply local law that most closely approximates
|
||||
an absolute waiver of all civil liability in connection with the
|
||||
Program, unless a warranty or assumption of liability accompanies a
|
||||
copy of the Program in return for a fee.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
state the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it 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.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program does terminal interaction, make it output a short
|
||||
notice like this when it starts in an interactive mode:
|
||||
|
||||
<program> Copyright (C) <year> <name of author>
|
||||
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, your program's commands
|
||||
might be different; for a GUI interface, you would use an "about box".
|
||||
|
||||
You should also get your employer (if you work as a programmer) or school,
|
||||
if any, to sign a "copyright disclaimer" for the program, if necessary.
|
||||
For more information on this, and how to apply and follow the GNU GPL, see
|
||||
<https://www.gnu.org/licenses/>.
|
||||
|
||||
The GNU General Public License does not permit incorporating your program
|
||||
into proprietary programs. If your program is a subroutine library, you
|
||||
may consider it more useful to permit linking proprietary applications with
|
||||
the library. If this is what you want to do, use the GNU Lesser General
|
||||
Public License instead of this License. But first, please read
|
||||
<https://www.gnu.org/licenses/why-not-lgpl.html>.
|
||||
373
README.md
373
README.md
@@ -1,93 +1,113 @@
|
||||
[](https://matrix.to/#/#element-web:matrix.org)
|
||||

|
||||

|
||||
[](https://localazy.com/p/element-web)
|
||||

|
||||

|
||||
[](https://translate.element.io/engage/element-web/)
|
||||
[](https://sonarcloud.io/summary/new_code?id=element-web)
|
||||
[](https://sonarcloud.io/summary/new_code?id=element-web)
|
||||
[](https://sonarcloud.io/summary/new_code?id=element-web)
|
||||
[](https://sonarcloud.io/summary/new_code?id=element-web)
|
||||
|
||||
# Element
|
||||
Element
|
||||
=======
|
||||
|
||||
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).
|
||||
React SDK](https://github.com/matrix-org/matrix-react-sdk).
|
||||
|
||||
# Supported Environments
|
||||
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
|
||||
|
||||
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.
|
||||
* Supported
|
||||
* Definition: Issues **actively triaged**, regressions **block** the release
|
||||
* Last 2 major versions of Chrome, Firefox, Safari, and Edge on desktop OSes
|
||||
* 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
|
||||
* Experimental
|
||||
* Definition: Issues **accepted**, regressions **do not block** the release
|
||||
* Element as an installed PWA via current stable version of Chrome, Firefox, and Safari
|
||||
* 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
|
||||
|
||||
For accessing Element on an Android or iOS device, we currently recommend the
|
||||
native apps [element-android](https://github.com/element-hq/element-android)
|
||||
and [element-ios](https://github.com/element-hq/element-ios).
|
||||
native apps [element-android](https://github.com/vector-im/element-android)
|
||||
and [element-ios](https://github.com/vector-im/element-ios).
|
||||
|
||||
# Getting Started
|
||||
Getting Started
|
||||
===============
|
||||
|
||||
The easiest way to test Element is to just use the hosted copy at <https://app.element.io>.
|
||||
The `develop` branch is continuously deployed to <https://develop.element.io>
|
||||
for those who like living dangerously.
|
||||
|
||||
To host your own instance of Element see [Installing Element Web](docs/install.md).
|
||||
To host your own copy of Element, the quickest bet is to use a pre-built
|
||||
released version of Element:
|
||||
|
||||
To install Element as a desktop application, see [Running as a desktop app](#running-as-a-desktop-app) below.
|
||||
1. Download the latest version from <https://github.com/vector-im/element-web/releases>
|
||||
1. Untar the tarball on your web server
|
||||
1. Move (or symlink) the `element-x.x.x` directory to an appropriate name
|
||||
1. Configure the correct caching headers in your webserver (see below)
|
||||
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. Enter the URL into your browser and log into Element!
|
||||
|
||||
# Important Security Notes
|
||||
Releases are signed using gpg and the OpenPGP standard, and can be checked against the public key located
|
||||
at <https://packages.riot.im/element-release-key.asc>.
|
||||
|
||||
## Separate domains
|
||||
Note that for the security of your chats will need to serve Element
|
||||
over HTTPS. Major browsers also do not allow you to use VoIP/video
|
||||
chats over HTTP, as WebRTC is only usable over HTTPS.
|
||||
There are some exceptions like when using localhost, which is
|
||||
considered a [secure context](https://developer.mozilla.org/docs/Web/Security/Secure_Contexts)
|
||||
and thus allowed.
|
||||
|
||||
To install Element as a desktop application, see [Running as a desktop
|
||||
app](#running-as-a-desktop-app) below.
|
||||
|
||||
Important Security Notes
|
||||
========================
|
||||
|
||||
Separate domains
|
||||
----------------
|
||||
|
||||
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)
|
||||
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.
|
||||
|
||||
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.
|
||||
situation, but it's still not good practice to do it in the first place. See
|
||||
<https://github.com/vector-im/element-web/issues/1977> for more details.
|
||||
|
||||
## Configuration best practices
|
||||
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
|
||||
* 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`
|
||||
* The `frame-ancestors 'none'` 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
|
||||
* 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
|
||||
* 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
|
||||
[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:
|
||||
|
||||
@@ -95,23 +115,22 @@ 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'";
|
||||
add_header Content-Security-Policy "frame-ancestors 'none'";
|
||||
```
|
||||
|
||||
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'"
|
||||
Header set Content-Security-Policy "frame-ancestors 'none'"
|
||||
```
|
||||
|
||||
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
|
||||
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.
|
||||
@@ -121,12 +140,12 @@ guide](https://classic.yarnpkg.com/en/docs/install) if you do not have it alread
|
||||
|
||||
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. Clone the repo: `git clone https://github.com/vector-im/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
|
||||
* If you're using the `develop` branch, then it is recommended to set up a
|
||||
proper development environment (see [Setting up a dev
|
||||
environment](./developer_guide.md#setting-up-a-dev-environment) below). Alternatively, you
|
||||
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
|
||||
@@ -141,29 +160,89 @@ will not appear in Settings without using the dist script. You can then mount th
|
||||
`webapp` directory on your web server to actually serve up the app, which is
|
||||
entirely static content.
|
||||
|
||||
# Running as a Desktop app
|
||||
Running as a Desktop app
|
||||
========================
|
||||
|
||||
Element can also be run as a desktop app, wrapped in Electron. You can download a
|
||||
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-desktop>.
|
||||
To build it yourself, follow the instructions at <https://github.com/vector-im/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.
|
||||
Other options for running as a desktop app:
|
||||
|
||||
# config.json
|
||||
* @asdf:matrix.org points out that you can use nativefier and it just works(tm)
|
||||
|
||||
```bash
|
||||
yarn global add nativefier
|
||||
nativefier https://app.element.io/
|
||||
```
|
||||
|
||||
The [configuration docs](docs/config.md#desktop-app-configuration) show how to
|
||||
override the desktop app's default settings if desired.
|
||||
|
||||
Running from Docker
|
||||
===================
|
||||
|
||||
The Docker image can be used to serve element-web as a web server. The easiest way to use
|
||||
it is to use the prebuilt image:
|
||||
|
||||
```bash
|
||||
docker run -p 80:80 vectorim/element-web
|
||||
```
|
||||
|
||||
To supply your own custom `config.json`, map a volume to `/app/config.json`. For example,
|
||||
if your custom config was located at `/etc/element-web/config.json` then your Docker command
|
||||
would be:
|
||||
|
||||
```bash
|
||||
docker run -p 80:80 -v /etc/element-web/config.json:/app/config.json vectorim/element-web
|
||||
```
|
||||
|
||||
To build the image yourself:
|
||||
|
||||
```bash
|
||||
git clone https://github.com/vector-im/element-web.git element-web
|
||||
cd element-web
|
||||
git checkout master
|
||||
docker build .
|
||||
```
|
||||
|
||||
If you're building a custom branch, or want to use the develop branch, check out the appropriate
|
||||
element-web branch and then run:
|
||||
|
||||
```bash
|
||||
docker build -t \
|
||||
--build-arg USE_CUSTOM_SDKS=true \
|
||||
--build-arg REACT_SDK_REPO="https://github.com/matrix-org/matrix-react-sdk.git" \
|
||||
--build-arg REACT_SDK_BRANCH="develop" \
|
||||
--build-arg JS_SDK_REPO="https://github.com/matrix-org/matrix-js-sdk.git" \
|
||||
--build-arg JS_SDK_BRANCH="develop" \
|
||||
.
|
||||
```
|
||||
|
||||
Running in Kubernetes
|
||||
=====================
|
||||
|
||||
The provided element-web docker image can also be run from within a Kubernetes cluster.
|
||||
See the [Kubernetes example](docs/kubernetes.md) for more details.
|
||||
|
||||
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
|
||||
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).
|
||||
Some of these features are described in [labs.md](https://github.com/vector-im/element-web/blob/develop/docs/labs.md).
|
||||
|
||||
# Caching requirements
|
||||
Caching requirements
|
||||
====================
|
||||
|
||||
Element requires the following URLs not to be cached, when/if you are serving Element from your own webserver:
|
||||
|
||||
@@ -180,37 +259,159 @@ webserver to return `Cache-Control: no-cache` for `/`. This ensures the browser
|
||||
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
|
||||
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.
|
||||
|
||||
# Translations
|
||||
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.
|
||||
|
||||
CSS hot-reload is available as an opt-in development feature. You can enable it
|
||||
by defining a `CSS_HOT_RELOAD` environment variable, in a `.env` file in the root
|
||||
of the repository. See `.env.example` for documentation and an example.
|
||||
|
||||
Setting up a dev environment
|
||||
============================
|
||||
|
||||
Much of the functionality in Element is actually in the `matrix-react-sdk` and
|
||||
`matrix-js-sdk` modules. 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
|
||||
```
|
||||
|
||||
Then similarly with `matrix-react-sdk`:
|
||||
|
||||
```bash
|
||||
git clone https://github.com/matrix-org/matrix-react-sdk.git
|
||||
pushd matrix-react-sdk
|
||||
yarn link
|
||||
yarn link matrix-js-sdk
|
||||
yarn install
|
||||
popd
|
||||
```
|
||||
|
||||
Clone the repo and switch to the `element-web` directory:
|
||||
|
||||
```bash
|
||||
git clone https://github.com/vector-im/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 link matrix-react-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/vector-im/element-web/issues/15750) and
|
||||
[#15774](https://github.com/vector-im/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-react-sdk` or `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
|
||||
============
|
||||
|
||||
To add a new translation, head to the [translating doc](docs/translating.md).
|
||||
|
||||
For a developer guide, see the [translating dev doc](docs/translating-dev.md).
|
||||
|
||||
# Triaging issues
|
||||
[<img src="https://translate.element.io/widgets/element-web/-/multi-auto.svg" alt="translationsstatus" width="340">](https://translate.element.io/engage/element-web/?utm_source=widget)
|
||||
|
||||
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).
|
||||
Triaging issues
|
||||
===============
|
||||
|
||||
We use [issue labels](https://github.com/element-hq/element-meta/wiki/Issue-labelling) to sort all incoming issues.
|
||||
Issues are triaged by community members and the Web App Team, following the [triage process](https://github.com/vector-im/element-meta/wiki/Triage-process).
|
||||
|
||||
## 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.
|
||||
We use [issue labels](https://github.com/vector-im/element-meta/wiki/Issue-labelling) to sort all incoming issues.
|
||||
|
||||
@@ -1,2 +0,0 @@
|
||||
// Yes, this is empty.
|
||||
module.exports = {};
|
||||
@@ -1 +0,0 @@
|
||||
module.exports = "image-file-stub";
|
||||
@@ -1,4 +0,0 @@
|
||||
{
|
||||
"en": "en_EN.json",
|
||||
"en-us": "en_US.json"
|
||||
}
|
||||
@@ -1,41 +0,0 @@
|
||||
/*
|
||||
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
|
||||
Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
const EventEmitter = require("events");
|
||||
const { LngLat, NavigationControl, LngLatBounds } = require("maplibre-gl");
|
||||
|
||||
class MockMap extends EventEmitter {
|
||||
addControl = jest.fn();
|
||||
removeControl = jest.fn();
|
||||
zoomIn = jest.fn();
|
||||
zoomOut = jest.fn();
|
||||
setCenter = jest.fn();
|
||||
setStyle = jest.fn();
|
||||
fitBounds = jest.fn();
|
||||
remove = jest.fn();
|
||||
}
|
||||
const MockMapInstance = new MockMap();
|
||||
|
||||
class MockAttributionControl {}
|
||||
class MockGeolocateControl extends EventEmitter {
|
||||
trigger = jest.fn();
|
||||
}
|
||||
const MockGeolocateInstance = new MockGeolocateControl();
|
||||
const MockMarker = {};
|
||||
MockMarker.setLngLat = jest.fn().mockReturnValue(MockMarker);
|
||||
MockMarker.addTo = jest.fn().mockReturnValue(MockMarker);
|
||||
MockMarker.remove = jest.fn().mockReturnValue(MockMarker);
|
||||
module.exports = {
|
||||
Map: jest.fn().mockReturnValue(MockMapInstance),
|
||||
GeolocateControl: jest.fn().mockReturnValue(MockGeolocateInstance),
|
||||
Marker: jest.fn().mockReturnValue(MockMarker),
|
||||
LngLat,
|
||||
LngLatBounds,
|
||||
NavigationControl,
|
||||
AttributionControl: MockAttributionControl,
|
||||
};
|
||||
@@ -1,2 +0,0 @@
|
||||
export const Icon = "div";
|
||||
export default "image-file-stub";
|
||||
@@ -1,11 +0,0 @@
|
||||
/*
|
||||
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 OR LicenseRef-Element-Commercial
|
||||
Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
export default function workerFactory(options) {
|
||||
return jest.fn;
|
||||
}
|
||||
@@ -1,37 +1,25 @@
|
||||
module.exports = {
|
||||
sourceMaps: true,
|
||||
presets: [
|
||||
[
|
||||
"@babel/preset-env",
|
||||
{
|
||||
targets: [
|
||||
"last 2 Chrome versions",
|
||||
"last 2 Firefox versions",
|
||||
"last 2 Safari versions",
|
||||
"last 2 Edge versions",
|
||||
],
|
||||
include: ["@babel/plugin-transform-class-properties"],
|
||||
},
|
||||
],
|
||||
["@babel/preset-typescript", { allowDeclareFields: true }],
|
||||
"sourceMaps": true,
|
||||
"presets": [
|
||||
["@babel/preset-env", {
|
||||
"targets": [
|
||||
"last 2 Chrome versions",
|
||||
"last 2 Firefox versions",
|
||||
"last 2 Safari versions",
|
||||
"last 2 Edge versions",
|
||||
],
|
||||
}],
|
||||
"@babel/preset-typescript",
|
||||
"@babel/preset-react",
|
||||
],
|
||||
plugins: [
|
||||
"plugins": [
|
||||
"@babel/plugin-proposal-export-default-from",
|
||||
"@babel/plugin-transform-numeric-separator",
|
||||
"@babel/plugin-transform-object-rest-spread",
|
||||
"@babel/plugin-transform-optional-chaining",
|
||||
"@babel/plugin-transform-nullish-coalescing-operator",
|
||||
|
||||
// transform logical assignment (??=, ||=, &&=). preset-env doesn't
|
||||
// normally bother with these (presumably because all the target
|
||||
// browsers support it natively), but they make our webpack version (or
|
||||
// something downstream of babel, at least) fall over.
|
||||
"@babel/plugin-transform-logical-assignment-operators",
|
||||
|
||||
"@babel/plugin-proposal-numeric-separator",
|
||||
"@babel/plugin-proposal-class-properties",
|
||||
"@babel/plugin-proposal-object-rest-spread",
|
||||
"@babel/plugin-proposal-optional-chaining",
|
||||
"@babel/plugin-proposal-nullish-coalescing-operator",
|
||||
"@babel/plugin-syntax-dynamic-import",
|
||||
"@babel/plugin-transform-runtime",
|
||||
["@babel/plugin-proposal-decorators", { version: "2023-11" }], // only needed by the js-sdk
|
||||
"@babel/plugin-transform-class-static-block", // only needed by the js-sdk for decorators
|
||||
],
|
||||
};
|
||||
|
||||
33
book.toml
33
book.toml
@@ -1,33 +0,0 @@
|
||||
# Documentation for possible options in this file is at
|
||||
# https://rust-lang.github.io/mdBook/format/config.html
|
||||
[book]
|
||||
title = "Element Web & Desktop"
|
||||
authors = ["New Vector Ltd.", "The Matrix.org Foundation C.I.C."]
|
||||
language = "en"
|
||||
multilingual = false
|
||||
|
||||
# The directory that documentation files are stored in
|
||||
src = "docs"
|
||||
|
||||
[build]
|
||||
# Prevent markdown pages from being automatically generated when they're
|
||||
# linked to in SUMMARY.md
|
||||
create-missing = false
|
||||
|
||||
[output.html]
|
||||
# Remove the numbers that appear before each item in the sidebar, as they can
|
||||
# get quite messy as we nest deeper
|
||||
no-section-label = true
|
||||
additional-css = ["docs/lib/custom.css"]
|
||||
|
||||
# The source code URL of the repository
|
||||
git-repository-url = "https://github.com/element-hq/element-web"
|
||||
|
||||
# The path that the docs are hosted on
|
||||
site-url = "/element-web/"
|
||||
additional-js = ["docs/lib/mermaid.min.js", "docs/lib/mermaid-init.js"]
|
||||
|
||||
[preprocessor]
|
||||
|
||||
[preprocessor.mermaid]
|
||||
command = "mdbook-mermaid"
|
||||
@@ -21,5 +21,5 @@ modules:
|
||||
# An example of pulling a module from NPM
|
||||
- "@vector-im/element-web-ilag-module@^0.0.1"
|
||||
|
||||
# An example of pulling a module from local filesystem during development
|
||||
- "file:/home/user/development/element-web-ilag-module"
|
||||
# An example of pulling a module from github
|
||||
- "github:vector-im/element-web-ilag-module#main"
|
||||
|
||||
341
code_style.md
341
code_style.md
@@ -3,8 +3,18 @@
|
||||
This code style applies to projects which the element-web team directly maintains or is reasonably
|
||||
adjacent to. As of writing, these are:
|
||||
|
||||
- element-desktop
|
||||
- element-web
|
||||
* element-desktop
|
||||
* element-web
|
||||
* matrix-react-sdk
|
||||
* matrix-js-sdk
|
||||
|
||||
Other projects might extend this code style for increased strictness. For example, matrix-events-sdk
|
||||
has stricter code organization to reduce the maintenance burden. These projects will declare their code
|
||||
style within their own repos.
|
||||
|
||||
Note that some requirements will be layer-specific. Where the requirements don't make sense for the
|
||||
project, they are used to the best of their ability, used in spirit, or ignored if not applicable,
|
||||
in that order.
|
||||
|
||||
## Guiding principles
|
||||
|
||||
@@ -41,28 +51,60 @@ adjacent to. As of writing, these are:
|
||||
|
||||
Unless otherwise specified, the following applies to all code:
|
||||
|
||||
1. Files must be formatted with Prettier.
|
||||
2. 120 character limit per line. Match existing code in the file if it is using a lower guide.
|
||||
3. A tab/indentation is 4 spaces.
|
||||
4. Newlines are Unix.
|
||||
5. A file has a single empty line at the end.
|
||||
6. Lines are trimmed of all excess whitespace, including blank lines.
|
||||
7. Long lines are broken up for readability.
|
||||
1. 120 character limit per line. Match existing code in the file if it is using a lower guide.
|
||||
2. A tab/indentation is 4 spaces.
|
||||
3. Newlines are Unix.
|
||||
4. A file has a single empty line at the end.
|
||||
5. Lines are trimmed of all excess whitespace, including blank lines.
|
||||
6. Long lines are broken up for readability.
|
||||
|
||||
## TypeScript / JavaScript
|
||||
## TypeScript / JavaScript {#typescript-javascript}
|
||||
|
||||
1. Write TypeScript. Turn JavaScript into TypeScript when working in the area.
|
||||
2. Use [TSDoc](https://tsdoc.org/) to document your code. See [Comments](#comments) below.
|
||||
3. Use named exports.
|
||||
2. Use named exports.
|
||||
3. Break long lines to appear as follows:
|
||||
|
||||
```typescript
|
||||
// Function arguments
|
||||
function doThing(
|
||||
arg1: string,
|
||||
arg2: string,
|
||||
arg3: string,
|
||||
): boolean {
|
||||
return !!arg1
|
||||
&& !!arg2
|
||||
&& !!arg3;
|
||||
}
|
||||
|
||||
// Calling a function
|
||||
doThing(
|
||||
"String 1",
|
||||
"String 2",
|
||||
"String 3",
|
||||
);
|
||||
|
||||
// Reduce line verbosity when possible/reasonable
|
||||
doThing(
|
||||
"String1", "String 2",
|
||||
"A much longer string 3",
|
||||
);
|
||||
|
||||
// Chaining function calls
|
||||
something.doThing()
|
||||
.doOtherThing()
|
||||
.doMore()
|
||||
.somethingElse(it =>
|
||||
useIt(it)
|
||||
);
|
||||
```
|
||||
4. Use semicolons for block/line termination.
|
||||
1. Except when defining interfaces, classes, and non-arrow functions specifically.
|
||||
5. When a statement's body is a single line, it must be written without curly braces, so long as the body is placed on
|
||||
5. When a statement's body is a single line, it may be written without curly braces, so long as the body is placed on
|
||||
the same line as the statement.
|
||||
|
||||
```typescript
|
||||
if (x) doThing();
|
||||
```
|
||||
|
||||
6. Blocks for `if`, `for`, `switch` and so on must have a space surrounding the condition, but not
|
||||
within the condition.
|
||||
|
||||
@@ -71,18 +113,59 @@ Unless otherwise specified, the following applies to all code:
|
||||
doThing();
|
||||
}
|
||||
```
|
||||
7. Mixing of logical operands requires brackets to explicitly define boolean logic.
|
||||
|
||||
7. lowerCamelCase is used for function and variable naming.
|
||||
8. UpperCamelCase is used for general naming.
|
||||
9. Interface names should not be marked with an uppercase `I`.
|
||||
10. One variable declaration per line.
|
||||
11. If a variable is not receiving a value on declaration, its type must be defined.
|
||||
```typescript
|
||||
if ((a > b && b > c) || (d < e)) return true;
|
||||
```
|
||||
8. Ternaries use the same rules as `if` statements, plus the following:
|
||||
|
||||
```typescript
|
||||
// Single line is acceptable
|
||||
const val = a > b ? doThing() : doOtherThing();
|
||||
|
||||
// Multiline is also okay
|
||||
const val = a > b
|
||||
? doThing()
|
||||
: doOtherThing();
|
||||
|
||||
// Use brackets when using multiple conditions.
|
||||
// Maximum 3 conditions, prefer 2 or less.
|
||||
const val = (a > b && b > c) ? doThing() : doOtherThing();
|
||||
```
|
||||
9. lowerCamelCase is used for function and variable naming.
|
||||
10. UpperCamelCase is used for general naming.
|
||||
11. Interface names should not be marked with an uppercase `I`.
|
||||
12. One variable declaration per line.
|
||||
13. If a variable is not receiving a value on declaration, its type must be defined.
|
||||
|
||||
```typescript
|
||||
let errorMessage: Optional<string>;
|
||||
```
|
||||
14. Objects, arrays, enums and so on must have each line terminated with a comma:
|
||||
|
||||
12. Objects can use shorthand declarations, including mixing of types.
|
||||
```typescript
|
||||
const obj = {
|
||||
prop: 1,
|
||||
else: 2,
|
||||
};
|
||||
|
||||
const arr = [
|
||||
"one",
|
||||
"two",
|
||||
];
|
||||
|
||||
enum Thing {
|
||||
Foo,
|
||||
Bar,
|
||||
}
|
||||
|
||||
doThing(
|
||||
"arg1",
|
||||
"arg2",
|
||||
);
|
||||
```
|
||||
15. Objects can use shorthand declarations, including mixing of types.
|
||||
|
||||
```typescript
|
||||
{
|
||||
@@ -92,8 +175,7 @@ Unless otherwise specified, the following applies to all code:
|
||||
// ... or ...
|
||||
{ room, prop: this.prop }
|
||||
```
|
||||
|
||||
13. Object keys should always be non-strings when possible.
|
||||
16. Object keys should always be non-strings when possible.
|
||||
|
||||
```typescript
|
||||
{
|
||||
@@ -102,31 +184,22 @@ Unless otherwise specified, the following applies to all code:
|
||||
[EventType.RoomMessage]: true,
|
||||
}
|
||||
```
|
||||
|
||||
14. If a variable's type should be boolean, make sure it really is one.
|
||||
17. Explicitly cast to a boolean.
|
||||
|
||||
```typescript
|
||||
const isRealUser = !!userId && ...; // good
|
||||
const isRealUser = Boolean(userId) && Boolean(userName); // also good
|
||||
const isRealUser = Boolean(userId) && isReal; // also good (where isReal is another boolean variable)
|
||||
const isRealUser = Boolean(userId && userName); // also fine
|
||||
const isRealUser = Boolean(userId || userName); // good: same as &&
|
||||
const isRealUser = userId && ...; // bad: isRealUser is userId's type, not a boolean
|
||||
|
||||
if (userId) // fine: userId is evaluated for truthiness, not stored as a boolean
|
||||
!!stringVar || Boolean(stringVar)
|
||||
```
|
||||
|
||||
15. Use `switch` statements when checking against more than a few enum-like values.
|
||||
16. Use `const` for constants, `let` for mutability.
|
||||
17. Describe types exhaustively (ensure noImplictAny would pass).
|
||||
18. Use `switch` statements when checking against more than a few enum-like values.
|
||||
19. Use `const` for constants, `let` for mutability.
|
||||
20. Describe types exhaustively (ensure noImplictAny would pass).
|
||||
1. Notable exceptions are arrow functions used as parameters, when a void return type is
|
||||
obvious, and when declaring and assigning a variable in the same line.
|
||||
18. Declare member visibility (public/private/protected).
|
||||
19. Private members are private and not prefixed unless required for naming conflicts.
|
||||
21. Declare member visibility (public/private/protected).
|
||||
22. Private members are private and not prefixed unless required for naming conflicts.
|
||||
1. Convention is to use an underscore or the word "internal" to denote conflicted member names.
|
||||
2. "Conflicted" typically refers to a getter which wants the same name as the underlying variable.
|
||||
20. Prefer readonly members over getters backed by a variable, unless an internal setter is required.
|
||||
21. Prefer Interfaces for object definitions, and types for parameter-value-only declarations.
|
||||
23. Prefer readonly members over getters backed by a variable, unless an internal setter is required.
|
||||
24. Prefer Interfaces for object definitions, and types for parameter-value-only declarations.
|
||||
1. Note that an explicit type is optional if not expected to be used outside of the function call,
|
||||
unlike in this example:
|
||||
|
||||
@@ -141,24 +214,22 @@ Unless otherwise specified, the following applies to all code:
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
22. Variables/properties which are `public static` should also be `readonly` when possible.
|
||||
23. Interface and type properties are terminated with semicolons, not commas.
|
||||
24. Prefer arrow formatting when declaring functions for interfaces/types:
|
||||
25. Variables/properties which are `public static` should also be `readonly` when possible.
|
||||
26. Interface and type properties are terminated with semicolons, not commas.
|
||||
27. Prefer arrow formatting when declaring functions for interfaces/types:
|
||||
|
||||
```typescript
|
||||
interface Test {
|
||||
myCallback: (arg: string) => Promise<void>;
|
||||
}
|
||||
```
|
||||
|
||||
25. Prefer a type definition over an inline type. For example, define an interface.
|
||||
26. Always prefer to add types or declare a type over the use of `any`. Prefer inferred types
|
||||
28. Prefer a type definition over an inline type. For example, define an interface.
|
||||
29. Always prefer to add types or declare a type over the use of `any`. Prefer inferred types
|
||||
when they are not `any`.
|
||||
1. When using `any`, a comment explaining why must be present.
|
||||
27. `import` should be used instead of `require`, as `require` does not have types.
|
||||
28. Export only what can be reused.
|
||||
29. Prefer a type like `Optional<X>` (`type Optional<T> = T | null | undefined`) instead
|
||||
30. `import` should be used instead of `require`, as `require` does not have types.
|
||||
31. Export only what can be reused.
|
||||
32. Prefer a type like `Optional<X>` (`type Optional<T> = T | null | undefined`) instead
|
||||
of truly optional parameters.
|
||||
1. A notable exception is when the likelihood of a bug is minimal, such as when a function
|
||||
takes an argument that is more often not required than required. An example where the
|
||||
@@ -174,13 +245,12 @@ Unless otherwise specified, the following applies to all code:
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
30. There should be approximately one interface, class, or enum per file unless the file is named
|
||||
33. There should be approximately one interface, class, or enum per file unless the file is named
|
||||
"types.ts", "global.d.ts", or ends with "-types.ts".
|
||||
1. The file name should match the interface, class, or enum name.
|
||||
31. Bulk functions can be declared in a single file, though named as "foo-utils.ts" or "utils/foo.ts".
|
||||
32. Imports are grouped by external module imports first, then by internal imports.
|
||||
33. File ordering is not strict, but should generally follow this sequence:
|
||||
34. Bulk functions can be declared in a single file, though named as "foo-utils.ts" or "utils/foo.ts".
|
||||
35. Imports are grouped by external module imports first, then by internal imports.
|
||||
36. File ordering is not strict, but should generally follow this sequence:
|
||||
1. Licence header
|
||||
2. Imports
|
||||
3. Constants
|
||||
@@ -195,16 +265,15 @@ Unless otherwise specified, the following applies to all code:
|
||||
5. Protected and abstract functions
|
||||
6. Public/private functions
|
||||
7. Public/protected/private static functions
|
||||
34. Variable names should be noticeably unique from their types. For example, "str: string" instead
|
||||
37. Variable names should be noticeably unique from their types. For example, "str: string" instead
|
||||
of "string: string".
|
||||
35. Use double quotes to enclose strings. You may use single quotes if the string contains double quotes.
|
||||
38. Use double quotes to enclose strings. You may use single quotes if the string contains double quotes.
|
||||
|
||||
```typescript
|
||||
const example1 = "simple string";
|
||||
const example2 = 'string containing "double quotes"';
|
||||
```
|
||||
|
||||
36. Prefer async-await to promise-chaining
|
||||
39. Prefer async-await to promise-chaining
|
||||
|
||||
```typescript
|
||||
async function () {
|
||||
@@ -213,29 +282,21 @@ Unless otherwise specified, the following applies to all code:
|
||||
}
|
||||
```
|
||||
|
||||
37. Avoid functions whose fundamental behaviour varies with different parameter types.
|
||||
Multiple return types are fine, but if the function's behaviour is going to change significantly,
|
||||
have two separate functions. For example, `SDKConfig.get()` with a string param which returns the
|
||||
type according to the param given is ok, but `SDKConfig.get()` with no args returning the whole
|
||||
config object would not be: this should just be a separate function.
|
||||
|
||||
## React
|
||||
|
||||
Inheriting all the rules of TypeScript, the following additionally apply:
|
||||
|
||||
1. Component source files are named with upper camel case (e.g. views/rooms/EventTile.js)
|
||||
2. They are organised in a typically two-level hierarchy - first whether the component is a view or a structure, and then a broad functional grouping (e.g. 'rooms' here)
|
||||
3. Types for lifecycle functions are not required (render, componentDidMount, and so on).
|
||||
4. Class components must always have a `Props` interface declared immediately above them. It can be
|
||||
1. Types for lifecycle functions are not required (render, componentDidMount, and so on).
|
||||
2. Class components must always have a `Props` interface declared immediately above them. It can be
|
||||
empty if the component accepts no props.
|
||||
5. Class components should have an `State` interface declared immediately above them, but after `Props`.
|
||||
6. Props and State should not be exported. Use `React.ComponentProps<typeof ComponentNameHere>`
|
||||
3. Class components should have an `State` interface declared immediately above them, but after `Props`.
|
||||
4. Props and State should not be exported. Use `React.ComponentProps<typeof ComponentNameHere>`
|
||||
instead.
|
||||
7. One component per file, except when a component is a utility component specifically for the "primary"
|
||||
5. One component per file, except when a component is a utility component specifically for the "primary"
|
||||
component. The utility component should not be exported.
|
||||
8. Exported constants, enums, interfaces, functions, etc must be separate from files containing components
|
||||
6. Exported constants, enums, interfaces, functions, etc must be separate from files containing components
|
||||
or stores.
|
||||
9. Stores should use a singleton pattern with a static instance property:
|
||||
7. Stores should use a singleton pattern with a static instance property:
|
||||
|
||||
```typescript
|
||||
class FooStore {
|
||||
@@ -251,52 +312,82 @@ Inheriting all the rules of TypeScript, the following additionally apply:
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
10. Stores must support using an alternative MatrixClient and dispatcher instance.
|
||||
11. Utilities which require JSX must be split out from utilities which do not. This is to prevent import
|
||||
cycles during runtime where components accidentally include more of the app than they intended.
|
||||
12. Interdependence between stores should be kept to a minimum. Break functions and constants out to utilities
|
||||
8. Stores must support using an alternative MatrixClient and dispatcher instance.
|
||||
9. Utilities which require JSX must be split out from utilities which do not. This is to prevent import
|
||||
cycles during runtime where components accidentally include more of the app than they intended.
|
||||
10. Interdependence between stores should be kept to a minimum. Break functions and constants out to utilities
|
||||
if at all possible.
|
||||
13. A component should only use CSS class names in line with the component name.
|
||||
1. When knowingly using a class name from another component, document it with a [comment](#comments).
|
||||
11. A component should only use CSS class names in line with the component name.
|
||||
1. When knowingly using a class name from another component, document it.
|
||||
12. Break components over multiple lines like so:
|
||||
|
||||
14. Curly braces within JSX should be padded with a space, however properties on those components should not.
|
||||
```typescript
|
||||
function render() {
|
||||
return <Component
|
||||
prop1="test"
|
||||
prop2={this.state.variable}
|
||||
/>;
|
||||
|
||||
// or
|
||||
|
||||
return (
|
||||
<Component
|
||||
prop1="test"
|
||||
prop2={this.state.variable}
|
||||
/>
|
||||
);
|
||||
|
||||
// or if children are needed (infer parens usage)
|
||||
|
||||
return <Component
|
||||
prop1="test"
|
||||
prop2={this.state.variable}
|
||||
>{ _t("Short string here") }</Component>;
|
||||
|
||||
|
||||
|
||||
return <Component
|
||||
prop1="test"
|
||||
prop2={this.state.variable}
|
||||
>
|
||||
{ _t("Longer string here") }
|
||||
</Component>;
|
||||
}
|
||||
```
|
||||
13. Curly braces within JSX should be padded with a space, however properties on those components should not.
|
||||
See above code example.
|
||||
15. Functions used as properties should either be defined on the class or stored in a variable. They should not
|
||||
14. Functions used as properties should either be defined on the class or stored in a variable. They should not
|
||||
be inline unless mocking/short-circuiting the value.
|
||||
16. Prefer hooks (functional components) over class components. Be consistent with the existing area if unsure
|
||||
15. Prefer hooks (functional components) over class components. Be consistent with the existing area if unsure
|
||||
which should be used.
|
||||
1. Unless the component is considered a "structure", in which case use classes.
|
||||
17. Write more views than structures. Structures are chunks of functionality like MatrixChat while views are
|
||||
16. Write more views than structures. Structures are chunks of functionality like MatrixChat while views are
|
||||
isolated components.
|
||||
18. Components should serve a single, or near-single, purpose.
|
||||
19. Prefer to derive information from component properties rather than establish state.
|
||||
20. Do not use `React.Component::forceUpdate`.
|
||||
17. Components should serve a single, or near-single, purpose.
|
||||
18. Prefer to derive information from component properties rather than establish state.
|
||||
19. Do not use `React.Component::forceUpdate`.
|
||||
|
||||
## Stylesheets (\*.pcss = PostCSS + Plugins)
|
||||
|
||||
Note: We use PostCSS + some plugins to process our styles. It looks like SCSS, but actually it is not.
|
||||
|
||||
1. The view's CSS file MUST have the same name as the component (e.g. `view/rooms/_MessageTile.css` for `MessageTile.tsx` component).
|
||||
2. Per-view CSS is optional - it could choose to inherit all its styling from the context of the rest of the app, although this is unusual.
|
||||
3. Class names must be prefixed with "mx\_".
|
||||
4. Class names must strictly denote the component which defines them.
|
||||
For example: `mx_MyFoo` for `MyFoo` component.
|
||||
5. Class names for DOM elements within a view which aren't components are named by appending a lower camel case identifier to the view's class name - e.g. .mx_MyFoo_randomDiv is how you'd name the class of an arbitrary div within the MyFoo view.
|
||||
6. Use the `$font` variables instead of manual values.
|
||||
7. Keep indentation/nesting to a minimum. Maximum suggested nesting is 5 layers.
|
||||
8. Use the whole class name instead of shortcuts:
|
||||
1. Class names must be prefixed with "mx_".
|
||||
2. Class names should denote the component which defines them, followed by any context:
|
||||
1. mx_MyFoo
|
||||
2. mx_MyFoo_avatar
|
||||
3. mx_MyFoo_avatar--user
|
||||
3. Use the `$font` and `$spacing` variables instead of manual values.
|
||||
4. Keep indentation/nesting to a minimum. Maximum suggested nesting is 5 layers.
|
||||
5. Use the whole class name instead of shortcuts:
|
||||
|
||||
```scss
|
||||
.mx_MyFoo {
|
||||
& .mx_MyFoo_avatar {
|
||||
// instead of &_avatar
|
||||
& .mx_MyFoo_avatar { // instead of &_avatar
|
||||
// ...
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
9. Break multiple selectors over multiple lines this way:
|
||||
6. Break multiple selectors over multiple lines this way:
|
||||
|
||||
```scss
|
||||
.mx_MyFoo,
|
||||
@@ -305,10 +396,9 @@ Note: We use PostCSS + some plugins to process our styles. It looks like SCSS, b
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
10. Non-shared variables should use $lowerCamelCase. Shared variables use $dashed-naming.
|
||||
11. Overrides to Z indexes, adjustments of dimensions/padding with pixels, and so on should all be
|
||||
[documented](#comments) for what the values mean:
|
||||
7. Non-shared variables should use $lowerCamelCase. Shared variables use $dashed-naming.
|
||||
8. Overrides to Z indexes, adjustments of dimensions/padding with pixels, and so on should all be
|
||||
documented for what the values mean:
|
||||
|
||||
```scss
|
||||
.mx_MyFoo {
|
||||
@@ -317,10 +407,7 @@ Note: We use PostCSS + some plugins to process our styles. It looks like SCSS, b
|
||||
z-index: 10; // above user avatar, but below dialogs
|
||||
}
|
||||
```
|
||||
|
||||
12. Avoid the use of `!important`. If `!important` is necessary, add a [comment](#comments) explaining why.
|
||||
13. The CSS for a component can override the rules for child components. For instance, .mxRoomList .mx_RoomTile {} would be the selector to override styles of RoomTiles when viewed in the context of a RoomList view. Overrides must be scoped to the View's CSS class - i.e. don't just define .mx_RoomTile {} in RoomList.css - only RoomTile.css is allowed to define its own CSS. Instead, say .mx_RoomList .mx_RoomTile {} to scope the override only to the context of RoomList views. N.B. overrides should be relatively rare as in general CSS inheritance should be enough.
|
||||
14. Components should render only within the bounding box of their outermost DOM element. Page-absolute positioning and negative CSS margins and similar are generally not cool and stop the component from being reused easily in different places.
|
||||
9. Avoid the use of `!important`. If necessary, add a comment.
|
||||
|
||||
## Tests
|
||||
|
||||
@@ -344,7 +431,9 @@ Note: We use PostCSS + some plugins to process our styles. It looks like SCSS, b
|
||||
// Use "it should..." terminology
|
||||
it("should call the correct API", async () => {
|
||||
// test-specific variables go here
|
||||
|
||||
// function calls/state changes go here
|
||||
|
||||
// expectations go here
|
||||
});
|
||||
});
|
||||
@@ -364,37 +453,3 @@ Note: We use PostCSS + some plugins to process our styles. It looks like SCSS, b
|
||||
});
|
||||
});
|
||||
```
|
||||
|
||||
## Comments
|
||||
|
||||
1. As a general principle: be liberal with comments. This applies to all files: stylesheets as well as
|
||||
JavaScript/TypeScript.
|
||||
|
||||
Good comments not only help future readers understand and maintain the code; they can also encourage good design
|
||||
by clearly setting out how different parts of the codebase interact where that would otherwise be implicit and
|
||||
subject to interpretation.
|
||||
|
||||
2. Aim to document all types, methods, class properties, functions, etc, with [TSDoc](https://tsdoc.org/) doc comments.
|
||||
This is _especially_ important for public interfaces in `matrix-js-sdk`, but is good practice in general.
|
||||
|
||||
Even very simple interfaces can often benefit from a doc-comment, both as a matter of consistency, and because simple
|
||||
interfaces have a habit of becoming more complex over time.
|
||||
|
||||
3. React components should be documented in the same way as other classes or functions. The documentation should give
|
||||
a brief description of how the component should be used, and, especially for more complex components, each of its
|
||||
properties should be clearly documented.
|
||||
|
||||
4. Inside a function, there is no need to comment every line, but consider:
|
||||
- before a particular multiline section of code within the function, give an overview of what it does,
|
||||
to make it easier for a reader to follow the flow through the function as a whole.
|
||||
- if it is anything less than obvious, explain _why_ we are doing a particular operation, with particular emphasis
|
||||
on how this function interacts with other parts of the codebase.
|
||||
|
||||
5. When making changes to existing code, authors are expected to read existing comments and make any necessary changes
|
||||
to ensure they remain accurate.
|
||||
|
||||
6. Reviewers are encouraged to consider whether more comments would be useful, and to ask the author to add them.
|
||||
|
||||
It is natural for an author to feel that the code they have just written is "obvious" and that comments would be
|
||||
redundant, whereas in reality it would take some time for reader unfamiliar with the code to understand it. A
|
||||
reviewer is well-placed to make a more objective judgement.
|
||||
|
||||
@@ -1 +1,5 @@
|
||||
{}
|
||||
{
|
||||
"src/components/views/auth/AuthFooter.tsx": "src/components/views/auth/VectorAuthFooter.tsx",
|
||||
"src/components/views/auth/AuthHeaderLogo.tsx": "src/components/views/auth/VectorAuthHeaderLogo.tsx",
|
||||
"src/components/views/auth/AuthPage.tsx": "src/components/views/auth/VectorAuthPage.tsx"
|
||||
}
|
||||
|
||||
@@ -12,7 +12,6 @@
|
||||
"disable_guests": false,
|
||||
"disable_login_language_selector": false,
|
||||
"disable_3pid_login": false,
|
||||
"force_verification": false,
|
||||
"brand": "Element",
|
||||
"integrations_ui_url": "https://scalar.vector.im/",
|
||||
"integrations_rest_url": "https://scalar.vector.im/api",
|
||||
@@ -20,16 +19,20 @@
|
||||
"https://scalar.vector.im/_matrix/integrations/v1",
|
||||
"https://scalar.vector.im/api",
|
||||
"https://scalar-staging.vector.im/_matrix/integrations/v1",
|
||||
"https://scalar-staging.vector.im/api"
|
||||
"https://scalar-staging.vector.im/api",
|
||||
"https://scalar-staging.riot.im/scalar/api"
|
||||
],
|
||||
"default_widget_container_height": 280,
|
||||
"bug_report_endpoint_url": "https://element.io/bugreports/submit",
|
||||
"uisi_autorageshake_app": "element-auto-uisi",
|
||||
"default_country_code": "GB",
|
||||
"show_labs_settings": false,
|
||||
"features": {},
|
||||
"features": { },
|
||||
"default_federate": true,
|
||||
"default_theme": "light",
|
||||
"room_directory": {
|
||||
"servers": ["matrix.org"]
|
||||
"servers": [
|
||||
"matrix.org"
|
||||
]
|
||||
},
|
||||
"enable_presence_by_hs_url": {
|
||||
"https://matrix.org": false,
|
||||
|
||||
17
contribute.json
Normal file
17
contribute.json
Normal file
@@ -0,0 +1,17 @@
|
||||
{
|
||||
"name": "Element",
|
||||
"description": "A glossy Matrix collaboration client for the web.",
|
||||
"repository": {
|
||||
"url": "https://github.com/vector-im/element-web",
|
||||
"license": "Apache License 2.0"
|
||||
},
|
||||
"bugs": {
|
||||
"list": "https://github.com/vector-im/element-web/issues",
|
||||
"report": "https://github.com/vector-im/element-web/issues/new/choose"
|
||||
},
|
||||
"keywords": [
|
||||
"chat",
|
||||
"riot",
|
||||
"matrix"
|
||||
]
|
||||
}
|
||||
2
debian/.gitignore
vendored
2
debian/.gitignore
vendored
@@ -1,2 +0,0 @@
|
||||
/files
|
||||
/tmp
|
||||
1
debian/conffiles
vendored
1
debian/conffiles
vendored
@@ -1 +0,0 @@
|
||||
/etc/element-web/config.json
|
||||
13
debian/control
vendored
13
debian/control
vendored
@@ -1,13 +0,0 @@
|
||||
Source: element-web
|
||||
Maintainer: support@element.io
|
||||
Section: web
|
||||
Priority: optional
|
||||
Homepage: https://element.io/
|
||||
|
||||
Package: element-web
|
||||
Architecture: all
|
||||
Recommends: httpd, element-io-archive-keyring
|
||||
Description:
|
||||
Element: the future of secure communication
|
||||
This package contains the web-based client that can be served through a web
|
||||
server.
|
||||
8
declaration.d.ts
vendored
8
declaration.d.ts
vendored
@@ -1,8 +0,0 @@
|
||||
/*
|
||||
* Copyright 2025 New Vector Ltd.
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Commercial
|
||||
* Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
declare module "*.module.css";
|
||||
@@ -1,126 +0,0 @@
|
||||
# Developer Guide
|
||||
|
||||
## Development
|
||||
|
||||
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.
|
||||
|
||||
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 [`docs/playwright.md`](./docs/playwright.md) for how to run the end-to-end tests.
|
||||
|
||||
## General github guidelines
|
||||
|
||||
1. **Pull requests must only be filed against the `develop` branch.**
|
||||
2. Try to keep your pull requests concise. Split them up if necessary.
|
||||
3. Ensure that you provide a description that explains the fix/feature and its intent.
|
||||
|
||||
## Adding new code
|
||||
|
||||
New code should be committed as follows:
|
||||
|
||||
- All new components: https://github.com/element-hq/element-web/tree/develop/src/components
|
||||
- CSS: https://github.com/element-hq/element-web/tree/develop/res/css
|
||||
- Theme specific CSS & resources: https://github.com/element-hq/element-web/tree/develop/res/themes
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user