Сравнить коммиты

1156 Коммитов

Автор SHA1 Сообщение Дата
Luc Didry
7827abb05f 📌 — Update Golang to 1.25.8
Некоторые проверки не удались
ESR Upgrade / Run ESR upgrade script from 5.37 to 7.8 (push) Has been skipped
ESR Upgrade / Run ESR upgrade script from 5.37 to 6.3 (push) Has been skipped
ESR Upgrade / Run ESR upgrade script from 6.3 to 7.8 (push) Has been skipped
Server CI Master / master-ci (push) Failing after 8m39s
Web App CI Master / master-ci (push) Failing after 21m26s
2026-04-22 16:24:34 +02:00
Luc Didry
286ab31a42 🩹 — Adapt limitless.patch for v10.11.0 2026-04-22 16:21:28 +02:00
Luc Didry
c890831b13 🚚 — Officially fork Mattermost
- 👷🩹 — Add limitless patch and GitlabCI recipe
- 📝 — Add instructions on how to use the patch from Framasoft
- 💄 — Add logo, thanks to Geoffrey Dorne
- 👷 — ARM64 cross-compilation in CI
2026-04-22 16:21:28 +02:00
Jesse Hallam
f6760151c4 Support Elasticsearch v9 (for v10.11) (#35925)
* Support Elasticsearch v9 alongside v8

* Add CI workflow changes for Elasticsearch v8/v9 testing

* Support Elasticsearch v7 in addition to v8/v9, add v7 CI test job

Lowers the minimum supported ES version from 8 to 7 to avoid dropping
v7 support in a dot release. Adds a dedicated CI job to verify v7
compatibility alongside the existing v8 and v9 (default) jobs.

* Fix ES7 plugin install crash on cgroup v2 hosts

* Fix ES 7 container startup on cgroup v2 Linux (GitHub Actions)

ES 7 bundles JDK 11, which crashes with a NullPointerException in
CgroupV2Subsystem.getMountPoint() on modern Linux kernels that use
cgroup v2 (including GitHub Actions ubuntu-latest runners). The flag
was already set during the Dockerfile RUN step, but not at runtime.

Adding -XX:-UseContainerSupport to ES_JAVA_OPTS in docker-compose
fixes the crash. The flag is harmless on ES 8/9 which ship JDK 17+
where the cgroup v2 bug is fixed (it simply opts out of container-aware
JVM sizing).

* Capture docker compose logs in CI test artifact

* Use ES 7.17.29 for v7 CI test; remove cgroup v2 workarounds

ES 7.17.0 bundled JDK 17.0.1 which had a cgroup v2 bug
(CgroupV2Subsystem NPE) not fixable via -XX:-UseContainerSupport.
ES 7.17.29 bundles JDK 22 where the bug is long fixed.

Reverts the -XX:-UseContainerSupport workarounds added in the
previous two commits as they were based on a wrong diagnosis
and are no longer needed.

---------

Co-authored-by: Mattermost Build <build@mattermost.com>
2026-04-20 20:44:31 +02:00
Rajat Dabade
b65ae49523 Upgraded board prepacked version to v9.2.4 (#36140)
Automatic Merge
2026-04-20 08:12:10 +02:00
Harshil Sharma
5854257739 Manual CP of 35755 for v10.11 (#36135)
Automatic Merge
2026-04-17 21:42:09 +02:00
Alejandro García Montoro
f36531c479 Update golang.org/x/image to v0.38.0 (#36148)
Co-authored-by: Mattermost Build <build@mattermost.com>
2026-04-17 17:55:10 +00:00
Alejandro García Montoro
29dd6d0cfd MM-68369: add missing TearDown in TestWebConnRejectBinaryFrameUnauthenticated (#36172)
The test at channels/app/platform/web_conn_test.go was added by #35988
without a defer th.TearDown() call. Setup(t) creates a PlatformService
that opens its own SqlStore pool and runs morph migrations against the
shared temp database. Without TearDown, that pool stays alive until
TestMain exits, so the morph-held idle connections are still attached
to the database when MainHelper.Close runs DROP DATABASE. Postgres
refuses the drop with "is being accessed by other users" and the whole
package panics in teardown.

On master and release-11.4 and later, setupTestHelper registers the
shutdown via tb.Cleanup automatically, so the same test does not leak
there. release-10.11 still uses the manual TearDown pattern, which is
why the fix is scoped to this branch.
2026-04-17 17:27:42 +00:00
Jesse Hallam
73d5f507a4 Cherry-pick Go 1.25.8 upgrade for release-10.11 (#36125)
* ci: shard server Postgres tests into 4 parallel runners (#35739)

* ci: add test sharding plumbing to server CI

Add infrastructure for upcoming test sharding without changing behavior:

- Add shard-index and shard-total inputs to server-test-template.yml
  (defaults preserve existing single-runner behavior)
- Add timing cache restore step (activates only when shard-total > 1)
- Add merge-postgres-test-results job to server-ci.yml that:
  - Merges JUnit XML reports from shard artifacts
  - Saves timing data cache for future shard balancing
  - Handles both single-artifact and multi-shard scenarios
- Add .gitignore entries for timing cache and shard work files

Co-authored-by: Claude <claude@anthropic.com>

* ci: shard server Postgres tests into 4 parallel runners

Extract sharding logic into standalone, tested scripts and enable
4-shard parallel test execution for server Postgres CI:

Scripts:
- server/scripts/shard-split.js: Node.js bin-packing solver that
  assigns test packages to shards using timing data from previous runs.
  Two-tier strategy: light packages (<2min) whole, heavy packages
  (api4, app) split at individual test level.
- server/scripts/run-shard-tests.sh: Multi-run wrapper that calls
  gotestsum directly for each package group with -run regex filters.
- server/scripts/shard-split.test.js: 8 test cases covering round-robin
  fallback, timing-based balancing, heavy package splitting, JUnit XML
  fallback, and enterprise package separation.

Workflow changes:
- server-test-template.yml: Add shard splitting step that discovers test
  packages and runs the solver. Modified Run Tests step to use wrapper
  script when sharding is active.
- server-ci.yml: Add 4-shard matrix to test-postgres-normal. Update
  merge job artifact patterns for shard-specific names.

Performance: 7.2 min with timing cache vs 62.5 min baseline = 88%
wall-time improvement. First run without cache uses JUnit XML fallback
or round-robin, then populates the cache for subsequent runs.

Co-authored-by: Claude <claude@anthropic.com>

* fix: raise heavy package threshold to 5 min to preserve test isolation

sqlstore integrity tests scan the entire database and fail when other
packages' test data is present. At 182s, sqlstore was just over the
120s threshold and getting split at test level. Raising to 300s keeps
only api4 (~38 min) and app (~15 min) as heavy — where the real
sharding gains are — while sqlstore, elasticsearch, etc. stay whole
and maintain their test isolation guarantees.

Co-authored-by: Claude <claude@anthropic.com>

* ci: only save test timing cache on default branch

PR branches always restore from master's timing cache via restore-keys
prefix matching. Timing data is stable day-to-day so this eliminates
cache misses on first PR runs and reduces cache storage.

Co-authored-by: Claude <claude@anthropic.com>

* ci: skip FIPS tests on PRs (enterprise CI handles compile check)

Per review feedback: the enterprise CI already runs a FIPS compile
check on every PR. Running the full FIPS test suite on PRs is redundant
since it uses the identical test suite as non-FIPS — the only
FIPS-specific failure mode is a build failure from non-approved crypto
imports, which the enterprise compile check catches.

Full FIPS tests continue to run on every push to master.

Co-authored-by: Claude <claude@anthropic.com>

* fix: address review feedback on run-shard-tests.sh

- Remove set -e so all test runs execute even if earlier ones fail;
  track failures and exit with error at the end (wiggin77)
- Remove unused top-level COVERAGE_FLAG variable (wiggin77)
- Fix RUN_IDX increment position so report, json, and coverage files
  share the same index (wiggin77)
- Update workflow comment: heavy threshold is 5 min, not 2 min (wiggin77)

Co-authored-by: Claude <claude@anthropic.com>

* style: use node: prefix for built-in fs module in shard-split.js

Co-authored-by: Claude <claude@anthropic.com>

* fix: avoid interpolating file paths into generated shell script

Read shard package lists from files at runtime instead of interpolating
them into the generated script via printf. This prevents theoretical
shell metacharacter injection from directory names, as flagged by
DryRun Security.

Co-authored-by: Claude <claude@anthropic.com>

* fix(ci): rename merged artifact to match server-ci-report glob

The merged artifact was named postgres-server-test-logs-merged which
does not match the *-test-logs pattern in server-ci-report.yml,
causing Postgres test results to be missing from PR/commit reports.

Also pins junit-report-merger to exact version 7.0.0 for supply chain
safety.

Co-authored-by: Claude <claude@anthropic.com>

* fix(ci): pass RACE_MODE env into Docker container

RACE_MODE was set on the host runner but never included in the docker
run --env list. The light-package path worked because the heredoc
expanded on the host, but run-shard-tests.sh reads RACE_MODE at
runtime inside the container where it was unset. This caused heavy
packages (api4, app) to silently lose -race detection.

Co-authored-by: Claude <claude@anthropic.com>

* fix(ci): discover new tests in heavy packages not in timing cache

Tests not present in the timing cache (newly added or renamed) would
not appear in any shard -run regex, causing them to silently skip.
After building items from the cache, run go test -list to discover
current test names and assign any cache-missing tests to shards via
the normal bin-packing algorithm with a small default duration.

Co-authored-by: Claude <claude@anthropic.com>

* fix(ci): add missing line continuation backslash in docker run

The previous --env FIPS_ENABLED line was missing a trailing backslash
after adding --env RACE_MODE, causing docker run to see a truncated
command and fail with "requires at least 1 argument".

Co-authored-by: Claude <claude@anthropic.com>

* fix(ci): add setup-go step for shard test discovery

go test -list in shard-split.js runs on the host runner via execSync,
but Go is only available inside the Docker container. Without this
step, every invocation fails silently and new-test discovery is a
no-op. Adding actions/setup-go before the shard split step ensures
the Go toolchain is available on the host.

Co-authored-by: Claude <claude@anthropic.com>

---------

Co-authored-by: Claude <claude@anthropic.com>

* updated go to version 1.25.8 (#35817)

* updated go to version 1.25.8

* updated gotestsum version to work with go 1.25.8

go 1.25 does not work with indirect tools 0.11 dependency pulled by
gotestsum.

* Use sync.WaitGroup.Go to simplify goroutine creation

Replace the wg.Add(1) + go func() { defer wg.Done() }() pattern with
wg.Go(), which was introduced in Go 1.25.

* pushes fips image on workflow dispatch to allow fips test to run on go version update

* fix new requirements for FIPS compliance imposed on updating to go 1.25.8

* updates openssl symbol check for library shipped with FIPS new versions

go-openssl v2 shipped with FIPS versions starting from 1.25 uses mkcgo to generate
bindings causing symbol names to be different.

* removes temp workflow-dispatch condition

* keep versions out of agents md file

* upgrade golangci-lint (#35845)

* test: clean up channel store data after TestChannelStore (#36066)

TestChannelStore sub-tests create channels, members, and team members
using fake TeamIds and UserIds (model.NewId() for non-existent rows).
These records are left in the database and cause integrity tests
(TestCheck*) running in the same binary to fail their full-table scans.

Register a t.Cleanup on TestChannelStore that purges the affected
tables entirely. A blanket purge is safe: the schema enforces no FK
constraints, and every test suite creates its own data independently.

* Fix command injection in server-test-template workflow (#36080)

Replace the unquoted heredoc (which embedded GITHUB_HEAD_REF into a
generated script) with a cp of the existing run-shard-tests.sh, which
already handles the light-only case. Pass BUILD_NUMBER and TEST_TARGET
as explicit docker env vars instead of interpolating them into script
content.

* fix(ci): restore testname format in sharded gotestsum runs (#36078)

run-shard-tests.sh called gotestsum directly without --format, so it
fell back to gotestsum's default (pkgname) instead of the testname
format set by the Makefile. Pass --format "${GOTESTSUM_FORMAT:-testname}"
to match the Makefile default.

Co-authored-by: Mattermost Build <build@mattermost.com>

* fix(lint): fix pre-existing golangci-lint v2.11.4 issues

Fix misspelling in comment and redundant nil check flagged by the
upgraded linter.

* ci: use golang image for test runner on release-10.11

mattermost-build-server images are not built for release branches.
Use the official golang image which is always available for any Go version.

* ci: use mattermost/mattermost-build-server for release-10.11

The mattermostdevelopment/ images are only built for master.
The production mattermost/ images are built for release branches.

* ci: use mattermost/mattermost-build-server in mmctl test template

The mattermostdevelopment/ images are only built for master.
The production mattermost/ images are built for release branches.

---------

Co-authored-by: Pavel Zeman <pavel.zeman@mattermost.com>
Co-authored-by: Claude <claude@anthropic.com>
Co-authored-by: Carlos Garcia <carlos.garcia@mattermost.com>
Co-authored-by: Mattermost Build <build@mattermost.com>
2026-04-16 09:14:15 -03:00
Caleb Roseland
384635216f Update msgpack fork dependency (#35988) (#36043)
(cherry picked from commit 17939826efa20a97f087b3d390ec5136df350bae)

Co-authored-by: Mattermost Build <build@mattermost.com>
2026-04-16 04:02:45 +00:00
sabril
26f09017e1 test: demote unstable tests (#36127) 2026-04-16 10:47:42 +08:00
Mattermost Build
610a28e9fa Automated cherry pick of #35562 (#36095)
* adds team member data sanitizing (#35562)

* adds team member data sanitizing

* assert using require

* adds data sanitizing to team members for user endpoint

* team admin data visibility now tests with different user

(cherry picked from commit 2be57a7ec0c67004b77c76386f20a630920196e3)

* removes wrong argument in test helper calls

* fix: add explicit permission grant in team members test (#36007)

* fix: add explicit permission grant in team members test

TestGetTeamMembersForUserRoleDataSanitization was relying on a permission
side-effect leaked from concurrent tests. Under fullyparallel, another test
temporarily adds PermissionReadOtherUsersTeams to system_user role, which
the team admin subtest accidentally benefits from. Under sequential execution
(binary parameters mode), no concurrent test leaks this permission, so the
team admin correctly gets 403.

Fix by explicitly granting ReadOtherUsersTeams in the subtest setup, matching
the pattern used in adjacent subtests.

Release Note
NONE

Co-authored-by: Claude <claude@anthropic.com>

* fix: remove explanatory comment per review feedback

---------

Co-authored-by: Claude <claude@anthropic.com>

* removes extra arg from test helper call

---------

Co-authored-by: Carlos Garcia <carlos.garcia@mattermost.com>
Co-authored-by: Pavel Zeman <pavel.zeman@mattermost.com>
Co-authored-by: Claude <claude@anthropic.com>
2026-04-16 08:58:14 +08:00
sabril
787fca6a08 add the E2E Tests/verified label (#36116) 2026-04-15 15:48:18 +00:00
unified-ci-app[bot]
e19259bd6b Update latest patch version to 10.11.15 (#36090)
Co-authored-by: unified-ci-app[bot] <121569378+unified-ci-app[bot]@users.noreply.github.com>
Co-authored-by: Mattermost Build <build@mattermost.com>
2026-04-15 22:32:50 +08:00
Andre Vasconcelos
667dffe31d Improved processing of attachments (#35854) (#36103)
# Conflicts:
#	server/channels/app/slack.go

Co-authored-by: Mattermost Build <build@mattermost.com>
2026-04-15 22:32:34 +08:00
Harshil Sharma
7526844c50 Fixed URL validation for integration actions (#35857) (#36108)
* Fixed URL validation for integratioon actions

* SImplified check to avoid subpath incompatibility

* minor tweak

* refactored for better tests

Co-authored-by: Mattermost Build <build@mattermost.com>
2026-04-15 22:32:14 +08:00
sabril
7ab7f0bd00 SEC-10095 test(cypress): demote unstable tests (#36099)
* test(cypress): demote unstable tests

* follow fixes

* fix merging playwright reports
2026-04-15 21:38:49 +08:00
nang2049
82b3f494b4 Add prepackaged version of github plugin v2.7. (#35968) (#36107)
Automatic Merge
2026-04-15 15:12:22 +02:00
Andre Vasconcelos
54b48f32d1 Bumping prepackaged zoom version to 1.13.0 (#35998) (#36030)
Automatic Merge
2026-04-15 12:12:13 +02:00
Carlos Garcia
b21ef30202 Mm 67896 manual cherry pick onto release 10.11 (#35989)
* improves time limit checks

* consistently check for presence of patch fields

* fix variable shadowing in test

* allow idempotent pinning operations with time limit expired

* new utility function for post limit time check

* fix style issue

* Add missing E2E CI files and delivery-platform migration for release-10.11

- Add calculate-playwright-results and calculate-cypress-results GitHub Actions
  (referenced by e2e-tests-playwright-template.yml and e2e-tests-cypress-template.yml
  but never backported to release-10.11)
- Add e2e-tests/playwright/merge.config.mjs (required by merge-reports step)
- Add run-specs Makefile target and server.run_specs.sh (required by run-failed-tests job)
- Fix merge-shard-results step: pin @playwright/test version and add fallback
  for when no blob reports exist (json reporter output used directly)
- Remove pull_request trigger from e2e-tests-ci.yml (delivery-platform migration)
- Remove dead e2e-fulltests-ci.yml and e2e-tests-ci-template.yml

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

---------

Co-authored-by: Mattermost Build <build@mattermost.com>
Co-authored-by: yasserfaraazkhan <attitude3cena.yf@gmail.com>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-14 18:38:57 +08:00
Amy Blais
e092af7a33 Revert "[release-10.11] Add prepackaged version of github plugin v2.7.0 (#35973)" (#36012)
Automatic Merge
2026-04-10 08:06:03 +02:00
Just Nev
4399e4c97c [release-10.11] Add prepackaged version of github plugin v2.7.0 (#35973)
Cherry-pick of e2e7aed678d12e9d2ed121682933943a917a32ba onto release-10.11

Co-authored-by: Nevyana Angelova <nevyangelova@192.168.100.47>
2026-04-08 13:15:42 +03:00
Jesse Hallam
70d1794916 [release-10.11] Automate setup-go-work as a dependency for Make targets (#35780)
* Automate setup-go-work as a dependency for Make targets (#35476)

* automate setup-go-work

It's all to easy to forget to `make setup-go-work`, only to run into mysterious build failures. Let's default to doing this automatically, unless `SKIP_SETUP_GO_WORK` is true (or the legacy `IGNORE_GO_WORK_IF_EXISTS`, which was oddly named, since we can't actually ignore it.)

* Make setup-go-work recipe fail-fast with set -e

* ci: post success to required e2e status contexts when no relevant changes (#35880)

* ci: post correct skip status from within cypress/playwright reusable workflows

The 'Required Status Checks' ruleset requires e2e-test/cypress-full/enterprise
and e2e-test/playwright-full/enterprise on master and release-*.* branches.
When a PR has no E2E-relevant changes, the jobs were silently skipped, leaving
required statuses unset and the PR permanently blocked.

Architecture fix: instead of a separate skip-e2e job in the caller that
hardcodes status context names, the skip logic now lives inside the reusable
workflows that already own and compute those context names.

Changes:
- e2e-tests-cypress.yml: add should_run input (default 'true') + skip job
  that uses the dynamically-computed context_name when should_run == 'false'
- e2e-tests-playwright.yml: same pattern
- e2e-tests-ci.yml: change e2e-cypress/e2e-playwright job conditions from
  should_run == 'true' to PR_NUMBER != '' (always run when there's a PR),
  pass should_run as input to both reusable workflows

* Add E2E template workflows for Cypress and Playwright

* Add check-e2e-test-only action for E2E workflow

* Fix: Remove circular E2E workflow file check - skip tests when only CI files change

* Add pull_request trigger to E2E workflow - run automatically on PR events

* Fix resolve-pr to use github.event context for automatic pull_request trigger

* Fix checkout condition to work with pull_request events

* Fix: Remove orphaned fi statement in check-changes script

---------

Co-authored-by: yasser khan <attitude3cena.yf@gmail.com>
2026-04-02 13:45:24 +00:00
Rajat Dabade
075d975ca7 Added FakeSetting for keys generation for support package (#35859) 2026-04-01 17:59:38 +03:00
Christopher Poile
c654f0502f [MM-67143] cherry pick of #34922 (#35800)
Automatic Merge
2026-03-27 07:30:55 +01:00
Harrison Healey
c64ff9d84e MM-66937 Fix broken IME handling in Find Channels modal (#35264) (#35798)
* MM-66937 Add E2E tests for bug

* MM-66937 Remove delayInputUpdate on that input to fix the bug

* Remove delayInputUpdate prop from QuickInput and SuggestionBox

* Run prettier

* Inline updateInputFromProps and remove eslint-disable that's no longer needed

* Fix snapshots
2026-03-27 08:14:04 +02:00
Mattermost Build
6838381cf9 [MM-65701] Fix for docextractor archive handling (#34983) (#35792)
Automatic Merge
2026-03-26 08:31:04 +01:00
Mattermost Build
450dba8cad Automated cherry pick of #35558 (#35716)
Automatic Merge
2026-03-20 21:30:55 +01:00
Guillermo Vayá
532f2882d1 [MM-67377] cherry-pick Fix (#35336) (#35657)
Automatic Merge
2026-03-20 12:30:54 +01:00
Ben Cooke
8ef7f78d8d fix conflicts (#35699)
Automatic Merge
2026-03-20 09:00:55 +01:00
Mattermost Build
5eceedaa89 Automated cherry pick of #35669 (#35695)
Automatic Merge
2026-03-20 07:31:11 +01:00
Bill Gardner
415033217e Update plugin-calls to v1.11.4 (#35662)
Automatic Merge
2026-03-19 08:00:55 +01:00
Julien Tant
6b2e530d00 Bumping prepackaged Playbooks plugin version to v2.4.4 (#35677)
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-18 12:23:43 -07:00
Mattermost Build
24a90356e6 Automated cherry pick of #35490 (#35650)
Automatic Merge
2026-03-18 14:30:54 +01:00
Mattermost Build
8c4ed0b65b Validate RefreshedToken differs from original invite token (#34864) (#35656)
Automatic Merge
2026-03-17 12:31:12 +01:00
Mattermost Build
305be32134 encode special characters on some error pages (#35492) (#35652)
Automatic Merge
2026-03-17 12:01:02 +01:00
Andre Vasconcelos
768dc7dfb9 Bumping prepackaged GitLab plugin version to v1.12.1 (#35595) (#35602)
Automatic Merge
2026-03-16 10:55:37 +01:00
Andre Vasconcelos
68dc691fee Bumping prepackaged MS Teams Meetings plugin version to 2.4.1 (#35564) (#35575)
Automatic Merge
2026-03-16 10:55:30 +01:00
unified-ci-app[bot]
4ecc6a0141 Update latest patch version to 10.11.14 (#35621)
Automatic Merge
2026-03-16 09:25:21 +01:00
Mattermost Build
bc1a2b34b1 keeps plugin config on reenablement (#35545) (#35581)
* keeps plugin config on reenablement

* fixes local config patch on plugin reenablement

(cherry picked from commit c9a4092ac0a20351e3c2e0ac0cb593cc28b5bc0e)

Co-authored-by: Carlos Garcia <carlos.garcia@mattermost.com>
2026-03-16 08:01:26 +02:00
Mattermost Build
8b7e26fa13 Automated cherry pick of #35269 (#35459)
* MM-67522 Add tests for syncing user statuses (#35269)

* MM-67522 Add tests for syncing user statuses

* Clean up newly added tests

* Fix style

* Use SyncResponse.StatusErrors when statuses fail to sync

(cherry picked from commit 033867a3448875d84653c81026d31bddf3ce4c40)

* Rename rctx to c

---------

Co-authored-by: Harrison Healey <harrisonmhealey@gmail.com>
2026-03-06 15:39:06 +00:00
Mattermost Build
a8d44e5918 Use standard session handler for updateUserAuth endpoint (#35488) (#35505)
Automatic Merge
2026-03-06 10:25:23 +01:00
Bill Gardner
fae6cc9001 update plugin-calls to v1.11.1 (#35447)
Automatic Merge
2026-03-03 10:55:20 +01:00
unified-ci-app[bot]
c29cf05d40 Update latest patch version to 10.11.13 (#35390)
Automatic Merge
2026-02-20 15:39:27 +02:00
Pablo Vélez
e1a78d1e91 Mm 66813 sso callback metadata (#34955) (#35383)
Automatic Merge
2026-02-20 09:09:32 +02:00
Ibrahim Serdar Acikgoz
21ced4716b [MM-67382] Improve mmctl output by filtering escape sequences #35191 (#35334)
Automatic Merge
2026-02-17 19:09:38 +02:00
Ibrahim Serdar Acikgoz
e68120775b Cherry pick of a06d506 (#35172) into release-10.11 (#35332)
Automatic Merge
2026-02-17 19:09:27 +02:00
catalintomai
25d7832030 MM-67099 - Membership Sync fix (#35230) (#35329)
Automatic Merge
2026-02-17 18:09:27 +02:00
Julien Tant
dbd201f208 Update Makefile (#35290)
Automatic Merge
2026-02-16 13:09:27 +02:00
Mattermost Build
39ba0a3cd7 MM-66886 Add rate limiting to login endpoint (#34943) (#35314)
Automatic Merge
2026-02-16 12:39:39 +02:00
Mattermost Build
eb8c99fe9c Add fileSize limit to extractors (#35200) (#35280)
Automatic Merge
2026-02-13 14:09:32 +02:00
Andre Vasconcelos
053dcf62b6 MM-67372: Improve link preview metadata handling and filtering (#35178) (#35222)
Automatic Merge
2026-02-13 13:09:26 +02:00
Doug Lauder
a8db85c026 Cherry-pick MM-66789 (Include log viewer (system console) in log root path validation) (#35253)
Automatic Merge
2026-02-13 12:09:37 +02:00
Harrison Healey
f000a183fc MM-67335 Fix export files having mismatched permissions (#35182) (10.11) (#35248)
Automatic Merge
2026-02-13 11:39:35 +02:00
Just Nev
23eb77c102 chore: Update zoom version to 1.12.0 (#35167) (#35190)
Automatic Merge
2026-02-13 11:09:36 +02:00
unified-ci-app[bot]
aa3240dd80 Update latest patch version to 10.11.12 (#35272)
Automatic Merge
2026-02-13 09:39:26 +02:00
Alejandro García Montoro
fddd4a70bc Avoid simple config when doing FTS in Postgres (#35063) (#35179)
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 13:00:44 +01:00
Doug Lauder
463f7a0511 Cherry-pick MM-66789: Restrict log downloads to a root path for support packets (#35164)
Automatic Merge
2026-02-02 21:23:28 +02:00
Ibrahim Serdar Acikgoz
d2594e5046 Patch MM-67126 issue (#35142)
Automatic Merge
2026-02-02 12:53:32 +02:00
Mattermost Build
83006ff8ca MM-67279: Fix private channel enumeration via /mute slash command (#35099) (#35149)
Automatic Merge
2026-01-30 18:23:33 +02:00
Christopher Poile
452bad21e9 manual cherry-pick: [MM-67202] Validate auth method in account switch (#34981) (#35143)
* fix account authorization type switch

* improve test clarity

* refactor tests for clarity
2026-01-30 16:36:57 +02:00
Mattermost Build
66fdb3f453 MM-67274: Fix panic in getBrowserVersion with empty User-Agent version (#35098) (#35133)
Automatic Merge
2026-01-30 12:53:37 +02:00
Mattermost Build
e813c0e19e MM-67268: Fix SSRF bypass via IPv4-mapped IPv6 literals (#35097) (#35130)
Automatic Merge
2026-01-30 11:53:31 +02:00
Christopher Poile
f626d98799 manual cherrypick: [MM-67130] Fix permalink preview permissions (#34909) (#35114)
* manual cherrypick: [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

* linter
2026-01-29 20:41:37 +00:00
Christopher Poile
f894103741 manual cherrypick: [MM-67074] Integration Action memory use fix (#34896) (#35089)
Automatic Merge
2026-01-28 18:53:28 +02:00
Carlos Garcia
20d28987a7 Manual cherry-pick MM-66167 fix (#35061) (#35087)
Automatic Merge
2026-01-28 13:53:28 +02:00
Christopher Poile
f68ad45595 [MM-67052] manual cherrypick: update mscfb and msoleps deps (#34910) (#35076)
Automatic Merge
2026-01-28 10:53:28 +02:00
Rajat Dabade
707f7ba42b Cherry-pick PR for guest-user-file-upload-permission for release-10.11 (#35073)
Automatic Merge
2026-01-27 14:53:28 +02:00
Alejandro García Montoro
0655a63354 Check password length (#35062)
Automatic Merge
2026-01-27 08:53:29 +02:00
Christopher Poile
51f2e2fdd5 Manual cherrypick MM-67055: Fix permalink embeds in ws msg (#34893) (#35059)
Automatic Merge
2026-01-26 19:23:30 +02:00
Daniel Espino García
21a86506f9 Manual Cherrypick: Add audits for accessing posts without membership (#31266) (#35022)
Automatic Merge
2026-01-26 12:23:28 +02:00
Mattermost Build
12dce033d6 MM-64725 - channel settings modal do not update url automatically (#33500) (#35052)
Automatic Merge
2026-01-26 11:53:39 +02:00
Rajat Dabade
4b8b1e5ca0 Cherry picker search-api-filter-guest-permission to release-10.11 (#35018)
Automatic Merge
2026-01-22 12:18:51 +02:00
Mattermost Build
3b1b8d9114 Automated cherry pick of #34693 (#34972)
Automatic Merge
2026-01-22 07:18:51 +02:00
Pablo Vélez
43e797010b MM-66092 - enhance user permissions data structure validations (#34654) (#35006)
Automatic Merge
2026-01-21 12:48:52 +02:00
Christopher Poile
ebe1bd4e31 MM-67077: Remove PSD file previews (#34898) (#35000)
Automatic Merge
2026-01-21 12:18:54 +02:00
Rajat Dabade
a75d26b4ac Upgraded board prepacked version to v9.2.2 (#34999)
Automatic Merge
2026-01-21 11:48:53 +02:00
Mattermost Build
17635d33d8 MM-67049: Fix unauthorized access to public channels in private teams (#34886) (#34994)
Automatic Merge
2026-01-20 13:54:38 +02:00
Mattermost Build
06c6ee2566 [MM-66789] Restrict ImportSettings.Directory changes via API and add validation (#34653) (#34987)
Automatic Merge
2026-01-20 12:54:28 +02:00
unified-ci-app[bot]
30aec66862 Update latest patch version to 10.11.11 (#34938)
Automatic Merge
2026-01-15 15:54:24 +02:00
Mattermost Build
ba27ba1f8c Automated cherry pick of #34715 (#34849)
Automatic Merge
2026-01-12 19:47:30 +02:00
M-ZubairAhmed
d6d3d5447e Cherry pick of #34679 (#34880)
Automatic Merge
2026-01-08 16:17:31 +02:00
Mattermost Build
fc8b22242d Automated cherry pick of #34441 (#34848)
Automatic Merge
2026-01-07 14:17:32 +02:00
Jesse Hallam
a07b1d7a8c MM-66424: Improve team filtering in common teams API (#34454) (#34854)
Cherry-pick 6404ab29acc04901c5cb1cf5ad97fc3c0693e2cd into release-10.11
2026-01-06 12:50:30 -04:00
Jesse Hallam
989f3a36dc MM-66757: Improve WebSocket user update events (#34600) (#34856)
* improve TestUserUpdateEvents

* improve CheckUserSanitization

* check user sanitization in TestUserUpdateEvents

* minimally sanitize user sent to event creator
2026-01-06 11:22:05 -05:00
Andre Vasconcelos
f423bea281 Manual cherry-pick on #34803 (#34817)
* Bumping prepackaged Jira Plugin version to v4.5.0 (#34803)

# Conflicts:
#	server/Makefile

* Fixing linter error that fails e2e smoke tests
2025-12-22 17:23:01 +02:00
Just Nev
ccc7fde051 Update Zoom prepackaged version to 1.11.0 (#34734) (#34765)
Co-authored-by: Nevyana Angelova <nevyangelova@Nevy-Macbook-16-2025.local>
2025-12-17 18:22:57 +02:00
Jesse Hallam
c9d60357db MM-65575: Fix server panic when bot posts trigger persistent notifications (#34174) (#34778)
* reproduce panic with test

* allow bots in the profile map

* explicitly prevent sending notifications to bots

* persistent notifications: handle senders not in the channel
2025-12-17 15:06:57 +00:00
unified-ci-app[bot]
e150243a7f Update latest patch version to 10.11.10 (#34771)
Co-authored-by: unified-ci-app[bot] <121569378+unified-ci-app[bot]@users.noreply.github.com>
2025-12-17 12:29:41 +02:00
Miguel de la Cruz
613bb616cd Avoid triggering unnecessary rerenders on the shared channels tooltip for users (#34336) (#34702)
Co-authored-by: Miguel de la Cruz <miguel@ctrlz.es>
Co-authored-by: Mattermost Build <build@mattermost.com>
2025-12-11 11:13:44 +02:00
Mattermost Build
f9fb13c7e6 [MM-65186] Keyboard focus is wrong when using Shift-Up to reply in thread (#34627) (#34697)
(cherry picked from commit 4fb41f3ba274f32b8e23f52e46b82e3d93f63af6)

Co-authored-by: M-ZubairAhmed <m-zubairahmed@protonmail.com>
2025-12-10 05:17:54 +00:00
Harshil Sharma
b3d6c0c564 perf: apply perfpsrint linter (#33967) (#34632)
* perf: apply perfpsrint linter (#33967)

* perf: apply perfpsrint linter

* further simplifications

* improved TestParseHashtags coverage

* more simplifications

* simplify renderBlockHTML further

---------

Co-authored-by: Jesse Hallam <jesse@mattermost.com>

* Fixed a bad merge

---------

Co-authored-by: Catena cyber <35799796+catenacyber@users.noreply.github.com>
Co-authored-by: Jesse Hallam <jesse@mattermost.com>
2025-12-02 18:21:30 +02:00
unified-ci-app[bot]
183e6c4a07 Update latest patch version to 10.11.9 (#34575)
Automatic Merge
2025-11-21 20:17:20 +02:00
Just Nev
7c36acb68c Update Jira prepackaged (#34551) (#34570)
Co-authored-by: Maria A Nunez <maria.nunez@mattermost.com>
2025-11-21 13:23:57 +00:00
unified-ci-app[bot]
9cee6d0cb4 Update latest patch version to 10.11.8 (#34509)
Automatic Merge
2025-11-17 11:31:48 +02:00
Christopher Speller
9d74b930db Update Agents plugin to v1.4.0 (#34129) (#34452)
Automatic Merge
2025-11-12 09:31:48 +02:00
Bill Gardner
1a5b8f9f88 Update Calls to v1.11.0 (#34399) (#34426)
Automatic Merge
2025-11-07 09:01:51 +02:00
Maria A Nunez
3b05384dd0 Update github prepackaged version (#34409) 2025-11-06 05:35:14 -05:00
unified-ci-app[bot]
d52b7210a7 Update latest patch version to 10.11.7 (#34392)
Automatic Merge
2025-11-05 09:01:47 +02:00
Mattermost Build
e7e23b94e0 Bump prepackage MsTeams plugin version to 2.3.0 (#34347) (#34359)
Automatic Merge
2025-10-31 11:59:24 +02:00
Ibrahim Serdar Acikgoz
75132b7a91 Manual cherry-pick of (37969b1) #34155 into release 10.11. (#34334)
Automatic Merge
2025-10-30 17:29:11 +02:00
Mattermost Build
b922174f48 Fix MM-65152 (#34199) (#34331)
Automatic Merge
2025-10-29 18:29:20 +02:00
unified-ci-app[bot]
9a7a491451 Update latest patch version to 10.11.6 (#34310)
Automatic Merge
2025-10-28 17:29:10 +02:00
Mattermost Build
46b5c436bb MM-66372: Improve OAuth state token validation (#34296) (#34300) 2025-10-28 00:46:33 +00:00
Mattermost Build
f361e7d75a Automated cherry pick of #34247 (#34257)
Automatic Merge
2025-10-27 12:59:15 +02:00
Rajat Dabade
56163e9e0e Upgraded board prepackage version to v9.1.7 (#34191)
Automatic Merge
2025-10-17 18:43:39 +03:00
Ibrahim Serdar Acikgoz
9f54e5cdc3 [MM-65684] Sanitize teams for /api/v4/channels/{channel_id}/common_teams endpoint (#34110) (#34182) 2025-10-17 16:55:42 +03:00
Miguel de la Cruz
e9f6e127a4 Update dependencies (#34175)
Co-authored-by: Miguel de la Cruz <miguel@ctrlz.es>
2025-10-17 10:03:58 +02:00
Mattermost Build
dad6bd7a15 Use validated redirectTo in error page (#34073) (#34169)
Automatic Merge
2025-10-16 16:13:38 +03:00
unified-ci-app[bot]
47c2b1ab8c Update latest patch version to 10.11.5 (#34150)
Automatic Merge
2025-10-15 11:13:43 +03:00
Mattermost Build
83a5be3f9e MM-65743: Sanitize in email verification endpoint (#33914) (#34121)
(cherry picked from commit 057efca74ee29862bca6ef6336bfbf3456f65bf6)

Co-authored-by: Jesse Hallam <jesse.hallam@gmail.com>
2025-10-13 06:38:25 +00:00
Mattermost Build
967e44805b Fix RHS reply input focus issues (#33965) (#34099)
Automatic Merge
2025-10-09 12:13:38 +03:00
JG Heithcock
375ce229f4 MM 65084 server-side (#33861) (#34006) (#34044)
* MM 65084 server-side (#33861) (#34006)

Automatic Merge

* Add ConsumeOnce method to store layers

---------

Co-authored-by: Mattermost Build <build@mattermost.com>
2025-10-06 15:20:08 -07:00
Mattermost Build
4b56488fcb [MM-65830] Fix mmctl system status exit code for health check failures (#33970) (#34069)
Automatic Merge
2025-10-06 14:43:38 +03:00
Jesse Hallam
9dd2c6f54f [MM-65837], [MM-65824] - Update Dependencies (#33972) (#34052)
* Update github.com/mholt/archives

* Update github.com/spf13/viper

* make batch migration worker tests less flaky

---------

Co-authored-by: Eva Sarafianou <eva.sarafianou@gmail.com>
2025-10-03 11:12:25 -03:00
Amy Blais
891a006890 Update msteams prepackaged plugin (#34049)
Automatic Merge
2025-10-03 16:36:25 +03:00
Mattermost Build
8be4905a96 ugprade to go 1.24.6 (#34004) (#34023)
(cherry picked from commit 3241b43f7ca6e0588d9e40ede9058340327fb7a4)

Co-authored-by: Jesse Hallam <jesse.hallam@gmail.com>
2025-10-01 11:30:41 -03:00
Mattermost Build
1cb37c06b2 workflows/server-ci-report.yml: security fixes by validating inputs (#33892) (#34018)
Automatic Merge
2025-10-01 12:36:16 +03:00
Mattermost Build
fcd316844e Improve self checks when adding a new channel member (#33404) (#33925)
Automatic Merge
2025-09-18 10:19:15 +03:00
Mattermost Build
98acefe911 Sanatize LastViewedAt and LastUpdateAt for other users on channel member object (#33835) (#33905)
Automatic Merge
2025-09-16 13:19:10 +03:00
unified-ci-app[bot]
d41872f1f3 Update latest patch version to 10.11.4 (#33903)
Automatic Merge
2025-09-16 11:49:11 +03:00
Mattermost Build
f1f6719f38 [MM-64883] Don't show unreads from muted channels in the favicon/desktop app (#33592) (#33863)
(cherry picked from commit ccb098972994a8d85ba8cedca95436d19d9477e0)

Co-authored-by: Devin Binnie <52460000+devinbinnie@users.noreply.github.com>
2025-09-09 15:51:28 +00:00
Mattermost Build
27fadafead Constant time comparison (#33588) (#33822)
Automatic Merge
2025-09-01 16:34:06 +03:00
Mattermost Build
ef896a4ea6 Mm 64925 - prevent slack import email auto validation for non admin users (#33609) (#33779)
Automatic Merge
2025-08-22 12:34:05 +03:00
Mattermost Build
e8c7e7d025 [MM-64453] Guest shouldn't discover public channels that they are not member of (#31327) (#33778)
Automatic Merge
2025-08-22 12:04:05 +03:00
Mattermost Build
24c4a3677b [MM-64445] api4/channels_test: Add tests cases for guest user private channels (#31319) (#33776)
Automatic Merge
2025-08-22 11:34:05 +03:00
unified-ci-app[bot]
6dd8c55207 Update latest patch version to 10.11.3 (#33775)
Automatic Merge
2025-08-22 10:34:04 +03:00
Mattermost Build
2a35a97a18 Relax post action requirements to allow undefined name (#33612) (#33767)
Automatic Merge
2025-08-21 13:04:04 +03:00
Mattermost Build
4c718c4b9a [MM-63579] Missing status indicator in compact display mode (#33651) (#33716)
(cherry picked from commit 573c78481ead916e5925836fa1e992456cb671c5)

Co-authored-by: M-ZubairAhmed <m-zubairahmed@protonmail.com>
2025-08-14 09:30:01 +00:00
Mattermost Build
628e088715 remove leftover mysql apt-key (#33708) (#33711)
(cherry picked from commit 527ea8421bc5f366209f21c609f200c3f38768c1)

Co-authored-by: sabril <5334504+saturninoabril@users.noreply.github.com>
2025-08-14 10:50:08 +03:00
Harrison Healey
004a6429e2 Add script to update web app package versions going forward (#33669) 2025-08-13 10:37:58 -04:00
Mattermost Build
2d5cdc6e21 [MM-64896][MM-64898] Pass inviteid/tokenid to relay state/props for external auth when auto-joining a team (#33545) (#33666)
Automatic Merge
2025-08-13 13:04:00 +03:00
unified-ci-app[bot]
ed9e2dbbce Update latest patch version to 10.11.2 (#33639)
Automatic Merge
2025-08-08 10:04:04 +03:00
Mattermost Build
e14175eb65 [MM-65015] Restore Mobile redirection on oauth login (#33626) (#33633) 2025-08-07 17:47:01 +00:00
Mattermost Build
540f4c1145 s/bookwork/bullseye to preserve glibc < 2.34 (#33546) (#33629)
With glibc 2.34 and the [removal of libpthread](https://developers.redhat.com/articles/2021/12/17/why-glibc-234-removed-libpthread), binaries built using [Debian bookworm](https://www.debian.org/releases/bookworm/) aren't compatible with older but still supported operating systems like RHEL8. In those environments, Mattermost fails to start with errors like:
```
mattermost/bin/mattermost: /lib64/libc.so.6: version `GLIBC_2.32' not found (required by mattermost/bin/mattermost)
mattermost/bin/mattermost: /lib64/libc.so.6: version `GLIBC_2.34' not found (required by mattermost/bin/mattermost)
```

One option might be to generate a static build and avoid the glibc dependency, but this kind of change is out of scope for now. Let's just revert back to using [Debian bullseye](https://www.debian.org/releases/bullseye/), which remains supported until at least August 2026.

(cherry picked from commit c2120b7224ce8d2f8dd34f17fbeba06296b733db)

Co-authored-by: Jesse Hallam <jesse.hallam@gmail.com>
2025-08-06 20:49:03 +00:00
unified-ci-app[bot]
59b427296b Update latest patch version to 10.11.1 (#33620)
Automatic Merge
2025-08-05 10:04:04 +03:00
Mattermost Build
5b955468ea MM-64957 - fix autoscroll not working (#33595) (#33603)
Automatic Merge
2025-07-31 19:34:00 +03:00
Mattermost Build
8f6b6f1d0d [MM-64911] Ensure redirect URL is validated before redirecting (#33559) (#33596)
Automatic Merge
2025-07-31 09:34:00 +03:00
Mattermost Build
04d2ca2e3e [MM-64893] Account for extra whitespace when replacing date on search hint (#33563) (#33590)
* [MM-64893] Account for extra whitespace when replacing date on search hint

* Fix ordering of caret position and selection range

* Revert "Fix ordering of caret position and selection range"

This reverts commit 9d6fc51ef35c242817a52b6206610abc5fc55503.

* Remove delayInputUpdate

(cherry picked from commit c775615868393566d6cf6caa0820869890da97a2)

Co-authored-by: Devin Binnie <52460000+devinbinnie@users.noreply.github.com>
2025-07-30 13:28:11 +00:00
Mattermost Build
6cbcf4e290 MM-64250 - solve js eror while downloading images (#33552) (#33589)
Automatic Merge
2025-07-30 15:34:00 +03:00
Mattermost Build
7eda0e799c Prepackage playbooks v2.3.0 (#33574) (#33579)
Automatic Merge
2025-07-29 11:34:00 +03:00
Mattermost Build
95eaf401af MM-64926: Membership sync sends sensitive data to remote (#33560) (#33577)
Automatic Merge
2025-07-29 10:33:59 +03:00
Harrison Healey
ce75debaca Make all internal dependencies use exact versions and ensure they match (#33564) 2025-07-28 12:44:06 +05:30
Mattermost Build
38208b8f06 MM-64755: Fix redirect in oauth login (#33388) (#33569)
Automatic Merge
2025-07-28 09:33:59 +03:00
Mattermost Build
d5190466de Fix PostgreSQL SSL connection issue with sslmode=require in distroless images (#33523) (#33538)
Automatic Merge
2025-07-23 13:28:49 +03:00
Mattermost Build
48e211b60c MM-64880 Revert change to border colour in list modals and remove a few things from applyTheme (#33508) (#33532)
Automatic Merge
2025-07-23 09:28:42 +03:00
Mattermost Build
4cb8d89403 [MM-64516] Do not allow user editable attributes to be used in ABAC table editor (#32522) (#33524)
Automatic Merge
2025-07-23 08:28:42 +03:00
Mattermost Build
4952acea88 update calls (#33477) (#33491)
Automatic Merge

(cherry picked from commit 59f74324547f8d821568136519dd888cce94ca9a)

Co-authored-by: Christopher Poile <cpoile@gmail.com>
2025-07-21 09:22:09 +03:00
Mattermost Build
e7fe67e03c Upgrading board prepackage version to v9.1.5 (#33447) (#33460)
Automatic Merge
2025-07-18 10:28:41 +03:00
Mattermost Build
f21005e359 Add URL validation to LinkMetadata cache and store (#31814) (#33453)
Automatic Merge
2025-07-17 20:58:42 +03:00
Mattermost Build
2fceeceba6 MM-64675: Enable modification of plugin settings in local mode (#33376) (#33452)
Automatic Merge
2025-07-17 20:28:42 +03:00
Mattermost Build
07a34f02b6 MM-64531: [Shared Channels] Users on different remote servers should not communicate unless the remotes have established secure connection. (#30985) (#33434)
Automatic Merge
2025-07-15 11:58:41 +03:00
Agniva De Sarker
3a6aeee57e MM-63652: Transition gossip encryption functionality to GA (#33349) (#33429)
Create a new config setting, and migrate the old values to new.

https://mattermost.atlassian.net/browse/MM-63652

Skip-Enterprise-PR: true

```release-note
NONE
```

* fix i18n

also fix unit tests

```release-note
NONE
```

* For fresh installations, default to true

```release-note
NONE
```

* gofmt files

```release-note
NONE
```

* Fixing some more strings

```release-note
NONE
```

* Update e2e tests

```release-note
NONE
```
2025-07-15 11:37:01 +05:30
Mattermost Build
7f4fbd803a MM-62745: [Shared Channels] Fix duplicate mentioning - local user with the same username as someone on the remote server - Part2 (#32101) (#33414)
Automatic Merge
2025-07-14 19:28:42 +03:00
unified-ci-app[bot]
b6e80b9f59 Update npm packages versions for release-10.11 2025-07-14 05:16:07 +00:00
Pablo Vélez
a17c387ff2 MM-64713 - channel invite modal in abac channel should keep filtered list of users (#32803) 2025-07-10 20:03:54 +02:00
Harshil Sharma
d1e5fdea2c Content flagging systems console settings (#31411)
* Added enable/disable setting and feature flag

* added rest of notifgication settings

* Added backend for content flagging setting and populated notification values from server side defaults

* WIP user selector

* Added common reviewers UI

* Added additonal reviewers section

* WIP

* WIP

* Team table base

* Added search in teams

* Added search in teams

* Added additional settings section

* WIP

* Inbtegrated reviewers settings

* WIP

* WIP

* Added server side validation

* cleanup

* cleanup

* [skip ci]

* Some refactoring

* type fixes

* lint fix

* test: add content flagging settings test file

* test: add comprehensive unit tests for content flagging settings

* enhanced tests

* test: add test file for content flagging additional settings

* test: add comprehensive unit tests for ContentFlaggingAdditionalSettingsSection

* Added additoonal settings test

* test: add empty test file for team reviewers section

* test: add comprehensive unit tests for TeamReviewersSection component

* test: update tests to handle async data fetching in team reviewers section

* test: add empty test file for content reviewers component

* feat: add comprehensive unit tests for ContentFlaggingContentReviewers component

* Added ContentFlaggingContentReviewersContentFlaggingContentReviewers test

* test: add notification settings test file for content flagging

* test: add comprehensive unit tests for content flagging notification settings

* Added ContentFlaggingNotificationSettingsSection tests

* test: add user profile pill test file

* test: add comprehensive unit tests for UserProfilePill component

* refactor: Replace enzyme shallow with renderWithContext in user_profile_pill tests

* Added UserProfilePill tests

* test: add empty test file for content reviewers team option

* test: add comprehensive unit tests for TeamOptionComponent

* Added TeamOptionComponent tests

* test: add empty test file for reason_option component

* test: add comprehensive unit tests for ReasonOption component

* Added ReasonOption tests

* cleanup

* Fixed i18n error

* fixed e2e test lijnt issues

* Updated test cases

* Added snaoshot

* Updated snaoshot

* lint fix

* lint fix

* review fixes

* updated snapshot

* CI

* Review fixes

* Removed an test, updated comment

* CI

* Test update
2025-07-10 17:47:16 +05:30
Ibrahim Serdar Acikgoz
254f641182 [MM-64371] Prevent WS being closed by browser due to navigation (#31367)
* prevent ws being closed by browser due to navigation

* add href back

---------

Co-authored-by: Mattermost Build <build@mattermost.com>
2025-07-10 11:30:54 +02:00
Cyrus
e2b6e807c4 [MM-21466] delete users cmd return err (#31191)
* refactored error managment for deleteUsersCmdF

* updated tests related to deleteUsersCmdF

* updated user_e2e_test to reflect changes made to the deleteUsersCmdF function

* Empty-Commit to retrigger workflow

* applied gofmt formating reqs to user_test.go

* added suggested changes to the deleteUsersCmdF regarding error gathering

* added requested changes regarding error aggragation on deleteUsersCmdF

* style(mmctl): removing trailing whitespace

* feat(mmctl): returning errors in deleteUserCmdF on err

* fix(mmctl): returns when err parsing args

* test(mmctl): updated tests to expect err instead of reading printer

* style: updating returned errs

* tests: updated test to reflect error change

* tests(mmctl): updated e2e DeleteUserCmd test

* Update server/cmd/mmctl/commands/user.go

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

* refactor: changing error to return username instead of email

* refactor: changing email to username for errors

---------

Co-authored-by: Arnaud Wanet <andrewwanet9@gmail.com>
Co-authored-by: Antonis Stamatiou <stamatiou.antonis@gmail.com>
Co-authored-by: Ben Schumacher <ben.schumacher@mattermost.com>
2025-07-09 17:12:04 +02:00
Matthew Birtch
b42f4fbffd MM-64483 YouTube Preview UI Update (#31288)
* fix youtube thumbnails

* fix lint issues, update snapshots

* Update _videos.scss

* Update _videos.scss

* revert change to 'YouTubeVideo' to 'YoutubeVideo'

* switch back to Youtube instead of YouTube

* accessibility fixes -add focus state

* fix lint issues

* Update youtube_video.test.tsx.snap

* remove logic for delaying different aspect ratios. always use 16:9

* Update _videos.scss

* fix rounded corners

* use css variables for radius

* restore attributes from original, remove bottom margin from player to prevent vertical shift

* fix issue with margin and nested 'video-div' elements

* update class to 'video-playing'

* fix linter issues

* address copilot review feedback and remove unused css

* Update youtube_video.test.tsx

* fixed failing test

* lint issue fix

* Update youtube_video.test.tsx

* review feedback changes

* Update _videos.scss

* update test and snapshot

* fix lint issues

* add scaling button on hover state back in

* feat: Make YouTube video component strings translatable

- Add useIntl import and formatMessage usage
- Create YouTubePrefix component for internationalized prefix
- Update YouTubeThumbnail component to use translatable strings
- Add translation IDs:
  - youtube_video.play.aria_label
  - youtube_video.thumbnail.alt_text  
  - youtube_video.play_button.aria_label
  - youtube_video.type

Addresses reviewer feedback to make hardcoded strings translatable
using React Intl's useIntl hook.

Co-authored-by: Matthew Birtch <matthewbirtch@users.noreply.github.com>

* fix lint issues

* Update en.json

* Update youtube_video.test.tsx.snap

* remove youtube prefix

* fix lint issues

* Update youtube_video.test.tsx.snap

* fix lint issue

---------

Co-authored-by: claude[bot] <209825114+claude[bot]@users.noreply.github.com>
Co-authored-by: Matthew Birtch <matthewbirtch@users.noreply.github.com>
2025-07-09 10:33:47 -04:00
Claudio Costa
47a7e62b44 Fix flaky test TestMmctlE2ESuite/TestPreferenceUpdateCmd (#33375) 2025-07-09 08:01:40 -06:00
Agniva De Sarker
c4dde3d0ab MM-64632: Fix a panic in bulk import (#33360)
We were incorrect de-referencing the channels slice
without checking for nil pointer first.

https://mattermost.atlassian.net/browse/MM-64632
```release-note
NONE
```
2025-07-09 09:37:36 +05:30
Harrison Healey
30ba6f573d MM-64681 Fix in: filter in mobile search box (#32120) 2025-07-08 14:45:28 -04:00
Harrison Healey
ad38971dd6 MM-64658 Fix handling of upload sessions (#32141)
* MM-64658 Fix handling of upload sessions

* Fix style issue
2025-07-08 16:46:00 +00:00
Harrison Healey
4b77485e8f MM-64718 Improve validation of thread follower imports (#33287)
* MM-64718 Improve validation of thread follower imports

* Add additional test cases and restucture tests
2025-07-08 11:57:48 -04:00
Harrison Healey
4bb35c5043 MM-64417 Change permissions table to use a grid for animation (#32573)
* MM-64417 Change permissions table to use a grid for animation

* Don't change padding on permissions table when animating

* Update snapshots

* Combine CSS for AdminPanel and AdminPanelTogglable

* Removed leftover reference to old CSS file

---------

Co-authored-by: Mattermost Build <build@mattermost.com>
2025-07-08 11:55:24 -04:00
sabril
780c893b4f upgrade playwright dependencies (#33348) 2025-07-08 23:00:48 +08:00
sabril
749f7d4d21 fix playwright test (#33353) 2025-07-08 21:58:59 +08:00
catalintomai
a8fa77f107 MM-64779: Upload type validation. (#33351) 2025-07-08 00:13:02 +02:00
Tom De Moor
f7cb74117b Translated using Weblate (Dutch)
Currently translated at 99.7% (2714 of 2720 strings)

Translation: Mattermost/server
Translate-URL: https://translate.mattermost.com/projects/mattermost/server/nl/
2025-07-07 18:44:34 +00:00
Tom De Moor
b4defc7aba Translated using Weblate (Dutch)
Currently translated at 99.9% (6448 of 6450 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/nl/
2025-07-07 18:44:34 +00:00
Tom De Moor
7b21a05a55 Translated using Weblate (Dutch)
Currently translated at 99.6% (6426 of 6450 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/nl/
2025-07-07 18:44:34 +00:00
MArtin Johnson
7e838d478f Translated using Weblate (Swedish)
Currently translated at 97.7% (6305 of 6450 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/sv/
2025-07-07 18:44:34 +00:00
MArtin Johnson
76c5c1a686 Translated using Weblate (Swedish)
Currently translated at 99.9% (2716 of 2718 strings)

Translation: Mattermost/server
Translate-URL: https://translate.mattermost.com/projects/mattermost/server/sv/
2025-07-07 18:44:34 +00:00
Ainārs Keišs
d635c547bd Translated using Weblate (Latvian)
Currently translated at 0.3% (24 of 6450 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/lv/
2025-07-07 18:44:34 +00:00
Tom De Moor
95f6b631f4 Translated using Weblate (Dutch)
Currently translated at 99.0% (6389 of 6450 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/nl/
2025-07-07 18:44:34 +00:00
Tom De Moor
e6f5f7697a Translated using Weblate (Dutch)
Currently translated at 99.9% (2716 of 2718 strings)

Translation: Mattermost/server
Translate-URL: https://translate.mattermost.com/projects/mattermost/server/nl/
2025-07-07 18:44:34 +00:00
Frank Paul Silye
4b47779608 Translated using Weblate (Norwegian Bokmål)
Currently translated at 81.4% (5255 of 6450 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/nb_NO/
2025-07-07 18:44:34 +00:00
jprusch
49330c48e7 Translated using Weblate (German)
Currently translated at 100.0% (6450 of 6450 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/de/
2025-07-07 18:44:34 +00:00
jprusch
082c72e36c Translated using Weblate (German)
Currently translated at 100.0% (2718 of 2718 strings)

Translation: Mattermost/server
Translate-URL: https://translate.mattermost.com/projects/mattermost/server/de/
2025-07-07 18:44:34 +00:00
Manuela Silva
9dd29b134f Translated using Weblate (Portuguese)
Currently translated at 5.1% (140 of 2718 strings)

Translation: Mattermost/server
Translate-URL: https://translate.mattermost.com/projects/mattermost/server/pt/
2025-07-07 18:44:34 +00:00
Manuela Silva
6db8b5e6a2 Translated using Weblate (Portuguese)
Currently translated at 2.5% (69 of 2718 strings)

Translation: Mattermost/server
Translate-URL: https://translate.mattermost.com/projects/mattermost/server/pt/
2025-07-07 18:44:34 +00:00
Manuela Silva
1171bde078 Translated using Weblate (Portuguese)
Currently translated at 1.6% (46 of 2718 strings)

Translation: Mattermost/server
Translate-URL: https://translate.mattermost.com/projects/mattermost/server/pt/
2025-07-07 18:44:34 +00:00
Serhii Khomiuk
dad0795c67 Translated using Weblate (Ukrainian)
Currently translated at 94.7% (6114 of 6450 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/uk/
2025-07-07 18:44:34 +00:00
Serhii Khomiuk
b9cf283ac7 Translated using Weblate (Ukrainian)
Currently translated at 97.6% (2655 of 2718 strings)

Translation: Mattermost/server
Translate-URL: https://translate.mattermost.com/projects/mattermost/server/uk/
2025-07-07 18:44:34 +00:00
Martin Mičuda
3eae025ccd Translated using Weblate (Czech)
Currently translated at 97.8% (2659 of 2718 strings)

Translation: Mattermost/server
Translate-URL: https://translate.mattermost.com/projects/mattermost/server/cs/
2025-07-07 18:44:34 +00:00
Harshil Sharma
bfbfff276d Added patch channel API doc for channel banner (#32100)
* Added patch channel API doc for channel banner

* Fixed typo
2025-07-07 10:41:29 +05:30
Ibrahim Serdar Acikgoz
5e76a1091c Fix bad link to ABAC Policy Edit page from Channel Management page (#33044) 2025-07-04 16:04:35 +02:00
Claudio Costa
4a7aeae861 [MM-64663] Fix potential panic in mmctl ldap job show command (#32575)
* Fix potential panic in `mmctl ldap job show` command

* fix examples and docs

---------

Co-authored-by: Christopher Poile <cpoile@gmail.com>
2025-07-04 07:48:17 -06:00
Claudio Costa
10b6784968 Skip code coverage generation on cherry-pick PRs (#33068)
* Skip code coverage generation on cherry-picks

* Skip upload step for webapp coverage for cherry-picks
2025-07-04 07:48:06 -06:00
unified-ci-app[bot]
cbf685b2f4 Update latest minor version to 10.11.0 (#33309)
Automatic Merge
2025-07-04 14:52:01 +03:00
Christopher Speller
c11df2ff7a Update Agents plugin to v1.2.4 (#33273) 2025-07-04 08:28:48 +03:00
Harrison Healey
5b6320b7dc MM-62744 Change how custom URLs are autolinked to fix remote user at-mentions (#32080)
* Stop explicitly passing autocompleteUrlSchemes into text formatting code

This is the first part of changing how autocompleteUrlSchemes works so
that it can be moved to be part of the parser like in mobile instead of
happening in the renderer.

I'm not a fan of using the global store directly in utils/markdown, but
this seems like the only way to have this apply to all the Markdown
that's rendered in various helpers throughout the app. Ideally, we'd
have some getMarkdownParser selector and a hook which provides the
config, but that's a future improvement to make"

* MM-62744 Move URL filtering to the Markdown parser instead of the renderer

MM-62744 is caused by two things:

1. URL autolinking takes place in the Markdown parser which occurs
   before at-mention parsing which (despite the "parsing" part) happens
   in the Markdown renderer in the web app.
2. The autolinking in marked is very aggressive and identifies anything
   that looks like some:text as a link.

Those lead to remote mentions like `@user:server` being incorrectly
parsed by Markdown as a link to `user:server`. It isn't renderered as a
link because the URL filtering logic in the Markdown parser blocks that,
but at that point, the Markdown renderer won't check if it's an
at-mention.

By moving the URL filtering to occur earlier, like it does in the mobile
app, the Markdown code won't autolink `@user:server` (unless the server
has `user` configured as a custom URL scheme for some reason), so it's
free to be turned into an at-mention by the renderer code.

* MM-62744 Ensure various regexes and features support remote mentions

* Update marked back to master
2025-07-03 11:05:12 -04:00
Sven Hüster
0d4c2b72f1 Improve clarity of channel notification limit messages (#32160)
* Improve clarity of channel notification limit messages

- Update user-facing messages to explain performance reasoning and provide guidance
- Enhance admin setting descriptions to be more informative about user experience  
- Change admin setting title to better reflect purpose

Fixes #32159

Co-authored-by: Sven Hüster <svelle@users.noreply.github.com>

* Update webapp/channels/src/i18n/en.json

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

* Update server/i18n/en.json

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

* Update server/i18n/en.json

* Update server/i18n/en.json

---------

Co-authored-by: claude[bot] <209825114+claude[bot]@users.noreply.github.com>
Co-authored-by: Sven Hüster <svelle@users.noreply.github.com>
Co-authored-by: Carrie Warner (Mattermost) <74422101+cwarnermm@users.noreply.github.com>
Co-authored-by: Matthew Birtch <mattbirtch@gmail.com>
2025-07-03 09:33:17 -04:00
Christopher Poile
55eb63a367 [MM-64735] Add defensive fallback for userHasReadPermissionOnSomeResources (#33072)
* Add defensive fallback for userHasReadPermissionOnSomeResources

When called with a string instead of an object, the function now falls back
to checking a single resource permission instead of failing.

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

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

* Revert "Add defensive fallback for userHasReadPermissionOnSomeResources"

This reverts commit f9c32bc3e2598467e7c8a520319ac5ae49135cbf.

* simpler fix -- remove string as a possible parameter

---------

Co-authored-by: Claude <noreply@anthropic.com>
2025-07-03 08:47:09 -04:00
yasser khan
5cd3a3f745 Fix(cypress): Fix e2e failing on master (#32494) 2025-07-03 10:19:58 +05:30
Harrison Healey
6004d15f9e MM-61595 Use dedicated popover component for post actions menu when empty (#31656)
* Link post actions menu button to existing menu

That menu isn't fully accessible because it uses the old Menu widget,
but the readout will at least be correct when tabbing through the post
controls.

* MM-61595 Use dedicated popover component for post actions menu when empty

* Update unit tests

* Split out ActionsMenuEmptyPopover to start of separate Popover component
2025-07-02 16:23:22 -04:00
Christopher Poile
9ad0f1e070 [MM-64708] Fix custom data retention policy navigation (#33011)
Fix navigation to custom data retention policy form by correcting permission
checking functions. The routes for creating and editing custom data retention
policies were using userHasReadPermissionOnSomeResources() with a single
string resource key, causing permission checks to fail and routes to be
hidden.

Changed both custom_policy_form and custom_policy_form_edit routes to use
userHasReadPermissionOnResource() instead, making them consistent with
other working data retention routes.

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

Co-authored-by: Claude <noreply@anthropic.com>
2025-07-02 14:03:49 -04:00
Maria A Nunez
466e3c3502 Fix accessibility issue with dropdown options (#30715)
* Added getOptionLabel to fix dropdown accessibility for options

* Fix tests

* Revert unnecessary cases

* Other unnecessary case

* Linting

* PR Feedback

* Cleanup

* Cursor assisted - unit tests

* Linting

* Linting i18n

* Fix test

---------

Co-authored-by: Mattermost Build <build@mattermost.com>
2025-07-02 13:19:48 -04:00
M-ZubairAhmed
0d9c4810f4 [MM-64618] ResizeObserver callback fires after component unmount during channel switching (#32668) 2025-07-02 22:30:17 +05:30
Jesse Hallam
d2188ce1dd remove spurious user limits log (#33038)
Only log a warning when the created user exceeds the `MaxUserLimits` if
`MaxUsersLimit > 0`. This was showing up spuriously on licensed servers
for which no limit applied.

Note that this is distinct from blocking user creation past
`MaxHardUsersLimit`.
2025-07-02 13:29:48 -03:00
Jesse Hallam
ebe03c1d45 Channel Store: No SELECT * (#32167)
* Replace SELECT * with explicit column lists in channel store

Migrates channel_store.go away from SELECT * patterns to explicit column
lists for better performance, maintainability, and schema safety.

- Replace GetPinnedPosts raw SQL with query builder using postSliceColumns()
- Replace "cc.*" in group channel search with channelSliceColumns()
- Replace GetChannelsBatchForIndexing raw SQL with query builder
- Replace channel member and team queries with respective column helpers
- Use SelectBuilder helper instead of manual ToSql() calls

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

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

* Replace SELECT * with COUNT(*) in user_test.go

Replaces unnecessary SELECT * queries with SELECT COUNT(*) in
TestPermanentDeleteUser bot count verification. Only needs to check
the count of bots, not retrieve full bot records.

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

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

---------

Co-authored-by: Claude <noreply@anthropic.com>
2025-07-02 15:35:54 +00:00
Nick Misasi
fb9b05b764 Add preview specific UTM parameters (#32509)
Automatic Merge
2025-07-02 17:52:01 +03:00
Pablo Vélez
e99aa4e430 MM-64428 - user tag invite filtering (#31226)
* MM-64428 - user tag invite filtering

* fix lint issues

* remove unnecesary line

* update translations and skip mysql tests

* simplify the solution so in abac channels the invitation link is never shown

* finish clean up of unnecessary code

* clean up and remove no longer necessary translations

* remove leftover props and remove no longer needed tests after simplification

---------

Co-authored-by: Mattermost Build <build@mattermost.com>
2025-07-02 14:55:02 +02:00
Pablo Vélez
f1893e4837 MM-64707 - abac channels should not list user groups in invite modal (#32574)
* MM-64707 - abac channels should not list user groups in invite modal

* fix linter
2025-07-02 12:30:46 +02:00
Ibrahim Serdar Acikgoz
0809ce7a62 [MM-64630] Fix an issue where multiple channels can't be removed from policies (#32164)
* Fix an issue where multiple channels can't be removed from policies

* actually fix the issue

* use hardcoded limit

* simplify removal
2025-07-01 20:48:57 +02:00
Miguel de la Cruz
d8758f8984 Improve response on team restore (#32118)
Co-authored-by: Miguel de la Cruz <miguel@ctrlz.es>
Co-authored-by: Mattermost Build <build@mattermost.com>
2025-07-01 16:54:30 +00:00
Christopher Poile
0832bf8fd4 [MM-64696] LDAP Wizard: Add help text for slow LDAP queries (#32161) 2025-07-01 10:14:33 -04:00
Daniel Espino García
1b7d27707d Fix MM64178 (#30957)
Co-authored-by: Mattermost Build <build@mattermost.com>
2025-06-30 16:43:59 -05:00
sabril
edbfc3d933 upgrade playwright dependencies (#32405) 2025-06-30 23:38:24 +08:00
Nick Misasi
db56476d51 Update subtitle for boards preview (#32168) 2025-06-30 11:12:51 -04:00
Hosted Weblate
d6072ff245 Update translation files
Updated by "Cleanup translation files" hook in Weblate.

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/
2025-06-30 14:17:02 +00:00
Tom De Moor
f8918360ff Translated using Weblate (Dutch)
Currently translated at 99.9% (6383 of 6386 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/nl/
2025-06-30 14:17:02 +00:00
Frank Paul Silye
21277e4755 Translated using Weblate (Norwegian Bokmål)
Currently translated at 82.2% (5253 of 6386 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/nb_NO/
2025-06-30 14:17:02 +00:00
Tom De Moor
71cb8cdfcc Translated using Weblate (Dutch)
Currently translated at 99.6% (6361 of 6386 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/nl/
2025-06-30 14:17:02 +00:00
jprusch
6b5c4aef01 Translated using Weblate (German)
Currently translated at 100.0% (6386 of 6386 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/de/
2025-06-30 14:17:02 +00:00
Tom De Moor
63c034ec77 Translated using Weblate (Dutch)
Currently translated at 98.7% (6304 of 6386 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/nl/
2025-06-30 14:17:02 +00:00
master7
2d46a1dc6b Translated using Weblate (Polish)
Currently translated at 99.6% (6363 of 6386 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/pl/
2025-06-30 14:17:02 +00:00
Manuela Silva
ff48b53e81 Translated using Weblate (Portuguese)
Currently translated at 22.2% (1422 of 6386 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/pt/
2025-06-30 14:17:02 +00:00
Manuela Silva
8323fec996 Translated using Weblate (Portuguese)
Currently translated at 18.6% (1191 of 6386 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/pt/
2025-06-30 14:17:02 +00:00
Sharuru
c9d7c73ad6 Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 100.0% (6386 of 6386 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/zh_Hans/
2025-06-30 14:17:02 +00:00
Sharuru
8e41f66817 Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 100.0% (2717 of 2717 strings)

Translation: Mattermost/server
Translate-URL: https://translate.mattermost.com/projects/mattermost/server/zh_Hans/
2025-06-30 14:17:02 +00:00
Frank Paul Silye
f58b2aef49 Translated using Weblate (Norwegian Bokmål)
Currently translated at 82.2% (5252 of 6386 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/nb_NO/
2025-06-30 14:17:02 +00:00
Frank Paul Silye
04a27801c7 Translated using Weblate (Norwegian Bokmål)
Currently translated at 4.2% (116 of 2717 strings)

Translation: Mattermost/server
Translate-URL: https://translate.mattermost.com/projects/mattermost/server/nb_NO/
2025-06-30 14:17:02 +00:00
master7
f01d9ec5dc Translated using Weblate (Polish)
Currently translated at 99.3% (6342 of 6386 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/pl/
2025-06-30 14:17:02 +00:00
Tom De Moor
898df23ac2 Translated using Weblate (Dutch)
Currently translated at 99.8% (2713 of 2717 strings)

Translation: Mattermost/server
Translate-URL: https://translate.mattermost.com/projects/mattermost/server/nl/
2025-06-30 14:17:02 +00:00
Manuela Silva
8618e3988b Translated using Weblate (Portuguese)
Currently translated at 14.3% (919 of 6386 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/pt/
2025-06-30 14:17:02 +00:00
Manuela Silva
ad8ee664ef Translated using Weblate (Portuguese)
Currently translated at 1.1% (30 of 2717 strings)

Translation: Mattermost/server
Translate-URL: https://translate.mattermost.com/projects/mattermost/server/pt/
2025-06-30 14:17:02 +00:00
Matthew Williams
73b67f2a66 Translated using Weblate (English (Australia))
Currently translated at 100.0% (6386 of 6386 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/en_AU/
2025-06-30 14:17:02 +00:00
jprusch
8fee4caa3c Translated using Weblate (German)
Currently translated at 98.8% (6311 of 6386 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/de/
2025-06-30 14:17:02 +00:00
Matthew Williams
2bbbc44649 Translated using Weblate (English (Australia))
Currently translated at 100.0% (2717 of 2717 strings)

Translation: Mattermost/server
Translate-URL: https://translate.mattermost.com/projects/mattermost/server/en_AU/
2025-06-30 14:17:02 +00:00
jprusch
6ee1896ffc Translated using Weblate (German)
Currently translated at 100.0% (2717 of 2717 strings)

Translation: Mattermost/server
Translate-URL: https://translate.mattermost.com/projects/mattermost/server/de/
2025-06-30 14:17:02 +00:00
master7
42914a6646 Translated using Weblate (Polish)
Currently translated at 98.9% (6322 of 6386 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/pl/
2025-06-30 14:17:02 +00:00
Matthew Williams
4aa65f17d1 Translated using Weblate (English (Australia))
Currently translated at 96.3% (6152 of 6386 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/en_AU/
2025-06-30 14:17:02 +00:00
Vicktor
efa3b3b8db feat(function component migration): migrate QuickInput to a function component (#31492)
* Initial commit

* feat(function component migration): migrate QuickInput to a function component

* fix: add missing export keyword

* Revert "Initial commit"

This reverts commit e40909c6d0590b67e00f62283f6e5a622fbaf9bb.

* refactor: reposition 'showClearButton' variable so tests pass

* refactor: ignore eslint warnings and rename props

Removed 'deleteProperty' calls since some props are destructured.

* refactor(quick_input): wrap functions in useCallback

Updated snapshots, tests, and removed dead code.

* fix(quick_input): add dependencies to useCallback

Restored quick_input.test.tsx to its initial state and made the value prop optional instead.
2025-06-30 16:05:25 +02:00
Christopher Speller
b3724d1151 Update Agents plugin to v1.2.2 (#32481) 2025-06-30 05:45:34 -07:00
Pablo Vélez
cd1e312190 MM-64690 - fix channel name input label (#32157)
* MM-64690 - fix channel name input label

* add correct font-weight

---------

Co-authored-by: Mattermost Build <build@mattermost.com>
2025-06-27 23:03:59 +02:00
Harrison Healey
fec77c26a1 Increase line height in RHS header (#32081) 2025-06-27 18:14:16 +00:00
Harrison Healey
5ffb7607cc MM-64669 Fix keyboard navigation of settings sidebar (#32098)
* MM-64669 Fix keyboard navigation of settings sidebar and add Playwright test

* MM-64669 Revert changes to Cypress test which masked keyboard bug

The changes that were previously made caused Cypress to refocus the
sidebar repeatedly which stopped the test from failing without fixing
the bug.

* Ensure focus highlight is always visible on sidebar tabs

This may not have been broken by the changes that caused MM-64669, but I
noticed it while I was in there and wanted to fix it.

* Fix settings modal scrolling while changing sections using arrow keys

* Remove accidentally-added field
2025-06-27 14:01:53 -04:00
Nick Misasi
62a4ce920e [CLD-9318] Button to re-open Preview Modal after closing (#32121)
* Remove pricing modal. Adjust everywhere to instead open mattermost.com/pricing. When air gapped, don't show buttons to view plans.

* Fix lint

* Further clean up of unused code. Fixes for linter

* Remove onboarding tasklist for previews, add Cloud previer banner

* Fixes for linter, i18n

* Revert dev lines

* Fix lint

* When below one minute, switch to seconds

* fix linter

* Add scaffolding for new Cloud Preview Modal

* Style updates

* Fix tests

* fixes for PR feedback

* useExternalLink for opening pricing modal with enriched params

* Fix i17n

* fix style

* Fix style, tests

* Fix linter, types

* Add file

* Make types even more fixed

* fix: correct test case for SKU label not provided scenario

The test "should not render SKU label when not provided" was incorrectly using baseContent which includes a SKU label. Fixed by creating contentWithoutSku that explicitly sets skuLabel to undefined to properly test the scenario where no SKU label is provided.

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

* Fine I'll do it myself

* fix linter

* Refactors

* Adjustments from PR review. Adjustments to video experience (poster/play button) and starting to translate

* Fix i18n

* Wrap translation strings with defineMessage for i18n extraction

- Add import for defineMessage and MessageDescriptor from react-intl
- Update type definition to use MessageDescriptor for better type safety  
- Wrap all skuLabel, title, and subtitle objects with defineMessage() calls
- This ensures the i18n-extract tool can properly detect translation strings

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

* Fix i18n

* Use regular modal close button

* Fix pipelines

* Fix i18n

* Update webapp/channels/src/components/cloud_preview_modal/preview_modal_content.scss

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

* Update webapp/channels/src/components/cloud_preview_modal/preview_modal_content.scss

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

* Update webapp/channels/src/components/cloud_preview_modal/preview_modal_content.scss

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

* Update webapp/channels/src/components/cloud_preview_modal/preview_modal_content.tsx

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

* Update webapp/channels/src/components/cloud_preview_modal/preview_modal_content.scss

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

* Update webapp/channels/src/components/cloud_preview_modal/preview_modal_content.scss

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

* Update webapp/channels/src/components/cloud_preview_modal/preview_modal_controller.tsx

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

* Update webapp/channels/src/components/cloud_preview_modal/preview_modal_controller.tsx

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

* Update webapp/channels/src/components/cloud_preview_modal/preview_modal_controller.scss

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

* Update webapp/channels/src/components/cloud_preview_modal/preview_modal_controller.tsx

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

* Update webapp/channels/src/components/cloud_preview_modal/preview_modal_controller.tsx

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

* Update webapp/channels/src/components/cloud_preview_modal/preview_modal_controller.tsx

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

* Update webapp/channels/src/components/cloud_preview_modal/preview_modal_controller.tsx

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

* Update webapp/channels/src/components/cloud_preview_modal/preview_modal_controller.scss

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

* Update webapp/channels/src/components/cloud_preview_modal/preview_modal_controller.scss

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

* Update webapp/channels/src/components/cloud_preview_modal/preview_modal_content.scss

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

* Update webapp/channels/src/components/cloud_preview_modal/preview_modal_content.scss

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

* Update webapp/channels/src/components/cloud_preview_modal/preview_modal_content.scss

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

* Update webapp/channels/src/components/cloud_preview_modal/preview_modal_content.scss

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

* Update webapp/channels/src/components/cloud_preview_modal/preview_modal_content.scss

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

* Update webapp/channels/src/components/cloud_preview_modal/preview_modal_content.scss

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

* Remove unnecessary CSS properties from preview modal content

Remove display: flex, height: 100%, and flex-direction: column from .preview-modal-content selector as they have no effect per code review feedback.

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

* Fixes for PR review

* Fix linter

* Fix i18n

* fix linter

* sticky button in bottom left to re-open preview modal when previously closed

* fix linter

* Resize to better fit in place when multiple teams are present

* Changes to address Harrison's feedback

* change file name, remove index.tsx

* Add the new files

* Rename to fix conflicts

* Add the new files

---------

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: Mattermost Build <build@mattermost.com>
Co-authored-by: Matthew Birtch <mattbirtch@gmail.com>
2025-06-27 10:35:47 -04:00
Ibrahim Serdar Acikgoz
037bff9aa3 [MM-64491] Fix system attributes section not appearting w/o a license (#32133) 2025-06-27 09:37:58 +02:00
catalintomai
2b8f7743b6 MM-64687: Racy tests in TestSharedChannelPostMetadataSync (#32144) 2025-06-27 09:11:54 +02:00
Nick Misasi
9e7849647c [CLD-9238] Direct preview user to proper team based on use case (#31784)
* Remove pricing modal. Adjust everywhere to instead open mattermost.com/pricing. When air gapped, don't show buttons to view plans.

* Fix lint

* Further clean up of unused code. Fixes for linter

* Remove onboarding tasklist for previews, add Cloud previer banner

* Fixes for linter, i18n

* Revert dev lines

* Fix lint

* When below one minute, switch to seconds

* fix linter

* Add scaffolding for new Cloud Preview Modal

* Style updates

* Fix tests

* fixes for PR feedback

* useExternalLink for opening pricing modal with enriched params

* Fix i17n

* fix style

* Fix style, tests

* Fix linter, types

* Add file

* Make types even more fixed

* fix: correct test case for SKU label not provided scenario

The test "should not render SKU label when not provided" was incorrectly using baseContent which includes a SKU label. Fixed by creating contentWithoutSku that explicitly sets skuLabel to undefined to properly test the scenario where no SKU label is provided.

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

* Fine I'll do it myself

* fix linter

* Refactors

* Adjustments from PR review. Adjustments to video experience (poster/play button) and starting to translate

* Fix i18n

* Accept use case in CWS login, redirect to proper team, with filtered content in preview modal

* Wrap translation strings with defineMessage for i18n extraction

- Add import for defineMessage and MessageDescriptor from react-intl
- Update type definition to use MessageDescriptor for better type safety  
- Wrap all skuLabel, title, and subtitle objects with defineMessage() calls
- This ensures the i18n-extract tool can properly detect translation strings

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

* Fix i18n

* Hiding modal will presist through refreshes

* Fix linter

* Add exception to notification permission bar for cloud previews

* Use regular modal close button

* Fix pipelines

* Fix i18n

* Update webapp/channels/src/components/cloud_preview_modal/preview_modal_content.scss

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

* Update webapp/channels/src/components/cloud_preview_modal/preview_modal_content.scss

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

* Update webapp/channels/src/components/cloud_preview_modal/preview_modal_content.scss

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

* Update webapp/channels/src/components/cloud_preview_modal/preview_modal_content.tsx

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

* Update webapp/channels/src/components/cloud_preview_modal/preview_modal_content.scss

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

* Update webapp/channels/src/components/cloud_preview_modal/preview_modal_content.scss

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

* Update webapp/channels/src/components/cloud_preview_modal/preview_modal_controller.tsx

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

* Update webapp/channels/src/components/cloud_preview_modal/preview_modal_controller.tsx

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

* Update webapp/channels/src/components/cloud_preview_modal/preview_modal_controller.scss

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

* Update webapp/channels/src/components/cloud_preview_modal/preview_modal_controller.tsx

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

* Update webapp/channels/src/components/cloud_preview_modal/preview_modal_controller.tsx

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

* Update webapp/channels/src/components/cloud_preview_modal/preview_modal_controller.tsx

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

* Update webapp/channels/src/components/cloud_preview_modal/preview_modal_controller.tsx

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

* Update webapp/channels/src/components/cloud_preview_modal/preview_modal_controller.scss

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

* Update webapp/channels/src/components/cloud_preview_modal/preview_modal_controller.scss

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

* Update webapp/channels/src/components/cloud_preview_modal/preview_modal_content.scss

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

* Update webapp/channels/src/components/cloud_preview_modal/preview_modal_content.scss

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

* Update webapp/channels/src/components/cloud_preview_modal/preview_modal_content.scss

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

* Update webapp/channels/src/components/cloud_preview_modal/preview_modal_content.scss

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

* Update webapp/channels/src/components/cloud_preview_modal/preview_modal_content.scss

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

* Update webapp/channels/src/components/cloud_preview_modal/preview_modal_content.scss

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

* Remove unnecessary CSS properties from preview modal content

Remove display: flex, height: 100%, and flex-direction: column from .preview-modal-content selector as they have no effect per code review feedback.

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

* feat: use getBool selector instead of get for boolean preference check

- Replace getPreference with getBool to avoid explicit === 'true' comparison
- Follows Harrison's review suggestion for cleaner boolean handling

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

* fix linter

* Fixes for PR review

* Fix linter

* Fix i18n

* fix linter

* Changes to address Harrison's feedback

* Change file name, remove index.tsx

* change file name, remove index.tsx

* Add the new files

---------

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: Mattermost Build <build@mattermost.com>
Co-authored-by: Matthew Birtch <mattbirtch@gmail.com>
2025-06-26 20:30:26 -04:00
Nick Misasi
a17f4ae5e1 [CLD-9186] Add framework for new Cloud Preview Modal (#31235)
* Remove pricing modal. Adjust everywhere to instead open mattermost.com/pricing. When air gapped, don't show buttons to view plans.

* Fix lint

* Further clean up of unused code. Fixes for linter

* Remove onboarding tasklist for previews, add Cloud previer banner

* Fixes for linter, i18n

* Revert dev lines

* Fix lint

* When below one minute, switch to seconds

* fix linter

* Add scaffolding for new Cloud Preview Modal

* Style updates

* Fix tests

* fixes for PR feedback

* useExternalLink for opening pricing modal with enriched params

* Fix i17n

* fix style

* Fix style, tests

* Fix linter, types

* Add file

* Make types even more fixed

* fix: correct test case for SKU label not provided scenario

The test "should not render SKU label when not provided" was incorrectly using baseContent which includes a SKU label. Fixed by creating contentWithoutSku that explicitly sets skuLabel to undefined to properly test the scenario where no SKU label is provided.

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

* Fine I'll do it myself

* fix linter

* Refactors

* Adjustments from PR review. Adjustments to video experience (poster/play button) and starting to translate

* Fix i18n

* Wrap translation strings with defineMessage for i18n extraction

- Add import for defineMessage and MessageDescriptor from react-intl
- Update type definition to use MessageDescriptor for better type safety  
- Wrap all skuLabel, title, and subtitle objects with defineMessage() calls
- This ensures the i18n-extract tool can properly detect translation strings

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

* Fix i18n

* Use regular modal close button

* Fix pipelines

* Fix i18n

* Update webapp/channels/src/components/cloud_preview_modal/preview_modal_content.scss

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

* Update webapp/channels/src/components/cloud_preview_modal/preview_modal_content.scss

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

* Update webapp/channels/src/components/cloud_preview_modal/preview_modal_content.scss

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

* Update webapp/channels/src/components/cloud_preview_modal/preview_modal_content.tsx

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

* Update webapp/channels/src/components/cloud_preview_modal/preview_modal_content.scss

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

* Update webapp/channels/src/components/cloud_preview_modal/preview_modal_content.scss

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

* Update webapp/channels/src/components/cloud_preview_modal/preview_modal_controller.tsx

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

* Update webapp/channels/src/components/cloud_preview_modal/preview_modal_controller.tsx

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

* Update webapp/channels/src/components/cloud_preview_modal/preview_modal_controller.scss

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

* Update webapp/channels/src/components/cloud_preview_modal/preview_modal_controller.tsx

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

* Update webapp/channels/src/components/cloud_preview_modal/preview_modal_controller.tsx

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

* Update webapp/channels/src/components/cloud_preview_modal/preview_modal_controller.tsx

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

* Update webapp/channels/src/components/cloud_preview_modal/preview_modal_controller.tsx

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

* Update webapp/channels/src/components/cloud_preview_modal/preview_modal_controller.scss

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

* Update webapp/channels/src/components/cloud_preview_modal/preview_modal_controller.scss

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

* Update webapp/channels/src/components/cloud_preview_modal/preview_modal_content.scss

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

* Update webapp/channels/src/components/cloud_preview_modal/preview_modal_content.scss

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

* Update webapp/channels/src/components/cloud_preview_modal/preview_modal_content.scss

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

* Update webapp/channels/src/components/cloud_preview_modal/preview_modal_content.scss

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

* Update webapp/channels/src/components/cloud_preview_modal/preview_modal_content.scss

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

* Update webapp/channels/src/components/cloud_preview_modal/preview_modal_content.scss

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

* Remove unnecessary CSS properties from preview modal content

Remove display: flex, height: 100%, and flex-direction: column from .preview-modal-content selector as they have no effect per code review feedback.

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

* Fixes for PR review

* Fix linter

* Fix i18n

* fix linter

* Changes to address Harrison's feedback

* change file name, remove index.tsx

* Add the new files

---------

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: Mattermost Build <build@mattermost.com>
Co-authored-by: Matthew Birtch <mattbirtch@gmail.com>
2025-06-26 16:39:40 -04:00
Lorenzo
2f31642b7c Remove SBOM generation since it's now in delivery-platform (#32073) 2025-06-26 13:40:18 -06:00
Miguel de la Cruz
d042d242dd Use master to fetch user profiles when creating a GM (#32152)
Co-authored-by: Miguel de la Cruz <miguel@ctrlz.es>
2025-06-26 13:47:29 +00:00
Christopher Speller
124ceb54ee Update Agents plugin to v1.2.1 (#32124) 2025-06-26 03:54:39 -07:00
Miguel de la Cruz
0704500609 Update shared channel app layer to make active check optional (#29602)
The `getSharedChannelsService` method was checking as well for the
Shared Channels to be active, which only the lead node of a cluster
is, so API operations that should run correctly like sharing/unsharing
a channel or inviting/uninviting a remote were returning a 400 bad
request.

This change updates the method to check for the Shared Channel service
to be active only on request, and on doing so it changes the error and
status code returned to indicate specifically that the service is
running but inactive, and returns a 500 as the situation is not an
error on the requester.

Co-authored-by: Mattermost Build <build@mattermost.com>
2025-06-26 10:54:17 +00:00
Miguel de la Cruz
d9a083dc82 Use master to get remotes to avoid race conditions in cloud (#31221)
Co-authored-by: Miguel de la Cruz <miguel@ctrlz.es>
2025-06-26 12:52:02 +02:00
Miguel de la Cruz
3fb62722a4 Show correct username and email for remote users (#31205)
Co-authored-by: Miguel de la Cruz <miguel@ctrlz.es>
2025-06-26 12:51:42 +02:00
David Krauser
aaa62a40ae [MM-64686] Expose audit logging functionality via plugin API (#31204)
This commit exposes audit logging functionality to plugins via the plugin API, allowing plugins to create and log audit records. Additionally, it addresses a gob encoding issue that could cause plugin crashes when audit data contains nil pointers or unregistered types.
2025-06-25 20:37:32 -04:00
Maria A Nunez
efb960a160 Fixed styling issues with multiples banners in System Console (#31822)
* Fixed styling issues with banners in System Console

* Fix Cypress test

---------

Co-authored-by: Mattermost Build <build@mattermost.com>
2025-06-24 18:11:11 -04:00
Christopher Poile
9b1e03a6b8 [MM-63557] mmctl: Add compliance export create cmd (#30594)
* Refactor job retrieval to support multiple statuses & multiple types

- Updated job retrieval functions to handle multiple job statuses.
- Renamed `GetJobsByTypeAndStatus` to `GetJobsByTypesAndStatuses` for consistency across the codebase.
- Adjusted related function signatures and implementations in the job store and retry layer to accommodate the new method.
- Updated tests to reflect changes in job retrieval logic and ensure proper functionality.

* Add compliance export create command and tests

- Introduced `ComplianceExportCreateCmd` to facilitate the creation of compliance export jobs with options for date, start, and end timestamps.
- Added unit tests for the new command, covering various scenarios including valid and invalid inputs.
- Updated documentation to include usage examples and options for the new command.
- Enhanced existing tests to ensure proper functionality of compliance export job handling.

* update docs

* update tests for new logic

* Refactor message export job tests to use DefaultPreviousJobPageSize

- Updated all test cases in worker_test.go to replace hardcoded page size of 100 with DefaultPreviousJobPageSize for consistency.
- Adjusted the worker.go file to define DefaultPreviousJobPageSize and use it in job retrieval logic.
- Ensured that the changes maintain the functionality of job data initialization and retrieval tests.

* PR comments

* PR comments, simplifications, clarifications, formatting

* prefer hypen over underscore in command names

* merge conflict

* update mmctl docs
2025-06-24 21:38:30 +00:00
Christopher Poile
b33a7e362f [MM-63556] mmctl: Add compliance export download cmd (#30576)
* add mmctl compliance export download command and tests

- Introduced `ComplianceExportDownloadCmd` to facilitate downloading compliance export files.
- Implemented the `DownloadComplianceExport` method in the Client interface for handling file downloads.
- Added unit tests for the download command, covering successful downloads, error handling for non-existent jobs, and retries on failure.
- Included end-to-end tests to validate the command's functionality.
- Updated documentation to include usage examples and options for the new command.

* don't know why this was left out

* PR comments

* adjust test for new retry logic

* refactored download fn for compliance_export and export

* fix test due to fixed logic

* docs
2025-06-24 16:27:54 -04:00
Jesse Hallam
60a747f975 Always require signatures for prepackaged plugins (#31785)
* Always require signatures for prepackaged plugins

We have always required signatures for packages installed via the marketplace -- whether remotely satisfied, or sourced from the prepackaged plugin cache.

However, prepackaged plugins discovered and automatically installed on
startup did not require a valid signature. Since we already ship
signatures for all Mattermost-authored prepackaged plugins, it's easy to
simply start requiring this.

Distributions of Mattermost that bundle their own prepackaged plugins
will have to include their own signatures. This in turn requires
distributing and configuring Mattermost with a custom public key via
`PluginSettings.SignaturePublicKeyFiles`.

Note that this enhanced security is neutered with a deployment that uses
a file-based `config.json`, as any exploit that allows appending to the
prepackaged plugins cache probably also allows modifying `config.json`
to register a new public key. A [database-based
config](https://docs.mattermost.com/configure/configuration-in-your-database.html)
is recommended.

Finally, we already support an optional setting
`PluginSettings.RequirePluginSignature` to always require a plugin
signature, although this effectively disables plugin uploads and
requires extra effort to deploy the corresponding signature. In
environments where only prepackaged plugins are used, this setting is
ideal.

Fixes: https://mattermost.atlassian.net/browse/MM-64627

* setup dev key, expect no plugins if sig fails

* Fix shadow variable errors in test helpers

Pre-declare signaturePublicKey variable in loops to avoid shadowing
the outer err variable used in error handling.

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

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

* Replace PrepackagedPlugin.Signature with SignaturePath for memory efficiency

- Changed PrepackagedPlugin struct to use SignaturePath string instead of Signature []byte
- Updated buildPrepackagedPlugin to use file descriptor instead of reading signature into memory
- Modified plugin installation and persistence to read from signature file paths
- Updated all tests to check SignaturePath instead of Signature field
- Removed unused bytes import from plugin.go

This change reduces memory usage by storing file paths instead of signature data
in memory while maintaining the same security verification functionality.

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

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

---------

Co-authored-by: Claude <noreply@anthropic.com>
2025-06-24 15:11:02 -03:00
Christopher Poile
e60f878090 [MM-63555] mmctl: Add compliance export show and cancel cmds (#30569)
* add compliance export cancel command and tests

- Introduced `ComplianceExportCancelCmd` to allow cancellation of compliance export jobs.
- Implemented unit tests for the cancellation command, covering successful cancellation, error handling for non-existent jobs, and cancellation in non-cancellable states.
- Added end-to-end tests to validate the command's functionality in the E2E test suite.

* mmctl docs

* clean up example text; remove unneeded getJob

* fix tests

* fix tests, again.

* prefer hyphen for command naming

* update docs
2025-06-24 12:26:43 -04:00
Christopher Poile
9399398e04 [MM-62888] mmctl: Add compliance export list cmd (#30914)
* Add compliance export list cmd and tests

- Introduced `ListComplianceExports` method in the Client interface to retrieve compliance export jobs.
- Added `compliance_export` command with subcommand `list` for listing compliance export jobs, including pagination options.
- Implemented end-to-end and unit tests for the compliance export listing functionality.

* Add docs for mmctl

* fix test typo

* added paging, tested

* update docs with better desc (how it's sorted)

* simplified, reusing job call

* add show cmd, unit tests, e2e tests

* update mmctl docs
2025-06-24 11:20:40 -04:00
Nick Misasi
5d7c3b52ed [CLD-9285] Add server version and edition (team vs ent) to ExternalLink component (#31783)
* Add server version and edition (team vs ent) to ExternalLink component

* fix: add proper Redux state setup to datetime_input.test.tsx

The test was failing because the useExternalLink hook (added in this PR)
requires access to config and license Redux state, but the datetime_input
tests weren't providing proper initial state. This caused components to
receive undefined values from Redux selectors, potentially affecting
locale/date formatting behavior.

Added defaultState with proper config and license structure to match
what other tests in the codebase use, ensuring consistent test environment.

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

* Revert to master

* Revert to master

---------

Co-authored-by: claude[bot] <209825114+claude[bot]@users.noreply.github.com>
Co-authored-by: Nick Misasi <nickmisasi@users.noreply.github.com>
2025-06-24 11:11:19 -04:00
lindalumitchell
1148bea55b Remove extra Tab keypress that was causing test failure (#31817)
Co-authored-by: Mattermost Build <build@mattermost.com>
2025-06-23 20:43:14 +00:00
Pablo Vélez
b3bc4b6f1b Mm 64299 disable guest invite in abac channels (#31139)
* MM-64299 - disable guest invite in abac channels

* filter the abac channel list for guest

* add filter in the back-end too

* add proper translation

* simplify the condition for enforced channels and add the unit tests

* enhance validation for not inviting guest users when abac enforced channel

* add missing translation

* add value to empty translation

* prevent showing the channel name if abac protected
2025-06-23 18:17:55 +02:00
Hosted Weblate
82c1de2b4b Update translation files
Updated by "Cleanup translation files" hook in Weblate.

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/
2025-06-23 13:41:23 +00:00
Serhii Khomiuk
645c5bc370 Translated using Weblate (Ukrainian)
Currently translated at 96.6% (6116 of 6330 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/uk/
2025-06-23 13:41:23 +00:00
MArtin Johnson
fb9d5e4999 Translated using Weblate (Swedish)
Currently translated at 99.9% (6324 of 6330 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/sv/
2025-06-23 13:41:23 +00:00
MArtin Johnson
8ab3f64436 Translated using Weblate (Swedish)
Currently translated at 99.8% (2703 of 2706 strings)

Translation: Mattermost/server
Translate-URL: https://translate.mattermost.com/projects/mattermost/server/sv/
2025-06-23 13:41:23 +00:00
Son Le
d7d3ddba67 Translated using Weblate (Vietnamese)
Currently translated at 72.9% (4616 of 6330 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/vi/
2025-06-23 13:41:23 +00:00
Son Le
fee3bed292 Translated using Weblate (Vietnamese)
Currently translated at 83.1% (2250 of 2706 strings)

Translation: Mattermost/server
Translate-URL: https://translate.mattermost.com/projects/mattermost/server/vi/
2025-06-23 13:41:23 +00:00
Son Le
45e1341f57 Translated using Weblate (Vietnamese)
Currently translated at 72.9% (4615 of 6330 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/vi/
2025-06-23 13:41:23 +00:00
Manuela Silva
3525bf33b0 Translated using Weblate (Portuguese)
Currently translated at 14.4% (915 of 6330 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/pt/
2025-06-23 13:41:23 +00:00
Manuela Silva
086bfca1e6 Translated using Weblate (Portuguese)
Currently translated at 0.5% (15 of 2706 strings)

Translation: Mattermost/server
Translate-URL: https://translate.mattermost.com/projects/mattermost/server/pt/
2025-06-23 13:41:23 +00:00
Ekaterine Papava
c5cca277ce Translated using Weblate (Georgian)
Currently translated at 8.6% (548 of 6330 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/ka/
2025-06-23 13:41:23 +00:00
Tom De Moor
602067453f Translated using Weblate (Dutch)
Currently translated at 99.9% (6327 of 6330 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/nl/
2025-06-23 13:41:23 +00:00
Tom De Moor
1b32700244 Translated using Weblate (Dutch)
Currently translated at 99.9% (2704 of 2706 strings)

Translation: Mattermost/server
Translate-URL: https://translate.mattermost.com/projects/mattermost/server/nl/
2025-06-23 13:41:23 +00:00
Manuela Silva
eccb014a9a Translated using Weblate (Portuguese)
Currently translated at 12.3% (779 of 6330 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/pt/
2025-06-23 13:41:23 +00:00
Serhii Khomiuk
a0cc456984 Translated using Weblate (Ukrainian)
Currently translated at 96.5% (6113 of 6330 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/uk/
2025-06-23 13:41:23 +00:00
Manuela Silva
cf74639d01 Translated using Weblate (Portuguese)
Currently translated at 9.3% (593 of 6330 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/pt/
2025-06-23 13:41:23 +00:00
Ekaterine Papava
205a8c9a04 Translated using Weblate (Georgian)
Currently translated at 8.6% (546 of 6330 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/ka/
2025-06-23 13:41:23 +00:00
jprusch
3d72cae0e8 Translated using Weblate (German)
Currently translated at 100.0% (6330 of 6330 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/de/
2025-06-23 13:41:23 +00:00
Manuela Silva
1e12714a59 Translated using Weblate (Portuguese)
Currently translated at 9.0% (576 of 6330 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/pt/
2025-06-23 13:41:23 +00:00
master7
a2a68792ea Translated using Weblate (Polish)
Currently translated at 100.0% (6330 of 6330 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/pl/
2025-06-23 13:41:23 +00:00
Frank Paul Silye
21c69135cb Translated using Weblate (Norwegian Bokmål)
Currently translated at 82.8% (5242 of 6330 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/nb_NO/
2025-06-23 13:41:23 +00:00
Ekaterine Papava
ba40f4ff8f Translated using Weblate (Georgian)
Currently translated at 8.6% (545 of 6330 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/ka/
2025-06-23 13:41:23 +00:00
kaakaa
4aa748649c Translated using Weblate (Japanese)
Currently translated at 100.0% (6330 of 6330 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/ja/
2025-06-23 13:41:23 +00:00
Frank Paul Silye
0f4097d665 Translated using Weblate (Norwegian Bokmål)
Currently translated at 82.7% (5241 of 6330 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/nb_NO/
2025-06-23 13:41:23 +00:00
kaakaa
d80f9b74e5 Translated using Weblate (Japanese)
Currently translated at 99.1% (6276 of 6330 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/ja/
2025-06-23 13:41:23 +00:00
Hosted Weblate
84506745b6 Update translation files
Updated by "Cleanup translation files" hook in Weblate.

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/
2025-06-23 13:41:23 +00:00
Christopher Speller
48ec3fe473 Update Agents plugin to v1.2.0 (#31806)
* Update Agents plugin to v1.2.0

* Rename
2025-06-23 04:57:28 -07:00
Ibrahim Serdar Acikgoz
2526a6c0bd add missing shadows to the access control policies page (#31364) 2025-06-23 11:03:01 +02:00
Christopher Poile
250e39c85f [MM-64603] LDAP Wizard: UX and Copy (#31649)
* improve pluralization

* changes to highlight strings -- might want to revert after review

* fix custom setting styling

* blank commit

* broken e2e test

* add css comments
2025-06-20 14:26:05 -04:00
Maria A Nunez
ec7c1e6d51 Removed NPS plugin (#31418)
Co-authored-by: Mattermost Build <build@mattermost.com>
2025-06-20 11:39:29 -04:00
Pablo Vélez
5fc74cd401 MM-64330 - filter abac users in channel invite (#31219)
* MM-64330 - filter abac users in channel invite

* implement cursor functionality for abac user filtering

* remove unnecessary comments

* refactor the backend implementation simplifying the functions

* refactor api to use opts as parameters, rename function

* add missing translation

* remove unnecesary test code

---------

Co-authored-by: Mattermost Build <build@mattermost.com>
2025-06-20 10:53:14 +02:00
Jesse Hallam
968550d275 Fix undefined variable 'opts' in getSidebarCategoriesT function (#31815)
The function was trying to use 'opts.TeamID' but 'opts' was not defined in the function scope. Changed it to use the 'teamId' parameter which is properly defined in the function signature.

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

Co-authored-by: Claude <noreply@anthropic.com>
2025-06-20 01:27:28 +00:00
Jesse Hallam
dcc72c4c61 MM-63728: simplify category store with graphql gone (#30848)
* move category permissions to api

In https://github.com/mattermost/mattermost/pull/21038, we changed the
behaviour of the channel category store to filter out deleted teams and
teams for which the user was not a member. This was necessary in part
due to querying multiple teams via GraphQL.

With GraphQL no longer supported, let's move the permissions to the
API instead and remove the `JOIN` to filter out teams in the store.

Note that we /don't/ prevent access to deleted teams. For better or
worse, deleted teams remain largely accessible via other API endpoints
anyway.

* remove ExcludeTeam / GraphQL support

As part of https://github.com/mattermost/mattermost/pull/20353, we added
`ExcludeTeam` and the associated logic to support a GraphQL API.

With GraphQL no longer supported, let's simplify this logic and remove
the filtering and associated complexity.

* Fix shadow variable declaration in channel_store_categories.go

Fixed golangci-lint error by reusing existing err variable rather than shadowing it.

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

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

* fix build issue

* Remove SidebarCategorySearchOpts and simplify API to use teamID string

Per code review feedback, this change removes the SidebarCategorySearchOpts
struct entirely since the Type field was never used in the store implementation.
All methods now accept a simple teamID string parameter instead of the struct,
which simplifies the API and makes the code clearer.

Changes:
- Remove SidebarCategorySearchOpts struct from store.go
- Update CreateInitialSidebarCategories and GetSidebarCategories signatures
- Update all implementations (sqlstore, retrylayer, timerlayer, mocks)
- Update all callers to pass teamID string directly
- Clean up unused imports

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

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

---------

Co-authored-by: Claude <noreply@anthropic.com>
2025-06-20 00:48:12 +00:00
Ben Schumacher
b69412d23f [MM-64347] Enable System Console UI for AuditSettings by default (#31118)
Co-authored-by: Doug Lauder <wiggin77@warpmail.net>
2025-06-19 20:18:46 +02:00
Rajat Dabade
f980a538c5 Updated board prepackaged version to v9.1.4 (#31771) 2025-06-19 23:43:18 +05:30
Harrison Healey
ebb68759ad Remove old avatar variants of status icons (#31768)
These predate the "circle with a check"-style status indicators we've
used for years now.
2025-06-19 10:11:35 -04:00
Harrison Healey
a3f60f797b MM-63725 Populate multiple sidebar categories at once whenever possible (#31064)
* Remove redundant sidebar tests from TestChannelStore

* MM-63725 Refactor to split out getOrphanedSidebarChannels

* MM-63725 Populate multiple sidebar categories at once whenever possible

* Fix shadowing
2025-06-19 10:09:36 -04:00
Devin Binnie
3bd0a2ad91 [MM-64639] Fix styling on thread item header (#31807) 2025-06-19 09:44:46 -04:00
Ben Schumacher
2661f77cea [MM-64502] Fix errcheck linter errors in channel_test.go (#31309)
Co-authored-by: Claude <noreply@anthropic.com>
2025-06-19 14:13:45 +02:00
Ben Schumacher
cfc1503d62 [MM-63355] Add AuthData to mmctl user search output (#30478) 2025-06-19 11:52:16 +02:00
Ben Schumacher
04a60b6609 [MM-57693] Add schema dump to Support Packet (#31162)
Co-authored-by: Claude <noreply@anthropic.com>
2025-06-19 11:33:55 +02:00
Arya Khochare
824d3b8259 Fixed errcheck issues in server/channels/app/file_test.go (#28941)
Co-authored-by: Ben Schumacher <ben.schumacher@mattermost.com>
2025-06-19 11:20:23 +02:00
Elias Nahum
731cc1fb5f Add server settings to further lock files on mobile (#30949)
* Add server settings to further lock files on mobile

* fix format with prettier

---------

Co-authored-by: Mattermost Build <build@mattermost.com>
Co-authored-by: Saturnino Abril <5334504+saturninoabril@users.noreply.github.com>
2025-06-19 09:37:32 +02:00
Devin Binnie
b1f609e6b8 [MM-61582][MM-61605][MM-61622][MM-63029][MM-63026][MM-63059] Mobile View accessibility fixes (#31328)
* [MM-61582] Ensure textbox changes size when the window is too small

* [MM-61605] Fix clipping on menu modal in mobile view

* [MM-61622] Make mobile view RHS scrollable

* [MM-63029] Fix mobile view Browse Channels modal arrangement

* [MM-63026] Make new channel body scrollable if needed, flex to full screen on mobile view

* [MM-63059] Make Settings Modal properly responsive with flexbox for mobile view

* Fix lint

* [MM-64033] Fix mobile view for User Groups, another fix for Browse Channels

* Fix notification modal

* PR feedback

---------

Co-authored-by: Mattermost Build <build@mattermost.com>
2025-06-19 11:13:42 +05:00
catalintomai
bd5ca1c07e MM-60640: [Shared Channels] Display remotes' names in Shared With tooltip (#30886) 2025-06-19 07:57:22 +02:00
Devin Binnie
bd16f4f9bf [MM-62989][MM-63039][MM-63033][MM-64174][MM-63040][MM-63032][MM-63001][MM-63006][MM-63037] Various accessibility fixes for the Create Channel modal (#30888)
* [MM-62989] Replace channel purpose input with Input component

* [MM-63039] Fix styles so that a11y--focused box shadow is applied to the private/public channel buttons

* [MM-63033] Add aria-describedby and role=alert to the URL input on create channel modal

* Fix lint

* [MM-63035] Change legend to label, fieldset to div in the Input component

* Fix i18n

* [MM-64174] Stop propagation of enter event while editing the new channel

* [MM-63037] Add role=img and an aria label to the error img icon

* Fix snap

* Revert "[MM-63035] Change legend to label, fieldset to div in the Input component"

This reverts commit e8516f3e6a266c77db2b1695a036db717041a9ef.

* [MM-63040] Remove tabindex=0 from GenericModal wrapper, fix issue with URLInput that I caused D:

* Fix snap

---------

Co-authored-by: Mattermost Build <build@mattermost.com>
2025-06-18 16:29:04 -04:00
Devin Binnie
1efc3dacaf [MM-61593] Add parameters for icon/dropdown text for the Calls button (#31654)
* [MM-61593] Add parameters for icon/dropdown text for the Calls button

* PR feedback
2025-06-18 11:00:01 -04:00
catalintomai
c5f79bba09 MM-64610: Restrict import upload for shared channels feature. (#31659) 2025-06-18 15:49:58 +02:00
Devin Binnie
26613fb4c6 [MM-63035][MM-63970][MM-63978][MM-64028][MM-64019][MM-64022][MM-64026][MM-64023][MM-61625] Create User Group modal accessibility fixes (#31047)
* [MM-63970] Add aria-live for creating a group, always use modal animation

* [MM-63978] Move my fix for multiselect remove button focus to the multiselect component

* [MM-63035][MM-64028] Change legend to label, fieldset to div in the Input component

* [MM-64019] Add fieldset and legend to Add people

* [MM-64026] Add required to Name and Mention boxes

* [MM-64023] Add results available aria-live area to multiselect

* [MM-64022] Restore original multivalueremove for users_email_input, use ariaLabelRenderer for Multiselect

* Use noteText for required for now

* Fix

* Fix e2e

* Only show required prompt when there are no users picked

* Fix cancel button submitting form

* PR feedback

* Do the required field for multiselect properly

* Other PR feedback

* Fix checks

---------

Co-authored-by: Mattermost Build <build@mattermost.com>
2025-06-18 09:25:13 -04:00
Devin Binnie
3d2aa70b7b [MM-61626] Replace most uses of <header> with <div> where not needed (#31371)
Co-authored-by: Mattermost Build <build@mattermost.com>
2025-06-18 09:20:03 -04:00
yasser khan
b784074212 Fix Flaky test failing on prod and in master branch (#31407) 2025-06-18 17:22:57 +05:30
Devin Binnie
df1b278f62 [MM-63007][MM-63004][MM-63020][MM-63009][MM-63008] More accessibility fixes around Search (#31409)
* [MM-63008] Make collapse button on search bar an actual button

* [MM-63004][MM-63020] Convert search box to floating-ui, fix some of the roles and labels that were incorrect

* [MM-63009] Add radiogroup and radio roles to the search box types

* [MM-63007] Ensure search box reads out number of results with suggestion items

* Fix playwright tests

* PR feedback

* Remove floating ui overlay

* Remove unnecessary .first() by being more specific about the search box

---------

Co-authored-by: Mattermost Build <build@mattermost.com>
2025-06-17 17:47:30 -04:00
Jesse Hallam
e367872c0b feat: Replace 5% grace period with configurable ExtraUsers field (#31629)
* feat: Replace 5% grace period with configurable ExtraUsers field

- Rename ExtraSeats to ExtraUsers in license Features struct
- Remove fixed 5% grace period and minimum 1 extra user logic
- Add configurable ExtraUsers field that allows exact control over additional seats
- Update calculateGraceLimit() to use extraUsers parameter directly
- When ExtraUsers is nil, defaults to 0 (hard cap with no overage)
- Special case maintained: zero user licenses always return 0 grace limit
- Update all tests to use new ExtraUsers functionality

Closes #31628

Co-authored-by: Jesse Hallam <lieut-data@users.noreply.github.com>

* feat: eliminate calculateGraceLimit function, use inline baseLimit + extraUsers

- Remove calculateGraceLimit function and replace with inline calculation
- Allow extraUsers even when baseLimit is 0 (behavioral change)
- Update tests to reflect new behavior
- Remove TestCalculateGraceLimit since function no longer exists

Co-authored-by: Jesse Hallam <lieut-data@users.noreply.github.com>

* feat: move ExtraUsers field to top level License struct

Move ExtraUsers field from Features struct to the top level License struct
for better organization and direct access. Update all references in limits.go
and limits_test.go to use the new field location.

Co-authored-by: Jesse Hallam <lieut-data@users.noreply.github.com>

* feat: use model.NewPointer for creating integer pointers in tests

Replace inline function declarations with model.NewPointer calls for cleaner code.

Co-authored-by: Jesse Hallam <lieut-data@users.noreply.github.com>

* feat: reorder ExtraUsers field to be after IsSeatCountEnforced

Co-authored-by: Jesse Hallam <lieut-data@users.noreply.github.com>

* fix: format Go files with gofmt

- Remove extra blank line in limits.go
- Align struct fields in limits_test.go table test

Co-authored-by: Jesse Hallam &lt;lieut-data@users.noreply.github.com&gt;

* Fix user limits tests and document ExtraUsers field

- Fix TestCreateUserOrGuestSeatCountEnforcement to use ExtraUsers instead of old grace period
- Add documentation to ExtraUsers field explaining it as a grace mechanism
- Update test comments to reflect hard limit terminology

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

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

---------

Co-authored-by: claude[bot] <209825114+claude[bot]@users.noreply.github.com>
Co-authored-by: Jesse Hallam <lieut-data@users.noreply.github.com>
Co-authored-by: Claude <noreply@anthropic.com>
2025-06-17 19:56:52 +00:00
Devin Binnie
744d284069 Fix delete button aria-label on User Groups list modal (#31651) 2025-06-17 18:23:00 +00:00
Claudio Costa
8949a5c91c Prepackage Calls v1.9.1 (#31652) 2025-06-17 11:31:37 -06:00
Devin Binnie
b191c922af [MM-63044] Fix overflow formatting on suggestion list (#31372)
* [MM-63044] Fix overflow formatting on suggestion list

* fix lint

---------

Co-authored-by: Mattermost Build <build@mattermost.com>
2025-06-17 11:06:59 -04:00
Daniel Espino García
fc14fa0e87 Fix getAllChannels api not returning DMs/GMs (#31362)
Automatic Merge
2025-06-17 09:16:06 +03:00
Agniva De Sarker
761bc7549b [AI assisted] MM-64298: Process setting status offline in batches (#31065)
When a user disconnects from the hub, we would spawn off a goroutine
which would make a cluster request, and then update the user status
as offline in the DB.

This was another case of unbounded concurrency where the number of
goroutines spawned was user controlled. Therefore, we would see
a clear spike in DB connections on master when a lot of users
would suddenly disconnect.

To fix this, we implement concurrency control in two areas:
1. In making the cluster request. We implement a counting semaphore
per-hub to avoid making unbounded cluster requests.
2. We use a buffered channel with a periodic flusher to process
status updates.

We also add a new store method to upsert multiple statuses
in a single query. The statusUpdateThreshold is set to 32, which means
no more than 32 rows will be upserted at one time, keeping the
SQL query load reasonable.

https://mattermost.atlassian.net/browse/MM-64298

```release-note
We improve DB connection spikes on user disconnect
by processing status updates in batches.
```
2025-06-17 09:20:34 +05:30
Devin Binnie
b99a22f175 [MM-63021] Modify input to have min/max length validation work the same as the validation around required, replace Create Team input with Input component (#31406) 2025-06-16 17:57:02 -04:00
Christopher Poile
548a47ae56 [MM-63152] LDAP Wizard (#31417)
* [MM-63717] LDAP Wizard skeleton (#31029)

* add ldap_wizard component to render its admin components

* i18n

* test adjustment

* keys and props fixes

* title fix

* fix placeholders

* fix value initialization

* linting

* remove all ...props (except custom component); any->unknown

* fix i18n (temp, will be changed in later PR)

* better return; simplify function checking/calling

* [MM-64259] Sections sidebar and navigation (#31059)

* initial sections list sidebar

* sidebar highlighting and scroll on click

* some tidying up

* add custom section titles for section sidebar

* i18n

* updating border on sections

* scss style lint

* color -> border-color

* simplify activeSectionKey initialization; remove trailing newline

* add useSectionNavigation; clean up ldap_wizard and scss; PR comments

* extract section of code into renderSidebar()

---------

Co-authored-by: Asaad Mahmood <asaadmahmood@users.noreply.github.com>

* [MM-64296] Add test connection for connection settings panel (#31190)

* button -> ldap test connect api

* fix console error by sanitizing value in text component

* return detailed error as error; adjust button -> primary, flushLeft

* middle of redesigning how we do hover text, first button

* add hover text to bools and file uploads

* i18n

* add LdapSettings as api type; add new endpoint to api yaml

* allow testing without first enabling LDAP and saving config

* i18n id changes

* improve TestLdapConnection to current standards

* PR comments

* safeDereference; cleaner returns

* remove hover markdown; formatting and typing simplification

* use button for "More Info"; i18n

* finish renaming help_text_hover -> help_text_more_info

* fix error output

* only send bindpassword if it has been changed

* fix: don't send blank bindPassword when it is still *****

* merge conflict

* [MM-64480] Refactor Admin Definition (#31280)

* move ldap definition to its own file for simplicity & context

* refactor admin_definition to eliminate circular dependencies

* merge conflicts

* before: buggy userHasReadPermissinOnSomeResources; after: fix incorrect snapshot

* merge conflict: new bindPasssword definition was left behind; fixed.

* merge conflict

* [MM-63765] LDAP Wizard: User filter expandable section (#31286)

* add "more info" hover to user filter help texts; make wider

* add expandable_setting type and component

* use Dislosure show/hide pattern for accessibility

* fix tooltip scss selectors

* fix hover -> more_info; make sure translation files are correct

* use join('\n\n') instead of the eslint disable line

* Revert "use join('\n\n') instead of the eslint disable line"

This reverts commit 274667e875b34703f14fee0706cd28b0125cefc9.

* [MM-64482] LDAP Wizard - Test User filters (#31312)

* initial cut at UI and backend for test filters

* api definitions; mocks

* clean up to current standards

* [MM-64512] - Test user filters UI (#31355)

* result_count -> total_count

* json cannot marshal error, returning error as string as god intended

* render errors with icon, hover text, and better feedback texts

* gather the settings that may be in expandable sections

* remove success, use error == "" to indicate success

* [MM-64536] LDAP Wizard: Test user attributes (#31373)

* LdapFilterTestResult -> LdapDiagnosticResult; FilterName -> TestName

* implement test_attributes endpoint and limited frontend (first step)

* adding EntriesWithValue

* [MM-64550] LDAP Wizard: Test user attributes UI (#31374)

* [MM-64551] LDAP Wizard: Test group attributes (#31375)

* remove Test LDAP button (not needed); reused helptext for other btn

* implement test_group_attributes endpoint; button/client-side paths

* [MM-64552] LDAP Wizard: Test group attributes UI (#31376)

* implement Test Group Attributes button

* simplify helper functions (improves useCallback dependencies)

* show the default filter that was used on the backend in the tooltip

* show the icon when there's an error (e.g. required filter/attribute)

* fix infinite rerendering

* fix error after failed save; fix navigation unlocked after save

* empty

* Adjust message feedback given we don't test the schema anymore

* improve css; don't use inline styles

* removed unneccesary pointer indirection

* improved i18n strings and logic

* combining filters/attributes/group attributes endpoints

improve types

* improve help text for User Filter (it's tricky)

* AvailableAttrs -> AvailableAttributes

* fix for e2e tests (renamed title)

* more e2e fixes

* skip broken e2e test

---------

Co-authored-by: Asaad Mahmood <asaadmahmood@users.noreply.github.com>
2025-06-16 16:19:33 -04:00
Claudio Costa
4278296d45 Limit Codecov spam (#31582) 2025-06-16 14:04:33 -06:00
Serhii Khomiuk
9564185e75 Translated using Weblate (Ukrainian)
Currently translated at 96.8% (6111 of 6310 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/uk/
2025-06-16 16:53:08 +00:00
master7
a9e4a6012e Translated using Weblate (Polish)
Currently translated at 100.0% (6310 of 6310 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/pl/
2025-06-16 16:53:08 +00:00
master7
3a0ffca814 Translated using Weblate (Polish)
Currently translated at 99.1% (2676 of 2700 strings)

Translation: Mattermost/server
Translate-URL: https://translate.mattermost.com/projects/mattermost/server/pl/
2025-06-16 16:53:08 +00:00
Frank Paul Silye
d4ea86d729 Translated using Weblate (Norwegian Bokmål)
Currently translated at 82.9% (5233 of 6310 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/nb_NO/
2025-06-16 16:53:08 +00:00
master7
fa9256fb32 Translated using Weblate (Polish)
Currently translated at 100.0% (6310 of 6310 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/pl/
2025-06-16 16:53:08 +00:00
Frank Paul Silye
674526183b Translated using Weblate (Norwegian Bokmål)
Currently translated at 82.8% (5225 of 6310 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/nb_NO/
2025-06-16 16:53:08 +00:00
master7
c2a53faa3e Translated using Weblate (Polish)
Currently translated at 99.6% (6290 of 6310 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/pl/
2025-06-16 16:53:08 +00:00
Tom De Moor
3a8cd5c2c0 Translated using Weblate (Dutch)
Currently translated at 99.9% (6307 of 6310 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/nl/
2025-06-16 16:53:08 +00:00
Tom De Moor
b099f2d67b Translated using Weblate (Dutch)
Currently translated at 99.7% (2693 of 2700 strings)

Translation: Mattermost/server
Translate-URL: https://translate.mattermost.com/projects/mattermost/server/nl/
2025-06-16 16:53:08 +00:00
jprusch
1c6b256337 Translated using Weblate (German)
Currently translated at 99.9% (6309 of 6310 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/de/
2025-06-16 16:53:08 +00:00
Devin Binnie
0232a84c1b [MM-63038] Allow Invite Modal to scroll under very small screen sizes (#31397)
* [MM-63038] Allow Invite Modal to scroll under very small screen sizes

* Fix lint
2025-06-16 12:44:41 -04:00
Devin Binnie
3e1a0c8f0d [MM-62988] Add username prop to multi-avatar component (#31398)
* [MM-62988] Add username prop to multi-avatar component

* Fix the file preview avatar as well
2025-06-16 12:44:02 -04:00
Harrison Healey
408f6ec849 MM-64372 Fix onboarding checklist being rendered behind team sidebar (#31365) 2025-06-16 10:27:24 -04:00
catalintomai
ed3a6d6b91 MM-61033: [Shared Channels] Removing a shared channel on one end should make the other remove the shared channel too (#30738) 2025-06-16 16:25:00 +02:00
Devin Binnie
7fad136933 [MM-63048] Add aria-label to the file preview back/forward buttons (#31388) 2025-06-16 09:16:23 -04:00
Matthew Birtch
77e50cf110 MM-61382 Date/Time Picker Input Fix and Refactor (#31330) 2025-06-16 08:01:16 -04:00
Matthew Birtch
6f5c92fc79 MM-64591 Fix contact sales button in banner (#31425) 2025-06-16 08:00:17 -04:00
unified-ci-app[bot]
768caaadda chore: Update NOTICE.txt file with updated dependencies (#31561)
Automatic Merge
2025-06-16 14:46:06 +03:00
catalintomai
1b5a76af55 MM-61437: [Shared Channels] Disable DM button from profile for shared channel user (#30903) 2025-06-16 13:09:09 +02:00
catalintomai
85391de22a MM-57326: [Shared Channels] Message priority, acknowledgement and persistent notifications need to be synced (#30736) 2025-06-16 02:30:21 +02:00
catalintomai
fa1c77d9b0 MM-52600: [Shared Channels] Shared channels do not sync channel membership (#30976) 2025-06-15 10:07:56 +02:00
Jesse Hallam
0082e3e94d enforce License.IsSeatCountEnforced if set (#31354)
* enforce License.IsSeatCountEnforced if set

If a license sets `IsSeatCountEnforced`, enforce the user limit therein
as a hard cap.

Fixes: https://mattermost.atlassian.net/browse/CLD-9260

* remove duplicate tests

* Improve user limit error messages and display

- Add separate error messages for licensed vs unlicensed servers
- Licensed servers: "Server exceeds maximum licensed users. ERROR_LICENSED_USERS_LIMITS"
- Unlicensed servers: "Server exceeds safe user limit. ERROR_SAFETY_LIMITS_EXCEEDED"
- Remove redundant "Contact administrator" text from activation errors shown to admins
- Fix system console to display actual server error messages instead of generic "Failed to activate user"

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

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

* Add license nil check and test coverage

- Add license != nil check in GetServerLimits to prevent panic
- Add test case to verify graceful handling of license being set to nil
- Ensures fallback to hard-coded limits when license becomes nil

Co-authored-by: lieut-data <lieut-data@users.noreply.github.com>

* Fix user limits tests to expect license-specific error IDs

Update test expectations to use the new license-specific error IDs:
- app.user.update_active.license_user_limit.exceeded for licensed server user activation
- api.user.create_user.license_user_limits.exceeded for licensed server user creation

Also update frontend to show actual server error messages instead of generic ones in system console.

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

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

* Remove redundant license nil test

The test couldn't meaningfully verify nil license behavior since it relied on
hard-coded constants that can't be modified in the test.

Co-authored-by: lieut-data <lieut-data@users.noreply.github.com>

* Fix whitespace issue in limits_test.go

Remove unnecessary trailing newline to pass style checks.

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

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

* updated i18n

* s/ERROR_LICENSED_USERS_LIMITS/ERROR_LICENSED_USERS_LIMIT_EXCEEDED/, expand warning log

* Add 5% grace period for licensed user limits

- Add calculateGraceLimit() function with 5% or +1 minimum grace
- Apply grace period only to licensed servers with seat count enforcement
- Handle zero user licenses by returning zero grace limit
- Add comprehensive test coverage for grace period scenarios
- Unlicensed servers maintain existing hard-coded limits without grace

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

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

* Fix TestCreateUserOrGuestSeatCountEnforcement to account for 5% grace period

The test was failing because it expected user creation to fail at exactly
the license limit, but the implementation now includes a 5% grace period
before enforcement kicks in.

Changes:
- Update test cases to create users up to the grace limit (6 for a 5-user license)
- Add comments explaining the grace period calculation
- Both regular user and guest user creation tests now properly validate
  enforcement at the grace limit rather than the base license limit

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

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

* Fix TestUpdateActiveWithUserLimits to account for 5% grace period

Update test expectations to match the new grace period behavior:
- At base limit (100) but below grace limit (105): should succeed
- At grace limit (105): should fail
- Above grace limit (106): should fail

This aligns the tests with the license enforcement implementation
that includes a 5% grace period above the licensed user count.

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

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

---------

Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: claude[bot] <209825114+claude[bot]@users.noreply.github.com>
Co-authored-by: lieut-data <lieut-data@users.noreply.github.com>
Co-authored-by: Mattermost Build <build@mattermost.com>
2025-06-13 17:12:05 -03:00
Stavros Foteinopoulos
f89326574f Add dispatch build (#31363)
Signed-off-by: Stavros Foteinopoulos <stafot@gmail.com>
2025-06-13 19:25:01 +00:00
Daniel Espino García
c1a0710ab5 Fix join private channel (#30875)
* Fix join private channel not showing on all needed scenarios

* Fix for other two instances of the logic

* Fix test

---------

Co-authored-by: Mattermost Build <build@mattermost.com>
2025-06-13 17:42:21 +02:00
catalintomai
c46ed6c681 MM-62751: [Shared Channels] Allow remote users to be discoverable in the create DM/GM modal (#30918) 2025-06-13 16:51:12 +02:00
M-ZubairAhmed
476b46d1d7 [MM-64501] Upgrade to web-vitals v5.0.3 (#31404) 2025-06-13 17:56:16 +05:30
Daniel Espino García
0376bc7cc1 Fix license upload when already set by env variable (#30974)
* Fix license upload when already set by env variable

* Add tooltip

* Fix tests and texts

* Fix snapshots

* Add disabled styles to secondary button

---------

Co-authored-by: Mattermost Build <build@mattermost.com>
2025-06-13 13:07:20 +02:00
Miguel de la Cruz
43018759e5 Adds support for GMs in shared channels (#31403)
* Adds support for GMs in shared channels

* Fix linter

* Remove creatorID from slack call

---------

Co-authored-by: Miguel de la Cruz <miguel@ctrlz.es>
2025-06-13 10:43:30 +00:00
Devin Binnie
07edaa875b [MM-63045] Add root component to read arbitrary text globally, ensure thread menu reads its actions on execution (#31353)
* [MM-63045] Add root component to read arbitrary text globally, ensure thread menu reads its actions on execution

* PR feedback

---------

Co-authored-by: Mattermost Build <build@mattermost.com>
2025-06-12 21:20:45 +00:00
Devin Binnie
926c7f1e49 [MM-61623][MM-61632][MM-61635] Remove min-width for the RHS when window size <400px (#31389)
Co-authored-by: yasserfaraazkhan <attitude3cena.yf@gmail.com>
2025-06-12 16:37:52 -04:00
Devin Binnie
74258c3b7a [MM-64425] Add configurable account deletion link (#31396)
* [MM-64425] Add configurable account deletion link

* Fix types

* PR feedback

---------

Co-authored-by: Mattermost Build <build@mattermost.com>
2025-06-12 11:00:00 -04:00
Devin Binnie
6d7a8c6d72 [MM-63027] Add status region for the channel filter dropdown (#31390)
Co-authored-by: yasserfaraazkhan <attitude3cena.yf@gmail.com>
2025-06-12 10:44:47 -04:00
Jesse Hallam
2ddb8e5d0a Replace SELECT * with explicit column lists in sqlstore (#31356) 2025-06-11 18:16:05 -03:00
Devin Binnie
65d3d5984f [MM-63041] Convert many inputs to the Input component, replace clientError with more correct client-side validation that conforms to the input (#31279)
* [MM-63041] Convert many inputs to the Input component, replace clientError with more correct client-side validation that conforms to the input

* Fix line length

* PR feedback

---------

Co-authored-by: Mattermost Build <build@mattermost.com>
2025-06-11 17:02:32 -04:00
Devin Binnie
e6be282568 [MM-61562] Ensure emoji picker focus returns to button when not selecting an emoji (#31370)
Co-authored-by: Mattermost Build <build@mattermost.com>
2025-06-11 15:58:43 -04:00
Devin Binnie
d41e5184e0 [MM-62987] Fix timestamp not actually being read (#31386) 2025-06-11 15:58:11 -04:00
Devin Binnie
0635c8b3f6 [MM-63057][MM-63003] Set aria-hidden on decorative icons (#31387)
* [MM-63057] Set aria-hidden=true on EditIcon to mark it decorative

* [MM-63003] Mark search lightbulb icon as decorative

* Snaps
2025-06-11 15:57:27 -04:00
Devin Binnie
25a4839a9e Automatic channel category sorting (#30866)
* Automatic channel category sorting

* Fix types

* AIed

* Fix issue where categories are updated for all users

* Move all logic to server, clean up

* PR feedback

* Fix lint

---------

Co-authored-by: Mattermost Build <build@mattermost.com>
2025-06-11 14:29:36 -04:00
M-ZubairAhmed
c6a11763a8 [MM-63799] Fix the high number of detached nodes in post list in dynamic-virtualized-list (#30864) 2025-06-11 22:42:15 +05:30
Devin Binnie
ee5926f03c [MM-62996] Add focusability to react-select remove button in notifications settings (#31238)
* [MM-62996] Fix the readout for react-select instructions on user_settings_notifications

* Update webapp/channels/src/components/user_settings/notifications/user_settings_notifications.tsx

Co-authored-by: Harrison Healey <harrisonmhealey@gmail.com>

---------

Co-authored-by: Mattermost Build <build@mattermost.com>
Co-authored-by: Harrison Healey <harrisonmhealey@gmail.com>
2025-06-11 15:35:28 +00:00
Devin Binnie
c47a84da39 [MM-63046] Have the draft actions labelled by their tooltip (#31369) 2025-06-11 09:27:11 -04:00
Chris Gibson
5e3a89d70c [GH-29960] Change behaviour for log messages that do not have a valid session (#30014)
Co-authored-by: Alejandro García Montoro <alejandro.garciamontoro@gmail.com>
Co-authored-by: Ben Schumacher <ben.schumacher@mattermost.com>
2025-06-11 14:15:40 +02:00
Ibrahim Serdar Acikgoz
fcce46655a Skip flaky test TestUnassignPoliciesFromChannels (#31380) 2025-06-11 12:45:22 +02:00
Rajat Dabade
9fe44bfa6a Updated board prepackaged version to v9.1.3 (#31306)
Automatic Merge
2025-06-11 13:16:06 +03:00
sabril
3230eaf84c e2e(fix): custom status expiry spec (#31358) 2025-06-11 11:27:45 +08:00
sabril
d84f455ba0 e2e(fix): dm category spec (#31359) 2025-06-11 11:24:17 +08:00
sabril
c0ab40d644 e2e(fix): message reaction spec (#31357) 2025-06-11 11:22:58 +08:00
Julien Tant
731bd7c414 MM-63285: Add property field methods to plugin API (#31035)
Co-authored-by: Claude <noreply@anthropic.com>
2025-06-10 16:10:28 -07:00
Harrison Healey
81856f9e7d MM-64544 Fix width of threads textbox at all screen sizes (#31366) 2025-06-10 20:22:16 +00:00
Jesse Hallam
e6d8bf5835 Upgrade Go to 1.24.3 (#31220)
* Upgrade Go to 1.24.3

Updates the following files:
- server/.go-version: 1.23.9 → 1.24.3
- server/build/Dockerfile.buildenv: golang:1.23.9-bullseye → golang:1.24.3-bullseye
- server/go.mod: go 1.23.0 → go 1.24.3, toolchain go1.23.9 → go1.24.3
- server/public/go.mod: go 1.23.0 → go 1.24.3, toolchain go1.23.9 → go1.24.3

Also fixes non-constant format string errors introduced by Go 1.24.3's stricter format string checking:
- Added response() helper function in slashcommands/util.go for simple string responses
- Removed unused responsef() function from slashcommands/util.go
- Replaced responsef() with response() for translated strings that don't need formatting
- Fixed fmt.Errorf and fmt.Fprintf calls to use proper format verbs instead of string concatenation
- Updated marketplace buildURL to handle format strings conditionally

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

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

* Update generated mocks for Go 1.24.3

Regenerated mocks using mockery v2.53.4 to ensure compatibility with Go 1.24.3.
This addresses mock generation failures that occurred with the Go upgrade.

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

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

* Update to bookworm and fix non-existent sha

Signed-off-by: Stavros Foteinopoulos <stafot@gmail.com>

* fix non-constant format string

---------

Signed-off-by: Stavros Foteinopoulos <stafot@gmail.com>
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Stavros Foteinopoulos <stafot@gmail.com>
2025-06-10 15:04:57 -03:00
Harrison Healey
d01d6501f7 MM-63050 Improve screen reader support for SuggestionList (#31228)
* Remove aria-live from SuggestionBox

aria-live isn't the idiomatic way to make the autocomplete accessible to
screen readers. Instead, we should've used aria-activedescendant which
was done for the at-mention autocomplete in a previous ticket, but that
didn't apply to other types of autocompletes. That lead to the
at-mention autocomplete being too noisy (as there were two different
things telling the user what the results were), and it meant that other
types of autocompletes didn't function.

This needs a couple direct followups:
1. The E2E tests need to be updated since they test for aria-live.
2. The Suggestion items for other types of autocompletes need IDs for
   the aria-activedescendant to work.

* Consistently set IDs for all SuggestionList items

Instead of leaving it up to the individual Suggestion components,
this'll ensure that a11y support works for all of them going forward as
long as they properly forward other props to the underlying li element.

I would've preferred if each instance of SuggestionList had unique IDs,
but they currently all use the ID suggestionList, and I didn't want to
update that ID across 55 different Cypress tests. There's should only be
a single SuggestionList visible at a time, so the current situation is
fine enough.

* Remove textboxId from AtMentionProvider

* Change suggestion list to scroll using IDs instead of findDOMNode and refs

* Add an aria-label to SuggestionList

* Make all Suggestion components use the option role

* Add number of results to SuggestionList readout

* Change SuggestionBox to only set aria-expanded with results

* Add tests for ARIA of SuggestionBox

* Address feedback
2025-06-10 12:56:25 -04:00
Harsh Aulakh
09a2037b61 MMCTL: Add import delete cmd for removing the import files (#29764)
Co-authored-by: Ben Schumacher <ben.schumacher@mattermost.com>
2025-06-10 12:06:38 +02:00
Ben Schumacher
0cf6361139 [MM-63578] Fix support packet caching issue (#31133)
Fix support packet caching issue by adding no-cache headers

Added Cache-Control headers to prevent browser caching when downloading support packets.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-06-10 11:39:06 +02:00
Claudio Costa
2fd319b0ac Fix webapp code coverage tracking (#31360) 2025-06-10 08:09:55 +00:00
Claudio Costa
8f74daa9b8 [MM-62409] Fix webapp coverage upload for master runs (#31320)
* Fix webapp coverage upload for master runs

* Only pass codecov token

* Update to trigger workflow
2025-06-10 08:37:04 +02:00
sabril
09146310db fix MM-T5671 (#31352)
Co-authored-by: Mattermost Build <build@mattermost.com>
2025-06-10 12:34:36 +08:00
sabril
5756643256 E2E/Test: Fix smoke tests (#31332)
* add passwd for psql local query and add server/postgres logs for debugging

* set license for smoke tests

* fix fmt
2025-06-10 11:45:29 +08:00
Ben Cooke
aac34f6db4 [MM-64360] Data retention: optionally preserve pinned posts (#31165)
* add new config to preserve pinned posts during data retention

* more graceful error if the pinned post was a reply in a deleted thread
2025-06-09 15:41:07 -04:00
Weblate (bot)
6eb2128abc Translations update from Mattermost Weblate (#31348)
* Translated using Weblate (German)

Currently translated at 100.0% (2700 of 2700 strings)

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

* Translated using Weblate (German)

Currently translated at 100.0% (6352 of 6352 strings)

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

* Translated using Weblate (Polish)

Currently translated at 98.9% (6287 of 6352 strings)

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

* Translated using Weblate (Polish)

Currently translated at 99.2% (6307 of 6352 strings)

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

* Translated using Weblate (Ukrainian)

Currently translated at 97.0% (6162 of 6352 strings)

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

* Translated using Weblate (Polish)

Currently translated at 99.6% (6328 of 6352 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: jprusch <rs@schaeferbarthold.de>
Co-authored-by: master7 <marcin.karkosz@rajska.info>
Co-authored-by: Serhii Khomiuk <sergiy.khomiuk@gmail.com>
2025-06-09 17:34:31 +00:00
Agniva De Sarker
2e23a20899 Improve claude code to run bash commands (#31316)
* Improve claude code to run bash commands

With this limitation removed, it can do more things in a PR.

```release-note
NONE
```

* Update claude.yml

* fix indentation

```release-note
NONE
```
2025-06-09 20:17:25 +05:30
kasyap dharanikota
596053b9af S3store/image type (#30451)
* add video type

* add video mime-type

* combine MIME type maps and update tests

* correct MIME type detection for video files

* format code

* lint fix

* simplified mimeType

* change avi mime type

* add avi type
2025-06-09 09:09:34 +05:30
Christopher Poile
c0f1cbf727 [MM-64296] Help for AI: Respect env overrides for consoleLevel (#31278)
* respect env overrides for consoleLevel; add tests

* clean up test

* merge conflict

* improve parallelizability

* be better commenting

* better name for fn, comment explaining why we're using it

* empty

* empty

* empty

---------

Co-authored-by: Mattermost Build <build@mattermost.com>
2025-06-07 17:35:08 -04:00
Devin Binnie
efc8094bc2 [MM-62992][MM-62994][MM-62995] Profile Settings accessibility fixes (#31236)
* [MM-62995] Add aria-live for Profile Picture upload

* [MM-62992][MM-62994] Add error icon and screen reader text to SettingItemMax

* Fix e2e

* PR feedback
2025-06-06 16:44:19 -04:00
Ben Schumacher
5b389c5224 [MM-63760] Only partially sanitize DB datasources for Support Packet (#30728)
Co-authored-by: Claude <noreply@anthropic.com>
2025-06-06 15:07:54 +02:00
Ben Schumacher
160cb91ab9 Fix error return value in Schedulers.scheduleJob (#31294) 2025-06-06 14:59:31 +02:00
Ben Schumacher
e3452dce94 [MM-29049] Fix remaining errcheck errors in app, api4 and web package (#31307)
Co-authored-by: Claude <noreply@anthropic.com>
2025-06-06 07:44:43 +02:00
Julien Tant
7e013f4c1a Fix cross-team search from: filter not working (#31277)
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Mattermost Build <build@mattermost.com>
2025-06-05 11:53:35 -07:00
Ben Schumacher
924ed4ae02 Fix Support Packet v2 version number (#30723) 2025-06-05 20:07:31 +02:00
Akhil Bisht
4e337b9a43 MM-61450 fix errcheck issue in server/channel/app/permissions_test.go (#31132) 2025-06-05 19:43:40 +02:00
Caleb Roseland
f2aa50170f MM-63705: bump styled-components & luxon (#31030) 2025-06-05 11:35:16 -05:00
Julien Tant
ef67b3bf5f Fix OpenAPI schema for custom profile attributes (#31070) 2025-06-05 16:31:42 +00:00
Devin Binnie
f3d20cfc15 [MM-62999] Fix label in notification settings for notification sound combo box (#31295) 2025-06-05 08:50:37 -04:00
Claudio Costa
65c5f40c6a [MM-62409] Generate and publish code coverage for webapp (#31144)
* Generate and publish code coverage for webapp

* Upate coverage output path

* Simplify coverage patterns

* Disable coverage file search

---------

Co-authored-by: Mattermost Build <build@mattermost.com>
2025-06-05 14:04:27 +02:00
Ben Schumacher
50d81c2a38 Move cluser node specific files it thier own directories in Support Packet (#30755) 2025-06-05 07:58:34 +02:00
Harshil Sharma
2337c580f6 Ignored email from client search (#31057)
* Ignored email from client search

* removed redundent email split

---------

Co-authored-by: Mattermost Build <build@mattermost.com>
2025-06-05 10:05:25 +05:30
Nick Misasi
91862811f5 [CLD-9186] Remove onboarding tasklist, add preview banner (#31203)
* Remove pricing modal. Adjust everywhere to instead open mattermost.com/pricing. When air gapped, don't show buttons to view plans.

* Fix lint

* Further clean up of unused code. Fixes for linter

* Remove onboarding tasklist for previews, add Cloud previer banner

* Fixes for linter, i18n

* Revert dev lines

* Fix lint

* When below one minute, switch to seconds

* fix linter

* fixes for PR feedback

* useExternalLink for opening pricing modal with enriched params

* Fix i17n

* Fix style, tests

* Update webapp/channels/src/components/announcement_bar/cloud_preview_announcement_bar/index.tsx

Co-authored-by: Guillermo Vayá <guillermo.vaya@mattermost.com>

* Fix linter

---------

Co-authored-by: Guillermo Vayá <guillermo.vaya@mattermost.com>
2025-06-04 16:24:58 -04:00
Harrison Healey
93d1ec5f1c Attempt to make ESLint-Webpack integration work in all editors (#31169)
* Attempt to make ESLint-Webpack integration work in all editors

* Reorder imports in Webpack config

This isn't validated by CI, but my local ESLint is complaining.
2025-06-04 20:09:54 +00:00
Harrison Healey
6517fa2fd1 MM-63411 Don't focus thread textbox automatically when it has a draft (#31250)
* MM-63411 Don't focus thread textbox automatically when it has a draft

* Add E2E test

* Add test files forgotten in previous commit

---------

Co-authored-by: Mattermost Build <build@mattermost.com>
2025-06-04 16:08:33 -04:00
Devin Binnie
a19eb5b9ef [MM-62983] Add aria-live region for updating the file preview modal carousel position (#31296) 2025-06-04 08:47:10 -04:00
unified-ci-app[bot]
20e3715f76 Update latest minor version to 10.10.0 (#31304)
Automatic Merge
2025-06-04 09:46:05 +03:00
Matthew Birtch
a87d29fce7 Remove redundant button styles and use proper button classes (#30929)
* remove redundant button styles and use proper button classes

* remove import for contact_us css

* fix view plans button to be xs

* tweak to disabled state on save button in floating bar

* change contact us to tertiary button like before

* updated btn-full on free edition right panel

* update contact button to be primary when shown in the trial card

* fix issue with hover state on save changes panel error state

* fix style lint issues

* update snapshots

* fixed a few license page buttons

* fix lint issue

* Update index.test.tsx.snap

* add empty end lines

* fixed scope of css so it doesn't affect product switcher

* upate button font size for xs, update bg color for button in announce bar

* fix lint error

* update missed cancel buttons to use proper classes

* fixed text spec to find the right button

* updated snapshots

* fix issue with test on cancel button

* update snapshots
2025-06-03 15:37:20 -04:00
Eva Sarafianou
0a7be9f034 Move from ubuntu to distroless image (#31136)
* Move from ubuntu to distroless image

* Update updated ubunty image for first stage

* Update server/build/Dockerfile

Co-authored-by: Daniel Schalla <daniel@mattermost.com>

* Update server/build/Dockerfile

Co-authored-by: Daniel Schalla <daniel@mattermost.com>

* Add mising env var for health check

* Add mattermost user in /etc/passwd

* Fix e2e userId

* use cypress in place of server. Wget and not curl

* Simplify e2e changes

---------

Co-authored-by: Daniel Schalla <daniel@mattermost.com>
2025-06-03 20:52:13 +03:00
Claudio Costa
05585e5388 Update gosaml2 to latest v0.10.0 (#31263) 2025-06-03 11:57:26 +02:00
Ibrahim Serdar Acikgoz
ec75435f3f [MM-64405] continously make syntax check (#31197)
* continously make syntax check

* reflect UX feedback
2025-06-03 11:10:25 +02:00
Miguel de la Cruz
147a5a0bd6 Remove the Beta label from Connected Workspaces (#31275)
Co-authored-by: Miguel de la Cruz <miguel@ctrlz.es>
Co-authored-by: Mattermost Build <build@mattermost.com>
2025-06-03 09:00:53 +00:00
Caleb Roseland
949b45a0f9 bump playbooks 1.41.1 (#31276) 2025-06-02 15:47:32 -05:00
Scott Bishel
ee0361894f MM-60200 Fix for Plugin Dialog with wrong channel ID. (#28122)
* save arguments to state for later usage

* add test

* feat: Add tests for submitInteractiveDialog with channel and thread context

* fix: Add missing properties to DialogSubmission in integration_actions.test.ts

* feat: Add channel_id to DialogSubmission objects in test file

* refactor: Move selectedThreadIdInTeam to views.threads state

* add channel id to state

* add unit test

* add unit test

* update submitInteractiveDialog

* update tests for changes

* remove log line

* refactor: Enhance submitInteractiveDialog proxy action with improved error handling

* add userID to submit data to plugin

* remove log message

* remove unnecessary default state

* lint fixes

* update unit test

* fixes from code review

* fixes from code review

* fixes from code review

* fix test, add userID to expected

---------

Co-authored-by: Mattermost Build <build@mattermost.com>
Co-authored-by: Caleb Roseland <caleb@calebroseland.com>
2025-06-02 13:12:12 -06:00
Nick Misasi
0cacee570a Remove in-product pricing modal (#31187)
* Remove pricing modal. Adjust everywhere to instead open mattermost.com/pricing. When air gapped, don't show buttons to view plans.

* Fix lint

* Further clean up of unused code. Fixes for linter

* fixes for PR feedback

* useExternalLink for opening pricing modal with enriched params

* Fix i17n

* Fix style, tests
2025-06-02 14:08:57 -04:00
Hosted Weblate
6484ae25b7 Update translation files
Updated by "Cleanup translation files" hook in Weblate.

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/
2025-06-02 17:43:53 +02:00
master7
e415157e39 Translated using Weblate (Polish)
Currently translated at 99.3% (6287 of 6329 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/pl/
2025-06-02 17:43:53 +02:00
Tom De Moor
0eab63ecfe Translated using Weblate (Dutch)
Currently translated at 99.9% (6326 of 6329 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/nl/
2025-06-02 17:43:53 +02:00
Tom De Moor
589085b1a4 Translated using Weblate (Dutch)
Currently translated at 99.7% (2686 of 2693 strings)

Translation: Mattermost/server
Translate-URL: https://translate.mattermost.com/projects/mattermost/server/nl/
2025-06-02 17:43:53 +02:00
Serhii Khomiuk
8f77f4d206 Translated using Weblate (Ukrainian)
Currently translated at 97.0% (6143 of 6329 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/uk/
2025-06-02 17:43:53 +02:00
Frank Paul Silye
f1202ef83b Translated using Weblate (Norwegian Bokmål)
Currently translated at 83.2% (5271 of 6329 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/nb_NO/
2025-06-02 17:43:53 +02:00
Frank Paul Silye
bf57f4a8af Translated using Weblate (Norwegian Bokmål)
Currently translated at 4.1% (113 of 2693 strings)

Translation: Mattermost/server
Translate-URL: https://translate.mattermost.com/projects/mattermost/server/nb_NO/
2025-06-02 17:43:53 +02:00
Tom De Moor
5c28507763 Translated using Weblate (Dutch)
Currently translated at 99.6% (6308 of 6329 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/nl/
2025-06-02 17:43:53 +02:00
Sharuru
e04f456093 Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 100.0% (6329 of 6329 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/zh_Hans/
2025-06-02 17:43:53 +02:00
Sharuru
2a753a6d82 Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 100.0% (2693 of 2693 strings)

Translation: Mattermost/server
Translate-URL: https://translate.mattermost.com/projects/mattermost/server/zh_Hans/
2025-06-02 17:43:53 +02:00
MArtin Johnson
86aada4cb0 Translated using Weblate (Swedish)
Currently translated at 99.9% (6328 of 6329 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/sv/
2025-06-02 17:43:53 +02:00
MArtin Johnson
d3f3a203e4 Translated using Weblate (Swedish)
Currently translated at 99.8% (2689 of 2693 strings)

Translation: Mattermost/server
Translate-URL: https://translate.mattermost.com/projects/mattermost/server/sv/
2025-06-02 17:43:53 +02:00
master7
f700236987 Translated using Weblate (Polish)
Currently translated at 99.1% (6277 of 6329 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/pl/
2025-06-02 17:43:53 +02:00
Manuela Silva
adf9187d6d Translated using Weblate (Portuguese)
Currently translated at 1.9% (125 of 6329 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/pt/
2025-06-02 17:43:53 +02:00
master7
0b9ed462a6 Translated using Weblate (Polish)
Currently translated at 99.0% (6266 of 6329 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/pl/
2025-06-02 17:43:53 +02:00
MArtin Johnson
4c0d46e186 Translated using Weblate (Swedish)
Currently translated at 99.0% (2668 of 2693 strings)

Translation: Mattermost/server
Translate-URL: https://translate.mattermost.com/projects/mattermost/server/sv/
2025-06-02 17:43:53 +02:00
Martin Mičuda
769a5b0495 Translated using Weblate (Czech)
Currently translated at 95.8% (6064 of 6329 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/cs/
2025-06-02 17:43:53 +02:00
master7
7de1b757e2 Translated using Weblate (Polish)
Currently translated at 98.6% (6246 of 6329 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/pl/
2025-06-02 17:43:53 +02:00
jprusch
dc58edf56a Translated using Weblate (German)
Currently translated at 100.0% (6329 of 6329 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/de/
2025-06-02 17:43:53 +02:00
jprusch
1ba1a54111 Translated using Weblate (German)
Currently translated at 100.0% (2693 of 2693 strings)

Translation: Mattermost/server
Translate-URL: https://translate.mattermost.com/projects/mattermost/server/de/
2025-06-02 17:43:53 +02:00
Ibrahim Serdar Acikgoz
5c54c8fefe Enable Attribte Based Access Control FF by default (#31269) 2025-06-02 15:40:28 +02:00
Miguel de la Cruz
c6c27e7752 Adds a feature flag and the logic to hide plugin interactions on shared channels (#31185)
* Adds a feature flag and the logic to hide plugin interactions on shared channels

* Address review comments

* Fix CI

* Address review comments

* Address review comments

---------

Co-authored-by: Miguel de la Cruz <miguel@ctrlz.es>
Co-authored-by: Mattermost Build <build@mattermost.com>
2025-06-02 12:59:19 +00:00
Uday Rana
58d6c71ed2 [MM-53650] Add disable emoticon rendering setting to webapp (#29414)
* add renderEmoticonsAsEmoji to post_markdown

* add renderEmoticonsAsEmoji to preferences, config

* add EnableRenderEmoticonsAsEmoji to GenerateClientConfig

* add EnableRenderEmoticonsAsEmoji to TeamSettings

* create renderEmoticonsAsEmoji component

* update translation file

* update tests

* add tests for RenderEmoticonsAsEmoji

* remove unused prop

* remove unused variables

* add test cases for undefined/false values for renderemoticonsasemoji

* switch strings from backticks to single quotes

* Update webapp/channels/src/components/user_settings/display/render_emoticons_as_emoji/render_emoticons_as_emoji.tsx

Co-authored-by: Harrison Healey <harrisonmhealey@gmail.com>

* Update webapp/channels/src/components/user_settings/display/render_emoticons_as_emoji/render_emoticons_as_emoji.tsx

Co-authored-by: Harrison Healey <harrisonmhealey@gmail.com>

* Update webapp/channels/src/components/user_settings/display/render_emoticons_as_emoji/render_emoticons_as_emoji.tsx

Co-authored-by: Harrison Healey <harrisonmhealey@gmail.com>

* Update webapp/channels/src/utils/emoticons.tsx

Co-authored-by: Harrison Healey <harrisonmhealey@gmail.com>

* remove server setting

* remove usestate

* update i18n

* remove config setting

* fix broken test

* fix focus edit button logic

* update tests for when render emoticons option is undefined

* remove config usage from selectors

* update setting display text

* remove 'automatically' from setting description

* use default from preferences instead of hardcoded true

* update component snapshot

* remove renderemoticonsasemoji = true from emoticons tests

* Apply suggestions from code review

* Switch from useEffect to useDidUpdate

* Run fix-style

* Add RenderEmoticonsAsEmoji component to test spec

* Rewrite RenderEmoticonsAsEmoji to mirror ManageTimezones and ManageLanguages

* Update UserSettingsDisplay snapshot

* Switch test to renderWithContext, update props

* Move options into const objects

* Wrap functions in useCallback

---------

Co-authored-by: Harrison Healey <harrisonmhealey@gmail.com>
Co-authored-by: Mattermost Build <build@mattermost.com>
2025-06-02 14:35:27 +02:00
unified-ci-app[bot]
ccddb63abb chore: Update NOTICE.txt file with updated dependencies (#31264)
Automatic Merge
2025-06-02 14:00:09 +03:00
Claudio Costa
d2292a13d2 Bump shared db pool size in store for parallel tests (#31262) 2025-06-02 09:59:21 +02:00
Ibrahim Serdar Acikgoz
a457d3b73c [MM-64367] Update property/attribute naming convetion (#31168)
Automatic Merge
2025-06-02 10:00:09 +03:00
Eva Sarafianou
c90dfa4895 Move to library archives (#31100)
* Move to library archives

* wrap the error with %w

Co-authored-by: Jesse Hallam <jesse.hallam@gmail.com>

* remove redundant format

---------

Co-authored-by: Jesse Hallam <jesse.hallam@gmail.com>
2025-06-02 09:21:37 +03:00
Sven Hüster
655d6f3fc7 [MM-63944] fix channel header color (#30899)
Automatic Merge
2025-06-02 09:00:09 +03:00
Ibrahim Serdar Acikgoz
6f26ad5cec [ABAC - Table Editor] Improvements on table editor and review feedback (#31125)
* reflect review comments

* update table editor

* adjust test limits

* reflect review comments

* MM-64376

* resolve conflicts

* address review comments

* fix merge conflict error
2025-06-01 12:05:57 +02:00
Jesse Hallam
489ea1fdd6 Remove SELECT * from product notices store (#31246)
* Remove SELECT * from product notices store

Replace wildcard selects with explicit column names and use SelectBuilder pattern for consistency with other stores.

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

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

* Update server/channels/store/sqlstore/product_notices_store.go

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

---------

Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-05-31 14:53:42 +05:30
Ibrahim Serdar Acikgoz
35e06a2ee8 [MM-64422] Update icons for CEL Table Editor (#31213) 2025-05-30 22:39:24 +02:00
Joram Wilander
2bba6ff4a7 Add Claude PR Assistant workflow (#31251) 2025-05-30 19:47:59 +00:00
Joram Wilander
0cc906d07e Update README first line to match new use cases (#31247)
* Update README first line to match new use cases

* Update README.md

Co-authored-by: Jesse Hallam <jesse.hallam@gmail.com>

---------

Co-authored-by: Carrie Warner (Mattermost) <74422101+cwarnermm@users.noreply.github.com>
Co-authored-by: Jesse Hallam <jesse.hallam@gmail.com>
2025-05-30 19:28:37 +00:00
Jesse Hallam
86a2368fe0 avoid SELECT * in channel_store_categories.go (#31245) 2025-05-30 14:14:17 -05:00
Ibrahim Serdar Acikgoz
2cf345dd5c removed channels will disappear from channel list in policy edit (#31140) 2025-05-30 18:59:59 +02:00
Claudio Costa
93aad1d1f0 Disable -race mode when running fully parallel tests (#31243) 2025-05-30 18:20:07 +02:00
Jesse Hallam
b7012952c4 MM-62158: Final migration for GetMemberUsersNotInChannel and GetMemberUsersInTeam (#31237)
* upgrade mattermost/squirrel

* migrate GetMemberUsersInTeam

* migrate GetMemberUsersNotInChannel
2025-05-30 16:20:05 +00:00
Jesse Hallam
e04f487cb8 adopt golangci-lint v2 (#31222)
* adopt golangci-lint v2

No actual linting changes in this commit, just upgraded tooling and
directives to ignore new linter rules. Adopting v2 solves some
gosec issues in v1 and also happens to be a nice performance boost!
As part of this PR, we also drop support for `MM_NO_ENTERPRISE_LINT`
which hasn't been need for a while anyway.

* simplify: go install is fine!

* missing GOBIN

* golangci-lint: drop legacy preset exclusion
2025-05-30 15:31:30 +00:00
David Krauser
761584c040 [MM-64244] Add websocket disconnect reason metric (#31032)
We've recently spent some effort improving websocket reconnection logic. With this commit, I've augmented the websocket reconnect metric to include a disconnect reason. This will help us measure the impact of these changes in production.
2025-05-30 08:15:20 -04:00
Claudio Costa
611b2a8e79 [MM-62408] Server Code Coverage with Fully Parallel Tests (#30078)
* TestPool

* Store infra

* Store tests updates

* Bump maximum concurrent postgres connections

* More infra

* channels/jobs

* channels/app

* channels/api4

* Protect i18n from concurrent access

* Replace some use of os.Setenv

* Remove debug

* Lint fixes

* Fix more linting

* Fix test

* Remove use of Setenv in drafts tests

* Fix flaky TestWebHubCloseConnOnDBFail

* Fix merge

* [MM-62408] Add CI job to generate test coverage (#30284)

* Add CI job to generate test coverage

* Remove use of Setenv in drafts tests

* Fix flaky TestWebHubCloseConnOnDBFail

* Fix more Setenv usage

* Fix more potential flakyness

* Remove parallelism from flaky test

* Remove conflicting env var

* Fix

* Disable parallelism

* Test atomic covermode

* Disable parallelism

* Enable parallelism

* Add upload coverage step

* Fix codecov.yml

* Add codecov.yml

* Remove redundant workspace field

* Add Parallel() util methods and refactor

* Fix formatting

* More formatting fixes

* Fix reporting
2025-05-30 13:58:26 +02:00
Ibrahim Serdar Acikgoz
1cf2f08108 [MM-64437] Hotfix on attribute view creation error (#31225) 2025-05-30 11:35:31 +02:00
Harshil Sharma
c9006b55e1 Fixed width of edit scheduled post UI (#31196) 2025-05-30 10:20:29 +05:30
Devin Binnie
e1c0c57d31 [MM-63933] Don't include channels from an archived team unless specified in GetChannelsForUser (#31163)
* [MM-63933] Don't include channels from an archived team unless specified in GetChannelsForUser

* PR feedback

---------

Co-authored-by: Mattermost Build <build@mattermost.com>
2025-05-29 13:35:38 +00:00
Daniel Espino García
293f38ad0b Ensure users status is set to offline when deactivated (#30900) 2025-05-29 10:41:14 +02:00
Agniva De Sarker
79bf1c34db MM-63217: Bump dependencies (#31021)
* MM-63217: Bump dependencies

Skip-Enterprise-PR: true

https://mattermost.atlassian.net/browse/MM-63217

```release-note
NONE
```

* fix go.mod

```release-note
NONE
```

* fix test

```release-note
NONE
```
2025-05-29 13:08:00 +05:30
Ibrahim Serdar Acikgoz
81d3273bc7 error when policy toggled but not selected (#31200) 2025-05-29 08:13:03 +02:00
Claudio Costa
d38c27f96f [MM-64402] Improve validation of imported attachments (#31201)
* Improve validation of imported attachments

* Simplify multiple errors handling

* Improve logic

* Fix abs paths in tests

* Remove redundant clean

* Implement additional validation

* Fix absolute paths in test

* Add additional tests

---------

Co-authored-by: Lorenzo Gallegos <1328683+enzowritescode@users.noreply.github.com>
2025-05-29 07:44:50 +02:00
Harrison Healey
07239a5217 MM-64316 Fix icon_emoji not working on webhook posts (#31068)
* MM-64316 Fix icon_emoji not working on webhook posts

* Add test case for custom emojis

* Remove unneeded test cleanup

---------

Co-authored-by: Mattermost Build <build@mattermost.com>
2025-05-28 22:54:06 +00:00
Pablo Vélez
e52e285ba6 MM-64378 - disable channel settings menu option for users with no permissions (#31178) 2025-05-29 00:27:01 +02:00
Jesse Hallam
332be84efd Revert "MM-63648 - markdown images sometimes do not show the more button (#30716)" (#31224)
This reverts commit 20f9f58e4c.
2025-05-28 21:53:34 +00:00
Jesse Hallam
7a61d498ea MM-64438: skip flaky: testGetNthRecentPostTime (#31223) 2025-05-28 17:47:43 -03:00
Daniel Espino García
6fc60583eb Fix dialog dropdown being cut-off (#30881)
* Fix dialog dropdown being cut-off

* Fix dropdown e2e tests

---------

Co-authored-by: Mattermost Build <build@mattermost.com>
2025-05-28 13:05:33 +02:00
catalintomai
62bd9d917d MM-62745: [Shared Channels] Fix duplicate mentioning - local user with the same username as someone on the remote server (#30734)
* initial checkin

* i18n/en.json

* fix e2e test

* fix Makefile

* initial checkin

* fix logic

* fix spacing

* simplify

* further simplify

* address spec update

* remove removeMention

* simplify code

* simplify code(2)

* simplify code(3)

* simplify code(4)

* update comment

* simplify comments

* remove useless test

---------

Co-authored-by: Catalin Tomai <catalintomai@catalins-macbook-pro-2.home>
2025-05-27 13:18:41 +00:00
catalintomai
e6ed3436fb MM-54023: [Shared Channels] Filter out system posts for channel update info that is not synced (#30735)
* initial checkin

* simplify tests, logic

* fix tests

* remove unneeded test

* fix spacing

* updates

* update logic

* fix logic

* move filtering to DB

* remove comment

---------

Co-authored-by: Catalin Tomai <catalintomai@catalins-macbook-pro-2.home>
2025-05-27 13:15:49 +00:00
Matthew Birtch
b6401d9042 MM-63950 replace --denim- variables (#30925) 2025-05-27 07:55:37 -04:00
Miguel de la Cruz
fbf105f6ef Improves the invite mechanism for remote clusters (#31025)
Co-authored-by: Miguel de la Cruz <miguel@ctrlz.es>
2025-05-27 13:39:13 +02:00
Miguel de la Cruz
e51ea025db Deletes CPA values on CPA field type change (#31122)
* Deletes CPA values on CPA field type change

* Fix error method name reference

* Cleans the state when a CPA field's type is updated

* Fix types

* Fix linter

* Webapp no longer makes a decision on the change and server sents a flag in the WS message

* Fix linter

---------

Co-authored-by: Miguel de la Cruz <miguel@ctrlz.es>
2025-05-27 13:38:05 +02:00
Miguel de la Cruz
b3649132d0 Sets the Custom Profile Attributes feature flag to true by default (#31160)
Co-authored-by: Miguel de la Cruz <miguel@ctrlz.es>
2025-05-27 13:35:02 +02:00
Agniva De Sarker
3d5cf06237 [AI assisted] MM-62927: add comprehensive whitespace validation tests for FileSettings paths (#31087)
https://mattermost.atlassian.net/browse/MM-62927

```release-note
NONE
```
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Mattermost Build <build@mattermost.com>
2025-05-27 10:03:12 +05:30
Matthew Birtch
649b939e6a MM-63898 Improve Blockquote Style (#31008)
* quote style exploration

* style tweak

* updated quote style

* Update _markdown.scss

* update value to match css

* fix linter issue

* changed reply bar to button-bg

* tweaks to compact mode

* a few more minor tweaks to spacing for compact mode and in edit preview mode

* fix lint issue

* add comment back in

* move to proper if statement for theme util
2025-05-26 22:20:42 -04:00
Maria A Nunez
5b28ddadb9 Accessibility: Add header tags missing in title sections (#30776)
* Fixed missing header in create account

* Fixed modal header

* Fixed header for suggestionList for autocomplete popup

* Fixed heading for search hints title

* Fixed header tag in search suggestion header

* Fixed header tag in RHS title

* Fixed header in RHS search results title

* Fixed header for RHS CHannel Info title

* Linting

* Fix tests

* Styling fix

* Linting

* PR Feedback

* Fixed tests

* Moved subtitle into h2

* Fix tests from merge

* Linting

* Fix snapshots

* Updated playwright tests snapshots

---------

Co-authored-by: Mattermost Build <build@mattermost.com>
2025-05-26 20:53:04 -04:00
Harrison Healey
1e0621252f Explicitly list exports from mattermost-redux (#31176) 2025-05-26 15:17:17 -04:00
Jesse Hallam
70a42ffd5f Reject mysql for enterprise advanced (#31164)
* reject MySQL with the enterprise advanced license

If a user attempts to set an Enterprise Advanced License while
configured with MySQL, reject the license. This SKU is not compatible
with MYSQL.

* fix trial typo

* suppress trial banner if MySQL

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

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

* fix types

* suppress mysql from show start trial modal

* Skip MySQL-incompatible tests for access control and channel banner features

Skip the following tests when running with MySQL database:
- Access control policy tests (create, get, delete, check/test expressions, search, assign/unassign, get channels)
- Channel banner tests in TestPatchChannel and TestCanEditChannelBanner

These features are not supported on MySQL and the tests would fail.
Tests will continue to run normally on PostgreSQL.

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

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

* Skip TestSearchChannelsForAccessControlPolicy subtest for MySQL

Add MySQL skip logic to the "SearchChannelsForAccessControlPolicy with regular user"
subtest as this access control feature is not supported on MySQL.

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

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

* reject trial license requests for MySQL

* return false on sku + mysql match, even if logger is nil

* Fix MySQL trial license tests to skip appropriately based on database driver

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

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

---------

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Claude <noreply@anthropic.com>
2025-05-26 15:44:32 -03:00
Hosted Weblate
f2bb82bc01 Update translation files
Updated by "Cleanup translation files" hook in Weblate.

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/
2025-05-26 20:38:25 +02:00
Frank Paul Silye
ebc9523cc4 Translated using Weblate (Norwegian Bokmål)
Currently translated at 83.4% (5268 of 6312 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/nb_NO/
2025-05-26 20:38:25 +02:00
ThrRip
68f8ff320a Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 100.0% (6312 of 6312 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/zh_Hans/
2025-05-26 20:38:25 +02:00
MArtin Johnson
34a4785ace Translated using Weblate (Swedish)
Currently translated at 99.4% (6275 of 6312 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/sv/
2025-05-26 20:38:25 +02:00
master7
e33f045199 Translated using Weblate (Polish)
Currently translated at 98.9% (6244 of 6312 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/pl/
2025-05-26 20:38:25 +02:00
ThrRip
a0492be56f Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 100.0% (2688 of 2688 strings)

Translation: Mattermost/server
Translate-URL: https://translate.mattermost.com/projects/mattermost/server/zh_Hans/
2025-05-26 20:38:25 +02:00
MArtin Johnson
f8d752f14b Translated using Weblate (Swedish)
Currently translated at 99.2% (2667 of 2688 strings)

Translation: Mattermost/server
Translate-URL: https://translate.mattermost.com/projects/mattermost/server/sv/
2025-05-26 20:38:25 +02:00
Frank Paul Silye
7e6d80c135 Translated using Weblate (Norwegian Bokmål)
Currently translated at 83.4% (5266 of 6312 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/nb_NO/
2025-05-26 20:38:25 +02:00
Frank Paul Silye
9c6f60aef1 Translated using Weblate (Norwegian Bokmål)
Currently translated at 83.3% (5263 of 6312 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/nb_NO/
2025-05-26 20:38:25 +02:00
Tom De Moor
ce7ae75a5e Translated using Weblate (Dutch)
Currently translated at 99.9% (6309 of 6312 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/nl/
2025-05-26 20:38:25 +02:00
Tom De Moor
e393ecacd7 Translated using Weblate (Dutch)
Currently translated at 99.7% (2681 of 2688 strings)

Translation: Mattermost/server
Translate-URL: https://translate.mattermost.com/projects/mattermost/server/nl/
2025-05-26 20:38:25 +02:00
Frank Paul Silye
47b813e0b7 Translated using Weblate (Norwegian Bokmål)
Currently translated at 82.3% (5197 of 6312 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/nb_NO/
2025-05-26 20:38:25 +02:00
Manuela Silva
d933b4fb48 Translated using Weblate (Portuguese)
Currently translated at 1.3% (84 of 6312 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/pt/
2025-05-26 20:38:25 +02:00
MArtin Johnson
686ffebc71 Translated using Weblate (Swedish)
Currently translated at 97.9% (6180 of 6312 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/sv/
2025-05-26 20:38:25 +02:00
Joaquim Homrighausen
7508941452 Translated using Weblate (Swedish)
Currently translated at 97.9% (6180 of 6312 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/sv/
2025-05-26 20:38:25 +02:00
MArtin Johnson
7fe4072be4 Translated using Weblate (Swedish)
Currently translated at 97.5% (6159 of 6312 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/sv/
2025-05-26 20:38:25 +02:00
Joaquim Homrighausen
f0ff87a17e Translated using Weblate (Swedish)
Currently translated at 97.5% (6159 of 6312 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/sv/
2025-05-26 20:38:25 +02:00
Joaquim Homrighausen
90077a6438 Translated using Weblate (Swedish)
Currently translated at 97.5% (6159 of 6312 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/sv/
2025-05-26 20:38:25 +02:00
MArtin Johnson
484176c4d2 Translated using Weblate (Swedish)
Currently translated at 97.5% (6159 of 6312 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/sv/
2025-05-26 20:38:25 +02:00
Joaquim Homrighausen
1324896414 Translated using Weblate (Swedish)
Currently translated at 97.5% (6159 of 6312 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/sv/
2025-05-26 20:38:25 +02:00
MArtin Johnson
a4327b6a9b Translated using Weblate (Swedish)
Currently translated at 97.5% (6159 of 6312 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/sv/
2025-05-26 20:38:25 +02:00
MArtin Johnson
3c46607591 Translated using Weblate (Swedish)
Currently translated at 97.5% (6159 of 6312 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/sv/
2025-05-26 20:38:25 +02:00
Joaquim Homrighausen
ec0503d74f Translated using Weblate (Swedish)
Currently translated at 97.5% (6159 of 6312 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/sv/
2025-05-26 20:38:25 +02:00
Joaquim Homrighausen
abc0d5d516 Translated using Weblate (Swedish)
Currently translated at 97.5% (6159 of 6312 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/sv/
2025-05-26 20:38:25 +02:00
MArtin Johnson
a4805de2e8 Translated using Weblate (Swedish)
Currently translated at 97.5% (6159 of 6312 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/sv/
2025-05-26 20:38:25 +02:00
Joaquim Homrighausen
0c0d31f479 Translated using Weblate (Swedish)
Currently translated at 97.5% (6159 of 6312 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/sv/
2025-05-26 20:38:25 +02:00
MArtin Johnson
794c0cf364 Translated using Weblate (Swedish)
Currently translated at 97.5% (6159 of 6312 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/sv/
2025-05-26 20:38:25 +02:00
MArtin Johnson
b9a95d69b2 Translated using Weblate (Swedish)
Currently translated at 98.8% (2658 of 2688 strings)

Translation: Mattermost/server
Translate-URL: https://translate.mattermost.com/projects/mattermost/server/sv/
2025-05-26 20:38:25 +02:00
MArtin Johnson
26f26fe66b Translated using Weblate (Swedish)
Currently translated at 98.8% (2657 of 2688 strings)

Translation: Mattermost/server
Translate-URL: https://translate.mattermost.com/projects/mattermost/server/sv/
2025-05-26 20:38:25 +02:00
Frank Paul Silye
e899ee5559 Translated using Weblate (Norwegian Bokmål)
Currently translated at 81.9% (5173 of 6312 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/nb_NO/
2025-05-26 20:38:25 +02:00
master7
1d7bac7bf7 Translated using Weblate (Polish)
Currently translated at 98.7% (6230 of 6312 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/pl/
2025-05-26 20:38:25 +02:00
Frank Paul Silye
6000873e4c Translated using Weblate (Norwegian Bokmål)
Currently translated at 81.8% (5164 of 6312 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/nb_NO/
2025-05-26 20:38:25 +02:00
Frank Paul Silye
ead521735a Translated using Weblate (Norwegian Bokmål)
Currently translated at 81.7% (5159 of 6312 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/nb_NO/
2025-05-26 20:38:25 +02:00
Frank Paul Silye
0a0690b4a0 Translated using Weblate (Norwegian Bokmål)
Currently translated at 81.4% (5140 of 6312 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/nb_NO/
2025-05-26 20:38:25 +02:00
Frank Paul Silye
781a897b75 Translated using Weblate (Norwegian Bokmål)
Currently translated at 81.4% (5139 of 6312 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/nb_NO/
2025-05-26 20:38:25 +02:00
Frank Paul Silye
f155094d8e Translated using Weblate (Norwegian Bokmål)
Currently translated at 80.4% (5079 of 6312 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/nb_NO/
2025-05-26 20:38:25 +02:00
master7
b483cd87cb Translated using Weblate (Polish)
Currently translated at 98.5% (6219 of 6312 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/pl/
2025-05-26 20:38:25 +02:00
jprusch
2eaa2dd6a7 Translated using Weblate (German)
Currently translated at 100.0% (6312 of 6312 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/de/
2025-05-26 20:38:25 +02:00
jprusch
b92f994d5a Translated using Weblate (German)
Currently translated at 100.0% (2688 of 2688 strings)

Translation: Mattermost/server
Translate-URL: https://translate.mattermost.com/projects/mattermost/server/de/
2025-05-26 20:38:25 +02:00
Ben Cooke
a461aa3ffb [MM-63638] Don't set auto add to false when changing the schema of a syncable (#30629)
* dont set auto add to false when chaning the schema of a syncable
2025-05-26 12:02:03 -04:00
Harrison Healey
00af66459a Enforce EOL newlines in CSS files (#31174) 2025-05-26 11:47:13 -04:00
yasser khan
1389f12daa Add playwright HTML report to the status check (#30952) 2025-05-26 19:22:47 +05:30
Caleb Roseland
db27d1edec MM-63907, MM-63906: Smooth navigation between User Properties and LDAP/SAML pages. (#31127) 2025-05-23 16:26:31 -05:00
Devin Binnie
2358699d91 MM-64030/MM-64025/MM-63985/MM-63986/MM-63987/MM-63976/MM-64018/MM-64017/MM-64034/MM-64029 - Various accessibility fixes around User Groups modals (#31147)
* Convert user groups main modal to GenericModal, convert menu to Menu component, fixes

* Added useFocusTrap on other modals, fix DOM ordering

* [MM-64018] Add proper aria-labels to the menu button

* [MM-64025] Convert user group button to an actual button

* [MM-64017] Fixed aria-label on 3-dot menu in view user group modal

* [MM-64030] Show aria-live region when search results are rendered

* Fix tests

* PR feedback

* PR feedback
2025-05-23 20:09:06 +00:00
Sven Hüster
583eb3f62c fixed the url styling for webhooks to now use pure html instead of ma… (#30845)
* fixed the url styling for webhooks to now use pure html instead of markdown

* remove code styling from outgoing webhook token

* updated test snapshots

* added code styling to more integrations tokens

* update snapshots

* fixed translation strings for english and german
2025-05-23 13:36:53 -04:00
Felipe Martin
a09bee609a feat: support SSO while embedded (#31002)
* feat: send a message to the parent window if embeddd

* feat: handle embedded sso flows

* fix: use new `isEmbedded` logic

* fix: postMessage targetOrigin

---------

Co-authored-by: Mattermost Build <build@mattermost.com>
2025-05-23 18:18:05 +02:00
Harrison Healey
e02e1aab10 Remove unused invalid CSS (#31145) 2025-05-22 21:01:35 +00:00
Devin Binnie
8f13cda09c [MM-64255] Fix height of automatic replies textarea (#31148) 2025-05-22 16:19:58 -04:00
sabril
f710512e3e separate visual tests from main test, update snapshots and dependencies (#31131) 2025-05-22 23:21:23 +08:00
M-ZubairAhmed
f800025a43 [MM-63884] Move DynamicVirtualizedList to monorepo (#30851) 2025-05-22 11:27:24 +05:30
Ben Cooke
bfe90c3704 New pluginapi method for syncables (#30790)
* new pluginapi method for syncables
---------
Co-authored-by: Mattermost Build <build@mattermost.com>
2025-05-21 14:44:34 -04:00
Jesse Hallam
c42d17b308 Fix notification message for posts with no text content (#31007)
* Fix notification message for posts with no text

Changed the default notification message from "did something new" to
"posted a message" for better clarity when receiving notifications
from posts with no readable text content.

Fixes: MM-61948

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

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

* address feedback from code review

---------

Co-authored-by: Claude <noreply@anthropic.com>
2025-05-21 18:32:40 +00:00
Jesse Hallam
31a8047973 Disable morph logging during TestMain (#30948)
* rm "No TEST_DATABASE... override" log message

Let's only log if this value is actually overridden.

* rm "(Created|Dropped) temporary database" message

* only log "Pinging SQL" on subsequent attempts

* disable morph logging from TestMain

* Fix style issues in store test files

- Add missing parameter to migrate() function calls in tests
- Remove unused log function in settings.go
- Fix formatting with go fmt

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

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

* within sqlstore, use "enable" vs "disable" for clarity

* remove trailing newline from morph logs

---------

Co-authored-by: Claude <noreply@anthropic.com>
2025-05-21 17:31:18 +00:00
Jesse Hallam
92db356484 MM-62158: group store no select star, part3 (#30927)
* migrate getGroupsAssociatedToChannelsByTeam

* migrate GetGroups

* migrate teamMembersMinusGroupMembersQuery

* migrate channelMembersMinusGroupMembersQuery
2025-05-21 14:19:38 -03:00
Ben Schumacher
6de3379994 [MM-61099] Fix errcheck issues in server/channels/app/brand.go (#30679)
* [MM-28779] Fix errcheck issues in server/channels/app/brand.go

Remove brand.go from the errcheck exclusion list in .golangci.yml and fixed the error by properly handling the return value from a.MoveFile().

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

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

* [MM-28779] Add test to verify brand image backup functionality

Add a new test that verifies backup of the original brand image happens when a new one is uploaded. This helps to ensure the fix for errcheck issues is working as expected.

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

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

* use seperate temporary filestore for each test

* Use FileSettings.Directory instead of finding the dir programatically

* Fix another test

* Fix defer

* Update server/channels/api4/job_test.go

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

* Fix bad bot commit

* Cleanup logs message

* cleanup file path

* Fix error variable names

* WIP:cleanup panic ussage

* Revert "WIP:cleanup panic ussage"

This reverts commit c3284e4427a41c818acc161926cd2535dee9a6b9.

* cleanup error checks

---------

Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Mattermost Build <build@mattermost.com>
2025-05-21 16:35:00 +02:00
sabril
1cb244e876 remove cypress tests of playbooks (#31128) 2025-05-21 16:37:01 +08:00
Claudio Costa
56c6d8a9ab Prepackage Calls v1.8.0 (#31124) 2025-05-21 09:21:39 +02:00
Agniva De Sarker
09ea32a03c MM-63300: Fix flaky test TestBusySet (#31116)
(*Busy).Set would set its own timer, and additionally
send a message across the cluster. In this case, the cluster
is mocked locally. But the timer calculation happens again.

We marshal the expiry time with b.expires.Unix() and send that
as part of model.ServerBusyState. This is parsed again in
ClusterEventChanged and converted to duration with time.Until.

Therefore, if it takes longer for the code to reach those lines,
then the new time calculated would have already expired, failing
the test.

To fix this, we increase the timeout. This slows down the test
at the cost of extra reliability. This is a common failure point
with any timer related tests.

Additionally, we also change the condition in compareBusyState
to check for less-than rather than strict equality.

https://mattermost.atlassian.net/browse/MM-63300

```release-note
NONE
```

Co-authored-by: Mattermost Build <build@mattermost.com>
2025-05-21 08:48:46 +05:30
Agniva De Sarker
ad56ab3fdc MM-62365: Remove unused field from MetricSample (#30991)
The Timestamp field was not used at all. Therefore
removing it.

https://mattermost.atlassian.net/browse/MM-62365

```release-note
NONE
```
2025-05-21 08:43:00 +05:30
sabril
27874fa4e5 skip flaky tests (#31110) 2025-05-21 10:38:51 +08:00
kshitij katiyar
14dfc71e10 Bump prepackage Jira plugin version to 4.3.0 (#31098)
Co-authored-by: Mattermost Build <build@mattermost.com>
2025-05-20 18:26:29 -04:00
Harrison Healey
1bfd3a6a6e Slightly improve performance of sidebar update APIs (#31061) 2025-05-20 21:16:28 +00:00
Harrison Healey
b70f1d859d MM-63923/MM-63924/MM-63925 Prevent deadlocks and constraint errors in UpdateSidebarCategories (#30965)
* MM-63925 Remove most nested transactions from channel_store_categories.go

There's one place which still has a nested transaction in
CreateInitialSidebarCategories, but that's because it's calling out to a
different part of the store. The only way to avoid that would be to
break the extraction like UpdateSidebarCategories does to update
preferences, but I chose not to follow that pattern here and leave it
as-is.

* MM-63923 Prevent deadlocks caused by updating multiple categories in a different order

* MM-63923 Prevent deadlocks while deleting from SidebarChannels

This could also have been resolved by sorting the categories, but
combining the queries seems a bit more elegant.

* MM-63924 Ensure adding SidebarChannels rows is idempotent

* Add additional test to cause deadlocks

* Prevent channels from appearing in a single category multiple times

* Other review feedback
2025-05-20 16:02:32 -04:00
Jesse Hallam
fa40a8c5d4 MM-64226: improved post deduplication (#31004)
Require access to a post before allowing PendingPostId to deduplicate.

Fixes: https://mattermost.atlassian.net/browse/MM-64226
2025-05-20 10:05:10 -03:00
Harsh Aulakh
8e033f41d1 add config reload e2e tests (#29396)
Co-authored-by: Ben Schumacher <ben.schumacher@mattermost.com>
2025-05-20 11:26:55 +02:00
Ben Schumacher
c2d08b7540 [MM-63772] Add LDAP setting to re-add removed members (#30787) 2025-05-20 11:15:25 +02:00
Caleb Roseland
5021fc72c6 Prepackage Playbooks 2.2.0 (#31067) 2025-05-19 16:42:22 -05:00
Jesse Hallam
65aec10162 MM-64336: simplify doc extractor (#31103)
* MM-64336: simplify doc extractor

Avoid creating a whole temporary directory when a single temporary file suffices.

Fixes: https://mattermost.atlassian.net/browse/MM-64337

* clarify -* semantics
2025-05-19 20:58:59 +00:00
Maria A Nunez
2213cdbaf7 User usage alert in License and System Statistics page (#31063)
* Added user over usager alert in License and System Statistics page

* Fixed case below 90

* Fixed constant

* Linting

* Change over user notification threshold to 0

* Fix tests

* Saved dismissed preference

* Text tweek

* Fix tests

* More tests fixed

* Snapshot updated
2025-05-19 14:31:47 -04:00
sabril
2116a6d94a MM-64282 E2E/Playwright: Test documentation format (#31050)
* initial implementation of test documentation in spec file with AI-assisted prompt from Claude and linter script

* update snapshots

---------

Co-authored-by: Mattermost Build <build@mattermost.com>
2025-05-20 01:07:47 +08:00
Weblate (bot)
a358401772 Translations update from Mattermost Weblate (#31099)
* Translated using Weblate (Portuguese (Brazil))

Currently translated at 94.4% (2509 of 2657 strings)

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

* Translated using Weblate (Portuguese (Brazil))

Currently translated at 74.3% (4617 of 6207 strings)

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

* Translated using Weblate (German)

Currently translated at 99.0% (6150 of 6207 strings)

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

* Translated using Weblate (Polish)

Currently translated at 99.2% (6161 of 6207 strings)

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

* Translated using Weblate (German)

Currently translated at 99.9% (6206 of 6207 strings)

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

* Translated using Weblate (Czech)

Currently translated at 100.0% (2657 of 2657 strings)

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

* Translated using Weblate (Czech)

Currently translated at 97.3% (6040 of 6207 strings)

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

* Translated using Weblate (Norwegian Bokmål)

Currently translated at 79.7% (4952 of 6207 strings)

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

* Translated using Weblate (Polish)

Currently translated at 99.4% (6171 of 6207 strings)

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

* Translated using Weblate (Dutch)

Currently translated at 99.4% (6172 of 6207 strings)

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

* Translated using Weblate (Norwegian Bokmål)

Currently translated at 79.8% (4958 of 6207 strings)

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

* Translated using Weblate (Polish)

Currently translated at 99.5% (6182 of 6207 strings)

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

* Translated using Weblate (Norwegian Bokmål)

Currently translated at 79.8% (4959 of 6207 strings)

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

* Translated using Weblate (Norwegian Bokmål)

Currently translated at 80.5% (5000 of 6207 strings)

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

* Translated using Weblate (Portuguese (Brazil))

Currently translated at 75.2% (4669 of 6207 strings)

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

* Translated using Weblate (Norwegian Bokmål)

Currently translated at 80.7% (5011 of 6207 strings)

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

* Translated using Weblate (Polish)

Currently translated at 100.0% (6207 of 6207 strings)

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

* Translated using Weblate (Norwegian Bokmål)

Currently translated at 80.7% (5013 of 6207 strings)

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

* Translated using Weblate (Japanese)

Currently translated at 100.0% (2657 of 2657 strings)

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

* Translated using Weblate (Japanese)

Currently translated at 98.2% (6099 of 6207 strings)

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

* Translated using Weblate (Dutch)

Currently translated at 99.6% (6184 of 6207 strings)

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

* Translated using Weblate (Japanese)

Currently translated at 100.0% (6207 of 6207 strings)

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

* Translated using Weblate (Norwegian Bokmål)

Currently translated at 80.8% (5017 of 6207 strings)

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

* Translated using Weblate (Norwegian Bokmål)

Currently translated at 81.1% (5034 of 6207 strings)

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

* Translated using Weblate (Norwegian Bokmål)

Currently translated at 4.2% (114 of 2657 strings)

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

* Translated using Weblate (Norwegian Bokmål)

Currently translated at 81.6% (5070 of 6207 strings)

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

* Translated using Weblate (Dutch)

Currently translated at 99.7% (6190 of 6207 strings)

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

* Translated using Weblate (Dutch)

Currently translated at 99.9% (6204 of 6207 strings)

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

* Translated using Weblate (Norwegian Bokmål)

Currently translated at 81.8% (5079 of 6207 strings)

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

* 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: Pineoak <marcel-carvalho@outlook.com>
Co-authored-by: jprusch <rs@schaeferbarthold.de>
Co-authored-by: master7 <marcin.karkosz@rajska.info>
Co-authored-by: Martin Mičuda <micuda@rematiptop.cz>
Co-authored-by: Frank Paul Silye <frankps@gmail.com>
Co-authored-by: Tom De Moor <tom@controlaltdieliet.be>
Co-authored-by: kaakaa <stooner.hoe@gmail.com>
2025-05-19 14:38:23 +00:00
Eva Sarafianou
d462b05a23 Update golang toolchain to 1.23.9 (#31062)
* Update golang toolchain

* remove comment

---------

Co-authored-by: Mattermost Build <build@mattermost.com>
2025-05-19 16:56:06 +03:00
unified-ci-app[bot]
fd4b53f2bc chore: Update NOTICE.txt file with updated dependencies (#31096)
Automatic Merge
2025-05-19 15:00:09 +03:00
dependabot[bot]
51c0908d7d Bump the github-actions-updates group with 3 updates (#31094)
Bumps the github-actions-updates group with 3 updates: [docker/build-push-action](https://github.com/docker/build-push-action), [github/codeql-action](https://github.com/github/codeql-action) and [aws-actions/configure-aws-credentials](https://github.com/aws-actions/configure-aws-credentials).


Updates `docker/build-push-action` from 6.16.0 to 6.17.0
- [Release notes](https://github.com/docker/build-push-action/releases)
- [Commits](14487ce63c...1dc7386353)

Updates `github/codeql-action` from 3.28.17 to 3.28.18
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](60168efe1c...ff0a06e83c)

Updates `aws-actions/configure-aws-credentials` from 4.2.0 to 4.2.1
- [Release notes](https://github.com/aws-actions/configure-aws-credentials/releases)
- [Changelog](https://github.com/aws-actions/configure-aws-credentials/blob/main/CHANGELOG.md)
- [Commits](f24d7193d9...b475783126)

---
updated-dependencies:
- dependency-name: docker/build-push-action
  dependency-version: 6.17.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: github-actions-updates
- dependency-name: github/codeql-action
  dependency-version: 3.28.18
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: github-actions-updates
- dependency-name: aws-actions/configure-aws-credentials
  dependency-version: 4.2.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: github-actions-updates
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-05-19 14:29:58 +03:00
Arya Khochare
f54d5b41c1 [MM-58163] Jobs paging/offset refactor (#30343)
Co-authored-by: Ben Schumacher <ben.schumacher@mattermost.com>
2025-05-19 12:31:25 +02:00
Pablo Vélez
04ec01d312 MM-63966 - save pannel not dissapearing after save (#30993)
* MM-63966 - save pannel not dissapearing after save

* adjust unit tests

* trim only on direct change

---------

Co-authored-by: Mattermost Build <build@mattermost.com>
2025-05-19 12:26:00 +02:00
Clément Collin
15df76600b MM-51488 Fixed checkboxes position in markdown lists (#30347)
- Special case of ordered lists

Co-authored-by: Mattermost Build <build@mattermost.com>
2025-05-17 00:13:34 +05:30
Claudio Costa
d69925a415 [MM-63838] Fix potential TypeError when Calls is disabled (#30867)
* Fix potential TypeError when Calls is disabled

* Use createSelector
2025-05-16 16:36:57 +02:00
kshitij katiyar
bc561620cb Bump prepackage Github plugin version to 2.4.0 (#30668)
Co-authored-by: Doug Lauder <wiggin77@warpmail.net>
2025-05-16 00:15:09 -04:00
kshitij katiyar
7aa94ce95a Bump prepackage GitLab plugin version to 1.10.0 (#30797)
* Bump prepackage Zoom plugin version to 1.9.0

* Bump prepackage GitLab plugin version to 1.10.0

* fixed zoom version

---------

Co-authored-by: Mattermost Build <build@mattermost.com>
2025-05-15 23:00:37 -04:00
Devin Binnie
62a93cd36f [MM-62980][MM-62970] Login and Password Reset accessibility fixes (#31028)
* [MM-62980] Set aria-describedby for Input component when again custom message is set

* [MM-62970] Change password reset send link input to Input

* Fix i18n

* Fix e2e

* fix snapshots

---------

Co-authored-by: yasserfaraazkhan <attitude3cena.yf@gmail.com>
2025-05-15 16:23:03 +00:00
Jesse Hallam
8127d105ad MM-63406: Update timezone automatically (#30856)
* MM-63406: Update timezone automatically

On focus as well as every 30 minutes, check if the timezone has changed.
Also, ignore the momentjs cache, otherwise this value is static as per https://momentjs.com/timezone/docs/#/using-timezones/guessing-user-timezone/

> By default Moment Timezone caches the detected timezone. This means that subsequent calls to moment.tz.guess() will always return the same value.

* migrate away from enzyme

* MM-63406: Address PR feedback - add constants and improve comments

* MM-63406: Address PR feedback - Extract timezone logic to a separate component

- Created a new TimezoneManager component for handling timezone updates
- Used fake timers in tests to properly test the periodic update
- Removed visibility change handler to simplify the component

* fix linting

* Remove comments from getBrowserTimezone function

* Move updateTimezone function before useEffect

* Simplify timezone detection with Intl.DateTimeFormat().resolvedOptions().timeZone

* Fix style issues

* Improve timezone manager tests with jest.getTimerCount()

Used jest.getTimerCount() to verify timer cleanup on unmount instead of spying on clearInterval.
This change addresses PR feedback in #30856.

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

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

* MM-63406: Simplify timezone updates to check every minute

- Simplify timezone manager by removing focus event and only checking every minute
- Replace 30-minute interval with 1-minute interval for more responsive timezone detection
- Update tests to match new implementation
- Change removes focus/blur event handling as per PR feedback

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

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

* revert to simpler approach

---------

Co-authored-by: Mattermost Build <build@mattermost.com>
Co-authored-by: Claude <noreply@anthropic.com>
2025-05-15 13:57:14 +00:00
Pablo Vélez
f9a92c1700 Mm 63844 add end user indicators (#30971)
MM-63844 - ABAC add end user indicators to channel manage users
2025-05-15 15:25:19 +02:00
Ibrahim Serdar Acikgoz
fbdecd806c Prepackage Metrics Plugin v0.7.0 (#31039) 2025-05-15 14:24:44 +02:00
Ibrahim Serdar Acikgoz
a344b3225b [MM-61756] Attribute Based Access Control - Phase 1 (#30785)
Attribute Based Access Control - Base
* MM-63662

* MM-63919

* MM-63954

* MM-63955 

* MM-63425

* MM-63426

* MM-63458

* MM-63459

* MM-63603

* MM-63845

* MM-64146

* MM-64199

* MM-64201

* MM-64233

* MM-64247

* MM-64268

---------

Co-authored-by: Harshil Sharma <harshilsharma63@gmail.com>
Co-authored-by: Pablo Andrés Vélez Vidal <pablovv2012@gmail.com>
Co-authored-by: abhijit-singh <abhijitsingh0702@gmail.com>
Co-authored-by: Harrison Healey <harrisonmhealey@gmail.com>
2025-05-15 11:33:08 +02:00
Harshil Sharma
4b445cbf16 Fixed a bug where wehbooj's overriden username didn't show up in non-CRT reply (#30996) 2025-05-15 14:18:23 +05:30
Pablo Vélez
08caad3b99 MM-64232 - adjust disabled styles channel settings modal (#30984)
* MM-64232 - adjust disabled styles channel settings modal

* fix styles

* adjust snapshot

---------

Co-authored-by: Mattermost Build <build@mattermost.com>
2025-05-15 02:22:09 +02:00
Ben Cooke
1634b57dbd fix flaky test (#31046) 2025-05-14 14:07:08 -04:00
Ben Cooke
6b4ab0a891 [MM-63774] Allow users to leave private channels when there is only 1 member (#30746)
* allow last user to leave private channel
---------
Co-authored-by: Mattermost Build <build@mattermost.com>
2025-05-14 11:58:13 -04:00
Pablo Vélez
9fe678cad3 MM-63968 - remove channel name input plus one (#30979)
* MM-63968 - remove channel name input plus one

* adjust test to most common use in webapp

* adjust error for min lenght and add back minlenght indicator under a param bool value

---------

Co-authored-by: Mattermost Build <build@mattermost.com>
2025-05-14 17:16:18 +02:00
Jesse Hallam
6358eee40b Pre-package MS Teams v2.2.1 (#31041) 2025-05-14 13:42:25 +00:00
Pablo Vélez
c4b60463ff MM-63965 - add scroll to advanced text editor (#30983)
* MM-63965 - add scroll to advanced text editor

* show scroll only when content wraps in more than one line

* fix unit test

---------

Co-authored-by: Mattermost Build <build@mattermost.com>
2025-05-14 15:30:04 +02:00
Jesse Hallam
d80d575f6c MM-63619: improve Groups API error semantics (#30961)
Instead of 5xx errors, return `http.StatusInvalidRequest` when
adding or deleting invalid user ids from groups.

Fixes: https://mattermost.atlassian.net/browse/MM-63619
2025-05-14 10:17:30 -03:00
Julien Tant
935b8902a8 MM-64155: Fix searchbox clear button to reset search type (#31006)
Co-authored-by: Claude <noreply@anthropic.com>
2025-05-13 14:07:38 -07:00
Ben Cooke
4af8acb702 update gosaml to match enterprise version (#31031) 2025-05-13 14:34:08 -04:00
Miguel de la Cruz
6ab6a008e6 Adds the capability to retrieve a property field by name (#30859)
* Adds the capability to retrieve a property field by name

Allows to retrieve a property field by name and groupID. As the name
is only unique within the context of a group, and we can have multiple
fields with the same name in the store, for this method the groupID is
directly included in the query instead of being an optional field.

* Adds the targetID parameter to correctly filter fields

* Ensure the method only retrieves non-deleted fields

---------

Co-authored-by: Miguel de la Cruz <miguel@ctrlz.es>
Co-authored-by: Mattermost Build <build@mattermost.com>
2025-05-13 12:45:35 +02:00
Pablo Vélez
64ed8f02dc MM-63912 - enhance validation for channel banner colors (#30981)
* MM-63912 - enhance validation for channel banner colors

* fix tests

* fix unit tests
2025-05-13 09:59:31 +02:00
Harshil Sharma
4ae5d647fb Permission schema error fix (#30953)
* Fixed an error in permission schema for team admins

* Updated test

---------

Co-authored-by: Mattermost Build <build@mattermost.com>
2025-05-13 12:22:25 +05:30
Ben Schumacher
e1c94e7b63 Add deactivation status to mmctl user search output (#30379) 2025-05-13 08:52:13 +02:00
dependabot[bot]
a8a2ae3af0 Bump the github-actions-updates group with 2 updates (#30997)
Bumps the github-actions-updates group with 2 updates: [tj-actions/changed-files](https://github.com/tj-actions/changed-files) and [aws-actions/configure-aws-credentials](https://github.com/aws-actions/configure-aws-credentials).


Updates `tj-actions/changed-files` from 4168bb487d5b82227665ab4ec90b67ce02691741 to 480f49412651059a414a6a5c96887abb1877de8a
- [Release notes](https://github.com/tj-actions/changed-files/releases)
- [Changelog](https://github.com/tj-actions/changed-files/blob/main/HISTORY.md)
- [Commits](4168bb487d...480f494126)

Updates `aws-actions/configure-aws-credentials` from 4.1.0 to 4.2.0
- [Release notes](https://github.com/aws-actions/configure-aws-credentials/releases)
- [Changelog](https://github.com/aws-actions/configure-aws-credentials/blob/main/CHANGELOG.md)
- [Commits](ececac1a45...f24d7193d9)

---
updated-dependencies:
- dependency-name: tj-actions/changed-files
  dependency-version: 480f49412651059a414a6a5c96887abb1877de8a
  dependency-type: direct:production
  dependency-group: github-actions-updates
- dependency-name: aws-actions/configure-aws-credentials
  dependency-version: 4.2.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: github-actions-updates
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-05-13 08:30:50 +03:00
Ben Cooke
b6b0c269c4 Use error from OnSamlLogin (#30745) 2025-05-12 18:41:54 -04:00
Jesse Hallam
f302b9844e migrate groupsBySyncableBaseQuery (#30926) 2025-05-12 15:03:02 -03:00
Weblate (bot)
6b48c67eeb Translations update from Mattermost Weblate (#31000)
* Translated using Weblate (Lithuanian)

Currently translated at 76.7% (4749 of 6185 strings)

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

* Translated using Weblate (French)

Currently translated at 81.1% (5021 of 6185 strings)

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

* Translated using Weblate (French)

Currently translated at 81.4% (5038 of 6185 strings)

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

* Translated using Weblate (Portuguese (Brazil))

Currently translated at 72.0% (4457 of 6185 strings)

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

* Translated using Weblate (Norwegian Bokmål)

Currently translated at 78.9% (4880 of 6185 strings)

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

* Translated using Weblate (Portuguese (Brazil))

Currently translated at 72.3% (4477 of 6185 strings)

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

* Translated using Weblate (Dutch)

Currently translated at 99.7% (2650 of 2657 strings)

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

* Translated using Weblate (Polish)

Currently translated at 100.0% (2657 of 2657 strings)

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

* Translated using Weblate (Polish)

Currently translated at 100.0% (6185 of 6185 strings)

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

* Translated using Weblate (Norwegian Bokmål)

Currently translated at 79.0% (4888 of 6185 strings)

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

* Translated using Weblate (Norwegian Bokmål)

Currently translated at 79.0% (4889 of 6185 strings)

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

* Translated using Weblate (Swedish)

Currently translated at 100.0% (2657 of 2657 strings)

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

* Translated using Weblate (Swedish)

Currently translated at 100.0% (6185 of 6185 strings)

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

* Translated using Weblate (Portuguese (Brazil))

Currently translated at 93.7% (2492 of 2657 strings)

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

* Translated using Weblate (Polish)

Currently translated at 100.0% (6185 of 6185 strings)

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

* Translated using Weblate (Ukrainian)

Currently translated at 99.9% (6184 of 6185 strings)

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

* Translated using Weblate (Norwegian Bokmål)

Currently translated at 79.1% (4893 of 6185 strings)

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

* Translated using Weblate (Norwegian Bokmål)

Currently translated at 3.5% (94 of 2657 strings)

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

* Translated using Weblate (Norwegian Bokmål)

Currently translated at 79.2% (4901 of 6185 strings)

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

* Translated using Weblate (Portuguese (Brazil))

Currently translated at 93.7% (2492 of 2657 strings)

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

* Translated using Weblate (Norwegian Bokmål)

Currently translated at 79.3% (4907 of 6185 strings)

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

* Translated using Weblate (Portuguese (Brazil))

Currently translated at 72.3% (4477 of 6185 strings)

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

* Translated using Weblate (Norwegian Bokmål)

Currently translated at 80.0% (4950 of 6185 strings)

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

* Translated using Weblate (Turkish)

Currently translated at 98.5% (2619 of 2657 strings)

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

* Translated using Weblate (Portuguese (Brazil))

Currently translated at 73.1% (4524 of 6185 strings)

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

* Translated using Weblate (Dutch)

Currently translated at 99.7% (2650 of 2657 strings)

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

* Translated using Weblate (Norwegian Bokmål)

Currently translated at 80.2% (4963 of 6185 strings)

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

* Translated using Weblate (Turkish)

Currently translated at 100.0% (2657 of 2657 strings)

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

* Translated using Weblate (Turkish)

Currently translated at 97.8% (6052 of 6185 strings)

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

* Translated using Weblate (Turkish)

Currently translated at 98.2% (6076 of 6185 strings)

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

* Translated using Weblate (Turkish)

Currently translated at 98.2% (6077 of 6185 strings)

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

* Translated using Weblate (Turkish)

Currently translated at 98.2% (6078 of 6185 strings)

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

* Translated using Weblate (Turkish)

Currently translated at 100.0% (2657 of 2657 strings)

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

* Translated using Weblate (Turkish)

Currently translated at 99.8% (6174 of 6185 strings)

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

* Translated using Weblate (Ukrainian)

Currently translated at 99.9% (6184 of 6185 strings)

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

* Translated using Weblate (German)

Currently translated at 100.0% (2657 of 2657 strings)

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

* Translated using Weblate (German)

Currently translated at 100.0% (6185 of 6185 strings)

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

* Translated using Weblate (Turkish)

Currently translated at 100.0% (6185 of 6185 strings)

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

* Translated using Weblate (Norwegian Bokmål)

Currently translated at 80.2% (4965 of 6185 strings)

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

* Update translation files

Updated by "Cleanup translation files" hook in Weblate.

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

* 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: evituzas <evita.svegzdaite@gmail.com>
Co-authored-by: Benjamin Danon <b@bndn.fr>
Co-authored-by: Pineoak <marcel-carvalho@outlook.com>
Co-authored-by: Frank Paul Silye <frankps@gmail.com>
Co-authored-by: Tom De Moor <tom@controlaltdieliet.be>
Co-authored-by: master7 <marcin.karkosz@rajska.info>
Co-authored-by: MArtin Johnson <martinjohnson@bahnhof.se>
Co-authored-by: Serhii Khomiuk <sergiy.khomiuk@gmail.com>
Co-authored-by: Kaya Zeren <kayazeren@gmail.com>
Co-authored-by: jprusch <rs@schaeferbarthold.de>
2025-05-12 20:40:53 +03:00
Nick Misasi
cf2702f5dd Pass the server's version in trial request payload (#30911)
Co-authored-by: Mattermost Build <build@mattermost.com>
2025-05-12 13:40:45 -04:00
David Krauser
a6a4674a21 Better handle missing cluster node info fields (#30844)
A recent change to the enterprise cluster code introduced the possibility that we could get cluster info with empty fields. This happens when we can't properly communicate with the related cluster node. In that case, we now show a warning to the admin.
2025-05-12 13:38:10 -04:00
David Krauser
4b64eb0e39 Handle error returned by GetClusterInfos() (#30919)
A recent change to the enterprise cluster code introduced a change to the enterprise API interface. GetClusterInfos() can now return an error. This commit introduces code to handle that error.
2025-05-12 13:37:58 -04:00
Devin Binnie
dfe6478fd7 [MM-63000][MM-63055][MM-63046] Various accessibility fixes around Drafts (#30924)
* [MM-63000] Use CSS hover state instead of component state, add focus-within to ensure buttons are focusable

* [MM-63046] Allow draft panel to be correctly focusable and navigable using correct roles

* [MM-63046] Use `name` as `aria-label` for `Action`

* update locator for scheduled drafts and fix failing playwright tests

* fix lint

* PR feedback

* PR feedback

---------

Co-authored-by: yasserfaraazkhan <attitude3cena.yf@gmail.com>
2025-05-12 16:38:06 +00:00
Agniva De Sarker
4803892492 MM-56906: Remove redundant calls on team switch (#30771)
On page load, we load ALL channels and channel members from all teams.
But then, on team_switch, we would again load channels and channel
members from that team. This was redundant and mainly kept
because previously the websocket events were considered unreliable.

Now with reliable websockets, and client-side pings, we can detect
broken connections faster and recover without loss.

Additionally, the getAllChannelMembers call would page through
all responses on the client side. This was inefficient and incur
extra latency. To optimize for this, we introduce server-side
streaming of the full response if page is set to -1.

This optimizes the intial response as well.

https://mattermost.atlassian.net/browse/MM-56906

```release-note
Optimize team switch operation by removing calls to get channels
and channel members.
```


Co-authored-by: Mattermost Build <build@mattermost.com>
2025-05-12 20:05:46 +05:30
Devin Binnie
883711c72d [MM-62973][MM-63028][MM-63034][MM-63027] Various accessibility fixes around Browse Channels modal (#30922)
* [MM-62973] Fix order of Close button and other buttons in the header

* [MM-63028] Add aria-live status area when searching for channels

* [MM-63027] Add announcement that channel is joined

* [MM-63034] Add role=checkbox and reformat HTML to have correct custom checkbox code

* Update snapshots from generic_modal change

* PR feedback

* PR feedback

* PR feedback
2025-05-12 09:14:20 -04:00
Devin Binnie
c82a24f396 [MM-62975][MM-62981] Invite Modal accessibility fixes (#30960)
* [MM-62975] Convert results table to actual table instead of divs

* [MM-62981] Ensure remove user button is focusable

* fix playwright test

* fix playwright test

---------

Co-authored-by: yasserfaraazkhan <attitude3cena.yf@gmail.com>
2025-05-12 09:08:03 -04:00
Clément Collin
e0f54447b9 MM-57014 Extended console log search to all log attributes (#30397) 2025-05-12 13:43:40 +02:00
Ben Schumacher
bb8aabc15e [MM-61765] Fix errcheck issues in server/channels/app/platform/license.go (#30954)
* [MM-61765] Fix errcheck issues in server/channels/app/platform/license.go

- Removed the errcheck exception for license.go from .golangci.yml
- Added proper error handling for RemoveLicense() calls
- Added proper error handling for ReloadConfig() and InvalidateAllCaches() calls
- Updated variable names to avoid conflicts

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

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

* simplify naming

---------

Co-authored-by: Claude <noreply@anthropic.com>
2025-05-12 13:41:59 +02:00
Ben Schumacher
4dbff921ba [MM-61499] Fix errcheck issues in server/channels/app/slashcommands/helper_test.go (#30880) 2025-05-12 11:20:14 +02:00
Ibrahim Serdar Acikgoz
d452f4f043 [MM-63661] add access control metrics (#30680) 2025-05-11 22:11:42 +02:00
Agniva De Sarker
509b8e9af7 MM-63130: Move to webHub iteration to be alloc-free (#30792)
We switch to using iterators introduced in Go 1.23
to make iteration alloc-free and fast. And since
element removal is allowed while iterating a map,
this also means we don't need to even copy the slice
any more.

While here, we also address the comment https://github.com/mattermost/mattermost/pull/30178#discussion_r1954862151.
I have simply gone back to using []string as the map
entry rather than a type alias or a redirection with
a struct.

https://mattermost.atlassian.net/browse/MM-63130

```release-note
NONE
```

* Changed back nil to len

```release-note
NONE
```

* fixing unused assignment

```release-note
NONE
```

* add benchmark

```
goos: linux
goarch: amd64
pkg: github.com/mattermost/mattermost/server/v8/channels/app/platform
cpu: Intel(R) Core(TM) i5-8265U CPU @ 1.60GHz
                               │   old.txt    │               new.txt               │
                               │    sec/op    │   sec/op     vs base                │
HubConnIndexIterator/2_users-8    93.53n ± 1%   38.09n ± 1%  -59.27% (p=0.000 n=10)
HubConnIndexIterator/3_users-8   106.30n ± 0%   38.41n ± 1%  -63.86% (p=0.000 n=10)
HubConnIndexIterator/4_users-8   111.30n ± 1%   38.66n ± 1%  -65.27% (p=0.000 n=10)
geomean                           103.4n        38.39n       -62.89%

                               │  old.txt   │               new.txt                │
                               │    B/op    │    B/op     vs base                  │
HubConnIndexIterator/2_users-8   16.00 ± 0%   24.00 ± 0%  +50.00% (p=0.000 n=10)
HubConnIndexIterator/3_users-8   24.00 ± 0%   24.00 ± 0%        ~ (p=1.000 n=10) ¹
HubConnIndexIterator/4_users-8   32.00 ± 0%   24.00 ± 0%  -25.00% (p=0.000 n=10)
geomean                          23.08        24.00        +4.00%
¹ all samples are equal

                               │  old.txt   │               new.txt               │
                               │ allocs/op  │ allocs/op   vs base                 │
HubConnIndexIterator/2_users-8   1.000 ± 0%   1.000 ± 0%       ~ (p=1.000 n=10) ¹
HubConnIndexIterator/3_users-8   1.000 ± 0%   1.000 ± 0%       ~ (p=1.000 n=10) ¹
HubConnIndexIterator/4_users-8   1.000 ± 0%   1.000 ± 0%       ~ (p=1.000 n=10) ¹
geomean                          1.000        1.000       +0.00%
¹ all samples are equal
```

```release-note
NONE
```

* ForChannel test as well

```release-note
NONE
```

* review comments

```release-note
NONE
```

* fix lint errors

```release-note
NONE
```

---------

Co-authored-by: Mattermost Build <build@mattermost.com>
2025-05-11 12:00:12 +05:30
David Krauser
67ab69606a Handle network connectivity changes in websocket (#30788)
This commit introduces listeners for network changes that will:
- Test the websocket if we get an offline event to check if we have disconnected.
- Re-connect the websocket immediately if we get an online event, and we are disconnected.

Additionally when a ping fails, we now immediately call the onclose() callback instead of waiting for the system to trigger it when the broken websocket closes. This allows us to re-connect much more quickly (since we don't have to wait for the broken websocket to get cleaned up by the system).
2025-05-09 15:39:10 -04:00
Maria A Nunez
190b4e7f03 System Console enterprise advanced upsells (#30937)
* First set of texts updated for Enterprise Adv upsells and trial

* Updated upsell message for all tiers

* Linting translation file

* Linting

* Reverting unintended styling changes

* my ide making lint more

* Fix tests

* More default texts updated

* Trial banner title

* Make advantages list translatable

* Text updates

* Fix tests

* More text tweaking

* Linting

* Reodered translations

* Fixed e2e test

* More linting

* Removed incorrect new test

* Fix test typo

---------

Co-authored-by: Mattermost Build <build@mattermost.com>
2025-05-09 13:33:48 -04:00
Ben Schumacher
cd3046773e [MM-61498] Fix errcheck issues in server/channels/app/slashcommands/command_test.go (#30879)
Co-authored-by: Claude <noreply@anthropic.com>
2025-05-09 13:56:35 +02:00
Agniva De Sarker
0ebd3e8085 MM-64209: Optimize completePopulatingCategoryChannelsT for MySQL (#30963)
For our MySQL customers, we have discovered that the query is not
able to choose the right plan by itself without adequate hints.

This is only for MySQL as we have confirmed from multiple customers
that Postgres takes the right index idx_sidebarcategories_userid_teamid
for the sidebarCategories table. And if it doesn't, then a VACUUM ANALYZE
fixes it.

But for MySQL, we have to do two things:
- Pass an index hint to let it use idx_sidebarcategories_userid_teamid.
- Pass an optimizer hint to materialize the sub-query. This is used
to materialize the doesNotHaveSidebarChannel sub-query into a temporary
table, letting MySQL reuse the contents of the table for further processing
in the parent sections of the query.

I have confirmed both locally and in the customer environment
that it gives a clear benefit.

*LOCAL*

OLD:
```
| -> Nested loop antijoin  (cost=2889.85 rows=19767) (actual time=3.355..38.033 rows=15 loops=1)
    -> Nested loop inner join  (cost=66.65 rows=110) (actual time=0.410..1.689 rows=220 loops=1)
        -> Filter: ((Channels.DeleteAt = 0) and (Channels.`Type` in ('O','P')))  (cost=25.25 rows=110) (actual time=0.394..0.886 rows=220 loops=1)
            -> Index lookup on Channels using idx_channels_team_id_display_name (TeamId='team01'), with index condition: (Channels.Id is not null)  (cost=25.25 rows=220) (actual time=0.389..0.793 rows=220 loops=1)
        -> Single-row covering index lookup on ChannelMembers using PRIMARY (ChannelId=Channels.Id, UserId='user000')  (cost=0.28 rows=1) (actual time=0.003..0.003 rows=1 loops=220)
    -> Nested loop inner join  (cost=4967.50 rows=180) (actual time=0.165..0.165 rows=1 loops=220)
        -> Covering index lookup on SidebarChannels using PRIMARY (ChannelId=Channels.Id)  (cost=7.86 rows=180) (actual time=0.055..0.062 rows=13 loops=220)
        -> Filter: ((SidebarCategories.TeamId = 'team01') and (SidebarCategories.UserId = 'user000'))  (cost=44.93 rows=1) (actual time=0.008..0.008 rows=0 loops=2881)
            -> Single-row index lookup on SidebarCategories using PRIMARY (Id=SidebarChannels.CategoryId)  (cost=44.93 rows=1) (actual time=0.006..0.006 rows=1 loops=2881)
 |
```

NEW:
```
 | -> Nested loop antijoin  (cost=5879.73 rows=58021) (actual time=1.544..3.135 rows=15 loops=1)
    -> Nested loop inner join  (cost=66.65 rows=110) (actual time=0.421..1.778 rows=220 loops=1)
        -> Filter: ((Channels.DeleteAt = 0) and (Channels.`Type` in ('O','P')))  (cost=25.25 rows=110) (actual time=0.405..0.945 rows=220 loops=1)
            -> Index lookup on Channels using idx_channels_team_id_display_name (TeamId='team01'), with index condition: (Channels.Id is not null)  (cost=25.25 rows=220) (actual time=0.400..0.859 rows=220 loops=1)
        -> Single-row covering index lookup on ChannelMembers using PRIMARY (ChannelId=Channels.Id, UserId='user000')  (cost=0.28 rows=1) (actual time=0.003..0.004 rows=1 loops=220)
    -> Single-row index lookup on <subquery2> using <auto_distinct_key> (ChannelId=Channels.Id)  (cost=130.37..130.37 rows=1) (actual time=0.006..0.006 rows=1 loops=220)
        -> Materialize with deduplication  (cost=130.35..130.35 rows=527) (actual time=1.118..1.118 rows=205 loops=1)
            -> Filter: (SidebarChannels.ChannelId is not null)  (cost=77.61 rows=527) (actual time=0.059..0.851 rows=523 loops=1)
                -> Nested loop inner join  (cost=77.61 rows=527) (actual time=0.058..0.786 rows=523 loops=1)
                    -> Covering index lookup on SidebarCategories using idx_sidebarcategories_userid_teamid (UserId='user000', TeamId='team01')  (cost=2.81 rows=15) (actual time=0.025..0.031 rows=15 loops=1)
                    -> Covering index lookup on SidebarChannels using idx_sidebarchannels_categoryid (CategoryId=SidebarCategories.Id)  (cost=1.70 rows=35) (actual time=0.032..0.046 rows=35 loops=15)
```

Performance improvement from 38ms to 3ms.

*CUSTOMER ENV* (with sensitive data wiped off)

OLD:
```
| -> Sort: channels.DisplayName  (actual time=512..512 rows=5 loops=1)
    -> Stream results  (cost=3.28 rows=1.44) (actual time=223..512 rows=5 loops=1)
        -> Nested loop antijoin  (cost=3.28 rows=1.44) (actual time=223..512 rows=5 loops=1)
            -> Nested loop inner join  (cost=3.02 rows=0.3) (actual time=0.025..0.0878 rows=5 loops=1)
                -> Covering index lookup on ChannelMembers using idx_channelmembers_user_id_channel_id_last_viewed_at (UserId='')  (cost=0.916 rows=6) (actual time=0.0146..0.023 rows=6 loops=1)
                -> Filter: ((channels.DeleteAt = 0) and (channels.TeamId = '') and (channels.`Type` in ('O','P')))  (cost=0.251 rows=0.05) (actual time=0.00999..0.0102 rows=0.833 loops=6)
                    -> Single-row index lookup on Channels using PRIMARY (Id=channelmembers.ChannelId)  (cost=0.251 rows=1) (actual time=0.00778..0.00785 rows=1 loops=6)
            -> Nested loop inner join  (cost=2.85 rows=4.81) (actual time=102..102 rows=0 loops=5)
                -> Covering index lookup on SidebarChannels using PRIMARY (ChannelId=channelmembers.ChannelId)  (cost=2.01 rows=4.81) (actual time=0.0125..13.8 rows=24134 loops=5)
                -> Filter: ((sidebarcategories.TeamId = '') and (sidebarcategories.UserId = ''))  (cost=1.54 rows=1) (actual time=0.00359..0.00359 rows=0 loops=120671)
                    -> Single-row index lookup on SidebarCategories using PRIMARY (Id=sidebarchannels.CategoryId)  (cost=1.54 rows=1) (actual time=0.00316..0.00319 rows=1 loops=120671)
```

NEW:
```
Here is the output

| -> Sort: channels.DisplayName  (actual time=0.12..0.12 rows=5 loops=1)
    -> Stream results  (cost=3.45 rows=4.01) (actual time=0.0797..0.11 rows=5 loops=1)
        -> Nested loop antijoin  (cost=3.45 rows=4.01) (actual time=0.0769..0.106 rows=5 loops=1)
            -> Nested loop inner join  (cost=3.02 rows=0.3) (actual time=0.0291..0.0555 rows=5 loops=1)
                -> Covering index lookup on ChannelMembers using idx_channelmembers_user_id_channel_id_last_viewed_at (UserId='')  (cost=0.916 rows=6) (actual time=0.0145..0.0162 rows=6 loops=1)
                -> Filter: ((channels.DeleteAt = 0) and (channels.TeamId = '') and (channels.`Type` in ('O','P')))  (cost=0.251 rows=0.05) (actual time=0.00611..0.00619 rows=0.833 loops=6)
                    -> Single-row index lookup on Channels using PRIMARY (Id=channelmembers.ChannelId)  (cost=0.251 rows=1) (actual time=0.0053..0.00534 rows=1 loops=6)
            -> Single-row index lookup on <subquery2> using <auto_distinct_key> (ChannelId=channelmembers.ChannelId)  (cost=7.01..7.01 rows=1) (actual time=0.00956..0.00956 rows=0 loops=5)
                -> Materialize with deduplication  (cost=7..7 rows=13.4) (actual time=0.0451..0.0451 rows=0 loops=1)
                    -> Filter: (sidebarchannels.ChannelId is not null)  (cost=5.66 rows=13.4) (actual time=0.0441..0.0441 rows=0 loops=1)
                        -> Nested loop inner join  (cost=5.66 rows=13.4) (actual time=0.0439..0.0439 rows=0 loops=1)
                            -> Covering index lookup on SidebarCategories using idx_sidebarcategories_userid_teamid (UserId='', TeamId='')  (cost=0.592 rows=3) (actual time=0.0105..0.0134 rows=3 loops=1)
                            -> Covering index lookup on SidebarChannels using idx_sidebarchannels_categoryid (CategoryId=sidebarcategories.Id)  (cost=1.39 rows=4.46) (actual time=0.00999..0.00999 rows=0 loops=3)
```

Performance improvement from 512ms to 0.12ms.

https://mattermost.atlassian.net/browse/MM-64209

```release-note
NONE
```
2025-05-09 09:48:07 +05:30
sabril
3be58f5f34 E2E/Playwright: Upgrade playwright dependencies (#30951)
* upgrade playwright dependencies

* fix test on scheduled messages
2025-05-08 23:39:15 +08:00
Devin Binnie
0058edb806 [MM-62987] Include description on aria-label for last reply time, make link focused when using up/down arrows. (#30837)
* [MM-62987] Include description on aria-label for last reply time, make link focused when using up/down arrows.

* PR feedback

---------

Co-authored-by: Mattermost Build <build@mattermost.com>
2025-05-08 10:50:14 -04:00
Devin Binnie
c33dbe8d37 [MM-63015] Add more descriptive page titles to login/create account/password reset pages (#30857)
* [MM-63015] Add more descriptive page titles to login/create account/password reset pages

* PR feedback

* Fix e2e

---------

Co-authored-by: Mattermost Build <build@mattermost.com>
2025-05-08 10:48:31 -04:00
Devin Binnie
0e806bf8e8 [MM-62971][MM-63017] Search box accessibility fixes (#30910)
* [MM-62971] Add role='button' and focusability to the file suggestion list items

* [MM-63017] Add aria-label to Close button in Search
2025-05-08 10:43:52 -04:00
Devin Binnie
7efb83396b [MM-62974][MM-62984][MM-63016][MM-63025] Various fixes for the Create Team screen (#30905)
* [MM-62974] Focus team name inputs when error occurs

* [MM-62984] Change h5 to label on create team screens

* [MM-63016] Add a page title for the create team page

* [MM-63025] Add role=alert and aria-describedby for error messages on create team page

* Fix i18n
2025-05-07 15:20:22 -04:00
Devin Binnie
ee61301b67 [MM-62986][MM-63011][MM-63013][MM-63014][MM-63018] Various accessibility fixes around login, account creation and MFA setup (#30847)
* [MM-62986] Ensure focus goes back to the inputs after an error for Login/Create Account/MFA

* [MM-63011] Show outline on Mattermost logo link when focused

* [MM-63018] Remove tabindex from the login/signup cards and use <form> element for submit

* [MM-63014] Toggle aria-label when show/hide password is pressed

* [MM-63013] Mention the field name when showing an error message about the password field

* Fix lint

* Update screenshots and fix tests

* Update screenshots and fix tests

* Fix tests

* Update webapp/channels/src/components/mfa/setup/setup.tsx

Co-authored-by: Harrison Healey <harrisonmhealey@gmail.com>

* update screenshots

---------

Co-authored-by: yasserfaraazkhan <attitude3cena.yf@gmail.com>
Co-authored-by: Harrison Healey <harrisonmhealey@gmail.com>
2025-05-07 15:19:33 -04:00
Ben Schumacher
92011a6c75 [MM-29111] Fix errcheck issues in server/channels/app/upload.go (#30678)
Co-authored-by: Claude <noreply@anthropic.com>
2025-05-07 13:40:51 +02:00
Ben Schumacher
bfb15ab179 [MM-61074] Fix errcheck issues in oauth_test.go and web_test.go (#30707)
Co-authored-by: Claude <noreply@anthropic.com>
2025-05-07 12:41:10 +02:00
KIMBOH LOVETTE
b8b3efda48 [GH-25995]_Validate SITE URL in mmctl auth login (#30362) 2025-05-07 12:24:18 +02:00
Guillermo Vayá
5b68afe452 [MM-63837] Bump x/net version to 0.39 (#30843)
* bump x/net version to 0.39

* modules-tidy

* upgrade dependencies for public

* tidy

---------

Co-authored-by: Mattermost Build <build@mattermost.com>
2025-05-07 11:41:31 +02:00
Ben Schumacher
dc2827a63e [MM-28923] Fix errcheck issues in server/channels/app/file.go (#30878)
Co-authored-by: Claude <noreply@anthropic.com>
2025-05-07 10:04:17 +02:00
Ben Schumacher
e10a1309c1 [MM-61774] Fix errcheck issues in server/channels/app/platform/status.go (#30876)
Co-authored-by: Claude <noreply@anthropic.com>
2025-05-07 09:04:22 +02:00
Jesse Hallam
7f1987caec wip (#30941) 2025-05-06 10:01:09 -03:00
unified-ci-app[bot]
c163fb10ac chore: Update NOTICE.txt file with updated dependencies (#30947)
Automatic Merge
2025-05-06 14:28:42 +03:00
Antonis Stamatiou
b0ba67438e fix: Ignore mm deps from Notice file (#30945)
Automatic Merge
2025-05-06 13:28:42 +03:00
dependabot[bot]
7992fffb76 Bump the github-actions-updates group across 1 directory with 5 updates (#30933)
Bumps the github-actions-updates group with 5 updates in the / directory:

| Package | From | To |
| --- | --- | --- |
| [docker/build-push-action](https://github.com/docker/build-push-action) | `6.15.0` | `6.16.0` |
| [github/codeql-action](https://github.com/github/codeql-action) | `3.28.15` | `3.28.17` |
| [actions/download-artifact](https://github.com/actions/download-artifact) | `4.2.1` | `4.3.0` |
| [tj-actions/changed-files](https://github.com/tj-actions/changed-files) | `9934ab3fdf63239da75d9e0fbd339c48620c72c4` | `4168bb487d5b82227665ab4ec90b67ce02691741` |
| [sigstore/cosign-installer](https://github.com/sigstore/cosign-installer) | `3.8.1` | `3.8.2` |



Updates `docker/build-push-action` from 6.15.0 to 6.16.0
- [Release notes](https://github.com/docker/build-push-action/releases)
- [Commits](471d1dc4e0...14487ce63c)

Updates `github/codeql-action` from 3.28.15 to 3.28.17
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](45775bd823...60168efe1c)

Updates `actions/download-artifact` from 4.2.1 to 4.3.0
- [Release notes](https://github.com/actions/download-artifact/releases)
- [Commits](95815c38cf...d3f86a106a)

Updates `tj-actions/changed-files` from 9934ab3fdf63239da75d9e0fbd339c48620c72c4 to 4168bb487d5b82227665ab4ec90b67ce02691741
- [Release notes](https://github.com/tj-actions/changed-files/releases)
- [Changelog](https://github.com/tj-actions/changed-files/blob/main/HISTORY.md)
- [Commits](9934ab3fdf...4168bb487d)

Updates `sigstore/cosign-installer` from 3.8.1 to 3.8.2
- [Release notes](https://github.com/sigstore/cosign-installer/releases)
- [Commits](d7d6bc7722...3454372f43)

---
updated-dependencies:
- dependency-name: docker/build-push-action
  dependency-version: 6.16.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: github-actions-updates
- dependency-name: github/codeql-action
  dependency-version: 3.28.17
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: github-actions-updates
- dependency-name: actions/download-artifact
  dependency-version: 4.3.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: github-actions-updates
- dependency-name: tj-actions/changed-files
  dependency-version: 4168bb487d5b82227665ab4ec90b67ce02691741
  dependency-type: direct:production
  dependency-group: github-actions-updates
- dependency-name: sigstore/cosign-installer
  dependency-version: 3.8.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: github-actions-updates
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-05-06 11:47:15 +03:00
Harshil Sharma
a5e68639c2 Channel banner permissions (#30917)
* Fixed save state panel for channel banner

* Defined default background color

* Updated test

* WIP

* wip

* removed unused param

* Updated tests

* CI

* Fixed mmctl test

* Fixed TestDoAdvancedPermissionsMigration test

* Test update

* lint fix

* lint fix

---------

Co-authored-by: Mattermost Build <build@mattermost.com>
2025-05-06 14:03:35 +05:30
Harshil Sharma
d73222dca9 Channel banner misc fixes (#30907)
* Fixed save state panel for channel banner

* Defined default background color

* Updated test

---------

Co-authored-by: Mattermost Build <build@mattermost.com>
2025-05-06 14:02:41 +05:30
Daniel Espino García
257abbfb0d Fix edit positioning, including its tooltip (#30884) 2025-05-06 09:58:53 +02:00
Martin Mičuda
f66d530b19 Translated using Weblate (Czech)
Currently translated at 98.2% (6075 of 6184 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/cs/
2025-05-06 08:35:57 +02:00
Martin Mičuda
a67cc4e472 Translated using Weblate (Czech)
Currently translated at 98.2% (6074 of 6184 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/cs/
2025-05-06 08:35:57 +02:00
master7
2c82dade94 Translated using Weblate (Polish)
Currently translated at 100.0% (6184 of 6184 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/pl/
2025-05-06 08:35:57 +02:00
Pineoak
dfc10ad4f5 Translated using Weblate (Portuguese (Brazil))
Currently translated at 72.0% (4458 of 6184 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/pt_BR/
2025-05-06 08:35:57 +02:00
Pineoak
a7bbca8724 Translated using Weblate (Portuguese (Brazil))
Currently translated at 71.8% (4446 of 6184 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/pt_BR/
2025-05-06 08:35:57 +02:00
Pineoak
2ef0543ce3 Translated using Weblate (Portuguese (Brazil))
Currently translated at 71.8% (4446 of 6184 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/pt_BR/
2025-05-06 08:35:57 +02:00
Frank Paul Silye
dfd54ba9a8 Translated using Weblate (Norwegian Bokmål)
Currently translated at 78.7% (4869 of 6184 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/nb_NO/
2025-05-06 08:35:57 +02:00
Pineoak
7c3b9cb48f Translated using Weblate (Portuguese (Brazil))
Currently translated at 71.8% (4446 of 6184 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/pt_BR/
2025-05-06 08:35:57 +02:00
Pineoak
3042013d3b Translated using Weblate (Portuguese (Brazil))
Currently translated at 71.8% (4446 of 6184 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/pt_BR/
2025-05-06 08:35:57 +02:00
Pineoak
b535d03fa4 Translated using Weblate (Portuguese (Brazil))
Currently translated at 71.8% (4446 of 6184 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/pt_BR/
2025-05-06 08:35:57 +02:00
Frank Paul Silye
86e25822cf Translated using Weblate (Norwegian Bokmål)
Currently translated at 78.5% (4857 of 6184 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/nb_NO/
2025-05-06 08:35:57 +02:00
Bohdan
a39d9ca007 Translated using Weblate (Ukrainian)
Currently translated at 100.0% (6184 of 6184 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/uk/
2025-05-06 08:35:57 +02:00
Bohdan
acab46acd8 Translated using Weblate (Ukrainian)
Currently translated at 100.0% (2656 of 2656 strings)

Translation: Mattermost/server
Translate-URL: https://translate.mattermost.com/projects/mattermost/server/uk/
2025-05-06 08:35:57 +02:00
Frank Paul Silye
6f8c353203 Translated using Weblate (Norwegian Bokmål)
Currently translated at 78.5% (4855 of 6184 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/nb_NO/
2025-05-06 08:35:57 +02:00
Tom De Moor
4b8284c2b0 Translated using Weblate (Dutch)
Currently translated at 99.9% (6180 of 6184 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/nl/
2025-05-06 08:35:57 +02:00
Tom De Moor
17f159f0c6 Translated using Weblate (Dutch)
Currently translated at 99.6% (2648 of 2656 strings)

Translation: Mattermost/server
Translate-URL: https://translate.mattermost.com/projects/mattermost/server/nl/
2025-05-06 08:35:57 +02:00
MArtin Johnson
7abd3029f6 Translated using Weblate (Swedish)
Currently translated at 99.0% (6125 of 6184 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/sv/
2025-05-06 08:35:57 +02:00
MArtin Johnson
bfb3208599 Translated using Weblate (Swedish)
Currently translated at 100.0% (2656 of 2656 strings)

Translation: Mattermost/server
Translate-URL: https://translate.mattermost.com/projects/mattermost/server/sv/
2025-05-06 08:35:57 +02:00
Serhii Khomiuk
9d1d88f1b2 Translated using Weblate (Ukrainian)
Currently translated at 99.7% (2649 of 2656 strings)

Translation: Mattermost/server
Translate-URL: https://translate.mattermost.com/projects/mattermost/server/uk/
2025-05-06 08:35:57 +02:00
Frank Paul Silye
d4ec0ac163 Translated using Weblate (Norwegian Bokmål)
Currently translated at 78.2% (4842 of 6184 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/nb_NO/
2025-05-06 08:35:57 +02:00
Lukáš Mlčůch
ea3f90ef73 Translated using Weblate (Czech)
Currently translated at 100.0% (2656 of 2656 strings)

Translation: Mattermost/server
Translate-URL: https://translate.mattermost.com/projects/mattermost/server/cs/
2025-05-06 08:35:57 +02:00
master7
571283fb9f Translated using Weblate (Polish)
Currently translated at 99.6% (6160 of 6184 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/pl/
2025-05-06 08:35:57 +02:00
Lukáš Mlčůch
ac7ddc3f61 Translated using Weblate (Czech)
Currently translated at 97.9% (6056 of 6184 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/cs/
2025-05-06 08:35:57 +02:00
master7
da2cc9a98b Translated using Weblate (Polish)
Currently translated at 99.1% (6134 of 6184 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/pl/
2025-05-06 08:35:57 +02:00
jprusch
d5c123981f Translated using Weblate (German)
Currently translated at 100.0% (6184 of 6184 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/de/
2025-05-06 08:35:57 +02:00
jprusch
f9ff866019 Translated using Weblate (German)
Currently translated at 100.0% (2656 of 2656 strings)

Translation: Mattermost/server
Translate-URL: https://translate.mattermost.com/projects/mattermost/server/de/
2025-05-06 08:35:57 +02:00
Frank Paul Silye
1cd07132ae Translated using Weblate (Norwegian Bokmål)
Currently translated at 78.1% (4833 of 6184 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/nb_NO/
2025-05-06 08:35:57 +02:00
master7
10f9c25038 Translated using Weblate (Polish)
Currently translated at 99.1% (6133 of 6184 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/pl/
2025-05-06 08:35:57 +02:00
master7
486574f6db Translated using Weblate (Polish)
Currently translated at 100.0% (2656 of 2656 strings)

Translation: Mattermost/server
Translate-URL: https://translate.mattermost.com/projects/mattermost/server/pl/
2025-05-06 08:35:57 +02:00
Frank Paul Silye
3383400462 Translated using Weblate (Norwegian Bokmål)
Currently translated at 77.9% (4818 of 6184 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/nb_NO/
2025-05-06 08:35:57 +02:00
unified-ci-app[bot]
027704e922 Update latest minor version to 10.9.0 (#30943)
Automatic Merge
2025-05-06 09:28:43 +03:00
sabril
6a4407de76 E2E/Playwright: Refactor and fix tests for scheduled posts (#30871) 2025-05-06 11:27:18 +08:00
Harrison Healey
15efbb658f MM-63616 Remove react-hot-loader and hot-loader/react-dom (#30744) 2025-05-05 16:51:23 -04:00
Harrison Healey
0c38d893e3 Fix errcheck issue on master (#30938) 2025-05-05 16:36:25 +00:00
Ivy Gesare
1bca62dc83 [MM-61505] Fix errcheck issues in server/channels/app/team_test.go (#29146)
Co-authored-by: Ben Schumacher <ben.schumacher@mattermost.com>
2025-05-05 12:43:16 +02:00
kasyap dharanikota
ddb4c4360c fix errcheck in server/channels/app/platform/session.go (#30595)
Co-authored-by: Ben Schumacher <ben.schumacher@mattermost.com>
2025-05-05 12:18:47 +02:00
Harshil Sharma
b7ff54acee System console tiered license check (#30916)
* Make the Mobile Security settings available on Enterprise Advance

* rename to minLicenseTier

* used license tier checks in system console

* lint fix

* renamed license in test

* Made license name display in single line

---------

Co-authored-by: Elias Nahum <nahumhbl@gmail.com>
2025-05-05 14:18:48 +05:30
Scott Bishel
ea4ab9aa90 Mm 63903 handle undefined options (#30887)
* fixes for deleted/changed select/multiselect attributes

* add testing for prepending scheme to url

* test: add unit tests for select and multiselect with removed options

* trim trailing '/'

* update location property

* lint fixes

---------

Co-authored-by: Caleb Roseland <caleb@calebroseland.com>
2025-05-02 10:58:57 -06:00
Caleb Roseland
141cfe36d1 fix default field type if missing value_type in attrs (#30913) 2025-05-02 11:53:23 -05:00
Harshil Sharma
a76c063d85 Renamed premium SKU to Enterprise Advanced (#30882) 2025-05-02 11:34:46 +05:30
Jesse Hallam
e1f47e22e7 MM-62158: group store no SELECT * (Part 1) (#30276)
* improved test coverage

* initial pass on removing SELECT * from group store
2025-05-01 09:39:05 -03:00
Pablo Vélez
80c58a9742 MM-63649 - fix preview embeded images (#30685)
* MM-63649 - fix preview embeded images

* enhance utils function and simplify validations in file preview modal component

* add new test for proxied images without extension

* simplify logic; apply DRY  unifying it via helper function

* if extension is available in file info, use it first

* add extra validation for the extension lenght if fileInfo.extension is present

---------

Co-authored-by: Mattermost Build <build@mattermost.com>
2025-05-01 13:41:50 +02:00
Pablo Vélez
20f9f58e4c MM-63648 - markdown images sometimes do not show the more button (#30716)
* MM-63648 - markdown images sometimes do not show the more button

* migrate test to testing-library and remove unnecesary props

---------

Co-authored-by: Mattermost Build <build@mattermost.com>
2025-05-01 11:20:41 +02:00
Miguel de la Cruz
2decc2ccdb Prevent synced CPA values to be updated from the API (#30687)
* Prevents the API from updating synced CPA values

The patch functions for CPA values now accept a parameter that checks
if they should allow for synced values to be updated, and prevent
those updates if necessary

* Fix linter

* Fix parameter after merge

---------

Co-authored-by: Miguel de la Cruz <miguel@ctrlz.es>
Co-authored-by: Scott Bishel <scott.bishel@mattermost.com>
Co-authored-by: Mattermost Build <build@mattermost.com>
2025-04-30 18:43:05 +02:00
Matthew Birtch
a001367d43 MM-63911 Fix link copied behavior and style in get link modal (#30854)
* changed copy link behavior to match behavior elsewhere

* update timing, fix linting issues, fix style in modal header

* updated test

* updated test and snapshot

* fix linting error

* Fix snapshots

---------

Co-authored-by: yasserfaraazkhan <attitude3cena.yf@gmail.com>
2025-04-30 07:09:06 +00:00
Matthew Birtch
f09df430b9 File attachment overflow hiding menu (#30855)
Automatic Merge
2025-04-30 08:42:40 +03:00
Scott Bishel
077f8e5061 update menus for channel bookmarks (#30801)
Co-authored-by: Mattermost Build <build@mattermost.com>
2025-04-29 08:20:19 -06:00
Claudio Costa
d443db2c21 Prepackage Calls v1.7.1 (#30863) 2025-04-29 07:51:13 -06:00
Harrison Healey
55f844b300 MM-63851 Fix mobile view (#30836)
* MM-63851 Re-add divs around mobile view header

* Revert layout changes in mobile view header

* Finish removing CSS rule
2025-04-29 09:18:06 -04:00
Ashish Karhade
b110419162 update CONTRIBUTING.md and github ISSUE_TEMPLATE (#30862)
Automatic Merge
2025-04-29 15:42:40 +03:00
M-ZubairAhmed
4f80dda772 [MM-63794] Remove the Redux Selector telemetry (#30794) 2025-04-29 16:51:43 +05:30
Ben Schumacher
df3560ed9c [MM-61086] Fix errcheck linter issue in batch_worker_test.go (#30644) 2025-04-29 11:08:38 +02:00
Ben Schumacher
f1ddeec2f6 [MM-61778] Fix errcheck issues in web_hub_test.go (#30676)
Co-authored-by: Claude <noreply@anthropic.com>
2025-04-29 10:23:53 +02:00
Ben Schumacher
2f5b70bfa2 [MM-29108] Fix errcheck issues in server/channels/app/team.go (#30683)
Co-authored-by: Claude <noreply@anthropic.com>
2025-04-29 09:03:06 +02:00
Roy Orbitson
2a6adbe7e2 Typo (#30372)
Co-authored-by: Ben Schumacher <ben.schumacher@mattermost.com>
2025-04-29 09:00:33 +02:00
Ben Schumacher
d0c4780eb1 [MM-28761] Fix errcheck linter issues in hosted_purchase_screening worker (#30624) 2025-04-29 08:57:52 +02:00
Ben Schumacher
5ee308bd83 [MM-61467] Fix errcheck linter issues in post_test.go (#30686) 2025-04-29 08:50:47 +02:00
Harrison Healey
210bdfcb72 MM-63056/MM-63058/MM-63049 Improve accessibility of Threads list (#30816)
* MM-63056 Add accessible name to Threads item menus

* MM-63058 Add accessible name to Threads mark as unread button

* MM-63049 Change Threads list to use tab pattern for filtering

* Revert accidentally added i18n string
2025-04-28 15:54:50 -04:00
Julien Tant
22ce9b606f [MM-63802] Hide search team selector if user only member of one team (#30791)
Co-authored-by: Mattermost Build <build@mattermost.com>
2025-04-28 18:56:50 +00:00
Hosted Weblate
ca932e550d Update translation files
Updated by "Cleanup translation files" hook in Weblate.

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/
2025-04-28 17:26:29 +02:00
Frank Paul Silye
0b5a9ae21a Translated using Weblate (Norwegian Bokmål)
Currently translated at 78.5% (4826 of 6144 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/nb_NO/
2025-04-28 17:26:29 +02:00
master7
fe6ec462a8 Translated using Weblate (Polish)
Currently translated at 100.0% (6144 of 6144 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/pl/
2025-04-28 17:26:29 +02:00
MArtin Johnson
655744e9a9 Translated using Weblate (Swedish)
Currently translated at 100.0% (6144 of 6144 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/sv/
2025-04-28 17:26:29 +02:00
Tom De Moor
92e267e4ee Translated using Weblate (Dutch)
Currently translated at 99.9% (6142 of 6144 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/nl/
2025-04-28 17:26:29 +02:00
MArtin Johnson
d646bd980d Translated using Weblate (Swedish)
Currently translated at 100.0% (2651 of 2651 strings)

Translation: Mattermost/server
Translate-URL: https://translate.mattermost.com/projects/mattermost/server/sv/
2025-04-28 17:26:29 +02:00
Tom De Moor
fa0b149e19 Translated using Weblate (Dutch)
Currently translated at 99.6% (2643 of 2651 strings)

Translation: Mattermost/server
Translate-URL: https://translate.mattermost.com/projects/mattermost/server/nl/
2025-04-28 17:26:29 +02:00
Frank Paul Silye
9a92294d74 Translated using Weblate (Norwegian Bokmål)
Currently translated at 78.4% (4823 of 6144 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/nb_NO/
2025-04-28 17:26:29 +02:00
jprusch
2a5ce71284 Translated using Weblate (German)
Currently translated at 100.0% (6144 of 6144 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/de/
2025-04-28 17:26:29 +02:00
jprusch
99a6c8ef5a Translated using Weblate (German)
Currently translated at 100.0% (2651 of 2651 strings)

Translation: Mattermost/server
Translate-URL: https://translate.mattermost.com/projects/mattermost/server/de/
2025-04-28 17:26:29 +02:00
Frank Paul Silye
e8544246d4 Translated using Weblate (Norwegian Bokmål)
Currently translated at 78.1% (4803 of 6144 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/nb_NO/
2025-04-28 17:26:29 +02:00
ThrRip
3e8d80aca9 Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 100.0% (6144 of 6144 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/zh_Hans/
2025-04-28 17:26:29 +02:00
ThrRip
608ca11389 Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 100.0% (2651 of 2651 strings)

Translation: Mattermost/server
Translate-URL: https://translate.mattermost.com/projects/mattermost/server/zh_Hans/
2025-04-28 17:26:29 +02:00
Frank Paul Silye
be98a5f946 Translated using Weblate (Norwegian Bokmål)
Currently translated at 78.0% (4796 of 6144 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/nb_NO/
2025-04-28 17:26:29 +02:00
Benjamin Danon
2bf3d6690b Translated using Weblate (French)
Currently translated at 81.6% (5014 of 6144 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/fr/
2025-04-28 17:26:29 +02:00
Matthew Williams
4f0dfd9a1d Translated using Weblate (English (Australia))
Currently translated at 100.0% (6144 of 6144 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/en_AU/
2025-04-28 17:26:29 +02:00
master7
bed64d2336 Translated using Weblate (Polish)
Currently translated at 100.0% (2651 of 2651 strings)

Translation: Mattermost/server
Translate-URL: https://translate.mattermost.com/projects/mattermost/server/pl/
2025-04-28 17:26:29 +02:00
Matthew Williams
cdc46023b5 Translated using Weblate (English (Australia))
Currently translated at 100.0% (2651 of 2651 strings)

Translation: Mattermost/server
Translate-URL: https://translate.mattermost.com/projects/mattermost/server/en_AU/
2025-04-28 17:26:29 +02:00
Frank Paul Silye
21d9bee299 Translated using Weblate (Norwegian Bokmål)
Currently translated at 78.0% (4794 of 6144 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/nb_NO/
2025-04-28 17:26:29 +02:00
master7
279a220cc4 Translated using Weblate (Polish)
Currently translated at 100.0% (6144 of 6144 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/pl/
2025-04-28 17:26:29 +02:00
Serhii Khomiuk
7751ebfbdf Translated using Weblate (Ukrainian)
Currently translated at 100.0% (6144 of 6144 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/uk/
2025-04-28 17:26:29 +02:00
Serhii Khomiuk
dafc50f49a Translated using Weblate (Ukrainian)
Currently translated at 100.0% (2651 of 2651 strings)

Translation: Mattermost/server
Translate-URL: https://translate.mattermost.com/projects/mattermost/server/uk/
2025-04-28 17:26:29 +02:00
David Krauser
94dcd9f311 Upgrade logr to v2.0.22 (#30827) 2025-04-28 10:20:42 -04:00
Agniva De Sarker
efde5e2717 [AI assisted] MM-62755: Refactor scanning to map to a util (#30780)
With some neat generics, I was able to refactor
the scanning to a util function. I used it to
refactor 3 places and also removed an unnecessary method.

Claude was quite good here.

https://mattermost.atlassian.net/browse/MM-62755
```release-note
NONE
```
2025-04-28 19:21:12 +05:30
Ben Schumacher
cd5523f5fb MM-29092 Fix error handling in auto_environment.go (#30610)
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Caleb Roseland <caleb@calebroseland.com>
2025-04-28 15:05:31 +02:00
Ben Schumacher
eea39a5f23 [MM-61087] Fix errcheck linter issues in channels/jobs/helper_test.go (#30643)
Co-authored-by: Claude <noreply@anthropic.com>
2025-04-28 15:02:10 +02:00
Ben Schumacher
6a228877b7 [MM-28762] Fix errcheck issues in jobs.go (#30708)
Co-authored-by: Claude <noreply@anthropic.com>
2025-04-28 14:57:40 +02:00
Ben Schumacher
6fc60c8e5f [MM-61105] Fix errcheck linter errors in config_test.go (#30689) 2025-04-28 14:53:45 +02:00
Matthew Birtch
34fb9adbc2 MM-63800 Add label tag for create account checkbox (#30799)
* added proper label tag for checkbox

* fix linting issues

* updated cursor on checkbox label

* remove uneccessary class on span

* resolve lint error

* Update screenshots

---------

Co-authored-by: yasserfaraazkhan <attitude3cena.yf@gmail.com>
2025-04-25 12:35:25 -04:00
Harrison Healey
80b61ad79b MM-61611 Fix layout of emoji picker in mobile view (#30747)
* Stop emoji picker header from overlapping tabs

* Move emoji picker header above tabs

There was also some stuff I could remove because the header will always
be visible.

* Don't scroll the emoji picker on hover

* MM-61611 Fix emoji picker tabs being covered in mobile view

* Improve layout of emoji picker and gif picker

A lot of the emoji picker was explicitly sized before which made it
difficult to make everything responsive in mobile view. Making the emoji
picker layout into a flexbox fixed that, but due to the way that it's
nested, that was a bit tricky, and it required a couple tricks:

1. The AutoSizer doesn't work if it's placed inside a flexbox container,
   but you can fix that by putting a div with position: relative in
   between it and the flexbox parent. That was already the case, but I
   accidentally removed it while trying to sort out the seemingly
   excessive nesting.
2. Children of flexbox elements will cause the parent to expand if they
   don't have min-height/min-width set. That's because the default
   value for those is 0 outside of flexbox, but it's auto inside of one.

This breaks the layout and animation of the skin tone selector in the
emoji picker, but that has issues on master as well, so it'll be
addressed in the next commit.

* Improve and fix opening animation for skin tone selector

While this looked worse before in mobile view, it had some weirdness in
desktop as well. I ended up rewriting the way that that animation worked
so that I could position it correctly in both mobile (where it doesn't
cover the input) and desktop (where it does).

Notably, that change required:

1. Changing the skin tone selector to wait until its contents are hidden
   to unmount them so that the position and size could be calculated
   correctly.
2. Removed the flexbox from the search row and used a margin to make the
   skin tone button pretend to offset the input. That let us smoothy
   expand the selector over the input without having the input resize
   behind it.

* Update CSS for positioning emojis and headings in emoji picker
2025-04-25 19:28:31 +03:00
Jesse Hallam
291d5a2ba7 fix missing newline in upgrader.go (#30853) 2025-04-25 11:21:37 -03:00
Daniel Espino García
71334c6d8b Report a problem (#30444)
* Add report a problem type and allow logs config

* Improve device type logic

* Add tests and minor fixes

* Add texts

* Fix tests by avoiding circular dependencies

* Fix test

* Fix useexternallink updating mailtos, and changing the content of query parameters

* Fix texts

* Fix e2e test

* Fix tsc

---------

Co-authored-by: Mattermost Build <build@mattermost.com>
2025-04-25 11:08:39 +02:00
Agniva De Sarker
29f7c895b8 MM-63878: Fix INSERT IGNORE in saveChannelT (#30850)
INSERT IGNORE will ignore ALL errors in the INSERT statement.
This is not what was intended. The right way is to do a
redundant update on duplicate key.

It's not great, but that's how MySQL wants us to do it.

https://mattermost.atlassian.net/browse/MM-63878
```release-note
NONE
```
2025-04-24 21:29:09 +05:30
Arya Khochare
faf68a6d86 MM-56630 Scroll Fix of center panel (#30144)
* pageup/pagedown button scroll for center post-list

* revert package.json

* changing id, using ? and returning in keyHandler

* added e2e test for pageup/pagedown scroll

* Fix dynamic-virtualized-list not being in lockfile and update path

Moving the package under the MM namespace wasn't necessary, but it stops
some warnings from NPM.

* Move E2E test from Cypress to Playwright

Cypress's cy.type doesn't seem to properly trigger browser functions
because it doesn't seem to use native keyboard events. A newer version
of Cypress has a new cy.press method which is supposed to use native
keyboard events, but it also only supports the tab key currently, so it
wouldn't be useful here.

* Fix new test on iPad

* Add page up/down support to RHS and Threads view

* Update type definitions for dynamic-virtualized-list

---------

Co-authored-by: Harrison Healey <harrisonmhealey@gmail.com>
2025-04-24 11:15:40 -04:00
Pablo Vélez
89319cafb1 Mm 61590 - trap focus in modals (#30622)
* MM-61590 - trap focus in modals

* Adjust focus trap for dynamic loading elements and multi modal support

* add tests and improve code in generic modal

* fix snapshot

---------

Co-authored-by: Mattermost Build <build@mattermost.com>
2025-04-24 11:46:36 +02:00
Agniva De Sarker
131cf039bb MM-63756: Added index to sidebarchannels table (#30724)
The (s SqlChannelStore) getSidebarCategoriesT gets called quite frequently.
- Team switch
- WS reconnect
- Category created
- Category updated
- Category deleted

Of these 1 and 2 are probably the most commonly called sources. Based on that,
the sidebarChannels table is not that well-optimized. Even though
the query time might be reasonable, without an index, it has to churn a lot of
DB CPU for a sequential scan.

We add a new index to optimize this.

CREATE INDEX idx_sidebarchannels_categoryid ON sidebarchannels(categoryid);

```
Before:
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
 Sort  (cost=40854.18..40854.19 rows=4 width=193) (actual time=251.635..251.646 rows=204 loops=1)
   Sort Key: sidebarcategories.sortorder, sidebarchannels.sortorder
   Sort Method: quicksort  Memory: 65kB
   Buffers: shared hit=1203 read=23668
   ->  Nested Loop  (cost=8.87..40854.14 rows=4 width=193) (actual time=251.345..251.455 rows=204 loops=1)
         Buffers: shared hit=1203 read=23668
         ->  Nested Loop  (cost=0.41..9.47 rows=1 width=54) (actual time=0.068..0.074 rows=1 loops=1)
               Buffers: shared hit=5
               ->  Seq Scan on teams  (cost=0.00..1.03 rows=1 width=27) (actual time=0.024..0.026 rows=1 loops=1)
                     Filter: (((id)::text = '3ee5y5ok6jgxicrmqstdnghmfr'::text) AND (deleteat = 0))
                     Rows Removed by Filter: 1
                     Buffers: shared hit=1
               ->  Index Scan using teammembers_pkey on teammembers  (cost=0.41..8.43 rows=1 width=27) (actual time=0.039..0.043 rows=1 loops=1)
                     Index Cond: (((teamid)::text = '3ee5y5ok6jgxicrmqstdnghmfr'::text) AND ((userid)::text = 'tc3p1yqw67d8idcp3g98awexqe'::text))
                     Filter: (deleteat = 0)
                     Buffers: shared hit=4
         ->  Hash Right Join  (cost=8.45..40844.62 rows=4 width=193) (actual time=251.274..251.361 rows=204 loops=1)
               Hash Cond: ((sidebarchannels.categoryid)::text = (sidebarcategories.id)::text)
               Buffers: shared hit=1198 read=23668
               ->  Seq Scan on sidebarchannels  (cost=0.00..37514.77 rows=1265277 width=100) (actual time=0.043..99.345 rows=1265444 loops=1)
                     Buffers: shared hit=1194 read=23668
               ->  Hash  (cost=8.44..8.44 rows=1 width=158) (actual time=0.047..0.047 rows=6 loops=1)
                     Buckets: 1024  Batches: 1  Memory Usage: 10kB
                     Buffers: shared hit=4
                     ->  Index Scan using idx_sidebarcategories_userid_teamid on sidebarcategories  (cost=0.42..8.44 rows=1 width=158) (actual time=0.029..0.037 rows=6 loops=1)
                           Index Cond: (((userid)::text = 'tc3p1yqw67d8idcp3g98awexqe'::text) AND ((teamid)::text = '3ee5y5ok6jgxicrmqstdnghmfr'::text))
                           Buffers: shared hit=4
 Planning:
   Buffers: shared hit=9
 Planning Time: 1.215 ms
 Execution Time: 251.755 ms
(31 rows)

After:
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
 Sort  (cost=1544.53..1544.54 rows=4 width=192) (actual time=0.834..0.859 rows=204 loops=1)
   Sort Key: sidebarcategories.sortorder, sidebarchannels.sortorder
   Sort Method: quicksort  Memory: 65kB
   Buffers: shared hit=58
   ->  Nested Loop Left Join  (cost=8.53..1544.49 rows=4 width=192) (actual time=0.066..0.252 rows=204 loops=1)
         Buffers: shared hit=58
         ->  Nested Loop  (cost=0.83..17.93 rows=1 width=157) (actual time=0.042..0.098 rows=6 loops=1)
               Buffers: shared hit=34
               ->  Nested Loop  (cost=0.42..9.48 rows=1 width=157) (actual time=0.030..0.049 rows=6 loops=1)
                     Buffers: shared hit=10
                     ->  Index Scan using idx_sidebarcategories_userid_teamid on sidebarcategories  (cost=0.42..8.44 rows=1 width=157) (actual time=0.018..0.022 rows=6 loops=1)
                           Index Cond: (((userid)::text = 'tc3p1yqw67d8idcp3g98awexqe'::text) AND ((teamid)::text = '3ee5y5ok6jgxicrmqstdnghmfr'::text))
                           Buffers: shared hit=4
                     ->  Seq Scan on teams  (cost=0.00..1.03 rows=1 width=27) (actual time=0.002..0.003 rows=1 loops=6)
                           Filter: (((id)::text = '3ee5y5ok6jgxicrmqstdnghmfr'::text) AND (deleteat = 0))
                           Rows Removed by Filter: 1
                           Buffers: shared hit=6
               ->  Index Scan using teammembers_pkey on teammembers  (cost=0.41..8.43 rows=1 width=27) (actual time=0.007..0.007 rows=1 loops=6)
                     Index Cond: (((teamid)::text = '3ee5y5ok6jgxicrmqstdnghmfr'::text) AND ((userid)::text = 'tc3p1yqw67d8idcp3g98awexqe'::text))
                     Filter: (deleteat = 0)
                     Buffers: shared hit=24
         ->  Bitmap Heap Scan on sidebarchannels  (cost=7.69..1522.35 rows=421 width=100) (actual time=0.012..0.017 rows=34 loops=6)
               Recheck Cond: ((categoryid)::text = (sidebarcategories.id)::text)
               Heap Blocks: exact=6
               Buffers: shared hit=24
               ->  Bitmap Index Scan on idx_sidebarchannels_categoryid  (cost=0.00..7.58 rows=421 width=0) (actual time=0.010..0.010 rows=34 loops=6)
                     Index Cond: ((categoryid)::text = (sidebarcategories.id)::text)
                     Buffers: shared hit=18
 Planning:
   Buffers: shared hit=18
 Planning Time: 0.543 ms
 Execution Time: 0.968 ms
(32 rows)
```

I have also looked at potentially re-ordering the JOINs to make
sidebarchannels and sidebarcategories JOIN earlier, but that didn't give
a major benefit.

Also looked at adding a compound index with (categoryid, sortorder) to improve
sorting performance, but that didn't give a major benefit from what the single
column index already gives.

The `completePopulatingCategoryChannelsT` query also partially benefits
from this. But the Postgres optimizer sometimes selects the index on categoryId
and sometimes on ChannelId, both giving equivalent performance. So there's no major
improvement there, but at the same time, no regression as well.

```
Original:
[bigdb] # EXPLAIN (ANALYZE, BUFFERS) SELECT Id FROM ChannelMembers LEFT JOIN Channels ON Channels.Id=ChannelMembers.ChannelId WHERE (ChannelMembers.UserId = 'tc3p1yqw67d8idcp3g98awexqe' AND Channels.Type IN ('D'
                                                                                                                                                                                                                ,'G') AND Channels.DeleteAt = 0 AND NOT EXISTS ( SELECT 1 FROM SidebarChannels JOIN SidebarCategories on SidebarChannels.CategoryId=SidebarCategories.Id WHERE (SidebarChannels.ChannelId = ChannelMembers.ChannelI
                                                                                                                                                                                                                                                                                                                                                                                d AND SidebarCategories.UserId = 'tc3p1yqw67d8idcp3g98awexqe' AND SidebarCategories.TeamId = '3ee5y5ok6jgxicrmqstdnghmfr') )) ORDER BY DisplayName ASC;
                                                                                            QUERY PLAN
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
 Sort  (cost=5864.68..5865.84 rows=463 width=40) (actual time=9.008..9.022 rows=39 loops=1)
   Sort Key: channels.displayname
   Sort Method: quicksort  Memory: 27kB
   Buffers: shared hit=2112
   ->  Nested Loop Anti Join  (cost=1.96..5844.18 rows=463 width=40) (actual time=0.188..8.932 rows=39 loops=1)
         Buffers: shared hit=2112
         ->  Nested Loop  (cost=0.99..3476.66 rows=463 width=67) (actual time=0.159..7.952 rows=39 loops=1)
               Buffers: shared hit=1956
               ->  Index Only Scan using idx_channelmembers_user_id_channel_id_last_viewed_at on channelmembers  (cost=0.56..40.78 rows=470 width=27) (actual time=0.036..0.467 rows=437 loops=1)
                     Index Cond: (userid = 'tc3p1yqw67d8idcp3g98awexqe'::text)
                     Heap Fetches: 45
                     Buffers: shared hit=208
               ->  Memoize  (cost=0.43..7.69 rows=1 width=40) (actual time=0.016..0.016 rows=0 loops=437)
                     Cache Key: channelmembers.channelid
                     Cache Mode: logical
                     Hits: 0  Misses: 437  Evictions: 0  Overflows: 0  Memory Usage: 42kB
                     Buffers: shared hit=1748
                     ->  Index Scan using channels_pkey on channels  (cost=0.42..7.68 rows=1 width=40) (actual time=0.015..0.015 rows=0 loops=437)
                           Index Cond: ((id)::text = (channelmembers.channelid)::text)
                           Filter: ((type = ANY ('{D,G}'::channel_type[])) AND (deleteat = 0))
                           Rows Removed by Filter: 1
                           Buffers: shared hit=1748
         ->  Nested Loop  (cost=0.97..5.10 rows=1 width=27) (actual time=0.023..0.023 rows=0 loops=39)
               Buffers: shared hit=156
               ->  Index Only Scan using sidebarchannels_pkey on sidebarchannels  (cost=0.55..4.56 rows=1 width=92) (actual time=0.022..0.022 rows=0 loops=39)
                     Index Cond: (channelid = (channelmembers.channelid)::text)
                     Heap Fetches: 0
                     Buffers: shared hit=156
               ->  Index Scan using sidebarcategories_pkey on sidebarcategories  (cost=0.42..0.48 rows=1 width=65) (never executed)
                     Index Cond: ((id)::text = (sidebarchannels.categoryid)::text)
                     Filter: (((userid)::text = 'tc3p1yqw67d8idcp3g98awexqe'::text) AND ((teamid)::text = '3ee5y5ok6jgxicrmqstdnghmfr'::text))
 Planning:
   Buffers: shared hit=48 dirtied=1
 Planning Time: 2.222 ms
 Execution Time: 9.142 ms
(35 rows)

New:
[bigdb] # EXPLAIN (ANALYZE, BUFFERS) SELECT Id FROM ChannelMembers LEFT JOIN Channels ON Channels.Id=ChannelMembers.ChannelId WHERE (ChannelMembers.UserId = 'tc3p1yqw67d8idcp3g98awexqe' AND Channels.Type IN ('D'
                                                                                                                                                                                                                ,'G') AND Channels.DeleteAt = 0 AND NOT EXISTS ( SELECT 1 FROM SidebarChannels JOIN SidebarCategories on SidebarChannels.CategoryId=SidebarCategories.Id WHERE (SidebarChannels.ChannelId = ChannelMembers.ChannelId AND SidebarCategories.UserId = 'tc3p1yqw67d8idcp3g98awexqe' AND SidebarCategories.TeamId = '3ee5y5ok6jgxicrmqstdnghmfr') )) ORDER BY DisplayName ASC;
                                                                                            QUERY PLAN
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
 Sort  (cost=5059.95..5061.11 rows=463 width=40) (actual time=12.072..12.086 rows=39 loops=1)
   Sort Key: channels.displayname
   Sort Method: quicksort  Memory: 27kB
   Buffers: shared hit=1984
   ->  Nested Loop Anti Join  (cost=9.10..5039.45 rows=463 width=40) (actual time=0.751..12.009 rows=39 loops=1)
         Join Filter: ((sidebarchannels.channelid)::text = (channelmembers.channelid)::text)
         Rows Removed by Join Filter: 7839
         Buffers: shared hit=1984
         ->  Nested Loop  (cost=0.99..3476.66 rows=463 width=67) (actual time=0.161..7.579 rows=39 loops=1)
               Buffers: shared hit=1956
               ->  Index Only Scan using idx_channelmembers_user_id_channel_id_last_viewed_at on channelmembers  (cost=0.56..40.78 rows=470 width=27) (actual time=0.036..0.449 rows=437 loops=1)
                     Index Cond: (userid = 'tc3p1yqw67d8idcp3g98awexqe'::text)
                     Heap Fetches: 45
                     Buffers: shared hit=208
               ->  Memoize  (cost=0.43..7.69 rows=1 width=40) (actual time=0.016..0.016 rows=0 loops=437)
                     Cache Key: channelmembers.channelid
                     Cache Mode: logical
                     Hits: 0  Misses: 437  Evictions: 0  Overflows: 0  Memory Usage: 42kB
                     Buffers: shared hit=1748
                     ->  Index Scan using channels_pkey on channels  (cost=0.42..7.68 rows=1 width=40) (actual time=0.014..0.014 rows=0 loops=437)
                           Index Cond: ((id)::text = (channelmembers.channelid)::text)
                           Filter: ((type = ANY ('{D,G}'::channel_type[])) AND (deleteat = 0))
                           Rows Removed by Filter: 1
                           Buffers: shared hit=1748
         ->  Materialize  (cost=8.11..1535.03 rows=4 width=27) (actual time=0.003..0.046 rows=201 loops=39)
               Buffers: shared hit=28
               ->  Nested Loop  (cost=8.11..1535.01 rows=4 width=27) (actual time=0.099..0.383 rows=201 loops=1)
                     Buffers: shared hit=28
                     ->  Index Scan using idx_sidebarcategories_userid_teamid on sidebarcategories  (cost=0.42..8.44 rows=1 width=65) (actual time=0.047..0.057 rows=6 loops=1)
                           Index Cond: (((userid)::text = 'tc3p1yqw67d8idcp3g98awexqe'::text) AND ((teamid)::text = '3ee5y5ok6jgxicrmqstdnghmfr'::text))
                           Buffers: shared hit=4
                     ->  Bitmap Heap Scan on sidebarchannels  (cost=7.69..1522.35 rows=421 width=92) (actual time=0.028..0.040 rows=34 loops=6)
                           Recheck Cond: ((categoryid)::text = (sidebarcategories.id)::text)
                           Heap Blocks: exact=6
                           Buffers: shared hit=24
                           ->  Bitmap Index Scan on idx_sidebarchannels_categoryid  (cost=0.00..7.58 rows=421 width=0) (actual time=0.023..0.023 rows=34 loops=6)
                                 Index Cond: ((categoryid)::text = (sidebarcategories.id)::text)
                                 Buffers: shared hit=18
 Planning:
   Buffers: shared hit=51
 Planning Time: 2.240 ms
 Execution Time: 12.210 ms
(42 rows)
```

Analysis on MySQL for completion:
```
Before:
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| -> Sort: SidebarCategories.SortOrder, SidebarChannels.SortOrder  (actual time=277.675..277.675 rows=4 loops=1)
    -> Stream results  (cost=138558.36 rows=1287808) (actual time=242.506..277.650 rows=4 loops=1)
        -> Left hash join (<hash>(SidebarChannels.CategoryId)=<hash>(SidebarCategories.Id)), extra conditions: (SidebarChannels.CategoryId = SidebarCategories.Id)  (cost=138558.36 rows=1287808) (actual time=242.498..277.626 rows=4 loops=1)
            -> Index lookup on SidebarCategories using idx_sidebarcategories_userid_teamid (UserId='qdggj9pyobgkjpj8htwzizks1r', TeamId='xmh7bupzajnudqf3h4mm76qapy')  (cost=1.40 rows=4) (actual time=0.092..0.094 rows=4 loops=1)
            -> Hash
                -> Table scan on SidebarChannels  (cost=8394.55 rows=321952) (actual time=0.123..106.334 rows=300002 loops=1)
 |
+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

After:
----------------------------------------------------------------+
| -> Sort: SidebarCategories.SortOrder, SidebarChannels.SortOrder  (actual time=0.739..0.742 rows=4 loops=1)
    -> Stream results  (cost=6.80 rows=7) (actual time=0.468..0.703 rows=4 loops=1)
        -> Nested loop left join  (cost=6.80 rows=7) (actual time=0.456..0.673 rows=4 loops=1)
            -> Index lookup on SidebarCategories using idx_sidebarcategories_userid_teamid (UserId='qdggj9pyobgkjpj8htwzizks1r', TeamId='xmh7bupzajnudqf3h4mm76qapy')  (cost=4.38 rows=4) (actual time=0.302..0.313 rows=4 loops=1)
            -> Index lookup on SidebarChannels using idx_sidebarchannels_categoryid (CategoryId=SidebarCategories.Id)  (cost=0.48 rows=2) (actual time=0.085..0.087 rows=0 loops=4)
 |
+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
```

Timing wise, it takes around 2s to add the index on a table with 1.2M rows
for Postgres. And it takes around 5s on MySQL on a table with 300K rows.
It looks like it takes longer on MySQL, but since both migrations are
non-locking, it should be fine.

https://mattermost.atlassian.net/browse/MM-63756
```release-note
NONE
```
2025-04-24 12:11:28 +05:30
Jesse Hallam
011f179831 avoid SELECT * in preference store (#30835) 2025-04-23 15:06:04 -04:00
Agniva De Sarker
271d928e87 MM-63467: Refactor constLabels to a common initializer (#30779)
This is useful to avoid mistakes while adding new metrics.

https://mattermost.atlassian.net/browse/MM-63467

```release-note
NONE
```

Co-authored-by: Mattermost Build <build@mattermost.com>
2025-04-23 21:59:51 +05:30
Pablo Vélez
6ae0efd285 MM61173 - settings modal base creation (#30338)
* MM-61173 - channel settings modal: base modal, initial commit, file creation and base component

* new enhancements to the base modal creation

* revert changes on textbox_links and edit channel header

* fix types and add back unintentioned deleted value

* add the preview textbox component

* extract logic for info tab into its own component

* add the purpose input to the window

* move other component logic to its own component and code clean up

* ability to update channel type

* more advances on the archive channel tab

* fix unit test in textbox

* fix translations

* do not show the archive modal in default channel

* fix issue with url editor not being resetted on undo action

* adjust text and styling for the header and purpose inputs

* remove textboxlinks and use button eye icon

* adjust test and preview button style

* add unit test to channel patch

* move logic from parent modal to info tab component

* fix border issues and focus back to preview textareas

* prevent saving changes when pressing enter when selecting an icon

* enhance input component to cover limits validations and enhances tests

* set default error message for save changes panel

* add props to provide custom value to the buttons

* remove channel input errors on reset button click

* create new component settings textbox

* rename component to advanced textbox and add unit tests

* styling of the info tab and add error state to advanced textbox

* add logic to prevent tab switch with unsaved changes

* adjust url error logic and code clean up

* code clean up and enhance comments

* add char min length to advanced textbox logic

* add the channel settings modal to the new menu

* add new test files and fix reset error

* remove unused error variables

* adjust translations and remove unncesary import

* enhance permissions for archive channels and manage channel settings

* Adjust permission tree so channel admins can convert from private to public

* enhance the test suit around channel conversion type

* fix some e2e tests and solve channel input name issue

* fix unit test by interacting first with the input element

* adjust e2e tests to channel settings modal changes

* remove commented tests and implement pr feedback

* adjust more pr feedback to the code

* more pr feedback enhancements

* further enhancements to tab navigation, and adjust more e2e tests

* remove unused components and fix e2e tests

* revert unnecessary permissions changes

* Add name label to textboxes

* adjust e2e and unit tests

* revert min lenght change value and adjust tests and snapshots

* Channel banner settings (#30721)

* Added channel banner setting header

* Updated section styling

* handled animation

* handled min and max lengths

* cleanup

* color change fix

* general improvements

* Fixed API test

* removed unused param className

* added e2e tests

* test: add channel settings configuration tab test file

* Based on the context, here's a concise commit message for this change:

feat: Add comprehensive tests for ChannelSettingsConfigurationTab

* added some more tests

* CI

* reverted package-lock.json changes in Playwright

* remove extra border from advaced textbox

* adjust styling for name label in advance texbox and restart preview state on modal close

* sync package.lock in playwright

---------

Co-authored-by: Mattermost Build <build@mattermost.com>
Co-authored-by: Harshil Sharma <harshilsharma63@gmail.com>
Co-authored-by: Harshil Sharma <18575143+harshilsharma63@users.noreply.github.com>
2025-04-23 12:49:54 +02:00
Amy Blais
f0dfe1c49f Updated minimum supported Edge, Chrome and Firefox versions (#30825)
Automatic Merge
2025-04-23 11:42:43 +03:00
Jesse Hallam
f6aeca7e50 avoid SELECT * in jobs store (#30832) 2025-04-23 12:11:09 +05:30
Jesse Hallam
3c9b2511bc avoid SELECT * in audit store (#30829) 2025-04-23 08:37:06 +02:00
M-ZubairAhmed
e9c54bf88e [MM-63685] Virtualize drafts in the drafts list (#30563) 2025-04-23 11:38:04 +05:30
Julien Tant
282f0769e5 [MM-62517] Improve cross team search UI (#30698)
Co-authored-by: Mattermost Build <build@mattermost.com>
2025-04-22 23:36:45 +00:00
Jesse Hallam
94bc32b50c avoid SELECT * in cluster discovery store (#30830) 2025-04-23 05:08:43 +08:00
Jesse Hallam
b095ba22b8 avoid SELECT * in notify admin store (#30834) 2025-04-22 17:27:33 -03:00
Devin Binnie
a36d29b459 [MM-63023] Conditionally make thread item elements focusable based on whether they have an interaction (#30592)
* [MM-63023] Conditionally make thread item elements focusable based on whether they have an interaction

* Fix i18n & PR feedback

* Remove focusability from the text preview div

* Fix tests
2025-04-22 15:55:30 -04:00
Jesse Hallam
018c909e2f avoid SELECT * in command stores (#30831)
* avoid SELECT * in command stores

* Define column names once and reuse as columns list in selects and inserts

* Define column names once and reuse with ExecBuilder
2025-04-22 19:37:10 +00:00
Harrison Healey
32ce2f13bb MM-62382/MM-63615 Remove explicit reference to react-popper and remaining references to popper.js (#30743)
* Replace usage of react-popper in onboarding with floating-ui

* Remove direct dependency on react-popper

Compass components still depend on react-popper, but none of the web app
code does any more.

* Remove direct dependency on popper.js

* Remove unneeded dependency on @types/bootstrap and remaining indirect dependency on popper.js
2025-04-22 15:35:21 -04:00
Jesse Hallam
981d1d869a avoid SELECT * in channel member history store (#30828) 2025-04-22 15:33:32 -04:00
Jesse Hallam
eb8aaba1bf avoid SELECT * in link metadata store (#30833)
* avoid SELECT * in link metadata store

* Address PR comment: define column names once and reuse
2025-04-22 19:29:09 +00:00
Jesse Hallam
701ddc896a MM-63791: guest permissions to teams (#30789)
* improve th.CreateGuestAndClient

* test coverage for guest user access to teams

* restrict guest access to public teams unless a member
2025-04-22 10:12:22 -03:00
Caleb Roseland
79561c44c2 MM-63276, MM-62707: CPA LDAP/SAML links and Duplicate field (#30772)
* Squashed commit of the following:

commit 42ef1ff8c3ff881b0f21cb4de23a5964f0bb106b
Merge: 4940da4326 c049748b88
Author: Mattermost Build <build@mattermost.com>
Date:   Fri Mar 14 21:15:22 2025 +0200

    Merge branch 'master' into MM-62695

commit 4940da4326ff787dd43fc486f06be415257181ae
Author: Julien Tant <julien@craftyx.fr>
Date:   Fri Mar 14 12:14:45 2025 -0700

    manage error the same way property field and value do

commit cd9ec590264ca3751a55fc0926318cbb6f46d471
Author: Julien Tant <julien@craftyx.fr>
Date:   Fri Mar 14 12:05:02 2025 -0700

    sanitize and validate

commit 2672e90b06331ff2e31a7807737cc1feff1c1beb
Author: Julien Tant <julien@craftyx.fr>
Date:   Fri Mar 14 12:02:20 2025 -0700

    use Len test method

commit d101950d655c7d6fd7a668a15554cc52a1d42667
Author: Julien Tant <julien@craftyx.fr>
Date:   Fri Mar 14 11:59:12 2025 -0700

    rearrange consts

commit ed1b8f66fb08f7be38615ced74282380d5d680b7
Author: Julien Tant <julien@craftyx.fr>
Date:   Fri Mar 14 11:58:56 2025 -0700

    rename CPASortOrder method

commit d3bc303fa3c9694d2f6d1531186f4fbe69efb956
Author: Julien Tant <julien@craftyx.fr>
Date:   Fri Mar 14 11:54:24 2025 -0700

    rename CustomProfileAttributes in method to CPA

commit b2323d44a6c3f31ea7c798f8a88c62878d5d2cdf
Author: Julien Tant <julien@craftyx.fr>
Date:   Fri Mar 14 11:54:02 2025 -0700

    Add SAML and LDAP attr

commit d411ae9da5a078cfbac60c5662bee27622ff31e5
Author: Julien Tant <julien@craftyx.fr>
Date:   Wed Mar 12 11:58:21 2025 -0700

    i18n

commit 27bc74c71462ae08d496104c908454ebc4f2def3
Author: Julien Tant <julien@craftyx.fr>
Date:   Wed Mar 12 11:11:23 2025 -0700

    fix TestDeleteCPAField test

commit 0d77071225d8575ace89cbe38c6c06fa94d7696b
Author: Julien Tant <julien@craftyx.fr>
Date:   Wed Mar 12 10:28:49 2025 -0700

    err->appErr

commit fe87a68caa49c7264c20c32cd4f598ffd18d503f
Author: Julien Tant <julien@craftyx.fr>
Date:   Wed Mar 12 10:22:13 2025 -0700

    i18n

commit 3b3ddf978fce66d9506416a10c03b21d6a12e9d0
Author: Julien Tant <julien@craftyx.fr>
Date:   Wed Mar 12 10:21:12 2025 -0700

    tests

commit 2f898bd53b832dea60dcdb960a71cd47709cddf8
Author: Julien Tant <julien@craftyx.fr>
Date:   Tue Mar 11 15:09:12 2025 -0700

    add validation and tests

commit a8c20841af6e82a6bf4f5dde6324b5e56c4d754e
Author: Julien Tant <julien@craftyx.fr>
Date:   Tue Mar 11 13:45:53 2025 -0700

    code style

commit 5bb3868b2ce93b9eb6e9d0836c597fa1176fbbbd
Merge: a4180d5d8f 7c25de2cff
Author: Mattermost Build <build@mattermost.com>
Date:   Tue Mar 11 22:24:06 2025 +0200

    Merge branch 'master' into MM-62695

commit a4180d5d8ff5e23a7a0a73b08806d37289e076ce
Author: Julien Tant <julien@craftyx.fr>
Date:   Tue Feb 25 11:53:54 2025 -0700

    use CPAField

commit 988177024ceebe73750ce48c40ea0a9ca6db75d6
Author: Julien Tant (aider) <julien@craftyx.fr>
Date:   Tue Feb 25 10:52:47 2025 -0700

    refactor: Move validateCustomProfileAttributesField to Validate method on CPAField struct

commit 783e64472c7ef3c1e33ce9a94b0716e96a72b105
Author: Julien Tant <julien@craftyx.fr>
Date:   Tue Feb 25 10:52:45 2025 -0700

    refactor: Improve custom profile attributes field handling and validation

commit aee06af59c748e74e5dc7718c1529527ac8c052a
Author: Julien Tant (aider) <julien@craftyx.fr>
Date:   Tue Feb 25 10:50:29 2025 -0700

    test: Add test case for CPA field with empty attributes

commit 7ab4455f9feb88826fcf6abb3b93a8a7bb53ed3e
Author: Julien Tant <julien@craftyx.fr>
Date:   Tue Feb 25 10:50:28 2025 -0700

    refactor: Cleanup whitespace and remove empty Attrs in custom profile attributes test

commit dbdb47d75818d58739c3962d8624388214382611
Author: Julien Tant (aider) <julien@craftyx.fr>
Date:   Tue Feb 25 10:48:08 2025 -0700

    test: Add test case for property field with empty attributes

commit 43872e06933b40f45caadbca7708eab283cebd8d
Author: Julien Tant (aider) <julien@craftyx.fr>
Date:   Tue Feb 25 10:44:39 2025 -0700

    test: Add tests for NewCPAFieldFromPropertyField and CPAFieldToPropertyField

commit 335f6b5c8901b6ecdc1e9f031a81695ffc269029
Merge: 01f632db46 e8ef26196c
Author: Julien Tant <julien@craftyx.fr>
Date:   Tue Feb 25 10:05:43 2025 -0700

    Merge branch 'master' into MM-62695

commit 01f632db46cf0eeeea0bac337b10c66fad815a24
Author: Julien Tant <julien@craftyx.fr>
Date:   Thu Feb 13 19:16:33 2025 -0700

    removed unused i18n

commit 0214d7eb947d3d8ecfde169cb07c210ecbfc9c92
Merge: db0e371ca2 68c11e9ecb
Author: Julien Tant <julien@craftyx.fr>
Date:   Thu Feb 13 19:15:08 2025 -0700

    Merge remote-tracking branch 'origin/master' into MM-62695

commit db0e371ca239b5286e58ad264c46a8891eafbe9b
Author: Julien Tant <julien@craftyx.fr>
Date:   Thu Feb 13 19:05:58 2025 -0700

    generic options

commit 3cd62774a1b54e5e9da0c1c5b2626de4f49116ca
Merge: d95e5d9838 41e0f97176
Author: Julien Tant <julien@craftyx.fr>
Date:   Thu Feb 13 10:48:47 2025 -0700

    Merge remote-tracking branch 'origin/master' into MM-62695

commit d95e5d9838b9b00bd4ef9ec066df03cfc52596d7
Author: Julien Tant <julien@craftyx.fr>
Date:   Wed Feb 12 17:07:28 2025 -0700

    style

commit 2256076ed174b25a5decc2631ee6abaa9fa1a3c1
Author: Julien Tant (aider) <julien@craftyx.fr>
Date:   Wed Feb 12 17:06:22 2025 -0700

    refactor: Make color field optional in custom profile attributes

commit 7382b8ecb3964083d24d879210aa3d137983b404
Author: Julien Tant <julien@craftyx.fr>
Date:   Wed Feb 12 16:40:10 2025 -0700

    fix api test

commit a54c2d653f9a2e46d989181f9ef5ffd3dcbdb8c0
Author: Julien Tant <julien@craftyx.fr>
Date:   Wed Feb 12 16:02:27 2025 -0700

    lint

commit 9d2e3f78f6ba836b599df7f3cdd4766bf47cd600
Author: Julien Tant <julien@craftyx.fr>
Date:   Wed Feb 12 15:50:31 2025 -0700

    use custom types rather than string

commit 4624df52cbda3cb9b0f8fa60b7a3d4f5ecf1c845
Author: Julien Tant (aider) <julien@craftyx.fr>
Date:   Wed Feb 12 15:40:52 2025 -0700

    refactor: Use consistent "ValidateCPAField" in error messages for custom profile attributes

commit 42716170b7158cc4d3ce06cfef36046be6290def
Author: Julien Tant <julien@craftyx.fr>
Date:   Wed Feb 12 15:36:04 2025 -0700

    fix casing in custom profilte attributes test

commit bcca3d87c47efcf95fcea2d1b380ce8aee89f7d4
Author: Julien Tant (aider) <julien@craftyx.fr>
Date:   Wed Feb 12 15:33:26 2025 -0700

    refactor: Modify CustomProfileAttributesSelectOption to use lowercase JSON keys

commit 861e12c1fcaedb69d331120bd4ae58757df1fae1
Author: Julien Tant <julien@craftyx.fr>
Date:   Wed Feb 12 15:29:23 2025 -0700

    i18n

commit a44f6f40eb5babab5f72a49078bec110a4645ddb
Author: Julien Tant <julien@craftyx.fr>
Date:   Wed Feb 12 15:21:08 2025 -0700

    improve test

commit b2f002016fb7438a4507f9cb1cc236a43fb71e27
Author: Julien Tant (aider) <julien@craftyx.fr>
Date:   Wed Feb 12 15:10:00 2025 -0700

    test: Add test case for preserving option IDs when patching select field

commit aac155ef23866d7b85ef49483eec5b610b2a8bc0
Author: Julien Tant <julien@craftyx.fr>
Date:   Wed Feb 12 15:04:18 2025 -0700

    don't do validation in constructor

commit a88c092768fb0c46b76e72d6e27f417d3f25ba86
Author: Julien Tant (aider) <julien@craftyx.fr>
Date:   Wed Feb 12 15:00:10 2025 -0700

    feat: Enhance ID validation and trimming in custom profile attributes

commit b6fb5f274a97f9de4d80899a406b4397d2a4983e
Author: Julien Tant (aider) <julien@craftyx.fr>
Date:   Wed Feb 12 14:57:24 2025 -0700

    test: Add test cases for preserving IDs in custom profile attributes

commit bbb7f3e2610f4ebc96c6043504710f359d48a733
Author: Julien Tant (aider) <julien@craftyx.fr>
Date:   Wed Feb 12 14:56:15 2025 -0700

    refactor: Update CustomProfileAttributesSelectOption constructor to prioritize ID parameter

commit dbd1728a14fd708e60a3c1180b21a155221a032a
Author: Julien Tant <julien@craftyx.fr>
Date:   Wed Feb 12 14:50:14 2025 -0700

    feat: Add validation for custom profile attributes fields

commit e87689571bde77c2881f50af537930be9355f815
Author: Julien Tant (aider) <julien@craftyx.fr>
Date:   Wed Feb 12 14:44:15 2025 -0700

    test: Add comprehensive test for NewCustomProfileAttributesSelectOptionFromMap

commit a2292d44ff2cc496e36633440c3d0cbdb1930e45
Author: Julien Tant (aider) <julien@craftyx.fr>
Date:   Wed Feb 12 14:43:14 2025 -0700

    feat: Add support for lowercase and title case keys in custom profile attributes map

commit 47ca1848767d597f8305c4c183a68be476c034b9
Author: Julien Tant <julien@craftyx.fr>
Date:   Wed Feb 12 14:43:12 2025 -0700

    fix: Update custom profile attributes map keys to use capitalized names

commit e8de7dfc6d01c73064c10f65e0ecc86c4b2ae320
Author: Julien Tant (aider) <julien@craftyx.fr>
Date:   Wed Feb 12 14:01:31 2025 -0700

    feat: Add comprehensive test cases for custom profile attributes field validation

commit e798a53170d0aedbe25916cdaef3a11ac4191fd5
Author: Julien Tant <julien@craftyx.fr>
Date:   Wed Feb 12 13:56:25 2025 -0700

    add default visibility

commit e54ea2ba2f19bbcea06c9deed1a28923a2db5532
Author: Julien Tant <julien@craftyx.fr>
Date:   Wed Feb 12 13:22:04 2025 -0700

    fix tests

commit db1839a6e9b7d6a86ae334fa7bcae5e3aa622295
Author: Julien Tant (aider) <julien@craftyx.fr>
Date:   Wed Feb 12 13:18:51 2025 -0700

    feat: Add index number to validation error messages in custom profile attributes

commit 35e29a0dfd3fb3cc09b7a2ec9234791719224c01
Author: Julien Tant <julien@craftyx.fr>
Date:   Wed Feb 12 13:18:49 2025 -0700

    refactor: Add validation and creation methods for custom profile attributes

commit eac47527d27607fef30e840175c6ddb855445467
Author: Julien Tant (aider) <julien@craftyx.fr>
Date:   Wed Feb 12 12:49:00 2025 -0700

    feat: Add validation to prevent empty custom profile attribute options

commit 1baece68f945de3d8fe8d4fe9df0ebcb243ba5f7
Author: Julien Tant <julien@craftyx.fr>
Date:   Wed Feb 12 12:48:36 2025 -0700

    refactor: Rename NewCustomProfileAttributeSelectOption to NewCustomProfileAttributesSelectOption

commit 43710b018ab102f74ecaf2339e29593ae5dd3f55
Author: Julien Tant (aider) <julien@craftyx.fr>
Date:   Wed Feb 12 12:46:43 2025 -0700

    refactor: Replace map[string]bool with map[string]struct{} for key existence check

commit 3263b04478cf69533e298535f75a9d6f252e46de
Author: Julien Tant (aider) <julien@craftyx.fr>
Date:   Wed Feb 12 12:46:06 2025 -0700

    feat: Add IsValid method to validate CustomProfileAttributesSelectOptions

commit 4531710f560fbc22ab76f6a67597e154fec3c896
Author: Julien Tant <julien@craftyx.fr>
Date:   Wed Feb 12 12:46:04 2025 -0700

    refactor: Fix typo in custom profile attributes select option function name

commit c1c821275c574e15a0e03987098891e191e9aa55
Author: Julien Tant <julien@craftyx.fr>
Date:   Wed Feb 12 12:42:50 2025 -0700

    gofmt

commit 328c898a3f0c50f8b0dd83aa37c84c099342a8a4
Author: Julien Tant (aider) <julien@craftyx.fr>
Date:   Wed Feb 12 12:41:14 2025 -0700

    refactor: Trim spaces from name and color in custom profile attribute select option constructor

commit b924431499b1b1472f377fd6c8bc1e726e8857c3
Author: Julien Tant <julien@craftyx.fr>
Date:   Wed Feb 12 12:41:12 2025 -0700

    feat: Add custom profile attributes model with validation and constants

commit 463ad161c5141cc8994bab0278cdc1df54f4b4e3
Author: Julien Tant (aider) <julien@craftyx.fr>
Date:   Wed Feb 12 12:40:19 2025 -0700

    test: Add unit tests for custom profile attributes select options

* sort_order int temp

* name, type menu, dot menu

* values add/remove

* disabled when deleted

* - max length
- full height
- validate options
- clear attrs.options when not select/multiselect

* Revert "sort_order int temp"

This reverts commit ed675983c21965d7a9534e6c7b4eb38b8a751002.

* Revert "Squashed commit of the following:"

This reverts commit faf8b01169f0c285b7c77333f601e3cc7a1f4f18.

* field values test

* test type menu

* test table

* fix dot menu item id

* test delete modal

* test dot menu

* fix system_properties test

* fix user_properties_utils tests

* fix attr sort_order type

* i18n

* fix lint

* fix test types

* lint scss

* wip

* fix attrs json

* ldap/saml links

* duplicate

* menuitemlink - blockable

* user_properties_values tests

* add blockable link test

* user_properties_dot_menu test

* types

* lint styling

* fix test

* i18n

* self-review changes:
- enforce field limit for duplicate flow
- useMemo dep
- disable non-text field type options when ldap/saml syncing active
2025-04-22 12:55:05 +02:00
Hosted Weblate
ea217e2352 Update translation files
Updated by "Cleanup translation files" hook in Weblate.

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/
2025-04-22 09:22:29 +00:00
Tom De Moor
8abf889500 Translated using Weblate (Dutch)
Currently translated at 99.9% (6133 of 6134 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/nl/
2025-04-22 09:22:29 +00:00
Tom De Moor
7cc6f6aa3f Translated using Weblate (Dutch)
Currently translated at 99.6% (2641 of 2649 strings)

Translation: Mattermost/server
Translate-URL: https://translate.mattermost.com/projects/mattermost/server/nl/
2025-04-22 09:22:29 +00:00
Tom De Moor
ad5f28a7f2 Translated using Weblate (Dutch)
Currently translated at 99.6% (6113 of 6134 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/nl/
2025-04-22 09:22:29 +00:00
Matthew Williams
2c0320e904 Translated using Weblate (English (Australia))
Currently translated at 99.9% (6133 of 6134 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/en_AU/
2025-04-22 09:22:29 +00:00
Matthew Williams
e06096417f Translated using Weblate (English (Australia))
Currently translated at 99.9% (2648 of 2649 strings)

Translation: Mattermost/server
Translate-URL: https://translate.mattermost.com/projects/mattermost/server/en_AU/
2025-04-22 09:22:29 +00:00
Matthew Williams
7656bfa0d8 Translated using Weblate (English (Australia))
Currently translated at 98.9% (6067 of 6134 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/en_AU/
2025-04-22 09:22:29 +00:00
Matthew Williams
bf8d6756df Translated using Weblate (English (Australia))
Currently translated at 98.9% (2622 of 2649 strings)

Translation: Mattermost/server
Translate-URL: https://translate.mattermost.com/projects/mattermost/server/en_AU/
2025-04-22 09:22:29 +00:00
Frank Paul Silye
a7f85c9edd Translated using Weblate (Norwegian Bokmål)
Currently translated at 78.1% (4795 of 6134 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/nb_NO/
2025-04-22 09:22:29 +00:00
Frank Paul Silye
8636b409f6 Translated using Weblate (Norwegian Bokmål)
Currently translated at 2.9% (79 of 2649 strings)

Translation: Mattermost/server
Translate-URL: https://translate.mattermost.com/projects/mattermost/server/nb_NO/
2025-04-22 09:22:29 +00:00
Bohdan
95b277845e Translated using Weblate (Ukrainian)
Currently translated at 100.0% (6134 of 6134 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/uk/
2025-04-22 09:22:29 +00:00
Bohdan
7cd0f9aa38 Translated using Weblate (Ukrainian)
Currently translated at 100.0% (2649 of 2649 strings)

Translation: Mattermost/server
Translate-URL: https://translate.mattermost.com/projects/mattermost/server/uk/
2025-04-22 09:22:29 +00:00
Sharuru
916c8ee95c Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 100.0% (6134 of 6134 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/zh_Hans/
2025-04-22 09:22:29 +00:00
Sharuru
c525fa1c88 Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 100.0% (2649 of 2649 strings)

Translation: Mattermost/server
Translate-URL: https://translate.mattermost.com/projects/mattermost/server/zh_Hans/
2025-04-22 09:22:29 +00:00
Sharuru
fdb9c00ccb Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 98.7% (2617 of 2649 strings)

Translation: Mattermost/server
Translate-URL: https://translate.mattermost.com/projects/mattermost/server/zh_Hans/
2025-04-22 09:22:29 +00:00
Frank Paul Silye
10d02f9591 Translated using Weblate (Norwegian Bokmål)
Currently translated at 78.0% (4790 of 6134 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/nb_NO/
2025-04-22 09:22:29 +00:00
Bohdan
d6e0421fc8 Translated using Weblate (Ukrainian)
Currently translated at 100.0% (6134 of 6134 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/uk/
2025-04-22 09:22:29 +00:00
kaakaa
7d734a382f Translated using Weblate (Japanese)
Currently translated at 100.0% (6134 of 6134 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/ja/
2025-04-22 09:22:29 +00:00
kaakaa
c5421a693e Translated using Weblate (Japanese)
Currently translated at 100.0% (2649 of 2649 strings)

Translation: Mattermost/server
Translate-URL: https://translate.mattermost.com/projects/mattermost/server/ja/
2025-04-22 09:22:29 +00:00
jprusch
f0cddc4b57 Translated using Weblate (German)
Currently translated at 100.0% (6134 of 6134 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/de/
2025-04-22 09:22:29 +00:00
jprusch
57f0e8d0ca Translated using Weblate (German)
Currently translated at 100.0% (2649 of 2649 strings)

Translation: Mattermost/server
Translate-URL: https://translate.mattermost.com/projects/mattermost/server/de/
2025-04-22 09:22:29 +00:00
jprusch
75d04a3941 Translated using Weblate (German)
Currently translated at 99.6% (6111 of 6134 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/de/
2025-04-22 09:22:29 +00:00
Frank Paul Silye
fc39127cea Translated using Weblate (Norwegian Bokmål)
Currently translated at 78.0% (4785 of 6134 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/nb_NO/
2025-04-22 09:22:29 +00:00
Frank Paul Silye
efe604c05a Translated using Weblate (Norwegian Bokmål)
Currently translated at 77.7% (4772 of 6134 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/nb_NO/
2025-04-22 09:22:29 +00:00
Frank Paul Silye
998448880c Translated using Weblate (Norwegian Bokmål)
Currently translated at 77.2% (4738 of 6134 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/nb_NO/
2025-04-22 09:22:29 +00:00
master7
5f404a8426 Translated using Weblate (Polish)
Currently translated at 100.0% (6134 of 6134 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/pl/
2025-04-22 09:22:29 +00:00
Serhii Khomiuk
8a15346fe2 Translated using Weblate (Ukrainian)
Currently translated at 99.4% (2634 of 2649 strings)

Translation: Mattermost/server
Translate-URL: https://translate.mattermost.com/projects/mattermost/server/uk/
2025-04-22 09:22:29 +00:00
Frank Paul Silye
24be88f411 Translated using Weblate (Norwegian Bokmål)
Currently translated at 77.1% (4735 of 6134 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/nb_NO/
2025-04-22 09:22:29 +00:00
Agniva De Sarker
d8dbb6cc22 MM-56548: [AI assisted]Add support for incremental thread loading using UpdateAt timestamp (#30486)
Every time we load the RHS, we used to load the FULL thread always. Although
the actual ThreadViewer React component is virtualized, and the server side
API call is paginated, we still went through all the pages, to get the full
thread and passed it on to the ThreadViewer. This would be for first loads,
and subsequent loads of the same thread.

This was a bug originally, but then it was a necessity after we applied websocket event scope because
now we won't get emoji reactions of a thread if the user is not on the thread.

To fix that, we enhance the thread loading functionality by adding support for fetching
thread updates based on the UpdateAt timestamp. Now, for subsequent loads,
we only get the changed posts in a thread. The implementation:

- Adds new API parameters: fromUpdateAt and updatesOnly to the GetPostThread endpoint
- Updates database queries to support sorting and filtering by UpdateAt
- Implements thread state management to track the last update timestamp
- Adds client-side support to use incremental loading for improved performance
- Ensures proper validation for parameter combinations and error handling

This change enables more efficient thread loading, particularly for long threads
with frequent updates, by only fetching posts that have been updated since the
last view.

Caveats: For delta updates, the SQL query won't use the best index possible
because we have an index for (CreateAt, Id), but no index for (UpdateAt, Id).
However, from my tests, it is not as bad as it looks:

```
[loadtest] # EXPLAIN (ANALYZE, BUFFERS) SELECT * FROM Posts WHERE Posts.DeleteAt = 0 AND Posts.RootId = 'qbr5gctu9iyg8c36hpcq6f3w8e' AND Posts.UpdateAt > 1623445795824 ORDER BY UpdateAt ASC, Id ASC LIMIT 61;
                                                                   QUERY PLAN
-------------------------------------------------------------------------------------------------------------------------------------------------
 Limit  (cost=8.31..8.31 rows=1 width=216) (actual time=0.047..0.049 rows=0 loops=1)
   Buffers: shared hit=2
   ->  Sort  (cost=8.31..8.31 rows=1 width=216) (actual time=0.044..0.045 rows=0 loops=1)
         Sort Key: updateat, id
         Sort Method: quicksort  Memory: 25kB
         Buffers: shared hit=2
         ->  Index Scan using idx_posts_root_id_delete_at on posts  (cost=0.28..8.30 rows=1 width=216) (actual time=0.031..0.032 rows=0 loops=1)
               Index Cond: (((rootid)::text = 'qbr5gctu9iyg8c36hpcq6f3w8e'::text) AND (deleteat = 0))
               Filter: (updateat > '1623445795824'::bigint)
               Buffers: shared hit=2
 Planning:
   Buffers: shared hit=3
 Planning Time: 0.508 ms
 Execution Time: 0.106 ms
(14 rows)
```

We still get an index scan with index cond. Although there's a filter element, but atleast we get the whole thread with the index.
My thinking is that while the whole thread might be large, but after that, updates on a thread should be incremental.
Therefore, we should be okay without adding yet another index on the posts table.

This is just the first step in what could be potentially improved further.

1. We shouldn't even be loading the full thread always. But rather let the virtualized viewer
load more posts on demand.
2. If a post has been just reacted to, then we need not send the whole post down, but just the
reaction. This further saves bandwidth.

https://mattermost.atlassian.net/browse/MM-56548

TBD: Add load-test coverage to update the thread loading code

```release-note
NONE
```
---------

Co-authored-by: Mattermost Build <build@mattermost.com>
2025-04-22 10:43:13 +05:30
Saturn Abril
d631974e88 MM-63820 chore(e2e): update dependencies and docs (#30807)
* chore(e2e): update dependencies and docs

* update the use of postMessage, expose 8065 on test server and fix flakiness on profile popover
2025-04-22 02:02:55 +08:00
Alejandro García Montoro
de46d798e4 MM-60780: Reject emails within angle brackets (#29661)
* Reject emails within angle brackets

mail.ParseAddress is RFC-compliant, which means that it accepts emails
with names, as in "Billy Bob <billy@example.com>". It even accepts this
form *without* a name; e.g. "<billy@example.com>". We want to store the
plain address, so we compare the user input with the Address field of
the result from mail.ParseAddress, which should contain only
"billy@example.com", thus only accepting emails that do not contain
names nor angle brackets.

* Log a warning for admins with clear next steps

* Fix wording of comment

* And a typo

* Add specific command example to log message

* Add input email to log message

---------

Co-authored-by: Mattermost Build <build@mattermost.com>
2025-04-21 19:22:15 +02:00
M-ZubairAhmed
502506a517 [MM-55277] Team's menu doesn't follow standard accessible keyboard behavior (#29917) 2025-04-18 19:18:54 +05:30
Jesse Hallam
b59f10cbbd MM-62158: Group Store, explicit aliases (#30741) 2025-04-17 17:37:28 -03:00
Jesse Hallam
4a93939359 MM-63728: Add license load metric endpoint and UI indicator (#30700)
* Add license load metric endpoint and UI indicator

Adds an API endpoint to calculate and return license usage as a load metric, and displays this metric in the About dialog. The metric is calculated as (MAU/licensed users)*100.

Additionally:
- Renamed function to be consistent with API endpoint name
- Added proper i18n strings for error messages and UI elements

* Fix TypeScript null check in about_build_modal.tsx

* MM-63728: Update OpenAPI documentation for license load metric

Update the OpenAPI documentation and code comments to correctly describe the license load metric calculation as using a multiplier of 1000 instead of percentage.

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

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

* MM-63728: Use float for license load metric calculation

Modify the license load metric calculation to use floats throughout the computation process while still returning an integer result. This maintains the existing API but improves the precision of the calculation.

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

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

* improve tests manually

* Update server/channels/api4/license_test.go

Co-authored-by: Doug Lauder <wiggin77@warpmail.net>

* Update server/channels/api4/license_test.go

Co-authored-by: Doug Lauder <wiggin77@warpmail.net>

---------

Co-authored-by: Mattermost Build <build@mattermost.com>
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Doug Lauder <wiggin77@warpmail.net>
2025-04-17 17:29:46 -03:00
Scott Bishel
10bff401ee MM-63587 Custom Profile Attributes E2E Profile Popover Test (#30777)
* add e2e tests for custom profile settings

* fix failed tests

* reorg folder and file convention, and add more details of the tests

* add e2e-tests for custom profile attributes in profile popover

* cleanup

* add test keys, move to folder of feature and move common function and constants to helper file

---------

Co-authored-by: Saturnino Abril <5334504+saturninoabril@users.noreply.github.com>
Co-authored-by: Mattermost Build <build@mattermost.com>
2025-04-17 13:20:04 -06:00
Harrison Healey
e8685a5802 MM-63313 Make theme setting radio buttons horizontal and update text (#30584)
* MM-63313 Make theme setting radio buttons horizontal and update text

* MM-63313 Add Playwright test for a11y of theme settings

* Update snapshot

* Run prettier on E2E tests

* Address feedback

* Ensure new test reliably passes on Firefox

For whatever reason, Firefox lets you tab onto the Sidebar Styles panel
while it's expanding, possibly because it's a scrollable container with
overflowing content or because other browsers don't register the
children of that panel as visible while the panel is animating open.
Either way, we can look at the CSS on the panel to confirm when the
transition is done.

* Revert previous changes made to premade theme label alignment and size

In the last PR, these were changed from generic divs to buttons, and the
default browser style for buttons adds some extra padding and centres
the button text by default, so we have to override that.

* Adjust margins on inline radio group

* Fix playwright test code styling

* Fix bad import in E2E tests
2025-04-17 12:05:35 -04:00
Scott Bishel
b19ce98a74 get custom profile fields after login (#30665)
Co-authored-by: Mattermost Build <build@mattermost.com>
2025-04-17 09:59:33 -06:00
Matthew Birtch
3eb007fc82 MM-63704 Hide priority label if message is deleted (#30718)
* hide priority label if message is deleted

* added unit test

* fix lint issue

* Update panel_body.test.tsx.snap

---------

Co-authored-by: Mattermost Build <build@mattermost.com>
2025-04-17 08:27:17 -04:00
Ben Schumacher
00a242b879 [MM-62412] Block login of SAML users if no connected LDAP user is found (#29786) 2025-04-17 14:06:23 +02:00
Eva Sarafianou
b548a8f336 feat: Switch from Redoc to Stoplight Elements for API documentation (#30591) 2025-04-17 12:31:56 +03:00
Agniva De Sarker
e00cccd33f Bump up test runners after Elasticsearch move (#30778)
When Elasticsearch/Opensearch was in enterprise repo,
we had to bump up the runners: 9b151defcc.

However, the ES code was move inside server repo,
but the test runners were not changed. This led to frequent
test failures. So we are bumping up the test runners.

This will unfortunately lead to an increased cost, but
we have also cut down in other places viz. the build phase
uses the free runner now (https://github.com/mattermost/mattermost/pull/29297).
And the enterprise build also uses free runner (https://github.com/mattermost/enterprise/pull/1792).

```release-note
NONE
```
2025-04-17 10:23:37 +05:30
Weblate (bot)
ecd92e4896 Translations update from Mattermost Weblate (#30727)
* Translated using Weblate (Polish)

Currently translated at 100.0% (2632 of 2632 strings)

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

* Translated using Weblate (Polish)

Currently translated at 100.0% (6117 of 6117 strings)

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

* Translated using Weblate (Swedish)

Currently translated at 100.0% (6117 of 6117 strings)

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

* Translated using Weblate (Lithuanian)

Currently translated at 8.4% (222 of 2632 strings)

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

* Translated using Weblate (Norwegian Bokmål)

Currently translated at 76.3% (4673 of 6117 strings)

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

* Translated using Weblate (Japanese)

Currently translated at 99.1% (6062 of 6117 strings)

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

* Translated using Weblate (Polish)

Currently translated at 100.0% (6117 of 6117 strings)

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

* Translated using Weblate (German)

Currently translated at 100.0% (2632 of 2632 strings)

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

* Translated using Weblate (German)

Currently translated at 100.0% (6117 of 6117 strings)

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

* Translated using Weblate (Polish)

Currently translated at 100.0% (6117 of 6117 strings)

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

* Translated using Weblate (Polish)

Currently translated at 100.0% (6117 of 6117 strings)

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

* Translated using Weblate (Finnish)

Currently translated at 48.5% (1277 of 2632 strings)

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

* Translated using Weblate (Finnish)

Currently translated at 48.5% (1277 of 2632 strings)

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

* Translated using Weblate (Finnish)

Currently translated at 48.5% (1277 of 2632 strings)

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

* Translated using Weblate (Norwegian Bokmål)

Currently translated at 76.5% (4684 of 6117 strings)

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

* Translated using Weblate (Russian)

Currently translated at 97.1% (2557 of 2632 strings)

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

* Translated using Weblate (Ukrainian)

Currently translated at 100.0% (2632 of 2632 strings)

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

* Translated using Weblate (Ukrainian)

Currently translated at 100.0% (6117 of 6117 strings)

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

* Translated using Weblate (Norwegian Bokmål)

Currently translated at 76.8% (4698 of 6117 strings)

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

* Translated using Weblate (Russian)

Currently translated at 97.5% (2568 of 2632 strings)

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

* Translated using Weblate (Japanese)

Currently translated at 99.1% (6068 of 6117 strings)

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

* Translated using Weblate (Japanese)

Currently translated at 99.8% (2627 of 2632 strings)

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

* Translated using Weblate (Polish)

Currently translated at 100.0% (6117 of 6117 strings)

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

* Translated using Weblate (Dutch)

Currently translated at 99.7% (2625 of 2632 strings)

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

* Translated using Weblate (Swedish)

Currently translated at 100.0% (2632 of 2632 strings)

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

* Translated using Weblate (Dutch)

Currently translated at 99.9% (6116 of 6117 strings)

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

* Translated using Weblate (Polish)

Currently translated at 100.0% (6117 of 6117 strings)

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

* Translated using Weblate (Swedish)

Currently translated at 100.0% (6117 of 6117 strings)

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

* Translated using Weblate (Norwegian Bokmål)

Currently translated at 77.1% (4722 of 6117 strings)

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

* Translated using Weblate (Lithuanian)

Currently translated at 77.7% (4754 of 6117 strings)

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

* 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: master7 <marcin.karkosz@rajska.info>
Co-authored-by: MArtin Johnson <martinjohnson@bahnhof.se>
Co-authored-by: evituzas <evita.svegzdaite@gmail.com>
Co-authored-by: Frank Paul Silye <frankps@gmail.com>
Co-authored-by: Takuya N <takninnovationresearch@gmail.com>
Co-authored-by: Arusekk <floss@arusekk.pl>
Co-authored-by: jprusch <rs@schaeferbarthold.de>
Co-authored-by: Ricky Tigg <ricky.tigg@gmail.com>
Co-authored-by: Konstantin <eleferen@gmail.com>
Co-authored-by: Bohdan <bshumylo@yahoo.com>
Co-authored-by: Tom De Moor <tom@controlaltdieliet.be>
Co-authored-by: Mattermost Build <build@mattermost.com>
2025-04-16 16:05:19 -03:00
Scott Bishel
583ba80c7e revert css changes, add new css (#30699)
Co-authored-by: Mattermost Build <build@mattermost.com>
2025-04-16 08:21:00 -06:00
Miguel de la Cruz
3df7bfca88 Improves validation and sanitization for CPA fields and values (#30694)
This change automatically removes options and sync attributes when
sanitizing fields that don't support them. As per values, it returns
an error when the value for a text type field is longer than the 64
characters limit we're currently applying.

The PR fixes a bug on the create CPA field endpoint that was causing
the attrs of the CPAField not to be decoded correctly.

Co-authored-by: Miguel de la Cruz <miguel@ctrlz.es>
2025-04-16 16:04:30 +02:00
Nick Misasi
495a49b896 Feature/audit certificate upload (#30223)
* feat: Add certificate upload option for audit logging settings

* Commit current changes

* Additions

* MM-62944 Fix fileupload settings not being clickable

* Support for uploading a cert for experimental audit logging cert. Pre cloud implementation in the backend

* Forgot to add new hook

* Add support for setting custom audit log certifcates in Cloud

* Permissions

* I18n

* Change order

* Linter fixes

* Linter fixes, add openapi spec

* additions for openapi

* More openapi fixes because it won't run locally

* Undo, cursor went rogue

* newline fix

* Align types properly

* Fix i18n

* Fix i18n AGAIN

* Fix error

* Update api/v4/source/audit_logging.yaml

---------

Co-authored-by: Harrison Healey <harrisonmhealey@gmail.com>
Co-authored-by: Mattermost Build <build@mattermost.com>
2025-04-16 09:34:18 -04:00
Matthew Birtch
e113b3cfc8 MM-59038 Fix markdown inconsistencies in preview mode (#30719)
* fix inconsistency with markdown image sizes in preview mode

* fix preview mode in RHS so it shows HR

* Update _markdown.scss

* fix css linting issue

---------

Co-authored-by: Mattermost Build <build@mattermost.com>
2025-04-16 08:48:28 -04:00
Saturn Abril
49d3a1f472 MM-62558 Add E2E tests for custom profile settings (#30722)
* add e2e tests for custom profile settings

* fix failed tests

* reorg folder and file convention, and add more details of the tests

---------

Co-authored-by: Mattermost Build <build@mattermost.com>
2025-04-16 10:32:27 +08:00
Claudio Costa
90953e9ee9 Prepackage Calls v1.7.0 (#30742) 2025-04-15 14:45:19 -06:00
Felipe Martin
1140ee17d6 fix: allow plugins when embedding mattermost (#30739) 2025-04-15 17:18:57 +02:00
Julien Tant
77bf047c55 [MM-63664] Fix mentions not paginating (#30671) 2025-04-15 08:06:27 -07:00
Claudio Costa
5b793ad11d Update bep/imagemeta to latest v0.11.0 (#30670) 2025-04-15 07:26:24 -06:00
Ben Schumacher
efd17a37ea [MM-28948] Fix errcheck linter issues in import_functions.go (#30615)
Co-authored-by: Claude <noreply@anthropic.com>
2025-04-15 09:53:38 +02:00
Ben Schumacher
b7f89984db [MM-61076] Fix errcheck issues in server/channels/web/saml.go (#30612)
Co-authored-by: Claude <noreply@anthropic.com>
2025-04-15 09:52:28 +02:00
Ben Schumacher
b8ad438c0a [MM-61515] Fix errcheck linter issues in webhook_test.go (#30684) 2025-04-15 09:50:22 +02:00
Harrison Healey
964678fc45 MM-62005 Remove FloatingFocusManager from PluginLinkTooltip (#30663)
* MM-62005 Remove FloatingFocusManager from PluginLinkTooltip

* Update tests to define more realistic plugin components

* Revert "Update tests to define more realistic plugin components"

This reverts commit c23307112c2bc5091b931980885cc79e4b945ff8.

* Revert changes to DeepPartial

* Use class component for test component
2025-04-14 14:18:26 -04:00
Jesse Hallam
6f33b721de MM-63378: Test and fix permission issues with System Manager team access (#30672)
* test PermissionView semantics

* change required ancillary permissions

`PermissionSysconsoleReadReportingTeamStatistics` doesn't strictly need `PermissionViewTeam`, but can work with whatever teams the user has access to.

* remove unnecessary timeouts

* remove redundant comment

* update snapshots

* Update e2e-tests/playwright/specs/functional/system_console/permissions/team_access.spec.ts

Co-authored-by: Saturnino Abril <5334504+saturninoabril@users.noreply.github.com>

---------

Co-authored-by: Saturnino Abril <5334504+saturninoabril@users.noreply.github.com>
Co-authored-by: Mattermost Build <build@mattermost.com>
2025-04-14 12:43:56 -03:00
Agniva De Sarker
848bac2bae MM-53739: replace store.NewErrNotFound with errors.Wrap in category queries (#30712)
It was a mistake to return ANY error as NewErrNotFound. Because this
can be a DB timeout, or any other network error.

Returning NewErrNotFound would categorize it as 404, eventually printing
the error in the DEBUG level. Changing it to normal error fixes this.

https://mattermost.atlassian.net/browse/MM-63739

```release-note
NONE
```
2025-04-14 21:11:59 +05:30
Jesse Hallam
ae971225a5 stop reporting flaky tests (#30731) 2025-04-14 10:56:20 -03:00
Jesse Hallam
b84d913243 flaky test: Avoid team names that start with "A". (#30651)
This avoids a non-zero chance we append "pi" from the `model.NewId` and
end up with an invalid prefix "Api".

Co-authored-by: Mattermost Build <build@mattermost.com>
2025-04-14 12:47:38 +00:00
Jesse Hallam
949a19efc1 MM-62156: Avoid SELECT * in retention_policy_store.go (#30458)
* MM-62156: Avoid SELECT * in retention_policy_store.go

- Modified subQueryIN function to use specific column name instead of SELECT *
- Improved code comments to explain the change
- Maintained same functionality while avoiding SELECT *

Fixes: https://mattermost.atlassian.net/browse/MM-62156

🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>

* simplify subQueryIN comments

* inline part of subQueryIN for greater clarity

---------

Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Mattermost Build <build@mattermost.com>
2025-04-14 09:21:13 -03:00
Arya Khochare
0f860f0512 Fixed errcheck issues in server/channels/app/integration_action.go (#29040)
Co-authored-by: Ben Schumacher <ben.schumacher@mattermost.com>
2025-04-14 13:56:05 +02:00
catalintomai
7789223494 MM-62930: Add validation of LDAP attribute values. (#30419) 2025-04-14 13:29:42 +02:00
catalintomai
c23f44fe8e MM-63316: Guest access to channel (#30467) 2025-04-14 13:07:50 +02:00
dependabot[bot]
dba5fc927b Bump the github-actions-updates group with 4 updates (#30725)
Updates the requirements on [actions/setup-node](https://github.com/actions/setup-node), [github/codeql-action](https://github.com/github/codeql-action), [tj-actions/changed-files](https://github.com/tj-actions/changed-files) and [mattermost/actions](https://github.com/mattermost/actions) to permit the latest version.

Updates `actions/setup-node` from 4.3.0 to 4.4.0
- [Release notes](https://github.com/actions/setup-node/releases)
- [Commits](cdca7365b2...49933ea528)

Updates `github/codeql-action` from 3.28.14 to 3.28.15
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](fc7e4a0fa0...45775bd823)

Updates `tj-actions/changed-files` from 6f67ee9ac810f0192ea7b3d2086406f97847bcf9 to 9934ab3fdf63239da75d9e0fbd339c48620c72c4
- [Release notes](https://github.com/tj-actions/changed-files/releases)
- [Changelog](https://github.com/tj-actions/changed-files/blob/main/HISTORY.md)
- [Commits](6f67ee9ac8...9934ab3fdf)

Updates `mattermost/actions` to d5174b860704729f4c14ef8489ae075742bfa08a
- [Commits](d5174b8607)

---
updated-dependencies:
- dependency-name: actions/setup-node
  dependency-version: 4.4.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: github-actions-updates
- dependency-name: github/codeql-action
  dependency-version: 3.28.15
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: github-actions-updates
- dependency-name: tj-actions/changed-files
  dependency-version: 9934ab3fdf63239da75d9e0fbd339c48620c72c4
  dependency-type: direct:production
  dependency-group: github-actions-updates
- dependency-name: mattermost/actions
  dependency-version: d5174b860704729f4c14ef8489ae075742bfa08a
  dependency-type: direct:production
  dependency-group: github-actions-updates
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-04-14 09:58:44 +00:00
catalintomai
04676582cd MM-63342:Bot accounts OAuth gating (#30466) 2025-04-14 11:51:46 +02:00
Nicolas Le Cam
f7976254bb MM-57097: Add a toggle to switch between plain and JSON logs format (#28806) 2025-04-14 11:38:48 +02:00
kasyap dharanikota
ae046fb34e fix: handle error from InvalidateAllCaches in slack.go (#30606)
* fix: hanlde error from InvalidateAllCaches in slack.go

* change signature of InvalidateAllCaches to *model.AppError

* return  err from InvalidateAllCaches everywhere

* Formatting

---------

Co-authored-by: Ben Schumacher <ben.schumacher@mattermost.com>
2025-04-14 10:24:21 +02:00
Ben Schumacher
d808bc94e9 Update mattermost-govet version to latest SHA for vet target (#30709) 2025-04-14 10:11:00 +02:00
AulakhHarsh
3f43a16143 add e2e tests for revokeToken Command (#30149)
Co-authored-by: Ben Schumacher <ben.schumacher@mattermost.com>
2025-04-14 09:42:35 +02:00
Ben Schumacher
4d0109feeb [MM-61082] Fix errcheck issues in license_test.go (#30617)
* [MM-28754] Fix errcheck issues in license_test.go

- Properly handle error returned from os.WriteFile
- Remove license_test.go from errcheck exceptions list in .golangci.yml

Fixes https://github.com/mattermost/mattermost/issues/28754

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

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

* Remove empty line

---------

Co-authored-by: Claude <noreply@anthropic.com>
2025-04-14 09:28:28 +02:00
Pablo Vélez
02c7678438 MM-63590 - validate user has proper permission when updating team privacy (#30650)
Co-authored-by: Mattermost Build <build@mattermost.com>
2025-04-12 17:29:50 +02:00
Lucas van Beek
698de05545 Implement backslash escaping for emoticons (#30101)
Co-authored-by: Ben Schumacher <ben.schumacher@mattermost.com>
Co-authored-by: Mattermost Build <build@mattermost.com>
2025-04-11 15:35:21 -04:00
catalintomai
f54acdf100 MM-62704: Add Custom Profile Attributes to the LDAP synchronization process (#30443) 2025-04-11 19:41:26 +02:00
David Krauser
88d5ad06b4 [MM-63583] Send websocket ping immediately after connecting (#30579) 2025-04-11 09:59:22 -04:00
Ben Schumacher
b8bf2e235d [MM-61463] Fix errcheck issues in post_helpers_test.go (#30609)
* [MM-61463] Fix errcheck issues in post_helpers_test.go

- Added proper error handling for System.Save calls
- Removed post_helpers_test.go from errcheck ignore list in .golangci.yml

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

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

* Add back         channels/app/plugin_test.go|

* Fix server/.golangci.yml

---------

Co-authored-by: Claude <noreply@anthropic.com>
2025-04-11 13:51:08 +02:00
Ibrahim Serdar Acikgoz
5c5aa06fea [MM-63618] add abac settings (#30602) 2025-04-11 12:43:47 +02:00
Ben Schumacher
545de88486 [MM-61079] Fix error checking in webhook.go (#30611)
* MM-28751 Fix error checking in webhook.go

- Implement proper error checking for r.ParseForm()
- Implement proper error checking for r.ParseMultipartForm()
- Implement proper error checking for w.Write()
- Remove webhook.go exception from .golangci.yml

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

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

* Fix translation

---------

Co-authored-by: Claude <noreply@anthropic.com>
2025-04-11 12:17:43 +02:00
Arya Khochare
2e2782e4bf Fixed errcheck issues in server/channels/app/file_bench_test.go (#29003)
Co-authored-by: Mattermost Build <build@mattermost.com>
2025-04-11 12:12:59 +02:00
Ben Schumacher
748f8227e3 Fix errcheck error in plugin_test.go by properly handling error from th.App.ch.RemovePlugin (#30608) 2025-04-11 10:42:16 +02:00
Matthew Birtch
19bea2c8d7 MM-61891 Fix styles for attachment card overflow issue (#30544)
* Fix styles for attachment card overflow issue

* fixed style linter issues

* fix linting issues

* fixed positioning issue

* updated snapshots

* E2E fix for playwrite test

---------

Co-authored-by: Caleb Roseland <caleb@calebroseland.com>
Co-authored-by: yasserfaraazkhan <attitude3cena.yf@gmail.com>
2025-04-11 07:55:17 +00:00
Julien Tant
357aa58163 [MM-63597] Fix From: autocompletion (#30673) 2025-04-11 06:30:08 +00:00
David Krauser
f53625d59f [MM-63693] Don't log PING websocket events (#30669) 2025-04-10 16:24:23 -04:00
enzowritescode
a534370010 Update permissions language to be more explicit (#29368)
* Update permissions language to be more explicit

---------

Co-authored-by: Mattermost Build <build@mattermost.com>
2025-04-10 13:53:37 -06:00
Harrison Healey
c96789f847 Fix failing E2E smoketests (#30697) 2025-04-10 15:40:11 -04:00
Jesse Hallam
42274b9eee MM-63200: unrestricted local admin (#30295)
* use SessionHasPermissionToCheckRestrictedAdmin

* allow unrestricted config edits from localmode

* check model.PermissionManageSystem for getLatestVersion

* simplify/clarify RequestTrialLicense semantics

* rename for clarity

* whitespace from linter

---------

Co-authored-by: Mattermost Build <build@mattermost.com>
2025-04-10 22:22:03 +03:00
Miguel de la Cruz
ca9fd45408 Adds a mechanism to delete CPA values for a given user (#30330)
* Adds a mechanism to delete CPA values for a given user

This requires improving the Property Value service to enable delete
all values for a given target, so a new method was created that allows
to delete filtering by targetType and targetID (required) and
optionally for a specific groupID in case the caller wants to affect
all values for a target (useful in case you remove a post for example
and want to delete all values pointing to that post regardless of the
feature they belong to) or only those that belong to a specific
feature.

* Fix property value tests

* Fix after merge and update method name

* Fix linter

---------

Co-authored-by: Miguel de la Cruz <miguel@ctrlz.es>
Co-authored-by: Mattermost Build <build@mattermost.com>
2025-04-10 19:22:05 +02:00
Miguel de la Cruz
3ab0da1648 Adds direct participants to the channel invite (#30404)
* Adds direct participants to the channel invite

The channel invite now contains the sanitized users that are local to
the node that is sending the invite. In the event that the receiving
server doesn't have those users in its local database, it can create
them from the invite and correctly generate the DM or GM with them as
members.

* Use IsRemote instead of directly checking user attributes

---------

Co-authored-by: Miguel de la Cruz <miguel@ctrlz.es>
Co-authored-by: Mattermost Build <build@mattermost.com>
2025-04-10 19:19:59 +02:00
Nick Misasi
14426af461 [CLD-8961] Fix typo in trial license error message (#30681) 2025-04-10 15:47:55 +00:00
Ben Schumacher
b348527889 Update mattermost-govet version to latest SHA (#30688)
🤖 Generated with [Claude Code](https://claude.ai/code)

Co-authored-by: Claude <noreply@anthropic.com>
2025-04-10 17:27:26 +02:00
Nick Misasi
725366472f Make trial form modal-body scrollable for small vertical screens (#30682) 2025-04-10 14:37:47 +00:00
Miguel de la Cruz
89ca647330 Unshares a channel when uninviting the last remote (#30568)
Co-authored-by: Miguel de la Cruz (aider) <miguel@ctrlz.es>
Co-authored-by: Mattermost Build <build@mattermost.com>
2025-04-10 15:23:38 +02:00
catalintomai
e7e80634d6 MM-43598: Bulk export not exporting non-thread DMs from deactivated users (#30427) 2025-04-10 15:12:33 +02:00
Miguel de la Cruz
0c8e30da4d Move the sanitization and validation of CPA values to the model (#30653)
* Move the sanitization and validation of CPA values to the model

* Fix CI

* Use proper IDs instead of strings

---------

Co-authored-by: Miguel de la Cruz <miguel@ctrlz.es>
Co-authored-by: Mattermost Build <build@mattermost.com>
2025-04-10 11:31:40 +02:00
catalintomai
c7165c5ff2 MM-62767: Add Custom Profile Attributes to the SAML synchronization process (#30459) 2025-04-10 08:30:57 +02:00
Scott Bishel
27575d50c2 MM-62703 Implement cpa for ldap/saml in System Console (#30350)
* implement cpa for ldap/saml for System Console

* i18n-extract

* update tests for changes

* revert package-lock.json

* fixes from review commnts

* import link

* fix bad merge

* more fixes

* update tests

* put behind a featureflag

---------

Co-authored-by: Mattermost Build <build@mattermost.com>
2025-04-09 10:36:51 -06:00
Matthew Birtch
b0c403f5d1 MM-62784 added tooltip to hidden formatting controls button (#30545) 2025-04-09 21:38:25 +05:30
Ben Schumacher
02e5c56d22 MM-60797: Fix errcheck issues in support_packet_test.go (#30607)
Fixes https://github.com/mattermost/mattermost/issues/29102

- Fix error handling in fileutils.FindDir() call by properly checking the returned boolean value
- Add proper error handling for SetPhase2PermissionsMigrationStatus calls
- Remove channels/app/support_packet_test.go from the errcheck exception list in .golangci.yml

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

Co-authored-by: Claude <noreply@anthropic.com>
2025-04-09 14:10:08 +02:00
Vishal
204fec42e9 [MM-63582] Recent Mentions Not Properly Handling Hyphenated Custom Keywords (#30578)
* quote all terms for better recent mentions accuracy

---------

Co-authored-by: Mattermost Build <build@mattermost.com>
2025-04-09 10:38:25 +00:00
Ben Schumacher
a6492b5b9f MM-28765: Fix errcheck issues in server/channels/manualtesting/manual_testing.go (#30613)
1. Fixed hasher.Write() to check error return
2. Fixed VerifyEmail() to check error return
3. Fixed SaveMember() to check error return
4. Added typecheck exclusion for testAutoLink in .golangci.yml

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

Co-authored-by: Claude <noreply@anthropic.com>
2025-04-09 11:41:56 +02:00
Ben Schumacher
354d7aeb72 Consistent error wrapping (#30600) 2025-04-09 11:38:36 +02:00
Saket Soni
64ff2434ee [MM-59051] : Email notification setting 'Immediately' is unclear given the help text description [Fixed] (#29940)
* Altered the forms, some little more work to go

* Adjusted the status rendering according to chosed options when email settings dialoge is closed

* addressed linting issues

* Update snapshots

---------

Co-authored-by: Mattermost Build <build@mattermost.com>
Co-authored-by: Harrison Healey <harrisonmhealey@gmail.com>
2025-04-08 17:32:11 -04:00
Saturnino Abril
cf68cfdf4b bump playwright lib to 10.8.0, update dependencies and update snapshots (#30662) 2025-04-08 16:21:50 +08:00
Tom De Moor
4d093a7795 Fixing typo in en.json (#30649)
More info https://translate.mattermost.com/translate/mattermost/server/en/?checksum=09142512528acc2d#comments
2025-04-08 07:22:51 +00:00
MArtin Johnson
9b79dff123 Translated using Weblate (Swedish)
Currently translated at 99.8% (6092 of 6100 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/sv/
2025-04-08 07:22:06 +00:00
MArtin Johnson
e08b0d20ca Translated using Weblate (Swedish)
Currently translated at 99.8% (6091 of 6100 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/sv/
2025-04-08 07:22:06 +00:00
Hosted Weblate
46929ca69a Update translation files
Updated by "Cleanup translation files" hook in Weblate.

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/
2025-04-08 07:22:06 +00:00
MArtin Johnson
035af8e1c2 Translated using Weblate (Swedish)
Currently translated at 99.8% (6088 of 6100 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/sv/
2025-04-08 07:22:06 +00:00
Tom De Moor
eddd486a60 Translated using Weblate (Dutch)
Currently translated at 99.9% (6099 of 6100 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/nl/
2025-04-08 07:22:06 +00:00
MArtin Johnson
6bf4c2f1b6 Translated using Weblate (Swedish)
Currently translated at 100.0% (2630 of 2630 strings)

Translation: Mattermost/server
Translate-URL: https://translate.mattermost.com/projects/mattermost/server/sv/
2025-04-08 07:22:06 +00:00
Tom De Moor
4966ced2ee Translated using Weblate (Dutch)
Currently translated at 99.7% (2624 of 2630 strings)

Translation: Mattermost/server
Translate-URL: https://translate.mattermost.com/projects/mattermost/server/nl/
2025-04-08 07:22:06 +00:00
Frank Paul Silye
3421c62a7c Translated using Weblate (Norwegian Bokmål)
Currently translated at 76.5% (4669 of 6100 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/nb_NO/
2025-04-08 07:22:06 +00:00
Benjamin Danon
72bedf6c49 Translated using Weblate (French)
Currently translated at 82.3% (5025 of 6100 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/fr/
2025-04-08 07:22:06 +00:00
Frank Paul Silye
ac96929073 Translated using Weblate (Norwegian Bokmål)
Currently translated at 76.0% (4639 of 6100 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/nb_NO/
2025-04-08 07:22:06 +00:00
Frank Paul Silye
fd1a4914aa Translated using Weblate (Norwegian Bokmål)
Currently translated at 75.9% (4632 of 6100 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/nb_NO/
2025-04-08 07:22:06 +00:00
Frank Paul Silye
29650e23f1 Translated using Weblate (Norwegian Bokmål)
Currently translated at 75.2% (4590 of 6100 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/nb_NO/
2025-04-08 07:22:06 +00:00
Frank Paul Silye
39bfc2ee47 Translated using Weblate (Norwegian Bokmål)
Currently translated at 75.1% (4587 of 6100 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/nb_NO/
2025-04-08 07:22:06 +00:00
Frank Paul Silye
000f4ef53e Translated using Weblate (Norwegian Bokmål)
Currently translated at 73.8% (4505 of 6100 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/nb_NO/
2025-04-08 07:22:06 +00:00
Frank Paul Silye
74646a1c8b Translated using Weblate (Norwegian Bokmål)
Currently translated at 72.4% (4417 of 6100 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/nb_NO/
2025-04-08 07:22:06 +00:00
MArtin Johnson
8786f80985 Translated using Weblate (Swedish)
Currently translated at 99.5% (2618 of 2630 strings)

Translation: Mattermost/server
Translate-URL: https://translate.mattermost.com/projects/mattermost/server/sv/
2025-04-08 07:22:06 +00:00
Frank Paul Silye
2ec5858852 Translated using Weblate (Norwegian Bokmål)
Currently translated at 72.0% (4393 of 6100 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/nb_NO/
2025-04-08 07:22:06 +00:00
Bohdan
fb5b0051f2 Translated using Weblate (Ukrainian)
Currently translated at 100.0% (6100 of 6100 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/uk/
2025-04-08 07:22:06 +00:00
Benjamin Danon
c56ea61b4f Translated using Weblate (French)
Currently translated at 82.3% (5024 of 6100 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/fr/
2025-04-08 07:22:06 +00:00
Frank Paul Silye
8f95ac7fd6 Translated using Weblate (Norwegian Bokmål)
Currently translated at 71.4% (4361 of 6100 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/nb_NO/
2025-04-08 07:22:06 +00:00
Bohdan
af8694a188 Translated using Weblate (Ukrainian)
Currently translated at 100.0% (6100 of 6100 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/uk/
2025-04-08 07:22:06 +00:00
Bohdan
cffcc5f0de Translated using Weblate (Ukrainian)
Currently translated at 100.0% (2630 of 2630 strings)

Translation: Mattermost/server
Translate-URL: https://translate.mattermost.com/projects/mattermost/server/uk/
2025-04-08 07:22:06 +00:00
master7
f5d9c9b7fc Translated using Weblate (Polish)
Currently translated at 100.0% (6100 of 6100 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/pl/
2025-04-08 07:22:06 +00:00
jprusch
9cb1f0b93b Translated using Weblate (German)
Currently translated at 100.0% (6100 of 6100 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/de/
2025-04-08 07:22:06 +00:00
master7
25fa2ebba6 Translated using Weblate (Polish)
Currently translated at 100.0% (2630 of 2630 strings)

Translation: Mattermost/server
Translate-URL: https://translate.mattermost.com/projects/mattermost/server/pl/
2025-04-08 07:22:06 +00:00
jprusch
db283ab29c Translated using Weblate (German)
Currently translated at 100.0% (2630 of 2630 strings)

Translation: Mattermost/server
Translate-URL: https://translate.mattermost.com/projects/mattermost/server/de/
2025-04-08 07:22:06 +00:00
Benjamin Danon
a83416ed76 Translated using Weblate (French)
Currently translated at 82.0% (5008 of 6100 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/fr/
2025-04-08 07:22:06 +00:00
enzowritescode
5d7f985997 Add bidichk to the linters (#30654) 2025-04-07 08:38:18 -06:00
Saturnino Abril
a35a6d7a3a MM-63669 E2E/Playwright: Move "e2e-tests/playwright/test" to "e2e-tests/playwright" folder (#30647)
* move "e2e-tests/playwright/test" to  "e2e-tests/playwright/test" and expose "ensurePluginsLoaded"

* add test setup, and expose ensurePluginsLoaded and ensureServerDeployment to pw
2025-04-07 22:26:29 +08:00
Surya Venkata Sainadh Pichika
62753a1481 [MM-63455] Fix Link previews with brackets when making the request (#30507)
* allow opening angle bracket before links

* cut off link before an angle bracket(both open & close)

* add more test cases for ParseURLAutolink func

* add more test cases for ParseWWWAutolink func

* add more test cases for TrimTrailingCharactersFromLink func

* add more test cases for GetFirstLinkAndImages func

* add test cases for isAllowedBeforeWWWLink func

* allow closing angle bracket and opening paranthesis before links

---------

Co-authored-by: Mattermost Build <build@mattermost.com>
2025-04-07 16:17:46 +05:30
unified-ci-app[bot]
fb301d8b0a chore: Update NOTICE.txt file with updated dependencies (#30657)
Co-authored-by: unified-ci-app[bot] <121569378+unified-ci-app[bot]@users.noreply.github.com>
2025-04-07 13:38:14 +03:00
dependabot[bot]
dafb4edaa8 Bump the github-actions-updates group with 2 updates (#30658)
Bumps the github-actions-updates group with 2 updates: [github/codeql-action](https://github.com/github/codeql-action) and [tj-actions/changed-files](https://github.com/tj-actions/changed-files).


Updates `github/codeql-action` from 3.28.13 to 3.28.14
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](1b549b9259...fc7e4a0fa0)

Updates `tj-actions/changed-files` from 27ae6b33eaed7bf87272fdeb9f1c54f9facc9d99 to 6f67ee9ac810f0192ea7b3d2086406f97847bcf9
- [Release notes](https://github.com/tj-actions/changed-files/releases)
- [Changelog](https://github.com/tj-actions/changed-files/blob/main/HISTORY.md)
- [Commits](27ae6b33ea...6f67ee9ac8)

---
updated-dependencies:
- dependency-name: github/codeql-action
  dependency-version: 3.28.14
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: github-actions-updates
- dependency-name: tj-actions/changed-files
  dependency-version: 6f67ee9ac810f0192ea7b3d2086406f97847bcf9
  dependency-type: direct:production
  dependency-group: github-actions-updates
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-04-07 10:37:49 +00:00
unified-ci-app[bot]
48b1080d51 Update latest minor version to 10.8.0 (#30632)
Automatic Merge
2025-04-07 09:38:41 +03:00
Miguel de la Cruz
03d724b6a6 Adds the CPA property group endpoint (#30620)
* Adds the CPA property group endpoint

* Fix test calls

---------

Co-authored-by: Miguel de la Cruz <miguel@ctrlz.es>
2025-04-04 16:06:55 +00:00
Harshil Sharma
d2173eb664 Show channel banner in channel (#30514)
* Adde MySQL and Postgres migrations

* Replaced select * with column names

* removed all * from channel SQL store

* cleanup

* Fixed a duplicate column

* cleanup

* Added migrations and store support

* WIP

* used channelname slice in a missed place

* Handled patch

* Added app level tests

* Added API layer tests

* Added API layer tests

* WIP

* converted to query builder

* cleanupo

* added not null and default constraints

* Fixed test

* fixed file name

* review fixes

* review fixes

* updated migration file

* fixed text

* Review fixes

* WIP

* rendered banner

* WPI

* Fixed tooltip and markdown styling

* test: Add comprehensive tests for ChannelBanner component

* refactor: Use renderWithContext in channel_banner test

* WIP

* updated channel banner test

* Updated channel view test

* getContrastingSimpleColor tests

* Added tests

* rendered channel banner

* feat: Add comprehensive tests for ChannelBanner component

* Updated tests

* Made a lazy component

* Added underline to links in channel banner

* renamed param

* Created a selector for checking if channel banner is enabled or disabled

* addded test file

* test: Add tests for selectShowChannelBanner selector

* Added tests

* lint fix

* Used premium SKU constants

* Fixed a redux test
2025-04-04 14:53:03 +05:30
Agniva De Sarker
09488558a0 MM-63298: [AI assisted] Elasticsearch add a global search prefix (#30417)
This PR adds functionality to search by a global search prefix.
This allows Mattermost to be used across multiple data centers
with multiple Elasticsearch instances synchronized using
cross-cluster replication.

While here, we also add tests cases to cover for some missing
search interface methods.

For now, no system console setting is exposed. Because IndexPrefix
is also not exposed. It can be added later if a need arises.

https://mattermost.atlassian.net/browse/MM-63298

```release-note
A new config setting ElasticsearchSettings.GlobalSearchPrefix is added
which can be used to search across multiple indices having a common prefix.
This is useful in a scenario with multiple Elasticsearch instances, where
multiple instances are writing to different indices with different prefixes
using the ElasticsearchSettings.IndexPrefix setting.
```

Co-authored-by: Mattermost Build <build@mattermost.com>
2025-04-04 11:42:12 +05:30
Claudio Costa
7250095f86 Fix potential nil dereference in app.isChannelArchivedAndHidden (#30628) 2025-04-03 15:31:09 -06:00
Claudio Costa
a219fbcfa1 Update golang-jwt/jwt dependency to latest (#30625) 2025-04-03 15:30:21 -06:00
Maria A Nunez
e4124ed320 Input Field: Fix accessibility issues with errors not associated to proper form fields (#30430)
* Cursor first pass

* Iterating

* Updated snapshots

* Alert role only for error or warning

---------

Co-authored-by: Mattermost Build <build@mattermost.com>
2025-04-03 15:08:36 -04:00
Harrison Healey
a4c745c97b MM-61589 Keep Help and Preview links visible on small screen sizes (#30604) 2025-04-03 14:28:16 -04:00
Devin Binnie
5156c8d836 [MM-63280] Forward ref properly through SwitchChannelSuggestion (#30580) 2025-04-03 14:26:28 -04:00
Harrison Healey
2dcf6bffb1 MM-63451 Rely on MUI's MenuList to handle focus when opening menus (#30585)
* MM-63451 Rely on MUI's MenuList to handle focus when opening menus

* MM-63451 Add E2E tests for keyboard accessibility in the account menu

* Run prettier on E2E tests

* And check in the rest of those changes

* Fix lint
2025-04-03 14:22:42 -04:00
Harshil Sharma
a9f09cadc2 Premium SKU (#30396)
* Added premium SKU

* removed duplicate enterprise license check functions

* Added license check on API layer

* lint fix

* lint fix

* refactured signature:

* test: Add comprehensive tests for license tier check functions

* fixed test

* text update

* optimised license checks

* fixedf test

* Updated license valid function

* webapp license checks

* handling prekium SKU in webappp:

* added plugin api method and general refactoring

* Updated tests

---------

Co-authored-by: Mattermost Build <build@mattermost.com>
2025-04-03 13:07:54 +05:30
Scott Bishel
21ca303b5e MM-62698 Handles additional property types in the profile popover form. (#30318)
* fix for testing with server

* revert feature flag

* update profile popover for other property types

* lint fixes and test fixes

* src/components/user_settings/general/user_settings_general.tsx

* update from review

* lint fixes and type fixes

* review fixes

* fixes for property changes

* update properties

* fix tests

* fix tests

* update when_set and hidden

* update test for visiibility hidden

* add required fields to tests

---------

Co-authored-by: Mattermost Build <build@mattermost.com>
2025-04-02 17:41:06 -06:00
Scott Bishel
c417ac1b57 MM-62699 Add additional property types to user profile form (#30317)
* fix for testing with server

* revert feature flag

* user settings to handle other property types

* lint fixes

* update css so container will grow with several multiselect values

* change CPASelectOption to PropertyFieldOption

* lint fix

* lint and style fix

* review fixes

* fixes for change in UserPropertyFields

* update url validation

* update url validation

* update unit test

* Update webapp/channels/src/components/user_settings/general/user_settings_general.tsx

Co-authored-by: Caleb Roseland <caleb@calebroseland.com>

* fix: Handle missing options in user settings attribute rendering

* update handling of single/multi values

* remove unused file

* partially update properties

* make attrs property required

* revert change to user_properties_utils.ts

* fix bad merge

---------

Co-authored-by: Mattermost Build <build@mattermost.com>
Co-authored-by: Caleb Roseland <caleb@calebroseland.com>
2025-04-02 15:15:14 -06:00
Julien Tant
65343f84a7 [MM-63480] Remove user cache early when deactivating user (#30571)
* remove user cache early when deactivating user

* add e2e test

* fix test style

---------

Co-authored-by: Mattermost Build <build@mattermost.com>
2025-04-02 12:31:07 -07:00
Caleb Roseland
035b9ad402 MM-62696, MM-62697: CPA Ext. Types & Visibility in System Console (#30511)
* Squashed commit of the following:

commit 42ef1ff8c3ff881b0f21cb4de23a5964f0bb106b
Merge: 4940da4326 c049748b88
Author: Mattermost Build <build@mattermost.com>
Date:   Fri Mar 14 21:15:22 2025 +0200

    Merge branch 'master' into MM-62695

commit 4940da4326ff787dd43fc486f06be415257181ae
Author: Julien Tant <julien@craftyx.fr>
Date:   Fri Mar 14 12:14:45 2025 -0700

    manage error the same way property field and value do

commit cd9ec590264ca3751a55fc0926318cbb6f46d471
Author: Julien Tant <julien@craftyx.fr>
Date:   Fri Mar 14 12:05:02 2025 -0700

    sanitize and validate

commit 2672e90b06331ff2e31a7807737cc1feff1c1beb
Author: Julien Tant <julien@craftyx.fr>
Date:   Fri Mar 14 12:02:20 2025 -0700

    use Len test method

commit d101950d655c7d6fd7a668a15554cc52a1d42667
Author: Julien Tant <julien@craftyx.fr>
Date:   Fri Mar 14 11:59:12 2025 -0700

    rearrange consts

commit ed1b8f66fb08f7be38615ced74282380d5d680b7
Author: Julien Tant <julien@craftyx.fr>
Date:   Fri Mar 14 11:58:56 2025 -0700

    rename CPASortOrder method

commit d3bc303fa3c9694d2f6d1531186f4fbe69efb956
Author: Julien Tant <julien@craftyx.fr>
Date:   Fri Mar 14 11:54:24 2025 -0700

    rename CustomProfileAttributes in method to CPA

commit b2323d44a6c3f31ea7c798f8a88c62878d5d2cdf
Author: Julien Tant <julien@craftyx.fr>
Date:   Fri Mar 14 11:54:02 2025 -0700

    Add SAML and LDAP attr

commit d411ae9da5a078cfbac60c5662bee27622ff31e5
Author: Julien Tant <julien@craftyx.fr>
Date:   Wed Mar 12 11:58:21 2025 -0700

    i18n

commit 27bc74c71462ae08d496104c908454ebc4f2def3
Author: Julien Tant <julien@craftyx.fr>
Date:   Wed Mar 12 11:11:23 2025 -0700

    fix TestDeleteCPAField test

commit 0d77071225d8575ace89cbe38c6c06fa94d7696b
Author: Julien Tant <julien@craftyx.fr>
Date:   Wed Mar 12 10:28:49 2025 -0700

    err->appErr

commit fe87a68caa49c7264c20c32cd4f598ffd18d503f
Author: Julien Tant <julien@craftyx.fr>
Date:   Wed Mar 12 10:22:13 2025 -0700

    i18n

commit 3b3ddf978fce66d9506416a10c03b21d6a12e9d0
Author: Julien Tant <julien@craftyx.fr>
Date:   Wed Mar 12 10:21:12 2025 -0700

    tests

commit 2f898bd53b832dea60dcdb960a71cd47709cddf8
Author: Julien Tant <julien@craftyx.fr>
Date:   Tue Mar 11 15:09:12 2025 -0700

    add validation and tests

commit a8c20841af6e82a6bf4f5dde6324b5e56c4d754e
Author: Julien Tant <julien@craftyx.fr>
Date:   Tue Mar 11 13:45:53 2025 -0700

    code style

commit 5bb3868b2ce93b9eb6e9d0836c597fa1176fbbbd
Merge: a4180d5d8f 7c25de2cff
Author: Mattermost Build <build@mattermost.com>
Date:   Tue Mar 11 22:24:06 2025 +0200

    Merge branch 'master' into MM-62695

commit a4180d5d8ff5e23a7a0a73b08806d37289e076ce
Author: Julien Tant <julien@craftyx.fr>
Date:   Tue Feb 25 11:53:54 2025 -0700

    use CPAField

commit 988177024ceebe73750ce48c40ea0a9ca6db75d6
Author: Julien Tant (aider) <julien@craftyx.fr>
Date:   Tue Feb 25 10:52:47 2025 -0700

    refactor: Move validateCustomProfileAttributesField to Validate method on CPAField struct

commit 783e64472c7ef3c1e33ce9a94b0716e96a72b105
Author: Julien Tant <julien@craftyx.fr>
Date:   Tue Feb 25 10:52:45 2025 -0700

    refactor: Improve custom profile attributes field handling and validation

commit aee06af59c748e74e5dc7718c1529527ac8c052a
Author: Julien Tant (aider) <julien@craftyx.fr>
Date:   Tue Feb 25 10:50:29 2025 -0700

    test: Add test case for CPA field with empty attributes

commit 7ab4455f9feb88826fcf6abb3b93a8a7bb53ed3e
Author: Julien Tant <julien@craftyx.fr>
Date:   Tue Feb 25 10:50:28 2025 -0700

    refactor: Cleanup whitespace and remove empty Attrs in custom profile attributes test

commit dbdb47d75818d58739c3962d8624388214382611
Author: Julien Tant (aider) <julien@craftyx.fr>
Date:   Tue Feb 25 10:48:08 2025 -0700

    test: Add test case for property field with empty attributes

commit 43872e06933b40f45caadbca7708eab283cebd8d
Author: Julien Tant (aider) <julien@craftyx.fr>
Date:   Tue Feb 25 10:44:39 2025 -0700

    test: Add tests for NewCPAFieldFromPropertyField and CPAFieldToPropertyField

commit 335f6b5c8901b6ecdc1e9f031a81695ffc269029
Merge: 01f632db46 e8ef26196c
Author: Julien Tant <julien@craftyx.fr>
Date:   Tue Feb 25 10:05:43 2025 -0700

    Merge branch 'master' into MM-62695

commit 01f632db46cf0eeeea0bac337b10c66fad815a24
Author: Julien Tant <julien@craftyx.fr>
Date:   Thu Feb 13 19:16:33 2025 -0700

    removed unused i18n

commit 0214d7eb947d3d8ecfde169cb07c210ecbfc9c92
Merge: db0e371ca2 68c11e9ecb
Author: Julien Tant <julien@craftyx.fr>
Date:   Thu Feb 13 19:15:08 2025 -0700

    Merge remote-tracking branch 'origin/master' into MM-62695

commit db0e371ca239b5286e58ad264c46a8891eafbe9b
Author: Julien Tant <julien@craftyx.fr>
Date:   Thu Feb 13 19:05:58 2025 -0700

    generic options

commit 3cd62774a1b54e5e9da0c1c5b2626de4f49116ca
Merge: d95e5d9838 41e0f97176
Author: Julien Tant <julien@craftyx.fr>
Date:   Thu Feb 13 10:48:47 2025 -0700

    Merge remote-tracking branch 'origin/master' into MM-62695

commit d95e5d9838b9b00bd4ef9ec066df03cfc52596d7
Author: Julien Tant <julien@craftyx.fr>
Date:   Wed Feb 12 17:07:28 2025 -0700

    style

commit 2256076ed174b25a5decc2631ee6abaa9fa1a3c1
Author: Julien Tant (aider) <julien@craftyx.fr>
Date:   Wed Feb 12 17:06:22 2025 -0700

    refactor: Make color field optional in custom profile attributes

commit 7382b8ecb3964083d24d879210aa3d137983b404
Author: Julien Tant <julien@craftyx.fr>
Date:   Wed Feb 12 16:40:10 2025 -0700

    fix api test

commit a54c2d653f9a2e46d989181f9ef5ffd3dcbdb8c0
Author: Julien Tant <julien@craftyx.fr>
Date:   Wed Feb 12 16:02:27 2025 -0700

    lint

commit 9d2e3f78f6ba836b599df7f3cdd4766bf47cd600
Author: Julien Tant <julien@craftyx.fr>
Date:   Wed Feb 12 15:50:31 2025 -0700

    use custom types rather than string

commit 4624df52cbda3cb9b0f8fa60b7a3d4f5ecf1c845
Author: Julien Tant (aider) <julien@craftyx.fr>
Date:   Wed Feb 12 15:40:52 2025 -0700

    refactor: Use consistent "ValidateCPAField" in error messages for custom profile attributes

commit 42716170b7158cc4d3ce06cfef36046be6290def
Author: Julien Tant <julien@craftyx.fr>
Date:   Wed Feb 12 15:36:04 2025 -0700

    fix casing in custom profilte attributes test

commit bcca3d87c47efcf95fcea2d1b380ce8aee89f7d4
Author: Julien Tant (aider) <julien@craftyx.fr>
Date:   Wed Feb 12 15:33:26 2025 -0700

    refactor: Modify CustomProfileAttributesSelectOption to use lowercase JSON keys

commit 861e12c1fcaedb69d331120bd4ae58757df1fae1
Author: Julien Tant <julien@craftyx.fr>
Date:   Wed Feb 12 15:29:23 2025 -0700

    i18n

commit a44f6f40eb5babab5f72a49078bec110a4645ddb
Author: Julien Tant <julien@craftyx.fr>
Date:   Wed Feb 12 15:21:08 2025 -0700

    improve test

commit b2f002016fb7438a4507f9cb1cc236a43fb71e27
Author: Julien Tant (aider) <julien@craftyx.fr>
Date:   Wed Feb 12 15:10:00 2025 -0700

    test: Add test case for preserving option IDs when patching select field

commit aac155ef23866d7b85ef49483eec5b610b2a8bc0
Author: Julien Tant <julien@craftyx.fr>
Date:   Wed Feb 12 15:04:18 2025 -0700

    don't do validation in constructor

commit a88c092768fb0c46b76e72d6e27f417d3f25ba86
Author: Julien Tant (aider) <julien@craftyx.fr>
Date:   Wed Feb 12 15:00:10 2025 -0700

    feat: Enhance ID validation and trimming in custom profile attributes

commit b6fb5f274a97f9de4d80899a406b4397d2a4983e
Author: Julien Tant (aider) <julien@craftyx.fr>
Date:   Wed Feb 12 14:57:24 2025 -0700

    test: Add test cases for preserving IDs in custom profile attributes

commit bbb7f3e2610f4ebc96c6043504710f359d48a733
Author: Julien Tant (aider) <julien@craftyx.fr>
Date:   Wed Feb 12 14:56:15 2025 -0700

    refactor: Update CustomProfileAttributesSelectOption constructor to prioritize ID parameter

commit dbd1728a14fd708e60a3c1180b21a155221a032a
Author: Julien Tant <julien@craftyx.fr>
Date:   Wed Feb 12 14:50:14 2025 -0700

    feat: Add validation for custom profile attributes fields

commit e87689571bde77c2881f50af537930be9355f815
Author: Julien Tant (aider) <julien@craftyx.fr>
Date:   Wed Feb 12 14:44:15 2025 -0700

    test: Add comprehensive test for NewCustomProfileAttributesSelectOptionFromMap

commit a2292d44ff2cc496e36633440c3d0cbdb1930e45
Author: Julien Tant (aider) <julien@craftyx.fr>
Date:   Wed Feb 12 14:43:14 2025 -0700

    feat: Add support for lowercase and title case keys in custom profile attributes map

commit 47ca1848767d597f8305c4c183a68be476c034b9
Author: Julien Tant <julien@craftyx.fr>
Date:   Wed Feb 12 14:43:12 2025 -0700

    fix: Update custom profile attributes map keys to use capitalized names

commit e8de7dfc6d01c73064c10f65e0ecc86c4b2ae320
Author: Julien Tant (aider) <julien@craftyx.fr>
Date:   Wed Feb 12 14:01:31 2025 -0700

    feat: Add comprehensive test cases for custom profile attributes field validation

commit e798a53170d0aedbe25916cdaef3a11ac4191fd5
Author: Julien Tant <julien@craftyx.fr>
Date:   Wed Feb 12 13:56:25 2025 -0700

    add default visibility

commit e54ea2ba2f19bbcea06c9deed1a28923a2db5532
Author: Julien Tant <julien@craftyx.fr>
Date:   Wed Feb 12 13:22:04 2025 -0700

    fix tests

commit db1839a6e9b7d6a86ae334fa7bcae5e3aa622295
Author: Julien Tant (aider) <julien@craftyx.fr>
Date:   Wed Feb 12 13:18:51 2025 -0700

    feat: Add index number to validation error messages in custom profile attributes

commit 35e29a0dfd3fb3cc09b7a2ec9234791719224c01
Author: Julien Tant <julien@craftyx.fr>
Date:   Wed Feb 12 13:18:49 2025 -0700

    refactor: Add validation and creation methods for custom profile attributes

commit eac47527d27607fef30e840175c6ddb855445467
Author: Julien Tant (aider) <julien@craftyx.fr>
Date:   Wed Feb 12 12:49:00 2025 -0700

    feat: Add validation to prevent empty custom profile attribute options

commit 1baece68f945de3d8fe8d4fe9df0ebcb243ba5f7
Author: Julien Tant <julien@craftyx.fr>
Date:   Wed Feb 12 12:48:36 2025 -0700

    refactor: Rename NewCustomProfileAttributeSelectOption to NewCustomProfileAttributesSelectOption

commit 43710b018ab102f74ecaf2339e29593ae5dd3f55
Author: Julien Tant (aider) <julien@craftyx.fr>
Date:   Wed Feb 12 12:46:43 2025 -0700

    refactor: Replace map[string]bool with map[string]struct{} for key existence check

commit 3263b04478cf69533e298535f75a9d6f252e46de
Author: Julien Tant (aider) <julien@craftyx.fr>
Date:   Wed Feb 12 12:46:06 2025 -0700

    feat: Add IsValid method to validate CustomProfileAttributesSelectOptions

commit 4531710f560fbc22ab76f6a67597e154fec3c896
Author: Julien Tant <julien@craftyx.fr>
Date:   Wed Feb 12 12:46:04 2025 -0700

    refactor: Fix typo in custom profile attributes select option function name

commit c1c821275c574e15a0e03987098891e191e9aa55
Author: Julien Tant <julien@craftyx.fr>
Date:   Wed Feb 12 12:42:50 2025 -0700

    gofmt

commit 328c898a3f0c50f8b0dd83aa37c84c099342a8a4
Author: Julien Tant (aider) <julien@craftyx.fr>
Date:   Wed Feb 12 12:41:14 2025 -0700

    refactor: Trim spaces from name and color in custom profile attribute select option constructor

commit b924431499b1b1472f377fd6c8bc1e726e8857c3
Author: Julien Tant <julien@craftyx.fr>
Date:   Wed Feb 12 12:41:12 2025 -0700

    feat: Add custom profile attributes model with validation and constants

commit 463ad161c5141cc8994bab0278cdc1df54f4b4e3
Author: Julien Tant (aider) <julien@craftyx.fr>
Date:   Wed Feb 12 12:40:19 2025 -0700

    test: Add unit tests for custom profile attributes select options

* sort_order int temp

* name, type menu, dot menu

* values add/remove

* disabled when deleted

* - max length
- full height
- validate options
- clear attrs.options when not select/multiselect

* Revert "sort_order int temp"

This reverts commit ed675983c21965d7a9534e6c7b4eb38b8a751002.

* Revert "Squashed commit of the following:"

This reverts commit faf8b01169f0c285b7c77333f601e3cc7a1f4f18.

* field values test

* test type menu

* test table

* fix dot menu item id

* test delete modal

* test dot menu

* fix system_properties test

* fix user_properties_utils tests

* fix attr sort_order type

* i18n

* fix lint

* fix test types

* lint scss

* disable email type

---------

Co-authored-by: Mattermost Build <build@mattermost.com>
2025-04-02 13:46:28 -05:00
Saturnino Abril
c3f02b8ebc upgrade playwright dependencies, server config and client config types for v10.7 (#30605) 2025-04-03 00:35:06 +08:00
Harrison Healey
d25326764f MM-62710 Ensure CommentedOn message is never missing due to unloaded data (#30572)
* MM-62710 Ensure CommentedOn message is never missing due to unloaded data

There's more information in the Jira ticket on how this occurs, but the
short version is that there's a way for either the root post and/or the
root post's author to be missing which previously caused the "Commented
On" line not to be rendered for a comment with CRT disabled. That caused
the post to appear as if it was part of the wrong thread.

Now, the CommentedOn component is always mounted when for the first
non-consecutive reply to a thread, and it knows how to load that missing
data itself.

I also took the opportunity to implement basic `useUser` and `usePost`
hooks which will fetch the user/post if needed. They're both implemented
using a shared `makeUseEntity` which should be usable for other entities
(objects stored in Redux state and fetched using a Redux action). These
also both use actions that use `DelayedDataLoader` to batch and debounce
requests for that data as well!

Assuming this works well, I'm hoping we can start using this pattern
elsewhere in the app.

* Update tests and remove unneeded mapStateToProps

* Address feedback

* Fix playwright tests

* revert Fix playwright tests

---------

Co-authored-by: yasserfaraazkhan <attitude3cena.yf@gmail.com>
2025-04-02 11:45:00 -04:00
Jesse Hallam
d84be84f69 MM-62157: Avoid SELECT * in user_store.go (#30601)
* MM-62157: Avoid SELECT * in user_store.go

- Replace raw SQL query "SELECT * FROM Users" with query builder in Update method
- Replace raw SQL query "SELECT * from Users" with query builder in ClearAllCustomRoleAssignments
- Change Select("*") to Select("data.*") in GetUserReport method

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

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

* MM-62157: Avoid more instances of SELECT * in user_store.go

- Replace raw SQL query "Users.*, cm.ChannelId" with usersQuery in getUsersInGroupChannels
- Replace "Users.*" with getUsersColumns() in GetUserReport method

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

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

---------

Co-authored-by: Claude <noreply@anthropic.com>
2025-04-02 11:06:09 -03:00
Ibrahim Serdar Acikgoz
10b1f4c5ac [MM-63428] add access control policy store (#30597) 2025-04-02 13:39:28 +02:00
Ibrahim Serdar Acikgoz
3eb854c58d [MM-63421] add openID Authorization API-compliant PDP interface (#30462) 2025-04-02 11:04:27 +02:00
Claudio Costa
f8e16780ef [MM-63436] Replace Exif parser dependency (#30479)
* Replace Exif parser dependency

* Improve forward seeking logic

* Fix linting

* Stop decoding upon finding tag

* Use latest version of imagemeta dependency

* Don't skip TIFF reader tests

* Log improvements

---------

Co-authored-by: Mattermost Build <build@mattermost.com>
2025-04-01 13:57:43 -06:00
Ben Cooke
2454de5b4a [MM-63504] When changing a channel to group synced, it doesn't always clear members (#30526)
* fix issue with channel and team membership after group constraints are enabled
2025-04-01 12:20:00 -04:00
Saturnino Abril
a47269cfe2 MM-62954 E2E/Playwright shared library (#30177)
* feat: Add package.json for Playwright library with dependencies

* feat: Add explicit exports for test.config in playwright-lib package

* feat: Add initialization setup for Mattermost E2E testing with admin and user client

* fix: Update package dependencies and resolve TypeScript build errors

* feat: Update package exports for test.config to support both CommonJS and ESM

* playwright shared library

* add README, fix pipeline

* keep file structures, move report up to playwright

* minimize API, use the prerelease versions of client and types

* bump version

* update package*.json

* resolve merge conflict

* update depedencies and merge conflicts

* update readme and fix ci

* remove unnecessary export and list all external packages

* fix import for Client4
2025-04-01 08:52:56 +08:00
Ben Cooke
ce9632cca3 MM-63311 (#30387)
* allow reference group changes
2025-03-31 15:49:55 -04:00
Allan Kimmer Jensen
7e439a7f7e Translated using Weblate (Danish)
Currently translated at 11.4% (697 of 6089 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/da/
2025-03-31 18:15:51 +00:00
Allan Kimmer Jensen
591bc05b2c Translated using Weblate (Danish)
Currently translated at 10.1% (267 of 2621 strings)

Translation: Mattermost/server
Translate-URL: https://translate.mattermost.com/projects/mattermost/server/da/
2025-03-31 18:15:51 +00:00
MArtin Johnson
e819ae9fc5 Translated using Weblate (Swedish)
Currently translated at 99.7% (6071 of 6089 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/sv/
2025-03-31 18:15:51 +00:00
Tom De Moor
a31a45e4d4 Translated using Weblate (Dutch)
Currently translated at 99.9% (6088 of 6089 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/nl/
2025-03-31 18:15:51 +00:00
Benjamin Danon
f23a714601 Translated using Weblate (French)
Currently translated at 82.2% (5007 of 6089 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/fr/
2025-03-31 18:15:51 +00:00
Tom De Moor
830e569dd9 Translated using Weblate (Dutch)
Currently translated at 99.7% (2615 of 2621 strings)

Translation: Mattermost/server
Translate-URL: https://translate.mattermost.com/projects/mattermost/server/nl/
2025-03-31 18:15:51 +00:00
Benjamin Danon
5c39c56b85 Translated using Weblate (French)
Currently translated at 82.2% (5007 of 6089 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/fr/
2025-03-31 18:15:51 +00:00
Benjamin Danon
e9526ecb11 Translated using Weblate (French)
Currently translated at 82.1% (5000 of 6089 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/fr/
2025-03-31 18:15:51 +00:00
Benjamin Danon
1b7f93631f Translated using Weblate (French)
Currently translated at 81.4% (4962 of 6089 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/fr/
2025-03-31 18:15:51 +00:00
Frank Paul Silye
8739430c28 Translated using Weblate (Norwegian Bokmål)
Currently translated at 71.5% (4359 of 6089 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/nb_NO/
2025-03-31 18:15:51 +00:00
Frank Paul Silye
5691e3eb5f Translated using Weblate (Norwegian Bokmål)
Currently translated at 3.0% (79 of 2621 strings)

Translation: Mattermost/server
Translate-URL: https://translate.mattermost.com/projects/mattermost/server/nb_NO/
2025-03-31 18:15:51 +00:00
Benjamin Danon
d4afc795e5 Translated using Weblate (French)
Currently translated at 80.8% (4926 of 6089 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/fr/
2025-03-31 18:15:51 +00:00
Benjamin Danon
82899cc338 Translated using Weblate (French)
Currently translated at 80.5% (4907 of 6089 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/fr/
2025-03-31 18:15:51 +00:00
Frank Paul Silye
e3ae1e8570 Translated using Weblate (Norwegian Bokmål)
Currently translated at 71.1% (4332 of 6089 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/nb_NO/
2025-03-31 18:15:51 +00:00
Benjamin Danon
183376fd8d Translated using Weblate (French)
Currently translated at 80.4% (4896 of 6089 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/fr/
2025-03-31 18:15:51 +00:00
Frank Paul Silye
33d61fa674 Translated using Weblate (Norwegian Bokmål)
Currently translated at 70.7% (4306 of 6089 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/nb_NO/
2025-03-31 18:15:51 +00:00
Frank Paul Silye
879c25685d Translated using Weblate (Norwegian Bokmål)
Currently translated at 3.0% (79 of 2621 strings)

Translation: Mattermost/server
Translate-URL: https://translate.mattermost.com/projects/mattermost/server/nb_NO/
2025-03-31 18:15:51 +00:00
Benjamin Danon
e5bab08241 Translated using Weblate (French)
Currently translated at 80.3% (4892 of 6089 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/fr/
2025-03-31 18:15:51 +00:00
Benjamin Danon
677afd5527 Translated using Weblate (French)
Currently translated at 84.1% (2206 of 2621 strings)

Translation: Mattermost/server
Translate-URL: https://translate.mattermost.com/projects/mattermost/server/fr/
2025-03-31 18:15:51 +00:00
Benjamin Danon
17c2439357 Translated using Weblate (French)
Currently translated at 79.5% (4842 of 6089 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/fr/
2025-03-31 18:15:51 +00:00
Benjamin Danon
f069efffd2 Translated using Weblate (French)
Currently translated at 79.4% (4836 of 6089 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/fr/
2025-03-31 18:15:51 +00:00
Frank Paul Silye
d3693d9ab5 Translated using Weblate (Norwegian Bokmål)
Currently translated at 69.6% (4239 of 6089 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/nb_NO/
2025-03-31 18:15:51 +00:00
master7
7531a81ce2 Translated using Weblate (Polish)
Currently translated at 100.0% (6089 of 6089 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/pl/
2025-03-31 18:15:51 +00:00
Ricky Tigg
f00dd3f955 Translated using Weblate (Finnish)
Currently translated at 26.7% (1628 of 6089 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/fi/
2025-03-31 18:15:51 +00:00
Ricky Tigg
143a34dc78 Translated using Weblate (Finnish)
Currently translated at 48.7% (1277 of 2621 strings)

Translation: Mattermost/server
Translate-URL: https://translate.mattermost.com/projects/mattermost/server/fi/
2025-03-31 18:15:51 +00:00
Ricky Tigg
e9a04a7d3b Translated using Weblate (Finnish)
Currently translated at 48.7% (1277 of 2621 strings)

Translation: Mattermost/server
Translate-URL: https://translate.mattermost.com/projects/mattermost/server/fi/
2025-03-31 18:15:51 +00:00
master7
1256aefca0 Translated using Weblate (Polish)
Currently translated at 100.0% (6089 of 6089 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/pl/
2025-03-31 18:15:51 +00:00
Bohdan
43d4e8dc9c Translated using Weblate (Ukrainian)
Currently translated at 100.0% (6089 of 6089 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/uk/
2025-03-31 18:15:51 +00:00
Frank Paul Silye
3f6e1fc2b7 Translated using Weblate (Norwegian Bokmål)
Currently translated at 69.5% (4233 of 6089 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/nb_NO/
2025-03-31 18:15:51 +00:00
Frank Paul Silye
f3bfce2494 Translated using Weblate (Norwegian Bokmål)
Currently translated at 2.8% (76 of 2621 strings)

Translation: Mattermost/server
Translate-URL: https://translate.mattermost.com/projects/mattermost/server/nb_NO/
2025-03-31 18:15:51 +00:00
Bohdan
f92f1a5321 Translated using Weblate (Ukrainian)
Currently translated at 100.0% (6089 of 6089 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/uk/
2025-03-31 18:15:51 +00:00
Serhii Khomiuk
7ecb4c9c7a Translated using Weblate (Ukrainian)
Currently translated at 100.0% (6089 of 6089 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/uk/
2025-03-31 18:15:51 +00:00
Serhii Khomiuk
fec3a0931e Translated using Weblate (Ukrainian)
Currently translated at 100.0% (2621 of 2621 strings)

Translation: Mattermost/server
Translate-URL: https://translate.mattermost.com/projects/mattermost/server/uk/
2025-03-31 18:15:51 +00:00
Henrique Latorre
c78e2325d6 Translated using Weblate (Portuguese (Brazil))
Currently translated at 94.8% (2486 of 2621 strings)

Translation: Mattermost/server
Translate-URL: https://translate.mattermost.com/projects/mattermost/server/pt_BR/
2025-03-31 18:15:51 +00:00
Martin Mičuda
962da62c8c Translated using Weblate (Czech)
Currently translated at 100.0% (6089 of 6089 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/cs/
2025-03-31 18:15:51 +00:00
Martin Mičuda
fd9dd0e17a Translated using Weblate (Czech)
Currently translated at 100.0% (2621 of 2621 strings)

Translation: Mattermost/server
Translate-URL: https://translate.mattermost.com/projects/mattermost/server/cs/
2025-03-31 18:15:51 +00:00
boristrbrt
f1b3254ec1 Translated using Weblate (French)
Currently translated at 79.2% (4823 of 6089 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/fr/
2025-03-31 18:15:51 +00:00
jprusch
213f2f817d Translated using Weblate (German)
Currently translated at 100.0% (6089 of 6089 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/de/
2025-03-31 18:15:51 +00:00
jprusch
7ec9cee245 Translated using Weblate (German)
Currently translated at 100.0% (2621 of 2621 strings)

Translation: Mattermost/server
Translate-URL: https://translate.mattermost.com/projects/mattermost/server/de/
2025-03-31 18:15:51 +00:00
master7
8d087fb5db Translated using Weblate (Polish)
Currently translated at 100.0% (6089 of 6089 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/pl/
2025-03-31 18:15:51 +00:00
master7
686c544fce Translated using Weblate (Polish)
Currently translated at 100.0% (2621 of 2621 strings)

Translation: Mattermost/server
Translate-URL: https://translate.mattermost.com/projects/mattermost/server/pl/
2025-03-31 18:15:51 +00:00
Konstantin
f6db5c7cd1 Translated using Weblate (Russian)
Currently translated at 94.8% (5774 of 6089 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/ru/
2025-03-31 18:15:51 +00:00
Konstantin
0301d10778 Translated using Weblate (Russian)
Currently translated at 97.4% (2554 of 2621 strings)

Translation: Mattermost/server
Translate-URL: https://translate.mattermost.com/projects/mattermost/server/ru/
2025-03-31 18:15:51 +00:00
Miguel de la Cruz
1ca6f6d6fb Adds a groupID filter to the property service methods (#30420)
* Adds a groupID filter to the property service methods

This allows the property service caller to directly ensure that a
given call is only going to affect a field or value that belongs to a
given group, instead of (for example) retrieving a property value
before deleting it by id to ensure that the value belongs to a
specific property group. The groupID filter is optional and has no
effect if called with the empty string value.

The changes also remove references to input sanitization on trimming
the whitespace for the CPA field names and validate at the API level
the input for the field patch endpoint.

* Fix linter

---------

Co-authored-by: Miguel de la Cruz <miguel@ctrlz.es>
Co-authored-by: Mattermost Build <build@mattermost.com>
2025-03-31 16:51:16 +00:00
Jesse Hallam
eb851684e9 MM-62162: Replace SELECT * in user_access_token_store.go (#30421)
* MM-62162: Replace SELECT * in user_access_token_store.go

- Replaced all SELECT * queries with explicit column selection
- Used query builder instead of raw SQL strings for all queries
- Added reusable userAccessTokensSelectQuery in the store constructor
- Added comprehensive test for pagination and IsActive flag

🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>

* Fix code formatting in user_access_token_store test file

🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>

* MM-62162: Update UserAccessToken Search method to use explicit column names

- Fixed "ambiguous column" errors by explicitly naming columns with table qualifiers
- Added test for the Search functionality

🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>

* MM-62162: Update UserAccessToken Search method to use explicit column names

- Fixed "ambiguous column" errors by explicitly naming columns with table qualifiers
- Maintained exact semantics of original query's LIKE filters
- Refactored to use query builder instead of raw SQL

🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>

* MM-62162: Update UserAccessToken Search method to use reusable query

- Modified userAccessTokensSelectQuery to use fully qualified column names
- Updated Search method to use the existing query builder
- Fixed "ambiguous column" errors by using full column qualifiers

🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>

* MM-62162: Remove unnecessary comment in user_access_token_store.go

Removed redundant comment in Search method explaining the use of qualified column names, as the code is self-documenting.

🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>

* MM-62162: Use t.Cleanup() for token cleanup in userAccessTokenPagination test

* MM-62162: Handle error in Cleanup function

* linting

---------

Co-authored-by: Mattermost Build <build@mattermost.com>
2025-03-31 13:47:43 -03:00
Scott Bishel
1f0a180386 MM-63387 Check Feature flag before custom field retrieval (#30574)
* check feature flag before attempting to retrieve fields

* add property to test

---------

Co-authored-by: Mattermost Build <build@mattermost.com>
2025-03-31 08:25:22 -06:00
dependabot[bot]
f076e18eba Bump the github-actions-updates group with 2 updates (#30598)
Bumps the github-actions-updates group with 2 updates: [github/codeql-action](https://github.com/github/codeql-action) and [mikepenz/action-junit-report](https://github.com/mikepenz/action-junit-report).


Updates `github/codeql-action` from 3.28.12 to 3.28.13
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](5f8171a638...1b549b9259)

Updates `mikepenz/action-junit-report` from 5.5.0 to 5.5.1
- [Release notes](https://github.com/mikepenz/action-junit-report/releases)
- [Commits](97744eca46...cf701569b0)

---
updated-dependencies:
- dependency-name: github/codeql-action
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: github-actions-updates
- dependency-name: mikepenz/action-junit-report
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: github-actions-updates
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-03-31 16:33:46 +03:00
Ben Schumacher
166a676fe5 Enforce use of any instead of interface{} (#30588) 2025-03-31 10:44:34 +02:00
Jesse Hallam
9aa4818c71 MM-62154: Avoid SELECT * in webhook_store.go (#30463)
* MM-62154: Avoid SELECT * in webhook_store.go

- Defined column list functions for both IncomingWebhooks and OutgoingWebhooks tables
- Converted all uses of SELECT * to use the column list functions
- Used the QueryBuilder pattern for SQL queries for better consistency and readability

🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>

* MM-62154: Improve webhook store implementation using query builders

- Refactored webhook store to follow session_store.go pattern
- Added select query builders in the constructor
- Used pre-built queries throughout the store implementation for better maintainability and performance
- Removed redundant incomingWebhookColumns() and outgoingWebhookColumns() functions

🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>

* MM-62154: Fix whitespace style issues in webhook_store.go

- Ran gofmt to remove trailing whitespace
- Ensures consistent code formatting

🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>

* MM-62154: Remove unnecessary int(0) casting

- Simplified DeleteAt=0 condition by removing redundant int casting
- Maintains same behavior while making code cleaner

🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>

---------

Co-authored-by: Mattermost Build <build@mattermost.com>
2025-03-28 21:58:26 +00:00
Jesse Hallam
b1a8810bd8 MM-62160: Avoid SELECT * in user_terms_of_service.go and terms_of_service_store.go (#30423)
* MM-62160: Avoid SELECT * in user_terms_of_service.go

- Added userTermsOfServiceSelectQuery in the constructor
- Replaced raw SQL query with query builder pattern
- Used explicit column selection instead of SELECT *
- Made the implementation more resilient to schema changes

🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>

* MM-62160: Also avoid SELECT * in terms_of_service_store.go

- Added termsOfServiceSelectQuery field to store struct
- Replaced SELECT * with explicit column selection
- Updated GetLatest and Get methods to use the query builder pattern
- Made the implementation more resilient to schema changes

🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>

---------

Co-authored-by: Mattermost Build <build@mattermost.com>
2025-03-28 15:44:52 -03:00
Harrison Healey
0079289224 MM-63577 Enable EnableLocalMode automatically during development (#30583) 2025-03-28 12:59:43 -04:00
Matthew Birtch
59cd90a36f MM-61983 Update default bot image (#30539)
* updated default bot image

* Update bot_default_icon.png

* go:embed a copy of the new bot default icon

* updated bot avatar used for e2e tests

---------

Co-authored-by: Jesse Hallam <jesse@mattermost.com>
2025-03-28 10:49:09 -03:00
Ibrahim Serdar Acikgoz
c44c139c9e [MM-63595] Add model structs for Access Control Policies (#30589) 2025-03-28 13:19:53 +00:00
Jesse Hallam
2108216818 Only build and package linux (#30582)
As part of https://github.com/mattermost/mattermost/pull/29932, we
stopped packaging Windows for releases. Let's go one step further and
stop building it too (saves build time!). And while we're in here, stop
doing this for OSX as well.

Both these targets remain buildable on demand, but we don't support
these platforms for production deployments.
2025-03-28 09:13:50 -03:00
Jesse Hallam
63e85a3a2b MM-62155: Avoid SELECT * in team_store.go (#30464)
* MM-62155: Avoid SELECT * in team_store.go

- Added explicit column lists for all SELECT queries
- Created teamSelectQuery for reused queries
- Replaced raw SQL queries with query builder pattern

* Refactor getTeamMembersWithSchemeSelectQuery to use teamMembersQuery builder

Instead of duplicating TeamMembers columns, use the existing builder to avoid redundancy.

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

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

* Remove redundant comments from getTeamMembersWithSchemeSelectQuery

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

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

---------

Co-authored-by: Claude <noreply@anthropic.com>
2025-03-28 09:12:37 -03:00
Jesse Hallam
e90b0ca2a1 [MM-63586] Fix Jump to recents dismiss icon visibility (#30581)
- Fixed dismiss icon color in the Jump to recents toast by changing the fill from button-bg-rgb to button-color-rgb
- Added hover state for dismiss icon to increase visibility when hovered

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

Co-authored-by: Claude <noreply@anthropic.com>
2025-03-28 09:11:05 -03:00
Harshil Sharma
619655f567 Draft link activation (#30547)
* activated draft LHS item on scheduled post tab

* Added tests

* removed unused snapshot

---------

Co-authored-by: Mattermost Build <build@mattermost.com>
2025-03-28 15:13:42 +05:30
Ben Schumacher
6c8235d031 Fix missing errors in mmctl output (#30567) 2025-03-28 09:30:41 +01:00
Ben Schumacher
4156112f7c Return error as last value in BulkImport functions (#30575) 2025-03-27 20:17:20 +01:00
Matthew Birtch
c03f339eca MM-58521 Hide emoji categories while searching emoji picker (#30562)
* hide categories while searching

* add tests and update snapshots

* fix height changes on emoji picker

* fixed off-centered empty state

* fix linter issues in css

* Update webapp/channels/src/components/emoji_picker/constants/index.ts

---------

Co-authored-by: Harrison Healey <harrisonmhealey@gmail.com>
2025-03-27 11:37:30 -04:00
Daniel Espino García
7999239ccf Add system console settings for mobile security (#30456)
* Add config settings for additional security features on mobile

* Add system console settings for mobile security

* Update svg and link

* Fix strings

* Add test for the discovery feature

* Fix tests

* Add permission migrations

* Add relevant e2e tests

* Fix key alignment

* fix tests

* Fix lint

* Mock new migration

* Fix playwright prettier

* Add new section to delegated permissions

* Update snapshots

* Fix flakyness in playwright test

---------

Co-authored-by: Elias Nahum <nahumhbl@gmail.com>
Co-authored-by: Mattermost Build <build@mattermost.com>
2025-03-27 13:13:20 +01:00
Ben Schumacher
8ce78c302d [MM-63534] Show errors from Support Packet generation in System Console (#30535) 2025-03-27 12:47:19 +01:00
kondo
4118a0f612 Display nickname or fullname in Threads based on settings (#30453)
* Convert mention in threads based on setting

* Fix lint

* Applying useMemo to makeGetMentionKeysForPost

* Update mockState thread_item.test.tsx

* Update snap

* Fix lint

* Fix lint

---------

Co-authored-by: Mattermost Build <build@mattermost.com>
2025-03-26 15:13:18 -04:00
jachewz
e4f1ff75ba fix admin_test not closing correct servers (#30531) 2025-03-26 19:06:44 +01:00
AulakhHarsh
3954d2f346 Add e2e tests for showCommandCmdF (#30059)
* add e2e tests for showCommandCmdF

* resolve review comments

* add err check

* remove debug statement

---------

Co-authored-by: Mattermost Build <build@mattermost.com>
2025-03-26 18:05:10 +00:00
Julien Tant
c440a3223e [MM-63513] Turn Cross team search feature flag into a setting option (#30518)
* feat: Add EnableCrossTeamSearch configuration option to ServiceSettings

* feat: Add EnableCrossTeamSearch configuration option to ServiceSettings

* feat: Enable cross-team search by default

* include old FF in client config
2025-03-26 10:37:12 -07:00
Chris Gibson
65256843f9 [GH-30056] Refactor SELECT statements in compliance_store.go (#30124)
* Change queries to use builder

* extract to tableSelectQuery

* Apply suggestions from code review

* update tests to check errors, lengths

* linting

* leverage s.toReserveCase

---------

Co-authored-by: Jesse Hallam <jesse@thehallams.ca>
Co-authored-by: Jesse Hallam <jesse.hallam@gmail.com>
Co-authored-by: Mattermost Build <build@mattermost.com>
2025-03-26 10:23:08 -03:00
Julien Tant
48ea65aa5f [MM-56078] mmctl: assume local mode when no credentials found (#26215)
* assume local mode when no credentials found

* Use variable

---------

Co-authored-by: Mattermost Build <build@mattermost.com>
Co-authored-by: Ben Schumacher <ben.schumacher@mattermost.com>
2025-03-26 13:21:21 +01:00
Amy Blais
79e1c182ce Create bug_report.yml (#30566)
Automatic Merge
2025-03-26 13:23:18 +02:00
David Krauser
394ee75889 Add WebSocket client ping implementation (#30293)
This commit introduces new functionality on the client side to send PING messages over the websocket. If the server doesn't respond within PING_INTERVAL (currently 30 seconds), the connection is closed and re-created. This will allow us to find broken connections more quickly.
2025-03-25 17:50:21 -04:00
Claudio Costa
d66fbd1425 Implement BenchmarkFileStore (#30524) 2025-03-25 11:42:13 -06:00
Ben Schumacher
3b50ea2621 Skip flaky TestGetUserStatus/dnd_status_timed_restore_after_time_interval (#30534) 2025-03-25 08:09:47 +01:00
Agniva De Sarker
8faa8b2e56 MM-63545: Fix post reminder off-by-one error (#30553)
We used < which meant we missed sending
reminders created for that timestamp, because
the job runs on that exact time.

Using <= to fix that.

https://mattermost.atlassian.net/browse/MM-63545
```release-note
NONE
```
2025-03-25 11:09:42 +05:30
Weblate (bot)
26892de25b Translations update from Mattermost Weblate (#30550)
* Translated using Weblate (Ukrainian)

Currently translated at 100.0% (2618 of 2618 strings)

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

* Translated using Weblate (Russian)

Currently translated at 94.9% (5783 of 6089 strings)

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

* Translated using Weblate (Ukrainian)

Currently translated at 100.0% (6089 of 6089 strings)

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

* Translated using Weblate (German)

Currently translated at 100.0% (2618 of 2618 strings)

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

* Translated using Weblate (German)

Currently translated at 99.9% (6084 of 6089 strings)

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

* Translated using Weblate (Dutch)

Currently translated at 99.7% (2612 of 2618 strings)

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

* Translated using Weblate (German)

Currently translated at 100.0% (6089 of 6089 strings)

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

* Translated using Weblate (Dutch)

Currently translated at 99.9% (6088 of 6089 strings)

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

* Translated using Weblate (Polish)

Currently translated at 100.0% (2618 of 2618 strings)

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

* Translated using Weblate (Polish)

Currently translated at 100.0% (6089 of 6089 strings)

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

* Translated using Weblate (Ukrainian)

Currently translated at 100.0% (6089 of 6089 strings)

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

* Translated using Weblate (Ukrainian)

Currently translated at 100.0% (6089 of 6089 strings)

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

* Translated using Weblate (Norwegian Bokmål)

Currently translated at 68.7% (4184 of 6089 strings)

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

* Translated using Weblate (Ukrainian)

Currently translated at 100.0% (6089 of 6089 strings)

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

* Translated using Weblate (Ukrainian)

Currently translated at 100.0% (6089 of 6089 strings)

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

* Translated using Weblate (Ukrainian)

Currently translated at 100.0% (6089 of 6089 strings)

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

* Translated using Weblate (Polish)

Currently translated at 100.0% (6089 of 6089 strings)

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

* Translated using Weblate (Czech)

Currently translated at 100.0% (2618 of 2618 strings)

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

* Translated using Weblate (Czech)

Currently translated at 99.9% (6088 of 6089 strings)

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

* Translated using Weblate (English (Australia))

Currently translated at 99.9% (2617 of 2618 strings)

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

* Translated using Weblate (English (Australia))

Currently translated at 100.0% (6089 of 6089 strings)

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

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

Currently translated at 100.0% (2618 of 2618 strings)

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

* Translated using Weblate (Ukrainian)

Currently translated at 100.0% (6089 of 6089 strings)

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

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

Currently translated at 100.0% (6089 of 6089 strings)

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

* Translated using Weblate (Ukrainian)

Currently translated at 100.0% (6089 of 6089 strings)

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

* Translated using Weblate (Norwegian Bokmål)

Currently translated at 69.0% (4207 of 6089 strings)

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

* Translated using Weblate (Czech)

Currently translated at 100.0% (2618 of 2618 strings)

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

* Translated using Weblate (Czech)

Currently translated at 100.0% (6089 of 6089 strings)

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

* Translated using Weblate (Polish)

Currently translated at 100.0% (6089 of 6089 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: Bohdan <bshumylo@yahoo.com>
Co-authored-by: Konstantin <eleferen@gmail.com>
Co-authored-by: jprusch <rs@schaeferbarthold.de>
Co-authored-by: Tom De Moor <tom@controlaltdieliet.be>
Co-authored-by: master7 <marcin.karkosz@rajska.info>
Co-authored-by: Frank Paul Silye <frankps@gmail.com>
Co-authored-by: Serhii Khomiuk <sergiy.khomiuk@gmail.com>
Co-authored-by: Karel Trojan <kareltrojan+mattermost@gmail.com>
Co-authored-by: Matthew Williams <Matthew.Williams@outlook.com.au>
Co-authored-by: ThrRip <coding@thrrip.space>
Co-authored-by: Martin Mičuda <micuda@rematiptop.cz>
2025-03-24 13:34:01 -03:00
dependabot[bot]
8e03c466ab Bump the github-actions-updates group with 5 updates (#30549)
Bumps the github-actions-updates group with 5 updates:

| Package | From | To |
| --- | --- | --- |
| [actions/upload-artifact](https://github.com/actions/upload-artifact) | `4.4.3` | `4.6.2` |
| [github/codeql-action](https://github.com/github/codeql-action) | `3.28.11` | `3.28.12` |
| [actions/download-artifact](https://github.com/actions/download-artifact) | `4.1.8` | `4.2.1` |
| [tj-actions/changed-files](https://github.com/tj-actions/changed-files) | `531f5f7d163941f0c1c04e0ff4d8bb243ac4366f` | `27ae6b33eaed7bf87272fdeb9f1c54f9facc9d99` |
| [getsentry/action-release](https://github.com/getsentry/action-release) | `3.1.0` | `3.1.1` |


Updates `actions/upload-artifact` from 4.4.3 to 4.6.2
- [Release notes](https://github.com/actions/upload-artifact/releases)
- [Commits](https://github.com/actions/upload-artifact/compare/v4.4.3...ea165f8d65b6e75b540449e92b4886f43607fa02)

Updates `github/codeql-action` from 3.28.11 to 3.28.12
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](https://github.com/github/codeql-action/compare/v3.28.11...5f8171a638ada777af81d42b55959a643bb29017)

Updates `actions/download-artifact` from 4.1.8 to 4.2.1
- [Release notes](https://github.com/actions/download-artifact/releases)
- [Commits](https://github.com/actions/download-artifact/compare/v4.1.8...95815c38cf2ff2164869cbab79da8d1f422bc89e)

Updates `tj-actions/changed-files` from 531f5f7d163941f0c1c04e0ff4d8bb243ac4366f to 27ae6b33eaed7bf87272fdeb9f1c54f9facc9d99
- [Release notes](https://github.com/tj-actions/changed-files/releases)
- [Changelog](https://github.com/tj-actions/changed-files/blob/main/HISTORY.md)
- [Commits](531f5f7d16...27ae6b33ea)

Updates `getsentry/action-release` from 3.1.0 to 3.1.1
- [Release notes](https://github.com/getsentry/action-release/releases)
- [Changelog](https://github.com/getsentry/action-release/blob/master/CHANGELOG.md)
- [Commits](fa247637f7...00ed2a6cc2)

---
updated-dependencies:
- dependency-name: actions/upload-artifact
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: github-actions-updates
- dependency-name: github/codeql-action
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: github-actions-updates
- dependency-name: actions/download-artifact
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: github-actions-updates
- dependency-name: tj-actions/changed-files
  dependency-type: direct:production
  dependency-group: github-actions-updates
- dependency-name: getsentry/action-release
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: github-actions-updates
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-03-24 16:22:57 +02:00
Jesús Espino
a7c4ad832e MM-63379: Fixing bot showing the local time (#30426)
* Fixing bot showing the local time

* feat: Add tests for bot and non-bot user time indicator behavior

* test: Update use_post_box_indicator tests with React rendering

* Fixing linter checks
2025-03-24 12:02:21 +00:00
Maria A Nunez
d69e8b3e90 Removed draft tour point (#30532)
* Removed draft tour point

* Removed unused texts

* Fixed e2e tests

* Linting

---------

Co-authored-by: Mattermost Build <build@mattermost.com>
2025-03-21 11:06:36 -04:00
Claudio Costa
e495fb3182 Prepackage Metrics Plugin v0.6.0 (#30529) 2025-03-20 13:39:53 -06:00
Julien Tant
cb89e5646e [MM-62695] Extend property types for CPA (#30201)
* test: Add unit tests for custom profile attributes select options

* feat: Add custom profile attributes model with validation and constants

* refactor: Trim spaces from name and color in custom profile attribute select option constructor

* gofmt

* refactor: Fix typo in custom profile attributes select option function name

* feat: Add IsValid method to validate CustomProfileAttributesSelectOptions

* refactor: Replace map[string]bool with map[string]struct{} for key existence check

* refactor: Rename NewCustomProfileAttributeSelectOption to NewCustomProfileAttributesSelectOption

* feat: Add validation to prevent empty custom profile attribute options

* refactor: Add validation and creation methods for custom profile attributes

* feat: Add index number to validation error messages in custom profile attributes

* fix tests

* add default visibility

* feat: Add comprehensive test cases for custom profile attributes field validation

* fix: Update custom profile attributes map keys to use capitalized names

* feat: Add support for lowercase and title case keys in custom profile attributes map

* test: Add comprehensive test for NewCustomProfileAttributesSelectOptionFromMap

* feat: Add validation for custom profile attributes fields

* refactor: Update CustomProfileAttributesSelectOption constructor to prioritize ID parameter

* test: Add test cases for preserving IDs in custom profile attributes

* feat: Enhance ID validation and trimming in custom profile attributes

* don't do validation in constructor

* test: Add test case for preserving option IDs when patching select field

* improve test

* i18n

* refactor: Modify CustomProfileAttributesSelectOption to use lowercase JSON keys

* fix casing in custom profilte attributes test

* refactor: Use consistent "ValidateCPAField" in error messages for custom profile attributes

* use custom types rather than string

* lint

* fix api test

* refactor: Make color field optional in custom profile attributes

* style

* generic options

* removed unused i18n

* test: Add tests for NewCPAFieldFromPropertyField and CPAFieldToPropertyField

* test: Add test case for property field with empty attributes

* refactor: Cleanup whitespace and remove empty Attrs in custom profile attributes test

* test: Add test case for CPA field with empty attributes

* refactor: Improve custom profile attributes field handling and validation

* refactor: Move validateCustomProfileAttributesField to Validate method on CPAField struct

* use CPAField

* code style

* add validation and tests

* tests

* i18n

* err->appErr

* fix TestDeleteCPAField test

* i18n

* Add SAML and LDAP attr

* rename CustomProfileAttributes in method to CPA

* rename CPASortOrder method

* rearrange consts

* use Len test method

* sanitize and validate

* manage error the same way property field and value do

* fix: Update test error ID for custom profile attributes validation

* test: Update error ID expectations in custom profile attributes tests

* refactor: Convert CPAAttrs.SortOrder from string to int

* json uses float64

* feat: Add length validation for custom profile attribute option name and color

---------

Co-authored-by: Mattermost Build <build@mattermost.com>
2025-03-20 18:47:40 +00:00
Andy Lerandy
7770c03919 [GH-30077] New actions for websocket group member update (#30086)
* Added: Update on `groups` & `profiles` on websocket.
2025-03-20 09:28:46 -04:00
Ben Schumacher
12cbe5e839 Improve error message for failed file copied (#30418) 2025-03-20 13:15:22 +01:00
Ben Schumacher
9b5d8d52bf [MM-62427] Add message attachments validation (#30180)
* Add message attachments validation

* Add props validation

* Validate slack attachment fields

* Update tests and library usage

* Improve interactive dialog error for length checks

* Allow predefined colors for slack attachments

* Fix TestPostAction

* Use const for data source

* Add tests

* Cleanup unused props

* Add happy path tests

* lint fixes

* Add validation for PostActionOptions
2025-03-20 12:53:50 +01:00
Agniva De Sarker
5609489e86 MM-62900: Avoid redundant query for channelID while indexing file (#30289)
The file already has the ChannelID field. Therefore, we avoid querying
the database again. This sometimes causes errors in customer environments
where  there is noticeable replication lag, causing files not to be
indexed entirely.

https://mattermost.atlassian.net/browse/MM-62900

```release-note
NONE
```

Co-authored-by: Mattermost Build <build@mattermost.com>
2025-03-20 11:46:44 +05:30
Agniva De Sarker
a51a8e9b60 MM-62964: Skip setting replica lag handle in case of an error (#30498)
Previously, we would set it to nil pointer which would eventually
cause a panic when ReplicaLagAbs/ReplicaLagTime would get called.

https://mattermost.atlassian.net/browse/MM-62964

```release-note
NONE
```

Co-authored-by: Mattermost Build <build@mattermost.com>
2025-03-20 11:38:29 +05:30
Harrison Healey
3b9f9b209a MM-63350 Add tests for inviting guest users to teams (#30448)
* MM-63350 Add tests for inviting guest users to teams

* Fix style issue

* Fix one more issue
2025-03-19 17:27:33 -04:00
Ben Schumacher
2e44a6a1ed Improve error message for failed file copied (#30418) 2025-03-19 19:48:26 +01:00
Ben Schumacher
d7d8b4163e [MM-63442] Fix GET /groups endpoint docs (#30473)
* Fix GET /groups endpoint docs

* Extend groups endpoint tests
2025-03-19 19:38:37 +01:00
Maria A Nunez
6bbf356c3c Fixed copy link icon styling (#30407) 2025-03-19 13:05:29 -04:00
Jesse Hallam
594e8d3171 MM-62159: Avoid SELECT * in channel_store_categories.go (#30424)
* MM-62159: Avoid SELECT * in channel_store_categories.go

- Added sidebarCategorySelectQuery field to SqlChannelStore struct
- Replaced SELECT * with explicit column selection in GetSidebarCategory and getSidebarCategoriesT functions
- Updated raw SQL query in addChannelToFavoritesCategoryT to use explicit column selection
- Made the implementation more resilient to schema changes

🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>

* use sc alias, simplify

* MM-62159: Fix ambiguous ID column in sidebar category queries

- Modified sidebarCategorySelectQuery initialization to explicitly use "sc" table alias for all columns
- Prevents "Column 'Id' in field list is ambiguous" error when joining with other tables

🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>

* MM-62159: Consistently use table aliases in sidebar categories queries

- Added 'sc' table alias to all sidebar category queries
- Ensures consistency and avoids ambiguous column errors in future joins

🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>

* MM-62159: Replace 'sc' alias with full 'SidebarCategories' table name

- Replaced all instances of the 'sc' alias with the full table name 'SidebarCategories'
- Updated the SidebarCategories query builder to use the full table name
- Removed commented-out debug printf statement

🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
2025-03-19 10:49:19 -03:00
Scott Bishel
fd717cfa64 MM-59065 - New channel menu using new menu system (#30093)
* New channel menu using new menu system

* fix e2e-tests

* remove extraneous separator

* lint fix

* fix test after merge

* update to pass properties to first menu item

* fix e2etest

* refactor: Update channel header menu items to use const event handlers

* refactor: Extract plugin item click handler in channel header menu

* refactor: Improve error handling and button click handlers in mobile channel header plugins

* lint fixes

* updates for code reveiw

* run i18n-extract

* fix unit test

* fix: Close channel dropdown menu by clicking channel header title

* fix: Use keyboard escape to close channel dropdown menu in e2e tests

* fix cypress test

* fix: Resolve MUI Menu component fragment rendering issue

* cleanup

* remove unneccessary css

* fixing testing issues

---------

Co-authored-by: Mattermost Build <build@mattermost.com>
2025-03-19 07:06:04 -05:00
Agniva De Sarker
8eadf849bb MM-60790: Prevent stemming in DB search when search term is a fully quoted string (#30214)
When a search term is a fully quoted string, we want to avoid
stemming if it is supported by the search backend.

For Postgres, it does provide a feature by which if we use the
"simple" search config, then no stemming is performed and an exact
match with the word is done without having to resort
to LIKE queries.

Unfortunately, for ES/OS this is not an option because
the message field is a text field, which means ES/OS will analyze it,
stem it and store it in its root form. Therefore, no exact match
can be possible with ES/OS.

The only solution here is to have yet another keyword field
for message which will store it in its raw form. But this
will effectively double the disk storage for post indices
and not a good design choice.

Ref: https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-term-query.html#avoid-term-query-text-fields

https://mattermost.atlassian.net/browse/MM-60790

```release-note
NONE
```

* re-arrange the tests to run only on DB

```release-note
NONE
```

---------

Co-authored-by: Mattermost Build <build@mattermost.com>
2025-03-19 12:10:29 +05:30
Harshil Sharma
c951a9cfac Thread reply edit file handling bug fix (#30470)
* Fixed a bug where escape would delete all typed content

* Fixed rootId and postID

* fixed tests

* Type fix

* Fixed a test

* Search result edit fix

* Removed a test change

* threads view isn't RHS

* Fixed a cypress test

* Fixed a cypress test

* Fixed a flaky playwighr test
2025-03-18 16:19:18 +05:30
Angelos Kyratzakos
c1d4f5cb9f migrate tag-based references to commit SHA-based references for github workflows (#30509) 2025-03-18 12:32:39 +02:00
Weblate (bot)
c95968c380 Translations update from Mattermost Weblate (#30502)
Automatic Merge
2025-03-17 17:53:15 +02:00
Alejandro García Montoro
350714f390 Bump Go to v1.23.7 (#30455)
* Update Go version to v1.23.7

* Bump golangci-lint to a version supporting Go 1.23

* Fix golangci-lint warnings

Several rules from gosimple, revive and staticcheck linters were
failing:
- Redefinition of built-in identifiers (max, min, new, recover...)
- Use of printf-like functions with simple strings
- Check for nil slices, when len already takes it into account

* Trigger Build

* Trigger Build

---------

Co-authored-by: Mattermost Build <build@mattermost.com>
2025-03-17 14:22:07 +01:00
Arya Khochare
33d207d81a Blank page in Browse Channel Modal fixed (Pagination reset on filter change) (#29921)
* Blank page in browse channel fixed (Pagination reset on filter change)

* method usage for archived channel menu item fixed

---------

Co-authored-by: Mattermost Build <build@mattermost.com>
2025-03-17 09:08:55 -04:00
dependabot[bot]
c22df96f6b Bump the github-actions-updates group across 1 directory with 6 updates (#30500)
Bumps the github-actions-updates group with 6 updates in the / directory:

| Package | From | To |
| --- | --- | --- |
| [actions/setup-node](https://github.com/actions/setup-node) | `4.2.0` | `4.3.0` |
| [docker/login-action](https://github.com/docker/login-action) | `3.3.0` | `3.4.0` |
| [github/codeql-action](https://github.com/github/codeql-action) | `3.28.10` | `3.28.11` |
| [tj-actions/changed-files](https://github.com/tj-actions/changed-files) | `dcc7a0cba800f454d79fff4b993e8c3555bcc0a8` | `531f5f7d163941f0c1c04e0ff4d8bb243ac4366f` |
| [getsentry/action-release](https://github.com/getsentry/action-release) | `3.0.0` | `3.1.0` |
| [mikepenz/action-junit-report](https://github.com/mikepenz/action-junit-report) | `5.4.0` | `5.5.0` |



Updates `actions/setup-node` from 4.2.0 to 4.3.0
- [Release notes](https://github.com/actions/setup-node/releases)
- [Commits](1d0ff469b7...cdca7365b2)

Updates `docker/login-action` from 3.3.0 to 3.4.0
- [Release notes](https://github.com/docker/login-action/releases)
- [Commits](9780b0c442...74a5d14239)

Updates `github/codeql-action` from 3.28.10 to 3.28.11
- [Release notes](https://github.com/github/codeql-action/releases)
- [Commits](https://github.com/github/codeql-action/compare/v3.28.10...v3.28.11)

Updates `tj-actions/changed-files` from dcc7a0cba800f454d79fff4b993e8c3555bcc0a8 to 531f5f7d163941f0c1c04e0ff4d8bb243ac4366f
- [Release notes](https://github.com/tj-actions/changed-files/releases)
- [Changelog](https://github.com/tj-actions/changed-files/blob/main/HISTORY.md)
- [Commits](dcc7a0cba8...531f5f7d16)

Updates `getsentry/action-release` from 3.0.0 to 3.1.0
- [Release notes](https://github.com/getsentry/action-release/releases)
- [Changelog](https://github.com/getsentry/action-release/blob/master/CHANGELOG.md)
- [Commits](f56d67ba2a...fa247637f7)

Updates `mikepenz/action-junit-report` from 5.4.0 to 5.5.0
- [Release notes](https://github.com/mikepenz/action-junit-report/releases)
- [Commits](b14027d33d...97744eca46)

---
updated-dependencies:
- dependency-name: actions/setup-node
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: github-actions-updates
- dependency-name: docker/login-action
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: github-actions-updates
- dependency-name: github/codeql-action
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: github-actions-updates
- dependency-name: tj-actions/changed-files
  dependency-type: direct:production
  dependency-group: github-actions-updates
- dependency-name: getsentry/action-release
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: github-actions-updates
- dependency-name: mikepenz/action-junit-report
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: github-actions-updates
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-03-17 10:42:10 +00:00
Christopher Poile
c049748b88 [MM-63314] Fix ClaimJob in HA environments (#30383)
* ClaimJob now returns newly claimed job

* internal code affected by change

* test changes required

* two branches: for mysql, use transaction; for postgres, use returning

* two branches: for mysql, use transaction; for postgres, use returning

* use same millis value for LastActivityAt and StartAt

* blank commit

---------

Co-authored-by: Mattermost Build <build@mattermost.com>
2025-03-14 10:24:26 -04:00
Daniel Espino García
c9504925e6 Fix user post box indicator flaky test (#30480) 2025-03-14 12:03:13 +01:00
Pablo Vélez
5f9f90c3e2 MM-T360 - search hashtags from mentions (#30406)
Co-authored-by: Mattermost Build <build@mattermost.com>
2025-03-14 09:57:31 +01:00
Nick Misasi
b5a4147847 Add company_country to trial license fetch (#30471)
Automatic Merge
2025-03-13 23:36:33 +02:00
Ben Cooke
ccd8a60168 Plugin groups (#30320)
* add new pluginapi methods

* SAML login hook

* set ReAddRemovedMembers to true for plugin groups

* change to DoLogin signature for SAML
2025-03-13 12:00:15 -04:00
Claudio Costa
0e0e54446d Prepackage Calls v1.6.0 (#30461) 2025-03-13 09:34:50 -06:00
Arya Khochare
4fbfd84957 [MM-61691] Deleting drafts when permanently deleting a user (#30233)
* deleting drafts on permanently deleting user

* verified count of drafts before deleting

* i18n fix

* use ExecBuilder

* changed error message to specify user

---------

Co-authored-by: Mattermost Build <build@mattermost.com>
Co-authored-by: Harshil Sharma <harshilsharma63@gmail.com>
2025-03-13 19:19:38 +05:30
Harshil Sharma
e2a7240e34 Fixed a bug where escape would delete all typed content (#30452) 2025-03-13 19:01:16 +05:30
Elias Nahum
3af8d50bbe Add config settings for additional security features on mobile (#30411) 2025-03-13 19:39:19 +08:00
Harshil Sharma
84fa496c69 Added missed license check for channel banner in patch channel API (#30445)
* Added missed license check for channel banner in patch channel API

* Extractced permission check function
2025-03-13 12:38:29 +05:30
Scott Bishel
4fc77ce368 update and add tests (#28140)
Co-authored-by: Mattermost Build <build@mattermost.com>
2025-03-12 22:24:16 +00:00
Ben Cooke
eb967b6b6d MM-61707 (#29606)
* updating maxattempts for ldap
2025-03-12 18:22:03 -04:00
Pablo Vélez
2102391672 MM-61566 - focus first focusable element (#30294)
* MM-61566 - focus first focusable element

* adjust e2e tests to new focused element

* adjust real-events library to use with cypress
2025-03-12 23:10:07 +01:00
Saurabh Sharma
cc92ee79c9 [MM-61640]: Add descriptive accessible names (#29928)
* [MA-57]: Add descriptive accessible names

* [MA-57]: Updated unread message to be translatable

* [MA-57]: Fixed failing e2e test cases

* [MA-57]: Added Type definition for channel sidebar helper function and fixed failing e2e test case

* rm capitalize

---------

Co-authored-by: ayush-chauhan233 <ayush.chauhan@brightscout.com>
Co-authored-by: Mattermost Build <build@mattermost.com>
Co-authored-by: M-ZubairAhmed <m-zubairahmed@protonmail.com>
2025-03-12 17:34:45 -04:00
Scott Bishel
7d2f0c2c31 only prompt on private channels (#30385)
Co-authored-by: Mattermost Build <build@mattermost.com>
2025-03-12 14:32:39 -06:00
Jesse Hallam
9fc83f24b5 MM-62161: Replace SELECT * in session_store.go (#30422)
* MM-62161: Replace SELECT * in session_store.go

- Replaced all SELECT * queries with explicit column selection
- Used query builder instead of raw SQL strings where possible
- Added reusable sessionSelectQuery in the store constructor
- Added comprehensive test for GetSessionsWithActiveDeviceIds

🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>

* Fix variable shadowing issues in session_store.go

Resolved variable shadowing by reassigning to the existing error variables instead of declaring new ones in scoped blocks.

🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>

* Fix code formatting in session_store test file

🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
2025-03-12 19:35:33 +00:00
Caleb Roseland
8a21016266 MM-63271: CPA Sorting in Profile Popover & Profile Settings (#30369)
* sort in selector

* test

* lint/test

* test
2025-03-12 13:27:35 -05:00
Julien Tant
9f1ec59fa0 [MM-62133] Activate crossteam search by default (#30348)
* activate cross team search by default

* fix e2e test

---------

Co-authored-by: Mattermost Build <build@mattermost.com>
2025-03-12 10:24:39 -07:00
Arya Khochare
52f37f8514 [MM-62185] Hide timezone notice for bot DMs (#30083)
* Hide timezone notice for bot DMs

* showRemoteUserHour to false

* use_post_box_indicator test

* added showRemoteUserHour in all test cases

---------

Co-authored-by: Mattermost Build <build@mattermost.com>
2025-03-12 12:20:19 -04:00
Sumit Bhanushali
ddec6882fc MM-63262 Added missing onClick event on channel header (#30339) 2025-03-12 12:15:24 -04:00
Jesse Hallam
fe7d6dcc13 MM-63420: skip flaky tests (#30457) 2025-03-12 15:45:15 +00:00
unified-ci-app[bot]
b365967329 Update latest minor version to 10.7.0 (#30449)
Co-authored-by: unified-ci-app[bot] <121569378+unified-ci-app[bot]@users.noreply.github.com>
2025-03-12 11:58:12 +02:00
Georg Bremer
40b5f71054 feat: Add Client4.createPostEphemeral method (#30117)
* feat: Add Client4.createPostEphemeral method

* Update webapp/platform/client/src/client4.ts

---------

Co-authored-by: Harrison Healey <harrisonmhealey@gmail.com>
Co-authored-by: Mattermost Build <build@mattermost.com>
2025-03-11 18:48:51 -04:00
Arya Khochare
a4c5e52b6b width of edit input fixed on using grammarly plugin (#30298) 2025-03-11 17:48:05 -04:00
Claudio Costa
7c25de2cff [MM-63345] Address Go v1.23 incompatibility issues with plugins (#30386)
* Address Go v1.23 incompatibility issues with plugins

* Install multiple Go versions for compatibility tests

* Rename
2025-03-11 17:44:42 +00:00
Pablo Vélez
661f7f6a83 Mm 62677 modal focus second part (#30099)
* MM-62312 - modal focus management; revamp quick switch channel modal!

* get quick switch test working

* configure the generic modal to accept refs to focus within and onhide to the origin element

* apply pr feedback, get modal element get autofocus, use id instead of ref

* update more direct channels modal to use generic modal

* fix unit tests and snapshots

* fix unit tests

* fix modal margin top to fit in smaller screens

* fix e2e test

* remove unnecesary onexited extra call

* fix e2e tests

* set correct label

* fix snapshots

* create helper function for sending custom focus event

* migrate quick switch modal to use new approach to focus

* migrate more direct channels modal to new approach

* fix snapshots

* fix types

* fix modal closing behavior

* fix snapshots

* fix cypress tests

* remove only

* MM-62677 - migrate modals, invite modal work

* user settings modal

* fix snapshots

* finish user settings migration

* migrate confirm modal to use generic modal

* notification preferences migration

* implement focus back to trigger to channel notifications modal

* fix test snapshots

* initial self code review

* fix CI errors, translation and some types

* add modal location param and adjust test

* fix cypress test text

* fix cypress test text

* fix e2e test for invitation modal

* fix e2e test selector

* adjust modal height

* temp

* fix e2e tests

* fix snapshot

* fix e2e tests

* fix snapshots

* fix snapshots

* fix snapshots

* fix e2e tests

* update snapshots

* fix snapshots

* fix linter

* Implement PR feedback

* fix e2e tests

* adjust styling for channel notifications modal

* more fixes to e2e tests

---------

Co-authored-by: Mattermost Build <build@mattermost.com>
2025-03-10 23:20:59 +01:00
Claudio Costa
1c6a130787 Prepackage Calls v1.5.2 (#30437) 2025-03-10 13:24:42 -06:00
Weblate (bot)
9a60b11486 Translations update from Mattermost Weblate (#30435)
* Translated using Weblate (Polish)

Currently translated at 100.0% (2609 of 2609 strings)

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

* Translated using Weblate (Russian)

Currently translated at 96.5% (2520 of 2609 strings)

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

* Translated using Weblate (German)

Currently translated at 100.0% (2609 of 2609 strings)

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

* Translated using Weblate (Ukrainian)

Currently translated at 99.8% (2604 of 2609 strings)

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

* Translated using Weblate (Ukrainian)

Currently translated at 96.6% (5869 of 6074 strings)

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

* Translated using Weblate (Ukrainian)

Currently translated at 97.0% (5895 of 6074 strings)

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

* Translated using Weblate (Ukrainian)

Currently translated at 97.1% (5901 of 6074 strings)

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

* Translated using Weblate (Ukrainian)

Currently translated at 97.6% (5932 of 6074 strings)

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

* Translated using Weblate (Ukrainian)

Currently translated at 98.8% (6005 of 6074 strings)

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

* Translated using Weblate (Ukrainian)

Currently translated at 99.0% (6017 of 6074 strings)

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

* Translated using Weblate (Norwegian Bokmål)

Currently translated at 2.6% (70 of 2609 strings)

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

* Translated using Weblate (Norwegian Bokmål)

Currently translated at 66.9% (4064 of 6074 strings)

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

* Translated using Weblate (Ukrainian)

Currently translated at 100.0% (2609 of 2609 strings)

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

* Translated using Weblate (Ukrainian)

Currently translated at 99.1% (6020 of 6074 strings)

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

* Translated using Weblate (Norwegian Bokmål)

Currently translated at 67.0% (4074 of 6074 strings)

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

* Translated using Weblate (Spanish)

Currently translated at 75.7% (4599 of 6074 strings)

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

* Translated using Weblate (Ukrainian)

Currently translated at 99.1% (6025 of 6074 strings)

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

* Translated using Weblate (Danish)

Currently translated at 11.4% (694 of 6074 strings)

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

* Translated using Weblate (Ukrainian)

Currently translated at 99.2% (6026 of 6074 strings)

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

* Translated using Weblate (Ukrainian)

Currently translated at 99.8% (6067 of 6074 strings)

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

---------

Co-authored-by: master7 <marcin.karkosz@rajska.info>
Co-authored-by: Konstantin <eleferen@gmail.com>
Co-authored-by: jprusch <rs@schaeferbarthold.de>
Co-authored-by: Bohdan <bshumylo@yahoo.com>
Co-authored-by: Frank Paul Silye <frankps@gmail.com>
Co-authored-by: Serhii Khomiuk <sergiy.khomiuk@gmail.com>
Co-authored-by: Carloswaldo <waldosaurio@gmail.com>
Co-authored-by: Allan Kimmer Jensen <hi@akj.io>
2025-03-10 16:11:28 -03:00
Saurabh Sharma
268b921913 [MM-61685]: Add described by prop to notifications settings (#29813)
* MM-61685: Add described by prop to notifications settings

* MM-61685: Fixed issue related to aria-described being overritten internally

* MM-61685: Moved Input component outside NotificationTab class component

* MM-61685: Fixed failing CI

---------

Co-authored-by: ayush-chauhan233 <ankur@brightscout.com>
Co-authored-by: ayush-chauhan233 <ayush.chauhan@brightscout.com>
Co-authored-by: Mattermost Build <build@mattermost.com>
2025-03-10 12:52:47 -04:00
ayush-chauhan233
2cb8d65522 [MM-61604]: Fixed aria-expanded not correctly announced by screen reader (#30262)
* [MM-61604]: Fixed aria-expanded not correctly announced by screen reader

* [MM-61604]: Translation changes
2025-03-10 11:08:57 -04:00
Miguel de la Cruz
c5e6d9f570 Updates the property service and store method signatures (#30103)
* Updates the property service and store method signatures

Getters can now receive a `groupID` that narrows down the query if
present, so it's not necessary to check for the group ID on the
returning values from the outside layers.

The Search methods now receive the `groupID` and the `targetID`
explicitly as parameters, incentivizing the use of the indexes that
the underlying tables have on the searches.

* Fix tests

---------

Co-authored-by: Miguel de la Cruz <miguel@ctrlz.es>
Co-authored-by: Mattermost Build <build@mattermost.com>
2025-03-10 14:26:47 +00:00
Clément Collin
dd258f5ee5 MM-53506 Fixed duplicated command response in thread/channel (#23969) (#30310)
- Ephemeral system answers from commands in threads are also posted in parent channel
- Removed an obsolete condition that provoked the bug
2025-03-10 10:42:40 +01:00
Scott Bishel
5fe7c36457 make sure RestrictSystemAdmin returns for all users access system console (#30384)
Co-authored-by: Mattermost Build <build@mattermost.com>
2025-03-08 08:13:19 -07:00
Claudio Costa
e549aaffb0 Fix incorrect error handling in api4.downloadJob (#30410) 2025-03-06 08:04:39 -06:00
Doug Lauder
dfca6c211d MM-63327 Config setting for ServiceSettings.FrameAncestors (#30409)
* Add Embedding page to system console, with single setting for Frame Ancestors
2025-03-05 18:01:43 -05:00
dependabot[bot]
ad73ef7340 Bump the github-actions-updates group across 1 directory with 8 updates (#30394)
Bumps the github-actions-updates group with 8 updates in the / directory:

| Package | From | To |
| --- | --- | --- |
| [docker/build-push-action](https://github.com/docker/build-push-action) | `6.13.0` | `6.15.0` |
| [github/codeql-action](https://github.com/github/codeql-action) | `3.28.9` | `3.28.10` |
| [ossf/scorecard-action](https://github.com/ossf/scorecard-action) | `2.4.0` | `2.4.1` |
| [getsentry/action-release](https://github.com/getsentry/action-release) | `1.10.3` | `3.0.0` |
| [aws-actions/configure-aws-credentials](https://github.com/aws-actions/configure-aws-credentials) | `4.0.3` | `4.1.0` |
| [sigstore/cosign-installer](https://github.com/sigstore/cosign-installer) | `3.8.0` | `3.8.1` |
| [docker/setup-buildx-action](https://github.com/docker/setup-buildx-action) | `3.9.0` | `3.10.0` |
| [mikepenz/action-junit-report](https://github.com/mikepenz/action-junit-report) | `5.3.0` | `5.4.0` |



Updates `docker/build-push-action` from 6.13.0 to 6.15.0
- [Release notes](https://github.com/docker/build-push-action/releases)
- [Commits](ca877d9245...471d1dc4e0)

Updates `github/codeql-action` from 3.28.9 to 3.28.10
- [Release notes](https://github.com/github/codeql-action/releases)
- [Commits](https://github.com/github/codeql-action/compare/v3.28.9...v3.28.10)

Updates `ossf/scorecard-action` from 2.4.0 to 2.4.1
- [Release notes](https://github.com/ossf/scorecard-action/releases)
- [Changelog](https://github.com/ossf/scorecard-action/blob/main/RELEASE.md)
- [Commits](62b2cac7ed...f49aabe0b5)

Updates `getsentry/action-release` from 1.10.3 to 3.0.0
- [Release notes](https://github.com/getsentry/action-release/releases)
- [Changelog](https://github.com/getsentry/action-release/blob/master/CHANGELOG.md)
- [Commits](12bba0bd9c...f56d67ba2a)

Updates `aws-actions/configure-aws-credentials` from 4.0.3 to 4.1.0
- [Release notes](https://github.com/aws-actions/configure-aws-credentials/releases)
- [Changelog](https://github.com/aws-actions/configure-aws-credentials/blob/main/CHANGELOG.md)
- [Commits](4fc4975a85...ececac1a45)

Updates `sigstore/cosign-installer` from 3.8.0 to 3.8.1
- [Release notes](https://github.com/sigstore/cosign-installer/releases)
- [Commits](c56c2d3e59...d7d6bc7722)

Updates `docker/setup-buildx-action` from 3.9.0 to 3.10.0
- [Release notes](https://github.com/docker/setup-buildx-action/releases)
- [Commits](f7ce87c1d6...b5ca514318)

Updates `mikepenz/action-junit-report` from 5.3.0 to 5.4.0
- [Release notes](https://github.com/mikepenz/action-junit-report/releases)
- [Commits](ee6b445351...b14027d33d)

---
updated-dependencies:
- dependency-name: docker/build-push-action
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: github-actions-updates
- dependency-name: github/codeql-action
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: github-actions-updates
- dependency-name: ossf/scorecard-action
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: github-actions-updates
- dependency-name: getsentry/action-release
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: github-actions-updates
- dependency-name: aws-actions/configure-aws-credentials
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: github-actions-updates
- dependency-name: sigstore/cosign-installer
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: github-actions-updates
- dependency-name: docker/setup-buildx-action
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: github-actions-updates
- dependency-name: mikepenz/action-junit-report
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: github-actions-updates
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-03-05 11:38:09 +02:00
Harrison Healey
2919380bd9 MM-63213 Remove background from more modal plus button (#30368) 2025-03-04 21:11:21 +00:00
Agniva De Sarker
a5d318cdfb [AI assisted] MM-63304: Wrap around dqPtr while unmarshalling (#30371)
If the deadQueue was full, we would be incorrectly sending
the wrong index for dqPtr. Fixed that and added a test case.

https://mattermost.atlassian.net/browse/MM-63304

```release-note
NONE
```
2025-03-04 13:36:04 +05:30
Caleb Roseland
7e9cff04c7 use break-word in profile popover fields (#30366) 2025-03-03 11:25:56 -06:00
Felipe Martin
255e1a8ac1 [MM-63325, MM-63329] feat: dont register plugins or show the footer if MMEMBED cookie is set to 1 (#30393)
* feat: no-op register plugin if MMEMBED=1
* feat: disable footer links when MMEMBED=1
2025-03-03 11:24:24 -05:00
Frank Paul Silye
854011cf77 Translated using Weblate (Norwegian Bokmål)
Currently translated at 66.7% (4056 of 6074 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/nb_NO/
2025-03-03 15:49:07 +00:00
Tom De Moor
5ef486c68a Translated using Weblate (Dutch)
Currently translated at 99.8% (2599 of 2604 strings)

Translation: Mattermost/server
Translate-URL: https://translate.mattermost.com/projects/mattermost/server/nl/
2025-03-03 15:49:07 +00:00
MArtin Johnson
a76969fadb Translated using Weblate (Swedish)
Currently translated at 100.0% (2604 of 2604 strings)

Translation: Mattermost/server
Translate-URL: https://translate.mattermost.com/projects/mattermost/server/sv/
2025-03-03 15:49:07 +00:00
Frank Paul Silye
e3a3220c4c Translated using Weblate (Norwegian Bokmål)
Currently translated at 66.7% (4054 of 6074 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/nb_NO/
2025-03-03 15:49:07 +00:00
Frank Paul Silye
529eff5b77 Translated using Weblate (Norwegian Bokmål)
Currently translated at 66.2% (4024 of 6074 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/nb_NO/
2025-03-03 15:49:07 +00:00
Frank Paul Silye
6bbfbcf620 Translated using Weblate (Norwegian Bokmål)
Currently translated at 2.5% (66 of 2604 strings)

Translation: Mattermost/server
Translate-URL: https://translate.mattermost.com/projects/mattermost/server/nb_NO/
2025-03-03 15:49:07 +00:00
Frank Paul Silye
0fd87fc5d1 Translated using Weblate (Norwegian Bokmål)
Currently translated at 65.1% (3955 of 6074 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/nb_NO/
2025-03-03 15:49:07 +00:00
Frank Paul Silye
25f3e51454 Translated using Weblate (Norwegian Bokmål)
Currently translated at 64.9% (3945 of 6074 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/nb_NO/
2025-03-03 15:49:07 +00:00
Frank Paul Silye
d489e7e141 Translated using Weblate (Norwegian Bokmål)
Currently translated at 64.3% (3907 of 6074 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/nb_NO/
2025-03-03 15:49:07 +00:00
Frank Paul Silye
2e2254a5e8 Translated using Weblate (Norwegian Bokmål)
Currently translated at 64.1% (3896 of 6074 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/nb_NO/
2025-03-03 15:49:07 +00:00
Serhii Khomiuk
f2ef3c9a98 Translated using Weblate (Ukrainian)
Currently translated at 100.0% (2604 of 2604 strings)

Translation: Mattermost/server
Translate-URL: https://translate.mattermost.com/projects/mattermost/server/uk/
2025-03-03 15:49:07 +00:00
Takuya N
8ea3e880a8 Translated using Weblate (Japanese)
Currently translated at 99.9% (2603 of 2604 strings)

Translation: Mattermost/server
Translate-URL: https://translate.mattermost.com/projects/mattermost/server/ja/
2025-03-03 15:49:07 +00:00
Martin Mičuda
3795d2756a Translated using Weblate (Czech)
Currently translated at 100.0% (6074 of 6074 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/cs/
2025-03-03 15:49:07 +00:00
Martin Mičuda
4608420072 Translated using Weblate (Czech)
Currently translated at 100.0% (6074 of 6074 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/cs/
2025-03-03 15:49:07 +00:00
Martin Mičuda
49d1275fc6 Translated using Weblate (Czech)
Currently translated at 100.0% (2604 of 2604 strings)

Translation: Mattermost/server
Translate-URL: https://translate.mattermost.com/projects/mattermost/server/cs/
2025-03-03 15:49:07 +00:00
Frank Paul Silye
8bff796c86 Translated using Weblate (Norwegian Bokmål)
Currently translated at 63.7% (3872 of 6074 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/nb_NO/
2025-03-03 15:49:07 +00:00
Frank Paul Silye
cb1474aba4 Translated using Weblate (Norwegian Bokmål)
Currently translated at 63.7% (3870 of 6074 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/nb_NO/
2025-03-03 15:49:07 +00:00
Frank Paul Silye
1e9f65580d Translated using Weblate (Norwegian Bokmål)
Currently translated at 63.4% (3853 of 6074 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/nb_NO/
2025-03-03 15:49:07 +00:00
master7
da15d0271b Translated using Weblate (Polish)
Currently translated at 100.0% (6074 of 6074 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/pl/
2025-03-03 15:49:07 +00:00
Frank Paul Silye
48dec9ed11 Translated using Weblate (Norwegian Bokmål)
Currently translated at 63.3% (3848 of 6074 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/nb_NO/
2025-03-03 15:49:07 +00:00
Frank Paul Silye
d1d63e6286 Translated using Weblate (Norwegian Bokmål)
Currently translated at 2.5% (66 of 2604 strings)

Translation: Mattermost/server
Translate-URL: https://translate.mattermost.com/projects/mattermost/server/nb_NO/
2025-03-03 15:49:07 +00:00
Ricardo Obregón
d7cf5ec1e7 Translated using Weblate (Spanish)
Currently translated at 86.9% (2265 of 2604 strings)

Translation: Mattermost/server
Translate-URL: https://translate.mattermost.com/projects/mattermost/server/es/
2025-03-03 15:49:07 +00:00
Bohdan
e3fc1151ae Translated using Weblate (Ukrainian)
Currently translated at 94.8% (5762 of 6074 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/uk/
2025-03-03 15:49:07 +00:00
Konstantin
6597573c60 Translated using Weblate (Russian)
Currently translated at 95.2% (5784 of 6074 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/ru/
2025-03-03 15:49:07 +00:00
Konstantin
16325b3d48 Translated using Weblate (Russian)
Currently translated at 96.6% (2516 of 2604 strings)

Translation: Mattermost/server
Translate-URL: https://translate.mattermost.com/projects/mattermost/server/ru/
2025-03-03 15:49:07 +00:00
jprusch
b0b2140ed6 Translated using Weblate (German)
Currently translated at 100.0% (2604 of 2604 strings)

Translation: Mattermost/server
Translate-URL: https://translate.mattermost.com/projects/mattermost/server/de/
2025-03-03 15:49:07 +00:00
master7
190e4c5dd1 Translated using Weblate (Polish)
Currently translated at 100.0% (6074 of 6074 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/pl/
2025-03-03 15:49:07 +00:00
master7
eb633deade Translated using Weblate (Polish)
Currently translated at 100.0% (2604 of 2604 strings)

Translation: Mattermost/server
Translate-URL: https://translate.mattermost.com/projects/mattermost/server/pl/
2025-03-03 15:49:07 +00:00
Frank Paul Silye
3eb2c5ca65 Translated using Weblate (Norwegian Bokmål)
Currently translated at 63.0% (3827 of 6074 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/nb_NO/
2025-03-03 15:49:07 +00:00
Ricardo Obregón
41f39c02e9 Translated using Weblate (Spanish)
Currently translated at 84.6% (2204 of 2604 strings)

Translation: Mattermost/server
Translate-URL: https://translate.mattermost.com/projects/mattermost/server/es/
2025-03-03 15:49:07 +00:00
Devin Binnie
7ab585e132 [MM-62711] Don't count non-members in the provided list (#30349)
Co-authored-by: Mattermost Build <build@mattermost.com>
2025-02-28 12:23:44 -05:00
kshitij katiyar
d0d20ac1ea Bump prepackage Jira plugin version to 4.2.1 (#30273) 2025-02-28 09:24:31 +01:00
Domenico Rizzo
b7d95f5368 [MM-23180] Take full-width punctuation marks as boundary for hyperlinks (#30084) 2025-02-28 10:00:45 +05:30
ayush-chauhan233
0acadb7b93 [MM-61592]: Updated the Theme list section in the settings modal (#29596)
* [MA-13]: Updated the Theme list section in the settings modal

* [MA-13]: Fixed failing e2e test cases

* [MA-13]: Fixed accordion and removed aria-label from button

* [MA-13]: Fixed grouping of radio buttons

* [MA-13]: Updated the Theme list structure

* [MA-13]: Minor styling changes

---------

Co-authored-by: Mattermost Build <build@mattermost.com>
2025-02-27 16:29:25 -05:00
Ben Schumacher
e1336b24bf Skip flaky test TestBusySet (#30363) 2025-02-27 16:59:49 +01:00
Devin Binnie
341186355d [MM-62798][MM-63193] Restrict channel permissions on archived channels when viewing archived channels is disabled (#30314)
* [MM-62798][MM-63193] Restrict channel permissions on archived channels when viewing archived channels is disabled

* PR feedback

* PR feedback
2025-02-27 15:05:16 +00:00
Devin Binnie
aa1f50cb30 [MM-62609] Show Group Mentions permissions if custom groups is enabled (#30319) 2025-02-27 09:25:19 -05:00
Agniva De Sarker
ac10bb12a5 Revert "Bump Go version to 1.23.6 (#30242)" (#30359)
This reverts commit acbbd4c58d.
2025-02-27 14:58:51 +05:30
Eva Sarafianou
690cbc9fa3 bump prepackaged msteams version (#30344) 2025-02-27 10:06:17 +02:00
Harrison Healey
470123125a MM-63205 Revert emoji store methods to return empty arrays instead of nil (#30337)
* MM-63205 Revert emoji store methods to return empty arrays instead of nil

* Update tests for getEmojiList

* Add case to TestGetEmojisByNames

* Update tests for searchEmoji and autocompleteEmoji
2025-02-26 15:40:52 -05:00
Devin Binnie
9f49403d0a [MM-62687] Patch permission check to avoid modifying the system admin (#30292)
* [MM-62687] Patch permission check to avoid modifying the system admin

* Check for manage system first

* PR feedback

* Add another test

* Lint

* Fix test
2025-02-26 20:25:02 +00:00
Doug Lauder
a732962f0a add readme to the remotecluster and sharedchannel service directories (#30123) 2025-02-26 19:35:54 +01:00
Alejandro García Montoro
acbbd4c58d Bump Go version to 1.23.6 (#30242)
* Bump Go version to 1.23.6

* Update CodeQL Github action as well

* Use server's Go version for CodeQL action

Co-authored-by: Antonis Stamatiou <stamatiou.antonis@gmail.com>

* Empty commit to trigger CI

* Bump golangci-lint to a version supporting Go 1.23

* Fix golangci-lint warnings

Several rules from gosimple, revive and staticcheck linters were
failing:
- Redefinition of built-in identifiers (max, min, new, recover...)
- Use of printf-like functions with simple strings
- Check for nil slices, when len already takes it into account

---------

Co-authored-by: Antonis Stamatiou <stamatiou.antonis@gmail.com>
Co-authored-by: Mattermost Build <build@mattermost.com>
2025-02-26 16:43:04 +01:00
enzowritescode
77ae2e2d6d Fix doc comments and IDE complaint about ie. vs i.e. (#30340) 2025-02-26 08:17:56 -07:00
ayush-chauhan233
8e9a09e512 [MM-61647][MM-61651]: Upgraded react-select to v5 (#30070)
* [MM-61647]: Upgraded react-select to v5
- Updated old type definitions with new v5 packaged type definitions.
- Removed some unused props
- Updated onBlur, onFocus and handleInputChange methods in user_input_email component

* Fix incorrect usage of handleInputChange in ChannelsInput

* Remove type assertions from dropdown_input_hybrid.tsx

* Simplify typing of users_emails_input.tsx

* [MM-61647][MM-61651]: Fixed some type definitions and e2e failing test case

* [MM-61647][MM-61651]: Fixed type error in dropdown_input_hybrid

* [MM-61647][MM-61651]: Fixed failing CI type error and e2e test cases

* [MM-61647][MM-61651]: Fixed failing e2e test case

* [MM-61647][MM-61651]: Updated the styles and reverted the test case changes
- Fixed the theme not getting correctly inherited
- Fixed the timezone and language settings getting saved on enter

---------

Co-authored-by: Harrison Healey <harrisonmhealey@gmail.com>
Co-authored-by: Mattermost Build <build@mattermost.com>
2025-02-25 17:13:51 -05:00
ayush-chauhan233
6ecaad2a41 MM-61652: Removed heading related role from channel header (#30277) 2025-02-25 16:59:30 -05:00
Harrison Healey
3902d00d0f MM-61947 Run DND expiry job more often and round expiry time to match interval (#29938)
* MM-61947 Run DND expiry job more often and round expiry time to match interval

* Move comment to make it godoc-compatible

* Change truncateDNDEndTime to work with seconds

---------

Co-authored-by: Mattermost Build <build@mattermost.com>
2025-02-25 16:20:00 -05:00
Arya Khochare
e8ef26196c Fixed errcheck issues in server/channels/app/permissions.go (#29064)
Co-authored-by: Ben Schumacher <ben.schumacher@mattermost.com>
2025-02-25 10:49:28 +01:00
Harshil Sharma
6e738f489f Channel banner sql migrations (#30274)
* Adde MySQL and Postgres migrations

* Replaced select * with column names

* removed all * from channel SQL store

* cleanup

* Fixed a duplicate column

* cleanup

* Added migrations and store support

* WIP

* used channelname slice in a missed place

* Handled patch

* Added app level tests

* Added API layer tests

* Added API layer tests

* WIP

* converted to query builder

* cleanupo

* added not null and default constraints

* Fixed test

* fixed file name

* review fixes

* review fixes

* updated migration file

* fixed text

* Review fixes
2025-02-25 14:52:15 +05:30
unified-ci-app[bot]
6df8726321 chore: Update NOTICE.txt file with updated dependencies (#30309)
Automatic Merge
2025-02-25 08:50:08 +02:00
Agniva De Sarker
4e5cb16955 MM-62079: Using a cache prefix to isolate cache keys for each test (#30261)
```release-note
A new config setting CacheSettings.RedisCachePrefix has been added which can be used to add a prefix to all Redis cache keys.
```
2025-02-25 09:22:15 +05:30
Ricky Tigg
e5755c925a Translated using Weblate (Finnish)
Currently translated at 26.8% (1630 of 6074 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/fi/
2025-02-24 19:18:11 +00:00
Ricky Tigg
2b04b68af3 Translated using Weblate (Finnish)
Currently translated at 47.9% (1249 of 2604 strings)

Translation: Mattermost/server
Translate-URL: https://translate.mattermost.com/projects/mattermost/server/fi/
2025-02-24 19:18:11 +00:00
Frank Paul Silye
b15b26515c Translated using Weblate (Norwegian Bokmål)
Currently translated at 62.4% (3796 of 6074 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/nb_NO/
2025-02-24 19:18:11 +00:00
Ricky Tigg
fcd12760c3 Translated using Weblate (Finnish)
Currently translated at 26.8% (1630 of 6074 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/fi/
2025-02-24 19:18:11 +00:00
Tom De Moor
f630590495 Translated using Weblate (Dutch)
Currently translated at 99.9% (6073 of 6074 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/nl/
2025-02-24 19:18:11 +00:00
Tom De Moor
d821358ddd Translated using Weblate (Dutch)
Currently translated at 99.8% (2601 of 2604 strings)

Translation: Mattermost/server
Translate-URL: https://translate.mattermost.com/projects/mattermost/server/nl/
2025-02-24 19:18:11 +00:00
Frank Paul Silye
bb95dd5bb8 Translated using Weblate (Norwegian Bokmål)
Currently translated at 60.9% (3704 of 6074 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/nb_NO/
2025-02-24 19:18:11 +00:00
Ricky Tigg
249e577a9c Translated using Weblate (Finnish)
Currently translated at 26.5% (1614 of 6074 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/fi/
2025-02-24 19:18:11 +00:00
kaakaa
029ba8eb50 Translated using Weblate (Japanese)
Currently translated at 100.0% (6074 of 6074 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/ja/
2025-02-24 19:18:11 +00:00
kaakaa
9c01c740bb Translated using Weblate (Japanese)
Currently translated at 100.0% (2604 of 2604 strings)

Translation: Mattermost/server
Translate-URL: https://translate.mattermost.com/projects/mattermost/server/ja/
2025-02-24 19:18:11 +00:00
Frank Paul Silye
c0ec0db89d Translated using Weblate (Norwegian Bokmål)
Currently translated at 60.8% (3693 of 6074 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/nb_NO/
2025-02-24 19:18:11 +00:00
Hosted Weblate
7728ccfeda Update translation files
Updated by "Remove blank strings" hook in Weblate.

Translation: Mattermost/server
Translate-URL: https://translate.mattermost.com/projects/mattermost/server/
2025-02-24 19:18:11 +00:00
Matthew Williams
7b6a0eb268 Translated using Weblate (English (Australia))
Currently translated at 100.0% (6074 of 6074 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/en_AU/
2025-02-24 19:18:11 +00:00
Matthew Williams
856a84e584 Translated using Weblate (English (Australia))
Currently translated at 99.9% (2602 of 2604 strings)

Translation: Mattermost/server
Translate-URL: https://translate.mattermost.com/projects/mattermost/server/en_AU/
2025-02-24 19:18:11 +00:00
Ricky Tigg
91d84a3840 Translated using Weblate (Finnish)
Currently translated at 25.4% (1543 of 6074 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/fi/
2025-02-24 19:18:11 +00:00
Ricky Tigg
3636031b97 Translated using Weblate (Finnish)
Currently translated at 47.0% (1224 of 2604 strings)

Translation: Mattermost/server
Translate-URL: https://translate.mattermost.com/projects/mattermost/server/fi/
2025-02-24 19:18:11 +00:00
master7
df5e00d70a Translated using Weblate (Polish)
Currently translated at 100.0% (6074 of 6074 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/pl/
2025-02-24 19:18:11 +00:00
ThrRip
266f19d914 Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 100.0% (6074 of 6074 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/zh_Hans/
2025-02-24 19:18:11 +00:00
ThrRip
0ea3da261b Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 100.0% (2604 of 2604 strings)

Translation: Mattermost/server
Translate-URL: https://translate.mattermost.com/projects/mattermost/server/zh_Hans/
2025-02-24 19:18:11 +00:00
Henrique Latorre
a4258848c1 Translated using Weblate (Portuguese (Brazil))
Currently translated at 73.8% (4486 of 6074 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/pt_BR/
2025-02-24 19:18:11 +00:00
master7
f6eb7ecea1 Translated using Weblate (Polish)
Currently translated at 99.3% (6037 of 6074 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/pl/
2025-02-24 19:18:11 +00:00
MArtin Johnson
2a3ffe71d2 Translated using Weblate (Swedish)
Currently translated at 100.0% (6074 of 6074 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/sv/
2025-02-24 19:18:11 +00:00
MArtin Johnson
40f20219ff Translated using Weblate (Swedish)
Currently translated at 100.0% (2604 of 2604 strings)

Translation: Mattermost/server
Translate-URL: https://translate.mattermost.com/projects/mattermost/server/sv/
2025-02-24 19:18:11 +00:00
Serhii Khomiuk
8b0984ca3e Translated using Weblate (Ukrainian)
Currently translated at 99.7% (2597 of 2604 strings)

Translation: Mattermost/server
Translate-URL: https://translate.mattermost.com/projects/mattermost/server/uk/
2025-02-24 19:18:11 +00:00
Serhii Khomiuk
2790d30743 Translated using Weblate (Ukrainian)
Currently translated at 99.3% (2588 of 2604 strings)

Translation: Mattermost/server
Translate-URL: https://translate.mattermost.com/projects/mattermost/server/uk/
2025-02-24 19:18:11 +00:00
Bohdan
9b4c10b0c8 Translated using Weblate (Ukrainian)
Currently translated at 94.7% (5756 of 6074 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/uk/
2025-02-24 19:18:11 +00:00
Serhii Khomiuk
c56881f79d Translated using Weblate (Ukrainian)
Currently translated at 94.7% (5756 of 6074 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/uk/
2025-02-24 19:18:11 +00:00
master7
ac6b745faf Translated using Weblate (Polish)
Currently translated at 99.1% (6025 of 6074 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/pl/
2025-02-24 19:18:11 +00:00
jprusch
15c046a3fb Translated using Weblate (German)
Currently translated at 100.0% (6074 of 6074 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/de/
2025-02-24 19:18:11 +00:00
Serhii Khomiuk
c518bb75e9 Translated using Weblate (Ukrainian)
Currently translated at 99.3% (2587 of 2604 strings)

Translation: Mattermost/server
Translate-URL: https://translate.mattermost.com/projects/mattermost/server/uk/
2025-02-24 19:18:11 +00:00
master7
fbb7ecf2c3 Translated using Weblate (Polish)
Currently translated at 100.0% (2604 of 2604 strings)

Translation: Mattermost/server
Translate-URL: https://translate.mattermost.com/projects/mattermost/server/pl/
2025-02-24 19:18:11 +00:00
jprusch
9a0033ce52 Translated using Weblate (German)
Currently translated at 100.0% (2604 of 2604 strings)

Translation: Mattermost/server
Translate-URL: https://translate.mattermost.com/projects/mattermost/server/de/
2025-02-24 19:18:11 +00:00
Serhii Khomiuk
299a7a8a18 Translated using Weblate (Ukrainian)
Currently translated at 94.6% (5751 of 6074 strings)

Translation: Mattermost/webapp
Translate-URL: https://translate.mattermost.com/projects/mattermost/webapp/uk/
2025-02-24 19:18:11 +00:00
Konstantin
424503adc0 Translated using Weblate (Russian)
Currently translated at 96.6% (2516 of 2604 strings)

Translation: Mattermost/server
Translate-URL: https://translate.mattermost.com/projects/mattermost/server/ru/
2025-02-24 19:18:11 +00:00
Scott Bishel
1803f1c215 MM-62564 - implement websockets for CPA (#30169)
* implement websockets for CPA

* fix for testing with server

* revert feature flag

* fix unit test

* update constant names

* add reconnect handler

---------

Co-authored-by: Mattermost Build <build@mattermost.com>
2025-02-24 11:53:54 -07:00
Scott Bishel
806fce3030 MM-62760 - Allow Team Admins to view team email (#30170)
* allow team admins to view team email.

* Update server/channels/api4/team_test.go

Co-authored-by: Caleb Roseland <caleb@calebroseland.com>

---------

Co-authored-by: Mattermost Build <build@mattermost.com>
Co-authored-by: Caleb Roseland <caleb@calebroseland.com>
2025-02-24 11:05:17 -07:00
Doug Lauder
09ff43acc6 Remove channel export plugin from transitional plugins list. Channel export plugin is now prepackaged. (#30193)
Co-authored-by: Mattermost Build <build@mattermost.com>
2025-02-24 11:39:34 -05:00
Harshil Sharma
920b3301e5 [MM-63196] Channel sql store migrate select * to specific columns (#30255)
* Adde MySQL and Postgres migrations

* Replaced select * with column names

* removed all * from channel SQL store

* cleanup

* Fixed a duplicate column

* cleanup

* used channelname slice in a missed place

* WIP

* converted to query builder

* cleanupo

* Review fixes
2025-02-24 09:13:12 +05:30
Agniva De Sarker
fa9af97727 MM-63195: Enforce MFA requirement for non-self requests (#30290)
https://mattermost.atlassian.net/browse/MM-63195

```release-note
NONE
```
2025-02-22 12:54:52 +05:30
Harrison Healey
96c2d4ae56 MM-62866 Update axios dependency (#30265)
I had to fight with NPM longer than I thought I would for the override
to take effect. I ended up having to manually tweak the
package-lock.json to get it to take.
2025-02-21 16:59:16 -05:00
Eva Sarafianou
53dac8e530 Clarify patch role permissions (#30128)
Co-authored-by: Ben Schumacher <ben.schumacher@mattermost.com>
Co-authored-by: Mattermost Build <build@mattermost.com>
2025-02-21 17:08:58 +02:00
David Krauser
1dbd1fa4db [MM-62924] WebSocketClient reconnection unit tests (#30135)
This commit adds some reconnection-specific unit tests to the WebSocketClient class, and fixes a few minor bugs:

- If `close()` is called during a reconnection delay, the socket won't close.
- If `send()` is called during a reconnection delay, we immediately try to reconnect (and don't respect any configured delays).
- If `initialize()` is called during a reconnection delay, we immediately try to reconnect (and don't respect any configured delays).
- If we receive two disconnection events, we'll attempt to reconnect with two new connections.

To allow for testing, I also needed to make the WebSocketClient more configurable. Specifically, the config allows for mocking the underlying websockets, and to control timeout delays.
2025-02-20 13:54:18 -05:00
Pablo Vélez
9e47f2ef0c Mm 62677 - modal focus management - find channels modal (#29957)
* MM-62312 - modal focus management; revamp quick switch channel modal!

* get quick switch test working

* configure the generic modal to accept refs to focus within and onhide to the origin element

* apply pr feedback, get modal element get autofocus, use id instead of ref

* update more direct channels modal to use generic modal

* fix unit tests and snapshots

* fix unit tests

* fix modal margin top to fit in smaller screens

* fix e2e test

* remove unnecesary onexited extra call

* fix e2e tests

* set correct label

* fix snapshots

* create helper function for sending custom focus event

* migrate quick switch modal to use new approach to focus

* migrate more direct channels modal to new approach

* fix snapshots

* fix types

* fix modal closing behavior

* fix snapshots

* fix cypress tests

* remove only

---------

Co-authored-by: Mattermost Build <build@mattermost.com>
2025-02-20 13:22:05 -05:00
Agniva De Sarker
fd356b62b4 [AI assisted] MM-62837: (#30268)
We did not invalidate the cache after converting a user to bot.
That led to issues. See JIRA for more details.

https://mattermost.atlassian.net/browse/MM-62837

```release-note
NONE
```
2025-02-20 21:45:44 +05:30
ayush-chauhan233
102e3472d8 [MM-61570]: Refactored the post priority menu and fixed the keyboard navigation issue in the menu. (#29583)
* [MA-7]: Refactored the post priority menu and fixed the keyboard navigation issue in the menu

* [MA-7]: Updated the menu list structure and fixed menu not closing bug

* [MA-7]: Review fixes minor code structure fixes

* [MA-7]: Fixed failing e2e test cases

* [MA-7]: Fixed styling and Keyboard behaviour of menu

* [MA-7]: Minor changes after rebased with master

* [MA-7]: Fixed failing playwright test case

* [MA-7]: Fixed failing e2e test cases

* [MA-7]: Fixed reverting of selected priority to previous value on menu close

* [MA-7]: Fixed failing smoke test

* [MA-7]: Fixed submenu pointer event and failing playwright test cases

* [MA-7]: Fixed failing playwright test case

* fix playwright tests

* fix playwright tests

---------

Co-authored-by: yasserfaraazkhan <attitude3cena.yf@gmail.com>
2025-02-19 21:30:22 +00:00
ayush-chauhan233
d76e0b9d3d [MM-61616]: Add tab roles inside Emoji Picker (#29902)
* MM-61616: Add tab roles inside Emoji Picker

* MM-61616: Update snapshot tests

* MM-61616: Update emoji_picker_category E2E

* MM-61616: Minor aria properties changes

* [MM-61616]: Removed tab roles from emoji picker and added aria-pressed attribute in button

---------

Co-authored-by: Mattermost Build <build@mattermost.com>
2025-02-19 15:54:59 -05:00
Vicktor
4aa4f6f703 [MM-22872] fix(messaging): DM list not scrolling when you press the up/down arrow keys (#29565)
* Set 'forwardRef' to 'true'

The Redux wrapper component not forwarding the ref to the parent resulted in the selected item ref being null.

* Add DM list test case

This test ensures the DM list scrolls items out of view into view when a user navigates using the Up and Down arrow keys.

* test(dm list): add zephyr test case number

---------

Co-authored-by: Mattermost Build <build@mattermost.com>
2025-02-19 15:42:31 -05:00
Claudio Costa
2f8c65a1ea Fix flaky TestGetMattermostLog (#29890) 2025-02-19 08:56:56 -06:00
ayush-chauhan233
8b2e1483c9 [MM-61610]: Added aria-activedescendant to the textbox (#29900)
* [MA-17]: Added aria-activedescendant to the textbox

* [MA-17]: Fixed id and ARIA attribute

* Rebased with master branch

* [MA-17]: Removed irrelevant attribute

* [MA-17]: Updated the logic to add textbox id to At mention suggestion

---------

Co-authored-by: Mattermost Build <build@mattermost.com>
2025-02-19 09:45:09 -05:00
Ibrahim Serdar Acikgoz
a7905541b8 [MM-62660] Makefile: add ability to run local file store tests as standalone (#30260)
* server/Makefile: add ability to test&benchmark local file store only

* remove benchmark
2025-02-19 10:18:07 +01:00
Pablo Vélez
b0b379e167 MM-61634 - adjust rhs a11y structure (#30168)
Co-authored-by: Mattermost Build <build@mattermost.com>
2025-02-19 00:26:41 -05:00
Devin Binnie
bd376d3473 [MM-62945] Load new channels for users added even if they're on a different team (#30167)
Co-authored-by: Mattermost Build <build@mattermost.com>
2025-02-18 19:04:33 +00:00
Devin Binnie
b604930cf6 [MM-60555] Use channel memberships to calculate total unread status instead of team memberships (#30166)
* [MM-60555] Use channel memberships to calculate total unread status instead of team memberships

* Fix lint

---------

Co-authored-by: Mattermost Build <build@mattermost.com>
2025-02-18 19:04:06 +00:00
Devin Binnie
ce61ed8f52 [MM-55090] Threads created by users should not be auto-followed on reply by the creator when they've left the channel (#30181)
Co-authored-by: Mattermost Build <build@mattermost.com>
Co-authored-by: Caleb Roseland <caleb@calebroseland.com>
2025-02-18 17:29:26 +00:00
Christopher Speller
89490a1093 Update Copilot plugin to v1.1.0 (#30098)
Co-authored-by: Mattermost Build <build@mattermost.com>
2025-02-18 07:16:11 -08:00
Christopher Speller
2b5275d871 chore: Update Playbooks plugin to v2.1.1 (#29996) 2025-02-18 12:18:36 +00:00
Amy Blais
ff566e243c Updated minimum supported Edge and Chrome versions (#30030)
Automatic Merge
2025-02-18 09:20:09 +02:00
Weblate (bot)
62a24aa91e Translations update from Mattermost Weblate (#30241)
* Translated using Weblate (Russian)

Currently translated at 96.8% (2519 of 2602 strings)

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

* Translated using Weblate (German)

Currently translated at 100.0% (2602 of 2602 strings)

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

* Translated using Weblate (Turkish)

Currently translated at 100.0% (2602 of 2602 strings)

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

* Translated using Weblate (German)

Currently translated at 100.0% (6071 of 6071 strings)

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

* Translated using Weblate (Turkish)

Currently translated at 100.0% (6071 of 6071 strings)

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

* Translated using Weblate (Czech)

Currently translated at 100.0% (2602 of 2602 strings)

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

* Translated using Weblate (Czech)

Currently translated at 100.0% (6071 of 6071 strings)

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

* Translated using Weblate (Polish)

Currently translated at 100.0% (2602 of 2602 strings)

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

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

Currently translated at 100.0% (2602 of 2602 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 100.0% (6071 of 6071 strings)

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

* Translated using Weblate (Norwegian Bokmål)

Currently translated at 60.5% (3673 of 6071 strings)

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

* Translated using Weblate (Swedish)

Currently translated at 99.8% (6060 of 6071 strings)

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

* Translated using Weblate (Dutch)

Currently translated at 99.8% (2599 of 2602 strings)

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

* Translated using Weblate (Dutch)

Currently translated at 99.9% (6070 of 6071 strings)

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

* Translated using Weblate (Ukrainian)

Currently translated at 99.2% (2583 of 2602 strings)

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

* Translated using Weblate (Polish)

Currently translated at 99.1% (6021 of 6071 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/

* 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: Konstantin <eleferen@gmail.com>
Co-authored-by: jprusch <rs@schaeferbarthold.de>
Co-authored-by: Kaya Zeren <kayazeren@gmail.com>
Co-authored-by: Martin Mičuda <micuda@rematiptop.cz>
Co-authored-by: master7 <marcin.karkosz@rajska.info>
Co-authored-by: ThrRip <coding@thrrip.space>
Co-authored-by: Frank Paul Silye <frankps@gmail.com>
Co-authored-by: MArtin Johnson <martinjohnson@bahnhof.se>
Co-authored-by: Tom De Moor <tom@controlaltdieliet.be>
Co-authored-by: Serhii Khomiuk <sergiy.khomiuk@gmail.com>
2025-02-17 19:09:54 +00:00
Ibrahim Serdar Acikgoz
3da6e7a75d server/Makefile: pin dbcmp (#30245) 2025-02-17 18:10:44 +01:00
Agniva De Sarker
32037706b5 MM-62960: Support both webhub iteration scopes properly (#30224)
When Channel iteration mode is enabled, we need to ensure that
channel scoped events do not fall through to the connIndex.All()
condition. This is possible because there are multiple hubs
in a given system. So a single event will flow through all of them
and in some hubs, a channel scoped event might not have any connections.

In that case, we need to stop processing further.

https://mattermost.atlassian.net/browse/MM-62960

```release-note
NONE
```
2025-02-17 19:39:39 +05:30
Tom De Moor
ab9fd5e4f6 Adding a label wip languages (#30100)
* adding extra label to WIP-languages

* adding an extra space

* fix linting

* modifying test

* updating test

---------

Co-authored-by: Tom De Moor <tom.demoor@vclbgent.be>
2025-02-17 14:03:52 +00:00
M-ZubairAhmed
cbb1081550 [MM-54861] Command + K shortcut to hyperlink text doesn't work when editing a post (#30195) 2025-02-17 13:41:26 +05:30
Agniva De Sarker
e7a246c065 [AI assisted]: MM-62914: Added MFA authentication for plugin requests as well (#30160)
We wipe the token if MFA authentication is enabled. Also added a test case
to lock in the functionality.

https://mattermost.atlassian.net/browse/MM-62914

```release-note
NONE
```
2025-02-17 12:20:21 +05:30
ayush-chauhan233
4750df98c2 [MM-62961] Fixed pointer event of submenus (#30219) 2025-02-17 06:06:38 +05:30
Harrison Healey
8b164711a4 MM-63138 Fix some console warnings (#30209)
* Fix forwardRef propTypes console error

The console error that was fixed by this is:
"Warning: forwardRef render functions do not support propTypes or defaultProps. Did you accidentally pass a React component?"

* Fix function component ref console error

This fixes the following error:
Warning: Function components cannot be given refs. Attempts to access this ref will fail. Did you mean to use React. forwardRef ()?
2025-02-14 16:21:52 -05:00
Harrison Healey
b6118b7701 MM-62383 Replace React Bootstrap with Floating UI in Emoji Picker (#29835)
* Convert EmojiPickerOverlay to functional component

* Convert EmojiPickerTabs to functional component

* Extract AddReactionButton from ReactionList

This is so that I can make part of it functional without rewriting
the whole thing.

* Convert PostReaction to functional component

* Add general version of useEmojiPicker and use for AddReactionButton

* Rename returned showEmojiPicker to emojiPickerOpen

* Add test for AddReactionButton

* Move showEmojiPicker state out of useEmojiPicker

I hoped to avoid this by just having the hook return the
show state, but unfortunately, too many of the existing places
rely on controlling the state themselves

* Change PostReaction to use useEmojiPicker

I ran into some trouble with this getting the hover state to properly
disappear from the PostComponent when clicking out of the picker. That
seems to be a downside of the browser's mouseenter/mouseleave not
handling cases where the component is covered up. It doesn't work 100%,
but it works at least as well as master by disabling pointer-events to
the FloatingOverlay (which I also think we could probably remove since
it's supposed to just be for darkening the backdrop behind the picker,
but it ended up being helpful for setting the z-index on mobile).

* Change AdvancedTextEditor to use new useEmojiPicker

I renamed its version of useEmojiPicker to useEditorEmojiPicker since it
still contains information about how to position the emoji or gifs in
the post text.

* Convert EditPost to use useEmojiPicker

* Convert CreateModalNameInput to use useEmoijPicker

* Convert CustomStatusModal to use useEmojiPicker

* Remove EmojiPickerOverlay and cleanup related code

* Remove unneeded translation string

* asdf Attempting to fix E2E test

* Improve how useEmojiPicker positions itself to stay on screen more

* Add offset between Emoji Picker and reference

* Add horizontallyWithin middleware and use it to right-align the emoji picker in the post textbox
2025-02-14 13:53:30 -05:00
Agniva De Sarker
da7192246e MM-62960: Improve webConn remove performance from hubConnectionIndex (#30178)
When we added iteration by channelID, this was a known tradeoff during that.
However, it has been observed that the regular connection removal function
creates considerable blocking of the processing loop, leading to high
CPU usage and API latencies.

To fix this, we add a reverse mapping of channelIDs to connections
and their positions in the slice. This helps us to remove the connection
from the slice without iteration.

Unfortunately, this still needs to iterate through all channelIDs
during invalidation of the channel member cache. However, the user
cache invalidation is not a regular activity. So it should be an acceptable
tradeoff to make.

https://mattermost.atlassian.net/browse/MM-62960

```release-note
A new config knob ServiceSettings.EnableWebHubChannelIteration which allows a user to control the performance of websocket broadcasting. By default, this setting is turned off. If it is turned on, it improves the websocket broadcasting performance at the expense of poor performance when users join/leave a channel. It is not recommended to turn it on unless you have atleast 200,000 concurrent users actively using MM.
```

Co-authored-by: Mattermost Build <build@mattermost.com>
2025-02-14 09:19:36 +05:30
Julien Tant
06d8c92504 Using StringInterface instead of mapStringAny (#30211) 2025-02-14 03:14:08 +00:00
Caleb Roseland
68c11e9ecb MM-61375: Update file handling for bookmarks (#30034) 2025-02-13 17:11:13 -06:00
Caleb Roseland
2182b1eaf9 MM-62548: CPA Reordering - drag and drop (#30097) 2025-02-13 17:09:35 -06:00
Harrison Healey
b2147476cc MM-62933 Revert position of post menu to match earlier versions (#30190)
Co-authored-by: Mattermost Build <build@mattermost.com>
2025-02-13 22:29:54 +00:00
Julien Tant
41e0f97176 Remove call for removed attribute Page (#30207) 2025-02-13 17:35:27 +00:00
Agniva De Sarker
1a58f923e0 [aider assisted] MM-61888: Add ClientSideUserIds field to MetricsSettings (#30127)
We add a new config setting to allow the admin to set a fixed
list of userIDs to track for all client side webapp metrics.

This gives the admin to get a deeper look at how the application
is behaving for a single user.

A new section in the system console is also added for the user
to edit this setting from the UI.

https://mattermost.atlassian.net/browse/MM-61888

```release-note
A new config setting MetricsSettings.ClientSideUserIds is added
where you can set the user ids you want to track for client side webapp
metrics.
```

* fix lint errors

```release-note
NONE
```

* fixing tests

```release-note
NONE
```
2025-02-13 21:10:34 +05:30
Julien Tant
632a60b332 [MM-62553]+[MM-62554] Property Architecture: cursor based pagination (#30119)
* refactor: Replace pagination with cursor-based pagination for custom profile attributes

* remove pagination loop on property value retrieval for CPA

* add migrations to optimize pagination on property fields and values

* adapt test to remove pagination check

* update migrations list

* postgres: drop index concurrently

* concurrent index manipulation must be done outside of a Tx

* fix: Correct SQL index drop syntax from "OM" to "ON" in migration files

* test: Add CountForGroup test cases for property field store

* refactor: Add CountForGroup method to PropertyFieldStore interface and implementations

* Fix style and i18n

* feat: Add optional deleted property field filtering to CountForGroup method

* refactor: Update CountForGroup to support optional deleted property fields

* test: Add comprehensive tests for CountForGroup with includeDeleted parameter

* adapt test + gen layers

* rename property service method and set the includeDelete to false

* refactor: Remove redundant constant and use CustomProfileAttributesFieldLimit directly

* fix tests

---------

Co-authored-by: Mattermost Build <build@mattermost.com>
2025-02-13 15:23:50 +00:00
Harrison Healey
4615ca5f28 MM-62944 Fix fileupload settings not being clickable (#30182)
Co-authored-by: Mattermost Build <build@mattermost.com>
2025-02-13 10:17:41 -05:00
Miguel de la Cruz
f85a8c61a4 Adds websocket messages to Custom Profile Attributes (#30163)
* Adds websocket messages to Custom Profile Attributes

The app layer now fires a websocket event as part of the operations
over Custom Profile Attribute fields and values. It updates as well
the Patch method for CPA values so all the changes are commited as
part of the same transaction.

To be able to do this last operation, the change adds methods to
upsert CPA values in both the store and the property service.

* Fix i18n strings

---------

Co-authored-by: Mattermost Build <build@mattermost.com>
Co-authored-by: Miguel de la Cruz <miguel@ctrlz.es>
2025-02-13 11:21:46 +00:00
Miguel de la Cruz
5ba80d51ae Updates the property field and value update methods to use a single query for multiple entities (#30198)
* Updates the property field and value update methods to use a single query for multiple entities

* Update server/channels/store/sqlstore/property_field_store.go

Co-authored-by: Julien Tant <785518+JulienTant@users.noreply.github.com>

---------

Co-authored-by: Miguel de la Cruz (aider) <miguel@ctrlz.es>
Co-authored-by: Julien Tant <785518+JulienTant@users.noreply.github.com>
2025-02-13 11:12:51 +00:00
Harshil Sharma
83ec1d9f7d added window title for scheduled post tab and fixed draft alignment (#30179)
* added window title for scheduled post tab and fixed draft alignment

* i18n fix
2025-02-13 12:11:53 +05:30
Nicolas Le Cam
4a44d23095 Remove docker hack around prometheus service (#28985)
* Remove uneeded hack in docker-compose now that problem is solved

* Remove obsolete attribute `version` in docker compose configuration files

---------

Co-authored-by: Mattermost Build <build@mattermost.com>
2025-02-12 14:18:53 -04:00
Harrison Healey
55bb6c51eb MM-62891 Fixed incorrectly applied label in Team Settings modal (#30116) 2025-02-11 10:50:42 -05:00
ayush-chauhan233
9aaa52136c [MM-61683]: Ensure radio button groups are properly formed (#30013)
* MM-61683: Ensure radio button groups are properly formed

* MM-61683: Fix the failing i18 CI

* MM-61683: Fix desktop notification translation IDs

* MM-61683: Fix lint-style

* MM-61683: Update name attribute inside channel notification modal
Add aria-label inside RadioSettingItem
Update snapshot

* MM-61683: Revert creating a constant for default messages and id

* MM-61683: Add legend tag inside radio setting item component

* MM-61683: Update snapshot

---------

Co-authored-by: Saurabh Sharma <saurabh.sharma@brightscout.com>
Co-authored-by: Mattermost Build <build@mattermost.com>
2025-02-11 10:46:06 -05:00
Ben Schumacher
d3dcc74e5a [MM-62762] Make config location in Support Packet human-readable (#30027)
Co-authored-by: Mattermost Build <build@mattermost.com>
2025-02-11 10:06:27 +01:00
ayush-chauhan233
b2b956c043 [MM-55278]: Fixed autofocus on submenu's first element (#29547) 2025-02-11 11:34:42 +05:30
enzowritescode
169274b3aa [MM-62864] Bump katex to 0.16.21 (#30095) 2025-02-11 11:18:01 +05:30
Weblate (bot)
dc37cf5cf9 Translations update from Mattermost Weblate (#30157)
Automatic Merge
2025-02-10 19:50:10 +02:00
Maria A Nunez
7efdcda20a Update User Limits for unlicensed servers (#30134)
* Update user soft and hard limits

* Fix testt

* Fix test
2025-02-10 11:55:42 -05:00
Arya Khochare
f6c4bdf365 [MM-62149] Avoid SELECT * in emoji_store.go (#30082)
* refractored select sql queries

* rm unused makeStringArgs

* linting

* leverage builder pattern

---------

Co-authored-by: Jesse Hallam <jesse.hallam@gmail.com>
2025-02-10 12:02:50 -04:00
Jesús Espino
9b87970c99 Migrating other 2 files from javascript to typescript (#29435)
* feat: Add initial store configuration for webapp channels

* refactor: Convert store/index.js to TypeScript with type definitions

* test: Add initial test file for store index

* refactor: Convert index.test.js to TypeScript with type annotations

* Removing old files

* Applying linter fixes

* Fixing some of the types errors

* fix: Type mock implementation of getState in global_actions.test.ts

* test: Add missing GlobalState import in global_actions.test.ts

* fix: Resolve TypeScript mock implementation error in global_actions.test.ts

* Some fixes

* Address CI problems

* Installing zen-observable types

* Addressing PR review comment

* Addressing PR review comment

* Addressing PR review comment

* Addressing PR review comment

* Addressing PR review comment

* Simpliying things

* Fixing CI

* Fixing types
2025-02-10 15:43:09 +01:00
3153 изменённых файлов: 244827 добавлений и 81059 удалений

64
.github/ISSUE_TEMPLATE/bug_report.yml поставляемый Обычный файл
Просмотреть файл

@@ -0,0 +1,64 @@
name: Bug report
description: Create a report about an issue you found
title: "[Bug]: "
labels: "Bug Report/Open"
body:
- type: checkboxes
attributes:
label: Before you file a bug report
description: Please ensure you can confirm the following
options:
- label: I have checked the [issue tracker](https://github.com/mattermost/mattermost/issues) and have not found an issue that matches the one I'm filing.
required: true
- label: "This issue is not a troubleshooting question. Troubleshooting questions go here: https://forum.mattermost.com/c/trouble-shoot/16."
required: true
- label: "This issue is not a feature request. You can request features and make product suggestions here: https://mattermost.uservoice.com/forums/306457-general/."
required: true
- label: This issue reproduces on one of the [currently supported server versions](https://docs.mattermost.com/about/mattermost-server-releases.html#latest-releases).
required: true
- label: I have read the [contribution guidelines](https://github.com/mattermost/mattermost/blob/master/CONTRIBUTING.md) and the [Mattermost Handbook Contribution Guidelines](https://handbook.mattermost.com/contributors/contributors/guidelines/contribution-guidelines).
required: true
- type: input
attributes:
label: Mattermost Server Version
description: |
What version of the Mattermost server are you using? You can find it by going to [Main Menu] > [About Mattermost].
validations:
required: true
- type: input
attributes:
label: Operating System
description: |
What operating system does this issue occur on?
Example: Windows 10
validations:
required: true
- type: textarea
attributes:
label: Steps to reproduce
description: |
Include a clear description of the steps taken to reproduce this issue.
It is also helpful to attach a screenshot or video if applicable.
validations:
required: true
- type: textarea
attributes:
label: Expected behavior
description: Include a clear description of what you expect to happen.
validations:
required: true
- type: textarea
attributes:
label: Observed behavior
description: Include a clear description of what actually happens.
validations:
required: true
- type: textarea
attributes:
label: Log Output
description: Please include output from the log files.
render: shell
- type: textarea
attributes:
label: Additional Information
description: If you have anything else to add to the ticket, you may do so here.

2
.github/actions/calculate-cypress-results/.gitignore поставляемый Обычный файл
Просмотреть файл

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

50
.github/actions/calculate-cypress-results/action.yaml поставляемый Обычный файл
Просмотреть файл

@@ -0,0 +1,50 @@
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%)
test_duration:
description: Wall-clock test duration (earliest start to latest end across all specs, formatted as "Xm Ys")
runs:
using: node24
main: dist/index.js

19347
.github/actions/calculate-cypress-results/dist/index.js поставляемый Обычный файл

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

15
.github/actions/calculate-cypress-results/jest.config.js поставляемый Обычный файл
Просмотреть файл

@@ -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,
},
],
},
};

9136
.github/actions/calculate-cypress-results/package-lock.json сгенерированный поставляемый Обычный файл

Разница между файлами не показана из-за своего большого размера Загрузить разницу

27
.github/actions/calculate-cypress-results/package.json поставляемый Обычный файл
Просмотреть файл

@@ -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"
}
}

3
.github/actions/calculate-cypress-results/src/index.ts поставляемый Обычный файл
Просмотреть файл

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

101
.github/actions/calculate-cypress-results/src/main.ts поставляемый Обычный файл
Просмотреть файл

@@ -0,0 +1,101 @@
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.info(`Test Duration: ${calc.testDuration}`);
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);
core.setOutput("test_duration", calc.testDuration);
}

271
.github/actions/calculate-cypress-results/src/merge.test.ts поставляемый Обычный файл
Просмотреть файл

@@ -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);
});
});

358
.github/actions/calculate-cypress-results/src/merge.ts поставляемый Обычный файл
Просмотреть файл

@@ -0,0 +1,358 @@
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
*/
/**
* Format milliseconds as "Xm Ys"
*/
function formatDuration(ms: number): string {
const totalSeconds = Math.round(ms / 1000);
const minutes = Math.floor(totalSeconds / 60);
const seconds = totalSeconds % 60;
return `${minutes}m ${seconds}s`;
}
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++;
}
}
}
// Compute test duration from earliest start to latest end across all specs
let earliestStart: number | null = null;
let latestEnd: number | null = null;
for (const spec of specs) {
const { start, end } = spec.result.stats;
if (start) {
const startMs = new Date(start).getTime();
if (earliestStart === null || startMs < earliestStart) {
earliestStart = startMs;
}
}
if (end) {
const endMs = new Date(end).getTime();
if (latestEnd === null || endMs > latestEnd) {
latestEnd = endMs;
}
}
}
const testDurationMs =
earliestStart !== null && latestEnd !== null
? latestEnd - earliestStart
: 0;
const testDuration = formatDuration(testDurationMs);
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,
testDuration,
};
}
/**
* 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 };
}

139
.github/actions/calculate-cypress-results/src/types.ts поставляемый Обычный файл
Просмотреть файл

@@ -0,0 +1,139 @@
/**
* 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;
testDuration: string;
}
export interface FailedTest {
title: string;
file: string;
}

17
.github/actions/calculate-cypress-results/tsconfig.json поставляемый Обычный файл
Просмотреть файл

@@ -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"]
}

1
.github/actions/calculate-cypress-results/tsconfig.tsbuildinfo поставляемый Обычный файл
Просмотреть файл

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

13
.github/actions/calculate-cypress-results/tsup.config.ts поставляемый Обычный файл
Просмотреть файл

@@ -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: [/.*/],
});

2
.github/actions/calculate-playwright-results/.gitignore поставляемый Обычный файл
Просмотреть файл

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

53
.github/actions/calculate-playwright-results/action.yaml поставляемый Обычный файл
Просмотреть файл

@@ -0,0 +1,53 @@
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%)
test_duration:
description: Test execution duration from stats (formatted as "Xm Ys")
runs:
using: node24
main: dist/index.js

19323
.github/actions/calculate-playwright-results/dist/index.js поставляемый Обычный файл

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

6
.github/actions/calculate-playwright-results/jest.config.js поставляемый Обычный файл
Просмотреть файл

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

9136
.github/actions/calculate-playwright-results/package-lock.json сгенерированный поставляемый Обычный файл

Разница между файлами не показана из-за своего большого размера Загрузить разницу

27
.github/actions/calculate-playwright-results/package.json поставляемый Обычный файл
Просмотреть файл

@@ -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"
}
}

3
.github/actions/calculate-playwright-results/src/index.ts поставляемый Обычный файл
Просмотреть файл

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

123
.github/actions/calculate-playwright-results/src/main.ts поставляемый Обычный файл
Просмотреть файл

@@ -0,0 +1,123 @@
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.info(`Test Duration: ${calc.testDuration}`);
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);
core.setOutput("test_duration", calc.testDuration);
}

509
.github/actions/calculate-playwright-results/src/merge.test.ts поставляемый Обычный файл
Просмотреть файл

@@ -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);
});
});

304
.github/actions/calculate-playwright-results/src/merge.ts поставляемый Обычный файл
Просмотреть файл

@@ -0,0 +1,304 @@
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,
};
}
/**
* Format milliseconds as "Xm Ys"
*/
function formatDuration(ms: number): string {
const totalSeconds = Math.round(ms / 1000);
const minutes = Math.floor(totalSeconds / 60);
const seconds = totalSeconds % 60;
return `${minutes}m ${seconds}s`;
}
/**
* 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}`;
const testDuration = formatDuration(stats.duration || 0);
return {
passed,
failed,
flaky,
skipped,
totalSpecs,
commitStatusMessage,
failedSpecs,
failedSpecsCount,
failedTests,
total,
passRate,
passing,
color,
testDuration,
};
}
/**
* 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,
};
}

89
.github/actions/calculate-playwright-results/src/types.ts поставляемый Обычный файл
Просмотреть файл

@@ -0,0 +1,89 @@
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;
testDuration: string;
}
export interface FailedTest {
title: string;
file: string;
}

17
.github/actions/calculate-playwright-results/tsconfig.json поставляемый Обычный файл
Просмотреть файл

@@ -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"]
}

1
.github/actions/calculate-playwright-results/tsconfig.tsbuildinfo поставляемый Обычный файл
Просмотреть файл

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

12
.github/actions/calculate-playwright-results/tsup.config.ts поставляемый Обычный файл
Просмотреть файл

@@ -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",
});

104
.github/actions/check-e2e-test-only/action.yml поставляемый Обычный файл
Просмотреть файл

@@ -0,0 +1,104 @@
---
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 (base branch ref 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 and base branch from PR number if not provided
BASE_REF=""
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')
BASE_REF=$(echo "$PR_DATA" | jq -r '.base.ref')
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
elif [ -n "$INPUT_PR_NUMBER" ]; then
# SHAs provided but we still need the base branch ref
BASE_REF=$(gh api "repos/${{ github.repository }}/pulls/${INPUT_PR_NUMBER}" --jq '.base.ref')
fi
# Default to master if base ref could not be determined
if [ -z "$BASE_REF" ] || [ "$BASE_REF" = "null" ]; then
BASE_REF="master"
fi
echo "PR base branch: ${BASE_REF}"
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- ]] && \
[[ ! "$file" =~ ^\.github/actions/ ]]; 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" ] && \
{ [ "$BASE_REF" = "master" ] || [[ "$BASE_REF" =~ ^release-[0-9]+\.[0-9]+$ ]]; }; then
echo "image_tag=${BASE_REF}" >> $GITHUB_OUTPUT
else
echo "image_tag=${SHORT_SHA}" >> $GITHUB_OUTPUT
fi

17
.github/codecov.yml поставляемый Обычный файл
Просмотреть файл

@@ -0,0 +1,17 @@
comment:
layout: "condensed_header, condensed_files, condensed_footer"
behavior: default
require_changes: "uncovered_patch" # only post comment if the patch has uncovered lines
hide_project_coverage: true # only show coverage on the git diff
coverage:
status:
changes: false
patch: false
project:
default:
threshold: 1.0
codecov:
notify:
after_n_builds: 2 # Server and webapp at this point
ignore:
- ^store/storetest.*

7
.github/workflows/api.yml поставляемый
Просмотреть файл

@@ -20,7 +20,7 @@ jobs:
- name: Checkout code
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- uses: actions/setup-node@1d0ff469b7ec7b3cb9d8673fde0c81c44821de2a # v4.2.0
- uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
with:
node-version-file: .nvmrc
cache: "npm"
@@ -28,8 +28,3 @@ jobs:
- name: Run build
run: make build
- uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3
with:
name: mattermost-api-reference
path: api/v4/html

Просмотреть файл

@@ -16,13 +16,13 @@ jobs:
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: opensearch/docker-login
uses: docker/login-action@9780b0c442fbb1117ed29e0efdff1e18412f7567 # v3.3.0
uses: docker/login-action@74a5d142397b4f367a81961eba4e8cd7edddf772 # v3.4.0
with:
username: ${{ secrets.DOCKERHUB_DEV_USERNAME }}
password: ${{ secrets.DOCKERHUB_DEV_TOKEN }}
- name: opensearch/build-and-push
uses: docker/build-push-action@ca877d9245402d1537745e0e356eab47c3520991 # v6.13.0
uses: docker/build-push-action@1dc73863535b631f98b2378be8619f83b136f4a0 # v6.17.0
with:
provenance: false
file: server/build/Dockerfile.opensearch

4
.github/workflows/build-server-image.yml поставляемый
Просмотреть файл

@@ -21,13 +21,13 @@ jobs:
run: echo GO_VERSION=$(cat .go-version) >> "${GITHUB_OUTPUT}"
- name: buildenv/docker-login
uses: docker/login-action@9780b0c442fbb1117ed29e0efdff1e18412f7567 # v3.3.0
uses: docker/login-action@74a5d142397b4f367a81961eba4e8cd7edddf772 # v3.4.0
with:
username: ${{ secrets.DOCKERHUB_DEV_USERNAME }}
password: ${{ secrets.DOCKERHUB_DEV_TOKEN }}
- name: buildenv/build-and-push
uses: docker/build-push-action@ca877d9245402d1537745e0e356eab47c3520991 # v6.13.0
uses: docker/build-push-action@1dc73863535b631f98b2378be8619f83b136f4a0 # v6.17.0
with:
provenance: false
file: server/build/Dockerfile.buildenv

38
.github/workflows/claude.yml поставляемый Обычный файл
Просмотреть файл

@@ -0,0 +1,38 @@
name: Claude Code
on:
issue_comment:
types: [created]
pull_request_review_comment:
types: [created]
issues:
types: [opened, assigned]
pull_request_review:
types: [submitted]
jobs:
claude:
if: |
(github.event_name == 'issue_comment' && contains(github.event.comment.body, '@claude')) ||
(github.event_name == 'pull_request_review_comment' && contains(github.event.comment.body, '@claude')) ||
(github.event_name == 'pull_request_review' && contains(github.event.review.body, '@claude')) ||
(github.event_name == 'issues' && (contains(github.event.issue.body, '@claude') || contains(github.event.issue.title, '@claude')))
runs-on: ubuntu-latest
permissions:
contents: read
pull-requests: read
issues: read
id-token: write
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
fetch-depth: 1
- name: Run Claude Code
id: claude
uses: anthropics/claude-code-action@beta
with:
anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}
model: claude-sonnet-4-20250514
allowed_tools: "Bash(cd:*),Bash(git:*),Bash(make:*),Bash(npm:*),Bash(go:*)"

61
.github/workflows/codeql-analysis.yml поставляемый
Просмотреть файл

@@ -3,9 +3,9 @@ name: "CodeQL"
on:
pull_request:
# The branches below must be a subset of the branches above
branches: [ master ]
branches: [master]
schedule:
- cron: '30 5,17 * * *'
- cron: "30 5,17 * * *"
permissions:
contents: read
@@ -13,7 +13,7 @@ permissions:
jobs:
analyze:
permissions:
security-events: write # for github/codeql-action/autobuild to send a status report
security-events: write # for github/codeql-action/autobuild to send a status report
name: Analyze
if: github.repository_owner == 'mattermost'
runs-on: ubuntu-latest
@@ -21,38 +21,37 @@ jobs:
strategy:
fail-fast: false
matrix:
language: [ 'go', 'javascript' ]
language: ["go", "javascript"]
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Checkout repository
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@v3.28.9
with:
languages: ${{ matrix.language }}
debug: false
config-file: ./.github/codeql/codeql-config.yml
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@ff0a06e83cb2de871e5a09832bc6a81e7276941f # v3.28.18
with:
languages: ${{ matrix.language }}
debug: false
config-file: ./.github/codeql/codeql-config.yml
- name: Build JavaScript
uses: github/codeql-action/autobuild@v3.28.9
if: ${{ matrix.language == 'javascript' }}
- name: Build JavaScript
uses: github/codeql-action/autobuild@ff0a06e83cb2de871e5a09832bc6a81e7276941f # v3.28.18
if: ${{ matrix.language == 'javascript' }}
- name: Setup go
uses: actions/setup-go@v5
with:
go-version: '1.22'
if: ${{ matrix.language == 'go' }}
- name: Setup go
uses: actions/setup-go@v5
with:
go-version-file: server/go.mod
if: ${{ matrix.language == 'go' }}
- name: Build Golang
run: |
cd server
make setup-go-work
make build-linux-amd64
if: ${{ matrix.language == 'go' }}
- name: Build Golang
run: |
cd server
make setup-go-work
make build-linux-amd64
if: ${{ matrix.language == 'go' }}
# Perform Analysis
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v3.28.9
# Perform Analysis
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@ff0a06e83cb2de871e5a09832bc6a81e7276941f # v3.28.18

56
.github/workflows/dispatch-server-builder-image.yml поставляемый Обычный файл
Просмотреть файл

@@ -0,0 +1,56 @@
# .github/workflows/dispatch-build.yml
name: Build & Push New Golang Docker Build Server Image
on:
workflow_dispatch:
inputs:
branch:
description: 'Git branch or PR ref to build'
required: true
tag:
description: 'Docker image tag (e.g. v1.2.3 or latest)'
required: true
jobs:
build-and-push:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 #4.2.2
with:
ref: ${{ github.event.inputs.branch }}
- name: Set up QEMU (optional, for multi-arch)
uses: docker/setup-qemu-action@29109295f81e9208d7d86ff1c6c12d2833863392
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@f7ce87c1d6bead3e36075b2ce75da1f6cc28aaca
- name: Login to DockerHub (development repo)
uses: docker/login-action@74a5d142397b4f367a81961eba4e8cd7edddf772
with:
registry: docker.io
username: ${{ secrets.DOCKERHUB_DEV_USERNAME }}
password: ${{ secrets.DOCKERHUB_DEV_TOKEN }}
- name: Build & push development image
run: |
docker buildx build \
--tag mattermostdevelopment/mattermost-build-server:${{ github.event.inputs.tag }} \
--push \
-f Dockerfile.buildenv .
- name: Login to DockerHub (production repo)
uses: docker/login-action@74a5d142397b4f367a81961eba4e8cd7edddf772
with:
registry: docker.io
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Build & push production image
run: |
docker buildx build \
--tag mattermost/mattermost-build-server:${{ github.event.inputs.tag }} \
--push \
-f Dockerfile.buildenv .

2
.github/workflows/docker-push-mirrored.yml поставляемый
Просмотреть файл

@@ -16,7 +16,7 @@ jobs:
- name: Checkout mattermost project
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: cd/Login to Docker Hub
uses: docker/login-action@9780b0c442fbb1117ed29e0efdff1e18412f7567 # v3.3.0
uses: docker/login-action@74a5d142397b4f367a81961eba4e8cd7edddf772 # v3.4.0
with:
username: ${{ secrets.DOCKERHUB_DEV_USERNAME }}
password: ${{ secrets.DOCKERHUB_DEV_TOKEN }}

337
.github/workflows/e2e-fulltests-ci.yml поставляемый
Просмотреть файл

@@ -1,337 +0,0 @@
---
name: E2E Tests
on:
# For PRs, this workflow gets triggered from the Argo Events platform.
# Check the following repo for details: https://github.com/mattermost/delivery-platform
workflow_dispatch:
inputs:
ref:
type: string
description: Git ref to test. Must be a full commit SHA for PR testing, and a tag for release testing. Ignored for daily tests.
required: false
PR_NUMBER:
type: string
description: PR number (if applicable)
required: false
ROLLING_RELEASE_FROM_TAG:
type: string
description: Mattermost release git tag for RollingRelease tests. Optional.
required: false
MM_ENV:
type: string
required: false
description: A comma-separated list of environment variables to set for the server. Spaces are not supported.
MM_SERVICE_OVERRIDES:
type: string
required: false
description: A comma-separated list of service overrides. E.g. "-elasticsearch,+opensearch"
REPORT_TYPE:
type: choice
description: The context this report is being generated in
options:
- PR
- RELEASE
- RELEASE_CLOUD
- MASTER
- MASTER_UNSTABLE
- CLOUD
- CLOUD_UNSTABLE
- NONE
default: NONE
RUN_CYPRESS:
type: string
description: Enable Cypress run
default: "true"
RUN_PLAYWRIGHT:
type: string
description: Enable Playwright run
default: "true"
concurrency:
group: "${{ github.workflow }}-${{ inputs.REPORT_TYPE }}-${{ inputs.PR_NUMBER || inputs.ref }}-${{ inputs.MM_ENV }}"
cancel-in-progress: true
jobs:
generate-test-variables:
runs-on: ubuntu-latest
permissions:
issues: write
pull-requests: write
defaults:
run:
shell: bash
outputs:
commit_sha: "${{ steps.generate.outputs.commit_sha }}"
BRANCH: "${{ steps.generate.outputs.BRANCH }}"
SERVER_IMAGE: "${{ steps.generate.outputs.SERVER_IMAGE }}"
status_check_context: "${{ steps.generate.outputs.status_check_context }}"
workers_number: "${{ steps.generate.outputs.workers_number }}"
server_uppercase: "${{ steps.generate.outputs.server_uppercase }}" # Required for license selection
SERVER: "${{ steps.generate.outputs.SERVER }}"
ENABLED_DOCKER_SERVICES: "${{ steps.generate.outputs.ENABLED_DOCKER_SERVICES }}"
TEST_FILTER_CYPRESS: "${{ steps.generate.outputs.TEST_FILTER_CYPRESS }}"
TEST_FILTER_PLAYWRIGHT: "tests/ --project=chrome" # Note: Run on chrome but eventually will enable to all projects which include firefox and ipad.
BUILD_ID: "${{ steps.generate.outputs.BUILD_ID }}"
TM4J_ENABLE: "${{ steps.generate.outputs.TM4J_ENABLE }}"
REPORT_TYPE: "${{ steps.generate.outputs.REPORT_TYPE }}"
TESTCASE_FAILURE_FATAL: "${{ steps.generate.outputs.TESTCASE_FAILURE_FATAL }}"
ROLLING_RELEASE_commit_sha: "${{ steps.generate.outputs.ROLLING_RELEASE_commit_sha }}"
ROLLING_RELEASE_SERVER_IMAGE: "${{ steps.generate.outputs.ROLLING_RELEASE_SERVER_IMAGE }}"
WORKFLOW_RUN_URL: "${{steps.generate.outputs.WORKFLOW_RUN_URL}}"
CYCLE_URL: "${{steps.generate.outputs.CYCLE_URL}}"
env:
GH_TOKEN: "${{ github.token }}"
REF: "${{ inputs.ref || github.sha }}"
PR_NUMBER: "${{ inputs.PR_NUMBER || '' }}"
REPORT_TYPE: "${{ inputs.REPORT_TYPE }}"
ROLLING_RELEASE_FROM_TAG: "${{ inputs.ROLLING_RELEASE_FROM_TAG }}"
AUTOMATION_DASHBOARD_URL: "${{ secrets.MM_E2E_AUTOMATION_DASHBOARD_URL }}"
# We could exclude the @smoke group for PRs, but then we wouldn't have it in the report
TEST_FILTER_CYPRESS_PR: >-
--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"
TEST_FILTER_CYPRESS_PROD_ONPREM: >-
--stage="@prod"
--excludeGroup="@te_only,@cloud_only,@high_availability"
--sortFirst="@compliance_export,@elasticsearch,@ldap_group,@ldap,@playbooks"
--sortLast="@saml,@keycloak,@plugin,@plugins_uninstall,@mfa,@license_removal"
TEST_FILTER_CYPRESS_PROD_CLOUD: >-
--stage="@prod"
--excludeGroup="@not_cloud,@cloud_trial,@e20_only,@te_only,@high_availability,@license_removal"
--sortFirst="@compliance_export,@elasticsearch,@ldap_group,@ldap,@playbooks"
--sortLast="@saml,@keycloak,@plugin,@plugins_uninstall,@mfa"
MM_ENV: "${{ inputs.MM_ENV || '' }}"
MM_SERVICE_OVERRIDES: "${{ inputs.MM_SERVICE_OVERRIDES }}"
steps:
- name: ci/checkout-repo
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
ref: "${{ inputs.ref || github.sha }}"
fetch-depth: 0
- name: ci/generate-test-variables
id: generate
run: |
MM_ENV_HASH=$(md5sum -z <<<"$MM_ENV" | cut -c-8)
TESTCASE_FAILURE_FATAL="true"
if grep -q CLOUD <<<"$REPORT_TYPE"; then
SERVER=cloud
else
SERVER=onprem
fi
case "$REPORT_TYPE" in
NONE | PR)
### Populate support variables
_COMMIT_SHA_COMPUTED=$(git rev-parse --verify "$REF") # NB: not actually used for resolving the commit; it's only to double check the value of 'inputs.ref'
### For image tag generation: utilize 'inputs.ref', assume that it is a full commit SHA
COMMIT_SHA="${REF}"
BRANCH="server-pr-${PR_NUMBER}" # For reference, the real branch name may be retrievable with command: 'jq -r .head.ref <pr.json'
SERVER_IMAGE_TAG="${COMMIT_SHA::7}"
SERVER_IMAGE_ORG=mattermostdevelopment
BUILD_ID_SUFFIX="${REPORT_TYPE@L}-${SERVER}-ent"
WORKERS_NUMBER=20
TEST_FILTER_CYPRESS="$TEST_FILTER_CYPRESS_PR"
COMPUTED_REPORT_TYPE="${REPORT_TYPE}"
### Run sanity assertions after variable generations
[ "$REF" = "${_COMMIT_SHA_COMPUTED}" ] # 'inputs.ref' must be a full commit hash, and the commit must exist
[ "$REPORT_TYPE" != "PR" ] || [ "$PR_NUMBER" -gt "0" ] # If report type is PR, then PR_NUMBER must be set to a number
;;
MASTER | MASTER_UNSTABLE | CLOUD | CLOUD_UNSTABLE)
### Populate support variables
_IS_TEST_UNSTABLE=$(sed -n -E 's/^.*(UNSTABLE).*$/\1/p' <<< "$REPORT_TYPE") # The variable's value is 'UNSTABLE' if report type is for unstable tests, otherwise it's empty
_TEST_FILTER_CYPRESS_VARIABLE="TEST_FILTER_CYPRESS_PROD_${SERVER@U}"
### For ref and image tag generation: ignore 'inputs.ref', and use master branch directly. Note that 'COMMIT_SHA' will be used for reporting the test result, and for checking out the testing scripts and test cases
COMMIT_SHA="$(git rev-parse --verify origin/master)"
BRANCH=master
SERVER_IMAGE_TAG=master
SERVER_IMAGE_ORG=mattermostdevelopment
BUILD_ID_SUFFIX="${_IS_TEST_UNSTABLE:+unstable-}daily-${SERVER}-ent"
BUILD_ID_SUFFIX_IN_STATUS_CHECK=true
WORKERS_NUMBER=10 # Daily tests are not time critical, and it's more efficient to run on fewer workers
TEST_FILTER_CYPRESS="${!_TEST_FILTER_CYPRESS_VARIABLE} ${_IS_TEST_UNSTABLE:+--invert}"
TM4J_ENABLE=true
COMPUTED_REPORT_TYPE="${REPORT_TYPE}"
[ -z "$_IS_TEST_UNSTABLE" ] || TESTCASE_FAILURE_FATAL="" # Assert that tests are stable. If they are not, the status check will be always green
;;
RELEASE | RELEASE_CLOUD)
### Populate support variables
_TEST_FILTER_CYPRESS_VARIABLE="TEST_FILTER_CYPRESS_PROD_${SERVER@U}"
### For ref and image tag generation: assume the 'inputs.ref' is a tag, and use the first two digits to construct the branch name
COMMIT_SHA="$(git rev-parse --verify HEAD)"
BRANCH=$(sed -E "s/v([0-9]+)\.([0-9]+)\..+$/release-\1.\2/g" <<<$REF)
SERVER_IMAGE_TAG="$(cut -c2- <<<$REF)" # Remove the leading 'v' from the given tag name, to generate the docker image tag
SERVER_IMAGE_ORG=mattermost
BUILD_ID_SUFFIX="release-${SERVER}-ent"
BUILD_ID_SUFFIX_IN_STATUS_CHECK=true
WORKERS_NUMBER=20
TEST_FILTER_CYPRESS="${!_TEST_FILTER_CYPRESS_VARIABLE}"
TM4J_ENABLE=true
COMPUTED_REPORT_TYPE=RELEASE
### Run sanity assertions after variable generations
git show-ref --verify "refs/tags/${REF}" # 'inputs.ref' must be a tag, for release report types
git show-ref --verify "refs/remotes/origin/${BRANCH}" # The release branch computed from the given tag must exist
;;
*)
echo "Fatal: unimplemented test type. Aborting."
exit 1
esac
if [ -n "$ROLLING_RELEASE_FROM_TAG" ]; then
ROLLING_RELEASE_COMMIT_SHA=$(git rev-parse --verify "$ROLLING_RELEASE_FROM_TAG")
ROLLING_RELEASE_SERVER_IMAGE_TAG=$(echo "$ROLLING_RELEASE_FROM_TAG" | sed 's/^v//') # Remove the leading 'v' from the given tag name, to generate the docker image tag
ROLLING_RELEASE_SERVER_IMAGE="mattermost/mattermost-enterprise-edition:${ROLLING_RELEASE_SERVER_IMAGE_TAG}"
BUILD_ID_SUFFIX="rolling${ROLLING_RELEASE_FROM_TAG/-/_}-$BUILD_ID_SUFFIX"
BUILD_ID_SUFFIX_IN_STATUS_CHECK=true
WORKERS_NUMBER=10 # Rolling release tests are particularly impacted by increased parallelism. It's more efficient to run on fewer workers
### Run sanity assertions after variable generations
git show-ref --verify "refs/tags/${ROLLING_RELEASE_FROM_TAG}" # 'inputs.ROLLING_RELEASE_FROM_TAG' must be a tag, for release report types
fi
ENABLED_DOCKER_SERVICES="postgres inbucket minio openldap elasticsearch keycloak"
for SVC_OP in $(tr , ' '<<<"$MM_SERVICE_OVERRIDES"); do
OP=$(cut -c1 <<<$SVC_OP)
SVC=$(cut -c2- <<<$SVC_OP)
case "$OP" in
"+") ENABLED_DOCKER_SERVICES="$ENABLED_DOCKER_SERVICES $SVC" ;;
"-") ENABLED_DOCKER_SERVICES=$(sed -E "s:(^| )${SVC}( |\$): :g" <<<"$ENABLED_DOCKER_SERVICES") ;;
*) echo "Invalid MM_SERVICE_OVERRIDE value: $SVC_OP"; exit 1 ;;
esac
done
# 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}-${BUILD_ID_SUFFIX}"
echo "commit_sha=${COMMIT_SHA}" >> $GITHUB_OUTPUT
echo "BRANCH=${BRANCH}" >> $GITHUB_OUTPUT
echo "SERVER_IMAGE=${SERVER_IMAGE_ORG}/mattermost-enterprise-edition:${SERVER_IMAGE_TAG}" >> $GITHUB_OUTPUT
echo "SERVER=${SERVER}" >> $GITHUB_OUTPUT
echo "server_uppercase=${SERVER@U}" >> $GITHUB_OUTPUT
echo "ENABLED_DOCKER_SERVICES=${ENABLED_DOCKER_SERVICES}" >> $GITHUB_OUTPUT
echo "status_check_context=E2E Tests/test${BUILD_ID_SUFFIX_IN_STATUS_CHECK:+-$BUILD_ID_SUFFIX}${MM_ENV:+/$MM_ENV_HASH}" >> $GITHUB_OUTPUT
echo "workers_number=${WORKERS_NUMBER}" >> $GITHUB_OUTPUT
echo "TEST_FILTER_CYPRESS=${TEST_FILTER_CYPRESS}" >> $GITHUB_OUTPUT
echo "TESTCASE_FAILURE_FATAL=${TESTCASE_FAILURE_FATAL}" >> $GITHUB_OUTPUT
echo "TM4J_ENABLE=${TM4J_ENABLE:-}" >> $GITHUB_OUTPUT
echo "REPORT_TYPE=${COMPUTED_REPORT_TYPE}" >> $GITHUB_OUTPUT
echo "ROLLING_RELEASE_commit_sha=${ROLLING_RELEASE_COMMIT_SHA}" >> $GITHUB_OUTPUT
echo "ROLLING_RELEASE_SERVER_IMAGE=${ROLLING_RELEASE_SERVER_IMAGE}" >> $GITHUB_OUTPUT
echo "BUILD_ID=${BUILD_ID}" >> $GITHUB_OUTPUT
# User notification variables
echo "WORKFLOW_RUN_URL=${{ github.server_url }}/${{ github.repository }}/actions/runs/${{github.run_id}}" >> $GITHUB_OUTPUT
echo "CYCLE_URL=${AUTOMATION_DASHBOARD_URL%%/api}/cycle/${BUILD_ID}" >> $GITHUB_OUTPUT
- name: ci/notify-user
env:
COMMIT_SHA: "${{steps.generate.outputs.commit_sha}}"
STATUS_CHECK_CONTEXT: "${{steps.generate.outputs.status_check_context}}"
WORKFLOW_RUN_URL: "${{steps.generate.outputs.WORKFLOW_RUN_URL}}"
CYCLE_URL: "${{steps.generate.outputs.CYCLE_URL}}"
RUN_CYPRESS: "${{inputs.RUN_CYPRESS == 'true' || ''}}"
RUN_PLAYWRIGHT: "${{inputs.RUN_PLAYWRIGHT == 'true' || ''}}"
run: |
if [ -n "$PR_NUMBER" ]; then
gh issue -R "${{ github.repository }}" comment "$PR_NUMBER" --body-file - <<EOF
E2E test run is starting for commit \`${COMMIT_SHA}\`${MM_ENV:+, with \`MM_ENV=$MM_ENV\`}${MM_SERVICE_OVERRIDES:+, Cypress service overrides \`$MM_SERVICE_OVERRIDES\`}.
To check the run progress:
- Cypress: ${RUN_CYPRESS:+look for commit status \`$STATUS_CHECK_CONTEXT\` or the access the [Automation Dashboard Cycle URL]($CYCLE_URL)}$([ -n "${RUN_CYPRESS:-}" ] || echo -n "will not run").
- Playwright: ${RUN_PLAYWRIGHT:+look for commit status \`$STATUS_CHECK_CONTEXT-playwright\`}$([ -n "${RUN_PLAYWRIGHT:-}" ] || echo -n "will not run").
You can also look at the [E2E test's Workflow Run URL]($WORKFLOW_RUN_URL) (run ID \`${{ github.run_id }}\`).
EOF
fi
e2e-fulltest-cypress:
needs:
- generate-test-variables
uses: ./.github/workflows/e2e-tests-ci-template.yml
if: ${{ inputs.RUN_CYPRESS == 'true' }}
with:
commit_sha: "${{ needs.generate-test-variables.outputs.commit_sha }}"
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 }}"
ENABLED_DOCKER_SERVICES: "${{ needs.generate-test-variables.outputs.ENABLED_DOCKER_SERVICES }}"
TEST_FILTER: "${{ needs.generate-test-variables.outputs.TEST_FILTER_CYPRESS }}"
MM_ENV: "${{ inputs.MM_ENV || '' }}"
BRANCH: "${{ needs.generate-test-variables.outputs.BRANCH }}"
BUILD_ID: "${{ needs.generate-test-variables.outputs.BUILD_ID }}"
REPORT_TYPE: "${{ needs.generate-test-variables.outputs.REPORT_TYPE }}"
ROLLING_RELEASE_commit_sha: "${{ needs.generate-test-variables.outputs.ROLLING_RELEASE_commit_sha }}"
ROLLING_RELEASE_SERVER_IMAGE: "${{ needs.generate-test-variables.outputs.ROLLING_RELEASE_SERVER_IMAGE }}"
secrets:
MM_LICENSE: "${{ secrets[format('MM_E2E_TEST_LICENSE_{0}_ENT', needs.generate-test-variables.outputs.server_uppercase)] }}"
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 }}"
REPORT_TM4J_API_KEY: "${{ needs.generate-test-variables.outputs.TM4J_ENABLE == 'true' && secrets.MM_E2E_TM4J_API_KEY || '' }}"
REPORT_TM4J_TEST_CYCLE_LINK_PREFIX: "${{ secrets.MM_E2E_TEST_CYCLE_LINK_PREFIX }}"
CWS_URL: "${{ needs.generate-test-variables.outputs.SERVER == 'cloud' && secrets.MM_E2E_CWS_URL || '' }}"
CWS_EXTRA_HTTP_HEADERS: "${{ needs.generate-test-variables.outputs.SERVER == 'cloud' && secrets.MM_E2E_CWS_EXTRA_HTTP_HEADERS || '' }}"
e2e-fulltest-playwright:
needs:
- generate-test-variables
uses: ./.github/workflows/e2e-tests-ci-template.yml
if: ${{ inputs.RUN_PLAYWRIGHT == 'true' }}
with:
commit_sha: "${{ needs.generate-test-variables.outputs.commit_sha }}"
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 }}"
TEST: playwright
TEST_FILTER: "${{ needs.generate-test-variables.outputs.TEST_FILTER_PLAYWRIGHT }}"
MM_ENV: "${{ inputs.MM_ENV || '' }}"
BRANCH: "${{ needs.generate-test-variables.outputs.BRANCH }}"
BUILD_ID: "${{ needs.generate-test-variables.outputs.BUILD_ID }}"
REPORT_TYPE: "${{ needs.generate-test-variables.outputs.REPORT_TYPE }}"
ROLLING_RELEASE_commit_sha: "${{ needs.generate-test-variables.outputs.ROLLING_RELEASE_commit_sha }}"
ROLLING_RELEASE_SERVER_IMAGE: "${{ needs.generate-test-variables.outputs.ROLLING_RELEASE_SERVER_IMAGE }}"
secrets:
MM_LICENSE: "${{ secrets[format('MM_E2E_TEST_LICENSE_{0}_ENT', needs.generate-test-variables.outputs.server_uppercase)] }}"
PUSH_NOTIFICATION_SERVER: "${{ secrets.MM_E2E_PUSH_NOTIFICATION_SERVER }}"
REPORT_WEBHOOK_URL: "${{ secrets.MM_E2E_REPORT_WEBHOOK_URL }}"
CWS_URL: "${{ needs.generate-test-variables.outputs.SERVER == 'cloud' && secrets.MM_E2E_CWS_URL || '' }}"
CWS_EXTRA_HTTP_HEADERS: "${{ needs.generate-test-variables.outputs.SERVER == 'cloud' && secrets.MM_E2E_CWS_EXTRA_HTTP_HEADERS || '' }}"
notify-user:
runs-on: ubuntu-latest
if: always()
needs:
- generate-test-variables
- e2e-fulltest-cypress
- e2e-fulltest-playwright
permissions:
issues: write
pull-requests: write
defaults:
run:
shell: bash
env:
GH_TOKEN: "${{ github.token }}"
PR_NUMBER: "${{ inputs.PR_NUMBER || '' }}"
MM_ENV: "${{ inputs.MM_ENV || '' }}"
COMMIT_SHA: "${{ needs.generate-test-variables.outputs.commit_sha }}"
STATUS_CHECK_CONTEXT: "${{ needs.generate-test-variables.outputs.status_check_context }}"
WORKFLOW_RUN_URL: "${{ needs.generate-test-variables.outputs.WORKFLOW_RUN_URL }}"
CYCLE_URL: "${{ needs.generate-test-variables.outputs.CYCLE_URL }}"
RUN_CYPRESS: "${{inputs.RUN_CYPRESS == 'true' || ''}}"
RUN_PLAYWRIGHT: "${{inputs.RUN_PLAYWRIGHT == 'true' || ''}}"
steps:
- name: ci/notify-user-test-completion
run: |
if [ -n "$PR_NUMBER" ]; then
gh issue -R "${{ github.repository }}" comment "$PR_NUMBER" --body-file - <<EOF
E2E test has completed for commit \`${COMMIT_SHA}\`${MM_ENV:+, with \`MM_ENV=$MM_ENV\`}.
Results summary:
- Cypress: ${RUN_CYPRESS:+pass rate is \`${{ needs.e2e-fulltest-cypress.outputs.pass_rate || 'unknown' }}\` (see [Automation Dashboard]($CYCLE_URL) and commit status check \`$STATUS_CHECK_CONTEXT\`)}$([ -n "${RUN_CYPRESS:-}" ] || echo -n "did not run").
- Playwright: ${RUN_PLAYWRIGHT:+pass rate is \`${{ needs.e2e-fulltest-playwright.outputs.pass_rate || 'unknown' }}\` (see commit status check \`$STATUS_CHECK_CONTEXT-playwright\`)}$([ -n "${RUN_PLAYWRIGHT:-}" ] || echo -n "did not run").
The run summary artifacts are available in the corresponding [Workflow Run]($WORKFLOW_RUN_URL).
EOF
fi

510
.github/workflows/e2e-tests-ci-template.yml поставляемый
Просмотреть файл

@@ -1,510 +0,0 @@
---
name: E2E Tests Template
on:
workflow_call:
inputs:
# NB: this does not support using branch names that belong to forks.
# In those cases, you should specify directly the commit SHA that you want to test, or
# some wrapper workflow that does it for you (e.g. the slash command for initiating a PR test)
commit_sha:
type: string
required: true
status_check_context:
type: string
required: true
workers_number:
type: string # Should ideally be a number; see https://github.com/orgs/community/discussions/67182
required: false
default: "1"
testcase_failure_fatal:
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
default: false
SERVER:
type: string # Valid values are: onprem, cloud
required: false
default: onprem
SERVER_IMAGE:
type: string
required: false
ENABLED_DOCKER_SERVICES:
type: string
required: false
TEST: # Valid values are: cypress, playwright
type: string
required: false
default: "cypress"
TEST_FILTER:
type: string
required: false
MM_ENV:
type: string
required: false
BRANCH:
type: string
required: false
BUILD_ID:
type: string
required: false
REPORT_TYPE:
type: string
required: false
ROLLING_RELEASE_commit_sha:
type: string
required: false
ROLLING_RELEASE_SERVER_IMAGE:
type: string
required: false
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
REPORT_TM4J_API_KEY:
required: false
REPORT_TM4J_TEST_CYCLE_LINK_PREFIX:
required: false
CWS_URL:
required: false
CWS_EXTRA_HTTP_HEADERS:
required: false
outputs:
passed:
value: "${{ jobs.report.outputs.passed }}"
failed:
value: "${{ jobs.report.outputs.failed }}"
failed_expected:
value: "${{ jobs.report.outputs.failed_expected }}"
pass_rate:
value: "${{ jobs.report.outputs.pass_rate }}"
jobs:
update-initial-status:
runs-on: ubuntu-latest
steps:
- uses: mattermost/actions/delivery/update-commit-status@main
env:
GITHUB_TOKEN: ${{ github.token }}
with:
repository_full_name: ${{ github.repository }}
commit_sha: ${{ inputs.commit_sha }}
context: ${{ inputs.status_check_context }}
description: E2E tests for mattermost server app
status: pending
cypress-check:
runs-on: ubuntu-latest
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@1d0ff469b7ec7b3cb9d8673fde0c81c44821de2a # v4.2.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-latest
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@1d0ff469b7ec7b3cb9d8673fde0c81c44821de2a # v4.2.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-latest
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-latest
needs:
- update-initial-status
defaults:
run:
shell: bash
outputs:
workers: "${{ steps.generate.outputs.workers }}"
node-cache-dependency-path: "${{ steps.generate.outputs.node-cache-dependency-path }}"
steps:
- name: ci/checkout-repo
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
ref: ${{ inputs.commit_sha }}
fetch-depth: 0
- name: ci/generate-build-variables
id: generate
env:
WORKERS: ${{ inputs.workers_number }}
TEST: ${{ inputs.TEST }}
run: |
[ "$WORKERS" -gt "0" ] # Assert that the workers number is an integer greater than 0
echo "workers="$(jq --slurp --compact-output '[range('"$WORKERS"')] | map(tostring)' /dev/null) >> $GITHUB_OUTPUT
echo "node-cache-dependency-path=e2e-tests/${TEST}/package-lock.json" >> $GITHUB_OUTPUT
generate-test-cycle:
runs-on: ubuntu-latest
needs:
- generate-build-variables
defaults:
run:
shell: bash
working-directory: e2e-tests
outputs:
status_check_url: "${{ steps.e2e-test-gencycle.outputs.status_check_url }}"
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@1d0ff469b7ec7b3cb9d8673fde0c81c44821de2a # v4.2.0
id: setup_node
with:
node-version-file: ".nvmrc"
cache: npm
cache-dependency-path: "e2e-tests/cypress/package-lock.json" # NB: the generate-cycle script is cypress-specific operation for now
- name: ci/e2e-test-gencycle
id: e2e-test-gencycle
env:
AUTOMATION_DASHBOARD_URL: "${{ secrets.AUTOMATION_DASHBOARD_URL }}"
AUTOMATION_DASHBOARD_TOKEN: "${{ secrets.AUTOMATION_DASHBOARD_TOKEN }}"
BRANCH: "${{ inputs.BRANCH }}"
BUILD_ID: "${{ inputs.BUILD_ID }}"
TEST: "${{ inputs.TEST }}"
TEST_FILTER: "${{ inputs.TEST_FILTER }}"
run: |
set -e -o pipefail
make generate-test-cycle | tee generate-test-cycle.out
# Extract cycle's dashboard URL, if present
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
test:
continue-on-error: true # Individual runner failures shouldn't prevent the completion of an E2E run
strategy:
fail-fast: false # Individual runner failures shouldn't prevent the completion of an E2E run
matrix:
#
# Note that E2E tests should be run only on ubuntu, for QA purposes.
# But it's useful to be able to run and debug the E2E tests for different OSes.
# Notes:
# - For MacOS: works on developer machines, but uses too many resources to be able to run on Github Actions
# - for Windows: cannot currently run on Github Actions, since the runners do not support running linux containers, at the moment
#
#os: [ubuntu-latest, windows-2022, macos-12-xl]
os: [ubuntu-latest]
worker_index: ${{ fromJSON(needs.generate-build-variables.outputs.workers) }} # https://docs.github.com/en/actions/learn-github-actions/expressions#example-returning-a-json-object
runs-on: "${{ matrix.os }}"
timeout-minutes: 120
needs:
- cypress-check
- playwright-check
- shell-check
- generate-build-variables
- generate-test-cycle
defaults:
run:
shell: bash
working-directory: e2e-tests
env:
AUTOMATION_DASHBOARD_URL: "${{ secrets.AUTOMATION_DASHBOARD_URL }}"
AUTOMATION_DASHBOARD_TOKEN: "${{ secrets.AUTOMATION_DASHBOARD_TOKEN }}"
SERVER: "${{ inputs.SERVER }}"
SERVER_IMAGE: "${{ inputs.SERVER_IMAGE }}"
MM_LICENSE: "${{ secrets.MM_LICENSE }}"
ENABLED_DOCKER_SERVICES: "${{ inputs.ENABLED_DOCKER_SERVICES }}"
TEST: "${{ inputs.TEST }}"
TEST_FILTER: "${{ inputs.TEST_FILTER }}"
MM_ENV: "${{ inputs.MM_ENV }}"
BRANCH: "${{ inputs.BRANCH }}"
BUILD_ID: "${{ inputs.BUILD_ID }}"
CI_BASE_URL: "${{ matrix.os }}-${{ matrix.worker_index }}"
CYPRESS_pushNotificationServer: "${{ secrets.PUSH_NOTIFICATION_SERVER }}"
CWS_URL: "${{ secrets.CWS_URL }}"
CWS_EXTRA_HTTP_HEADERS: "${{ secrets.CWS_EXTRA_HTTP_HEADERS }}"
ROLLING_RELEASE_COMMIT_SHA: "${{ inputs.ROLLING_RELEASE_commit_sha }}"
ROLLING_RELEASE_SERVER_IMAGE: "${{ inputs.ROLLING_RELEASE_SERVER_IMAGE }}"
steps:
- name: ci/checkout-repo
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
ref: ${{ inputs.commit_sha }}
fetch-depth: 0
- name: ci/setup-macos-docker
if: runner.os == 'macos'
# https://github.com/actions/runner-images/issues/17#issuecomment-1537238473
run: |
brew install docker docker-compose
colima start
mkdir -p ~/.docker/cli-plugins
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@1d0ff469b7ec7b3cb9d8673fde0c81c44821de2a # v4.2.0
id: setup_node
with:
node-version-file: ".nvmrc"
cache: npm
cache-dependency-path: ${{ needs.generate-build-variables.outputs.node-cache-dependency-path }}
- name: ci/e2e-test
run: |
make cloud-init
if [ -n "$ROLLING_RELEASE_SERVER_IMAGE" ]; then
echo "RollingRelease: checking out E2E test cases from revision ${ROLLING_RELEASE_COMMIT_SHA}, for initial smoketest"
git checkout "${ROLLING_RELEASE_COMMIT_SHA}" -- "${TEST}/" && git status
(
echo "RollingRelease: running initial smoketest against image $ROLLING_RELEASE_SERVER_IMAGE"
export SERVER_IMAGE="$ROLLING_RELEASE_SERVER_IMAGE"
export TEST_FILTER=""
export AUTOMATION_DASHBOARD_URL=""
make
)
echo "RollingRelease: asserting smoketest result has zero failures."
FAILURES=$(jq -r '.failed' "${TEST}/results/summary.json")
if [ "$FAILURES" -ne "0" ]; then
echo "RollingRelease: initial smoketest for rolling release E2E run has nonzero ($FAILURES) failures. Aborting test run." >&2
exit 1
fi
rm -rfv "${TEST}/{results,logs}"
echo "RollingRelease: reset the E2E test cases to the revision to test"
git reset --hard HEAD && git status
echo "RollingRelease: smoketest completed. Starting full E2E tests."
fi
make
make cloud-teardown
- name: ci/e2e-test-store-results
uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3
if: always()
with:
name: e2e-test-results-${{ inputs.TEST }}-${{ matrix.os }}-${{ matrix.worker_index }}
path: |
e2e-tests/${{ inputs.TEST }}/logs/
e2e-tests/${{ inputs.TEST }}/results/
retention-days: 1
report:
runs-on: ubuntu-latest
needs:
- test
- generate-build-variables
defaults:
run:
shell: bash
working-directory: e2e-tests
outputs:
passed: "${{ steps.calculate-results.outputs.passed }}"
failed: "${{ steps.calculate-results.outputs.failed }}"
failed_expected: "${{ steps.calculate-results.outputs.failed_expected }}"
pass_rate: "${{ steps.calculate-results.outputs.pass_rate }}"
commit_status_message: "${{ steps.calculate-results.outputs.commit_status_message }}"
steps:
- name: ci/checkout-repo
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
ref: ${{ inputs.commit_sha }}
fetch-depth: 0
- name: ci/download-artifacts
uses: actions/download-artifact@fa0a91b85d4f404e444e00e005971372dc801d16 # v4.1.8
with:
pattern: e2e-test-results-${{ inputs.TEST }}-*
path: e2e-tests/${{ inputs.TEST }}/
merge-multiple: true
- name: ci/upload-report-global
uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3
with:
name: e2e-test-results-${{ inputs.TEST }}
path: |
e2e-tests/${{ inputs.TEST }}/logs/
e2e-tests/${{ inputs.TEST }}/results/
- name: ci/setup-node
if: "${{ inputs.enable_reporting }}"
uses: actions/setup-node@1d0ff469b7ec7b3cb9d8673fde0c81c44821de2a # v4.2.0
id: setup_node
with:
node-version-file: ".nvmrc"
cache: npm
cache-dependency-path: ${{ needs.generate-build-variables.outputs.node-cache-dependency-path }}
- name: ci/publish-report
if: "${{ inputs.enable_reporting }}"
env:
TYPE: "${{ inputs.REPORT_TYPE }}"
TEST: "${{ inputs.TEST }}"
SERVER: "${{ inputs.SERVER }}"
SERVER_IMAGE: "${{ inputs.SERVER_IMAGE }}"
AUTOMATION_DASHBOARD_URL: "${{ secrets.AUTOMATION_DASHBOARD_URL }}"
WEBHOOK_URL: "${{ secrets.REPORT_WEBHOOK_URL }}"
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: |
make report
# The results dir may have been modified as part of the reporting: re-upload
- name: ci/upload-report-global
if: "${{ inputs.enable_reporting }}"
uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3
with:
name: e2e-test-results-${{ inputs.TEST }}
path: |
e2e-tests/${{ inputs.TEST }}/logs/
e2e-tests/${{ inputs.TEST }}/results/
overwrite: true
- name: ci/report-calculate-results
id: calculate-results
env:
TEST: "${{ inputs.TEST }}"
run: |
AD_CYCLE_FILE="${TEST}/results/ad_cycle.json"
if [ -f "$AD_CYCLE_FILE" ]; then
# Prefer using the Automation Dashboard's results to calculate failures
export PASSED=$(jq -r .pass "$AD_CYCLE_FILE")
export FAILED=$(jq -r .fail "$AD_CYCLE_FILE")
export FAILED_EXPECTED=$(jq -r ".known + .flaky + .skipped" "$AD_CYCLE_FILE")
else
# Otherwise, utilize summary.json to calculate the failures
# NB: in this job, this file only makes sense if a single worker is used, as with Playwright
export PASSED=$(jq '.passed' "${TEST}/results/summary.json")
export FAILED=$(jq '.failed' "${TEST}/results/summary.json")
export FAILED_EXPECTED=$(jq '.failed_expected' "${TEST}/results/summary.json")
fi
export TOTAL_SPECS=$(( PASSED + FAILED ))
export PASS_RATE=$(jq -r '100 * (env.PASSED | tonumber) / (env.TOTAL_SPECS | tonumber)' <<<'{}' | xargs -l printf '%.2f')
if [ "$FAILED" = "0" ]; then
export COMMIT_STATUS_MESSAGE="All test cases passed"
else
export COMMIT_STATUS_MESSAGE="${FAILED} test cases failed. Please check the workflow logs"
fi
echo "passed=${PASSED:?}" >> $GITHUB_OUTPUT
echo "failed=${FAILED:?}" >> $GITHUB_OUTPUT
echo "failed_expected=${FAILED_EXPECTED:?}" >> $GITHUB_OUTPUT
echo "pass_rate=${PASS_RATE:?}%" >> $GITHUB_OUTPUT
echo "commit_status_message=${COMMIT_STATUS_MESSAGE:?}" >> $GITHUB_OUTPUT
echo "$COMMIT_STATUS_MESSAGE"
- name: ci/e2e-test-assert-results
if: "${{ inputs.testcase_failure_fatal }}"
run: |
# Assert that the run contained 0 failures
[ "${{ steps.calculate-results.outputs.failed }}" = "0" ]
update-failure-final-status:
runs-on: ubuntu-latest
if: failure() || cancelled()
needs:
- generate-test-cycle
- test
- report
steps:
- uses: mattermost/actions/delivery/update-commit-status@main
env:
GITHUB_TOKEN: ${{ github.token }}
with:
repository_full_name: ${{ github.repository }}
commit_sha: ${{ inputs.commit_sha }}
context: ${{ inputs.status_check_context }}
description: ${{ needs.report.outputs.commit_status_message || 'Error during test execution' }}
status: failure
target_url: "${{ needs.generate-test-cycle.outputs.status_check_url }}"
update-success-final-status:
runs-on: ubuntu-latest
if: success()
needs:
- generate-test-cycle
- test
- report
steps:
- uses: mattermost/actions/delivery/update-commit-status@main
env:
GITHUB_TOKEN: ${{ github.token }}
with:
repository_full_name: ${{ github.repository }}
commit_sha: ${{ inputs.commit_sha }}
context: ${{ inputs.status_check_context }}
description: ${{ needs.report.outputs.commit_status_message || 'Error during test execution' }}
status: success
target_url: "${{ needs.generate-test-cycle.outputs.status_check_url }}"

226
.github/workflows/e2e-tests-ci.yml поставляемый
Просмотреть файл

@@ -1,17 +1,225 @@
---
name: E2E Smoketests
name: E2E Tests (pull request)
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:
e2e-smoketest:
uses: ./.github/workflows/e2e-tests-ci-template.yml
resolve-pr:
runs-on: ubuntu-24.04
outputs:
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/checkout-repo
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
fetch-depth: 0
- name: ci/resolve-pr-and-commit
id: resolve
env:
GH_TOKEN: ${{ github.token }}
INPUT_PR_NUMBER: ${{ inputs.pr_number || github.event.pull_request.number }}
INPUT_COMMIT_SHA: ${{ inputs.commit_sha || github.event.pull_request.head.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_DATA=$(gh api "repos/${{ github.repository }}/commits/${INPUT_COMMIT_SHA}/pulls" \
--jq '.[0] // empty' 2>/dev/null || echo "")
PR_NUMBER=$(echo "$PR_DATA" | jq -r '.number // empty' 2>/dev/null || echo "")
if [ -z "$PR_NUMBER" ]; then
echo "::error::No PR found for commit ${INPUT_COMMIT_SHA}. This workflow is for PRs only."
exit 1
fi
echo "Found PR #${PR_NUMBER} for commit ${INPUT_COMMIT_SHA}"
# Skip if PR is already merged to master or a release branch.
# The e2e-tests-on-merge workflow handles post-merge E2E tests.
PR_MERGED=$(echo "$PR_DATA" | jq -r '.merged_at // empty' 2>/dev/null || echo "")
PR_BASE_REF=$(echo "$PR_DATA" | jq -r '.base.ref // empty' 2>/dev/null || echo "")
if [ -n "$PR_MERGED" ]; then
if [ "$PR_BASE_REF" = "master" ] || [[ "$PR_BASE_REF" =~ ^release-[0-9]+\.[0-9]+$ ]]; then
echo "PR #${PR_NUMBER} is already merged to ${PR_BASE_REF}. Skipping - handled by e2e-tests-on-merge workflow."
echo "PR_NUMBER=" >> $GITHUB_OUTPUT
echo "COMMIT_SHA=" >> $GITHUB_OUTPUT
exit 0
fi
fi
echo "PR_NUMBER=${PR_NUMBER}" >> $GITHUB_OUTPUT
echo "COMMIT_SHA=${INPUT_COMMIT_SHA}" >> $GITHUB_OUTPUT
exit 0
fi
# Neither provided
echo "::error::Either pr_number or commit_sha must be provided"
exit 1
- name: ci/check-e2e-test-only
if: steps.resolve.outputs.PR_NUMBER != ''
id: e2e-check
uses: ./.github/actions/check-e2e-test-only
with:
pr_number: ${{ steps.resolve.outputs.PR_NUMBER }}
check-changes:
needs: resolve-pr
if: needs.resolve-pr.outputs.PR_NUMBER != ''
runs-on: ubuntu-24.04
outputs:
should_run: "${{ steps.check.outputs.should_run }}"
steps:
- name: ci/checkout-repo
if: inputs.commit_sha != '' || github.event.pull_request
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.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
echo "should_run=${SHOULD_RUN}" >> $GITHUB_OUTPUT
echo "Should run E2E tests: ${SHOULD_RUN}"
e2e-cypress:
needs:
- resolve-pr
- check-changes
if: needs.resolve-pr.outputs.PR_NUMBER != ''
permissions:
statuses: write
uses: ./.github/workflows/e2e-tests-cypress.yml
with:
commit_sha: "${{ inputs.commit_sha }}"
status_check_context: "E2E Tests/smoketests"
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 }}"
should_run: "${{ needs.check-changes.outputs.should_run }}"
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.resolve-pr.outputs.PR_NUMBER != ''
permissions:
statuses: write
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 }}"
should_run: "${{ needs.check-changes.outputs.should_run }}"
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 }}"

649
.github/workflows/e2e-tests-cypress-template.yml поставляемый Обычный файл
Просмотреть файл

@@ -0,0 +1,649 @@
---
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
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 }}"
start_time: "${{ steps.generate-workers.outputs.start_time }}"
steps:
- name: ci/generate-workers
id: generate-workers
run: |
echo "workers=$(jq -nc '[range(${{ inputs.workers }})]')" >> $GITHUB_OUTPUT
echo "start_time=$(date +%s)" >> $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@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.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: 30
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@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
ref: ${{ inputs.commit_sha }}
fetch-depth: 0
- name: ci/setup-node
uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.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@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
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 }}
test_duration: ${{ steps.calculate.outputs.test_duration }}
end_time: ${{ steps.record-end-time.outputs.end_time }}
steps:
- name: ci/checkout-repo
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- name: ci/download-results
uses: actions/download-artifact@70fc10c6e5e1ce46ad2ea6f2b72d43f7d47b13c3 # v8.0.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
- name: ci/record-end-time
id: record-end-time
run: echo "end_time=$(date +%s)" >> $GITHUB_OUTPUT
run-failed-tests:
runs-on: ubuntu-24.04
timeout-minutes: 30
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@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
ref: ${{ inputs.commit_sha }}
fetch-depth: 0
- name: ci/setup-node
uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.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@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
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 }}"
duration: "${{ steps.duration.outputs.duration }}"
duration_display: "${{ steps.duration.outputs.duration_display }}"
retest_display: "${{ steps.duration.outputs.retest_display }}"
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@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.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@70fc10c6e5e1ce46ad2ea6f2b72d43f7d47b13c3 # v8.0.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 "test_duration=${{ needs.calculate-results.outputs.test_duration }}" >> $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@70fc10c6e5e1ce46ad2ea6f2b72d43f7d47b13c3 # v8.0.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@70fc10c6e5e1ce46ad2ea6f2b72d43f7d47b13c3 # v8.0.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 "test_duration=${{ steps.use-previous.outputs.test_duration }}" >> $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 "test_duration=${{ steps.recalculate.outputs.test_duration }}" >> $GITHUB_OUTPUT
{
echo "failed_tests<<EOF"
echo "$RECALCULATE_FAILED_TESTS"
echo "EOF"
} >> $GITHUB_OUTPUT
fi
- name: ci/compute-duration
id: duration
env:
START_TIME: ${{ needs.generate-test-cycle.outputs.start_time }}
FIRST_PASS_END_TIME: ${{ needs.calculate-results.outputs.end_time }}
RETEST_RESULT: ${{ needs.run-failed-tests.result }}
RETEST_SPEC_COUNT: ${{ needs.calculate-results.outputs.failed_specs_count }}
TEST_DURATION: ${{ steps.final-results.outputs.test_duration }}
run: |
NOW=$(date +%s)
ELAPSED=$((NOW - START_TIME))
MINUTES=$((ELAPSED / 60))
SECONDS=$((ELAPSED % 60))
DURATION="${MINUTES}m ${SECONDS}s"
# Compute first-pass and re-run durations
FIRST_PASS_ELAPSED=$((FIRST_PASS_END_TIME - START_TIME))
FP_MIN=$((FIRST_PASS_ELAPSED / 60))
FP_SEC=$((FIRST_PASS_ELAPSED % 60))
FIRST_PASS="${FP_MIN}m ${FP_SEC}s"
if [ "$RETEST_RESULT" != "skipped" ]; then
RERUN_ELAPSED=$((NOW - FIRST_PASS_END_TIME))
RR_MIN=$((RERUN_ELAPSED / 60))
RR_SEC=$((RERUN_ELAPSED % 60))
RUN_BREAKDOWN=" (first-pass: ${FIRST_PASS}, re-run: ${RR_MIN}m ${RR_SEC}s)"
else
RUN_BREAKDOWN=""
fi
# Duration icons: >20m high alert, >15m warning, otherwise clock
if [ "$MINUTES" -ge 20 ]; then
DURATION_DISPLAY=":rotating_light: ${DURATION}${RUN_BREAKDOWN} | test: ${TEST_DURATION}"
elif [ "$MINUTES" -ge 15 ]; then
DURATION_DISPLAY=":warning: ${DURATION}${RUN_BREAKDOWN} | test: ${TEST_DURATION}"
else
DURATION_DISPLAY=":clock3: ${DURATION}${RUN_BREAKDOWN} | test: ${TEST_DURATION}"
fi
# Retest indicator with spec count
if [ "$RETEST_RESULT" != "skipped" ]; then
RETEST_DISPLAY=":repeat: re-run ${RETEST_SPEC_COUNT} spec(s)"
else
RETEST_DISPLAY=""
fi
echo "duration=${DURATION}" >> $GITHUB_OUTPUT
echo "duration_display=${DURATION_DISPLAY}" >> $GITHUB_OUTPUT
echo "retest_display=${RETEST_DISPLAY}" >> $GITHUB_OUTPUT
- name: ci/upload-combined-results
if: inputs.workers > 1
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
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 }}
DURATION_DISPLAY: ${{ steps.duration.outputs.duration_display }}
RETEST_DISPLAY: ${{ steps.duration.outputs.retest_display }}
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 retest part for message
RETEST_PART=""
if [ -n "$RETEST_DISPLAY" ]; then
RETEST_PART=" | ${RETEST_DISPLAY}"
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}${RETEST_PART} | [full report](${REPORT_URL})\n${DURATION_DISPLAY}"
}]
}
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 }}
DURATION_DISPLAY: ${{ steps.duration.outputs.duration_display }}
RETEST_RESULT: ${{ needs.run-failed-tests.result }}
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 "| duration | ${DURATION_DISPLAY} |"
if [ "$RETEST_RESULT" != "skipped" ]; then
echo "| retested | Yes |"
else
echo "| retested | No |"
fi
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 }}, ${{ needs.report.outputs.duration }}, 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 }}, ${{ needs.report.outputs.duration }}, 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 поставляемый Обычный файл
Просмотреть файл

@@ -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"
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')"
should_run:
type: string
required: false
default: "true"
description: "Set to 'false' to skip tests and post a success status without running E2E"
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 }}"
context_suffix: "${{ steps.build-vars.outputs.context_suffix }}"
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
# Generate context name suffix based on report type
REPORT_TYPE="${{ inputs.report_type }}"
case "$REPORT_TYPE" in
MASTER) echo "context_suffix=/master" >> $GITHUB_OUTPUT ;;
RELEASE) echo "context_suffix=/release" >> $GITHUB_OUTPUT ;;
RELEASE_CUT) echo "context_suffix=/release-cut" >> $GITHUB_OUTPUT ;;
*) echo "context_suffix=" >> $GITHUB_OUTPUT ;;
esac
skip:
needs:
- generate-build-variables
if: inputs.should_run == 'false'
runs-on: ubuntu-24.04
permissions:
statuses: write
steps:
- name: ci/post-skip-status
env:
GH_TOKEN: ${{ github.token }}
COMMIT_SHA: ${{ inputs.commit_sha }}
CONTEXT_NAME: "e2e-test/cypress-full/${{ inputs.server_edition || 'enterprise' }}${{ needs.generate-build-variables.outputs.context_suffix }}"
run: |
gh api repos/${{ github.repository }}/statuses/${COMMIT_SHA} \
-f state=success \
-f context="${CONTEXT_NAME}" \
-f description="No E2E-relevant changes - skipped" \
-f target_url="https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}"
echo "Posted success for ${CONTEXT_NAME}"
cypress-full:
needs:
- generate-build-variables
if: inputs.should_run != 'false'
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: 40
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' }}${{ needs.generate-build-variables.outputs.context_suffix }}"
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 }}

583
.github/workflows/e2e-tests-playwright-template.yml поставляемый Обычный файл
Просмотреть файл

@@ -0,0 +1,583 @@
---
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
workers:
description: "Number of parallel shards"
type: number
required: false
default: 2
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
generate-test-variables:
runs-on: ubuntu-24.04
outputs:
workers: "${{ steps.generate-workers.outputs.workers }}"
start_time: "${{ steps.generate-workers.outputs.start_time }}"
steps:
- name: ci/generate-workers
id: generate-workers
run: |
echo "workers=$(jq -nc '[range(1; ${{ inputs.workers }} + 1)]')" >> $GITHUB_OUTPUT
echo "start_time=$(date +%s)" >> $GITHUB_OUTPUT
run-tests:
runs-on: ubuntu-24.04
timeout-minutes: 30
continue-on-error: true
needs:
- generate-test-variables
if: needs.generate-test-variables.result == 'success'
strategy:
fail-fast: false
matrix:
worker_index: ${{ fromJSON(needs.generate-test-variables.outputs.workers) }}
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 }}"
PW_SHARD: "${{ format('--shard={0}/{1}', matrix.worker_index, inputs.workers) }}"
BRANCH: "${{ inputs.branch }}-${{ inputs.test_type }}"
BUILD_ID: "${{ inputs.build_id }}"
CI_BASE_URL: "${{ inputs.test_type }}-test-${{ matrix.worker_index }}"
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@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.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@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
if: always()
with:
name: playwright-${{ inputs.test_type }}-${{ inputs.server_edition }}-results-${{ matrix.worker_index }}
path: |
e2e-tests/playwright/logs/
e2e-tests/playwright/results/
retention-days: 5
calculate-results:
runs-on: ubuntu-24.04
needs:
- generate-test-variables
- run-tests
if: always() && needs.generate-test-variables.result == 'success'
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 }}
test_duration: ${{ steps.calculate.outputs.test_duration }}
end_time: ${{ steps.record-end-time.outputs.end_time }}
steps:
- name: ci/checkout-repo
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- name: ci/setup-node
uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0
with:
node-version-file: ".nvmrc"
cache: npm
cache-dependency-path: "e2e-tests/playwright/package-lock.json"
- name: ci/download-shard-results
uses: actions/download-artifact@70fc10c6e5e1ce46ad2ea6f2b72d43f7d47b13c3 # v8.0.0
with:
pattern: playwright-${{ inputs.test_type }}-${{ inputs.server_edition }}-results-*
path: e2e-tests/playwright/shard-results/
merge-multiple: true
- name: ci/merge-shard-results
working-directory: e2e-tests/playwright
run: |
mkdir -p results/reporter
# Merge blob reports using Playwright merge-reports (per docs)
npm install --no-save @playwright/test
npx playwright merge-reports --config merge.config.mjs ./shard-results/results/blob-report/
- name: ci/calculate
id: calculate
uses: ./.github/actions/calculate-playwright-results
with:
original-results-path: e2e-tests/playwright/results/reporter/results.json
- name: ci/upload-merged-results
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
with:
name: playwright-${{ inputs.test_type }}-${{ inputs.server_edition }}-results
path: e2e-tests/playwright/results/
retention-days: 5
- name: ci/record-end-time
id: record-end-time
run: echo "end_time=$(date +%s)" >> $GITHUB_OUTPUT
run-failed-tests:
runs-on: ubuntu-24.04
timeout-minutes: 30
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@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.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@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
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:
- generate-test-variables
- 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 }}"
duration: "${{ steps.duration.outputs.duration }}"
duration_display: "${{ steps.duration.outputs.duration_display }}"
retest_display: "${{ steps.duration.outputs.retest_display }}"
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@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0
with:
node-version-file: ".nvmrc"
cache: npm
cache-dependency-path: "e2e-tests/playwright/package-lock.json"
# Download merged results (uploaded by calculate-results)
- name: ci/download-results
uses: actions/download-artifact@70fc10c6e5e1ce46ad2ea6f2b72d43f7d47b13c3 # v8.0.0
with:
name: playwright-${{ inputs.test_type }}-${{ inputs.server_edition }}-results
path: e2e-tests/playwright/results/
# Download retest results (only if retest ran)
- name: ci/download-retest-results
if: needs.run-failed-tests.result != 'skipped'
uses: actions/download-artifact@70fc10c6e5e1ce46ad2ea6f2b72d43f7d47b13c3 # v8.0.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@8df5847569e6427dd6c4fb1cf565c83acfa8afa7 # v6.0.0
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/"
# 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/compute-duration
id: duration
env:
START_TIME: ${{ needs.generate-test-variables.outputs.start_time }}
FIRST_PASS_END_TIME: ${{ needs.calculate-results.outputs.end_time }}
RETEST_RESULT: ${{ needs.run-failed-tests.result }}
RETEST_SPEC_COUNT: ${{ needs.calculate-results.outputs.failed_specs_count }}
TEST_DURATION: ${{ steps.final-results.outputs.test_duration }}
run: |
NOW=$(date +%s)
ELAPSED=$((NOW - START_TIME))
MINUTES=$((ELAPSED / 60))
SECONDS=$((ELAPSED % 60))
DURATION="${MINUTES}m ${SECONDS}s"
# Compute first-pass and re-run durations
FIRST_PASS_ELAPSED=$((FIRST_PASS_END_TIME - START_TIME))
FP_MIN=$((FIRST_PASS_ELAPSED / 60))
FP_SEC=$((FIRST_PASS_ELAPSED % 60))
FIRST_PASS="${FP_MIN}m ${FP_SEC}s"
if [ "$RETEST_RESULT" != "skipped" ]; then
RERUN_ELAPSED=$((NOW - FIRST_PASS_END_TIME))
RR_MIN=$((RERUN_ELAPSED / 60))
RR_SEC=$((RERUN_ELAPSED % 60))
RUN_BREAKDOWN=" (first-pass: ${FIRST_PASS}, re-run: ${RR_MIN}m ${RR_SEC}s)"
else
RUN_BREAKDOWN=""
fi
# Duration icons: >20m high alert, >15m warning, otherwise clock
if [ "$MINUTES" -ge 20 ]; then
DURATION_DISPLAY=":rotating_light: ${DURATION}${RUN_BREAKDOWN} | test: ${TEST_DURATION}"
elif [ "$MINUTES" -ge 15 ]; then
DURATION_DISPLAY=":warning: ${DURATION}${RUN_BREAKDOWN} | test: ${TEST_DURATION}"
else
DURATION_DISPLAY=":clock3: ${DURATION}${RUN_BREAKDOWN} | test: ${TEST_DURATION}"
fi
# Retest indicator with spec count
if [ "$RETEST_RESULT" != "skipped" ]; then
RETEST_DISPLAY=":repeat: re-run ${RETEST_SPEC_COUNT} spec(s)"
else
RETEST_DISPLAY=""
fi
echo "duration=${DURATION}" >> $GITHUB_OUTPUT
echo "duration_display=${DURATION_DISPLAY}" >> $GITHUB_OUTPUT
echo "retest_display=${RETEST_DISPLAY}" >> $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 }}
DURATION_DISPLAY: ${{ steps.duration.outputs.duration_display }}
RETEST_DISPLAY: ${{ steps.duration.outputs.retest_display }}
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 retest part for message
RETEST_PART=""
if [ -n "$RETEST_DISPLAY" ]; then
RETEST_PART=" | ${RETEST_DISPLAY}"
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}${RETEST_PART} | [full report](${REPORT_URL})\n${DURATION_DISPLAY}"
}]
}
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 }}
DURATION_DISPLAY: ${{ steps.duration.outputs.duration_display }}
RETEST_RESULT: ${{ needs.run-failed-tests.result }}
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 "| duration | ${DURATION_DISPLAY} |"
if [ "$RETEST_RESULT" != "skipped" ]; then
echo "| retested | Yes |"
else
echo "| retested | No |"
fi
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 }}, ${{ needs.report.outputs.duration }}, 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 }}, ${{ needs.report.outputs.duration }}, 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 }}

185
.github/workflows/e2e-tests-playwright.yml поставляемый Обычный файл
Просмотреть файл

@@ -0,0 +1,185 @@
---
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"
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')"
should_run:
type: string
required: false
default: "true"
description: "Set to 'false' to skip tests and post a success status without running E2E"
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 }}"
context_suffix: "${{ steps.build-vars.outputs.context_suffix }}"
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
# Generate context name suffix based on report type
REPORT_TYPE="${{ inputs.report_type }}"
case "$REPORT_TYPE" in
MASTER) echo "context_suffix=/master" >> $GITHUB_OUTPUT ;;
RELEASE) echo "context_suffix=/release" >> $GITHUB_OUTPUT ;;
RELEASE_CUT) echo "context_suffix=/release-cut" >> $GITHUB_OUTPUT ;;
*) echo "context_suffix=" >> $GITHUB_OUTPUT ;;
esac
skip:
needs:
- generate-build-variables
if: inputs.should_run == 'false'
runs-on: ubuntu-24.04
permissions:
statuses: write
steps:
- name: ci/post-skip-status
env:
GH_TOKEN: ${{ github.token }}
COMMIT_SHA: ${{ inputs.commit_sha }}
CONTEXT_NAME: "e2e-test/playwright-full/${{ inputs.server_edition || 'enterprise' }}${{ needs.generate-build-variables.outputs.context_suffix }}"
run: |
gh api repos/${{ github.repository }}/statuses/${COMMIT_SHA} \
-f state=success \
-f context="${CONTEXT_NAME}" \
-f description="No E2E-relevant changes - skipped" \
-f target_url="https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}"
echo "Posted success for ${CONTEXT_NAME}"
playwright-full:
needs:
- generate-build-variables
if: inputs.should_run != 'false'
uses: ./.github/workflows/e2e-tests-playwright-template.yml
with:
test_type: full
test_filter: '--grep-invert "@visual"'
workers: 4
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' }}${{ needs.generate-build-variables.outputs.context_suffix }}"
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 }}

150
.github/workflows/e2e-tests-verified-label.yml поставляемый Обычный файл
Просмотреть файл

@@ -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"

10
.github/workflows/esrupgrade-common.yml поставляемый
Просмотреть файл

@@ -32,6 +32,7 @@ jobs:
run: |
cd server/build
docker compose --no-ansi run --rm start_dependencies
cat ../tests/custom-schema-cpa.ldif | docker compose --ansi never exec -T openldap bash -c 'ldapadd -Y EXTERNAL -H ldapi:/// -w mostest || true';
cat ../tests/test-data.ldif | docker compose --no-ansi exec -T openldap bash -c 'ldapadd -x -D "cn=admin,dc=mm,dc=test,dc=com" -w mostest';
docker compose --no-ansi exec -T minio sh -c 'mkdir -p /data/mattermost-test';
docker compose --no-ansi ps
@@ -89,7 +90,7 @@ jobs:
# We skip the very last line, which simply contains the date of the dump
head -n -1 ${DUMP_SERVER_NAME} | gzip > ${DUMP_SERVER_NAME}.gz
- name: Upload dump
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
with:
name: upgraded-dump-server
path: ${{ env.DUMP_SERVER_NAME }}.gz
@@ -103,6 +104,7 @@ jobs:
run: |
cd server/build
docker compose --no-ansi run --rm start_dependencies
cat ../tests/custom-schema-cpa.ldif | docker compose --ansi never exec -T openldap bash -c 'ldapadd -Y EXTERNAL -H ldapi:/// -w mostest || true';
cat ../tests/test-data.ldif | docker compose --no-ansi exec -T openldap bash -c 'ldapadd -x -D "cn=admin,dc=mm,dc=test,dc=com" -w mostest';
docker compose --no-ansi exec -T minio sh -c 'mkdir -p /data/mattermost-test';
docker compose --no-ansi ps
@@ -134,7 +136,7 @@ jobs:
# We skip the very last line, which simply contains the date of the dump
head -n -1 ${DUMP_SCRIPT_NAME} | gzip > ${DUMP_SCRIPT_NAME}.gz
- name: Upload dump
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
with:
name: upgraded-dump-script
path: ${{ env.DUMP_SCRIPT_NAME }}.gz
@@ -145,7 +147,7 @@ jobs:
- esr-upgrade-script
steps:
- name: Retrieve dumps
uses: actions/download-artifact@v4
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
- name: Diff dumps
run: |
gzip -d upgraded-dump-server/${DUMP_SERVER_NAME}.gz
@@ -153,7 +155,7 @@ jobs:
diff upgraded-dump-server/$DUMP_SERVER_NAME upgraded-dump-script/$DUMP_SCRIPT_NAME > $DIFF_NAME
- name: Upload diff
if: failure() # Upload the diff only if the previous step failed; i.e., if the diff is non-empty
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
with:
name: dumps-diff
path: ${{ env.DIFF_NAME }}

2
.github/workflows/i18n-ci-template.yml поставляемый
Просмотреть файл

@@ -15,7 +15,7 @@ jobs:
- name: Get changed files
id: changed-files
uses: tj-actions/changed-files@dcc7a0cba800f454d79fff4b993e8c3555bcc0a8 # v45.0.7
uses: tj-actions/changed-files@480f49412651059a414a6a5c96887abb1877de8a # v45.0.7
with:
files: |
server/i18n/*.json

2
.github/workflows/migration.yml поставляемый
Просмотреть файл

@@ -66,7 +66,7 @@ jobs:
$TEST_IMAGE \
make test-migration
- name: Upload artifacts
uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
with:
name: Migration logs
path: server/migration.log

11
.github/workflows/mmctl-test-template.yml поставляемый
Просмотреть файл

@@ -31,9 +31,9 @@ jobs:
- name: Store required variables for publishing results
run: |
echo "${{ inputs.name }}" > server/test-name
echo "${{ github.event.pull_request.number }}" > server/pr-number
echo "${{ github.event.pull_request.number }}" > server/pr-number
- name: Setup Go
uses: actions/setup-go@41dfa10bad2bb2ae585af6ee5bb4d7d973ad74ed # v5.1.0
uses: actions/setup-go@f111f3307d8850f501ac008e886eec1fd1932a34 # v5.3.0
with:
go-version: ${{ steps.go.outputs.GO_VERSION }}
cache-dependency-path: server/go.sum
@@ -49,12 +49,14 @@ jobs:
run: |
cd server/build
docker compose --ansi never run --rm start_dependencies
cat ../tests/custom-schema-objectID.ldif | docker compose --ansi never exec -T openldap bash -c 'ldapadd -Y EXTERNAL -H ldapi:/// -w mostest || true';
cat ../tests/custom-schema-cpa.ldif | docker compose --ansi never exec -T openldap bash -c 'ldapadd -Y EXTERNAL -H ldapi:/// -w mostest || true';
cat ../tests/test-data.ldif | docker compose --ansi never exec -T openldap bash -c 'ldapadd -x -D "cn=admin,dc=mm,dc=test,dc=com" -w mostest';
docker compose --ansi never exec -T minio sh -c 'mkdir -p /data/mattermost-test';
docker compose --ansi never ps
- name: Run mmctl Tests
env:
BUILD_IMAGE: mattermostdevelopment/mattermost-build-server:${{ steps.go.outputs.GO_VERSION }}
BUILD_IMAGE: mattermost/mattermost-build-server:${{ steps.go.outputs.GO_VERSION }}
run: |
if [[ ${{ github.ref_name }} == 'master' ]]; then
export TESTFLAGS="-timeout 90m -race"
@@ -64,6 +66,7 @@ jobs:
docker run --net ghactions_mm-test \
--ulimit nofile=8096:8096 \
--env-file=server/build/dotenv/test.env \
--env TEST_DATABASE_POSTGRESQL_DSN="${{ inputs.datasource }}" \
--env MM_SQLSETTINGS_DATASOURCE="${{ inputs.datasource }}" \
--env MMCTL_TESTFLAGS="$TESTFLAGS" \
-v $(go env GOCACHE):/go/cache \
@@ -78,7 +81,7 @@ jobs:
docker compose --ansi never stop
- name: Archive logs
if: ${{ always() }}
uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
with:
name: ${{ inputs.logsartifact }}
path: |

6
.github/workflows/scorecards-analysis.yml поставляемый
Просмотреть файл

@@ -26,7 +26,7 @@ jobs:
persist-credentials: false
- name: "Run analysis"
uses: ossf/scorecard-action@62b2cac7ed8198b15735ed49ab1e5cf35480ba46 # v2.4.0
uses: ossf/scorecard-action@f49aabe0b5af0936a0987cfb85d86b75731b0186 # v2.4.1
with:
results_file: results.sarif
results_format: sarif
@@ -48,7 +48,7 @@ jobs:
# Upload the results as artifacts (optional). Commenting out will disable uploads of run results in SARIF
# format to the repository Actions tab.
- name: "Upload artifact"
uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
with:
name: SARIF file
path: results.sarif
@@ -56,6 +56,6 @@ jobs:
# Upload the results to GitHub's code scanning dashboard.
- name: "Upload to code-scanning"
uses: github/codeql-action/upload-sarif@0a35e8f6866a39b001e5f7ad1d0daf9836786896 # v2.27.0
uses: github/codeql-action/upload-sarif@ff0a06e83cb2de871e5a09832bc6a81e7276941f # v2.27.0
with:
sarif_file: results.sarif

2
.github/workflows/sentry.yaml поставляемый
Просмотреть файл

@@ -20,5 +20,5 @@ jobs:
- name: cd/Checkout mattermost project
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: cd/Create Sentry release
uses: getsentry/action-release@12bba0bd9c0f65f9f80d4965db646a1aed373d36 # v1.10.3
uses: getsentry/action-release@00ed2a6cc2171514e031a0f5b4b3cdc586dc171a # v3.1.1

18
.github/workflows/server-ci-artifacts.yml поставляемый
Просмотреть файл

@@ -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@fec7b836001c9380d4bfaf28d443945c103a098c
- uses: mattermost/actions/delivery/update-commit-status@d5174b860704729f4c14ef8489ae075742bfa08a
env:
GITHUB_TOKEN: ${{ github.token }}
with:
@@ -33,14 +33,14 @@ jobs:
- update-initial-status
steps:
- name: cd/configure-aws-credentials
uses: aws-actions/configure-aws-credentials@4fc4975a852c8cd99761e2de1f4ba73402e44dd9 # v4.0.3
uses: aws-actions/configure-aws-credentials@b47578312673ae6fa5b5096b330d9fbac3d116df # v4.2.1
with:
aws-region: us-east-1
aws-access-key-id: ${{ secrets.PR_BUILDS_BUCKET_AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.PR_BUILDS_BUCKET_AWS_SECRET_ACCESS_KEY }}
- name: cd/download-artifacts-from-PR-workflow
uses: actions/download-artifact@fa0a91b85d4f404e444e00e005971372dc801d16 # v4.1.8
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
with:
run-id: ${{ github.event.workflow_run.id }}
github-token: ${{ github.token }}
@@ -77,18 +77,18 @@ jobs:
TAG: ${{ steps.set_tag.outputs.TAG }}
steps:
- name: cd/docker-login
uses: docker/login-action@9780b0c442fbb1117ed29e0efdff1e18412f7567 # v3.3.0
uses: docker/login-action@74a5d142397b4f367a81961eba4e8cd7edddf772 # v3.4.0
with:
username: mattermostdev
password: ${{ secrets.DOCKERHUB_DEV_TOKEN }}
- name: cd/setup-cosign
uses: sigstore/cosign-installer@c56c2d3e59e4281cc41dea2217323ba5694b171e # v3.8.0
uses: sigstore/cosign-installer@3454372f43399081ed03b604cb2d021dabca52bb # v3.8.2
with:
cosign-release: v${{ env.COSIGN_VERSION }}
- name: cd/download-artifacts-from-PR-workflow
uses: actions/download-artifact@fa0a91b85d4f404e444e00e005971372dc801d16 # v4.1.8
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
with:
run-id: ${{ github.event.workflow_run.id }}
github-token: ${{ github.token }}
@@ -96,7 +96,7 @@ jobs:
path: server/build/
- name: cd/setup-docker-buildx
uses: docker/setup-buildx-action@f7ce87c1d6bead3e36075b2ce75da1f6cc28aaca # v3.9.0
uses: docker/setup-buildx-action@b5ca514318bd6ebac0fb2aedd5d36ec1b5c232a2 # v3.10.0
- name: cd/set-docker-tag
id: set_tag
@@ -155,7 +155,7 @@ jobs:
needs:
- build-docker
steps:
- uses: mattermost/actions/delivery/update-commit-status@fec7b836001c9380d4bfaf28d443945c103a098c
- uses: mattermost/actions/delivery/update-commit-status@d5174b860704729f4c14ef8489ae075742bfa08a
env:
GITHUB_TOKEN: ${{ github.token }}
with:
@@ -171,7 +171,7 @@ jobs:
needs:
- build-docker
steps:
- uses: mattermost/actions/delivery/update-commit-status@fec7b836001c9380d4bfaf28d443945c103a098c
- uses: mattermost/actions/delivery/update-commit-status@d5174b860704729f4c14ef8489ae075742bfa08a
env:
GITHUB_TOKEN: ${{ github.token }}
with:

66
.github/workflows/server-ci-report.yml поставляемый
Просмотреть файл

@@ -15,21 +15,44 @@ jobs:
REPORT_MATRIX: ${{ steps.report.outputs.REPORT_MATRIX }}
steps:
- name: report/download-artifacts-from-PR-workflow
uses: actions/download-artifact@fa0a91b85d4f404e444e00e005971372dc801d16 # v4.1.8
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
with:
run-id: ${{ github.event.workflow_run.id }}
github-token: ${{ github.token }}
pattern: "*-test-logs"
path: reports
- name: report/validate-and-prepare-data
id: validate
run: |
# Create validated data file
> /tmp/validated-tests.json
find "reports" -type f -name "test-name" | while read -r test_file; do
folder=$(basename "$(dirname "$test_file")")
test_name_raw=$(cat "$test_file" | tr -d '\n\r')
# Validate test name: allow alphanumeric, spaces, hyphens, underscores, parentheses, and dots
if [[ "$test_name_raw" =~ ^[a-zA-Z0-9\ \(\)_.-]+$ ]] && [[ ${#test_name_raw} -le 100 ]]; then
# Use jq to safely escape the test name as JSON
test_name_escaped=$(echo -n "$test_name_raw" | jq -R .)
echo "{\"artifact\": \"$folder\", \"name\": $test_name_escaped}" >> /tmp/validated-tests.json
else
echo "Warning: Skipping invalid test name in $test_file: '$test_name_raw'" >&2
fi
done
# Verify we have at least some valid tests
if [[ ! -s /tmp/validated-tests.json ]]; then
echo "Error: No valid test names found" >&2
exit 1
fi
- name: report/generate-report-matrix
id: report
run: |
find "reports" -type f -name "test-name" | while read -r test_file; do
folder=$(basename "$(dirname "$test_file")")
test_name=$(cat "$test_file")
echo "{\"artifact\": \"$folder\", \"name\": \"$test_name\"}"
done | jq -s '{ "test": . }' | tee /tmp/report-matrix
# Convert validated JSON objects to matrix format
jq -s '{ "test": . }' /tmp/validated-tests.json | tee /tmp/report-matrix
echo REPORT_MATRIX=$(cat /tmp/report-matrix | jq --compact-output --monochrome-output) >> ${GITHUB_OUTPUT}
publish-report:
@@ -45,7 +68,7 @@ jobs:
matrix: ${{ fromJson(needs.generate-report-matrix.outputs.REPORT_MATRIX) }}
steps:
- name: report/download-artifacts-from-PR-workflow
uses: actions/download-artifact@fa0a91b85d4f404e444e00e005971372dc801d16 # v4.1.8
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
with:
run-id: ${{ github.event.workflow_run.id }}
github-token: ${{ github.token }}
@@ -54,10 +77,24 @@ jobs:
- name: report/fetch-pr-number
if: github.event.workflow_run.name == 'Server CI PR'
id: incoming-pr
run: echo "NUMBER=$(cat ${{ matrix.test.artifact }}/pr-number)" >> ${GITHUB_OUTPUT}
env:
ARTIFACT: "${{ matrix.test.artifact }}"
run: |
if [[ -f "$ARTIFACT/pr-number" ]]; then
pr_number=$(cat "$ARTIFACT/pr-number" | tr -d '\n\r' | grep -E '^[0-9]+$')
if [[ -n "$pr_number" ]] && [[ ${#pr_number} -le 10 ]]; then
echo "NUMBER=$pr_number" >> ${GITHUB_OUTPUT}
else
echo "Invalid PR number format" >&2
exit 1
fi
else
echo "PR number file not found" >&2
exit 1
fi
- name: Publish test report
id: report
uses: mikepenz/action-junit-report@ee6b445351cd81e2f73a16a0e52d598aeac2197f # v5.3.0
uses: mikepenz/action-junit-report@cf701569b05ccdd861a76b8607a66d76f6fd4857 # v5.5.1
with:
report_paths: ${{ matrix.test.artifact }}/report.xml
check_name: ${{ matrix.test.name }} (Results)
@@ -69,17 +106,6 @@ jobs:
include_passed: true
check_annotations: true
- name: Report retried tests via webhook (master)
if: ${{ steps.report.outputs.flaky_summary != '<table><tr><th>Test</th><th>Retries</th></tr></table>' && github.event.workflow_run.name == 'Server CI Master' && github.event.workflow_run.head_branch == 'master' }}
uses: mattermost/action-mattermost-notify@b7d118e440bf2749cd18a4a8c88e7092e696257a # v2.0.0
with:
MATTERMOST_WEBHOOK_URL: ${{ secrets.MM_COMMUNITY_DEVELOPERS_INCOMING_WEBHOOK_FROM_GH_ACTIONS }}
TEXT: |-
#### ⚠️ One or more flaky tests detected ⚠️
* Failing job: [github.com/mattermost/mattermost:${{ matrix.test.name }}](${{ github.event.workflow_run.html_url }})
* Ideally, this would have been caught in a pull request, but now a volunteer is required. If you're willing to help, submit a separate pull request to skip the flaky tests (e.g. [23360](https://github.com/mattermost/mattermost/pull/23360)) and file JIRA ticket (e.g. [MM-52743](https://mattermost.atlassian.net/browse/MM-52743)) for later investigation.
* Finally, reply to this message with a link to the created JIRA ticket.
- name: Report retried tests (pull request)
uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1
if: ${{ steps.report.outputs.flaky_summary != '<table><tr><th>Test</th><th>Retries</th></tr></table>' && github.event.workflow_run.name == 'Server CI PR' }}

64
.github/workflows/server-ci-template.yml поставляемый
Просмотреть файл

@@ -19,7 +19,7 @@ jobs:
id: go
run: echo GO_VERSION=$(cat .go-version) >> "${GITHUB_OUTPUT}"
- name: Setup Go
uses: actions/setup-go@41dfa10bad2bb2ae585af6ee5bb4d7d973ad74ed # v5.1.0
uses: actions/setup-go@f111f3307d8850f501ac008e886eec1fd1932a34 # v5.3.0
with:
go-version: ${{ steps.go.outputs.GO_VERSION }}
cache-dependency-path: |
@@ -44,7 +44,7 @@ jobs:
id: go
run: echo GO_VERSION=$(cat .go-version) >> "${GITHUB_OUTPUT}"
- name: Setup Go
uses: actions/setup-go@41dfa10bad2bb2ae585af6ee5bb4d7d973ad74ed # v5.1.0
uses: actions/setup-go@f111f3307d8850f501ac008e886eec1fd1932a34 # v5.3.0
with:
go-version: ${{ steps.go.outputs.GO_VERSION }}
cache-dependency-path: |
@@ -69,7 +69,7 @@ jobs:
id: go
run: echo GO_VERSION=$(cat .go-version) >> "${GITHUB_OUTPUT}"
- name: Setup Go
uses: actions/setup-go@41dfa10bad2bb2ae585af6ee5bb4d7d973ad74ed # v5.1.0
uses: actions/setup-go@f111f3307d8850f501ac008e886eec1fd1932a34 # v5.3.0
with:
go-version: ${{ steps.go.outputs.GO_VERSION }}
cache-dependency-path: |
@@ -92,7 +92,7 @@ jobs:
id: go
run: echo GO_VERSION=$(cat .go-version) >> "${GITHUB_OUTPUT}"
- name: Setup Go
uses: actions/setup-go@41dfa10bad2bb2ae585af6ee5bb4d7d973ad74ed # v5.1.0
uses: actions/setup-go@f111f3307d8850f501ac008e886eec1fd1932a34 # v5.3.0
with:
go-version: ${{ steps.go.outputs.GO_VERSION }}
cache-dependency-path: |
@@ -117,7 +117,7 @@ jobs:
id: go
run: echo GO_VERSION=$(cat .go-version) >> "${GITHUB_OUTPUT}"
- name: Setup Go
uses: actions/setup-go@41dfa10bad2bb2ae585af6ee5bb4d7d973ad74ed # v5.1.0
uses: actions/setup-go@f111f3307d8850f501ac008e886eec1fd1932a34 # v5.3.0
with:
go-version: ${{ steps.go.outputs.GO_VERSION }}
cache-dependency-path: |
@@ -130,7 +130,7 @@ jobs:
- name: Run plugin-checker
run: make plugin-checker
- name: Run mattermost-vet
run: make vet BUILD_NUMBER='${GITHUB_HEAD_REF}' MM_NO_ENTERPRISE_LINT=true
run: make vet BUILD_NUMBER='${GITHUB_HEAD_REF}'
check-mattermost-vet-api:
name: Vet API
runs-on: ubuntu-22.04
@@ -144,7 +144,7 @@ jobs:
id: go
run: echo GO_VERSION=$(cat .go-version) >> "${GITHUB_OUTPUT}"
- name: Setup Go
uses: actions/setup-go@41dfa10bad2bb2ae585af6ee5bb4d7d973ad74ed # v5.1.0
uses: actions/setup-go@f111f3307d8850f501ac008e886eec1fd1932a34 # v5.3.0
with:
go-version: ${{ steps.go.outputs.GO_VERSION }}
cache-dependency-path: |
@@ -195,7 +195,7 @@ jobs:
id: go
run: echo GO_VERSION=$(cat .go-version) >> "${GITHUB_OUTPUT}"
- name: Setup Go
uses: actions/setup-go@41dfa10bad2bb2ae585af6ee5bb4d7d973ad74ed # v5.1.0
uses: actions/setup-go@f111f3307d8850f501ac008e886eec1fd1932a34 # v5.3.0
with:
go-version: ${{ steps.go.outputs.GO_VERSION }}
cache-dependency-path: |
@@ -220,7 +220,7 @@ jobs:
id: go
run: echo GO_VERSION=$(cat .go-version) >> "${GITHUB_OUTPUT}"
- name: Setup Go
uses: actions/setup-go@41dfa10bad2bb2ae585af6ee5bb4d7d973ad74ed # v5.1.0
uses: actions/setup-go@f111f3307d8850f501ac008e886eec1fd1932a34 # v5.3.0
with:
go-version: ${{ steps.go.outputs.GO_VERSION }}
cache-dependency-path: |
@@ -264,6 +264,44 @@ jobs:
datasource: mmuser:mostest@tcp(mysql:3306)/mattermost_test?charset=utf8mb4&multiStatements=true&maxAllowedPacket=4194304
drivername: mysql
logsartifact: mysql-server-test-logs
test-elasticsearch-v8:
name: Elasticsearch v8 Compatibility
needs: check-mattermost-vet
uses: ./.github/workflows/server-test-template.yml
secrets: inherit
with:
name: Elasticsearch v8 Compatibility
datasource: postgres://mmuser:mostest@postgres:5432/mattermost_test?sslmode=disable&connect_timeout=10
drivername: postgres
logsartifact: elasticsearch-v8-server-test-logs
elasticsearch-version: "8.9.0"
test-target: "test-server-elasticsearch"
test-elasticsearch-v7:
name: Elasticsearch v7 Compatibility
needs: check-mattermost-vet
uses: ./.github/workflows/server-test-template.yml
secrets: inherit
with:
name: Elasticsearch v7 Compatibility
datasource: postgres://mmuser:mostest@postgres:5432/mattermost_test?sslmode=disable&connect_timeout=10
drivername: postgres
logsartifact: elasticsearch-v7-server-test-logs
elasticsearch-version: "7.17.29"
test-target: "test-server-elasticsearch"
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-') }}
name: Generate Test Coverage
needs: check-mattermost-vet
uses: ./.github/workflows/server-test-template.yml
secrets: inherit
with:
name: Generate Test Coverage
datasource: postgres://mmuser:mostest@postgres:5432/mattermost_test?sslmode=disable&connect_timeout=10
drivername: postgres
logsartifact: coverage-server-test-logs
fullyparallel: true
enablecoverage: true
test-mmctl:
name: Run mmctl tests
needs: check-mattermost-vet
@@ -288,14 +326,14 @@ jobs:
id: go
run: echo GO_VERSION=$(cat .go-version) >> "${GITHUB_OUTPUT}"
- name: Setup Go
uses: actions/setup-go@41dfa10bad2bb2ae585af6ee5bb4d7d973ad74ed # v5.1.0
uses: actions/setup-go@f111f3307d8850f501ac008e886eec1fd1932a34 # v5.3.0
with:
go-version: ${{ steps.go.outputs.GO_VERSION }}
cache-dependency-path: |
server/go.sum
server/public/go.sum
- name: ci/setup-node
uses: actions/setup-node@1d0ff469b7ec7b3cb9d8673fde0c81c44821de2a # v4.2.0
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
id: setup_node
with:
node-version-file: ".nvmrc"
@@ -309,7 +347,7 @@ jobs:
make build-cmd BUILD_NUMBER='${GITHUB_HEAD_REF}-${GITHUB_RUN_ID}'
make package BUILD_NUMBER='${GITHUB_HEAD_REF}-${GITHUB_RUN_ID}'
- name: Persist dist artifacts
uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
with:
name: server-dist-artifact
path: server/dist/
@@ -317,7 +355,7 @@ jobs:
compression-level: 0
retention-days: 2
- name: Persist build artifacts
uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
with:
name: server-build-artifact
path: server/build/

150
.github/workflows/server-test-template.yml поставляемый
Просмотреть файл

@@ -14,22 +14,67 @@ on:
logsartifact:
required: true
type: string
fullyparallel:
required: false
type: boolean
default: false
enablecoverage:
required: false
type: boolean
default: false
elasticsearch-version:
required: false
type: string
default: "9.0.0"
test-target:
required: false
type: string
default: "test-server"
# -- Test sharding inputs (leave defaults for non-sharded callers) --
shard-index:
required: false
type: number
default: -1 # -1 = no sharding; run all tests
shard-total:
required: false
type: number
default: 1
permissions:
id-token: write
contents: read
jobs:
test:
name: ${{ inputs.name }}
runs-on: ubuntu-22.04
runs-on: ubuntu-latest-8-cores
continue-on-error: ${{ inputs.fullyparallel }} # Used to avoid blocking PRs in case of flakiness
env:
COMPOSE_PROJECT_NAME: ghactions
steps:
- name: Checkout mattermost project
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Restore test timing data
if: inputs.shard-total > 1
id: timing-cache
uses: actions/cache/restore@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3
with:
path: |
server/prev-report.xml
server/prev-gotestsum.json
# Always restore from master — timing is only saved on the default
# branch and is stable enough for shard balancing.
key: server-test-timing-master
restore-keys: |
server-test-timing-
- name: Calculate Golang Version
id: go
working-directory: ./server
run: echo GO_VERSION=$(cat .go-version) >> "${GITHUB_OUTPUT}"
- name: Setup Go
uses: actions/setup-go@41dfa10bad2bb2ae585af6ee5bb4d7d973ad74ed # v5.1.0
uses: actions/setup-go@f111f3307d8850f501ac008e886eec1fd1932a34 # v5.3.0
with:
go-version: ${{ steps.go.outputs.GO_VERSION }}
cache-dependency-path: server/go.sum
@@ -38,19 +83,93 @@ jobs:
echo "${{ inputs.name }}" > server/test-name
echo "${{ github.event.pull_request.number }}" > server/pr-number
- name: Run docker compose
env:
ELASTICSEARCH_VERSION: ${{ inputs.elasticsearch-version }}
run: |
cd server/build
docker compose --ansi never run --rm start_dependencies
cat ../tests/custom-schema-objectID.ldif | docker compose --ansi never exec -T openldap bash -c 'ldapadd -Y EXTERNAL -H ldapi:/// -w mostest || true';
cat ../tests/custom-schema-cpa.ldif | docker compose --ansi never exec -T openldap bash -c 'ldapadd -Y EXTERNAL -H ldapi:/// -w mostest || true';
cat ../tests/test-data.ldif | docker compose --ansi never exec -T openldap bash -c 'ldapadd -x -D "cn=admin,dc=mm,dc=test,dc=com" -w mostest';
docker compose --ansi never exec -T minio sh -c 'mkdir -p /data/mattermost-test';
docker compose --ansi never ps
# ── Test-level sharding ────────────────────────────────────────────
# When shard-total > 1, we split tests across N parallel runners.
#
# Two-tier splitting strategy:
# - "Light" packages (< 5 min): assigned whole to a shard
# - "Heavy" packages (≥ 5 min, e.g. api4, app): individual tests
# are distributed across shards using -run regex filters
#
# See server/scripts/shard-split.js for the full algorithm.
# ─────────────────────────────────────────────────────────────────────
- name: Setup Go for test discovery
if: inputs.shard-total > 1
uses: actions/setup-go@4b73464bb391d4059bd26b0524d20df3927bd417 # v6.3.0
with:
go-version: ${{ steps.go.outputs.GO_VERSION }}
- name: Split tests across shards
if: inputs.shard-total > 1
id: test_split
working-directory: server
env:
SHARD_INDEX: ${{ inputs.shard-index }}
SHARD_TOTAL: ${{ inputs.shard-total }}
run: |
set -euo pipefail
# ── List all test packages ──
echo "::group::Listing test packages"
TE_PKGS=$(find ./public/ ./ -name '*_test.go' -not -path './enterprise/*' -not -path './cmd/mmctl/*' 2>/dev/null \
| sed 's|/[^/]*$||' | sort -u \
| sed 's|^\./|github.com/mattermost/mattermost/server/v8/|' \
| sed 's|github.com/mattermost/mattermost/server/v8/public/|github.com/mattermost/mattermost/server/public/|')
EE_PKGS=$(find ./enterprise/ -name '*_test.go' 2>/dev/null \
| sed 's|/[^/]*$||' | sort -u \
| sed 's|^\./|github.com/mattermost/mattermost/server/v8/|')
ALL_PKGS=$(printf '%s\n%s' "$TE_PKGS" "$EE_PKGS" | grep -v '^$' | sort -u)
TOTAL_PKGS=$(echo "$ALL_PKGS" | wc -l)
echo "Found $TOTAL_PKGS test packages"
echo "::endgroup::"
if [[ "$TOTAL_PKGS" -eq 0 ]]; then
echo "WARNING: No test packages found"
echo "has_packages=false" >> "$GITHUB_OUTPUT"
exit 0
fi
echo "$ALL_PKGS" > all-packages.txt
# ── Run shard solver ──
node scripts/shard-split.js
echo "has_packages=true" >> "$GITHUB_OUTPUT"
- name: Run Tests
env:
BUILD_IMAGE: mattermostdevelopment/mattermost-build-server:${{ steps.go.outputs.GO_VERSION }}
BUILD_IMAGE: mattermost/mattermost-build-server:${{ steps.go.outputs.GO_VERSION }}
run: |
if [[ ${{ github.ref_name }} == 'master' ]]; then
if [[ ${{ github.ref_name }} == 'master' && ${{ inputs.fullyparallel }} != true && "${{ inputs.test-target }}" == "test-server" ]]; then
export RACE_MODE="-race"
fi
TEST_TARGET="${{ inputs.test-target }}${RACE_MODE}"
BUILD_NUMBER="${GITHUB_HEAD_REF}-${GITHUB_RUN_ID}"
DOCKER_CMD="make ${TEST_TARGET}"
# When sharding is active, use the multi-run wrapper script.
# run-shard-tests.sh detects heavy runs itself and falls back to
# light-only mode when shard-heavy-runs.txt is absent or empty.
if [[ "${{ inputs.shard-total }}" -gt 1 && -f server/shard-te-packages.txt ]]; then
cp server/scripts/run-shard-tests.sh server/run-shard-tests.sh
chmod +x server/run-shard-tests.sh
DOCKER_CMD="/mattermost/server/run-shard-tests.sh"
fi
docker run --net ghactions_mm-test \
--ulimit nofile=8096:8096 \
--env-file=server/build/dotenv/test.env \
@@ -58,23 +177,40 @@ jobs:
--env MM_SQLSETTINGS_DATASOURCE="${{ inputs.datasource }}" \
--env TEST_DATABASE_MYSQL_DSN="${{ inputs.datasource }}" \
--env TEST_DATABASE_POSTGRESQL_DSN="${{ inputs.datasource }}" \
--env ENABLE_FULLY_PARALLEL_TESTS="${{ inputs.fullyparallel }}" \
--env ENABLE_COVERAGE="${{ inputs.enablecoverage }}" \
-v $(go env GOCACHE):/go/cache \
-e GOCACHE=/go/cache \
--env RACE_MODE \
--env TEST_TARGET \
--env BUILD_NUMBER \
-v $PWD:/mattermost \
-w /mattermost/server \
$BUILD_IMAGE \
make test-server$RACE_MODE BUILD_NUMBER=$GITHUB_HEAD_REF-$GITHUB_RUN_ID
$DOCKER_CMD
- name: Upload coverage to Codecov
if: ${{ inputs.enablecoverage }}
uses: codecov/codecov-action@v5
with:
token: ${{ secrets.CODECOV_TOKEN }}
disable_search: true
files: server/cover.out
- name: Stop docker compose
if: ${{ always() }}
run: |
cd server/build
docker compose --ansi never logs --no-color > ../../docker-compose.log 2>&1
docker compose --ansi never stop
- name: Archive logs
if: ${{ always() }}
uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
with:
name: ${{ inputs.logsartifact }}
path: |
server/gotestsum.json
server/report.xml
server/cover.out
server/test-name
server/pr-number
server/pr-number
docker-compose.log

11
.github/workflows/snyk-sbom.yml поставляемый
Просмотреть файл

@@ -1,11 +0,0 @@
name: Snyk - Software Bill of Materials (SBOM)
on:
release:
types: [published]
jobs:
sbom:
permissions:
contents: write
uses: mattermost/actions-workflows/.github/workflows/snyk-sbom.yml@9f3b82abb56fb8327b6b6e2d3fc16b92e45120ba
secrets: inherit

2
.github/workflows/tag-public-module.yaml поставляемый
Просмотреть файл

@@ -51,7 +51,7 @@ jobs:
level: ${{ inputs.semver_bump }}
- name: release/create-annotated-tag
uses: mattermost/actions/delivery/create-tag@93502485eec8db2fd67b54c71a02462e06d0fa46
uses: mattermost/actions/delivery/create-tag@d5174b860704729f4c14ef8489ae075742bfa08a
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:

2
.github/workflows/webapp-ci-master.yml поставляемый
Просмотреть файл

@@ -8,3 +8,5 @@ on:
jobs:
master-ci:
uses: ./.github/workflows/webapp-ci-template.yml
secrets:
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}

2
.github/workflows/webapp-ci-pr.yml поставляемый
Просмотреть файл

@@ -18,3 +18,5 @@ concurrency:
jobs:
pr-ci:
uses: ./.github/workflows/webapp-ci-template.yml
secrets:
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}

11
.github/workflows/webapp-ci-template.yml поставляемый
Просмотреть файл

@@ -4,6 +4,9 @@
name: Web App CI Template
on:
workflow_call:
secrets:
CODECOV_TOKEN:
required: true
jobs:
check-lint:
@@ -75,6 +78,14 @@ jobs:
NODE_OPTIONS: --max_old_space_size=5120
run: |
npm run test-ci
- name: Upload coverage to Codecov
# Skip coverage upload for cherry-pick PRs into release branches.
if: ${{ github.event_name != 'pull_request' || !startsWith(github.event.pull_request.base.ref, 'release-') }}
uses: codecov/codecov-action@v5
with:
token: ${{ secrets.CODECOV_TOKEN }}
disable_search: true
files: ./webapp/channels/coverage/lcov.info
build:
runs-on: ubuntu-22.04

13
.gitignore поставляемый
Просмотреть файл

@@ -40,9 +40,9 @@ e2e-tests/playwright/playwright-report
e2e-tests/playwright/storage_state
e2e-tests/playwright/test-results
e2e-tests/playwright/results
e2e-tests/playwright/tests/**/*-darwin.png
e2e-tests/playwright/tests/**/*-window.png
e2e-tests/playwright/tests/accessibility/**/*-snapshots
e2e-tests/playwright/specs/**/*-darwin.png
e2e-tests/playwright/specs/**/*-window.png
e2e-tests/playwright/specs/accessibility/**/*-snapshots
e2e-tests/playwright/.eslintcache
# ignore temporary added configuration for pgloader
@@ -159,3 +159,10 @@ docker-compose.override.yaml
.notice-work/
.aider*
.env
**/CLAUDE.local.md
CLAUDE.md
.cursorrules
server/prev-report.xml
server/prev-gotestsum.json
server/shard-*.txt

127
.gitlab-ci.yml Обычный файл
Просмотреть файл

@@ -0,0 +1,127 @@
---
image: debian:bookworm
stages:
- build
- publish
variables:
DEBIAN_FRONTEND: noninteractive
PATH: /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/local/go/bin:/usr/local/go/bin
GO_VERSION: 1.25.8
GO_HASHSUM: ceb5e041bbc3893846bd1614d76cb4681c91dadee579426cf21a63f2d7e03be6
build:
stage: build
before_script:
- mkdir artifacts
- apt update
- apt install -qq -y build-essential libpng-dev libpng16-16 wget curl git
- ulimit -n 8096
- cd /tmp
- wget -q "https://go.dev/dl/go${GO_VERSION}.linux-amd64.tar.gz"
- >
echo \
"${GO_HASHSUM} go${GO_VERSION}.linux-amd64.tar.gz" \
> "go${GO_VERSION}.linux-amd64.tar.gz.sha256sum"
- sha256sum -c "go${GO_VERSION}.linux-amd64.tar.gz.sha256sum"
- tar -C /usr/local -xzf "go${GO_VERSION}.linux-amd64.tar.gz"
- cd -
script:
- >
sed -e "s/^\(BUILD_NUMBER\) ?= .*/\1 = $CI_JOB_ID/" \
-e "s/^\(BUILD_HASH = \).*/\1$(git rev-parse HEAD)/" \
-i server/Makefile
- git apply limitless.patch
- cd server
- make validate-go-version
- make setup-go-work
- make build-linux-arm64
- make build-linux-amd64
- cd -
- >
mv server/bin/mostlymatter \
"mostlymatter-amd64-$(basename "$CI_COMMIT_TAG" -limitless)"
- >
mv server/bin/linux_arm64/mostlymatter \
"mostlymatter-arm64-$(basename "$CI_COMMIT_TAG" -limitless)"
cache:
key: "$CI_COMMIT_TAG"
policy: push
paths:
- "mostlymatter-*"
rules:
- if: '$CI_COMMIT_TAG =~ /limitless/'
# Release
publish:
stage: publish
image: framasoft/upload-packages:latest
needs:
- build
before_script:
- mkdir -p ~/.minisign
- chmod 700 ~/.minisign
- >
echo 'untrusted comment: minisign encrypted secret key' \
> ~/.minisign/minisign.key
- echo "$MINISIG_KEY" >> ~/.minisign/minisign.key
- chmod 600 ~/.minisign/minisign.key
- >
echo "$MINISIG_PWD" |
minisign -Sm "mostlymatter-amd64-$(basename "$CI_COMMIT_TAG" -limitless)"
- >
sha512sum "mostlymatter-amd64-$(basename "$CI_COMMIT_TAG" -limitless)" \
> "mostlymatter-amd64-$(basename "$CI_COMMIT_TAG" -limitless).sha512"
- >
echo "$MINISIG_PWD" |
minisign -Sm "mostlymatter-arm64-$(basename "$CI_COMMIT_TAG" -limitless)"
- >
sha512sum "mostlymatter-arm64-$(basename "$CI_COMMIT_TAG" -limitless)" \
> "mostlymatter-arm64-$(basename "$CI_COMMIT_TAG" -limitless).sha512"
script:
- eval $(ssh-agent -s)
- ssh-add <(echo "${DEPLOYEMENT_KEY}" | base64 --decode -i)
- >
echo "put mostlymatter-amd64-$(basename "$CI_COMMIT_TAG" -limitless)" |
sftp -o "VerifyHostKeyDNS yes" \
-o "StrictHostKeyChecking accept-new" \
${DEPLOYEMENT_USER}@${DEPLOYEMENT_HOST}:public/
- >
echo "put mostlymatter-amd64-$(basename "$CI_COMMIT_TAG" -limitless).minisig" |
sftp -o "VerifyHostKeyDNS yes" \
-o "StrictHostKeyChecking accept-new" \
${DEPLOYEMENT_USER}@${DEPLOYEMENT_HOST}:public/
- >
echo "put mostlymatter-amd64-$(basename "$CI_COMMIT_TAG" -limitless).sha512" |
sftp -o "VerifyHostKeyDNS yes" \
-o "StrictHostKeyChecking accept-new" \
${DEPLOYEMENT_USER}@${DEPLOYEMENT_HOST}:public/
- >
echo "put mostlymatter-arm64-$(basename "$CI_COMMIT_TAG" -limitless)" |
sftp -o "VerifyHostKeyDNS yes" \
-o "StrictHostKeyChecking accept-new" \
${DEPLOYEMENT_USER}@${DEPLOYEMENT_HOST}:public/
- >
echo "put mostlymatter-arm64-$(basename "$CI_COMMIT_TAG" -limitless).minisig" |
sftp -o "VerifyHostKeyDNS yes" \
-o "StrictHostKeyChecking accept-new" \
${DEPLOYEMENT_USER}@${DEPLOYEMENT_HOST}:public/
- >
echo "put mostlymatter-arm64-$(basename "$CI_COMMIT_TAG" -limitless).sha512" |
sftp -o "VerifyHostKeyDNS yes" \
-o "StrictHostKeyChecking accept-new" \
${DEPLOYEMENT_USER}@${DEPLOYEMENT_HOST}:public/
- >
cat <<EOF
================================================================================================
== mostlymatter-$(basename "$CI_COMMIT_TAG" -limitless) published on https://packages.framasoft.org/projects/mostlymatter/ ==
================================================================================================
EOF
cache:
key: "$CI_COMMIT_TAG"
policy: pull
paths:
- "mostlymatter-amd64-$CI_COMMIT_TAG"
- "mostlymatter-arm64-$CI_COMMIT_TAG"
rules:
- if: '$DEPLOYEMENT_HOST && $DEPLOYEMENT_USER && $DEPLOYEMENT_KEY && $MINISIG_KEY && $MINISIG_PWD && $CI_COMMIT_TAG =~ /limitless/'

Просмотреть файл

@@ -2,4 +2,6 @@
Thank you for your interest in contributing! Please see the [Mattermost Contribution Guide](https://developers.mattermost.com/contribute/getting-started/) which describes the process for making code contributions across Mattermost projects and [join our "Contributors" community channel](https://community.mattermost.com/core/channels/tickets) to ask questions from community members and the Mattermost core team.
In addition, we recommend reviewing the [Contribution Guidelines](https://handbook.mattermost.com/contributors/contributors/guidelines/contribution-guidelines) in the Mattermost Handbook, which provide comprehensive best practices and expectations for contributors.
When you submit a pull request, it goes through a [code review process outlined here](https://developers.mattermost.com/contribute/getting-started/code-review/).

109
MOSTLYMATTER_HOW_TO.md Обычный файл
Просмотреть файл

@@ -0,0 +1,109 @@
# How to use Framasofts patch to compile Mostlymatter
## Setup the repository
```bash
git clone https://framagit.org/framasoft/framateam/mostlymatter.git
cd mostlymatter
git remote add upstream https://github.com/mattermost/mattermost.git
```
## New version
Refresh you local repository.
```bash
git fetch -p --all
```
Set some env vars.
```bash
export NEW_VERSION=10.5.1
```
As you will need to cherry-pick some commits (the main fork commit and a fix-patch commit), you will need to go on an old release branch.
```bash
export OLD_VERSION=10.5.0
```
```bash
export BASE_VERSION=$(echo "$NEW_VERSION" | sed -e "s/\.[^.]\+$//")
git checkout "release-$OLD_VERSION"
git log --graph --abbrev-commit --date=relative \
--pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr by %an)%Creset' \
--max-count=3
```
Note the commits youll need (usually, the two first commits).
Go to the main branch of the version you want and reset the code to this version, then create a new branch with the version you want to compile from the main branch of this version.
```bash
git branch | grep -q "release-$BASE_VERSION\$" &&
git checkout "release-$BASE_VERSION" ||
git checkout -b "release-$BASE_VERSION" "upstream/release-$BASE_VERSION"
git reset --hard "v$NEW_VERSION"
git checkout -b "release-$NEW_VERSION" "release-$BASE_VERSION"
```
Cherry-pick the commits (use the oldest first!).
```bash
for i in 4b3d29da 056a5f8c
do
git cherry-pick "$i"
done
```
If you compile a bugfix version (ex: `10.5.1`, using the commits of the `10.5.0` version), you should be just fine
But if you compile a new version (ex: `10.6.0`), there is a lot of chances that you need to fix the `limitless.patch` file.
To test the patch:
```bash
git apply limitless.patch &&
echo -e "\033[0;36mPatch applied successfully\033[0;36m" &&
rm -rf server/cmd/mostlymatter &&
git checkout -- server
```
If the patch does not apply, fix it. The fix is usually those steps:
- remove the `server/.golangci.yml` part of the patch
- manually apply this part (its mostly replacing `mattermost` by `mostlymatter` in this file)
- `git apply limitless.patch`
- `git add server`
- `git diff --cached > limitless.patch`
- `git restore --staged -- server`
- `git checkout -- server`
- `rm -rf server/cmd/mostlymatter`
- `git add limitless.patch`
- `git commit --amend`
Now, you can retest the patch:
```bash
git apply limitless.patch &&
echo -e "\033[0;36mPatch applied successfully\033[0;36m" &&
rm -rf server/cmd/mostlymatter &&
git checkout -- server
```
Tag the new version (`limitless` is needed in the tag name for the CI to run) and push to Gitlab:
```bash
git tag "v$NEW_VERSION-limitless" -m "v$NEW_VERSION-limitless"
git push -u origin "release-$NEW_VERSION"
```
The CI will compile mostlymatter. Note that it will not be available as an artifact.
You can use the step of [.gitlab-ci.yml](.gitlab-ci.yml) to compile Mostlymatter without using the CI.
## Publish
The secrets are set in GitLab CI variables :
- `MINISIG_KEY`
- `MINISIG_PWD`
- `DEPLOYEMENT_KEY` (ssh private key encoded with base64)
- `DEPLOYEMENT_USER`
- `DEPLOYEMENT_HOST`
The CI will publish the compiled mostlymatter binary through sftp.

Просмотреть файл

@@ -2971,6 +2971,64 @@ AWS SDK for the Go programming language.
limitations under the License.
---
## axios
This product contains 'axios' by Matt Zabriskie.
Promise based HTTP client for the browser and node.js
* HOMEPAGE:
* https://axios-http.com
* LICENSE: MIT
# Copyright (c) 2014-present Matt Zabriskie & Collaborators
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.
---
## bep/imagemeta
This product contains 'bep/imagemeta' by Bjørn Erik Pedersen.
Go library for reading EXIF, IPTC and XMP image meta data from JPEG, TIFF, PNG, and WebP files.
* HOMEPAGE:
* https://github.com/bep/imagemeta
* LICENSE: MIT License
MIT License
Copyright (c) 2022 Bjørn Erik Pedersen
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.
---
## blang/semver
@@ -3379,41 +3437,6 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
---
## code.sajari.com/docconv
This product contains 'code.sajari.com/docconv' by Search.io.
Converts PDF, DOC, DOCX, XML, HTML, RTF, etc to plain text
* HOMEPAGE:
* https://github.com/sajari/docconv
* LICENSE: MIT License
The MIT License (MIT)
Copyright (c) 2014 Sajari Pty Ltd
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.
---
## color-contrast-checker
@@ -3926,16 +3949,6 @@ 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.
---
## dynamic-virtualized-list
This product contains 'dynamic-virtualized-list'.
security holding package
---
## elastic/go-elasticsearch
@@ -9054,14 +9067,14 @@ SOFTWARE.
---
## mholt/archiver
## mholt/archives
This product contains 'mholt/archiver' by Matt Holt.
This product contains 'mholt/archives' by Matt Holt.
Easily create & extract archives, and compress & decompress files of various formats
Cross-platform library to create & extract archives, compress & decompress files, and walk virtual file systems across various formats
* HOMEPAGE:
* https://pkg.go.dev/github.com/mholt/archiver/v4
* https://pkg.go.dev/github.com/mholt/archives
* LICENSE: MIT License
@@ -9390,27 +9403,27 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
---
## oov/psd
## monaco-editor
This product contains 'psd' by oov.
This product contains 'monaco-editor'.
A PSD/PSB file reader for go
A browser based code editor
* HOMEPAGE:
* https://github.com/oov/psd
* https://github.com/microsoft/monaco-editor
* LICENSE: MIT
MIT License
The MIT License (MIT)
Copyright (c) 2016 oov
Copyright (c) 2016 - present Microsoft Corporation
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:
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.
@@ -9423,6 +9436,43 @@ 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.
---
## monaco-editor-webpack-plugin
This product contains 'monaco-editor-webpack-plugin' by Microsoft Corporation.
A webpack plugin for the Monaco Editor
* HOMEPAGE:
* https://github.com/microsoft/monaco-editor#readme
* LICENSE: MIT
The MIT License (MIT)
Copyright (c) 2016 - present Microsoft Corporation
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
@@ -9883,21 +9933,6 @@ 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.
---
## popper.js
This product contains 'popper.js' by Federico Zivolo.
A kickass library to manage your poppers
* HOMEPAGE:
* https://popper.js.org/
* LICENSE: MIT
---
## process
@@ -10660,42 +10695,6 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
---
## react-hot-loader
This product contains 'react-hot-loader' by Dan Abramov.
Tweak React components in real time.
* HOMEPAGE:
* https://github.com/gaearon/react-hot-loader
* LICENSE: MIT
MIT License
Copyright (c) 2016 Dan Abramov
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.
---
## react-intl
@@ -10799,42 +10798,6 @@ SOFTWARE.
---
## react-popper
This product contains 'react-popper' by Travis Arnold.
Official library to use Popper on React projects
* HOMEPAGE:
* https://popper.js.org/react-popper
* LICENSE: MIT
The MIT License (MIT)
Copyright (c) 2018 React Popper authors
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.
---
## react-redux
@@ -11604,44 +11567,6 @@ RudderStack is an open-source, warehouse-first Customer Data Pipeline and Segmen
---
## rwcarlsen/goexif
This product contains 'goexif' by Robert Carlsen.
Decode embedded EXIF meta data from image files.
* HOMEPAGE:
* https://github.com/rwcarlsen/goexif
* LICENSE: BSD-2-Clause
Copyright (c) 2012, Robert Carlsen & Contributors
All rights reserved.
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.
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 HOLDER 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.
---
## semver
@@ -12971,5 +12896,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.

Просмотреть файл

@@ -1,97 +1,33 @@
# [![Mattermost logo](https://user-images.githubusercontent.com/7205829/137170381-fe86eef0-bccc-4fdd-8e92-b258884ebdd7.png)](https://mattermost.com)
![](mostlymatter/logo_with_white_background-small.png) Mostlymatter is a fork of [Mattermost](https://mattermost.com) meant to remove the users and messages limits.
[Mattermost](https://mattermost.com) is an open source platform for secure collaboration across the entire software development lifecycle. This repo is the primary source for core development on the Mattermost platform; it's written in Go and React and runs as a single Linux binary with MySQL or PostgreSQL. A new compiled version is released under an MIT license every month on the 16th.
[Mattermost](https://mattermost.com) is an open core, self-hosted collaboration platform that offers chat, workflow automation, voice calling, screen sharing, and AI integration. This repo is the primary source for core development on the Mattermost platform; it's written in Go and React, runs as a single Linux binary, and relies on PostgreSQL. A new compiled version is released under an MIT license every month on the 16th.
[Deploy Mattermost on-premises](https://mattermost.com/deploy/?utm_source=github-mattermost-server-readme), or [try it for free in the cloud](https://mattermost.com/sign-up/?utm_source=github-mattermost-server-readme).
Please go to <https://github.com/mattermost/mattermost/> for installation instructions.
<img width="1006" alt="mattermost user interface" src="https://user-images.githubusercontent.com/7205829/136107976-7a894c9e-290a-490d-8501-e5fdbfc3785a.png">
## Differences between Mostlymatter and Mattermost
Learn more about the following use cases with Mattermost:
Our fork is limited to the backend (the binary), we dont modify the front-end and we dont provide compiled version of the other tools of Mattermost (like `mmctl`).
- [DevSecOps](https://mattermost.com/solutions/use-cases/devops/?utm_source=github-mattermost-server-readme)
- [Incident Resolution](https://mattermost.com/solutions/use-cases/incident-resolution/?utm_source=github-mattermost-server-readme)
- [IT Service Desk](https://mattermost.com/solutions/use-cases/it-service-desk/?utm_source=github-mattermost-server-readme)
We multiplied the limits in `server/channels/app/limits.go` by 1,000.
Other useful resources:
The user limits should be 5,000,000 and 11,000,000.
- [Download and Install Mattermost](https://docs.mattermost.com/guides/deployment.html) - Install, setup, and configure your own Mattermost instance.
- [Product documentation](https://docs.mattermost.com/) - Learn how to run a Mattermost instance and take advantage of all the features.
- [Developer documentation](https://developers.mattermost.com/) - Contribute code to Mattermost or build an integration via APIs, Webhooks, slash commands, Apps, and plugins.
We replaced the name `Mattermost` by `Mostlymatter` (and `mattermost` by `mostlymatter`) in the server strings (logging, help pages…) to avoid confusion between our the official build and our own but we kept the copyright comments.
Table of contents
=================
The modifications are contained in the file [`limitless.patch`](limitless.patch).
- [Install Mattermost](#install-mattermost)
- [Native mobile and desktop apps](#native-mobile-and-desktop-apps)
- [Get security bulletins](#get-security-bulletins)
- [Get involved](#get-involved)
- [Learn more](#learn-more)
- [License](#license)
- [Get the latest news](#get-the-latest-news)
- [Contributing](#contributing)
To apply our modifications and compile Mostlymatter, please have a look at [MOSTLYMATTER_HOW_TO.md](MOSTLYMATTER_HOW_TO.md).
## Install Mattermost
## Get Mostlymatter binaries
- [Download and Install Mattermost Self-Hosted](https://docs.mattermost.com/guides/deployment.html) - Deploy a Mattermost Self-hosted instance in minutes via Docker, Ubuntu, or tar.
- [Get started in the cloud](https://mattermost.com/sign-up/?utm_source=github-mattermost-server-readme) to try Mattermost today.
- [Developer machine setup](https://developers.mattermost.com/contribute/server/developer-setup) - Follow this guide if you want to write code for Mattermost.
Go to <https://packages.framasoft.org/projects/mostlymatter/> to get the binaries you want.
Other install guides:
- [Deploy Mattermost on Docker](https://docs.mattermost.com/install/install-docker.html)
- [Mattermost Omnibus](https://docs.mattermost.com/install/installing-mattermost-omnibus.html)
- [Install Mattermost from Tar](https://docs.mattermost.com/install/install-tar.html)
- [Ubuntu 20.04 LTS](https://docs.mattermost.com/install/installing-ubuntu-2004-LTS.html)
- [Kubernetes](https://docs.mattermost.com/install/install-kubernetes.html)
- [Helm](https://docs.mattermost.com/install/install-kubernetes.html#installing-the-operators-via-helm)
- [Debian Buster](https://docs.mattermost.com/install/install-debian.html)
- [RHEL 8](https://docs.mattermost.com/install/install-rhel-8.html)
- [More server install guides](https://docs.mattermost.com/guides/deployment.html)
## Native mobile and desktop apps
In addition to the web interface, you can also download Mattermost clients for [Android](https://mattermost.com/pl/android-app/), [iOS](https://mattermost.com/pl/ios-app/), [Windows PC](https://docs.mattermost.com/install/desktop-app-install.html#windows-10-windows-8-1), [macOS](https://docs.mattermost.com/install/desktop-app-install.html#macos-10-9), and [Linux](https://docs.mattermost.com/install/desktop-app-install.html#linux).
[<img src="https://user-images.githubusercontent.com/30978331/272826427-6200c98f-7319-42c3-86d4-0b33ae99e01a.png" alt="Get Mattermost on Google Play" height="50px"/>](https://mattermost.com/pl/android-app/) [<img src="https://developer.apple.com/assets/elements/badges/download-on-the-app-store.svg" alt="Get Mattermost on the App Store" height="50px"/>](https://itunes.apple.com/us/app/mattermost/id1257222717?mt=8) [![Get Mattermost on Windows PC](https://user-images.githubusercontent.com/33878967/33095357-39cab8d2-ceb8-11e7-89a6-67dccc571ca3.png)](https://docs.mattermost.com/install/desktop.html#windows-10-windows-8-1-windows-7) [![Get Mattermost on Mac OSX](https://user-images.githubusercontent.com/33878967/33095355-39a36f2a-ceb8-11e7-9b33-73d4f6d5d6c1.png)](https://docs.mattermost.com/install/desktop.html#macos-10-9) [![Get Mattermost on Linux](https://user-images.githubusercontent.com/33878967/33095354-3990e256-ceb8-11e7-965d-b00a16e578de.png)](https://docs.mattermost.com/install/desktop.html#linux)
## Get security bulletins
Receive notifications of critical security updates. The sophistication of online attackers is perpetually increasing. If you're deploying Mattermost it's highly recommended you subscribe to the Mattermost Security Bulletin mailing list for updates on critical security releases.
[Subscribe here](https://mattermost.com/security-updates/#sign-up)
## Get involved
- [Contribute to Mattermost](https://handbook.mattermost.com/contributors/contributors/ways-to-contribute)
- [Find "Help Wanted" projects](https://github.com/mattermost/mattermost-server/issues?page=1&q=is%3Aissue+is%3Aopen+%22Help+Wanted%22&utf8=%E2%9C%93)
- [Join Developer Discussion on a Mattermost server for contributors](https://community.mattermost.com/signup_user_complete/?id=f1924a8db44ff3bb41c96424cdc20676)
- [Get Help With Mattermost](https://docs.mattermost.com/guides/get-help.html)
## Learn more
- [API options - webhooks, slash commands, drivers, and web service](https://api.mattermost.com/)
- [See who's using Mattermost](https://mattermost.com/customers/)
- [Browse over 700 Mattermost integrations](https://mattermost.com/marketplace/)
Follow the instructions on top of the page to verify the binaries you downloaded.
## License
See the [LICENSE file](LICENSE.txt) for license rights and limitations.
## Get the latest news
## License of Mostlymatters logo
- **X** - Follow [Mattermost on X, formerly Twitter](https://twitter.com/mattermost).
- **Blog** - Get the latest updates from the [Mattermost blog](https://mattermost.com/blog/).
- **Facebook** - Follow [Mattermost on Facebook](https://www.facebook.com/MattermostHQ).
- **LinkedIn** - Follow [Mattermost on LinkedIn](https://www.linkedin.com/company/mattermost/).
- **Email** - Subscribe to our [newsletter](https://mattermost.us11.list-manage.com/subscribe?u=6cdba22349ae374e188e7ab8e&id=2add1c8034) (1 or 2 per month).
- **Mattermost** - Join the ~contributors channel on [the Mattermost Community Server](https://community.mattermost.com).
- **IRC** - Join the #matterbridge channel on [Freenode](https://freenode.net/) (thanks to [matterircd](https://github.com/42wim/matterircd)).
- **YouTube** - Subscribe to [Mattermost](https://www.youtube.com/@MattermostHQ).
## Contributing
[![Small Image](https://img.shields.io/badge/Contribute%20with-Gitpod-908a85?logo=gitpod)](https://gitpod.io/#https://github.com/mattermost/mattermost)
Please see [CONTRIBUTING.md](./CONTRIBUTING.md).
[Join the Mattermost Contributors server](https://community.mattermost.com/signup_user_complete/?id=codoy5s743rq5mk18i7u5ksz7e) to join community discussions about contributions, development, and more.
[CC-By-NC v4.0](https://creativecommons.org/licenses/by-nc/4.0/deed.en) [Geoffrey Dorne](https://geoffreydorne.com)

Просмотреть файл

@@ -59,13 +59,15 @@ build-v4: node_modules playbooks
@cat $(V4_SRC)/metrics.yaml >> $(V4_YAML)
@cat $(V4_SRC)/scheduled_post.yaml >> $(V4_YAML)
@cat $(V4_SRC)/custom_profile_attributes.yaml >> $(V4_YAML)
@cat $(V4_SRC)/audit_logging.yaml >> $(V4_YAML)
@cat $(V4_SRC)/access_control.yaml >> $(V4_YAML)
@if [ -r $(PLAYBOOKS_SRC)/paths.yaml ]; then cat $(PLAYBOOKS_SRC)/paths.yaml >> $(V4_YAML); fi
@if [ -r $(PLAYBOOKS_SRC)/merged-definitions.yaml ]; then cat $(PLAYBOOKS_SRC)/merged-definitions.yaml >> $(V4_YAML); else cat $(V4_SRC)/definitions.yaml >> $(V4_YAML); fi
@echo Extracting code samples
cd server && go run . $(V4_YAML)
@node_modules/.bin/swagger-cli validate $(V4_YAML)
@node_modules/.bin/redocly -t ./v4/html/ssr_template.hbs build-docs ./v4/html/static/mattermost-openapi-v4.yaml -o ./v4/html/index.html
@cp ./v4/html/ssr_template.hbs ./v4/html/index.html
@echo Complete
node_modules: package.json $(wildcard package-lock.json)
@@ -75,9 +77,8 @@ node_modules: package.json $(wildcard package-lock.json)
touch $@
run:
@echo Starting redoc server
@node_modules/.bin/redocly preview-docs ./v4/html/static/mattermost-openapi-v4.yaml
@echo Starting local server
python3 -m http.server 8080 --directory ./v4/html
clean:
@echo Cleaning

Просмотреть файл

@@ -1,6 +1,6 @@
# Mattermost API Documentation
This repository holds the API reference available at [https://api.mattermost.com](https://api.mattermost.com).
This repository holds the API reference documentation for Mattermost available at [https://developers.mattermost.com/api-reference](https://developers.mattermost.com/api-reference).
The Mattermost API reference uses the [OpenAPI standard](https://openapis.org/) and the [ReDoc document generator](https://github.com/Rebilly/ReDoc).
@@ -25,4 +25,4 @@ To test locally, run `make build`, `make run` and navigate to `http://127.0.0.1:
## Deployment
Deployment is handled automatically by our Jenkins CLI machine. When a pull request is merged it will automatically be deployed to [https://api.mattermost.com](https://api.mattermost.com).
Deployment is handled automatically by our Github Actions. When a pull request is merged, it will automatically be deployed to [https://developers.mattermost.com/api-reference](https://developers.mattermost.com/api-reference).

Просмотреть файл

@@ -1,7 +1,7 @@
{
"name": "mattermost-api-reference",
"version": "1.0.0",
"description": "This repository holds the API reference available at [https://api.mattermost.com](https://api.mattermost.com).",
"description": "This repository holds the API reference documentation for Mattermost available at https://developers.mattermost.com/api-reference",
"main": "index.js",
"dependencies": {
"@redocly/cli": "^1.13.0",
@@ -28,6 +28,5 @@
"license": "ISC",
"bugs": {
"url": "https://github.com/mattermost/mattermost/issues"
},
"homepage": "https://api.mattermost.com/"
}
}

Просмотреть файл

@@ -4,27 +4,25 @@
<head>
<meta charset="utf8" />
<title>Mattermost API Reference</title>
<!-- needed for adaptive design -->
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="shortcut icon" href="./static/favicon.ico">
<script src="https://unpkg.com/@stoplight/elements/web-components.min.js"></script>
<link rel="stylesheet" href="https://unpkg.com/@stoplight/elements/styles.min.css">
<style>
body {
padding: 0;
margin: 0;
height: 100vh;
}
label[type="tag"] {
text-transform: uppercase;
}
h1{
text-transform: capitalize;
}
</style>
{{{redocHead}}}
{{#unless disableGoogleFont}}<link href="https://fonts.googleapis.com/css?family=Montserrat:300,400,700|Roboto:300,400,700" rel="stylesheet">{{/unless}}
</head>
<body>
{{{redocHTML}}}
<elements-api
apiDescriptionUrl="./static/mattermost-openapi-v4.yaml"
router="hash"
layout="sidebar"
/>
</body>
</html>

534
api/v4/source/access_control.yaml Обычный файл
Просмотреть файл

@@ -0,0 +1,534 @@
/api/v4/access_control_policies:
put:
tags:
- access control
summary: Create an access control policy
description: |
Creates a new access control policy.
##### Permissions
Must have the `manage_system` permission.
operationId: CreateAccessControlPolicy
requestBody:
required: true
content:
application/json:
schema:
$ref: "#/components/schemas/AccessControlPolicy"
responses:
"200":
description: Access control policy created successfully.
content:
application/json:
schema:
$ref: "#/components/schemas/AccessControlPolicy"
"400":
$ref: "#/components/responses/BadRequest"
"401":
$ref: "#/components/responses/Unauthorized"
"403":
$ref: "#/components/responses/Forbidden"
"500":
$ref: "#/components/responses/InternalServerError"
/api/v4/access_control_policies/cel/check:
post:
tags:
- access control
summary: Check an access control policy expression
description: |
Checks the syntax and validity of an access control policy expression.
##### Permissions
Must have the `manage_system` permission.
operationId: CheckAccessControlPolicyExpression
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
expression:
type: string
description: The expression to check.
responses:
"200":
description: Expression check result.
content:
application/json:
schema:
type: array
items:
$ref: "#/components/schemas/ExpressionError"
"400":
$ref: "#/components/responses/BadRequest"
"401":
$ref: "#/components/responses/Unauthorized"
"403":
$ref: "#/components/responses/Forbidden"
"500":
$ref: "#/components/responses/InternalServerError"
/api/v4/access_control_policies/cel/test:
post:
tags:
- access control
summary: Test an access control policy expression
description: |
Tests an access control policy expression against users to see who would be affected.
##### Permissions
Must have the `manage_system` permission.
operationId: TestAccessControlPolicyExpression
requestBody:
required: true
content:
application/json:
schema:
$ref: "#/components/schemas/QueryExpressionParams"
responses:
"200":
description: Expression test result.
content:
application/json:
schema:
$ref: "#/components/schemas/AccessControlPolicyTestResponse"
"400":
$ref: "#/components/responses/BadRequest"
"401":
$ref: "#/components/responses/Unauthorized"
"403":
$ref: "#/components/responses/Forbidden"
"500":
$ref: "#/components/responses/InternalServerError"
/api/v4/access_control_policies/search:
post:
tags:
- access control
summary: Search access control policies
description: |
Searches for access control policies based on given criteria.
##### Permissions
Must have the `manage_system` permission.
operationId: SearchAccessControlPolicies
requestBody:
required: true
content:
application/json:
schema:
$ref: "#/components/schemas/AccessControlPolicySearch"
responses:
"200":
description: Search results for access control policies.
content:
application/json:
schema:
$ref: "#/components/schemas/AccessControlPoliciesWithCount"
"400":
$ref: "#/components/responses/BadRequest"
"401":
$ref: "#/components/responses/Unauthorized"
"403":
$ref: "#/components/responses/Forbidden"
"500":
$ref: "#/components/responses/InternalServerError"
/api/v4/access_control_policies/cel/autocomplete/fields:
get:
tags:
- access control
summary: Get autocomplete fields for access control policies
description: |
Provides a list of fields that can be used for autocompletion when creating/editing access control policy expressions.
##### Permissions
Must have the `manage_system` permission.
operationId: GetAccessControlPolicyAutocompleteFields
parameters:
- name: after
in: query
description: The field ID to start after for pagination.
required: false
schema:
type: string
- name: limit
in: query
description: The maximum number of fields to return.
required: true
schema:
type: integer
default: 60
responses:
"200":
description: Autocomplete fields retrieved successfully.
content:
application/json:
schema:
$ref: "#/components/schemas/AccessControlFieldsAutocompleteResponse"
"400":
$ref: "#/components/responses/BadRequest"
"401":
$ref: "#/components/responses/Unauthorized"
"403":
$ref: "#/components/responses/Forbidden"
"500":
$ref: "#/components/responses/InternalServerError"
"/api/v4/access_control_policies/{policy_id}":
get:
tags:
- access control
summary: Get an access control policy
description: |
Gets a specific access control policy by its ID.
##### Permissions
Must have the `manage_system` permission.
operationId: GetAccessControlPolicy
parameters:
- name: policy_id
in: path
description: The ID of the access control policy.
required: true
schema:
type: string
responses:
"200":
description: Access control policy retrieved successfully.
content:
application/json:
schema:
$ref: "#/components/schemas/AccessControlPolicy"
"400":
$ref: "#/components/responses/BadRequest"
"401":
$ref: "#/components/responses/Unauthorized"
"403":
$ref: "#/components/responses/Forbidden"
"404":
$ref: "#/components/responses/NotFound"
"500":
$ref: "#/components/responses/InternalServerError"
delete:
tags:
- access control
summary: Delete an access control policy
description: |
Deletes an access control policy by its ID.
##### Permissions
Must have the `manage_system` permission.
operationId: DeleteAccessControlPolicy
parameters:
- name: policy_id
in: path
description: The ID of the access control policy.
required: true
schema:
type: string
responses:
"200":
description: Access control policy deleted successfully.
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"
"500":
$ref: "#/components/responses/InternalServerError"
"/api/v4/access_control_policies/{policy_id}/activate":
get:
tags:
- access control
summary: Activate or deactivate an access control policy
deprecated: true
description: |
This endpoint is deprecated. Use the POST /api/v4/access_control_policies/{policy_id}/activate instead.
responses:
"405":
$ref: "#/components/responses/MethodNotAllowed"
post:
tags:
- access control
summary: Activate or deactivate an access control policy
description: |
Updates the active status of an access control policy.
##### Permissions
Must have the `manage_system` permission.
operationId: UpdateAccessControlPolicyActiveStatus
parameters:
- name: policy_id
in: path
description: The ID of the access control policy.
required: true
schema:
type: string
- name: active
in: query
description: Set to "true" to activate, "false" to deactivate.
required: true
schema:
type: boolean
responses:
"200":
description: Policy active status updated successfully.
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"
"500":
$ref: "#/components/responses/InternalServerError"
"/api/v4/access_control_policies/{policy_id}/assign":
post:
tags:
- access control
summary: Assign an access control policy to channels
description: |
Assigns an access control policy to a list of channels.
##### Permissions
Must have the `manage_system` permission.
operationId: AssignAccessControlPolicyToChannels
parameters:
- name: policy_id
in: path
description: The ID of the access control policy.
required: true
schema:
type: string
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
channel_ids:
type: array
items:
type: string
description: The IDs of the channels to assign the policy to.
responses:
"200":
description: Policy assigned to channels successfully.
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"
"500":
$ref: "#/components/responses/InternalServerError"
"/api/v4/access_control_policies/{policy_id}/unassign":
delete:
tags:
- access control
summary: Unassign an access control policy from channels
description: |
Unassigns an access control policy from a list of channels.
##### Permissions
Must have the `manage_system` permission.
operationId: UnassignAccessControlPolicyFromChannels
parameters:
- name: policy_id
in: path
description: The ID of the access control policy.
required: true
schema:
type: string
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
channel_ids:
type: array
items:
type: string
description: The IDs of the channels to unassign the policy from.
responses:
"200":
description: Policy unassigned from channels successfully.
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"
"500":
$ref: "#/components/responses/InternalServerError"
"/api/v4/access_control_policies/{policy_id}/resources/channels":
get:
tags:
- access control
summary: Get channels for an access control policy
description: |
Retrieves a paginated list of channels to which a specific access control policy is applied.
##### Permissions
Must have the `manage_system` permission.
operationId: GetChannelsForAccessControlPolicy
parameters:
- name: policy_id
in: path
description: The ID of the access control policy.
required: true
schema:
type: string
- name: after
in: query
description: The channel ID to start after for pagination.
required: false
schema:
type: string
- name: limit
in: query
description: The maximum number of channels to return.
required: true
schema:
type: integer
default: 60
responses:
"200":
description: Channels retrieved successfully.
content:
application/json:
schema:
$ref: "#/components/schemas/ChannelsWithCount"
"400":
$ref: "#/components/responses/BadRequest"
"401":
$ref: "#/components/responses/Unauthorized"
"403":
$ref: "#/components/responses/Forbidden"
"404":
$ref: "#/components/responses/NotFound"
"500":
$ref: "#/components/responses/InternalServerError"
"/api/v4/access_control_policies/{policy_id}/resources/channels/search":
post:
tags:
- access control
summary: Search channels for an access control policy
description: |
Searches for channels associated with a specific access control policy based on search criteria.
##### Permissions
Must have the `manage_system` permission.
operationId: SearchChannelsForAccessControlPolicy
parameters:
- name: policy_id
in: path
description: The ID of the access control policy.
required: true
schema:
type: string
requestBody:
required: true
content:
application/json:
schema:
$ref: "#/components/schemas/ChannelSearch"
responses:
"200":
description: Channel search results retrieved successfully.
content:
application/json:
schema:
$ref: "#/components/schemas/ChannelsWithCount"
"400":
$ref: "#/components/responses/BadRequest"
"401":
$ref: "#/components/responses/Unauthorized"
"403":
$ref: "#/components/responses/Forbidden"
"404":
$ref: "#/components/responses/NotFound"
"500":
$ref: "#/components/responses/InternalServerError"
"/api/v4/channels/{channel_id}/access_control/attributes":
get:
tags:
- access control
- channels
summary: Get access control attributes for a channel
description: |
Retrieves the effective access control policy attributes for a specific channel.
This can be used to understand what attributes are currently being applied to the channel by the access control system.
##### Permissions
Must have `read_channel` permission for the specified channel.
operationId: GetChannelAccessControlAttributes
parameters:
- name: channel_id
in: path
description: The ID of the channel.
required: true
schema:
type: string
responses:
"200":
description: Access control attributes retrieved successfully.
content:
application/json:
schema:
type: object # Placeholder - define more specifically if the structure is known
additionalProperties: true
description: A map of attribute names to their values as applied to the channel.
"400":
$ref: "#/components/responses/BadRequest"
"401":
$ref: "#/components/responses/Unauthorized"
"403":
$ref: "#/components/responses/Forbidden"
"404":
$ref: "#/components/responses/NotFound"
"500":
$ref: "#/components/responses/InternalServerError"
/api/v4/access_control_policies/cel/visual_ast:
post:
tags:
- access control
summary: Get the visual AST for a CEL expression
description: |
Retrieves the visual AST for a CEL expression.
##### Permissions
Must have the `manage_system` permission.
operationId: GetCELVisualAST
requestBody:
required: true
content:
application/json:
schema:
$ref: "#/components/schemas/CELExpression"
responses:
"200":
description: Visual AST retrieved successfully.
content:
application/json:
schema:
$ref: "#/components/schemas/VisualExpression"
"400":
$ref: "#/components/responses/BadRequest"
"401":
$ref: "#/components/responses/Unauthorized"
"403":
$ref: "#/components/responses/Forbidden"
"500":
$ref: "#/components/responses/InternalServerError"

68
api/v4/source/audit_logging.yaml Обычный файл
Просмотреть файл

@@ -0,0 +1,68 @@
/api/v4/audit_logs/certificate:
post:
tags:
- audit_logs
summary: Upload audit log certificate
description: |
Upload the certificate to be used for TLS verification with the audit log service.
##### Permissions
Must have `sysconsole_write_experimental_features` permission.
__Minimum server version__: 10.9
operationId: AddAuditLogCertificate
requestBody:
content:
multipart/form-data:
schema:
type: object
properties:
certificate:
description: The certificate file
type: string
format: binary
required:
- certificate
responses:
"200":
description: Certificate upload successful
content:
application/json:
schema:
$ref: "#/components/schemas/StatusOK"
"400":
$ref: "#/components/responses/BadRequest"
"401":
$ref: "#/components/responses/Unauthorized"
"403":
$ref: "#/components/responses/Forbidden"
"413":
$ref: "#/components/responses/TooLarge"
"501":
$ref: "#/components/responses/NotImplemented"
delete:
tags:
- audit_logs
summary: Remove audit log certificate
description: |
Delete the current certificate being used with the audit log service.
##### Permissions
Must have `sysconsole_write_experimental_features` permission.
__Minimum server version__: 9.5
operationId: RemoveAuditLogCertificate
responses:
"200":
description: Certificate deletion successful
content:
application/json:
schema:
$ref: "#/components/schemas/StatusOK"
"401":
$ref: "#/components/responses/Unauthorized"
"403":
$ref: "#/components/responses/Forbidden"
"501":
$ref: "#/components/responses/NotImplemented"

Просмотреть файл

@@ -641,6 +641,8 @@
type: string
description: Markdown-formatted text to display in the header of the
channel
banner_info:
$ref: "#/components/schemas/ChannelBanner"
description: Channel object to be updated
required: true
responses:
@@ -2515,3 +2517,41 @@
$ref: "#/components/responses/Forbidden"
"404":
$ref: "#/components/responses/NotFound"
"/api/v4/sharedchannels/{channel_id}/remotes":
get:
tags:
- channels
summary: Get remote clusters for a shared channel
description: |
Gets the remote clusters information for a shared channel.
__Minimum server version__: 10.10
##### Permissions
Must be authenticated and have the `read_channel` permission for the channel.
operationId: GetSharedChannelRemotes
parameters:
- name: channel_id
in: path
description: Channel GUID
required: true
schema:
type: string
responses:
"200":
description: Remote clusters retrieval successful
content:
application/json:
schema:
type: array
items:
$ref: "#/components/schemas/RemoteClusterInfo"
"400":
$ref: "#/components/responses/BadRequest"
"401":
$ref: "#/components/responses/Unauthorized"
"403":
$ref: "#/components/responses/Forbidden"
"404":
$ref: "#/components/responses/NotFound"

Просмотреть файл

@@ -53,7 +53,36 @@
type:
type: string
attrs:
type: string
type: object
properties:
visibility:
type: string
description: "Visibility of the attribute"
enum: ["hidden", "when_set", "always"]
default: "when_set"
sort_order:
type: number
description: "Sort order for displaying this attribute"
options:
type: array
description: "Options for select/multiselect fields"
items:
type: object
properties:
name:
type: string
color:
type: string
value_type:
type: string
description: "Type of text value"
enum: ["email", "url", "phone"]
ldap:
type: string
description: "LDAP attribute for syncing"
saml:
type: string
description: "SAML attribute for syncing"
responses:
"201":
description: Custom Profile Attribute field creation successful
@@ -106,7 +135,38 @@
type:
type: string
attrs:
type: string
type: object
properties:
visibility:
type: string
description: "Visibility of the attribute"
enum: ["hidden", "when_set", "always"]
default: "when_set"
sort_order:
type: number
description: "Sort order for displaying this attribute"
options:
type: array
description: "Options for select/multiselect fields"
items:
type: object
properties:
id:
type: string
name:
type: string
color:
type: string
value_type:
type: string
description: "Type of text value"
enum: ["email", "url", "phone"]
ldap:
type: string
description: "LDAP attribute for syncing"
saml:
type: string
description: "SAML attribute for syncing"
responses:
"200":
description: Custom Profile Attribute field patch successful
@@ -218,6 +278,35 @@
$ref: "#/components/responses/Unauthorized"
"403":
$ref: "#/components/responses/Forbidden"
"/api/v4/custom_profile_attributes/group":
get:
tags:
- custom profile attributes
summary: Get Custom Profile Attribute property group data
description: |
Get the property group used for Custom Profile Attributes.
__Minimum server version__: 10.8
##### Permissions
Must be authenticated.
operationId: GetCPAGroup
responses:
"200":
description: Group fetch successful
content:
application/json:
schema:
type: object
properties:
id:
type: string
description: The ID of the custom profile attributes group
"401":
$ref: "#/components/responses/Unauthorized"
"403":
$ref: "#/components/responses/Forbidden"
"/api/v4/users/{user_id}/custom_profile_attributes":
get:
tags:

Просмотреть файл

@@ -1,9 +1,8 @@
components:
securitySchemes:
bearerAuth: # arbitrary name for the security scheme
bearerAuth:
type: http
scheme: bearer
bearerFormat: Token
responses:
Forbidden:
description: Do not have appropriate permissions
@@ -29,6 +28,12 @@ components:
application/json:
schema:
$ref: "#/components/schemas/AppError"
MethodNotAllowed:
description: Method not allowed
content:
application/json:
schema:
$ref: "#/components/schemas/AppError"
TooLarge:
description: Content too large
content:
@@ -175,8 +180,6 @@ components:
type: string
total_member_count:
type: integer
active_member_count:
type: integer
TeamExists:
type: object
properties:
@@ -1283,6 +1286,131 @@ components:
type: string
session_id:
type: string
LdapSettings:
type: object
properties:
Enable:
type: boolean
EnableSync:
type: boolean
LdapServer:
type: string
LdapPort:
type: integer
ConnectionSecurity:
type: string
BaseDN:
type: string
BindUsername:
type: string
BindPassword:
type: string
MaximumLoginAttempts:
type: integer
UserFilter:
type: string
GroupFilter:
type: string
GuestFilter:
type: string
EnableAdminFilter:
type: boolean
AdminFilter:
type: string
GroupDisplayNameAttribute:
type: string
GroupIdAttribute:
type: string
FirstNameAttribute:
type: string
LastNameAttribute:
type: string
EmailAttribute:
type: string
UsernameAttribute:
type: string
NicknameAttribute:
type: string
IdAttribute:
type: string
PositionAttribute:
type: string
LoginIdAttribute:
type: string
PictureAttribute:
type: string
SyncIntervalMinutes:
type: integer
ReAddRemovedMembers:
type: boolean
SkipCertificateVerification:
type: boolean
PublicCertificateFile:
type: string
PrivateKeyFile:
type: string
QueryTimeout:
type: integer
MaxPageSize:
type: integer
LoginFieldName:
type: string
LoginButtonColor:
type: string
LoginButtonBorderColor:
type: string
LoginButtonTextColor:
type: string
LdapDiagnosticResult:
type: object
properties:
test_name:
type: string
description: Name/type of the diagnostic test being performed
test_value:
type: string
description: The actual test value (filter string or attribute name)
total_count:
type: integer
description: Number of entries found by the filter
message:
type: string
description: Optional success/info message
error:
type: string
description: Optional error message if test failed
sample_results:
type: array
description: Array of sample LDAP entries found
items:
type: object
properties:
dn:
type: string
description: Distinguished Name
username:
type: string
description: Username
email:
type: string
description: Email
first_name:
type: string
description: First name
last_name:
type: string
description: Last name
id:
type: string
description: ID attribute
display_name:
type: string
description: Display name for groups
available_attributes:
type: object
description: Map of all available LDAP attributes
additionalProperties:
type: string
Config:
type: object
properties:
@@ -1574,6 +1702,12 @@ components:
type: string
ReportAProblemLink:
type: string
ReportAProblemType:
type: string
ReportAProblemMail:
type: string
AllowDownloadLogs:
type: boolean
SupportEmail:
type: string
GitLabSettings:
@@ -2048,6 +2182,12 @@ components:
type: boolean
ReportAProblemLink:
type: boolean
ReportAProblemType:
type: boolean
ReportAProblemMail:
type: boolean
AllowDownloadLogs:
type: boolean
SupportEmail:
type: boolean
GitLabSettings:
@@ -3924,6 +4064,193 @@ components:
description: Explains the error behind why a scheduled post could not have been sent
metadata:
$ref: "#/components/schemas/PostMetadata"
AccessControlFieldsAutocompleteResponse:
type: object
properties:
fields:
type: array
items:
type: object
properties:
name:
type: string
description: The name of the field.
description:
type: string
description: A description of the field.
AccessControlPoliciesWithCount:
type: object
properties:
policies:
type: array
items:
$ref: "#/components/schemas/AccessControlPolicy"
total_count:
type: integer
description: The total number of policies.
AccessControlPolicy:
type: object
properties:
id:
type: string
description: The unique identifier of the policy.
name:
type: string
description: The unique name for the policy.
display_name:
type: string
description: The human-readable name for the policy.
description:
type: string
description: A description of the policy.
expression:
type: string
description: The CEL expression defining the policy rules.
is_active:
type: boolean
description: Whether the policy is currently active and enforced.
create_at:
type: integer
format: int64
description: The time in milliseconds the policy was created.
update_at:
type: integer
format: int64
description: The time in milliseconds the policy was last updated.
delete_at:
type: integer
format: int64
description: The time in milliseconds the policy was deleted.
AccessControlPolicySearch:
type: object
properties:
term:
type: string
description: The search term to match against policy names or display names.
is_active:
type: boolean
description: Filter policies by active status.
page:
type: integer
description: The page number to return.
per_page:
type: integer
description: The number of policies to return per page.
# Add other potential search/filter fields like sort_by, sort_direction
AccessControlPolicyTestResponse:
type: object
properties:
users:
type: array
items:
$ref: "#/components/schemas/User"
description: A list of users affected by the policy expression.
total_count:
type: integer
description: The total number of users affected.
ChannelSearch: # Added based on dataretention.yaml and access_control.go usage
type: object
properties:
term:
type: string
description: The string to search in the channel name, display name, and purpose.
team_ids:
type: array
items:
type: string
description: Filters results to channels belonging to the given team ids.
public:
type: boolean
description: Filters results to only return Public / Open channels.
private:
type: boolean
description: Filters results to only return Private channels.
deleted:
type: boolean
description: Filters results to only return deleted / archived channels.
include_deleted:
type: boolean
description: Whether to include deleted channels in the search results.
# Add other potential search fields like not_associated_to_group, exclude_default_channels etc.
ChannelsWithCount: # Added based on access_control.go usage
type: object
properties:
channels:
$ref: "#/components/schemas/ChannelListWithTeamData" # Referencing existing type used in similar contexts
total_count:
type: integer
description: The total number of channels.
ExpressionError:
type: object
properties:
message:
type: string
description: The error message.
field:
type: string
description: The field related to the error, if applicable.
line:
type: integer
description: The line number where the error occurred in the expression.
column:
type: integer
description: The column number where the error occurred in the expression.
QueryExpressionParams:
type: object
properties:
expression:
type: string
description: The policy expression to test.
term:
type: string
description: A search term to filter users against whom the expression is tested.
limit:
type: integer
description: The maximum number of users to return.
after:
type: string
description: The ID of the user to start the test after (for pagination).
CELExpression:
type: object
properties:
expression:
type: string
description: The CEL expression to visualize.
VisualExpression:
type: object
properties:
conditions:
type: array
items:
$ref: "#/components/schemas/Condition"
description: The visual AST for the CEL expression
Condition:
type: object
properties:
attribute:
type: string
description: The attribute name.
operator:
type: string
description: The operator of a single condition.
value:
type: string
description: The value.
value_type:
type: string
description: The value type.
ChannelBanner:
type: object
properties:
enabled:
type: boolean
description: enabled indicates whether the channel banner is enabled or not
text:
type: string
description: text is the actual text that renders in the channel banner. Markdown is supported.
background_color:
type: string
description: background_color is the HEX color code for the banner's backgroubd
externalDocs:
description: Find out more about Mattermost
url: 'https://about.mattermost.com'

Просмотреть файл

@@ -8,9 +8,6 @@
team.
`not_associated_to_team` **OR** `not_associated_to_channel` is required.
If you use `not_associated_to_team`, you must be a team admin for that particular team (permission to manage that team).
@@ -49,14 +46,12 @@
in: query
description: Team GUID which is used to return all the groups not associated to
this team
required: true
schema:
type: string
- name: not_associated_to_channel
in: query
description: Group GUID which is used to return all the groups not associated to
this channel
required: true
schema:
type: string
- name: since
@@ -1040,6 +1035,59 @@
schema:
type: boolean
default: false
- name: include_member_count
in: query
description: Boolean which adds a `member_count` field to each group object.
schema:
type: boolean
default: false
- name: include_timezones
in: query
description: Boolean which adds timezone information for group members.
schema:
type: boolean
default: false
- name: include_total_count
in: query
description: Boolean which adds total count of groups in the response.
schema:
type: boolean
default: false
- name: include_archived
in: query
description: Boolean which includes archived groups in the response.
schema:
type: boolean
default: false
- name: filter_archived
in: query
description: Boolean which filters out archived groups from the response.
schema:
type: boolean
default: false
- name: filter_parent_team_permitted
in: query
description: Boolean which filters groups based on parent team permissions.
schema:
type: boolean
default: false
- name: filter_has_member
in: query
description: User ID to filter groups that have this member.
schema:
type: string
- name: include_member_ids
in: query
description: Boolean which adds member IDs to the group objects.
schema:
type: boolean
default: false
- name: only_syncable_sources
in: query
description: Boolean which includes groups from syncable sources.
schema:
type: boolean
default: false
responses:
"200":
description: Group list retrieval successful

Просмотреть файл

@@ -22,3 +22,34 @@
$ref: "#/components/responses/Forbidden"
"404":
$ref: "#/components/responses/NotFound"
"/api/v4/imports/{import_name}":
delete:
tags:
- imports
summary: Delete an import file
description: |
Deletes an import file.
__Minimum server version__: 5.31
##### Permissions
Must have `manage_system` permissions.
operationId: DeleteImport
parameters:
- name: import_name
in: path
description: The name of the import file to delete
required: true
schema:
type: string
responses:
"400":
$ref: "#/components/responses/BadRequest"
"401":
$ref: "#/components/responses/Unauthorized"
"403":
$ref: "#/components/responses/Forbidden"
"500":
$ref: "#/components/responses/InternalServerError"

Просмотреть файл

@@ -1,184 +1,173 @@
openapi: 3.0.0
info:
description: >
There is also a work-in-progress [Postman API
reference](https://documenter.getpostman.com/view/4508214/RW8FERUn).
version: 4.0.0
title: Mattermost API Reference
termsOfService: https://about.mattermost.com/default-terms/
contact:
email: feedback@mattermost.com
x-logo:
url: https://mattermost.com/wp-content/uploads/2022/02/logoHorizontal.png
backgroundColor: "#FFFFFF"
tags:
- name: introduction
description: >
The Mattermost Web Services API is used by Mattermost clients and third
party applications to interact with the server. [JavaScript and Golang
drivers for](/#tag/drivers) connecting to the APIs are also available.
The Mattermost Web Services API enables Mattermost clients and third-party applications
to interact with Mattermost servers.
### Support
[Official JavaScript and Golang drivers](#/#official-drivers)
are available to simplify API integration.
Mattermost core committers work with the community to keep the API documentation up-to-date.
By using this API, you agree to our [terms of service](https://about.mattermost.com/default-terms/).
If you have questions on API routes not listed in this reference, please [join the Mattermost community server](https://community.mattermost.com) to ask questions in the Developers channel, [or post questions to our Developer Discussion forum](https://forum.mattermost.org/c/dev).
[Find out more about Mattermost](https://about.mattermost.com/)
## Contents
### Core Concepts
* [Schema & Conventions](#/#schema--conventions)
* [Authentication](#/#authentication)
* [Rate Limiting](#/#rate-limiting)
* [Error Handling](#/#error-handling)
* [WebSocket](#/#websocket)
* [Authentication](#/#authentication-1)
* [Websocket Events](#/#websocket-events)
* [Websocket API](#/#websocket-api)
### Drivers
* [Official Drivers](#/#official-drivers)
* [Community-built Drivers](#/#community-built-drivers)
### Community
* [Support](#/#support)
* [Contributing](#/#contributing)
[Bug reports](https://github.com/mattermost/mattermost/issues) in the documentation or the API are also welcome, as are pull requests to fix the issues.
## Schema & Conventions
- All API access is through HTTP(S) requests at `your-mattermost-url/api/v4`.
### Contributing
- All request and response bodies are `application/json`.
- When using endpoints that require a user id, the string `me` can be used in place
of the user id to indicate the action is to be taken for the logged in user.
When you have answers to API questions not addressed in our documentation we ask you to consider making a pull request to improve our reference. Small and large changes are all welcome.
- For all endpoints that implement pagination via the `per_page` parameter:
- Maximum items per page: 200 (requests exceeding this will be silently truncated)
We also have [Help Wanted tickets](https://github.com/mattermost/mattermost/issues?q=is%3Aopen+is%3Aissue+label%3AArea%2FAPI) available for community members who would like to help others more easily use the APIs. We acknowledge everyone's contribution in the [release notes of our next version](https://docs.mattermost.com/administration/changelog.html#contributors).
- Default value if a paged API requires a `per_page` parameter and it is not provided: 60
## Authentication
The source code for this API reference is hosted at https://github.com/mattermost/mattermost/tree/master/api.
- name: schema
description: >
All API access is through HTTP(S) requests at
`your-mattermost-url.com/api/v4`. All request and response bodies are
`application/json`.
When using endpoints that require a user id, the string `me` can be used in place of the user id to indicate the action is to be taken for the logged in user.
For all endpoints that implement pagination via the `per_page` parameter, the maximum number of items returned per request is capped at 200. If `per_page` exceeds 200, the list will be silently truncated to 200 items.
- name: drivers
description: >
The easiest way to interact with the Mattermost Web Service API is through
a language specific driver.
#### Official Drivers
* Mattermost JavaScript/TypeScript Driver
* [NPM](https://www.npmjs.com/package/@mattermost/client)
* [Source](https://github.com/mattermost/mattermost/tree/master/webapp/platform/client)
* [Mattermost Golang Driver](https://pkg.go.dev/github.com/mattermost/mattermost/server/public/model#Client4)
#### Community-built Drivers
For community-built drivers and API wrappers, see [our app directory](https://mattermost.com/marketplace/).
- name: authentication
description: >
There are multiple ways to authenticate against the Mattermost API.
All examples assume there is a Mattermost instance running at http://localhost:8065.
### Session Token
#### Session Token
Make an HTTP POST to `your-mattermost-url.com/api/v4/users/login` with a JSON body indicating the users `login_id`, `password` and optionally the MFA `token`. The `login_id` can be an email, username or an AD/LDAP ID depending on the system's configuration.
```
Make an HTTP POST to `your-mattermost-url/api/v4/users/login` with a JSON
body indicating the user's `login_id`, `password` and optionally the MFA
`token`. The `login_id` can be an email, username or an AD/LDAP ID
depending on the system's configuration.
```bash
curl -i -d '{"login_id":"someone@nowhere.com","password":"thisisabadpassword"}' http://localhost:8065/api/v4/users/login
```
NOTE: If you're running cURL on windows, you will have to change the single quotes to double quotes, and escape the inner double quotes with backslash, like below:
```
```bash
curl -i -d "{\"login_id\":\"someone@nowhere.com\",\"password\":\"thisisabadpassword\"}" http://localhost:8065/api/v4/users/login
```
If successful, the response will contain a `Token` header and a user object in the body.
```
```http
HTTP/1.1 200 OK
Set-Cookie: MMSID=hyr5dmb1mbb49c44qmx4whniso; Path=/; Max-Age=2592000; HttpOnly
Token: hyr5dmb1mbb49c44qmx4whniso
X-Ratelimit-Limit: 10
X-Ratelimit-Remaining: 9
X-Ratelimit-Reset: 1
X-Request-Id: smda55ckcfy89b6tia58shk5fh
X-Version-Id: developer
Date: Fri, 11 Sep 2015 13:21:14 GMT
Content-Length: 657
Content-Type: application/json; charset=utf-8
Content-Type: application/json
Permissions-Policy:
Referrer-Policy: no-referrer
Token: ckh3t4knu3fzujt76o57f5jo4w
Vary: Origin
Vary: Accept-Encoding
X-Content-Type-Options: nosniff
X-Request-Id: bk3uzm335jr9tnoh4mcsybmmjr
X-Version-Id: 10.6.0.13685270376.215f100adf6ccda09afcaaa84ac4bfbd.true
Date: Fri, 28 Mar 2025 09:33:22 GMT
Content-Length: 796
{{user object as json}}
```
Include the `Token` as part of the `Authorization` header on your future API requests with the `Bearer` method.
```bash
curl -i -H 'Authorization: Bearer ckh3t4knu3fzujt76o57f5jo4w' http://localhost:8065/api/v4/users/me
```
Alternatively, include the `Token` as your `MMAUTHTOKEN` cookie value on you future API requests:
curl -i -H 'Authorization: Bearer hyr5dmb1mbb49c44qmx4whniso' http://localhost:8065/api/v4/users/me
```bash
curl -i -H 'Cookie: MMAUTHTOKEN=ckh3t4knu3fzujt76o57f5jo4w' http://localhost:8065/api/v4/users/me
```
You should now be able to access the API as the user you logged in as.
#### Personal Access Tokens
Using [personal access tokens](https://docs.mattermost.com/developer/personal-access-tokens.html) is very similar to using a session token. The only real difference is that session tokens will expire, while personal access tokens will live until they are manually revoked by the user or an admin.
### Personal Access Tokens
Using [personal access tokens](https://developers.mattermost.com/integrate/reference/personal-access-token/) is very similar to using a session token. The only real difference is that session tokens will expire, while personal access tokens will live until they are manually revoked by the user or an admin.
Just like session tokens, include the personal access token as part of the `Authorization` header in your requests using the `Bearer` method. Assuming our personal access token is `9xuqwrwgstrb3mzrxb83nb357a`, we could use it as shown below.
```
```bash
curl -i -H 'Authorization: Bearer 9xuqwrwgstrb3mzrxb83nb357a' http://localhost:8065/api/v4/users/me
```
## Rate Limiting
Whenever you make an HTTP request to the Mattermost API you might notice
the following headers included in the response:
```http
X-Ratelimit-Limit: 10
X-Ratelimit-Remaining: 9
X-Ratelimit-Reset: 1441983590
```
#### OAuth 2.0
These headers are telling you your current rate limit status.
Mattermost has the ability to act as an [OAuth 2.0](https://tools.ietf.org/html/rfc6749) service provider.
| Header | Description |
|:-----------------------|:-------------------------------------------------------------------|
| X-Ratelimit-Limit | The maximum number of requests you can make per second. |
| X-Ratelimit-Remaining | The number of requests remaining in the current window. |
| X-Ratelimit-Reset | The remaining UTC epoch seconds before the rate limit resets. |
If you exceed your rate limit for a window you will receive the following error in the body of the response:
The official documentation for [using your Mattermost server as an OAuth 2.0 service provider can be found here.](https://docs.mattermost.com/developer/oauth-2-0-applications.html)
```http
HTTP/1.1 429 Too Many Requests
Date: Tue, 10 Sep 2015 11:20:28 GMT
X-RateLimit-Limit: 10
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 1
limit exceeded
```
## Error Handling
For an example on how to register an OAuth 2.0 app with your Mattermost instance, please see the [Mattermost-Zapier integration documentation](https://docs.mattermost.com/integrations/zapier.html#register-zapier-as-an-oauth-2-0-application).
- name: errors
description: >
All errors will return an appropriate HTTP response code along with the
following JSON body:
```
```json
{
"id": "the.error.id",
"message": "Something went wrong", // the reason for the error
@@ -188,75 +177,21 @@ tags:
}
```
- name: rate limiting
description: >
Whenever you make an HTTP request to the Mattermost API you might notice
the following headers included in the response:
```
## WebSocket
In addition to the HTTP RESTful web service, Mattermost also offers a WebSocket event delivery system and some API functionality.
X-Ratelimit-Limit: 10
X-Ratelimit-Remaining: 9
X-Ratelimit-Reset: 1441983590
```
To connect to the WebSocket follow the standard opening handshake as [defined by the RFC specification](https://tools.ietf.org/html/rfc6455#section-1.3) to the `/api/v4/websocket` endpoint of Mattermost.
These headers are telling you your current rate limit status.
| Header | Description |
| ------ | ----------- |
| X-Ratelimit-Limit | The maximum number of requests you can make per second. |
| X-Ratelimit-Remaining | The number of requests remaining in the current window. |
| X-Ratelimit-Reset | The remaining UTC epoch seconds before the rate limit resets. |
If you exceed your rate limit for a window you will receive the following error in the body of the response:
```
HTTP/1.1 429 Too Many Requests
Date: Tue, 10 Sep 2015 11:20:28 GMT
X-RateLimit-Limit: 10
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 1
limit exceeded
```
- name: WebSocket
description: >
In addition to the HTTP RESTful web service, Mattermost also offers a
WebSocket event delivery system and some API functionality.
To connect to the WebSocket follow the standard opening handshake as [defined by the RFC specification](https://tools.ietf.org/html/rfc6455#section-1.3) to the `/api/v4/websocket` endpoint of Mattermost.
#### Authentication
The Mattermost WebSocket can be authenticated using [the standard API authentication methods](/#tag/authentication) (by a cookie or with an explicit Authorization header) or through an authentication challenge. If you're authenticating from a browser and have logged in with the Mattermost API, your authentication cookie should already be set. This is how the Mattermost webapp authenticates with the WebSocket.
### Authentication
The Mattermost WebSocket can be authenticated using [the standard API authentication methods](/#/#authentication) (by a cookie or with an explicit Authorization header) or through an authentication challenge. If you're authenticating from a browser and have logged in with the Mattermost API, your authentication cookie should already be set. This is how the Mattermost webapp authenticates with the WebSocket.
To authenticate with an authentication challenge, first connect the WebSocket and then send the following JSON over the connection:
```
```json
{
"seq": 1,
"action": "authentication_challenge",
@@ -264,37 +199,27 @@ tags:
"token": "mattermosttokengoeshere"
}
}
```
If successful, you will receive a standard OK response over the WebSocket connection:
```
```json
{
"status": "OK",
"seq_reply": 1
}
```
Once successfully authenticated, the server will pass a `hello` WebSocket event containing server version over the connection.
#### Events
### Websocket Events
WebSocket events are primarily used to alert the client to changes in Mattermost, such as delivering new posts or alerting the client that another user is typing in a channel.
Events on the WebSocket will have the form:
```
```json
{
"event": "hello",
"data": {
@@ -308,112 +233,62 @@ tags:
},
"seq": 0
}
```
The `event` field indicates the event type, `data` contains any data relevant to the event and `broadcast` contains information about who the event was sent to. For example, the above example has `user_id` set to "ay5sq51sebfh58ktrce5ijtcwy" meaning that only the user with that ID received this event broadcast. The `omit_users` field can contain an array of user IDs that were specifically omitted from receiving the event.
The list of Mattermost WebSocket events are:
- added_to_team
- authentication_challenge
- channel_converted
- channel_created
- channel_deleted
- channel_member_updated
- channel_updated
- channel_viewed
- config_changed
- delete_team
- direct_added
- emoji_added
- ephemeral_message
- group_added
- hello
- leave_team
- license_changed
- memberrole_updated
- new_user
- plugin_disabled
- plugin_enabled
- plugin_statuses_changed
- post_deleted
- post_edited
- post_unread
- posted
- preference_changed
- preferences_changed
- preferences_deleted
- reaction_added
- reaction_removed
- response
- role_updated
- status_change
- typing
- update_team
- user_added
- user_removed
- user_role_updated
- user_updated
- dialog_opened
- thread_updated
- thread_follow_changed
- thread_read_changed
#### WebSocket API
### Websocket API
Mattermost has some basic support for WebSocket APIs. A connected WebSocket can make requests by sending the following over the connection:
```
```json
{
"action": "user_typing",
"seq": 2,
@@ -422,37 +297,28 @@ tags:
"parent_id": ""
}
}
```
This is an example of making a `user_typing` request, with the purpose of alerting the server that the connected client has begun typing in a channel or thread. The `action` field indicates what is being requested, and performs a similar duty as the route in a HTTP API. The `data` field is used to add any additional data along with the request. The server supports binary websocket messages as well in case the client has such a requirement.
The `seq` or sequence number is set by the client and should be incremented with every use. It is used to distinguish responses to requests that come down the WebSocket. For example, a standard response to the above request would be:
```
```json
{
"status": "OK",
"seq_reply": 2
}
```
Notice `seq_reply` is 2, matching the `seq` of the original request. Using this a client can distinguish which request the response is meant for.
If there was any information to respond with, it would be encapsulated in a `data` field.
In the case of an error, the response would be:
```
```json
{
"status": "FAIL",
"seq_reply": 2,
@@ -461,32 +327,65 @@ tags:
"message": "Some error message here"
}
}
```
The list of WebSocket API actions is:
- user_typing
- get_statuses
- get_statuses_by_ids
To see how these actions work, please refer to either the [Golang WebSocket driver](https://github.com/mattermost/mattermost/blob/master/server/public/model/websocket_client.go) or our [JavaScript WebSocket driver](https://github.com/mattermost/mattermost/blob/master/webapp/platform/client/src/websocket.ts).
- name: common parameters
description: >
- `per_page`: For paged APIs, the number of items to return per page.
The maximum number of items returned per request is capped at 200. If `per_page` exceeds 200, the list will be silently truncated to 200 items.
## Drivers
The easiest way to interact with the Mattermost Web Service API is through
a language specific driver.
If a paged API requires a `per_page` parameter and it is not provided, the default value is 60.
### Official Drivers
* Mattermost JavaScript/TypeScript Driver
* [NPM](https://www.npmjs.com/package/@mattermost/client)
* [Source](https://github.com/mattermost/mattermost/tree/master/webapp/platform/client)
* [Mattermost Golang Driver](https://pkg.go.dev/github.com/mattermost/mattermost/server/public/model#Client4)
### Community-built Drivers
For community-built drivers and API wrappers, see [our app directory](https://mattermost.com/marketplace-category/mattermost-developers-tools/).
## Support
Mattermost core committers work with the community to keep the API documentation up-to-date.
If you have questions on API routes not listed in this reference, you can:
- [Join the Mattermost community server](https://community.mattermost.com) to ask questions in the Developers channel
- Contact us at feedback@mattermost.com
[Bug reports](https://github.com/mattermost/mattermost/issues) in the documentation or the API are also welcome, as are pull requests to fix the issues.
## Contributing
When you have answers to API questions not addressed in our documentation we ask you to consider making a pull request to improve our reference. Small and large changes are all welcome.
We also have [Help Wanted tickets](https://github.com/mattermost/mattermost/issues?q=is%3Aopen+is%3Aissue+label%3AArea%2FAPI) available for community members who would like to help others more easily use the APIs. We acknowledge everyone's contribution in the [release notes of our next version](https://docs.mattermost.com/administration/changelog.html#contributors).
The source code for this API reference is hosted at https://github.com/mattermost/mattermost/tree/master/api.
version: 4.0.0
title: Mattermost API
tags:
- name: users
description: >
Endpoints for creating, getting and interacting with users.
When using endpoints that require a user id, the string `me` can be used in place of the user id to indicate the action is to be taken for the logged in user.
- name: bots
description: Endpoints for creating, getting and updating bot users.
@@ -561,64 +460,11 @@ tags:
description: Endpoints related to export files.
- name: metrics
description: Endpoints related to metrics, including the Client Performance Monitoring feature.
x-tagGroups:
- name: Overview
tags:
- introduction
- schema
- name: Standard Features
tags:
- drivers
- authentication
- errors
- rate limiting
- WebSocket
- common parameters
- name: Endpoints
tags:
- users
- bots
- teams
- channels
- posts
- threads
- files
- uploads
- bookmarks
- preferences
- status
- emoji
- reactions
- webhooks
- commands
- system
- brand
- OAuth
- SAML
- LDAP
- groups
- compliance
- cluster
- cloud
- elasticsearch
- bleve
- data retention
- jobs
- plugins
- roles
- schemes
- integration_actions
- remote clusters
- shared channels
- terms of service
- imports
- permissions
- exports
- usage
- reports
- custom profile attributes
- metrics
- name: audit_logs
description: Endpoints for managing audit log certificates and configuration.
servers:
- url: http://your-mattermost-url.com
- url: https://your-mattermost-url.com
- url: "{your-mattermost-url}"
variables:
your-mattermost-url:
default: http://localhost:8065
paths:

Просмотреть файл

@@ -44,6 +44,95 @@
$ref: "#/components/responses/InternalServerError"
"501":
$ref: "#/components/responses/NotImplemented"
/api/v4/ldap/test_connection:
post:
tags:
- LDAP
summary: Test LDAP connection with specific settings
description: >
Test the LDAP connection using the provided settings without modifying
the current server configuration.
##### Permissions
Must have `sysconsole_read_authentication_ldap` or `manage_system` permission.
operationId: TestLdapConnection
requestBody:
description: LDAP settings to test
required: true
content:
application/json:
schema:
$ref: "#/components/schemas/LdapSettings"
responses:
"200":
description: LDAP connection test successful
content:
application/json:
schema:
$ref: "#/components/schemas/StatusOK"
"400":
$ref: "#/components/responses/BadRequest"
"401":
$ref: "#/components/responses/Unauthorized"
"403":
$ref: "#/components/responses/Forbidden"
"500":
$ref: "#/components/responses/InternalServerError"
"501":
$ref: "#/components/responses/NotImplemented"
/api/v4/ldap/test_diagnostics:
post:
tags:
- LDAP
summary: Test LDAP diagnostics with specific settings
description: >
Test LDAP diagnostics using the provided settings to validate configuration
and see sample results without modifying the current server configuration.
Use the `test` query parameter to specify which diagnostic to run.
##### Permissions
Must have `sysconsole_read_authentication_ldap` or `manage_system` permission.
operationId: TestLdapDiagnostics
parameters:
- in: query
name: test
required: true
description: Type of LDAP diagnostic test to run
schema:
type: string
enum:
- filters
- attributes
- group_attributes
example: filters
requestBody:
description: LDAP settings to test diagnostics with
required: true
content:
application/json:
schema:
$ref: "#/components/schemas/LdapSettings"
responses:
"200":
description: LDAP diagnostic test results
content:
application/json:
schema:
type: array
items:
$ref: "#/components/schemas/LdapDiagnosticResult"
"400":
$ref: "#/components/responses/BadRequest"
"401":
$ref: "#/components/responses/Unauthorized"
"403":
$ref: "#/components/responses/Forbidden"
"500":
$ref: "#/components/responses/InternalServerError"
"501":
$ref: "#/components/responses/NotImplemented"
/api/v4/ldap/groups:
get:
tags:

Просмотреть файл

@@ -401,6 +401,12 @@
schema:
type: integer
default: 0
- name: fromUpdateAt
in: query
description: The update_at timestamp to return the next page of posts from. You cannot set this flag with direction=down.
schema:
type: integer
default: 0
- name: direction
in: query
description: The direction to return the posts. Either up or down.
@@ -425,6 +431,12 @@
schema:
type: boolean
default: false
- name: updatesOnly
in: query
description: This flag is used to make the API work with the updateAt value. If you set this flag, you must set a value for fromUpdateAt.
schema:
type: boolean
default: false
responses:
"200":
description: Post list retrieval successful

Просмотреть файл

@@ -100,7 +100,8 @@
##### Permissions
`manage_system` permission is required.
Must have `sysconsole_write_user_management_permissions` or `manage_system` permission.
When updating the role of a system admin, the `manage_system` permission is mandatory.
__Minimum server version__: 4.9

Просмотреть файл

@@ -226,3 +226,88 @@
$ref: "#/components/responses/Unauthorized"
"403":
$ref: "#/components/responses/Forbidden"
"/api/v4/sharedchannels/{channel_id}/remotes":
get:
tags:
- shared channels
summary: Get remote clusters for a shared channel
description: |
Gets the remote clusters information for a shared channel.
__Minimum server version__: 10.11
##### Permissions
Must be authenticated and have the `read_channel` permission for the channel.
operationId: GetSharedChannelRemotes
parameters:
- name: channel_id
in: path
description: Channel GUID
required: true
schema:
type: string
responses:
"200":
description: Remote clusters retrieval successful
content:
application/json:
schema:
type: array
items:
$ref: "#/components/schemas/RemoteClusterInfo"
"400":
$ref: "#/components/responses/BadRequest"
"401":
$ref: "#/components/responses/Unauthorized"
"403":
$ref: "#/components/responses/Forbidden"
"404":
$ref: "#/components/responses/NotFound"
"/api/v4/sharedchannels/users/{user_id}/can_dm/{other_user_id}":
get:
tags:
- shared channels
summary: Check if user can DM another user in shared channels context
description: |
Checks if a user can send direct messages to another user, considering shared channel restrictions.
This is specifically for shared channels where DMs require direct connections between clusters.
__Minimum server version__: 10.11
##### Permissions
Must be authenticated and have permission to view the user.
operationId: CanUserDirectMessage
parameters:
- name: user_id
in: path
description: User GUID
required: true
schema:
type: string
- name: other_user_id
in: path
description: Other user GUID
required: true
schema:
type: string
responses:
"200":
description: DM permission check successful
content:
application/json:
schema:
type: object
properties:
can_dm:
type: boolean
description: Whether the user can send DMs to the other user
"400":
$ref: "#/components/responses/BadRequest"
"401":
$ref: "#/components/responses/Unauthorized"
"403":
$ref: "#/components/responses/Forbidden"
"404":
$ref: "#/components/responses/NotFound"

Просмотреть файл

@@ -611,6 +611,37 @@
$ref: "#/components/responses/BadRequest"
"501":
$ref: "#/components/responses/NotImplemented"
/api/v4/license/load_metric:
get:
tags:
- system
summary: Get license load metric
description: >
Get the current license load metric, calculated based on monthly active users
against the licensed user count. Returns a value of 0 when there is no license loaded or
the license doesn't have a user count.
__Minimum server version__: 10.8
##### Permissions
Must be logged in.
operationId: GetLicenseLoadMetric
responses:
"200":
description: License load metric retrieval successful
content:
application/json:
schema:
type: object
properties:
load:
type: integer
description: Current license load metric as an integer
"401":
$ref: "#/components/responses/Unauthorized"
"500":
$ref: "#/components/responses/InternalServerError"
/api/v4/license/renewal:
get:
tags:

Просмотреть файл

@@ -74,6 +74,61 @@
$ref: "#/components/responses/Unauthorized"
"403":
$ref: "#/components/responses/Forbidden"
/api/v4/users/login/sso/code-exchange:
post:
deprecated: true
tags:
- users
summary: Exchange SSO login code for session tokens
description: >
Exchange a short-lived login_code for session tokens using SAML code exchange (mobile SSO flow).
**Deprecated:** This endpoint is deprecated and will be removed in a future release.
Mobile clients should use the direct SSO callback flow instead.
##### Permissions
No permission required.
operationId: LoginSSOCodeExchange
requestBody:
content:
application/json:
schema:
type: object
required:
- login_code
- code_verifier
- state
properties:
login_code:
description: Short-lived one-time code from SSO callback
type: string
code_verifier:
description: SAML verifier to prove code possession
type: string
state:
description: State parameter to prevent CSRF attacks
type: string
description: SSO code exchange object
required: true
responses:
"200":
description: Code exchange successful
content:
application/json:
schema:
type: object
properties:
token:
description: Session token for authentication
type: string
csrf:
description: CSRF token for request validation
type: string
"400":
$ref: "#/components/responses/BadRequest"
"403":
$ref: "#/components/responses/Forbidden"
/api/v4/users/logout:
post:
tags:
@@ -3266,3 +3321,25 @@
$ref: "#/components/responses/Unauthorized"
"403":
$ref: "#/components/responses/Forbidden"
"/api/v4/users/{user_id}/reset_failed_attempts":
post:
tags:
- users
summary: Reset the failed password attempts for a user
description: |
Reset the FailedAttempts field for a user to 0. This will only work for ldap and email/password users.
##### Permissions
Requires `sysconsole_write_user_management_users` permission.
operationId: resetPasswordFailedAttempts
responses:
"200":
description: User's thread update successful
"400":
$ref: "#/components/responses/BadRequest"
"401":
$ref: "#/components/responses/Unauthorized"
"404":
$ref: "#/components/responses/NotFound"

Просмотреть файл

@@ -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='tests/functional/system_console/system_users/actions.spec.ts --project=chrome' ;;
export TEST_FILTER_DEFAULT='functional/system_console/system_users/actions.spec.ts' ;;
* )
export TEST_FILTER_DEFAULT='' ;;
esac

Просмотреть файл

@@ -14,17 +14,20 @@ 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
: ${TEST:?} # See E2E tests' readme
: ${TEST:?} # See E2E tests' readme
: ${BRANCH:?} # May be either a ref, a commit hash, or 'server-pr-PR_NUMBER' (if TYPE=PR)
: ${BUILD_ID:?}
: ${SERVER:?} # May be either 'onprem' or 'cloud'
@@ -56,20 +59,27 @@ if [ -n "${TM4J_API_KEY:-}" ]; then
# Assert that the test type is among the ones supported by Zephyr, and select the corresponding folderId
case "${SERVER}-${TYPE}" in
onprem-RELEASE)
export TM4J_FOLDER_ID="2014475" ;;
export TM4J_FOLDER_ID="2014475"
;;
onprem-MASTER)
export TM4J_FOLDER_ID="2014476" ;;
export TM4J_FOLDER_ID="2014476"
;;
onprem-MASTER_UNSTABLE)
export TM4J_FOLDER_ID="2014478" ;;
export TM4J_FOLDER_ID="2014478"
;;
cloud-RELEASE)
export TM4J_FOLDER_ID="2014474" ;;
export TM4J_FOLDER_ID="2014474"
;;
cloud-CLOUD)
export TM4J_FOLDER_ID="2014479" ;;
export TM4J_FOLDER_ID="2014479"
;;
cloud-CLOUD_UNSTABLE)
export TM4J_FOLDER_ID="2014481" ;;
export TM4J_FOLDER_ID="2014481"
;;
*)
mme2e_log "Error: unsupported Zephyr environment for the requested report (SERVER=${SERVER}, TYPE=${TYPE}). Aborting." >&2
exit 1
;;
esac
: ${TEST_CYCLE_LINK_PREFIX:?}
: ${TM4J_CYCLE_KEY:-} # Optional. Populated automatically by the reporting script
@@ -97,15 +107,15 @@ if [ ! -d "results/" ]; then
fi
case "$TEST" in
cypress)
npm i
node save_report.js
;;
playwright)
if [ -n "$WEBHOOK_URL" ]; then
PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD=1 npm i
# Utilize environment data and report files to generate the webhook body
./report.webhookgen.js | curl -X POST -fsSL -H 'Content-Type: application/json' -d @- "$WEBHOOK_URL"
fi
;;
cypress)
npm i
node save_report.js
;;
playwright)
if [ -n "$WEBHOOK_URL" ]; then
PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD=1 npm i
# Utilize environment data and report files to generate the webhook body
node report.webhookgen.js | curl -X POST -fsSL -H 'Content-Type: application/json' -d @- "$WEBHOOK_URL"
fi
;;
esac

Просмотреть файл

@@ -48,6 +48,7 @@ generate_docker_compose_file() {
services:
server:
image: \${SERVER_IMAGE}
platform: linux/amd64
restart: always
env_file:
- "./.env.server"
@@ -61,9 +62,12 @@ services:
MM_CLUSTERSETTINGS_READONLYCONFIG: "false"
MM_SERVICEENVIRONMENT: "test"
MM_FEATUREFLAGS_MOVETHREADSENABLED: "true"
MM_FEATUREFLAGS_CUSTOMPROFILEATTRIBUTES: "true"
MM_LOGSETTINGS_ENABLEDIAGNOSTICS: "false"
MM_LOGSETTINGS_CONSOLELEVEL: "DEBUG"
network_mode: host
ports:
- "8065:8065"
depends_on:
$(for service in $ENABLED_DOCKER_SERVICES; do
# The server container will start only if all other dependent services are healthy
@@ -78,7 +82,7 @@ $(for service in $ENABLED_DOCKER_SERVICES; do
$(if mme2e_is_token_in_list "postgres" "$ENABLED_DOCKER_SERVICES"; then
echo '
postgres:
image: mattermostdevelopment/mirrored-postgres:13
image: mattermostdevelopment/mirrored-postgres:14
restart: "no"
network_mode: host
networks: !reset []
@@ -136,7 +140,7 @@ $(if mme2e_is_token_in_list "openldap" "$ENABLED_DOCKER_SERVICES"; then
fi)
$(if mme2e_is_token_in_list "elasticsearch" "$ENABLED_DOCKER_SERVICES"; then
echo '
echo '
elasticsearch:
restart: "no"
network_mode: host
@@ -160,7 +164,7 @@ $(if mme2e_is_token_in_list "elasticsearch" "$ENABLED_DOCKER_SERVICES"; then
fi)
$(if mme2e_is_token_in_list "opensearch" "$ENABLED_DOCKER_SERVICES"; then
echo '
echo '
opensearch:
restart: "no"
network_mode: host
@@ -178,7 +182,7 @@ $(if mme2e_is_token_in_list "opensearch" "$ENABLED_DOCKER_SERVICES"; then
fi)
$(if mme2e_is_token_in_list "redis" "$ENABLED_DOCKER_SERVICES"; then
echo '
echo '
redis:
restart: "no"
network_mode: host
@@ -276,7 +280,7 @@ $(if mme2e_is_token_in_list "webhook-interactions" "$ENABLED_DOCKER_SERVICES"; t
$(if mme2e_is_token_in_list "playwright" "$ENABLED_DOCKER_SERVICES"; then
echo '
playwright:
image: mcr.microsoft.com/playwright:v1.49.1-noble
image: mcr.microsoft.com/playwright:v1.53.0-noble
entrypoint: ["/bin/bash", "-c"]
command: ["until [ -f /var/run/mm_terminate ]; do sleep 5; done"]
env_file:
@@ -293,7 +297,7 @@ $(if mme2e_is_token_in_list "playwright" "$ENABLED_DOCKER_SERVICES"; then
PW_RESET_BEFORE_TEST: "false"
PW_HEADLESS: "true"
PW_SLOWMO: 0
PW_WORKERS: 2
PW_WORKERS: 1
PW_SNAPSHOT_ENABLE: "false"
PW_PERCY_ENABLE: "false"
ulimits:
@@ -335,11 +339,11 @@ generate_env_files() {
# Generating service-specific env vars
for SERVICE in $ENABLED_DOCKER_SERVICES; do
case $SERVICE in
case $SERVICE in
opensearch)
echo "MM_ELASTICSEARCHSETTINGS_BACKEND=opensearch" >>.env.server
;;
esac
esac
done
# Generating TEST-specific env files
@@ -373,7 +377,7 @@ generate_env_files() {
keycloak)
echo "CYPRESS_keycloakBaseUrl=http://localhost:8484" >>.env.cypress
;;
elasticsearch|opensearch)
elasticsearch | opensearch)
echo "CYPRESS_elasticsearchConnectionURL=http://localhost:9200" >>.env.cypress
;;
esac
@@ -382,8 +386,8 @@ generate_env_files() {
case "$SERVER" in
cloud)
echo "CYPRESS_serverEdition=Cloud" >>.env.cypress
echo "CYPRESS_cwsURL=${CWS_URL}" >> .env.cypress
echo "CYPRESS_cwsAPIURL=${CWS_URL}" >> .env.cypress
echo "CYPRESS_cwsURL=${CWS_URL}" >>.env.cypress
echo "CYPRESS_cwsAPIURL=${CWS_URL}" >>.env.cypress
;;
*)
echo "CYPRESS_serverEdition=E20" >>.env.cypress

Просмотреть файл

@@ -5,11 +5,10 @@ cd "$(dirname "$0")"
mme2e_log "Configuring starting server parameters that may be changed at runtime"
for SETTING in \
TeamSettings.EnableOpenServer=true \
PluginSettings.Enable=true \
PluginSettings.EnableUploads=true \
PluginSettings.AutomaticPrepackagedPlugins=true
do
TeamSettings.EnableOpenServer=true \
PluginSettings.Enable=true \
PluginSettings.EnableUploads=true \
PluginSettings.AutomaticPrepackagedPlugins=true; do
mme2e_log "Configuring parameter: $SETTING"
# shellcheck disable=SC2046
${MME2E_DC_SERVER} exec -T -- server mmctl --local config set $(tr '=' ' ' <<<$SETTING)
@@ -23,24 +22,30 @@ fi
if [ "$TEST" = "cypress" ]; then
mme2e_log "Prepare Cypress: install dependencies"
${MME2E_DC_SERVER} exec -T -u 0 -- cypress bash -c "id $MME2E_UID || useradd -u $MME2E_UID -m nodeci" # Works around the node image's assumption that the app files are owned by user 1000
# Create user in Cypress container and work around the node image's assumption that the app files are owned by user 1000
mme2e_log "Creating user for Cypress container"
${MME2E_DC_SERVER} exec -T -u 0 -- cypress bash -c "id $MME2E_UID || useradd -u $MME2E_UID -m nodeci"
${MME2E_DC_SERVER} exec -T -u "$MME2E_UID" -- cypress npm i
${MME2E_DC_SERVER} exec -T -u "$MME2E_UID" -- cypress cypress install
mme2e_log "Prepare Cypress: populating fixtures"
${MME2E_DC_SERVER} exec -T -u "$MME2E_UID" -- cypress tee tests/fixtures/keycloak.crt >/dev/null <../../server/build/docker/keycloak/keycloak.crt
# Download plugins using wget in the Cypress container
for PLUGIN_URL in \
"https://github.com/mattermost/mattermost-plugin-gitlab/releases/download/v1.3.0/com.github.manland.mattermost-plugin-gitlab-1.3.0.tar.gz" \
"https://github.com/mattermost/mattermost-plugin-demo/releases/download/v0.9.0/com.mattermost.demo-plugin-0.9.0.tar.gz" \
"https://github.com/mattermost/mattermost-plugin-demo/releases/download/v0.8.0/com.mattermost.demo-plugin-0.8.0.tar.gz"
do
"https://github.com/mattermost/mattermost-plugin-demo/releases/download/v0.8.0/com.mattermost.demo-plugin-0.8.0.tar.gz"; do
PLUGIN_NAME="${PLUGIN_URL##*/}"
PLUGIN_PATH="tests/fixtures/$PLUGIN_NAME"
# Check if file exists
if ${MME2E_DC_SERVER} exec -T -u "$MME2E_UID" -- cypress test -f "$PLUGIN_PATH"; then
mme2e_log "Skipping installation of plugin $PLUGIN_NAME: file exists"
continue
fi
# Use wget in the Cypress container instead of curl in server (for distroless compatibility)
mme2e_log "Downloading $PLUGIN_NAME to fixtures directory"
${MME2E_DC_SERVER} exec -T -- server curl -L --silent "${PLUGIN_URL}" | ${MME2E_DC_SERVER} exec -T -u "$MME2E_UID" -- cypress tee "$PLUGIN_PATH" >/dev/null
${MME2E_DC_SERVER} exec -T -u "$MME2E_UID" -- cypress wget -q -O "/cypress/$PLUGIN_PATH" "$PLUGIN_URL"
done
fi
@@ -55,6 +60,8 @@ for SERVICE in $ENABLED_DOCKER_SERVICES; do
continue
fi
mme2e_log "Configuring the $SERVICE container"
${MME2E_DC_SERVER} exec -T openldap bash -c 'ldapadd -Y EXTERNAL -H ldapi:/// -w mostest || true' <../../server/tests/custom-schema-objectID.ldif
${MME2E_DC_SERVER} exec -T -- openldap bash -c 'ldapadd -Y EXTERNAL -H ldapi:/// -w mostest || true' <../../server/tests/custom-schema-cpa.ldif
${MME2E_DC_SERVER} exec -T -- openldap bash -c 'ldapadd -x -D "cn=admin,dc=mm,dc=test,dc=com" -w mostest' <../../server/tests/test-data.ldif
;;
minio)

Просмотреть файл

@@ -42,7 +42,7 @@ else
fi
# Collect run results
cat > ../cypress/results/summary.json <<EOF
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),
@@ -51,4 +51,4 @@ cat > ../cypress/results/summary.json <<EOF
EOF
# Collect server logs
${MME2E_DC_SERVER} logs --no-log-prefix -- server > "../cypress/logs/${LOGFILE_SUFFIX}_mattermost.log" 2>&1
${MME2E_DC_SERVER} logs --no-log-prefix -- server >"../cypress/logs/${LOGFILE_SUFFIX}_mattermost.log" 2>&1

Просмотреть файл

@@ -37,14 +37,12 @@ EOF
# Run Playwright test
# NB: do not exit the script if some testcases fail
${MME2E_DC_SERVER} exec -i -u "$MME2E_UID" -- playwright bash -c "cd e2e-tests/playwright && npm run test -- ${TEST_FILTER}" | tee ../playwright/logs/playwright.log || true
${MME2E_DC_SERVER} exec -i -u "$MME2E_UID" -- playwright bash -c "cd e2e-tests/playwright && npm run test:ci -- ${TEST_FILTER} ${PW_SHARD:-}" | tee ../playwright/logs/playwright.log || true
# Collect run results
# Documentation on the results.json file: https://playwright.dev/docs/api/class-testcase#test-case-expected-status
# NB: the following line is needed only for compatibility reasons, to support RollingRelease tests for versions prior to v10.1.0
# It can be removed after releases <=v10.0.x are phased out
mv -v ../playwright/playwright-report/results.json ../playwright/results/reporter/results.json 2>/dev/null || true
jq -f /dev/stdin ../playwright/results/reporter/results.json > ../playwright/results/summary.json <<EOF
jq -f /dev/stdin ../playwright/results/reporter/results.json >../playwright/results/summary.json <<EOF
{
passed: .stats.expected,
failed: .stats.unexpected,

101
e2e-tests/.ci/server.run_specs.sh Исполняемый файл
Просмотреть файл

@@ -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"

Просмотреть файл

@@ -11,6 +11,13 @@ mme2e_wait_image "$SERVER_IMAGE" 4 30
mme2e_log "Starting E2E containers"
${MME2E_DC_SERVER} create
${MME2E_DC_SERVER} up -d --remove-orphans
# Postgres check
if ! mme2e_wait_command_success "${MME2E_DC_SERVER} exec -T -- postgres pg_isready -h localhost" "Waiting for postgres to accept connections" "30" "5"; then
mme2e_log "Postgres not accepting connections"
exit 1
fi
if ! mme2e_wait_service_healthy server 60 10; then
mme2e_log "Mattermost container not healthy, retry attempts exhausted. Giving up." >&2
exit 1
@@ -18,9 +25,21 @@ fi
# shellcheck disable=SC2043
for MIGRATION in migration_advanced_permissions_phase_2; do
# Query explanation: if it doesn't find the migration in the table, there are 0 results and the command fails with a divide-by-zero error. Otherwise the command succeeds
MIGRATION_CHECK_COMMAND="${MME2E_DC_SERVER} exec -T -- postgres psql -U mmuser mattermost_test -c \"select 1 / (select count(*) from Systems where name = '${MIGRATION}' and value = 'true');\""
if ! mme2e_wait_command_success "$MIGRATION_CHECK_COMMAND >/dev/null 2>&1" "Waiting for migration to be completed: ${MIGRATION}" "30" "10"; then
MIGRATION_CHECK_COMMAND="${MME2E_DC_SERVER} exec -T postgres sh -c 'PGPASSWORD=mostest psql -U mmuser mattermost_test -c \"select 1 / (select count(*) from Systems where name = '\''${MIGRATION}'\'' and value = '\''true'\'');\"'"
if ! mme2e_wait_command_success "$MIGRATION_CHECK_COMMAND" "Waiting for migration to be completed: ${MIGRATION}" "10" "10"; then
mme2e_log "Migration ${MIGRATION} not completed, retry attempts exhausted. Giving up." >&2
LOG_DIR="../${TEST}/logs"
mkdir -p "$LOG_DIR"
# Save server logs to a file
${MME2E_DC_SERVER} logs --no-log-prefix -- server >"$LOG_DIR/server.log"
mme2e_log "Server logs saved to server.log"
# Save postgres logs to a file
${MME2E_DC_SERVER} logs --no-log-prefix -- postgres >"$LOG_DIR/postgres.log"
mme2e_log "Postgres logs saved to postgres.log"
exit 2
fi
mme2e_log "${MIGRATION}: completed."

Просмотреть файл

@@ -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

17
e2e-tests/cypress/package-lock.json сгенерированный
Просмотреть файл

@@ -42,6 +42,7 @@
"cypress-file-upload": "5.0.8",
"cypress-multi-reporters": "1.6.4",
"cypress-plugin-tab": "1.0.5",
"cypress-real-events": "1.14.0",
"cypress-wait-until": "3.0.1",
"dayjs": "1.11.10",
"deepmerge": "4.3.1",
@@ -4611,6 +4612,15 @@
"ally.js": "^1.4.1"
}
},
"node_modules/cypress-real-events": {
"version": "1.14.0",
"resolved": "https://registry.npmjs.org/cypress-real-events/-/cypress-real-events-1.14.0.tgz",
"integrity": "sha512-XmI8y3OZLh6cjRroPalzzS++iv+pGCaD9G9kfIbtspgv7GVsDt30dkZvSXfgZb4rAN+3pOkMVB7e0j4oXydW7Q==",
"dev": true,
"peerDependencies": {
"cypress": "^4.x || ^5.x || ^6.x || ^7.x || ^8.x || ^9.x || ^10.x || ^11.x || ^12.x || ^13.x || ^14.x"
}
},
"node_modules/cypress-wait-until": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/cypress-wait-until/-/cypress-wait-until-3.0.1.tgz",
@@ -14931,6 +14941,13 @@
"ally.js": "^1.4.1"
}
},
"cypress-real-events": {
"version": "1.14.0",
"resolved": "https://registry.npmjs.org/cypress-real-events/-/cypress-real-events-1.14.0.tgz",
"integrity": "sha512-XmI8y3OZLh6cjRroPalzzS++iv+pGCaD9G9kfIbtspgv7GVsDt30dkZvSXfgZb4rAN+3pOkMVB7e0j4oXydW7Q==",
"dev": true,
"requires": {}
},
"cypress-wait-until": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/cypress-wait-until/-/cypress-wait-until-3.0.1.tgz",

Просмотреть файл

@@ -37,6 +37,7 @@
"cypress-file-upload": "5.0.8",
"cypress-multi-reporters": "1.6.4",
"cypress-plugin-tab": "1.0.5",
"cypress-real-events": "1.14.0",
"cypress-wait-until": "3.0.1",
"dayjs": "1.11.10",
"deepmerge": "4.3.1",

Двоичные данные
e2e-tests/cypress/tests/fixtures/bot-default-avatar.png поставляемый

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 3.3 KiB

После

Ширина:  |  Высота:  |  Размер: 2.4 KiB

Просмотреть файл

@@ -1,23 +0,0 @@
{
"checklists": [
{
"items": [
{
"title": "Untitled task"
}
],
"title": "Default checklist"
}
],
"create_channel_member_on_new_participant": true,
"create_channel_member_on_removed_participant": true,
"description": "Customize this playbook's description to give an overview of when and how this playbook is run.",
"message_on_join": "Welcome! This channel was automatically created as part of a playbook run.",
"metrics": [],
"reminder_timer_default_seconds": 604800,
"retrospective_enabled": true,
"retrospective_template": "### Summary\nThis should contain 2-3 sentences that give a reader an overview of what happened, what was the cause, and what was done. The briefer the better as this is what future teams will look at first for reference.\n\n### What was the impact?\nThis section describes the impact of this playbook run as experienced by internal and external customers as well as stakeholders.\n\n### What were the contributing factors?\nThis playbook may be a reactive protocol to a situation that is otherwise undesirable. If that's the case, this section explains the reasons that caused the situation in the first place. There may be multiple root causes - this helps stakeholders understand why.\n\n### What was done?\nThis section tells the story of how the team collaborated throughout the event to achieve the outcome. This will help future teams learn from this experience on what they could try.\n\n### What did we learn?\nThis section should include perspective from everyone that was involved to celebrate the victories and identify areas for improvement. For example: What went well? What didn't go well? What should be done differently next time?\n\n### Follow-up tasks\nThis section lists the action items to turn learnings into changes that help the team become more proficient with iterations. It could include tweaking the playbook, publishing the retrospective, or other improvements. The best follow-ups will have a clear owner as well as due date.\n\n### Timeline highlights\nThis section is a curated log that details the most important moments. It can contain key communications, screen shots, or other artifacts. Use the built-in timeline feature to help you retrace and replay the sequence of events.",
"status_update_enabled": true,
"title": "Example Playbook",
"version": 1
}

Просмотреть файл

@@ -50,6 +50,7 @@ describe('Verify Accessibility Support in different sections in Settings and Pro
{key: 'click_to_reply', label: 'Click to open threads', type: 'radio'},
{key: 'channel_display_mode', label: 'Channel Display', type: 'radio'},
{key: 'one_click_reactions_enabled', label: 'Quick reactions on messages', type: 'radio'},
{key: 'renderEmoticonsAsEmoji', label: 'Render emoticons as emojis', type: 'radio'},
{key: 'languages', label: 'Language', type: 'dropdown'},
],
sidebar: [
@@ -169,36 +170,43 @@ describe('Verify Accessibility Support in different sections in Settings and Pro
cy.get('#displayButton').click();
cy.get('#languagesEdit').click();
cy.get('#displayLanguage').within(() => {
cy.get('input').should('have.attr', 'aria-autocomplete', 'list').and('have.attr', 'aria-labelledby', 'changeInterfaceLanguageLabel').as('inputEl');
});
cy.findByRole('combobox', {name: 'Dropdown selector to change the interface language'}).should('have.attr', 'aria-autocomplete', 'list').and('have.attr', 'aria-labelledby', 'changeInterfaceLanguageLabel').as('inputEl');
cy.get('#changeInterfaceLanguageLabel').should('be.visible').and('have.text', 'Change interface language');
// # When enter key is pressed on dropdown, it should expand and collapse
cy.get('@inputEl').typeWithForce('{enter}');
cy.get('#displayLanguage>div').should('have.class', 'react-select__control--menu-is-open');
cy.get('@inputEl').typeWithForce('{enter}');
cy.get('#displayLanguage>div').should('not.have.class', 'react-select__control--menu-is-open');
// # When space key is pressed on dropdown, it should expand and should collapse when esc key is pressed
cy.get('@inputEl').typeWithForce(' ');
cy.findByRole('listbox').should('have.class', 'react-select__menu-list').as('listBox');
cy.get('@inputEl').typeWithForce('{esc}');
cy.get('@listBox').should('not.exist');
// # Press down arrow twice and check aria label
cy.get('@inputEl').typeWithForce('{enter}');
cy.get('@inputEl').typeWithForce(' ');
cy.get('@inputEl').typeWithForce('{downarrow}{downarrow}');
cy.get('#displayLanguage>span').as('ariaEl').within(($el) => {
cy.wrap($el).should('have.attr', 'aria-live', 'assertive');
cy.get('#aria-context').should('contain', 'option English (Australia) focused').and('contain', 'Use Up and Down to choose options, press Enter to select the currently focused option, press Escape to exit the menu, press Tab to select the option and exit the menu.');
cy.get('#displayLanguage').within(($el) => {
cy.wrap($el).findByRole('log').should('have.attr', 'aria-live', 'assertive').as('ariaEl');
});
cy.get('@ariaEl').within(($el) => {
cy.wrap($el).get('#aria-focused').should('contain', 'option English (Australia) focused');
cy.wrap($el).get('#aria-guidance').should('contain', 'Use Up and Down to choose options, press Enter to select the currently focused option, press Escape to exit the menu, press Tab to select the option and exit the menu.');
});
// # Check if language setting gets changed after user presses enter
cy.get('@inputEl').typeWithForce('{enter}');
// # Check if language setting gets changed after user presses space
cy.get('@inputEl').typeWithForce(' ');
cy.get('#displayLanguage').should('contain', 'English (Australia)');
cy.get('@ariaEl').get('#aria-selection-event').should('contain', 'option English (Australia), selected');
cy.get('@ariaEl').within(($el) => {
cy.wrap($el).get('#aria-selection').should('contain', 'option English (Australia) selected');
});
// # Press down arrow, then up arrow and press enter
// # Press down arrow, then up arrow and press space
cy.get('@inputEl').typeWithForce('{downarrow}{downarrow}{downarrow}{uparrow}');
cy.get('@ariaEl').get('#aria-context').should('contain', 'option English (US) focused');
cy.get('@inputEl').typeWithForce('{enter}');
cy.get('@ariaEl').within(($el) => {
cy.wrap($el).get('#aria-focused').should('contain', 'option English (US) focused');
});
cy.get('@inputEl').typeWithForce(' ');
cy.get('#displayLanguage').should('contain', 'English (US)');
cy.get('@ariaEl').get('#aria-selection-event').should('contain', 'option English (US), selected');
cy.get('@ariaEl').within(($el) => {
cy.wrap($el).get('#aria-selection').should('contain', 'option English (US) selected');
});
});
it('MM-T1488 Profile Picture should read labels', () => {

Просмотреть файл

@@ -105,9 +105,9 @@ describe('Verify Accessibility Support in Dropdown Menus', () => {
{id: 'invitePeople', label: 'Invite People dialog'},
{id: 'teamSettings', label: 'Team Settings dialog'},
{id: 'manageMembers', label: 'Manage Members dialog'},
{id: 'joinTeam', text: 'Join Another Team'},
{id: 'joinTeam', text: 'Join another team'},
{id: 'leaveTeam', label: 'Leave Team dialog'},
{id: 'createTeam', text: 'Create a Team'},
{id: 'createTeam', text: 'Create a team'},
];
menuItems.forEach((item) => {

Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше