Contributing

Bug reports, ideas, translations, documentation and code are all welcome. This page explains where to talk, how to send a change, the conventions the code follows, and the rules for security problems and licences.

Where to talk

Everything starts in the community repository, whatever part of Antimatter it is about:

  • Bugs and feature requests: open an issue and pick Bug report, Feature request, or Plugin or integration request. Search the existing issues first; if yours is there, add a thumbs-up or your details.
  • Questions and ideas: the Discussions, in the Q&A or Ideas categories.
  • Before a bigger change, open an issue or a discussion to agree on the approach first. It saves a pull request that can't be merged as it is.

Issues labelled good first issue and help wanted are good places to start. Say in a comment that you are working on one. New issues are labelled status/triage, then status/accepted, status/planned or status/wontfix. Issues stay in the community repository whatever they are about: the code repositories don't take issues. Planned work is on the Antimatter roadmap.

Repositories and branches

The code is in the AntimatterChat organisation; Where the code lives lists the repositories. In every repository:

  • main is the default branch and holds Antimatter's code. Branch from it and send pull requests to it.
  • Repositories forked from Mattermost also have an upstream branch, a mirror of Mattermost's code used to bring in their changes. Don't base work on it.

Each repository's README explains how to build and test it. For the server and the web interfaces, see Building from source; for apps, Build, install and debug.

Pull requests

  1. Fork the repository and create a branch from main.
  2. Keep each pull request to one change. Small pull requests are reviewed faster.
  3. Follow the style of the code around you, and add or update tests where it makes sense.
  4. Describe what you changed and why, and link the issue it fixes: Fixes AntimatterChat/community#123.
  5. Make sure the checks pass. A maintainer reviews the pull request and may ask for changes.

In the server repository, fill in the pull request template: a Summary, and the Release Note block, which must always be there. Write NONE in it when the change touches no API, configuration, database schema or visible behaviour.

By contributing, you agree that your contribution is licensed under the licence of the repository you contribute to.

Commits and code style

Commits

Commit messages in the history are one short sentence saying what changes, in sentence case and without a final full stop. Changes to one part are prefixed with it, for example Fusion: a compact conversation header on phones or Server: community attributes, and admin-only user attributes. One commit per change; explain the reasons in the body when they aren't obvious.

Server (Go)

  • Run make check-style in server/ before pushing.
  • Never run go mod tidy directly; run make modules-tidy.
  • In request paths, log with the request's logger. In the store layer, take a request.CTX, not a context.Context.
  • New API endpoints go in server/channels/api4, with their types in server/public/model and, ideally, a method in model.Client4 and in the TypeScript client.

Web interfaces (TypeScript and React)

  • Run make check-style and make check-types in webapp/.
  • The classic interface follows webapp/STYLE_GUIDE.md: functional components, hooks for Redux, theme variables for colours, accessible markup.
  • Fusion's components live in webapp/fusion/src/fusion, with their styles in webapp/fusion/src/fusion/styles. They build class names with the am() helper and use Fusion's design tokens; follow the files next to yours.
  • Don't add new window.* globals for apps. New app-facing utilities go under window.WebappUtils, as webapp/AGENTS.md explains.
  • A change to the app registry (plugins/registry.ts) usually belongs in both interfaces' copies.

Translations

Antimatter and its bundled apps are translated into 37 languages. Contributors add the English strings; the other languages are updated in batches.

Adding a string to the web interfaces

  1. Write it with an ID and a literal English text: formatMessage({id: 'fusion.channelMenu.settings', defaultMessage: 'Channel settings'}) or <FormattedMessage id='…' defaultMessage='…'/>. The English shown in the app comes from defaultMessage.
  2. Run make i18n-extract in webapp/ (or npm run i18n-extract in webapp/fusion or webapp/channels). It updates that package's src/i18n/en.json.
  3. Fill in the new entry's description in en.json: where the string appears and how it is used. It is the context translators, human or machine, work from.

npm run i18n-extract:check fails when en.json is out of date with the code.

Adding a string to the server

  1. Use an ID in the code, for example model.NewAppError(…, "app.community_attributes.invalid.app_error", …) or i18n.T("…").
  2. Run make i18n-extract in server/. It adds the ID to server/i18n/en.json in the right order.
  3. Write the English translation and the description of the new entry.

Other languages

Each language has its own file next to en.json (fr.json, pt-BR.json, zh-TW.json…). To report a wrong translation, open an issue in the community repository with the language, the text and where it appears.

The bundled apps keep their strings in webapp/i18n/; see Translations in the apps page.

Documentation and this website

This website and its documentation are in the antimatter.chat repository. Pages are HTML fragments in src/pages/; python3 src/build.py builds the site. Corrections and missing explanations are welcome as issues or pull requests.

Security problems

Never report a security problem in a public issue, discussion or pull request.

Report it privately with GitHub's private vulnerability reporting: open the Security tab of the affected repository (for example the server) and choose Report a vulnerability. If you don't know which repository is affected, report it on the community repository. Include the component and its version, what an attacker could do, how to reproduce it, and any configuration it depends on.

The maintainers answer there, keep you updated while they fix it, and publish an advisory once a fixed release is out. Please give them reasonable time before disclosing the problem. Fixes go into the latest release. The full policy is in the security policy.

Licences

  • The server is under the GNU Affero General Public License v3.0 (AGPL v3). In the same repository, the admin tools and configuration files (server/templates/, server/i18n/, server/public/ and webapp/) are under the Apache License 2.0. See LICENSE.txt and NOTICE.txt.
  • Apps: Antimatter's own apps, such as Polls, are under the AGPL v3; apps forked from Mattermost keep their original licence. Each repository says which in its LICENSE file.
  • The desktop and mobile apps are under the Apache License 2.0. The Docker repository is under the Apache License 2.0, except its Dockerfile, under the AGPL v3.

The AGPL means that if you run a modified Antimatter server for other people over a network, you must offer them the source code of your changes. Antimatter is based on Mattermost; it is not affiliated with or endorsed by Mattermost, Inc.

Everyone taking part follows the code of conduct.