Skip to content

This PR overhauls the Dockerfile.custom build process to support cross-architecture builds and significantly optimizes build performance.#6

Open
nihaldivyam wants to merge 170 commits into
masterfrom
mattermost-oidc-fix
Open

This PR overhauls the Dockerfile.custom build process to support cross-architecture builds and significantly optimizes build performance.#6
nihaldivyam wants to merge 170 commits into
masterfrom
mattermost-oidc-fix

Conversation

@nihaldivyam

Copy link
Copy Markdown
Member

Build Performance & Context

  • Optimized Build Context: Created a .dockerignore file to exclude node_modules, .parcel-cache, and other local build artifacts. This reduced the build context transfer
    from 1.44GB to ~1MB, dramatically speeding up the initial build phase.
  • Improved Layer Caching:
    • Restructured the webapp builder to copy workspace package.json files individually before running npm ci, allowing for better Docker layer caching when source files
      change.
    • Restructured the server builder to copy go.work and the public module's dependency files before downloading modules.

Native Dependency & Architecture Support

  • Node.js Environment: Switched the webapp-builder to Node 22 (LTS) for better compatibility with native modules like canvas on modern V8 versions.
  • System Libraries: Added required Debian libraries (libcairo2-dev, libpango1.0-dev, libjpeg-dev, pkg-config, etc.) to the builder stage to ensure native modules can be
    compiled for Linux ARM64.
  • Native Module Handling:
    • Implemented npm ci --ignore-scripts followed by a targeted npm rebuild canvas to ensure native bindings are correct for the target OS without triggering
      problematic image optimization binaries.
  • Go Build Fixes:
    • Updated Go version to 1.26.1 to satisfy go.work requirements.
    • Fixed the go build target to ./cmd/mattermost to resolve "multiple packages" errors and ensure a single binary output.

Webapp Optimization

  • Optional Image Optimization: Modified webapp/channels/webpack.config.js to support the SKIP_IMAGE_OPTIMIZATION environment variable. This allows the Docker build to
    bypass image-webpack-loader (which often fails on ARM64 due to incompatible pre-built binaries for optipng and gifsicle) while maintaining a production-ready
    configuration.

Verification Results

  • Successfully built the Mattermost production image on an ARM64 host (Mac Apple Silicon) targeting Linux ARM64.
  • Verified that both the server and mmctl binaries are correctly built and placed in the final image.
  • Verified that webapp assets are correctly compiled and copied to the /mattermost/client directory.

esarafianou and others added 30 commits April 1, 2026 14:12
…attermost#35842)

* Use repo checkout for Dockerfile in server-ci-artifacts build-docker job

The build-docker job was downloading server-build-artifact to get the
Dockerfile and supporting files for every PR. Switch to checking out
server/build/ directly from the repo for external PRs, while keeping
the artifact-based flow for same-repo PRs so that Dockerfile changes
can be tested before merge.

Only upload server-build-artifact when the PR comes from the same repo,
since external PRs no longer use it.

Made-with: Cursor

* retrigger pipelines

* undo previous commit

---------

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

* dont .gitignore AGENTS.md

* AGENTS.md to document previous CODEOWNERS responsibilities

* update from https://developers.mattermost.com/contribute/more-info/server/schema-migration-guide/

* CREATE INDEX CONCURRENTLY now vetted

* rewrite and move to README.md

* dont limit to 80 chars

* rewrite webapp AGENTS.md and add to README.md

---------

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

* fix style issues

* simplify the openApiSync spec test

* README.md tweaks

* fix missing licenses

* simplify README.md

