Compare commits
1 commit
develop
...
t3chguy/no
Author | SHA1 | Date | |
---|---|---|---|
|
a52d4aed9f |
309 changed files with 24292 additions and 30640 deletions
|
@ -23,7 +23,7 @@ indent_size = 4
|
|||
trim_trailing_whitespace = true
|
||||
|
||||
[*.{yml,yaml}]
|
||||
indent_size = 4
|
||||
indent_size = 2
|
||||
|
||||
[package.json]
|
||||
indent_size = 2
|
||||
|
|
|
@ -1,72 +0,0 @@
|
|||
module.exports = {
|
||||
plugins: ["matrix-org"],
|
||||
extends: ["./.eslintrc.js"],
|
||||
parserOptions: {
|
||||
project: ["./tsconfig.module_system.json"],
|
||||
},
|
||||
overrides: [
|
||||
{
|
||||
files: ["module_system/**/*.{ts,tsx}"],
|
||||
extends: ["plugin:matrix-org/typescript", "plugin:matrix-org/react"],
|
||||
// NOTE: These rules are frozen and new rules should not be added here.
|
||||
// New changes belong in https://github.com/matrix-org/eslint-plugin-matrix-org/
|
||||
rules: {
|
||||
// Things we do that break the ideal style
|
||||
"prefer-promise-reject-errors": "off",
|
||||
"quotes": "off",
|
||||
|
||||
// We disable this while we're transitioning
|
||||
"@typescript-eslint/no-explicit-any": "off",
|
||||
// We're okay with assertion errors when we ask for them
|
||||
"@typescript-eslint/no-non-null-assertion": "off",
|
||||
|
||||
// Ban matrix-js-sdk/src imports in favour of matrix-js-sdk/src/matrix imports to prevent unleashing hell.
|
||||
"no-restricted-imports": [
|
||||
"error",
|
||||
{
|
||||
paths: [
|
||||
{
|
||||
name: "matrix-js-sdk",
|
||||
message: "Please use matrix-js-sdk/src/matrix instead",
|
||||
},
|
||||
{
|
||||
name: "matrix-js-sdk/",
|
||||
message: "Please use matrix-js-sdk/src/matrix instead",
|
||||
},
|
||||
{
|
||||
name: "matrix-js-sdk/src",
|
||||
message: "Please use matrix-js-sdk/src/matrix instead",
|
||||
},
|
||||
{
|
||||
name: "matrix-js-sdk/src/",
|
||||
message: "Please use matrix-js-sdk/src/matrix instead",
|
||||
},
|
||||
{
|
||||
name: "matrix-js-sdk/src/index",
|
||||
message: "Please use matrix-js-sdk/src/matrix instead",
|
||||
},
|
||||
{
|
||||
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",
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
135
.eslintrc.js
135
.eslintrc.js
|
@ -1,95 +1,72 @@
|
|||
module.exports = {
|
||||
plugins: ["matrix-org"],
|
||||
extends: ["plugin:matrix-org/babel", "plugin:matrix-org/react"],
|
||||
parserOptions: {
|
||||
project: ["./tsconfig.json"],
|
||||
},
|
||||
extends: [
|
||||
"plugin:matrix-org/babel",
|
||||
"plugin:matrix-org/react",
|
||||
],
|
||||
env: {
|
||||
browser: true,
|
||||
node: true,
|
||||
},
|
||||
rules: {
|
||||
// Things we do that break the ideal style
|
||||
quotes: "off",
|
||||
"quotes": "off",
|
||||
},
|
||||
settings: {
|
||||
react: {
|
||||
version: "detect",
|
||||
},
|
||||
version: 'detect'
|
||||
}
|
||||
},
|
||||
overrides: [
|
||||
{
|
||||
files: ["src/**/*.{ts,tsx}", "test/**/*.{ts,tsx}", "scripts/*.ts"],
|
||||
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",
|
||||
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",
|
||||
// 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",
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
// 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",
|
||||
}],
|
||||
}],
|
||||
},
|
||||
{
|
||||
files: ["test/**/*.{ts,tsx}"],
|
||||
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/ban-ts-comment": "off",
|
||||
"@typescript-eslint/no-floating-promises": "off",
|
||||
},
|
||||
},
|
||||
],
|
||||
}],
|
||||
};
|
||||
|
|
|
@ -1,2 +0,0 @@
|
|||
# prettier
|
||||
7921a6cbf86b035d2b0c1daecb4c24beaf5a5abc
|
6
.github/CODEOWNERS
vendored
6
.github/CODEOWNERS
vendored
|
@ -1,5 +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/i18n/strings
|
||||
* @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.
|
||||
- [ ] Sign-off given on the changes (see [CONTRIBUTING.md](https://github.com/element-hq/element-web/blob/develop/CONTRIBUTING.md)).
|
||||
* [ ] 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
|
||||
-->
|
||||
|
|
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
|
266
.github/labels.yml
vendored
266
.github/labels.yml
vendored
|
@ -1,266 +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: "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-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-react-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"
|
||||
]
|
||||
}
|
||||
|
|
52
.github/workflows/backport.yml
vendored
52
.github/workflows/backport.yml
vendored
|
@ -1,30 +1,30 @@
|
|||
name: Backport
|
||||
on:
|
||||
pull_request_target:
|
||||
types:
|
||||
- closed
|
||||
- labeled
|
||||
branches:
|
||||
- develop
|
||||
pull_request_target:
|
||||
types:
|
||||
- closed
|
||||
- labeled
|
||||
branches:
|
||||
- develop
|
||||
|
||||
jobs:
|
||||
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@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 }}
|
||||
|
|
60
.github/workflows/build.yml
vendored
60
.github/workflows/build.yml
vendored
|
@ -1,49 +1,27 @@
|
|||
name: Build
|
||||
on:
|
||||
pull_request: {}
|
||||
push:
|
||||
branches: [develop, master]
|
||||
merge_group:
|
||||
types: [checks_requested]
|
||||
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 }}
|
||||
# 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-latest
|
||||
- windows-latest
|
||||
- macos-latest
|
||||
isDevelop:
|
||||
- ${{ github.event_name == 'push' && github.ref_name == 'develop' }}
|
||||
# Skip the ubuntu-latest build for the develop branch as the dedicated CD build_develop workflow handles that
|
||||
exclude:
|
||||
- isDevelop: true
|
||||
image: ubuntu-latest
|
||||
runs-on: ${{ matrix.image }}
|
||||
defaults:
|
||||
run:
|
||||
shell: bash
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
build:
|
||||
name: "Build"
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
|
||||
- uses: actions/setup-node@v4
|
||||
with:
|
||||
cache: "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: Install Dependencies
|
||||
run: "./scripts/layered.sh"
|
||||
|
||||
- name: Build
|
||||
run: "yarn build"
|
||||
- name: Build
|
||||
run: "yarn build"
|
||||
|
|
78
.github/workflows/build_debian.yaml
vendored
78
.github/workflows/build_debian.yaml
vendored
|
@ -1,78 +0,0 @@
|
|||
name: Build Debian package
|
||||
on:
|
||||
release:
|
||||
types: [published]
|
||||
concurrency: ${{ github.workflow }}
|
||||
jobs:
|
||||
build:
|
||||
name: Build package
|
||||
environment: packages.element.io
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
R2_INCOMING_BUCKET: ${{ vars.R2_INCOMING_BUCKET }}
|
||||
R2_URL: ${{ vars.CF_R2_S3_API }}
|
||||
VERSION: ${{ github.ref_name }}
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- 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@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 }}
|
168
.github/workflows/build_develop.yml
vendored
168
.github/workflows/build_develop.yml
vendored
|
@ -1,126 +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
|
||||
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-latest
|
||||
environment: develop
|
||||
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@v4
|
||||
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@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@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.
|
||||
- name: Deploy to R2
|
||||
run: |
|
||||
aws s3 cp dist/develop.tar.gz s3://$R2_BUCKET/develop.tar.gz --endpoint-url $R2_URL --region=auto
|
||||
aws s3 cp _deploy/ s3://$R2_BUCKET/ --recursive --endpoint-url $R2_URL --region=auto
|
||||
env:
|
||||
AWS_ACCESS_KEY_ID: ${{ secrets.CF_R2_ACCESS_KEY_ID }}
|
||||
AWS_SECRET_ACCESS_KEY: ${{ secrets.CF_R2_TOKEN }}
|
||||
|
||||
- name: Deploy to Cloudflare Pages
|
||||
id: cfp
|
||||
uses: cloudflare/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).)*$
|
||||
|
|
137
.github/workflows/dockerhub.yaml
vendored
137
.github/workflows/dockerhub.yaml
vendored
|
@ -1,94 +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.workflow }}-${{ github.ref_name }}
|
||||
|
||||
permissions:
|
||||
id-token: write # needed for signing the images with GitHub OIDC Token
|
||||
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
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- variant: vanilla
|
||||
# Variant we ship to aid ESS in providing a build on the OpenCoDE platform including specific modules
|
||||
- variant: opendesk
|
||||
flavor: suffix=-opendesk,onlatest=true
|
||||
prepare: mv variants/openDesk/* .
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0 # needed for docker-package to be able to calculate the version
|
||||
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: Install Cosign
|
||||
uses: sigstore/cosign-installer@59acb6260d9c0ba8f4a2f9d9b48431a222b68e20 # v3
|
||||
- name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v1
|
||||
|
||||
- name: Prepare
|
||||
if: matrix.prepare
|
||||
run: ${{ matrix.prepare }}
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v2
|
||||
with:
|
||||
install: true
|
||||
|
||||
- name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@49b3bc8e6bdd4a60e6116a5414239cba5943d3cf # v3
|
||||
- name: Login to Docker Hub
|
||||
uses: docker/login-action@v1
|
||||
with:
|
||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@aa33708b10e362ff993539393ff100fa93ed6a27 # v3
|
||||
with:
|
||||
install: true
|
||||
- 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: Login to Docker Hub
|
||||
uses: docker/login-action@9780b0c442fbb1117ed29e0efdff1e18412f7567 # v3
|
||||
with:
|
||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||
- 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: Docker meta
|
||||
id: meta
|
||||
uses: docker/metadata-action@8e5442c4ef9f78752691e2d8f8d19755c6f78e81 # v5
|
||||
with:
|
||||
images: |
|
||||
vectorim/element-web
|
||||
tags: |
|
||||
type=ref,event=branch
|
||||
type=ref,event=tag
|
||||
flavor: |
|
||||
latest=${{ contains(github.ref_name, '-rc.') && 'false' || 'auto' }}
|
||||
${{ matrix.flavor }}
|
||||
|
||||
- name: Build and push
|
||||
id: build-and-push
|
||||
uses: docker/build-push-action@5176d81f87c23d6fc96624dfdbcd9f3830bbe445 # v6
|
||||
with:
|
||||
context: .
|
||||
push: true
|
||||
platforms: linux/amd64,linux/arm64
|
||||
tags: ${{ steps.meta.outputs.tags }}
|
||||
labels: ${{ steps.meta.outputs.labels }}
|
||||
|
||||
- name: Sign the images with GitHub OIDC Token
|
||||
env:
|
||||
DIGEST: ${{ steps.build-and-push.outputs.digest }}
|
||||
TAGS: ${{ steps.meta.outputs.tags }}
|
||||
run: |
|
||||
images=""
|
||||
for tag in ${TAGS}; do
|
||||
images+="${tag}@${DIGEST} "
|
||||
done
|
||||
cosign sign --yes ${images}
|
||||
|
||||
- name: Update repo description
|
||||
if: matrix.variant == 'vanilla'
|
||||
uses: peter-evans/dockerhub-description@e98e4d1628a5f3be2be7c231e50981aee98723ae # v4
|
||||
continue-on-error: true
|
||||
with:
|
||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||
repository: vectorim/element-web
|
||||
- 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
|
||||
|
|
116
.github/workflows/docs.yml
vendored
116
.github/workflows/docs.yml
vendored
|
@ -1,116 +0,0 @@
|
|||
name: Deploy documentation
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [develop]
|
||||
workflow_dispatch: {}
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
pages: write
|
||||
id-token: write
|
||||
|
||||
concurrency:
|
||||
group: "pages"
|
||||
cancel-in-progress: false
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: GitHub Pages
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Fetch element-desktop
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
repository: element-hq/element-desktop
|
||||
path: element-desktop
|
||||
|
||||
- name: Fetch element-web
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
path: element-web
|
||||
|
||||
- name: Fetch matrix-react-sdk
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
repository: matrix-org/matrix-react-sdk
|
||||
path: matrix-react-sdk
|
||||
|
||||
- name: Fetch matrix-js-sdk
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
repository: matrix-org/matrix-js-sdk
|
||||
path: matrix-js-sdk
|
||||
|
||||
- uses: actions/setup-node@v4
|
||||
with:
|
||||
cache: "yarn"
|
||||
cache-dependency-path: element-web/yarn.lock
|
||||
node-version: "lts/*"
|
||||
|
||||
- name: 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-react-sdk ../matrix-js-sdk > docs/automations.md
|
||||
echo "- [Automations](automations.md)" >> docs/SUMMARY.md
|
||||
|
||||
- name: Setup mdBook
|
||||
uses: peaceiris/actions-mdbook@v2
|
||||
with:
|
||||
mdbook-version: "0.4.10"
|
||||
|
||||
- name: Install mdbook extensions
|
||||
run: cargo install mdbook-combiner mdbook-mermaid
|
||||
|
||||
- name: Prepare docs
|
||||
run: |
|
||||
mkdir docs
|
||||
|
||||
mv element-desktop/README.md element-desktop/docs/
|
||||
mv element-desktop/docs "docs/Element Desktop"
|
||||
|
||||
mv element-web/README.md element-web/docs/
|
||||
mv element-web/docs/lib docs/
|
||||
mv element-web/docs "docs/Element Web"
|
||||
|
||||
mv matrix-react-sdk/README.md matrix-react-sdk/docs/
|
||||
mv matrix-react-sdk/docs "docs/Matrix React SDK"
|
||||
|
||||
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@v3
|
||||
with:
|
||||
path: ./book
|
||||
|
||||
deploy:
|
||||
environment:
|
||||
name: github-pages
|
||||
url: ${{ steps.deployment.outputs.page_url }}
|
||||
runs-on: ubuntu-latest
|
||||
needs: build
|
||||
steps:
|
||||
- name: Deploy to GitHub Pages
|
||||
id: deployment
|
||||
uses: actions/deploy-pages@v4
|
29
.github/workflows/end-to-end-tests.yaml
vendored
29
.github/workflows/end-to-end-tests.yaml
vendored
|
@ -1,29 +0,0 @@
|
|||
# Triggers after the "Downstream artifacts" build has finished, to run the
|
||||
# matrix-react-sdk playwright tests (with access to repo secrets)
|
||||
|
||||
name: matrix-react-sdk End to End Tests
|
||||
on:
|
||||
merge_group:
|
||||
types: [checks_requested]
|
||||
pull_request: {}
|
||||
push:
|
||||
branches: [develop, master]
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.event.workflow_run.head_branch || github.run_id }}
|
||||
cancel-in-progress: ${{ github.event.workflow_run.event == 'pull_request' }}
|
||||
|
||||
jobs:
|
||||
playwright:
|
||||
name: Playwright
|
||||
uses: matrix-org/matrix-react-sdk/.github/workflows/end-to-end-tests.yaml@develop
|
||||
permissions:
|
||||
actions: read
|
||||
issues: read
|
||||
pull-requests: read
|
||||
with:
|
||||
element-web-sha: ${{ github.sha }}
|
||||
react-sdk-repository: matrix-org/matrix-react-sdk
|
||||
# We only want to run the playwright tests on merge queue to prevent regressions
|
||||
# from creeping in. They take a long time to run and consume multiple concurrent runners.
|
||||
skip: ${{ github.event_name != 'merge_group' }}
|
278
.github/workflows/issue_closed.yml
vendored
278
.github/workflows/issue_closed.yml
vendored
|
@ -2,155 +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]
|
||||
issues:
|
||||
types: [ closed ]
|
||||
jobs:
|
||||
tidy:
|
||||
name: Tidy closed issues
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/github-script@v7
|
||||
id: main
|
||||
with:
|
||||
# PAT needed as the GITHUB_TOKEN won't be able to see cross-references from other orgs (matrix-org)
|
||||
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@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,
|
||||
});
|
||||
|
|
10
.github/workflows/localazy_download.yaml
vendored
10
.github/workflows/localazy_download.yaml
vendored
|
@ -1,10 +0,0 @@
|
|||
name: Localazy Download
|
||||
on:
|
||||
workflow_dispatch: {}
|
||||
schedule:
|
||||
- cron: "0 6 * * 1,3,5" # Every Monday, Wednesday and Friday at 6am UTC
|
||||
jobs:
|
||||
download:
|
||||
uses: matrix-org/matrix-web-i18n/.github/workflows/localazy_download.yaml@main
|
||||
secrets:
|
||||
ELEMENT_BOT_TOKEN: ${{ secrets.ELEMENT_BOT_TOKEN }}
|
11
.github/workflows/localazy_upload.yaml
vendored
11
.github/workflows/localazy_upload.yaml
vendored
|
@ -1,11 +0,0 @@
|
|||
name: Localazy Upload
|
||||
on:
|
||||
push:
|
||||
branches: [develop]
|
||||
paths:
|
||||
- "src/i18n/strings/en_EN.json"
|
||||
jobs:
|
||||
upload:
|
||||
uses: matrix-org/matrix-web-i18n/.github/workflows/localazy_upload.yaml@main
|
||||
secrets:
|
||||
LOCALAZY_WRITE_KEY: ${{ secrets.LOCALAZY_WRITE_KEY }}
|
90
.github/workflows/pending-reviews.yaml
vendored
90
.github/workflows/pending-reviews.yaml
vendored
|
@ -1,90 +0,0 @@
|
|||
name: Pending reviews automation
|
||||
on:
|
||||
# We run it on a schedule instead of on pull_request_* events to not create confusing messaging in the PR
|
||||
schedule:
|
||||
- cron: "*/10 * * * *"
|
||||
concurrency: ${{ github.workflow }}
|
||||
jobs:
|
||||
bot:
|
||||
name: Pending reviews bot
|
||||
runs-on: ubuntu-latest
|
||||
environment: Matrix
|
||||
env:
|
||||
URL: "https://github.com/pulls?q=is%3Apr+is%3Aopen+repo%3Amatrix-org%2Fmatrix-js-sdk+repo%3Amatrix-org%2Fmatrix-react-sdk+repo%3Aelement-hq%2Felement-web+repo%3Aelement-hq%2Felement-desktop+review-requested%3A%40me+sort%3Aupdated-desc+"
|
||||
RELEASE_BLOCKERS_URL: "https://github.com/pulls?q=is%3Aopen+repo%3Amatrix-org%2Fmatrix-js-sdk+repo%3Amatrix-org%2Fmatrix-react-sdk+repo%3Aelement-hq%2Felement-web+repo%3Aelement-hq%2Felement-desktop+sort%3Aupdated-desc+label%3AX-Release-Blocker+"
|
||||
steps:
|
||||
- uses: actions/github-script@v7
|
||||
env:
|
||||
HS_URL: ${{ secrets.BETABOT_HS_URL }}
|
||||
ROOM_ID: ${{ secrets.ROOM_ID }}
|
||||
TOKEN: ${{ secrets.BETABOT_ACCESS_TOKEN }}
|
||||
with:
|
||||
# PAT needed as the GITHUB_TOKEN won't be able to see cross-references from other orgs (matrix-org)
|
||||
github-token: ${{ secrets.ELEMENT_BOT_TOKEN }}
|
||||
script: |
|
||||
const { HS_URL, ROOM_ID, TOKEN, URL, RELEASE_BLOCKERS_URL } = process.env;
|
||||
|
||||
async function updateCounter(counter, link, severity, title, value, clearOnZero) {
|
||||
const apiUrl = `${HS_URL}/_matrix/client/v3/rooms/${ROOM_ID}/state/re.jki.counter/${counter}`;
|
||||
const headers = {
|
||||
"Content-Type": "application/json",
|
||||
"Authorization": `Bearer ${TOKEN}`,
|
||||
};
|
||||
const res = await fetch(apiUrl, {
|
||||
method: "GET",
|
||||
headers,
|
||||
});
|
||||
|
||||
const data = await res.json();
|
||||
|
||||
if (data.value === issueCount) {
|
||||
console.log("Pending review count already correct");
|
||||
return;
|
||||
}
|
||||
|
||||
let body = {};
|
||||
if (issueCount || !clearOnZero) {
|
||||
body = JSON.stringify({
|
||||
link,
|
||||
severity,
|
||||
title,
|
||||
value,
|
||||
});
|
||||
}
|
||||
|
||||
await fetch(apiUrl, {
|
||||
method: "PUT",
|
||||
body,
|
||||
headers,
|
||||
});
|
||||
}
|
||||
|
||||
const repos = [
|
||||
"element-hq/element-desktop",
|
||||
"element-hq/element-web",
|
||||
"matrix-org/matrix-react-sdk",
|
||||
"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);
|
17
.github/workflows/pull_request.yaml
vendored
17
.github/workflows/pull_request.yaml
vendored
|
@ -1,11 +1,12 @@
|
|||
name: Pull Request
|
||||
on:
|
||||
pull_request_target:
|
||||
types: [opened, edited, labeled, unlabeled, synchronize]
|
||||
merge_group:
|
||||
types: [checks_requested]
|
||||
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
|
||||
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 }}
|
||||
|
|
11
.github/workflows/release-drafter.yml
vendored
11
.github/workflows/release-drafter.yml
vendored
|
@ -1,11 +0,0 @@
|
|||
name: Release Drafter
|
||||
on:
|
||||
push:
|
||||
branches: [staging]
|
||||
workflow_dispatch: {}
|
||||
concurrency: ${{ github.workflow }}
|
||||
jobs:
|
||||
draft:
|
||||
uses: matrix-org/matrix-js-sdk/.github/workflows/release-drafter-workflow.yml@develop
|
||||
with:
|
||||
include-changes: matrix-react-sdk
|
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 }}
|
||||
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-react-sdk
|
||||
matrix-js-sdk
|
62
.github/workflows/release.yml
vendored
62
.github/workflows/release.yml
vendored
|
@ -1,62 +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 }}
|
||||
jobs:
|
||||
release:
|
||||
uses: matrix-org/matrix-js-sdk/.github/workflows/release-make.yml@develop
|
||||
secrets:
|
||||
ELEMENT_BOT_TOKEN: ${{ secrets.ELEMENT_BOT_TOKEN }}
|
||||
GPG_PRIVATE_KEY: ${{ secrets.GPG_PRIVATE_KEY }}
|
||||
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-latest
|
||||
steps:
|
||||
- name: Notify element-desktop repo that element-web release has completed to re-trigger release-drafter
|
||||
uses: benc-uk/workflow-dispatch@25b02cc069be46d637e8fe2f1e8484008e9e9609 # 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-latest
|
||||
steps:
|
||||
- name: Wait for dockerhub
|
||||
uses: t3chguy/wait-on-check-action@18541021811b56544d90e0f073401c2b99e249d6 # fork
|
||||
with:
|
||||
ref: master
|
||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
wait-interval: 10
|
||||
check-name: "Docker Buildx (vanilla)"
|
||||
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
|
124
.github/workflows/release_prepare.yml
vendored
124
.github/workflows/release_prepare.yml
vendored
|
@ -1,124 +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-react-sdk:
|
||||
description: Prepare matrix-react-sdk
|
||||
required: true
|
||||
type: boolean
|
||||
default: true
|
||||
matrix-js-sdk:
|
||||
description: Prepare matrix-js-sdk
|
||||
required: true
|
||||
type: boolean
|
||||
default: true
|
||||
jobs:
|
||||
prepare:
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
# The order is specified bottom-up to avoid any races for allchange
|
||||
REPOS: matrix-js-sdk matrix-react-sdk element-web element-desktop
|
||||
steps:
|
||||
- name: Checkout Element Desktop
|
||||
uses: actions/checkout@v4
|
||||
if: inputs.element-desktop
|
||||
with:
|
||||
repository: element-hq/element-desktop
|
||||
path: element-desktop
|
||||
ref: staging
|
||||
fetch-depth: 0
|
||||
fetch-tags: true
|
||||
token: ${{ secrets.ELEMENT_BOT_TOKEN }}
|
||||
- name: Checkout Element Web
|
||||
uses: actions/checkout@v4
|
||||
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 React SDK
|
||||
uses: actions/checkout@v4
|
||||
if: inputs.matrix-react-sdk
|
||||
with:
|
||||
repository: matrix-org/matrix-react-sdk
|
||||
path: matrix-react-sdk
|
||||
ref: staging
|
||||
fetch-depth: 0
|
||||
fetch-tags: true
|
||||
token: ${{ secrets.ELEMENT_BOT_TOKEN }}
|
||||
- name: Checkout Matrix JS SDK
|
||||
uses: actions/checkout@v4
|
||||
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: Merge develop
|
||||
run: |
|
||||
git config --global user.email "releases@riot.im"
|
||||
git config --global user.name "RiotRobot"
|
||||
for REPO in $REPOS; do [ -d "$REPO" ] && git -C "$REPO" merge origin/develop; done
|
||||
|
||||
- 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
|
||||
allowed-conclusions: success
|
||||
|
||||
- name: Wait for matrix-react-sdk draft
|
||||
if: inputs.matrix-react-sdk
|
||||
uses: t3chguy/wait-on-check-action@18541021811b56544d90e0f073401c2b99e249d6 # fork
|
||||
with:
|
||||
ref: staging
|
||||
repo: matrix-org/matrix-react-sdk
|
||||
repo-token: ${{ secrets.ELEMENT_BOT_TOKEN }}
|
||||
wait-interval: 10
|
||||
check-name: 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
|
||||
allowed-conclusions: success
|
||||
|
||||
- name: Wait for element-desktop draft
|
||||
if: inputs.element-desktop
|
||||
uses: t3chguy/wait-on-check-action@18541021811b56544d90e0f073401c2b99e249d6 # fork
|
||||
with:
|
||||
ref: staging
|
||||
repo: element-hq/element-desktop
|
||||
repo-token: ${{ secrets.ELEMENT_BOT_TOKEN }}
|
||||
wait-interval: 10
|
||||
check-name: draft
|
||||
allowed-conclusions: success
|
23
.github/workflows/sonarqube.yml
vendored
23
.github/workflows/sonarqube.yml
vendored
|
@ -1,16 +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
|
||||
group: ${{ github.workflow }}-${{ github.event.workflow_run.head_branch }}
|
||||
cancel-in-progress: true
|
||||
jobs:
|
||||
sonarqube:
|
||||
name: 🩻 SonarQube
|
||||
uses: matrix-org/matrix-js-sdk/.github/workflows/sonarcloud.yml@develop
|
||||
secrets:
|
||||
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
|
||||
ELEMENT_BOT_TOKEN: ${{ secrets.ELEMENT_BOT_TOKEN }}
|
||||
sonarqube:
|
||||
name: 🩻 SonarQube
|
||||
uses: matrix-org/matrix-js-sdk/.github/workflows/sonarcloud.yml@develop
|
||||
secrets:
|
||||
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
|
||||
|
|
150
.github/workflows/static_analysis.yaml
vendored
150
.github/workflows/static_analysis.yaml
vendored
|
@ -1,107 +1,85 @@
|
|||
name: Static Analysis
|
||||
on:
|
||||
pull_request: {}
|
||||
push:
|
||||
branches: [develop, master]
|
||||
merge_group:
|
||||
types: [checks_requested]
|
||||
repository_dispatch:
|
||||
types: [element-web-notify]
|
||||
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 }}
|
||||
# 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-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
ts_lint:
|
||||
name: "Typescript Syntax Check"
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
|
||||
- uses: actions/setup-node@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
|
||||
- uses: actions/setup-node@v3
|
||||
with:
|
||||
hardcoded-words: "Element"
|
||||
cache: 'yarn'
|
||||
node-version: 16
|
||||
|
||||
js_lint:
|
||||
name: "ESLint"
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Install Dependencies
|
||||
run: "./scripts/layered.sh"
|
||||
|
||||
- uses: actions/setup-node@v4
|
||||
with:
|
||||
cache: "yarn"
|
||||
node-version: "lts/*"
|
||||
- name: Typecheck
|
||||
run: "yarn run lint:types"
|
||||
|
||||
# Does not need branch matching as only analyses this layer
|
||||
- name: Install Deps
|
||||
run: "yarn install --frozen-lockfile"
|
||||
i18n_lint:
|
||||
name: "i18n Check"
|
||||
uses: matrix-org/matrix-react-sdk/.github/workflows/i18n_check.yml@develop
|
||||
|
||||
- name: Run Linter
|
||||
run: "yarn run lint:js"
|
||||
js_lint:
|
||||
name: "ESLint"
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
|
||||
style_lint:
|
||||
name: "Style Lint"
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-node@v3
|
||||
with:
|
||||
cache: 'yarn'
|
||||
node-version: 16
|
||||
|
||||
- uses: actions/setup-node@v4
|
||||
with:
|
||||
cache: "yarn"
|
||||
node-version: "lts/*"
|
||||
# Does not need branch matching as only analyses this layer
|
||||
- name: Install Deps
|
||||
run: "yarn install --pure-lockfile"
|
||||
|
||||
# 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:js"
|
||||
|
||||
- name: Run Linter
|
||||
run: "yarn run lint:style"
|
||||
style_lint:
|
||||
name: "Style Lint"
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
|
||||
workflow_lint:
|
||||
name: "Workflow Lint"
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-node@v3
|
||||
with:
|
||||
cache: 'yarn'
|
||||
node-version: 16
|
||||
|
||||
- uses: actions/setup-node@v4
|
||||
with:
|
||||
cache: "yarn"
|
||||
node-version: "lts/*"
|
||||
# Needs branch matching as it inherits .stylelintrc.js from matrix-react-sdk
|
||||
- name: Install Dependencies
|
||||
run: "./scripts/layered.sh"
|
||||
|
||||
# Does not need branch matching as only analyses this layer
|
||||
- name: Install Deps
|
||||
run: "yarn install --frozen-lockfile"
|
||||
- name: Run Linter
|
||||
run: "yarn run lint:style"
|
||||
|
||||
- name: Run Linter
|
||||
run: "yarn lint:workflows"
|
||||
analyse_dead_code:
|
||||
name: "Analyse Dead Code"
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
|
||||
analyse_dead_code:
|
||||
name: "Analyse Dead Code"
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-node@v3
|
||||
with:
|
||||
cache: 'yarn'
|
||||
node-version: 16
|
||||
|
||||
- uses: actions/setup-node@v4
|
||||
with:
|
||||
cache: "yarn"
|
||||
node-version: "lts/*"
|
||||
- name: Install Deps
|
||||
run: "scripts/layered.sh"
|
||||
|
||||
- name: Install Deps
|
||||
run: "scripts/layered.sh"
|
||||
|
||||
- name: Dead Code Analysis
|
||||
run: "yarn run analyse:unused-exports"
|
||||
- name: Dead Code Analysis
|
||||
run: "yarn run analyse:unused-exports"
|
||||
|
|
21
.github/workflows/sync-labels.yml
vendored
21
.github/workflows/sync-labels.yml
vendored
|
@ -1,21 +0,0 @@
|
|||
name: Sync labels
|
||||
on:
|
||||
workflow_dispatch: {}
|
||||
schedule:
|
||||
- cron: "0 1 * * *" # 1am every day
|
||||
push:
|
||||
branches:
|
||||
- develop
|
||||
paths:
|
||||
- .github/labels.yml
|
||||
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 }}
|
82
.github/workflows/tests.yaml
vendored
82
.github/workflows/tests.yaml
vendored
|
@ -1,60 +1,38 @@
|
|||
name: Tests
|
||||
on:
|
||||
pull_request: {}
|
||||
push:
|
||||
branches: [develop, master]
|
||||
merge_group:
|
||||
types: [checks_requested]
|
||||
repository_dispatch:
|
||||
types: [element-web-notify]
|
||||
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 }}
|
||||
# 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@v4
|
||||
jest:
|
||||
name: Jest
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Yarn cache
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
cache: "yarn"
|
||||
node-version: "lts/*"
|
||||
- name: Yarn cache
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
cache: 'yarn'
|
||||
node-version: 16
|
||||
|
||||
- name: Install Dependencies
|
||||
run: "./scripts/layered.sh"
|
||||
- name: Install Dependencies
|
||||
run: "./scripts/layered.sh"
|
||||
|
||||
- name: Get number of CPU cores
|
||||
id: cpu-cores
|
||||
uses: SimenB/github-actions-cpu-cores@97ba232459a8e02ff6121db9362b09661c875ab8 # v2
|
||||
- name: Run tests with coverage
|
||||
run: "yarn coverage --ci"
|
||||
|
||||
- name: Run tests with coverage
|
||||
run: "yarn coverage --ci --max-workers ${{ steps.cpu-cores.outputs.count }}"
|
||||
|
||||
- name: Upload Artifact
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: coverage
|
||||
path: |
|
||||
coverage
|
||||
!coverage/lcov-report
|
||||
|
||||
skip_sonar:
|
||||
name: Skip SonarCloud in merge queue
|
||||
if: github.event_name == 'merge_group'
|
||||
runs-on: ubuntu-latest
|
||||
needs: jest
|
||||
steps:
|
||||
- name: Skip SonarCloud
|
||||
uses: Sibz/github-status-action@faaa4d96fecf273bd762985e0e7f9f933c774918 # v1
|
||||
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 }}
|
||||
- name: Upload Artifact
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: coverage
|
||||
path: |
|
||||
coverage
|
||||
!coverage/lcov-report
|
||||
|
|
26
.github/workflows/triage-assigned.yml
vendored
26
.github/workflows/triage-assigned.yml
vendored
|
@ -1,18 +1,18 @@
|
|||
name: Move issued assigned to specific team members to their boards
|
||||
|
||||
on:
|
||||
issues:
|
||||
types: [assigned]
|
||||
issues:
|
||||
types: [ assigned ]
|
||||
|
||||
jobs:
|
||||
web-app-team:
|
||||
runs-on: ubuntu-latest
|
||||
if: |
|
||||
contains(github.event.issue.assignees.*.login, 't3chguy') ||
|
||||
contains(github.event.issue.assignees.*.login, 'andybalaam') ||
|
||||
contains(github.event.issue.assignees.*.login, 'MidhunSureshR')
|
||||
steps:
|
||||
- uses: actions/add-to-project@main
|
||||
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 }}
|
||||
|
|
19
.github/workflows/triage-incoming.yml
vendored
19
.github/workflows/triage-incoming.yml
vendored
|
@ -1,14 +1,15 @@
|
|||
name: Move new issues into Issue triage board
|
||||
|
||||
on:
|
||||
issues:
|
||||
types: [opened]
|
||||
issues:
|
||||
types: [ opened ]
|
||||
|
||||
jobs:
|
||||
automate-project-columns:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/add-to-project@main
|
||||
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 }}
|
||||
|
|
407
.github/workflows/triage-labelled.yml
vendored
407
.github/workflows/triage-labelled.yml
vendored
|
@ -1,200 +1,231 @@
|
|||
name: Move labelled issues to correct projects
|
||||
|
||||
on:
|
||||
issues:
|
||||
types: [labeled]
|
||||
workflow_call:
|
||||
secrets:
|
||||
ELEMENT_BOT_TOKEN:
|
||||
required: true
|
||||
issues:
|
||||
types: [labeled]
|
||||
|
||||
jobs:
|
||||
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-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@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-latest
|
||||
if: >
|
||||
contains(github.event.issue.labels.*.name, 'good first issue') ||
|
||||
contains(github.event.issue.labels.*.name, 'Hacktoberfest')
|
||||
steps:
|
||||
- uses: actions/github-script@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-latest
|
||||
if: >
|
||||
contains(github.event.issue.labels.*.name, 'X-Needs-Info')
|
||||
steps:
|
||||
- id: add_to_project
|
||||
uses: actions/add-to-project@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-latest
|
||||
if: >
|
||||
contains(github.event.issue.labels.*.name, 'Z-Flaky-Test')
|
||||
steps:
|
||||
- id: add_to_project
|
||||
uses: actions/add-to-project@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-latest
|
||||
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@main
|
||||
with:
|
||||
project-url: https://github.com/orgs/element-hq/projects/18
|
||||
github-token: ${{ secrets.ELEMENT_BOT_TOKEN }}
|
||||
|
||||
add_product_issues:
|
||||
name: X-Needs-Product to product project board
|
||||
runs-on: ubuntu-latest
|
||||
if: >
|
||||
contains(github.event.issue.labels.*.name, 'X-Needs-Product')
|
||||
steps:
|
||||
- uses: actions/add-to-project@main
|
||||
with:
|
||||
project-url: https://github.com/orgs/element-hq/projects/28
|
||||
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: actions/add-to-project@main
|
||||
with:
|
||||
project-url: https://github.com/orgs/element-hq/projects/48
|
||||
github-token: ${{ secrets.ELEMENT_BOT_TOKEN }}
|
||||
|
||||
voip:
|
||||
name: Add labelled issues to VoIP project board
|
||||
runs-on: ubuntu-latest
|
||||
if: >
|
||||
contains(github.event.issue.labels.*.name, 'Team: VoIP')
|
||||
steps:
|
||||
- uses: actions/add-to-project@main
|
||||
with:
|
||||
project-url: https://github.com/orgs/element-hq/projects/41
|
||||
github-token: ${{ secrets.ELEMENT_BOT_TOKEN }}
|
||||
|
||||
verticals_feature:
|
||||
name: Add labelled issues to Verticals Feature project
|
||||
runs-on: ubuntu-latest
|
||||
if: >
|
||||
contains(github.event.issue.labels.*.name, 'Team: Verticals Feature')
|
||||
steps:
|
||||
- uses: actions/add-to-project@main
|
||||
with:
|
||||
project-url: https://github.com/orgs/element-hq/projects/57
|
||||
github-token: ${{ secrets.ELEMENT_BOT_TOKEN }}
|
||||
|
||||
tech_debt:
|
||||
name: Add labelled issues to tech debt project
|
||||
runs-on: ubuntu-latest
|
||||
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@main
|
||||
with:
|
||||
project-url: https://github.com/orgs/element-hq/projects/101
|
||||
github-token: ${{ secrets.ELEMENT_BOT_TOKEN }}
|
||||
|
||||
element_r:
|
||||
name: Add Element R issues to Crypto Team board
|
||||
runs-on: ubuntu-latest
|
||||
if: >
|
||||
contains(github.event.issue.labels.*.name, 'A-Element-R')
|
||||
steps:
|
||||
- id: add_to_project
|
||||
uses: actions/add-to-project@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: Workstream,module
|
||||
field-values: Element-R,web
|
||||
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_URL: https://github.com/orgs/element-hq/projects/76
|
||||
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 }}
|
||||
|
||||
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 }}
|
||||
|
||||
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 }}
|
||||
|
||||
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 }}
|
||||
|
|
260
.github/workflows/triage-move-review-requests.yml
vendored
260
.github/workflows/triage-move-review-requests.yml
vendored
|
@ -1,139 +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 ]
|
||||
|
||||
jobs:
|
||||
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: "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@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!) {
|
||||
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-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: "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@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!) {
|
||||
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 }}
|
17
.github/workflows/triage-stale-flaky-tests.yml
vendored
17
.github/workflows/triage-stale-flaky-tests.yml
vendored
|
@ -1,17 +0,0 @@
|
|||
name: Close stale flaky issues
|
||||
on:
|
||||
schedule:
|
||||
- cron: "30 1 * * *"
|
||||
jobs:
|
||||
close:
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
issues: write
|
||||
steps:
|
||||
- uses: actions/stale@v9
|
||||
with:
|
||||
only-labels: "Z-Flaky-Test"
|
||||
days-before-stale: 14
|
||||
days-before-close: 0
|
||||
close-issue-message: "This flaky test issue has not been updated in 14 days. It is being closed as presumed resolved."
|
||||
exempt-issue-labels: "Z-Flaky-Test-Disabled"
|
130
.github/workflows/triage-unlabelled.yml
vendored
130
.github/workflows/triage-unlabelled.yml
vendored
|
@ -1,71 +1,71 @@
|
|||
name: Move unlabelled from needs info columns to triaged
|
||||
|
||||
on:
|
||||
issues:
|
||||
types: [unlabeled]
|
||||
issues:
|
||||
types: [ unlabeled ]
|
||||
|
||||
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@303f24a24c67ce7adf565a07e96720faf126fe36
|
||||
if: ${{ env.ALREADY_IN_BOARD == 'true' && env.SKIP_ACTION != 'true' }}
|
||||
with:
|
||||
project: Issue triage
|
||||
column: Triaged
|
||||
repo-token: ${{ secrets.ELEMENT_BOT_TOKEN }}
|
||||
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-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@v7
|
||||
with:
|
||||
script: |
|
||||
github.rest.issues.removeLabel({
|
||||
issue_number: context.issue.number,
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
name: ['Z-Labs']
|
||||
})
|
||||
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']
|
||||
})
|
||||
|
|
32
.github/workflows/update-jitsi.yml
vendored
32
.github/workflows/update-jitsi.yml
vendored
|
@ -1,32 +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
|
||||
jobs:
|
||||
update:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- uses: actions/setup-node@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@c5a7806660adbe173f04e3e038b0ccdcd758773c # v6
|
||||
with:
|
||||
token: ${{ secrets.ELEMENT_BOT_TOKEN }}
|
||||
branch: actions/jitsi-update
|
||||
delete-branch: true
|
||||
title: Jitsi Update
|
||||
labels: |
|
||||
T-Task
|
102
.github/workflows/update-topics.yaml
vendored
102
.github/workflows/update-topics.yaml
vendored
|
@ -1,102 +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 }}
|
||||
jobs:
|
||||
bot:
|
||||
name: Release topic update
|
||||
runs-on: ubuntu-latest
|
||||
environment: Matrix
|
||||
steps:
|
||||
- uses: actions/github-script@v7
|
||||
env:
|
||||
HS_URL: ${{ secrets.BETABOT_HS_URL }}
|
||||
LOBBY_ROOM_ID: ${{ secrets.ROOM_ID }}
|
||||
PUBLIC_ROOM_ID: "!YTvKGNlinIzlkMTVRl:matrix.org"
|
||||
ANNOUNCEMENT_ROOM_ID: "!bijaLdadorKgNGtHdA:matrix.org"
|
||||
TOKEN: ${{ secrets.BETABOT_ACCESS_TOKEN }}
|
||||
RELEASE_STATUS: "Release status: ${{ inputs.expected_status }} expected ${{ inputs.expected_date }}"
|
||||
with:
|
||||
script: |
|
||||
const { HS_URL, TOKEN, RELEASE_STATUS, LOBBY_ROOM_ID, PUBLIC_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);
|
||||
});
|
||||
}
|
||||
|
||||
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 }}
|
2
.gitignore
vendored
2
.gitignore
vendored
|
@ -27,5 +27,3 @@ electron/pub
|
|||
# Auto-generated file
|
||||
/src/modules.ts
|
||||
/build_config.yaml
|
||||
/book
|
||||
/index.html
|
||||
|
|
|
@ -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 --config .eslintrc-module_system.js module_system"],
|
||||
"*.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,34 +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/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
|
||||
|
||||
# This file is owned, parsed, and generated by allchange, which doesn't comply with prettier
|
||||
/CHANGELOG.md
|
||||
/docs/changelogs
|
||||
|
||||
# Downloaded and already minified
|
||||
res/jitsi_external_api.min.js
|
|
@ -1 +0,0 @@
|
|||
module.exports = require("eslint-plugin-matrix-org/.prettierrc.js");
|
0
.sentryclirc
Normal file
0
.sentryclirc
Normal file
|
@ -1,4 +1,3 @@
|
|||
module.exports = {
|
||||
...require("matrix-react-sdk/.stylelintrc.js"),
|
||||
extends: ["stylelint-config-standard"],
|
||||
};
|
||||
|
|
8018
CHANGELOG.md
8018
CHANGELOG.md
File diff suppressed because it is too large
Load diff
138
CONTRIBUTING.md
138
CONTRIBUTING.md
|
@ -1,4 +1,5 @@
|
|||
# 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 under the same license as the project
|
||||
|
@ -8,7 +9,8 @@ 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
|
||||
|
@ -17,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".
|
||||
|
||||
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
|
||||
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
|
||||
* 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,
|
||||
* 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.
|
||||
* 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
|
||||
|
@ -67,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
|
||||
```
|
||||
|
@ -76,18 +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:
|
||||
|
||||
- matrix-react-sdk
|
||||
- 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
|
||||
|
@ -95,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.
|
||||
|
@ -115,8 +104,8 @@ 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`, `matrix-react-sdk` or `element-web`, you
|
||||
|
@ -124,7 +113,7 @@ 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` in `matrix-react-sdk`, and
|
||||
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.
|
||||
|
||||
|
@ -140,7 +129,7 @@ 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
|
||||
|
@ -150,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") {
|
||||
|
@ -172,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.
|
||||
|
||||
|
@ -186,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
|
||||
|
@ -199,12 +187,12 @@ give away to contributors - if you feel that Matrix-branded apparel is missing
|
|||
from your life, please mail us your shipping address to matrix at matrix.org
|
||||
and we'll try to fix it :)
|
||||
|
||||
## Sign off
|
||||
|
||||
Sign off
|
||||
--------
|
||||
In order to have a concrete record that your contribution is intentional
|
||||
and you agree to license it under the same terms as the project's license, we've
|
||||
adopted the same lightweight approach that the Linux Kernel
|
||||
(https://www.kernel.org/doc/html/latest/process/submitting-patches.html), Docker
|
||||
(https://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
|
||||
|
@ -271,27 +259,19 @@ on Git 2.17+ you can mass signoff using rebase:
|
|||
git rebase --signoff origin/develop
|
||||
```
|
||||
|
||||
## Private sign off
|
||||
Review expectations
|
||||
===================
|
||||
|
||||
If you would like to provide your legal name privately to the Matrix.org
|
||||
Foundation (instead of in a public commit or comment), you can do so by emailing
|
||||
your legal name and a link to the pull request to dco@matrix.org. It helps to
|
||||
include "sign off" or similar in the subject line. You will then be instructed
|
||||
further.
|
||||
See https://github.com/vector-im/element-meta/wiki/Review-process
|
||||
|
||||
Once private sign off is complete, doing so for future contributions will not
|
||||
be required.
|
||||
|
||||
# Review expectations
|
||||
|
||||
See https://github.com/element-hq/element-meta/wiki/Review-process
|
||||
|
||||
# Merge Strategy
|
||||
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:
|
||||
|
||||
|
@ -299,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.
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
# Builder
|
||||
FROM --platform=$BUILDPLATFORM node:20-bullseye as builder
|
||||
FROM node:14-buster as builder
|
||||
|
||||
# Support custom branches of the react-sdk and js-sdk. This also helps us build
|
||||
# images of element-web develop.
|
||||
|
@ -15,7 +15,7 @@ WORKDIR /src
|
|||
|
||||
COPY . /src
|
||||
RUN dos2unix /src/scripts/docker-link-repos.sh && bash /src/scripts/docker-link-repos.sh
|
||||
RUN yarn --network-timeout=200000 install
|
||||
RUN yarn --network-timeout=100000 install
|
||||
|
||||
RUN dos2unix /src/scripts/docker-package.sh && bash /src/scripts/docker-package.sh
|
||||
|
||||
|
@ -23,7 +23,7 @@ RUN dos2unix /src/scripts/docker-package.sh && bash /src/scripts/docker-package.
|
|||
RUN cp /src/config.sample.json /src/webapp/config.json
|
||||
|
||||
# App
|
||||
FROM nginx:alpine-slim
|
||||
FROM nginx:alpine
|
||||
|
||||
COPY --from=builder /src/webapp /app
|
||||
|
||||
|
|
252
README.md
252
README.md
|
@ -1,93 +1,113 @@
|
|||
[![Chat](https://img.shields.io/matrix/element-web:matrix.org?logo=matrix)](https://matrix.to/#/#element-web:matrix.org)
|
||||
![Tests](https://github.com/element-hq/element-web/actions/workflows/tests.yaml/badge.svg)
|
||||
![Static Analysis](https://github.com/element-hq/element-web/actions/workflows/static_analysis.yaml/badge.svg)
|
||||
[![Localazy](https://img.shields.io/endpoint?url=https%3A%2F%2Fconnect.localazy.com%2Fstatus%2Felement-web%2Fdata%3Fcontent%3Dall%26title%3Dlocalazy%26logo%3Dtrue)](https://localazy.com/p/element-web)
|
||||
![Tests](https://github.com/vector-im/element-web/actions/workflows/tests.yaml/badge.svg)
|
||||
![Static Analysis](https://github.com/vector-im/element-web/actions/workflows/static_analysis.yaml/badge.svg)
|
||||
[![Weblate](https://translate.element.io/widgets/element-web/-/element-web/svg-badge.svg)](https://translate.element.io/engage/element-web/)
|
||||
[![Quality Gate Status](https://sonarcloud.io/api/project_badges/measure?project=element-web&metric=alert_status)](https://sonarcloud.io/summary/new_code?id=element-web)
|
||||
[![Coverage](https://sonarcloud.io/api/project_badges/measure?project=element-web&metric=coverage)](https://sonarcloud.io/summary/new_code?id=element-web)
|
||||
[![Vulnerabilities](https://sonarcloud.io/api/project_badges/measure?project=element-web&metric=vulnerabilities)](https://sonarcloud.io/summary/new_code?id=element-web)
|
||||
[![Bugs](https://sonarcloud.io/api/project_badges/measure?project=element-web&metric=bugs)](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
|
||||
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
|
||||
framed and protect from [clickjacking][owasp-clickjacking].
|
||||
- The `frame-ancestors 'self'` directive to your `Content-Security-Policy`
|
||||
header, as the modern replacement for `X-Frame-Options` (though both should be
|
||||
included since not all browsers support it yet, see
|
||||
[this][owasp-clickjacking-csp]).
|
||||
- The `X-Content-Type-Options: nosniff` header, to [disable MIME
|
||||
sniffing][mime-sniffing].
|
||||
- The `X-XSS-Protection: 1; mode=block;` header, for basic XSS protection in
|
||||
legacy browsers.
|
||||
* The `X-Frame-Options: SAMEORIGIN` header, to prevent Element Web from being
|
||||
framed and protect from [clickjacking][owasp-clickjacking].
|
||||
* 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
|
||||
sniffing][mime-sniffing].
|
||||
* The `X-XSS-Protection: 1; mode=block;` header, for basic XSS protection in
|
||||
legacy browsers.
|
||||
|
||||
[mime-sniffing]: https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types#mime_sniffing
|
||||
[owasp-clickjacking-csp]: https://cheatsheetseries.owasp.org/cheatsheets/Clickjacking_Defense_Cheat_Sheet.html#content-security-policy-frame-ancestors-examples
|
||||
[owasp-clickjacking]: https://cheatsheetseries.owasp.org/cheatsheets/Clickjacking_Defense_Cheat_Sheet.html
|
||||
[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,10 +140,10 @@ 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](#setting-up-a-dev-environment) below). Alternatively, you
|
||||
can use <https://develop.element.io> - the continuous integration release of
|
||||
|
@ -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,7 +259,8 @@ 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
|
||||
===========
|
||||
|
||||
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
|
||||
|
@ -202,7 +282,7 @@ 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)
|
||||
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.
|
||||
|
||||
|
@ -210,7 +290,8 @@ 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
|
||||
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
|
||||
|
@ -219,7 +300,7 @@ having to manually rebuild each time.
|
|||
|
||||
First clone and build `matrix-js-sdk`:
|
||||
|
||||
```bash
|
||||
``` bash
|
||||
git clone https://github.com/matrix-org/matrix-js-sdk.git
|
||||
pushd matrix-js-sdk
|
||||
yarn link
|
||||
|
@ -241,7 +322,7 @@ popd
|
|||
Clone the repo and switch to the `element-web` directory:
|
||||
|
||||
```bash
|
||||
git clone https://github.com/element-hq/element-web.git
|
||||
git clone https://github.com/vector-im/element-web.git
|
||||
cd element-web
|
||||
```
|
||||
|
||||
|
@ -266,9 +347,9 @@ Wait a few seconds for the initial build to finish; you should see something lik
|
|||
[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.
|
||||
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.
|
||||
|
||||
|
@ -277,8 +358,8 @@ for changes. If the inotify limits are too low your build will fail silently or
|
|||
`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.
|
||||
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:
|
||||
|
||||
|
@ -296,7 +377,7 @@ 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.
|
||||
|
@ -305,7 +386,8 @@ If any of these steps error with, `file table overflow`, you are probably on a m
|
|||
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
|
||||
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
|
||||
|
@ -318,14 +400,18 @@ yarn test
|
|||
|
||||
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
|
||||
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).
|
||||
|
||||
We use [issue labels](https://github.com/vector-im/element-meta/wiki/Issue-labelling) to sort all incoming issues.
|
||||
|
|
|
@ -1,34 +1,24 @@
|
|||
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",
|
||||
],
|
||||
|
|
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"
|
||||
|
|
302
code_style.md
302
code_style.md
|
@ -3,10 +3,10 @@
|
|||
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
|
||||
- matrix-react-sdk
|
||||
- matrix-js-sdk
|
||||
* 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
|
||||
|
@ -51,28 +51,60 @@ in that order.
|
|||
|
||||
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.
|
||||
|
||||
|
@ -81,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
|
||||
{
|
||||
|
@ -102,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
|
||||
{
|
||||
|
@ -112,32 +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:
|
||||
|
||||
|
@ -152,26 +214,23 @@ 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
|
||||
`?` operator is inappropriate is when taking a room ID: typically the caller should
|
||||
|
@ -186,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
|
||||
|
@ -207,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 () {
|
||||
|
@ -225,12 +282,6 @@ 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:
|
||||
|
@ -261,55 +312,81 @@ Inheriting all the rules of TypeScript, the following additionally apply:
|
|||
}
|
||||
}
|
||||
```
|
||||
|
||||
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.
|
||||
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:
|
||||
|
||||
1. When knowingly using a class name from another component, document it with a [comment](#comments).
|
||||
```typescript
|
||||
function render() {
|
||||
return <Component
|
||||
prop1="test"
|
||||
prop2={this.state.variable}
|
||||
/>;
|
||||
|
||||
12. Curly braces within JSX should be padded with a space, however properties on those components should not.
|
||||
// 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.
|
||||
13. 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.
|
||||
14. 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.
|
||||
15. 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.
|
||||
16. Components should serve a single, or near-single, purpose.
|
||||
17. Prefer to derive information from component properties rather than establish state.
|
||||
18. 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. Class names must be prefixed with "mx\_".
|
||||
2. Class names must denote the component which defines them, followed by any context.
|
||||
The context is not further specified here in terms of meaning or syntax.
|
||||
Use whatever is appropriate for your implementation use case.
|
||||
Some examples:
|
||||
1. `mx_MyFoo`
|
||||
2. `mx_MyFoo_avatar`
|
||||
3. `mx_MyFoo_avatarUser`
|
||||
4. `mx_MyFoo_avatar--user`
|
||||
3. Use the `$font` variables instead of manual values.
|
||||
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
|
||||
// ...
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
6. Break multiple selectors over multiple lines this way:
|
||||
|
||||
```scss
|
||||
|
@ -319,10 +396,9 @@ Note: We use PostCSS + some plugins to process our styles. It looks like SCSS, b
|
|||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
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](#comments) for what the values mean:
|
||||
documented for what the values mean:
|
||||
|
||||
```scss
|
||||
.mx_MyFoo {
|
||||
|
@ -331,8 +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
|
||||
}
|
||||
```
|
||||
|
||||
9. Avoid the use of `!important`. If `!important` is necessary, add a [comment](#comments) explaining why.
|
||||
9. Avoid the use of `!important`. If necessary, add a comment.
|
||||
|
||||
## Tests
|
||||
|
||||
|
@ -356,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
|
||||
});
|
||||
});
|
||||
|
@ -376,38 +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.
|
||||
|
|
|
@ -22,13 +22,17 @@
|
|||
"https://scalar-staging.vector.im/api",
|
||||
"https://scalar-staging.riot.im/scalar/api"
|
||||
],
|
||||
"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,
|
||||
|
|
|
@ -1,13 +1,17 @@
|
|||
{
|
||||
"name": "Element",
|
||||
"name": "Element",
|
||||
"description": "A glossy Matrix collaboration client for the web.",
|
||||
"repository": {
|
||||
"url": "https://github.com/element-hq/element-web",
|
||||
"license": "Apache License 2.0"
|
||||
"url": "https://github.com/vector-im/element-web",
|
||||
"license": "Apache License 2.0"
|
||||
},
|
||||
"bugs": {
|
||||
"list": "https://github.com/element-hq/element-web/issues",
|
||||
"report": "https://github.com/element-hq/element-web/issues/new/choose"
|
||||
"list": "https://github.com/vector-im/element-web/issues",
|
||||
"report": "https://github.com/vector-im/element-web/issues/new/choose"
|
||||
},
|
||||
"keywords": ["chat", "riot", "matrix"]
|
||||
"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:
|
||||
A feature-rich client for Matrix.org
|
||||
This package contains the web-based client that can be served through a web
|
||||
server.
|
|
@ -1,41 +0,0 @@
|
|||
# Summary
|
||||
|
||||
- [Introduction](../README.md)
|
||||
|
||||
# Usage
|
||||
|
||||
- [Betas](betas.md)
|
||||
- [Labs](labs.md)
|
||||
|
||||
# Setup
|
||||
|
||||
- [Install](install.md)
|
||||
- [Config](config.md)
|
||||
- [Custom home page](custom-home.md)
|
||||
- [Kubernetes](kubernetes.md)
|
||||
- [Jitsi](jitsi.md)
|
||||
- [Encryption](e2ee.md)
|
||||
|
||||
# Build
|
||||
|
||||
- [Customisations](customisations.md)
|
||||
- [Modules](modules.md)
|
||||
- [Native Node modules](native-node-modules.md)
|
||||
|
||||
# Contribution
|
||||
|
||||
- [Choosing an issue](choosing-an-issue.md)
|
||||
- [Translation](translating.md)
|
||||
- [Netlify builds](pr-previews.md)
|
||||
- [Code review](review.md)
|
||||
|
||||
# Development
|
||||
|
||||
- [App load order](app-load.md)
|
||||
- [Translation](translating-dev.md)
|
||||
- [Theming](theming.md)
|
||||
- [Memory profiling](memory-profiles-and-leaks.md)
|
||||
- [Jitsi](jitsi-dev.md)
|
||||
- [Feature flags](feature-flags.md)
|
||||
- [OIDC and delegated authentication](oidc.md)
|
||||
- [Release Process](release.md)
|
152
docs/app-load.md
152
docs/app-load.md
|
@ -4,105 +4,81 @@
|
|||
been kept untouched for posterity.
|
||||
|
||||
Old slow flow:
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
A1(((load_modernizr))) --> B
|
||||
A2((rageshake)) --> B
|
||||
B(((skin))) --> C
|
||||
C(((olm))) --> D
|
||||
D{mobile} --> E
|
||||
E((config)) --> F
|
||||
F((i18n)) --> G
|
||||
style F stroke:lime
|
||||
G(((theme))) --> H
|
||||
H(((modernizr))) --> app
|
||||
style H stroke:red
|
||||
```
|
||||
![image](https://user-images.githubusercontent.com/2403652/73848963-00a2a080-4821-11ea-97d4-1200fc2638f3.png)
|
||||
|
||||
Current more parallel flow:
|
||||
![image](https://user-images.githubusercontent.com/2403652/83146440-303a2900-a0ee-11ea-806b-4f53f039b957.png)
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
subgraph index.ts
|
||||
style index.ts stroke:orange
|
||||
<details><summary>Code</summary>
|
||||
<p>
|
||||
<pre><code>
|
||||
digraph G {
|
||||
node [shape=box];
|
||||
|
||||
A[/rageshake/] --> B{mobile}
|
||||
B-- No -->C1(.)
|
||||
B-- Yes -->C2((redirect))
|
||||
C1 --> D[/olm/] --> R
|
||||
C1 --> E[platform] --> F[/config/]
|
||||
F --> G1[/skin/]
|
||||
F --> R
|
||||
G1 --> H
|
||||
G1 --> R
|
||||
F --> G2[/theme/]
|
||||
G2 --> H
|
||||
G2 --> R
|
||||
F --> G3[/i18n/]
|
||||
G3 --> H
|
||||
G3 --> R
|
||||
H{modernizr}-- No --> J((incompatible))-- user ignore --> R
|
||||
H-- Yes --> R
|
||||
subgraph cluster_0 {
|
||||
color=orange;
|
||||
node [style=filled];
|
||||
label = "index.ts";
|
||||
|
||||
linkStyle 0,7,9,11,12,14,15 stroke:blue;
|
||||
linkStyle 4,8,10,13,16 stroke:red;
|
||||
end
|
||||
entrypoint, s0, ready [shape=point];
|
||||
rageshake, config, i18n, theme, skin, olm [shape=parallelogram];
|
||||
mobile [shape=diamond, label="mobile"];
|
||||
modernizr [shape=diamond];
|
||||
redirect, incompatible [shape=egg];
|
||||
|
||||
R>ready] --> 2A
|
||||
style R stroke:gray
|
||||
entrypoint -> rageshake;
|
||||
rageshake -> mobile [color=blue];
|
||||
mobile -> s0 [label="No"];
|
||||
mobile -> redirect [label="Yes"];
|
||||
|
||||
subgraph init.tsx
|
||||
style init.tsx stroke:lime
|
||||
2A[loadApp] --> 2B[matrixchat]
|
||||
end
|
||||
s0 -> platform;
|
||||
s0 -> olm;
|
||||
platform -> config;
|
||||
|
||||
```
|
||||
config -> i18n [color=blue];
|
||||
config -> theme [color=blue];
|
||||
config -> skin [color=blue];
|
||||
|
||||
i18n -> modernizr [color=blue];
|
||||
theme -> modernizr [color=blue];
|
||||
skin -> modernizr [color=blue];
|
||||
|
||||
modernizr -> ready [label="Yes"];
|
||||
modernizr -> incompatible [label="No"];
|
||||
incompatible -> ready [label="user ignore"];
|
||||
|
||||
olm -> ready [color=red];
|
||||
config -> ready [color=red];
|
||||
skin -> ready [color=red];
|
||||
theme -> ready [color=red];
|
||||
i18n -> ready [color=red];
|
||||
}
|
||||
|
||||
subgraph cluster_1 {
|
||||
color = green;
|
||||
node [style=filled];
|
||||
label = "init.tsx";
|
||||
|
||||
ready -> loadApp;
|
||||
loadApp -> matrixchat;
|
||||
}
|
||||
}
|
||||
</code></pre>
|
||||
</p>
|
||||
</details>
|
||||
|
||||
Key:
|
||||
|
||||
- Parallelogram: async/await task
|
||||
- Box: sync task
|
||||
- Diamond: conditional branch
|
||||
- Circle: user interaction
|
||||
- Blue arrow: async task is allowed to settle but allowed to fail
|
||||
- Red arrow: async task success is asserted
|
||||
+ Parallelogram: async/await task
|
||||
+ Box: sync task
|
||||
+ Diamond: conditional branch
|
||||
+ Egg: user interaction
|
||||
+ Blue arrow: async task is allowed to settle but allowed to fail
|
||||
+ Red arrow: async task success is asserted
|
||||
|
||||
Notes:
|
||||
|
||||
- A task begins when all its dependencies (arrows going into it) are fulfilled.
|
||||
- The success of setting up rageshake is never asserted, element-web has a fallback path for running without IDB (and thus rageshake).
|
||||
- Everything is awaited to be settled before the Modernizr check, to allow it to make use of things like i18n if they are successful.
|
||||
+ A task begins when all its dependencies (arrows going into it) are fulfilled.
|
||||
+ The success of setting up rageshake is never asserted, element-web has a fallback path for running without IDB (and thus rageshake).
|
||||
+ Everything is awaited to be settled before the Modernizr check, to allow it to make use of things like i18n if they are successful.
|
||||
|
||||
Underlying dependencies:
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
A((rageshake))
|
||||
B{mobile}
|
||||
C((config))
|
||||
D(((olm)))
|
||||
E((i18n))
|
||||
F(((load_modernizr)))
|
||||
G(((modernizr)))
|
||||
H(((skin)))
|
||||
I(((theme)))
|
||||
X[app]
|
||||
|
||||
A --> G
|
||||
A --> B
|
||||
A-- assert -->X
|
||||
F --> G --> X
|
||||
G --> H --> X
|
||||
C --> I --> X
|
||||
C --> E --> X
|
||||
E --> G
|
||||
B --> C-- assert -->X
|
||||
B --> D --> X
|
||||
|
||||
style X stroke:red
|
||||
style G stroke:red
|
||||
style E stroke:lime
|
||||
linkStyle 0,11 stroke:yellow;
|
||||
linkStyle 2,13 stroke:red;
|
||||
```
|
||||
![image](https://user-images.githubusercontent.com/2403652/73848977-08624500-4821-11ea-9830-bb0317c41086.png)
|
||||
|
|
|
@ -1,14 +0,0 @@
|
|||
# Beta features
|
||||
|
||||
Beta features are features that are not ready for production yet but the team
|
||||
wants more people to try the features and give feedback on them.
|
||||
|
||||
Before a feature gets into its beta phase, it is often a labs feature (see
|
||||
[Labs](https://github.com/element-hq/element-web/blob/develop/docs/labs.md)).
|
||||
|
||||
**Be warned! Beta features may not be completely finalised or stable!**
|
||||
|
||||
## Video rooms (`feature_video_rooms`)
|
||||
|
||||
Enables support for creating and joining video rooms, which are persistent video
|
||||
chats that users can jump in and out of.
|
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
@ -18,12 +18,12 @@ If you're looking for inspiration on where to start, keep reading!
|
|||
## Finding a good first issue
|
||||
|
||||
All the issues for Element Web live in the
|
||||
[element-web](https://github.com/element-hq/element-web) repository, including
|
||||
[element-web](https://github.com/vector-im/element-web) repository, including
|
||||
issues that actually need fixing in `matrix-react-sdk` or one of the related
|
||||
repos.
|
||||
|
||||
The first place to look is for
|
||||
[issues tagged with "good first issue"](https://github.com/element-hq/element-web/issues?q=is%3Aopen+is%3Aissue+label%3A%22good+first+issue%22).
|
||||
[issues tagged with "good first issue"](https://github.com/vector-im/element-web/issues?q=is%3Aopen+is%3Aissue+label%3A%22good+first+issue%22).
|
||||
|
||||
Look through that list and find something that catches your interest. If there
|
||||
is nothing, there, try gently asking in
|
||||
|
@ -33,19 +33,19 @@ someone to add something.
|
|||
When you're looking through the list, here are some things that might make an
|
||||
issue a **GOOD** choice:
|
||||
|
||||
- It is a problem or feature you care about.
|
||||
- It concerns a type of code you know a little about.
|
||||
- You think you can understand what's needed.
|
||||
- It already has approval from Element Web's designers (look for comments from
|
||||
members of the
|
||||
[Product](https://github.com/orgs/element-hq/teams/product/members) or
|
||||
[Design](https://github.com/orgs/element-hq/teams/design/members) teams).
|
||||
* It is a problem or feature you care about.
|
||||
* It concerns a type of code you know a little about.
|
||||
* You think you can understand what's needed.
|
||||
* It already has approval from Element Web's designers (look for comments from
|
||||
members of the
|
||||
[Product](https://github.com/orgs/vector-im/teams/product/members) or
|
||||
[Design](https://github.com/orgs/vector-im/teams/design/members) teams).
|
||||
|
||||
Here are some things that might make it a **BAD** choice:
|
||||
|
||||
- You don't understand it (maybe add a comment asking a clarifying question).
|
||||
- It sounds difficult, or is part of a larger change you don't know about.
|
||||
- **It is tagged with `X-Needs-Design` or `X-Needs-Product`.**
|
||||
* You don't understand it (maybe add a comment asking a clarifying question).
|
||||
* It sounds difficult, or is part of a larger change you don't know about.
|
||||
* **It is tagged with `X-Needs-Design` or `X-Needs-Product`.**
|
||||
|
||||
**Element Web's Design and Product teams tend to be very busy**, so if you make
|
||||
changes that require approval from one of those teams, you will probably have
|
||||
|
@ -57,7 +57,7 @@ way the product works, or how it looks in a specific area.
|
|||
Once you've fixed a few small things, you can consider taking on something a
|
||||
little larger. This should mostly be driven by what you find interesting, but
|
||||
you may also find the
|
||||
[Help Wanted](https://github.com/element-hq/element-web/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-desc+label%3A%22Help+Wanted%22)
|
||||
[Help Wanted](https://github.com/vector-im/element-web/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-desc+label%3A%22Help+Wanted%22)
|
||||
label useful.
|
||||
|
||||
Note that the same comment applies as in the previous section: if you want to
|
||||
|
|
479
docs/config.md
479
docs/config.md
|
@ -1,13 +1,5 @@
|
|||
# Configuration
|
||||
|
||||
### 🦖 Deprecation notice
|
||||
|
||||
Configuration keys were previously a mix of camelCase and snake_case.
|
||||
We standardised to snake_case but added compatibility for camelCase to all settings.
|
||||
This backwards compatibility will be getting removed in a future release so please ensure you are using snake_case.
|
||||
|
||||
---
|
||||
|
||||
You can configure the app by copying `config.sample.json` to `config.json` or `config.$domain.json` and customising it.
|
||||
Element will attempt to load first `config.$domain.json` and if it fails `config.json`. This mechanism allows different
|
||||
configuration options depending on if you're hitting e.g. `app1.example.com` or `app2.example.com`. Configs are not mixed
|
||||
|
@ -25,7 +17,7 @@ for the desktop app the application will need to be exited fully (including via
|
|||
|
||||
## Homeserver configuration
|
||||
|
||||
In order for Element to even start you will need to tell it what homeserver to connect to _by default_. Users will be
|
||||
In order for Element to even start you will need to tell it what homeserver to connect to *by default*. Users will be
|
||||
able to use a different homeserver if they like, though this can be disabled with `"disable_custom_urls": true` in your
|
||||
config.
|
||||
|
||||
|
@ -34,18 +26,18 @@ One of the following options **must** be supplied:
|
|||
1. `default_server_config`: The preferred method of setting the homeserver connection information. Simply copy/paste
|
||||
your [`/.well-known/matrix/client`](https://spec.matrix.org/latest/client-server-api/#getwell-knownmatrixclient)
|
||||
into this field. For example:
|
||||
```json
|
||||
{
|
||||
"default_server_config": {
|
||||
"m.homeserver": {
|
||||
"base_url": "https://matrix-client.matrix.org"
|
||||
},
|
||||
"m.identity_server": {
|
||||
"base_url": "https://vector.im"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
```json
|
||||
{
|
||||
"default_server_config": {
|
||||
"m.homeserver": {
|
||||
"base_url": "https://matrix-client.matrix.org"
|
||||
},
|
||||
"m.identity_server": {
|
||||
"base_url": "https://vector.im"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
2. `default_server_name`: A different method of connecting to the homeserver by looking up the connection information
|
||||
using `.well-known`. When using this option, simply use your server's domain name (the part at the end of user IDs):
|
||||
`"default_server_name": "matrix.org"`
|
||||
|
@ -53,9 +45,8 @@ One of the following options **must** be supplied:
|
|||
information. These are the same values seen as `base_url` in the `default_server_config` example, with `default_is_url`
|
||||
being optional.
|
||||
|
||||
If both `default_server_config` and `default_server_name` are used, Element will try to look up the connection
|
||||
information using `.well-known`, and if that fails, take `default_server_config` as the homeserver connection
|
||||
information.
|
||||
If a combination of these three methods is used then Element will fail to load. This is because it is unclear which
|
||||
should be considered "first".
|
||||
|
||||
## Labs flags
|
||||
|
||||
|
@ -67,10 +58,10 @@ To force a labs flag on or off, use the following:
|
|||
|
||||
```json
|
||||
{
|
||||
"features": {
|
||||
"feature_you_want_to_turn_on": true,
|
||||
"feature_you_want_to_keep_off": false
|
||||
}
|
||||
"features": {
|
||||
"feature_you_want_to_turn_on": true,
|
||||
"feature_you_want_to_keep_off": false
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
@ -91,25 +82,25 @@ instance. As of writing those settings are not fully documented, however a few a
|
|||
inputs.
|
||||
3. `room_directory`: Optionally defines how the room directory component behaves. Currently only a single property, `servers`
|
||||
is supported to add additional servers to the dropdown. For example:
|
||||
```json
|
||||
{
|
||||
"room_directory": {
|
||||
"servers": ["matrix.org", "example.org"]
|
||||
}
|
||||
}
|
||||
```
|
||||
```json
|
||||
{
|
||||
"room_directory": {
|
||||
"servers": ["matrix.org", "example.org"]
|
||||
}
|
||||
}
|
||||
```
|
||||
4. `setting_defaults`: Optional configuration for settings which are not described by this document and support the `config`
|
||||
level. This list is incomplete. For example:
|
||||
```json
|
||||
{
|
||||
"setting_defaults": {
|
||||
"MessageComposerInput.showStickersButton": false,
|
||||
"MessageComposerInput.showPollsButton": false
|
||||
}
|
||||
}
|
||||
```
|
||||
These values will take priority over the hardcoded defaults for the settings. For a list of available settings, see
|
||||
[Settings.tsx](https://github.com/matrix-org/matrix-react-sdk/blob/develop/src/settings/Settings.tsx).
|
||||
```json
|
||||
{
|
||||
"setting_defaults": {
|
||||
"MessageComposerInput.showStickersButton": false,
|
||||
"MessageComposerInput.showPollsButton": false
|
||||
}
|
||||
}
|
||||
```
|
||||
These values will take priority over the hardcoded defaults for the settings. For a list of available settings, see
|
||||
[Settings.tsx](https://github.com/matrix-org/matrix-react-sdk/blob/develop/src/settings/Settings.tsx).
|
||||
|
||||
## Customisation & branding
|
||||
|
||||
|
@ -137,9 +128,9 @@ complete re-branding/private labeling, a more personalised experience can be ach
|
|||
This setting is ignored if your homeserver provides `/.well-known/matrix/client` in its well-known location, and the JSON file
|
||||
at that location has a key `m.tile_server` (or the unstable version `org.matrix.msc3488.tile_server`). In this case, the
|
||||
configuration found in the well-known location is used instead.
|
||||
10. `welcome_user_id`: **DEPRECATED** An optional user ID to start a DM with after creating an account. Defaults to nothing (no DM created).
|
||||
10. `welcome_user_id`: An optional user ID to start a DM with after creating an account. Defaults to nothing (no DM created).
|
||||
11. `custom_translations_url`: An optional URL to allow overriding of translatable strings. The JSON file must be in a format of
|
||||
`{"affected|translation|key": {"languageCode": "new string"}}`. See https://github.com/matrix-org/matrix-react-sdk/pull/7886 for details.
|
||||
`{"affected string": {"languageCode": "new string"}}`. See https://github.com/matrix-org/matrix-react-sdk/pull/7886 for details.
|
||||
12. `branding`: Options for configuring various assets used within the app. Described in more detail down below.
|
||||
13. `embedded_pages`: Further optional URLs for various assets used within the app. Described in more detail down below.
|
||||
14. `disable_3pid_login`: When `false` (default), **enables** the options to log in with email address or phone number. Set to
|
||||
|
@ -148,13 +139,6 @@ complete re-branding/private labeling, a more personalised experience can be ach
|
|||
to hide this dropdown.
|
||||
16. `disable_guests`: When `false` (default), **enable** guest-related functionality (peeking/previewing rooms, etc) for unregistered
|
||||
users. Set to `true` to disable this functionality.
|
||||
17. `user_notice`: Optional notice to show to the user, e.g. for sunsetting a deployment and pushing users to move in their own time.
|
||||
Takes a configuration object as below:
|
||||
1. `title`: Required. Title to show at the top of the notice.
|
||||
2. `description`: Required. The description to use for the notice.
|
||||
3. `show_once`: Optional. If true then the notice will only be shown once per device.
|
||||
18. `help_url`: The URL to point users to for help with the app, defaults to `https://element.io/help`.
|
||||
19. `help_encrption_url`: The URL to point users to for help with encryption, defaults to `https://element.io/help#encryption`.
|
||||
|
||||
### `desktop_builds` and `mobile_builds`
|
||||
|
||||
|
@ -167,10 +151,6 @@ Starting with `desktop_builds`, the following subproperties are available:
|
|||
1. `available`: Required. When `true`, the desktop app can be downloaded from somewhere.
|
||||
2. `logo`: Required. A URL to a logo (SVG), intended to be shown at 24x24 pixels.
|
||||
3. `url`: Required. The download URL for the app. This is used as a hyperlink.
|
||||
4. `url_macos`: Optional. Direct link to download macOS desktop app.
|
||||
5. `url_win32`: Optional. Direct link to download Windows 32-bit desktop app.
|
||||
6. `url_win64`: Optional. Direct link to download Windows 64-bit desktop app.
|
||||
7. `url_linux`: Optional. Direct link to download Linux desktop app.
|
||||
|
||||
When `desktop_builds` is not specified at all, the app will assume desktop downloads are available from https://element.io
|
||||
|
||||
|
@ -185,16 +165,16 @@ Together, these two options might look like the following in your config:
|
|||
|
||||
```json
|
||||
{
|
||||
"desktop_builds": {
|
||||
"available": true,
|
||||
"logo": "https://example.org/assets/logo-small.svg",
|
||||
"url": "https://example.org/not_element/download"
|
||||
},
|
||||
"mobile_builds": {
|
||||
"ios": null,
|
||||
"android": "https://example.org/not_element/android",
|
||||
"fdroid": "https://example.org/not_element/fdroid"
|
||||
}
|
||||
"desktop_builds": {
|
||||
"available": true,
|
||||
"logo": "https://example.org/assets/logo-small.svg",
|
||||
"url": "https://example.org/not_element/download"
|
||||
},
|
||||
"mobile_builds": {
|
||||
"ios": null,
|
||||
"android": "https://example.org/not_element/android",
|
||||
"fdroid": "https://example.org/not_element/fdroid"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
@ -225,18 +205,18 @@ Together, the options might look like this in your config:
|
|||
|
||||
```json
|
||||
{
|
||||
"branding": {
|
||||
"welcome_background_url": "https://example.org/assets/background.jpg",
|
||||
"auth_header_logo_url": "https://example.org/assets/logo.svg",
|
||||
"auth_footer_links": [
|
||||
{ "text": "FAQ", "url": "https://example.org/faq" },
|
||||
{ "text": "Donate", "url": "https://example.org/donate" }
|
||||
]
|
||||
},
|
||||
"embedded_pages": {
|
||||
"welcome_url": "https://example.org/assets/welcome.html",
|
||||
"home_url": "https://example.org/assets/home.html"
|
||||
}
|
||||
"branding": {
|
||||
"welcome_background_url": "https://example.org/assets/background.jpg",
|
||||
"auth_header_logo_url": "https://example.org/assets/logo.svg",
|
||||
"auth_footer_links": [
|
||||
{"text": "FAQ", "url": "https://example.org/faq"},
|
||||
{"text": "Donate", "url": "https://example.org/donate"}
|
||||
]
|
||||
},
|
||||
"embedded_pages": {
|
||||
"welcome_url": "https://example.org/assets/welcome.html",
|
||||
"home_url": "https://example.org/assets/home.html"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
@ -254,59 +234,16 @@ When Element is deployed alongside a homeserver with SSO-only login, some option
|
|||
user can be sent to in order to log them out of that system too, making logout symmetric between Element and the SSO system.
|
||||
2. `sso_redirect_options`: Options to define how to handle unauthenticated users. If the object contains `"immediate": true`, then
|
||||
all unauthenticated users will be automatically redirected to the SSO system to start their login. If instead you'd only like to
|
||||
have users which land on the welcome page to be redirected, use `"on_welcome_page": true`. Additionally, there is an option to
|
||||
redirect anyone landing on the login page, by using `"on_login_page": true`. As an example:
|
||||
```json
|
||||
{
|
||||
"sso_redirect_options": {
|
||||
"immediate": false,
|
||||
"on_welcome_page": true,
|
||||
"on_login_page": true
|
||||
}
|
||||
}
|
||||
```
|
||||
It is most common to use the `immediate` flag instead of `on_welcome_page`.
|
||||
|
||||
## Native OIDC
|
||||
|
||||
Native OIDC support is currently in labs and is subject to change.
|
||||
|
||||
Static OIDC Client IDs are preferred and can be specified under `oidc_static_clients` as a mapping from `issuer` to configuration object containing `client_id`.
|
||||
Issuer must have a trailing forward slash. As an example:
|
||||
|
||||
```json
|
||||
{
|
||||
"oidc_static_clients": {
|
||||
"https://auth.example.com/": {
|
||||
"client_id": "example-client-id"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
If a matching static client is not found, the app will attempt to dynamically register a client using metadata specified under `oidc_metadata`.
|
||||
The app has sane defaults for the metadata properties below but on stricter policy identity providers they may not pass muster, e.g. `contacts` may be required.
|
||||
The following subproperties are available:
|
||||
|
||||
1. `client_uri`: This is the base URI for the OIDC client registration, typically `logo_uri`, `tos_uri`, and `policy_uri` must be either on the same domain or a subdomain of this URI.
|
||||
2. `logo_uri`: Optional URI for the client logo.
|
||||
3. `tos_uri`: Optional URI for the client's terms of service.
|
||||
4. `policy_uri`: Optional URI for the client's privacy policy.
|
||||
5. `contacts`: Optional list of contact emails for the client.
|
||||
|
||||
As an example:
|
||||
|
||||
```json
|
||||
{
|
||||
"oidc_metadata": {
|
||||
"client_uri": "https://example.com",
|
||||
"logo_uri": "https://example.com/logo.png",
|
||||
"tos_uri": "https://example.com/tos",
|
||||
"policy_uri": "https://example.com/policy",
|
||||
"contacts": ["support@example.com"]
|
||||
}
|
||||
}
|
||||
```
|
||||
have users which land on the welcome page to be redirected, use `"on_welcome_page": true`. As an example:
|
||||
```json
|
||||
{
|
||||
"sso_redirect_options": {
|
||||
"immediate": false,
|
||||
"on_welcome_page": true
|
||||
}
|
||||
}
|
||||
```
|
||||
It is most common to use the `immediate` flag instead of `on_welcome_page`.
|
||||
|
||||
## VoIP / Jitsi calls
|
||||
|
||||
|
@ -319,84 +256,77 @@ More information about the Jitsi setup can be found [here](./jitsi.md).
|
|||
The VoIP and Jitsi options are:
|
||||
|
||||
1. `jitsi`: Optional configuration for how to start Jitsi conferences. Currently can only contain a single `preferred_domain`
|
||||
value which points at the domain of the Jitsi instance. Defaults to `meet.element.io`. This is _not_ used if the Jitsi widget
|
||||
value which points at the domain of the Jitsi instance. Defaults to `meet.element.io`. This is *not* used if the Jitsi widget
|
||||
was created by an integration manager, or if the homeserver provides Jitsi information in `/.well-known/matrix/client`. For
|
||||
example:
|
||||
```json
|
||||
{
|
||||
"jitsi": {
|
||||
"preferred_domain": "meet.jit.si"
|
||||
}
|
||||
}
|
||||
```
|
||||
```json
|
||||
{
|
||||
"jitsi": {
|
||||
"preferred_domain": "meet.jit.si"
|
||||
}
|
||||
}
|
||||
```
|
||||
2. `jitsi_widget`: Optional configuration for the built-in Jitsi widget. Currently can only contain a single `skip_built_in_welcome_screen`
|
||||
value, denoting whether the "Join Conference" button should be shown. When `true` (default `false`), Jitsi calls will skip to
|
||||
the call instead of having a screen with a single button on it. This is most useful if the Jitsi instance being used already
|
||||
has a landing page for users to test audio and video before joining the call, otherwise users will automatically join the call.
|
||||
For example:
|
||||
```json
|
||||
{
|
||||
"jitsi_widget": {
|
||||
"skip_built_in_welcome_screen": true
|
||||
}
|
||||
}
|
||||
```
|
||||
```json
|
||||
{
|
||||
"jitsi_widget": {
|
||||
"skip_built_in_welcome_screen": true
|
||||
}
|
||||
}
|
||||
```
|
||||
3. `voip`: Optional configuration for various VoIP features. Currently can only contain a single `obey_asserted_identity` value to
|
||||
send MSC3086-style asserted identity messages during VoIP calls in the room corresponding to the asserted identity. This _must_
|
||||
send MSC3086-style asserted identity messages during VoIP calls in the room corresponding to the asserted identity. This *must*
|
||||
only be set in trusted environments. The option defaults to `false`. For example:
|
||||
```json
|
||||
{
|
||||
"voip": {
|
||||
"obey_asserted_identity": false
|
||||
}
|
||||
}
|
||||
```
|
||||
```json
|
||||
{
|
||||
"voip": {
|
||||
"obey_asserted_identity": false
|
||||
}
|
||||
}
|
||||
```
|
||||
4. `widget_build_url`: Optional URL to have Element make a request to when a user presses the voice/video call buttons in the app,
|
||||
if a call would normally be started by the action. The URL will be called with a `roomId` query parameter to identify the room
|
||||
being called in. The URL must respond with a JSON object similar to the following:
|
||||
```json
|
||||
{
|
||||
"widget_id": "$arbitrary_string",
|
||||
"widget": {
|
||||
"creatorUserId": "@user:example.org",
|
||||
"id": "$the_same_widget_id",
|
||||
"type": "m.custom",
|
||||
"waitForIframeLoad": true,
|
||||
"name": "My Widget Name Here",
|
||||
"avatar_url": "mxc://example.org/abc123",
|
||||
"url": "https://example.org/widget.html",
|
||||
"data": {
|
||||
"title": "Subtitle goes here"
|
||||
}
|
||||
},
|
||||
"layout": {
|
||||
"container": "top",
|
||||
"index": 0,
|
||||
"width": 65,
|
||||
"height": 50
|
||||
}
|
||||
}
|
||||
```
|
||||
The `widget` is the `content` of a normal widget state event. The `layout` is the layout specifier for the widget being created,
|
||||
as defined by the `io.element.widgets.layout` state event. By default this applies to all rooms, but the behaviour can be skipped for
|
||||
2-person rooms, causing Element to fall back to 1:1 VoIP, by setting the option `widget_build_url_ignore_dm` to `true`.
|
||||
```json
|
||||
{
|
||||
"widget_id": "$arbitrary_string",
|
||||
"widget": {
|
||||
"creatorUserId": "@user:example.org",
|
||||
"id": "$the_same_widget_id",
|
||||
"type": "m.custom",
|
||||
"waitForIframeLoad": true,
|
||||
"name": "My Widget Name Here",
|
||||
"avatar_url": "mxc://example.org/abc123",
|
||||
"url": "https://example.org/widget.html",
|
||||
"data": {
|
||||
"title": "Subtitle goes here"
|
||||
}
|
||||
},
|
||||
"layout": {
|
||||
"container": "top",
|
||||
"index": 0,
|
||||
"width": 65,
|
||||
"height": 50
|
||||
}
|
||||
}
|
||||
```
|
||||
The `widget` is the `content` of a normal widget state event. The `layout` is the layout specifier for the widget being created,
|
||||
as defined by the `io.element.widgets.layout` state event.
|
||||
5. `audio_stream_url`: Optional URL to pass to Jitsi to enable live streaming. This option is considered experimental and may be removed
|
||||
at any time without notice.
|
||||
6. `element_call`: Optional configuration for native group calls using Element Call, with the following subkeys:
|
||||
- `url`: The URL of the Element Call instance to use for native group calls. This option is considered experimental
|
||||
- `url`: The URL of the Element Call instance to use for native group calls. This option is considered experimental
|
||||
and may be removed at any time without notice. Defaults to `https://call.element.io`.
|
||||
- `use_exclusively`: A boolean specifying whether Element Call should be used exclusively as the only VoIP stack in
|
||||
- `use_exclusively`: A boolean specifying whether Element Call should be used exclusively as the only VoIP stack in
|
||||
the app, removing the ability to start legacy 1:1 calls or Jitsi calls. Defaults to `false`.
|
||||
- `participant_limit`: The maximum number of users who can join a call; if
|
||||
this number is exceeded, the user will not be able to join a given call.
|
||||
- `brand`: Optional name for the app. Defaults to `Element Call`. This is
|
||||
used throughout the application in various strings/locations.
|
||||
- `guest_spa_url`: Optional URL for an Element Call single-page app (SPA),
|
||||
for guest links. If this is set, Element Web will expose a "join" link
|
||||
for public video rooms, which can then be shared to non-matrix users.
|
||||
The target Element Call SPA is typically set up to use a homeserver that
|
||||
allows users to register without email ("passwordless guest users") and to
|
||||
federate.
|
||||
- `participant_limit`: The maximum number of users who can join a call; if
|
||||
this number is exceeded, the user will not be able to join a given call.
|
||||
- `brand`: Optional name for the app. Defaults to `Element Call`. This is
|
||||
used throughout the application in various strings/locations.
|
||||
|
||||
## Bug reporting
|
||||
|
||||
|
@ -406,10 +336,10 @@ If you run your own rageshake server to collect bug reports, the following optio
|
|||
not present in the config, the app will disable all rageshake functionality. Set to `https://element.io/bugreports/submit` to submit
|
||||
rageshakes to us, or use your own rageshake server.
|
||||
2. `uisi_autorageshake_app`: If a user has enabled the "automatically send debug logs on decryption errors" flag, this option will be sent
|
||||
alongside the rageshake so the rageshake server can filter them by app name. By default, this will be `element-auto-uisi`
|
||||
(in contrast to other rageshakes submitted by the app, which use `element-web`).
|
||||
3. `existing_issues_url`: URL for where to find existing issues.
|
||||
4. `new_issue_url`: URL for where to submit new issues.
|
||||
alongside the rageshake so the rageshake server can filter them by app name. By default, this will be `element-web`, as with any other
|
||||
rageshake submitted by the app.
|
||||
|
||||
If you are using the element.io rageshake server, please set this to `element-auto-uisi` so we can better filter them.
|
||||
|
||||
If you would like to use [Sentry](https://sentry.io/) for rageshake data, add a `sentry` object to your config with the following values:
|
||||
|
||||
|
@ -420,17 +350,18 @@ For example:
|
|||
|
||||
```json
|
||||
{
|
||||
"sentry": {
|
||||
"dsn": "dsn-goes-here",
|
||||
"environment": "production"
|
||||
}
|
||||
"sentry": {
|
||||
"dsn": "dsn-goes-here",
|
||||
"environment": "production"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Integration managers
|
||||
|
||||
Integration managers are embedded applications within Element to help the user configure bots, bridges, and widgets. An integration manager
|
||||
is a separate piece of software not typically available with your homeserver. To disable integrations, set the options defined here to `null`.
|
||||
is a separate piece of software not typically available with your homeserver. To disable integrations, leave the options defined here out of
|
||||
your config.
|
||||
|
||||
1. `integrations_ui_url`: The UI URL for the integration manager.
|
||||
2. `integrations_rest_url`: The REST interface URL for the integration manager.
|
||||
|
@ -440,15 +371,15 @@ If you would like to use Scalar, the integration manager maintained by Element,
|
|||
|
||||
```json
|
||||
{
|
||||
"integrations_ui_url": "https://scalar.vector.im/",
|
||||
"integrations_rest_url": "https://scalar.vector.im/api",
|
||||
"integrations_widgets_urls": [
|
||||
"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.riot.im/scalar/api"
|
||||
]
|
||||
"integrations_ui_url": "https://scalar.vector.im/",
|
||||
"integrations_rest_url": "https://scalar.vector.im/api",
|
||||
"integrations_widgets_urls": [
|
||||
"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.riot.im/scalar/api"
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
|
@ -458,9 +389,9 @@ If you would like to include a custom message when someone is reporting an event
|
|||
|
||||
```json
|
||||
{
|
||||
"report_event": {
|
||||
"admin_message_md": "Please be sure to review our [terms of service](https://example.org/terms) before reporting a message."
|
||||
}
|
||||
"report_event": {
|
||||
"admin_message_md": "Please be sure to review our [terms of service](https://example.org/terms) before reporting a message."
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
@ -468,7 +399,9 @@ To add additional "terms and conditions" links throughout the app, use the follo
|
|||
|
||||
```json
|
||||
{
|
||||
"terms_and_conditions_links": [{ "text": "Code of conduct", "url": "https://example.org/code-of-conduct" }]
|
||||
"terms_and_conditions_links": [
|
||||
{ "text": "Code of conduct", "url": "https://example.org/code-of-conduct" }
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
|
@ -485,9 +418,42 @@ analytics are deemed impossible and the user won't be asked to opt in to the sys
|
|||
There are additional root-level options which can be specified:
|
||||
|
||||
1. `analytics_owner`: the company name used in dialogs talking about analytics - this defaults to `brand`,
|
||||
and is useful when the provider of analytics is different from the provider of the Element instance.
|
||||
and is useful when the provider of analytics is different from the provider of the Element instance.
|
||||
2. `privacy_policy_url`: URL to the privacy policy including the analytics collection policy.
|
||||
|
||||
## Server hosting links
|
||||
|
||||
If you would like to encourage matrix.org users to sign up for a service like [Element Matrix Services](https://element.io/matrix-services/server-hosting),
|
||||
the following configuration options can be set. Note that if the options are missing from the configuration then the hosting prompts
|
||||
will not be shown to the user.
|
||||
|
||||
1. `hosting_signup_link`: Optional URL to link the user to when talking about "Upgrading your account". Will contain a query parameter
|
||||
of `utm_campaign` to denote which link the user clicked on within the app. Only ever applies to matrix.org users specifically.
|
||||
2. `host_signup`: Optional configuration for an account importer to your hosting platform. The API surface of this is not documented
|
||||
at the moment, but can be configured with the following subproperties:
|
||||
1. `brand`: The brand name to use.
|
||||
2. `url`: The iframe URL for the importer.
|
||||
3. `domains`: The homeserver domains to show the importer to.
|
||||
4. `cookie_policy_url`: The URL to the cookie policy for the importer.
|
||||
5. `privacy_policy_url`: The URL to the privacy policy for the importer.
|
||||
6. `terms_of_service_url`: The URL to the terms of service for the importer.
|
||||
|
||||
If you're looking to mirror a setup from our production/development environments, the following config should be used:
|
||||
|
||||
```json
|
||||
{
|
||||
"hosting_signup_link": "https://element.io/matrix-services?utm_source=element-web&utm_medium=web",
|
||||
"host_signup": {
|
||||
"brand": "Element Home",
|
||||
"domains": [ "matrix.org" ],
|
||||
"url": "https://ems.element.io/element-home/in-app-loader",
|
||||
"cookie_policy_url": "https://element.io/cookie-policy",
|
||||
"privacy_policy_url": "https://element.io/privacy",
|
||||
"terms_of_service_url": "https://element.io/terms-of-service"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Miscellaneous
|
||||
|
||||
Element supports other options which don't quite fit into other sections of this document.
|
||||
|
@ -497,10 +463,10 @@ set this value to the following at a minimum:
|
|||
|
||||
```json
|
||||
{
|
||||
"enable_presence_by_hs_url": {
|
||||
"https://matrix.org": false,
|
||||
"https://matrix-client.matrix.org": false
|
||||
}
|
||||
"enable_presence_by_hs_url": {
|
||||
"https://matrix.org": false,
|
||||
"https://matrix-client.matrix.org": false
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
@ -517,8 +483,8 @@ Element will check multiple sources when looking for an identity server to use i
|
|||
the following order of preference:
|
||||
|
||||
1. The identity server set in the user's account data
|
||||
- For a new user, no value is present in their account data. It is only set
|
||||
if the user visits Settings and manually changes their identity server.
|
||||
* For a new user, no value is present in their account data. It is only set
|
||||
if the user visits Settings and manually changes their identity server.
|
||||
2. The identity server provided by the `.well-known` lookup that occurred at
|
||||
login
|
||||
3. The identity server provided by the Riot config file
|
||||
|
@ -533,7 +499,7 @@ decentralised.
|
|||
|
||||
## Desktop app configuration
|
||||
|
||||
See https://github.com/element-hq/element-desktop#user-specified-configjson
|
||||
See https://github.com/vector-im/element-desktop#user-specified-configjson
|
||||
|
||||
## UI Features
|
||||
|
||||
|
@ -544,38 +510,38 @@ preferences.
|
|||
|
||||
Currently, the following UI feature flags are supported:
|
||||
|
||||
- `UIFeature.urlPreviews` - Whether URL previews are enabled across the entire application.
|
||||
- `UIFeature.feedback` - Whether prompts to supply feedback are shown.
|
||||
- `UIFeature.voip` - Whether or not VoIP is shown readily to the user. When disabled,
|
||||
Jitsi widgets will still work though they cannot easily be added.
|
||||
- `UIFeature.widgets` - Whether or not widgets will be shown.
|
||||
- `UIFeature.advancedSettings` - Whether or not sections titled "advanced" in room and
|
||||
user settings are shown to the user.
|
||||
- `UIFeature.shareQrCode` - Whether or not the QR code on the share room/event dialog
|
||||
is shown.
|
||||
- `UIFeature.shareSocial` - Whether or not the social icons on the share room/event dialog
|
||||
are shown.
|
||||
- `UIFeature.identityServer` - Whether or not functionality requiring an identity server
|
||||
is shown. When disabled, the user will not be able to interact with the identity
|
||||
server (sharing email addresses, 3PID invites, etc).
|
||||
- `UIFeature.thirdPartyId` - Whether or not UI relating to third party identifiers (3PIDs)
|
||||
is shown. Typically this is considered "contact information" on the homeserver, and is
|
||||
not directly related to the identity server.
|
||||
- `UIFeature.registration` - Whether or not the registration page is accessible. Typically
|
||||
useful if accounts are managed externally.
|
||||
- `UIFeature.passwordReset` - Whether or not the password reset page is accessible. Typically
|
||||
useful if accounts are managed externally.
|
||||
- `UIFeature.deactivate` - Whether or not the deactivate account button is accessible. Typically
|
||||
useful if accounts are managed externally.
|
||||
- `UIFeature.advancedEncryption` - Whether or not advanced encryption options are shown to the
|
||||
user.
|
||||
- `UIFeature.roomHistorySettings` - Whether or not the room history settings are shown to the user.
|
||||
This should only be used if the room history visibility options are managed by the server.
|
||||
- `UIFeature.TimelineEnableRelativeDates` - Display relative date separators (eg: 'Today', 'Yesterday') in the
|
||||
timeline for recent messages. When false day dates will be used.
|
||||
- `UIFeature.BulkUnverifiedSessionsReminder` - Display popup reminders to verify or remove unverified sessions. Defaults
|
||||
to true.
|
||||
- `UIFeature.locationSharing` - Whether or not location sharing menus will be shown.
|
||||
* `UIFeature.urlPreviews` - Whether URL previews are enabled across the entire application.
|
||||
* `UIFeature.feedback` - Whether prompts to supply feedback are shown.
|
||||
* `UIFeature.voip` - Whether or not VoIP is shown readily to the user. When disabled,
|
||||
Jitsi widgets will still work though they cannot easily be added.
|
||||
* `UIFeature.widgets` - Whether or not widgets will be shown.
|
||||
* `UIFeature.flair` - Whether or not community flair is shown in rooms.
|
||||
* `UIFeature.communities` - Whether or not to show any UI related to communities. Implicitly
|
||||
disables `UIFeature.flair` when disabled.
|
||||
* `UIFeature.advancedSettings` - Whether or not sections titled "advanced" in room and
|
||||
user settings are shown to the user.
|
||||
* `UIFeature.shareQrCode` - Whether or not the QR code on the share room/event dialog
|
||||
is shown.
|
||||
* `UIFeature.shareSocial` - Whether or not the social icons on the share room/event dialog
|
||||
are shown.
|
||||
* `UIFeature.identityServer` - Whether or not functionality requiring an identity server
|
||||
is shown. When disabled, the user will not be able to interact with the identity
|
||||
server (sharing email addresses, 3PID invites, etc).
|
||||
* `UIFeature.thirdPartyId` - Whether or not UI relating to third party identifiers (3PIDs)
|
||||
is shown. Typically this is considered "contact information" on the homeserver, and is
|
||||
not directly related to the identity server.
|
||||
* `UIFeature.registration` - Whether or not the registration page is accessible. Typically
|
||||
useful if accounts are managed externally.
|
||||
* `UIFeature.passwordReset` - Whether or not the password reset page is accessible. Typically
|
||||
useful if accounts are managed externally.
|
||||
* `UIFeature.deactivate` - Whether or not the deactivate account button is accessible. Typically
|
||||
useful if accounts are managed externally.
|
||||
* `UIFeature.advancedEncryption` - Whether or not advanced encryption options are shown to the
|
||||
user.
|
||||
* `UIFeature.roomHistorySettings` - Whether or not the room history settings are shown to the user.
|
||||
This should only be used if the room history visibility options are managed by the server.
|
||||
* `UIFeature.TimelineEnableRelativeDates` - Display relative date separators (eg: 'Today', 'Yesterday') in the
|
||||
timeline for recent messages. When false day dates will be used.
|
||||
|
||||
## Undocumented / developer options
|
||||
|
||||
|
@ -585,4 +551,3 @@ The following are undocumented or intended for developer use only.
|
|||
2. `sync_timeline_limit`
|
||||
3. `dangerously_allow_unsafe_and_insecure_passwords`
|
||||
4. `latex_maths_delims`: An optional setting to override the default delimiters used for maths parsing. See https://github.com/matrix-org/matrix-react-sdk/pull/5939 for details. Only used when `feature_latex_maths` is enabled.
|
||||
5. `voice_broadcast.chunk_length`: Target chunk length in seconds for the Voice Broadcast feature currently under development.
|
||||
|
|
|
@ -26,6 +26,7 @@ The home page can be overridden in `config.json` to provide all users of an elem
|
|||
}
|
||||
```
|
||||
|
||||
|
||||
## `home.html` Example
|
||||
|
||||
The following is a simple example for a custom `home.html`:
|
||||
|
@ -61,3 +62,4 @@ It may be needed to set CORS headers for the `home.html` to enable element-deskt
|
|||
```
|
||||
add_header Access-Control-Allow-Origin *;
|
||||
```
|
||||
|
||||
|
|
|
@ -1,13 +1,5 @@
|
|||
# Customisations
|
||||
|
||||
### 🦖 DEPRECATED
|
||||
|
||||
Customisations have been deprecated in favour of the [Module API](https://github.com/element-hq/element-web/blob/develop/docs/modules.md).
|
||||
If you have use cases from customisations which are not yet available via the Module API please open an issue.
|
||||
Customisations will be removed from the codebase in a future release.
|
||||
|
||||
---
|
||||
|
||||
Element Web and the React SDK support "customisation points" that can be used to
|
||||
easily add custom logic specific to a particular deployment of Element Web.
|
||||
|
||||
|
@ -38,7 +30,7 @@ maintenance.
|
|||
|
||||
**Note**: The project deliberately does not exclude `customisations.json` from Git.
|
||||
This is to ensure that in shared projects it's possible to have a common config. By
|
||||
default, Element Web does _not_ ship with this file to prevent conflicts.
|
||||
default, Element Web does *not* ship with this file to prevent conflicts.
|
||||
|
||||
### Custom components
|
||||
|
||||
|
@ -49,10 +41,9 @@ that properties/state machines won't change.
|
|||
### Component visibility customisation
|
||||
|
||||
UI for some actions can be hidden via the ComponentVisibility customisation:
|
||||
|
||||
- inviting users to rooms and spaces,
|
||||
- creating rooms,
|
||||
- creating spaces,
|
||||
- inviting users to rooms and spaces,
|
||||
- creating rooms,
|
||||
- creating spaces,
|
||||
|
||||
To customise visibility create a customisation module from [ComponentVisibility](https://github.com/matrix-org/matrix-react-sdk/blob/master/src/customisations/ComponentVisibility.ts) following the instructions above.
|
||||
|
||||
|
@ -64,7 +55,6 @@ might be shown to the user, but they won't have permission to invite users to
|
|||
the current room: the button will appear disabled.
|
||||
|
||||
For example, to only allow users who meet a certain condition to create spaces:
|
||||
|
||||
```typescript
|
||||
function shouldShowComponent(component: UIComponent): boolean {
|
||||
if (component === UIComponent.CreateSpaces) {
|
||||
|
@ -75,5 +65,4 @@ function shouldShowComponent(component: UIComponent): boolean {
|
|||
return true;
|
||||
}
|
||||
```
|
||||
|
||||
In this example, all UI related to creating a space will be hidden unless the users meets the custom condition.
|
||||
|
|
40
docs/e2ee.md
40
docs/e2ee.md
|
@ -10,34 +10,12 @@ Set the following on your homeserver's
|
|||
|
||||
```json
|
||||
{
|
||||
"io.element.e2ee": {
|
||||
"default": false
|
||||
}
|
||||
"io.element.e2ee": {
|
||||
"default": false
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Disabling encryption
|
||||
|
||||
Set the following on your homeserver's
|
||||
`/.well-known/matrix/client` config:
|
||||
|
||||
```json
|
||||
{
|
||||
"io.element.e2ee": {
|
||||
"force_disable": true
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
When `force_disable` is true:
|
||||
|
||||
- all rooms will be created with encryption disabled, and it will not be possible to enable
|
||||
encryption from room settings.
|
||||
- any `io.element.e2ee.default` value will be disregarded.
|
||||
|
||||
Note: If the server is configured to forcibly enable encryption for some or all rooms,
|
||||
this behaviour will be overridden.
|
||||
|
||||
# Secure backup
|
||||
|
||||
By default, Element strongly encourages (but does not require) users to set up
|
||||
|
@ -51,9 +29,9 @@ following on your homeserver's `/.well-known/matrix/client` config:
|
|||
|
||||
```json
|
||||
{
|
||||
"io.element.e2ee": {
|
||||
"secure_backup_required": true
|
||||
}
|
||||
"io.element.e2ee": {
|
||||
"secure_backup_required": true
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
@ -66,9 +44,9 @@ only offer one of these, you can signal this via the
|
|||
|
||||
```json
|
||||
{
|
||||
"io.element.e2ee": {
|
||||
"secure_backup_setup_methods": ["passphrase"]
|
||||
}
|
||||
"io.element.e2ee": {
|
||||
"secure_backup_setup_methods": ["passphrase"]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
|
|
@ -5,10 +5,10 @@ flexibility and control over when and where those features are enabled.
|
|||
|
||||
For example, flags make the following things possible:
|
||||
|
||||
- Extended testing of a feature via labs on develop
|
||||
- Enabling features when ready instead of the first moment the code is released
|
||||
- Testing a feature with a specific set of users (by enabling only on a specific
|
||||
Element instance)
|
||||
* Extended testing of a feature via labs on develop
|
||||
* Enabling features when ready instead of the first moment the code is released
|
||||
* Testing a feature with a specific set of users (by enabling only on a specific
|
||||
Element instance)
|
||||
|
||||
The size of the feature controlled by a feature flag may vary widely: it could
|
||||
be a large project like reactions or a smaller change to an existing algorithm.
|
||||
|
@ -37,7 +37,6 @@ When starting work on a feature, we should create a matching feature flag:
|
|||
1. Add a new
|
||||
[setting](https://github.com/matrix-org/matrix-react-sdk/blob/develop/src/settings/Settings.tsx)
|
||||
of the form:
|
||||
|
||||
```js
|
||||
"feature_cats": {
|
||||
isFeature: true,
|
||||
|
@ -46,14 +45,11 @@ When starting work on a feature, we should create a matching feature flag:
|
|||
default: false,
|
||||
},
|
||||
```
|
||||
|
||||
2. Check whether the feature is enabled as appropriate:
|
||||
|
||||
```js
|
||||
SettingsStore.getValue("feature_cats");
|
||||
SettingsStore.getValue("feature_cats")
|
||||
```
|
||||
|
||||
3. Document the feature in the [labs documentation](https://github.com/element-hq/element-web/blob/develop/docs/labs.md)
|
||||
3. Document the feature in the [labs documentation](https://github.com/vector-im/element-web/blob/develop/docs/labs.md)
|
||||
|
||||
With these steps completed, the feature is disabled by default, but can be
|
||||
enabled on develop and nightly by interested users for testing.
|
||||
|
@ -64,9 +60,9 @@ The following lists a few common options.
|
|||
## Enabling by default on develop and nightly
|
||||
|
||||
Set the feature to `true` in the
|
||||
[develop](https://github.com/element-hq/element-web/blob/develop/element.io/develop/config.json)
|
||||
[develop](https://github.com/vector-im/element-web/blob/develop/element.io/develop/config.json)
|
||||
and
|
||||
[nightly](https://github.com/element-hq/element-desktop/blob/develop/element.io/nightly/config.json)
|
||||
[nightly](https://github.com/vector-im/element-desktop/blob/develop/element.io/nightly/config.json)
|
||||
configs:
|
||||
|
||||
```json
|
||||
|
@ -78,9 +74,9 @@ configs:
|
|||
## Enabling by default on staging, app, and release
|
||||
|
||||
Set the feature to `true` in the
|
||||
[staging / app](https://github.com/element-hq/element-web/blob/develop/element.io/app/config.json)
|
||||
[staging / app](https://github.com/vector-im/element-web/blob/develop/element.io/app/config.json)
|
||||
and
|
||||
[release](https://github.com/element-hq/element-desktop/blob/develop/element.io/release/config.json)
|
||||
[release](https://github.com/vector-im/element-desktop/blob/develop/element.io/release/config.json)
|
||||
configs.
|
||||
|
||||
**Note:** The above will only enable the feature for https://app.element.io and official Element
|
||||
|
@ -92,22 +88,20 @@ cover these cases, change the setting's `default` in `Settings.tsx` to `true`.
|
|||
Once we're confident that a feature is working well, we should remove or convert the flag.
|
||||
|
||||
If the feature is meant to be turned off/on by the user:
|
||||
|
||||
1. Remove `isFeature` from the [setting](https://github.com/matrix-org/matrix-react-sdk/blob/develop/src/settings/Settings.ts)
|
||||
2. Change the `default` to `true` (if desired).
|
||||
3. Remove the feature from the [labs documentation](https://github.com/element-hq/element-web/blob/develop/docs/labs.md)
|
||||
3. Remove the feature from the [labs documentation](https://github.com/vector-im/element-web/blob/develop/docs/labs.md)
|
||||
4. Celebrate! 🥳
|
||||
|
||||
If the feature is meant to be forced on (non-configurable):
|
||||
|
||||
1. Remove the [setting](https://github.com/matrix-org/matrix-react-sdk/blob/develop/src/settings/Settings.ts)
|
||||
2. Remove all `getValue` lines that test for the feature.
|
||||
3. Remove the feature from the [labs documentation](https://github.com/element-hq/element-web/blob/develop/docs/labs.md)
|
||||
3. Remove the feature from the [labs documentation](https://github.com/vector-im/element-web/blob/develop/docs/labs.md)
|
||||
4. If applicable, remove the feature state from
|
||||
[develop](https://github.com/element-hq/element-web/blob/develop/element.io/develop/config.json),
|
||||
[nightly](https://github.com/element-hq/element-desktop/blob/develop/element.io/nightly/config.json),
|
||||
[staging / app](https://github.com/element-hq/element-web/blob/develop/element.io/app/config.json),
|
||||
[develop](https://github.com/vector-im/element-web/blob/develop/element.io/develop/config.json),
|
||||
[nightly](https://github.com/vector-im/element-desktop/blob/develop/element.io/nightly/config.json),
|
||||
[staging / app](https://github.com/vector-im/element-web/blob/develop/element.io/app/config.json),
|
||||
and
|
||||
[release](https://github.com/element-hq/element-desktop/blob/develop/element.io/release/config.json)
|
||||
[release](https://github.com/vector-im/element-desktop/blob/develop/element.io/release/config.json)
|
||||
configs
|
||||
5. Celebrate! 🥳
|
||||
|
|
|
@ -1,80 +0,0 @@
|
|||
# Installing Element Web
|
||||
|
||||
**Familiarise yourself with the [Important Security Notes](../README.md#important-security-notes) before starting, they apply to all installation methods.**
|
||||
|
||||
_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._
|
||||
|
||||
## Release tarball
|
||||
|
||||
1. Download the latest version from <https://github.com/element-hq/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](config.md) for details.
|
||||
1. Enter the URL into your browser and log into Element!
|
||||
|
||||
Releases are signed using gpg and the OpenPGP standard,
|
||||
and can be checked against the public key located at <https://packages.element.io/element-release-key.asc>.
|
||||
|
||||
## Debian package
|
||||
|
||||
Element Web is now also available as a Debian package for Debian and Ubuntu based systems.
|
||||
|
||||
```shell
|
||||
sudo apt install -y wget apt-transport-https
|
||||
sudo wget -O /usr/share/keyrings/element-io-archive-keyring.gpg https://packages.element.io/debian/element-io-archive-keyring.gpg
|
||||
echo "deb [signed-by=/usr/share/keyrings/element-io-archive-keyring.gpg] https://packages.element.io/debian/ default main" | sudo tee /etc/apt/sources.list.d/element-io.list
|
||||
sudo apt update
|
||||
sudo apt install element-web
|
||||
```
|
||||
|
||||
Configure the app by modifying `/etc/element-web/config.json`. See the [configuration docs](config.md) for details.
|
||||
|
||||
Then point your chosen web server (e.g. Caddy, Nginx, Apache, etc) at the `/usr/share/element-web` webroot.
|
||||
|
||||
## 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/element-hq/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" \
|
||||
.
|
||||
```
|
||||
|
||||
## Kubernetes
|
||||
|
||||
The provided element-web docker image can also be run from within a Kubernetes cluster.
|
||||
See the [Kubernetes example](kubernetes.md) for more details.
|
|
@ -1,7 +1,7 @@
|
|||
# Jitsi wrapper developer docs
|
||||
|
||||
_If you're looking for information on how to set up Jitsi in your Element, see
|
||||
[jitsi.md](./jitsi.md) instead._
|
||||
*If you're looking for information on how to set up Jitsi in your Element, see
|
||||
[jitsi.md](./jitsi.md) instead.*
|
||||
|
||||
These docs are for developers wondering how the different conference buttons work
|
||||
within Element. If you're not a developer, you're probably looking for [jitsi.md](./jitsi.md).
|
||||
|
@ -46,24 +46,24 @@ end up creating a widget with a URL like `https://integrations.example.org?widge
|
|||
The integration manager's wrapper will typically have another iframe to isolate the
|
||||
widget from the client by yet another layer. The wrapper often provides other functionality
|
||||
which might not be available on the embedded site, such as a fullscreen button or the
|
||||
communication layer with the client (all widgets _should_ be talking to the client
|
||||
communication layer with the client (all widgets *should* be talking to the client
|
||||
over `postMessage`, even if they aren't going to be using the widget APIs).
|
||||
|
||||
Widgets added with the `/addwidget` command will _not_ be wrapped as they are not going
|
||||
through an integration manager. The widgets themselves _should_ also work outside of
|
||||
Widgets added with the `/addwidget` command will *not* be wrapped as they are not going
|
||||
through an integration manager. The widgets themselves *should* also work outside of
|
||||
Element. Widgets currently have a "pop out" button which opens them in a new tab and
|
||||
therefore have no connection back to Riot.
|
||||
|
||||
## Jitsi widgets from integration managers
|
||||
|
||||
Integration managers will create an entire widget event and send it over `postMessage`
|
||||
for the client to add to the room. This means that the integration manager gets to
|
||||
for the client to add to the room. This means that the integration manager gets to
|
||||
decide the conference domain, conference name, and other aspects of the widget. As
|
||||
a result, users can end up with a Jitsi widget that does not use the same conference
|
||||
server they specified in their config.json - this is expected.
|
||||
|
||||
Some integration managers allow the user to change the conference name while others
|
||||
will generate one for the user.
|
||||
will generate one for the user.
|
||||
|
||||
## Jitsi widgets generated by Element itself
|
||||
|
||||
|
@ -79,7 +79,7 @@ The Jitsi widget created by Element uses a local `jitsi.html` wrapper (or one ho
|
|||
required `postMessage` calls are fulfilled.
|
||||
|
||||
**Note**: Per [jitsi.md](./jitsi.md) the `preferredDomain` can also come from the server's
|
||||
client .well-known data.
|
||||
client .well-known data.
|
||||
|
||||
## The Jitsi wrapper in Element
|
||||
|
||||
|
@ -92,9 +92,9 @@ and less risky to load. The local wrapper URL is populated with the conference i
|
|||
from the original widget (which could be a v1 or v2 widget) so the user joins the right
|
||||
call.
|
||||
|
||||
Critically, when the widget URL is reconstructed it does _not_ take into account the
|
||||
Critically, when the widget URL is reconstructed it does *not* take into account the
|
||||
config.json's `preferredDomain` for Jitsi. If it did this, users would end up on different
|
||||
conference servers and therefore different calls entirely.
|
||||
conference servers and therefore different calls entirely.
|
||||
|
||||
**Note**: Per [jitsi.md](./jitsi.md) the `preferredDomain` can also come from the server's
|
||||
client .well-known data.
|
||||
|
|
|
@ -24,14 +24,13 @@ Element will use the Jitsi server that is embedded in the widget, even if it is
|
|||
one you configured. This is because conference calls must be held on a single Jitsi
|
||||
server and cannot be split over multiple servers.
|
||||
|
||||
However, you can configure Element to _start_ a conference with your Jitsi server by adding
|
||||
However, you can configure Element to *start* a conference with your Jitsi server by adding
|
||||
to your [config](./config.md) the following:
|
||||
|
||||
```json
|
||||
{
|
||||
"jitsi": {
|
||||
"preferred_domain": "your.jitsi.example.org"
|
||||
}
|
||||
"jitsi": {
|
||||
"preferredDomain": "your.jitsi.example.org"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
@ -47,12 +46,11 @@ domain will appear later in the URL as a configuration parameter.
|
|||
**Hint**: If you want everyone on your homeserver to use the same Jitsi server by
|
||||
default, and you are using element-web 1.6 or newer, set the following on your homeserver's
|
||||
`/.well-known/matrix/client` config:
|
||||
|
||||
```json
|
||||
{
|
||||
"im.vector.riot.jitsi": {
|
||||
"preferredDomain": "your.jitsi.example.org"
|
||||
}
|
||||
"im.vector.riot.jitsi": {
|
||||
"preferredDomain": "your.jitsi.example.org"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
@ -64,7 +62,7 @@ Element Android (1.0.5+) supports custom Jitsi domains, similar to Element Web a
|
|||
calls work directly between clients or via TURN servers configured on the respective
|
||||
homeservers.
|
||||
|
||||
For rooms with more than 2 joined members, when creating a Jitsi conference via call/video buttons of the toolbar (not via integration manager), Element Android will create a widget using the [wrapper](https://github.com/element-hq/element-web/blob/develop/docs/jitsi-dev.md) hosted on `app.element.io`.
|
||||
For rooms with more than 2 joined members, when creating a Jitsi conference via call/video buttons of the toolbar (not via integration manager), Element Android will create a widget using the [wrapper](https://github.com/vector-im/element-web/blob/develop/docs/jitsi-dev.md) hosted on `app.element.io`.
|
||||
The domain used is the one specified by the `/.well-known/matrix/client` endpoint, and if not present it uses the fallback defined in `config.json` (meet.element.io)
|
||||
|
||||
For active Jitsi widgets in the room, a native Jitsi widget UI is created and points to the instance specified in the `domain` key of the widget content data.
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
# Running in Kubernetes
|
||||
Running in Kubernetes
|
||||
=====================
|
||||
|
||||
In case you would like to deploy element-web in a kubernetes cluster you can use
|
||||
the provided Kubernetes example below as a starting point. Note that this example assumes the
|
||||
|
@ -162,7 +163,7 @@ Then you can deploy it to your cluster with something like `kubectl apply -f my-
|
|||
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'";
|
||||
spec:
|
||||
rules:
|
||||
- host: element.example.nl
|
||||
|
@ -177,3 +178,4 @@ Then you can deploy it to your cluster with something like `kubectl apply -f my-
|
|||
number: 80
|
||||
|
||||
---
|
||||
|
||||
|
|
105
docs/labs.md
105
docs/labs.md
|
@ -4,9 +4,6 @@ If Labs is enabled in the [Element config](config.md), you can enable some of th
|
|||
to `Settings->Labs`. This list is non-exhaustive and subject to change, chat in
|
||||
[#element-web:matrix.org](https://matrix.to/#/#element-web:matrix.org) for more information.
|
||||
|
||||
If a labs features gets more stable, it _may_ be promoted to a beta feature
|
||||
(see [Betas](https://github.com/element-hq/element-web/blob/develop/docs/betas.md)).
|
||||
|
||||
**Be warned! Labs features are not finalised, they may be fragile, they may change, they may be
|
||||
dropped. Ask in the room if you are unclear about any details here.**
|
||||
|
||||
|
@ -37,6 +34,29 @@ date from the calendar.
|
|||
|
||||
Also adds the `/jumptodate 2022-01-31` slash command.
|
||||
|
||||
## Render simple counters in room header (`feature_state_counters`)
|
||||
|
||||
Allows rendering of labelled counters above the message list.
|
||||
|
||||
Once enabled, send a custom state event to a room to set values:
|
||||
|
||||
1. In a room, type `/devtools` to bring up the devtools interface
|
||||
2. Click "Send Custom Event"
|
||||
3. Toggle from "Event" to "State Event"
|
||||
4. Set the event type to: `re.jki.counter` and give it a unique key
|
||||
5. Specify the content in the following format:
|
||||
|
||||
```
|
||||
{
|
||||
"link": "",
|
||||
"severity": "normal",
|
||||
"title": "my counter",
|
||||
"value": 0
|
||||
}
|
||||
```
|
||||
|
||||
That's it. Now should see your new counter under the header.
|
||||
|
||||
## New ways to ignore people (`feature_mjolnir`)
|
||||
|
||||
When enabled, a new settings tab appears for users to be able to manage their ban lists.
|
||||
|
@ -63,6 +83,11 @@ present in the room. The Bridge info tab pulls information from the `m.bridge` s
|
|||
bridges are not expected to be compatible, and users should not rely on this
|
||||
tab as the single source of truth just yet.
|
||||
|
||||
## Presence indicator in room list (`feature_presence_in_room_list`)
|
||||
|
||||
This adds a presence indicator in the room list next to DM rooms where the other
|
||||
person is online.
|
||||
|
||||
## Custom themes (`feature_custom_themes`)
|
||||
|
||||
Custom themes are possible through Element's [theme support](./theming.md), though
|
||||
|
@ -72,15 +97,67 @@ theme definition.
|
|||
|
||||
For some sample themes, check out [aaronraimist/element-themes](https://github.com/aaronraimist/element-themes).
|
||||
|
||||
## Message preview tweaks
|
||||
|
||||
To enable message previews in the left panel for reactions in all rooms, enable `feature_roomlist_preview_reactions_all`.
|
||||
|
||||
To enable message previews for reactions in DMs only, enable `feature_roomlist_preview_reactions_dms`. This is ignored when it is enabled for all rooms.
|
||||
|
||||
## Dehydrated devices (`feature_dehydration`)
|
||||
|
||||
Allows users to receive encrypted messages by creating a device that is stored
|
||||
encrypted on the server, as described in [MSC2697](https://github.com/matrix-org/matrix-doc/pull/2697).
|
||||
|
||||
## Breadcrumbs v2 (`feature_breadcrumbs_v2`)
|
||||
|
||||
Instead of showing the horizontal list of breadcrumbs under the filter field, the new UX is an interactive context menu
|
||||
triggered by the button to the right of the filter field.
|
||||
|
||||
## Spotlight search (`feature_spotlight`) [In Development]
|
||||
|
||||
Switches to a new room search experience.
|
||||
|
||||
## Extensible events rendering (`feature_extensible_events`) [In Development]
|
||||
|
||||
*Intended for developer use only at the moment.*
|
||||
|
||||
Extensible Events are a [new event format](https://github.com/matrix-org/matrix-doc/pull/1767) which
|
||||
supports graceful fallback in unknown event types. Instead of rendering nothing or a blank space, events
|
||||
can define a series of other events which represent the event's information but in different ways. The
|
||||
base of these fallbacks being text.
|
||||
|
||||
Turning this flag on indicates that, when possible, the extensible events structure should be parsed on
|
||||
supported event types. This should lead to zero perceptual change in the timeline except in cases where
|
||||
the sender is using unknown/unrecognised event types.
|
||||
|
||||
Sending events with extensible events structure is always enabled - this should not affect any downstream
|
||||
client.
|
||||
|
||||
## Right panel stays open (`feature_right_panel_default_open`)
|
||||
|
||||
This is an experimental default open right panel mode as a quick fix for those
|
||||
who prefer to have the right panel open consistently across rooms.
|
||||
|
||||
If no right panel state is known for the room or it was closed on the last room
|
||||
visit, it will default to the room member list. Otherwise, the saved card last
|
||||
used in that room is shown.
|
||||
|
||||
## Pin drop location sharing (`feature_location_share_pin_drop`) [In Development]
|
||||
|
||||
Enables sharing a pin drop location to the timeline.
|
||||
|
||||
## Live location sharing (`feature_location_share_live`) [In Development]
|
||||
|
||||
Enables sharing your current location to the timeline, with live updates.
|
||||
|
||||
## Threaded Messaging (`feature_thread`)
|
||||
|
||||
Threading allows users to branch out a new conversation from the main timeline of a room. This is particularly useful in high traffic rooms where multiple conversations can happen in parallel or when a single discussion might stretch over a very long period of time.
|
||||
|
||||
Threads can be access by clicking their summary below the root event on the room timeline. Users can find a comprehensive list of threads by click the icon on the room header button.
|
||||
|
||||
This feature might work in degraded mode if the homeserver a user is connected to does not advertise support for the unstable feature `org.matrix.msc3440` when calling the `/versions` API endpoint.
|
||||
|
||||
## Video rooms (`feature_video_rooms`)
|
||||
|
||||
Enables support for creating and joining video rooms, which are persistent video chats that users can jump in and out of.
|
||||
|
@ -97,27 +174,15 @@ This feature allows users to place and join native [MSC3401](https://github.com/
|
|||
|
||||
If you're enabling this at the deployment level, you may also want to reference the docs for the `element_call` config section.
|
||||
|
||||
## Disable per-sender encryption for Element Call (`feature_disable_call_per_sender_encryption`)
|
||||
|
||||
The default for embedded Element Call in Element Web is per-participant encryption.
|
||||
This labs flag disables encryption for embedded Element Call in encrypted rooms.
|
||||
|
||||
Under the hood this stops Element Web from adding the `perParticipantE2EE` flag for the Element Call widget url.
|
||||
|
||||
This is useful while we experiment with encryption and to make calling compatible with platforms that don't use encryption yet.
|
||||
|
||||
## Rich text in room topics (`feature_html_topic`) [In Development]
|
||||
|
||||
Enables rendering of MD / HTML in room topics.
|
||||
|
||||
## New room header & details (`feature_new_room_decoration_ui`) [In Development]
|
||||
## Exploring public spaces (`feature_exploring_public_spaces`)
|
||||
|
||||
Refactors visually the room header and room sidebar
|
||||
Enables exploring public spaces in the new search dialog. Requires the server to
|
||||
have [MSC3827](https://github.com/matrix-org/matrix-spec-proposals/pull/3827) enabled.
|
||||
|
||||
## Enable the notifications panel in the room header (`feature_notifications`)
|
||||
## Favourite Messages (`feature_favourite_messages`) [In Development]
|
||||
|
||||
Unreliable in encrypted rooms.
|
||||
|
||||
## Knock rooms (`feature_ask_to_join`) [In Development]
|
||||
|
||||
Enables knock feature for rooms. This allows users to ask to join a room.
|
||||
Enables users to bookmark a message or content for a later reference.
|
||||
|
|
|
@ -1,14 +0,0 @@
|
|||
/* Prevent collapsible headings from wrapping onto two lines eagerly */
|
||||
summary > h1,
|
||||
summary > h2,
|
||||
summary > h3,
|
||||
summary > h4,
|
||||
summary > h5,
|
||||
summary > h6 {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
/* Prevent longer checkbox lists from wrapping eagerly */
|
||||
input + p {
|
||||
display: inline;
|
||||
}
|
|
@ -1 +0,0 @@
|
|||
mermaid.initialize({ startOnLoad:true });
|
1648
docs/lib/mermaid.min.js
vendored
1648
docs/lib/mermaid.min.js
vendored
File diff suppressed because one or more lines are too long
|
@ -1,11 +1,11 @@
|
|||
## Memory leaks
|
||||
|
||||
Element usually emits slow behaviour just before it is about to crash. Getting a
|
||||
Element usually emits slow behaviour just before it is about to crash. Getting a
|
||||
memory snapshot (below) just before that happens is ideal in figuring out what
|
||||
is going wrong.
|
||||
|
||||
Common symptoms are clicking on a room and it feels like the tab froze and scrolling
|
||||
becoming jumpy/staggered.
|
||||
becoming jumpy/staggered.
|
||||
|
||||
If you receive a white screen (electron) or the chrome crash page, it is likely
|
||||
run out of memory and it is too late for a memory profile. Please do report when
|
||||
|
@ -22,8 +22,8 @@ and anything newer is still in the warmup stages of the app.
|
|||
|
||||
**Memory profiles can contain sensitive information.** If you are submitting a memory
|
||||
profile to us for debugging purposes, please pick the appropriate Element developer and
|
||||
send them over an encrypted private message. _Do not share your memory profile in
|
||||
public channels or with people you do not trust._
|
||||
send them over an encrypted private message. *Do not share your memory profile in
|
||||
public channels or with people you do not trust.*
|
||||
|
||||
### Taking a memory profile (Firefox)
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@ at runtime.
|
|||
|
||||
## Installing modules
|
||||
|
||||
If you already have a module you want to install, such as our [ILAG Module](https://github.com/element-hq/element-web-ilag-module),
|
||||
If you already have a module you want to install, such as our [ILAG Module](https://github.com/vector-im/element-web-ilag-module),
|
||||
then copy `build_config.sample.yaml` to `build_config.yaml` in the same directory. In your new `build_config.yaml` simply
|
||||
add the reference to the module as described by the sample file, using the same syntax you would for `yarn add`:
|
||||
|
||||
|
@ -30,18 +30,15 @@ Once your change to the module API is accepted, the `@matrix-org/react-sdk-modul
|
|||
`matrix-react-sdk` and `element-web` layers (usually by us, the maintainers) to ensure your module can operate.
|
||||
|
||||
If you're not adding anything to the module API, or your change was accepted per above, then start off with a clone of
|
||||
our [ILAG module](https://github.com/element-hq/element-web-ilag-module) which will give you a general idea for what the
|
||||
our [ILAG module](https://github.com/vector-im/element-web-ilag-module) which will give you a general idea for what the
|
||||
structure of a module is and how it works.
|
||||
|
||||
The following requirements are key for any module:
|
||||
|
||||
1. The module must depend on `@matrix-org/react-sdk-module-api` (usually as a dev dependency).
|
||||
2. The module's `main` entrypoint must have a `default` export for the `RuntimeModule` instance, supporting a constructor
|
||||
which takes a single parameter: a `ModuleApi` instance. This instance is passed to `super()`.
|
||||
3. The module must be deployed in a way where `yarn add` can access it, as that is how the build system will try to
|
||||
install it. Note that while this is often NPM, it can also be a GitHub/GitLab repo or private NPM registry.
|
||||
Be careful when using git dependencies in yarn classic, many lifecycle scripts will not be executed which may mean
|
||||
that your module is not built and thus may fail to be imported.
|
||||
|
||||
... and that's pretty much it. As with any code, please be responsible and call things in line with the documentation.
|
||||
Both `RuntimeModule` and `ModuleApi` have extensive documentation to describe what is proper usage and how to set things
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
# Native Node Modules
|
||||
|
||||
This documentation moved to the [`element-desktop`](https://github.com/element-hq/element-desktop/blob/develop/docs/native-node-modules.md) repository.
|
||||
This documentation moved to the [`element-desktop`](https://github.com/vector-im/element-desktop/blob/develop/docs/native-node-modules.md) repository.
|
||||
|
|
43
docs/oidc.md
43
docs/oidc.md
|
@ -1,43 +0,0 @@
|
|||
# OIDC and delegated authentication
|
||||
|
||||
## Compatibility/OIDC-aware mode
|
||||
|
||||
[MSC2965: OIDC provider discovery](https://github.com/matrix-org/matrix-spec-proposals/pull/2965)
|
||||
[MSC3824: OIDC aware clients](https://github.com/matrix-org/matrix-spec-proposals/pull/3824)
|
||||
This mode uses an SSO flow to gain a `loginToken` from the authentication provider, then continues with SSO login.
|
||||
Element Web uses [MSC2965: OIDC provider discovery](https://github.com/matrix-org/matrix-spec-proposals/pull/2965) to discover the configured provider.
|
||||
Wherever valid MSC2965 configuration is discovered, OIDC-aware login flow will be the only option offered.
|
||||
|
||||
## (🧪Experimental) OIDC-native flow
|
||||
|
||||
Can be enabled by a config-level-only setting in `config.json`
|
||||
|
||||
```json
|
||||
{
|
||||
"features": {
|
||||
"feature_oidc_native_flow": true
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
See https://areweoidcyet.com/client-implementation-guide/ for implementation details.
|
||||
|
||||
Element Web uses [MSC2965: OIDC provider discovery](https://github.com/matrix-org/matrix-spec-proposals/pull/2965) to discover the configured provider.
|
||||
Where OIDC native login flow is enabled and valid MSC2965 configuration is discovered, OIDC native login flow will be the only login option offered.
|
||||
Element Web will attempt to [dynamically register](https://openid.net/specs/openid-connect-registration-1_0.html) with the configured OP.
|
||||
Then, authentication will be completed [as described here](https://areweoidcyet.com/client-implementation-guide/).
|
||||
|
||||
#### Statically configured OIDC clients
|
||||
|
||||
Clients that are already registered with the OP can configure their `client_id` in `config.json`.
|
||||
Where static configuration exists for the OP dynamic client registration will not be attempted.
|
||||
|
||||
```json
|
||||
{
|
||||
"oidc_static_clients": {
|
||||
"https://dummyoidcprovider.com/": {
|
||||
"client_id": "abc123"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
270
docs/release.md
270
docs/release.md
|
@ -1,270 +0,0 @@
|
|||
> Tip: Paste this into the browser console to make the checkboxes on this page tickable. (Bear in mind that your ticks will be lost if you reload though.)
|
||||
>
|
||||
> ```
|
||||
> document.querySelectorAll("input[type='checkbox']").forEach(i => {i.disabled = false;})
|
||||
> ```
|
||||
|
||||
<details><summary><h1>Branches</h1></summary><blockquote>
|
||||
|
||||
#### develop
|
||||
|
||||
The develop branch holds the very latest and greatest code we have to offer, as such it may be less stable. It corresponds to the develop.element.io CD platform.
|
||||
|
||||
#### staging
|
||||
|
||||
The staging branch corresponds to the very latest release regardless of whether it is an RC or not. Deployed to staging.element.io manually.
|
||||
|
||||
#### master
|
||||
|
||||
The master branch is the most stable as it is the very latest non-RC release. Deployed to app.element.io manually.
|
||||
|
||||
</blockquote></details>
|
||||
|
||||
<details><summary><h1>Versions</h1></summary><blockquote>
|
||||
|
||||
The matrix-js-sdk follows semver, the matrix-react-sdk loosely follows semver, most releases for both will bump the minor version number.
|
||||
Breaking changes will bump the major version number.
|
||||
Element Web & Element Desktop do not follow semver and always have matching version numbers. The patch version number is normally incremented for every release.
|
||||
|
||||
</blockquote></details>
|
||||
|
||||
<details><summary><h1>Release Types</h1></summary><blockquote>
|
||||
|
||||
#### Release candidate
|
||||
|
||||
A normal release begins with a Release Candidate on the Tick phase of the release cycle,
|
||||
and may contain as many further RCs as are needed before the Tock phase of cycle.
|
||||
Each subsequent RC may add additional commits via any of the means of preparation.
|
||||
|
||||
A normal release is the most typical run-of-the-mill release,
|
||||
with at least one RC (Release Candidate) followed by a FINAL release.
|
||||
The typical cadence for these is every 2 weeks we'll do a new initial RC,
|
||||
then the following week we'll do that release cycle's FINAL release with sometimes more RCs in between, as needed.
|
||||
|
||||
#### Final
|
||||
|
||||
A normal release culminates with a Final release on the Tock phase of the cycle.
|
||||
This may be merely shipping the very latest RC with an adjusted version number,
|
||||
but can also include (hopefully small) additional changes present on `staging` if they are deemed safe to skip an RC.
|
||||
|
||||
### Hotfix / Security
|
||||
|
||||
This is an accelerated type of release which sits somewhere between RC and Final.
|
||||
They tend to contain few patches delta from the previous release but also skip any form of RC
|
||||
and in the case of Security the patch lands on GitHub only moments prior.
|
||||
For all intents and purposes they are the same as a Final release but with a different purpose.
|
||||
|
||||
</blockquote></details>
|
||||
|
||||
<details><summary><h1>Release Blockers</h1></summary><blockquote>
|
||||
|
||||
You should become release rabbit on the day after the last full release.
|
||||
For that week, it's your job to keep an eye on the Releases room and see whether any issues marked `X-Release-Blocker` are opened,
|
||||
or were already open. You should chase people to fix them, so that on RC day you can make the release.
|
||||
|
||||
If release-blocking issues are still open, you need to delay the release until they are fixed or reclassified.
|
||||
|
||||
There are two labels for tracking release blockers.
|
||||
|
||||
#### X-Release-Blocker
|
||||
|
||||
This label applied to an issue means we cannot ship a release affected by the specific issue.
|
||||
This means we cannot cut branches for an RC but security & hotfix releases may still be fine.
|
||||
|
||||
#### X-Upcoming-Release-Blocker
|
||||
|
||||
This label applied to an issue means that the next (read: not current) release cycle will be affected by the specific issue.
|
||||
This label will automagically convert to `X-Release-Blocker` at the conclusion of a full release.
|
||||
|
||||
</blockquote></details>
|
||||
|
||||
<details><summary><h1>Repositories</h1></summary><blockquote>
|
||||
|
||||
This release process revolves around our four main repositories:
|
||||
|
||||
- [Element Desktop](https://github.com/element-hq/element-desktop/)
|
||||
- [Element Web](https://github.com/element-hq/element-web/)
|
||||
- [Matrix React SDK](https://github.com/matrix-org/matrix-react-sdk/)
|
||||
- [Matrix JS SDK](https://github.com/matrix-org/matrix-js-sdk/)
|
||||
|
||||
We own other repositories, but they have more ad-hoc releases and are not part of the bi-weekly cycle:
|
||||
|
||||
- https://github.com/matrix-org/matrix-web-i18n/
|
||||
- https://github.com/matrix-org/matrix-react-sdk-module-api
|
||||
|
||||
</blockquote></details>
|
||||
|
||||
<details><summary><h1>Prerequisites</h1></summary><blockquote>
|
||||
|
||||
- You must be part of the 2 Releasers GitHub groups:
|
||||
- <https://github.com/orgs/element-hq/teams/element-web-releasers>
|
||||
- <https://github.com/orgs/matrix-org/teams/element-web-releasers>
|
||||
- You will need access to the **VPN** ([docs](https://gitlab.matrix.org/new-vector/internal/-/wikis/SRE/Tailscale)) to be able to follow the instructions under Deploy below.
|
||||
- You will need the ability to **SSH** in to the production machines to be able to follow the instructions under Deploy below. Ensure that your SSH key has a non-empty passphrase, and you registered your SSH key with Ops. Log a ticket at https://github.com/matrix-org/matrix-ansible-private and ask for:
|
||||
- Two-factor authentication to be set up on your SSH key. (This is needed to get access to production).
|
||||
- SSH access to `horme` (staging.element.io and app.element.io)
|
||||
- Permission to sudo on horme as the user `element`
|
||||
- You need "**jumphost**" configuration in your local `~/.ssh/config`. This should have been set up as part of your onboarding.
|
||||
|
||||
</blockquote></details>
|
||||
|
||||
<details><summary><h1>Overview</h1></summary><blockquote>
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
P[[Prepare staging branches]]
|
||||
P --> R1
|
||||
|
||||
subgraph Releasing
|
||||
R1[[Releasing matrix-js-sdk]]
|
||||
R2[[Releasing matrix-react-sdk]]
|
||||
R3[[Releasing element-web]]
|
||||
R4[[Releasing element-desktop]]
|
||||
|
||||
R1 --> R2 --> R3 --> R4
|
||||
end
|
||||
|
||||
R4 --> D1
|
||||
|
||||
subgraph Deploying
|
||||
D1[\Deploy staging.element.io/]
|
||||
D2[\Check dockerhub/]
|
||||
D3[\Deploy app.element.io/]
|
||||
D4[\Check desktop package/]
|
||||
|
||||
D1 --> D2 --> D
|
||||
D{FINAL?}
|
||||
D -->|Yes| D3 --> D4
|
||||
end
|
||||
|
||||
D -->|No| H1
|
||||
D4 --> H1
|
||||
|
||||
subgraph Housekeeping
|
||||
H1[\Update topics/]
|
||||
H2[\Announce/]
|
||||
H3[\Archive done column/]
|
||||
H4[\Add diary entry/]
|
||||
H5[\Renovate/]
|
||||
|
||||
H1 --> H2 --> H
|
||||
|
||||
H{FINAL?}
|
||||
H -->|Yes| H3 --> H4 --> DONE
|
||||
H -->|No| H5
|
||||
end
|
||||
|
||||
DONE([You are done!])
|
||||
H5 --> DONE
|
||||
```
|
||||
|
||||
</blockquote></details>
|
||||
|
||||
---
|
||||
|
||||
# Preparation
|
||||
|
||||
The goal of this stage is to get the code you want to ship onto the `staging` branch.
|
||||
There are multiple ways to accomplish this depending on the type of release you need to perform.
|
||||
|
||||
For the first RC in a given release cycle the easiest way to prepare branches is using the
|
||||
[Cut branches automation](https://github.com/element-hq/element-web/actions/workflows/release_prepare.yml) -
|
||||
this will take `develop` and merge it into the `staging` on the chosen repositories.
|
||||
|
||||
For subsequent RCs, if you need to include a change you may PR it directly to the `staging` branch or rely on the
|
||||
backport automation via labelling a PR to `develop` with `backport staging` which will cause a new PR to be opened
|
||||
which backports the requested change to the `staging` branch.
|
||||
|
||||
For security, you may wish to merge the security advisory private fork or apply the patches manually and then push them directly to `staging`.
|
||||
It is worth noting that at the end of the Final/Hotfix/Security release `staging` is merged to `master` which is merged back into `develop` -
|
||||
this means that any commit which goes to `staging` will eventually make its way back to the default branch.
|
||||
|
||||
- [ ] The staging branch is prepared
|
||||
|
||||
# Releasing
|
||||
|
||||
Shortly after concluding the preparation stage (or pushing any changes to `staging` in general);
|
||||
a draft release will be automatically made on the 4 project repositories with suggested changelogs and version numbers.
|
||||
|
||||
_Note: we should add a step here to write summaries atop the changelogs manually, or via AI_
|
||||
|
||||
Publishing the SDKs to npm also commits a dependency upgrade to the relevant downstream projects,
|
||||
if you skip a layer of this release (e.g. for a hotfix) then the dependency will remain on `#develop` which will be
|
||||
switched back to the version of the dependency from the master branch to not leak develop code into a release.
|
||||
|
||||
### Matrix JS SDK
|
||||
|
||||
- [ ] Check the draft release which has been generated by [the automation](https://github.com/matrix-org/matrix-js-sdk/actions/workflows/release-drafter.yml)
|
||||
- [ ] Make any changes to the release notes in the draft release as are necessary - **Do not click publish, only save draft**
|
||||
- [ ] Kick off a release using [the automation](https://github.com/matrix-org/matrix-js-sdk/actions/workflows/release.yml) - making sure to select the right type of release. For anything other than an RC: choose final. You should not need to ever switch off either of the Publishing options.
|
||||
|
||||
### Matrix React SDK
|
||||
|
||||
- [ ] Check the draft release which has been generated by [the automation](https://github.com/matrix-org/matrix-react-sdk/actions/workflows/release-drafter.yml)
|
||||
- [ ] Make any changes to the release notes in the draft release as are necessary - **Do not click publish, only save draft**
|
||||
- [ ] Kick off a release using [the automation](https://github.com/matrix-org/matrix-react-sdk/actions/workflows/release.yml) - making sure to select the right type of release. For anything other than an RC: choose final. You should not need to ever switch off either of the Publishing options.
|
||||
|
||||
### Element Web
|
||||
|
||||
- [ ] Check the draft release which has been generated by [the automation](https://github.com/element-hq/element-web/actions/workflows/release-drafter.yml)
|
||||
- [ ] Make any changes to the release notes in the draft release as are necessary - **Do not click publish, only save draft**
|
||||
- [ ] Kick off a release using [the automation](https://github.com/element-hq/element-web/actions/workflows/release.yml) - making sure to select the right type of release. For anything other than an RC: choose final. You should not need to ever switch off either of the Publishing options.
|
||||
|
||||
### Element Desktop
|
||||
|
||||
- [ ] Check the draft release which has been generated by [the automation](https://github.com/element-hq/element-desktop/actions/workflows/release-drafter.yml)
|
||||
- [ ] Make any changes to the release notes in the draft release as are necessary - **Do not click publish, only save draft**
|
||||
- [ ] Kick off a release using [the automation](https://github.com/element-hq/element-desktop/actions/workflows/release.yml) - making sure to select the right type of release. For anything other than an RC: choose final. You should not need to ever switch off either of the Publishing options.
|
||||
|
||||
# Deploying
|
||||
|
||||
We ship the SDKs to npm, this happens as part of the release process.
|
||||
We ship Element Web to dockerhub, `*.element.io`, and packages.element.io.
|
||||
We ship Element Desktop to packages.element.io.
|
||||
|
||||
- [ ] Check that element-web has shipped to dockerhub
|
||||
- [ ] Deploy staging.element.io. [See docs.](https://handbook.element.io/books/element-web-team/page/deploying-appstagingelementio)
|
||||
- [ ] Test staging.element.io
|
||||
|
||||
For final releases additionally do these steps:
|
||||
|
||||
- [ ] Deploy app.element.io. [See docs.](https://handbook.element.io/books/element-web-team/page/deploying-appstagingelementio)
|
||||
- [ ] Test app.element.io
|
||||
- [ ] Ensure Element Web package has shipped to packages.element.io
|
||||
- [ ] Ensure Element Desktop packages have shipped to packages.element.io
|
||||
|
||||
# Housekeeping
|
||||
|
||||
We have some manual housekeeping to do in order to prepare for the next release.
|
||||
|
||||
- [ ] Update topics using [the automation](https://github.com/element-hq/element-web/actions/workflows/update-topics.yaml). It will autodetect the current latest version. Don't forget the date you supply should be e.g. September 5th (including the "th") for the script to work.
|
||||
- [ ] Announce the release in [#element-web-announcements:matrix.org](https://matrix.to/#/#element-web-announcements:matrix.org)
|
||||
|
||||
<details><summary>(show)</summary>
|
||||
|
||||
With wording like:
|
||||
|
||||
> Element Web v1.11.24 is here!
|
||||
>
|
||||
> This version adds ... and fixes bugs ...
|
||||
>
|
||||
> Check it out at app.element.io, in Element Desktop, or from Docker Hub. Changelog and more details at https://github.com/element-hq/element-web/releases/tag/v1.11.24
|
||||
|
||||
</details>
|
||||
|
||||
For the first RC of a given release cycle do these steps:
|
||||
|
||||
- [ ] Go to the [matrix-js-sdk Renovate dashboard](https://github.com/matrix-org/matrix-js-sdk/issues/2406) and click the checkbox to create/update its PRs.
|
||||
|
||||
- [ ] Go to the [matrix-react-sdk Renovate dashboard](https://github.com/matrix-org/matrix-react-sdk/issues/9667) and click the checkbox to create/update its PRs.
|
||||
|
||||
- [ ] Go to the [element-web Renovate dashboard](https://github.com/element-hq/element-web/issues/22941) and click the checkbox to create/update its PRs.
|
||||
|
||||
- [ ] Go to the [element-desktop Renovate dashboard](https://github.com/element-hq/element-desktop/issues/465) and click the checkbox to create/update its PRs.
|
||||
|
||||
- [ ] Later, check back and merge the PRs that succeeded to build. The ones that failed will get picked up by the [maintainer](https://docs.google.com/document/d/1V5VINWXATMpz9UBw4IKmVVB8aw3CxM0Jt7igtHnDfSk/edit#).
|
||||
|
||||
For final releases additionally do these steps:
|
||||
|
||||
- [ ] Archive done column on the [team board](https://github.com/orgs/element-hq/projects/67/views/34) _Note: this should be automated_
|
||||
- [ ] Add entry to the [milestones diary](https://docs.google.com/document/d/1cpRFJdfNCo2Ps6jqzQmatzbYEToSrQpyBug0aP_iwZE/edit#heading=h.6y55fw4t283z). The document says only to add significant releases, but we add all of them just in case.
|
|
@ -10,53 +10,53 @@ When reviewing code, here are some things we look for and also things we avoid:
|
|||
|
||||
### We review for
|
||||
|
||||
- Correctness
|
||||
- Performance
|
||||
- Accessibility
|
||||
- Security
|
||||
- Quality via automated and manual testing
|
||||
- Comments and documentation where needed
|
||||
- Sharing knowledge of different areas among the team
|
||||
- Ensuring it's something we're comfortable maintaining for the long term
|
||||
- Progress indicators and local echo where appropriate with network activity
|
||||
* Correctness
|
||||
* Performance
|
||||
* Accessibility
|
||||
* Security
|
||||
* Quality via automated and manual testing
|
||||
* Comments and documentation where needed
|
||||
* Sharing knowledge of different areas among the team
|
||||
* Ensuring it's something we're comfortable maintaining for the long term
|
||||
* Progress indicators and local echo where appropriate with network activity
|
||||
|
||||
### We should avoid
|
||||
|
||||
- Style nits that are already handled by the linter
|
||||
- Dramatically increasing scope
|
||||
* Style nits that are already handled by the linter
|
||||
* Dramatically increasing scope
|
||||
|
||||
### Good practices
|
||||
|
||||
- Use empathetic language
|
||||
- See also [Mindful Communication in Code
|
||||
Reviews](https://kickstarter.engineering/a-guide-to-mindful-communication-in-code-reviews-48aab5282e5e)
|
||||
and [How to Do Code Reviews Like a Human](https://mtlynch.io/human-code-reviews-1/)
|
||||
- Authors should prefer smaller commits for easier reviewing and bisection
|
||||
- Reviewers should be explicit about required versus optional changes
|
||||
- Reviews are conversations and the PR author should feel comfortable
|
||||
discussing and pushing back on changes before making them
|
||||
- Reviewers are encouraged to ask for tests where they believe it is reasonable
|
||||
- Core team should lead by example through their tone and language
|
||||
- Take the time to thank and point out good code changes
|
||||
- Using softer language like "please" and "what do you think?" goes a long way
|
||||
towards making others feel like colleagues working towards a common goal
|
||||
* Use empathetic language
|
||||
* See also [Mindful Communication in Code
|
||||
Reviews](https://kickstarter.engineering/a-guide-to-mindful-communication-in-code-reviews-48aab5282e5e)
|
||||
and [How to Do Code Reviews Like a Human](https://mtlynch.io/human-code-reviews-1/)
|
||||
* Authors should prefer smaller commits for easier reviewing and bisection
|
||||
* Reviewers should be explicit about required versus optional changes
|
||||
* Reviews are conversations and the PR author should feel comfortable
|
||||
discussing and pushing back on changes before making them
|
||||
* Reviewers are encouraged to ask for tests where they believe it is reasonable
|
||||
* Core team should lead by example through their tone and language
|
||||
* Take the time to thank and point out good code changes
|
||||
* Using softer language like "please" and "what do you think?" goes a long way
|
||||
towards making others feel like colleagues working towards a common goal
|
||||
|
||||
### Workflow
|
||||
|
||||
- Authors should request review from the element-web team by default (if someone on
|
||||
the team is clearly the expert in an area, a direct review request to them may
|
||||
be more appropriate)
|
||||
- Reviewers should remove the team review request and request review from
|
||||
themselves when starting a review to avoid double review
|
||||
- If there are multiple related PRs authors should reference each of the PRs in
|
||||
the others before requesting review. Reviewers might start reviewing from
|
||||
different places and could miss other required PRs.
|
||||
- Avoid force pushing to a PR after the first round of review
|
||||
- Use the GitHub default of merge commits when landing (avoid alternate options
|
||||
like squash or rebase)
|
||||
- PR author merges after review (assuming they have write access)
|
||||
- Assign issues only when in progress to indicate to others what can be picked
|
||||
up
|
||||
* Authors should request review from the element-web team by default (if someone on
|
||||
the team is clearly the expert in an area, a direct review request to them may
|
||||
be more appropriate)
|
||||
* Reviewers should remove the team review request and request review from
|
||||
themselves when starting a review to avoid double review
|
||||
* If there are multiple related PRs authors should reference each of the PRs in
|
||||
the others before requesting review. Reviewers might start reviewing from
|
||||
different places and could miss other required PRs.
|
||||
* Avoid force pushing to a PR after the first round of review
|
||||
* Use the GitHub default of merge commits when landing (avoid alternate options
|
||||
like squash or rebase)
|
||||
* PR author merges after review (assuming they have write access)
|
||||
* Assign issues only when in progress to indicate to others what can be picked
|
||||
up
|
||||
|
||||
## Code Quality
|
||||
|
||||
|
@ -64,10 +64,10 @@ In the past, we have occasionally written different kinds of tests for
|
|||
Element and the SDKs, but it hasn't been a consistent focus. Going forward, we'd
|
||||
like to change that.
|
||||
|
||||
- For new features, code reviewers will expect some form of automated testing to
|
||||
be included by default
|
||||
- For bug fixes, regression tests are of course great to have, but we don't want
|
||||
to block fixes on this, so we won't require them at this time
|
||||
* For new features, code reviewers will expect some form of automated testing to
|
||||
be included by default
|
||||
* For bug fixes, regression tests are of course great to have, but we don't want
|
||||
to block fixes on this, so we won't require them at this time
|
||||
|
||||
The above policy is not a strict rule, but instead it's meant to be a
|
||||
conversation between the author and reviewer. As an author, try to think about
|
||||
|
@ -104,10 +104,10 @@ perspective.
|
|||
In more detail, our usual process for changes that affect the UI or alter user
|
||||
functionality is:
|
||||
|
||||
- For changes that will go live when merged, always flag Design and Product
|
||||
teams as appropriate
|
||||
- For changes guarded by a feature flag, Design and Product review is not
|
||||
required (though may still be useful) since we can continue tweaking
|
||||
* For changes that will go live when merged, always flag Design and Product
|
||||
teams as appropriate
|
||||
* For changes guarded by a feature flag, Design and Product review is not
|
||||
required (though may still be useful) since we can continue tweaking
|
||||
|
||||
As it can be difficult to review design work from looking at just the changed
|
||||
files in a PR, a [preview site](./pr-previews.md) that includes your changes
|
||||
|
|
|
@ -1,29 +1,31 @@
|
|||
# Theming Element
|
||||
Theming Element
|
||||
============
|
||||
|
||||
Themes are a very basic way of providing simple alternative look & feels to the
|
||||
Element app via CSS & custom imagery.
|
||||
|
||||
They are _NOT_ co be confused with 'skins', which describe apps which sit on top
|
||||
They are *NOT* co be confused with 'skins', which describe apps which sit on top
|
||||
of matrix-react-sdk - e.g. in theory Element itself is a react-sdk skin.
|
||||
As of March 2022, skins are not fully supported; Element is the only available skin.
|
||||
|
||||
To define a theme for Element:
|
||||
|
||||
1. Pick a name, e.g. `teal`. at time of writing we have `light` and `dark`.
|
||||
2. Fork `src/skins/vector/css/themes/dark.pcss` to be `teal.pcss`
|
||||
3. Fork `src/skins/vector/css/themes/_base.pcss` to be `_teal.pcss`
|
||||
4. Override variables in `_teal.pcss` as desired. You may wish to delete ones
|
||||
1. Pick a name, e.g. `teal`. at time of writing we have `light` and `dark`.
|
||||
2. Fork `src/skins/vector/css/themes/dark.pcss` to be `teal.pcss`
|
||||
3. Fork `src/skins/vector/css/themes/_base.pcss` to be `_teal.pcss`
|
||||
4. Override variables in `_teal.pcss` as desired. You may wish to delete ones
|
||||
which don't differ from `_base.pcss`, to make it clear which are being
|
||||
overridden. If every single colour is being changed (as per `_dark.pcss`)
|
||||
then you might as well keep them all.
|
||||
5. Add the theme to the list of entrypoints in webpack.config.js
|
||||
6. Add the theme to the list of themes in matrix-react-sdk's UserSettings.js
|
||||
7. Sit back and admire your handywork.
|
||||
5. Add the theme to the list of entrypoints in webpack.config.js
|
||||
6. Add the theme to the list of themes in matrix-react-sdk's UserSettings.js
|
||||
7. Sit back and admire your handywork.
|
||||
|
||||
In future, the assets for a theme will probably be gathered together into a
|
||||
single directory tree.
|
||||
|
||||
# Custom Themes
|
||||
Custom Themes
|
||||
=============
|
||||
|
||||
Themes derived from the built in themes may also be defined in settings.
|
||||
|
||||
|
@ -31,7 +33,7 @@ To avoid name collisions, the internal name of a theme is
|
|||
`custom-${theme.name}`. So if you want to set the custom theme below as the
|
||||
default theme, you would use `default_theme: "custom-Electric Blue"`.
|
||||
|
||||
e.g. in config.json:
|
||||
eg. in config.json:
|
||||
|
||||
```
|
||||
"setting_defaults": {
|
||||
|
@ -63,10 +65,8 @@ e.g. in config.json:
|
|||
"timeline-text-color": "#2e2f32",
|
||||
"timeline-text-secondary-color": "#61708b",
|
||||
"timeline-highlights-color": "#f3f8fd",
|
||||
},
|
||||
"compound": {
|
||||
"--cpd-color-icon-accent-tertiary": "var(--cpd-color-blue-800)",
|
||||
"--cpd-color-text-action-accent": "var(--cpd-color-blue-900)"
|
||||
"username-colors": ["#ff0000", ...]
|
||||
"avatar-background-colors": ["#cc0000", ...]
|
||||
}
|
||||
}, {
|
||||
"name": "Deep Purple",
|
||||
|
@ -91,6 +91,8 @@ e.g. in config.json:
|
|||
}
|
||||
```
|
||||
|
||||
`compound` may contain overrides for any [semantic design token](https://compound.element.io/?path=/docs/tokens-semantic-colors--docs) belonging to our design system. The above example shows how you might change the accent color to blue by setting the relevant semantic tokens to refer to blue [base tokens](https://compound.element.io/?path=/docs/tokens-color-palettes--docs).
|
||||
`username-colors` is expected to contain 8 colors. `avatar-background-colors` is expected to contain 3 colors. Both values are optional and have fallbacks from the built-in theme.
|
||||
|
||||
These are exposed as `--username-colors_0`, ... and `--avatar-background-colors_0`, ... respectively in CSS.
|
||||
|
||||
All properties in `fonts` are optional, and will default to the standard Riot fonts.
|
||||
|
|
|
@ -2,25 +2,19 @@
|
|||
|
||||
## Requirements
|
||||
|
||||
- A working [Development Setup](../README.md#setting-up-a-dev-environment)
|
||||
- Including up-to-date versions of matrix-react-sdk and matrix-js-sdk
|
||||
- Latest LTS version of Node.js installed
|
||||
- Be able to understand English
|
||||
- A working [Development Setup](../README.md#setting-up-a-dev-environment)
|
||||
- Including up-to-date versions of matrix-react-sdk and matrix-js-sdk
|
||||
- Latest LTS version of Node.js installed
|
||||
- Be able to understand English
|
||||
- Be able to understand the language you want to translate Element into
|
||||
|
||||
## Translating strings vs. marking strings for translation
|
||||
|
||||
Translating strings are done with the `_t()` function found in matrix-react-sdk/lib/languageHandler.js.
|
||||
It is recommended to call this function wherever you introduce a string constant which should be translated.
|
||||
However, translating can not be performed until after the translation system has been initialized.
|
||||
Thus, sometimes translation must be performed at a different location in the source code than where the string is introduced.
|
||||
This breaks some tooling and makes it difficult to find translatable strings.
|
||||
Therefore, there is the alternative `_td()` function which is used to mark strings for translation,
|
||||
without actually performing the translation (which must still be performed separately, and after the translation system has been initialized).
|
||||
Translating strings are done with the `_t()` function found in matrix-react-sdk/lib/languageHandler.js. It is recommended to call this function wherever you introduce a string constant which should be translated. However, translating can not be performed until after the translation system has been initialized. Thus, sometimes translation must be performed at a different location in the source code than where the string is introduced. This breaks some tooling and makes it difficult to find translatable strings. Therefore, there is the alternative `_td()` function which is used to mark strings for translation, without actually performing the translation (which must still be performed separately, and after the translation system has been initialized).
|
||||
|
||||
Basically, whenever a translatable string is introduced, you should call either `_t()` immediately OR `_td()` and later `_t()`.
|
||||
|
||||
Example:
|
||||
|
||||
```
|
||||
// Module-level constant
|
||||
const COLORS = {
|
||||
|
@ -34,49 +28,36 @@ function getColorName(hex) {
|
|||
}
|
||||
```
|
||||
|
||||
## Key naming rules
|
||||
|
||||
These rules are based on https://github.com/element-hq/element-x-android/blob/develop/tools/localazy/README.md
|
||||
At this time we are not trying to have a translation key per UI element as some methodologies use,
|
||||
whilst that would offer the greatest flexibility, it would also make reuse between projects nigh impossible.
|
||||
We are aiming for a set of common strings to be shared then some more localised translations per context they may appear in.
|
||||
|
||||
1. Ensure the string doesn't already exist in a related project, such as https://localazy.com/p/element
|
||||
2. Keys for common strings, i.e. strings that can be used at multiple places must start by `action_` if this is a verb, or `common_` if not
|
||||
3. Keys for common accessibility strings must start by `a11y_`. Example: `a11y_hide_password`
|
||||
4. Otherwise, try to group keys logically and nest where appropriate, such as `keyboard_` for strings relating to keyboard shortcuts.
|
||||
5. Ensure your translation keys do not include `.` or `|` or ` `. Try to balance string length against descriptiveness.
|
||||
|
||||
## Adding new strings
|
||||
|
||||
1. Check if the import `import { _t } from 'matrix-react-sdk/src/languageHandler';` is present. If not add it to the other import statements. Also import `_td` if needed.
|
||||
1. Add `_t()` to your string passing the translation key you come up with based on the rules above. If the string is introduced at a point before the translation system has not yet been initialized, use `_td()` instead, and call `_t()` at the appropriate time.
|
||||
1. Run `yarn i18n` to add the keys to `src/i18n/strings/en_EN.json`
|
||||
1. Modify the new entries in `src/i18n/strings/en_EN.json` with the English (UK) translations for the added keys.
|
||||
1. Check if the import ``import { _t } from 'matrix-react-sdk/src/languageHandler';`` is present. If not add it to the other import statements. Also import `_td` if needed.
|
||||
1. Add ``_t()`` to your string. (Don't forget curly braces when you assign an expression to JSX attributes in the render method). If the string is introduced at a point before the translation system has not yet been initialized, use `_td()` instead, and call `_t()` at the appropriate time.
|
||||
1. Run `yarn i18n` to update ``src/i18n/strings/en_EN.json``
|
||||
1. If you added a string with a plural, you can add other English plural variants to ``src/i18n/strings/en_EN.json`` (remeber to edit the one in the same project as the source file containing your new translation).
|
||||
|
||||
## Editing existing strings
|
||||
|
||||
Edits to existing strings should be performed only via Localazy.
|
||||
There you can also require all translations to be redone if the meaning of the string has changed significantly.
|
||||
1. Edit every occurrence of the string inside `_t()` and `_td()` in the JSX files.
|
||||
1. Run `yarn i18n` to update `src/i18n/strings/en_EN.json`. (Be sure to run this in the same project as the JSX files you just edited.)
|
||||
1. Run `yarn prunei18n` to remove the old string from `src/i18n/strings/*.json`.
|
||||
|
||||
## Adding variables inside a string.
|
||||
|
||||
1. Extend your `_t()` call. Instead of `_t(TKEY)` use `_t(TKEY, {})`
|
||||
1. Extend your ``_t()`` call. Instead of ``_t(STRING)`` use ``_t(STRING, {})``
|
||||
1. Decide how to name it. Please think about if the person who has to translate it can understand what it does. E.g. using the name 'recipient' is bad, because a translator does not know if it is the name of a person, an email address, a user ID, etc. Rather use e.g. recipientEmailAddress.
|
||||
1. Add it to the array in `_t` for example `_t(TKEY, {variable: this.variable})`
|
||||
1. Add the variable inside the string. The syntax for variables is `%(variable)s`. Please note the _s_ at the end. The name of the variable has to match the previous used name.
|
||||
1. Add it to the array in ``_t`` for example ``_t(STRING, {variable: this.variable})``
|
||||
1. Add the variable inside the string. The syntax for variables is ``%(variable)s``. Please note the _s_ at the end. The name of the variable has to match the previous used name.
|
||||
|
||||
- You can use the special `count` variable to choose between multiple versions of the same string, in order to get the correct pluralization. E.g. `_t('You have %(count)s new messages', { count: 2 })` would show 'You have 2 new messages', while `_t('You have %(count)s new messages', { count: 1 })` would show 'You have one new message' (assuming a singular version of the string has been added to the translation file. See above). Passing in `count` is much preferred over having an if-statement choose the correct string to use, because some languages have much more complicated plural rules than english (e.g. they might need a completely different form if there are three things rather than two).
|
||||
- If you want to translate text that includes e.g. hyperlinks or other HTML you have to also use tag substitution, e.g. `_t('<a>Click here!</a>', {}, { 'a': (sub) => <a>{sub}</a> })`. If you don't do the tag substitution you will end up showing literally '<a>' rather than making a hyperlink.
|
||||
- You can also use React components with normal variable substitution if you want to insert HTML markup, e.g. `_t('Your email address is %(emailAddress)s', { emailAddress: <i>{userEmailAddress}</i> })`.
|
||||
- You can use the special ``count`` variable to choose between multiple versions of the same string, in order to get the correct pluralization. E.g. ``_t('You have %(count)s new messages', { count: 2 })`` would show 'You have 2 new messages', while ``_t('You have %(count)s new messages', { count: 1 })`` would show 'You have one new message' (assuming a singular version of the string has been added to the translation file. See above). Passing in ``count`` is much prefered over having an if-statement choose the correct string to use, because some languages have much more complicated plural rules than english (e.g. they might need a completely different form if there are three things rather than two).
|
||||
- If you want to translate text that includes e.g. hyperlinks or other HTML you have to also use tag substitution, e.g. ``_t('<a>Click here!</a>', {}, { 'a': (sub) => <a>{sub}</a> })``. If you don't do the tag substitution you will end up showing literally '<a>' rather than making a hyperlink.
|
||||
- You can also use React components with normal variable substitution if you want to insert HTML markup, e.g. ``_t('Your email address is %(emailAddress)s', { emailAddress: <i>{userEmailAddress}</i> })``.
|
||||
|
||||
## Things to know/Style Guides
|
||||
|
||||
- Do not use `_t()` inside `getDefaultProps`: the translations aren't loaded when `getDefaultProps` is called, leading to missing translations. Use `_td()` to indicate that `_t()` will be called on the string later.
|
||||
- If using translated strings as constants, translated strings can't be in constants loaded at class-load time since the translations won't be loaded. Mark the strings using `_td()` instead and perform the actual translation later.
|
||||
- If a string is presented in the UI with punctuation like a full stop, include this in the translation strings, since punctuation varies between languages too.
|
||||
- Avoid "translation in parts", i.e. concatenating translated strings or using translated strings in variable substitutions. Context is important for translations, and translating partial strings this way is simply not always possible.
|
||||
- Concatenating strings often also introduces an implicit assumption about word order (e.g. that the subject of the sentence comes first), which is incorrect for many languages.
|
||||
- Translation 'smell test': If you have a string that does not begin with a capital letter (is not the start of a sentence) or it ends with e.g. ':' or a preposition (e.g. 'to') you should recheck that you are not trying to translate a partial sentence.
|
||||
- If you have multiple strings, that are almost identical, except some part (e.g. a word or two) it is still better to translate the full sentence multiple times. It may seem like inefficient repetition, but unlike programming where you try to minimize repetition, translation is much faster if you have many, full, clear, sentences to work with, rather than fewer, but incomplete sentence fragments.
|
||||
- Don't forget curly braces when you assign an expression to JSX attributes in the render method)
|
||||
- Do not use `_t()` inside ``getDefaultProps``: the translations aren't loaded when `getDefaultProps` is called, leading to missing translations. Use `_td()` to indicate that `_t()` will be called on the string later.
|
||||
- If using translated strings as constants, translated strings can't be in constants loaded at class-load time since the translations won't be loaded. Mark the strings using `_td()` instead and perform the actual translation later.
|
||||
- If a string is presented in the UI with punctuation like a full stop, include this in the translation strings, since punctuation varies between languages too.
|
||||
- Avoid "translation in parts", i.e. concatenating translated strings or using translated strings in variable substitutions. Context is important for translations, and translating partial strings this way is simply not always possible.
|
||||
- Concatenating strings often also introduces an implicit assumption about word order (e.g. that the subject of the sentence comes first), which is incorrect for many languages.
|
||||
- Translation 'smell test': If you have a string that does not begin with a capital letter (is not the start of a sentence) or it ends with e.g. ':' or a preposition (e.g. 'to') you should recheck that you are not trying to translate a partial sentence.
|
||||
- If you have multiple strings, that are almost identical, except some part (e.g. a word or two) it is still better to translate the full sentence multiple times. It may seem like inefficient repetion, but unlike programming where you try to minimize repetition, translation is much faster if you have many, full, clear, sentences to work with, rather than fewer, but incomplete sentence fragments.
|
||||
|
|
|
@ -2,34 +2,63 @@
|
|||
|
||||
## Requirements
|
||||
|
||||
- Web Browser
|
||||
- Be able to understand English
|
||||
- Be able to understand the language you want to translate Element into
|
||||
- Web Browser
|
||||
- Be able to understand English
|
||||
- Be able to understand the language you want to translate Element into
|
||||
|
||||
## Join #element-translations:matrix.org
|
||||
## Step 0: Join #element-translations:matrix.org
|
||||
|
||||
1. Come and join https://matrix.to/#/#element-translations:matrix.org for general discussion
|
||||
1. Come and join https://matrix.to/#/#element-translations:matrix.org for general discussion
|
||||
2. Join https://matrix.to/#/#element-translators:matrix.org for language-specific rooms
|
||||
3. Read scrollback and/or ask if anyone else is working on your language, and co-ordinate if needed. In general little-or-no coordination is needed though :)
|
||||
3. Read scrollback and/or ask if anyone else is working on your language, and co-ordinate if needed. In general little-or-no coordination is needed though :)
|
||||
|
||||
## Step 1: Preparing your Weblate Profile
|
||||
|
||||
1. Head to https://translate.element.io and register either via Github or email
|
||||
2. After registering check if you got an email to verify your account and click the link (if there is none head to step 1.4)
|
||||
3. Log into weblate
|
||||
4. Head to https://translate.element.io/accounts/profile/ and select the languages you know and maybe another language you know too.
|
||||
|
||||
## How to check if your language already is being translated
|
||||
|
||||
Go to https://localazy.com/p/element-web. If your language is listed then you can get started. Have a read
|
||||
of https://localazy.com/docs/general/translating-strings if you need help getting started. If your language is not yet
|
||||
listed please express your wishes to start translating it in the general discussion room linked above.
|
||||
Go to https://translate.element.io/projects/element-web/ and visit the 2 sub-projects.
|
||||
If your language is listed go to Step 2a and if not go to Step 2b
|
||||
|
||||
### What are `%(something)s`?
|
||||
## Step 2a: Helping on existing languages.
|
||||
|
||||
These things are placeholders that are expanded when displayed by Element. They can be room names, usernames or similar.
|
||||
If you find one, you can move to the right place for your language, but not delete it as the variable will be missing if you do.
|
||||
A special case is `%(count)s` as this is also used to determine which pluralisation is used.
|
||||
1. Head to one of the projects listed https://translate.element.io/projects/element-web/
|
||||
2. Click on the ``translate`` button on the right side of your language
|
||||
3. Fill in the translations in the writeable field. You will see the original English string and the string of your second language above.
|
||||
|
||||
### What are `<link>Something</link>`
|
||||
Head to the explanations under Steb 2b
|
||||
|
||||
These things are markup tags, they encapsulate sections of translations to be marked up, with links, buttons, emphasis and such.
|
||||
You must keep these markers surrounding the equivalent string in your language that needs to be marked up.
|
||||
## Step 2b: Adding a new language
|
||||
|
||||
### When will my translations be available?
|
||||
1. Go to one of the projects listed https://translate.element.io/projects/element-web/
|
||||
2. Click the ``Start new translation`` button at the bottom
|
||||
3. Select a language
|
||||
4. Start translating like in 2a.3
|
||||
5. Repeat these steps for the other projects which are listed at the link of step 2b.1
|
||||
|
||||
We automatically pull changes from Localazy 3 times a week, so your translations should be available at https://develop.element.io
|
||||
within a few days of you submitting them and them being approved. They will then also be included in the following release cycle.
|
||||
### What means the green button under the text field?
|
||||
|
||||
The green button let you save our translations directly. Please only use it if you are 100% sure about that translation. If you do not know a translation please DO NOT click that button. Use the arrows above the translations field and click to the right.
|
||||
|
||||
### What means the yellow button under the text field?
|
||||
|
||||
The yellow button has to be used if you are unsure about the translation but you have a rough idea. It adds a new suggestion to the string which can than be reviewed by others.
|
||||
|
||||
### What are "%(something)s"?
|
||||
|
||||
These things are variables that are expanded when displayed by Element. They can be room names, usernames or similar. If you find one, you can move to the right place for your language, but not delete it as the variable will be missing if you do.
|
||||
|
||||
A special case is `%(urlStart)s` and `%(urlEnd)s` which are used to mark the beginning of a hyperlink (i.e. `<a href="/somewhere">` and `</a>`. You must keep these markers surrounding the equivalent string in your language that needs to be hyperlinked.
|
||||
|
||||
### "I want to come back to this string. How?"
|
||||
|
||||
You can use inside the translation field "Review needed" checkbox. It will be shown as Strings that need to be reviewed.
|
||||
|
||||
|
||||
### Further reading
|
||||
|
||||
The official Weblate doc provides some more in-depth explanation on how to do translations and talks about do and don'ts. You can find it at: https://docs.weblate.org/en/latest/user/translating.html
|
|
@ -6,7 +6,7 @@ official element.io distribution, but these files may be useful if you want to
|
|||
inspect the configuration used there.
|
||||
|
||||
Element Desktop uses a separate config (see
|
||||
https://github.com/element-hq/element-desktop/tree/develop/element.io).
|
||||
https://github.com/vector-im/element-desktop/tree/develop/element.io).
|
||||
|
||||
Deployment scripts (such as app/deploy.py) are meant to be run on the web server
|
||||
hosting the Element installation.
|
||||
|
|
|
@ -1,13 +1,5 @@
|
|||
{
|
||||
"default_server_name": "matrix.org",
|
||||
"default_server_config": {
|
||||
"m.homeserver": {
|
||||
"base_url": "https://matrix-client.matrix.org"
|
||||
},
|
||||
"m.identity_server": {
|
||||
"base_url": "https://vector.im"
|
||||
}
|
||||
},
|
||||
"brand": "Element",
|
||||
"integrations_ui_url": "https://scalar.vector.im/",
|
||||
"integrations_rest_url": "https://scalar.vector.im/api",
|
||||
|
@ -18,11 +10,16 @@
|
|||
"https://scalar-staging.vector.im/api",
|
||||
"https://scalar-staging.riot.im/scalar/api"
|
||||
],
|
||||
"hosting_signup_link": "https://element.io/matrix-services?utm_source=element-web&utm_medium=web",
|
||||
"bug_report_endpoint_url": "https://element.io/bugreports/submit",
|
||||
"uisi_autorageshake_app": "element-auto-uisi",
|
||||
"show_labs_settings": false,
|
||||
"room_directory": {
|
||||
"servers": ["matrix.org", "gitter.im"]
|
||||
"showLabsSettings": false,
|
||||
"roomDirectory": {
|
||||
"servers": [
|
||||
"matrix.org",
|
||||
"gitter.im",
|
||||
"libera.chat"
|
||||
]
|
||||
},
|
||||
"enable_presence_by_hs_url": {
|
||||
"https://matrix.org": false,
|
||||
|
@ -38,13 +35,20 @@
|
|||
"text": "Cookie Policy"
|
||||
}
|
||||
],
|
||||
"hostSignup": {
|
||||
"brand": "Element Home",
|
||||
"cookiePolicyUrl": "https://element.io/cookie-policy",
|
||||
"domains": [
|
||||
"matrix.org"
|
||||
],
|
||||
"privacyPolicyUrl": "https://element.io/privacy",
|
||||
"termsOfServiceUrl": "https://element.io/terms-of-service",
|
||||
"url": "https://ems.element.io/element-home/in-app-loader"
|
||||
},
|
||||
"posthog": {
|
||||
"project_api_key": "phc_Jzsm6DTm6V2705zeU5dcNvQDlonOR68XvX2sh1sEOHO",
|
||||
"api_host": "https://posthog.element.io"
|
||||
"projectApiKey": "phc_Jzsm6DTm6V2705zeU5dcNvQDlonOR68XvX2sh1sEOHO",
|
||||
"apiHost": "https://posthog.element.io"
|
||||
},
|
||||
"privacy_policy_url": "https://element.io/cookie-policy",
|
||||
"map_style_url": "https://api.maptiler.com/maps/streets/style.json?key=fU3vlMsMn4Jb6dnEIFsx",
|
||||
"setting_defaults": {
|
||||
"RustCrypto.staged_rollout_percent": 60
|
||||
}
|
||||
"map_style_url": "https://api.maptiler.com/maps/streets/style.json?key=fU3vlMsMn4Jb6dnEIFsx"
|
||||
}
|
||||
|
|
|
@ -1,13 +1,5 @@
|
|||
{
|
||||
"default_server_name": "matrix.org",
|
||||
"default_server_config": {
|
||||
"m.homeserver": {
|
||||
"base_url": "https://matrix-client.matrix.org"
|
||||
},
|
||||
"m.identity_server": {
|
||||
"base_url": "https://vector.im"
|
||||
}
|
||||
},
|
||||
"brand": "Element",
|
||||
"integrations_ui_url": "https://scalar.vector.im/",
|
||||
"integrations_rest_url": "https://scalar.vector.im/api",
|
||||
|
@ -18,11 +10,16 @@
|
|||
"https://scalar-staging.vector.im/api",
|
||||
"https://scalar-staging.riot.im/scalar/api"
|
||||
],
|
||||
"hosting_signup_link": "https://element.io/matrix-services?utm_source=element-web&utm_medium=web",
|
||||
"bug_report_endpoint_url": "https://element.io/bugreports/submit",
|
||||
"uisi_autorageshake_app": "element-auto-uisi",
|
||||
"show_labs_settings": true,
|
||||
"room_directory": {
|
||||
"servers": ["matrix.org", "gitter.im"]
|
||||
"showLabsSettings": true,
|
||||
"roomDirectory": {
|
||||
"servers": [
|
||||
"matrix.org",
|
||||
"gitter.im",
|
||||
"libera.chat"
|
||||
]
|
||||
},
|
||||
"enable_presence_by_hs_url": {
|
||||
"https://matrix.org": false,
|
||||
|
@ -38,26 +35,31 @@
|
|||
"text": "Cookie Policy"
|
||||
}
|
||||
],
|
||||
"hostSignup": {
|
||||
"brand": "Element Home",
|
||||
"cookiePolicyUrl": "https://element.io/cookie-policy",
|
||||
"domains": [
|
||||
"matrix.org"
|
||||
],
|
||||
"privacyPolicyUrl": "https://element.io/privacy",
|
||||
"termsOfServiceUrl": "https://element.io/terms-of-service",
|
||||
"url": "https://ems.element.io/element-home/in-app-loader"
|
||||
},
|
||||
"sentry": {
|
||||
"dsn": "https://029a0eb289f942508ae0fb17935bd8c5@sentry.matrix.org/6",
|
||||
"environment": "develop"
|
||||
},
|
||||
"posthog": {
|
||||
"project_api_key": "phc_Jzsm6DTm6V2705zeU5dcNvQDlonOR68XvX2sh1sEOHO",
|
||||
"api_host": "https://posthog.element.io"
|
||||
"projectApiKey": "phc_Jzsm6DTm6V2705zeU5dcNvQDlonOR68XvX2sh1sEOHO",
|
||||
"apiHost": "https://posthog.element.io"
|
||||
},
|
||||
"privacy_policy_url": "https://element.io/cookie-policy",
|
||||
"features": {
|
||||
"threadsActivityCentre": true,
|
||||
"feature_video_rooms": true,
|
||||
"feature_new_room_decoration_ui": true,
|
||||
"feature_element_call_video_rooms": true
|
||||
},
|
||||
"setting_defaults": {
|
||||
"RustCrypto.staged_rollout_percent": 100
|
||||
"feature_spotlight": true,
|
||||
"feature_video_rooms": true
|
||||
},
|
||||
"element_call": {
|
||||
"url": "https://call.element.dev"
|
||||
"url": "https://element-call.netlify.app"
|
||||
},
|
||||
"map_style_url": "https://api.maptiler.com/maps/streets/style.json?key=fU3vlMsMn4Jb6dnEIFsx"
|
||||
}
|
||||
|
|
|
@ -1,58 +0,0 @@
|
|||
/*
|
||||
Copyright 2023 The Matrix.org Foundation C.I.C.
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
import { env } from "process";
|
||||
|
||||
import type { Config } from "jest";
|
||||
|
||||
const config: Config = {
|
||||
testEnvironment: "jsdom",
|
||||
testEnvironmentOptions: {
|
||||
url: "http://localhost/",
|
||||
},
|
||||
testMatch: ["<rootDir>/test/**/*-test.[tj]s?(x)"],
|
||||
setupFiles: ["jest-canvas-mock"],
|
||||
setupFilesAfterEnv: ["<rootDir>/node_modules/matrix-react-sdk/test/setupTests.ts"],
|
||||
moduleNameMapper: {
|
||||
"\\.(css|scss|pcss)$": "<rootDir>/__mocks__/cssMock.js",
|
||||
"\\.(gif|png|ttf|woff2)$": "<rootDir>/node_modules/matrix-react-sdk/__mocks__/imageMock.js",
|
||||
"\\.svg$": "<rootDir>/node_modules/matrix-react-sdk/__mocks__/svg.js",
|
||||
"\\$webapp/i18n/languages.json": "<rootDir>/node_modules/matrix-react-sdk/__mocks__/languages.json",
|
||||
"^react$": "<rootDir>/node_modules/react",
|
||||
"^react-dom$": "<rootDir>/node_modules/react-dom",
|
||||
"^matrix-js-sdk$": "<rootDir>/node_modules/matrix-js-sdk/src",
|
||||
"^matrix-react-sdk$": "<rootDir>/node_modules/matrix-react-sdk/src",
|
||||
"decoderWorker\\.min\\.js": "<rootDir>/node_modules/matrix-react-sdk/__mocks__/empty.js",
|
||||
"decoderWorker\\.min\\.wasm": "<rootDir>/node_modules/matrix-react-sdk/__mocks__/empty.js",
|
||||
"waveWorker\\.min\\.js": "<rootDir>/node_modules/matrix-react-sdk/__mocks__/empty.js",
|
||||
"context-filter-polyfill": "<rootDir>/node_modules/matrix-react-sdk/__mocks__/empty.js",
|
||||
"FontManager.ts": "<rootDir>/node_modules/matrix-react-sdk/__mocks__/FontManager.js",
|
||||
"workers/(.+)Factory": "<rootDir>/node_modules/matrix-react-sdk/__mocks__/workerFactoryMock.js",
|
||||
"^!!raw-loader!.*": "jest-raw-loader",
|
||||
"recorderWorkletFactory": "<rootDir>/node_modules/matrix-react-sdk/__mocks__/empty.js",
|
||||
"^fetch-mock$": "<rootDir>/node_modules/fetch-mock",
|
||||
},
|
||||
transformIgnorePatterns: ["/node_modules/(?!matrix-js-sdk).+$", "/node_modules/(?!matrix-react-sdk).+$"],
|
||||
coverageReporters: ["text-summary", "lcov"],
|
||||
testResultsProcessor: "@casualbot/jest-sonar-reporter",
|
||||
};
|
||||
|
||||
// if we're running under GHA, enable the GHA reporter
|
||||
if (env["GITHUB_ACTIONS"] !== undefined) {
|
||||
config.reporters = [["github-actions", { silent: false }], "summary"];
|
||||
}
|
||||
|
||||
export default config;
|
|
@ -1,37 +0,0 @@
|
|||
{
|
||||
"readKey": "a7688614897667993891-866e2615b0a22e6ccef56aea9b10e815efa3e1296752a7a30bd9925f1a8f33e7",
|
||||
|
||||
"upload": {
|
||||
"type": "json",
|
||||
"keySeparator": "|",
|
||||
"deprecate": "file",
|
||||
"features": ["plural_object", "filter_untranslated"],
|
||||
"files": [
|
||||
{
|
||||
"pattern": "src/i18n/strings/en_EN.json",
|
||||
"file": "element-web.json",
|
||||
"lang": "inherited"
|
||||
},
|
||||
{
|
||||
"group": "existing",
|
||||
"pattern": "src/i18n/strings/*.json",
|
||||
"file": "element-web.json",
|
||||
"excludes": ["src/i18n/strings/en_EN.json"],
|
||||
"lang": "${autodetectLang}"
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
"download": {
|
||||
"files": [
|
||||
{
|
||||
"conditions": "equals: ${file}, element-web.json",
|
||||
"output": "src/i18n/strings/${langLsrUnderscore}.json"
|
||||
}
|
||||
],
|
||||
"includeSourceLang": "${includeSourceLang|false}",
|
||||
"langAliases": {
|
||||
"en": "en-EN"
|
||||
}
|
||||
}
|
||||
}
|
|
@ -65,7 +65,7 @@ export function installer(config: BuildConfig): void {
|
|||
// else must be a module, we assume.
|
||||
const pkgJsonStr = fs.readFileSync("./package.json", "utf-8");
|
||||
const optionalDepNames = getOptionalDepNames(pkgJsonStr);
|
||||
const installedModules = optionalDepNames.filter((d) => !currentOptDeps.includes(d));
|
||||
const installedModules = optionalDepNames.filter(d => !currentOptDeps.includes(d));
|
||||
|
||||
// Ensure all the modules are compatible. We check them all and report at the end to
|
||||
// try and save the user some time debugging this sort of failure.
|
||||
|
@ -80,7 +80,7 @@ export function installer(config: BuildConfig): void {
|
|||
if (incompatibleNames.length > 0) {
|
||||
console.error(
|
||||
"The following modules are not compatible with this version of element-web. Please update the module " +
|
||||
"references and try again.",
|
||||
"references and try again.",
|
||||
JSON.stringify(incompatibleNames, null, 4), // stringify to get prettier/complete output
|
||||
);
|
||||
exitCode = 1;
|
||||
|
@ -123,43 +123,39 @@ function readCurrentPackageDetails(): RawDependencies {
|
|||
};
|
||||
}
|
||||
|
||||
function writePackageDetails(deps: RawDependencies): void {
|
||||
function writePackageDetails(deps: RawDependencies) {
|
||||
fs.writeFileSync("./yarn.lock", deps.lockfile, "utf-8");
|
||||
fs.writeFileSync("./package.json", deps.packageJson, "utf-8");
|
||||
}
|
||||
|
||||
function callYarnAdd(dep: string): void {
|
||||
function callYarnAdd(dep: string) {
|
||||
// Add the module to the optional dependencies section just in case something
|
||||
// goes wrong in restoring the original package details.
|
||||
childProcess.execSync(`yarn add -O ${dep}`, {
|
||||
env: process.env,
|
||||
stdio: ["inherit", "inherit", "inherit"],
|
||||
stdio: ['inherit', 'inherit', 'inherit'],
|
||||
});
|
||||
}
|
||||
|
||||
function getOptionalDepNames(pkgJsonStr: string): string[] {
|
||||
return Object.keys(JSON.parse(pkgJsonStr)?.["optionalDependencies"] ?? {});
|
||||
return Object.keys(JSON.parse(pkgJsonStr)?.['optionalDependencies'] ?? {});
|
||||
}
|
||||
|
||||
function findDepVersionInPackageJson(dep: string, pkgJsonStr: string): string {
|
||||
const pkgJson = JSON.parse(pkgJsonStr);
|
||||
const packages = {
|
||||
...(pkgJson["optionalDependencies"] ?? {}),
|
||||
...(pkgJson["devDependencies"] ?? {}),
|
||||
...(pkgJson["dependencies"] ?? {}),
|
||||
...(pkgJson['optionalDependencies'] ?? {}),
|
||||
...(pkgJson['devDependencies'] ?? {}),
|
||||
...(pkgJson['dependencies'] ?? {}),
|
||||
};
|
||||
return packages[dep];
|
||||
}
|
||||
|
||||
function getTopLevelDependencyVersion(dep: string): string {
|
||||
const dependencyTree = JSON.parse(
|
||||
childProcess
|
||||
.execSync(`npm list ${dep} --depth=0 --json`, {
|
||||
env: process.env,
|
||||
stdio: ["inherit", "pipe", "pipe"],
|
||||
})
|
||||
.toString("utf-8"),
|
||||
);
|
||||
const dependencyTree = JSON.parse(childProcess.execSync(`npm list ${dep} --depth=0 --json`, {
|
||||
env: process.env,
|
||||
stdio: ['inherit', 'pipe', 'pipe'],
|
||||
}).toString('utf-8'));
|
||||
|
||||
/*
|
||||
What a dependency tree looks like:
|
||||
|
@ -185,22 +181,11 @@ function getModuleApiVersionFor(moduleName: string): string {
|
|||
return findDepVersionInPackageJson(moduleApiDepName, pkgJsonStr);
|
||||
}
|
||||
|
||||
// A list of Module API versions that are supported in addition to the currently installed one
|
||||
// defined in the package.json. This is necessary because semantic versioning is applied to both
|
||||
// the Module-side surface of the API and the Client-side surface of the API. So breaking changes
|
||||
// in the Client-side surface lead to a major bump even though the Module-side surface stays
|
||||
// compatible. We aim to not break the Module-side surface so we maintain a list of compatible
|
||||
// older versions.
|
||||
const backwardsCompatibleMajorVersions = ["1.0.0"];
|
||||
|
||||
function isModuleVersionCompatible(ourApiVersion: string, moduleApiVersion: string): boolean {
|
||||
if (!moduleApiVersion) return false;
|
||||
return (
|
||||
semver.satisfies(ourApiVersion, moduleApiVersion) ||
|
||||
backwardsCompatibleMajorVersions.some((version) => semver.satisfies(version, moduleApiVersion))
|
||||
);
|
||||
return semver.satisfies(ourApiVersion, moduleApiVersion);
|
||||
}
|
||||
|
||||
function writeModulesTs(content: string): void {
|
||||
function writeModulesTs(content: string) {
|
||||
fs.writeFileSync("./src/modules.ts", content, "utf-8");
|
||||
}
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue