Compare commits

...

219 commits

Author SHA1 Message Date
Harrison Healey
1a4de869b3
MM-67538 Add ability for plugins to load asynchronously (#35238)
Some checks are pending
API / build (push) Waiting to run
Server CI / Compute Go Version (push) Waiting to run
Server CI / Check mocks (push) Blocked by required conditions
Server CI / Check go mod tidy (push) Blocked by required conditions
Server CI / check-style (push) Blocked by required conditions
Server CI / Check serialization methods for hot structs (push) Blocked by required conditions
Server CI / Vet API (push) Blocked by required conditions
Server CI / Check migration files (push) Blocked by required conditions
Server CI / Generate email templates (push) Blocked by required conditions
Server CI / Check store layers (push) Blocked by required conditions
Server CI / Check mmctl docs (push) Blocked by required conditions
Server CI / Postgres with binary parameters (push) Blocked by required conditions
Server CI / Postgres (push) Blocked by required conditions
Server CI / Postgres (FIPS) (push) Blocked by required conditions
Server CI / Generate Test Coverage (push) Blocked by required conditions
Server CI / Run mmctl tests (push) Blocked by required conditions
Server CI / Run mmctl tests (FIPS) (push) Blocked by required conditions
Server CI / Build mattermost server app (push) Blocked by required conditions
Web App CI / check-lint (push) Waiting to run
Web App CI / check-i18n (push) Blocked by required conditions
Web App CI / check-types (push) Blocked by required conditions
Web App CI / test (platform) (push) Blocked by required conditions
Web App CI / test (mattermost-redux) (push) Blocked by required conditions
Web App CI / test (channels shard 1/4) (push) Blocked by required conditions
Web App CI / test (channels shard 2/4) (push) Blocked by required conditions
Web App CI / test (channels shard 3/4) (push) Blocked by required conditions
Web App CI / test (channels shard 4/4) (push) Blocked by required conditions
Web App CI / upload-coverage (push) Blocked by required conditions
Web App CI / build (push) Blocked by required conditions
Automatic Merge
2026-02-11 08:23:28 +02:00
sabril
a711b22717
SEC-9513 feat: e2e tests on master and releases (#35205)
* feat: e2e tests on master and releases

* (for pipelines testing only, will be removed after)

* remove test pipelines
2026-02-11 13:02:25 +08:00
Christopher Poile
1ac14a9dfb
[MM-67140] Added session validation on logout (#34959)
Some checks are pending
API / build (push) Waiting to run
Server CI / Compute Go Version (push) Waiting to run
Server CI / Check mocks (push) Blocked by required conditions
Server CI / Check go mod tidy (push) Blocked by required conditions
Server CI / check-style (push) Blocked by required conditions
Server CI / Check serialization methods for hot structs (push) Blocked by required conditions
Server CI / Vet API (push) Blocked by required conditions
Server CI / Check migration files (push) Blocked by required conditions
Server CI / Generate email templates (push) Blocked by required conditions
Server CI / Check store layers (push) Blocked by required conditions
Server CI / Check mmctl docs (push) Blocked by required conditions
Server CI / Postgres with binary parameters (push) Blocked by required conditions
Server CI / Postgres (push) Blocked by required conditions
Server CI / Postgres (FIPS) (push) Blocked by required conditions
Server CI / Generate Test Coverage (push) Blocked by required conditions
Server CI / Run mmctl tests (push) Blocked by required conditions
Server CI / Run mmctl tests (FIPS) (push) Blocked by required conditions
Server CI / Build mattermost server app (push) Blocked by required conditions
Web App CI / check-lint (push) Waiting to run
Web App CI / check-i18n (push) Blocked by required conditions
Web App CI / check-types (push) Blocked by required conditions
Web App CI / test (platform) (push) Blocked by required conditions
Web App CI / test (mattermost-redux) (push) Blocked by required conditions
Web App CI / test (channels shard 1/4) (push) Blocked by required conditions
Web App CI / test (channels shard 2/4) (push) Blocked by required conditions
Web App CI / test (channels shard 3/4) (push) Blocked by required conditions
Web App CI / test (channels shard 4/4) (push) Blocked by required conditions
Web App CI / upload-coverage (push) Blocked by required conditions
Web App CI / build (push) Blocked by required conditions
* add authentication status to audit log for logouts

* improve audit log testing for other tests

---------

Co-authored-by: Mattermost Build <build@mattermost.com>
2026-02-10 15:12:14 -05:00
Christopher Poile
121b429b8e
[MM-65588] Fix OAuth login with redirect_to URL (#34944)
Co-authored-by: Mattermost Build <build@mattermost.com>
2026-02-10 15:06:28 -05:00
Daniel Espino García
1c7246da68
Autotranslation Frontend integration (#34717)
Some checks are pending
API / build (push) Waiting to run
Server CI / Compute Go Version (push) Waiting to run
Server CI / Check mocks (push) Blocked by required conditions
Server CI / Check go mod tidy (push) Blocked by required conditions
Server CI / check-style (push) Blocked by required conditions
Server CI / Check serialization methods for hot structs (push) Blocked by required conditions
Server CI / Vet API (push) Blocked by required conditions
Server CI / Check migration files (push) Blocked by required conditions
Server CI / Generate email templates (push) Blocked by required conditions
Server CI / Check store layers (push) Blocked by required conditions
Server CI / Check mmctl docs (push) Blocked by required conditions
Server CI / Postgres with binary parameters (push) Blocked by required conditions
Server CI / Postgres (push) Blocked by required conditions
Server CI / Postgres (FIPS) (push) Blocked by required conditions
Server CI / Generate Test Coverage (push) Blocked by required conditions
Server CI / Run mmctl tests (push) Blocked by required conditions
Server CI / Run mmctl tests (FIPS) (push) Blocked by required conditions
Server CI / Build mattermost server app (push) Blocked by required conditions
Web App CI / check-lint (push) Waiting to run
Web App CI / check-i18n (push) Blocked by required conditions
Web App CI / check-types (push) Blocked by required conditions
Web App CI / test (platform) (push) Blocked by required conditions
Web App CI / test (mattermost-redux) (push) Blocked by required conditions
Web App CI / test (channels shard 1/4) (push) Blocked by required conditions
Web App CI / test (channels shard 2/4) (push) Blocked by required conditions
Web App CI / test (channels shard 3/4) (push) Blocked by required conditions
Web App CI / test (channels shard 4/4) (push) Blocked by required conditions
Web App CI / upload-coverage (push) Blocked by required conditions
Web App CI / build (push) Blocked by required conditions
* AutoTranslate config settings

* comment out Agents provider

* Add auto translate timeout config validation

* i18n messages for autotranslation config validation

* fix test

* validate url for libreTranslate

* Feedback review

* Admin Console UI for Auto-Translation

* fix admin console conditional section display

* i18n

* removed unintentional change

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* update admin.general.localization.autoTranslateProviderDescription newline

* fix lint

* Fix types

* UX feedback review

* fix typo in i18n

* Fix AutoTranslation feature flag

* feedback review

* Fix test default values

* feedback review

* re-add isHidden property to feature discovery

* Database Migrations, Indexes and Methods for Auto-Translation

* i18n

* fix retrylayer and storetest

* Fix search query

* fix lint

* remove the request.CTX and modify Translation model

* fix lint and external url

* Add settings to playwright

* Add empty as a valid value for the Provider

* Update jsonb queries

* Fix queries and add model methods

* fix go lint

* go lint fix 2

* fix db migrations

* feedback review + store cache

* increase migration number

* cleanup autotranslation store cache

* use NULL as objectType for posts

* fix bad merge

* fix tests

* add missing i18n

* Active WebSocket Connection User Tracking

* copilot feedback and fix styles

* remove duplicate calls

* remove early return to mitigate timing attacks

* Switch prop bags column to boolean

* fix lint

* fix tests

* Remove database search

* use Builder methods

* review feedback

* AutoTranslation interface with Core Translation Logic

* update timeouts to use short/medium/long translations

* external exports

* add configured languages to autotranslations

* added post prop for detected language

* fix bugs for storing translation and call translation service

* clean up interface

* add translations to GetPost repsonses and in the create post response

* use metadata for translation information and add new column for state of a translation

* change websocket event name

* change metadata to a map

* single in memory queue in the cluster leader

* remove unused definition

* Revert "remove unused definition"

This reverts commit e3e50cef30.

* remove webhub changes

* remove last webhub bit

* tidy up interface

* Frontend integration

* tidy up

* fix api response for translations

* Add Agents provider for auto translations (#34706)

* Add LLM backed autotranslation support

* Remove AU changes

* Remove orphaned tests for deleted GetActiveUserIDsForChannel

The GetActiveUserIDsForChannel function was removed from PlatformService
as part of the autotranslations refactoring, but its tests were left behind
causing linter/vet errors. This removes the orphaned test code:
- BenchmarkGetActiveUserIDsForChannel
- TestGetActiveUserIDsForChannel
- waitForActiveConnections helper

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* Add missing i18n translations and fix linter errors

- Add 17 missing translation strings for autotranslation feature
- Fix shadow variable declarations in post.go and autotranslation.go
- Remove unused autoQueueMaxAge constant
- Remove unused setupWithFastIteration test function
- Use slices.Contains instead of manual loop
- Use maps.Copy instead of manual loop
- Remove empty if branch

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* Fix tests

* Fixes for PR review

* add files

* Update webapp/channels/src/components/admin_console/localization/localization.scss

Co-authored-by: Matthew Birtch <mattbirtch@gmail.com>

* fixes

* Fixes

* Didn't save

* Add a translation

* Fix translations

* Fix shadow err

---------

Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Matthew Birtch <mattbirtch@gmail.com>

* tidy up code for review

* add support for editing posts

* i18n-extract

* i18n

* Rename show translations and add util to get message

* Fix get posts, migrations, websockets and configuration styles

* Fix CI

* i18n-extract

* Fix webapp tests

* Address UX feedback

* i18n-extract

* Fix lint

* updated shimmer animation, fixed issue with the width on compact icon buttons

* fix migrations

* fix markdown masking for bold, italics and strikethrough

* Address feedback

* Add missing changes

* Fix and add tests

* Fix circular dependencies

* lint

* lint

* lint and i18n

* Fix lint

* Fix i18n

* Minor changes

* Add check for whether the channel is translated or not for this user

* Fix lint and add missing change

* Fix lint

* Fix test

* Remove uneeded console log

* Fix duplicated code

* Fix small screen show translation modal

* Remove interactions on show translation modal

* Disable auto translation when the language is not supported

* Fix typo

* Fix copy text

* Fix updating autotranslation for normal users

* Fix autotranslate button showing when it shouldn't

* Fix styles

* Fix test

* Fix frontend member related changes

* Revert post improvements and remove duplicated code from bad merge

* Address feedback

* Fix test and i18n

* Fix e2e tests

* Revert lingering change from post improvements

* Fix lint

---------

Co-authored-by: Elias Nahum <nahumhbl@gmail.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: BenCookie95 <benkcooke@gmail.com>
Co-authored-by: Nick Misasi <nick.misasi@mattermost.com>
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Matthew Birtch <mattbirtch@gmail.com>
Co-authored-by: Mattermost Build <build@mattermost.com>
2026-02-10 17:21:01 +01:00
Christopher Poile
24957f5e22
[MM-63393] Add support for preferred_username claims (#30852)
* rebased all prev commits into one (see commit desc)

add UsePreferredUsername support to gitlab; tests

resort en.json

update an out of date comment

webapp i18n

simplify username logic

new arguments needed in tests

debug statements -- revert

* merge conflicts

* fix i18n

---------

Co-authored-by: Mattermost Build <build@mattermost.com>
2026-02-10 10:10:27 -05:00
Harrison Healey
ecd16ec9ef
MM-67137 Fix references to window in client package (#35195)
* MM-67137 Fix references to window in client package

* Fix Client tests running on compiled code

* Mostly revert changes to limit the chance of accidental changes
2026-02-10 09:41:32 -05:00
Andre Vasconcelos
7d89d327ec
Bumping prepackaged version of GitHub plugin (#35223) 2026-02-10 15:11:09 +02:00
Ben Schumacher
cbc9406815
[MM-67114] Add mmctl license get command (#34878)
Some checks are pending
API / build (push) Waiting to run
Server CI / Compute Go Version (push) Waiting to run
Server CI / Check mocks (push) Blocked by required conditions
Server CI / Check go mod tidy (push) Blocked by required conditions
Server CI / check-style (push) Blocked by required conditions
Server CI / Check serialization methods for hot structs (push) Blocked by required conditions
Server CI / Vet API (push) Blocked by required conditions
Server CI / Check migration files (push) Blocked by required conditions
Server CI / Generate email templates (push) Blocked by required conditions
Server CI / Check store layers (push) Blocked by required conditions
Server CI / Check mmctl docs (push) Blocked by required conditions
Server CI / Postgres with binary parameters (push) Blocked by required conditions
Server CI / Postgres (push) Blocked by required conditions
Server CI / Postgres (FIPS) (push) Blocked by required conditions
Server CI / Generate Test Coverage (push) Blocked by required conditions
Server CI / Run mmctl tests (push) Blocked by required conditions
Server CI / Run mmctl tests (FIPS) (push) Blocked by required conditions
Server CI / Build mattermost server app (push) Blocked by required conditions
Web App CI / check-lint (push) Waiting to run
Web App CI / check-i18n (push) Blocked by required conditions
Web App CI / check-types (push) Blocked by required conditions
Web App CI / test (platform) (push) Blocked by required conditions
Web App CI / test (mattermost-redux) (push) Blocked by required conditions
Web App CI / test (channels shard 1/4) (push) Blocked by required conditions
Web App CI / test (channels shard 2/4) (push) Blocked by required conditions
Web App CI / test (channels shard 3/4) (push) Blocked by required conditions
Web App CI / test (channels shard 4/4) (push) Blocked by required conditions
Web App CI / upload-coverage (push) Blocked by required conditions
Web App CI / build (push) Blocked by required conditions
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-10 08:26:59 +01:00
Ben Schumacher
9e7cd64800
[MM-67502] Sanitize secret plugin settings inside sections (#35214) 2026-02-10 08:24:21 +01:00
Ben Cooke
76b3528c2b
[MM-67231] Etag fixes for autotranslations (#35196)
Some checks are pending
API / build (push) Waiting to run
Server CI / Compute Go Version (push) Waiting to run
Server CI / Check mocks (push) Blocked by required conditions
Server CI / Check go mod tidy (push) Blocked by required conditions
Server CI / check-style (push) Blocked by required conditions
Server CI / Check serialization methods for hot structs (push) Blocked by required conditions
Server CI / Vet API (push) Blocked by required conditions
Server CI / Check migration files (push) Blocked by required conditions
Server CI / Generate email templates (push) Blocked by required conditions
Server CI / Check store layers (push) Blocked by required conditions
Server CI / Check mmctl docs (push) Blocked by required conditions
Server CI / Postgres with binary parameters (push) Blocked by required conditions
Server CI / Postgres (push) Blocked by required conditions
Server CI / Postgres (FIPS) (push) Blocked by required conditions
Server CI / Generate Test Coverage (push) Blocked by required conditions
Server CI / Run mmctl tests (push) Blocked by required conditions
Server CI / Run mmctl tests (FIPS) (push) Blocked by required conditions
Server CI / Build mattermost server app (push) Blocked by required conditions
Web App CI / check-lint (push) Waiting to run
Web App CI / check-i18n (push) Blocked by required conditions
Web App CI / check-types (push) Blocked by required conditions
Web App CI / test (platform) (push) Blocked by required conditions
Web App CI / test (mattermost-redux) (push) Blocked by required conditions
Web App CI / test (channels shard 1/4) (push) Blocked by required conditions
Web App CI / test (channels shard 2/4) (push) Blocked by required conditions
Web App CI / test (channels shard 3/4) (push) Blocked by required conditions
Web App CI / test (channels shard 4/4) (push) Blocked by required conditions
Web App CI / upload-coverage (push) Blocked by required conditions
Web App CI / build (push) Blocked by required conditions
2026-02-09 18:32:26 -05:00
Pablo Vélez
74b5fb066c
MM-67022 - Implement ExpireAt handling for BoR sender to persist countdown (#34796)
* MM-67022 - Implement ExpireAt handling for BoR sender to persist countdown

* enhance read receipt caching, invalidate unread count cache and add GetUnreadCountForPost method

* Use dedicated cache for read receipt unread counts

* fix vet lint

* fix format

* Fix BoR sender countdown after reload in clustered setup

* Fix cache bypass for BoR sender countdown on clustered servers

---------

Co-authored-by: Mattermost Build <build@mattermost.com>
Co-authored-by: Harshil Sharma <harshilsharma63@gmail.com>
2026-02-09 15:47:27 -05:00
Asaad Mahmood
3a68fb9efc
MM-67430 - Removing artificial spacing from modal (#35173)
* MM-67430 - Removing artificial spacing from modal

* Updating forward post modal

---------

Co-authored-by: Mattermost Build <build@mattermost.com>
2026-02-09 21:48:21 +05:00
Weblate (bot)
bdbe2f1374
Translations update from Mattermost Weblate (#35213)
* Update translation files

Updated by "Cleanup translation files" hook in Weblate.

Translation: Mattermost/server
Translate-URL: https://translate.mattermost.com/projects/mattermost/server/

* Translated using Weblate (Italian)

Currently translated at 69.1% (2039 of 2947 strings)

Translation: Mattermost/server
Translate-URL: https://translate.mattermost.com/projects/mattermost/server/it/

* Translated using Weblate (Italian)

Currently translated at 47.2% (3291 of 6966 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/it/

* Translated using Weblate (Chinese (Simplified Han script))

Currently translated at 100.0% (2947 of 2947 strings)

Translation: Mattermost/server
Translate-URL: https://translate.mattermost.com/projects/mattermost/server/zh_Hans/

* Translated using Weblate (Chinese (Simplified Han script))

Currently translated at 98.2% (6843 of 6966 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/zh_Hans/

* Translated using Weblate (Dutch)

Currently translated at 97.7% (6811 of 6966 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/nl/

* Translated using Weblate (Dutch)

Currently translated at 99.0% (2918 of 2947 strings)

Translation: Mattermost/server
Translate-URL: https://translate.mattermost.com/projects/mattermost/server/nl/

* Translated using Weblate (Czech)

Currently translated at 92.3% (2721 of 2947 strings)

Translation: Mattermost/server
Translate-URL: https://translate.mattermost.com/projects/mattermost/server/cs/

* Translated using Weblate (Czech)

Currently translated at 87.8% (6117 of 6966 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/cs/

* Translated using Weblate (Norwegian Bokmål)

Currently translated at 78.3% (5459 of 6966 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/nb_NO/

* Translated using Weblate (Swedish)

Currently translated at 92.6% (6452 of 6966 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/sv/

* Translated using Weblate (Dutch)

Currently translated at 99.8% (2942 of 2947 strings)

Translation: Mattermost/server
Translate-URL: https://translate.mattermost.com/projects/mattermost/server/nl/

* Translated using Weblate (Dutch)

Currently translated at 97.9% (6824 of 6966 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/nl/

* Translated using Weblate (German)

Currently translated at 100.0% (2947 of 2947 strings)

Translation: Mattermost/server
Translate-URL: https://translate.mattermost.com/projects/mattermost/server/de/

* Translated using Weblate (German)

Currently translated at 95.1% (6631 of 6966 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/de/

* Translated using Weblate (Chinese (Simplified Han script))

Currently translated at 99.1% (6909 of 6966 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/zh_Hans/

* Translated using Weblate (Dutch)

Currently translated at 98.3% (6853 of 6966 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/nl/

---------

Co-authored-by: thePanz <thepanz@gmail.com>
Co-authored-by: Sharuru <mave@foxmail.com>
Co-authored-by: Tom De Moor <tom@controlaltdieliet.be>
Co-authored-by: Roman belda <roman@romanbelda.cz>
Co-authored-by: Frank Paul Silye <frankps@gmail.com>
Co-authored-by: Kristoffer Grundström <swedishsailfishosuser@tutanota.com>
Co-authored-by: jprusch <rs@schaeferbarthold.de>
2026-02-09 14:31:47 +00:00
Andre Vasconcelos
13a0d63b3c
MM-67372: Improve link preview metadata handling and filtering (#35178)
* MM-67372: Filter SVG images from OpenGraph metadata to prevent DoS

This commit adds server-side filtering of SVG images from OpenGraph
metadata to mitigate a DoS vulnerability where malicious SVG images
in og:image tags can crash Chromium-based browsers and Safari.

Changes:
- Add IsSVGImageURL() helper function in model package to detect SVG URLs
- Filter SVG images in parseOpenGraphMetadata() for regular HTML pages
- Filter SVG images in parseOpenGraphFromOEmbed() for oEmbed responses
- Add defense-in-depth filtering in TruncateOpenGraph() and getImagesForPost()
- Add comprehensive tests for all SVG filtering functionality

SVG detection is based on:
- File extension (.svg, .svgz) - case-insensitive
- MIME type (image/svg+xml)

Reference: https://issues.chromium.org/issues/40057345

* MM-67372: Filter SVG images from cache/DB and direct SVG URLs

This commit addresses remaining attack vectors for the SVG DoS vulnerability:

1. Cache/DB filtering: Apply TruncateOpenGraph when returning OpenGraph
   from cache or database to filter stale data that was stored before
   the initial fix was deployed.

2. Direct SVG URLs: Filter PostImage entries with Format="svg" to prevent
   browser crashes when someone posts a direct link to an SVG file.

3. Embed creation: Skip creating image embeds for SVG images and create
   link embeds instead.

4. New SVG detection: Return nil instead of creating PostImage when
   fetching direct SVG URLs to prevent storing them in the database.

These changes ensure that even environments with pre-existing malicious
link metadata will be protected after a server restart.

* MM-67372: Fix test expectation for SVG image handling

* Removed duplicate logic in favor of already implemented FilterSVGImages in model

* Addressing PR comments

* Replacing exact match comparison with prefix check

* Added new test cases for unit tests
2026-02-09 16:26:14 +02:00
Ibrahim Serdar Acikgoz
b947f1c38a
Add fileSize limit to extractors (#35200) 2026-02-09 15:22:30 +01:00
sabril
bffe406e9f
(chore): upgrade playwright and its dependencies (#35175) 2026-02-09 21:30:07 +08:00
Alejandro García Montoro
139ff4ded2
Fix permissions in GetGroupsByNames (#35119)
The reliance on ViewUsersRestrictions was causing a SQL bug, since the
original query did not join with the Users table. Instead, use
model.GroupSearchOpts to rely on AllowReference, which should be used to
filter the results in all cases, except when the user is a sysadmin (has
the PermissionSysconsoleReadUserManagementGroups permission).

Co-authored-by: Mattermost Build <build@mattermost.com>
2026-02-09 10:13:48 +00:00
David Krauser
892492a0a8
[MM-66836] Add ability to delete orphaned protected fields from uninstalled plugins (#34867)
This change allows admins to delete protected property fields when the source plugin has been uninstalled, providing a cleanup mechanism for orphaned fields. If a field has the protected attribute set to true, but the associated source plugin is not installed, an admin can remove that field from the admin console.
2026-02-06 20:45:27 -05:00
David Krauser
a995682464
[MM-66836] Add UI support for protected and source_only property fields (#34860)
- Disable editing of protected fields in admin console and user profiles
- Show "Managed by: {pluginId}" indicator for protected fields in admin panel
- Disable dot menu button for protected fields in property management table
- Hide source_only fields from all user/profile views (user settings, profile popover, admin user management)
- source_only fields remain visible only in the field management configuration view
- Add i18n messages for protected field indicators
2026-02-06 19:21:25 -05:00
David Krauser
1cfe3d92b6
[MM-66836] Integrate PropertyAccessService into API and app layers (#34818)
Updates all Custom Profile Attribute endpoints and app layer methods to pass caller user IDs through to the PropertyAccessService. This connects the access control service introduced in #34812 to the REST API, Plugin API, and internal app operations.

Also updates the OpenAPI spec to document the new field attributes (protected, source_plugin_id, access_mode) and adds notes about protected field restrictions.
2026-02-06 18:06:51 -05:00
David Krauser
63c3c70fe9
[MM-66836] Add some access control mechanisms with a wrapper around the property service (#34812)
Custom profile attributes (properties) in Mattermost need to support security-critical use cases like Attribute-Based Access Control (ABAC), external identity system synchronization, and privacy-preserving collaboration. Without access controls on these properties, any user or component could modify property fields and values, making them unsuitable for security decisions. Additionally, different properties require different visibility patterns - some need to be publicly readable, some should only be visible to their managing system, and some require privacy-preserving visibility where users can only see shared values.

This change introduces the PropertyAccessService, a wrapper around PropertyService that enforces access control for all property operations. This service is introduced in isolation and is not yet hooked up to the Plugin API, REST API, or app layer. It provides the foundation for a single enforcement point that will apply access restrictions consistently across all code paths once integrated.
2026-02-06 16:21:51 -05:00
David Krauser
9f40d051ee
[MM-66942] Ensure consistent option ID generation across all field creation paths (#34725)
Option IDs are automatically generated for fields in the REST API, but plugins creating fields directly don't get this behavior. This change makes option ID generation consistent by automatically generating IDs for all select/multiselect options, regardless of whether they're created via REST API or plugin code. The option IDs are generated (if necessary) in the store layer right before saving, which is the same place we generate Field IDs if they don't exist.
2026-02-06 16:19:42 -05:00
Daniel Espino García
2bd29c0359
Add the ability to patch channel autotranslations (#35078)
* Add the ability to patch channel autotranslations

* Fix lint

* Update docs

* Fix CI

* Fix CI

* Fix mmctl test

* Check whether the channel is translated for the user when checking user enabled

* Fix wrong uses of patch acrros e2e and frontend

* Fix test

* Fix wording

* Fix tests and column name

* Move group constrained test so they don't mess with the basic entities

* Fix patch sending too much information
2026-02-06 18:19:06 +01:00
Alejandro García Montoro
f6574143a8
Document URL search in Postgres through tests (#35194)
* Document URL search in Postgres through test

* Use the length of the expectedIDs slice

* Simplify creation of posts
2026-02-06 13:25:21 +01:00
Ibrahim Serdar Acikgoz
197fa160b4
[MM-67126] harden checks (#35171) 2026-02-05 21:48:36 +01:00
Ibrahim Serdar Acikgoz
c31fe3f244
invalidate channel cache after deleting a channel access control policy (#35174) 2026-02-05 21:45:11 +01:00
Ben Cooke
9ac02ecfdd
Update translation primary key to include objectType (#35040) 2026-02-05 15:00:08 -05:00
Ibrahim Serdar Acikgoz
22e4e9c171
Improve mmctl output by filtering escape sequences (#35191) 2026-02-05 15:32:35 +01:00
Daniel Espino García
1273632d1a
Add endpoint to update channel member autotranslations (#35072)
* Add endpoint to update channel member autotranslations

* Add several improvements and remove unneeded functions

* Add user id to audit record

* Ensure autotranslation is defined

* Update texts

* Fix merge

* Add new column for channel member autotranslations (#35111)

* Minor renamings

---------

Co-authored-by: Mattermost Build <build@mattermost.com>
Co-authored-by: Ben Cooke <benkcooke@gmail.com>
2026-02-05 13:43:50 +01:00
Ibrahim Serdar Acikgoz
a06d5065e7
apply view restrcitions while fetching group members (#35172) 2026-02-05 12:45:57 +01:00
Amy Blais
444ada7251
Update en.json (#35160)
Automatic Merge
2026-02-05 09:23:28 +02:00
sabril
5a408b757c
(fix): verified by label and playwright rerun on failed specs (#35161) 2026-02-05 08:48:29 +08:00
Just Nev
4887c501e1
chore: Update zoom version to 1.12.0 (#35167)
Co-authored-by: Nevyana Angelova <nevyangelova@Nevy-Macbook-16-2025.local>
Co-authored-by: Mattermost Build <build@mattermost.com>
2026-02-04 18:03:04 +07:00
Alejandro García Montoro
67226f32a4
Avoid simple config when doing FTS in Postgres (#35063)
This commit reverts PR #30214, which addressed bug MM-60790 but caused a
performance regression tracked by MM-66782.

This revert has two implications:

1. The performance issue is solved.
2. The original bug is re-introduced.

Re-introducing the original bug seems not to be ideal, but I argue that
the original PR did not actually fix the bug:

- Before that PR, looking for a quoted string would return additional
  results: the UX was slightly confusing, because when the user looked
  for the word "stateful", the results would contain matches like
  "states" (see MM-60790).
- After that PR, looking for a quoted string can timeout, so that the
  list of results becomes empty. The UX here may be less confusing,
  since the user simply doesn't find what they're looking for, and they
  may assume that string is not present in any post, but it's completely
  wrong: the result list is empty because the SQL query timed out and
  thus the endpoint returned 0 results.

The solution to the original issue should be addressed via
Elasticsearch, which should provide a more refined and precise search
results.

For more information on the investigation on this issue and the
motivation behind the revert, see
https://mattermost.atlassian.net/wiki/x/IYAk_w

Co-authored-by: Mattermost Build <build@mattermost.com>
2026-02-04 12:02:02 +01:00
unified-ci-app[bot]
030a4e1921
Update latest minor version to 11.5.0 (#35176)
Automatic Merge
2026-02-04 12:23:27 +02:00
sabril
e499decea0
(test): fix flaky and migrate to playwright (#35156) 2026-02-04 12:21:17 +08:00
sabril
51e6431275
MM-67328 Bulk migrate Enzyme to RTL (M2 to M6) (#35068)
* migrate(enzyme): bulk migration to rtl

* updated per suggestion

---------

Co-authored-by: Mattermost Build <build@mattermost.com>
2026-02-04 01:42:48 +00:00
Nick Misasi
0263262ef4
MM-66577 Preserve locale in rewrite prompt (#35013)
Some checks failed
API / build (push) Has been cancelled
Server CI / Compute Go Version (push) Has been cancelled
Web App CI / check-lint (push) Has been cancelled
Server CI / Check mocks (push) Has been cancelled
Server CI / Check go mod tidy (push) Has been cancelled
Server CI / check-style (push) Has been cancelled
Server CI / Check serialization methods for hot structs (push) Has been cancelled
Server CI / Vet API (push) Has been cancelled
Server CI / Check migration files (push) Has been cancelled
Server CI / Generate email templates (push) Has been cancelled
Server CI / Check store layers (push) Has been cancelled
Server CI / Check mmctl docs (push) Has been cancelled
Server CI / Postgres with binary parameters (push) Has been cancelled
Server CI / Postgres (push) Has been cancelled
Server CI / Postgres (FIPS) (push) Has been cancelled
Server CI / Generate Test Coverage (push) Has been cancelled
Server CI / Run mmctl tests (push) Has been cancelled
Server CI / Run mmctl tests (FIPS) (push) Has been cancelled
Server CI / Build mattermost server app (push) Has been cancelled
Web App CI / check-i18n (push) Has been cancelled
Web App CI / check-types (push) Has been cancelled
Web App CI / test (platform) (push) Has been cancelled
Web App CI / test (mattermost-redux) (push) Has been cancelled
Web App CI / test (channels shard 1/4) (push) Has been cancelled
Web App CI / test (channels shard 2/4) (push) Has been cancelled
Web App CI / test (channels shard 3/4) (push) Has been cancelled
Web App CI / test (channels shard 4/4) (push) Has been cancelled
Web App CI / upload-coverage (push) Has been cancelled
Web App CI / build (push) Has been cancelled
* Preserve rewrite locale in prompt

* Add license header to rewrite tests
2026-02-03 11:32:03 -05:00
Nick Misasi
aa5d51131d
Register product icon change (#34883)
* Adjust registerProduct to accept generic icon

* Undo unnecessary changes

* Anotha one

* Fix linting errors in product menu tests

- Fix jsx-quotes to use single quotes instead of double quotes
- Fix react/jsx-max-props-per-line by placing props on separate lines
- Fix react/jsx-no-literals by wrapping literal strings in JSX expression containers
- Fix react/jsx-wrap-multilines by wrapping multiline JSX in parentheses
- Fix react/jsx-closing-bracket-location for proper bracket alignment

* don't use snapshots or enzyme

* Fix pipelines?
2026-02-03 10:45:02 -05:00
Erwan Martin
f3c6602725
Allow building the server on FreeBSD (#25838)
* Allow building the server on FreeBSD

* Fix merge

---------

Co-authored-by: Erwan Martin <erwan@pepper.com>
Co-authored-by: Alejandro García Montoro <alejandro.garciamontoro@gmail.com>
2026-02-03 14:05:16 +00:00
Ben Cooke
36479bd721
Configurable workers and move sweeper job to job infra (#35007)
Some checks are pending
API / build (push) Waiting to run
Server CI / Compute Go Version (push) Waiting to run
Server CI / Check mocks (push) Blocked by required conditions
Server CI / Check go mod tidy (push) Blocked by required conditions
Server CI / check-style (push) Blocked by required conditions
Server CI / Check serialization methods for hot structs (push) Blocked by required conditions
Server CI / Vet API (push) Blocked by required conditions
Server CI / Check migration files (push) Blocked by required conditions
Server CI / Generate email templates (push) Blocked by required conditions
Server CI / Check store layers (push) Blocked by required conditions
Server CI / Check mmctl docs (push) Blocked by required conditions
Server CI / Postgres with binary parameters (push) Blocked by required conditions
Server CI / Postgres (push) Blocked by required conditions
Server CI / Postgres (FIPS) (push) Blocked by required conditions
Server CI / Generate Test Coverage (push) Blocked by required conditions
Server CI / Run mmctl tests (push) Blocked by required conditions
Server CI / Run mmctl tests (FIPS) (push) Blocked by required conditions
Server CI / Build mattermost server app (push) Blocked by required conditions
Web App CI / check-lint (push) Waiting to run
Web App CI / check-i18n (push) Blocked by required conditions
Web App CI / check-types (push) Blocked by required conditions
Web App CI / test (platform) (push) Blocked by required conditions
Web App CI / test (mattermost-redux) (push) Blocked by required conditions
Web App CI / test (channels shard 1/4) (push) Blocked by required conditions
Web App CI / test (channels shard 2/4) (push) Blocked by required conditions
Web App CI / test (channels shard 3/4) (push) Blocked by required conditions
Web App CI / test (channels shard 4/4) (push) Blocked by required conditions
Web App CI / upload-coverage (push) Blocked by required conditions
Web App CI / build (push) Blocked by required conditions
2026-02-02 15:52:42 -05:00
Matthew Birtch
95ba2db4f0
[MM-66862] Channel Info RHS: add ability to rename and open channel settings (#34708)
* Channel Info RHS: add rename-from-info and settings access

Add channel name editable area with pencil hover and wire to a lightweight Rename Channel modal; add Channel Settings item to RHS menu with permission checks; ensure navigation after rename uses relative path to avoid 404.

* linter changes

* add padding so field labels don't get cut off

* fixes for keyboard accessibility and tooltips

* don't show channel settings for DMs and GMs

* chore(i18n): run extract to reorder new keys and fix CI

Re-extracted webapp i18n to place newly added keys (editable tooltips and rename modal) in canonical order expected by translation tooling.

* use generic_btn.cancel/save for rename modal buttons

* chore(i18n): remove unused rename_channel.cancel/save keys

* updated tests to account for new elements in the info rhs

* add cypress test for new rhs info function

* fix linting issues

* fixed tests

* linter fixes

* tweak position of edit button

* style tweaks, remove subtitle from info rhs head (redundant now), update archived state

* added 'unarchive' button to archived notice, updated translations

* fixed tests that I broke in channel info header

* add url name to channel info view

* update to 'channel handle' instead of url name'

* change order of channel handle

* add copy button

* Update about_area_channel.test.tsx

* fixed test and brought back channel subtitle in header for consistency

* fixed header test

* make channel info rhs scrollable

* fix merge issue

* Fix lint

---------

Co-authored-by: yasserfaraazkhan <attitude3cena.yf@gmail.com>
2026-02-02 17:34:32 +00:00
Harrison Healey
4049300129
Change moduleResolution to bundler for web app (#35081)
This tells the TypeScript compiler (only used for type checking in the web app)
to use the `imports` and `exports` field of a package's `package.json` to find
modules. Those fields are standard in newer versions of Node.js, and hopefully
supporting them means that we'll have to do less work to configure tooling in
the future.

We could also get similar behaviour by using the `nodenext` option, but that
adds some additional requirements to include file extensions which ES Modules
technically require, but I don't think we need to enforce because other tooling
doesn't require them.

I wanted to make that change in all of the subpackages as well, but we can't do
that without having TypeScript output ES Modules which, unless we change their
build processes to generate multiple formats (like the shared package in
client package, or the types package which is more than I want to do at the
moment.

The changes to other files are either because they incorrectly imported types
from a file that isn't intentionally exposed by the plugin or it's because we
had a typo in a file path.
2026-02-02 12:08:04 -05:00
Weblate (bot)
6f9b6f3364
Translations update from Mattermost Weblate (#35159)
Some checks are pending
API / build (push) Waiting to run
Server CI / Compute Go Version (push) Waiting to run
Server CI / Check mocks (push) Blocked by required conditions
Server CI / Check go mod tidy (push) Blocked by required conditions
Server CI / check-style (push) Blocked by required conditions
Server CI / Check serialization methods for hot structs (push) Blocked by required conditions
Server CI / Vet API (push) Blocked by required conditions
Server CI / Check migration files (push) Blocked by required conditions
Server CI / Generate email templates (push) Blocked by required conditions
Server CI / Check store layers (push) Blocked by required conditions
Server CI / Check mmctl docs (push) Blocked by required conditions
Server CI / Postgres with binary parameters (push) Blocked by required conditions
Server CI / Postgres (push) Blocked by required conditions
Server CI / Postgres (FIPS) (push) Blocked by required conditions
Server CI / Generate Test Coverage (push) Blocked by required conditions
Server CI / Run mmctl tests (push) Blocked by required conditions
Server CI / Run mmctl tests (FIPS) (push) Blocked by required conditions
Server CI / Build mattermost server app (push) Blocked by required conditions
Web App CI / check-lint (push) Waiting to run
Web App CI / check-i18n (push) Blocked by required conditions
Web App CI / check-types (push) Blocked by required conditions
Web App CI / test (platform) (push) Blocked by required conditions
Web App CI / test (mattermost-redux) (push) Blocked by required conditions
Web App CI / test (channels shard 1/4) (push) Blocked by required conditions
Web App CI / test (channels shard 2/4) (push) Blocked by required conditions
Web App CI / test (channels shard 3/4) (push) Blocked by required conditions
Web App CI / test (channels shard 4/4) (push) Blocked by required conditions
Web App CI / upload-coverage (push) Blocked by required conditions
Web App CI / build (push) Blocked by required conditions
* Update translation files

Updated by "Cleanup translation files" hook in Weblate.

Translation: Mattermost/server
Translate-URL: https://translate.mattermost.com/projects/mattermost/server/

* Update translation files

Updated by "Cleanup translation files" hook in Weblate.

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/

* Translated using Weblate (Polish)

Currently translated at 99.0% (2924 of 2951 strings)

Translation: Mattermost/server
Translate-URL: https://translate.mattermost.com/projects/mattermost/server/pl/

* Translated using Weblate (Norwegian Bokmål)

Currently translated at 78.3% (5457 of 6963 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/nb_NO/

* Translated using Weblate (Polish)

Currently translated at 95.2% (6630 of 6963 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/pl/

* Update translation files

Updated by "Cleanup translation files" hook in Weblate.

Translation: Mattermost/server
Translate-URL: https://translate.mattermost.com/projects/mattermost/server/

---------

Co-authored-by: master7 <marcin.karkosz@rajska.info>
Co-authored-by: Frank Paul Silye <frankps@gmail.com>
2026-02-02 14:04:07 +00:00
Jesse Hallam
70a50edcf2
[MM-67021] Fix 500 errors on check-cws-connection in non-Cloud environments (#34786)
* Fix 500 errors on check-cws-connection in non-Cloud environments

The check-cws-connection endpoint was returning 500 errors in
self-hosted enterprise environments because:

1. The client only checked BuildEnterpriseReady before making the
   request, which is true for all enterprise builds
2. The server handler didn't check for a Cloud license before
   attempting to connect to CWS
3. The CWS URL is not configured in non-Cloud environments, causing
   the connection check to fail

This fix:
- Server: Add IsCloud() license check to match other cloud endpoints,
  returning 403 instead of 500 for non-Cloud licenses
- Client: Add Cloud license check to skip the request entirely in
  non-Cloud environments

* Add unit tests for check-cws-connection license check

* Return JSON status from check-cws-connection endpoint

Change the check-cws-connection endpoint to return 200 with a JSON body
containing status (available/unavailable) instead of using HTTP error
codes. This allows the endpoint to be used for air-gap detection on
self-hosted instances, not just Cloud deployments.

* i18n

---------

Co-authored-by: Mattermost Build <build@mattermost.com>
2026-02-02 13:41:14 +00:00
unified-ci-app[bot]
b74b5fe83f
chore: Update NOTICE.txt file with updated dependencies (#35158)
Automatic Merge
2026-02-02 13:23:28 +02:00
Harshil Sharma
990e9b34bf
Removed initial BOR post reveal WS event for post author (#34939)
* Removed initial BOR post reveal WS event for post author

* restored package lock

---------

Co-authored-by: Mattermost Build <build@mattermost.com>
2026-02-02 16:16:50 +05:30
Harshil Sharma
dc69319c67
Moved flag post option before delete post (#35019)
Co-authored-by: Mattermost Build <build@mattermost.com>
2026-02-02 16:16:21 +05:30
sabril
981ff0bc46
MM-66362 feat: run e2e full tests after successful smoke tests both in cypress and playwright (#34868)
Some checks are pending
API / build (push) Waiting to run
Server CI / Compute Go Version (push) Waiting to run
Server CI / Check mocks (push) Blocked by required conditions
Server CI / Check go mod tidy (push) Blocked by required conditions
Server CI / check-style (push) Blocked by required conditions
Server CI / Check serialization methods for hot structs (push) Blocked by required conditions
Server CI / Vet API (push) Blocked by required conditions
Server CI / Check migration files (push) Blocked by required conditions
Server CI / Generate email templates (push) Blocked by required conditions
Server CI / Check store layers (push) Blocked by required conditions
Server CI / Check mmctl docs (push) Blocked by required conditions
Server CI / Postgres with binary parameters (push) Blocked by required conditions
Server CI / Postgres (push) Blocked by required conditions
Server CI / Postgres (FIPS) (push) Blocked by required conditions
Server CI / Generate Test Coverage (push) Blocked by required conditions
Server CI / Run mmctl tests (push) Blocked by required conditions
Server CI / Run mmctl tests (FIPS) (push) Blocked by required conditions
Server CI / Build mattermost server app (push) Blocked by required conditions
Web App CI / check-lint (push) Waiting to run
Web App CI / check-i18n (push) Blocked by required conditions
Web App CI / check-types (push) Blocked by required conditions
Web App CI / test (platform) (push) Blocked by required conditions
Web App CI / test (mattermost-redux) (push) Blocked by required conditions
Web App CI / test (channels shard 1/4) (push) Blocked by required conditions
Web App CI / test (channels shard 2/4) (push) Blocked by required conditions
Web App CI / test (channels shard 3/4) (push) Blocked by required conditions
Web App CI / test (channels shard 4/4) (push) Blocked by required conditions
Web App CI / upload-coverage (push) Blocked by required conditions
Web App CI / build (push) Blocked by required conditions
* feat: run e2e full tests after successful smoke tests both in cypress and playwright

* fix lint check on jsdoc req in playwright test

* update smoke test filter

* update test filter for cypress tests

* update docker services, fix branch convention and rearrange secrets

* update e2e-test workflow docs

* reorganized

* fix lint

* fix playwright template

* fix results assertion

* add retest, e2e-test-verified, gh comments of failed tests, path filters, run e2e-tests check first and demote unstable tests

* run using master image for e2e-only changes, add ts/js actions for cypress and playwright calculations, add verified by label

---------

Co-authored-by: Mattermost Build <build@mattermost.com>
2026-02-02 08:37:55 +08:00
Pablo Vélez
8db2ef6b9f
MM-67365 - adjust bor icons and priority labels in compact mode (#35121)
Some checks failed
API / build (push) Has been cancelled
Server CI / Compute Go Version (push) Has been cancelled
Web App CI / check-lint (push) Has been cancelled
Server CI / Check mocks (push) Has been cancelled
Server CI / Check go mod tidy (push) Has been cancelled
Server CI / check-style (push) Has been cancelled
Server CI / Check serialization methods for hot structs (push) Has been cancelled
Server CI / Vet API (push) Has been cancelled
Server CI / Check migration files (push) Has been cancelled
Server CI / Generate email templates (push) Has been cancelled
Server CI / Check store layers (push) Has been cancelled
Server CI / Check mmctl docs (push) Has been cancelled
Server CI / Postgres with binary parameters (push) Has been cancelled
Server CI / Postgres (push) Has been cancelled
Server CI / Postgres (FIPS) (push) Has been cancelled
Server CI / Generate Test Coverage (push) Has been cancelled
Server CI / Run mmctl tests (push) Has been cancelled
Server CI / Run mmctl tests (FIPS) (push) Has been cancelled
Server CI / Build mattermost server app (push) Has been cancelled
Web App CI / check-i18n (push) Has been cancelled
Web App CI / check-types (push) Has been cancelled
Web App CI / test (platform) (push) Has been cancelled
Web App CI / test (mattermost-redux) (push) Has been cancelled
Web App CI / test (channels shard 1/4) (push) Has been cancelled
Web App CI / test (channels shard 2/4) (push) Has been cancelled
Web App CI / test (channels shard 3/4) (push) Has been cancelled
Web App CI / test (channels shard 4/4) (push) Has been cancelled
Web App CI / upload-coverage (push) Has been cancelled
Web App CI / build (push) Has been cancelled
* MM-67365 - adjust bor icons and priority labels in compact mode

* fix linter issue
2026-01-31 15:09:25 -05:00
Julien Tant
288816834d
Bump playbooks to v2.7.0 (#35150)
Some checks are pending
API / build (push) Waiting to run
Server CI / Compute Go Version (push) Waiting to run
Server CI / Check mocks (push) Blocked by required conditions
Server CI / Check go mod tidy (push) Blocked by required conditions
Server CI / check-style (push) Blocked by required conditions
Server CI / Check serialization methods for hot structs (push) Blocked by required conditions
Server CI / Vet API (push) Blocked by required conditions
Server CI / Check migration files (push) Blocked by required conditions
Server CI / Generate email templates (push) Blocked by required conditions
Server CI / Check store layers (push) Blocked by required conditions
Server CI / Check mmctl docs (push) Blocked by required conditions
Server CI / Postgres with binary parameters (push) Blocked by required conditions
Server CI / Postgres (push) Blocked by required conditions
Server CI / Postgres (FIPS) (push) Blocked by required conditions
Server CI / Generate Test Coverage (push) Blocked by required conditions
Server CI / Run mmctl tests (push) Blocked by required conditions
Server CI / Run mmctl tests (FIPS) (push) Blocked by required conditions
Server CI / Build mattermost server app (push) Blocked by required conditions
Web App CI / check-lint (push) Waiting to run
Web App CI / check-i18n (push) Blocked by required conditions
Web App CI / check-types (push) Blocked by required conditions
Web App CI / test (platform) (push) Blocked by required conditions
Web App CI / test (mattermost-redux) (push) Blocked by required conditions
Web App CI / test (channels shard 1/4) (push) Blocked by required conditions
Web App CI / test (channels shard 2/4) (push) Blocked by required conditions
Web App CI / test (channels shard 3/4) (push) Blocked by required conditions
Web App CI / test (channels shard 4/4) (push) Blocked by required conditions
Web App CI / upload-coverage (push) Blocked by required conditions
Web App CI / build (push) Blocked by required conditions
2026-01-30 11:42:41 -07:00
Andre Vasconcelos
3321db82c3
Bumping prepackaged version of MS Teams Meetings plugin to 2.4.0 (#35146) 2026-01-30 18:03:20 +02:00
Jesse Hallam
5bb5261c72
MM-67279: Fix private channel enumeration via /mute slash command (#35099)
Some checks are pending
API / build (push) Waiting to run
Server CI / Compute Go Version (push) Waiting to run
Server CI / Check mocks (push) Blocked by required conditions
Server CI / Check go mod tidy (push) Blocked by required conditions
Server CI / check-style (push) Blocked by required conditions
Server CI / Check serialization methods for hot structs (push) Blocked by required conditions
Server CI / Vet API (push) Blocked by required conditions
Server CI / Check migration files (push) Blocked by required conditions
Server CI / Generate email templates (push) Blocked by required conditions
Server CI / Check store layers (push) Blocked by required conditions
Server CI / Check mmctl docs (push) Blocked by required conditions
Server CI / Postgres with binary parameters (push) Blocked by required conditions
Server CI / Postgres (push) Blocked by required conditions
Server CI / Postgres (FIPS) (push) Blocked by required conditions
Server CI / Generate Test Coverage (push) Blocked by required conditions
Server CI / Run mmctl tests (push) Blocked by required conditions
Server CI / Run mmctl tests (FIPS) (push) Blocked by required conditions
Server CI / Build mattermost server app (push) Blocked by required conditions
Web App CI / check-lint (push) Waiting to run
Web App CI / check-i18n (push) Blocked by required conditions
Web App CI / check-types (push) Blocked by required conditions
Web App CI / test (platform) (push) Blocked by required conditions
Web App CI / test (mattermost-redux) (push) Blocked by required conditions
Web App CI / test (channels shard 1/4) (push) Blocked by required conditions
Web App CI / test (channels shard 2/4) (push) Blocked by required conditions
Web App CI / test (channels shard 3/4) (push) Blocked by required conditions
Web App CI / test (channels shard 4/4) (push) Blocked by required conditions
Web App CI / upload-coverage (push) Blocked by required conditions
Web App CI / build (push) Blocked by required conditions
* MM-67279: Fix private channel enumeration via /mute slash command

Return the same error message when a user tries to mute a channel
they are not a member of as when the channel doesn't exist. This
prevents authenticated users from discovering private channels
by observing different error responses.

* update i18n

---------

Co-authored-by: Mattermost Build <build@mattermost.com>
2026-01-30 14:43:23 +00:00
Nick Misasi
90bdd6ae54
MM-67141 Update AI rewrite prompt guidance (#35011)
* Improve rewrite menu guidance

Keep AI rewrite prompts visible on focus and clarify the empty-state instruction.

* Apply suggestions from code review

* Apply suggestion from @nickmisasi

* Fix rewrite menu test assertions

Update test expectations to match component string values after defaultMessage changes. Fix syntax error with unterminated string and correct placeholder text expectation.

---------

Co-authored-by: Mattermost Build <build@mattermost.com>
2026-01-30 14:14:29 +00:00
Nick Misasi
fe4100956c
[MM-66581] Include some thread context in AI Rewrites prompt (#34931)
* Include last root, and most recent 10 posts in a thread with the rewrite system prompt

* Include user's names in the thread context for better reference

* Revert package-lock to master

* Fix tests
2026-01-30 09:14:06 -05:00
Alejandro García Montoro
1c1a445a3e
MM-67380: COALESCE Drafts.Type to the empty string if NULL (#35109)
Some checks are pending
API / build (push) Waiting to run
Server CI / Compute Go Version (push) Waiting to run
Server CI / Check mocks (push) Blocked by required conditions
Server CI / Check go mod tidy (push) Blocked by required conditions
Server CI / check-style (push) Blocked by required conditions
Server CI / Check serialization methods for hot structs (push) Blocked by required conditions
Server CI / Vet API (push) Blocked by required conditions
Server CI / Check migration files (push) Blocked by required conditions
Server CI / Generate email templates (push) Blocked by required conditions
Server CI / Check store layers (push) Blocked by required conditions
Server CI / Check mmctl docs (push) Blocked by required conditions
Server CI / Postgres with binary parameters (push) Blocked by required conditions
Server CI / Postgres (push) Blocked by required conditions
Server CI / Postgres (FIPS) (push) Blocked by required conditions
Server CI / Generate Test Coverage (push) Blocked by required conditions
Server CI / Run mmctl tests (push) Blocked by required conditions
Server CI / Run mmctl tests (FIPS) (push) Blocked by required conditions
Server CI / Build mattermost server app (push) Blocked by required conditions
Web App CI / check-lint (push) Waiting to run
Web App CI / check-i18n (push) Blocked by required conditions
Web App CI / check-types (push) Blocked by required conditions
Web App CI / test (platform) (push) Blocked by required conditions
Web App CI / test (mattermost-redux) (push) Blocked by required conditions
Web App CI / test (channels shard 1/4) (push) Blocked by required conditions
Web App CI / test (channels shard 2/4) (push) Blocked by required conditions
Web App CI / test (channels shard 3/4) (push) Blocked by required conditions
Web App CI / test (channels shard 4/4) (push) Blocked by required conditions
Web App CI / upload-coverage (push) Blocked by required conditions
Web App CI / build (push) Blocked by required conditions
When the Type column was added to the Drafts table, it did not add a
DEFAULT value, so we need to handle the NULL values for the pre-existing
rows.

Co-authored-by: Mattermost Build <build@mattermost.com>
2026-01-29 21:14:56 +01:00
Doug Lauder
7f6a98fd7a
MM-66789 Restrict log downloads to a root path for support packets (#35014)
* [MM-66789] Fix arbitrary file read vulnerability in advanced logging

  Add path validation to prevent reading files outside the logging root
  directory via GetAdvancedLogs (used in support packet generation).

  Security controls:
  - Validate file paths are within logging root before reading
  - Support MM_LOG_PATH environment variable to allow system admins
    to configure a custom logging root directory
  - Resolve symlinks to prevent bypass attacks
  - Detect and block path traversal attempts

  Also adds:
  - Audit logging for support packet generation
  - Config-time validation that logs errors for paths outside logging
    root (will become blocking in future version)
  - Comprehensive test coverage for path validation

* Update server/channels/app/platform/log_test.go

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* fix linter errors

* Update server/channels/api4/system.go

Co-authored-by: Ben Schumacher <ben.schumacher@mattermost.com>

* Simplify unit tests for platform/log_test.go by moving some test logic to config/logger_test.go

* Fix unit tests requiring logging root to be set

* enforce LogSettings.FileLocation path validation; simplify path checking

* fix linter errors

* use dir in logging root for all unit test logging

* MM_LOG_PATH is set once, centrally, for all tests

* fix flaky test

* fix flaky test

---------

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Mattermost Build <build@mattermost.com>
Co-authored-by: Ben Schumacher <ben.schumacher@mattermost.com>
2026-01-29 13:29:55 -05:00
Jesse Hallam
1346cf529a
MM-67274: Fix panic in getBrowserVersion with empty User-Agent version (#35098)
* MM-67274: Fix panic in getBrowserVersion with empty User-Agent version

Refactor getBrowserVersion to use a table-driven approach that
centralizes bounds checking, preventing panic when User-Agent strings
contain identifiers like "Mattermost Mobile/" with no version token.

* Refactor user agent tests to use structured test cases

Move expected values into the testUserAgent struct for clarity,
making it easier to see what each test case expects at a glance.
2026-01-29 13:12:35 -05:00
Alejandro García Montoro
7201f42d95
MM-67277: Add check to legacy hasher (#35092)
* Add check to legacy hasher

* Make the linter happy
2026-01-29 17:47:48 +01:00
Christopher Poile
168fb51666
[MM-67202] Validate auth method in account switch (#34981)
* fix account authorization type switch

* improve test clarity

* refactor tests for clarity
2026-01-29 16:14:19 +00:00
Ben Cooke
36173a4948
Use one timeout config for requests to translation providers (#34957)
Some checks are pending
API / build (push) Waiting to run
Server CI / Compute Go Version (push) Waiting to run
Server CI / Check mocks (push) Blocked by required conditions
Server CI / Check go mod tidy (push) Blocked by required conditions
Server CI / check-style (push) Blocked by required conditions
Server CI / Check serialization methods for hot structs (push) Blocked by required conditions
Server CI / Vet API (push) Blocked by required conditions
Server CI / Check migration files (push) Blocked by required conditions
Server CI / Generate email templates (push) Blocked by required conditions
Server CI / Check store layers (push) Blocked by required conditions
Server CI / Check mmctl docs (push) Blocked by required conditions
Server CI / Postgres with binary parameters (push) Blocked by required conditions
Server CI / Postgres (push) Blocked by required conditions
Server CI / Postgres (FIPS) (push) Blocked by required conditions
Server CI / Generate Test Coverage (push) Blocked by required conditions
Server CI / Run mmctl tests (push) Blocked by required conditions
Server CI / Run mmctl tests (FIPS) (push) Blocked by required conditions
Server CI / Build mattermost server app (push) Blocked by required conditions
Web App CI / check-lint (push) Waiting to run
Web App CI / check-i18n (push) Blocked by required conditions
Web App CI / check-types (push) Blocked by required conditions
Web App CI / test (platform) (push) Blocked by required conditions
Web App CI / test (mattermost-redux) (push) Blocked by required conditions
Web App CI / test (channels shard 1/4) (push) Blocked by required conditions
Web App CI / test (channels shard 2/4) (push) Blocked by required conditions
Web App CI / test (channels shard 3/4) (push) Blocked by required conditions
Web App CI / test (channels shard 4/4) (push) Blocked by required conditions
Web App CI / upload-coverage (push) Blocked by required conditions
Web App CI / build (push) Blocked by required conditions
2026-01-29 10:00:22 -05:00
Alejandro García Montoro
2b075c9b74
MM-65970: New way to build routes in Client4 (#34499)
* Add Client4 route building functions

* Make DoAPIRequestWithHeaders add the API URL

This makes it consistent with the other DoAPIXYZ functions, which all
prepend the provided URL with the client's API URL.

* Use the new route building logic in Client4

* Address review comments

- clean renamed to cleanSegment
- JoinRoutes and JoinSegments joined in Join
- newClientRoute uses Join

* Fix new routes from merge

* Remove unused import

* Simplify error handling around clientRoute (#34870)

---------

Co-authored-by: Jesse Hallam <jesse@mattermost.com>
Co-authored-by: Jesse Hallam <jesse.hallam@gmail.com>
Co-authored-by: Mattermost Build <build@mattermost.com>
2026-01-29 14:26:47 +00:00
Jesse Hallam
5d787969c2
MM-67268: Fix SSRF bypass via IPv4-mapped IPv6 literals (#35097)
Canonicalize IPv4-mapped IPv6 addresses (e.g., ::ffff:127.0.0.1) to
their native IPv4 form in IsReservedIP before checking against reserved
IP ranges. This prevents attackers from bypassing SSRF protections by
using IPv4-mapped IPv6 literals to access internal services.
2026-01-29 14:36:47 +01:00
Ben Cooke
4195b8bc5c
Metrics for Autotranslations (#34900) 2026-01-29 05:46:45 -05:00
Alejandro García Montoro
62df0b0417
Update the FIPS flavour of Playbooks to v2.6.2 (#35096)
Some checks are pending
API / build (push) Waiting to run
Server CI / Compute Go Version (push) Waiting to run
Server CI / Check mocks (push) Blocked by required conditions
Server CI / Check go mod tidy (push) Blocked by required conditions
Server CI / check-style (push) Blocked by required conditions
Server CI / Check serialization methods for hot structs (push) Blocked by required conditions
Server CI / Vet API (push) Blocked by required conditions
Server CI / Check migration files (push) Blocked by required conditions
Server CI / Generate email templates (push) Blocked by required conditions
Server CI / Check store layers (push) Blocked by required conditions
Server CI / Check mmctl docs (push) Blocked by required conditions
Server CI / Postgres with binary parameters (push) Blocked by required conditions
Server CI / Postgres (push) Blocked by required conditions
Server CI / Postgres (FIPS) (push) Blocked by required conditions
Server CI / Generate Test Coverage (push) Blocked by required conditions
Server CI / Run mmctl tests (push) Blocked by required conditions
Server CI / Run mmctl tests (FIPS) (push) Blocked by required conditions
Server CI / Build mattermost server app (push) Blocked by required conditions
Web App CI / check-lint (push) Waiting to run
Web App CI / check-i18n (push) Blocked by required conditions
Web App CI / check-types (push) Blocked by required conditions
Web App CI / test (platform) (push) Blocked by required conditions
Web App CI / test (mattermost-redux) (push) Blocked by required conditions
Web App CI / test (channels shard 1/4) (push) Blocked by required conditions
Web App CI / test (channels shard 2/4) (push) Blocked by required conditions
Web App CI / test (channels shard 3/4) (push) Blocked by required conditions
Web App CI / test (channels shard 4/4) (push) Blocked by required conditions
Web App CI / upload-coverage (push) Blocked by required conditions
Web App CI / build (push) Blocked by required conditions
Automatic Merge
2026-01-29 08:53:28 +02:00
sabril
7417d07733
Test/RTL: Use userEvent as much as possible and remove unneeded jest.clearAllMocks() (#35070)
Some checks are pending
API / build (push) Waiting to run
Server CI / Compute Go Version (push) Waiting to run
Server CI / Check mocks (push) Blocked by required conditions
Server CI / Check go mod tidy (push) Blocked by required conditions
Server CI / check-style (push) Blocked by required conditions
Server CI / Check serialization methods for hot structs (push) Blocked by required conditions
Server CI / Vet API (push) Blocked by required conditions
Server CI / Check migration files (push) Blocked by required conditions
Server CI / Generate email templates (push) Blocked by required conditions
Server CI / Check store layers (push) Blocked by required conditions
Server CI / Check mmctl docs (push) Blocked by required conditions
Server CI / Postgres with binary parameters (push) Blocked by required conditions
Server CI / Postgres (push) Blocked by required conditions
Server CI / Postgres (FIPS) (push) Blocked by required conditions
Server CI / Generate Test Coverage (push) Blocked by required conditions
Server CI / Run mmctl tests (push) Blocked by required conditions
Server CI / Run mmctl tests (FIPS) (push) Blocked by required conditions
Server CI / Build mattermost server app (push) Blocked by required conditions
Web App CI / check-lint (push) Waiting to run
Web App CI / check-i18n (push) Blocked by required conditions
Web App CI / check-types (push) Blocked by required conditions
Web App CI / test (platform) (push) Blocked by required conditions
Web App CI / test (mattermost-redux) (push) Blocked by required conditions
Web App CI / test (channels shard 1/4) (push) Blocked by required conditions
Web App CI / test (channels shard 2/4) (push) Blocked by required conditions
Web App CI / test (channels shard 3/4) (push) Blocked by required conditions
Web App CI / test (channels shard 4/4) (push) Blocked by required conditions
Web App CI / upload-coverage (push) Blocked by required conditions
Web App CI / build (push) Blocked by required conditions
* use userEvent as much as possible then fireEvent only if needed

* remove unnecessary jest.clearAllMocks

* update comments
2026-01-29 00:52:24 +08:00
Christopher Poile
67b8c89508
MM-67130: Fix permalink preview permissions (#34909)
* remove permalink embeds when user loses access to orginating channel

* remove posts & embeds on team_leave event; simplify preview index.ts

* cleanup

* remove dead code

* more dead code elimination
2026-01-28 15:01:40 +00:00
Doug Lauder
b2eb45e615
Add missing auditRec.Success calls; fix missing return on error. (#34954)
Some checks are pending
API / build (push) Waiting to run
Server CI / Compute Go Version (push) Waiting to run
Server CI / Check mocks (push) Blocked by required conditions
Server CI / Check go mod tidy (push) Blocked by required conditions
Server CI / check-style (push) Blocked by required conditions
Server CI / Check serialization methods for hot structs (push) Blocked by required conditions
Server CI / Vet API (push) Blocked by required conditions
Server CI / Check migration files (push) Blocked by required conditions
Server CI / Generate email templates (push) Blocked by required conditions
Server CI / Check store layers (push) Blocked by required conditions
Server CI / Check mmctl docs (push) Blocked by required conditions
Server CI / Postgres with binary parameters (push) Blocked by required conditions
Server CI / Postgres (push) Blocked by required conditions
Server CI / Postgres (FIPS) (push) Blocked by required conditions
Server CI / Generate Test Coverage (push) Blocked by required conditions
Server CI / Run mmctl tests (push) Blocked by required conditions
Server CI / Run mmctl tests (FIPS) (push) Blocked by required conditions
Server CI / Build mattermost server app (push) Blocked by required conditions
Web App CI / check-lint (push) Waiting to run
Web App CI / check-i18n (push) Blocked by required conditions
Web App CI / check-types (push) Blocked by required conditions
Web App CI / test (platform) (push) Blocked by required conditions
Web App CI / test (mattermost-redux) (push) Blocked by required conditions
Web App CI / test (channels shard 1/4) (push) Blocked by required conditions
Web App CI / test (channels shard 2/4) (push) Blocked by required conditions
Web App CI / test (channels shard 3/4) (push) Blocked by required conditions
Web App CI / test (channels shard 4/4) (push) Blocked by required conditions
Web App CI / upload-coverage (push) Blocked by required conditions
Web App CI / build (push) Blocked by required conditions
Co-authored-by: Mattermost Build <build@mattermost.com>
2026-01-27 23:07:53 +00:00
Julien Tant
73d7e66e97
Bump playbooks to v2.6.2 (#35077)
Some checks are pending
API / build (push) Waiting to run
Server CI / Compute Go Version (push) Waiting to run
Server CI / Check mocks (push) Blocked by required conditions
Server CI / Check go mod tidy (push) Blocked by required conditions
Server CI / check-style (push) Blocked by required conditions
Server CI / Check serialization methods for hot structs (push) Blocked by required conditions
Server CI / Vet API (push) Blocked by required conditions
Server CI / Check migration files (push) Blocked by required conditions
Server CI / Generate email templates (push) Blocked by required conditions
Server CI / Check store layers (push) Blocked by required conditions
Server CI / Check mmctl docs (push) Blocked by required conditions
Server CI / Postgres with binary parameters (push) Blocked by required conditions
Server CI / Postgres (push) Blocked by required conditions
Server CI / Postgres (FIPS) (push) Blocked by required conditions
Server CI / Generate Test Coverage (push) Blocked by required conditions
Server CI / Run mmctl tests (push) Blocked by required conditions
Server CI / Run mmctl tests (FIPS) (push) Blocked by required conditions
Server CI / Build mattermost server app (push) Blocked by required conditions
Web App CI / check-lint (push) Waiting to run
Web App CI / check-i18n (push) Blocked by required conditions
Web App CI / check-types (push) Blocked by required conditions
Web App CI / test (platform) (push) Blocked by required conditions
Web App CI / test (mattermost-redux) (push) Blocked by required conditions
Web App CI / test (channels shard 1/4) (push) Blocked by required conditions
Web App CI / test (channels shard 2/4) (push) Blocked by required conditions
Web App CI / test (channels shard 3/4) (push) Blocked by required conditions
Web App CI / test (channels shard 4/4) (push) Blocked by required conditions
Web App CI / upload-coverage (push) Blocked by required conditions
Web App CI / build (push) Blocked by required conditions
Automatic Merge
2026-01-27 23:53:27 +02:00
Carlos Garcia
320b3b411f
adds detailed error message to ES test connection (#35009)
* adds detailed error message to ES test connection

* changed to semicolon for consistency

* updated snapshots for elasticsearch settings test
2026-01-27 22:46:53 +01:00
Scott Bishel
fb22f56635
MM-67269 - Fix popout windows for subpath deployments (#35027)
* MM-67269 - Fix popout windows for subpath deployments

Popout windows were failing with 404 errors when Mattermost is served
from a subpath (e.g., https://company.com/mattermost). The popout
functions were constructing URLs without including the subpath prefix.

Changes:
- Updated popoutThread() and popoutRhsPlugin() to use getBasePath()
  helper function which includes window.basename
- Added unit tests to verify popout URLs include subpath when configured
- Follows established pattern used throughout codebase (getSiteURL,
  cookie paths, React Router)

This ensures popout windows open at the correct URL:
  /subpath/_popout/... instead of /_popout/...

Co-Authored-By: Claude Sonnet 4.5 (1M context) <noreply@anthropic.com>

* Clear mocks and set default base path in tests

---------

Co-authored-by: Claude Sonnet 4.5 (1M context) <noreply@anthropic.com>
Co-authored-by: Mattermost Build <build@mattermost.com>
2026-01-27 14:25:15 -07:00
Christopher Poile
eeaf9c8e3e
Fix bad merge (#35079) 2026-01-27 15:50:38 -05:00
Weblate (bot)
ea9333b2e8
Translations update from Mattermost Weblate (#35055)
* Translated using Weblate (Korean)

Currently translated at 92.0% (6275 of 6816 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/ko/

* Translated using Weblate (Polish)

Currently translated at 97.2% (6629 of 6816 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/pl/

* Translated using Weblate (Polish)

Currently translated at 100.0% (2933 of 2933 strings)

Translation: Mattermost/server
Translate-URL: https://translate.mattermost.com/projects/mattermost/server/pl/

* Translated using Weblate (Polish)

Currently translated at 97.3% (6636 of 6816 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/pl/

* Translated using Weblate (Chinese (Simplified Han script))

Currently translated at 96.2% (6563 of 6816 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/zh_Hans/

* Translated using Weblate (Dutch)

Currently translated at 99.8% (2929 of 2933 strings)

Translation: Mattermost/server
Translate-URL: https://translate.mattermost.com/projects/mattermost/server/nl/

* Translated using Weblate (Dutch)

Currently translated at 100.0% (6816 of 6816 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/nl/

* Translated using Weblate (Korean)

Currently translated at 92.1% (6278 of 6816 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/ko/

* Translated using Weblate (Norwegian Bokmål)

Currently translated at 5.0% (147 of 2933 strings)

Translation: Mattermost/server
Translate-URL: https://translate.mattermost.com/projects/mattermost/server/nb_NO/

* Translated using Weblate (Chinese (Simplified Han script))

Currently translated at 96.7% (6597 of 6816 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/zh_Hans/

* Translated using Weblate (Swedish)

Currently translated at 95.8% (2812 of 2933 strings)

Translation: Mattermost/server
Translate-URL: https://translate.mattermost.com/projects/mattermost/server/sv/

* Translated using Weblate (Swedish)

Currently translated at 95.8% (2812 of 2933 strings)

Translation: Mattermost/server
Translate-URL: https://translate.mattermost.com/projects/mattermost/server/sv/

* Translated using Weblate (Swedish)

Currently translated at 94.7% (6460 of 6816 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/sv/

* Update translation files

Updated by "Cleanup translation files" hook in Weblate.

Translation: Mattermost/server
Translate-URL: https://translate.mattermost.com/projects/mattermost/server/

* Update translation files

Updated by "Cleanup translation files" hook in Weblate.

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/

---------

Co-authored-by: wooki-00 <wookismile@naver.com>
Co-authored-by: master7 <marcin.karkosz@rajska.info>
Co-authored-by: ThrRip <coding@thrrip.space>
Co-authored-by: Tom De Moor <tom@controlaltdieliet.be>
Co-authored-by: avasconcelos114 <andre.onogoro@gmail.com>
Co-authored-by: Frank Paul Silye <frankps@gmail.com>
Co-authored-by: Kristoffer Grundström <swedishsailfishosuser@tutanota.com>
Co-authored-by: MArtin Johnson <martinjohnson@bahnhof.se>
Co-authored-by: Mattermost Build <build@mattermost.com>
2026-01-27 19:05:43 +00:00
Christopher Poile
fe3052073d
[MM-67074] Integration Action memory use fix (#34896) 2026-01-27 11:54:11 -05:00
Nick Misasi
fbe5ad0ea2
[MM-66591] Channel Summarization - header icon pluggable + citation support (#34687)
* Add pluggable ChannelHeaderIcon

* Add orchestration for post/channel/team citations in post render

* Updates to suit new format cor citations

* Fix linter

* Fix stylelint property order errors in _markdown.scss

* Fix TypeScript type errors

- Add missing ChannelHeaderIcon to initialComponents in plugins reducer
- Fix SelectProps generic to use 'false' instead of 'boolean' for isMulti in dropdown_input_hybrid

* Update channel_header snapshots to include ChannelHeaderIcon Pluggable

* PR feedback changes

* Add snapshots

* Add export for DatePicker

* PR Feedback

---------

Co-authored-by: Mattermost Build <build@mattermost.com>
2026-01-27 11:46:12 -05:00
Carlos Garcia
3388093c00
updates opensearch library dependency and adds tests for caused_by error reason returned (#34826) 2026-01-27 16:01:22 +01:00
Ibrahim Serdar Acikgoz
ced9a56e39
[MM-67126] Deprecate UpdateAccessControlPolicyActiveStatus API in favor of new one (#34940) 2026-01-27 15:49:08 +01:00
Carlos Garcia
89a29ce3c2
MM-66167 fix (#35061)
* use BUILD_ENTERPRISE_READY instead of hardcoded value in Makefile

* fixes MM-66167
2026-01-27 15:29:22 +01:00
Dylan Haussermann
8e7b3da702
Fixtures that allow install of a plugin from a target repo (#34520)
Some checks are pending
API / build (push) Waiting to run
Server CI / Compute Go Version (push) Waiting to run
Server CI / Check mocks (push) Blocked by required conditions
Server CI / Check go mod tidy (push) Blocked by required conditions
Server CI / check-style (push) Blocked by required conditions
Server CI / Check serialization methods for hot structs (push) Blocked by required conditions
Server CI / Vet API (push) Blocked by required conditions
Server CI / Check migration files (push) Blocked by required conditions
Server CI / Generate email templates (push) Blocked by required conditions
Server CI / Check store layers (push) Blocked by required conditions
Server CI / Check mmctl docs (push) Blocked by required conditions
Server CI / Postgres with binary parameters (push) Blocked by required conditions
Server CI / Postgres (push) Blocked by required conditions
Server CI / Postgres (FIPS) (push) Blocked by required conditions
Server CI / Generate Test Coverage (push) Blocked by required conditions
Server CI / Run mmctl tests (push) Blocked by required conditions
Server CI / Run mmctl tests (FIPS) (push) Blocked by required conditions
Server CI / Build mattermost server app (push) Blocked by required conditions
Web App CI / check-lint (push) Waiting to run
Web App CI / check-i18n (push) Blocked by required conditions
Web App CI / check-types (push) Blocked by required conditions
Web App CI / test (platform) (push) Blocked by required conditions
Web App CI / test (mattermost-redux) (push) Blocked by required conditions
Web App CI / test (channels shard 1/4) (push) Blocked by required conditions
Web App CI / test (channels shard 2/4) (push) Blocked by required conditions
Web App CI / test (channels shard 3/4) (push) Blocked by required conditions
Web App CI / test (channels shard 4/4) (push) Blocked by required conditions
Web App CI / upload-coverage (push) Blocked by required conditions
Web App CI / build (push) Blocked by required conditions
* Fixtures that allow install of a plugin from a target repo

* Fixed linting error and applied `prettier` formating.

* Implemeted feedback from code review

* Remove unused AdminConfig import

---------

Co-authored-by: Mattermost Build <build@mattermost.com>
2026-01-27 21:41:49 +08:00
Ibrahim Serdar Acikgoz
dfbe788732
[MM-64365] omit group constrained channels from the ch. selector for ABAC (#35010) 2026-01-27 13:31:58 +01:00
Alejandro García Montoro
4cd9a266f8
Update the FIPS flavour of Boards to v9.2.2 (#35064)
Automatic Merge
2026-01-27 08:53:33 +02:00
Harshil Sharma
c6b205f0d7
Fixed WS payload for post burn event (#34936)
* Handled WS payload

* increased WS faliure timeout to elliminate flakiness

* lint fix

---------

Co-authored-by: Mattermost Build <build@mattermost.com>
2026-01-27 11:57:06 +05:30
unified-ci-app[bot]
8ff88242a9
chore: Update NOTICE.txt file with updated dependencies (#35053)
Automatic Merge
2026-01-27 08:23:28 +02:00
lindalumitchell
ace5810d65
Update file_preview.js (#35028)
Some checks are pending
API / build (push) Waiting to run
Server CI / Compute Go Version (push) Waiting to run
Server CI / Check mocks (push) Blocked by required conditions
Server CI / Check go mod tidy (push) Blocked by required conditions
Server CI / check-style (push) Blocked by required conditions
Server CI / Check serialization methods for hot structs (push) Blocked by required conditions
Server CI / Vet API (push) Blocked by required conditions
Server CI / Check migration files (push) Blocked by required conditions
Server CI / Generate email templates (push) Blocked by required conditions
Server CI / Check store layers (push) Blocked by required conditions
Server CI / Check mmctl docs (push) Blocked by required conditions
Server CI / Postgres with binary parameters (push) Blocked by required conditions
Server CI / Postgres (push) Blocked by required conditions
Server CI / Postgres (FIPS) (push) Blocked by required conditions
Server CI / Generate Test Coverage (push) Blocked by required conditions
Server CI / Run mmctl tests (push) Blocked by required conditions
Server CI / Run mmctl tests (FIPS) (push) Blocked by required conditions
Server CI / Build mattermost server app (push) Blocked by required conditions
Web App CI / check-lint (push) Waiting to run
Web App CI / check-i18n (push) Blocked by required conditions
Web App CI / check-types (push) Blocked by required conditions
Web App CI / test (platform) (push) Blocked by required conditions
Web App CI / test (mattermost-redux) (push) Blocked by required conditions
Web App CI / test (channels shard 1/4) (push) Blocked by required conditions
Web App CI / test (channels shard 2/4) (push) Blocked by required conditions
Web App CI / test (channels shard 3/4) (push) Blocked by required conditions
Web App CI / test (channels shard 4/4) (push) Blocked by required conditions
Web App CI / upload-coverage (push) Blocked by required conditions
Web App CI / build (push) Blocked by required conditions
Co-authored-by: Mattermost Build <build@mattermost.com>
2026-01-27 05:50:08 +00:00
sabril
3db7477e45
MM-67281: (test) Migrate Enzyme to RTL (#35029)
* test: migrate enzyme to rtl

* replace renderWithIntl with renderWithContext

* remove jest.clearAllMocks

* use userEvent

* fix unrelated lint error
2026-01-27 12:22:13 +08:00
Scott Bishel
c537b88f93
MM-65023 Add tooltip to actions buttons, display error (#33773)
* Add tooltip support and error handling for action buttons

- Add tooltip field to PostAction type definition
- Display tooltips on hover for action buttons
- Add comprehensive error handling for button actions
- Show error messages when actions fail
- Clear previous errors on subsequent actions
- Add tests for error handling functionality

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>

* Add E2E tests for action button error handling and tooltips

- Test error message display when action buttons fail
- Test error clearing when successful actions are performed
- Test tooltip display on action button hover
- Use scoped selectors to avoid test interference
- Cover complete error lifecycle and tooltip functionality

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>

* Use WithTooltip component for action button tooltips

Replace native HTML title attribute with WithTooltip component to provide
consistent tooltip styling and behavior across the application.

Changes:
- Import and wrap ActionBtn with WithTooltip component
- Remove title attribute from ActionBtn
- Update E2E test to check for .tooltipContainer instead of title attribute

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* Fix TypeScript errors and test patterns in message attachment tests

- Fix TypeScript type errors in mock event objects by using arrow functions instead of jest.fn()
- Update async test pattern to use process.nextTick() with done callback instead of await
- Update test snapshots to reflect error handling wrapper div
- Fix whitespace formatting in E2E test file

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 (1M context) <noreply@anthropic.com>

* updated actionError to accept react node, replace hardcoded error with FormattedMessage components

* Fix test to handle FormattedMessage in actionError state

Update test expectation to check for FormattedMessage React element
instead of plain string when no error message is provided. This aligns
with the recent change to support internationalization in error messages.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 (1M context) <noreply@anthropic.com>

* Disable tooltip interactions when no tooltip text is present

Adds disabled prop to WithTooltip component when action.tooltip is empty or undefined, preventing unnecessary tooltip event handlers from being attached to action buttons that don't have tooltips.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 (1M context) <noreply@anthropic.com>

* Add tests for action button tooltip behavior

Adds three test cases to verify tooltip functionality:
- Tooltip is disabled when action.tooltip is undefined
- Tooltip is disabled when action.tooltip is empty string
- Tooltip is enabled and displays correctly when action.tooltip has a value

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 (1M context) <noreply@anthropic.com>

* fix e2e test

---------

Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Mattermost Build <build@mattermost.com>
2026-01-26 20:07:09 -07:00
sabril
7b1c32e34c
MM-67725: (test) Migrate enzyme to RTL (#34966) 2026-01-27 09:52:46 +08:00
Ben Cooke
a1c85007e1
Autotranslations MVP (#34696)
---------

Co-authored-by: Elias Nahum <nahumhbl@gmail.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Nick Misasi <nick.misasi@mattermost.com>
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Matthew Birtch <mattbirtch@gmail.com>
Co-authored-by: Mattermost Build <build@mattermost.com>
2026-01-26 17:05:34 -05:00
Ibrahim Serdar Acikgoz
df00184250
fix merge defect on server/channels/app/post_test.go (#35057)
Some checks are pending
API / build (push) Waiting to run
Server CI / Compute Go Version (push) Waiting to run
Server CI / Check mocks (push) Blocked by required conditions
Server CI / Check go mod tidy (push) Blocked by required conditions
Server CI / check-style (push) Blocked by required conditions
Server CI / Check serialization methods for hot structs (push) Blocked by required conditions
Server CI / Vet API (push) Blocked by required conditions
Server CI / Check migration files (push) Blocked by required conditions
Server CI / Generate email templates (push) Blocked by required conditions
Server CI / Check store layers (push) Blocked by required conditions
Server CI / Check mmctl docs (push) Blocked by required conditions
Server CI / Postgres with binary parameters (push) Blocked by required conditions
Server CI / Postgres (push) Blocked by required conditions
Server CI / Postgres (FIPS) (push) Blocked by required conditions
Server CI / Generate Test Coverage (push) Blocked by required conditions
Server CI / Run mmctl tests (push) Blocked by required conditions
Server CI / Run mmctl tests (FIPS) (push) Blocked by required conditions
Server CI / Build mattermost server app (push) Blocked by required conditions
Web App CI / check-lint (push) Waiting to run
Web App CI / check-i18n (push) Blocked by required conditions
Web App CI / check-types (push) Blocked by required conditions
Web App CI / test (platform) (push) Blocked by required conditions
Web App CI / test (mattermost-redux) (push) Blocked by required conditions
Web App CI / test (channels shard 1/4) (push) Blocked by required conditions
Web App CI / test (channels shard 2/4) (push) Blocked by required conditions
Web App CI / test (channels shard 3/4) (push) Blocked by required conditions
Web App CI / test (channels shard 4/4) (push) Blocked by required conditions
Web App CI / upload-coverage (push) Blocked by required conditions
Web App CI / build (push) Blocked by required conditions
2026-01-26 13:33:51 +01:00
Jesse Hallam
b62727e091
[MM-67290] Document that Elasticsearch backend type change requires server restart (#35038)
* [MM-67290] Document that Elasticsearch backend type change requires server restart

* Update Elasticsearch settings test snapshots

Update snapshots to reflect the new help text for the backend type
setting that documents the server restart requirement.
2026-01-26 09:27:31 +01:00
Alejandro García Montoro
7bbf8c71a2
Add missing check (#35034)
Some checks failed
API / build (push) Has been cancelled
Server CI / Compute Go Version (push) Has been cancelled
Web App CI / check-lint (push) Has been cancelled
Server CI / Check mocks (push) Has been cancelled
Server CI / Check go mod tidy (push) Has been cancelled
Server CI / check-style (push) Has been cancelled
Server CI / Check serialization methods for hot structs (push) Has been cancelled
Server CI / Vet API (push) Has been cancelled
Server CI / Check migration files (push) Has been cancelled
Server CI / Generate email templates (push) Has been cancelled
Server CI / Check store layers (push) Has been cancelled
Server CI / Check mmctl docs (push) Has been cancelled
Server CI / Postgres with binary parameters (push) Has been cancelled
Server CI / Postgres (push) Has been cancelled
Server CI / Postgres (FIPS) (push) Has been cancelled
Server CI / Generate Test Coverage (push) Has been cancelled
Server CI / Run mmctl tests (push) Has been cancelled
Server CI / Run mmctl tests (FIPS) (push) Has been cancelled
Server CI / Build mattermost server app (push) Has been cancelled
Web App CI / check-i18n (push) Has been cancelled
Web App CI / check-types (push) Has been cancelled
Web App CI / test (platform) (push) Has been cancelled
Web App CI / test (mattermost-redux) (push) Has been cancelled
Web App CI / test (channels shard 1/4) (push) Has been cancelled
Web App CI / test (channels shard 2/4) (push) Has been cancelled
Web App CI / test (channels shard 3/4) (push) Has been cancelled
Web App CI / test (channels shard 4/4) (push) Has been cancelled
Web App CI / upload-coverage (push) Has been cancelled
Web App CI / build (push) Has been cancelled
2026-01-24 13:55:59 +01:00
Christopher Poile
86797c508c
update mscfb and msoleps indirect dependencies to fix oom vuln. (#34910)
Some checks are pending
API / build (push) Waiting to run
Server CI / Compute Go Version (push) Waiting to run
Server CI / Check mocks (push) Blocked by required conditions
Server CI / Check go mod tidy (push) Blocked by required conditions
Server CI / check-style (push) Blocked by required conditions
Server CI / Check serialization methods for hot structs (push) Blocked by required conditions
Server CI / Vet API (push) Blocked by required conditions
Server CI / Check migration files (push) Blocked by required conditions
Server CI / Generate email templates (push) Blocked by required conditions
Server CI / Check store layers (push) Blocked by required conditions
Server CI / Check mmctl docs (push) Blocked by required conditions
Server CI / Postgres with binary parameters (push) Blocked by required conditions
Server CI / Postgres (push) Blocked by required conditions
Server CI / Postgres (FIPS) (push) Blocked by required conditions
Server CI / Generate Test Coverage (push) Blocked by required conditions
Server CI / Run mmctl tests (push) Blocked by required conditions
Server CI / Run mmctl tests (FIPS) (push) Blocked by required conditions
Server CI / Build mattermost server app (push) Blocked by required conditions
Web App CI / check-lint (push) Waiting to run
Web App CI / check-i18n (push) Blocked by required conditions
Web App CI / check-types (push) Blocked by required conditions
Web App CI / test (platform) (push) Blocked by required conditions
Web App CI / test (mattermost-redux) (push) Blocked by required conditions
Web App CI / test (channels shard 1/4) (push) Blocked by required conditions
Web App CI / test (channels shard 2/4) (push) Blocked by required conditions
Web App CI / test (channels shard 3/4) (push) Blocked by required conditions
Web App CI / test (channels shard 4/4) (push) Blocked by required conditions
Web App CI / upload-coverage (push) Blocked by required conditions
Web App CI / build (push) Blocked by required conditions
2026-01-23 23:56:01 +02:00
Pablo Vélez
37ec26b81a
MM-61383 - add back offline user help for messagging (#34756)
* MM-61383 - add back offline user help for messagging

* Apply suggestions from code review

Co-authored-by: Matthew Birtch <mattbirtch@gmail.com>

* Apply suggestions from code review

Co-authored-by: Matthew Birtch <mattbirtch@gmail.com>

* Use non-breaking spaces for code indendation display

* Fix avatar status badge being cut off in Mentioning Help page

* show help in popout, if available

* fix styling

* missing i18n

* help page titles

* missing i18n

* additional i18n

* fix missing values

* Make help link always visible, fix accessibility

* Fix CSS property ordering in help button styles

---------

Co-authored-by: Jesse Hallam <jesse.hallam@gmail.com>
Co-authored-by: Matthew Birtch <mattbirtch@gmail.com>
Co-authored-by: Jesse Hallam <jesse@mattermost.com>
Co-authored-by: Mattermost Build <build@mattermost.com>
2026-01-23 17:28:39 -04:00
Christopher Poile
9efe617be8
MM-67055: Fix permalink embeds in WebSocket messages (#34893) 2026-01-23 16:11:16 -05:00
Harrison Healey
777867dc36
Define types for WebSocket messages and migrate WebSocket actions to TS (#34603)
Some checks are pending
API / build (push) Waiting to run
Server CI / Compute Go Version (push) Waiting to run
Server CI / Check mocks (push) Blocked by required conditions
Server CI / Check go mod tidy (push) Blocked by required conditions
Server CI / check-style (push) Blocked by required conditions
Server CI / Check serialization methods for hot structs (push) Blocked by required conditions
Server CI / Vet API (push) Blocked by required conditions
Server CI / Check migration files (push) Blocked by required conditions
Server CI / Generate email templates (push) Blocked by required conditions
Server CI / Check store layers (push) Blocked by required conditions
Server CI / Check mmctl docs (push) Blocked by required conditions
Server CI / Postgres with binary parameters (push) Blocked by required conditions
Server CI / Postgres (push) Blocked by required conditions
Server CI / Postgres (FIPS) (push) Blocked by required conditions
Server CI / Generate Test Coverage (push) Blocked by required conditions
Server CI / Run mmctl tests (push) Blocked by required conditions
Server CI / Run mmctl tests (FIPS) (push) Blocked by required conditions
Server CI / Build mattermost server app (push) Blocked by required conditions
Web App CI / check-lint (push) Waiting to run
Web App CI / check-i18n (push) Blocked by required conditions
Web App CI / check-types (push) Blocked by required conditions
Web App CI / test (platform) (push) Blocked by required conditions
Web App CI / test (mattermost-redux) (push) Blocked by required conditions
Web App CI / test (channels shard 1/4) (push) Blocked by required conditions
Web App CI / test (channels shard 2/4) (push) Blocked by required conditions
Web App CI / test (channels shard 3/4) (push) Blocked by required conditions
Web App CI / test (channels shard 4/4) (push) Blocked by required conditions
Web App CI / upload-coverage (push) Blocked by required conditions
Web App CI / build (push) Blocked by required conditions
* Add TS definitions for every WebSocket event

* Remove unused WebSocket events

* Add a few extra fields to POSTED events

* Stop reusing WS event types as Redux actions

* Remove now-unused WS event types from mattermost-redux

* Rename some types to be clearer

* Use new WebSocketEvents and WebSocketMessage type everywhere

* Reorganize and export named types for WS messages

* Use new types in websocket_actions.jsx the best we can

* Rename websocket_actions.jsx to websocket_actions.tsx

* Migrate websocket_actions.tsx to TypeScript

* Break up websocket_messages.ts and group together WebSocketMessages types

* Rename websocket_actions.tsx to websocket_actions.ts
2026-01-23 14:29:40 -05:00
Matthew Birtch
09c4a61fed
[MM-67030] Remove newsletter signup and replace with terms/privacy agreement (#34801)
* remove newsletter signup and replace with terms/privacy agreement

* removed subscribeToSecurityNewsletter, made checkbox required

* update signup test to remove newsletter and ensure the terms checkbox is required

* update unit test and e2e test to reflect changes

* fix e2e test

* Removed susbcribe-newsletter endpoint in server

* Update signup.test.tsx

* remove unused css

* remove unused css

* fixed broken tests

* fixed linter issues

* Remove redundant IntlProvider and comments

* Remove usage of test IDs from Signup tests

* Remove usage of fireEvent

* Remove usage of mountWithIntl from Signup tests

* update e2e tests

* fix playwright test

* Fix Lint in signup.ts

---------

Co-authored-by: maria.nunez <maria.nunez@mattermost.com>
Co-authored-by: Mattermost Build <build@mattermost.com>
Co-authored-by: Harrison Healey <harrisonmhealey@gmail.com>
Co-authored-by: yasserfaraazkhan <attitude3cena.yf@gmail.com>
2026-01-23 18:24:27 +00:00
Andre Vasconcelos
3a394b25e4
Bumping version of prepackaged Gitlab plugin to 1.12.0 (#35033) 2026-01-23 17:41:11 +02:00
sabril
66e5ab4c5e
E2E/Test Playwright upgrade (#35008)
Some checks are pending
API / build (push) Waiting to run
Server CI / Compute Go Version (push) Waiting to run
Server CI / Check mocks (push) Blocked by required conditions
Server CI / Check go mod tidy (push) Blocked by required conditions
Server CI / check-style (push) Blocked by required conditions
Server CI / Check serialization methods for hot structs (push) Blocked by required conditions
Server CI / Vet API (push) Blocked by required conditions
Server CI / Check migration files (push) Blocked by required conditions
Server CI / Generate email templates (push) Blocked by required conditions
Server CI / Check store layers (push) Blocked by required conditions
Server CI / Check mmctl docs (push) Blocked by required conditions
Server CI / Postgres with binary parameters (push) Blocked by required conditions
Server CI / Postgres (push) Blocked by required conditions
Server CI / Postgres (FIPS) (push) Blocked by required conditions
Server CI / Generate Test Coverage (push) Blocked by required conditions
Server CI / Run mmctl tests (push) Blocked by required conditions
Server CI / Run mmctl tests (FIPS) (push) Blocked by required conditions
Server CI / Build mattermost server app (push) Blocked by required conditions
Web App CI / check-lint (push) Waiting to run
Web App CI / check-i18n (push) Blocked by required conditions
Web App CI / check-types (push) Blocked by required conditions
Web App CI / test (platform) (push) Blocked by required conditions
Web App CI / test (mattermost-redux) (push) Blocked by required conditions
Web App CI / test (channels shard 1/4) (push) Blocked by required conditions
Web App CI / test (channels shard 2/4) (push) Blocked by required conditions
Web App CI / test (channels shard 3/4) (push) Blocked by required conditions
Web App CI / test (channels shard 4/4) (push) Blocked by required conditions
Web App CI / upload-coverage (push) Blocked by required conditions
Web App CI / build (push) Blocked by required conditions
* chore: playwright upgrade

* add luxon and chalk as dependency, and relax peer dependency to @playwright/test with >=1.55.0

---------

Co-authored-by: Mattermost Build <build@mattermost.com>
2026-01-23 12:11:27 +08:00
JG Heithcock
d695a0db7a
MM-67111-Remove Cancel button on User Attributes page (#34945)
Some checks are pending
API / build (push) Waiting to run
Server CI / Compute Go Version (push) Waiting to run
Server CI / Check mocks (push) Blocked by required conditions
Server CI / Check go mod tidy (push) Blocked by required conditions
Server CI / check-style (push) Blocked by required conditions
Server CI / Check serialization methods for hot structs (push) Blocked by required conditions
Server CI / Vet API (push) Blocked by required conditions
Server CI / Check migration files (push) Blocked by required conditions
Server CI / Generate email templates (push) Blocked by required conditions
Server CI / Check store layers (push) Blocked by required conditions
Server CI / Check mmctl docs (push) Blocked by required conditions
Server CI / Postgres with binary parameters (push) Blocked by required conditions
Server CI / Postgres (push) Blocked by required conditions
Server CI / Postgres (FIPS) (push) Blocked by required conditions
Server CI / Generate Test Coverage (push) Blocked by required conditions
Server CI / Run mmctl tests (push) Blocked by required conditions
Server CI / Run mmctl tests (FIPS) (push) Blocked by required conditions
Server CI / Build mattermost server app (push) Blocked by required conditions
Web App CI / check-lint (push) Waiting to run
Web App CI / check-i18n (push) Blocked by required conditions
Web App CI / check-types (push) Blocked by required conditions
Web App CI / test (platform) (push) Blocked by required conditions
Web App CI / test (mattermost-redux) (push) Blocked by required conditions
Web App CI / test (channels shard 1/4) (push) Blocked by required conditions
Web App CI / test (channels shard 2/4) (push) Blocked by required conditions
Web App CI / test (channels shard 3/4) (push) Blocked by required conditions
Web App CI / test (channels shard 4/4) (push) Blocked by required conditions
Web App CI / upload-coverage (push) Blocked by required conditions
Web App CI / build (push) Blocked by required conditions
Remove Cancel button on User Attribute page in System Console.
2026-01-22 22:00:18 +00:00
boristrbrt
fcd3ebcb31
fix(scheduled): enhance timezone formatting by incorporating user loc… (#34305)
Some checks are pending
API / build (push) Waiting to run
Server CI / Compute Go Version (push) Waiting to run
Server CI / Check mocks (push) Blocked by required conditions
Server CI / Check go mod tidy (push) Blocked by required conditions
Server CI / check-style (push) Blocked by required conditions
Server CI / Check serialization methods for hot structs (push) Blocked by required conditions
Server CI / Vet API (push) Blocked by required conditions
Server CI / Check migration files (push) Blocked by required conditions
Server CI / Generate email templates (push) Blocked by required conditions
Server CI / Check store layers (push) Blocked by required conditions
Server CI / Check mmctl docs (push) Blocked by required conditions
Server CI / Postgres with binary parameters (push) Blocked by required conditions
Server CI / Postgres (push) Blocked by required conditions
Server CI / Postgres (FIPS) (push) Blocked by required conditions
Server CI / Generate Test Coverage (push) Blocked by required conditions
Server CI / Run mmctl tests (push) Blocked by required conditions
Server CI / Run mmctl tests (FIPS) (push) Blocked by required conditions
Server CI / Build mattermost server app (push) Blocked by required conditions
Web App CI / check-lint (push) Waiting to run
Web App CI / check-i18n (push) Blocked by required conditions
Web App CI / check-types (push) Blocked by required conditions
Web App CI / test (platform) (push) Blocked by required conditions
Web App CI / test (mattermost-redux) (push) Blocked by required conditions
Web App CI / test (channels shard 1/4) (push) Blocked by required conditions
Web App CI / test (channels shard 2/4) (push) Blocked by required conditions
Web App CI / test (channels shard 3/4) (push) Blocked by required conditions
Web App CI / test (channels shard 4/4) (push) Blocked by required conditions
Web App CI / upload-coverage (push) Blocked by required conditions
Web App CI / build (push) Blocked by required conditions
* fix(scheduled): enhance timezone formatting by incorporating user locale in scheduled time display

* fix: lint issue

* fix: add jsdocs and unit test
2026-01-21 15:24:59 -08:00
Matthew Birtch
c01e9f791f
[MM-67189] loading screen fixes - move measureAndReport, reduce minimum time, fix z-index issue (#34947)
* move measureAndReport out of setTimeOut and reduce minimum time

* fix z-index issue where system console header shows on top

---------

Co-authored-by: Mattermost Build <build@mattermost.com>
2026-01-21 16:43:33 -05:00
Ben Schumacher
ed3a7e8539
Add trigger field to command execution logs (#34950)
Some checks are pending
API / build (push) Waiting to run
Server CI / Compute Go Version (push) Waiting to run
Server CI / Check mocks (push) Blocked by required conditions
Server CI / Check go mod tidy (push) Blocked by required conditions
Server CI / check-style (push) Blocked by required conditions
Server CI / Check serialization methods for hot structs (push) Blocked by required conditions
Server CI / Vet API (push) Blocked by required conditions
Server CI / Check migration files (push) Blocked by required conditions
Server CI / Generate email templates (push) Blocked by required conditions
Server CI / Check store layers (push) Blocked by required conditions
Server CI / Check mmctl docs (push) Blocked by required conditions
Server CI / Postgres with binary parameters (push) Blocked by required conditions
Server CI / Postgres (push) Blocked by required conditions
Server CI / Postgres (FIPS) (push) Blocked by required conditions
Server CI / Generate Test Coverage (push) Blocked by required conditions
Server CI / Run mmctl tests (push) Blocked by required conditions
Server CI / Run mmctl tests (FIPS) (push) Blocked by required conditions
Server CI / Build mattermost server app (push) Blocked by required conditions
Web App CI / check-lint (push) Waiting to run
Web App CI / check-i18n (push) Blocked by required conditions
Web App CI / check-types (push) Blocked by required conditions
Web App CI / test (platform) (push) Blocked by required conditions
Web App CI / test (mattermost-redux) (push) Blocked by required conditions
Web App CI / test (channels shard 1/4) (push) Blocked by required conditions
Web App CI / test (channels shard 2/4) (push) Blocked by required conditions
Web App CI / test (channels shard 3/4) (push) Blocked by required conditions
Web App CI / test (channels shard 4/4) (push) Blocked by required conditions
Web App CI / upload-coverage (push) Blocked by required conditions
Web App CI / build (push) Blocked by required conditions
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-21 11:31:05 +01:00
Harrison Healey
fa399a5b05
Remove most unused props (#34979)
Some checks failed
API / build (push) Waiting to run
Server CI / Compute Go Version (push) Waiting to run
Server CI / Check mocks (push) Blocked by required conditions
Server CI / Check go mod tidy (push) Blocked by required conditions
Server CI / check-style (push) Blocked by required conditions
Server CI / Check serialization methods for hot structs (push) Blocked by required conditions
Server CI / Vet API (push) Blocked by required conditions
Server CI / Check migration files (push) Blocked by required conditions
Server CI / Generate email templates (push) Blocked by required conditions
Server CI / Check store layers (push) Blocked by required conditions
Server CI / Check mmctl docs (push) Blocked by required conditions
Server CI / Postgres with binary parameters (push) Blocked by required conditions
Server CI / Postgres (push) Blocked by required conditions
Server CI / Postgres (FIPS) (push) Blocked by required conditions
Server CI / Generate Test Coverage (push) Blocked by required conditions
Server CI / Run mmctl tests (push) Blocked by required conditions
Server CI / Run mmctl tests (FIPS) (push) Blocked by required conditions
Server CI / Build mattermost server app (push) Blocked by required conditions
Web App CI / check-lint (push) Waiting to run
Web App CI / check-i18n (push) Blocked by required conditions
Web App CI / check-types (push) Blocked by required conditions
Web App CI / test (platform) (push) Blocked by required conditions
Web App CI / test (mattermost-redux) (push) Blocked by required conditions
Web App CI / test (channels shard 1/4) (push) Blocked by required conditions
Web App CI / test (channels shard 2/4) (push) Blocked by required conditions
Web App CI / test (channels shard 3/4) (push) Blocked by required conditions
Web App CI / test (channels shard 4/4) (push) Blocked by required conditions
Web App CI / upload-coverage (push) Blocked by required conditions
Web App CI / build (push) Blocked by required conditions
Push mirrored docker images / cd/Push mirrored docker images (push) Has been cancelled
* Remove some unused props

* Removed unused state and actions involving profilesWithoutTeam

* Remove unused page prop from DataGrid

* Remove some unused props from system console components

* Remove some unused props related to self serve and trials

* Remove unused props from post related components

* Remove unused props from user settings components

* Remove some more unused props
2026-01-20 17:52:14 -05:00
Eva Sarafianou
86024cb4cc
Update runtime chainguard image for fips (#34997) 2026-01-20 23:09:51 +02:00
Jesse Hallam
41e5c7286b
Remove vestigial MySQL support (#34865)
* Remove legacy quoteColumnName() utility

Since Mattermost only supports PostgreSQL, the quoteColumnName() helper
that was designed to handle database-specific column quoting is no longer
needed. The function was a no-op that simply returned the column name
unchanged.

Remove the function from utils.go and update status_store.go to use
the "Manual" column name directly.

* Remove legacy driver checks from store.go

Since Mattermost only supports PostgreSQL, remove conditional checks
for different database drivers:

- Simplify specialSearchChars() to always return PostgreSQL-compatible chars
- Remove driver check from computeBinaryParam()
- Remove driver check from computeDefaultTextSearchConfig()
- Simplify GetDbVersion() to use PostgreSQL syntax directly
- Remove switch statement from ensureMinimumDBVersion()
- Remove unused driver parameter from versionString()

* Remove MySQL alternatives for batch delete operations

Since Mattermost only supports PostgreSQL, remove the MySQL-specific
DELETE...LIMIT syntax and keep only the PostgreSQL array-based approach:

- reaction_store.go: Use PostgreSQL array syntax for PermanentDeleteBatch
- file_info_store.go: Use PostgreSQL array syntax for PermanentDeleteBatch
- preference_store.go: Use PostgreSQL tuple IN subquery for DeleteInvalidVisibleDmsGms

* Remove MySQL alternatives for UPDATE...FROM syntax

Since Mattermost only supports PostgreSQL, remove the MySQL-specific
UPDATE syntax that joins tables differently:

- thread_store.go: Use PostgreSQL UPDATE...FROM syntax in
  MarkAllAsReadByChannels and MarkAllAsReadByTeam
- post_store.go: Use PostgreSQL UPDATE...FROM syntax in deleteThreadFiles

* Remove MySQL alternatives for JSON and subquery operations

Since Mattermost only supports PostgreSQL, remove the MySQL-specific
JSON and subquery syntax:

- thread_store.go: Use PostgreSQL JSONB operators for updating participants
- access_control_policy_store.go: Use PostgreSQL JSONB @> operator for
  querying JSON imports
- session_store.go: Use PostgreSQL subquery syntax for Cleanup
- job_store.go: Use PostgreSQL subquery syntax for Cleanup

* Remove MySQL alternatives for CTE queries

Since Mattermost only supports PostgreSQL, simplify code that
uses CTEs (Common Table Expressions):

- channel_store.go: Remove MySQL CASE-based fallback in
  UpdateLastViewedAt and use PostgreSQL CTE exclusively
- draft_store.go: Remove driver checks in DeleteEmptyDraftsByCreateAtAndUserId,
  DeleteOrphanDraftsByCreateAtAndUserId, and determineMaxDraftSize

* Remove driver checks in migrate.go and schema_dump.go

Simplify migration code to use PostgreSQL driver directly since
PostgreSQL is the only supported database.

* Remove driver checks in sqlx_wrapper.go

Always apply lowercase named parameter transformation since PostgreSQL
is the only supported database.

* Remove driver checks in user_store.go

Simplify user store functions to use PostgreSQL-only code paths:
- Remove isPostgreSQL parameter from helper functions
- Use LEFT JOIN pattern instead of subqueries for bot filtering
- Always use case-insensitive LIKE with lower() for search
- Remove MySQL-specific role filtering alternatives

* Remove driver checks in post_store.go

Simplify post_store.go to use PostgreSQL-only code paths:
- Inline getParentsPostsPostgreSQL into getParentsPosts
- Use PostgreSQL TO_CHAR/TO_TIMESTAMP for date formatting in analytics
- Use PostgreSQL array syntax for batch deletes
- Simplify determineMaxPostSize to always use information_schema
- Use PostgreSQL jsonb subtraction for thread participants
- Always execute RefreshPostStats (PostgreSQL materialized views)
- Use materialized views for AnalyticsPostCountsByDay
- Simplify AnalyticsPostCountByTeam to always use countByTeam

* Remove driver checks in channel_store.go

Simplify channel_store.go to use PostgreSQL-only code paths:
- Always use sq.Dollar.ReplacePlaceholders for UNION queries
- Use PostgreSQL LEFT JOIN for retention policy exclusion
- Use PostgreSQL jsonb @> operator for access control policy imports
- Simplify buildLIKEClause to always use LOWER() for case-insensitive search
- Simplify buildFulltextClauseX to always use PostgreSQL to_tsvector/to_tsquery
- Simplify searchGroupChannelsQuery to use ARRAY_TO_STRING/ARRAY_AGG

* Remove driver checks in file_info_store.go

Simplify file_info_store.go to use PostgreSQL-only code paths:
- Always use PostgreSQL to_tsvector/to_tsquery for file search
- Use file_stats materialized view for CountAll()
- Use file_stats materialized view for GetStorageUsage() when not including deleted
- Always execute RefreshFileStats() for materialized view refresh

* Remove driver checks in attributes_store.go

Simplify attributes_store.go to use PostgreSQL-only code paths:
- Always execute RefreshAttributes() for materialized view refresh
- Remove isPostgreSQL parameter from generateSearchQueryForExpression
- Always use PostgreSQL LOWER() LIKE LOWER() syntax for case-insensitive search

* Remove driver checks in retention_policy_store.go

Simplify retention_policy_store.go to use PostgreSQL-only code paths:
- Remove isPostgres parameter from scanRetentionIdsForDeletion
- Always use pq.Array for scanning retention IDs
- Always use pq.Array for inserting retention IDs
- Remove unused json import

* Remove driver checks in property stores

Simplify property_field_store.go and property_value_store.go to use
PostgreSQL-only code paths:
- Always use PostgreSQL type casts (::text, ::jsonb, ::bigint, etc.)
- Remove isPostgres variable and conditionals

* Remove driver checks in channel_member_history_store.go

Simplify PermanentDeleteBatch to use PostgreSQL-only code path:
- Always use ctid-based subquery for DELETE with LIMIT

* Remove remaining driver checks in user_store.go

Simplify user_store.go to use PostgreSQL-only code paths:
- Use LEFT JOIN for bot exclusion in AnalyticsActiveCountForPeriod
- Use LEFT JOIN for bot exclusion in IsEmpty

* Simplify fulltext search by consolidating buildFulltextClause functions

Remove convertMySQLFullTextColumnsToPostgres and consolidate
buildFulltextClause and buildFulltextClauseX into a single function
that takes variadic column arguments and returns sq.Sqlizer.

* Simplify SQL stores leveraging PostgreSQL-only support

- Simplify UpdateMembersRole in channel_store.go and team_store.go
  to use UPDATE...RETURNING instead of SELECT + UPDATE
- Simplify GetPostReminders in post_store.go to use DELETE...RETURNING
- Simplify DeleteOrphanedRows queries by removing MySQL workarounds
  for subquery locking issues
- Simplify UpdateUserLastSyncAt to use UPDATE...FROM...RETURNING
  instead of fetching user first then updating
- Remove MySQL index hint workarounds in ORDER BY clauses
- Update outdated comments referencing MySQL
- Consolidate buildFulltextClause and remove convertMySQLFullTextColumnsToPostgres

* Remove MySQL-specific test artifacts

- Delete unused MySQLStopWords variable and stop_word.go file
- Remove redundant testSearchEmailAddressesWithQuotes test
  (already covered by testSearchEmailAddresses)
- Update comment that referenced MySQL query planning

* Remove MySQL references from server code outside sqlstore

- Update config example and DSN parsing docs to reflect PostgreSQL-only support
- Remove mysql:// scheme check from IsDatabaseDSN
- Simplify SanitizeDataSource to only handle PostgreSQL
- Remove outdated MySQL comments from model and plugin code

* Remove MySQL references from test files

- Update test DSNs to use PostgreSQL format
- Remove dead mysql-replica flag and replicaFlag variable
- Simplify tests that had MySQL/PostgreSQL branches

* Update docs and test config to use PostgreSQL

- Update mmctl config set example to use postgres driver
- Update test-config.json to use PostgreSQL DSN format

* Remove MySQL migration scripts, test data, and docker image

Delete MySQL-related files that are no longer needed:
- ESR upgrade scripts (esr.*.mysql.*.sql)
- MySQL schema dumps (mattermost-mysql-*.sql)
- MySQL replication test scripts (replica-*.sh, mysql-migration-test.sh)
- MySQL test warmup data (mysql_migration_warmup.sql)
- MySQL docker image reference from mirror-docker-images.json

* Remove MySQL references from webapp

- Simplify minimumHashtagLength description to remove MySQL-specific configuration note
- Remove unused HIDE_MYSQL_STATS_NOTIFICATION preference constant
- Update en.json i18n source file

* clean up e2e-tests

* rm server/tests/template.load

* Use teamMemberSliceColumns() in UpdateMembersRole RETURNING clause

Refactor to use the existing helper function instead of hardcoding
the column names, ensuring consistency if the columns are updated.

* u.id -> u.Id

* address code review feedback

---------

Co-authored-by: Mattermost Build <build@mattermost.com>
2026-01-20 21:01:59 +00:00
Christopher Poile
dcda5304ff
Suppress SiteURL log error when in CI or local_testing mode (#34982) 2026-01-20 14:58:08 -05:00
Harrison Healey
fde4393144
Update web app package versions to 11.4.0 (#35003)
Some checks are pending
API / build (push) Waiting to run
Server CI / Compute Go Version (push) Waiting to run
Server CI / Check mocks (push) Blocked by required conditions
Server CI / Check go mod tidy (push) Blocked by required conditions
Server CI / check-style (push) Blocked by required conditions
Server CI / Check serialization methods for hot structs (push) Blocked by required conditions
Server CI / Vet API (push) Blocked by required conditions
Server CI / Check migration files (push) Blocked by required conditions
Server CI / Generate email templates (push) Blocked by required conditions
Server CI / Check store layers (push) Blocked by required conditions
Server CI / Check mmctl docs (push) Blocked by required conditions
Server CI / Postgres with binary parameters (push) Blocked by required conditions
Server CI / Postgres (push) Blocked by required conditions
Server CI / Postgres (FIPS) (push) Blocked by required conditions
Server CI / Generate Test Coverage (push) Blocked by required conditions
Server CI / Run mmctl tests (push) Blocked by required conditions
Server CI / Run mmctl tests (FIPS) (push) Blocked by required conditions
Server CI / Build mattermost server app (push) Blocked by required conditions
Web App CI / check-lint (push) Waiting to run
Web App CI / check-i18n (push) Blocked by required conditions
Web App CI / check-types (push) Blocked by required conditions
Web App CI / test (platform) (push) Blocked by required conditions
Web App CI / test (mattermost-redux) (push) Blocked by required conditions
Web App CI / test (channels shard 1/4) (push) Blocked by required conditions
Web App CI / test (channels shard 2/4) (push) Blocked by required conditions
Web App CI / test (channels shard 3/4) (push) Blocked by required conditions
Web App CI / test (channels shard 4/4) (push) Blocked by required conditions
Web App CI / upload-coverage (push) Blocked by required conditions
Web App CI / build (push) Blocked by required conditions
2026-01-20 11:58:20 -05:00
Alejandro García Montoro
5e99f12c3a
MM-67119: Remove unused Channel.Etag (#34951)
* Remove unused Channel.Etag

Computing the etag for a channel is complex due to user-specific data,
so we remove the unused Etag function to avoid confusion until a
performance need for it arises.

* Remove etag from Client4.GetChannel and tests

* make mocks

* Fix missing GetChannel calls
2026-01-20 17:46:17 +01:00
sabril
3ebc90bde0
fix: E2E/Tests related to create account and invite people (#34953)
* fix: e2e tests related to create account and invite people

* fix failed test
2026-01-20 11:59:47 -04:00
Caleb Roseland
28bcb6394b
fix(webapp): bundle loading screen CSS with content hash (#34930)
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-20 09:36:01 -06:00
Daniel Espino García
b5a816a657
Add audits for accessing posts without membership (#31266)
Some checks are pending
API / build (push) Waiting to run
Server CI / Compute Go Version (push) Waiting to run
Server CI / Check mocks (push) Blocked by required conditions
Server CI / Check go mod tidy (push) Blocked by required conditions
Server CI / check-style (push) Blocked by required conditions
Server CI / Check serialization methods for hot structs (push) Blocked by required conditions
Server CI / Vet API (push) Blocked by required conditions
Server CI / Check migration files (push) Blocked by required conditions
Server CI / Generate email templates (push) Blocked by required conditions
Server CI / Check store layers (push) Blocked by required conditions
Server CI / Check mmctl docs (push) Blocked by required conditions
Server CI / Postgres with binary parameters (push) Blocked by required conditions
Server CI / Postgres (push) Blocked by required conditions
Server CI / Postgres (FIPS) (push) Blocked by required conditions
Server CI / Generate Test Coverage (push) Blocked by required conditions
Server CI / Run mmctl tests (push) Blocked by required conditions
Server CI / Run mmctl tests (FIPS) (push) Blocked by required conditions
Server CI / Build mattermost server app (push) Blocked by required conditions
Web App CI / check-lint (push) Waiting to run
Web App CI / check-i18n (push) Blocked by required conditions
Web App CI / check-types (push) Blocked by required conditions
Web App CI / test (platform) (push) Blocked by required conditions
Web App CI / test (mattermost-redux) (push) Blocked by required conditions
Web App CI / test (channels shard 1/4) (push) Blocked by required conditions
Web App CI / test (channels shard 2/4) (push) Blocked by required conditions
Web App CI / test (channels shard 3/4) (push) Blocked by required conditions
Web App CI / test (channels shard 4/4) (push) Blocked by required conditions
Web App CI / upload-coverage (push) Blocked by required conditions
Web App CI / build (push) Blocked by required conditions
* Add audits for accessing posts without membership

* Fix tests

* Use correct audit level

* Address feedback

* Add missing checks all over the app

* Fix lint

* Fix test

* Fix tests

* Fix enterprise test

* Add missing test and docs

* Fix merge

* Fix lint

* Add audit logs on the web socket hook for permalink posts

* Fix lint

* Fix merge conflicts

* Handle all events with "non_channel_member_access" parameter

* Fix lint and tests

* Fix merge

* Fix tests
2026-01-20 10:38:27 +01:00
Nick Misasi
b2f93dec1a
[MM-67118] Add Agents to @ mention autocomplete in channel (#34881)
Some checks are pending
API / build (push) Waiting to run
Server CI / Compute Go Version (push) Waiting to run
Server CI / Check mocks (push) Blocked by required conditions
Server CI / Check go mod tidy (push) Blocked by required conditions
Server CI / check-style (push) Blocked by required conditions
Server CI / Check serialization methods for hot structs (push) Blocked by required conditions
Server CI / Vet API (push) Blocked by required conditions
Server CI / Check migration files (push) Blocked by required conditions
Server CI / Generate email templates (push) Blocked by required conditions
Server CI / Check store layers (push) Blocked by required conditions
Server CI / Check mmctl docs (push) Blocked by required conditions
Server CI / Postgres with binary parameters (push) Blocked by required conditions
Server CI / Postgres (push) Blocked by required conditions
Server CI / Postgres (FIPS) (push) Blocked by required conditions
Server CI / Generate Test Coverage (push) Blocked by required conditions
Server CI / Run mmctl tests (push) Blocked by required conditions
Server CI / Run mmctl tests (FIPS) (push) Blocked by required conditions
Server CI / Build mattermost server app (push) Blocked by required conditions
Web App CI / check-lint (push) Waiting to run
Web App CI / check-i18n (push) Blocked by required conditions
Web App CI / check-types (push) Blocked by required conditions
Web App CI / test (platform) (push) Blocked by required conditions
Web App CI / test (mattermost-redux) (push) Blocked by required conditions
Web App CI / test (channels shard 1/4) (push) Blocked by required conditions
Web App CI / test (channels shard 2/4) (push) Blocked by required conditions
Web App CI / test (channels shard 3/4) (push) Blocked by required conditions
Web App CI / test (channels shard 4/4) (push) Blocked by required conditions
Web App CI / upload-coverage (push) Blocked by required conditions
Web App CI / build (push) Blocked by required conditions
* Add support for autocomplete of plugin-created bots

* stashing

* Add support for including agents in the autocomplete list for @ mentions

* Change server response to be users rather than interface

* fix
2026-01-19 16:10:57 -05:00
Nick Misasi
c62d103d76
[MM-67160] Add audit logging for recap API endpoints (#34929)
* Add audit logging for recap API endpoints

- Add audit event constants for all recap operations
- Implement Auditable interface for Recap model
- Add comprehensive audit logging to all 6 recap endpoints
- Log channel_ids to track implicit channel content access
- Use LevelContent for content-related operations, LevelAPI for listing

* Address PR feedback: standardize audit method order and extract helper function

- Standardized order of audit record method calls across all handlers:
  set object type first, then prior state (if applicable), then result state
- Extracted duplicated channel ID extraction logic into addRecapChannelIDsToAuditRec helper function
2026-01-19 13:46:43 -05:00
Just Nev
0ace6a45cd
Update prepackaged Jira plugin to v4.5.1 (#34978)
Some checks are pending
API / build (push) Waiting to run
Server CI / Compute Go Version (push) Waiting to run
Server CI / Check mocks (push) Blocked by required conditions
Server CI / Check go mod tidy (push) Blocked by required conditions
Server CI / check-style (push) Blocked by required conditions
Server CI / Check serialization methods for hot structs (push) Blocked by required conditions
Server CI / Vet API (push) Blocked by required conditions
Server CI / Check migration files (push) Blocked by required conditions
Server CI / Generate email templates (push) Blocked by required conditions
Server CI / Check store layers (push) Blocked by required conditions
Server CI / Check mmctl docs (push) Blocked by required conditions
Server CI / Postgres with binary parameters (push) Blocked by required conditions
Server CI / Postgres (push) Blocked by required conditions
Server CI / Postgres (FIPS) (push) Blocked by required conditions
Server CI / Generate Test Coverage (push) Blocked by required conditions
Server CI / Run mmctl tests (push) Blocked by required conditions
Server CI / Run mmctl tests (FIPS) (push) Blocked by required conditions
Server CI / Build mattermost server app (push) Blocked by required conditions
Web App CI / check-lint (push) Waiting to run
Web App CI / check-i18n (push) Blocked by required conditions
Web App CI / check-types (push) Blocked by required conditions
Web App CI / test (platform) (push) Blocked by required conditions
Web App CI / test (mattermost-redux) (push) Blocked by required conditions
Web App CI / test (channels shard 1/4) (push) Blocked by required conditions
Web App CI / test (channels shard 2/4) (push) Blocked by required conditions
Web App CI / test (channels shard 3/4) (push) Blocked by required conditions
Web App CI / test (channels shard 4/4) (push) Blocked by required conditions
Web App CI / upload-coverage (push) Blocked by required conditions
Web App CI / build (push) Blocked by required conditions
Co-authored-by: Nevyana Angelova <nevyangelova@192.168.100.42>
2026-01-19 17:25:27 +00:00
Harrison Healey
b8c9f931bb
Update package-lock.json (#34958) 2026-01-19 11:40:37 -05:00
Weblate (bot)
bb8c2660ed
Translations update from Mattermost Weblate (#34977)
* Translated using Weblate (Hungarian)

Currently translated at 71.0% (2072 of 2916 strings)

Translation: Mattermost/server
Translate-URL: https://translate.mattermost.com/projects/mattermost/server/hu/

* Translated using Weblate (Slovenian)

Currently translated at 37.5% (1096 of 2916 strings)

Translation: Mattermost/server
Translate-URL: https://translate.mattermost.com/projects/mattermost/server/sl/

* Translated using Weblate (Hungarian)

Currently translated at 63.5% (4303 of 6768 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/hu/

* Translated using Weblate (German)

Currently translated at 97.0% (6571 of 6768 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/de/

* Translated using Weblate (Polish)

Currently translated at 97.1% (6578 of 6768 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/pl/

* Translated using Weblate (Dutch)

Currently translated at 99.8% (2912 of 2916 strings)

Translation: Mattermost/server
Translate-URL: https://translate.mattermost.com/projects/mattermost/server/nl/

* Translated using Weblate (Dutch)

Currently translated at 97.1% (6578 of 6768 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/nl/

* Translated using Weblate (German)

Currently translated at 97.3% (6587 of 6768 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/de/

* Translated using Weblate (Polish)

Currently translated at 97.3% (6588 of 6768 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/pl/

* Translated using Weblate (Belarusian)

Currently translated at 98.0% (6635 of 6768 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/be/

* Translated using Weblate (Dutch)

Currently translated at 97.2% (6582 of 6768 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/nl/

* Translated using Weblate (Korean)

Currently translated at 92.7% (6274 of 6768 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/ko/

* Translated using Weblate (German)

Currently translated at 97.9% (6626 of 6768 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/de/

* Translated using Weblate (Polish)

Currently translated at 97.4% (6598 of 6768 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/pl/

* Translated using Weblate (Norwegian Bokmål)

Currently translated at 5.0% (147 of 2916 strings)

Translation: Mattermost/server
Translate-URL: https://translate.mattermost.com/projects/mattermost/server/nb_NO/

* Translated using Weblate (Dutch)

Currently translated at 97.7% (6615 of 6768 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/nl/

* Translated using Weblate (Ukrainian)

Currently translated at 89.5% (2611 of 2916 strings)

Translation: Mattermost/server
Translate-URL: https://translate.mattermost.com/projects/mattermost/server/uk/

* Translated using Weblate (Dutch)

Currently translated at 98.4% (6666 of 6768 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/nl/

* Translated using Weblate (Polish)

Currently translated at 97.6% (6609 of 6768 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/pl/

* Translated using Weblate (Dutch)

Currently translated at 98.7% (6684 of 6768 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/nl/

* Translated using Weblate (Dutch)

Currently translated at 98.7% (6685 of 6768 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/nl/

* Translated using Weblate (German)

Currently translated at 97.2% (6626 of 6816 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/de/

* Translated using Weblate (Dutch)

Currently translated at 100.0% (6768 of 6768 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/nl/

---------

Co-authored-by: Csaba Tóth <csaba.toth@odootech.hu>
Co-authored-by: Tom De Moor <tom@controlaltdieliet.be>
Co-authored-by: jprusch <rs@schaeferbarthold.de>
Co-authored-by: master7 <marcin.karkosz@rajska.info>
Co-authored-by: Vadim Asadchi <vadim.asadchi@codex-soft.com>
Co-authored-by: avasconcelos114 <andre.onogoro@gmail.com>
Co-authored-by: Frank Paul Silye <frankps@gmail.com>
Co-authored-by: Serhii Khomiuk <sergiy.khomiuk@gmail.com>
2026-01-19 13:42:13 +00:00
unified-ci-app[bot]
2a8b2069f5
chore: Update NOTICE.txt file with updated dependencies (#34969)
Automatic Merge
2026-01-19 13:24:25 +02:00
Asaad Mahmood
4773d0fc6f
MM-64655 - Updating mobile RHS (#34007)
Some checks failed
API / build (push) Has been cancelled
Server CI / Compute Go Version (push) Has been cancelled
Web App CI / check-lint (push) Has been cancelled
Server CI / Check mocks (push) Has been cancelled
Server CI / Check go mod tidy (push) Has been cancelled
Server CI / check-style (push) Has been cancelled
Server CI / Check serialization methods for hot structs (push) Has been cancelled
Server CI / Vet API (push) Has been cancelled
Server CI / Check migration files (push) Has been cancelled
Server CI / Generate email templates (push) Has been cancelled
Server CI / Check store layers (push) Has been cancelled
Server CI / Check mmctl docs (push) Has been cancelled
Server CI / Postgres with binary parameters (push) Has been cancelled
Server CI / Postgres (push) Has been cancelled
Server CI / Postgres (FIPS) (push) Has been cancelled
Server CI / Generate Test Coverage (push) Has been cancelled
Server CI / Run mmctl tests (push) Has been cancelled
Server CI / Run mmctl tests (FIPS) (push) Has been cancelled
Server CI / Build mattermost server app (push) Has been cancelled
Web App CI / check-i18n (push) Has been cancelled
Web App CI / check-types (push) Has been cancelled
Web App CI / test (platform) (push) Has been cancelled
Web App CI / test (mattermost-redux) (push) Has been cancelled
Web App CI / test (channels shard 1/4) (push) Has been cancelled
Web App CI / test (channels shard 2/4) (push) Has been cancelled
Web App CI / test (channels shard 3/4) (push) Has been cancelled
Web App CI / test (channels shard 4/4) (push) Has been cancelled
Web App CI / upload-coverage (push) Has been cancelled
Web App CI / build (push) Has been cancelled
* MM-64655 - Updating mobile RHS

* Updating lint

* Updating test

* Updating test

* Updating sidebar items
2026-01-17 11:12:03 +05:00
Devin Binnie
f00dd11e34
[MM-67138][MM-67139] Update Audit/Activity logging for Desktop App external auth (#34928)
Some checks are pending
API / build (push) Waiting to run
Server CI / Compute Go Version (push) Waiting to run
Server CI / Check mocks (push) Blocked by required conditions
Server CI / Check go mod tidy (push) Blocked by required conditions
Server CI / check-style (push) Blocked by required conditions
Server CI / Check serialization methods for hot structs (push) Blocked by required conditions
Server CI / Vet API (push) Blocked by required conditions
Server CI / Check migration files (push) Blocked by required conditions
Server CI / Generate email templates (push) Blocked by required conditions
Server CI / Check store layers (push) Blocked by required conditions
Server CI / Check mmctl docs (push) Blocked by required conditions
Server CI / Postgres with binary parameters (push) Blocked by required conditions
Server CI / Postgres (push) Blocked by required conditions
Server CI / Postgres (FIPS) (push) Blocked by required conditions
Server CI / Generate Test Coverage (push) Blocked by required conditions
Server CI / Run mmctl tests (push) Blocked by required conditions
Server CI / Run mmctl tests (FIPS) (push) Blocked by required conditions
Server CI / Build mattermost server app (push) Blocked by required conditions
Web App CI / check-lint (push) Waiting to run
Web App CI / check-i18n (push) Blocked by required conditions
Web App CI / check-types (push) Blocked by required conditions
Web App CI / test (platform) (push) Blocked by required conditions
Web App CI / test (mattermost-redux) (push) Blocked by required conditions
Web App CI / test (channels shard 1/4) (push) Blocked by required conditions
Web App CI / test (channels shard 2/4) (push) Blocked by required conditions
Web App CI / test (channels shard 3/4) (push) Blocked by required conditions
Web App CI / test (channels shard 4/4) (push) Blocked by required conditions
Web App CI / upload-coverage (push) Blocked by required conditions
Web App CI / build (push) Blocked by required conditions
* [MM-67138][MM-67139] Update Audit/Activity logging for Desktop App external auth

* PR feedback

---------

Co-authored-by: Mattermost Build <build@mattermost.com>
2026-01-16 13:28:44 -05:00
Asaad Mahmood
b097098af3
MM-64942 - Fixing default error bookmarks bar (#34869)
Co-authored-by: Mattermost Build <build@mattermost.com>
2026-01-16 22:01:01 +05:00
Pablo Vélez
be3b5d4b7c
MM-66092 - enhance user permissions data structure validations (#34654)
Some checks are pending
API / build (push) Waiting to run
Server CI / Compute Go Version (push) Waiting to run
Server CI / Check mocks (push) Blocked by required conditions
Server CI / Check go mod tidy (push) Blocked by required conditions
Server CI / check-style (push) Blocked by required conditions
Server CI / Check serialization methods for hot structs (push) Blocked by required conditions
Server CI / Vet API (push) Blocked by required conditions
Server CI / Check migration files (push) Blocked by required conditions
Server CI / Generate email templates (push) Blocked by required conditions
Server CI / Check store layers (push) Blocked by required conditions
Server CI / Check mmctl docs (push) Blocked by required conditions
Server CI / Postgres with binary parameters (push) Blocked by required conditions
Server CI / Postgres (push) Blocked by required conditions
Server CI / Postgres (FIPS) (push) Blocked by required conditions
Server CI / Generate Test Coverage (push) Blocked by required conditions
Server CI / Run mmctl tests (push) Blocked by required conditions
Server CI / Run mmctl tests (FIPS) (push) Blocked by required conditions
Server CI / Build mattermost server app (push) Blocked by required conditions
Web App CI / check-lint (push) Waiting to run
Web App CI / check-i18n (push) Blocked by required conditions
Web App CI / check-types (push) Blocked by required conditions
Web App CI / test (platform) (push) Blocked by required conditions
Web App CI / test (mattermost-redux) (push) Blocked by required conditions
Web App CI / test (channels shard 1/4) (push) Blocked by required conditions
Web App CI / test (channels shard 2/4) (push) Blocked by required conditions
Web App CI / test (channels shard 3/4) (push) Blocked by required conditions
Web App CI / test (channels shard 4/4) (push) Blocked by required conditions
Web App CI / upload-coverage (push) Blocked by required conditions
Web App CI / build (push) Blocked by required conditions
* MM-66092 - enhance permissions validations

* Remove unnecessary empty role updates from tests

* Strengthen scheme role validation in member role updates including imports

---------

Co-authored-by: Mattermost Build <build@mattermost.com>
2026-01-16 10:59:07 -04:00
Asaad Mahmood
53feec3e79
MM-66674 - Updating alignment for GenericModal (#34861)
* MM-66674 - Updating alignment for GenericModal

* Updating modal content sizing

---------

Co-authored-by: Mattermost Build <build@mattermost.com>
2026-01-16 17:33:43 +05:00
sabril
9268d4b1d0
MM-66672 Migrate tests to RTL (#34508)
Some checks are pending
API / build (push) Waiting to run
Server CI / Compute Go Version (push) Waiting to run
Server CI / Check mocks (push) Blocked by required conditions
Server CI / Check go mod tidy (push) Blocked by required conditions
Server CI / check-style (push) Blocked by required conditions
Server CI / Check serialization methods for hot structs (push) Blocked by required conditions
Server CI / Vet API (push) Blocked by required conditions
Server CI / Check migration files (push) Blocked by required conditions
Server CI / Generate email templates (push) Blocked by required conditions
Server CI / Check store layers (push) Blocked by required conditions
Server CI / Check mmctl docs (push) Blocked by required conditions
Server CI / Postgres with binary parameters (push) Blocked by required conditions
Server CI / Postgres (push) Blocked by required conditions
Server CI / Postgres (FIPS) (push) Blocked by required conditions
Server CI / Generate Test Coverage (push) Blocked by required conditions
Server CI / Run mmctl tests (push) Blocked by required conditions
Server CI / Run mmctl tests (FIPS) (push) Blocked by required conditions
Server CI / Build mattermost server app (push) Blocked by required conditions
Web App CI / check-lint (push) Waiting to run
Web App CI / check-i18n (push) Blocked by required conditions
Web App CI / check-types (push) Blocked by required conditions
Web App CI / test (platform) (push) Blocked by required conditions
Web App CI / test (mattermost-redux) (push) Blocked by required conditions
Web App CI / test (channels shard 1/4) (push) Blocked by required conditions
Web App CI / test (channels shard 2/4) (push) Blocked by required conditions
Web App CI / test (channels shard 3/4) (push) Blocked by required conditions
Web App CI / test (channels shard 4/4) (push) Blocked by required conditions
Web App CI / upload-coverage (push) Blocked by required conditions
Web App CI / build (push) Blocked by required conditions
* migrate tests to rtl

* keep snapshots but the rtl way and maintain the same test cases

---------

Co-authored-by: Mattermost Build <build@mattermost.com>
2026-01-16 06:04:40 +00:00
sabril
53975de036
MM-66671 Migrate tests to RTL, batches E1 and E2 (#34506)
* migrate tests to RTL on batches E1 and E2

* maintain snapshot and match orig test cases

---------

Co-authored-by: Mattermost Build <build@mattermost.com>
2026-01-16 05:31:38 +00:00
sabril
0a12ca2f7d
E2E/Playwright: Reorganize user and team creation (#34912)
* pw: reorganize user and team creation

* fix types and lint
2026-01-16 13:11:27 +08:00
Christopher Poile
38b413a276
MM-67077: Remove PSD file previews (#34898)
Some checks are pending
API / build (push) Waiting to run
Server CI / Compute Go Version (push) Waiting to run
Server CI / Check mocks (push) Blocked by required conditions
Server CI / Check go mod tidy (push) Blocked by required conditions
Server CI / check-style (push) Blocked by required conditions
Server CI / Check serialization methods for hot structs (push) Blocked by required conditions
Server CI / Vet API (push) Blocked by required conditions
Server CI / Check migration files (push) Blocked by required conditions
Server CI / Generate email templates (push) Blocked by required conditions
Server CI / Check store layers (push) Blocked by required conditions
Server CI / Check mmctl docs (push) Blocked by required conditions
Server CI / Postgres with binary parameters (push) Blocked by required conditions
Server CI / Postgres (push) Blocked by required conditions
Server CI / Postgres (FIPS) (push) Blocked by required conditions
Server CI / Generate Test Coverage (push) Blocked by required conditions
Server CI / Run mmctl tests (push) Blocked by required conditions
Server CI / Run mmctl tests (FIPS) (push) Blocked by required conditions
Server CI / Build mattermost server app (push) Blocked by required conditions
Web App CI / check-lint (push) Waiting to run
Web App CI / check-i18n (push) Blocked by required conditions
Web App CI / check-types (push) Blocked by required conditions
Web App CI / test (platform) (push) Blocked by required conditions
Web App CI / test (mattermost-redux) (push) Blocked by required conditions
Web App CI / test (channels shard 1/4) (push) Blocked by required conditions
Web App CI / test (channels shard 2/4) (push) Blocked by required conditions
Web App CI / test (channels shard 3/4) (push) Blocked by required conditions
Web App CI / test (channels shard 4/4) (push) Blocked by required conditions
Web App CI / upload-coverage (push) Blocked by required conditions
Web App CI / build (push) Blocked by required conditions
* remove image preview support for PSD files

* remove psd as a supported image type in webapp

* remove unneeded comments
2026-01-15 13:39:46 -05:00
Amy Blais
688e0c6c4e
Update en.json (#34935)
Some checks are pending
API / build (push) Waiting to run
Server CI / Compute Go Version (push) Waiting to run
Server CI / Check mocks (push) Blocked by required conditions
Server CI / Check go mod tidy (push) Blocked by required conditions
Server CI / check-style (push) Blocked by required conditions
Server CI / Check serialization methods for hot structs (push) Blocked by required conditions
Server CI / Vet API (push) Blocked by required conditions
Server CI / Check migration files (push) Blocked by required conditions
Server CI / Generate email templates (push) Blocked by required conditions
Server CI / Check store layers (push) Blocked by required conditions
Server CI / Check mmctl docs (push) Blocked by required conditions
Server CI / Postgres with binary parameters (push) Blocked by required conditions
Server CI / Postgres (push) Blocked by required conditions
Server CI / Postgres (FIPS) (push) Blocked by required conditions
Server CI / Generate Test Coverage (push) Blocked by required conditions
Server CI / Run mmctl tests (push) Blocked by required conditions
Server CI / Run mmctl tests (FIPS) (push) Blocked by required conditions
Server CI / Build mattermost server app (push) Blocked by required conditions
Web App CI / check-lint (push) Waiting to run
Web App CI / check-i18n (push) Blocked by required conditions
Web App CI / check-types (push) Blocked by required conditions
Web App CI / test (platform) (push) Blocked by required conditions
Web App CI / test (mattermost-redux) (push) Blocked by required conditions
Web App CI / test (channels shard 1/4) (push) Blocked by required conditions
Web App CI / test (channels shard 2/4) (push) Blocked by required conditions
Web App CI / test (channels shard 3/4) (push) Blocked by required conditions
Web App CI / test (channels shard 4/4) (push) Blocked by required conditions
Web App CI / upload-coverage (push) Blocked by required conditions
Web App CI / build (push) Blocked by required conditions
Automatic Merge
2026-01-15 16:24:24 +02:00
Vicktor
52411cf613
Migrate UserList to a function component (#34511)
Some checks are pending
API / build (push) Waiting to run
Server CI / Compute Go Version (push) Waiting to run
Server CI / Check mocks (push) Blocked by required conditions
Server CI / Check go mod tidy (push) Blocked by required conditions
Server CI / check-style (push) Blocked by required conditions
Server CI / Check serialization methods for hot structs (push) Blocked by required conditions
Server CI / Vet API (push) Blocked by required conditions
Server CI / Check migration files (push) Blocked by required conditions
Server CI / Generate email templates (push) Blocked by required conditions
Server CI / Check store layers (push) Blocked by required conditions
Server CI / Check mmctl docs (push) Blocked by required conditions
Server CI / Postgres with binary parameters (push) Blocked by required conditions
Server CI / Postgres (push) Blocked by required conditions
Server CI / Postgres (FIPS) (push) Blocked by required conditions
Server CI / Generate Test Coverage (push) Blocked by required conditions
Server CI / Run mmctl tests (push) Blocked by required conditions
Server CI / Run mmctl tests (FIPS) (push) Blocked by required conditions
Server CI / Build mattermost server app (push) Blocked by required conditions
Web App CI / check-lint (push) Waiting to run
Web App CI / check-i18n (push) Blocked by required conditions
Web App CI / check-types (push) Blocked by required conditions
Web App CI / test (platform) (push) Blocked by required conditions
Web App CI / test (mattermost-redux) (push) Blocked by required conditions
Web App CI / test (channels shard 1/4) (push) Blocked by required conditions
Web App CI / test (channels shard 2/4) (push) Blocked by required conditions
Web App CI / test (channels shard 3/4) (push) Blocked by required conditions
Web App CI / test (channels shard 4/4) (push) Blocked by required conditions
Web App CI / upload-coverage (push) Blocked by required conditions
Web App CI / build (push) Blocked by required conditions
2026-01-15 07:16:34 +00:00
Nick Misasi
0885f56010
Add optional Claude.md orchestration for Webapp folder (#34668)
Some checks are pending
API / build (push) Waiting to run
Server CI / Compute Go Version (push) Waiting to run
Server CI / Check mocks (push) Blocked by required conditions
Server CI / Check go mod tidy (push) Blocked by required conditions
Server CI / check-style (push) Blocked by required conditions
Server CI / Check serialization methods for hot structs (push) Blocked by required conditions
Server CI / Vet API (push) Blocked by required conditions
Server CI / Check migration files (push) Blocked by required conditions
Server CI / Generate email templates (push) Blocked by required conditions
Server CI / Check store layers (push) Blocked by required conditions
Server CI / Check mmctl docs (push) Blocked by required conditions
Server CI / Postgres with binary parameters (push) Blocked by required conditions
Server CI / Postgres (push) Blocked by required conditions
Server CI / Postgres (FIPS) (push) Blocked by required conditions
Server CI / Generate Test Coverage (push) Blocked by required conditions
Server CI / Run mmctl tests (push) Blocked by required conditions
Server CI / Run mmctl tests (FIPS) (push) Blocked by required conditions
Server CI / Build mattermost server app (push) Blocked by required conditions
Web App CI / check-lint (push) Waiting to run
Web App CI / check-i18n (push) Blocked by required conditions
Web App CI / check-types (push) Blocked by required conditions
Web App CI / test (platform) (push) Blocked by required conditions
Web App CI / test (mattermost-redux) (push) Blocked by required conditions
Web App CI / test (channels shard 1/4) (push) Blocked by required conditions
Web App CI / test (channels shard 2/4) (push) Blocked by required conditions
Web App CI / test (channels shard 3/4) (push) Blocked by required conditions
Web App CI / test (channels shard 4/4) (push) Blocked by required conditions
Web App CI / upload-coverage (push) Blocked by required conditions
Web App CI / build (push) Blocked by required conditions
* Add CLAUDE.md documentation files for webapp directories

- Add root webapp CLAUDE.md with overview and build commands
- Add channels CLAUDE.md with architecture and testing info
- Add documentation for actions, components, selectors, utils
- Add documentation for sass, tests, and mattermost-redux
- Add platform documentation for client and types
- Update .gitignore

* Add CLAUDE docs and allow tracking

* Clarify CLAUDE instructions for i18n workflow

* Refactor webapp/CLAUDE.md into a nested hierarchy

Decomposed the monolithic webapp/CLAUDE.md into focused, context-aware
files distributed across the directory structure:
- webapp/CLAUDE.md (Root overview)
- webapp/channels/CLAUDE.md (Channels workspace)
- webapp/channels/src/components/CLAUDE.md
- webapp/channels/src/actions/CLAUDE.md
- webapp/channels/src/selectors/CLAUDE.md
- webapp/channels/src/packages/mattermost-redux/CLAUDE.md
- webapp/platform/CLAUDE.md (Platform workspace)
- webapp/platform/client/CLAUDE.md

* Move files to optional, then add script to move them to proper claud.md
2026-01-14 13:04:20 -05:00
Scott Bishel
cc2b47bc9b
MM-66561 Add distinct archive icon for private channels (#34736)
Some checks are pending
API / build (push) Waiting to run
Server CI / Compute Go Version (push) Waiting to run
Server CI / Check mocks (push) Blocked by required conditions
Server CI / Check go mod tidy (push) Blocked by required conditions
Server CI / check-style (push) Blocked by required conditions
Server CI / Check serialization methods for hot structs (push) Blocked by required conditions
Server CI / Vet API (push) Blocked by required conditions
Server CI / Check migration files (push) Blocked by required conditions
Server CI / Generate email templates (push) Blocked by required conditions
Server CI / Check store layers (push) Blocked by required conditions
Server CI / Check mmctl docs (push) Blocked by required conditions
Server CI / Postgres with binary parameters (push) Blocked by required conditions
Server CI / Postgres (push) Blocked by required conditions
Server CI / Postgres (FIPS) (push) Blocked by required conditions
Server CI / Generate Test Coverage (push) Blocked by required conditions
Server CI / Run mmctl tests (push) Blocked by required conditions
Server CI / Run mmctl tests (FIPS) (push) Blocked by required conditions
Server CI / Build mattermost server app (push) Blocked by required conditions
Web App CI / check-lint (push) Waiting to run
Web App CI / check-i18n (push) Blocked by required conditions
Web App CI / check-types (push) Blocked by required conditions
Web App CI / test (platform) (push) Blocked by required conditions
Web App CI / test (mattermost-redux) (push) Blocked by required conditions
Web App CI / test (channels shard 1/4) (push) Blocked by required conditions
Web App CI / test (channels shard 2/4) (push) Blocked by required conditions
Web App CI / test (channels shard 3/4) (push) Blocked by required conditions
Web App CI / test (channels shard 4/4) (push) Blocked by required conditions
Web App CI / upload-coverage (push) Blocked by required conditions
Web App CI / build (push) Blocked by required conditions
* MM-66561 Add distinct archive icon for private channels

Archived private channels now display an archive-lock icon instead of the standard archive icon to better indicate their original privacy level. Implemented utility functions to centralize icon selection logic across all channel list views, sidebars, headers, and suggestion providers.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 (1M context) <noreply@anthropic.com>

* MM-66561 Fix linting and TypeScript errors

Fix ESLint and TypeScript issues introduced in the archive icon implementation:
- Remove extra blank lines to comply with no-multiple-empty-lines rule
- Remove unused container variables in test files
- Fix import order to comply with import/order rule
- Remove unused React import
- Fix TypeScript type errors by using General.OPEN_CHANNEL/PRIVATE_CHANNEL from mattermost-redux/constants which preserves literal types

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 (1M context) <noreply@anthropic.com>

* MM-66561 Fix test failures for archive icon changes

Update test snapshots and fix test data issues related to the new distinct archive icons for public and private channels.

- Update snapshots for channel list components to include new channelType prop and data-testid attributes
- Fix channel_mention_provider test by preserving actual module exports in mock
- Add missing purpose field to searchable_channel_list test data
- Fix async state handling in new_channel_modal test using waitFor instead of act

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 (1M context) <noreply@anthropic.com>

* MM-66561 Fix remaining Cypress E2E test failures for archive icons

Fix three failing Cypress tests related to archive icon changes:

1. join_archived_channel_spec.ts (MM-T1682, MM-T1683)
   - Add data-testid to archive icon in channel header
   - Update test to use findByTestId instead of CSS class selector
   - Compass icon components render as SVG, not <i> with classes

2. archived_channels_spec.js (system console tests)
   - Add "000-" prefix to private channel name/display name
   - Ensures proper alphabetical sorting on first page of results

3. long_draft_spec.js (MM-T211)
   - Fix Cypress alias timing issues in nested then() callbacks
   - Use local variable to track height changes during iteration
   - Replace cy.get('@alias').should() with direct expect() assertions

All tests now pass with the distinct archive icons for private channels.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 (1M context) <noreply@anthropic.com>

* fix lint issue

* MM-66561 Refine archive icon styling and search results display

- Restore CSS classes on channel header icon for proper color and size
- Fix icon alignment by removing top offset in channel header context
- Replace "Archived" text with icon-only tooltip in search results
- Add context-specific styling to prevent conflicts between header and search

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 (1M context) <noreply@anthropic.com>

* tweaks to css and move withtooltip to wrap the span

* lint fix

* lint fix

* Fix archived channel icons visual test API usage

Update test to use correct Playwright API patterns:
- Use adminClient.createChannel with pw.random.channel for channel creation
- Use adminClient.deleteChannel instead of pw.apiClient.deleteChannel
- Use pw.testBrowser.login(adminUser) instead of loginAsAdmin
- Remove channelsPage.toBeVisible check for archived channels since they lack post-create element

Co-Authored-By: Claude Sonnet 4.5 (1M context) <noreply@anthropic.com>

* Apply prettier formatting to archived channel icons test

Co-Authored-By: Claude Sonnet 4.5 (1M context) <noreply@anthropic.com>

* Fix timing issue in MM-T633 Elasticsearch webhook attachment search test

The test was intermittently failing because it searched immediately after posting the webhook, before Elasticsearch had time to index the new post. Added explicit wait for post to appear and increased indexing wait time to 3 seconds to ensure the attachment text is indexed before performing the search.

Co-Authored-By: Claude Sonnet 4.5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.5 (1M context) <noreply@anthropic.com>
Co-authored-by: Matthew Birtch <mattbirtch@gmail.com>
2026-01-14 15:35:27 +00:00
Ben Schumacher
cf1682a0e7
Add documentation for plugin RPC architecture (#34587)
* Add documentation for plugin RPC architecture

Document the bidirectional RPC communication between Mattermost server
and plugin processes. Added an architectural overview with ASCII diagram
and godoc comments for hooksRPCClient, hooksRPCServer, apiRPCClient,
and apiRPCServer explaining their roles in the plugin system.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* update

---------

Co-authored-by: Claude <noreply@anthropic.com>
2026-01-14 09:58:40 +01:00
sabril
dab04576a1
MM-66972 Upgrade to node 24 and main dependencies with babel, webpack and jest (#34760)
Some checks are pending
API / build (push) Waiting to run
Server CI / Compute Go Version (push) Waiting to run
Server CI / Check mocks (push) Blocked by required conditions
Server CI / Check go mod tidy (push) Blocked by required conditions
Server CI / check-style (push) Blocked by required conditions
Server CI / Check serialization methods for hot structs (push) Blocked by required conditions
Server CI / Vet API (push) Blocked by required conditions
Server CI / Check migration files (push) Blocked by required conditions
Server CI / Generate email templates (push) Blocked by required conditions
Server CI / Check store layers (push) Blocked by required conditions
Server CI / Check mmctl docs (push) Blocked by required conditions
Server CI / Postgres with binary parameters (push) Blocked by required conditions
Server CI / Postgres (push) Blocked by required conditions
Server CI / Postgres (FIPS) (push) Blocked by required conditions
Server CI / Generate Test Coverage (push) Blocked by required conditions
Server CI / Run mmctl tests (push) Blocked by required conditions
Server CI / Run mmctl tests (FIPS) (push) Blocked by required conditions
Server CI / Build mattermost server app (push) Blocked by required conditions
Web App CI / check-lint (push) Waiting to run
Web App CI / check-i18n (push) Blocked by required conditions
Web App CI / check-types (push) Blocked by required conditions
Web App CI / test (platform) (push) Blocked by required conditions
Web App CI / test (mattermost-redux) (push) Blocked by required conditions
Web App CI / test (channels shard 1/4) (push) Blocked by required conditions
Web App CI / test (channels shard 2/4) (push) Blocked by required conditions
Web App CI / test (channels shard 3/4) (push) Blocked by required conditions
Web App CI / test (channels shard 4/4) (push) Blocked by required conditions
Web App CI / upload-coverage (push) Blocked by required conditions
Web App CI / build (push) Blocked by required conditions
* chore: upgrade to node 24 and dependencies mainly with babel, webpack and jest

* fix components tests, make trial modal passed on all node 20-24

* fix cache for platform packages

* updated test

---------

Co-authored-by: Mattermost Build <build@mattermost.com>
2026-01-14 13:14:01 +08:00
Matthew Birtch
92339d03ab
[MM-67044] Update connected workspaces empty state illustrations (#34820)
Some checks are pending
API / build (push) Waiting to run
Server CI / Compute Go Version (push) Waiting to run
Server CI / Check mocks (push) Blocked by required conditions
Server CI / Check go mod tidy (push) Blocked by required conditions
Server CI / check-style (push) Blocked by required conditions
Server CI / Check serialization methods for hot structs (push) Blocked by required conditions
Server CI / Vet API (push) Blocked by required conditions
Server CI / Check migration files (push) Blocked by required conditions
Server CI / Generate email templates (push) Blocked by required conditions
Server CI / Check store layers (push) Blocked by required conditions
Server CI / Check mmctl docs (push) Blocked by required conditions
Server CI / Postgres with binary parameters (push) Blocked by required conditions
Server CI / Postgres (push) Blocked by required conditions
Server CI / Postgres (FIPS) (push) Blocked by required conditions
Server CI / Generate Test Coverage (push) Blocked by required conditions
Server CI / Run mmctl tests (push) Blocked by required conditions
Server CI / Run mmctl tests (FIPS) (push) Blocked by required conditions
Server CI / Build mattermost server app (push) Blocked by required conditions
Web App CI / check-lint (push) Waiting to run
Web App CI / check-i18n (push) Blocked by required conditions
Web App CI / check-types (push) Blocked by required conditions
Web App CI / test (platform) (push) Blocked by required conditions
Web App CI / test (mattermost-redux) (push) Blocked by required conditions
Web App CI / test (channels shard 1/4) (push) Blocked by required conditions
Web App CI / test (channels shard 2/4) (push) Blocked by required conditions
Web App CI / test (channels shard 3/4) (push) Blocked by required conditions
Web App CI / test (channels shard 4/4) (push) Blocked by required conditions
Web App CI / upload-coverage (push) Blocked by required conditions
Web App CI / build (push) Blocked by required conditions
* update illustration and spacing

* updated illustrations

* Update controls.tsx
2026-01-13 15:34:20 -05:00
Matthew Birtch
7ea7b3384f
[MM-67081] [MM-62584] Updates to illustrations and loading screen (#34855)
* remove illustrations no longer used

* fix paths without fills

* fixes to illustrations

* svg fixes

* update preparing workspace illustrations and fix some styles

* remove unused

* updated ip filtering

* updated search hint image, remove old one

* update threads search hint

* remove unused wrench illustration

* update initial loading screen

* fix to invite illustration

* removed comments to disable the redirect

* change to use media queries for dark mode

* fixed issue with shortcut not being visible on light themes in search hint

* remove unneeded js for darkmode since we use css

* fix linter issue

* remove unused css

* updated snapshot

* update access problem illustration

* remove access denied svg and replace with access problem (since it's the same)

* remove access denied happy and replace with access problem svg

* Update access_problem_svg.tsx

* rename man_with_mailbox to email_inbox

* fixed colors of access_problem

* rename illustrations to have consistent _svg suffix
2026-01-13 13:41:26 -05:00
Christopher Poile
a18b80ba4c
MM-67049: Fix unauthorized access to public channels in private teams (#34886)
* do not return channels from teams a user is not a member of

* add explicit tests (clearer than adding it above)

* linting

* explicitly test incudeDeleted true and false--it was implicit before
2026-01-13 18:21:06 +00:00
Nick Misasi
8e4cadbc88
[MM-66359] Recaps MVP (#34337)
* initial commit for POC of Plugin Bridge

* Updates

* POC for plugin bridge

* Updates from collaboration

* Fixes

* Refactor Plugin Bridge to use HTTP/REST instead of RPC

- Remove ExecuteBridgeCall hook and Context.SourcePluginId
- Implement HTTP-based bridge using existing PluginHTTP infrastructure
- Add CallPlugin API method with endpoint parameter instead of method name
- Update CallPluginBridge to construct HTTP POST requests
- Add proper headers: Mattermost-User-Id, Mattermost-Plugin-ID
- Use 'com.mattermost.server' as plugin ID for core server calls
- Update ai.go to use REST endpoint /inter-plugin/v1/completion
- Add comprehensive spec documentation in server/spec.md
- Add MIGRATION_GUIDE.md for plugin developers
- Fix 401/404 issues by setting correct headers and URL paths

* Improve Plugin Bridge security and architecture

- Create ServeInternalPluginRequest for internal plugin calls (core + plugin-to-plugin)
- Move header-setting logic from CallPluginBridge to ServeInternalPluginRequest
- Improve separation of concerns: business logic vs HTTP transport
- Add security documentation explaining header protection

Security Improvements:
- ServeInternalPluginRequest is NOT exposed as HTTP route (internal only)
- Headers (Mattermost-User-Id, Mattermost-Plugin-ID) are set by trusted server code
- External requests cannot spoof these headers (stripped by servePluginRequest)
- Core calls use 'com.mattermost.server' as plugin ID for authorization
- Plugin-to-plugin calls use real plugin ID (enforced by server)

Backward Compatibility:
- Keep ServeInterPluginRequest for existing API.PluginHTTP callers (deprecated)
- All tests pass

Docs:
- Update spec.md with security model explanation
- Update MIGRATION_GUIDE.md with correct header usage examples

* Space

* cursor please stop creating markdown files

* Fix style

* Fix i18n, linter

* REMOVE MARKDOWN

* Remove CallPlugin method from plugin API interface

Per review feedback, this method is no longer needed.

Co-authored-by: Nick Misasi <nickmisasi@users.noreply.github.com>

* Remove CallPlugin method implementation from PluginAPI

Co-authored-by: Nick Misasi <nickmisasi@users.noreply.github.com>

* fixes

* Add AI OpenAPI spec

* fix openapi spec

* Use agents client (#34225)

* Use agents client

* Remove default agent

* Fixes

* fix: modify system prompts to ensure JSON is being returned

* Base implementation for recaps working

* small fixes

* Adjustments

* remove webapp changes

* Add feature flags for rewrites and ai bridge, clean up

* Remove comments that aren't helpful

* Fix i18n

* Remove rewrites

* Fix tests

* Fix i18n

* adjust i18n again

* Add back translations

* Remove leftover mock code

* remove model file

* Changes from PR review

* Make the real substitutions

* Include a basic invokation of the client with noop to ensure build works

* more fix

* Remove unneeded change

* Updates from review

* Fixes

* Remove some logic from rewrites to clean up branch

* Use v1.5.0 of agents plugin

* A bunch more additions for general UX flow

* Add missing files

* Add mocks

* Fixes for vet-api, i18n, build, types, etc

* One more linter fix

* Fix i18n and some tests

* Refactors and cleanup in backend code

* remove rogue markdown file

* fixes after refactors from backend

* Add back renamed files, and add tests

* More self code review

* More fixes

* More refactors

* Fix call stack exceeded bug

* Include read messages if there are no unreads

* Fix test failure: use correct error message key for recap permission denied

The getRecapAndCheckOwnership function was using strings.ToLower(callerName)
to generate error keys, which caused 'GetRecap' to become 'getrecap' instead
of the expected 'get'. Changed to use the correct static key that matches
the en.json localization file.

Fixes TestGetRecap/get_recap_by_non-owner test failure.

Co-authored-by: Nick Misasi <nickmisasi@users.noreply.github.com>

* Consolidate permission errors down to a single string

* Fixes for i18n, worktrees making this difficult

* Fix i18n

* Fix i18n once and for all (for real) (final)

* Fix duplicate getAgents method in client4.ts

* Remove duplicate ai state from initial_state.ts

* Fix types

* Fix tests

* Fix return type of GetAgents and GetServices

* Add tests for recaps components

* Fix types

* Update i18n

* Fixes

* Fixes

* More cleanup

* Revert random file

* Use undefined

* fix linter

* Address feedback

* Missed a git add

* Fixes

* Fix i18n

* Remove fallback

* Fixes for PR

---------

Co-authored-by: claude[bot] <209825114+claude[bot]@users.noreply.github.com>
Co-authored-by: Nick Misasi <nickmisasi@users.noreply.github.com>
Co-authored-by: Christopher Speller <crspeller@gmail.com>
Co-authored-by: Felipe Martin <me@fmartingr.com>
Co-authored-by: Mattermost Build <build@mattermost.com>
2026-01-13 11:59:22 -05:00
Weblate (bot)
9e1d4c2072
Translations update from Mattermost Weblate (#34918)
* Translated using Weblate (German)

Currently translated at 100.0% (2916 of 2916 strings)

Translation: Mattermost/server
Translate-URL: https://translate.mattermost.com/projects/mattermost/server/de/

* Translated using Weblate (Polish)

Currently translated at 100.0% (2916 of 2916 strings)

Translation: Mattermost/server
Translate-URL: https://translate.mattermost.com/projects/mattermost/server/pl/

* Translated using Weblate (Belarusian)

Currently translated at 100.0% (2916 of 2916 strings)

Translation: Mattermost/server
Translate-URL: https://translate.mattermost.com/projects/mattermost/server/be/

* Translated using Weblate (Belarusian)

Currently translated at 100.0% (2916 of 2916 strings)

Translation: Mattermost/server
Translate-URL: https://translate.mattermost.com/projects/mattermost/server/be/

* Update translation files

Updated by "Cleanup translation files" hook in Weblate.

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/

---------

Co-authored-by: jprusch <rs@schaeferbarthold.de>
Co-authored-by: master7 <marcin.karkosz@rajska.info>
Co-authored-by: Mikhail Rimashevski <mikhail@codex-soft.com>
Co-authored-by: Vadim Asadchi <vadim.asadchi@codex-soft.com>
2026-01-13 17:23:30 +01:00
Jesse Hallam
65d69b0498
Use testify ElementsMatch instead of sorting slices before comparison (#34899)
Simplifies test code by using ElementsMatch which handles order-independent
slice comparison. Removes custom sort implementations and manual sorting
that was only needed for equality checks.

Co-authored-by: Mattermost Build <build@mattermost.com>
2026-01-13 11:40:03 -04:00
Ben Schumacher
43bfdbfd1b
[MM-66840] Add CPU cores and total memory to Support Packet (#34658)
Some checks are pending
API / build (push) Waiting to run
Server CI / Compute Go Version (push) Waiting to run
Server CI / Check mocks (push) Blocked by required conditions
Server CI / Check go mod tidy (push) Blocked by required conditions
Server CI / check-style (push) Blocked by required conditions
Server CI / Check serialization methods for hot structs (push) Blocked by required conditions
Server CI / Vet API (push) Blocked by required conditions
Server CI / Check migration files (push) Blocked by required conditions
Server CI / Generate email templates (push) Blocked by required conditions
Server CI / Check store layers (push) Blocked by required conditions
Server CI / Check mmctl docs (push) Blocked by required conditions
Server CI / Postgres with binary parameters (push) Blocked by required conditions
Server CI / Postgres (push) Blocked by required conditions
Server CI / Postgres (FIPS) (push) Blocked by required conditions
Server CI / Generate Test Coverage (push) Blocked by required conditions
Server CI / Run mmctl tests (push) Blocked by required conditions
Server CI / Run mmctl tests (FIPS) (push) Blocked by required conditions
Server CI / Build mattermost server app (push) Blocked by required conditions
Web App CI / check-lint (push) Waiting to run
Web App CI / check-i18n (push) Blocked by required conditions
Web App CI / check-types (push) Blocked by required conditions
Web App CI / test (platform) (push) Blocked by required conditions
Web App CI / test (mattermost-redux) (push) Blocked by required conditions
Web App CI / test (channels shard 1/4) (push) Blocked by required conditions
Web App CI / test (channels shard 2/4) (push) Blocked by required conditions
Web App CI / test (channels shard 3/4) (push) Blocked by required conditions
Web App CI / test (channels shard 4/4) (push) Blocked by required conditions
Web App CI / upload-coverage (push) Blocked by required conditions
Web App CI / build (push) Blocked by required conditions
* [MM-66840] Add CPU cores and total memory to support packet

Add system resource information to support packet diagnostics to help
with troubleshooting and capacity analysis.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* Clarify that memory is in MB

* Add comment clarifying CPU/memory are host values

Clarifies that the CPU cores and total memory values in the support
packet represent the host machine's resources, not any container limits
that may be configured in Docker or Kubernetes environments.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude <noreply@anthropic.com>
2026-01-13 16:23:32 +01:00
Vicktor
d61635fc4a
Migrate FileUploadSetting to a function component (#34514)
Some checks are pending
API / build (push) Waiting to run
Server CI / Compute Go Version (push) Waiting to run
Server CI / Check mocks (push) Blocked by required conditions
Server CI / Check go mod tidy (push) Blocked by required conditions
Server CI / check-style (push) Blocked by required conditions
Server CI / Check serialization methods for hot structs (push) Blocked by required conditions
Server CI / Vet API (push) Blocked by required conditions
Server CI / Check migration files (push) Blocked by required conditions
Server CI / Generate email templates (push) Blocked by required conditions
Server CI / Check store layers (push) Blocked by required conditions
Server CI / Check mmctl docs (push) Blocked by required conditions
Server CI / Postgres with binary parameters (push) Blocked by required conditions
Server CI / Postgres (push) Blocked by required conditions
Server CI / Postgres (FIPS) (push) Blocked by required conditions
Server CI / Generate Test Coverage (push) Blocked by required conditions
Server CI / Run mmctl tests (push) Blocked by required conditions
Server CI / Run mmctl tests (FIPS) (push) Blocked by required conditions
Server CI / Build mattermost server app (push) Blocked by required conditions
Web App CI / check-lint (push) Waiting to run
Web App CI / check-i18n (push) Blocked by required conditions
Web App CI / check-types (push) Blocked by required conditions
Web App CI / test (platform) (push) Blocked by required conditions
Web App CI / test (mattermost-redux) (push) Blocked by required conditions
Web App CI / test (channels shard 1/4) (push) Blocked by required conditions
Web App CI / test (channels shard 2/4) (push) Blocked by required conditions
Web App CI / test (channels shard 3/4) (push) Blocked by required conditions
Web App CI / test (channels shard 4/4) (push) Blocked by required conditions
Web App CI / upload-coverage (push) Blocked by required conditions
Web App CI / build (push) Blocked by required conditions
2026-01-13 02:09:41 +00:00
Vicktor
bf2535df13
refactor(audits): migrate Audits to a function component (#34528) 2026-01-13 02:08:52 +00:00
Caleb Roseland
db55f9fa43
MM-66653: migrate i18n extraction from mmjstool to @formatjs/cli (#34498)
* feat(webapp): migrate i18n extraction from mmjstool to @formatjs/cli

Replace custom mmjstool with industry-standard @formatjs/cli for i18n
message extraction. Adds support for localizeMessage as a recognized
extraction function and enables comprehensive ESLint rules for i18n.

Changes by area:

Dependencies (package.json):
- Add @formatjs/cli v6.7.4
- Remove @mattermost/mmjstool dependency
- Replace i18n-extract script with formatjs command
- Remove mmjstool-specific scripts (clean-empty, check-empty-src)
- Add i18n-extract:check for diff validation

Code (utils.tsx):
- Refactor localizeMessage to accept MessageDescriptor format
- Support {id, defaultMessage, description} parameters
- Maintain Redux store access (non-React context compatible)
- Add comprehensive JSDoc documentation

Linting (.eslintrc.json):
- Configure formatjs settings with additionalFunctionNames
- Enable 9 formatjs ESLint rules including enforce-id (error)
- Ensure all messages require explicit manual IDs

CI/CD (webapp-ci.yml):
- Simplify i18n check to formatjs extraction + diff
- Remove mmjstool and mobile-dir references

Context: Second attempt at PR #25830. Uses manual IDs only with
[id] placeholder pattern to enforce explicit ID requirements.
ESLint will catch missing IDs during development.

* chore(webapp): add temporary i18n reconciliation tooling

Add helper script to analyze conflicts between en.json and
defaultMessage values in code. This tooling will be reverted
after initial migration cleanup is complete.

Tooling added:
- scripts/i18n-reconcile-conflicts.js: Analyzes conflicts
  - Detects spelling corrections
  - Identifies placeholder mismatches
  - Flags significant content changes
  - Provides recommendations on which version to keep

- npm script: i18n-reconcile

Usage:
  npm run i18n-reconcile

This will be reverted after reconciling the ~50 duplicate message
warnings and determining correct versions for conflicting messages.

* chore(webapp): upgrade eslint-plugin-formatjs and centralize formatjs deps

Move @formatjs/cli to root webapp package.json alongside other formatjs
dependencies for better monorepo organization. Upgrade eslint-plugin-formatjs
from 4.12.2 to 5.4.2 for latest features and bug fixes.

Changes:
- Upgrade eslint-plugin-formatjs: 4.12.2 → 5.4.2
- Move @formatjs/cli to webapp/package.json (from channels)
- Centralize formatjs tooling at monorepo root level

This provides:
- Better dependency management in monorepo
- Latest formatjs ESLint rules and features
- Consistent tooling across workspaces

* feat(webapp): make localizeMessage fully compatible with formatMessage API

Extend localizeMessage to accept a values parameter for placeholder
interpolation, making it fully compatible with react-intl's formatMessage API.
Remove the now-redundant localizeAndFormatMessage function.

Changes to localizeMessage:
- Add values parameter for {placeholder} interpolation
- Use getIntl() for proper ICU message formatting
- Support full formatMessage feature parity outside React contexts
- Update JSDoc with interpolation examples
- Mark as deprecated (prefer useIntl in React components)

Code cleanup:
- Remove localizeAndFormatMessage function (redundant)
- Migrate all localizeAndFormatMessage usages to localizeMessage
- Remove unused imports: getCurrentLocale, getTranslations
- Add getIntl import

Files migrated:
- notification_actions.tsx: notification.crt message
- app_command_parser_dependencies.ts: intlShim formatMessage

This consolidates i18n logic and provides a single, feature-complete
localization function for non-React contexts.

Example usage:
  // Before (old function)
  localizeAndFormatMessage(
    {id: 'welcome', defaultMessage: 'Hello {name}'},
    {name: 'John'}
  )

  // After (consolidated)
  localizeMessage(
    {id: 'welcome', defaultMessage: 'Hello {name}'},
    {name: 'John'}
  )

* refactor(i18n): remove intlShim abstraction, use IntlShape directly

Remove intlShim wrapper and use react-intl's IntlShape type throughout.

Key Changes:
- Remove intlShim constant from app_command_parser_dependencies.ts
- Update errorMessage() signature to accept IntlShape parameter
- Use IntlShape for intl properties in AppCommandParser and ParsedCommand
- Call getIntl() at function start in actions (command.ts, marketplace.ts)
- Pass IntlShape to AppCommandParser and doAppSubmit consistently

Files Modified:
- app_command_parser_dependencies.ts: Remove intlShim, update errorMessage
- app_command_parser.ts: Use IntlShape type
- command.ts, marketplace.ts: Call getIntl() early, pass to parser
- app_provider.tsx, command_provider.tsx: Use getIntl() in constructor
- apps.ts: Update doAppSubmit signature

Benefits: Better type safety, standard react-intl patterns, eliminates
unnecessary abstraction.

Context: Part of migration to @formatjs/cli tooling.

* refactor(webapp): remove deprecated t() function and refactor login validation

Remove the deprecated t() function that was used as a marker for the old
mmjstool extraction. With @formatjs/cli, this is no longer needed as
extraction happens directly from formatMessage calls.

Changes:
- Remove t() function definition from utils/i18n.tsx
- Remove t() import and marker calls from login.tsx
- Refactor login validation logic from multiple if statements to a clean
  switch(true) pattern that evaluates boolean combinations directly
- Add helpful comments documenting the structure of login method combinations
- Add default case as safety fallback

The switch(true) pattern eliminates the need to build a key string and makes
the login method combination logic clearer and more maintainable.

Prompt: Remove deprecated t() translation marker function used by old mmjstool.
Refactor login validation from if blocks to switch(true) with boolean cases.

* refactor(i18n): share IntlProvider's intl instance with getIntl()

Make getIntl() return the same IntlShape instance that IntlProvider creates,
ensuring consistency between React components (using useIntl()) and non-React
contexts (using getIntl()).

Changes:
- Add intlInstance storage in utils/i18n.tsx
- Export setIntl() function to store the intl instance
- Modify getIntl() to return stored instance if available, with fallback to
  createIntl() for tests and early initialization
- Add IntlCapture component in IntlProvider that uses useIntl() hook to
  capture and store the intl instance via setIntl()

Benefits:
- Single source of truth: Both React and non-React code use the same IntlShape
- Consistent translations: No duplicate translation loading or potential desync
- Leverages IntlProvider's translation loading lifecycle automatically
- Maintains fallback for edge cases where IntlProvider hasn't mounted yet

Prompt: Refactor getIntl() to reuse IntlProvider's intl instance instead of
creating a separate instance, ensuring both React and non-React contexts use
the same translations and intl configuration.

* 1

* exclude test files

* reset en.json

* refactor(i18n): inline message ID constants for formatjs extraction

Replace dynamic ID references with literal strings to enable proper formatjs
extraction. Formatjs can only extract from static message IDs, not from
variables or computed IDs.

Changes:
- configuration_bar.tsx: Inline AnnouncementBarMessages constants to literal
  string IDs ('announcement_bar.error.past_grace', 'announcement_bar.error.preview_mode')
- system_analytics.test.tsx: Replace variable IDs (totalPlaybooksID,
  totalPlaybookRunsID) with literal strings ('total_playbooks', 'total_playbook_runs')
- password.tsx: Use full message descriptor from passwordErrors object instead
  of dynamic ID with hardcoded defaultMessage. The errorId is still built
  dynamically using template strings, but the actual message is looked up from
  the passwordErrors defineMessages block where formatjs can extract it.

This eliminates all "[id]" placeholder entries from extraction output and
ensures all messages have proper extractable definitions.

Prompt: Fix dynamic message ID references that formatjs extraction can't parse.
Inline constants and use message descriptor lookups to enable clean extraction
without [id] placeholders.

* fix(i18n): add missing defaultMessage to drafts.tooltipText

The drafts.tooltipText FormattedMessage had an empty defaultMessage, causing
formatjs extraction to output an empty string for this message.

Added the proper defaultMessage with plural formatting for draft and scheduled
post counts.

Prompt: Fix empty defaultMessage in drafts tooltip causing extraction issues.

* feat(i18n): add --preserve-whitespace flag to formatjs extraction

Add the --preserve-whitespace flag to ensure formatjs extraction maintains
exact whitespace from defaultMessage values. This is important for messages
with intentional formatting like tabs, multiple spaces, or line breaks.

Prompt: Add --preserve-whitespace to i18n extraction to maintain exact formatting.

* feat(i18n): add custom formatjs formatter matching mmjstool ordering

Create custom formatter that replicates mmjstool's sorting behavior:
- Case-insensitive alphabetical sorting
- Underscore (_) sorts before dot (.) to match existing en.json ordering
- Simple key-value format (extracts defaultMessage)

The underscore-before-dot collation matches mmjstool's actual behavior and
reduces diff size by 50% compared to standard alphabetical sorting.

Changes:
- scripts/formatter.js: Custom compareMessages, format, and compile functions
- package.json: Use --format scripts/formatter.js instead of --format simple

Prompt: Create custom formatjs formatter matching mmjstool's exact sorting
behavior including underscore-before-dot collation to minimize migration diff.

* feat(i18n): enhance reconciliation script with git history metadata

Add git log lookups to show when each message was last modified in both
en.json and code files. This enables data-driven decisions about which
version to keep when resolving conflicts.

Enhancements:
- getEnJsonLastModified(): Find when an en.json entry last changed
- findCodeFile(): Locate source file for a message ID (handles id= and id:)
- getCodeLastModified(): Get last modification date for source files
- Caching for performance (minimizes git operations)

Output includes:
  📅 en.json:  [date] | [hash] | [commit message]
  📅 code:     [date] | [hash] | [commit message]
  📂 file:     [source file path]

Analysis shows en.json entries from 2023 while code actively updated
2024-2025, indicating code is more authoritative.

Prompt: Add git history to reconciliation report showing modification dates
for data-driven conflict resolution decisions.

* feat(i18n): add optional duplicate message ID check script

Add i18n-extract:check-duplicates script that fails if the same message ID
has different defaultMessages in multiple locations. This is kept as an
optional standalone script rather than auto-chained with i18n-extract to
allow the migration to proceed while duplicates are addressed separately.

Usage:
  npm run i18n-extract:check-duplicates

The script runs formatjs extract to /dev/null and checks stderr for
"Duplicate message id" warnings, failing if any are found.

Prompt: Add optional duplicate ID check as standalone npm script for gradual
migration without blocking on existing duplicate message IDs.

* about.enterpriseEditionLearn

* admin.accesscontrol.title

* eslint-plugin-formatjs version to eslint 8 compat

* admin.channel_settings.channel_detail.access_control_policy_title

* admin.connectionSecurityTls
- now: admin.connectionSecurityTls.title

* admin.customProfileAttribDesc
now:
- admin.customProfileAttribDesc.ldap
- admin.customProfileAttribDesc.saml

* admin.gitlab.clientSecretExample

* package-lock

* admin.google.EnableMarkdownDesc
- fix err `]` in admin.google.EnableMarkdownDesc.openid
- now:
  - admin.google.EnableMarkdownDesc.oauth
  - admin.google.EnableMarkdownDesc.openid

* admin.image.amazonS3BucketExample
- now:
  - admin.image.amazonS3BucketExample
  - admin.image.amazonS3BucketExampleExport

* admin.license.trialCard.contactSales

* admin.log.AdvancedLoggingJSONDescription
- now:
  - admin.log.AdvancedLoggingJSONDescription
  - admin.log.AdvancedAuditLoggingJSONDescription

* admin.rate.noteDescription
- now
  - admin.rate.noteDescription
  - admin.info_banner.restart_required.desc (3)

* admin.system_properties.user_properties.title
- now:
  - admin.system_properties.user_properties.title
  - admin.accesscontrol.user_properties.link.label

* admin.system_users.filters.team.allTeams, admin.system_users.filters.team.noTeams

* admin.user_item.email_title

* announcement_bar.error.preview_mode

* channel_settings.error_purpose_length

* deactivate_member_modal.desc
- now:
  - deactivate_member_modal.desc
  - deactivate_member_modal.desc_with_confirmation

* deleteChannelModal.canViewArchivedChannelsWarning

* edit_channel_header_modal.error

* filtered_channels_list.search
- now:
  - filtered_channels_list.search
  - filtered_channels_list.search.label

* flag_post.flag

* generic_icons.collapse

* installed_outgoing_oauth_connections.header

* intro_messages.group_message

* intro_messages.notificationPreferences
- now:
  - intro_messages.notificationPreferences
  - intro_messages.notificationPreferences.label

* katex.error

* multiselect.placeholder
- now:
  - multiselect.placeholder
  - multiselect.placeholder.addMembers

* post_info.pin, post_info.unpin, rhs_root.mobile.flag

take en.json

* texteditor.rewrite.rewriting

* user_groups_modal.addPeople

split to user_groups_modal.addPeople.field_title

* user.settings.general.validImage

take en.json

* userSettings.adminMode.modal_header

take en.json

* webapp.mattermost.feature.start_call

split to user_profile.call.start

* admin.general.localization.enableExperimentalLocalesDescription

take en.json

* login.contact_admin.title, login.contact_admin.detail

take en.json

* fix: correct spelling of "complementary" in accessibility sections

* Revert "about.enterpriseEditionLearn"

This reverts commit 23ababe1ce.

* about.enterpriseEditionLearn, about.planNameLearn

* fix: improve clarity and consistency in activity log and command descriptions

* fix: update emoji upload limits and improve help text for emoji creation

* fix easy round 1

* fix: improve messaging for free trial notifications and sales contact

take en.json

* admin.billing.subscription.planDetails.features.limitedFileStorage

take en.json

* admin.billing.subscription.updatePaymentInfo

take en.json

* fix easy round 2

* admin.complianceExport.exportFormat.globalrelay

take en.json

* fix round 3

* fix round 4

* fix round 5

* fix round 6

* fix closing tag, newlines, and popout title

* fix linting, +

* update snapshots

* test(webapp): update tests to match formatjs migration message changes

Update test assertions to reflect message text changes from the
mmjstool → @formatjs/cli migration. All changes align with the
corresponding i18n message updates in the codebase.

Changes:
- limits.test.tsx: Update capitalization (Message History → Message history,
  File Storage → File storage)
- emoji_picker.test.tsx: Update label (Recent → Recently Used)
- command.test.js: Add period to error message
- channel_activity_warning_modal.test.tsx: Update warning text assertion
- channel_settings_archive_tab.test.tsx: Update archive warning text
- feature_discovery.test.tsx: Update agreement name (Software and Services
  License Agreement → Software Evaluation Agreement)
- flag_post_modal.test.tsx: Update placeholder text (Select a reason for
  flagging → Select a reason)
- channel_intro_message.test.tsx: Remove trailing space from assertion
- elasticsearch_settings.tsx: Fix searchableStrings placeholder names
  (documentationLink → link) to match updated message format

All 983 test suites passing (12 tests fixed, 9088 tests total).

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* chore(i18n): improve cross-platform compatibility and cleanup temporary tooling

Simplify i18n check scripts to reuse npm run i18n-extract, improving
cross-platform compatibility and reducing duplication.

Changes:
- Refactor i18n-extract:check to reuse base extraction command
  - Uses project-local temp file instead of /tmp (Windows compatible)
  - Simplified from duplicated formatjs command to npm run reuse
  - Add --throws flag to fail fast on extraction errors
  - Add helpful error message: "To update: npm run i18n-extract"

- Add i18n-extract:check to main check script
  - Now runs alongside ESLint and Stylelint checks
  - Ensures en.json stays in sync with code changes

- Remove i18n-extract:check-duplicates script
  - Redundant - duplicates are caught by i18n-extract automatically
  - Avoided grep dependency (not cross-platform)

- Remove temporary reconciliation tooling
  - Deleted scripts/i18n-reconcile-conflicts.js (served its purpose)
  - Removed i18n-reconcile npm script

- Add .i18n-check.tmp.json to .gitignore

i18n-extract:check now works on Windows, macOS, and Linux.
Requires only diff command (available via Git on Windows).

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* ci(webapp): simplify i18n check using npm script

Replace custom i18n check in CI with npm run i18n-extract:check for
consistency with local development workflow.

Changes:
- Update check-i18n job to use npm run i18n-extract:check
- Remove manual cp/extract/diff steps (3 lines → 1 line)
- Consistent behavior between CI and local development
- Cross-platform compatible (no /tmp dependency)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* feat(i18n): add i18n extraction targets to Makefile and workspace scripts

Add Make targets and npm workspace scripts for i18n message extraction
to provide consistent tooling access across the project.

Changes:
- Add make i18n-extract target to webapp/Makefile
  - Extracts i18n messages from code to en.json

- Add make i18n-extract-check target to webapp/Makefile
  - Checks if en.json is in sync with code

- Add i18n-extract workspace script to webapp/package.json
  - Runs extraction across all workspaces

- Add i18n-extract:check workspace script to webapp/package.json
  - Runs sync check across all workspaces

Usage:
  make i18n-extract         # Extract messages
  make i18n-extract-check   # Check if en.json needs update
  npm run i18n-extract      # From webapp root
  npm run i18n-extract:check

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* feat(i18n): add cross-platform cleanup utility for temp files

Add Node.js cleanup script to handle temporary file removal in a
cross-platform manner, replacing platform-specific rm commands.

Changes:
- Add webapp/scripts/cleanup.js
  - Cross-platform file deletion utility
  - Silently handles missing files
  - Works on Windows/Mac/Linux

- Update i18n-extract:check to use cleanup script
  - Removes .i18n-check.tmp.json after diff
  - Cleans up on both success and failure paths

Usage:
  node scripts/cleanup.js <file1> [file2] [...]

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* chore(i18n): remove 'defineMessage' from additionalFunctionNames in ESLint config

* chore(i18n): update i18n-extract check script and remove unused cleanup utility

context: WSL is already required on windows

* chore(i18n): remove ESLint rule disabling for formatjs placeholders in admin definition

* chore(i18n): admin_definition
- re-add defineMessage to eslint additionalfunctionnames
- mark additional individual placeholder lines in admin_definition

* fix(i18n): correct typo in enterprise edition link message

* chore(i18n): fix escape sequences

* revert emoji.ts changes

* fix snapshots

* fix admin.google.EnableMarkdownDesc
- keep en.json but fix linkAPI and <strong>Create</strong>

* restore newlines, and final corrections check

* update snapshots

* fix: i18n

* chore(e2e): admin.complianceExport.exportJobStartTime.title

* chore(e2e): emoji_picker.travel-places

* chore(e2e): user.settings.general.incorrectPassword

* chore(e2e): signup_user_completed.create

* chore(e2e): fix Invite People

* chore(fix): admin console email heading

* chore(e2e): fix edit_channel_header_modal.placeholder

* chore(e2e): fix Create account

* chore(e2e): fix Create account

* chore(e2e): correct success message text in password update alert

* fix: admin guide label

* chore(e2e): update role name in invite people combobox

* chore(e2e): more "Create account"

* chore(e2e): fix authentication_spec

* lint

---------

Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Mattermost Build <build@mattermost.com>
2026-01-12 17:22:04 -06:00
Devin Binnie
c6a44406e0
[MM-66898] Adjust popout titles (#34768)
Some checks are pending
API / build (push) Waiting to run
Server CI / Compute Go Version (push) Waiting to run
Server CI / Check mocks (push) Blocked by required conditions
Server CI / Check go mod tidy (push) Blocked by required conditions
Server CI / check-style (push) Blocked by required conditions
Server CI / Check serialization methods for hot structs (push) Blocked by required conditions
Server CI / Vet API (push) Blocked by required conditions
Server CI / Check migration files (push) Blocked by required conditions
Server CI / Generate email templates (push) Blocked by required conditions
Server CI / Check store layers (push) Blocked by required conditions
Server CI / Check mmctl docs (push) Blocked by required conditions
Server CI / Postgres with binary parameters (push) Blocked by required conditions
Server CI / Postgres (push) Blocked by required conditions
Server CI / Postgres (FIPS) (push) Blocked by required conditions
Server CI / Generate Test Coverage (push) Blocked by required conditions
Server CI / Run mmctl tests (push) Blocked by required conditions
Server CI / Run mmctl tests (FIPS) (push) Blocked by required conditions
Server CI / Build mattermost server app (push) Blocked by required conditions
Web App CI / check-lint (push) Waiting to run
Web App CI / check-i18n (push) Blocked by required conditions
Web App CI / check-types (push) Blocked by required conditions
Web App CI / test (platform) (push) Blocked by required conditions
Web App CI / test (mattermost-redux) (push) Blocked by required conditions
Web App CI / test (channels shard 1/4) (push) Blocked by required conditions
Web App CI / test (channels shard 2/4) (push) Blocked by required conditions
Web App CI / test (channels shard 3/4) (push) Blocked by required conditions
Web App CI / test (channels shard 4/4) (push) Blocked by required conditions
Web App CI / upload-coverage (push) Blocked by required conditions
Web App CI / build (push) Blocked by required conditions
* [MM-66898] Adjust popout titles

* Added support for browser window titles, fixed a bug in the thread menu

* Fix conflicting web app title

* Fix issue with DM channel thread with user not on team and no replies

* Fix again

* Fix lint

---------

Co-authored-by: Mattermost Build <build@mattermost.com>
2026-01-12 17:15:10 +00:00
Weblate (bot)
ec3ba68e32
Translations update from Mattermost Weblate (#34906)
Some checks are pending
API / build (push) Waiting to run
Server CI / Compute Go Version (push) Waiting to run
Server CI / Check mocks (push) Blocked by required conditions
Server CI / Check go mod tidy (push) Blocked by required conditions
Server CI / check-style (push) Blocked by required conditions
Server CI / Check serialization methods for hot structs (push) Blocked by required conditions
Server CI / Vet API (push) Blocked by required conditions
Server CI / Check migration files (push) Blocked by required conditions
Server CI / Generate email templates (push) Blocked by required conditions
Server CI / Check store layers (push) Blocked by required conditions
Server CI / Check mmctl docs (push) Blocked by required conditions
Server CI / Postgres with binary parameters (push) Blocked by required conditions
Server CI / Postgres (push) Blocked by required conditions
Server CI / Postgres (FIPS) (push) Blocked by required conditions
Server CI / Generate Test Coverage (push) Blocked by required conditions
Server CI / Run mmctl tests (push) Blocked by required conditions
Server CI / Run mmctl tests (FIPS) (push) Blocked by required conditions
Server CI / Build mattermost server app (push) Blocked by required conditions
Web App CI / check-lint (push) Waiting to run
Web App CI / check-i18n (push) Blocked by required conditions
Web App CI / check-types (push) Blocked by required conditions
Web App CI / test (platform) (push) Blocked by required conditions
Web App CI / test (mattermost-redux) (push) Blocked by required conditions
Web App CI / test (channels shard 1/4) (push) Blocked by required conditions
Web App CI / test (channels shard 2/4) (push) Blocked by required conditions
Web App CI / test (channels shard 3/4) (push) Blocked by required conditions
Web App CI / test (channels shard 4/4) (push) Blocked by required conditions
Web App CI / upload-coverage (push) Blocked by required conditions
Web App CI / build (push) Blocked by required conditions
* Translated using Weblate (Belarusian)

Currently translated at 61.0% (1780 of 2915 strings)

Translation: Mattermost/server
Translate-URL: https://translate.mattermost.com/projects/mattermost/server/be/

* Translated using Weblate (Belarusian)

Currently translated at 76.6% (5182 of 6761 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/be/

* Translated using Weblate (Belarusian)

Currently translated at 61.0% (1780 of 2915 strings)

Translation: Mattermost/server
Translate-URL: https://translate.mattermost.com/projects/mattermost/server/be/

* Translated using Weblate (Belarusian)

Currently translated at 87.7% (5934 of 6761 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/be/

* Translated using Weblate (Belarusian)

Currently translated at 87.7% (5936 of 6761 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/be/

* Translated using Weblate (Belarusian)

Currently translated at 99.9% (2913 of 2915 strings)

Translation: Mattermost/server
Translate-URL: https://translate.mattermost.com/projects/mattermost/server/be/

* Translated using Weblate (Belarusian)

Currently translated at 100.0% (6761 of 6761 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/be/

* Translated using Weblate (Belarusian)

Currently translated at 100.0% (2915 of 2915 strings)

Translation: Mattermost/server
Translate-URL: https://translate.mattermost.com/projects/mattermost/server/be/

* Translated using Weblate (Belarusian)

Currently translated at 100.0% (6761 of 6761 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/be/

* Translated using Weblate (Swedish)

Currently translated at 96.3% (2809 of 2915 strings)

Translation: Mattermost/server
Translate-URL: https://translate.mattermost.com/projects/mattermost/server/sv/

* Translated using Weblate (Belarusian)

Currently translated at 100.0% (6761 of 6761 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/be/

* Translated using Weblate (Norwegian Bokmål)

Currently translated at 82.8% (5601 of 6761 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/nb_NO/

* Translated using Weblate (Belarusian)

Currently translated at 100.0% (6761 of 6761 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/be/

* Translated using Weblate (Swedish)

Currently translated at 96.3% (2810 of 2915 strings)

Translation: Mattermost/server
Translate-URL: https://translate.mattermost.com/projects/mattermost/server/sv/

* Translated using Weblate (Swedish)

Currently translated at 96.3% (2810 of 2915 strings)

Translation: Mattermost/server
Translate-URL: https://translate.mattermost.com/projects/mattermost/server/sv/

* Translated using Weblate (Finnish)

Currently translated at 23.5% (1593 of 6761 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/fi/

* Update translation files

Updated by "Cleanup translation files" hook in Weblate.

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/

---------

Co-authored-by: Vadim Asadchi <vadim.asadchi@codex-soft.com>
Co-authored-by: Kristoffer Grundström <swedishsailfishosuser@tutanota.com>
Co-authored-by: Frank Paul Silye <frankps@gmail.com>
Co-authored-by: MArtin Johnson <martinjohnson@bahnhof.se>
Co-authored-by: Ricky Tigg <ricky.tigg@gmail.com>
2026-01-12 12:47:53 +00:00
Andre Vasconcelos
d9123c33f1
MM-67037 Skipping flaky test TestAddChannelMemberNoUserRequestor (#34805)
* Skipping flaky test flagged in PR#34803

* Skipping flaky test for JIRA issue MM-67041
2026-01-12 11:06:09 +02:00
M-ZubairAhmed
43bab4d7c7
[MM-67025] Add new E2E for testing keyboard shortcut Shift+Up (#34793)
Some checks are pending
API / build (push) Waiting to run
Server CI / Compute Go Version (push) Waiting to run
Server CI / Check mocks (push) Blocked by required conditions
Server CI / Check go mod tidy (push) Blocked by required conditions
Server CI / check-style (push) Blocked by required conditions
Server CI / Check serialization methods for hot structs (push) Blocked by required conditions
Server CI / Vet API (push) Blocked by required conditions
Server CI / Check migration files (push) Blocked by required conditions
Server CI / Generate email templates (push) Blocked by required conditions
Server CI / Check store layers (push) Blocked by required conditions
Server CI / Check mmctl docs (push) Blocked by required conditions
Server CI / Postgres with binary parameters (push) Blocked by required conditions
Server CI / Postgres (push) Blocked by required conditions
Server CI / Postgres (FIPS) (push) Blocked by required conditions
Server CI / Generate Test Coverage (push) Blocked by required conditions
Server CI / Run mmctl tests (push) Blocked by required conditions
Server CI / Run mmctl tests (FIPS) (push) Blocked by required conditions
Server CI / Build mattermost server app (push) Blocked by required conditions
Web App CI / check-lint (push) Waiting to run
Web App CI / check-i18n (push) Blocked by required conditions
Web App CI / check-types (push) Blocked by required conditions
Web App CI / test (platform) (push) Blocked by required conditions
Web App CI / test (mattermost-redux) (push) Blocked by required conditions
Web App CI / test (channels shard 1/4) (push) Blocked by required conditions
Web App CI / test (channels shard 2/4) (push) Blocked by required conditions
Web App CI / test (channels shard 3/4) (push) Blocked by required conditions
Web App CI / test (channels shard 4/4) (push) Blocked by required conditions
Web App CI / upload-coverage (push) Blocked by required conditions
Web App CI / build (push) Blocked by required conditions
* add e2e test for Shift+Up keyboard shortcut in center channel

* Update dependencies in package-lock.json

* Update package-lock.json

* Update package-lock.json

---------

Co-authored-by: Mattermost Build <build@mattermost.com>
2026-01-12 13:01:14 +08:00
Jesse Hallam
07ba32e849
MM-62151 avoid select * for post store (#34709)
Some checks failed
API / build (push) Has been cancelled
Server CI / Compute Go Version (push) Has been cancelled
Web App CI / check-lint (push) Has been cancelled
Server CI / Check mocks (push) Has been cancelled
Server CI / Check go mod tidy (push) Has been cancelled
Server CI / check-style (push) Has been cancelled
Server CI / Check serialization methods for hot structs (push) Has been cancelled
Server CI / Vet API (push) Has been cancelled
Server CI / Check migration files (push) Has been cancelled
Server CI / Generate email templates (push) Has been cancelled
Server CI / Check store layers (push) Has been cancelled
Server CI / Check mmctl docs (push) Has been cancelled
Server CI / Postgres with binary parameters (push) Has been cancelled
Server CI / Postgres (push) Has been cancelled
Server CI / Postgres (FIPS) (push) Has been cancelled
Server CI / Generate Test Coverage (push) Has been cancelled
Server CI / Run mmctl tests (push) Has been cancelled
Server CI / Run mmctl tests (FIPS) (push) Has been cancelled
Server CI / Build mattermost server app (push) Has been cancelled
Web App CI / check-i18n (push) Has been cancelled
Web App CI / check-types (push) Has been cancelled
Web App CI / test (platform) (push) Has been cancelled
Web App CI / test (mattermost-redux) (push) Has been cancelled
Web App CI / test (channels shard 1/4) (push) Has been cancelled
Web App CI / test (channels shard 2/4) (push) Has been cancelled
Web App CI / test (channels shard 3/4) (push) Has been cancelled
Web App CI / test (channels shard 4/4) (push) Has been cancelled
Web App CI / upload-coverage (push) Has been cancelled
Web App CI / build (push) Has been cancelled
* fix SELECT * in user_store.go

* MM-62151: Avoid SELECT * in post store SQL queries

Replace all SELECT * patterns in post_store.go with explicit column
specifications using postSliceColumns() and postSliceColumnsWithName()
helper functions. This prevents unnecessary data transfer and protects
against schema changes.

Changes:
- Use Squirrel's .Column() method for cleaner query building
- Remove unqueryvet linter exception for post_store.go
- Fix 11 SELECT * occurrences in various query methods

* leverage postsQuery where we can

* more builder simplifications

* add noSelectStar to linter

---------

Co-authored-by: Mattermost Build <build@mattermost.com>
2026-01-09 18:23:16 +00:00
Carlos Garcia
81dc5f8801
bumps go version to 1.24.11 (#34876) 2026-01-09 17:22:23 +01:00
Rajat Dabade
e45dd2ccf3
Upgraded board version to v9.2.2 (#34884) 2026-01-09 20:31:21 +05:30
sabril
0b0658bdd0
chore: upgrade playwright to 1.57 and its dependencies (#34769)
Some checks are pending
API / build (push) Waiting to run
Server CI / Compute Go Version (push) Waiting to run
Server CI / Check mocks (push) Blocked by required conditions
Server CI / Check go mod tidy (push) Blocked by required conditions
Server CI / check-style (push) Blocked by required conditions
Server CI / Check serialization methods for hot structs (push) Blocked by required conditions
Server CI / Vet API (push) Blocked by required conditions
Server CI / Check migration files (push) Blocked by required conditions
Server CI / Generate email templates (push) Blocked by required conditions
Server CI / Check store layers (push) Blocked by required conditions
Server CI / Check mmctl docs (push) Blocked by required conditions
Server CI / Postgres with binary parameters (push) Blocked by required conditions
Server CI / Postgres (push) Blocked by required conditions
Server CI / Postgres (FIPS) (push) Blocked by required conditions
Server CI / Generate Test Coverage (push) Blocked by required conditions
Server CI / Run mmctl tests (push) Blocked by required conditions
Server CI / Run mmctl tests (FIPS) (push) Blocked by required conditions
Server CI / Build mattermost server app (push) Blocked by required conditions
Web App CI / check-lint (push) Waiting to run
Web App CI / check-i18n (push) Blocked by required conditions
Web App CI / check-types (push) Blocked by required conditions
Web App CI / test (platform) (push) Blocked by required conditions
Web App CI / test (mattermost-redux) (push) Blocked by required conditions
Web App CI / test (channels shard 1/4) (push) Blocked by required conditions
Web App CI / test (channels shard 2/4) (push) Blocked by required conditions
Web App CI / test (channels shard 3/4) (push) Blocked by required conditions
Web App CI / test (channels shard 4/4) (push) Blocked by required conditions
Web App CI / upload-coverage (push) Blocked by required conditions
Web App CI / build (push) Blocked by required conditions
* chore: upgrade playwright to 1.57 and its dependencies

* bump webapp's npm to accept ^11.0.0

* updated per comment

* fix failed tests
2026-01-09 10:48:19 +08:00
Carlos Garcia
0f432a1ee3
fixes registry used for mattermost-build-server image push and pull (#34882)
Some checks failed
Server CI / Compute Go Version (push) Waiting to run
Server CI / Check mocks (push) Blocked by required conditions
Server CI / Check go mod tidy (push) Blocked by required conditions
Server CI / check-style (push) Blocked by required conditions
Server CI / Check serialization methods for hot structs (push) Blocked by required conditions
Server CI / Vet API (push) Blocked by required conditions
Server CI / Check migration files (push) Blocked by required conditions
Server CI / Generate email templates (push) Blocked by required conditions
Server CI / Check store layers (push) Blocked by required conditions
Server CI / Check mmctl docs (push) Blocked by required conditions
Server CI / Postgres with binary parameters (push) Blocked by required conditions
Server CI / Postgres (push) Blocked by required conditions
Server CI / Postgres (FIPS) (push) Blocked by required conditions
Server CI / Generate Test Coverage (push) Blocked by required conditions
Server CI / Run mmctl tests (push) Blocked by required conditions
Server CI / Run mmctl tests (FIPS) (push) Blocked by required conditions
Server CI / Build mattermost server app (push) Blocked by required conditions
Web App CI / check-lint (push) Waiting to run
Web App CI / check-i18n (push) Blocked by required conditions
Web App CI / check-types (push) Blocked by required conditions
Web App CI / test (platform) (push) Blocked by required conditions
Web App CI / test (mattermost-redux) (push) Blocked by required conditions
Web App CI / test (channels shard 1/4) (push) Blocked by required conditions
Web App CI / test (channels shard 2/4) (push) Blocked by required conditions
Web App CI / test (channels shard 3/4) (push) Blocked by required conditions
Web App CI / test (channels shard 4/4) (push) Blocked by required conditions
Web App CI / upload-coverage (push) Blocked by required conditions
Web App CI / build (push) Blocked by required conditions
BuildEnv Docker Image / build-image (push) Has been cancelled
BuildEnv Docker Image / build-image-fips (push) Has been cancelled
* fixes registry used for mattermost-build-server image push and pull

* fixes credentials needed for logging in to mattermosr registry
2026-01-08 19:57:02 +00:00
unified-ci-app[bot]
4389116b19
Update latest minor version to 11.4.0 (#34874)
Some checks are pending
API / build (push) Waiting to run
Server CI / Compute Go Version (push) Waiting to run
Server CI / Check mocks (push) Blocked by required conditions
Server CI / Check go mod tidy (push) Blocked by required conditions
Server CI / check-style (push) Blocked by required conditions
Server CI / Check serialization methods for hot structs (push) Blocked by required conditions
Server CI / Vet API (push) Blocked by required conditions
Server CI / Check migration files (push) Blocked by required conditions
Server CI / Generate email templates (push) Blocked by required conditions
Server CI / Check store layers (push) Blocked by required conditions
Server CI / Check mmctl docs (push) Blocked by required conditions
Server CI / Postgres with binary parameters (push) Blocked by required conditions
Server CI / Postgres (push) Blocked by required conditions
Server CI / Postgres (FIPS) (push) Blocked by required conditions
Server CI / Generate Test Coverage (push) Blocked by required conditions
Server CI / Run mmctl tests (push) Blocked by required conditions
Server CI / Run mmctl tests (FIPS) (push) Blocked by required conditions
Server CI / Build mattermost server app (push) Blocked by required conditions
Web App CI / check-lint (push) Waiting to run
Web App CI / check-i18n (push) Blocked by required conditions
Web App CI / check-types (push) Blocked by required conditions
Web App CI / test (platform) (push) Blocked by required conditions
Web App CI / test (mattermost-redux) (push) Blocked by required conditions
Web App CI / test (channels shard 1/4) (push) Blocked by required conditions
Web App CI / test (channels shard 2/4) (push) Blocked by required conditions
Web App CI / test (channels shard 3/4) (push) Blocked by required conditions
Web App CI / test (channels shard 4/4) (push) Blocked by required conditions
Web App CI / upload-coverage (push) Blocked by required conditions
Web App CI / build (push) Blocked by required conditions
Automatic Merge
2026-01-08 09:47:31 +02:00
Carlos Garcia
9e30501885
updates Dockerfile go version to 1.24.11 to generate new build containers (#34871)
Some checks are pending
BuildEnv Docker Image / build-image (push) Waiting to run
BuildEnv Docker Image / build-image-fips (push) Waiting to run
Server CI / Compute Go Version (push) Waiting to run
Server CI / Check mocks (push) Blocked by required conditions
Server CI / Check go mod tidy (push) Blocked by required conditions
Server CI / check-style (push) Blocked by required conditions
Server CI / Check serialization methods for hot structs (push) Blocked by required conditions
Server CI / Vet API (push) Blocked by required conditions
Server CI / Check migration files (push) Blocked by required conditions
Server CI / Generate email templates (push) Blocked by required conditions
Server CI / Check store layers (push) Blocked by required conditions
Server CI / Check mmctl docs (push) Blocked by required conditions
Server CI / Postgres with binary parameters (push) Blocked by required conditions
Server CI / Postgres (push) Blocked by required conditions
Server CI / Postgres (FIPS) (push) Blocked by required conditions
Server CI / Generate Test Coverage (push) Blocked by required conditions
Server CI / Run mmctl tests (push) Blocked by required conditions
Server CI / Run mmctl tests (FIPS) (push) Blocked by required conditions
Server CI / Build mattermost server app (push) Blocked by required conditions
Web App CI / check-lint (push) Waiting to run
Web App CI / check-i18n (push) Blocked by required conditions
Web App CI / check-types (push) Blocked by required conditions
Web App CI / test (platform) (push) Blocked by required conditions
Web App CI / test (mattermost-redux) (push) Blocked by required conditions
Web App CI / test (channels shard 1/4) (push) Blocked by required conditions
Web App CI / test (channels shard 2/4) (push) Blocked by required conditions
Web App CI / test (channels shard 3/4) (push) Blocked by required conditions
Web App CI / test (channels shard 4/4) (push) Blocked by required conditions
Web App CI / upload-coverage (push) Blocked by required conditions
Web App CI / build (push) Blocked by required conditions
2026-01-07 23:11:37 +01:00
Doug Lauder
df6763a1e0
MM-66769: Suppress browser notification warning for MS 365 mobile apps (#34606)
Some checks are pending
API / build (push) Waiting to run
Server CI / Compute Go Version (push) Waiting to run
Server CI / Check mocks (push) Blocked by required conditions
Server CI / Check go mod tidy (push) Blocked by required conditions
Server CI / check-style (push) Blocked by required conditions
Server CI / Check serialization methods for hot structs (push) Blocked by required conditions
Server CI / Vet API (push) Blocked by required conditions
Server CI / Check migration files (push) Blocked by required conditions
Server CI / Generate email templates (push) Blocked by required conditions
Server CI / Check store layers (push) Blocked by required conditions
Server CI / Check mmctl docs (push) Blocked by required conditions
Server CI / Postgres with binary parameters (push) Blocked by required conditions
Server CI / Postgres (push) Blocked by required conditions
Server CI / Postgres (FIPS) (push) Blocked by required conditions
Server CI / Generate Test Coverage (push) Blocked by required conditions
Server CI / Run mmctl tests (push) Blocked by required conditions
Server CI / Run mmctl tests (FIPS) (push) Blocked by required conditions
Server CI / Build mattermost server app (push) Blocked by required conditions
Web App CI / check-lint (push) Waiting to run
Web App CI / check-i18n (push) Blocked by required conditions
Web App CI / check-types (push) Blocked by required conditions
Web App CI / test (platform) (push) Blocked by required conditions
Web App CI / test (mattermost-redux) (push) Blocked by required conditions
Web App CI / test (channels shard 1/4) (push) Blocked by required conditions
Web App CI / test (channels shard 2/4) (push) Blocked by required conditions
Web App CI / test (channels shard 3/4) (push) Blocked by required conditions
Web App CI / test (channels shard 4/4) (push) Blocked by required conditions
Web App CI / upload-coverage (push) Blocked by required conditions
Web App CI / build (push) Blocked by required conditions
* MM-66769: Suppress browser notification warning for MS 365 mobile apps

   When accessing Mattermost through MS Teams or Outlook mobile embedded
   browsers, users were seeing an "unsupported browser" warning banner.
   These browsers intentionally don't support the Notification API, but
   are otherwise fully functional.

   This change adds detection for Teams and Outlook mobile browsers and
   suppresses the notification warning banner for these apps:
   - Added isTeamsMobile(), isOutlookMobile(), and isM365Mobile() to user_agent.tsx
   - Updated NotificationPermissionBar to skip showing warning for M365 mobile apps
   - Detection patterns: TeamsMobile-Android/iOS, Teams/ on mobile, and PKeyAuth/1.0

* Don't show unsupported notice in Notification settings for MS 365 mobile apps

---------

Co-authored-by: Mattermost Build <build@mattermost.com>
2026-01-07 13:33:11 -05:00
Rajat Dabade
c7f6efdfb0
Guest cannot add file to post without upload_file permission (#34538)
* Guest cannot add file to post without upload_file permission

* Move checks to api layer, addd checks in update patch post scheduled post

* Minor

* Linter fixes

* i18n translations

* removed the duplicated check from scheduled_post app layer

* Move scheduled post permission test from app layer to API layer

The permission check for updating scheduled posts belonging to other
users was moved from the app layer to the API layer in the PR. This
commit moves the corresponding test to the API layer to match.

* Move scheduled post delete permission check to API layer

Move the permission check for deleting scheduled posts from the app
layer to the API layer, consistent with update permission check.
Also enhance API tests to verify posts aren't modified after forbidden
operations.

* Fix inconsistent status code for non-existent scheduled post

Return StatusNotFound instead of StatusInternalServerError when a
scheduled post doesn't exist in UpdateScheduledPost, matching the
API layer behavior.

* Fix flaky TestAddUserToChannelCreatesChannelMemberHistoryRecord test

Use ElementsMatch instead of Equal to compare user ID slices since the
order returned from GetUsersInChannelDuring is not guaranteed.

---------

Co-authored-by: Mattermost Build <build@mattermost.com>
Co-authored-by: Jesse Hallam <jesse@mattermost.com>
2026-01-07 10:40:05 -04:00
Rajat Dabade
0481bd1fb0
Fliter post in search api with no read content channel permission (#34620)
* Fliter post in search api with no read content channel permission

* Added test

* Review comments

* reverted the unnecessary code

* linter fixes

* Fix filter functions to handle non-existent channels gracefully

When filtering posts/files by channel permissions, GetChannels() returns
a 404 error if all requested channels don't exist. This caused the
entire filter operation to fail. Now we ignore 404 errors and continue
processing, allowing non-existent channels to be filtered out as expected.

---------

Co-authored-by: Mattermost Build <build@mattermost.com>
Co-authored-by: Jesse Hallam <jesse@mattermost.com>
2026-01-07 10:21:55 -04:00
Arya Khochare
0184153d16
changed api spec definition for userThread (#34819) 2026-01-07 10:10:42 -04:00
Alexandre Sollier
586adbd6f0
[MM-62503] Channel Title Description not Scrollable (#29827)
Some checks are pending
API / build (push) Waiting to run
Server CI / Compute Go Version (push) Waiting to run
Server CI / Check mocks (push) Blocked by required conditions
Server CI / Check go mod tidy (push) Blocked by required conditions
Server CI / check-style (push) Blocked by required conditions
Server CI / Check serialization methods for hot structs (push) Blocked by required conditions
Server CI / Vet API (push) Blocked by required conditions
Server CI / Check migration files (push) Blocked by required conditions
Server CI / Generate email templates (push) Blocked by required conditions
Server CI / Check store layers (push) Blocked by required conditions
Server CI / Check mmctl docs (push) Blocked by required conditions
Server CI / Postgres with binary parameters (push) Blocked by required conditions
Server CI / Postgres (push) Blocked by required conditions
Server CI / Postgres (FIPS) (push) Blocked by required conditions
Server CI / Generate Test Coverage (push) Blocked by required conditions
Server CI / Run mmctl tests (push) Blocked by required conditions
Server CI / Run mmctl tests (FIPS) (push) Blocked by required conditions
Server CI / Build mattermost server app (push) Blocked by required conditions
Web App CI / check-lint (push) Waiting to run
Web App CI / check-i18n (push) Blocked by required conditions
Web App CI / check-types (push) Blocked by required conditions
Web App CI / test (platform) (push) Blocked by required conditions
Web App CI / test (mattermost-redux) (push) Blocked by required conditions
Web App CI / test (channels shard 1/4) (push) Blocked by required conditions
Web App CI / test (channels shard 2/4) (push) Blocked by required conditions
Web App CI / test (channels shard 3/4) (push) Blocked by required conditions
Web App CI / test (channels shard 4/4) (push) Blocked by required conditions
Web App CI / upload-coverage (push) Blocked by required conditions
Web App CI / build (push) Blocked by required conditions
This makes the content of the channel info right sidebar scrollable by
wrapping its components in a `<Scrollbars>` component.

Signed-off-by: Kuruyia <github@kuruyia.net>
Co-authored-by: Mattermost Build <build@mattermost.com>
2026-01-06 18:13:51 +00:00
Harrison Healey
2f409ba46b
MM-65828 Add ThemeProvider and make app use Denim theme by default (#34755) 2026-01-06 11:49:20 -05:00
Harrison Healey
98124364ea
MM-66800 Migrate Add Channels menu to new menu component (#34757)
* MM-66800 Migrate Add Channels menu to new menu component

* Re-run i18n-extract

* Apply hovered style to Add Channels button when menu is open

* Update menu alignment

* Update snapshots
2026-01-06 11:48:04 -05:00
Jesse Hallam
84e267e9e8
[MM-66789] Restrict ImportSettings.Directory changes via API and add validation (#34653)
This change enhances security by preventing ImportSettings.Directory from being modified through the API and adds validation to prevent directory conflicts.

Changes:

- Restricted ImportSettings.Directory from being changed via API

- Added validation to prevent directory conflicts with plugin directory

- Added error message translation

- Updated and added comprehensive tests

Co-authored-by: Mattermost Build <build@mattermost.com>
2026-01-06 16:30:07 +00:00
Ben Schumacher
413cf4d67c
[MM-66918] Return descriptive errors from IsValidWebAuthRedirectURL (#34712)
Some checks are pending
API / build (push) Waiting to run
Server CI / Compute Go Version (push) Waiting to run
Server CI / Check mocks (push) Blocked by required conditions
Server CI / Check go mod tidy (push) Blocked by required conditions
Server CI / check-style (push) Blocked by required conditions
Server CI / Check serialization methods for hot structs (push) Blocked by required conditions
Server CI / Vet API (push) Blocked by required conditions
Server CI / Check migration files (push) Blocked by required conditions
Server CI / Generate email templates (push) Blocked by required conditions
Server CI / Check store layers (push) Blocked by required conditions
Server CI / Check mmctl docs (push) Blocked by required conditions
Server CI / Postgres with binary parameters (push) Blocked by required conditions
Server CI / Postgres (push) Blocked by required conditions
Server CI / Postgres (FIPS) (push) Blocked by required conditions
Server CI / Generate Test Coverage (push) Blocked by required conditions
Server CI / Run mmctl tests (push) Blocked by required conditions
Server CI / Run mmctl tests (FIPS) (push) Blocked by required conditions
Server CI / Build mattermost server app (push) Blocked by required conditions
Web App CI / check-lint (push) Waiting to run
Web App CI / check-i18n (push) Blocked by required conditions
Web App CI / check-types (push) Blocked by required conditions
Web App CI / test (platform) (push) Blocked by required conditions
Web App CI / test (mattermost-redux) (push) Blocked by required conditions
Web App CI / test (channels shard 1/4) (push) Blocked by required conditions
Web App CI / test (channels shard 2/4) (push) Blocked by required conditions
Web App CI / test (channels shard 3/4) (push) Blocked by required conditions
Web App CI / test (channels shard 4/4) (push) Blocked by required conditions
Web App CI / upload-coverage (push) Blocked by required conditions
Web App CI / build (push) Blocked by required conditions
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-06 10:19:22 +01:00
Joram Wilander
d844530496
Fix copyright date and address for email footers (#34813)
Some checks are pending
API / build (push) Waiting to run
Server CI / Compute Go Version (push) Waiting to run
Server CI / Check mocks (push) Blocked by required conditions
Server CI / Check go mod tidy (push) Blocked by required conditions
Server CI / check-style (push) Blocked by required conditions
Server CI / Check serialization methods for hot structs (push) Blocked by required conditions
Server CI / Vet API (push) Blocked by required conditions
Server CI / Check migration files (push) Blocked by required conditions
Server CI / Generate email templates (push) Blocked by required conditions
Server CI / Check store layers (push) Blocked by required conditions
Server CI / Check mmctl docs (push) Blocked by required conditions
Server CI / Postgres with binary parameters (push) Blocked by required conditions
Server CI / Postgres (push) Blocked by required conditions
Server CI / Postgres (FIPS) (push) Blocked by required conditions
Server CI / Generate Test Coverage (push) Blocked by required conditions
Server CI / Run mmctl tests (push) Blocked by required conditions
Server CI / Run mmctl tests (FIPS) (push) Blocked by required conditions
Server CI / Build mattermost server app (push) Blocked by required conditions
Web App CI / check-lint (push) Waiting to run
Web App CI / check-i18n (push) Blocked by required conditions
Web App CI / check-types (push) Blocked by required conditions
Web App CI / test (platform) (push) Blocked by required conditions
Web App CI / test (mattermost-redux) (push) Blocked by required conditions
Web App CI / test (channels shard 1/4) (push) Blocked by required conditions
Web App CI / test (channels shard 2/4) (push) Blocked by required conditions
Web App CI / test (channels shard 3/4) (push) Blocked by required conditions
Web App CI / test (channels shard 4/4) (push) Blocked by required conditions
Web App CI / upload-coverage (push) Blocked by required conditions
Web App CI / build (push) Blocked by required conditions
* Fix copyright date and address for email footers

* Update footer for email template
2026-01-05 13:59:37 -05:00
Eva Sarafianou
08087a1420
Update golang.org/x/crypto (#34838) 2026-01-05 16:09:22 +02:00
M-ZubairAhmed
cc427af41b
[MM-66827] Omit invite_id from team creation response based on permissions (#34693) 2026-01-05 13:48:19 +00:00
Weblate (bot)
346bc3f561
Translations update from Mattermost Weblate (#34844)
* Translated using Weblate (German)

Currently translated at 100.0% (6761 of 6761 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/de/

* Translated using Weblate (Polish)

Currently translated at 100.0% (6761 of 6761 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/pl/

* Translated using Weblate (Swedish)

Currently translated at 96.3% (2808 of 2915 strings)

Translation: Mattermost/server
Translate-URL: https://translate.mattermost.com/projects/mattermost/server/sv/

* Translated using Weblate (Indonesian)

Currently translated at 2.9% (197 of 6761 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/id/

* Translated using Weblate (Polish)

Currently translated at 100.0% (6761 of 6761 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/pl/

---------

Co-authored-by: jprusch <rs@schaeferbarthold.de>
Co-authored-by: master7 <marcin.karkosz@rajska.info>
Co-authored-by: Kristoffer Grundström <swedishsailfishosuser@tutanota.com>
Co-authored-by: Vimobe <raymond.sigar@gmail.com>
2026-01-05 11:44:04 +00:00
unified-ci-app[bot]
a4f3473952
chore: Update NOTICE.txt file with updated dependencies (#34843)
Some checks are pending
API / build (push) Waiting to run
Server CI / Compute Go Version (push) Waiting to run
Server CI / Check mocks (push) Blocked by required conditions
Server CI / Check go mod tidy (push) Blocked by required conditions
Server CI / check-style (push) Blocked by required conditions
Server CI / Check serialization methods for hot structs (push) Blocked by required conditions
Server CI / Vet API (push) Blocked by required conditions
Server CI / Check migration files (push) Blocked by required conditions
Server CI / Generate email templates (push) Blocked by required conditions
Server CI / Check store layers (push) Blocked by required conditions
Server CI / Check mmctl docs (push) Blocked by required conditions
Server CI / Postgres with binary parameters (push) Blocked by required conditions
Server CI / Postgres (push) Blocked by required conditions
Server CI / Postgres (FIPS) (push) Blocked by required conditions
Server CI / Generate Test Coverage (push) Blocked by required conditions
Server CI / Run mmctl tests (push) Blocked by required conditions
Server CI / Run mmctl tests (FIPS) (push) Blocked by required conditions
Server CI / Build mattermost server app (push) Blocked by required conditions
Web App CI / check-lint (push) Waiting to run
Web App CI / check-i18n (push) Blocked by required conditions
Web App CI / check-types (push) Blocked by required conditions
Web App CI / test (platform) (push) Blocked by required conditions
Web App CI / test (mattermost-redux) (push) Blocked by required conditions
Web App CI / test (channels shard 1/4) (push) Blocked by required conditions
Web App CI / test (channels shard 2/4) (push) Blocked by required conditions
Web App CI / test (channels shard 3/4) (push) Blocked by required conditions
Web App CI / test (channels shard 4/4) (push) Blocked by required conditions
Web App CI / upload-coverage (push) Blocked by required conditions
Web App CI / build (push) Blocked by required conditions
Automatic Merge
2026-01-05 13:02:00 +02:00
Harshil Sharma
10ef05252d
Returning pending post ID for post creator for BoR post (#34758)
Co-authored-by: Mattermost Build <build@mattermost.com>
2026-01-05 15:36:44 +05:30
unified-ci-app[bot]
2e377f6c91
chore: Update NOTICE.txt file with updated dependencies (#34825)
Automatic Merge
2026-01-05 09:31:59 +02:00
Weblate (bot)
96f159c251
Translations update from Mattermost Weblate (#34835)
Some checks failed
API / build (push) Has been cancelled
Server CI / Compute Go Version (push) Has been cancelled
Web App CI / check-lint (push) Has been cancelled
Server CI / Check mocks (push) Has been cancelled
Server CI / Check go mod tidy (push) Has been cancelled
Server CI / check-style (push) Has been cancelled
Server CI / Check serialization methods for hot structs (push) Has been cancelled
Server CI / Vet API (push) Has been cancelled
Server CI / Check migration files (push) Has been cancelled
Server CI / Generate email templates (push) Has been cancelled
Server CI / Check store layers (push) Has been cancelled
Server CI / Check mmctl docs (push) Has been cancelled
Server CI / Postgres with binary parameters (push) Has been cancelled
Server CI / Postgres (push) Has been cancelled
Server CI / Postgres (FIPS) (push) Has been cancelled
Server CI / Generate Test Coverage (push) Has been cancelled
Server CI / Run mmctl tests (push) Has been cancelled
Server CI / Run mmctl tests (FIPS) (push) Has been cancelled
Server CI / Build mattermost server app (push) Has been cancelled
Web App CI / check-i18n (push) Has been cancelled
Web App CI / check-types (push) Has been cancelled
Web App CI / test (platform) (push) Has been cancelled
Web App CI / test (mattermost-redux) (push) Has been cancelled
Web App CI / test (channels shard 1/4) (push) Has been cancelled
Web App CI / test (channels shard 2/4) (push) Has been cancelled
Web App CI / test (channels shard 3/4) (push) Has been cancelled
Web App CI / test (channels shard 4/4) (push) Has been cancelled
Web App CI / upload-coverage (push) Has been cancelled
Web App CI / build (push) Has been cancelled
* Translated using Weblate (English (Australia))

Currently translated at 100.0% (2915 of 2915 strings)

Translation: Mattermost/server
Translate-URL: https://translate.mattermost.com/projects/mattermost/server/en_AU/

* Translated using Weblate (Polish)

Currently translated at 100.0% (2915 of 2915 strings)

Translation: Mattermost/server
Translate-URL: https://translate.mattermost.com/projects/mattermost/server/pl/

* Translated using Weblate (English (Australia))

Currently translated at 100.0% (6762 of 6762 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/en_AU/

* Translated using Weblate (Polish)

Currently translated at 100.0% (6762 of 6762 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/pl/

* Translated using Weblate (German)

Currently translated at 100.0% (2915 of 2915 strings)

Translation: Mattermost/server
Translate-URL: https://translate.mattermost.com/projects/mattermost/server/de/

* Translated using Weblate (German)

Currently translated at 100.0% (6762 of 6762 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/de/

* Translated using Weblate (Portuguese)

Currently translated at 30.5% (2068 of 6762 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/pt/

* Translated using Weblate (Norwegian Bokmål)

Currently translated at 82.8% (5599 of 6762 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/nb_NO/

* Translated using Weblate (Dutch)

Currently translated at 99.8% (2912 of 2915 strings)

Translation: Mattermost/server
Translate-URL: https://translate.mattermost.com/projects/mattermost/server/nl/

* Translated using Weblate (Dutch)

Currently translated at 99.9% (6761 of 6762 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/nl/

* Translated using Weblate (Swedish)

Currently translated at 98.3% (6648 of 6762 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/sv/

* Translated using Weblate (Polish)

Currently translated at 100.0% (6762 of 6762 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/pl/

* Translated using Weblate (Swedish)

Currently translated at 98.3% (6653 of 6762 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/sv/

* Update translation files

Updated by "Cleanup translation files" hook in Weblate.

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/

---------

Co-authored-by: Matthew Williams <Matthew.Williams@outlook.com.au>
Co-authored-by: master7 <marcin.karkosz@rajska.info>
Co-authored-by: jprusch <rs@schaeferbarthold.de>
Co-authored-by: Manuela Silva <mmsrs@sky.com>
Co-authored-by: Frank Paul Silye <frankps@gmail.com>
Co-authored-by: Tom De Moor <tom@controlaltdieliet.be>
Co-authored-by: MArtin Johnson <martinjohnson@bahnhof.se>
2025-12-29 19:26:01 +00:00
Pablo Vélez
b94c037f28
MM-66910 - Fix isPostInteractable to exclude burn-on-read posts (#34764)
Some checks failed
API / build (push) Has been cancelled
Server CI / Compute Go Version (push) Has been cancelled
Web App CI / check-lint (push) Has been cancelled
Server CI / Check mocks (push) Has been cancelled
Server CI / Check go mod tidy (push) Has been cancelled
Server CI / check-style (push) Has been cancelled
Server CI / Check serialization methods for hot structs (push) Has been cancelled
Server CI / Vet API (push) Has been cancelled
Server CI / Check migration files (push) Has been cancelled
Server CI / Generate email templates (push) Has been cancelled
Server CI / Check store layers (push) Has been cancelled
Server CI / Check mmctl docs (push) Has been cancelled
Server CI / Postgres with binary parameters (push) Has been cancelled
Server CI / Postgres (push) Has been cancelled
Server CI / Postgres (FIPS) (push) Has been cancelled
Server CI / Generate Test Coverage (push) Has been cancelled
Server CI / Run mmctl tests (push) Has been cancelled
Server CI / Run mmctl tests (FIPS) (push) Has been cancelled
Server CI / Build mattermost server app (push) Has been cancelled
Web App CI / check-i18n (push) Has been cancelled
Web App CI / check-types (push) Has been cancelled
Web App CI / test (platform) (push) Has been cancelled
Web App CI / test (mattermost-redux) (push) Has been cancelled
Web App CI / test (channels shard 1/4) (push) Has been cancelled
Web App CI / test (channels shard 2/4) (push) Has been cancelled
Web App CI / test (channels shard 3/4) (push) Has been cancelled
Web App CI / test (channels shard 4/4) (push) Has been cancelled
Web App CI / upload-coverage (push) Has been cancelled
Web App CI / build (push) Has been cancelled
* MM-66910 - Fix isPostInteractable to exclude burn-on-read posts

* prevent R reply, clean up test files and improve structure

* remove unused canPostBeForwarded variable and use props for forward check

---------

Co-authored-by: Mattermost Build <build@mattermost.com>
2025-12-23 22:54:08 +01:00
Pablo Vélez
732ddaeae4
MM-66924 - MarkAllThreadsAsReadModal to use ConfirmModal (#34732)
Some checks failed
API / build (push) Has been cancelled
Server CI / Compute Go Version (push) Has been cancelled
Web App CI / check-lint (push) Has been cancelled
Server CI / Check mocks (push) Has been cancelled
Server CI / Check go mod tidy (push) Has been cancelled
Server CI / check-style (push) Has been cancelled
Server CI / Check serialization methods for hot structs (push) Has been cancelled
Server CI / Vet API (push) Has been cancelled
Server CI / Check migration files (push) Has been cancelled
Server CI / Generate email templates (push) Has been cancelled
Server CI / Check store layers (push) Has been cancelled
Server CI / Check mmctl docs (push) Has been cancelled
Server CI / Postgres with binary parameters (push) Has been cancelled
Server CI / Postgres (push) Has been cancelled
Server CI / Postgres (FIPS) (push) Has been cancelled
Server CI / Generate Test Coverage (push) Has been cancelled
Server CI / Run mmctl tests (push) Has been cancelled
Server CI / Run mmctl tests (FIPS) (push) Has been cancelled
Server CI / Build mattermost server app (push) Has been cancelled
Web App CI / check-i18n (push) Has been cancelled
Web App CI / check-types (push) Has been cancelled
Web App CI / test (platform) (push) Has been cancelled
Web App CI / test (mattermost-redux) (push) Has been cancelled
Web App CI / test (channels shard 1/4) (push) Has been cancelled
Web App CI / test (channels shard 2/4) (push) Has been cancelled
Web App CI / test (channels shard 3/4) (push) Has been cancelled
Web App CI / test (channels shard 4/4) (push) Has been cancelled
Web App CI / upload-coverage (push) Has been cancelled
Web App CI / build (push) Has been cancelled
* MM-66924 - MarkAllThreadsAsReadModal to use ConfirmModal and remove unused styles

* adjust translations

* adjust texts as requested and do not use confirm modal

* update mark all threads as read modal description for clarity
2025-12-22 18:53:20 +01:00
Weblate (bot)
6e14959d28
Translations update from Mattermost Weblate (#34827)
* Translated using Weblate (Polish)

Currently translated at 99.5% (6726 of 6758 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/pl/

* Translated using Weblate (German)

Currently translated at 99.1% (2888 of 2913 strings)

Translation: Mattermost/server
Translate-URL: https://translate.mattermost.com/projects/mattermost/server/de/

* Translated using Weblate (Chinese (Simplified Han script))

Currently translated at 100.0% (2913 of 2913 strings)

Translation: Mattermost/server
Translate-URL: https://translate.mattermost.com/projects/mattermost/server/zh_Hans/

* Translated using Weblate (Polish)

Currently translated at 100.0% (6758 of 6758 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/pl/

* Translated using Weblate (Chinese (Simplified Han script))

Currently translated at 100.0% (6758 of 6758 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/zh_Hans/

* Translated using Weblate (German)

Currently translated at 100.0% (2913 of 2913 strings)

Translation: Mattermost/server
Translate-URL: https://translate.mattermost.com/projects/mattermost/server/de/

* Translated using Weblate (German)

Currently translated at 100.0% (6758 of 6758 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/de/

* Translated using Weblate (Norwegian Bokmål)

Currently translated at 82.9% (5604 of 6758 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/nb_NO/

* Translated using Weblate (Polish)

Currently translated at 99.1% (2887 of 2913 strings)

Translation: Mattermost/server
Translate-URL: https://translate.mattermost.com/projects/mattermost/server/pl/

* Translated using Weblate (Swedish)

Currently translated at 96.3% (2807 of 2913 strings)

Translation: Mattermost/server
Translate-URL: https://translate.mattermost.com/projects/mattermost/server/sv/

* Translated using Weblate (Dutch)

Currently translated at 99.8% (2910 of 2913 strings)

Translation: Mattermost/server
Translate-URL: https://translate.mattermost.com/projects/mattermost/server/nl/

* Translated using Weblate (Dutch)

Currently translated at 99.9% (6757 of 6758 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/nl/

* Translated using Weblate (Polish)

Currently translated at 100.0% (2913 of 2913 strings)

Translation: Mattermost/server
Translate-URL: https://translate.mattermost.com/projects/mattermost/server/pl/

* Update translation files

Updated by "Cleanup translation files" hook in Weblate.

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/

---------

Co-authored-by: master7 <marcin.karkosz@rajska.info>
Co-authored-by: jprusch <rs@schaeferbarthold.de>
Co-authored-by: Sharuru <mave@foxmail.com>
Co-authored-by: Frank Paul Silye <frankps@gmail.com>
Co-authored-by: Kristoffer Grundström <swedishsailfishosuser@tutanota.com>
Co-authored-by: Tom De Moor <tom@controlaltdieliet.be>
2025-12-22 16:38:26 +00:00
Tom De Moor
62f71d1134
Removing Alpha Label (#34806) 2025-12-22 15:02:49 +00:00
Harshil Sharma
3a288a4b4f
Bor post disable flagging (#34759)
Some checks are pending
API / build (push) Waiting to run
Server CI / Compute Go Version (push) Waiting to run
Server CI / Check mocks (push) Blocked by required conditions
Server CI / Check go mod tidy (push) Blocked by required conditions
Server CI / check-style (push) Blocked by required conditions
Server CI / Check serialization methods for hot structs (push) Blocked by required conditions
Server CI / Vet API (push) Blocked by required conditions
Server CI / Check migration files (push) Blocked by required conditions
Server CI / Generate email templates (push) Blocked by required conditions
Server CI / Check store layers (push) Blocked by required conditions
Server CI / Check mmctl docs (push) Blocked by required conditions
Server CI / Postgres with binary parameters (push) Blocked by required conditions
Server CI / Postgres (push) Blocked by required conditions
Server CI / Postgres (FIPS) (push) Blocked by required conditions
Server CI / Generate Test Coverage (push) Blocked by required conditions
Server CI / Run mmctl tests (push) Blocked by required conditions
Server CI / Run mmctl tests (FIPS) (push) Blocked by required conditions
Server CI / Build mattermost server app (push) Blocked by required conditions
Web App CI / check-lint (push) Waiting to run
Web App CI / check-i18n (push) Blocked by required conditions
Web App CI / check-types (push) Blocked by required conditions
Web App CI / test (platform) (push) Blocked by required conditions
Web App CI / test (mattermost-redux) (push) Blocked by required conditions
Web App CI / test (channels shard 1/4) (push) Blocked by required conditions
Web App CI / test (channels shard 2/4) (push) Blocked by required conditions
Web App CI / test (channels shard 3/4) (push) Blocked by required conditions
Web App CI / test (channels shard 4/4) (push) Blocked by required conditions
Web App CI / upload-coverage (push) Blocked by required conditions
Web App CI / build (push) Blocked by required conditions
* Disabled flagging BoR post

* Added post type checks in flagPost() API

* i18n fixes

* fixes

---------

Co-authored-by: Mattermost Build <build@mattermost.com>
2025-12-22 12:25:54 +05:30
Matthew Birtch
1a16a7bd7f
[MM-67033] invite input padding (#34811)
Some checks are pending
API / build (push) Waiting to run
Server CI / Compute Go Version (push) Waiting to run
Server CI / Check mocks (push) Blocked by required conditions
Server CI / Check go mod tidy (push) Blocked by required conditions
Server CI / check-style (push) Blocked by required conditions
Server CI / Check serialization methods for hot structs (push) Blocked by required conditions
Server CI / Vet API (push) Blocked by required conditions
Server CI / Check migration files (push) Blocked by required conditions
Server CI / Generate email templates (push) Blocked by required conditions
Server CI / Check store layers (push) Blocked by required conditions
Server CI / Check mmctl docs (push) Blocked by required conditions
Server CI / Postgres with binary parameters (push) Blocked by required conditions
Server CI / Postgres (push) Blocked by required conditions
Server CI / Postgres (FIPS) (push) Blocked by required conditions
Server CI / Generate Test Coverage (push) Blocked by required conditions
Server CI / Run mmctl tests (push) Blocked by required conditions
Server CI / Run mmctl tests (FIPS) (push) Blocked by required conditions
Server CI / Build mattermost server app (push) Blocked by required conditions
Web App CI / check-lint (push) Waiting to run
Web App CI / check-i18n (push) Blocked by required conditions
Web App CI / check-types (push) Blocked by required conditions
Web App CI / test (platform) (push) Blocked by required conditions
Web App CI / test (mattermost-redux) (push) Blocked by required conditions
Web App CI / test (channels shard 1/4) (push) Blocked by required conditions
Web App CI / test (channels shard 2/4) (push) Blocked by required conditions
Web App CI / test (channels shard 3/4) (push) Blocked by required conditions
Web App CI / test (channels shard 4/4) (push) Blocked by required conditions
Web App CI / upload-coverage (push) Blocked by required conditions
Web App CI / build (push) Blocked by required conditions
fix spacing on invite modal input
2025-12-21 20:28:44 -05:00
Doug Lauder
338cf4a5a0
Add docs re Shared Channels APIs calls and data flow (#34682)
* Add docs re Shared Channels APIs calls and data flow

* add diagrams
2025-12-21 16:15:07 -05:00
Vicktor
c1de5c4b6e
refactor(generated_setting): migrate GeneratedSetting to a function component (#34527)
Some checks failed
API / build (push) Has been cancelled
Server CI / Compute Go Version (push) Has been cancelled
Web App CI / check-lint (push) Has been cancelled
Server CI / Check mocks (push) Has been cancelled
Server CI / Check go mod tidy (push) Has been cancelled
Server CI / check-style (push) Has been cancelled
Server CI / Check serialization methods for hot structs (push) Has been cancelled
Server CI / Vet API (push) Has been cancelled
Server CI / Check migration files (push) Has been cancelled
Server CI / Generate email templates (push) Has been cancelled
Server CI / Check store layers (push) Has been cancelled
Server CI / Check mmctl docs (push) Has been cancelled
Server CI / Postgres with binary parameters (push) Has been cancelled
Server CI / Postgres (push) Has been cancelled
Server CI / Postgres (FIPS) (push) Has been cancelled
Server CI / Generate Test Coverage (push) Has been cancelled
Server CI / Run mmctl tests (push) Has been cancelled
Server CI / Run mmctl tests (FIPS) (push) Has been cancelled
Server CI / Build mattermost server app (push) Has been cancelled
Web App CI / check-i18n (push) Has been cancelled
Web App CI / check-types (push) Has been cancelled
Web App CI / test (platform) (push) Has been cancelled
Web App CI / test (mattermost-redux) (push) Has been cancelled
Web App CI / test (channels shard 1/4) (push) Has been cancelled
Web App CI / test (channels shard 2/4) (push) Has been cancelled
Web App CI / test (channels shard 3/4) (push) Has been cancelled
Web App CI / test (channels shard 4/4) (push) Has been cancelled
Web App CI / upload-coverage (push) Has been cancelled
Web App CI / build (push) Has been cancelled
* refactor(generated_setting): migrate GeneratedSetting to a function component

* refactor(generated_setting): wrap regenerate function with useCallback

* test(custom_plugin_settings): update snapshots

---------

Co-authored-by: Mattermost Build <build@mattermost.com>
2025-12-19 14:59:54 -05:00
Pablo Vélez
1a21d34aab
MM-66925 - improve user email and password modals (#34739)
* MM-66925 - improve user email and password  modals

* adjust error modal styling

* adjust e2e tests
2025-12-19 15:52:59 +01:00
Andre Vasconcelos
a17bb19844
Bumping prepackaged Jira Plugin version to v4.5.0 (#34803) 2025-12-19 16:23:55 +02:00
Pablo Vélez
a7e5b3b0a0
MM-66891 - show only timer for sender when all recipients reveal message (#34745)
Co-authored-by: Mattermost Build <build@mattermost.com>
2025-12-19 12:58:31 +01:00
Devin Binnie
402b70e645
[MM-66889] Load scheduled posts for team in thread popout (#34766)
Some checks failed
API / build (push) Has been cancelled
Server CI / Compute Go Version (push) Has been cancelled
Web App CI / check-lint (push) Has been cancelled
Server CI / Check mocks (push) Has been cancelled
Server CI / Check go mod tidy (push) Has been cancelled
Server CI / check-style (push) Has been cancelled
Server CI / Check serialization methods for hot structs (push) Has been cancelled
Server CI / Vet API (push) Has been cancelled
Server CI / Check migration files (push) Has been cancelled
Server CI / Generate email templates (push) Has been cancelled
Server CI / Check store layers (push) Has been cancelled
Server CI / Check mmctl docs (push) Has been cancelled
Server CI / Postgres with binary parameters (push) Has been cancelled
Server CI / Postgres (push) Has been cancelled
Server CI / Postgres (FIPS) (push) Has been cancelled
Server CI / Generate Test Coverage (push) Has been cancelled
Server CI / Run mmctl tests (push) Has been cancelled
Server CI / Run mmctl tests (FIPS) (push) Has been cancelled
Server CI / Build mattermost server app (push) Has been cancelled
Web App CI / check-i18n (push) Has been cancelled
Web App CI / check-types (push) Has been cancelled
Web App CI / test (platform) (push) Has been cancelled
Web App CI / test (mattermost-redux) (push) Has been cancelled
Web App CI / test (channels shard 1/4) (push) Has been cancelled
Web App CI / test (channels shard 2/4) (push) Has been cancelled
Web App CI / test (channels shard 3/4) (push) Has been cancelled
Web App CI / test (channels shard 4/4) (push) Has been cancelled
Web App CI / upload-coverage (push) Has been cancelled
Web App CI / build (push) Has been cancelled
2025-12-18 14:39:36 -05:00
Pablo Vélez
b998f8c6e8
remove 'only' from Main Post Input accessibility test (#34799)
Some checks are pending
API / build (push) Waiting to run
Server CI / Compute Go Version (push) Waiting to run
Server CI / Check mocks (push) Blocked by required conditions
Server CI / Check go mod tidy (push) Blocked by required conditions
Server CI / check-style (push) Blocked by required conditions
Server CI / Check serialization methods for hot structs (push) Blocked by required conditions
Server CI / Vet API (push) Blocked by required conditions
Server CI / Check migration files (push) Blocked by required conditions
Server CI / Generate email templates (push) Blocked by required conditions
Server CI / Check store layers (push) Blocked by required conditions
Server CI / Check mmctl docs (push) Blocked by required conditions
Server CI / Postgres with binary parameters (push) Blocked by required conditions
Server CI / Postgres (push) Blocked by required conditions
Server CI / Postgres (FIPS) (push) Blocked by required conditions
Server CI / Generate Test Coverage (push) Blocked by required conditions
Server CI / Run mmctl tests (push) Blocked by required conditions
Server CI / Run mmctl tests (FIPS) (push) Blocked by required conditions
Server CI / Build mattermost server app (push) Blocked by required conditions
Web App CI / check-lint (push) Waiting to run
Web App CI / check-i18n (push) Blocked by required conditions
Web App CI / check-types (push) Blocked by required conditions
Web App CI / test (platform) (push) Blocked by required conditions
Web App CI / test (mattermost-redux) (push) Blocked by required conditions
Web App CI / test (channels shard 1/4) (push) Blocked by required conditions
Web App CI / test (channels shard 2/4) (push) Blocked by required conditions
Web App CI / test (channels shard 3/4) (push) Blocked by required conditions
Web App CI / test (channels shard 4/4) (push) Blocked by required conditions
Web App CI / upload-coverage (push) Blocked by required conditions
Web App CI / build (push) Blocked by required conditions
2025-12-18 17:30:35 +01:00
Daniel Espino García
55e056c0b8
Update YAML files to document magic link endpoints (#34617) 2025-12-18 13:36:56 +01:00
Pablo Vélez
e08db85569
MM-66939 -Hide plugin actions menu for burn-on-read posts (#34729) 2025-12-18 12:31:09 +01:00
Pablo Vélez
f1a7778650
MM-66907 - hide bor ui elements with prof or ent licenses (#34787)
Some checks are pending
API / build (push) Waiting to run
Server CI / Compute Go Version (push) Waiting to run
Server CI / Check mocks (push) Blocked by required conditions
Server CI / Check go mod tidy (push) Blocked by required conditions
Server CI / check-style (push) Blocked by required conditions
Server CI / Check serialization methods for hot structs (push) Blocked by required conditions
Server CI / Vet API (push) Blocked by required conditions
Server CI / Check migration files (push) Blocked by required conditions
Server CI / Generate email templates (push) Blocked by required conditions
Server CI / Check store layers (push) Blocked by required conditions
Server CI / Check mmctl docs (push) Blocked by required conditions
Server CI / Postgres with binary parameters (push) Blocked by required conditions
Server CI / Postgres (push) Blocked by required conditions
Server CI / Postgres (FIPS) (push) Blocked by required conditions
Server CI / Generate Test Coverage (push) Blocked by required conditions
Server CI / Run mmctl tests (push) Blocked by required conditions
Server CI / Run mmctl tests (FIPS) (push) Blocked by required conditions
Server CI / Build mattermost server app (push) Blocked by required conditions
Web App CI / check-lint (push) Waiting to run
Web App CI / check-i18n (push) Blocked by required conditions
Web App CI / check-types (push) Blocked by required conditions
Web App CI / test (platform) (push) Blocked by required conditions
Web App CI / test (mattermost-redux) (push) Blocked by required conditions
Web App CI / test (channels shard 1/4) (push) Blocked by required conditions
Web App CI / test (channels shard 2/4) (push) Blocked by required conditions
Web App CI / test (channels shard 3/4) (push) Blocked by required conditions
Web App CI / test (channels shard 4/4) (push) Blocked by required conditions
Web App CI / upload-coverage (push) Blocked by required conditions
Web App CI / build (push) Blocked by required conditions
2025-12-18 10:53:38 +01:00
Takuya N
a3a83e5239
style: remove padding-left: 7px from each post in the thread view on mobile (#34208)
Also keep it unchanged in padding-bottom: 0 in the mobile view.

Signed-off-by: Takuya Noguchi <takninnovationresearch@gmail.com>
Co-authored-by: Mattermost Build <build@mattermost.com>
2025-12-18 09:40:19 +01:00
Pablo Vélez
e0052be9c3
MM-66890 - Set default for BurnOnRead feature flag to true (#34763)
* MM-66890 - Set default for BurnOnRead feature flag to true

* enable the feature by default

* fix unit tests

* fix e2e tests

---------

Co-authored-by: Mattermost Build <build@mattermost.com>
2025-12-18 09:39:44 +01:00
Nick Misasi
11e849d416
Update prepackaged Agents to 1.7.2 (#34780)
Automatic Merge
2025-12-18 10:31:23 +02:00
M-ZubairAhmed
4a47f97447
[MM-64810] Editing a post scrolls the user to the bottom of the channel unexpectedly (#34685) 2025-12-18 05:31:05 +00:00
Harshil Sharma
7c94aed6ba
Added debug log to indicate the job is not running as the node is not a leader node (#34701)
* Added debug log to indicate the job is not running as the node is not cluster node

* Setting log level to info for debugging test server issue

* testing

* Removed debugging code

---------

Co-authored-by: Mattermost Build <build@mattermost.com>
2025-12-18 10:16:48 +05:30
Ibrahim Serdar Acikgoz
bbac501431
fix build error (#34783)
Some checks are pending
API / build (push) Waiting to run
Server CI / Compute Go Version (push) Waiting to run
Server CI / Check mocks (push) Blocked by required conditions
Server CI / Check go mod tidy (push) Blocked by required conditions
Server CI / check-style (push) Blocked by required conditions
Server CI / Check serialization methods for hot structs (push) Blocked by required conditions
Server CI / Vet API (push) Blocked by required conditions
Server CI / Check migration files (push) Blocked by required conditions
Server CI / Generate email templates (push) Blocked by required conditions
Server CI / Check store layers (push) Blocked by required conditions
Server CI / Check mmctl docs (push) Blocked by required conditions
Server CI / Postgres with binary parameters (push) Blocked by required conditions
Server CI / Postgres (push) Blocked by required conditions
Server CI / Postgres (FIPS) (push) Blocked by required conditions
Server CI / Generate Test Coverage (push) Blocked by required conditions
Server CI / Run mmctl tests (push) Blocked by required conditions
Server CI / Run mmctl tests (FIPS) (push) Blocked by required conditions
Server CI / Build mattermost server app (push) Blocked by required conditions
Web App CI / check-lint (push) Waiting to run
Web App CI / check-i18n (push) Blocked by required conditions
Web App CI / check-types (push) Blocked by required conditions
Web App CI / test (platform) (push) Blocked by required conditions
Web App CI / test (mattermost-redux) (push) Blocked by required conditions
Web App CI / test (channels shard 1/4) (push) Blocked by required conditions
Web App CI / test (channels shard 2/4) (push) Blocked by required conditions
Web App CI / test (channels shard 3/4) (push) Blocked by required conditions
Web App CI / test (channels shard 4/4) (push) Blocked by required conditions
Web App CI / upload-coverage (push) Blocked by required conditions
Web App CI / build (push) Blocked by required conditions
2025-12-17 16:19:09 +00:00
Ibrahim Serdar Acikgoz
1c68d36a03
Filter burn on read posts from search results (#34747) 2025-12-17 16:23:26 +01:00
Pablo Vélez
a14ee02f32
enforce InviteUser permission for team invite settings (#34715)
* enforce InviteUser permission for team invite settings

* Fix variable shadowing in TestUpdateTeamInviteUserPermission

---------

Co-authored-by: Mattermost Build <build@mattermost.com>
Co-authored-by: Jesse Hallam <jesse@mattermost.com>
2025-12-17 14:52:17 +00:00
Daniel Espino García
0901686681
[MM-66710] Do not allow MFA enforcement on magic link accounts (#34614)
* [MM-66710] Do not allow MFA enforcement on magic link accounts

* Update server/i18n/en.json

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* Fix blocker when changing configuration

---------

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Mattermost Build <build@mattermost.com>
2025-12-17 15:46:41 +01:00
Daniel Espino García
9f2605a275
[MM-66709] Avoid magic link login if already logged in (#34613) 2025-12-17 13:50:18 +01:00
Pablo Vélez
2bb714a8e1
MM-66948: Filter expired BoR from flagged posts (#34744)
Co-authored-by: Mattermost Build <build@mattermost.com>
2025-12-17 11:45:44 +01:00
Ibrahim Serdar Acikgoz
7dce49ee84
Fix an issue where files for BoR messages were not properly deleted (#34743)
Some checks are pending
API / build (push) Waiting to run
Server CI / Compute Go Version (push) Waiting to run
Server CI / Check mocks (push) Blocked by required conditions
Server CI / Check go mod tidy (push) Blocked by required conditions
Server CI / check-style (push) Blocked by required conditions
Server CI / Check serialization methods for hot structs (push) Blocked by required conditions
Server CI / Vet API (push) Blocked by required conditions
Server CI / Check migration files (push) Blocked by required conditions
Server CI / Generate email templates (push) Blocked by required conditions
Server CI / Check store layers (push) Blocked by required conditions
Server CI / Check mmctl docs (push) Blocked by required conditions
Server CI / Postgres with binary parameters (push) Blocked by required conditions
Server CI / Postgres (push) Blocked by required conditions
Server CI / Postgres (FIPS) (push) Blocked by required conditions
Server CI / Generate Test Coverage (push) Blocked by required conditions
Server CI / Run mmctl tests (push) Blocked by required conditions
Server CI / Run mmctl tests (FIPS) (push) Blocked by required conditions
Server CI / Build mattermost server app (push) Blocked by required conditions
Web App CI / check-lint (push) Waiting to run
Web App CI / check-i18n (push) Blocked by required conditions
Web App CI / check-types (push) Blocked by required conditions
Web App CI / test (platform) (push) Blocked by required conditions
Web App CI / test (mattermost-redux) (push) Blocked by required conditions
Web App CI / test (channels shard 1/4) (push) Blocked by required conditions
Web App CI / test (channels shard 2/4) (push) Blocked by required conditions
Web App CI / test (channels shard 3/4) (push) Blocked by required conditions
Web App CI / test (channels shard 4/4) (push) Blocked by required conditions
Web App CI / upload-coverage (push) Blocked by required conditions
Web App CI / build (push) Blocked by required conditions
2025-12-17 10:19:04 +01:00
sabril
d7aebb555d
fix flaky notifications tests and migrated to playwright (#34449)
Co-authored-by: Mattermost Build <build@mattermost.com>
2025-12-17 06:51:20 +00:00
Harrison Healey
5fe3987e91
Update web app package versions to 11.3.0 (#34750)
Some checks are pending
API / build (push) Waiting to run
Server CI / Compute Go Version (push) Waiting to run
Server CI / Check mocks (push) Blocked by required conditions
Server CI / Check go mod tidy (push) Blocked by required conditions
Server CI / check-style (push) Blocked by required conditions
Server CI / Check serialization methods for hot structs (push) Blocked by required conditions
Server CI / Vet API (push) Blocked by required conditions
Server CI / Check migration files (push) Blocked by required conditions
Server CI / Generate email templates (push) Blocked by required conditions
Server CI / Check store layers (push) Blocked by required conditions
Server CI / Check mmctl docs (push) Blocked by required conditions
Server CI / Postgres with binary parameters (push) Blocked by required conditions
Server CI / Postgres (push) Blocked by required conditions
Server CI / Postgres (FIPS) (push) Blocked by required conditions
Server CI / Generate Test Coverage (push) Blocked by required conditions
Server CI / Run mmctl tests (push) Blocked by required conditions
Server CI / Run mmctl tests (FIPS) (push) Blocked by required conditions
Server CI / Build mattermost server app (push) Blocked by required conditions
Web App CI / check-lint (push) Waiting to run
Web App CI / check-i18n (push) Blocked by required conditions
Web App CI / check-types (push) Blocked by required conditions
Web App CI / test (platform) (push) Blocked by required conditions
Web App CI / test (mattermost-redux) (push) Blocked by required conditions
Web App CI / test (channels shard 1/4) (push) Blocked by required conditions
Web App CI / test (channels shard 2/4) (push) Blocked by required conditions
Web App CI / test (channels shard 3/4) (push) Blocked by required conditions
Web App CI / test (channels shard 4/4) (push) Blocked by required conditions
Web App CI / upload-coverage (push) Blocked by required conditions
Web App CI / build (push) Blocked by required conditions
2025-12-16 14:26:18 -05:00
M-ZubairAhmed
3d5730c7a0
Added RHS state selector and updated suppress logic to prevent rhs suppression when in mention, search, or flag states. (#34684)
Some checks are pending
API / build (push) Waiting to run
Server CI / Compute Go Version (push) Waiting to run
Server CI / Check mocks (push) Blocked by required conditions
Server CI / Check go mod tidy (push) Blocked by required conditions
Server CI / check-style (push) Blocked by required conditions
Server CI / Check serialization methods for hot structs (push) Blocked by required conditions
Server CI / Vet API (push) Blocked by required conditions
Server CI / Check migration files (push) Blocked by required conditions
Server CI / Generate email templates (push) Blocked by required conditions
Server CI / Check store layers (push) Blocked by required conditions
Server CI / Check mmctl docs (push) Blocked by required conditions
Server CI / Postgres with binary parameters (push) Blocked by required conditions
Server CI / Postgres (push) Blocked by required conditions
Server CI / Postgres (FIPS) (push) Blocked by required conditions
Server CI / Generate Test Coverage (push) Blocked by required conditions
Server CI / Run mmctl tests (push) Blocked by required conditions
Server CI / Run mmctl tests (FIPS) (push) Blocked by required conditions
Server CI / Build mattermost server app (push) Blocked by required conditions
Web App CI / check-lint (push) Waiting to run
Web App CI / check-i18n (push) Blocked by required conditions
Web App CI / check-types (push) Blocked by required conditions
Web App CI / test (platform) (push) Blocked by required conditions
Web App CI / test (mattermost-redux) (push) Blocked by required conditions
Web App CI / test (channels shard 1/4) (push) Blocked by required conditions
Web App CI / test (channels shard 2/4) (push) Blocked by required conditions
Web App CI / test (channels shard 3/4) (push) Blocked by required conditions
Web App CI / test (channels shard 4/4) (push) Blocked by required conditions
Web App CI / upload-coverage (push) Blocked by required conditions
Web App CI / build (push) Blocked by required conditions
2025-12-16 07:33:33 +00:00
Jesse Hallam
895aa387d9
MM-66952: Disable Generate Test Coverage job in CI (#34749)
Some checks are pending
API / build (push) Waiting to run
Server CI / Compute Go Version (push) Waiting to run
Server CI / Check mocks (push) Blocked by required conditions
Server CI / Check go mod tidy (push) Blocked by required conditions
Server CI / check-style (push) Blocked by required conditions
Server CI / Check serialization methods for hot structs (push) Blocked by required conditions
Server CI / Vet API (push) Blocked by required conditions
Server CI / Check migration files (push) Blocked by required conditions
Server CI / Generate email templates (push) Blocked by required conditions
Server CI / Check store layers (push) Blocked by required conditions
Server CI / Check mmctl docs (push) Blocked by required conditions
Server CI / Postgres with binary parameters (push) Blocked by required conditions
Server CI / Postgres (push) Blocked by required conditions
Server CI / Postgres (FIPS) (push) Blocked by required conditions
Server CI / Generate Test Coverage (push) Blocked by required conditions
Server CI / Run mmctl tests (push) Blocked by required conditions
Server CI / Run mmctl tests (FIPS) (push) Blocked by required conditions
Server CI / Build mattermost server app (push) Blocked by required conditions
Web App CI / check-lint (push) Waiting to run
Web App CI / check-i18n (push) Blocked by required conditions
Web App CI / check-types (push) Blocked by required conditions
Web App CI / test (platform) (push) Blocked by required conditions
Web App CI / test (mattermost-redux) (push) Blocked by required conditions
Web App CI / test (channels shard 1/4) (push) Blocked by required conditions
Web App CI / test (channels shard 2/4) (push) Blocked by required conditions
Web App CI / test (channels shard 3/4) (push) Blocked by required conditions
Web App CI / test (channels shard 4/4) (push) Blocked by required conditions
Web App CI / upload-coverage (push) Blocked by required conditions
Web App CI / build (push) Blocked by required conditions
Temporarily disable the test coverage job which is running out of memory and causing spurious CI failures.
2025-12-15 16:08:37 -04:00
Jesse Hallam
6404ab29ac
MM-66424: Improve team filtering in common teams API (#34454)
* add Client4.GetDirectOrGroupMessageMembersCommonTeams

* Improve team filtering in common teams API

Filter the common teams to only include teams the requesting user is a
member of, ensuring proper access control.

* simplify GetDirectOrGroupMessageMembersCommonTeamsAsUser
2025-12-15 15:06:48 -04:00
Weblate (bot)
a3fda6a64c
Translations update from Mattermost Weblate (#34746)
Some checks are pending
API / build (push) Waiting to run
Server CI / Compute Go Version (push) Waiting to run
Server CI / Check mocks (push) Blocked by required conditions
Server CI / Check go mod tidy (push) Blocked by required conditions
Server CI / check-style (push) Blocked by required conditions
Server CI / Check serialization methods for hot structs (push) Blocked by required conditions
Server CI / Vet API (push) Blocked by required conditions
Server CI / Check migration files (push) Blocked by required conditions
Server CI / Generate email templates (push) Blocked by required conditions
Server CI / Check store layers (push) Blocked by required conditions
Server CI / Check mmctl docs (push) Blocked by required conditions
Server CI / Postgres with binary parameters (push) Blocked by required conditions
Server CI / Postgres (push) Blocked by required conditions
Server CI / Postgres (FIPS) (push) Blocked by required conditions
Server CI / Generate Test Coverage (push) Blocked by required conditions
Server CI / Run mmctl tests (push) Blocked by required conditions
Server CI / Run mmctl tests (FIPS) (push) Blocked by required conditions
Server CI / Build mattermost server app (push) Blocked by required conditions
Web App CI / check-lint (push) Waiting to run
Web App CI / check-i18n (push) Blocked by required conditions
Web App CI / check-types (push) Blocked by required conditions
Web App CI / test (platform) (push) Blocked by required conditions
Web App CI / test (mattermost-redux) (push) Blocked by required conditions
Web App CI / test (channels shard 1/4) (push) Blocked by required conditions
Web App CI / test (channels shard 2/4) (push) Blocked by required conditions
Web App CI / test (channels shard 3/4) (push) Blocked by required conditions
Web App CI / test (channels shard 4/4) (push) Blocked by required conditions
Web App CI / upload-coverage (push) Blocked by required conditions
Web App CI / build (push) Blocked by required conditions
* Translated using Weblate (Polish)

Currently translated at 100.0% (6724 of 6724 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/pl/

* Translated using Weblate (German)

Currently translated at 100.0% (2867 of 2867 strings)

Translation: Mattermost/server
Translate-URL: https://translate.mattermost.com/projects/mattermost/server/de/

* Translated using Weblate (German)

Currently translated at 100.0% (6724 of 6724 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/de/

* Translated using Weblate (Polish)

Currently translated at 100.0% (6724 of 6724 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/pl/

* Update translation files

Updated by "Cleanup translation files" hook in Weblate.

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/

---------

Co-authored-by: master7 <marcin.karkosz@rajska.info>
Co-authored-by: jprusch <rs@schaeferbarthold.de>
2025-12-15 16:48:05 +00:00
Jesse Hallam
54f2e9b4af
MM-66943: Fix SavePluginConfig wiping other plugins' configs (#34733)
Some checks failed
API / build (push) Has been cancelled
Server CI / Compute Go Version (push) Has been cancelled
Web App CI / check-lint (push) Has been cancelled
Server CI / Check mocks (push) Has been cancelled
Server CI / Check go mod tidy (push) Has been cancelled
Server CI / check-style (push) Has been cancelled
Server CI / Check serialization methods for hot structs (push) Has been cancelled
Server CI / Vet API (push) Has been cancelled
Server CI / Check migration files (push) Has been cancelled
Server CI / Generate email templates (push) Has been cancelled
Server CI / Check store layers (push) Has been cancelled
Server CI / Check mmctl docs (push) Has been cancelled
Server CI / Postgres with binary parameters (push) Has been cancelled
Server CI / Postgres (push) Has been cancelled
Server CI / Postgres (FIPS) (push) Has been cancelled
Server CI / Generate Test Coverage (push) Has been cancelled
Server CI / Run mmctl tests (push) Has been cancelled
Server CI / Run mmctl tests (FIPS) (push) Has been cancelled
Server CI / Build mattermost server app (push) Has been cancelled
Web App CI / check-i18n (push) Has been cancelled
Web App CI / check-types (push) Has been cancelled
Web App CI / test (platform) (push) Has been cancelled
Web App CI / test (mattermost-redux) (push) Has been cancelled
Web App CI / test (channels shard 1/4) (push) Has been cancelled
Web App CI / test (channels shard 2/4) (push) Has been cancelled
Web App CI / test (channels shard 3/4) (push) Has been cancelled
Web App CI / test (channels shard 4/4) (push) Has been cancelled
Web App CI / upload-coverage (push) Has been cancelled
Web App CI / build (push) Has been cancelled
2025-12-12 16:45:51 -04:00
Just Nev
b61389526b
Update Zoom prepackaged version to 1.11.0 (#34734)
Co-authored-by: Nevyana Angelova <nevyangelova@Nevy-Macbook-16-2025.local>
2025-12-12 17:04:11 +00:00
Daniel Espino García
4c25967c17
[MM-66799] Remove magic link users password (#34616)
Some checks are pending
API / build (push) Waiting to run
Server CI / Compute Go Version (push) Waiting to run
Server CI / Check mocks (push) Blocked by required conditions
Server CI / Check go mod tidy (push) Blocked by required conditions
Server CI / check-style (push) Blocked by required conditions
Server CI / Check serialization methods for hot structs (push) Blocked by required conditions
Server CI / Vet API (push) Blocked by required conditions
Server CI / Check migration files (push) Blocked by required conditions
Server CI / Generate email templates (push) Blocked by required conditions
Server CI / Check store layers (push) Blocked by required conditions
Server CI / Check mmctl docs (push) Blocked by required conditions
Server CI / Postgres with binary parameters (push) Blocked by required conditions
Server CI / Postgres (push) Blocked by required conditions
Server CI / Postgres (FIPS) (push) Blocked by required conditions
Server CI / Generate Test Coverage (push) Blocked by required conditions
Server CI / Run mmctl tests (push) Blocked by required conditions
Server CI / Run mmctl tests (FIPS) (push) Blocked by required conditions
Server CI / Build mattermost server app (push) Blocked by required conditions
Web App CI / check-lint (push) Waiting to run
Web App CI / check-i18n (push) Blocked by required conditions
Web App CI / check-types (push) Blocked by required conditions
Web App CI / test (platform) (push) Blocked by required conditions
Web App CI / test (mattermost-redux) (push) Blocked by required conditions
Web App CI / test (channels shard 1/4) (push) Blocked by required conditions
Web App CI / test (channels shard 2/4) (push) Blocked by required conditions
Web App CI / test (channels shard 3/4) (push) Blocked by required conditions
Web App CI / test (channels shard 4/4) (push) Blocked by required conditions
Web App CI / upload-coverage (push) Blocked by required conditions
Web App CI / build (push) Blocked by required conditions
Co-authored-by: Mattermost Build <build@mattermost.com>
2025-12-12 16:25:38 +01:00
Pablo Vélez
8d1bde6daa
Fix: Split CI cache for platform builds to use source-based key (#34713) 2025-12-12 15:55:58 +01:00
Christopher Speller
36285d192b
Update Agents plugin to v1.7.1 (#34716)
Some checks are pending
API / build (push) Waiting to run
Server CI / Compute Go Version (push) Waiting to run
Server CI / Check mocks (push) Blocked by required conditions
Server CI / Check go mod tidy (push) Blocked by required conditions
Server CI / check-style (push) Blocked by required conditions
Server CI / Check serialization methods for hot structs (push) Blocked by required conditions
Server CI / Vet API (push) Blocked by required conditions
Server CI / Check migration files (push) Blocked by required conditions
Server CI / Generate email templates (push) Blocked by required conditions
Server CI / Check store layers (push) Blocked by required conditions
Server CI / Check mmctl docs (push) Blocked by required conditions
Server CI / Postgres with binary parameters (push) Blocked by required conditions
Server CI / Postgres (push) Blocked by required conditions
Server CI / Postgres (FIPS) (push) Blocked by required conditions
Server CI / Generate Test Coverage (push) Blocked by required conditions
Server CI / Run mmctl tests (push) Blocked by required conditions
Server CI / Run mmctl tests (FIPS) (push) Blocked by required conditions
Server CI / Build mattermost server app (push) Blocked by required conditions
Web App CI / check-lint (push) Waiting to run
Web App CI / check-i18n (push) Blocked by required conditions
Web App CI / check-types (push) Blocked by required conditions
Web App CI / test (platform) (push) Blocked by required conditions
Web App CI / test (mattermost-redux) (push) Blocked by required conditions
Web App CI / test (channels shard 1/4) (push) Blocked by required conditions
Web App CI / test (channels shard 2/4) (push) Blocked by required conditions
Web App CI / test (channels shard 3/4) (push) Blocked by required conditions
Web App CI / test (channels shard 4/4) (push) Blocked by required conditions
Web App CI / upload-coverage (push) Blocked by required conditions
Web App CI / build (push) Blocked by required conditions
Automatic Merge
2025-12-12 08:24:16 +02:00
Harshil Sharma
61651b0df7
User id auth control (#34441)
* Disabled user ID auth if email and username login are disabled

* Added tests

* lint fix

---------

Co-authored-by: Mattermost Build <build@mattermost.com>
2025-12-12 10:53:46 +05:30
Jesse Hallam
a21169e2a8
MM-65959: Add FIPS indicator to about dialog (#34463)
Some checks are pending
API / build (push) Waiting to run
Server CI / Compute Go Version (push) Waiting to run
Server CI / Check mocks (push) Blocked by required conditions
Server CI / Check go mod tidy (push) Blocked by required conditions
Server CI / check-style (push) Blocked by required conditions
Server CI / Check serialization methods for hot structs (push) Blocked by required conditions
Server CI / Vet API (push) Blocked by required conditions
Server CI / Check migration files (push) Blocked by required conditions
Server CI / Generate email templates (push) Blocked by required conditions
Server CI / Check store layers (push) Blocked by required conditions
Server CI / Check mmctl docs (push) Blocked by required conditions
Server CI / Postgres with binary parameters (push) Blocked by required conditions
Server CI / Postgres (push) Blocked by required conditions
Server CI / Postgres (FIPS) (push) Blocked by required conditions
Server CI / Generate Test Coverage (push) Blocked by required conditions
Server CI / Run mmctl tests (push) Blocked by required conditions
Server CI / Run mmctl tests (FIPS) (push) Blocked by required conditions
Server CI / Build mattermost server app (push) Blocked by required conditions
Web App CI / check-lint (push) Waiting to run
Web App CI / check-i18n (push) Blocked by required conditions
Web App CI / check-types (push) Blocked by required conditions
Web App CI / test (platform) (push) Blocked by required conditions
Web App CI / test (mattermost-redux) (push) Blocked by required conditions
Web App CI / test (channels shard 1/4) (push) Blocked by required conditions
Web App CI / test (channels shard 2/4) (push) Blocked by required conditions
Web App CI / test (channels shard 3/4) (push) Blocked by required conditions
Web App CI / test (channels shard 4/4) (push) Blocked by required conditions
Web App CI / upload-coverage (push) Blocked by required conditions
Web App CI / build (push) Blocked by required conditions
2025-12-11 18:37:29 -04:00
Jesse Hallam
6ef73af2cc
MM-65960: Avoid replica race lag when accessing TelemetryID (#34586)
* avoid replica race lag when remembering ServerID

In an HA environment, with a master and read replica, querying the server id from the store runs the risk of returning a value saved to master but not yet replicated. Avoid this by using the telemetry service value directly when available.

Fixes: MM-65960

* Add Get(ByName)WithContext

* explicitly use master for ServerId

* mock GetByNameWithContext

* more mocking

* more mocks
2025-12-11 17:34:36 -04:00
Devin Binnie
959022f953
[MM-66875][MM-66876] Implement RHS plugin popout (#34692)
* [MM-66875] Implement RHS popout component

* [MM-66876] Add RHS plugin popouts

* Give plugins a way to check when popouts are opened

* Fix test

* Fix border radius

* Fix lint

* Update title to just show plugin name

* Add server name to plugin popout for Desktop App

* Fix test

---------

Co-authored-by: Mattermost Build <build@mattermost.com>
2025-12-11 14:04:43 -05:00
Daniel Espino García
2884751a85
[MM-66708] Disallow interacting with password and login method for magic link accounts (#34615)
* [MM-66708] Disallow interacting with password and login method for magic link accounts

* Fix test and update getLoginType response

---------

Co-authored-by: Mattermost Build <build@mattermost.com>
2025-12-11 17:38:39 +01:00
Harrison Healey
c85c9ee3fd
MM-66880 Fix Components package being included in build twice (#34690)
Some checks are pending
API / build (push) Waiting to run
Server CI / Compute Go Version (push) Waiting to run
Server CI / Check mocks (push) Blocked by required conditions
Server CI / Check go mod tidy (push) Blocked by required conditions
Server CI / check-style (push) Blocked by required conditions
Server CI / Check serialization methods for hot structs (push) Blocked by required conditions
Server CI / Vet API (push) Blocked by required conditions
Server CI / Check migration files (push) Blocked by required conditions
Server CI / Generate email templates (push) Blocked by required conditions
Server CI / Check store layers (push) Blocked by required conditions
Server CI / Check mmctl docs (push) Blocked by required conditions
Server CI / Postgres with binary parameters (push) Blocked by required conditions
Server CI / Postgres (push) Blocked by required conditions
Server CI / Postgres (FIPS) (push) Blocked by required conditions
Server CI / Generate Test Coverage (push) Blocked by required conditions
Server CI / Run mmctl tests (push) Blocked by required conditions
Server CI / Run mmctl tests (FIPS) (push) Blocked by required conditions
Server CI / Build mattermost server app (push) Blocked by required conditions
Web App CI / check-lint (push) Waiting to run
Web App CI / check-i18n (push) Blocked by required conditions
Web App CI / check-types (push) Blocked by required conditions
Web App CI / test (platform) (push) Blocked by required conditions
Web App CI / test (mattermost-redux) (push) Blocked by required conditions
Web App CI / test (channels shard 1/4) (push) Blocked by required conditions
Web App CI / test (channels shard 2/4) (push) Blocked by required conditions
Web App CI / test (channels shard 3/4) (push) Blocked by required conditions
Web App CI / test (channels shard 4/4) (push) Blocked by required conditions
Web App CI / upload-coverage (push) Blocked by required conditions
Web App CI / build (push) Blocked by required conditions
2025-12-11 09:15:44 -05:00
Jesse Hallam
219530c82c
Add fast test hasher to speed up CI tests (#34707)
The production password hasher uses PBKDF2 with 600,000 iterations,
which is slow especially when combined with race detection. This
adds a fast test hasher (work factor 1) that can be used during tests
to speed up user creation.

The fast hasher is only available in non-production builds via build
tags, ensuring it cannot be used in production.
2025-12-11 09:46:21 -04:00
Ibrahim Serdar Acikgoz
c519789529
Fix build order issue in TS types (#34711) 2025-12-11 10:40:04 +01:00
Ibrahim Serdar Acikgoz
084006c0ea
[MM-61758] Burn on read feature (#34703)
Some checks are pending
API / build (push) Waiting to run
Server CI / Compute Go Version (push) Waiting to run
Server CI / Check mocks (push) Blocked by required conditions
Server CI / Check go mod tidy (push) Blocked by required conditions
Server CI / check-style (push) Blocked by required conditions
Server CI / Check serialization methods for hot structs (push) Blocked by required conditions
Server CI / Vet API (push) Blocked by required conditions
Server CI / Check migration files (push) Blocked by required conditions
Server CI / Generate email templates (push) Blocked by required conditions
Server CI / Check store layers (push) Blocked by required conditions
Server CI / Check mmctl docs (push) Blocked by required conditions
Server CI / Postgres with binary parameters (push) Blocked by required conditions
Server CI / Postgres (push) Blocked by required conditions
Server CI / Postgres (FIPS) (push) Blocked by required conditions
Server CI / Generate Test Coverage (push) Blocked by required conditions
Server CI / Run mmctl tests (push) Blocked by required conditions
Server CI / Run mmctl tests (FIPS) (push) Blocked by required conditions
Server CI / Build mattermost server app (push) Blocked by required conditions
Web App CI / check-lint (push) Waiting to run
Web App CI / check-i18n (push) Blocked by required conditions
Web App CI / check-types (push) Blocked by required conditions
Web App CI / test (platform) (push) Blocked by required conditions
Web App CI / test (mattermost-redux) (push) Blocked by required conditions
Web App CI / test (channels shard 1/4) (push) Blocked by required conditions
Web App CI / test (channels shard 2/4) (push) Blocked by required conditions
Web App CI / test (channels shard 3/4) (push) Blocked by required conditions
Web App CI / test (channels shard 4/4) (push) Blocked by required conditions
Web App CI / upload-coverage (push) Blocked by required conditions
Web App CI / build (push) Blocked by required conditions
* Add read receipt store for burn on read message types

* update mocks

* fix invalidation target

* have consistent case on index creation

* Add temporary posts table

* add mock

* add transaction support

* reflect review comments

* wip: Add reveal endpoint

* user check error id instead

* wip: Add ws events and cleanup for burn on read posts

* add burn endpoint for explicitly burning messages

* add translations

* Added logic to associate files of BoR post with the post

* Added test

* fixes

* disable pinning posts and review comments

* MM-66594 - Burn on read UI integration (#34647)

* MM-66244 - add BoR visual components to message editor

* MM-66246 - BoR visual indicator for sender and receiver

* MM-66607 - bor - add timer countdown and autodeletion

* add the system console max time to live config

* use the max expire at and create global scheduler to register bor messages

* use seconds for BoR config values in BE

* implement the read by text shown in the tooltip logic

* unestack the posts from same receiver and BoR  and fix styling

* avoid opening reply RHS

* remove unused dispatchers

* persis the BoR label in the drafts

* move expiration value to metadata

* adjust unit tests to metadata insted of props

* code clean up and some performance improvements; add period grace for deletion too

* adjust migration serie number

* hide bor messages when config is off

* performance improvements on post component and code clean up

* keep bor existing post functionality if config is disabled

* Add read receipt store for burn on read message types

* Add temporary posts table

* add transaction support

* reflect review comments

* wip: Add reveal endpoint

* user check error id instead

* wip: Add ws events and cleanup for burn on read posts

* avoid reacting to unrevealed bor messages

* adjust migration number

* Add read receipt store for burn on read message types

* have consistent case on index creation

* Add temporary posts table

* add mock

* add transaction support

* reflect review comments

* wip: Add reveal endpoint

* user check error id instead

* wip: Add ws events and cleanup for burn on read posts

* add burn endpoint for explicitly burning messages

* adjust post reveal and type with backend changes

* use real config values, adjust icon usage and style

* adjust the delete from from sender and receiver

* improve self deleting logic by placing in badge, use burn endpoint

* adjust websocket events handling for the read by sender label information

* adjust styling for concealed and error state

* update burn-on-read post event handling for improved recipient tracking and multi-device sync

* replace burn_on_read with type in database migrations and model

* remove burn_on_read metadata from PostMetadata and related structures

* Added logic to associate files of BoR post with the post

* Added test

* adjust migration name and fix linter

* Add read receipt store for burn on read message types

* update mocks

* have consistent case on index creation

* Add temporary posts table

* add mock

* add transaction support

* reflect review comments

* wip: Add reveal endpoint

* user check error id instead

* wip: Add ws events and cleanup for burn on read posts

* add burn endpoint for explicitly burning messages

* Added logic to associate files of BoR post with the post

* Added test

* disable pinning posts and review comments

* show attachment on bor reveal

* remove unused translation

* Enhance burn-on-read post handling and refine previous post ID retrieval logic

* adjust the returning chunk to work with bor messages

* read temp post from master db

* read from master

* show the copy link button to the sender

* revert unnecessary check

* restore correct json tag

* remove unused error handling  and clarify burn-on-read comment

* improve type safety and use proper selectors

* eliminate code duplication in deletion handler

* optimize performance and add documentation

* delete bor message for sender once all receivers reveal it

* add burn on read to scheduled posts

* add feature enable check

* use master to avoid  all read recipients race condition

---------

Co-authored-by: Mattermost Build <build@mattermost.com>
Co-authored-by: Ibrahim Serdar Acikgoz <serdaracikgoz86@gmail.com>
Co-authored-by: Harshil Sharma <harshilsharma63@gmail.com>

* squash migrations into single file

* add configuration for the scheduler

* don't run messagehasbeenposted hook

* remove parallel tests on burn on read

* add clean up for closing opened modals from previous tests

* simplify delete menu item rendering

* add cleanup step to close open modals after each test to prevent pollution

* streamline delete button visibility logic for Burn on Read posts

* improve reliability of closing post menu and modals by using body ESC key

---------

Co-authored-by: Harshil Sharma <harshilsharma63@gmail.com>
Co-authored-by: Pablo Vélez <pablovv2012@gmail.com>
Co-authored-by: Mattermost Build <build@mattermost.com>
2025-12-11 07:59:50 +01:00
1905 changed files with 160263 additions and 64827 deletions

View file

@ -0,0 +1,2 @@
node_modules/
.env

View file

@ -0,0 +1,48 @@
name: Calculate Cypress Results
description: Calculate Cypress test results with optional merge of retest results
author: Mattermost
inputs:
original-results-path:
description: Path to the original Cypress results directory (e.g., e2e-tests/cypress/results)
required: true
retest-results-path:
description: Path to the retest Cypress results directory (optional - if not provided, only calculates from original)
required: false
write-merged:
description: Whether to write merged results back to the original directory (default true)
required: false
default: "true"
outputs:
# Merge outputs
merged:
description: Whether merge was performed (true/false)
# Calculation outputs (same as calculate-cypress-test-results)
passed:
description: Number of passed tests
failed:
description: Number of failed tests
pending:
description: Number of pending/skipped tests
total_specs:
description: Total number of spec files
commit_status_message:
description: Message for commit status (e.g., "X failed, Y passed (Z spec files)")
failed_specs:
description: Comma-separated list of failed spec files (for retest)
failed_specs_count:
description: Number of failed spec files
failed_tests:
description: Markdown table rows of failed tests (for GitHub summary)
total:
description: Total number of tests (passed + failed)
pass_rate:
description: Pass rate percentage (e.g., "100.00")
color:
description: Color for webhook based on pass rate (green=100%, yellow=99%+, orange=98%+, red=<98%)
runs:
using: node24
main: dist/index.js

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,15 @@
/** @type {import('ts-jest').JestConfigWithTsJest} */
module.exports = {
preset: "ts-jest",
testEnvironment: "node",
testMatch: ["**/*.test.ts"],
moduleFileExtensions: ["ts", "js"],
transform: {
"^.+\\.ts$": [
"ts-jest",
{
useESM: false,
},
],
},
};

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,27 @@
{
"name": "calculate-cypress-results",
"private": true,
"version": "0.1.0",
"main": "dist/index.js",
"scripts": {
"build": "tsup",
"prettier": "npx prettier --write \"src/**/*.ts\"",
"local-action": "local-action . src/main.ts .env",
"test": "jest --verbose",
"test:watch": "jest --watch --verbose",
"test:silent": "jest --silent",
"tsc": "tsc -b"
},
"dependencies": {
"@actions/core": "3.0.0"
},
"devDependencies": {
"@github/local-action": "7.0.0",
"@types/jest": "30.0.0",
"@types/node": "25.2.0",
"jest": "30.2.0",
"ts-jest": "29.4.6",
"tsup": "8.5.1",
"typescript": "5.9.3"
}
}

View file

@ -0,0 +1,3 @@
import { run } from "./main";
run();

View file

@ -0,0 +1,99 @@
import * as core from "@actions/core";
import {
loadSpecFiles,
mergeResults,
writeMergedResults,
calculateResultsFromSpecs,
} from "./merge";
export async function run(): Promise<void> {
const originalPath = core.getInput("original-results-path", {
required: true,
});
const retestPath = core.getInput("retest-results-path"); // Optional
const shouldWriteMerged = core.getInput("write-merged") !== "false"; // Default true
core.info(`Original results: ${originalPath}`);
core.info(`Retest results: ${retestPath || "(not provided)"}`);
let merged = false;
let specs;
if (retestPath) {
// Check if retest path has results
const retestSpecs = await loadSpecFiles(retestPath);
if (retestSpecs.length > 0) {
core.info(`Found ${retestSpecs.length} retest spec files`);
// Merge results
core.info("Merging results...");
const mergeResult = await mergeResults(originalPath, retestPath);
specs = mergeResult.specs;
merged = true;
core.info(`Retested specs: ${mergeResult.retestFiles.join(", ")}`);
core.info(`Total merged specs: ${specs.length}`);
// Write merged results back to original directory
if (shouldWriteMerged) {
core.info("Writing merged results to original directory...");
const writeResult = await writeMergedResults(
originalPath,
retestPath,
);
core.info(`Updated files: ${writeResult.updatedFiles.length}`);
core.info(
`Removed duplicates: ${writeResult.removedFiles.length}`,
);
}
} else {
core.warning(
`No retest results found at ${retestPath}, using original only`,
);
specs = await loadSpecFiles(originalPath);
}
} else {
core.info("No retest path provided, using original results only");
specs = await loadSpecFiles(originalPath);
}
core.info(`Calculating results from ${specs.length} spec files...`);
// Handle case where no results found
if (specs.length === 0) {
core.setFailed("No Cypress test results found");
return;
}
// Calculate all outputs from final results
const calc = calculateResultsFromSpecs(specs);
// Log results
core.startGroup("Final Results");
core.info(`Passed: ${calc.passed}`);
core.info(`Failed: ${calc.failed}`);
core.info(`Pending: ${calc.pending}`);
core.info(`Total: ${calc.total}`);
core.info(`Pass Rate: ${calc.passRate}%`);
core.info(`Color: ${calc.color}`);
core.info(`Spec Files: ${calc.totalSpecs}`);
core.info(`Failed Specs Count: ${calc.failedSpecsCount}`);
core.info(`Commit Status Message: ${calc.commitStatusMessage}`);
core.info(`Failed Specs: ${calc.failedSpecs || "none"}`);
core.endGroup();
// Set all outputs
core.setOutput("merged", merged.toString());
core.setOutput("passed", calc.passed);
core.setOutput("failed", calc.failed);
core.setOutput("pending", calc.pending);
core.setOutput("total_specs", calc.totalSpecs);
core.setOutput("commit_status_message", calc.commitStatusMessage);
core.setOutput("failed_specs", calc.failedSpecs);
core.setOutput("failed_specs_count", calc.failedSpecsCount);
core.setOutput("failed_tests", calc.failedTests);
core.setOutput("total", calc.total);
core.setOutput("pass_rate", calc.passRate);
core.setOutput("color", calc.color);
}

View file

@ -0,0 +1,271 @@
import { calculateResultsFromSpecs } from "./merge";
import type { ParsedSpecFile, MochawesomeResult } from "./types";
/**
* Helper to create a mochawesome result for testing
*/
function createMochawesomeResult(
specFile: string,
tests: { title: string; state: "passed" | "failed" | "pending" }[],
): MochawesomeResult {
return {
stats: {
suites: 1,
tests: tests.length,
passes: tests.filter((t) => t.state === "passed").length,
pending: tests.filter((t) => t.state === "pending").length,
failures: tests.filter((t) => t.state === "failed").length,
start: new Date().toISOString(),
end: new Date().toISOString(),
duration: 1000,
testsRegistered: tests.length,
passPercent: 0,
pendingPercent: 0,
other: 0,
hasOther: false,
skipped: 0,
hasSkipped: false,
},
results: [
{
uuid: "uuid-1",
title: specFile,
fullFile: `/app/e2e-tests/cypress/tests/integration/${specFile}`,
file: `tests/integration/${specFile}`,
beforeHooks: [],
afterHooks: [],
tests: tests.map((t, i) => ({
title: t.title,
fullTitle: `${specFile} > ${t.title}`,
timedOut: null,
duration: 500,
state: t.state,
speed: "fast",
pass: t.state === "passed",
fail: t.state === "failed",
pending: t.state === "pending",
context: null,
code: "",
err: t.state === "failed" ? { message: "Test failed" } : {},
uuid: `test-uuid-${i}`,
parentUUID: "uuid-1",
isHook: false,
skipped: false,
})),
suites: [],
passes: tests
.filter((t) => t.state === "passed")
.map((_, i) => `test-uuid-${i}`),
failures: tests
.filter((t) => t.state === "failed")
.map((_, i) => `test-uuid-${i}`),
pending: tests
.filter((t) => t.state === "pending")
.map((_, i) => `test-uuid-${i}`),
skipped: [],
duration: 1000,
root: true,
rootEmpty: false,
_timeout: 60000,
},
],
};
}
function createParsedSpecFile(
specFile: string,
tests: { title: string; state: "passed" | "failed" | "pending" }[],
): ParsedSpecFile {
return {
filePath: `/path/to/${specFile}.json`,
specPath: `tests/integration/${specFile}`,
result: createMochawesomeResult(specFile, tests),
};
}
describe("calculateResultsFromSpecs", () => {
it("should calculate all outputs correctly for passing results", () => {
const specs: ParsedSpecFile[] = [
createParsedSpecFile("login.spec.ts", [
{
title: "should login with valid credentials",
state: "passed",
},
]),
createParsedSpecFile("messaging.spec.ts", [
{ title: "should send a message", state: "passed" },
]),
];
const calc = calculateResultsFromSpecs(specs);
expect(calc.passed).toBe(2);
expect(calc.failed).toBe(0);
expect(calc.pending).toBe(0);
expect(calc.total).toBe(2);
expect(calc.passRate).toBe("100.00");
expect(calc.color).toBe("#43A047"); // green
expect(calc.totalSpecs).toBe(2);
expect(calc.failedSpecs).toBe("");
expect(calc.failedSpecsCount).toBe(0);
expect(calc.commitStatusMessage).toBe("100% passed (2), 2 specs");
});
it("should calculate all outputs correctly for results with failures", () => {
const specs: ParsedSpecFile[] = [
createParsedSpecFile("login.spec.ts", [
{
title: "should login with valid credentials",
state: "passed",
},
]),
createParsedSpecFile("channels.spec.ts", [
{ title: "should create a channel", state: "failed" },
]),
];
const calc = calculateResultsFromSpecs(specs);
expect(calc.passed).toBe(1);
expect(calc.failed).toBe(1);
expect(calc.pending).toBe(0);
expect(calc.total).toBe(2);
expect(calc.passRate).toBe("50.00");
expect(calc.color).toBe("#F44336"); // red
expect(calc.totalSpecs).toBe(2);
expect(calc.failedSpecs).toBe("tests/integration/channels.spec.ts");
expect(calc.failedSpecsCount).toBe(1);
expect(calc.commitStatusMessage).toBe(
"50.0% passed (1/2), 1 failed, 2 specs",
);
expect(calc.failedTests).toContain("should create a channel");
});
it("should handle pending tests correctly", () => {
const specs: ParsedSpecFile[] = [
createParsedSpecFile("login.spec.ts", [
{ title: "should login", state: "passed" },
{ title: "should logout", state: "pending" },
]),
];
const calc = calculateResultsFromSpecs(specs);
expect(calc.passed).toBe(1);
expect(calc.failed).toBe(0);
expect(calc.pending).toBe(1);
expect(calc.total).toBe(1); // Total excludes pending
expect(calc.passRate).toBe("100.00");
});
it("should limit failed tests to 10 entries", () => {
const specs: ParsedSpecFile[] = [
createParsedSpecFile("big-test.spec.ts", [
{ title: "test 1", state: "failed" },
{ title: "test 2", state: "failed" },
{ title: "test 3", state: "failed" },
{ title: "test 4", state: "failed" },
{ title: "test 5", state: "failed" },
{ title: "test 6", state: "failed" },
{ title: "test 7", state: "failed" },
{ title: "test 8", state: "failed" },
{ title: "test 9", state: "failed" },
{ title: "test 10", state: "failed" },
{ title: "test 11", state: "failed" },
{ title: "test 12", state: "failed" },
]),
];
const calc = calculateResultsFromSpecs(specs);
expect(calc.failed).toBe(12);
expect(calc.failedTests).toContain("...and 2 more failed tests");
});
});
describe("merge simulation", () => {
it("should produce correct results when merging original with retest", () => {
// Simulate original: 2 passed, 1 failed
const originalSpecs: ParsedSpecFile[] = [
createParsedSpecFile("login.spec.ts", [
{ title: "should login", state: "passed" },
]),
createParsedSpecFile("messaging.spec.ts", [
{ title: "should send message", state: "passed" },
]),
createParsedSpecFile("channels.spec.ts", [
{ title: "should create channel", state: "failed" },
]),
];
// Verify original has failure
const originalCalc = calculateResultsFromSpecs(originalSpecs);
expect(originalCalc.passed).toBe(2);
expect(originalCalc.failed).toBe(1);
expect(originalCalc.passRate).toBe("66.67");
// Simulate retest: channels.spec.ts now passes
const retestSpec = createParsedSpecFile("channels.spec.ts", [
{ title: "should create channel", state: "passed" },
]);
// Simulate merge: replace original channels.spec.ts with retest
const specMap = new Map<string, ParsedSpecFile>();
for (const spec of originalSpecs) {
specMap.set(spec.specPath, spec);
}
specMap.set(retestSpec.specPath, retestSpec);
const mergedSpecs = Array.from(specMap.values());
// Calculate final results
const finalCalc = calculateResultsFromSpecs(mergedSpecs);
expect(finalCalc.passed).toBe(3);
expect(finalCalc.failed).toBe(0);
expect(finalCalc.pending).toBe(0);
expect(finalCalc.total).toBe(3);
expect(finalCalc.passRate).toBe("100.00");
expect(finalCalc.color).toBe("#43A047"); // green
expect(finalCalc.totalSpecs).toBe(3);
expect(finalCalc.failedSpecs).toBe("");
expect(finalCalc.failedSpecsCount).toBe(0);
expect(finalCalc.commitStatusMessage).toBe("100% passed (3), 3 specs");
});
it("should handle case where retest still fails", () => {
// Original: 1 passed, 1 failed
const originalSpecs: ParsedSpecFile[] = [
createParsedSpecFile("login.spec.ts", [
{ title: "should login", state: "passed" },
]),
createParsedSpecFile("channels.spec.ts", [
{ title: "should create channel", state: "failed" },
]),
];
// Retest: channels.spec.ts still fails
const retestSpec = createParsedSpecFile("channels.spec.ts", [
{ title: "should create channel", state: "failed" },
]);
// Merge
const specMap = new Map<string, ParsedSpecFile>();
for (const spec of originalSpecs) {
specMap.set(spec.specPath, spec);
}
specMap.set(retestSpec.specPath, retestSpec);
const mergedSpecs = Array.from(specMap.values());
const finalCalc = calculateResultsFromSpecs(mergedSpecs);
expect(finalCalc.passed).toBe(1);
expect(finalCalc.failed).toBe(1);
expect(finalCalc.passRate).toBe("50.00");
expect(finalCalc.color).toBe("#F44336"); // red
expect(finalCalc.failedSpecs).toBe(
"tests/integration/channels.spec.ts",
);
expect(finalCalc.failedSpecsCount).toBe(1);
});
});

View file

@ -0,0 +1,323 @@
import * as fs from "fs/promises";
import * as path from "path";
import type {
MochawesomeResult,
ParsedSpecFile,
CalculationResult,
FailedTest,
TestItem,
SuiteItem,
ResultItem,
} from "./types";
/**
* Find all JSON files in a directory recursively
*/
async function findJsonFiles(dir: string): Promise<string[]> {
const files: string[] = [];
try {
const entries = await fs.readdir(dir, { withFileTypes: true });
for (const entry of entries) {
const fullPath = path.join(dir, entry.name);
if (entry.isDirectory()) {
const subFiles = await findJsonFiles(fullPath);
files.push(...subFiles);
} else if (entry.isFile() && entry.name.endsWith(".json")) {
files.push(fullPath);
}
}
} catch {
// Directory doesn't exist or not accessible
}
return files;
}
/**
* Parse a mochawesome JSON file
*/
async function parseSpecFile(filePath: string): Promise<ParsedSpecFile | null> {
try {
const content = await fs.readFile(filePath, "utf8");
const result: MochawesomeResult = JSON.parse(content);
// Extract spec path from results[0].file
const specPath = result.results?.[0]?.file;
if (!specPath) {
return null;
}
return {
filePath,
specPath,
result,
};
} catch {
return null;
}
}
/**
* Extract all tests from a result recursively
*/
function getAllTests(result: MochawesomeResult): TestItem[] {
const tests: TestItem[] = [];
function extractFromSuite(suite: SuiteItem | ResultItem) {
tests.push(...(suite.tests || []));
for (const nestedSuite of suite.suites || []) {
extractFromSuite(nestedSuite);
}
}
for (const resultItem of result.results || []) {
extractFromSuite(resultItem);
}
return tests;
}
/**
* Get color based on pass rate
*/
function getColor(passRate: number): string {
if (passRate === 100) {
return "#43A047"; // green
} else if (passRate >= 99) {
return "#FFEB3B"; // yellow
} else if (passRate >= 98) {
return "#FF9800"; // orange
} else {
return "#F44336"; // red
}
}
/**
* Calculate results from parsed spec files
*/
export function calculateResultsFromSpecs(
specs: ParsedSpecFile[],
): CalculationResult {
let passed = 0;
let failed = 0;
let pending = 0;
const failedSpecsSet = new Set<string>();
const failedTestsList: FailedTest[] = [];
for (const spec of specs) {
const tests = getAllTests(spec.result);
for (const test of tests) {
if (test.state === "passed") {
passed++;
} else if (test.state === "failed") {
failed++;
failedSpecsSet.add(spec.specPath);
failedTestsList.push({
title: test.title,
file: spec.specPath,
});
} else if (test.state === "pending") {
pending++;
}
}
}
const totalSpecs = specs.length;
const failedSpecs = Array.from(failedSpecsSet).join(",");
const failedSpecsCount = failedSpecsSet.size;
// Build failed tests markdown table (limit to 10)
let failedTests = "";
const uniqueFailedTests = failedTestsList.filter(
(test, index, self) =>
index ===
self.findIndex(
(t) => t.title === test.title && t.file === test.file,
),
);
if (uniqueFailedTests.length > 0) {
const limitedTests = uniqueFailedTests.slice(0, 10);
failedTests = limitedTests
.map((t) => {
const escapedTitle = t.title
.replace(/`/g, "\\`")
.replace(/\|/g, "\\|");
return `| ${escapedTitle} | ${t.file} |`;
})
.join("\n");
if (uniqueFailedTests.length > 10) {
const remaining = uniqueFailedTests.length - 10;
failedTests += `\n| _...and ${remaining} more failed tests_ | |`;
}
} else if (failed > 0) {
failedTests = "| Unable to parse failed tests | - |";
}
// Calculate totals and pass rate
// Pass rate = passed / (passed + failed), excluding pending
const total = passed + failed;
const passRate = total > 0 ? ((passed * 100) / total).toFixed(2) : "0.00";
const color = getColor(parseFloat(passRate));
// Build commit status message
const rate = total > 0 ? (passed * 100) / total : 0;
const rateStr = rate === 100 ? "100%" : `${rate.toFixed(1)}%`;
const specSuffix = totalSpecs > 0 ? `, ${totalSpecs} specs` : "";
const commitStatusMessage =
rate === 100
? `${rateStr} passed (${passed})${specSuffix}`
: `${rateStr} passed (${passed}/${total}), ${failed} failed${specSuffix}`;
return {
passed,
failed,
pending,
totalSpecs,
commitStatusMessage,
failedSpecs,
failedSpecsCount,
failedTests,
total,
passRate,
color,
};
}
/**
* Load all spec files from a mochawesome results directory
*/
export async function loadSpecFiles(
resultsPath: string,
): Promise<ParsedSpecFile[]> {
// Mochawesome results are at: results/mochawesome-report/json/tests/
const mochawesomeDir = path.join(
resultsPath,
"mochawesome-report",
"json",
"tests",
);
const jsonFiles = await findJsonFiles(mochawesomeDir);
const specs: ParsedSpecFile[] = [];
for (const file of jsonFiles) {
const parsed = await parseSpecFile(file);
if (parsed) {
specs.push(parsed);
}
}
return specs;
}
/**
* Merge original and retest results
* - For each spec in retest, replace the matching spec in original
* - Keep original specs that are not in retest
*/
export async function mergeResults(
originalPath: string,
retestPath: string,
): Promise<{
specs: ParsedSpecFile[];
retestFiles: string[];
mergedCount: number;
}> {
const originalSpecs = await loadSpecFiles(originalPath);
const retestSpecs = await loadSpecFiles(retestPath);
// Build a map of original specs by spec path
const specMap = new Map<string, ParsedSpecFile>();
for (const spec of originalSpecs) {
specMap.set(spec.specPath, spec);
}
// Replace with retest results
const retestFiles: string[] = [];
for (const retestSpec of retestSpecs) {
specMap.set(retestSpec.specPath, retestSpec);
retestFiles.push(retestSpec.specPath);
}
return {
specs: Array.from(specMap.values()),
retestFiles,
mergedCount: retestSpecs.length,
};
}
/**
* Write merged results back to the original directory
* This updates the original JSON files with retest results
*/
export async function writeMergedResults(
originalPath: string,
retestPath: string,
): Promise<{ updatedFiles: string[]; removedFiles: string[] }> {
const mochawesomeDir = path.join(
originalPath,
"mochawesome-report",
"json",
"tests",
);
const retestMochawesomeDir = path.join(
retestPath,
"mochawesome-report",
"json",
"tests",
);
const originalJsonFiles = await findJsonFiles(mochawesomeDir);
const retestJsonFiles = await findJsonFiles(retestMochawesomeDir);
const updatedFiles: string[] = [];
const removedFiles: string[] = [];
// For each retest file, find and replace the original
for (const retestFile of retestJsonFiles) {
const retestSpec = await parseSpecFile(retestFile);
if (!retestSpec) continue;
const specPath = retestSpec.specPath;
// Find all original files with matching spec path
// Prefer nested path (under integration/), remove flat duplicates
let nestedFile: string | null = null;
const flatFiles: string[] = [];
for (const origFile of originalJsonFiles) {
const origSpec = await parseSpecFile(origFile);
if (origSpec && origSpec.specPath === specPath) {
if (origFile.includes("/integration/")) {
nestedFile = origFile;
} else {
flatFiles.push(origFile);
}
}
}
// Update the nested file (proper location) or first flat file if no nested
const retestContent = await fs.readFile(retestFile, "utf8");
if (nestedFile) {
await fs.writeFile(nestedFile, retestContent);
updatedFiles.push(nestedFile);
// Remove flat duplicates
for (const flatFile of flatFiles) {
await fs.unlink(flatFile);
removedFiles.push(flatFile);
}
} else if (flatFiles.length > 0) {
await fs.writeFile(flatFiles[0], retestContent);
updatedFiles.push(flatFiles[0]);
}
}
return { updatedFiles, removedFiles };
}

View file

@ -0,0 +1,138 @@
/**
* Mochawesome result structure for a single spec file
*/
export interface MochawesomeResult {
stats: MochawesomeStats;
results: ResultItem[];
}
export interface MochawesomeStats {
suites: number;
tests: number;
passes: number;
pending: number;
failures: number;
start: string;
end: string;
duration: number;
testsRegistered: number;
passPercent: number;
pendingPercent: number;
other: number;
hasOther: boolean;
skipped: number;
hasSkipped: boolean;
}
export interface ResultItem {
uuid: string;
title: string;
fullFile: string;
file: string;
beforeHooks: Hook[];
afterHooks: Hook[];
tests: TestItem[];
suites: SuiteItem[];
passes: string[];
failures: string[];
pending: string[];
skipped: string[];
duration: number;
root: boolean;
rootEmpty: boolean;
_timeout: number;
}
export interface SuiteItem {
uuid: string;
title: string;
fullFile: string;
file: string;
beforeHooks: Hook[];
afterHooks: Hook[];
tests: TestItem[];
suites: SuiteItem[];
passes: string[];
failures: string[];
pending: string[];
skipped: string[];
duration: number;
root: boolean;
rootEmpty: boolean;
_timeout: number;
}
export interface TestItem {
title: string;
fullTitle: string;
timedOut: boolean | null;
duration: number;
state: "passed" | "failed" | "pending";
speed: string | null;
pass: boolean;
fail: boolean;
pending: boolean;
context: string | null;
code: string;
err: TestError;
uuid: string;
parentUUID: string;
isHook: boolean;
skipped: boolean;
}
export interface TestError {
message?: string;
estack?: string;
diff?: string | null;
}
export interface Hook {
title: string;
fullTitle: string;
timedOut: boolean | null;
duration: number;
state: string | null;
speed: string | null;
pass: boolean;
fail: boolean;
pending: boolean;
context: string | null;
code: string;
err: TestError;
uuid: string;
parentUUID: string;
isHook: boolean;
skipped: boolean;
}
/**
* Parsed spec file with its path and results
*/
export interface ParsedSpecFile {
filePath: string;
specPath: string;
result: MochawesomeResult;
}
/**
* Calculation result outputs
*/
export interface CalculationResult {
passed: number;
failed: number;
pending: number;
totalSpecs: number;
commitStatusMessage: string;
failedSpecs: string;
failedSpecsCount: number;
failedTests: string;
total: number;
passRate: string;
color: string;
}
export interface FailedTest {
title: string;
file: string;
}

View file

@ -0,0 +1,17 @@
{
"compilerOptions": {
"target": "ES2022",
"module": "CommonJS",
"moduleResolution": "Node",
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true,
"outDir": "./dist",
"rootDir": "./src",
"declaration": true,
"isolatedModules": true
},
"include": ["src/**/*"],
"exclude": ["node_modules", "dist", "**/*.test.ts"]
}

View file

@ -0,0 +1 @@
{"root":["./src/index.ts","./src/main.ts","./src/merge.ts","./src/types.ts"],"version":"5.9.3"}

View file

@ -0,0 +1,13 @@
import { defineConfig } from "tsup";
export default defineConfig({
entry: ["src/index.ts"],
format: ["cjs"],
target: "node24",
clean: true,
minify: false,
sourcemap: false,
splitting: false,
bundle: true,
noExternal: [/.*/],
});

View file

@ -0,0 +1,2 @@
node_modules/
.env

View file

@ -0,0 +1,51 @@
name: Calculate Playwright Results
description: Calculate Playwright test results with optional merge of retest results
author: Mattermost
inputs:
original-results-path:
description: Path to the original Playwright results.json file
required: true
retest-results-path:
description: Path to the retest Playwright results.json file (optional - if not provided, only calculates from original)
required: false
output-path:
description: Path to write the merged results.json file (defaults to original-results-path)
required: false
outputs:
# Merge outputs
merged:
description: Whether merge was performed (true/false)
# Calculation outputs (same as calculate-playwright-test-results)
passed:
description: Number of passed tests (not including flaky)
failed:
description: Number of failed tests
flaky:
description: Number of flaky tests (failed initially but passed on retry)
skipped:
description: Number of skipped tests
total_specs:
description: Total number of spec files
commit_status_message:
description: Message for commit status (e.g., "X failed, Y passed (Z spec files)")
failed_specs:
description: Comma-separated list of failed spec files (for retest)
failed_specs_count:
description: Number of failed spec files
failed_tests:
description: Markdown table rows of failed tests (for GitHub summary)
total:
description: Total number of tests (passed + flaky + failed)
pass_rate:
description: Pass rate percentage (e.g., "100.00")
passing:
description: Number of passing tests (passed + flaky)
color:
description: Color for webhook based on pass rate (green=100%, yellow=99%+, orange=98%+, red=<98%)
runs:
using: node24
main: dist/index.js

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,6 @@
module.exports = {
preset: "ts-jest",
testEnvironment: "node",
testMatch: ["**/*.test.ts"],
moduleFileExtensions: ["ts", "js"],
};

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,27 @@
{
"name": "calculate-playwright-results",
"private": true,
"version": "0.1.0",
"main": "dist/index.js",
"scripts": {
"build": "tsup",
"prettier": "npx prettier --write \"src/**/*.ts\"",
"local-action": "local-action . src/main.ts .env",
"test": "jest --verbose",
"test:watch": "jest --watch --verbose",
"test:silent": "jest --silent",
"tsc": "tsc -b"
},
"dependencies": {
"@actions/core": "3.0.0"
},
"devDependencies": {
"@github/local-action": "7.0.0",
"@types/jest": "30.0.0",
"@types/node": "25.2.0",
"jest": "30.2.0",
"ts-jest": "29.4.6",
"tsup": "8.5.1",
"typescript": "5.9.3"
}
}

View file

@ -0,0 +1,3 @@
import { run } from "./main";
run();

View file

@ -0,0 +1,121 @@
import * as core from "@actions/core";
import * as fs from "fs/promises";
import type { PlaywrightResults } from "./types";
import { mergeResults, calculateResults } from "./merge";
export async function run(): Promise<void> {
const originalPath = core.getInput("original-results-path", {
required: true,
});
const retestPath = core.getInput("retest-results-path"); // Optional
const outputPath = core.getInput("output-path") || originalPath;
core.info(`Original results: ${originalPath}`);
core.info(`Retest results: ${retestPath || "(not provided)"}`);
core.info(`Output path: ${outputPath}`);
// Check if original file exists
const originalExists = await fs
.access(originalPath)
.then(() => true)
.catch(() => false);
if (!originalExists) {
core.setFailed(`Original results not found at ${originalPath}`);
return;
}
// Read original file
core.info("Reading original results...");
const originalContent = await fs.readFile(originalPath, "utf8");
const original: PlaywrightResults = JSON.parse(originalContent);
core.info(
`Original: ${original.suites.length} suites, stats: ${JSON.stringify(original.stats)}`,
);
// Check if retest path is provided and exists
let finalResults: PlaywrightResults;
let merged = false;
if (retestPath) {
const retestExists = await fs
.access(retestPath)
.then(() => true)
.catch(() => false);
if (retestExists) {
// Read retest file and merge
core.info("Reading retest results...");
const retestContent = await fs.readFile(retestPath, "utf8");
const retest: PlaywrightResults = JSON.parse(retestContent);
core.info(
`Retest: ${retest.suites.length} suites, stats: ${JSON.stringify(retest.stats)}`,
);
// Merge results
core.info("Merging results at suite level...");
const mergeResult = mergeResults(original, retest);
finalResults = mergeResult.merged;
merged = true;
core.info(`Retested specs: ${mergeResult.retestFiles.join(", ")}`);
core.info(
`Kept ${original.suites.length - mergeResult.retestFiles.length} original suites`,
);
core.info(`Added ${retest.suites.length} retest suites`);
core.info(`Total merged suites: ${mergeResult.totalSuites}`);
// Write merged results
core.info(`Writing merged results to ${outputPath}...`);
await fs.writeFile(
outputPath,
JSON.stringify(finalResults, null, 2),
);
} else {
core.warning(
`Retest results not found at ${retestPath}, using original only`,
);
finalResults = original;
}
} else {
core.info("No retest path provided, using original results only");
finalResults = original;
}
// Calculate all outputs from final results
const calc = calculateResults(finalResults);
// Log results
core.startGroup("Final Results");
core.info(`Passed: ${calc.passed}`);
core.info(`Failed: ${calc.failed}`);
core.info(`Flaky: ${calc.flaky}`);
core.info(`Skipped: ${calc.skipped}`);
core.info(`Passing (passed + flaky): ${calc.passing}`);
core.info(`Total: ${calc.total}`);
core.info(`Pass Rate: ${calc.passRate}%`);
core.info(`Color: ${calc.color}`);
core.info(`Spec Files: ${calc.totalSpecs}`);
core.info(`Failed Specs Count: ${calc.failedSpecsCount}`);
core.info(`Commit Status Message: ${calc.commitStatusMessage}`);
core.info(`Failed Specs: ${calc.failedSpecs || "none"}`);
core.endGroup();
// Set all outputs
core.setOutput("merged", merged.toString());
core.setOutput("passed", calc.passed);
core.setOutput("failed", calc.failed);
core.setOutput("flaky", calc.flaky);
core.setOutput("skipped", calc.skipped);
core.setOutput("total_specs", calc.totalSpecs);
core.setOutput("commit_status_message", calc.commitStatusMessage);
core.setOutput("failed_specs", calc.failedSpecs);
core.setOutput("failed_specs_count", calc.failedSpecsCount);
core.setOutput("failed_tests", calc.failedTests);
core.setOutput("total", calc.total);
core.setOutput("pass_rate", calc.passRate);
core.setOutput("passing", calc.passing);
core.setOutput("color", calc.color);
}

View file

@ -0,0 +1,509 @@
import { mergeResults, computeStats, calculateResults } from "./merge";
import type { PlaywrightResults, Suite } from "./types";
describe("mergeResults", () => {
const createSuite = (file: string, tests: { status: string }[]): Suite => ({
title: file,
file,
column: 0,
line: 0,
specs: [
{
title: "test spec",
ok: true,
tags: [],
tests: tests.map((t) => ({
timeout: 60000,
annotations: [],
expectedStatus: "passed",
projectId: "chrome",
projectName: "chrome",
results: [
{
workerIndex: 0,
parallelIndex: 0,
status: t.status,
duration: 1000,
errors: [],
stdout: [],
stderr: [],
retry: 0,
startTime: new Date().toISOString(),
annotations: [],
},
],
})),
},
],
});
it("should keep original suites not in retest", () => {
const original: PlaywrightResults = {
config: {},
suites: [
createSuite("spec1.ts", [{ status: "passed" }]),
createSuite("spec2.ts", [{ status: "failed" }]),
createSuite("spec3.ts", [{ status: "passed" }]),
],
stats: {
startTime: new Date().toISOString(),
duration: 10000,
expected: 2,
unexpected: 1,
skipped: 0,
flaky: 0,
},
};
const retest: PlaywrightResults = {
config: {},
suites: [createSuite("spec2.ts", [{ status: "passed" }])],
stats: {
startTime: new Date().toISOString(),
duration: 5000,
expected: 1,
unexpected: 0,
skipped: 0,
flaky: 0,
},
};
const result = mergeResults(original, retest);
expect(result.totalSuites).toBe(3);
expect(result.retestFiles).toEqual(["spec2.ts"]);
expect(result.merged.suites.map((s) => s.file)).toEqual([
"spec1.ts",
"spec3.ts",
"spec2.ts",
]);
});
it("should compute correct stats from merged suites", () => {
const original: PlaywrightResults = {
config: {},
suites: [
createSuite("spec1.ts", [{ status: "passed" }]),
createSuite("spec2.ts", [{ status: "failed" }]),
],
stats: {
startTime: new Date().toISOString(),
duration: 10000,
expected: 1,
unexpected: 1,
skipped: 0,
flaky: 0,
},
};
const retest: PlaywrightResults = {
config: {},
suites: [createSuite("spec2.ts", [{ status: "passed" }])],
stats: {
startTime: new Date().toISOString(),
duration: 5000,
expected: 1,
unexpected: 0,
skipped: 0,
flaky: 0,
},
};
const result = mergeResults(original, retest);
expect(result.stats.expected).toBe(2);
expect(result.stats.unexpected).toBe(0);
expect(result.stats.duration).toBe(15000);
});
});
describe("computeStats", () => {
it("should count flaky tests correctly", () => {
const suites: Suite[] = [
{
title: "spec1.ts",
file: "spec1.ts",
column: 0,
line: 0,
specs: [
{
title: "flaky test",
ok: true,
tags: [],
tests: [
{
timeout: 60000,
annotations: [],
expectedStatus: "passed",
projectId: "chrome",
projectName: "chrome",
results: [
{
workerIndex: 0,
parallelIndex: 0,
status: "failed",
duration: 1000,
errors: [],
stdout: [],
stderr: [],
retry: 0,
startTime: new Date().toISOString(),
annotations: [],
},
{
workerIndex: 0,
parallelIndex: 0,
status: "passed",
duration: 1000,
errors: [],
stdout: [],
stderr: [],
retry: 1,
startTime: new Date().toISOString(),
annotations: [],
},
],
},
],
},
],
},
];
const stats = computeStats(suites);
expect(stats.expected).toBe(0);
expect(stats.flaky).toBe(1);
expect(stats.unexpected).toBe(0);
});
});
describe("calculateResults", () => {
const createSuiteWithSpec = (
file: string,
specTitle: string,
testResults: { status: string; retry: number }[],
): Suite => ({
title: file,
file,
column: 0,
line: 0,
specs: [
{
title: specTitle,
ok: testResults[testResults.length - 1].status === "passed",
tags: [],
tests: [
{
timeout: 60000,
annotations: [],
expectedStatus: "passed",
projectId: "chrome",
projectName: "chrome",
results: testResults.map((r) => ({
workerIndex: 0,
parallelIndex: 0,
status: r.status,
duration: 1000,
errors:
r.status === "failed"
? [{ message: "error" }]
: [],
stdout: [],
stderr: [],
retry: r.retry,
startTime: new Date().toISOString(),
annotations: [],
})),
location: {
file,
line: 10,
column: 5,
},
},
],
},
],
});
it("should calculate all outputs correctly for passing results", () => {
const results: PlaywrightResults = {
config: {},
suites: [
createSuiteWithSpec("login.spec.ts", "should login", [
{ status: "passed", retry: 0 },
]),
createSuiteWithSpec(
"messaging.spec.ts",
"should send message",
[{ status: "passed", retry: 0 }],
),
],
stats: {
startTime: new Date().toISOString(),
duration: 5000,
expected: 2,
unexpected: 0,
skipped: 0,
flaky: 0,
},
};
const calc = calculateResults(results);
expect(calc.passed).toBe(2);
expect(calc.failed).toBe(0);
expect(calc.flaky).toBe(0);
expect(calc.skipped).toBe(0);
expect(calc.total).toBe(2);
expect(calc.passing).toBe(2);
expect(calc.passRate).toBe("100.00");
expect(calc.color).toBe("#43A047"); // green
expect(calc.totalSpecs).toBe(2);
expect(calc.failedSpecs).toBe("");
expect(calc.failedSpecsCount).toBe(0);
expect(calc.commitStatusMessage).toBe("100% passed (2), 2 specs");
});
it("should calculate all outputs correctly for results with failures", () => {
const results: PlaywrightResults = {
config: {},
suites: [
createSuiteWithSpec("login.spec.ts", "should login", [
{ status: "passed", retry: 0 },
]),
createSuiteWithSpec(
"channels.spec.ts",
"should create channel",
[
{ status: "failed", retry: 0 },
{ status: "failed", retry: 1 },
{ status: "failed", retry: 2 },
],
),
],
stats: {
startTime: new Date().toISOString(),
duration: 10000,
expected: 1,
unexpected: 1,
skipped: 0,
flaky: 0,
},
};
const calc = calculateResults(results);
expect(calc.passed).toBe(1);
expect(calc.failed).toBe(1);
expect(calc.flaky).toBe(0);
expect(calc.total).toBe(2);
expect(calc.passing).toBe(1);
expect(calc.passRate).toBe("50.00");
expect(calc.color).toBe("#F44336"); // red
expect(calc.totalSpecs).toBe(2);
expect(calc.failedSpecs).toBe("channels.spec.ts");
expect(calc.failedSpecsCount).toBe(1);
expect(calc.commitStatusMessage).toBe(
"50.0% passed (1/2), 1 failed, 2 specs",
);
expect(calc.failedTests).toContain("should create channel");
});
});
describe("full integration: original with failure, retest passes", () => {
const createSuiteWithSpec = (
file: string,
specTitle: string,
testResults: { status: string; retry: number }[],
): Suite => ({
title: file,
file,
column: 0,
line: 0,
specs: [
{
title: specTitle,
ok: testResults[testResults.length - 1].status === "passed",
tags: [],
tests: [
{
timeout: 60000,
annotations: [],
expectedStatus: "passed",
projectId: "chrome",
projectName: "chrome",
results: testResults.map((r) => ({
workerIndex: 0,
parallelIndex: 0,
status: r.status,
duration: 1000,
errors:
r.status === "failed"
? [{ message: "error" }]
: [],
stdout: [],
stderr: [],
retry: r.retry,
startTime: new Date().toISOString(),
annotations: [],
})),
location: {
file,
line: 10,
column: 5,
},
},
],
},
],
});
it("should merge and calculate correctly when failed test passes on retest", () => {
// Original: 2 passed, 1 failed (channels.spec.ts)
const original: PlaywrightResults = {
config: {},
suites: [
createSuiteWithSpec("login.spec.ts", "should login", [
{ status: "passed", retry: 0 },
]),
createSuiteWithSpec(
"messaging.spec.ts",
"should send message",
[{ status: "passed", retry: 0 }],
),
createSuiteWithSpec(
"channels.spec.ts",
"should create channel",
[
{ status: "failed", retry: 0 },
{ status: "failed", retry: 1 },
{ status: "failed", retry: 2 },
],
),
],
stats: {
startTime: new Date().toISOString(),
duration: 18000,
expected: 2,
unexpected: 1,
skipped: 0,
flaky: 0,
},
};
// Retest: channels.spec.ts now passes
const retest: PlaywrightResults = {
config: {},
suites: [
createSuiteWithSpec(
"channels.spec.ts",
"should create channel",
[{ status: "passed", retry: 0 }],
),
],
stats: {
startTime: new Date().toISOString(),
duration: 3000,
expected: 1,
unexpected: 0,
skipped: 0,
flaky: 0,
},
};
// Step 1: Verify original has failure
const originalCalc = calculateResults(original);
expect(originalCalc.passed).toBe(2);
expect(originalCalc.failed).toBe(1);
expect(originalCalc.passRate).toBe("66.67");
// Step 2: Merge results
const mergeResult = mergeResults(original, retest);
// Step 3: Verify merge structure
expect(mergeResult.totalSuites).toBe(3);
expect(mergeResult.retestFiles).toEqual(["channels.spec.ts"]);
expect(mergeResult.merged.suites.map((s) => s.file)).toEqual([
"login.spec.ts",
"messaging.spec.ts",
"channels.spec.ts",
]);
// Step 4: Calculate final results
const finalCalc = calculateResults(mergeResult.merged);
// Step 5: Verify all outputs
expect(finalCalc.passed).toBe(3);
expect(finalCalc.failed).toBe(0);
expect(finalCalc.flaky).toBe(0);
expect(finalCalc.skipped).toBe(0);
expect(finalCalc.total).toBe(3);
expect(finalCalc.passing).toBe(3);
expect(finalCalc.passRate).toBe("100.00");
expect(finalCalc.color).toBe("#43A047"); // green
expect(finalCalc.totalSpecs).toBe(3);
expect(finalCalc.failedSpecs).toBe("");
expect(finalCalc.failedSpecsCount).toBe(0);
expect(finalCalc.commitStatusMessage).toBe("100% passed (3), 3 specs");
expect(finalCalc.failedTests).toBe("");
});
it("should handle case where retest still fails", () => {
// Original: 2 passed, 1 failed
const original: PlaywrightResults = {
config: {},
suites: [
createSuiteWithSpec("login.spec.ts", "should login", [
{ status: "passed", retry: 0 },
]),
createSuiteWithSpec(
"channels.spec.ts",
"should create channel",
[{ status: "failed", retry: 0 }],
),
],
stats: {
startTime: new Date().toISOString(),
duration: 10000,
expected: 1,
unexpected: 1,
skipped: 0,
flaky: 0,
},
};
// Retest: channels.spec.ts still fails
const retest: PlaywrightResults = {
config: {},
suites: [
createSuiteWithSpec(
"channels.spec.ts",
"should create channel",
[
{ status: "failed", retry: 0 },
{ status: "failed", retry: 1 },
],
),
],
stats: {
startTime: new Date().toISOString(),
duration: 5000,
expected: 0,
unexpected: 1,
skipped: 0,
flaky: 0,
},
};
const mergeResult = mergeResults(original, retest);
const finalCalc = calculateResults(mergeResult.merged);
expect(finalCalc.passed).toBe(1);
expect(finalCalc.failed).toBe(1);
expect(finalCalc.passRate).toBe("50.00");
expect(finalCalc.color).toBe("#F44336"); // red
expect(finalCalc.failedSpecs).toBe("channels.spec.ts");
expect(finalCalc.failedSpecsCount).toBe(1);
});
});

View file

@ -0,0 +1,291 @@
import type {
PlaywrightResults,
Suite,
Test,
Stats,
MergeResult,
CalculationResult,
FailedTest,
} from "./types";
interface TestInfo {
title: string;
file: string;
finalStatus: string;
hadFailure: boolean;
}
/**
* Extract all tests from suites recursively with their info
*/
function getAllTestsWithInfo(suites: Suite[]): TestInfo[] {
const tests: TestInfo[] = [];
function extractFromSuite(suite: Suite) {
for (const spec of suite.specs || []) {
for (const test of spec.tests || []) {
if (!test.results || test.results.length === 0) {
continue;
}
const finalResult = test.results[test.results.length - 1];
const hadFailure = test.results.some(
(r) => r.status === "failed" || r.status === "timedOut",
);
tests.push({
title: spec.title || test.projectName,
file: test.location?.file || suite.file,
finalStatus: finalResult.status,
hadFailure,
});
}
}
for (const nestedSuite of suite.suites || []) {
extractFromSuite(nestedSuite);
}
}
for (const suite of suites) {
extractFromSuite(suite);
}
return tests;
}
/**
* Extract all tests from suites recursively
*/
function getAllTests(suites: Suite[]): Test[] {
const tests: Test[] = [];
function extractFromSuite(suite: Suite) {
for (const spec of suite.specs || []) {
tests.push(...spec.tests);
}
for (const nestedSuite of suite.suites || []) {
extractFromSuite(nestedSuite);
}
}
for (const suite of suites) {
extractFromSuite(suite);
}
return tests;
}
/**
* Compute stats from suites
*/
export function computeStats(
suites: Suite[],
originalStats?: Stats,
retestStats?: Stats,
): Stats {
const tests = getAllTests(suites);
let expected = 0;
let unexpected = 0;
let skipped = 0;
let flaky = 0;
for (const test of tests) {
if (!test.results || test.results.length === 0) {
continue;
}
const finalResult = test.results[test.results.length - 1];
const finalStatus = finalResult.status;
// Check if any result was a failure
const hadFailure = test.results.some(
(r) => r.status === "failed" || r.status === "timedOut",
);
if (finalStatus === "skipped") {
skipped++;
} else if (finalStatus === "failed" || finalStatus === "timedOut") {
unexpected++;
} else if (finalStatus === "passed") {
if (hadFailure) {
flaky++;
} else {
expected++;
}
}
}
// Compute duration as sum of both runs
const duration =
(originalStats?.duration || 0) + (retestStats?.duration || 0);
return {
startTime: originalStats?.startTime || new Date().toISOString(),
duration,
expected,
unexpected,
skipped,
flaky,
};
}
/**
* Get color based on pass rate
*/
function getColor(passRate: number): string {
if (passRate === 100) {
return "#43A047"; // green
} else if (passRate >= 99) {
return "#FFEB3B"; // yellow
} else if (passRate >= 98) {
return "#FF9800"; // orange
} else {
return "#F44336"; // red
}
}
/**
* Calculate all outputs from results
*/
export function calculateResults(
results: PlaywrightResults,
): CalculationResult {
const stats = results.stats || {
expected: 0,
unexpected: 0,
skipped: 0,
flaky: 0,
startTime: new Date().toISOString(),
duration: 0,
};
const passed = stats.expected;
const failed = stats.unexpected;
const flaky = stats.flaky;
const skipped = stats.skipped;
// Count unique spec files
const specFiles = new Set<string>();
for (const suite of results.suites) {
specFiles.add(suite.file);
}
const totalSpecs = specFiles.size;
// Get all tests with info for failed tests extraction
const testsInfo = getAllTestsWithInfo(results.suites);
// Extract failed specs
const failedSpecsSet = new Set<string>();
const failedTestsList: FailedTest[] = [];
for (const test of testsInfo) {
if (test.finalStatus === "failed" || test.finalStatus === "timedOut") {
failedSpecsSet.add(test.file);
failedTestsList.push({
title: test.title,
file: test.file,
});
}
}
const failedSpecs = Array.from(failedSpecsSet).join(",");
const failedSpecsCount = failedSpecsSet.size;
// Build failed tests markdown table (limit to 10)
let failedTests = "";
const uniqueFailedTests = failedTestsList.filter(
(test, index, self) =>
index ===
self.findIndex(
(t) => t.title === test.title && t.file === test.file,
),
);
if (uniqueFailedTests.length > 0) {
const limitedTests = uniqueFailedTests.slice(0, 10);
failedTests = limitedTests
.map((t) => {
const escapedTitle = t.title
.replace(/`/g, "\\`")
.replace(/\|/g, "\\|");
return `| ${escapedTitle} | ${t.file} |`;
})
.join("\n");
if (uniqueFailedTests.length > 10) {
const remaining = uniqueFailedTests.length - 10;
failedTests += `\n| _...and ${remaining} more failed tests_ | |`;
}
} else if (failed > 0) {
failedTests = "| Unable to parse failed tests | - |";
}
// Calculate totals and pass rate
const passing = passed + flaky;
const total = passing + failed;
const passRate = total > 0 ? ((passing * 100) / total).toFixed(2) : "0.00";
const color = getColor(parseFloat(passRate));
// Build commit status message
const rate = total > 0 ? (passing * 100) / total : 0;
const rateStr = rate === 100 ? "100%" : `${rate.toFixed(1)}%`;
const specSuffix = totalSpecs > 0 ? `, ${totalSpecs} specs` : "";
const commitStatusMessage =
rate === 100
? `${rateStr} passed (${passing})${specSuffix}`
: `${rateStr} passed (${passing}/${total}), ${failed} failed${specSuffix}`;
return {
passed,
failed,
flaky,
skipped,
totalSpecs,
commitStatusMessage,
failedSpecs,
failedSpecsCount,
failedTests,
total,
passRate,
passing,
color,
};
}
/**
* Merge original and retest results at suite level
* - Keep original suites that are NOT in retest
* - Add all retest suites (replacing matching originals)
*/
export function mergeResults(
original: PlaywrightResults,
retest: PlaywrightResults,
): MergeResult {
// Get list of retested spec files
const retestFiles = retest.suites.map((s) => s.file);
// Filter original suites - keep only those NOT in retest
const keptOriginalSuites = original.suites.filter(
(suite) => !retestFiles.includes(suite.file),
);
// Merge: kept original suites + all retest suites
const mergedSuites = [...keptOriginalSuites, ...retest.suites];
// Compute stats from merged suites
const stats = computeStats(mergedSuites, original.stats, retest.stats);
const merged: PlaywrightResults = {
config: original.config,
suites: mergedSuites,
stats,
};
return {
merged,
stats,
totalSuites: mergedSuites.length,
retestFiles,
};
}

View file

@ -0,0 +1,88 @@
export interface PlaywrightResults {
config: Record<string, unknown>;
suites: Suite[];
stats?: Stats;
}
export interface Suite {
title: string;
file: string;
column: number;
line: number;
specs: Spec[];
suites?: Suite[];
}
export interface Spec {
title: string;
ok: boolean;
tags: string[];
tests: Test[];
}
export interface Test {
timeout: number;
annotations: unknown[];
expectedStatus: string;
projectId: string;
projectName: string;
results: TestResult[];
location?: TestLocation;
}
export interface TestResult {
workerIndex: number;
parallelIndex: number;
status: string;
duration: number;
errors: unknown[];
stdout: unknown[];
stderr: unknown[];
retry: number;
startTime: string;
annotations: unknown[];
attachments?: unknown[];
}
export interface TestLocation {
file: string;
line: number;
column: number;
}
export interface Stats {
startTime: string;
duration: number;
expected: number;
unexpected: number;
skipped: number;
flaky: number;
}
export interface MergeResult {
merged: PlaywrightResults;
stats: Stats;
totalSuites: number;
retestFiles: string[];
}
export interface CalculationResult {
passed: number;
failed: number;
flaky: number;
skipped: number;
totalSpecs: number;
commitStatusMessage: string;
failedSpecs: string;
failedSpecsCount: number;
failedTests: string;
total: number;
passRate: string;
passing: number;
color: string;
}
export interface FailedTest {
title: string;
file: string;
}

View file

@ -0,0 +1,17 @@
{
"compilerOptions": {
"target": "ES2022",
"module": "CommonJS",
"moduleResolution": "Node",
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true,
"outDir": "dist",
"rootDir": "./src",
"declaration": true,
"isolatedModules": true
},
"include": ["src/**/*"],
"exclude": ["node_modules", "dist", "**/*.test.ts"]
}

View file

@ -0,0 +1 @@
{"root":["./src/index.ts","./src/main.ts","./src/merge.ts","./src/types.ts"],"version":"5.9.3"}

View file

@ -0,0 +1,12 @@
import { defineConfig } from "tsup";
export default defineConfig({
entry: ["src/index.ts"],
format: ["cjs"],
outDir: "dist",
clean: true,
noExternal: [/.*/], // Bundle all dependencies
minify: false,
sourcemap: false,
target: "node24",
});

View file

@ -0,0 +1,91 @@
---
name: Check E2E Test Only
description: Check if PR contains only E2E test changes and determine the appropriate docker image tag
inputs:
base_sha:
description: Base commit SHA (PR base)
required: false
head_sha:
description: Head commit SHA (PR head)
required: false
pr_number:
description: PR number (used to fetch SHAs via API if base_sha/head_sha not provided)
required: false
outputs:
e2e_test_only:
description: Whether the PR contains only E2E test changes (true/false)
value: ${{ steps.check.outputs.e2e_test_only }}
image_tag:
description: Docker image tag to use (master for E2E-only, short SHA for mixed)
value: ${{ steps.check.outputs.image_tag }}
runs:
using: composite
steps:
- name: ci/check-e2e-test-only
id: check
shell: bash
env:
GH_TOKEN: ${{ github.token }}
INPUT_BASE_SHA: ${{ inputs.base_sha }}
INPUT_HEAD_SHA: ${{ inputs.head_sha }}
INPUT_PR_NUMBER: ${{ inputs.pr_number }}
run: |
# Resolve SHAs from PR number if not provided
if [ -z "$INPUT_BASE_SHA" ] || [ -z "$INPUT_HEAD_SHA" ]; then
if [ -z "$INPUT_PR_NUMBER" ]; then
echo "::error::Either base_sha/head_sha or pr_number must be provided"
exit 1
fi
echo "Resolving SHAs from PR #${INPUT_PR_NUMBER}"
PR_DATA=$(gh api "repos/${{ github.repository }}/pulls/${INPUT_PR_NUMBER}")
INPUT_BASE_SHA=$(echo "$PR_DATA" | jq -r '.base.sha')
INPUT_HEAD_SHA=$(echo "$PR_DATA" | jq -r '.head.sha')
if [ -z "$INPUT_BASE_SHA" ] || [ "$INPUT_BASE_SHA" = "null" ] || \
[ -z "$INPUT_HEAD_SHA" ] || [ "$INPUT_HEAD_SHA" = "null" ]; then
echo "::error::Could not resolve SHAs for PR #${INPUT_PR_NUMBER}"
exit 1
fi
fi
SHORT_SHA="${INPUT_HEAD_SHA::7}"
# Get changed files - try git first, fall back to API
CHANGED_FILES=$(git diff --name-only "$INPUT_BASE_SHA"..."$INPUT_HEAD_SHA" 2>/dev/null || \
gh api "repos/${{ github.repository }}/pulls/${INPUT_PR_NUMBER}/files" --jq '.[].filename' 2>/dev/null || echo "")
if [ -z "$CHANGED_FILES" ]; then
echo "::warning::Could not determine changed files, assuming not E2E-only"
echo "e2e_test_only=false" >> $GITHUB_OUTPUT
echo "image_tag=${SHORT_SHA}" >> $GITHUB_OUTPUT
exit 0
fi
echo "Changed files:"
echo "$CHANGED_FILES"
# Check if all files are E2E-related
E2E_TEST_ONLY="true"
while IFS= read -r file; do
[ -z "$file" ] && continue
if [[ ! "$file" =~ ^e2e-tests/ ]] && \
[[ ! "$file" =~ ^\.github/workflows/e2e- ]]; then
echo "Non-E2E file found: $file"
E2E_TEST_ONLY="false"
break
fi
done <<< "$CHANGED_FILES"
echo "E2E test only: ${E2E_TEST_ONLY}"
# Set outputs
echo "e2e_test_only=${E2E_TEST_ONLY}" >> $GITHUB_OUTPUT
if [ "$E2E_TEST_ONLY" = "true" ]; then
echo "image_tag=master" >> $GITHUB_OUTPUT
else
echo "image_tag=${SHORT_SHA}" >> $GITHUB_OUTPUT
fi

View file

@ -15,13 +15,28 @@ runs:
path: |
webapp/node_modules
webapp/channels/node_modules
webapp/platform/client/node_modules
webapp/platform/components/node_modules
webapp/platform/types/node_modules
key: node-modules-${{ runner.os }}-${{ hashFiles('webapp/package-lock.json') }}
- name: ci/cache-platform-builds
uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
id: cache-platform-builds
with:
path: |
webapp/platform/types/lib
webapp/platform/client/lib
webapp/platform/components/dist
key: node-modules-${{ runner.os }}-${{ hashFiles('webapp/package-lock.json') }}
key: platform-builds-${{ runner.os }}-${{ hashFiles('webapp/platform/types/src/**', 'webapp/platform/client/src/**', 'webapp/platform/components/src/**') }}
- name: ci/get-node-modules
if: steps.cache-node-modules.outputs.cache-hit != 'true'
shell: bash
working-directory: webapp
run: |
make node_modules
- name: ci/build-platform-packages
if: steps.cache-platform-builds.outputs.cache-hit != 'true'
shell: bash
working-directory: webapp
run: |
npm run build --workspace=platform/types --workspace=platform/client --workspace=platform/components

352
.github/e2e-tests-workflows.md vendored Normal file
View file

@ -0,0 +1,352 @@
# E2E Test Pipelines
Three automated E2E test pipelines cover different stages of the development lifecycle.
## Pipelines
| Pipeline | Trigger | Editions Tested | Image Source |
|----------|---------|----------------|--------------|
| **PR** (`e2e-tests-ci.yml`) | Argo Events on `Enterprise CI/docker-image` status | enterprise | `mattermostdevelopment/**` |
| **Merge to master/release** (`e2e-tests-on-merge.yml`) | Platform delivery after docker build (`delivery-platform/.github/workflows/mattermost-platform-delivery.yaml`) | enterprise, fips | `mattermostdevelopment/**` |
| **Release cut** (`e2e-tests-on-release.yml`) | Platform release after docker build (`delivery-platform/.github/workflows/release-mattermost-platform.yml`) | enterprise, fips, team (future) | `mattermost/**` |
All pipelines follow the **smoke-then-full** pattern: smoke tests run first, full tests only run if smoke passes.
## Workflow Files
```
.github/workflows/
├── e2e-tests-ci.yml # PR orchestrator
├── e2e-tests-on-merge.yml # Merge orchestrator (master/release branches)
├── e2e-tests-on-release.yml # Release cut orchestrator
├── e2e-tests-cypress.yml # Shared wrapper: cypress smoke -> full
├── e2e-tests-playwright.yml # Shared wrapper: playwright smoke -> full
├── e2e-tests-cypress-template.yml # Template: actual cypress test execution
└── e2e-tests-playwright-template.yml # Template: actual playwright test execution
```
### Call hierarchy
```
e2e-tests-ci.yml ─────────────────┐
e2e-tests-on-merge.yml ───────────┤──► e2e-tests-cypress.yml ──► e2e-tests-cypress-template.yml
e2e-tests-on-release.yml ─────────┘ e2e-tests-playwright.yml ──► e2e-tests-playwright-template.yml
```
---
## Pipeline 1: PR (`e2e-tests-ci.yml`)
Runs E2E tests for every PR commit after the enterprise docker image is built. Fails if the commit is not associated with an open PR.
**Trigger chain:**
```
PR commit ─► Enterprise CI builds docker image
─► Argo Events detects "Enterprise CI/docker-image" status
─► dispatches e2e-tests-ci.yml
```
For PRs from forks, `body.branches` may be empty so the workflow falls back to `master` for workflow files (trusted code), while `commit_sha` still points to the fork's commit.
**Jobs:** 2 (cypress + playwright), each does smoke -> full
**Commit statuses (4 total):**
| Context | Description (pending) | Description (result) |
|---------|----------------------|---------------------|
| `e2e-test/cypress-smoke\|enterprise` | `tests running, image_tag:abc1234` | `100% passed (1313), 440 specs, image_tag:abc1234` |
| `e2e-test/cypress-full\|enterprise` | `tests running, image_tag:abc1234` | `100% passed (1313), 440 specs, image_tag:abc1234` |
| `e2e-test/playwright-smoke\|enterprise` | `tests running, image_tag:abc1234` | `100% passed (200), 50 specs, image_tag:abc1234` |
| `e2e-test/playwright-full\|enterprise` | `tests running, image_tag:abc1234` | `99.5% passed (199/200), 1 failed, 50 specs, image_tag:abc1234` |
**Manual trigger (CLI):**
```bash
gh workflow run e2e-tests-ci.yml \
--repo mattermost/mattermost \
--field pr_number="35171"
```
**Manual trigger (GitHub UI):**
1. Go to **Actions** > **E2E Tests (smoke-then-full)**
2. Click **Run workflow**
3. Fill in `pr_number` (e.g., `35171`)
4. Click **Run workflow**
### On-demand testing
For on-demand E2E testing, the existing triggers still work:
- **Comment triggers**: `/e2e-test`, `/e2e-test fips`, or with `MM_ENV` parameters
- **Label trigger**: `E2E/Run`
These are separate from the automated workflow and can be used for custom test configurations or re-runs.
---
## Pipeline 2: Merge (`e2e-tests-on-merge.yml`)
Runs E2E tests after every push/merge to `master` or `release-*` branches.
**Trigger chain:**
```
Push to master/release-*
─► Argo Events (mattermost-platform-package sensor)
─► delivery-platform/.github/workflows/mattermost-platform-delivery.yaml
─► builds docker images (enterprise + fips)
─► trigger-e2e-tests job dispatches e2e-tests-on-merge.yml
```
**Jobs:** 4 (cypress + playwright) x (enterprise + fips), smoke skipped, full tests only
**Commit statuses (4 total):**
| Context | Description example |
|---------|-------------------|
| `e2e-test/cypress-full\|enterprise` | `100% passed (1313), 440 specs, image_tag:abc1234_def5678` |
| `e2e-test/cypress-full\|fips` | `100% passed (1313), 440 specs, image_tag:abc1234_def5678` |
| `e2e-test/playwright-full\|enterprise` | `100% passed (200), 50 specs, image_tag:abc1234_def5678` |
| `e2e-test/playwright-full\|fips` | `100% passed (200), 50 specs, image_tag:abc1234_def5678` |
**Manual trigger (CLI):**
```bash
# For master
gh workflow run e2e-tests-on-merge.yml \
--repo mattermost/mattermost \
--field branch="master" \
--field commit_sha="<full_commit_sha>" \
--field server_image_tag="<image_tag>"
# For release branch
gh workflow run e2e-tests-on-merge.yml \
--repo mattermost/mattermost \
--field branch="release-11.4" \
--field commit_sha="<full_commit_sha>" \
--field server_image_tag="<image_tag>"
```
**Manual trigger (GitHub UI):**
1. Go to **Actions** > **E2E Tests (master/release - merge)**
2. Click **Run workflow**
3. Fill in:
- `branch`: `master` or `release-11.4`
- `commit_sha`: full 40-char SHA
- `server_image_tag`: e.g., `abc1234_def5678`
4. Click **Run workflow**
---
## Pipeline 3: Release Cut (`e2e-tests-on-release.yml`)
Runs E2E tests after a release cut against the published release images.
**Trigger chain:**
```
Manual release cut
─► delivery-platform/.github/workflows/release-mattermost-platform.yml
─► builds and publishes release docker images
─► trigger-e2e-tests job dispatches e2e-tests-on-release.yml
```
**Jobs:** 4 (cypress + playwright) x (enterprise + fips), smoke skipped, full tests only. Team edition planned for future.
**Commit statuses (4 total, 6 when team is enabled):**
Descriptions include alias tags showing which rolling docker tags point to the same image.
RC example (11.4.0-rc3):
| Context | Description example |
|---------|-------------------|
| `e2e-test/cypress-full\|enterprise` | `100% passed (1313), 440 specs, image_tag:11.4.0-rc3 (release-11.4, release-11)` |
| `e2e-test/cypress-full\|fips` | `100% passed (1313), 440 specs, image_tag:11.4.0-rc3 (release-11.4, release-11)` |
| `e2e-test/cypress-full\|team` (future) | `100% passed (1313), 440 specs, image_tag:11.4.0-rc3 (release-11.4, release-11)` |
Stable example (11.4.0) — includes `MAJOR.MINOR` alias:
| Context | Description example |
|---------|-------------------|
| `e2e-test/cypress-full\|enterprise` | `100% passed (1313), 440 specs, image_tag:11.4.0 (release-11.4, release-11, 11.4)` |
| `e2e-test/cypress-full\|fips` | `100% passed (1313), 440 specs, image_tag:11.4.0 (release-11.4, release-11, 11.4)` |
| `e2e-test/cypress-full\|team` (future) | `100% passed (1313), 440 specs, image_tag:11.4.0 (release-11.4, release-11, 11.4)` |
**Manual trigger (CLI):**
```bash
gh workflow run e2e-tests-on-release.yml \
--repo mattermost/mattermost \
--field branch="release-11.4" \
--field commit_sha="<full_commit_sha>" \
--field server_image_tag="11.4.0" \
--field server_image_aliases="release-11.4, release-11, 11.4"
```
**Manual trigger (GitHub UI):**
1. Go to **Actions** > **E2E Tests (release cut)**
2. Click **Run workflow**
3. Fill in:
- `branch`: `release-11.4`
- `commit_sha`: full 40-char SHA
- `server_image_tag`: e.g., `11.4.0` or `11.4.0-rc3`
- `server_image_aliases`: e.g., `release-11.4, release-11, 11.4` (optional)
4. Click **Run workflow**
---
## Commit Status Format
**Context name:** `e2e-test/<phase>|<edition>`
Where `<phase>` is `cypress-smoke`, `cypress-full`, `playwright-smoke`, or `playwright-full`.
**Description format:**
- All passed: `100% passed (<count>), <specs> specs, image_tag:<tag>[ (<aliases>)]`
- With failures: `<rate>% passed (<passed>/<total>), <failed> failed, <specs> specs, image_tag:<tag>[ (<aliases>)]`
- Pending: `tests running, image_tag:<tag>[ (<aliases>)]`
- Pass rate: `100%` if all pass, otherwise one decimal (e.g., `99.5%`)
- Aliases only present for release cuts
### Failure behavior
1. **Smoke test fails**: Full tests are skipped, only smoke commit status shows failure
2. **Full test fails**: Full commit status shows failure with pass rate
3. **Both pass**: Both smoke and full commit statuses show success
4. **No PR found** (PR pipeline only): Workflow fails immediately
---
## Smoke-then-Full Pattern
Each wrapper (Cypress/Playwright) follows this flow:
```
generate-build-variables (branch, build_id, server_image)
─► smoke tests (1 worker, minimal docker services)
─► if smoke passes ─► full tests (20 workers cypress / 1 worker playwright, all docker services)
─► report (aggregate results, update commit status)
```
### Test filtering
| Framework | Smoke | Full |
|-----------|-------|------|
| **Cypress** | `--stage=@prod --group=@smoke` | `--stage="@prod" --excludeGroup="@te_only,@cloud_only,@high_availability" --sortFirst=... --sortLast=...` |
| **Playwright** | `--grep @smoke` | `--grep-invert "@smoke\|@visual"` |
### Worker configuration
| Framework | Smoke Workers | Full Workers |
|-----------|---------------|--------------|
| **Cypress** | 1 | 20 |
| **Playwright** | 1 | 1 (uses internal parallelism via `PW_WORKERS`) |
### Docker services
| Test Phase | Docker Services |
|------------|-----------------|
| Smoke | `postgres inbucket` |
| Full | `postgres inbucket minio openldap elasticsearch keycloak` |
---
## Tagging Smoke Tests
### Cypress
Add `@smoke` to the Group comment at the top of spec files:
```javascript
// Stage: @prod
// Group: @channels @messaging @smoke
```
### Playwright
Add `@smoke` to the test tag option:
```typescript
test('critical login flow', {tag: ['@smoke', '@login']}, async ({pw}) => {
// ...
});
```
---
## Shared Wrapper Inputs
The wrappers (`e2e-tests-cypress.yml`, `e2e-tests-playwright.yml`) accept these inputs:
| Input | Default | Description |
|-------|---------|-------------|
| `server_edition` | `enterprise` | Edition: `enterprise`, `fips`, or `team` |
| `server_image_repo` | `mattermostdevelopment` | Docker namespace: `mattermostdevelopment` or `mattermost` |
| `server_image_tag` | derived from `commit_sha` | Docker image tag |
| `server_image_aliases` | _(empty)_ | Alias tags shown in commit status description |
| `ref_branch` | _(empty)_ | Source branch name for webhook messages (e.g., `master` or `release-11.4`) |
The automation dashboard branch name is derived from context:
- PR: `server-pr-<pr_number>` (e.g., `server-pr-35205`)
- Master merge: `server-master-<image_tag>` (e.g., `server-master-abc1234_def5678`)
- Release merge: `server-release-<version>-<image_tag>` (e.g., `server-release-11.4-abc1234_def5678`)
- Fallback: `server-commit-<image_tag>`
The test type suffix (`-smoke` or `-full`) is appended by the template.
The server image is derived as:
```
{server_image_repo}/{edition_image_name}:{server_image_tag}
```
Where `edition_image_name` maps to:
- `enterprise` -> `mattermost-enterprise-edition`
- `fips` -> `mattermost-enterprise-fips-edition`
- `team` -> `mattermost-team-edition`
---
## Webhook Message Format
After full tests complete, a webhook notification is sent to the configured `REPORT_WEBHOOK_URL`. The results line uses the same `commit_status_message` as the GitHub commit status. The source line varies by pipeline using `report_type` and `ref_branch`.
**Report types:** `PR`, `MASTER`, `RELEASE`, `RELEASE_CUT`
### PR
```
:open-pull-request: mattermost-pr-35205
:docker: mattermostdevelopment/mattermost-enterprise-edition:abc1234
100% passed (1313), 440 specs | full report
```
### Merge to master
```
:git_merge: abc1234 on master
:docker: mattermostdevelopment/mattermost-enterprise-edition:abc1234_def5678
100% passed (1313), 440 specs | full report
```
### Merge to release branch
```
:git_merge: abc1234 on release-11.4
:docker: mattermostdevelopment/mattermost-enterprise-edition:abc1234_def5678
100% passed (1313), 440 specs | full report
```
### Release cut
```
:github_round: abc1234 on release-11.4
:docker: mattermost/mattermost-enterprise-edition:11.4.0-rc3
100% passed (1313), 440 specs | full report
```
The commit short SHA links to the commit on GitHub. The PR number links to the pull request.
---
## Related Files
- `e2e-tests/cypress/` - Cypress test suite
- `e2e-tests/playwright/` - Playwright test suite
- `e2e-tests/.ci/` - CI configuration and environment files
- `e2e-tests/Makefile` - Makefile with targets for running tests, generating cycles, and reporting

View file

@ -20,7 +20,7 @@ jobs:
- name: Checkout code
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
- uses: actions/setup-node@395ad3262231945c25e8478fd5baf05154b1d79f # v6.1.0
with:
node-version-file: .nvmrc
cache: "npm"

View file

@ -33,8 +33,8 @@ jobs:
- name: buildenv/docker-login
uses: docker/login-action@74a5d142397b4f367a81961eba4e8cd7edddf772 # v3.4.0
with:
username: ${{ secrets.DOCKERHUB_DEV_USERNAME }}
password: ${{ secrets.DOCKERHUB_DEV_TOKEN }}
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: buildenv/build
uses: docker/build-push-action@1dc73863535b631f98b2378be8619f83b136f4a0 # v6.17.0
@ -44,16 +44,16 @@ jobs:
load: true
push: false
pull: false
tags: mattermostdevelopment/mattermost-build-server:test
tags: mattermost/mattermost-build-server:test
- name: buildenv/test
run: |
docker run --rm mattermostdevelopment/mattermost-build-server:test /bin/sh -c "go version && node --version"
docker run --rm mattermost/mattermost-build-server:test /bin/sh -c "go version && node --version"
- name: buildenv/calculate-golang-version
id: go
run: |
GO_VERSION=$(docker run --rm mattermostdevelopment/mattermost-build-server:test go version | awk '{print $3}' | sed 's/go//')
GO_VERSION=$(docker run --rm mattermost/mattermost-build-server:test go version | awk '{print $3}' | sed 's/go//')
echo "GO_VERSION=${GO_VERSION}" >> "${GITHUB_OUTPUT}"
- name: buildenv/push
@ -65,7 +65,7 @@ jobs:
load: false
push: true
pull: true
tags: mattermostdevelopment/mattermost-build-server:${{ steps.go.outputs.GO_VERSION }}
tags: mattermost/mattermost-build-server:${{ steps.go.outputs.GO_VERSION }}
build-image-fips:
runs-on: ubuntu-22.04
@ -79,8 +79,8 @@ jobs:
- name: buildenv/docker-login
uses: docker/login-action@74a5d142397b4f367a81961eba4e8cd7edddf772 # v3.4.0
with:
username: ${{ secrets.DOCKERHUB_DEV_USERNAME }}
password: ${{ secrets.DOCKERHUB_DEV_TOKEN }}
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: buildenv/build
uses: docker/build-push-action@1dc73863535b631f98b2378be8619f83b136f4a0 # v6.17.0
@ -90,16 +90,16 @@ jobs:
load: true
push: false
pull: false
tags: mattermostdevelopment/mattermost-build-server-fips:test
tags: mattermost/mattermost-build-server-fips:test
- name: buildenv/test
run: |
docker run --rm --entrypoint bash mattermostdevelopment/mattermost-build-server-fips:test -c "go version && node --version"
docker run --rm --entrypoint bash mattermost/mattermost-build-server-fips:test -c "go version && node --version"
- name: buildenv/calculate-golang-version
id: go
run: |
GO_VERSION=$(docker run --rm --entrypoint bash mattermostdevelopment/mattermost-build-server-fips:test -c "go version" | awk '{print $3}' | sed 's/go//')
GO_VERSION=$(docker run --rm --entrypoint bash mattermost/mattermost-build-server-fips:test -c "go version" | awk '{print $3}' | sed 's/go//')
echo "GO_VERSION=${GO_VERSION}" >> "${GITHUB_OUTPUT}"
- name: buildenv/push
@ -111,4 +111,4 @@ jobs:
load: false
push: true
pull: true
tags: mattermostdevelopment/mattermost-build-server-fips:${{ steps.go.outputs.GO_VERSION }}
tags: mattermost/mattermost-build-server-fips:${{ steps.go.outputs.GO_VERSION }}

View file

@ -263,7 +263,6 @@ jobs:
status_check_context: "${{ needs.generate-test-variables.outputs.status_check_context }}"
workers_number: "${{ needs.generate-test-variables.outputs.workers_number }}"
testcase_failure_fatal: "${{ needs.generate-test-variables.outputs.TESTCASE_FAILURE_FATAL == 'true' }}"
run_preflight_checks: false
enable_reporting: true
SERVER: "${{ needs.generate-test-variables.outputs.SERVER }}"
SERVER_IMAGE: "${{ needs.generate-test-variables.outputs.SERVER_IMAGE }}"
@ -300,7 +299,6 @@ jobs:
status_check_context: "${{ needs.generate-test-variables.outputs.status_check_context }}-playwright"
workers_number: "1"
testcase_failure_fatal: "${{ needs.generate-test-variables.outputs.TESTCASE_FAILURE_FATAL == 'true' }}"
run_preflight_checks: false
enable_reporting: true
SERVER: "${{ needs.generate-test-variables.outputs.SERVER }}"
SERVER_IMAGE: "${{ needs.generate-test-variables.outputs.SERVER_IMAGE }}"

69
.github/workflows/e2e-tests-check.yml vendored Normal file
View file

@ -0,0 +1,69 @@
---
name: E2E Tests Check
on:
pull_request:
paths:
- "e2e-tests/**"
- "webapp/platform/client/**"
- "webapp/platform/types/**"
- ".github/workflows/e2e-*.yml"
jobs:
check:
runs-on: ubuntu-24.04
steps:
- name: ci/checkout-repo
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
fetch-depth: 0
- name: ci/setup-node
uses: actions/setup-node@395ad3262231945c25e8478fd5baf05154b1d79f # v6.1.0
with:
node-version-file: ".nvmrc"
cache: npm
cache-dependency-path: |
e2e-tests/cypress/package-lock.json
e2e-tests/playwright/package-lock.json
# Cypress check
- name: ci/cypress/npm-install
working-directory: e2e-tests/cypress
run: npm ci
- name: ci/cypress/npm-check
working-directory: e2e-tests/cypress
run: npm run check
# Playwright check
- name: ci/get-webapp-node-modules
working-directory: webapp
run: make node_modules
- name: ci/playwright/npm-install
working-directory: e2e-tests/playwright
run: npm ci
- name: ci/playwright/npm-check
working-directory: e2e-tests/playwright
run: npm run check
# Shell check
- name: ci/shell-check
working-directory: e2e-tests
run: make check-shell
# E2E-only check and trigger
- name: ci/check-e2e-test-only
id: check
uses: ./.github/actions/check-e2e-test-only
with:
base_sha: ${{ github.event.pull_request.base.sha }}
head_sha: ${{ github.event.pull_request.head.sha }}
- name: ci/trigger-e2e-with-master-image
if: steps.check.outputs.e2e_test_only == 'true'
env:
GH_TOKEN: ${{ github.token }}
PR_NUMBER: ${{ github.event.pull_request.number }}
IMAGE_TAG: ${{ steps.check.outputs.image_tag }}
run: |
echo "Triggering E2E tests for PR #${PR_NUMBER} with mattermostdevelopment/mattermost-enterprise-edition:${IMAGE_TAG}"
gh workflow run e2e-tests-ci.yml --field pr_number="${PR_NUMBER}"

View file

@ -20,12 +20,6 @@ on:
type: boolean
required: false
default: true
# NB: the following toggles will skip individual steps, rather than the whole jobs,
# to let the dependent jobs run even if these are false
run_preflight_checks:
type: boolean
required: false
default: true
enable_reporting:
type: boolean
required: false
@ -107,7 +101,7 @@ jobs:
update-initial-status:
runs-on: ubuntu-24.04
steps:
- uses: mattermost/actions/delivery/update-commit-status@main
- uses: mattermost/actions/delivery/update-commit-status@f324ac89b05cc3511cb06e60642ac2fb829f0a63
env:
GITHUB_TOKEN: ${{ github.token }}
with:
@ -117,92 +111,6 @@ jobs:
description: E2E tests for mattermost server app
status: pending
cypress-check:
runs-on: ubuntu-24.04
needs:
- update-initial-status
defaults:
run:
working-directory: e2e-tests/cypress
steps:
- name: ci/checkout-repo
if: "${{ inputs.run_preflight_checks }}"
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
ref: ${{ inputs.commit_sha }}
fetch-depth: 0
- name: ci/setup-node
if: "${{ inputs.run_preflight_checks }}"
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
id: setup_node
with:
node-version-file: ".nvmrc"
cache: npm
cache-dependency-path: "e2e-tests/cypress/package-lock.json"
- name: ci/cypress/npm-install
if: "${{ inputs.run_preflight_checks }}"
run: |
npm ci
- name: ci/cypress/npm-check
if: "${{ inputs.run_preflight_checks }}"
run: |
npm run check
playwright-check:
runs-on: ubuntu-24.04
needs:
- update-initial-status
defaults:
run:
working-directory: e2e-tests/playwright
steps:
- name: ci/checkout-repo
if: "${{ inputs.run_preflight_checks }}"
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
ref: ${{ inputs.commit_sha }}
fetch-depth: 0
- name: ci/setup-node
if: "${{ inputs.run_preflight_checks }}"
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
id: setup_node
with:
node-version-file: ".nvmrc"
cache: npm
cache-dependency-path: "e2e-tests/playwright/package-lock.json"
- name: ci/get-webapp-node-modules
if: "${{ inputs.run_preflight_checks }}"
working-directory: webapp
# requires build of client and types
run: |
make node_modules
- name: ci/playwright/npm-install
if: "${{ inputs.run_preflight_checks }}"
run: |
npm ci
- name: ci/playwright/npm-check
if: "${{ inputs.run_preflight_checks }}"
run: |
npm run check
shell-check:
runs-on: ubuntu-24.04
needs:
- update-initial-status
defaults:
run:
working-directory: e2e-tests
steps:
- name: ci/checkout-repo
if: "${{ inputs.run_preflight_checks }}"
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
ref: ${{ inputs.commit_sha }}
fetch-depth: 0
- name: ci/shell-check
if: "${{ inputs.run_preflight_checks }}"
run: make check-shell
generate-build-variables:
runs-on: ubuntu-24.04
needs:
@ -246,7 +154,7 @@ jobs:
ref: ${{ inputs.commit_sha }}
fetch-depth: 0
- name: ci/setup-node
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
uses: actions/setup-node@395ad3262231945c25e8478fd5baf05154b1d79f # v6.1.0
id: setup_node
with:
node-version-file: ".nvmrc"
@ -290,9 +198,6 @@ jobs:
runs-on: "${{ matrix.os }}"
timeout-minutes: 120
needs:
- cypress-check
- playwright-check
- shell-check
- generate-build-variables
- generate-test-cycle
defaults:
@ -333,7 +238,7 @@ jobs:
ln -sfn /usr/local/opt/docker-compose/bin/docker-compose ~/.docker/cli-plugins/docker-compose
sudo ln -sf $HOME/.colima/default/docker.sock /var/run/docker.sock
- name: ci/setup-node
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
uses: actions/setup-node@395ad3262231945c25e8478fd5baf05154b1d79f # v6.1.0
id: setup_node
with:
node-version-file: ".nvmrc"
@ -364,7 +269,9 @@ jobs:
echo "RollingRelease: smoketest completed. Starting full E2E tests."
fi
make
make cloud-teardown
- name: ci/cloud-teardown
if: always()
run: make cloud-teardown
- name: ci/e2e-test-store-results
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
if: always()
@ -412,7 +319,7 @@ jobs:
e2e-tests/${{ inputs.TEST }}/results/
- name: ci/setup-node
if: "${{ inputs.enable_reporting }}"
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
uses: actions/setup-node@395ad3262231945c25e8478fd5baf05154b1d79f # v6.1.0
id: setup_node
with:
node-version-file: ".nvmrc"
@ -427,12 +334,14 @@ jobs:
SERVER_IMAGE: "${{ inputs.SERVER_IMAGE }}"
AUTOMATION_DASHBOARD_URL: "${{ secrets.AUTOMATION_DASHBOARD_URL }}"
WEBHOOK_URL: "${{ secrets.REPORT_WEBHOOK_URL }}"
PR_NUMBER: "${{ inputs.PR_NUMBER }}"
BRANCH: "${{ inputs.BRANCH }}"
BUILD_ID: "${{ inputs.BUILD_ID }}"
MM_ENV: "${{ inputs.MM_ENV }}"
TM4J_API_KEY: "${{ secrets.REPORT_TM4J_API_KEY }}"
TEST_CYCLE_LINK_PREFIX: "${{ secrets.REPORT_TM4J_TEST_CYCLE_LINK_PREFIX }}"
run: |
echo "DEBUG: TYPE=${TYPE}, PR_NUMBER=${PR_NUMBER:-<not set>}"
make report
# The results dir may have been modified as part of the reporting: re-upload
- name: ci/upload-report-global
@ -469,12 +378,6 @@ jobs:
echo "📤 Uploading to s3://${AWS_S3_BUCKET}/${S3_PATH}/"
if [[ -d "$LOCAL_LOGS_PATH" ]]; then
aws s3 sync "$LOCAL_LOGS_PATH" "s3://${AWS_S3_BUCKET}/${S3_PATH}/logs/" \
--acl public-read \
--cache-control "no-cache"
fi
if [[ -d "$LOCAL_RESULTS_PATH" ]]; then
aws s3 sync "$LOCAL_RESULTS_PATH" "s3://${AWS_S3_BUCKET}/${S3_PATH}/results/" \
--acl public-read \
@ -534,7 +437,7 @@ jobs:
- test
- report
steps:
- uses: mattermost/actions/delivery/update-commit-status@main
- uses: mattermost/actions/delivery/update-commit-status@f324ac89b05cc3511cb06e60642ac2fb829f0a63
env:
GITHUB_TOKEN: ${{ github.token }}
with:
@ -557,7 +460,7 @@ jobs:
- test
- report
steps:
- uses: mattermost/actions/delivery/update-commit-status@main
- uses: mattermost/actions/delivery/update-commit-status@f324ac89b05cc3511cb06e60642ac2fb829f0a63
env:
GITHUB_TOKEN: ${{ github.token }}
with:

View file

@ -1,49 +1,207 @@
---
name: E2E Smoketests
name: E2E Tests (smoke-then-full)
on:
# For PRs, this workflow gets triggered from the Argo Events platform.
# Check the following repo for details: https://github.com/mattermost/delivery-platform
# Argo Events Trigger (automated):
# - Triggered by: Enterprise CI/docker-image status check (success)
# - Payload: { ref: "<branch>", inputs: { commit_sha: "<sha>" } }
# - Uses commit-specific docker image
# - Checks for relevant file changes before running tests
#
# Manual Trigger:
# - Enter PR number only - commit SHA is resolved automatically from PR head
# - Uses commit-specific docker image
# - E2E tests always run (no file change check)
#
workflow_dispatch:
inputs:
commit_sha:
pr_number:
description: "PR number to test (for manual triggers)"
type: string
required: true
required: false
commit_sha:
description: "Commit SHA to test (for Argo Events)"
type: string
required: false
jobs:
generate-test-variables:
resolve-pr:
runs-on: ubuntu-24.04
outputs:
BRANCH: "${{ steps.generate.outputs.BRANCH }}"
BUILD_ID: "${{ steps.generate.outputs.BUILD_ID }}"
SERVER_IMAGE: "${{ steps.generate.outputs.SERVER_IMAGE }}"
PR_NUMBER: "${{ steps.resolve.outputs.PR_NUMBER }}"
COMMIT_SHA: "${{ steps.resolve.outputs.COMMIT_SHA }}"
SERVER_IMAGE_TAG: "${{ steps.e2e-check.outputs.image_tag }}"
steps:
- name: ci/smoke/generate-test-variables
id: generate
run: |
### Populate support variables
COMMIT_SHA=${{ inputs.commit_sha }}
SERVER_IMAGE_TAG="${COMMIT_SHA::7}"
- name: ci/checkout-repo
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
fetch-depth: 0
# BUILD_ID format: $pipelineID-$imageTag-$testType-$serverType-$serverEdition
# Reference on BUILD_ID parsing: https://github.com/saturninoabril/automation-dashboard/blob/175891781bf1072c162c58c6ec0abfc5bcb3520e/lib/common_utils.ts#L3-L23
BUILD_ID="${{ github.run_id }}_${{ github.run_attempt }}-${SERVER_IMAGE_TAG}-smoketest-onprem-ent"
echo "BRANCH=server-smoketest-${COMMIT_SHA::7}" >> $GITHUB_OUTPUT
echo "BUILD_ID=${BUILD_ID}" >> $GITHUB_OUTPUT
echo "SERVER_IMAGE=mattermostdevelopment/mattermost-enterprise-edition:${SERVER_IMAGE_TAG}" >> $GITHUB_OUTPUT
e2e-smoketest:
- name: ci/resolve-pr-and-commit
id: resolve
env:
GH_TOKEN: ${{ github.token }}
INPUT_PR_NUMBER: ${{ inputs.pr_number }}
INPUT_COMMIT_SHA: ${{ inputs.commit_sha }}
run: |
# Validate inputs
if [ -n "$INPUT_PR_NUMBER" ] && ! [[ "$INPUT_PR_NUMBER" =~ ^[0-9]+$ ]]; then
echo "::error::Invalid PR number format. Must be numeric."
exit 1
fi
if [ -n "$INPUT_COMMIT_SHA" ] && ! [[ "$INPUT_COMMIT_SHA" =~ ^[a-f0-9]{7,40}$ ]]; then
echo "::error::Invalid commit SHA format. Must be 7-40 hex characters."
exit 1
fi
# Manual trigger: PR number provided, resolve commit SHA from PR head
if [ -n "$INPUT_PR_NUMBER" ]; then
echo "Manual trigger: resolving commit SHA from PR #${INPUT_PR_NUMBER}"
PR_DATA=$(gh api "repos/${{ github.repository }}/pulls/${INPUT_PR_NUMBER}")
COMMIT_SHA=$(echo "$PR_DATA" | jq -r '.head.sha')
if [ -z "$COMMIT_SHA" ] || [ "$COMMIT_SHA" = "null" ]; then
echo "::error::Could not resolve commit SHA for PR #${INPUT_PR_NUMBER}"
exit 1
fi
echo "PR_NUMBER=${INPUT_PR_NUMBER}" >> $GITHUB_OUTPUT
echo "COMMIT_SHA=${COMMIT_SHA}" >> $GITHUB_OUTPUT
exit 0
fi
# Argo Events trigger: commit SHA provided, resolve PR number
if [ -n "$INPUT_COMMIT_SHA" ]; then
echo "Automated trigger: resolving PR number from commit ${INPUT_COMMIT_SHA}"
PR_NUMBER=$(gh api "repos/${{ github.repository }}/commits/${INPUT_COMMIT_SHA}/pulls" \
--jq '.[0].number // empty' 2>/dev/null || echo "")
if [ -n "$PR_NUMBER" ]; then
echo "Found PR #${PR_NUMBER} for commit ${INPUT_COMMIT_SHA}"
echo "PR_NUMBER=${PR_NUMBER}" >> $GITHUB_OUTPUT
echo "COMMIT_SHA=${INPUT_COMMIT_SHA}" >> $GITHUB_OUTPUT
else
echo "::error::No PR found for commit ${INPUT_COMMIT_SHA}. This workflow is for PRs only."
exit 1
fi
exit 0
fi
# Neither provided
echo "::error::Either pr_number or commit_sha must be provided"
exit 1
- name: ci/check-e2e-test-only
id: e2e-check
uses: ./.github/actions/check-e2e-test-only
with:
pr_number: ${{ steps.resolve.outputs.PR_NUMBER }}
check-changes:
needs: resolve-pr
runs-on: ubuntu-24.04
outputs:
should_run: "${{ steps.check.outputs.should_run }}"
steps:
- name: ci/checkout-repo
if: inputs.commit_sha != ''
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
ref: ${{ needs.resolve-pr.outputs.COMMIT_SHA }}
fetch-depth: 0
- name: ci/check-relevant-changes
id: check
env:
GH_TOKEN: ${{ github.token }}
PR_NUMBER: ${{ needs.resolve-pr.outputs.PR_NUMBER }}
COMMIT_SHA: ${{ needs.resolve-pr.outputs.COMMIT_SHA }}
INPUT_PR_NUMBER: ${{ inputs.pr_number }}
run: |
# Manual trigger (pr_number provided): always run E2E tests
if [ -n "$INPUT_PR_NUMBER" ]; then
echo "Manual trigger detected - skipping file change check"
echo "should_run=true" >> $GITHUB_OUTPUT
exit 0
fi
# Automated trigger (commit_sha provided): check for relevant file changes
echo "Automated trigger detected - checking for relevant file changes"
# Get the base branch of the PR
BASE_SHA=$(gh api "repos/${{ github.repository }}/pulls/${PR_NUMBER}" --jq '.base.sha')
# Get changed files between base and head
CHANGED_FILES=$(git diff --name-only "${BASE_SHA}...${COMMIT_SHA}")
echo "Changed files:"
echo "$CHANGED_FILES"
# Check for relevant changes
SHOULD_RUN="false"
# Check for server Go files
if echo "$CHANGED_FILES" | grep -qE '^server/.*\.go$'; then
echo "Found server Go file changes"
SHOULD_RUN="true"
fi
# Check for webapp ts/js/tsx/jsx files
if echo "$CHANGED_FILES" | grep -qE '^webapp/.*\.(ts|tsx|js|jsx)$'; then
echo "Found webapp TypeScript/JavaScript file changes"
SHOULD_RUN="true"
fi
# Check for e2e-tests ts/js/tsx/jsx files
if echo "$CHANGED_FILES" | grep -qE '^e2e-tests/.*\.(ts|tsx|js|jsx)$'; then
echo "Found e2e-tests TypeScript/JavaScript file changes"
SHOULD_RUN="true"
fi
# Check for E2E-related CI workflow files
if echo "$CHANGED_FILES" | grep -qE '^\.github/workflows/e2e-.*\.yml$'; then
echo "Found E2E CI workflow file changes"
SHOULD_RUN="true"
fi
echo "should_run=${SHOULD_RUN}" >> $GITHUB_OUTPUT
echo "Should run E2E tests: ${SHOULD_RUN}"
e2e-cypress:
needs:
- generate-test-variables
uses: ./.github/workflows/e2e-tests-ci-template.yml
- resolve-pr
- check-changes
if: needs.check-changes.outputs.should_run == 'true'
uses: ./.github/workflows/e2e-tests-cypress.yml
with:
commit_sha: "${{ inputs.commit_sha }}"
status_check_context: "E2E Tests/smoketests"
TEST: cypress
REPORT_TYPE: none
SERVER: onprem
BRANCH: "${{ needs.generate-test-variables.outputs.BRANCH }}"
BUILD_ID: "${{ needs.generate-test-variables.outputs.BUILD_ID }}"
SERVER_IMAGE: "${{ needs.generate-test-variables.outputs.SERVER_IMAGE }}"
commit_sha: "${{ needs.resolve-pr.outputs.COMMIT_SHA }}"
server: "onprem"
server_image_tag: "${{ needs.resolve-pr.outputs.SERVER_IMAGE_TAG }}"
enable_reporting: true
report_type: "PR"
pr_number: "${{ needs.resolve-pr.outputs.PR_NUMBER }}"
secrets:
MM_LICENSE: "${{ secrets.MM_E2E_TEST_LICENSE_ONPREM_ENT }}"
AUTOMATION_DASHBOARD_URL: "${{ secrets.MM_E2E_AUTOMATION_DASHBOARD_URL }}"
AUTOMATION_DASHBOARD_TOKEN: "${{ secrets.MM_E2E_AUTOMATION_DASHBOARD_TOKEN }}"
PUSH_NOTIFICATION_SERVER: "${{ secrets.MM_E2E_PUSH_NOTIFICATION_SERVER }}"
REPORT_WEBHOOK_URL: "${{ secrets.MM_E2E_REPORT_WEBHOOK_URL }}"
CWS_URL: "${{ secrets.MM_E2E_CWS_URL }}"
CWS_EXTRA_HTTP_HEADERS: "${{ secrets.MM_E2E_CWS_EXTRA_HTTP_HEADERS }}"
e2e-playwright:
needs:
- resolve-pr
- check-changes
if: needs.check-changes.outputs.should_run == 'true'
uses: ./.github/workflows/e2e-tests-playwright.yml
with:
commit_sha: "${{ needs.resolve-pr.outputs.COMMIT_SHA }}"
server: "onprem"
server_image_tag: "${{ needs.resolve-pr.outputs.SERVER_IMAGE_TAG }}"
enable_reporting: true
report_type: "PR"
pr_number: "${{ needs.resolve-pr.outputs.PR_NUMBER }}"
secrets:
MM_LICENSE: "${{ secrets.MM_E2E_TEST_LICENSE_ONPREM_ENT }}"
AWS_ACCESS_KEY_ID: "${{ secrets.CYPRESS_AWS_ACCESS_KEY_ID }}"
AWS_SECRET_ACCESS_KEY: "${{ secrets.CYPRESS_AWS_SECRET_ACCESS_KEY }}"
REPORT_WEBHOOK_URL: "${{ secrets.MM_E2E_REPORT_WEBHOOK_URL }}"

View file

@ -0,0 +1,575 @@
---
name: E2E Tests - Cypress Template
on:
workflow_call:
inputs:
# Test configuration
test_type:
description: "Type of test run (smoke or full)"
type: string
required: true
test_filter:
description: "Test filter arguments"
type: string
required: true
workers:
description: "Number of parallel workers"
type: number
required: false
default: 1
timeout_minutes:
description: "Job timeout in minutes"
type: number
required: false
default: 30
enabled_docker_services:
description: "Space-separated list of docker services to enable"
type: string
required: false
default: "postgres inbucket"
# Common build variables
commit_sha:
type: string
required: true
branch:
type: string
required: true
build_id:
type: string
required: true
server_image_tag:
description: "Server image tag (e.g., master or short SHA)"
type: string
required: true
server:
type: string
required: false
default: onprem
server_edition:
description: "Server edition: enterprise (default), fips, or team"
type: string
required: false
default: enterprise
server_image_repo:
description: "Docker registry: mattermostdevelopment (default) or mattermost"
type: string
required: false
default: mattermostdevelopment
server_image_aliases:
description: "Comma-separated alias tags for description (e.g., 'release-11.4, release-11')"
type: string
required: false
# Reporting options
enable_reporting:
type: boolean
required: false
default: false
report_type:
type: string
required: false
ref_branch:
description: "Source branch name for webhook messages (e.g., 'master' or 'release-11.4')"
type: string
required: false
pr_number:
type: string
required: false
# Commit status configuration
context_name:
description: "GitHub commit status context name"
type: string
required: true
outputs:
passed:
description: "Number of passed tests"
value: ${{ jobs.report.outputs.passed }}
failed:
description: "Number of failed tests"
value: ${{ jobs.report.outputs.failed }}
status_check_url:
description: "URL to test results"
value: ${{ jobs.generate-test-cycle.outputs.status_check_url }}
secrets:
MM_LICENSE:
required: false
AUTOMATION_DASHBOARD_URL:
required: false
AUTOMATION_DASHBOARD_TOKEN:
required: false
PUSH_NOTIFICATION_SERVER:
required: false
REPORT_WEBHOOK_URL:
required: false
CWS_URL:
required: false
CWS_EXTRA_HTTP_HEADERS:
required: false
env:
SERVER_IMAGE: "${{ inputs.server_image_repo }}/${{ inputs.server_edition == 'fips' && 'mattermost-enterprise-fips-edition' || inputs.server_edition == 'team' && 'mattermost-team-edition' || 'mattermost-enterprise-edition' }}:${{ inputs.server_image_tag }}"
jobs:
update-initial-status:
runs-on: ubuntu-24.04
steps:
- name: ci/set-initial-status
uses: mattermost/actions/delivery/update-commit-status@f324ac89b05cc3511cb06e60642ac2fb829f0a63
env:
GITHUB_TOKEN: ${{ github.token }}
with:
repository_full_name: ${{ github.repository }}
commit_sha: ${{ inputs.commit_sha }}
context: ${{ inputs.context_name }}
description: "tests running, image_tag:${{ inputs.server_image_tag }}${{ inputs.server_image_aliases && format(' ({0})', inputs.server_image_aliases) || '' }}"
status: pending
generate-test-cycle:
runs-on: ubuntu-24.04
outputs:
status_check_url: "${{ steps.generate-cycle.outputs.status_check_url }}"
workers: "${{ steps.generate-workers.outputs.workers }}"
steps:
- name: ci/generate-workers
id: generate-workers
run: |
echo "workers=$(jq -nc '[range(${{ inputs.workers }})]')" >> $GITHUB_OUTPUT
- name: ci/checkout-repo
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
ref: ${{ inputs.commit_sha }}
fetch-depth: 0
- name: ci/setup-node
uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6.2.0
with:
node-version-file: ".nvmrc"
cache: npm
cache-dependency-path: "e2e-tests/cypress/package-lock.json"
- name: ci/generate-test-cycle
id: generate-cycle
working-directory: e2e-tests
env:
AUTOMATION_DASHBOARD_URL: "${{ secrets.AUTOMATION_DASHBOARD_URL }}"
AUTOMATION_DASHBOARD_TOKEN: "${{ secrets.AUTOMATION_DASHBOARD_TOKEN }}"
BRANCH: "${{ inputs.branch }}-${{ inputs.test_type }}"
BUILD_ID: "${{ inputs.build_id }}"
TEST: cypress
TEST_FILTER: "${{ inputs.test_filter }}"
run: |
set -e -o pipefail
make generate-test-cycle | tee generate-test-cycle.out
TEST_CYCLE_ID=$(sed -nE "s/^.*id: '([^']+)'.*$/\1/p" <generate-test-cycle.out)
if [ -n "$TEST_CYCLE_ID" ]; then
echo "status_check_url=https://automation-dashboard.vercel.app/cycles/${TEST_CYCLE_ID}" >> $GITHUB_OUTPUT
else
echo "status_check_url=${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}" >> $GITHUB_OUTPUT
fi
run-tests:
runs-on: ubuntu-24.04
timeout-minutes: ${{ fromJSON(inputs.timeout_minutes) }}
continue-on-error: ${{ inputs.workers > 1 }}
needs:
- generate-test-cycle
if: needs.generate-test-cycle.result == 'success'
strategy:
fail-fast: false
matrix:
worker_index: ${{ fromJSON(needs.generate-test-cycle.outputs.workers) }}
defaults:
run:
working-directory: e2e-tests
env:
AUTOMATION_DASHBOARD_URL: "${{ secrets.AUTOMATION_DASHBOARD_URL }}"
AUTOMATION_DASHBOARD_TOKEN: "${{ secrets.AUTOMATION_DASHBOARD_TOKEN }}"
SERVER: "${{ inputs.server }}"
MM_LICENSE: "${{ secrets.MM_LICENSE }}"
ENABLED_DOCKER_SERVICES: "${{ inputs.enabled_docker_services }}"
TEST: cypress
TEST_FILTER: "${{ inputs.test_filter }}"
BRANCH: "${{ inputs.branch }}-${{ inputs.test_type }}"
BUILD_ID: "${{ inputs.build_id }}"
CI_BASE_URL: "${{ inputs.test_type }}-test-${{ matrix.worker_index }}"
CYPRESS_pushNotificationServer: "${{ secrets.PUSH_NOTIFICATION_SERVER }}"
CWS_URL: "${{ secrets.CWS_URL }}"
CWS_EXTRA_HTTP_HEADERS: "${{ secrets.CWS_EXTRA_HTTP_HEADERS }}"
steps:
- name: ci/checkout-repo
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
ref: ${{ inputs.commit_sha }}
fetch-depth: 0
- name: ci/setup-node
uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6.2.0
with:
node-version-file: ".nvmrc"
cache: npm
cache-dependency-path: "e2e-tests/cypress/package-lock.json"
- name: ci/run-tests
run: |
make cloud-init
make
- name: ci/cloud-teardown
if: always()
run: make cloud-teardown
- name: ci/upload-results
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
if: always()
with:
name: cypress-${{ inputs.test_type }}-${{ inputs.server_edition }}-results-${{ matrix.worker_index }}
path: |
e2e-tests/cypress/logs/
e2e-tests/cypress/results/
retention-days: 5
calculate-results:
runs-on: ubuntu-24.04
needs:
- generate-test-cycle
- run-tests
if: always() && needs.generate-test-cycle.result == 'success'
outputs:
passed: ${{ steps.calculate.outputs.passed }}
failed: ${{ steps.calculate.outputs.failed }}
pending: ${{ steps.calculate.outputs.pending }}
total_specs: ${{ steps.calculate.outputs.total_specs }}
failed_specs: ${{ steps.calculate.outputs.failed_specs }}
failed_specs_count: ${{ steps.calculate.outputs.failed_specs_count }}
failed_tests: ${{ steps.calculate.outputs.failed_tests }}
commit_status_message: ${{ steps.calculate.outputs.commit_status_message }}
total: ${{ steps.calculate.outputs.total }}
pass_rate: ${{ steps.calculate.outputs.pass_rate }}
color: ${{ steps.calculate.outputs.color }}
steps:
- name: ci/checkout-repo
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- name: ci/download-results
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
with:
pattern: cypress-${{ inputs.test_type }}-${{ inputs.server_edition }}-results-*
path: e2e-tests/cypress/
merge-multiple: true
- name: ci/calculate
id: calculate
uses: ./.github/actions/calculate-cypress-results
with:
original-results-path: e2e-tests/cypress/results
run-failed-tests:
runs-on: ubuntu-24.04
timeout-minutes: ${{ fromJSON(inputs.timeout_minutes) }}
needs:
- generate-test-cycle
- run-tests
- calculate-results
if: >-
always() &&
needs.calculate-results.result == 'success' &&
needs.calculate-results.outputs.failed != '0' &&
fromJSON(needs.calculate-results.outputs.failed_specs_count) <= 20
defaults:
run:
working-directory: e2e-tests
env:
AUTOMATION_DASHBOARD_URL: "${{ secrets.AUTOMATION_DASHBOARD_URL }}"
AUTOMATION_DASHBOARD_TOKEN: "${{ secrets.AUTOMATION_DASHBOARD_TOKEN }}"
SERVER: "${{ inputs.server }}"
MM_LICENSE: "${{ secrets.MM_LICENSE }}"
ENABLED_DOCKER_SERVICES: "${{ inputs.enabled_docker_services }}"
TEST: cypress
BRANCH: "${{ inputs.branch }}-${{ inputs.test_type }}-retest"
BUILD_ID: "${{ inputs.build_id }}-retest"
CYPRESS_pushNotificationServer: "${{ secrets.PUSH_NOTIFICATION_SERVER }}"
CWS_URL: "${{ secrets.CWS_URL }}"
CWS_EXTRA_HTTP_HEADERS: "${{ secrets.CWS_EXTRA_HTTP_HEADERS }}"
steps:
- name: ci/checkout-repo
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
ref: ${{ inputs.commit_sha }}
fetch-depth: 0
- name: ci/setup-node
uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6.2.0
with:
node-version-file: ".nvmrc"
cache: npm
cache-dependency-path: "e2e-tests/cypress/package-lock.json"
- name: ci/run-failed-specs
env:
SPEC_FILES: ${{ needs.calculate-results.outputs.failed_specs }}
run: |
echo "Retesting failed specs: $SPEC_FILES"
make cloud-init
make start-server run-specs
- name: ci/cloud-teardown
if: always()
run: make cloud-teardown
- name: ci/upload-retest-results
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
if: always()
with:
name: cypress-${{ inputs.test_type }}-${{ inputs.server_edition }}-retest-results
path: |
e2e-tests/cypress/logs/
e2e-tests/cypress/results/
retention-days: 5
report:
runs-on: ubuntu-24.04
needs:
- generate-test-cycle
- run-tests
- calculate-results
- run-failed-tests
if: always() && needs.calculate-results.result == 'success'
outputs:
passed: "${{ steps.final-results.outputs.passed }}"
failed: "${{ steps.final-results.outputs.failed }}"
commit_status_message: "${{ steps.final-results.outputs.commit_status_message }}"
defaults:
run:
working-directory: e2e-tests
steps:
- name: ci/checkout-repo
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- name: ci/setup-node
uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6.2.0
with:
node-version-file: ".nvmrc"
cache: npm
cache-dependency-path: "e2e-tests/cypress/package-lock.json"
# PATH A: run-failed-tests was skipped (no failures to retest)
- name: ci/download-results-path-a
if: needs.run-failed-tests.result == 'skipped'
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
with:
pattern: cypress-${{ inputs.test_type }}-${{ inputs.server_edition }}-results-*
path: e2e-tests/cypress/
merge-multiple: true
- name: ci/use-previous-calculation
if: needs.run-failed-tests.result == 'skipped'
id: use-previous
run: |
echo "passed=${{ needs.calculate-results.outputs.passed }}" >> $GITHUB_OUTPUT
echo "failed=${{ needs.calculate-results.outputs.failed }}" >> $GITHUB_OUTPUT
echo "pending=${{ needs.calculate-results.outputs.pending }}" >> $GITHUB_OUTPUT
echo "total_specs=${{ needs.calculate-results.outputs.total_specs }}" >> $GITHUB_OUTPUT
echo "failed_specs=${{ needs.calculate-results.outputs.failed_specs }}" >> $GITHUB_OUTPUT
echo "failed_specs_count=${{ needs.calculate-results.outputs.failed_specs_count }}" >> $GITHUB_OUTPUT
echo "commit_status_message=${{ needs.calculate-results.outputs.commit_status_message }}" >> $GITHUB_OUTPUT
echo "total=${{ needs.calculate-results.outputs.total }}" >> $GITHUB_OUTPUT
echo "pass_rate=${{ needs.calculate-results.outputs.pass_rate }}" >> $GITHUB_OUTPUT
echo "color=${{ needs.calculate-results.outputs.color }}" >> $GITHUB_OUTPUT
{
echo "failed_tests<<EOF"
echo "${{ needs.calculate-results.outputs.failed_tests }}"
echo "EOF"
} >> $GITHUB_OUTPUT
# PATH B: run-failed-tests ran, need to merge and recalculate
- name: ci/download-original-results
if: needs.run-failed-tests.result != 'skipped'
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
with:
pattern: cypress-${{ inputs.test_type }}-${{ inputs.server_edition }}-results-*
path: e2e-tests/cypress/
merge-multiple: true
- name: ci/download-retest-results
if: needs.run-failed-tests.result != 'skipped'
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
with:
name: cypress-${{ inputs.test_type }}-${{ inputs.server_edition }}-retest-results
path: e2e-tests/cypress/retest-results/
- name: ci/calculate-results
if: needs.run-failed-tests.result != 'skipped'
id: recalculate
uses: ./.github/actions/calculate-cypress-results
with:
original-results-path: e2e-tests/cypress/results
retest-results-path: e2e-tests/cypress/retest-results/results
# Set final outputs from either path
- name: ci/set-final-results
id: final-results
env:
USE_PREVIOUS_FAILED_TESTS: ${{ steps.use-previous.outputs.failed_tests }}
RECALCULATE_FAILED_TESTS: ${{ steps.recalculate.outputs.failed_tests }}
run: |
if [ "${{ needs.run-failed-tests.result }}" == "skipped" ]; then
echo "passed=${{ steps.use-previous.outputs.passed }}" >> $GITHUB_OUTPUT
echo "failed=${{ steps.use-previous.outputs.failed }}" >> $GITHUB_OUTPUT
echo "pending=${{ steps.use-previous.outputs.pending }}" >> $GITHUB_OUTPUT
echo "total_specs=${{ steps.use-previous.outputs.total_specs }}" >> $GITHUB_OUTPUT
echo "failed_specs=${{ steps.use-previous.outputs.failed_specs }}" >> $GITHUB_OUTPUT
echo "failed_specs_count=${{ steps.use-previous.outputs.failed_specs_count }}" >> $GITHUB_OUTPUT
echo "commit_status_message=${{ steps.use-previous.outputs.commit_status_message }}" >> $GITHUB_OUTPUT
echo "total=${{ steps.use-previous.outputs.total }}" >> $GITHUB_OUTPUT
echo "pass_rate=${{ steps.use-previous.outputs.pass_rate }}" >> $GITHUB_OUTPUT
echo "color=${{ steps.use-previous.outputs.color }}" >> $GITHUB_OUTPUT
{
echo "failed_tests<<EOF"
echo "$USE_PREVIOUS_FAILED_TESTS"
echo "EOF"
} >> $GITHUB_OUTPUT
else
echo "passed=${{ steps.recalculate.outputs.passed }}" >> $GITHUB_OUTPUT
echo "failed=${{ steps.recalculate.outputs.failed }}" >> $GITHUB_OUTPUT
echo "pending=${{ steps.recalculate.outputs.pending }}" >> $GITHUB_OUTPUT
echo "total_specs=${{ steps.recalculate.outputs.total_specs }}" >> $GITHUB_OUTPUT
echo "failed_specs=${{ steps.recalculate.outputs.failed_specs }}" >> $GITHUB_OUTPUT
echo "failed_specs_count=${{ steps.recalculate.outputs.failed_specs_count }}" >> $GITHUB_OUTPUT
echo "commit_status_message=${{ steps.recalculate.outputs.commit_status_message }}" >> $GITHUB_OUTPUT
echo "total=${{ steps.recalculate.outputs.total }}" >> $GITHUB_OUTPUT
echo "pass_rate=${{ steps.recalculate.outputs.pass_rate }}" >> $GITHUB_OUTPUT
echo "color=${{ steps.recalculate.outputs.color }}" >> $GITHUB_OUTPUT
{
echo "failed_tests<<EOF"
echo "$RECALCULATE_FAILED_TESTS"
echo "EOF"
} >> $GITHUB_OUTPUT
fi
- name: ci/upload-combined-results
if: inputs.workers > 1
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
with:
name: cypress-${{ inputs.test_type }}-${{ inputs.server_edition }}-results
path: |
e2e-tests/cypress/logs/
e2e-tests/cypress/results/
- name: ci/publish-report
if: inputs.enable_reporting && env.REPORT_WEBHOOK_URL != ''
env:
REPORT_WEBHOOK_URL: ${{ secrets.REPORT_WEBHOOK_URL }}
COMMIT_STATUS_MESSAGE: ${{ steps.final-results.outputs.commit_status_message }}
COLOR: ${{ steps.final-results.outputs.color }}
REPORT_URL: ${{ needs.generate-test-cycle.outputs.status_check_url }}
TEST_TYPE: ${{ inputs.test_type }}
REPORT_TYPE: ${{ inputs.report_type }}
COMMIT_SHA: ${{ inputs.commit_sha }}
REF_BRANCH: ${{ inputs.ref_branch }}
PR_NUMBER: ${{ inputs.pr_number }}
run: |
# Capitalize test type
TEST_TYPE_CAP=$(echo "$TEST_TYPE" | sed 's/.*/\u&/')
# Build source line based on report type
COMMIT_SHORT="${COMMIT_SHA::7}"
COMMIT_URL="https://github.com/${{ github.repository }}/commit/${COMMIT_SHA}"
if [ "$REPORT_TYPE" = "RELEASE_CUT" ]; then
SOURCE_LINE=":github_round: [${COMMIT_SHORT}](${COMMIT_URL}) on \`${REF_BRANCH}\`"
elif [ "$REPORT_TYPE" = "MASTER" ] || [ "$REPORT_TYPE" = "RELEASE" ]; then
SOURCE_LINE=":git_merge: [${COMMIT_SHORT}](${COMMIT_URL}) on \`${REF_BRANCH}\`"
else
SOURCE_LINE=":open-pull-request: [mattermost-pr-${PR_NUMBER}](https://github.com/${{ github.repository }}/pull/${PR_NUMBER})"
fi
# Build payload with attachments
PAYLOAD=$(cat <<EOF
{
"username": "E2E Test",
"icon_url": "https://mattermost.com/wp-content/uploads/2022/02/icon_WS.png",
"attachments": [{
"color": "${COLOR}",
"text": "**Results - Cypress ${TEST_TYPE_CAP} Tests**\n\n${SOURCE_LINE}\n:docker: \`${{ env.SERVER_IMAGE }}\`\n${COMMIT_STATUS_MESSAGE} | [full report](${REPORT_URL})"
}]
}
EOF
)
# Send to webhook
curl -X POST -H "Content-Type: application/json" -d "$PAYLOAD" "$REPORT_WEBHOOK_URL"
- name: ci/write-job-summary
if: always()
env:
STATUS_CHECK_URL: ${{ needs.generate-test-cycle.outputs.status_check_url }}
TEST_TYPE: ${{ inputs.test_type }}
PASSED: ${{ steps.final-results.outputs.passed }}
FAILED: ${{ steps.final-results.outputs.failed }}
PENDING: ${{ steps.final-results.outputs.pending }}
TOTAL_SPECS: ${{ steps.final-results.outputs.total_specs }}
FAILED_SPECS_COUNT: ${{ steps.final-results.outputs.failed_specs_count }}
FAILED_SPECS: ${{ steps.final-results.outputs.failed_specs }}
COMMIT_STATUS_MESSAGE: ${{ steps.final-results.outputs.commit_status_message }}
FAILED_TESTS: ${{ steps.final-results.outputs.failed_tests }}
run: |
{
echo "## E2E Test Results - Cypress ${TEST_TYPE}"
echo ""
if [ "$FAILED" = "0" ]; then
echo "All tests passed: **${PASSED} passed**"
else
echo "<details>"
echo "<summary>${FAILED} failed, ${PASSED} passed</summary>"
echo ""
echo "| Test | File |"
echo "|------|------|"
echo "${FAILED_TESTS}"
echo "</details>"
fi
echo ""
echo "### Calculation Outputs"
echo ""
echo "| Output | Value |"
echo "|--------|-------|"
echo "| passed | ${PASSED} |"
echo "| failed | ${FAILED} |"
echo "| pending | ${PENDING} |"
echo "| total_specs | ${TOTAL_SPECS} |"
echo "| failed_specs_count | ${FAILED_SPECS_COUNT} |"
echo "| commit_status_message | ${COMMIT_STATUS_MESSAGE} |"
echo "| failed_specs | ${FAILED_SPECS:-none} |"
echo ""
echo "---"
echo "[View Full Report](${STATUS_CHECK_URL})"
} >> $GITHUB_STEP_SUMMARY
- name: ci/assert-results
run: |
[ "${{ steps.final-results.outputs.failed }}" = "0" ]
update-success-status:
runs-on: ubuntu-24.04
if: always() && needs.report.result == 'success' && needs.calculate-results.result == 'success'
needs:
- generate-test-cycle
- calculate-results
- report
steps:
- uses: mattermost/actions/delivery/update-commit-status@f324ac89b05cc3511cb06e60642ac2fb829f0a63
env:
GITHUB_TOKEN: ${{ github.token }}
with:
repository_full_name: ${{ github.repository }}
commit_sha: ${{ inputs.commit_sha }}
context: ${{ inputs.context_name }}
description: "${{ needs.report.outputs.commit_status_message }}, image_tag:${{ inputs.server_image_tag }}${{ inputs.server_image_aliases && format(' ({0})', inputs.server_image_aliases) || '' }}"
status: success
target_url: ${{ needs.generate-test-cycle.outputs.status_check_url }}
update-failure-status:
runs-on: ubuntu-24.04
if: always() && (needs.report.result != 'success' || needs.calculate-results.result != 'success')
needs:
- generate-test-cycle
- calculate-results
- report
steps:
- uses: mattermost/actions/delivery/update-commit-status@f324ac89b05cc3511cb06e60642ac2fb829f0a63
env:
GITHUB_TOKEN: ${{ github.token }}
with:
repository_full_name: ${{ github.repository }}
commit_sha: ${{ inputs.commit_sha }}
context: ${{ inputs.context_name }}
description: "${{ needs.report.outputs.commit_status_message }}, image_tag:${{ inputs.server_image_tag }}${{ inputs.server_image_aliases && format(' ({0})', inputs.server_image_aliases) || '' }}"
status: failure
target_url: ${{ needs.generate-test-cycle.outputs.status_check_url }}

194
.github/workflows/e2e-tests-cypress.yml vendored Normal file
View file

@ -0,0 +1,194 @@
---
name: E2E Tests - Cypress
on:
workflow_call:
inputs:
commit_sha:
type: string
required: true
enable_reporting:
type: boolean
required: false
default: false
server:
type: string
required: false
default: onprem
report_type:
type: string
required: false
pr_number:
type: string
required: false
server_image_tag:
type: string
required: false
description: "Server image tag (e.g., master or short SHA)"
server_edition:
type: string
required: false
description: "Server edition: enterprise (default), fips, or team"
server_image_repo:
type: string
required: false
default: mattermostdevelopment
description: "Docker registry: mattermostdevelopment (default) or mattermost"
skip_smoke:
type: boolean
required: false
default: false
description: "Skip smoke tests and run full tests directly"
server_image_aliases:
type: string
required: false
description: "Comma-separated alias tags for context name (e.g., 'release-11.4, release-11')"
ref_branch:
type: string
required: false
description: "Source branch name for webhook messages (e.g., 'master' or 'release-11.4')"
secrets:
MM_LICENSE:
required: false
AUTOMATION_DASHBOARD_URL:
required: false
AUTOMATION_DASHBOARD_TOKEN:
required: false
PUSH_NOTIFICATION_SERVER:
required: false
REPORT_WEBHOOK_URL:
required: false
CWS_URL:
required: false
CWS_EXTRA_HTTP_HEADERS:
required: false
jobs:
generate-build-variables:
runs-on: ubuntu-24.04
outputs:
branch: "${{ steps.build-vars.outputs.branch }}"
build_id: "${{ steps.build-vars.outputs.build_id }}"
server_image_tag: "${{ steps.build-vars.outputs.server_image_tag }}"
server_image: "${{ steps.build-vars.outputs.server_image }}"
steps:
- name: ci/generate-build-variables
id: build-vars
env:
COMMIT_SHA: ${{ inputs.commit_sha }}
PR_NUMBER: ${{ inputs.pr_number }}
INPUT_SERVER_IMAGE_TAG: ${{ inputs.server_image_tag }}
RUN_ID: ${{ github.run_id }}
RUN_ATTEMPT: ${{ github.run_attempt }}
run: |
# Use provided server_image_tag or derive from commit SHA
if [ -n "$INPUT_SERVER_IMAGE_TAG" ]; then
SERVER_IMAGE_TAG="$INPUT_SERVER_IMAGE_TAG"
else
SERVER_IMAGE_TAG="${COMMIT_SHA::7}"
fi
# Validate server_image_tag format (alphanumeric, dots, hyphens, underscores)
if ! [[ "$SERVER_IMAGE_TAG" =~ ^[a-zA-Z0-9._-]+$ ]]; then
echo "::error::Invalid server_image_tag format: ${SERVER_IMAGE_TAG}"
exit 1
fi
echo "server_image_tag=${SERVER_IMAGE_TAG}" >> $GITHUB_OUTPUT
# Generate branch name
REF_BRANCH="${{ inputs.ref_branch }}"
if [ -n "$PR_NUMBER" ]; then
echo "branch=server-pr-${PR_NUMBER}" >> $GITHUB_OUTPUT
elif [ -n "$REF_BRANCH" ]; then
echo "branch=server-${REF_BRANCH}-${SERVER_IMAGE_TAG}" >> $GITHUB_OUTPUT
else
echo "branch=server-commit-${SERVER_IMAGE_TAG}" >> $GITHUB_OUTPUT
fi
# Determine server image name
EDITION="${{ inputs.server_edition }}"
REPO="${{ inputs.server_image_repo }}"
REPO="${REPO:-mattermostdevelopment}"
case "$EDITION" in
fips) IMAGE_NAME="mattermost-enterprise-fips-edition" ;;
team) IMAGE_NAME="mattermost-team-edition" ;;
*) IMAGE_NAME="mattermost-enterprise-edition" ;;
esac
SERVER_IMAGE="${REPO}/${IMAGE_NAME}:${SERVER_IMAGE_TAG}"
echo "server_image=${SERVER_IMAGE}" >> $GITHUB_OUTPUT
# Validate server_image_aliases format if provided
ALIASES="${{ inputs.server_image_aliases }}"
if [ -n "$ALIASES" ] && ! [[ "$ALIASES" =~ ^[a-zA-Z0-9._,\ -]+$ ]]; then
echo "::error::Invalid server_image_aliases format: ${ALIASES}"
exit 1
fi
# Generate build ID
if [ -n "$EDITION" ] && [ "$EDITION" != "enterprise" ]; then
echo "build_id=${RUN_ID}_${RUN_ATTEMPT}-${SERVER_IMAGE_TAG}-cypress-onprem-${EDITION}" >> $GITHUB_OUTPUT
else
echo "build_id=${RUN_ID}_${RUN_ATTEMPT}-${SERVER_IMAGE_TAG}-cypress-onprem-ent" >> $GITHUB_OUTPUT
fi
cypress-smoke:
if: ${{ !inputs.skip_smoke }}
needs:
- generate-build-variables
uses: ./.github/workflows/e2e-tests-cypress-template.yml
with:
test_type: smoke
test_filter: "--stage=@prod --group=@smoke"
workers: 1
timeout_minutes: 30
enabled_docker_services: "postgres inbucket"
commit_sha: ${{ inputs.commit_sha }}
branch: ${{ needs.generate-build-variables.outputs.branch }}
build_id: ${{ needs.generate-build-variables.outputs.build_id }}
server_image_tag: ${{ needs.generate-build-variables.outputs.server_image_tag }}
server_edition: ${{ inputs.server_edition }}
server_image_repo: ${{ inputs.server_image_repo }}
server_image_aliases: ${{ inputs.server_image_aliases }}
server: ${{ inputs.server }}
context_name: "e2e-test/cypress-smoke/${{ inputs.server_edition || 'enterprise' }}"
secrets:
MM_LICENSE: ${{ secrets.MM_LICENSE }}
AUTOMATION_DASHBOARD_URL: ${{ secrets.AUTOMATION_DASHBOARD_URL }}
AUTOMATION_DASHBOARD_TOKEN: ${{ secrets.AUTOMATION_DASHBOARD_TOKEN }}
PUSH_NOTIFICATION_SERVER: ${{ secrets.PUSH_NOTIFICATION_SERVER }}
CWS_URL: ${{ secrets.CWS_URL }}
CWS_EXTRA_HTTP_HEADERS: ${{ secrets.CWS_EXTRA_HTTP_HEADERS }}
# Full Tests (runs if smoke passed or skipped)
cypress-full:
needs:
- cypress-smoke
- generate-build-variables
if: always() && (needs.cypress-smoke.result == 'skipped' || needs.cypress-smoke.outputs.failed == '0')
uses: ./.github/workflows/e2e-tests-cypress-template.yml
with:
test_type: full
test_filter: '--stage="@prod" --excludeGroup="@te_only,@cloud_only,@high_availability" --sortFirst="@compliance_export,@elasticsearch,@ldap_group,@ldap" --sortLast="@saml,@keycloak,@plugin,@plugins_uninstall,@mfa,@license_removal"'
workers: 20
timeout_minutes: 60
enabled_docker_services: "postgres inbucket minio openldap elasticsearch keycloak"
commit_sha: ${{ inputs.commit_sha }}
branch: ${{ needs.generate-build-variables.outputs.branch }}
build_id: ${{ needs.generate-build-variables.outputs.build_id }}
server_image_tag: ${{ needs.generate-build-variables.outputs.server_image_tag }}
server_edition: ${{ inputs.server_edition }}
server_image_repo: ${{ inputs.server_image_repo }}
server_image_aliases: ${{ inputs.server_image_aliases }}
server: ${{ inputs.server }}
enable_reporting: ${{ inputs.enable_reporting }}
report_type: ${{ inputs.report_type }}
ref_branch: ${{ inputs.ref_branch }}
pr_number: ${{ inputs.pr_number }}
context_name: "e2e-test/cypress-full/${{ inputs.server_edition || 'enterprise' }}"
secrets:
MM_LICENSE: ${{ secrets.MM_LICENSE }}
AUTOMATION_DASHBOARD_URL: ${{ secrets.AUTOMATION_DASHBOARD_URL }}
AUTOMATION_DASHBOARD_TOKEN: ${{ secrets.AUTOMATION_DASHBOARD_TOKEN }}
PUSH_NOTIFICATION_SERVER: ${{ secrets.PUSH_NOTIFICATION_SERVER }}
REPORT_WEBHOOK_URL: ${{ secrets.REPORT_WEBHOOK_URL }}
CWS_URL: ${{ secrets.CWS_URL }}
CWS_EXTRA_HTTP_HEADERS: ${{ secrets.CWS_EXTRA_HTTP_HEADERS }}

134
.github/workflows/e2e-tests-on-merge.yml vendored Normal file
View file

@ -0,0 +1,134 @@
---
name: E2E Tests (master/release - merge)
on:
workflow_dispatch:
inputs:
branch:
type: string
required: true
description: "Branch name (e.g., 'master' or 'release-11.4')"
commit_sha:
type: string
required: true
description: "Commit SHA to test"
server_image_tag:
type: string
required: true
description: "Docker image tag (e.g., 'abc1234_def5678' or 'master')"
jobs:
generate-build-variables:
runs-on: ubuntu-24.04
outputs:
report_type: "${{ steps.vars.outputs.report_type }}"
ref_branch: "${{ steps.vars.outputs.ref_branch }}"
steps:
- name: ci/checkout-repo
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
ref: ${{ inputs.branch }}
fetch-depth: 50
- name: ci/generate-variables
id: vars
env:
BRANCH: ${{ inputs.branch }}
COMMIT_SHA: ${{ inputs.commit_sha }}
run: |
# Strip refs/heads/ prefix if present
BRANCH="${BRANCH#refs/heads/}"
# Validate branch is master or release-X.Y
if [[ "$BRANCH" == "master" ]]; then
echo "report_type=MASTER" >> $GITHUB_OUTPUT
elif [[ "$BRANCH" =~ ^release-[0-9]+\.[0-9]+$ ]]; then
echo "report_type=RELEASE" >> $GITHUB_OUTPUT
else
echo "::error::Branch ${BRANCH} must be 'master' or 'release-X.Y' format."
exit 1
fi
echo "ref_branch=${BRANCH}" >> $GITHUB_OUTPUT
# Validate commit exists on the branch
if ! git merge-base --is-ancestor "$COMMIT_SHA" HEAD; then
echo "::error::Commit ${COMMIT_SHA} is not on branch ${BRANCH}."
exit 1
fi
# Enterprise Edition
e2e-cypress:
needs: generate-build-variables
uses: ./.github/workflows/e2e-tests-cypress.yml
with:
commit_sha: ${{ inputs.commit_sha }}
server_image_tag: ${{ inputs.server_image_tag }}
skip_smoke: true
server: onprem
enable_reporting: true
report_type: ${{ needs.generate-build-variables.outputs.report_type }}
ref_branch: ${{ needs.generate-build-variables.outputs.ref_branch }}
secrets:
MM_LICENSE: "${{ secrets.MM_E2E_TEST_LICENSE_ONPREM_ENT }}"
AUTOMATION_DASHBOARD_URL: "${{ secrets.MM_E2E_AUTOMATION_DASHBOARD_URL }}"
AUTOMATION_DASHBOARD_TOKEN: "${{ secrets.MM_E2E_AUTOMATION_DASHBOARD_TOKEN }}"
PUSH_NOTIFICATION_SERVER: "${{ secrets.MM_E2E_PUSH_NOTIFICATION_SERVER }}"
REPORT_WEBHOOK_URL: "${{ secrets.MM_E2E_REPORT_WEBHOOK_URL }}"
CWS_URL: "${{ secrets.MM_E2E_CWS_URL }}"
CWS_EXTRA_HTTP_HEADERS: "${{ secrets.MM_E2E_CWS_EXTRA_HTTP_HEADERS }}"
e2e-playwright:
needs: generate-build-variables
uses: ./.github/workflows/e2e-tests-playwright.yml
with:
commit_sha: ${{ inputs.commit_sha }}
server_image_tag: ${{ inputs.server_image_tag }}
skip_smoke: true
server: onprem
enable_reporting: true
report_type: ${{ needs.generate-build-variables.outputs.report_type }}
ref_branch: ${{ needs.generate-build-variables.outputs.ref_branch }}
secrets:
MM_LICENSE: "${{ secrets.MM_E2E_TEST_LICENSE_ONPREM_ENT }}"
AWS_ACCESS_KEY_ID: "${{ secrets.CYPRESS_AWS_ACCESS_KEY_ID }}"
AWS_SECRET_ACCESS_KEY: "${{ secrets.CYPRESS_AWS_SECRET_ACCESS_KEY }}"
REPORT_WEBHOOK_URL: "${{ secrets.MM_E2E_REPORT_WEBHOOK_URL }}"
# Enterprise FIPS Edition
e2e-cypress-fips:
needs: generate-build-variables
uses: ./.github/workflows/e2e-tests-cypress.yml
with:
commit_sha: ${{ inputs.commit_sha }}
server_image_tag: ${{ inputs.server_image_tag }}
server_edition: fips
skip_smoke: true
server: onprem
enable_reporting: true
report_type: ${{ needs.generate-build-variables.outputs.report_type }}
ref_branch: ${{ needs.generate-build-variables.outputs.ref_branch }}
secrets:
MM_LICENSE: "${{ secrets.MM_E2E_TEST_LICENSE_ONPREM_ENT }}"
AUTOMATION_DASHBOARD_URL: "${{ secrets.MM_E2E_AUTOMATION_DASHBOARD_URL }}"
AUTOMATION_DASHBOARD_TOKEN: "${{ secrets.MM_E2E_AUTOMATION_DASHBOARD_TOKEN }}"
PUSH_NOTIFICATION_SERVER: "${{ secrets.MM_E2E_PUSH_NOTIFICATION_SERVER }}"
REPORT_WEBHOOK_URL: "${{ secrets.MM_E2E_REPORT_WEBHOOK_URL }}"
CWS_URL: "${{ secrets.MM_E2E_CWS_URL }}"
CWS_EXTRA_HTTP_HEADERS: "${{ secrets.MM_E2E_CWS_EXTRA_HTTP_HEADERS }}"
e2e-playwright-fips:
needs: generate-build-variables
uses: ./.github/workflows/e2e-tests-playwright.yml
with:
commit_sha: ${{ inputs.commit_sha }}
server_image_tag: ${{ inputs.server_image_tag }}
server_edition: fips
skip_smoke: true
server: onprem
enable_reporting: true
report_type: ${{ needs.generate-build-variables.outputs.report_type }}
ref_branch: ${{ needs.generate-build-variables.outputs.ref_branch }}
secrets:
MM_LICENSE: "${{ secrets.MM_E2E_TEST_LICENSE_ONPREM_ENT }}"
AWS_ACCESS_KEY_ID: "${{ secrets.CYPRESS_AWS_ACCESS_KEY_ID }}"
AWS_SECRET_ACCESS_KEY: "${{ secrets.CYPRESS_AWS_SECRET_ACCESS_KEY }}"
REPORT_WEBHOOK_URL: "${{ secrets.MM_E2E_REPORT_WEBHOOK_URL }}"

View file

@ -0,0 +1,137 @@
---
name: E2E Tests (release cut)
on:
workflow_dispatch:
inputs:
branch:
type: string
required: true
description: "Release branch (e.g., 'release-11.4')"
commit_sha:
type: string
required: true
description: "Commit SHA to test"
server_image_tag:
type: string
required: true
description: "Docker image tag (e.g., '11.4.0', '11.4.0-rc3', or 'release-11.4')"
server_image_aliases:
type: string
required: false
description: "Comma-separated alias tags (e.g., 'release-11.4, release-11')"
jobs:
validate:
runs-on: ubuntu-24.04
outputs:
ref_branch: "${{ steps.check.outputs.ref_branch }}"
steps:
- name: ci/checkout-repo
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
ref: ${{ inputs.branch }}
fetch-depth: 50
- name: ci/validate-inputs
id: check
env:
BRANCH: ${{ inputs.branch }}
COMMIT_SHA: ${{ inputs.commit_sha }}
run: |
# Strip refs/heads/ prefix if present
BRANCH="${BRANCH#refs/heads/}"
if ! [[ "$BRANCH" =~ ^release-[0-9]+\.[0-9]+$ ]]; then
echo "::error::Branch ${BRANCH} must be 'release-X.Y' format."
exit 1
elif ! git merge-base --is-ancestor "$COMMIT_SHA" HEAD; then
echo "::error::Commit ${COMMIT_SHA} is not on branch ${BRANCH}."
exit 1
fi
echo "ref_branch=${BRANCH}" >> $GITHUB_OUTPUT
# Enterprise Edition
e2e-cypress:
needs: validate
uses: ./.github/workflows/e2e-tests-cypress.yml
with:
commit_sha: ${{ inputs.commit_sha }}
server_image_tag: ${{ inputs.server_image_tag }}
server_image_repo: mattermost
server_image_aliases: ${{ inputs.server_image_aliases }}
skip_smoke: true
server: onprem
enable_reporting: true
report_type: RELEASE_CUT
ref_branch: ${{ needs.validate.outputs.ref_branch }}
secrets:
MM_LICENSE: "${{ secrets.MM_E2E_TEST_LICENSE_ONPREM_ENT }}"
AUTOMATION_DASHBOARD_URL: "${{ secrets.MM_E2E_AUTOMATION_DASHBOARD_URL }}"
AUTOMATION_DASHBOARD_TOKEN: "${{ secrets.MM_E2E_AUTOMATION_DASHBOARD_TOKEN }}"
PUSH_NOTIFICATION_SERVER: "${{ secrets.MM_E2E_PUSH_NOTIFICATION_SERVER }}"
REPORT_WEBHOOK_URL: "${{ secrets.MM_E2E_REPORT_WEBHOOK_URL }}"
CWS_URL: "${{ secrets.MM_E2E_CWS_URL }}"
CWS_EXTRA_HTTP_HEADERS: "${{ secrets.MM_E2E_CWS_EXTRA_HTTP_HEADERS }}"
e2e-playwright:
needs: validate
uses: ./.github/workflows/e2e-tests-playwright.yml
with:
commit_sha: ${{ inputs.commit_sha }}
server_image_tag: ${{ inputs.server_image_tag }}
server_image_repo: mattermost
server_image_aliases: ${{ inputs.server_image_aliases }}
skip_smoke: true
server: onprem
enable_reporting: true
report_type: RELEASE_CUT
ref_branch: ${{ needs.validate.outputs.ref_branch }}
secrets:
MM_LICENSE: "${{ secrets.MM_E2E_TEST_LICENSE_ONPREM_ENT }}"
AWS_ACCESS_KEY_ID: "${{ secrets.CYPRESS_AWS_ACCESS_KEY_ID }}"
AWS_SECRET_ACCESS_KEY: "${{ secrets.CYPRESS_AWS_SECRET_ACCESS_KEY }}"
REPORT_WEBHOOK_URL: "${{ secrets.MM_E2E_REPORT_WEBHOOK_URL }}"
# Enterprise FIPS Edition
e2e-cypress-fips:
needs: validate
uses: ./.github/workflows/e2e-tests-cypress.yml
with:
commit_sha: ${{ inputs.commit_sha }}
server_image_tag: ${{ inputs.server_image_tag }}
server_edition: fips
server_image_repo: mattermost
server_image_aliases: ${{ inputs.server_image_aliases }}
skip_smoke: true
server: onprem
enable_reporting: true
report_type: RELEASE_CUT
ref_branch: ${{ needs.validate.outputs.ref_branch }}
secrets:
MM_LICENSE: "${{ secrets.MM_E2E_TEST_LICENSE_ONPREM_ENT }}"
AUTOMATION_DASHBOARD_URL: "${{ secrets.MM_E2E_AUTOMATION_DASHBOARD_URL }}"
AUTOMATION_DASHBOARD_TOKEN: "${{ secrets.MM_E2E_AUTOMATION_DASHBOARD_TOKEN }}"
PUSH_NOTIFICATION_SERVER: "${{ secrets.MM_E2E_PUSH_NOTIFICATION_SERVER }}"
REPORT_WEBHOOK_URL: "${{ secrets.MM_E2E_REPORT_WEBHOOK_URL }}"
CWS_URL: "${{ secrets.MM_E2E_CWS_URL }}"
CWS_EXTRA_HTTP_HEADERS: "${{ secrets.MM_E2E_CWS_EXTRA_HTTP_HEADERS }}"
e2e-playwright-fips:
needs: validate
uses: ./.github/workflows/e2e-tests-playwright.yml
with:
commit_sha: ${{ inputs.commit_sha }}
server_image_tag: ${{ inputs.server_image_tag }}
server_edition: fips
server_image_repo: mattermost
server_image_aliases: ${{ inputs.server_image_aliases }}
skip_smoke: true
server: onprem
enable_reporting: true
report_type: RELEASE_CUT
ref_branch: ${{ needs.validate.outputs.ref_branch }}
secrets:
MM_LICENSE: "${{ secrets.MM_E2E_TEST_LICENSE_ONPREM_ENT }}"
AWS_ACCESS_KEY_ID: "${{ secrets.CYPRESS_AWS_ACCESS_KEY_ID }}"
AWS_SECRET_ACCESS_KEY: "${{ secrets.CYPRESS_AWS_SECRET_ACCESS_KEY }}"
REPORT_WEBHOOK_URL: "${{ secrets.MM_E2E_REPORT_WEBHOOK_URL }}"

View file

@ -0,0 +1,89 @@
---
name: E2E Tests - Override Status
on:
workflow_dispatch:
inputs:
pr_number:
description: "PR number to update status for"
required: true
type: string
jobs:
override-status:
runs-on: ubuntu-24.04
steps:
- name: Validate inputs
env:
PR_NUMBER: ${{ inputs.pr_number }}
run: |
if ! [[ "$PR_NUMBER" =~ ^[0-9]+$ ]]; then
echo "::error::Invalid PR number format. Must be numeric."
exit 1
fi
- name: Get PR head SHA
id: pr-info
env:
GH_TOKEN: ${{ github.token }}
PR_NUMBER: ${{ inputs.pr_number }}
run: |
PR_DATA=$(gh api repos/${{ github.repository }}/pulls/${PR_NUMBER})
HEAD_SHA=$(echo "$PR_DATA" | jq -r '.head.sha')
echo "head_sha=$HEAD_SHA" >> $GITHUB_OUTPUT
- name: Override failed full test statuses
env:
GH_TOKEN: ${{ github.token }}
COMMIT_SHA: ${{ steps.pr-info.outputs.head_sha }}
run: |
# Only full tests can be overridden (smoke tests must pass)
FULL_TEST_CONTEXTS=("e2e-test/playwright-full/enterprise" "e2e-test/cypress-full/enterprise")
for CONTEXT_NAME in "${FULL_TEST_CONTEXTS[@]}"; do
echo "Checking: $CONTEXT_NAME"
# Get current status
STATUS_JSON=$(gh api repos/${{ github.repository }}/commits/${COMMIT_SHA}/statuses \
--jq "[.[] | select(.context == \"$CONTEXT_NAME\")] | first // empty")
if [ -z "$STATUS_JSON" ]; then
echo " No status found, skipping"
continue
fi
CURRENT_DESC=$(echo "$STATUS_JSON" | jq -r '.description // ""')
CURRENT_URL=$(echo "$STATUS_JSON" | jq -r '.target_url // ""')
CURRENT_STATE=$(echo "$STATUS_JSON" | jq -r '.state // ""')
echo " Current: $CURRENT_DESC ($CURRENT_STATE)"
# Only override if status is failure
if [ "$CURRENT_STATE" != "failure" ]; then
echo " Not failed, skipping"
continue
fi
# Parse and construct new message
if [[ "$CURRENT_DESC" =~ ^([0-9]+)\ failed,\ ([0-9]+)\ passed$ ]]; then
FAILED="${BASH_REMATCH[1]}"
PASSED="${BASH_REMATCH[2]}"
NEW_MSG="${FAILED} failed (verified), ${PASSED} passed"
elif [[ "$CURRENT_DESC" =~ ^([0-9]+)\ failed\ \([^)]+\),\ ([0-9]+)\ passed$ ]]; then
FAILED="${BASH_REMATCH[1]}"
PASSED="${BASH_REMATCH[2]}"
NEW_MSG="${FAILED} failed (verified), ${PASSED} passed"
else
NEW_MSG="${CURRENT_DESC} (verified)"
fi
echo " New: $NEW_MSG"
# Update status via GitHub API
gh api repos/${{ github.repository }}/statuses/${COMMIT_SHA} \
-f state=success \
-f context="$CONTEXT_NAME" \
-f description="$NEW_MSG" \
-f target_url="$CURRENT_URL"
echo " Updated to success"
done

View file

@ -0,0 +1,465 @@
---
name: E2E Tests - Playwright Template
on:
workflow_call:
inputs:
# Test configuration
test_type:
description: "Type of test run (smoke or full)"
type: string
required: true
test_filter:
description: "Test filter arguments (e.g., --grep @smoke)"
type: string
required: true
timeout_minutes:
description: "Job timeout in minutes"
type: number
required: false
default: 60
enabled_docker_services:
description: "Space-separated list of docker services to enable"
type: string
required: false
default: "postgres inbucket"
# Common build variables
commit_sha:
type: string
required: true
branch:
type: string
required: true
build_id:
type: string
required: true
server_image_tag:
description: "Server image tag (e.g., master or short SHA)"
type: string
required: true
server:
type: string
required: false
default: onprem
server_edition:
description: "Server edition: enterprise (default), fips, or team"
type: string
required: false
default: enterprise
server_image_repo:
description: "Docker registry: mattermostdevelopment (default) or mattermost"
type: string
required: false
default: mattermostdevelopment
server_image_aliases:
description: "Comma-separated alias tags for description (e.g., 'release-11.4, release-11')"
type: string
required: false
# Reporting options
enable_reporting:
type: boolean
required: false
default: false
report_type:
type: string
required: false
ref_branch:
description: "Source branch name for webhook messages (e.g., 'master' or 'release-11.4')"
type: string
required: false
pr_number:
type: string
required: false
# Commit status configuration
context_name:
description: "GitHub commit status context name"
type: string
required: true
outputs:
passed:
description: "Number of passed tests"
value: ${{ jobs.report.outputs.passed }}
failed:
description: "Number of failed tests"
value: ${{ jobs.report.outputs.failed }}
report_url:
description: "URL to test report on S3"
value: ${{ jobs.report.outputs.report_url }}
secrets:
MM_LICENSE:
required: false
REPORT_WEBHOOK_URL:
required: false
AWS_ACCESS_KEY_ID:
required: true
AWS_SECRET_ACCESS_KEY:
required: true
env:
SERVER_IMAGE: "${{ inputs.server_image_repo }}/${{ inputs.server_edition == 'fips' && 'mattermost-enterprise-fips-edition' || inputs.server_edition == 'team' && 'mattermost-team-edition' || 'mattermost-enterprise-edition' }}:${{ inputs.server_image_tag }}"
jobs:
update-initial-status:
runs-on: ubuntu-24.04
steps:
- name: ci/set-initial-status
uses: mattermost/actions/delivery/update-commit-status@f324ac89b05cc3511cb06e60642ac2fb829f0a63
env:
GITHUB_TOKEN: ${{ github.token }}
with:
repository_full_name: ${{ github.repository }}
commit_sha: ${{ inputs.commit_sha }}
context: ${{ inputs.context_name }}
description: "tests running, image_tag:${{ inputs.server_image_tag }}${{ inputs.server_image_aliases && format(' ({0})', inputs.server_image_aliases) || '' }}"
status: pending
run-tests:
runs-on: ubuntu-24.04
timeout-minutes: ${{ fromJSON(inputs.timeout_minutes) }}
defaults:
run:
working-directory: e2e-tests
env:
SERVER: "${{ inputs.server }}"
MM_LICENSE: "${{ secrets.MM_LICENSE }}"
ENABLED_DOCKER_SERVICES: "${{ inputs.enabled_docker_services }}"
TEST: playwright
TEST_FILTER: "${{ inputs.test_filter }}"
BRANCH: "${{ inputs.branch }}-${{ inputs.test_type }}"
BUILD_ID: "${{ inputs.build_id }}"
steps:
- name: ci/checkout-repo
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
ref: ${{ inputs.commit_sha }}
fetch-depth: 0
- name: ci/setup-node
uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6.2.0
with:
node-version-file: ".nvmrc"
cache: npm
cache-dependency-path: "e2e-tests/playwright/package-lock.json"
- name: ci/get-webapp-node-modules
working-directory: webapp
run: make node_modules
- name: ci/run-tests
run: |
make cloud-init
make
- name: ci/cloud-teardown
if: always()
run: make cloud-teardown
- name: ci/upload-results
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
if: always()
with:
name: playwright-${{ inputs.test_type }}-${{ inputs.server_edition }}-results
path: |
e2e-tests/playwright/logs/
e2e-tests/playwright/results/
retention-days: 5
calculate-results:
runs-on: ubuntu-24.04
needs:
- run-tests
if: always()
outputs:
passed: ${{ steps.calculate.outputs.passed }}
failed: ${{ steps.calculate.outputs.failed }}
flaky: ${{ steps.calculate.outputs.flaky }}
skipped: ${{ steps.calculate.outputs.skipped }}
total_specs: ${{ steps.calculate.outputs.total_specs }}
failed_specs: ${{ steps.calculate.outputs.failed_specs }}
failed_specs_count: ${{ steps.calculate.outputs.failed_specs_count }}
failed_tests: ${{ steps.calculate.outputs.failed_tests }}
commit_status_message: ${{ steps.calculate.outputs.commit_status_message }}
total: ${{ steps.calculate.outputs.total }}
pass_rate: ${{ steps.calculate.outputs.pass_rate }}
passing: ${{ steps.calculate.outputs.passing }}
color: ${{ steps.calculate.outputs.color }}
steps:
- name: ci/checkout-repo
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- name: ci/download-results
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
with:
name: playwright-${{ inputs.test_type }}-${{ inputs.server_edition }}-results
path: e2e-tests/playwright/
- name: ci/calculate
id: calculate
uses: ./.github/actions/calculate-playwright-results
with:
original-results-path: e2e-tests/playwright/results/reporter/results.json
run-failed-tests:
runs-on: ubuntu-24.04
timeout-minutes: ${{ fromJSON(inputs.timeout_minutes) }}
needs:
- run-tests
- calculate-results
if: >-
always() &&
needs.calculate-results.result == 'success' &&
needs.calculate-results.outputs.failed != '0' &&
fromJSON(needs.calculate-results.outputs.failed_specs_count) <= 20
defaults:
run:
working-directory: e2e-tests
env:
SERVER: "${{ inputs.server }}"
MM_LICENSE: "${{ secrets.MM_LICENSE }}"
ENABLED_DOCKER_SERVICES: "${{ inputs.enabled_docker_services }}"
TEST: playwright
BRANCH: "${{ inputs.branch }}-${{ inputs.test_type }}-retest"
BUILD_ID: "${{ inputs.build_id }}-retest"
steps:
- name: ci/checkout-repo
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
ref: ${{ inputs.commit_sha }}
fetch-depth: 0
- name: ci/setup-node
uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6.2.0
with:
node-version-file: ".nvmrc"
cache: npm
cache-dependency-path: "e2e-tests/playwright/package-lock.json"
- name: ci/get-webapp-node-modules
working-directory: webapp
run: make node_modules
- name: ci/run-failed-specs
env:
SPEC_FILES: ${{ needs.calculate-results.outputs.failed_specs }}
run: |
echo "Retesting failed specs: $SPEC_FILES"
make cloud-init
make start-server run-specs
- name: ci/cloud-teardown
if: always()
run: make cloud-teardown
- name: ci/upload-retest-results
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
if: always()
with:
name: playwright-${{ inputs.test_type }}-${{ inputs.server_edition }}-retest-results
path: |
e2e-tests/playwright/logs/
e2e-tests/playwright/results/
retention-days: 5
report:
runs-on: ubuntu-24.04
needs:
- run-tests
- calculate-results
- run-failed-tests
if: always() && needs.calculate-results.result == 'success'
outputs:
passed: "${{ steps.final-results.outputs.passed }}"
failed: "${{ steps.final-results.outputs.failed }}"
commit_status_message: "${{ steps.final-results.outputs.commit_status_message }}"
report_url: "${{ steps.upload-to-s3.outputs.report_url }}"
defaults:
run:
working-directory: e2e-tests
steps:
- name: ci/checkout-repo
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- name: ci/setup-node
uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6.2.0
with:
node-version-file: ".nvmrc"
cache: npm
cache-dependency-path: "e2e-tests/playwright/package-lock.json"
# Download original results (always needed)
- name: ci/download-results
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
with:
name: playwright-${{ inputs.test_type }}-${{ inputs.server_edition }}-results
path: e2e-tests/playwright/
# Download retest results (only if retest ran)
- name: ci/download-retest-results
if: needs.run-failed-tests.result != 'skipped'
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
with:
name: playwright-${{ inputs.test_type }}-${{ inputs.server_edition }}-retest-results
path: e2e-tests/playwright/retest-results/
# Calculate results (with optional merge of retest results)
- name: ci/calculate-results
id: final-results
uses: ./.github/actions/calculate-playwright-results
with:
original-results-path: e2e-tests/playwright/results/reporter/results.json
retest-results-path: ${{ needs.run-failed-tests.result != 'skipped' && 'e2e-tests/playwright/retest-results/results/reporter/results.json' || '' }}
- name: ci/aws-configure
uses: aws-actions/configure-aws-credentials@61815dcd50bd041e203e49132bacad1fd04d2708 # v5.1.1
with:
aws-region: us-east-1
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
- name: ci/upload-to-s3
id: upload-to-s3
env:
AWS_REGION: us-east-1
AWS_S3_BUCKET: mattermost-cypress-report
PR_NUMBER: "${{ inputs.pr_number }}"
RUN_ID: "${{ github.run_id }}"
COMMIT_SHA: "${{ inputs.commit_sha }}"
TEST_TYPE: "${{ inputs.test_type }}"
run: |
LOCAL_RESULTS_PATH="playwright/results/"
LOCAL_LOGS_PATH="playwright/logs/"
# Use PR number if available, otherwise use commit SHA prefix
if [ -n "$PR_NUMBER" ]; then
S3_PATH="server-pr-${PR_NUMBER}/e2e-reports/playwright-${TEST_TYPE}/${RUN_ID}"
else
S3_PATH="server-commit-${COMMIT_SHA::7}/e2e-reports/playwright-${TEST_TYPE}/${RUN_ID}"
fi
if [[ -d "$LOCAL_RESULTS_PATH" ]]; then
aws s3 sync "$LOCAL_RESULTS_PATH" "s3://${AWS_S3_BUCKET}/${S3_PATH}/results/" \
--acl public-read --cache-control "no-cache"
fi
REPORT_URL="https://${AWS_S3_BUCKET}.s3.amazonaws.com/${S3_PATH}/results/reporter/index.html"
echo "report_url=$REPORT_URL" >> "$GITHUB_OUTPUT"
- name: ci/publish-report
if: inputs.enable_reporting && env.REPORT_WEBHOOK_URL != ''
env:
REPORT_WEBHOOK_URL: ${{ secrets.REPORT_WEBHOOK_URL }}
COMMIT_STATUS_MESSAGE: ${{ steps.final-results.outputs.commit_status_message }}
COLOR: ${{ steps.final-results.outputs.color }}
REPORT_URL: ${{ steps.upload-to-s3.outputs.report_url }}
TEST_TYPE: ${{ inputs.test_type }}
REPORT_TYPE: ${{ inputs.report_type }}
COMMIT_SHA: ${{ inputs.commit_sha }}
REF_BRANCH: ${{ inputs.ref_branch }}
PR_NUMBER: ${{ inputs.pr_number }}
run: |
# Capitalize test type
TEST_TYPE_CAP=$(echo "$TEST_TYPE" | sed 's/.*/\u&/')
# Build source line based on report type
COMMIT_SHORT="${COMMIT_SHA::7}"
COMMIT_URL="https://github.com/${{ github.repository }}/commit/${COMMIT_SHA}"
if [ "$REPORT_TYPE" = "RELEASE_CUT" ]; then
SOURCE_LINE=":github_round: [${COMMIT_SHORT}](${COMMIT_URL}) on \`${REF_BRANCH}\`"
elif [ "$REPORT_TYPE" = "MASTER" ] || [ "$REPORT_TYPE" = "RELEASE" ]; then
SOURCE_LINE=":git_merge: [${COMMIT_SHORT}](${COMMIT_URL}) on \`${REF_BRANCH}\`"
else
SOURCE_LINE=":open-pull-request: [mattermost-pr-${PR_NUMBER}](https://github.com/${{ github.repository }}/pull/${PR_NUMBER})"
fi
# Build payload with attachments
PAYLOAD=$(cat <<EOF
{
"username": "E2E Test",
"icon_url": "https://mattermost.com/wp-content/uploads/2022/02/icon_WS.png",
"attachments": [{
"color": "${COLOR}",
"text": "**Results - Playwright ${TEST_TYPE_CAP} Tests**\n\n${SOURCE_LINE}\n:docker: \`${{ env.SERVER_IMAGE }}\`\n${COMMIT_STATUS_MESSAGE} | [full report](${REPORT_URL})"
}]
}
EOF
)
# Send to webhook
curl -X POST -H "Content-Type: application/json" -d "$PAYLOAD" "$REPORT_WEBHOOK_URL"
- name: ci/write-job-summary
if: always()
env:
REPORT_URL: ${{ steps.upload-to-s3.outputs.report_url }}
TEST_TYPE: ${{ inputs.test_type }}
PASSED: ${{ steps.final-results.outputs.passed }}
FAILED: ${{ steps.final-results.outputs.failed }}
FLAKY: ${{ steps.final-results.outputs.flaky }}
SKIPPED: ${{ steps.final-results.outputs.skipped }}
TOTAL_SPECS: ${{ steps.final-results.outputs.total_specs }}
FAILED_SPECS_COUNT: ${{ steps.final-results.outputs.failed_specs_count }}
FAILED_SPECS: ${{ steps.final-results.outputs.failed_specs }}
COMMIT_STATUS_MESSAGE: ${{ steps.final-results.outputs.commit_status_message }}
FAILED_TESTS: ${{ steps.final-results.outputs.failed_tests }}
run: |
{
echo "## E2E Test Results - Playwright ${TEST_TYPE}"
echo ""
if [ "$FAILED" = "0" ]; then
echo "All tests passed: **${PASSED} passed**"
else
echo "<details>"
echo "<summary>${FAILED} failed, ${PASSED} passed</summary>"
echo ""
echo "| Test | File |"
echo "|------|------|"
echo "${FAILED_TESTS}"
echo "</details>"
fi
echo ""
echo "### Calculation Outputs"
echo ""
echo "| Output | Value |"
echo "|--------|-------|"
echo "| passed | ${PASSED} |"
echo "| failed | ${FAILED} |"
echo "| flaky | ${FLAKY} |"
echo "| skipped | ${SKIPPED} |"
echo "| total_specs | ${TOTAL_SPECS} |"
echo "| failed_specs_count | ${FAILED_SPECS_COUNT} |"
echo "| commit_status_message | ${COMMIT_STATUS_MESSAGE} |"
echo "| failed_specs | ${FAILED_SPECS:-none} |"
echo ""
echo "---"
echo "[View Full Report](${REPORT_URL})"
} >> $GITHUB_STEP_SUMMARY
- name: ci/assert-results
run: |
[ "${{ steps.final-results.outputs.failed }}" = "0" ]
update-success-status:
runs-on: ubuntu-24.04
if: always() && needs.report.result == 'success' && needs.calculate-results.result == 'success'
needs:
- calculate-results
- report
steps:
- uses: mattermost/actions/delivery/update-commit-status@f324ac89b05cc3511cb06e60642ac2fb829f0a63
env:
GITHUB_TOKEN: ${{ github.token }}
with:
repository_full_name: ${{ github.repository }}
commit_sha: ${{ inputs.commit_sha }}
context: ${{ inputs.context_name }}
description: "${{ needs.report.outputs.commit_status_message }}, image_tag:${{ inputs.server_image_tag }}${{ inputs.server_image_aliases && format(' ({0})', inputs.server_image_aliases) || '' }}"
status: success
target_url: ${{ needs.report.outputs.report_url }}
update-failure-status:
runs-on: ubuntu-24.04
if: always() && (needs.report.result != 'success' || needs.calculate-results.result != 'success')
needs:
- calculate-results
- report
steps:
- uses: mattermost/actions/delivery/update-commit-status@f324ac89b05cc3511cb06e60642ac2fb829f0a63
env:
GITHUB_TOKEN: ${{ github.token }}
with:
repository_full_name: ${{ github.repository }}
commit_sha: ${{ inputs.commit_sha }}
context: ${{ inputs.context_name }}
description: "${{ needs.report.outputs.commit_status_message }}, image_tag:${{ inputs.server_image_tag }}${{ inputs.server_image_aliases && format(' ({0})', inputs.server_image_aliases) || '' }}"
status: failure
target_url: ${{ needs.report.outputs.report_url }}

View file

@ -0,0 +1,181 @@
---
name: E2E Tests - Playwright
on:
workflow_call:
inputs:
commit_sha:
type: string
required: true
enable_reporting:
type: boolean
required: false
default: false
server:
type: string
required: false
default: onprem
report_type:
type: string
required: false
pr_number:
type: string
required: false
server_image_tag:
type: string
required: false
description: "Server image tag (e.g., master or short SHA)"
server_edition:
type: string
required: false
description: "Server edition: enterprise (default), fips, or team"
server_image_repo:
type: string
required: false
default: mattermostdevelopment
description: "Docker registry: mattermostdevelopment (default) or mattermost"
skip_smoke:
type: boolean
required: false
default: false
description: "Skip smoke tests and run full tests directly"
server_image_aliases:
type: string
required: false
description: "Comma-separated alias tags for context name (e.g., 'release-11.4, release-11')"
ref_branch:
type: string
required: false
description: "Source branch name for webhook messages (e.g., 'master' or 'release-11.4')"
secrets:
MM_LICENSE:
required: false
REPORT_WEBHOOK_URL:
required: false
AWS_ACCESS_KEY_ID:
required: true
AWS_SECRET_ACCESS_KEY:
required: true
jobs:
generate-build-variables:
runs-on: ubuntu-24.04
outputs:
branch: "${{ steps.build-vars.outputs.branch }}"
build_id: "${{ steps.build-vars.outputs.build_id }}"
server_image_tag: "${{ steps.build-vars.outputs.server_image_tag }}"
server_image: "${{ steps.build-vars.outputs.server_image }}"
steps:
- name: ci/generate-build-variables
id: build-vars
env:
COMMIT_SHA: ${{ inputs.commit_sha }}
PR_NUMBER: ${{ inputs.pr_number }}
INPUT_SERVER_IMAGE_TAG: ${{ inputs.server_image_tag }}
RUN_ID: ${{ github.run_id }}
RUN_ATTEMPT: ${{ github.run_attempt }}
run: |
# Use provided server_image_tag or derive from commit SHA
if [ -n "$INPUT_SERVER_IMAGE_TAG" ]; then
SERVER_IMAGE_TAG="$INPUT_SERVER_IMAGE_TAG"
else
SERVER_IMAGE_TAG="${COMMIT_SHA::7}"
fi
# Validate server_image_tag format (alphanumeric, dots, hyphens, underscores)
if ! [[ "$SERVER_IMAGE_TAG" =~ ^[a-zA-Z0-9._-]+$ ]]; then
echo "::error::Invalid server_image_tag format: ${SERVER_IMAGE_TAG}"
exit 1
fi
echo "server_image_tag=${SERVER_IMAGE_TAG}" >> $GITHUB_OUTPUT
# Generate branch name
REF_BRANCH="${{ inputs.ref_branch }}"
if [ -n "$PR_NUMBER" ]; then
echo "branch=server-pr-${PR_NUMBER}" >> $GITHUB_OUTPUT
elif [ -n "$REF_BRANCH" ]; then
echo "branch=server-${REF_BRANCH}-${SERVER_IMAGE_TAG}" >> $GITHUB_OUTPUT
else
echo "branch=server-commit-${SERVER_IMAGE_TAG}" >> $GITHUB_OUTPUT
fi
# Determine server image name
EDITION="${{ inputs.server_edition }}"
REPO="${{ inputs.server_image_repo }}"
REPO="${REPO:-mattermostdevelopment}"
case "$EDITION" in
fips) IMAGE_NAME="mattermost-enterprise-fips-edition" ;;
team) IMAGE_NAME="mattermost-team-edition" ;;
*) IMAGE_NAME="mattermost-enterprise-edition" ;;
esac
SERVER_IMAGE="${REPO}/${IMAGE_NAME}:${SERVER_IMAGE_TAG}"
echo "server_image=${SERVER_IMAGE}" >> $GITHUB_OUTPUT
# Validate server_image_aliases format if provided
ALIASES="${{ inputs.server_image_aliases }}"
if [ -n "$ALIASES" ] && ! [[ "$ALIASES" =~ ^[a-zA-Z0-9._,\ -]+$ ]]; then
echo "::error::Invalid server_image_aliases format: ${ALIASES}"
exit 1
fi
# Generate build ID
if [ -n "$EDITION" ] && [ "$EDITION" != "enterprise" ]; then
echo "build_id=${RUN_ID}_${RUN_ATTEMPT}-${SERVER_IMAGE_TAG}-playwright-onprem-${EDITION}" >> $GITHUB_OUTPUT
else
echo "build_id=${RUN_ID}_${RUN_ATTEMPT}-${SERVER_IMAGE_TAG}-playwright-onprem-ent" >> $GITHUB_OUTPUT
fi
playwright-smoke:
if: ${{ !inputs.skip_smoke }}
needs:
- generate-build-variables
uses: ./.github/workflows/e2e-tests-playwright-template.yml
with:
test_type: smoke
test_filter: "--grep @smoke"
timeout_minutes: 30
enabled_docker_services: "postgres inbucket"
commit_sha: ${{ inputs.commit_sha }}
branch: ${{ needs.generate-build-variables.outputs.branch }}
build_id: ${{ needs.generate-build-variables.outputs.build_id }}
server_image_tag: ${{ needs.generate-build-variables.outputs.server_image_tag }}
server_edition: ${{ inputs.server_edition }}
server_image_repo: ${{ inputs.server_image_repo }}
server_image_aliases: ${{ inputs.server_image_aliases }}
server: ${{ inputs.server }}
context_name: "e2e-test/playwright-smoke/${{ inputs.server_edition || 'enterprise' }}"
pr_number: ${{ inputs.pr_number }}
secrets:
MM_LICENSE: ${{ secrets.MM_LICENSE }}
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
# Full Tests (runs if smoke passed or skipped)
playwright-full:
needs:
- playwright-smoke
- generate-build-variables
if: always() && (needs.playwright-smoke.result == 'skipped' || needs.playwright-smoke.outputs.failed == '0')
uses: ./.github/workflows/e2e-tests-playwright-template.yml
with:
test_type: full
test_filter: '--grep-invert "@visual"'
timeout_minutes: 120
enabled_docker_services: "postgres inbucket minio openldap elasticsearch keycloak"
commit_sha: ${{ inputs.commit_sha }}
branch: ${{ needs.generate-build-variables.outputs.branch }}
build_id: ${{ needs.generate-build-variables.outputs.build_id }}
server_image_tag: ${{ needs.generate-build-variables.outputs.server_image_tag }}
server_edition: ${{ inputs.server_edition }}
server_image_repo: ${{ inputs.server_image_repo }}
server_image_aliases: ${{ inputs.server_image_aliases }}
server: ${{ inputs.server }}
enable_reporting: ${{ inputs.enable_reporting }}
report_type: ${{ inputs.report_type }}
ref_branch: ${{ inputs.ref_branch }}
pr_number: ${{ inputs.pr_number }}
context_name: "e2e-test/playwright-full/${{ inputs.server_edition || 'enterprise' }}"
secrets:
MM_LICENSE: ${{ secrets.MM_LICENSE }}
REPORT_WEBHOOK_URL: ${{ secrets.REPORT_WEBHOOK_URL }}
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}

View file

@ -0,0 +1,150 @@
---
name: "E2E Tests/verified"
on:
pull_request:
types: [labeled]
env:
REPORT_WEBHOOK_URL: ${{ secrets.MM_E2E_REPORT_WEBHOOK_URL }}
jobs:
approve-e2e:
if: github.event.label.name == 'E2E Tests/verified'
runs-on: ubuntu-24.04
steps:
- name: ci/check-user-permission
id: check-permission
env:
GH_TOKEN: ${{ github.token }}
LABEL_AUTHOR: ${{ github.event.sender.login }}
run: |
# Check if user has write permission to the repository
PERMISSION=$(gh api repos/${{ github.repository }}/collaborators/${LABEL_AUTHOR}/permission --jq '.permission' 2>/dev/null || echo "none")
if [[ "$PERMISSION" != "admin" && "$PERMISSION" != "write" ]]; then
echo "User ${LABEL_AUTHOR} doesn't have write permission to the repository (permission: ${PERMISSION})"
exit 1
fi
echo "User ${LABEL_AUTHOR} has ${PERMISSION} permission to the repository"
- name: ci/override-failed-statuses
id: override
env:
GH_TOKEN: ${{ github.token }}
COMMIT_SHA: ${{ github.event.pull_request.head.sha }}
run: |
# Only full tests can be overridden (smoke tests must pass)
FULL_TEST_CONTEXTS=("e2e-test/playwright-full/enterprise" "e2e-test/cypress-full/enterprise")
OVERRIDDEN=""
WEBHOOK_DATA="[]"
for CONTEXT_NAME in "${FULL_TEST_CONTEXTS[@]}"; do
echo "Checking: $CONTEXT_NAME"
# Get current status
STATUS_JSON=$(gh api repos/${{ github.repository }}/commits/${COMMIT_SHA}/statuses \
--jq "[.[] | select(.context == \"$CONTEXT_NAME\")] | first // empty")
if [ -z "$STATUS_JSON" ]; then
echo " No status found, skipping"
continue
fi
CURRENT_DESC=$(echo "$STATUS_JSON" | jq -r '.description // ""')
CURRENT_URL=$(echo "$STATUS_JSON" | jq -r '.target_url // ""')
CURRENT_STATE=$(echo "$STATUS_JSON" | jq -r '.state // ""')
echo " Current: $CURRENT_DESC ($CURRENT_STATE)"
# Only override if status is failure
if [ "$CURRENT_STATE" != "failure" ]; then
echo " Not failed, skipping"
continue
fi
# Prefix existing description
if [ -n "$CURRENT_DESC" ]; then
NEW_MSG="(verified) ${CURRENT_DESC}"
else
NEW_MSG="(verified)"
fi
echo " New: $NEW_MSG"
# Update status via GitHub API
gh api repos/${{ github.repository }}/statuses/${COMMIT_SHA} \
-f state=success \
-f context="$CONTEXT_NAME" \
-f description="$NEW_MSG" \
-f target_url="$CURRENT_URL"
echo " Updated to success"
OVERRIDDEN="${OVERRIDDEN}- ${CONTEXT_NAME}\n"
# Collect data for webhook
TEST_TYPE="unknown"
if [[ "$CONTEXT_NAME" == *"playwright"* ]]; then
TEST_TYPE="playwright"
elif [[ "$CONTEXT_NAME" == *"cypress"* ]]; then
TEST_TYPE="cypress"
fi
WEBHOOK_DATA=$(echo "$WEBHOOK_DATA" | jq \
--arg context "$CONTEXT_NAME" \
--arg test_type "$TEST_TYPE" \
--arg description "$CURRENT_DESC" \
--arg report_url "$CURRENT_URL" \
'. + [{context: $context, test_type: $test_type, description: $description, report_url: $report_url}]')
done
echo "overridden<<EOF" >> $GITHUB_OUTPUT
echo -e "$OVERRIDDEN" >> $GITHUB_OUTPUT
echo "EOF" >> $GITHUB_OUTPUT
echo "webhook_data<<EOF" >> $GITHUB_OUTPUT
echo "$WEBHOOK_DATA" >> $GITHUB_OUTPUT
echo "EOF" >> $GITHUB_OUTPUT
- name: ci/build-webhook-message
if: env.REPORT_WEBHOOK_URL != '' && steps.override.outputs.overridden != ''
id: webhook-message
env:
WEBHOOK_DATA: ${{ steps.override.outputs.webhook_data }}
run: |
MESSAGE_TEXT=""
while IFS= read -r item; do
[ -z "$item" ] && continue
CONTEXT=$(echo "$item" | jq -r '.context')
DESCRIPTION=$(echo "$item" | jq -r '.description')
REPORT_URL=$(echo "$item" | jq -r '.report_url')
MESSAGE_TEXT="${MESSAGE_TEXT}- **${CONTEXT}**: ${DESCRIPTION}, [view report](${REPORT_URL})\n"
done < <(echo "$WEBHOOK_DATA" | jq -c '.[]')
{
echo "message_text<<EOF"
echo -e "$MESSAGE_TEXT"
echo "EOF"
} >> $GITHUB_OUTPUT
- name: ci/send-webhook-notification
if: env.REPORT_WEBHOOK_URL != '' && steps.override.outputs.overridden != ''
env:
REPORT_WEBHOOK_URL: ${{ env.REPORT_WEBHOOK_URL }}
MESSAGE_TEXT: ${{ steps.webhook-message.outputs.message_text }}
PR_NUMBER: ${{ github.event.pull_request.number }}
PR_URL: ${{ github.event.pull_request.html_url }}
COMMIT_SHA: ${{ github.event.pull_request.head.sha }}
SENDER: ${{ github.event.sender.login }}
run: |
PAYLOAD=$(cat <<EOF
{
"username": "E2E Test",
"icon_url": "https://mattermost.com/wp-content/uploads/2022/02/icon_WS.png",
"text": "**:white_check_mark: E2E Tests Verified**\n\nBy: \`@${SENDER}\` via \`E2E Tests/verified\` trigger-label\n:open-pull-request: [mattermost-pr-${PR_NUMBER}](${PR_URL}), commit: \`${COMMIT_SHA:0:7}\`\n\n${MESSAGE_TEXT}"
}
EOF
)
curl -X POST -H "Content-Type: application/json" -d "$PAYLOAD" "$REPORT_WEBHOOK_URL"

View file

@ -46,7 +46,7 @@ jobs:
echo "BUILD_IMAGE=mattermost/mattermost-build-server-fips:${{ inputs.go-version }}" >> "${GITHUB_OUTPUT}"
echo "LOG_ARTIFACT_NAME=${{ inputs.logsartifact }}-fips" >> "${GITHUB_OUTPUT}"
else
echo "BUILD_IMAGE=mattermostdevelopment/mattermost-build-server:${{ inputs.go-version }}" >> "${GITHUB_OUTPUT}"
echo "BUILD_IMAGE=mattermost/mattermost-build-server:${{ inputs.go-version }}" >> "${GITHUB_OUTPUT}"
echo "LOG_ARTIFACT_NAME=${{ inputs.logsartifact }}" >> "${GITHUB_OUTPUT}"
fi

View file

@ -17,7 +17,7 @@ jobs:
if: github.repository_owner == 'mattermost' && github.event.workflow_run.event == 'pull_request' && github.event.workflow_run.conclusion == 'success'
runs-on: ubuntu-22.04
steps:
- uses: mattermost/actions/delivery/update-commit-status@d5174b860704729f4c14ef8489ae075742bfa08a
- uses: mattermost/actions/delivery/update-commit-status@f324ac89b05cc3511cb06e60642ac2fb829f0a63
env:
GITHUB_TOKEN: ${{ github.token }}
with:
@ -155,7 +155,7 @@ jobs:
needs:
- build-docker
steps:
- uses: mattermost/actions/delivery/update-commit-status@d5174b860704729f4c14ef8489ae075742bfa08a
- uses: mattermost/actions/delivery/update-commit-status@f324ac89b05cc3511cb06e60642ac2fb829f0a63
env:
GITHUB_TOKEN: ${{ github.token }}
with:
@ -171,7 +171,7 @@ jobs:
needs:
- build-docker
steps:
- uses: mattermost/actions/delivery/update-commit-status@d5174b860704729f4c14ef8489ae075742bfa08a
- uses: mattermost/actions/delivery/update-commit-status@f324ac89b05cc3511cb06e60642ac2fb829f0a63
env:
GITHUB_TOKEN: ${{ github.token }}
with:

View file

@ -12,7 +12,6 @@ on:
pull_request:
paths:
- "server/**"
- "e2e-tests/**"
- ".github/workflows/server-ci.yml"
- ".github/workflows/server-test-template.yml"
- ".github/workflows/mmctl-test-template.yml"
@ -40,7 +39,7 @@ jobs:
name: Check mocks
needs: go
runs-on: ubuntu-22.04
container: mattermostdevelopment/mattermost-build-server:${{ needs.go.outputs.version }}
container: mattermost/mattermost-build-server:${{ needs.go.outputs.version }}
defaults:
run:
working-directory: server
@ -57,7 +56,7 @@ jobs:
name: Check go mod tidy
needs: go
runs-on: ubuntu-22.04
container: mattermostdevelopment/mattermost-build-server:${{ needs.go.outputs.version }}
container: mattermost/mattermost-build-server:${{ needs.go.outputs.version }}
defaults:
run:
working-directory: server
@ -74,7 +73,7 @@ jobs:
name: check-style
needs: go
runs-on: ubuntu-22.04
container: mattermostdevelopment/mattermost-build-server:${{ needs.go.outputs.version }}
container: mattermost/mattermost-build-server:${{ needs.go.outputs.version }}
defaults:
run:
working-directory: server
@ -91,7 +90,7 @@ jobs:
name: Check serialization methods for hot structs
needs: go
runs-on: ubuntu-22.04
container: mattermostdevelopment/mattermost-build-server:${{ needs.go.outputs.version }}
container: mattermost/mattermost-build-server:${{ needs.go.outputs.version }}
defaults:
run:
working-directory: server
@ -108,7 +107,7 @@ jobs:
name: Vet API
needs: go
runs-on: ubuntu-22.04
container: mattermostdevelopment/mattermost-build-server:${{ needs.go.outputs.version }}
container: mattermost/mattermost-build-server:${{ needs.go.outputs.version }}
defaults:
run:
working-directory: server
@ -123,7 +122,7 @@ jobs:
name: Check migration files
needs: go
runs-on: ubuntu-22.04
container: mattermostdevelopment/mattermost-build-server:${{ needs.go.outputs.version }}
container: mattermost/mattermost-build-server:${{ needs.go.outputs.version }}
defaults:
run:
working-directory: server
@ -138,7 +137,7 @@ jobs:
name: Generate email templates
needs: go
runs-on: ubuntu-22.04
container: mattermostdevelopment/mattermost-build-server:${{ needs.go.outputs.version }}
container: mattermost/mattermost-build-server:${{ needs.go.outputs.version }}
defaults:
run:
working-directory: server
@ -155,7 +154,7 @@ jobs:
name: Check store layers
needs: go
runs-on: ubuntu-22.04
container: mattermostdevelopment/mattermost-build-server:${{ needs.go.outputs.version }}
container: mattermost/mattermost-build-server:${{ needs.go.outputs.version }}
defaults:
run:
working-directory: server
@ -172,7 +171,7 @@ jobs:
name: Check mmctl docs
needs: go
runs-on: ubuntu-22.04
container: mattermostdevelopment/mattermost-build-server:${{ needs.go.outputs.version }}
container: mattermost/mattermost-build-server:${{ needs.go.outputs.version }}
defaults:
run:
working-directory: server
@ -227,8 +226,9 @@ jobs:
fips-enabled: true
test-coverage:
name: Generate Test Coverage
# Skip coverage generation for cherry-pick PRs into release branches.
if: ${{ github.event_name != 'pull_request' || !startsWith(github.event.pull_request.base.ref, 'release-') }}
# Disabled: Running out of memory and causing spurious failures.
# Old condition: ${{ github.event_name != 'pull_request' || !startsWith(github.event.pull_request.base.ref, 'release-') }}
if: false
needs: go
uses: ./.github/workflows/server-test-template.yml
secrets: inherit
@ -270,7 +270,7 @@ jobs:
name: Build mattermost server app
needs: go
runs-on: ubuntu-22.04
container: mattermostdevelopment/mattermost-build-server:${{ needs.go.outputs.version }}
container: mattermost/mattermost-build-server:${{ needs.go.outputs.version }}
defaults:
run:
working-directory: server
@ -281,6 +281,12 @@ jobs:
steps:
- name: Checkout mattermost project
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: ci/setup-node
uses: actions/setup-node@395ad3262231945c25e8478fd5baf05154b1d79f # v6.1.0
with:
node-version-file: ".nvmrc"
cache: "npm"
cache-dependency-path: "webapp/package-lock.json"
- name: Run setup-go-work
run: make setup-go-work
- name: Build

View file

@ -59,7 +59,7 @@ jobs:
echo "BUILD_IMAGE=mattermost/mattermost-build-server-fips:${{ inputs.go-version }}" >> "${GITHUB_OUTPUT}"
echo "LOG_ARTIFACT_NAME=${{ inputs.logsartifact }}-fips" >> "${GITHUB_OUTPUT}"
else
echo "BUILD_IMAGE=mattermostdevelopment/mattermost-build-server:${{ inputs.go-version }}" >> "${GITHUB_OUTPUT}"
echo "BUILD_IMAGE=mattermost/mattermost-build-server:${{ inputs.go-version }}" >> "${GITHUB_OUTPUT}"
echo "LOG_ARTIFACT_NAME=${{ inputs.logsartifact }}" >> "${GITHUB_OUTPUT}"
fi

View file

@ -7,7 +7,6 @@ on:
pull_request:
paths:
- "webapp/**"
- "e2e-tests/**"
- ".github/workflows/webapp-ci.yml"
- ".github/actions/webapp-setup/**"
@ -41,18 +40,10 @@ jobs:
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: ci/setup
uses: ./.github/actions/webapp-setup
- name: ci/lint
- name: ci/i18n-extract
working-directory: webapp/channels
run: |
cp src/i18n/en.json /tmp/en.json
mkdir -p /tmp/fake-mobile-dir/assets/base/i18n/
echo '{}' > /tmp/fake-mobile-dir/assets/base/i18n/en.json
npm run mmjstool -- i18n extract-webapp --webapp-dir ./src --mobile-dir /tmp/fake-mobile-dir
diff /tmp/en.json src/i18n/en.json
# Address weblate behavior which does not remove whole translation item when translation string is set to empty
npm run mmjstool -- i18n clean-empty --webapp-dir ./src --mobile-dir /tmp/fake-mobile-dir --check
npm run mmjstool -- i18n check-empty-src --webapp-dir ./src --mobile-dir /tmp/fake-mobile-dir
rm -rf tmp
npm run i18n-extract:check
check-types:
needs: check-lint

2
.gitignore vendored
View file

@ -161,5 +161,5 @@ docker-compose.override.yaml
.env
**/CLAUDE.local.md
CLAUDE.md
**/CLAUDE.md
.cursorrules

2
.nvmrc
View file

@ -1 +1 @@
20.11
24.11

View file

@ -2527,83 +2527,16 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
---
## Masterminds/semver
## LumenResearch/uasurfer
This product contains 'Masterminds/semver' by Masterminds.
Work with Semantic Versions in Go
* LICENSE: MIT License
Copyright (C) 2014-2019, Matt Butcher and Matt Farina
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
---
## anthonynsimon/bild
This product contains 'anthonynsimon/bild' by anthonynsimon.
Image processing algorithms in pure Go
* HOMEPAGE:
* https://github.com/anthonynsimon/bild
* LICENSE: MIT License
MIT License
Copyright (c) 2016-2024 Anthony Simon
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
---
## avct/uasurfer
This product contains 'uasurfer' by Avocet.
This product contains 'LumenResearch/uasurfer' by Lumen Research.
Go package for fast and reliable abstraction of browser user agent strings.
* HOMEPAGE:
* https://github.com/avct/uasurfer
* https://github.com/LumenResearch/uasurfer
* LICENSE: Apache-2.0
* LICENSE: Other
Apache License
@ -2798,6 +2731,73 @@ Go package for fast and reliable abstraction of browser user agent strings.
See the License for the specific language governing permissions and
limitations under the License.
---
## Masterminds/semver
This product contains 'Masterminds/semver' by Masterminds.
Work with Semantic Versions in Go
* LICENSE: MIT License
Copyright (C) 2014-2019, Matt Butcher and Matt Farina
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
---
## anthonynsimon/bild
This product contains 'anthonynsimon/bild' by anthonynsimon.
Image processing algorithms in pure Go
* HOMEPAGE:
* https://github.com/anthonynsimon/bild
* LICENSE: MIT License
MIT License
Copyright (c) 2016-2024 Anthony Simon
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
---
## aws/aws-sdk-go-v2
@ -5918,6 +5918,9 @@ This product contains 'h2non/go-is-svg' by Tom.
Check if a given buffer is a valid SVG image in Go (golang)
* HOMEPAGE:
* https://github.com/h2non/go-is-svg
* LICENSE: MIT License
The MIT License
@ -9692,41 +9695,6 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
---
## oov/psd
This product contains 'psd' by oov.
A PSD/PSB file reader for go
* HOMEPAGE:
* https://github.com/oov/psd
* LICENSE: MIT
MIT License
Copyright (c) 2016 oov
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
---
## opensearch-project/opensearch-go
@ -10893,6 +10861,21 @@ Internationalize React apps. This library provides React components and an API t
---
## react-intl
This product contains 'react-intl' by Eric Ferraiuolo.
Internationalize React apps. This library provides React components and an API to format dates, numbers, and strings, including pluralization and handling translations.
* HOMEPAGE:
* https://formatjs.github.io/docs/react-intl
* LICENSE: BSD-3-Clause
---
## react-is
@ -12897,6 +12880,48 @@ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
---
## x/sys
This product contains 'x/sys' by Go.
[mirror] Go packages for low-level interaction with the operating system
* HOMEPAGE:
* https://golang.org/x/sys
* LICENSE: BSD 3-Clause "New" or "Revised" License
Copyright 2009 The Go Authors.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following disclaimer
in the documentation and/or other materials provided with the
distribution.
* Neither the name of Google LLC nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
---
## x/term
@ -13048,5 +13073,3 @@ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

View file

@ -20,6 +20,8 @@ build-v4: node_modules playbooks
@cat $(V4_SRC)/posts.yaml >> $(V4_YAML)
@cat $(V4_SRC)/preferences.yaml >> $(V4_YAML)
@cat $(V4_SRC)/files.yaml >> $(V4_YAML)
@cat $(V4_SRC)/recaps.yaml >> $(V4_YAML)
@cat $(V4_SRC)/ai.yaml >> $(V4_YAML)
@cat $(V4_SRC)/uploads.yaml >> $(V4_YAML)
@cat $(V4_SRC)/jobs.yaml >> $(V4_YAML)
@cat $(V4_SRC)/system.yaml >> $(V4_YAML)

View file

@ -283,11 +283,16 @@
$ref: "#/components/responses/InternalServerError"
"/api/v4/access_control_policies/{policy_id}/activate":
get:
deprecated: true
tags:
- access control
summary: Activate or deactivate an access control policy
description: |
Updates the active status of an access control policy.
**Deprecated:** This endpoint will be removed in a future release. Use the dedicated access control policy update endpoint instead.
Link: </api/v4/access_control_policies/activate>; rel="successor-version"
##### Permissions
Must have the `manage_system` permission.
operationId: UpdateAccessControlPolicyActiveStatus

View file

@ -24,6 +24,32 @@
$ref: "#/components/responses/Unauthorized"
"500":
$ref: "#/components/responses/InternalServerError"
/api/v4/agents/status:
get:
tags:
- agents
summary: Get agents bridge status
description: >
Retrieve the status of the AI plugin bridge.
Returns availability boolean and a reason code if unavailable.
##### Permissions
Must be authenticated.
__Minimum server version__: 11.2
operationId: GetAgentsStatus
responses:
"200":
description: Status retrieved successfully
content:
application/json:
schema:
$ref: "#/components/schemas/AgentsIntegrityResponse"
"401":
$ref: "#/components/responses/Unauthorized"
"500":
$ref: "#/components/responses/InternalServerError"
/api/v4/llmservices:
get:
tags:

54
api/v4/source/ai.yaml Normal file
View file

@ -0,0 +1,54 @@
/api/v4/ai/agents:
get:
tags:
- ai
summary: Get available AI agents
description: >
Retrieve all available AI agents from the AI plugin's bridge API.
If a user ID is provided, only agents accessible to that user are returned.
##### Permissions
Must be authenticated.
__Minimum server version__: 11.2
operationId: GetAIAgents
responses:
"200":
description: AI agents retrieved successfully
content:
application/json:
schema:
$ref: "#/components/schemas/AgentsResponse"
"401":
$ref: "#/components/responses/Unauthorized"
"500":
$ref: "#/components/responses/InternalServerError"
/api/v4/ai/services:
get:
tags:
- ai
summary: Get available AI services
description: >
Retrieve all available AI services from the AI plugin's bridge API.
If a user ID is provided, only services accessible to that user
(via their permitted bots) are returned.
##### Permissions
Must be authenticated.
__Minimum server version__: 11.2
operationId: GetAIServices
responses:
"200":
description: AI services retrieved successfully
content:
application/json:
schema:
$ref: "#/components/schemas/ServicesResponse"
"401":
$ref: "#/components/responses/Unauthorized"
"500":
$ref: "#/components/responses/InternalServerError"

View file

@ -606,18 +606,36 @@
summary: Patch a channel
description: >
Partially update a channel by providing only the fields you want to
update. Omitted fields will not be updated. The fields that can be
updated are defined in the request body, all other provided fields will
be ignored.
update. Omitted fields will not be updated. At least one of the allowed
fields must be provided.
**Public and private channels:** Can update `name`, `display_name`,
`purpose`, `header`, `group_constrained`, `autotranslation`, and
`banner_info` (subject to permissions and channel type).
**Direct and group message channels:** Only `header` and (when not
restricted by config) `autotranslation` can be updated; the caller
must be a channel member. Updating `name`, `display_name`, or `purpose`
is not allowed.
The default channel (e.g. Town Square) cannot have its `name` changed.
##### Permissions
If updating a public channel, `manage_public_channel_members` permission is required. If updating a private channel, `manage_private_channel_members` permission is required.
- **Public channel:** For property updates (name, display_name, purpose, header, group_constrained),
`manage_public_channel_properties` is required. For `autotranslation`, `manage_public_channel_auto_translation`
is required. For `banner_info`, `manage_public_channel_banner` is required (Channel Banner feature and
Enterprise license required).
- **Private channel:** For property updates, `manage_private_channel_properties` is required. For
`autotranslation`, `manage_private_channel_auto_translation` is required. For `banner_info`,
`manage_private_channel_banner` is required (Channel Banner feature and Enterprise license required).
- **Direct or group message channel:** Must be a member of the channel; only `header` and (when allowed)
`autotranslation` can be updated.
operationId: PatchChannel
parameters:
- name: channel_id
in: path
description: Channel GUID
description: Channel ID
required: true
schema:
type: string
@ -630,20 +648,34 @@
name:
type: string
description: The unique handle for the channel, will be present in the
channel URL
channel URL. Cannot be updated for direct or group message channels.
Cannot be changed for the default channel (e.g. Town Square).
display_name:
type: string
description: The non-unique UI name for the channel
description: The non-unique UI name for the channel. Cannot be updated
for direct or group message channels.
purpose:
type: string
description: A short description of the purpose of the channel
description: A short description of the purpose of the channel. Cannot
be updated for direct or group message channels.
header:
type: string
description: Markdown-formatted text to display in the header of the
channel
group_constrained:
type: boolean
description: When true, only members of the linked LDAP groups can join
the channel. Only applicable to public and private channels.
autotranslation:
type: boolean
description: Enable or disable automatic message translation in the
channel. Requires the auto-translation feature and appropriate
channel permission. May be restricted for direct and group message
channels by server configuration.
banner_info:
$ref: "#/components/schemas/ChannelBanner"
description: Channel object to be updated
description: Channel patch object; include only the fields to update. At least
one field must be provided.
required: true
responses:
"200":
@ -1600,6 +1632,61 @@
$ref: "#/components/responses/Forbidden"
"404":
$ref: "#/components/responses/NotFound"
"/api/v4/channels/{channel_id}/members/{user_id}/autotranslation":
put:
tags:
- channels
summary: Update channel member autotranslation setting
description: >
Update a user's autotranslation setting for a channel. This controls whether
messages in the channel should not be automatically translated for the user.
By default, autotranslations are enabled for all users if the channel is enabled
for autotranslation.
##### Permissions
Must be logged in as the user or have `edit_other_users` permission.
operationId: UpdateChannelMemberAutotranslation
parameters:
- name: channel_id
in: path
description: Channel GUID
required: true
schema:
type: string
- name: user_id
in: path
description: User GUID
required: true
schema:
type: string
requestBody:
content:
application/json:
schema:
type: object
required:
- autotranslation_disabled
properties:
autotranslation_disabled:
type: boolean
description: Whether to disable autotranslation for the user in this channel
required: true
responses:
"200":
description: Channel member autotranslation setting update successful
content:
application/json:
schema:
$ref: "#/components/schemas/StatusOK"
"400":
$ref: "#/components/responses/BadRequest"
"401":
$ref: "#/components/responses/Unauthorized"
"403":
$ref: "#/components/responses/Forbidden"
"404":
$ref: "#/components/responses/NotFound"
"/api/v4/channels/members/{user_id}/view":
post:
tags:

View file

@ -360,6 +360,36 @@
$ref: "#/components/responses/Forbidden"
"501":
$ref: "#/components/responses/NotImplemented"
/api/v4/cloud/check-cws-connection:
get:
tags:
- cloud
summary: Check CWS connection
description: >
Checks whether the Customer Web Server (CWS) is reachable from this instance.
Used to detect if the deployment is air-gapped.
##### Permissions
No permissions required.
__Minimum server version__: 5.28
__Note:__ This is intended for internal use and is subject to change.
operationId: CheckCWSConnection
responses:
"200":
description: CWS connection status returned successfully
content:
application/json:
schema:
type: object
properties:
status:
type: string
description: Connection status - "available" if CWS is reachable, "unavailable" if not
enum:
- available
- unavailable
/api/v4/cloud/webhook:
post:
tags:

View file

@ -83,6 +83,17 @@
saml:
type: string
description: "SAML attribute for syncing"
protected:
type: boolean
description: "If true, the field is read-only and cannot be modified."
source_plugin_id:
type: string
description: "The ID of the plugin that created this field. This attribute cannot be changed."
access_mode:
type: string
description: "Access mode of the field"
enum: ["", "source_only", "shared_only"]
default: ""
responses:
"201":
description: Custom Profile Attribute field creation successful
@ -108,6 +119,9 @@
updated. The fields that can be updated are defined in the
request body, all other provided fields will be ignored.
**Note:** Fields with `attrs.protected = true` cannot be
modified and will return an error.
_This endpoint is experimental._
__Minimum server version__: 10.5
@ -167,6 +181,17 @@
saml:
type: string
description: "SAML attribute for syncing"
protected:
type: boolean
description: "If true, the field is read-only and cannot be modified."
source_plugin_id:
type: string
description: "The ID of the plugin that created this field. This attribute cannot be changed."
access_mode:
type: string
description: "Access mode of the field"
enum: ["", "source_only", "shared_only"]
default: ""
responses:
"200":
description: Custom Profile Attribute field patch successful
@ -229,6 +254,9 @@
that can be updated are defined in the request body, all other
provided fields will be ignored.
**Note:** Values for fields with `attrs.protected = true` cannot be
updated and will return an error.
_This endpoint is experimental._
__Minimum server version__: 10.5
@ -356,6 +384,9 @@
description: |
Update Custom Profile Attribute field values for a specific user.
**Note:** Values for fields with `attrs.protected = true` cannot be
updated and will return an error.
_This endpoint is experimental._
__Minimum server version__: 11

View file

@ -3704,7 +3704,7 @@ components:
type: array
description: list of users participating in this thread. only includes IDs unless 'extended' was set to 'true'
items:
$ref: "#/components/schemas/Post"
$ref: "#/components/schemas/User"
post:
$ref: "#/components/schemas/Post"
RelationalIntegrityCheckData:
@ -4048,6 +4048,15 @@ components:
items:
$ref: "#/components/schemas/BridgeServiceInfo"
description: List of available LLM services
AgentsIntegrityResponse:
type: object
properties:
available:
type: boolean
description: Whether the AI plugin bridge is available
reason:
type: string
description: Reason code if not available (translation ID)
PostAcknowledgement:
type: object
properties:
@ -4633,6 +4642,83 @@ components:
active:
type: boolean
description: The active status of the policy.
Recap:
type: object
properties:
id:
type: string
description: Unique identifier for the recap
user_id:
type: string
description: ID of the user who created the recap
title:
type: string
description: AI-generated title for the recap (max 5 words)
create_at:
type: integer
format: int64
description: The time in milliseconds the recap was created
update_at:
type: integer
format: int64
description: The time in milliseconds the recap was last updated
delete_at:
type: integer
format: int64
description: The time in milliseconds the recap was deleted
read_at:
type: integer
format: int64
description: The time in milliseconds the recap was marked as read
total_message_count:
type: integer
description: Total number of messages summarized across all channels
status:
type: string
enum: [pending, processing, completed, failed]
description: Current status of the recap job
bot_id:
type: string
description: ID of the AI agent/bot used to generate this recap
channels:
type: array
items:
$ref: "#/components/schemas/RecapChannel"
description: List of channel summaries included in this recap
RecapChannel:
type: object
properties:
id:
type: string
description: Unique identifier for the recap channel
recap_id:
type: string
description: ID of the parent recap
channel_id:
type: string
description: ID of the channel that was summarized
channel_name:
type: string
description: Display name of the channel
highlights:
type: array
items:
type: string
description: Key discussion points and important information from the channel
action_items:
type: array
items:
type: string
description: Tasks, todos, and action items mentioned in the channel
source_post_ids:
type: array
items:
type: string
description: IDs of the posts used to generate this summary
create_at:
type: integer
format: int64
description: The time in milliseconds the recap channel was created
externalDocs:
description: Find out more about Mattermost
url: 'https://about.mattermost.com'

View file

@ -462,8 +462,10 @@ tags:
description: Endpoints related to metrics, including the Client Performance Monitoring feature.
- name: audit_logs
description: Endpoints for managing audit log certificates and configuration.
- name: ai
description: Endpoints for interacting with AI agents and services.
- name: recaps
description: Endpoints for creating and managing AI-powered channel recaps that summarize unread messages.
- name: agents
description: Endpoints for interacting with AI agents and LLM services.
servers:
- url: "{your-mattermost-url}"
variables:

View file

@ -1162,6 +1162,109 @@
"501":
$ref: "#/components/responses/NotImplemented"
"/api/v4/posts/{post_id}/reveal":
get:
tags:
- posts
summary: Reveal a burn-on-read post
description: >
Reveal a burn-on-read post. This endpoint allows a user to reveal a post
that was created with burn-on-read functionality. Once revealed, the post
content becomes visible to the user. If the post is already revealed and
not expired, this is a no-op. If the post has expired, an error will be returned.
##### Permissions
Must have `read_channel` permission for the channel the post is in.<br/>
Must be a member of the channel the post is in.<br/>
Cannot reveal your own post.
##### Feature Flag
Requires `BurnOnRead` feature flag and Enterprise Advanced license.
__Minimum server version__: 11.2
operationId: RevealPost
parameters:
- name: post_id
in: path
description: The identifier of the post to reveal
required: true
schema:
type: string
responses:
"200":
description: Post revealed successfully
headers:
Has-Inaccessible-Posts:
schema:
type: boolean
description: This header is included with the value "true" if the post is past the cloud's plan limit.
content:
application/json:
schema:
$ref: "#/components/schemas/Post"
"400":
$ref: "#/components/responses/BadRequest"
"401":
$ref: "#/components/responses/Unauthorized"
"403":
$ref: "#/components/responses/Forbidden"
"501":
$ref: "#/components/responses/NotImplemented"
"/api/v4/posts/{post_id}/burn":
delete:
tags:
- posts
summary: Burn a burn-on-read post
description: >
Burn a burn-on-read post. This endpoint allows a user to burn a post that
was created with burn-on-read functionality. If the user is the author of
the post, the post will be permanently deleted. If the user is not the author,
the post will be expired for that user by updating their read receipt expiration
time. If the user has not revealed the post yet, an error will be returned.
If the post is already expired for the user, this is a no-op.
##### Permissions
Must have `read_channel` permission for the channel the post is in.<br/>
Must be a member of the channel the post is in.
##### Feature Flag
Requires `BurnOnRead` feature flag and Enterprise Advanced license.
__Minimum server version__: 11.2
operationId: BurnPost
parameters:
- name: post_id
in: path
description: The identifier of the post to burn
required: true
schema:
type: string
responses:
"200":
description: Post burned successfully
headers:
Has-Inaccessible-Posts:
schema:
type: boolean
description: This header is included with the value "true" if the post is past the cloud's plan limit.
content:
application/json:
schema:
$ref: "#/components/schemas/StatusOK"
"400":
$ref: "#/components/responses/BadRequest"
"401":
$ref: "#/components/responses/Unauthorized"
"403":
$ref: "#/components/responses/Forbidden"
"501":
$ref: "#/components/responses/NotImplemented"
"/api/v4/posts/rewrite":
post:
tags:

240
api/v4/source/recaps.yaml Normal file
View file

@ -0,0 +1,240 @@
"/api/v4/recaps":
post:
tags:
- recaps
- ai
summary: Create a channel recap
description: >
Create a new AI-powered recap for the specified channels. The recap will
summarize unread messages in the selected channels, extracting highlights
and action items. This creates a background job that processes the recap
asynchronously. The recap is created for the authenticated user.
##### Permissions
Must be authenticated. User must be a member of all specified channels.
__Minimum server version__: 11.2
operationId: CreateRecap
requestBody:
content:
application/json:
schema:
type: object
required:
- channel_ids
- title
- agent_id
properties:
title:
type: string
description: Title for the recap
channel_ids:
type: array
items:
type: string
description: List of channel IDs to include in the recap
minItems: 1
agent_id:
type: string
description: ID of the AI agent to use for generating the recap
description: Recap creation request
required: true
responses:
"201":
description: Recap creation successful. The recap will be processed asynchronously.
content:
application/json:
schema:
$ref: "#/components/schemas/Recap"
"400":
$ref: "#/components/responses/BadRequest"
"401":
$ref: "#/components/responses/Unauthorized"
"403":
$ref: "#/components/responses/Forbidden"
get:
tags:
- recaps
- ai
summary: Get current user's recaps
description: >
Get a paginated list of recaps created by the authenticated user.
##### Permissions
Must be authenticated.
__Minimum server version__: 11.2
operationId: GetRecapsForUser
parameters:
- name: page
in: query
description: The page to select.
schema:
type: integer
default: 0
- name: per_page
in: query
description: The number of recaps per page.
schema:
type: integer
default: 60
responses:
"200":
description: Recaps retrieval successful
content:
application/json:
schema:
type: array
items:
$ref: "#/components/schemas/Recap"
"400":
$ref: "#/components/responses/BadRequest"
"401":
$ref: "#/components/responses/Unauthorized"
"/api/v4/recaps/{recap_id}":
get:
tags:
- recaps
- ai
summary: Get a specific recap
description: >
Get a recap by its ID, including all channel summaries. Only the authenticated
user who created the recap can retrieve it.
##### Permissions
Must be authenticated. Can only retrieve recaps created by the current user.
__Minimum server version__: 11.2
operationId: GetRecap
parameters:
- name: recap_id
in: path
description: Recap GUID
required: true
schema:
type: string
responses:
"200":
description: Recap retrieval successful
content:
application/json:
schema:
$ref: "#/components/schemas/Recap"
"401":
$ref: "#/components/responses/Unauthorized"
"403":
$ref: "#/components/responses/Forbidden"
"404":
$ref: "#/components/responses/NotFound"
delete:
tags:
- recaps
- ai
summary: Delete a recap
description: >
Delete a recap by its ID. Only the authenticated user who created the recap
can delete it.
##### Permissions
Must be authenticated. Can only delete recaps created by the current user.
__Minimum server version__: 11.2
operationId: DeleteRecap
parameters:
- name: recap_id
in: path
description: Recap GUID
required: true
schema:
type: string
responses:
"200":
description: Recap deletion successful
content:
application/json:
schema:
$ref: "#/components/schemas/StatusOK"
"401":
$ref: "#/components/responses/Unauthorized"
"403":
$ref: "#/components/responses/Forbidden"
"404":
$ref: "#/components/responses/NotFound"
"/api/v4/recaps/{recap_id}/read":
post:
tags:
- recaps
- ai
summary: Mark a recap as read
description: >
Mark a recap as read by the authenticated user. This updates the recap's
read status and timestamp.
##### Permissions
Must be authenticated. Can only mark recaps created by the current user as read.
__Minimum server version__: 11.2
operationId: MarkRecapAsRead
parameters:
- name: recap_id
in: path
description: Recap GUID
required: true
schema:
type: string
responses:
"200":
description: Recap marked as read successfully
content:
application/json:
schema:
$ref: "#/components/schemas/Recap"
"401":
$ref: "#/components/responses/Unauthorized"
"403":
$ref: "#/components/responses/Forbidden"
"404":
$ref: "#/components/responses/NotFound"
"/api/v4/recaps/{recap_id}/regenerate":
post:
tags:
- recaps
- ai
summary: Regenerate a recap
description: >
Regenerate a recap by its ID. This creates a new background job to
regenerate the AI-powered recap with the latest messages from the
specified channels.
##### Permissions
Must be authenticated. Can only regenerate recaps created by the current user.
__Minimum server version__: 11.2
operationId: RegenerateRecap
parameters:
- name: recap_id
in: path
description: Recap GUID
required: true
schema:
type: string
responses:
"200":
description: Recap regeneration initiated successfully
content:
application/json:
schema:
$ref: "#/components/schemas/Recap"
"401":
$ref: "#/components/responses/Unauthorized"
"403":
$ref: "#/components/responses/Forbidden"
"404":
$ref: "#/components/responses/NotFound"

View file

@ -1366,6 +1366,18 @@
required: true
schema:
type: string
- name: graceful
in: query
description: If true, returns an array with both successful invites and errors instead of aborting on first error.
required: false
schema:
type: boolean
- name: guest_magic_link
in: query
description: If true, invites guests with magic link (passwordless) authentication. Requires guest magic link feature to be enabled.
required: false
schema:
type: boolean
requestBody:
content:
application/json:

View file

@ -27,6 +27,9 @@
password:
description: The password used for email authentication.
type: string
magic_link_token:
description: Magic link token for passwordless guest authentication. When provided, authenticates the user using the magic link token instead of password. Requires guest magic link feature to be enabled.
type: string
description: User authentication object
required: true
responses:

View file

@ -58,7 +58,7 @@ mme2e_wait_image () {
IMAGE_NAME=${1?}
RETRIES_LEFT=${2:-1}
RETRIES_INTERVAL=${3:-10}
mme2e_wait_command_success "docker pull $IMAGE_NAME" "Waiting for docker image ${IMAGE_NAME} to be available" "$RETRIES_LEFT" "$RETRIES_INTERVAL"
mme2e_wait_command_success "docker pull --platform linux/amd64 $IMAGE_NAME" "Waiting for docker image ${IMAGE_NAME} to be available" "$RETRIES_LEFT" "$RETRIES_INTERVAL"
}
mme2e_is_token_in_list() {
local TOKEN=$1
@ -98,7 +98,7 @@ case "${TEST:-$TEST_DEFAULT}" in
cypress )
export TEST_FILTER_DEFAULT='--stage=@prod --group=@smoke' ;;
playwright )
export TEST_FILTER_DEFAULT='functional/system_console/system_users/actions.spec.ts' ;;
export TEST_FILTER_DEFAULT='--grep @smoke' ;;
* )
export TEST_FILTER_DEFAULT='' ;;
esac

View file

@ -14,13 +14,16 @@ cd "$(dirname "$0")"
: ${WEBHOOK_URL:-} # Optional. Mattermost webhook to post the report back to
: ${RELEASE_DATE:-} # Optional. If set, its value will be included in the report as the release date of the tested artifact
if [ "$TYPE" = "PR" ]; then
# In this case, we expect the PR number to be present in the BRANCH variable
BRANCH_REGEX='^server-pr-[0-9]+$'
if ! grep -qE "${BRANCH_REGEX}" <<<"$BRANCH"; then
mme2e_log "Error: when using TYPE=PR, the BRANCH variable should respect regex '$BRANCH_REGEX'. Aborting." >&2
exit 1
# Try to determine PR number: first from PR_NUMBER, then from BRANCH (server-pr-XXXX format)
if [ -n "${PR_NUMBER:-}" ]; then
export PULL_REQUEST="https://github.com/mattermost/mattermost/pull/${PR_NUMBER}"
elif grep -qE '^server-pr-[0-9]+$' <<<"${BRANCH:-}"; then
PR_NUMBER="${BRANCH##*-}"
export PULL_REQUEST="https://github.com/mattermost/mattermost/pull/${PR_NUMBER}"
else
mme2e_log "Warning: TYPE=PR but cannot determine PR number from PR_NUMBER or BRANCH. Falling back to TYPE=NONE."
TYPE=NONE
fi
export PULL_REQUEST="https://github.com/mattermost/mattermost/pull/${BRANCH##*-}"
fi
# Env vars used during the test. Their values will be included in the report

View file

@ -48,6 +48,7 @@ generate_docker_compose_file() {
services:
server:
image: \${SERVER_IMAGE}
platform: linux/amd64
restart: always
env_file:
- "./.env.server"
@ -260,7 +261,7 @@ $(if mme2e_is_token_in_list "webhook-interactions" "$ENABLED_DOCKER_SERVICES"; t
# shellcheck disable=SC2016
echo '
webhook-interactions:
image: mattermostdevelopment/mirrored-node:${NODE_VERSION_REQUIRED}
image: node:${NODE_VERSION_REQUIRED}
command: sh -c "npm install --global --legacy-peer-deps && exec node webhook_serve.js"
healthcheck:
test: ["CMD", "curl", "-s", "-o/dev/null", "127.0.0.1:3000"]
@ -275,11 +276,21 @@ $(if mme2e_is_token_in_list "webhook-interactions" "$ENABLED_DOCKER_SERVICES"; t
fi)
$(if mme2e_is_token_in_list "playwright" "$ENABLED_DOCKER_SERVICES"; then
# shellcheck disable=SC2016
echo '
playwright:
image: mcr.microsoft.com/playwright:v1.56.0-noble
image: mcr.microsoft.com/playwright:v1.58.0-noble
entrypoint: ["/bin/bash", "-c"]
command: ["until [ -f /var/run/mm_terminate ]; do sleep 5; done"]
command:
- |
# Install Node.js based on .nvmrc
NODE_VERSION=$$(cat /mattermost/.nvmrc)
echo "Installing Node.js $${NODE_VERSION}..."
curl -fsSL https://deb.nodesource.com/setup_$${NODE_VERSION%%.*}.x | bash -
apt-get install -y nodejs
echo "Node.js version: $$(node --version)"
# Wait for termination signal
until [ -f /var/run/mm_terminate ]; do sleep 5; done
env_file:
- "./.env.playwright"
environment:

101
e2e-tests/.ci/server.run_specs.sh Executable file
View file

@ -0,0 +1,101 @@
#!/bin/bash
# shellcheck disable=SC2038
# Run specific spec files
# Usage: SPEC_FILES="path/to/spec1.ts,path/to/spec2.ts" make start-server run-specs
set -e -u -o pipefail
cd "$(dirname "$0")"
. .e2erc
if [ -z "${SPEC_FILES:-}" ]; then
mme2e_log "Error: SPEC_FILES environment variable is required"
mme2e_log "Usage: SPEC_FILES=\"path/to/spec.ts\" make start-server run-specs"
exit 1
fi
mme2e_log "Running spec files: $SPEC_FILES"
case $TEST in
cypress)
mme2e_log "Running Cypress with specified specs"
# Initialize cypress report directory
${MME2E_DC_SERVER} exec -T -u "$MME2E_UID" -- cypress bash <<EOF
rm -rf logs results
mkdir -p logs
mkdir -p results/junit
mkdir -p results/mochawesome-report/json/tests
touch results/junit/empty.xml
echo '<?xml version="1.0" encoding="UTF-8"?>' > results/junit/empty.xml
EOF
# Run cypress with specific spec files and mochawesome reporter
LOGFILE_SUFFIX="${CI_BASE_URL//\//_}_specs"
${MME2E_DC_SERVER} exec -T -u "$MME2E_UID" -- cypress npx cypress run \
--spec "$SPEC_FILES" \
--reporter cypress-multi-reporters \
--reporter-options configFile=reporter-config.json \
| tee "../cypress/logs/${LOGFILE_SUFFIX}_cypress.log" || true
# Collect run results
if [ -d ../cypress/results/mochawesome-report/json/tests/ ]; then
cat >../cypress/results/summary.json <<EOF
{
"passed": $(find ../cypress/results/mochawesome-report/json/tests/ -name '*.json' | xargs -l jq -r '.stats.passes' | jq -s add),
"failed": $(find ../cypress/results/mochawesome-report/json/tests/ -name '*.json' | xargs -l jq -r '.stats.failures' | jq -s add),
"failed_expected": 0
}
EOF
fi
# Collect server logs
${MME2E_DC_SERVER} logs --no-log-prefix -- server >"../cypress/logs/${LOGFILE_SUFFIX}_mattermost.log" 2>&1
;;
playwright)
mme2e_log "Running Playwright with specified specs"
# Convert comma-separated to space-separated for playwright
SPEC_ARGS=$(echo "$SPEC_FILES" | tr ',' ' ')
# Initialize playwright report and logs directory
${MME2E_DC_SERVER} exec -T -u "$MME2E_UID" -- playwright bash <<EOF
cd e2e-tests/playwright
rm -rf logs results storage_state
mkdir -p logs results
touch logs/mattermost.log
EOF
# Install dependencies
mme2e_log "Prepare Playwright: install dependencies"
${MME2E_DC_SERVER} exec -T -u "$MME2E_UID" -- playwright bash <<EOF
cd webapp/
npm install --cache /tmp/empty-cache
cd ../e2e-tests/playwright
npm install --cache /tmp/empty-cache
EOF
# Run playwright with specific spec files
LOGFILE_SUFFIX="${CI_BASE_URL//\//_}_specs"
${MME2E_DC_SERVER} exec -T -u "$MME2E_UID" -- playwright bash -c "cd e2e-tests/playwright && npm run test:ci -- $SPEC_ARGS" | tee "../playwright/logs/${LOGFILE_SUFFIX}_playwright.log" || true
# Collect run results (if results.json exists)
if [ -f ../playwright/results/reporter/results.json ]; then
jq -f /dev/stdin ../playwright/results/reporter/results.json >../playwright/results/summary.json <<EOF
{
passed: .stats.expected,
failed: .stats.unexpected,
failed_expected: (.stats.skipped + .stats.flaky)
}
EOF
mme2e_log "Results file found and summary generated"
fi
# Collect server logs
${MME2E_DC_SERVER} logs --no-log-prefix -- server >"../playwright/logs/${LOGFILE_SUFFIX}_mattermost.log" 2>&1
;;
*)
mme2e_log "Error, unsupported value for TEST: $TEST" >&2
mme2e_log "Aborting" >&2
exit 1
;;
esac
mme2e_log "Spec run complete"

View file

@ -9,7 +9,7 @@ clean:
rm -fv .ci/server.yml
rm -fv .ci/.env.{server,dashboard,cypress,playwright}
.PHONY: generate-server start-server run-test stop-server restart-server
.PHONY: generate-server start-server run-test run-specs stop-server restart-server
generate-server:
bash ./.ci/server.generate.sh
start-server: generate-server
@ -17,6 +17,8 @@ start-server: generate-server
bash ./.ci/server.prepare.sh
run-test:
bash ./.ci/server.run_test.sh
run-specs:
bash ./.ci/server.run_specs.sh
stop-server: generate-server
bash ./.ci/server.stop.sh
restart-server: stop-server start-server

View file

@ -74,7 +74,6 @@
"mochawesome-merge": "4.4.1",
"mochawesome-report-generator": "6.2.0",
"moment-timezone": "0.6.0",
"mysql": "2.18.1",
"path": "0.12.7",
"pdf-parse": "1.1.1",
"pg": "8.16.3",
@ -93,7 +92,6 @@
"integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==",
"dev": true,
"license": "Apache-2.0",
"peer": true,
"dependencies": {
"@jridgewell/gen-mapping": "^0.3.5",
"@jridgewell/trace-mapping": "^0.3.24"
@ -1071,7 +1069,6 @@
"integrity": "sha512-60X7qkglvrap8mn1lh2ebxXdZYtUcpd7gsmy9kLaBJ4i/WdY8PqTSdxyA8qraikqKQK5C1KRBKXqznrVapyNaw==",
"dev": true,
"license": "MIT",
"peer": true,
"engines": {
"node": ">=6.9.0"
}
@ -1114,6 +1111,7 @@
"integrity": "sha512-N4ntErOlKvcbTt01rr5wj3y55xnIdx1ymrfIr8C2WnM1Y9glFgWaGDEULJIazOX3XM9NRzhfJ6zZnQ1sBNWU+w==",
"dev": true,
"license": "MIT",
"peer": true,
"dependencies": {
"@nicolo-ribaudo/eslint-scope-5-internals": "5.1.1-v1",
"eslint-visitor-keys": "^2.1.0",
@ -1150,7 +1148,6 @@
"integrity": "sha512-lJjzvrbEeWrhB4P3QBsH7tey117PjLZnDbLiQEKjQ/fNJTjuq4HSqgFA+UNSwZT8D7dxxbnuSBMsa1lrWzKlQg==",
"dev": true,
"license": "MIT",
"peer": true,
"dependencies": {
"@babel/parser": "^7.28.0",
"@babel/types": "^7.28.0",
@ -1168,7 +1165,6 @@
"integrity": "sha512-2+1thGUUWWjLTYTHZWK1n8Yga0ijBz1XAhUXcKy81rd5g6yh7hGqMp45v7cadSbEHc9G3OTv45SyneRN3ps4DQ==",
"dev": true,
"license": "MIT",
"peer": true,
"dependencies": {
"@babel/compat-data": "^7.27.2",
"@babel/helper-validator-option": "^7.27.1",
@ -1186,7 +1182,6 @@
"integrity": "sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==",
"dev": true,
"license": "MIT",
"peer": true,
"engines": {
"node": ">=6.9.0"
}
@ -1197,7 +1192,6 @@
"integrity": "sha512-0gSFWUPNXNopqtIPQvlD5WgXYI5GY2kP2cCvoT8kczjbfcfuIljTbcWrulD1CIPIX2gt1wghbDy08yE1p+/r3w==",
"dev": true,
"license": "MIT",
"peer": true,
"dependencies": {
"@babel/traverse": "^7.27.1",
"@babel/types": "^7.27.1"
@ -1212,7 +1206,6 @@
"integrity": "sha512-dSOvYwvyLsWBeIRyOeHXp5vPj5l1I011r52FM1+r1jCERv+aFXYk4whgQccYEGYxK2H3ZAIA8nuPkQ0HaUo3qg==",
"dev": true,
"license": "MIT",
"peer": true,
"dependencies": {
"@babel/helper-module-imports": "^7.27.1",
"@babel/helper-validator-identifier": "^7.27.1",
@ -1231,7 +1224,6 @@
"integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==",
"dev": true,
"license": "MIT",
"peer": true,
"engines": {
"node": ">=6.9.0"
}
@ -1252,7 +1244,6 @@
"integrity": "sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==",
"dev": true,
"license": "MIT",
"peer": true,
"engines": {
"node": ">=6.9.0"
}
@ -1263,7 +1254,6 @@
"integrity": "sha512-/V9771t+EgXz62aCcyofnQhGM8DQACbRhvzKFsXKC9QM+5MadF8ZmIm0crDMaz3+o0h0zXfJnd4EhbYbxsrcFw==",
"dev": true,
"license": "MIT",
"peer": true,
"dependencies": {
"@babel/template": "^7.27.2",
"@babel/types": "^7.28.2"
@ -1278,7 +1268,6 @@
"integrity": "sha512-jVZGvOxOuNSsuQuLRTh13nU0AogFlw32w/MT+LV6D3sP5WdbW61E77RnkbaO2dUvmPAYrBDJXGn5gGS6tH4j8g==",
"dev": true,
"license": "MIT",
"peer": true,
"dependencies": {
"@babel/types": "^7.28.0"
},
@ -1305,7 +1294,6 @@
"integrity": "sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw==",
"dev": true,
"license": "MIT",
"peer": true,
"dependencies": {
"@babel/code-frame": "^7.27.1",
"@babel/parser": "^7.27.2",
@ -1321,7 +1309,6 @@
"integrity": "sha512-mGe7UK5wWyh0bKRfupsUchrQGqvDbZDbKJw+kcRGSmdHVYrv+ltd0pnpDTVpiTqnaBru9iEvA8pz8W46v0Amwg==",
"dev": true,
"license": "MIT",
"peer": true,
"dependencies": {
"@babel/code-frame": "^7.27.1",
"@babel/generator": "^7.28.0",
@ -1341,7 +1328,6 @@
"integrity": "sha512-ruv7Ae4J5dUYULmeXw1gmb7rYRz57OWCPM57pHojnLq/3Z1CK2lNSLTCVjxVk1F/TZHwOZZrOWi0ur95BbLxNQ==",
"dev": true,
"license": "MIT",
"peer": true,
"dependencies": {
"@babel/helper-string-parser": "^7.27.1",
"@babel/helper-validator-identifier": "^7.27.1"
@ -1813,7 +1799,6 @@
"integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==",
"dev": true,
"license": "MIT",
"peer": true,
"dependencies": {
"@jridgewell/sourcemap-codec": "^1.5.0",
"@jridgewell/trace-mapping": "^0.3.24"
@ -1825,7 +1810,6 @@
"integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==",
"dev": true,
"license": "MIT",
"peer": true,
"engines": {
"node": ">=6.0.0"
}
@ -1836,7 +1820,6 @@
"integrity": "sha512-ZMp1V8ZFcPG5dIWnQLr3NSI1MiCU7UETdS/A0G8V/XWHvJv3ZsFqutJn1Y5RPmAPX6F3BiE397OqveU/9NCuIA==",
"dev": true,
"license": "MIT",
"peer": true,
"dependencies": {
"@jridgewell/gen-mapping": "^0.3.5",
"@jridgewell/trace-mapping": "^0.3.25"
@ -1847,8 +1830,7 @@
"resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz",
"integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==",
"dev": true,
"license": "MIT",
"peer": true
"license": "MIT"
},
"node_modules/@jridgewell/trace-mapping": {
"version": "0.3.30",
@ -1856,7 +1838,6 @@
"integrity": "sha512-GQ7Nw5G2lTu/BtHTKfXhKHok2WGetd4XYcVKGx00SjAk8GMwgJM3zr6zORiPGuOE+/vkc90KtTosSSvaCjKb2Q==",
"dev": true,
"license": "MIT",
"peer": true,
"dependencies": {
"@jridgewell/resolve-uri": "^3.1.0",
"@jridgewell/sourcemap-codec": "^1.4.14"
@ -1884,6 +1865,7 @@
"integrity": "sha512-2795KUkp2EkuJ9NVohPkJmrgKunt6OZiLyo8zUoIWPJjxQ0upjiWJz/KenABx38v8+QfpSEN8tZSBN3lsZCueg==",
"dev": true,
"license": "MIT",
"peer": true,
"peerDependencies": {
"typescript": "^4.3.0 || ^5.0.0"
},
@ -2866,7 +2848,6 @@
"integrity": "sha512-FXx2pKgId/WyYo2jXw63kk7/+TY7u7AziEJxJAnSFzHlqTAS3Ync6SvgYAN/k4/PQpnnVuzoMuVnByKK2qp0ag==",
"dev": true,
"license": "MIT",
"peer": true,
"dependencies": {
"@types/estree": "*",
"@types/json-schema": "*"
@ -2878,7 +2859,6 @@
"integrity": "sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg==",
"dev": true,
"license": "MIT",
"peer": true,
"dependencies": {
"@types/eslint": "*",
"@types/estree": "*"
@ -3179,6 +3159,7 @@
"integrity": "sha512-pUXGCuHnnKw6PyYq93lLRiZm3vjuslIy7tus1lIQTYVK9bL8XBgJnCWm8a0KcTtHC84Yya1Q6rtll+duSMj0dg==",
"dev": true,
"license": "MIT",
"peer": true,
"dependencies": {
"@typescript-eslint/scope-manager": "8.39.1",
"@typescript-eslint/types": "8.39.1",
@ -3397,7 +3378,6 @@
"integrity": "sha512-nuBEDgQfm1ccRp/8bCQrx1frohyufl4JlbMMZ4P1wpeOfDhF6FQkxZJ1b/e+PLwr6X1Nhw6OLme5usuBWYBvuQ==",
"dev": true,
"license": "MIT",
"peer": true,
"dependencies": {
"@webassemblyjs/helper-numbers": "1.13.2",
"@webassemblyjs/helper-wasm-bytecode": "1.13.2"
@ -3408,24 +3388,21 @@
"resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.13.2.tgz",
"integrity": "sha512-6oXyTOzbKxGH4steLbLNOu71Oj+C8Lg34n6CqRvqfS2O71BxY6ByfMDRhBytzknj9yGUPVJ1qIKhRlAwO1AovA==",
"dev": true,
"license": "MIT",
"peer": true
"license": "MIT"
},
"node_modules/@webassemblyjs/helper-api-error": {
"version": "1.13.2",
"resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.13.2.tgz",
"integrity": "sha512-U56GMYxy4ZQCbDZd6JuvvNV/WFildOjsaWD3Tzzvmw/mas3cXzRJPMjP83JqEsgSbyrmaGjBfDtV7KDXV9UzFQ==",
"dev": true,
"license": "MIT",
"peer": true
"license": "MIT"
},
"node_modules/@webassemblyjs/helper-buffer": {
"version": "1.14.1",
"resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.14.1.tgz",
"integrity": "sha512-jyH7wtcHiKssDtFPRB+iQdxlDf96m0E39yb0k5uJVhFGleZFoNw1c4aeIcVUPPbXUVJ94wwnMOAqUHyzoEPVMA==",
"dev": true,
"license": "MIT",
"peer": true
"license": "MIT"
},
"node_modules/@webassemblyjs/helper-numbers": {
"version": "1.13.2",
@ -3433,7 +3410,6 @@
"integrity": "sha512-FE8aCmS5Q6eQYcV3gI35O4J789wlQA+7JrqTTpJqn5emA4U2hvwJmvFRC0HODS+3Ye6WioDklgd6scJ3+PLnEA==",
"dev": true,
"license": "MIT",
"peer": true,
"dependencies": {
"@webassemblyjs/floating-point-hex-parser": "1.13.2",
"@webassemblyjs/helper-api-error": "1.13.2",
@ -3445,8 +3421,7 @@
"resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.13.2.tgz",
"integrity": "sha512-3QbLKy93F0EAIXLh0ogEVR6rOubA9AoZ+WRYhNbFyuB70j3dRdwH9g+qXhLAO0kiYGlg3TxDV+I4rQTr/YNXkA==",
"dev": true,
"license": "MIT",
"peer": true
"license": "MIT"
},
"node_modules/@webassemblyjs/helper-wasm-section": {
"version": "1.14.1",
@ -3454,7 +3429,6 @@
"integrity": "sha512-ds5mXEqTJ6oxRoqjhWDU83OgzAYjwsCV8Lo/N+oRsNDmx/ZDpqalmrtgOMkHwxsG0iI//3BwWAErYRHtgn0dZw==",
"dev": true,
"license": "MIT",
"peer": true,
"dependencies": {
"@webassemblyjs/ast": "1.14.1",
"@webassemblyjs/helper-buffer": "1.14.1",
@ -3468,7 +3442,6 @@
"integrity": "sha512-4LtOzh58S/5lX4ITKxnAK2USuNEvpdVV9AlgGQb8rJDHaLeHciwG4zlGr0j/SNWlr7x3vO1lDEsuePvtcDNCkw==",
"dev": true,
"license": "MIT",
"peer": true,
"dependencies": {
"@xtuc/ieee754": "^1.2.0"
}
@ -3479,7 +3452,6 @@
"integrity": "sha512-Lde1oNoIdzVzdkNEAWZ1dZ5orIbff80YPdHx20mrHwHrVNNTjNr8E3xz9BdpcGqRQbAEa+fkrCb+fRFTl/6sQw==",
"dev": true,
"license": "Apache-2.0",
"peer": true,
"dependencies": {
"@xtuc/long": "4.2.2"
}
@ -3489,8 +3461,7 @@
"resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.13.2.tgz",
"integrity": "sha512-3NQWGjKTASY1xV5m7Hr0iPeXD9+RDobLll3T9d2AO+g3my8xy5peVyjSag4I50mR1bBSN/Ct12lo+R9tJk0NZQ==",
"dev": true,
"license": "MIT",
"peer": true
"license": "MIT"
},
"node_modules/@webassemblyjs/wasm-edit": {
"version": "1.14.1",
@ -3498,7 +3469,6 @@
"integrity": "sha512-RNJUIQH/J8iA/1NzlE4N7KtyZNHi3w7at7hDjvRNm5rcUXa00z1vRz3glZoULfJ5mpvYhLybmVcwcjGrC1pRrQ==",
"dev": true,
"license": "MIT",
"peer": true,
"dependencies": {
"@webassemblyjs/ast": "1.14.1",
"@webassemblyjs/helper-buffer": "1.14.1",
@ -3516,7 +3486,6 @@
"integrity": "sha512-AmomSIjP8ZbfGQhumkNvgC33AY7qtMCXnN6bL2u2Js4gVCg8fp735aEiMSBbDR7UQIj90n4wKAFUSEd0QN2Ukg==",
"dev": true,
"license": "MIT",
"peer": true,
"dependencies": {
"@webassemblyjs/ast": "1.14.1",
"@webassemblyjs/helper-wasm-bytecode": "1.13.2",
@ -3531,7 +3500,6 @@
"integrity": "sha512-PTcKLUNvBqnY2U6E5bdOQcSM+oVP/PmrDY9NzowJjislEjwP/C4an2303MCVS2Mg9d3AJpIGdUFIQQWbPds0Sw==",
"dev": true,
"license": "MIT",
"peer": true,
"dependencies": {
"@webassemblyjs/ast": "1.14.1",
"@webassemblyjs/helper-buffer": "1.14.1",
@ -3545,7 +3513,6 @@
"integrity": "sha512-JLBl+KZ0R5qB7mCnud/yyX08jWFw5MsoalJ1pQ4EdFlgj9VdXKGuENGsiCIjegI1W7p91rUlcB/LB5yRJKNTcQ==",
"dev": true,
"license": "MIT",
"peer": true,
"dependencies": {
"@webassemblyjs/ast": "1.14.1",
"@webassemblyjs/helper-api-error": "1.13.2",
@ -3561,7 +3528,6 @@
"integrity": "sha512-kPSSXE6De1XOR820C90RIo2ogvZG+c3KiHzqUoO/F34Y2shGzesfqv7o57xrxovZJH/MetF5UjroJ/R/3isoiw==",
"dev": true,
"license": "MIT",
"peer": true,
"dependencies": {
"@webassemblyjs/ast": "1.14.1",
"@xtuc/long": "4.2.2"
@ -3572,16 +3538,14 @@
"resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz",
"integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==",
"dev": true,
"license": "BSD-3-Clause",
"peer": true
"license": "BSD-3-Clause"
},
"node_modules/@xtuc/long": {
"version": "4.2.2",
"resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz",
"integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==",
"dev": true,
"license": "Apache-2.0",
"peer": true
"license": "Apache-2.0"
},
"node_modules/accepts": {
"version": "2.0.0",
@ -3603,6 +3567,7 @@
"integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==",
"dev": true,
"license": "MIT",
"peer": true,
"bin": {
"acorn": "bin/acorn"
},
@ -3616,7 +3581,6 @@
"integrity": "sha512-wKmbr/DDiIXzEOiWrTTUcDm24kQ2vGfZQvM2fwg2vXqR5uW6aapr7ObPtj1th32b9u90/Pf4AItvdTh42fBmVQ==",
"dev": true,
"license": "MIT",
"peer": true,
"engines": {
"node": ">=10.13.0"
},
@ -3671,7 +3635,6 @@
"integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==",
"dev": true,
"license": "MIT",
"peer": true,
"dependencies": {
"ajv": "^8.0.0"
},
@ -3690,7 +3653,6 @@
"integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==",
"dev": true,
"license": "MIT",
"peer": true,
"dependencies": {
"fast-deep-equal": "^3.1.3",
"fast-uri": "^3.0.1",
@ -3707,8 +3669,7 @@
"resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz",
"integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==",
"dev": true,
"license": "MIT",
"peer": true
"license": "MIT"
},
"node_modules/ally.js": {
"version": "1.4.1",
@ -4198,16 +4159,6 @@
"tweetnacl": "^0.14.3"
}
},
"node_modules/bignumber.js": {
"version": "9.0.0",
"resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.0.0.tgz",
"integrity": "sha512-t/OYhhJ2SD+YGBQcjY8GzzDHEk9f3nerxjtfa6tlMXfe7frs/WozhvCNoGvpM0P3bNf3Gq5ZRMlGr5f3r4/N8A==",
"dev": true,
"license": "MIT",
"engines": {
"node": "*"
}
},
"node_modules/blob-util": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/blob-util/-/blob-util-2.0.2.tgz",
@ -4340,8 +4291,7 @@
"resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz",
"integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==",
"dev": true,
"license": "MIT",
"peer": true
"license": "MIT"
},
"node_modules/byte-length": {
"version": "1.0.2",
@ -4462,8 +4412,7 @@
"url": "https://github.com/sponsors/ai"
}
],
"license": "CC-BY-4.0",
"peer": true
"license": "CC-BY-4.0"
},
"node_modules/caseless": {
"version": "0.12.0",
@ -4558,7 +4507,6 @@
"integrity": "sha512-rNjApaLzuwaOTjCiT8lSDdGN1APCiqkChLMJxJPWLunPAt5fy8xgU9/jNOchV84wfIxrA0lRQB7oCT8jrn/wrQ==",
"dev": true,
"license": "MIT",
"peer": true,
"engines": {
"node": ">=6.0"
}
@ -4848,8 +4796,7 @@
"resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz",
"integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==",
"dev": true,
"license": "MIT",
"peer": true
"license": "MIT"
},
"node_modules/cookie": {
"version": "0.7.2",
@ -4871,13 +4818,6 @@
"node": ">=6.6.0"
}
},
"node_modules/core-util-is": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz",
"integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==",
"dev": true,
"license": "MIT"
},
"node_modules/cross-env": {
"version": "10.0.0",
"resolved": "https://registry.npmjs.org/cross-env/-/cross-env-10.0.0.tgz",
@ -4935,6 +4875,7 @@
"dev": true,
"hasInstallScript": true,
"license": "MIT",
"peer": true,
"dependencies": {
"@cypress/request": "^3.0.9",
"@cypress/xvfb": "^1.2.4",
@ -5423,8 +5364,7 @@
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.200.tgz",
"integrity": "sha512-rFCxROw7aOe4uPTfIAx+rXv9cEcGx+buAF4npnhtTqCJk5KDFRnh3+KYj7rdVh6lsFt5/aPs+Irj9rZ33WMA7w==",
"dev": true,
"license": "ISC",
"peer": true
"license": "ISC"
},
"node_modules/emoji-regex": {
"version": "9.2.2",
@ -5473,6 +5413,7 @@
"integrity": "sha512-rRqJg/6gd538VHvR3PSrdRBb/1Vy2YfzHqzvbhGIQpDRKIa4FgV/54b5Q1xYSxOOwKvjXweS26E0Q+nAMwp2pQ==",
"dev": true,
"license": "MIT",
"peer": true,
"dependencies": {
"ansi-colors": "^4.1.1",
"strip-ansi": "^6.0.1"
@ -5603,8 +5544,7 @@
"resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.7.0.tgz",
"integrity": "sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==",
"dev": true,
"license": "MIT",
"peer": true
"license": "MIT"
},
"node_modules/es-object-atoms": {
"version": "1.1.1",
@ -5702,6 +5642,7 @@
"integrity": "sha512-TS9bTNIryDzStCpJN93aC5VRSW3uTx9sClUn4B87pwiCaJh220otoI0X8mJKr+VcPtniMdN8GKjlwgWGUv5ZKA==",
"dev": true,
"license": "MIT",
"peer": true,
"dependencies": {
"@eslint-community/eslint-utils": "^4.2.0",
"@eslint-community/regexpp": "^4.12.1",
@ -5903,6 +5844,7 @@
"integrity": "sha512-whOE1HFo/qJDyX4SnXzP4N6zOWn79WhnCUY/iDR0mPfQZO8wcYE4JClzI2oZrhBnnMUCBCHZhO6VQyoBU95mZA==",
"dev": true,
"license": "MIT",
"peer": true,
"dependencies": {
"@rtsao/scc": "^1.1.0",
"array-includes": "^3.1.9",
@ -6535,8 +6477,7 @@
"url": "https://opencollective.com/fastify"
}
],
"license": "BSD-3-Clause",
"peer": true
"license": "BSD-3-Clause"
},
"node_modules/fast-xml-parser": {
"version": "5.2.5",
@ -6916,7 +6857,6 @@
"integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==",
"dev": true,
"license": "MIT",
"peer": true,
"engines": {
"node": ">=6.9.0"
}
@ -7083,8 +7023,7 @@
"resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz",
"integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==",
"dev": true,
"license": "BSD-2-Clause",
"peer": true
"license": "BSD-2-Clause"
},
"node_modules/glob/node_modules/minimatch": {
"version": "10.0.3",
@ -7985,13 +7924,6 @@
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/isarray": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
"integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==",
"dev": true,
"license": "MIT"
},
"node_modules/isexe": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
@ -8046,7 +7978,6 @@
"integrity": "sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==",
"dev": true,
"license": "MIT",
"peer": true,
"dependencies": {
"@types/node": "*",
"merge-stream": "^2.0.0",
@ -8062,7 +7993,6 @@
"integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==",
"dev": true,
"license": "MIT",
"peer": true,
"dependencies": {
"has-flag": "^4.0.0"
},
@ -8079,6 +8009,7 @@
"integrity": "sha512-twQoecYPiVA5K/h6SxtORw/Bs3ar+mLUtoPSc7iMXzQzK8d7eJ/R09wmTwAjiamETn1cXYPGfNnu7DMoHgu12w==",
"dev": true,
"license": "MIT",
"peer": true,
"bin": {
"jiti": "lib/jiti-cli.mjs"
}
@ -8116,7 +8047,6 @@
"integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==",
"dev": true,
"license": "MIT",
"peer": true,
"bin": {
"jsesc": "bin/jsesc"
},
@ -8136,8 +8066,7 @@
"resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz",
"integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==",
"dev": true,
"license": "MIT",
"peer": true
"license": "MIT"
},
"node_modules/json-schema": {
"version": "0.4.0",
@ -8173,7 +8102,6 @@
"integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==",
"dev": true,
"license": "MIT",
"peer": true,
"bin": {
"json5": "lib/cli.js"
},
@ -8449,7 +8377,6 @@
"integrity": "sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg==",
"dev": true,
"license": "MIT",
"peer": true,
"engines": {
"node": ">=6.11.5"
}
@ -8652,7 +8579,6 @@
"integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==",
"dev": true,
"license": "ISC",
"peer": true,
"dependencies": {
"yallist": "^3.0.2"
}
@ -8874,6 +8800,7 @@
"integrity": "sha512-5EK+Cty6KheMS/YLPPMJC64g5V61gIR25KsRItHw6x4hEKT6Njp1n9LOlH4gpevuwMVS66SXaBBpg+RWZkza4A==",
"dev": true,
"license": "MIT",
"peer": true,
"dependencies": {
"browser-stdout": "^1.3.1",
"chokidar": "^4.0.1",
@ -9372,29 +9299,6 @@
"dev": true,
"license": "MIT"
},
"node_modules/mysql": {
"version": "2.18.1",
"resolved": "https://registry.npmjs.org/mysql/-/mysql-2.18.1.tgz",
"integrity": "sha512-Bca+gk2YWmqp2Uf6k5NFEurwY/0td0cpebAucFpY/3jhrwrVGuxU2uQFCHjU19SJfje0yQvi+rVWdq78hR5lig==",
"dev": true,
"license": "MIT",
"dependencies": {
"bignumber.js": "9.0.0",
"readable-stream": "2.3.7",
"safe-buffer": "5.1.2",
"sqlstring": "2.3.1"
},
"engines": {
"node": ">= 0.6"
}
},
"node_modules/mysql/node_modules/safe-buffer": {
"version": "5.1.2",
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
"integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
"dev": true,
"license": "MIT"
},
"node_modules/natural-compare": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz",
@ -9417,8 +9321,7 @@
"resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz",
"integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==",
"dev": true,
"license": "MIT",
"peer": true
"license": "MIT"
},
"node_modules/node-ensure": {
"version": "0.0.0",
@ -9432,8 +9335,7 @@
"resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.19.tgz",
"integrity": "sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==",
"dev": true,
"license": "MIT",
"peer": true
"license": "MIT"
},
"node_modules/notp": {
"version": "2.0.3",
@ -10264,13 +10166,6 @@
"node": ">= 0.6.0"
}
},
"node_modules/process-nextick-args": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz",
"integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==",
"dev": true,
"license": "MIT"
},
"node_modules/prop-types": {
"version": "15.8.1",
"resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz",
@ -10441,29 +10336,6 @@
"dev": true,
"license": "MIT"
},
"node_modules/readable-stream": {
"version": "2.3.7",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz",
"integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==",
"dev": true,
"license": "MIT",
"dependencies": {
"core-util-is": "~1.0.0",
"inherits": "~2.0.3",
"isarray": "~1.0.0",
"process-nextick-args": "~2.0.0",
"safe-buffer": "~5.1.1",
"string_decoder": "~1.1.1",
"util-deprecate": "~1.0.1"
}
},
"node_modules/readable-stream/node_modules/safe-buffer": {
"version": "5.1.2",
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
"integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
"dev": true,
"license": "MIT"
},
"node_modules/readdirp": {
"version": "4.1.2",
"resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz",
@ -10619,7 +10491,6 @@
"integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==",
"dev": true,
"license": "MIT",
"peer": true,
"engines": {
"node": ">=0.10.0"
}
@ -10852,7 +10723,6 @@
"integrity": "sha512-Gn/JaSk/Mt9gYubxTtSn/QCV4em9mpAPiR1rqy/Ocu19u/G9J5WWdNoUT4SiV6mFC3y6cxyFcFwdzPM3FgxGAQ==",
"dev": true,
"license": "MIT",
"peer": true,
"dependencies": {
"@types/json-schema": "^7.0.9",
"ajv": "^8.9.0",
@ -10891,7 +10761,6 @@
"integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==",
"dev": true,
"license": "MIT",
"peer": true,
"dependencies": {
"fast-deep-equal": "^3.1.3"
},
@ -10904,8 +10773,7 @@
"resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz",
"integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==",
"dev": true,
"license": "MIT",
"peer": true
"license": "MIT"
},
"node_modules/semver": {
"version": "6.3.1",
@ -10972,6 +10840,7 @@
"integrity": "sha512-b0IrY3b1gVMsWvJppCf19g1p3JSnS0hQi6xu4Hi40CIhf0Lx8pQHcvBL+xunShpmOiQzg1NOia812NAWdSaShw==",
"dev": true,
"license": "Apache-2.0",
"peer": true,
"dependencies": {
"@servie/events": "^1.0.0",
"byte-length": "^1.0.2",
@ -11229,7 +11098,6 @@
"integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
"dev": true,
"license": "BSD-3-Clause",
"peer": true,
"engines": {
"node": ">=0.10.0"
}
@ -11240,7 +11108,6 @@
"integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==",
"dev": true,
"license": "MIT",
"peer": true,
"dependencies": {
"buffer-from": "^1.0.0",
"source-map": "^0.6.0"
@ -11256,16 +11123,6 @@
"node": ">= 10.x"
}
},
"node_modules/sqlstring": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/sqlstring/-/sqlstring-2.3.1.tgz",
"integrity": "sha512-ooAzh/7dxIG5+uDik1z/Rd1vli0+38izZhGzSa34FwR7IbelPWCCKSNIl8jlL/F7ERvy8CB2jNeM1E9i9mXMAQ==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">= 0.6"
}
},
"node_modules/sshpk": {
"version": "1.18.0",
"resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.18.0.tgz",
@ -11659,7 +11516,6 @@
"integrity": "sha512-+6erLbBm0+LROX2sPXlUYx/ux5PyE9K/a92Wrt6oA+WDAoFTdpHE5tCYCI5PNzq2y8df4rA+QgHLJuR4jNymsg==",
"dev": true,
"license": "BSD-2-Clause",
"peer": true,
"dependencies": {
"@jridgewell/source-map": "^0.3.3",
"acorn": "^8.14.0",
@ -11679,7 +11535,6 @@
"integrity": "sha512-vkZjpUjb6OMS7dhV+tILUW6BhpDR7P2L/aQSAv+Uwk+m8KATX9EccViHTJR2qDtACKPIYndLGCyl3FMo+r2LMw==",
"dev": true,
"license": "MIT",
"peer": true,
"dependencies": {
"@jridgewell/trace-mapping": "^0.3.25",
"jest-worker": "^27.4.5",
@ -11714,8 +11569,7 @@
"resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
"integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==",
"dev": true,
"license": "MIT",
"peer": true
"license": "MIT"
},
"node_modules/thirty-two": {
"version": "0.0.2",
@ -12038,6 +11892,7 @@
"integrity": "sha512-CWBzXQrc/qOkhidw1OzBTQuYRbfyxDXJMVJ1XNwUHGROVmuaeiEm3OslpZ1RV96d7SKKjZKrSJu3+t/xlw3R9A==",
"dev": true,
"license": "Apache-2.0",
"peer": true,
"bin": {
"tsc": "bin/tsc",
"tsserver": "bin/tsserver"
@ -12106,6 +11961,7 @@
"integrity": "sha512-gTtSdWX9xiMPA/7MV9STjJOOYtWwIJIYxkQxnSV1U3xcE+mnJSH3f6zI0RYP+ew66WSlZ5ed+h0VCxsvdC1jJg==",
"dev": true,
"license": "MIT",
"peer": true,
"dependencies": {
"@typescript-eslint/scope-manager": "8.41.0",
"@typescript-eslint/types": "8.41.0",
@ -12394,7 +12250,6 @@
}
],
"license": "MIT",
"peer": true,
"dependencies": {
"escalade": "^3.2.0",
"picocolors": "^1.1.1"
@ -12513,7 +12368,6 @@
"integrity": "sha512-c5EGNOiyxxV5qmTtAB7rbiXxi1ooX1pQKMLX/MIabJjRA0SJBQOjKF+KSVfHkr9U1cADPon0mRiVe/riyaiDUA==",
"dev": true,
"license": "MIT",
"peer": true,
"dependencies": {
"glob-to-regexp": "^0.4.1",
"graceful-fs": "^4.1.2"
@ -12528,7 +12382,6 @@
"integrity": "sha512-rHY3vHXRbkSfhG6fH8zYQdth/BtDgXXuR2pHF++1f/EBkI8zkgM5XWfsC3BvOoW9pr1CvZ1qQCxhCEsbNgT50g==",
"dev": true,
"license": "MIT",
"peer": true,
"dependencies": {
"@types/eslint-scope": "^3.7.7",
"@types/estree": "^1.0.8",
@ -12578,7 +12431,6 @@
"integrity": "sha512-yd1RBzSGanHkitROoPFd6qsrxt+oFhg/129YzheDGqeustzX0vTZJZsSsQjVQC4yzBQ56K55XU8gaNCtIzOnTg==",
"dev": true,
"license": "MIT",
"peer": true,
"engines": {
"node": ">=10.13.0"
}
@ -12589,7 +12441,6 @@
"integrity": "sha512-d4lC8xfavMeBjzGr2vECC3fsGXziXZQyJxD868h2M/mBI3PwAuODxAkLkq5HYuvrPYcUtiLzsTo8U3PgX3Ocww==",
"dev": true,
"license": "MIT",
"peer": true,
"dependencies": {
"graceful-fs": "^4.2.4",
"tapable": "^2.2.0"
@ -12604,7 +12455,6 @@
"integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
"dev": true,
"license": "MIT",
"peer": true,
"engines": {
"node": ">= 0.6"
}
@ -12615,7 +12465,6 @@
"integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
"dev": true,
"license": "MIT",
"peer": true,
"dependencies": {
"mime-db": "1.52.0"
},
@ -12629,7 +12478,6 @@
"integrity": "sha512-Re10+NauLTMCudc7T5WLFLAwDhQ0JWdrMK+9B2M8zR5hRExKmsRDCBA7/aV/pNJFltmBFO5BAMlQFi/vq3nKOg==",
"dev": true,
"license": "MIT",
"peer": true,
"engines": {
"node": ">=6"
}
@ -12906,8 +12754,7 @@
"resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz",
"integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==",
"dev": true,
"license": "ISC",
"peer": true
"license": "ISC"
},
"node_modules/yargs": {
"version": "17.7.2",

View file

@ -69,7 +69,6 @@
"mochawesome-merge": "4.4.1",
"mochawesome-report-generator": "6.2.0",
"moment-timezone": "0.6.0",
"mysql": "2.18.1",
"path": "0.12.7",
"pdf-parse": "1.1.1",
"pg": "8.16.3",
@ -101,6 +100,7 @@
"start:webhook": "node webhook_serve.js",
"pretest": "npm run clean",
"test": "cross-env TZ=Etc/UTC cypress run",
"test:smoke": "node run_tests.js --stage='@prod' --group='@smoke'",
"test:ci": "node run_tests.js",
"uniq-meta": "grep -r \"^// $META:\" cypress | grep -ow '@\\w*' | sort | uniq",
"check": "eslint .",

View file

@ -0,0 +1,15 @@
{
"reporterEnabled": "mocha-junit-reporter, mochawesome",
"mochaJunitReporterReporterOptions": {
"mochaFile": "results/junit/test_results[hash].xml",
"toConsole": false
},
"mochawesomeReporterOptions": {
"reportDir": "results/mochawesome-report",
"reportFilename": "json/tests/[name]",
"quiet": true,
"overwrite": false,
"html": false,
"json": true
}
}

View file

@ -7,7 +7,6 @@
// - Use element ID when selecting an element. Create one if none.
// ***************************************************************
// Stage: @prod
// Group: @channels @accessibility
import {getRandomId} from '../../../utils';

View file

@ -50,7 +50,7 @@ describe('Verify Accessibility Support in Popovers', () => {
{ariaLabel: 'People & Body', header: 'People & Body'},
{ariaLabel: 'Animals & Nature', header: 'Animals & Nature'},
{ariaLabel: 'Food & Drink', header: 'Food & Drink'},
{ariaLabel: 'Travel Places', header: 'Travel Places'},
{ariaLabel: 'Travel & Places', header: 'Travel & Places'},
{ariaLabel: 'Activities', header: 'Activities'},
{ariaLabel: 'Objects', header: 'Objects'},
{ariaLabel: 'Symbols', header: 'Symbols'},

View file

@ -7,7 +7,6 @@
// - Use element ID when selecting an element. Create one if none.
// ***************************************************************
// Stage: @prod
// Group: @channels @account_setting
import * as TIMEOUTS from '../../../../fixtures/timeouts';
@ -85,7 +84,7 @@ describe('Profile > Profile Settings > Email', () => {
cy.get('#primaryEmail').should('be.visible').click().blur();
// * Check that the correct error message is shown.
cy.get('#error_primaryEmail').should('be.visible').should('have.text', 'Please enter a valid email address');
cy.get('#error_primaryEmail').should('be.visible').should('have.text', 'Please enter a valid email address.');
});
it('MM-T2067 email address already taken error', () => {

View file

@ -7,7 +7,6 @@
// - Use element ID when selecting an element. Create one if none.
// ***************************************************************
// Stage: @prod
// Group: @channels @account_setting
describe('Account Settings', () => {

View file

@ -7,7 +7,6 @@
// - Use element ID when selecting an element. Create one if none.
// ***************************************************************
// Stage: @prod
// Group: @channels @channel
import * as TIMEOUTS from '../../../fixtures/timeouts';

View file

@ -7,7 +7,6 @@
// - Use element ID when selecting an element. Create one if none.
// ***************************************************************
// Stage: @prod
// Group: @channels @channel
import {getAdminAccount} from '../../../support/env';
@ -103,7 +102,7 @@ describe('Archived channels', () => {
function verifyViewingArchivedChannel(channel) {
// * Verify that we've switched to the correct channel and that the header contains the archived icon
cy.get('#channelHeaderTitle').should('contain', channel.display_name);
cy.get('#channelHeaderInfo .icon__archive').should('be.visible');
cy.findByTestId('channel-header-archive-icon').should('be.visible');
// * Verify that the channel is visible in the sidebar with the archived icon
cy.get(`#sidebarItem_${channel.name}`).should('be.visible').

View file

@ -61,7 +61,9 @@ describe('Authentication', () => {
cy.get('#input_name').clear().type(`test${getRandomId()}`);
cy.findByText('Create Account').click();
cy.get('#signup-body-card-form-check-terms-and-privacy').check();
cy.findByText('Create account').click();
// * Make sure account was created successfully and we are at the select team page
cy.findByText('Teams you can join:', {timeout: TIMEOUTS.ONE_MIN}).should('be.visible');
@ -113,7 +115,9 @@ describe('Authentication', () => {
cy.get('#input_name').clear().type(`test${getRandomId()}`);
cy.findByText('Create Account').click();
cy.get('#signup-body-card-form-check-terms-and-privacy').check();
cy.findByText('Create account').click();
// * Make sure account was not created successfully
cy.get('.AlertBanner__title').scrollIntoView().should('be.visible');
@ -146,7 +150,9 @@ describe('Authentication', () => {
cy.get('#input_name').clear().type(username);
cy.findByText('Create Account').click();
cy.get('#signup-body-card-form-check-terms-and-privacy').check();
cy.findByText('Create account').click();
// * Make sure account was created successfully and we are on the team joining page
cy.findByText('Teams you can join:', {timeout: TIMEOUTS.ONE_MIN}).should('be.visible');

View file

@ -61,14 +61,18 @@ describe('Authentication', () => {
cy.get('#input_password-input').clear().type('less');
cy.findByText('Create Account').click();
cy.get('#signup-body-card-form-check-terms-and-privacy').check();
cy.findByText('Create account').click();
// * Assert the error is what is expected;
cy.findByText('Your password must be 7-72 characters long.').should('be.visible');
cy.get('#input_password-input').clear().type('greaterthan7');
cy.findByText('Create Account').click();
cy.get('#signup-body-card-form-check-terms-and-privacy').check();
cy.findByText('Create account').click();
// * Assert that we are not shown an MFA screen and instead a Teams You Can join page
cy.findByText('Teams you can join:', {timeout: TIMEOUTS.ONE_MIN}).should('be.visible');
@ -112,9 +116,11 @@ describe('Authentication', () => {
cy.get('#input_name').clear().type(`BestUsernameInTheWorld${getRandomId()}`);
cy.get('#signup-body-card-form-check-terms-and-privacy').check();
['NOLOWERCASE123!', 'noupppercase123!', 'NoNumber!', 'NoSymbol123'].forEach((option) => {
cy.get('#input_password-input').clear().type(option);
cy.findByText('Create Account').click();
cy.findByText('Create account').click();
// * Assert the error is what is expected;
cy.findByText('Your password must be 5-72 characters long and include both lowercase and uppercase letters, numbers, and special characters.').should('be.visible');

View file

@ -149,9 +149,11 @@ describe('Authentication', () => {
cy.get('#input_password-input').type('Test123456!');
cy.get('#signup-body-card-form-check-terms-and-privacy').check();
['1user', 'te', 'user#1', 'user!1'].forEach((option) => {
cy.get('#input_name').clear().type(option);
cy.findByText('Create Account').click();
cy.findByText('Create account').click();
// * Assert the error is what is expected;
cy.get('.Input___error').scrollIntoView().should('be.visible');
@ -183,7 +185,9 @@ describe('Authentication', () => {
cy.get('#input_name').clear().type(`Test${getRandomId()}`);
cy.findByText('Create Account').click();
cy.get('#signup-body-card-form-check-terms-and-privacy').check();
cy.findByText('Create account').click();
// * Make sure account was created successfully and we are on the team joining page
cy.findByText('Teams you can join:', {timeout: TIMEOUTS.ONE_MIN}).should('be.visible');
@ -245,7 +249,9 @@ describe('Authentication', () => {
cy.get('#input_name').clear().type(`Test${getRandomId()}`);
cy.findByText('Create Account').click();
cy.get('#signup-body-card-form-check-terms-and-privacy').check();
cy.findByText('Create account').click();
// * Make sure account was not created successfully
cy.get('.AlertBanner__title').scrollIntoView().should('be.visible');
@ -271,7 +277,7 @@ describe('Authentication', () => {
cy.findByText('Copy invite link').click();
// # Input email, select member
cy.findByLabelText('Add or Invite People').type(`test-${getRandomId()}@mattermost.com{downarrow}{downarrow}{enter}`, {force: true});
cy.findByLabelText('Invite People').type(`test-${getRandomId()}@mattermost.com{downarrow}{downarrow}{enter}`, {force: true});
// # Click invite members button
cy.findByRole('button', {name: 'Invite'}).click({force: true});

View file

@ -7,7 +7,6 @@
// - Use element ID when selecting an element. Create one if none.
// ***************************************************************
// Stage: @prod
// Group: @channels @messaging @benchmark
import {reportBenchmarkResults} from '../../../utils/benchmark';

View file

@ -207,7 +207,6 @@ describe('Channel Info RHS', () => {
cy.get('#channel-info-btn').click();
cy.apiPatchChannel(testChannel.id, {
...testChannel,
purpose: 'purpose for the tests',
}).then(() => {
cy.uiGetRHS().findByText('purpose for the tests').should('be.visible');
@ -221,12 +220,44 @@ describe('Channel Info RHS', () => {
cy.get('#channel-info-btn').click();
cy.apiPatchChannel(testChannel.id, {
...testChannel,
header: 'header for the tests',
}).then(() => {
cy.uiGetRHS().findByText('header for the tests').should('be.visible');
});
});
it('should be able to rename channel from About area', () => {
// # Create a dedicated channel for renaming to avoid affecting other tests
cy.apiCreateChannel(testTeam.id, 'channel-to-rename', 'Channel To Rename', 'O').then(({channel}) => {
cy.apiAddUserToChannel(channel.id, admin.id);
// # Go to the channel
cy.visit(`/${testTeam.name}/channels/${channel.name}`);
// # Open Channel Info RHS
cy.get('#channel-info-btn').click();
// # Click edit on channel name (first Edit in About)
cy.uiGetRHS().findAllByLabelText('Edit').first().click({force: true});
// * Rename Channel modal appears
cy.findByRole('heading', {name: /rename channel/i}).should('be.visible');
// # Fill display name and URL
cy.findByPlaceholderText(/enter display name/i).clear().type('Renamed Channel');
cy.get('.url-input-button').click();
cy.get('.url-input-container input').clear().type('renamed-channel');
cy.get('.url-input-container button.url-input-button').click();
// # Save
cy.findByRole('button', {name: /save/i}).click();
// * URL updated
cy.location('pathname').should('include', `/${testTeam.name}/channels/renamed-channel`);
// * Header shows new name
cy.get('#channelHeaderTitle').should('contain', 'Renamed Channel');
});
});
});
describe('bottom menu', () => {
it('should be able to manage notifications', () => {
@ -237,11 +268,29 @@ describe('Channel Info RHS', () => {
cy.get('#channel-info-btn').click();
// # Click on "Notification Preferences"
cy.uiGetRHS().findByText('Notification Preferences').should('be.visible').click();
cy.uiGetRHS().findByTestId('channel_info_rhs-menu').findByText('Notification Preferences').scrollIntoView().should('be.visible').click();
// * Ensures the modal is there
cy.get('.ChannelNotificationModal').should('be.visible');
});
it('should open Channel Settings from RHS menu', () => {
// # Go to test channel
cy.visit(`/${testTeam.name}/channels/${testChannel.name}`);
// # Close RHS if it's open, then click on the channel info button
cy.get('body').then(($body) => {
if ($body.find('#rhsCloseButton').length > 0) {
cy.get('#rhsCloseButton').click();
}
cy.get('#channel-info-btn').should('be.visible').click();
});
// * Channel Settings item is visible in RHS menu
cy.uiGetRHS().findByTestId('channel_info_rhs-menu').findByText('Channel Settings').scrollIntoView().should('be.visible').click();
// * Channel Settings modal opens
cy.get('.ChannelSettingsModal').should('be.visible');
});
it('should be able to view files and come back', () => {
// # Go to test channel
cy.visit(`/${testTeam.name}/channels/${testChannel.name}`);
@ -250,7 +299,7 @@ describe('Channel Info RHS', () => {
cy.get('#channel-info-btn').click();
// # Click on "Files"
cy.uiGetRHS().findByTestId('channel_info_rhs-menu').findByText('Files').should('be.visible').click();
cy.uiGetRHS().findByTestId('channel_info_rhs-menu').findByText('Files').scrollIntoView().should('be.visible').click();
// * Ensure we see the files RHS
cy.uiGetRHS().findByText('No files yet').should('be.visible');
@ -277,10 +326,10 @@ describe('Channel Info RHS', () => {
cy.get('#channel-info-btn').click();
// # Click on "Pinned Messages"
cy.uiGetRHS().findByTestId('channel_info_rhs-menu').findByText('Pinned messages').should('be.visible').click();
cy.uiGetRHS().findByTestId('channel_info_rhs-menu').findByText('Pinned messages').scrollIntoView().should('be.visible').click();
// * Ensure we see the Pinned Post RHS
cy.uiGetRHS().findByText('Hello channel info rhs spec').should('be.visible');
cy.uiGetRHS().findByText('Hello channel info rhs spec').first().should('be.visible');
// # Click the Back Icon
cy.uiGetRHS().get('[aria-label="Back Icon"]').click();
@ -296,7 +345,7 @@ describe('Channel Info RHS', () => {
cy.get('#channel-info-btn').click();
// # Click on "Members"
cy.uiGetRHS().findByTestId('channel_info_rhs-menu').findByText('Members').should('be.visible').click();
cy.uiGetRHS().findByTestId('channel_info_rhs-menu').findByText('Members').scrollIntoView().should('be.visible').click();
// * Ensure we see the members
cy.uiGetRHS().contains('sysadmin').should('be.visible');
@ -382,7 +431,6 @@ describe('Channel Info RHS', () => {
cy.get('#channel-info-btn').click();
cy.apiPatchChannel(groupChannel.id, {
...groupChannel,
header: 'header for the tests',
}).then(() => {
cy.uiGetRHS().findByText('header for the tests').should('be.visible');
@ -399,7 +447,7 @@ describe('Channel Info RHS', () => {
cy.get('#channel-info-btn').click();
// # Click on "Notification Preferences"
cy.uiGetRHS().findByText('Notification Preferences').should('be.visible').click();
cy.uiGetRHS().findByTestId('channel_info_rhs-menu').findByText('Notification Preferences').scrollIntoView().should('be.visible').click();
// * Ensures the modal is there
cy.get('.ChannelNotificationModal').should('be.visible');
@ -476,7 +524,6 @@ describe('Channel Info RHS', () => {
cy.get('#channel-info-btn').click();
cy.apiPatchChannel(directChannel.id, {
...directChannel,
header: 'header for the tests',
}).then(() => {
cy.uiGetRHS().findByText('header for the tests').should('be.visible');
@ -489,6 +536,6 @@ describe('Channel Info RHS', () => {
function ensureRHSIsOpenOnChannelInfo(testChannel) {
cy.get('#rhsContainer').then((rhsContainer) => {
cy.wrap(rhsContainer).findByText('Info').should('be.visible');
cy.wrap(rhsContainer).findByText(testChannel.display_name).should('be.visible');
cy.wrap(rhsContainer).find('.sidebar--right__title__subtitle').should('contain', testChannel.display_name);
});
}

View file

@ -7,7 +7,6 @@
// - Use element ID when selecting an element. Create one if none.
// ***************************************************************
// Stage: @prod
// Group: @channels @channel @rhs
import * as TIMEOUTS from '../../../fixtures/timeouts';

View file

@ -7,7 +7,6 @@
// - Use element ID when selecting an element. Create one if none.
// ***************************************************************
// Stage: @prod
// Group: @channels @dm_category
import * as MESSAGES from '../../../fixtures/messages';

View file

@ -7,7 +7,6 @@
// - Use element ID when selecting an element. Create one if none.
// ***************************************************************
// Stage: @prod
// Group: @channels @channel_sidebar
import {

View file

@ -7,7 +7,6 @@
// - Use element ID when selecting an element. Create one if none.
// ***************************************************************
// Stage: @prod
// Group: @channels @collapsed_reply_threads
import {Channel} from '@mattermost/types/channels';

View file

@ -7,7 +7,6 @@
// - Use element ID when selecting an element. Create one if none.
// ***************************************************************
// Stage: @prod
// Group: @channels @custom_status
import moment from 'moment-timezone';

View file

@ -7,7 +7,6 @@
// - Use element ID when selecting an element. Create one if none.
// ***************************************************************
// Stage: @prod
// Group: @channels @custom_status
describe('Custom Status - Setting a Custom Status', () => {

View file

@ -49,7 +49,7 @@ describe('Verify Accessibility Support in different input fields', () => {
// * Verify Accessibility Support in Add or Invite People input field
cy.get('.users-emails-input__control').should('be.visible').within(() => {
cy.get('input').should('have.attr', 'aria-label', 'Add or Invite People').and('have.attr', 'aria-autocomplete', 'list');
cy.get('input').should('have.attr', 'aria-label', 'Invite People').and('have.attr', 'aria-autocomplete', 'list');
cy.get('.users-emails-input__placeholder').should('have.text', 'Enter a name or email address');
});
@ -58,7 +58,7 @@ describe('Verify Accessibility Support in different input fields', () => {
// * Verify Accessibility Support in Invite People input field
cy.get('.users-emails-input__control').should('be.visible').within(() => {
cy.get('input').should('have.attr', 'aria-label', 'Add or Invite People').and('have.attr', 'aria-autocomplete', 'list');
cy.get('input').should('have.attr', 'aria-label', 'Invite People').and('have.attr', 'aria-autocomplete', 'list');
cy.get('.users-emails-input__placeholder').should('have.text', 'Enter a name or email address');
});
@ -202,12 +202,12 @@ describe('Verify Accessibility Support in different input fields', () => {
cy.get('#FormattingControl_ul').should('be.focused').and('have.attr', 'aria-label', 'bulleted list').tab();
// * Verify if the focus is on the numbered list button
cy.get('#FormattingControl_ol').should('be.focused').and('have.attr', 'aria-label', 'numbered list').tab().tab();
cy.get('#FormattingControl_ol').should('be.focused').and('have.attr', 'aria-label', 'numbered list').tab().tab().tab();
// * Verify if the focus is on the formatting options button
cy.get('#toggleFormattingBarButton').should('be.focused').and('have.attr', 'aria-label', 'formatting').tab();
// * Verify if the focus is on the attachment icon
// * Verify if the focus is on the attachment icon (skipping burn-on-read button when enabled)
cy.get('#fileUploadButton').should('be.focused').and('have.attr', 'aria-label', 'attachment').tab();
// * Verify if the focus is on the emoji picker

View file

@ -1,222 +0,0 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
// ***************************************************************
// - [#] indicates a test step (e.g. # Go to a page)
// - [*] indicates an assertion (e.g. * Check the title)
// - Use element ID when selecting an element. Create one if none.
// ***************************************************************
// Stage: @prod
// Group: @channels @enterprise @accessibility
import {Channel} from '@mattermost/types/channels';
import {Team} from '@mattermost/types/teams';
import {UserProfile} from '@mattermost/types/users';
import * as TIMEOUTS from '../../../../fixtures/timeouts';
describe('Verify Accessibility Support in Modals & Dialogs', () => {
let testTeam: Team;
let testChannel: Channel;
let testUser: UserProfile;
let selectedRowText: string;
before(() => {
// * Check if server has license for Guest Accounts
cy.apiRequireLicenseForFeature('GuestAccounts');
cy.apiInitSetup({userPrefix: 'user000a'}).then(({team, channel, user}) => {
testTeam = team;
testChannel = channel;
testUser = user;
cy.apiCreateUser({prefix: 'user000b'}).then(({user: newUser}) => {
cy.apiAddUserToTeam(testTeam.id, newUser.id).then(() => {
cy.apiAddUserToChannel(testChannel.id, newUser.id);
});
});
});
});
beforeEach(() => {
// # Login as sysadmin and visit the town-square
cy.apiAdminLogin();
cy.visit(`/${testTeam.name}/channels/town-square`);
});
it('MM-T1466 Accessibility Support in Direct Messages Dialog screen', () => {
// * Verify the aria-label in create direct message button
cy.uiAddDirectMessage().click();
// * Verify the accessibility support in Direct Messages Dialog
cy.findAllByRole('dialog', {name: 'Direct Messages'}).eq(0).within(() => {
cy.findByRole('heading', {name: 'Direct Messages'});
// * Verify the accessibility support in search input
cy.findByLabelText('Search for people').
should('have.attr', 'aria-autocomplete', 'list');
// # Search for a text and then check up and down arrow
cy.findByLabelText('Search for people').
typeWithForce('s').
wait(TIMEOUTS.HALF_SEC).
typeWithForce('{downarrow}{downarrow}{downarrow}{uparrow}');
cy.get('#multiSelectList').children().eq(2).should('have.class', 'more-modal__row--selected').within(() => {
cy.get('.more-modal__name').invoke('text').then((user) => {
selectedRowText = user.split(' - ')[0].replace('@', '');
});
// * Verify image alt is displayed
cy.get('img.Avatar').should('have.attr', 'alt', 'user profile image');
});
// * Verify if the reader is able to read out the selected row
cy.get('.filtered-user-list div.sr-only:not([role="status"])').
should('have.attr', 'aria-live', 'polite').
and('have.attr', 'aria-atomic', 'true').
invoke('text').then((text) => {
expect(text).equal(selectedRowText);
});
// # Search for an invalid text
const additionalSearchTerm = 'somethingwhichdoesnotexist';
cy.findByLabelText('Search for people').clear().
typeWithForce(additionalSearchTerm).
wait(TIMEOUTS.HALF_SEC);
// * Check if reader can read no results
cy.get('.multi-select__wrapper').should('have.attr', 'aria-live', 'polite').and('have.text', `No results found matching ${additionalSearchTerm}`);
});
});
it('MM-T1467 Accessibility Support in Browse Channels Dialog screen', () => {
function getChannelAriaLabel(channel) {
return channel.display_name.toLowerCase() + ', ' + channel.purpose.toLowerCase();
}
// # Create atleast 2 channels
let otherChannel;
cy.apiCreateChannel(testTeam.id, 'z_accessibility', 'Z Accessibility', 'O', 'other purpose').then(({channel}) => {
otherChannel = channel;
});
cy.apiCreateChannel(testTeam.id, 'accessibility', 'Accessibility', 'O', 'some purpose').then(({channel}) => {
cy.apiLogin(testUser).then(() => {
cy.reload();
// * Verify the aria-label in more public channels button
cy.uiBrowseOrCreateChannel('Browse channels');
// * Verify the accessibility support in More Channels Dialog
cy.findByRole('dialog', {name: 'Browse Channels'}).within(() => {
cy.findByRole('heading', {name: 'Browse Channels'});
// * Verify the accessibility support in search input
cy.findByPlaceholderText('Search channels');
cy.get('#moreChannelsList').should('be.visible').then((el) => {
return el[0].children.length === 2;
});
// # Hide already joined channels
cy.findByText('Hide Joined').click();
// # Focus on the Create Channel button and TAB five time
cy.get('#createNewChannelButton').focus().tab().tab().tab().tab().tab();
// * Verify channel name is highlighted and reader reads the channel name and channel description
cy.get('#moreChannelsList').within(() => {
const selectedChannel = getChannelAriaLabel(channel);
cy.findByLabelText(selectedChannel).should('be.visible').should('be.focused');
});
// * Press Tab again and verify if focus changes to next row
cy.focused().tab();
cy.findByLabelText(getChannelAriaLabel(otherChannel)).should('be.focused');
});
});
});
});
it('MM-T1468 Accessibility Support in Add people to Channel Dialog screen', () => {
// # Add atleast 5 users
for (let i = 0; i < 5; i++) {
cy.apiCreateUser().then(({user}) => {
cy.apiAddUserToTeam(testTeam.id, user.id);
});
}
// # Visit the test channel, and wait for the page to fully load
cy.visit(`/${testTeam.name}/channels/${testChannel.name}`);
// # Open Add Members Dialog
cy.uiOpenChannelMenu('Members');
cy.uiGetButton('Add').click();
// * Verify the accessibility support in Add people Dialog
cy.findAllByRole('dialog').eq(0).within(() => {
const modalName = `Add people to ${testChannel.display_name}`;
cy.findByRole('heading', {name: modalName});
cy.wait(TIMEOUTS.ONE_SEC);
// * Verify the accessibility support in search input
cy.findByLabelText('Search for people or groups').
should('have.attr', 'aria-autocomplete', 'list');
// # Search for a text and then check up and down arrow
cy.findByLabelText('Search for people or groups').
wait(TIMEOUTS.HALF_SEC).
typeWithForce('u').
wait(TIMEOUTS.HALF_SEC).
typeWithForce('{downarrow}{downarrow}{downarrow}{downarrow}{uparrow}');
cy.get('#multiSelectList').
children().eq(2).
should('have.class', 'more-modal__row--selected').
within(() => {
cy.get('.more-modal__name').invoke('text').then((user) => {
selectedRowText = user.split(' - ')[0].replace('@', '');
});
// * Verify image alt is displayed
cy.get('img.Avatar').should('have.attr', 'alt', 'user profile image');
});
// * Verify if the reader is able to read out the selected row
cy.get('.filtered-user-list div.sr-only:not([role="status"])').
should('have.attr', 'aria-live', 'polite').
and('have.attr', 'aria-atomic', 'true').
invoke('text').then((text) => {
// Check that the readout starts with the selected user since it may be followed by
// "Already in Channel" depending on which user was selected
expect(text).to.match(new RegExp(`^${selectedRowText}\\b`));
});
// # Search for an invalid text and check if reader can read no results
cy.findByLabelText('Search for people or groups').
typeWithForce('somethingwhichdoesnotexist').
wait(TIMEOUTS.HALF_SEC);
// * Check if reader can read no results
cy.get('.custom-no-options-message').
should('be.visible').
and('contain', 'No matches found - Invite them to the team');
});
});
it('MM-T1515 Verify Accessibility Support in Invite People Flow', () => {
// # Open Invite People
cy.uiGetLHSHeader().click();
cy.get("#sidebarTeamMenu li:contains('Invite people')").should('be.visible').click();
// * Verify accessibility support in Invite People Dialog
cy.findByTestId('invitationModal').should('have.attr', 'aria-modal', 'true').and('have.attr', 'aria-labelledby', 'invitation_modal_title').and('have.attr', 'role', 'dialog');
cy.get('#invitation_modal_title').should('be.visible').and('contain.text', 'Invite people to');
// # Press tab
cy.get('button.icon-close').focus().tab({shift: true}).tab();
// * Verify tab focuses on close button
cy.get('button.icon-close').should('have.attr', 'aria-label', 'Close').and('be.focused');
});
});

View file

@ -58,7 +58,9 @@ describe('Authentication', () => {
cy.get('#input_name').clear().type(`Test${getRandomId()}`);
cy.findByText('Create Account').click();
cy.get('#signup-body-card-form-check-terms-and-privacy').check();
cy.findByText('Create account').click();
// * Make sure account was not created successfully
cy.get('.AlertBanner__title').scrollIntoView().should('be.visible');

View file

@ -7,7 +7,6 @@
// - Use element ID when selecting an element. Create one if none.
// ***************************************************************
// Stage: @prod
// Group: @channels @enterprise @not_cloud @system_console
describe('MM-T2574 Session Lengths', () => {

View file

@ -78,13 +78,16 @@ describe('Guest Accounts', () => {
// # Click "Save".
cy.findByText('Save').click().wait(TIMEOUTS.ONE_SEC);
// # Get MFA secret
// # Visit a page to trigger MFA setup redirect, then complete MFA setup for admin
cy.visit('/');
cy.url().should('include', 'mfa/setup');
cy.uiGetMFASecret(sysadmin.id).then((secret) => {
adminMFASecret = secret;
});
// # Navigate to Guest Access page.
cy.visit('/admin_console/authentication/guest_access');
cy.url().should('include', '/admin_console/authentication/guest_access');
// # Enable guest accounts.
cy.findByTestId('GuestAccountsSettings.Enabletrue').check();
@ -144,20 +147,20 @@ describe('Guest Accounts', () => {
// # Create an account with Email and Password.
cy.get('#input_name').type(username);
cy.get('#input_password-input').type(username);
cy.findByText('Create Account').click();
cy.findByText('Create account').click();
// * When MFA is enforced for Guest Access, guest user should be forced to configure MFA while creating an account.
cy.url().should('include', 'mfa/setup');
cy.get('#mfa').wait(TIMEOUTS.HALF_SEC).find('.col-sm-12').then((p) => {
cy.get('#mfa').wait(TIMEOUTS.HALF_SEC).find('p.col-sm-12 span').then((p) => {
const secretp = p.text();
const secret = secretp.split(' ')[1];
const token = authenticator.generateToken(secret);
cy.get('#mfa').find('.form-control').type(token);
cy.get('#mfa').find('.btn.btn-primary').click();
cy.findByPlaceholderText('MFA Code').type(token);
cy.findByText('Save').click();
cy.wait(TIMEOUTS.ONE_SEC);
cy.get('#mfa').find('.btn.btn-primary').click();
cy.findByText('Okay').click();
});
cy.apiLogout();
});

View file

@ -134,9 +134,9 @@ describe('Guest Account - Guest User Invitation Flow', () => {
cy.findByText('Update email').should('be.visible').click();
// * Update email outside whitelisted domain and verify error message
cy.findByTestId('resetEmailModal').should('be.visible').within(() => {
cy.findByTestId('resetEmailForm').should('be.visible').get('input').type(email);
cy.findByTestId('resetEmailButton').click();
cy.get('#resetEmailModal').should('be.visible').within(() => {
cy.get('input[type="email"]').type(email);
cy.get('button.btn-primary.confirm').click();
cy.get('.error').should('be.visible').and('have.text', 'The email you provided does not belong to an accepted domain for guest accounts. Please contact your administrator or sign up with a different email.');
cy.get('.close').click();
});

View file

@ -7,7 +7,6 @@
// - Use element ID when selecting an element. Create one if none.
// ***************************************************************
// Stage: @prod
// Group: @channels @enterprise @guest_account
/**

View file

@ -106,7 +106,7 @@ describe('Guest Account - Member Invitation Flow', () => {
cy.get('#input_email').type(email);
cy.get('#input_name').type(username);
cy.get('#input_password-input').type('Testing123');
cy.findByText('Create Account').click();
cy.findByText('Create account').click();
// * Verify if user is added to the invited team
cy.uiGetLHSHeader().findByText(testTeam.display_name);

View file

@ -85,9 +85,9 @@ describe('Guest Account - Verify Manage Guest Users', () => {
// * Update email of Guest User
const email = `temp-${getRandomId()}@mattermost.com`;
cy.findByTestId('resetEmailModal').should('be.visible').within(() => {
cy.findByTestId('resetEmailForm').should('be.visible').get('input').type(email);
cy.findByTestId('resetEmailButton').click();
cy.get('#resetEmailModal').should('be.visible').within(() => {
cy.get('input[type="email"]').type(email);
cy.get('button.btn-primary.confirm').click();
});
// * Verify if Guest's email was updated

Some files were not shown because too many files have changed in this diff Show more