* trigger server-ci on tools/mattermost-govet/**

* Apply mattermost/mattermost-govet@470cf78

---------

Co-authored-by: Mattermost Build <build@mattermost.com>
* replace for tablewriter not longer needed

jaytaylof/html2text project has been updated and now it supports
tablewriter 1.0.0

* Replace fwSeeker with bufReadSeeker to support backward seeks for imagemeta v0.17

* Bump server dependencies (includes imagemeta v0.12→v0.17)

* revert the imagemeta upgrade to reduce risk this time

* modules-tidy

---------

Co-authored-by: Jesse Hallam <jesse@mattermost.com>
…ayering violation (mattermost#35805)a

* Move password hashers from server/v8 to server/public to fix layering violation

* Revert "Move password hashers from server/v8 to server/public to fix layering violation"

This reverts commit 8cad5b8.

* invert dependency between hashers and model

* make modules-tidy

---------

Co-authored-by: Jesse Hallam <jesse@mattermost.com>
Co-authored-by: Mattermost Build <build@mattermost.com>
Co-authored-by: Mattermost Build <build@mattermost.com>
…ermost#35915)

The SupportSettings.AllowDownloadLogs toggle in Site Configuration >
Customization was missing the RESOURCE_KEYS.SITE.CUSTOMIZATION
write-permission guard that all neighboring controls have, allowing
read-only admins to toggle it when they shouldn't be able to.

Co-authored-by: Mattermost Build <build@mattermost.com>
* Translated using Weblate (Russian)

Currently translated at 86.2% (2583 of 2996 strings)

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

* Translated using Weblate (Russian)

Currently translated at 86.8% (2603 of 2996 strings)

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

* Translated using Weblate (Norwegian Bokmål)

Currently translated at 77.4% (5489 of 7087 strings)

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

* Translated using Weblate (Norwegian Bokmål)

Currently translated at 77.6% (5503 of 7087 strings)

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

* Translated using Weblate (Polish)

Currently translated at 98.2% (2943 of 2996 strings)

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

* Translated using Weblate (Russian)

Currently translated at 89.0% (2667 of 2996 strings)

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

* Translated using Weblate (Norwegian Bokmål)

Currently translated at 78.0% (5530 of 7087 strings)

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

* Translated using Weblate (Polish)

Currently translated at 97.0% (6877 of 7087 strings)

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

* Translated using Weblate (Polish)

Currently translated at 98.3% (2948 of 2996 strings)

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

* Translated using Weblate (Portuguese)

Currently translated at 6.9% (207 of 2996 strings)

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

* Translated using Weblate (Portuguese)

Currently translated at 28.2% (1999 of 7087 strings)

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

* Translated using Weblate (Portuguese)

Currently translated at 28.3% (2012 of 7087 strings)

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

* Translated using Weblate (Norwegian Bokmål)

Currently translated at 78.2% (5546 of 7087 strings)

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

* Translated using Weblate (Norwegian Bokmål)

Currently translated at 78.2% (5548 of 7087 strings)

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

* Translated using Weblate (Norwegian Bokmål)

Currently translated at 78.6% (5577 of 7087 strings)

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

* Translated using Weblate (Norwegian Bokmål)

Currently translated at 78.8% (5591 of 7087 strings)

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

* Translated using Weblate (Dutch)

Currently translated at 100.0% (2996 of 2996 strings)

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

* Translated using Weblate (Polish)

Currently translated at 99.0% (2968 of 2996 strings)

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

* Translated using Weblate (Dutch)

Currently translated at 100.0% (7087 of 7087 strings)

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

* Translated using Weblate (Norwegian Bokmål)

Currently translated at 78.9% (5597 of 7087 strings)

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

* Translated using Weblate (Polish)

Currently translated at 97.2% (6894 of 7087 strings)

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

* Translated using Weblate (Norwegian Bokmål)

Currently translated at 79.1% (5608 of 7087 strings)

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

* Translated using Weblate (Swedish)

Currently translated at 91.9% (6513 of 7087 strings)

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

* Translated using Weblate (German)

Currently translated at 100.0% (2997 of 2997 strings)

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

* Translated using Weblate (Polish)

Currently translated at 100.0% (2997 of 2997 strings)

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

* Translated using Weblate (Polish)

Currently translated at 97.4% (6903 of 7087 strings)

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

* Translated using Weblate (Swedish)

Currently translated at 92.0% (6523 of 7087 strings)

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

* Translated using Weblate (Polish)

Currently translated at 97.8% (6932 of 7087 strings)

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

* Translated using Weblate (Russian)

Currently translated at 78.3% (5553 of 7087 strings)

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

* Translated using Weblate (Norwegian Bokmål)

Currently translated at 79.2% (5615 of 7087 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.3% (5622 of 7087 strings)

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

* Translated using Weblate (Russian)

Currently translated at 78.6% (5575 of 7087 strings)

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

* Translated using Weblate (Russian)

Currently translated at 78.9% (5597 of 7087 strings)

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

* Translated using Weblate (Norwegian Bokmål)

Currently translated at 79.3% (5623 of 7087 strings)

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

* Translated using Weblate (Japanese)

Currently translated at 88.8% (6294 of 7087 strings)

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

* Translated using Weblate (Polish)

Currently translated at 97.8% (6933 of 7087 strings)

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

* Translated using Weblate (Japanese)

Currently translated at 89.0% (6308 of 7087 strings)

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

* Translated using Weblate (Polish)

Currently translated at 98.0% (6947 of 7087 strings)

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

* Translated using Weblate (Japanese)

Currently translated at 89.3% (6329 of 7087 strings)

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

* Update translation files

Updated by "Cleanup translation files" hook in Weblate.

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

* Update translation files

Updated by "Cleanup translation files" hook in Weblate.

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

* Translated using Weblate (Japanese)

Currently translated at 90.0% (6385 of 7089 strings)

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

* Translated using Weblate (German)

Currently translated at 99.9% (7085 of 7089 strings)

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

* Translated using Weblate (Norwegian Bokmål)

Currently translated at 79.4% (5629 of 7089 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.4% (5631 of 7089 strings)

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

* Translated using Weblate (Russian)

Currently translated at 79.7% (5656 of 7089 strings)

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

---------

Co-authored-by: Dmitriy Q <krotesk@mail.ru>
Co-authored-by: Frank Paul Silye <frankps@gmail.com>
Co-authored-by: master7 <marcin.karkosz@rajska.info>
Co-authored-by: Manuela Silva <mmsrs@sky.com>
Co-authored-by: Tom De Moor <tom@controlaltdieliet.be>
Co-authored-by: Kristoffer Grundström <swedishsailfishosuser@tutanota.com>
Co-authored-by: jprusch <rs@schaeferbarthold.de>
Co-authored-by: Takayuki Maruyama <bis5.wsys@gmail.com>
…ompletion (mattermost#35908)

* MM-68158: Fix shared channel remote display and add WebSocket notification

  Fix getSharedChannelRemotes API handler passing ChannelId instead of
  RemoteId to GetRemoteCluster, which always failed the lookup. Add
  RemoteId to SharedChannelRemoteStatus model and store query.

  Add shared_channel_remote_updated WebSocket event published from the
  onInvite callback so the UI refreshes its cached remote names when the
  async invite completes, instead of showing the generic "Shared with
  trusted organizations" fallback.

* Improved unit tests per review comments
Co-authored-by: Mattermost Build <build@mattermost.com>
)

The invite modal's UsersEmailsInput component treated whitespace as a
token delimiter alongside comma and semicolon. This caused typing a
space (e.g., between a first and last name) to split and clear the
input field.

Split the delimiter regex into two: typedInputDelimiter (/[,;]+/) for
interactive typing and pasteDelimiter (/[\s,;]+/) for paste operations
where whitespace-separated values are expected. Added .trim() to split
entries to handle the comma-then-space typing pattern correctly.

Updated onboarding invite description text to reflect the new delimiter
behavior (comma or semicolon instead of space or comma).
…35768)

* (test): vh1-8+EC enzyme to rtl bulk migration

* address comments
* Added nil checks

* Added test for DM and GM

* Updated operation order
…5772)

* Fixing issues with browser channels modal

- Fixing "jumping around" issue on hover due to buttons being rendered dynamically
- Added max width for purpose so it doesn't take up the whole screen when long purpose is written

* Fixing modal overflow in mobile screen sizes

* Simplifying join button layout fix

* Fixing styles to be consistent with existing modals
…termost#35933)

* Fix Enterprise Advanced upsell messaging for Enterprise licenses

Update the license settings upsell panel to highlight only Enterprise Advanced-exclusive capabilities so Enterprise customers are not shown features they already have.

Made-with: Cursor

* Update license settings snapshot for Enterprise upsell

Refresh the Enterprise license snapshot so the license settings test matches the new Enterprise Advanced upsell content.

Made-with: Cursor

---------

Co-authored-by: Mattermost Build <build@mattermost.com>
…er service errors (mattermost#35949)

* Use multi-level logging for shared channel and remote cluster service errors

  Service-specific log levels (LvlRemoteClusterServiceError, LvlSharedChannelServiceError)
  were hidden from the main log by default, requiring explicit configuration to see them.
  Switch all call sites to use LogM with multi-level combos so each log line is attributed
  to both the standard level (error/warn) and the service-specific level. This surfaces
  errors in the main log while preserving the ability to isolate them into dedicated files.

  Each instance was reviewed and either kept as error (DB failures, security issues, config
  errors, exhausted retries on critical data) or downgraded to warn (transient network
  failures, remote-side reported errors with retry logic, non-critical data like profile
  images, reactions, acknowledgements, and status).
Co-authored-by: unified-ci-app[bot] <121569378+unified-ci-app[bot]@users.noreply.github.com>
* fix mock server response for translations

---------

Co-authored-by: Mattermost Build <build@mattermost.com>
…mattermost#35940)

* Update docs-impact workflow to keep stale comment instead of deleting

When a re-run of the docs impact analysis determines that documentation
updates are no longer needed, the previous bot comment was deleted while
the Docs/Needed label was kept. This left the label without context.

Instead of deleting the comment, update it to explain that a previous
analysis had flagged the PR but the latest run found no docs impact.
This preserves the audit trail and gives maintainers context to decide
whether to remove the label.

Made-with: Cursor

* Update .github/workflows/docs-impact-review.yml

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

---------

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Co-authored-by: Nevyana Angelova <nevyangelova@192.168.100.47>
This stops a warning from Babel which points out that passing a minor version
as a number will have issues because 16.2 is identical to 16.20.
* MM-68179: Run sendLoop workers on all HA nodes

  In HA clusters, sendLoop worker goroutines only ran on the leader node.
  When an API request to send a channel invite landed on a non-leader node,
  SendMsg enqueued the task to a local in-memory channel but no goroutine
  consumed it, silently losing the message. Fix by starting sendLoop workers
  in Start() on all nodes, independent of the leader-only ping lifecycle.

  - Separate sendLoop lifecycle (Start/Shutdown) from ping lifecycle
    (pingStart/pingStop on leader change)
  - Rename resume/pause to pingStart/pingStop for clarity
  - Change Active() to mean "service started" via atomic.Bool
  - Remove SetActive (no longer needed; tests use Start())

* address review comment

* Added idempotency guard to Start()

* Start() and Shutdown(): CompareAndSwap instead of Load/Store — eliminates races where concurrent calls could both proceed. Only the winner of the CAS executes; the loser returns nil
  immediately.

Ping test: replaced time.Sleep with assert.Never/assert.Eventually — no more brittle fixed sleeps. Uses assert.Never to verify no pings fire on non-leader, and assert.Eventually to
  verify pings stop after losing leadership (snapshot-then-compare pattern).

* make unit tests parallel capable

---------

Co-authored-by: Mattermost Build <build@mattermost.com>
Log only a 5-character prefix of the password reset token in audit
entries instead of the full 64-character bearer credential (CWE-532).

Co-authored-by: Mattermost Build <build@mattermost.com>
* markdown message preview fixed

* message preview overflow fix

* fix show_more test

* restore package-lock.json

* pull package-lock from master

* package-lock line break

* Fix missing newline at end of package-lock.json

* Update test snapshots

---------

Co-authored-by: David Krauser <david@krauser.org>
Co-authored-by: Mattermost Build <build@mattermost.com>
Co-authored-by: David Krauser <david@kruser.org>
NARSimoes and others added 30 commits April 22, 2026 21:36
Error: Action failed with error: HttpError: Resource not accessible by integration
mattermost#36178
…logs (mattermost#36214)

* Surface ws_event type in oversized cluster publish message logs

When a best-effort UDP gossip send fails with "message too long", the log
only shows event: publish with no further context. Tag the ClusterMessage
with the originating WebSocket event type so it appears in the error log.

* Update enterprise.pin to latest after enterprise PR mattermost#2133 merged

https://claude.ai/code/session_01Y1Abg1eDjKQBJvy7XhCtG6

* Bump

---------

Co-authored-by: Mattermost Build <build@mattermost.com>
Co-authored-by: Claude <noreply@anthropic.com>
* Default template property field permissions to sysadmin

Templates define the schema that linked fields inherit, so their
permission levels should default to sysadmin rather than member. This
aligns the create handler with TestLinkedProperties expectations.

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

* Require sysadmin for template property field creation

The target_type-based scope check lets team admins create template
fields with target_type=team, which would then inherit sysadmin-level
permission defaults and lock the creator out. Enforce manage_system for
any template creation so the permission gate matches the intent of the
"create template field as non-admin fails" test.

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

---------

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…nostics (mattermost#35835)

* MM-67975: Add container CPU and memory limits to support packet diagnostics

Add two new optional fields to SupportPacketDiagnostics.Server:
- container_cpu_limit (float64): effective CPU limit in CPUs (e.g. 0.5, 2.0)
- container_memory_limit_mb (uint64): memory limit in MB

Both fields are populated from cgroups v2 (/sys/fs/cgroup/memory.max and
/sys/fs/cgroup/cpu.max) on Linux. Fields use omitempty so they are absent
from the output on bare metal or when no container limits are configured,
preserving backwards compatibility.

Non-Linux builds compile and produce no output for these fields via a
container_limits_other.go stub, following the existing memory_linux.go /
memory_other.go pattern.

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

* Fix golangci-lint errors: govet shadow and gofmt formatting

- Fix govet shadow: use var memBytes uint64 + err = instead of memBytes, err :=
  to avoid shadowing the outer err variable (which is reused after this block)
- Fix gofmt: add extra space before // 512 MB comment to align with
  the longer v2CPUMax line in the same assignment block

* fix(platform): ceil memory MB conversion and return zero-values for missing cgroup files

- Use ceiling division for MemoryLimitMB so sub-1MB limits map to 1 instead
  of 0 (which omitempty would silently drop)
- Absorb os.ErrNotExist in getContainerLimits so non-v2/bare-metal hosts
  return ContainerLimits{}, nil as the function comment promises
- Update test: missing cgroup file now asserts zero-values, not an error

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

* test(platform): add subtest locking ceil-to-MB behavior for sub-MB memory limits

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

* test(platform): add subtest for missing cpu.max returning zero values

Locks in the os.ErrNotExist branch for cpu.max (lines 57-60 in
container_limits_linux.go), which was previously unreachable via the
existing missing-memory test since that test returns early before
reading cpu.max.

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

---------

Co-authored-by: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
…tion failure (mattermost#36138)

* fix(mmctl): prevent nil pointer panic in websocket command on connection failure

When the WebSocket connection fails immediately, Listen() closes EventChannel
via defer. Reading from a closed channel with a plain receive returns nil,
causing a panic in ToJSON(). Switch to range so the loop exits cleanly,
add a nil guard, and surface ListenError to the caller.

Fixes MM-68351

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

* test(mmctl): add unit tests for websocket nil event and ListenError handling

Extracts the event-processing loop into processWebSocketEvents to enable
unit testing, and adds tests covering the nil-event skip and error surfacing.

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

* test(mmctl): add happy-path subtest for processWebSocketEvents

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

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
…t#36081)

* MM-67352 Prevent composer scroll jumps on formatting click

Keep formatting controls from stealing textarea focus on mousedown so long drafts stay in place when markdown buttons are clicked. Add a regression test for the formatting bar interaction.

Made-with: Cursor

* Update webapp/channels/src/components/advanced_text_editor/formatting_bar/formatting_icon.tsx

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

---------

Co-authored-by: Harrison Healey <harrisonmhealey@gmail.com>
Co-authored-by: Mattermost Build <build@mattermost.com>
* MM-66082: Fix invite modal paste by reading text/plain from clipboard

UsersEmailsInput always called preventDefault on paste but read clipboard
data with the legacy 'Text' type, which is empty in modern browsers.
That blocked default paste while adding nothing. Read text/plain first,
fall back to Text, skip custom handling when there is no meaningful
content, and only preventDefault when handling pasted text.

Co-authored-by: Maria A Nunez <maria.nunez@mattermost.com>

* Fix ESLint no-void in UsersEmailsInput paste handler

Replace void promise with .catch(() => undefined) so async paste
processing satisfies the no-void rule.

Co-authored-by: Maria A Nunez <maria.nunez@mattermost.com>

* MM-66082: Keep arbitrary pasted invite text as draft

Only treat obvious list pastes (comma, semicolon, newline) as bulk
invite input. Let arbitrary pasted text remain in the input so the
existing search and no-match UX can handle it, and keep space-delimited
text as draft rather than splitting it into invite tokens.

Co-authored-by: Maria A Nunez <maria.nunez@mattermost.com>

* MM-66082: Restore space-delimited email paste handling

Treat space-separated paste as bulk invite input only when every token
is a valid email. Keep mixed or free-form space-separated paste as draft
text so the existing no-match search UX still applies.

Co-authored-by: Maria A Nunez <maria.nunez@mattermost.com>

* MM-66082: Fix invite paste parsing in modal input

Treat pasted input as bulk invite tokens only when it is a single valid
email, an obvious comma/semicolon/newline list, or a space-separated list
of valid emails. Leave mixed or arbitrary pasted text as draft so the
existing no-match search UX still applies. Add focused widget and invite
view regression coverage for the affected paste paths.

Co-authored-by: Maria A Nunez <maria.nunez@mattermost.com>

* tests: use example invite paste fixtures

Replace product-specific test data with example.com values, restore the
space-paste length assertion, rename the invalid-word fixture, and remove
extra clipboard MIME lookups that were not needed for the supported paste
path.

Co-authored-by: Maria A Nunez <maria.nunez@mattermost.com>

* MM-66082: Fix invite input typing regressions

Fix premature chip creation while typing valid emails by using the paste
classifier only when it returns bulk mode, keep the valid address default
message wired correctly, and add regression coverage for typing and blur
behavior in both UsersEmailsInput and InviteView.

Co-authored-by: Maria A Nunez <maria.nunez@mattermost.com>

---------

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
…#36242)

The react-select input uses classNamePrefix ManagedCategory, so it did not
inherit the global react-select__input theme color. Set color to
var(--center-channel-color) on the input and input-container to match
placeholder and single-value styling.

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: Devin Binnie <devinbinnie@users.noreply.github.com>
Co-authored-by: Cursor Agent <cursoragent@cursor.com>
* Introduce model.SanitizeFilename and model.IsValidFilename, and
apply them in genFileInfoFromReader and FileInfo.IsValid. The
sanitizer uses filepath.Base, NFC-normalizes Unicode, strips ASCII
control characters, collapses backslashes to forward slashes, and
truncates to the VARCHAR(256) fileinfo.name column width.
…most#36241)

* Fix invite modal input text clipping and modal width overflow

Root cause: react-select v5 auto-sizes the input container using a CSS
grid with data-value attribute, which grows the grid columns based on
input text width. This caused the control, modal-content, and the
dropdown menu to exceed the modal-dialog's 600px width.

Changes:

1. invitation_modal.scss: Add max-width:100% and overflow:hidden on
   .modal-content to prevent it from overflowing the 600px modal-dialog.

2. users_emails_input.tsx: Override react-select's styles:
   - input.gridTemplateColumns: '0 minmax(0, 1fr)' prevents the sizer
     column from auto-expanding based on typed text width.
   - valueContainer.gridTemplateColumns: 'minmax(0, 1fr)' prevents the
     value-container grid from auto-sizing columns beyond the container.
   - Remove old display:flex and width:100% overrides that fought with
     react-select v5's inline-grid layout.

3. users_emails_input.scss:
   - Remove legacy width:1px on react-select input wrapper.
   - Add min-width:0 and max-width:100% on value-container and
     input-container for proper flex/grid containment.
   - Constrain dropdown menu to max-width:100%.
   - Allow no-match text and menu notices to wrap with overflow-wrap
     and word-break. Use min-height instead of fixed height so wrapped
     text fits.

Fixes: MM-68461

Co-authored-by: Maria A Nunez <maria.nunez@mattermost.com>

* Fix stylelint property order in invitation_modal.scss

Co-authored-by: Maria A Nunez <maria.nunez@mattermost.com>

* Update snapshot for react-select style changes

Co-authored-by: Maria A Nunez <maria.nunez@mattermost.com>

* Add min-width: 0 to input-container to prevent shrink/overflow regressions

Co-authored-by: Maria A Nunez <maria.nunez@mattermost.com>

---------

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: Mattermost Build <build@mattermost.com>
sqlstore's TestMain calls sqlstore.InitTest (which opens postgres and
drops tables) before mainHelper.Main, so the -test.list bailout added
in mattermost#36222 never fired and shard-split discovery failed on the GitHub
host. Bail out at the top of TestMain instead, and restore HEAVY_MS
so sqlstore can still be treated as whole.

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-authored-by: Mattermost Build <build@mattermost.com>
* Adds version to the property group model

* Ensures that the REST API rejects v1 group calls

* Ensures field version and group version match

* Simplify property groups on app layer tests

* Add GetByID to PropertyGroupStore and enforce field/group version match on update

* Simplify bits of the code

* Fix i18n and add generic errors

* Fix PropertyGroupStore mock to return stable IDs and default zero version to V1

* Fix tests that were using nonexistent group IDs

* Fix rigidness on valid group names

* Update group not found slug

* Temporary allow to use tempaltes with v1

* Explicitly including tempaltes in the IsPSAv1 check for conflict check

* Return 404 on group not found and template explicit inclusion on patch API endpoint

* Fix CPA test that would use fields from unregistered groups

---------

Co-authored-by: Miguel de la Cruz <miguel@ctrlz.es>
* [MM-68231] Tighten post info authorization

Align post info channel access with the standard read path while preserving expected public-channel discoverability. Add regression coverage for guest and compliance-mode access checks.

Made-with: Cursor

* [MM-68231] Strengthen post info test coverage

Tighten the new post info regression coverage so the guest denial case proves its setup and the compliance case asserts the expected non-compliance behavior first.

Made-with: Cursor

* [MM-68231] Expand post info authorization coverage

Add focused regression coverage for invite-team access, compliance behavior on open teams, private-channel permission boundaries, and outsider denial for DM and GM post info.

Made-with: Cursor
* Remove unused property fields index

* Update server/channels/db/migrations/migrations.list

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

---------

Co-authored-by: Miguel de la Cruz <miguel@ctrlz.es>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
…6153)

* MM-68353 - show placeholder for redacted files in preview when permission policies are enabled

* add tests for rendering redacted files placeholder in post message preview based on permission policies
… deletes (mattermost#36264)

* omit error_* fields if empty, add status code

* MM-68378: Add tests for 404-delete semantics in ES/OS indexing jobs

* MM-68378: Fix empty error fields and spurious failures for OS/ES bulk deletes

- Log resp.Status unconditionally in OnFailure so status-only failures
  (resp.Error nil, err nil) are always identifiable
- Downgrade per-item OnFailure log from Error to Warn; the job-level
  Error log already captures the aggregate failure
- Track real failures in a separate atomic counter shared between the
  OnFailure callback and the close closure; 404 deletes (document not
  found) are silently skipped and not counted
- Report num_failed from the real counter in close stats; retain
  stats_num_failed as the raw SDK count for reference
…6221)

Rate limiting from mattermost.com should not cause CI to fail since it
is transient and unrelated to code changes in the PR.
mattermost#36037)

* MM-67319 Move ShortcutKey component into Shared Package

* MM-67322 Add i18n-extract support for shared package and move key constants

* MM-67320 Move WithTooltip into shared package without modification

* Add CSS variables for standard z-indices

* Update TooltipShortcut to point to shared ShortcutKey

* Update TooltipContent to use shared Emoji

* Move isMessageDescriptor into shared package

* Add Floating UI as explicit dependency of shared package

* Fix WithTooltip imports

* Fix imports for ShortcutX types

* Move/copy tooltip constants into shared package

* Fix WithTooltip tests

* Remove unneeded TODO comments

* Actually share new modules with plugins

* Stop publishing src folder for shared package
Add OpenID Connect authentication via two new API endpoints:
- GET /api/v4/auth/oidc/start (initiates auth flow)
- GET /api/v4/auth/oidc/complete (handles callback)

Configured via environment variables: OIDC_ISSUER, OIDC_CLIENT_ID,
OIDC_CLIENT_SECRET, OIDC_REDIRECT_URL. Works with any OIDC provider
(Keycloak, Auth0, Azure AD, etc).

Upstream Mattermost v11 removed OIDC from the free tier. This patch
restores it for all users without requiring an Enterprise license.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.