From 6417c9342a89ebf333b139c2d8ad6cf6c139e45c Mon Sep 17 00:00:00 2001 From: Eva Sarafianou Date: Tue, 21 Jul 2026 13:40:08 +0300 Subject: [PATCH 1/5] docs: port P13/P14 content drift into monorepo (#37590) * docs(P13c): add missing manage-plugins.mdx to Administration Guide Configure source/administration-guide/configure/manage-plugins.rst existed in the Sphinx repo pre-fork but was never carried over during the initial P2 move or the P13c Configure reconciliation pass. Port it verbatim (RST -> MDX) with links/anchors verified against the current docs/main tree (mmctl-command-line-tool, plugins, plugins-configuration-settings, popular-integrations, environment-configuration-settings#maximum-file-size, air-gapped-deployment). #### Release Note ```release-note NONE ``` Co-authored-by: Cursor * docs(P13/P14): port remaining content drift into monorepo Ports outstanding content-only drift identified in docs-experimental phase-P13/P14: V11.9 docs major release content, Azure Blob Storage guide, ID-attribute case-sensitivity notes, ranked attribute types and attribute value masking for ABAC, plugin management guide linkage, and the P14 markdown action buttons reference page with its interactive-messages cross-reference. Excludes all automation/workflow files, which are handled separately. Co-authored-by: Cursor * docs(sidebar): link top-level category headers to their landing page buildCategory() only recognized a literal index.md(x) filename as a category's landing page, but Overview, Deployment Guide, Administration Guide, Security & Compliance, End User Guide, Integrations Guide, Get Help, and Use Case Guide all use a *-index.md(x) filename instead (to avoid collisions when flattening for URL stability). As a result, clicking most top-level sidebar categories only expanded/collapsed the list instead of navigating to their overview page. Recognize the *-index.md(x) convention as a fallback so these categories link correctly, matching the existing Deployment Guide/Overview behavior. Co-authored-by: Cursor * docs(P13/P14): fix blog link typo and restore dropped Open Source Components entry Audit against Sphinx source (docs/source/product-overview/) found two drops from the 7e915c99f8 content-drift port: - mattermost-v11-changelog.mdx: blog link slug had an erroneous "-0" (mattermost-v11-9-0-is-now-available -> mattermost-v11-9-is-now-available), likely copy-pasted from the v11.8.0 entry above it. - mobile-app-changelog.mdx: the 2.42.0 release entry's "Open Source Components" subsection (voximplant/react-native-foreground-service removal) was dropped entirely during the RST->MDX port. #### Release Note ```release-note NONE ``` Co-authored-by: Cursor * docs(fix): remove standalone SQL comment line breaking MDX parse A lone "--" comment line inside a
 SQL block was parsed by
remark as a setext heading underline, splitting the surrounding
paragraph and leaving the  tag unclosed. CI caught this in the
docusaurus build. Merge the comment into the surrounding paragraph.

Co-authored-by: Cursor 

* docs(fix): escape curly braces in JSONB path literal breaking SSG render

'{options}' inside a SQL 
 block was parsed by MDX as a JSX
expression referencing an undefined "options" identifier, causing
"ReferenceError: options is not defined" during static site
generation. Escape the braces the same way already done for other
JSONB path literals elsewhere in this file. Verified with a full local
docusaurus build.

Co-authored-by: Cursor 

* docs(sidebar): reuse the landing-file resolver for nested category sorting/labels

The prior fix only applied the index.md(x) / *-index.md(x) fallback to
a category's own link resolution. Nested category sort keys and the
category label fallback still assumed a literal index.mdx, so a
sub-directory using the *-index.md(x) naming convention would sort by
its default position (9999) instead of its declared sidebar_position,
and its category label would fall back to a humanized directory name
instead of the landing page's title. Factor the resolver into a shared
findIndexFile() helper and use it in both places.

Co-authored-by: Cursor 

---------

Co-authored-by: Cursor 
---
 .../plugins/interactive-messages/index.md     |    6 +
 .../reference/markdown-actions/index.md       |  227 +++
 .../authentication-configuration-settings.mdx |   16 +
 .../configure/azure-blob-storage.mdx          |  200 +++
 .../environment-configuration-settings.mdx    |  172 ++-
 .../integrations-configuration-settings.mdx   |    9 +
 .../configure/manage-plugins.mdx              |  182 +++
 .../plugins-configuration-settings.mdx        |   26 +
 .../configure/site-configuration-settings.mdx |    2 +-
 .../admin/abac-channel-access-rules.mdx       |    5 +
 .../admin/abac-system-wide-policies.mdx       |   26 +
 .../manage/admin/server-configuration.mdx     |    2 +
 .../manage/admin/user-attributes.mdx          |   13 +
 .../manage/statistics.mdx                     |    2 +-
 .../onboard/sso-saml-entraid.mdx              |  123 +-
 .../scale/backing-storage-benchmarks.mdx      |    2 +-
 ...-availability-cluster-based-deployment.mdx | 1363 ++++++++++++-----
 .../scale/performance-monitoring-metrics.mdx  |    1 +
 .../upgrade/enterprise-roll-out-checklist.mdx |    2 +-
 .../upgrade/important-upgrade-notes.mdx       |  290 ++++
 .../upgrade/open-source-components.mdx        |    2 +
 .../server/linux/deploy-rhel.mdx              |    4 +-
 .../server/linux/deploy-tar.mdx               |    4 +-
 .../end-user-guide/collaborate/make-calls.mdx |    6 +-
 docs/main/integrations-guide/plugins.mdx      |    2 +
 .../mattermost-desktop-releases.mdx           |    2 +-
 .../mattermost-mobile-releases.mdx            |    2 +-
 .../mattermost-server-releases.mdx            |    7 +-
 .../mattermost-v10-changelog.mdx              |    8 +
 .../mattermost-v11-changelog.mdx              |  188 +++
 .../product-overview/mobile-app-changelog.mdx |   67 +
 docs/main/product-overview/release-policy.mdx |    3 +-
 .../product-overview/ui-ada-changelog.mdx     |   32 +
 .../main/product-overview/version-archive.mdx |   74 +-
 .../scripts/gen-documentation-sidebar.mjs     |   31 +-
 .../images/entra-attributes-and-claims.png    |  Bin 0 -> 46776 bytes
 docs/site/static/images/entra-tenant-id.png   |  Bin 0 -> 69703 bytes
 37 files changed, 2665 insertions(+), 436 deletions(-)
 create mode 100644 docs/develop/integrate/reference/markdown-actions/index.md
 create mode 100644 docs/main/administration-guide/configure/azure-blob-storage.mdx
 create mode 100644 docs/main/administration-guide/configure/manage-plugins.mdx
 create mode 100644 docs/site/static/images/entra-attributes-and-claims.png
 create mode 100644 docs/site/static/images/entra-tenant-id.png

diff --git a/docs/develop/integrate/plugins/interactive-messages/index.md b/docs/develop/integrate/plugins/interactive-messages/index.md
index fddd692dfd20..ec6f9bfd2f4e 100644
--- a/docs/develop/integrate/plugins/interactive-messages/index.md
+++ b/docs/develop/integrate/plugins/interactive-messages/index.md
@@ -17,6 +17,12 @@ To try it out, you can use this [Matterpoll plugin](https://github.com/matterpol
 
 ![image](poll.png)
 
+## Markdown action buttons
+
+In addition to message-attachment buttons and menus, you can embed interactive affordances directly in a post's markdown body using `mmaction://` links backed by a `mm_blocks_actions` post prop. This is useful when a short message reads naturally with an inline "Approve" or "Reject" link and a full message attachment isn't warranted.
+
+See [markdown action buttons](/developers/integrate/reference/markdown-actions) for the full schema, limits, and end-to-end flow.
+
 ## Message buttons
 
 Add message buttons as `actions` in your integration [message attachments](https://docs.mattermost.com/developer/message-attachments.html).
diff --git a/docs/develop/integrate/reference/markdown-actions/index.md b/docs/develop/integrate/reference/markdown-actions/index.md
new file mode 100644
index 000000000000..51af5547f7c2
--- /dev/null
+++ b/docs/develop/integrate/reference/markdown-actions/index.md
@@ -0,0 +1,227 @@
+---
+title: "Markdown action buttons"
+description: "Markdown action buttons let an integration turn an inline post-markdown link into an action affordance. Clicking the link dispatches a post action to the integration's endpoint instead of navigating away, expanding interactivity beyond message attachments."
+sidebar_label: "Markdown action buttons"
+sidebar_position: 45
+---
+
+:::note Part of a broader framework
+Markdown action buttons are one binding surface in a broader Interactive Messages framework under active development. Additional binding surfaces and action types are planned for future iterations.
+:::
+
+Use markdown action buttons to add inline, in-text affordances to a post — without using a message attachment. They're useful when:
+
+- A short message reads naturally with an "Approve" or "Reject" inline link.
+- An integration wants to mix narrative text and action affordances in the same post body.
+- The visual weight of a full message attachment isn't warranted.
+
+For attachment-style buttons and menus, see [interactive messages](/developers/integrate/plugins/interactive-messages).
+
+## How it works
+
+A markdown action has two parts:
+
+1. A markdown link in the post body using the `mmaction://` scheme, where the link host is the action ID:
+
+   ```text
+   [Approve](mmaction://approve?ticket=ISS-101)
+   ```
+
+2. A matching entry in the post's `props.mm_blocks_actions` registry that tells the server what to do when the link is clicked:
+
+   ```json
+   {
+     "mm_blocks_actions": {
+       "approve": {
+         "type": "external",
+         "url": "https://integration.example.com/hook/approve",
+         "context": {"project": "Demo Project"}
+       }
+     }
+   }
+   ```
+
+The client renders the link as a button. Clicking it dispatches a request to the Mattermost server, which forwards the call to the integration's `url` along with merged query parameters and any server-side context.
+
+## Example post payload
+
+The following payload posts a message with two markdown action buttons. The body markdown references action IDs defined in `mm_blocks_actions`.
+
+```json
+{
+  "channel_id": "qmd5oqtwoibz8cuzxzg5ekshgr",
+  "message": "Ticket ISS-101 needs review: [Approve](mmaction://approve?ticket=ISS-101) [Reject](mmaction://reject?ticket=ISS-101)",
+  "props": {
+    "mm_blocks_actions": {
+      "approve": {
+        "type": "external",
+        "url": "https://integration.example.com/hook/approve",
+        "context": {"project": "Demo Project"}
+      },
+      "reject": {
+        "type": "external",
+        "url": "https://integration.example.com/hook/reject",
+        "context": {"project": "Demo Project"}
+      }
+    }
+  }
+}
+```
+
+You can send this payload using the [create post REST API](https://api.mattermost.com/#operation/CreatePost), an [incoming webhook](/developers/integrate/webhooks/incoming), or from a [plugin](/developers/integrate/plugins/components/server).
+
+### Submit using the REST API
+
+```bash
+curl -X POST $MM_URL/api/v4/posts \
+  -H "Authorization: Bearer $BOT_TOKEN" \
+  -H "Content-Type: application/json" \
+  -d '{
+    "channel_id": "'$CHANNEL_ID'",
+    "message": "Ticket ISS-101 needs review: [Approve](mmaction://approve?ticket=ISS-101) [Reject](mmaction://reject?ticket=ISS-101)",
+    "props": {
+      "mm_blocks_actions": {
+        "approve": {
+          "type": "external",
+          "url": "https://integration.example.com/hook/approve",
+          "context": {"project": "Demo Project"}
+        },
+        "reject": {
+          "type": "external",
+          "url": "https://integration.example.com/hook/reject",
+          "context": {"project": "Demo Project"}
+        }
+      }
+    }
+  }'
+```
+
+### Submit from a plugin
+
+A server-side plugin creates posts with markdown actions through the existing `API.CreatePost` / `API.UpdatePost` interfaces. The action `url` typically points at the plugin's own HTTP handler.
+
+```go
+post := &model.Post{
+    ChannelId: channelID,
+    UserId:    p.botID,
+    Message: "Ticket ISS-101 needs review: " +
+        "[Approve](mmaction://approve?ticket=ISS-101) " +
+        "[Reject](mmaction://reject?ticket=ISS-101)",
+    Props: model.StringInterface{
+        "mm_blocks_actions": map[string]any{
+            "approve": map[string]any{
+                "type":    "external",
+                "url":     fmt.Sprintf("/plugins/%s/inline_action/approve", manifest.Id),
+                "context": map[string]any{"project": "Demo Project"},
+            },
+            "reject": map[string]any{
+                "type":    "external",
+                "url":     fmt.Sprintf("/plugins/%s/inline_action/reject", manifest.Id),
+                "context": map[string]any{"project": "Demo Project"},
+            },
+        },
+    },
+}
+_, err := p.API.CreatePost(post)
+```
+
+Plugin updates to `mm_blocks_actions` via `UpdatePost` are accepted only when the updated value passes validation. Removal of the `mm_blocks_actions` prop by non-integration sessions is restricted to prevent dropping or corrupting actions on posts owned by another integration.
+
+## Link syntax
+
+```text
+[