This is an automated email from the ASF dual-hosted git repository.

morningman pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/doris-website.git


The following commit(s) were added to refs/heads/master by this push:
     new be63568fe7e feat: add Doris Operator downloads (#3987)
be63568fe7e is described below

commit be63568fe7ef60807cc4055ad2a2a45ba81d54b4
Author: Mingyu Chen (Rayner) <[email protected]>
AuthorDate: Thu Jul 16 13:47:28 2026 +0800

    feat: add Doris Operator downloads (#3987)
    
    ## Summary
    
    - Add Doris Operator to the Doris Ecosystem download selector with
    source, ASC, and SHA-512 links for published releases.
    - Add Docker pull commands for published Operator binary tags.
    - Render binary commands in a copyable terminal-style panel that wraps
    long commands so the version remains visible.
    
    ## Test Plan
    
    - [x] `node --test
    src/components/download-form/download-form-tools.test.js`
    - [x] `git diff --check upstream-apache/master...HEAD`
    - [ ] Full site build (not run per request)
    
    ## Versions
    
    - [x] dev
    - [ ] 4.x
    - [ ] 3.x
    - [ ] 2.1 or older (not covered by version/language sync gate)
    
    ## Languages
    
    - [ ] Chinese
    - [x] English
    - [ ] Japanese candidate translation needed
    
    ## Docs Checklist
    
    - [x] Checked by AI
    - [x] Test Cases Built
    - [x] Updated required version and language counterparts, or explained
    why not
    - [x] If only one language changed, confirmed whether source/translation
    counterparts need sync
    
    This changes shared frontend download data and UI; no versioned or
    localized documentation counterparts are required.
---
 .../current/ecosystem/doris-operator.md            | 314 +++++++++++++++++++++
 releasenotes/ecosystem/doris-operator.md           | 314 +++++++++++++++++++++
 .../download-form-next/DownloadFormNext.tsx        |  15 +-
 .../download-form-next/download-page.scss          |   7 +
 .../download-form/download-form-tools.test.js      | 141 +++++++++
 .../download-form/download-form-tools.tsx          | 234 ++++++++++-----
 src/constant/download.data.ts                      |  66 +++++
 7 files changed, 1013 insertions(+), 78 deletions(-)

diff --git 
a/i18n/zh-CN/docusaurus-plugin-content-docs-releases/current/ecosystem/doris-operator.md
 
b/i18n/zh-CN/docusaurus-plugin-content-docs-releases/current/ecosystem/doris-operator.md
index 1d4b0ccb6bc..f10d918f7a3 100644
--- 
a/i18n/zh-CN/docusaurus-plugin-content-docs-releases/current/ecosystem/doris-operator.md
+++ 
b/i18n/zh-CN/docusaurus-plugin-content-docs-releases/current/ecosystem/doris-operator.md
@@ -54,6 +54,126 @@
 - [gohalo](https://github.com/gohalo)
 - [catpineapple](https://github.com/catpineapple)
 
+## 25.7.0
+
+来源:[Release Notes 25.7.0](https://github.com/apache/doris-operator/issues/423)
+
+该版本改进了 drop node 对计算组重命名的兼容性和调试镜像构建,并修复 DDC Pod 信息挂载、PVC 单元测试及事件处理问题。
+
+### 功能与改进
+
+- drop node 
操作兼容重命名后的计算组。[#417](https://github.com/apache/doris-operator/pull/417)
+- 升级用于构建调试镜像的 Go 版本。[#424](https://github.com/apache/doris-operator/pull/424)
+
+### Bug 修复
+
+- 修正拼写错误。[#413](https://github.com/apache/doris-operator/pull/413)
+- 修复 DDC 容器缺少 Pod 
信息挂载的问题。[#415](https://github.com/apache/doris-operator/pull/415)
+- 修复 PVC 构建单元测试失败的问题。[#420](https://github.com/apache/doris-operator/pull/420)
+- 避免 `EventString` 为 nil 
时出现空指针错误。[#422](https://github.com/apache/doris-operator/pull/422)
+
+### 致谢
+
+- [intelligentfu8](https://github.com/intelligentfu8)
+- [ztonny](https://github.com/ztonny)
+
+## 25.6.0
+
+来源:[Release Notes 25.6.0](https://github.com/apache/doris-operator/issues/414)
+
+该版本支持使用 `dorisctl` 管理存算分离 Doris 集群,并修复首次部署时未创建 PVC 的问题。
+
+### 功能与改进
+
+- 支持使用 `dorisctl` 管理存算分离 Doris 
集群。[#412](https://github.com/apache/doris-operator/pull/412)
+
+### Bug 修复
+
+- 修复首次部署时未创建 PVC 的问题。[#410](https://github.com/apache/doris-operator/pull/410)
+
+### 致谢
+
+- [intelligentfu8](https://github.com/intelligentfu8)
+
+## 25.5.3
+
+来源:[Release Notes 25.5.3](https://github.com/apache/doris-operator/issues/408)
+
+该版本改进了 DDC 部署的默认镜像和文档,并避免内部 reconcile annotation 出现在自定义资源中。
+
+### 功能与改进
+
+- 使用 BE 镜像作为默认 Init Container 
镜像。[#405](https://github.com/apache/doris-operator/pull/405)
+- 在 README 中增加两个功能说明。[#406](https://github.com/apache/doris-operator/pull/406)
+- 增加适用于不同场景的 FoundationDB 
使用示例。[#407](https://github.com/apache/doris-operator/pull/407)
+
+### Bug 修复
+
+- 避免仅用于 reconcile 状态检查的 annotation 
出现在自定义资源中。[#404](https://github.com/apache/doris-operator/pull/404)
+
+### 致谢
+
+- [intelligentfu8](https://github.com/intelligentfu8)
+
+## 25.5.2
+
+来源:[Release Notes 25.5.2](https://github.com/apache/doris-operator/issues/403)
+
+该版本改进了 DDC reconcile 和调试行为。
+
+### 功能与改进
+
+- `DorisDisaggregatedCluster` 状态已一致时避免重复 
reconcile。[#399](https://github.com/apache/doris-operator/pull/399)
+- 增加用于进入调试模式的 `apache.com.doris/runmode` 
annotation。[#400](https://github.com/apache/doris-operator/pull/400)
+- 默认启用 `DorisDisaggregatedCluster` 
reconcile。[#402](https://github.com/apache/doris-operator/pull/402)
+
+### 致谢
+
+- [intelligentfu8](https://github.com/intelligentfu8)
+
+## 25.5.1
+
+来源:[Release Notes 25.5.1](https://github.com/apache/doris-operator/issues/398)
+
+该版本为 DDC 增加 Kerberos 支持,并使存算分离组件的发布版本与 Operator 版本保持一致。
+
+### 功能与改进
+
+- DDC 支持 Kerberos。[#396](https://github.com/apache/doris-operator/pull/396)
+
+### Bug 修复
+
+- 使存算分离组件的发布版本与 Operator 
版本保持一致。[#395](https://github.com/apache/doris-operator/pull/395)
+
+### 致谢
+
+- [intelligentfu8](https://github.com/intelligentfu8)
+
+## 25.5.0
+
+来源:[Release Notes 25.5.0](https://github.com/apache/doris-operator/issues/394)
+
+该版本为存算分离集群增加 Workload Group 和 Helm chart 支持,同时改进 DDC 初始化,并修复镜像、权限和 MetaService 
配置问题。
+
+### 功能与改进
+
+- 为存算分离 Doris 集群增加 Workload Group 
支持。[#378](https://github.com/apache/doris-operator/pull/378)
+- 支持 reconcile `DorisDisaggregatedCluster` 
资源。[#379](https://github.com/apache/doris-operator/pull/379)
+- 增加存算分离 Doris 集群的 Helm chart 
支持。[#379](https://github.com/apache/doris-operator/pull/379) 
[#386](https://github.com/apache/doris-operator/pull/386) 
[#388](https://github.com/apache/doris-operator/pull/388) 
[#393](https://github.com/apache/doris-operator/pull/393)
+- DDC 支持跳过默认系统初始化检查。[#389](https://github.com/apache/doris-operator/pull/389)
+
+### Bug 修复
+
+- 调整默认 Operator 镜像。[#377](https://github.com/apache/doris-operator/pull/377)
+- 增加聚合 `ClusterRole`。[#380](https://github.com/apache/doris-operator/pull/380)
+- 修复存算分离集群的 MetaService 
副本数问题。[#382](https://github.com/apache/doris-operator/pull/382)
+
+### 致谢
+
+- [wdxxl](https://github.com/wdxxl)
+- [catpineapple](https://github.com/catpineapple)
+- [intelligentfu8](https://github.com/intelligentfu8)
+
 ## 25.4.0
 
 来源:[Release Notes 25.4.0](https://github.com/apache/doris-operator/issues/376)
@@ -97,6 +217,28 @@
 - [catpineapple](https://github.com/catpineapple)
 - [intelligentfu8](https://github.com/intelligentfu8)
 
+## 25.2.1
+
+来源:[Release Notes 25.2.1](https://github.com/apache/doris-operator/issues/360)
+
+该版本在 Helm chart 中增加存算分离集群资源,改进发布流程中的版本替换和镜像仓库,并修复 Helm chart 问题。
+
+### 功能与改进
+
+- 在 Helm chart 
中增加用于部署存算分离集群的自定义资源。[#355](https://github.com/apache/doris-operator/pull/355)
+- 将版本字段改为可在发布流程中替换的变量。[#354](https://github.com/apache/doris-operator/pull/354)
+- 将镜像从 SelectDB 仓库迁移到 Apache 
仓库。[#357](https://github.com/apache/doris-operator/pull/357)
+
+### Bug 修复
+
+- 回退 PR 354 中的部分变更。[#358](https://github.com/apache/doris-operator/pull/358)
+- 修复 Helm chart 的 
`apiVersion`。[#359](https://github.com/apache/doris-operator/pull/359)
+
+### 致谢
+
+- [xiacongling](https://github.com/xiacongling)
+- [intelligentfu8](https://github.com/intelligentfu8)
+
 ## 25.2.0
 
 来源:[Release Notes 25.2.0](https://github.com/apache/doris-operator/issues/351)
@@ -128,3 +270,175 @@
 
 - [catpineapple](https://github.com/catpineapple)
 - [intelligentfu8](https://github.com/intelligentfu8)
+
+## 25.1.0
+
+来源:[Release Notes 25.1.0](https://github.com/apache/doris-operator/issues/333)
+
+该版本改进 BE 调度和配置更新,增加 controller 测试,修复 StatefulSet 准备逻辑,并将镜像 tag 迁移到 Apache 仓库。
+
+### 功能与改进
+
+- 为 BE 增加 FE 亲和性,使 Operator 优先将 BE 调度到运行 FE 
的节点。[#328](https://github.com/apache/doris-operator/pull/328)
+- 监听 ConfigMap 变更,并在启动配置变更后重启 
Doris。[#331](https://github.com/apache/doris-operator/pull/331)
+- BE 支持跳过默认系统初始化。[#321](https://github.com/apache/doris-operator/pull/321)
+- 增加 controller 单元测试。[#322](https://github.com/apache/doris-operator/pull/322)
+
+### Bug 修复
+
+- 修复传递给 `prepareStatefulsetApply` 
的参数。[#326](https://github.com/apache/doris-operator/pull/326)
+
+### 其他变更
+
+- 将所有镜像 tag 从 SelectDB 仓库迁移到 Apache 
仓库。[#329](https://github.com/apache/doris-operator/pull/329)
+
+### 致谢
+
+- [catpineapple](https://github.com/catpineapple)
+- [intelligentfu8](https://github.com/intelligentfu8)
+
+## 24.2.0
+
+来源:[Release Note 24.2.0](https://github.com/apache/doris-operator/issues/319)
+
+该版本为 `DorisDisaggregatedCluster` 增加多 Secret 支持,并支持通过 decommission 缩容计算组中的 
BE。同时,该版本改进 Arrow Flight SQL 端口暴露、资源清理、测试、文档和示例。
+
+### 功能与改进
+
+- 支持通过 decommission 缩容 DDC 计算组中的 
BE。[#306](https://github.com/apache/doris-operator/pull/306)
+- DDC 支持用户名、密码配置和多个 
Secret。[#312](https://github.com/apache/doris-operator/pull/312)
+- 将 Arrow Flight SQL 
端口暴露为容器端口。[#295](https://github.com/apache/doris-operator/pull/295)
+- 在存算分离 Service 中暴露 Arrow Flight SQL 
端口。[#307](https://github.com/apache/doris-operator/pull/307)
+- 扩充单元测试覆盖。[#315](https://github.com/apache/doris-operator/pull/315)
+- 重构计算组资源清理逻辑。[#318](https://github.com/apache/doris-operator/pull/318)
+
+### Bug 修复
+
+- 修复删除计算组时的 SQL Client 
行为。[#314](https://github.com/apache/doris-operator/pull/314)
+- 修复 Service label。[#318](https://github.com/apache/doris-operator/pull/318)
+- 修复 `UniqueId` 
包含连字符时无法删除计算组的问题。[#318](https://github.com/apache/doris-operator/pull/318)
+- 在集群更新期间缩容 FE 
时增加安全检查。[#320](https://github.com/apache/doris-operator/pull/320)
+
+### 其他变更
+
+- 改进 README。[#303](https://github.com/apache/doris-operator/pull/303)
+- 删除未使用的文件,包括已废弃的 Dockerfile 和 DDM 
代码。[#309](https://github.com/apache/doris-operator/pull/309) 
[#314](https://github.com/apache/doris-operator/pull/314)
+- 改进 `DorisDisaggregatedCluster` CRD 
使用示例。[#313](https://github.com/apache/doris-operator/pull/313)
+
+### 致谢
+
+- [jonasbrami](https://github.com/jonasbrami)
+- [hechao-ustc](https://github.com/hechao-ustc)
+- [intelligentfu8](https://github.com/intelligentfu8)
+- [catpineapple](https://github.com/catpineapple)
+
+## 24.1.0
+
+来源:[Release Note 24.1.0](https://github.com/apache/doris-operator/issues/293)
+
+该版本为 `DorisCluster` 增加 Workload Group 支持,引入滚动重启,并修复 FE 部署和访问问题。
+
+Workload Group 需要使用 Apache Doris 2.1.7 或更高版本的官方镜像。对于更早的 Doris 版本,需要自行构建兼容镜像。
+
+### 功能与改进
+
+- 为 Doris BE 增加 Workload Group 
支持。[#289](https://github.com/apache/doris-operator/pull/289)
+- 支持滚动重启 Doris 集群。[#292](https://github.com/apache/doris-operator/pull/292)
+- 更新 Makefile 中的 controller-gen 
版本。[#275](https://github.com/apache/doris-operator/pull/275)
+- 在 GitHub Actions 
中增加许可证检查。[#278](https://github.com/apache/doris-operator/pull/278) 
[#279](https://github.com/apache/doris-operator/pull/279) 
[#280](https://github.com/apache/doris-operator/pull/280)
+- 增加默认 Issue 模板。[#288](https://github.com/apache/doris-operator/pull/288)
+
+### Bug 修复
+
+- 修复 `DorisCluster` 资源中未设置 FE `electionNumber` 
时的空指针错误。[#285](https://github.com/apache/doris-operator/pull/285)
+- 修复 FE 访问地址,改为使用 Service 名称和 
namespace。[#291](https://github.com/apache/doris-operator/pull/291)
+
+### 致谢
+
+- [intelligentfu8](https://github.com/intelligentfu8)
+- [catpineapple](https://github.com/catpineapple)
+
+## 24.0.0
+
+来源:[Release Note 24.0.0](https://github.com/apache/doris-operator/issues/272)
+
+该版本引入 `DorisDisaggregatedCluster`(DDC)自定义资源,用于部署存算分离 Apache Doris 集群。同时,该版本通过 
`DorisCluster`(DCR)扩展存算一体部署能力。
+
+DDC 仅适用于 Apache Doris 3.0.2 或更高版本。
+
+### 新功能
+
+#### DorisDisaggregatedCluster
+
+- 增加 FoundationDB 
模块访问能力。[#186](https://github.com/apache/doris-operator/pull/186)
+- 支持部署 MetaService 模块。[#194](https://github.com/apache/doris-operator/pull/194)
+- 支持部署 FE 模块。[#199](https://github.com/apache/doris-operator/pull/199)
+- 支持部署计算组模块。[#185](https://github.com/apache/doris-operator/pull/185) 
[#189](https://github.com/apache/doris-operator/pull/189) 
[#192](https://github.com/apache/doris-operator/pull/192) 
[#197](https://github.com/apache/doris-operator/pull/197)
+- 为存算分离 Doris 组件增加镜像 entrypoint 
支持。[#195](https://github.com/apache/doris-operator/pull/195) 
[#196](https://github.com/apache/doris-operator/pull/196)
+- 支持缩容 FE。[#225](https://github.com/apache/doris-operator/pull/225)
+- 支持缩容计算组并清理资源。[#238](https://github.com/apache/doris-operator/pull/238)
+- 支持通过 SQL 接口缩容 FE。[#255](https://github.com/apache/doris-operator/pull/255)
+- 支持通过 SQL 接口缩容计算组。[#256](https://github.com/apache/doris-operator/pull/256)
+
+#### DorisCluster
+
+- 通过 External Service 暴露 Arrow Flight SQL 
端口。[#251](https://github.com/apache/doris-operator/pull/251)
+
+### 功能改进
+
+#### DorisDisaggregatedCluster
+
+- 支持通过 `be.conf` 和 PVC 
配置创建计算组。[#198](https://github.com/apache/doris-operator/pull/198)
+- 改进 README 和 DDC 示例 YAML 
文件。[#203](https://github.com/apache/doris-operator/pull/203) 
[#210](https://github.com/apache/doris-operator/pull/210) 
[#211](https://github.com/apache/doris-operator/pull/211) 
[#214](https://github.com/apache/doris-operator/pull/214)
+- 将 README 
示例更新为使用最新版本。[#220](https://github.com/apache/doris-operator/pull/220)
+- 增加用于启用 DDC 部署的 Operator 
开关。[#204](https://github.com/apache/doris-operator/pull/204)
+- 增加 
`SystemInitialization`,用于准备系统环境。[#212](https://github.com/apache/doris-operator/pull/212)
+- 根据 Doris 
命名变更同步计算组术语。[#215](https://github.com/apache/doris-operator/pull/215) 
[#245](https://github.com/apache/doris-operator/pull/245)
+- 删除 MetaService 副本 
CRD。[#227](https://github.com/apache/doris-operator/pull/227)
+- 将 MetaService CRD 重构为 `DorisDisaggregatedCluster` 
CRD。[#234](https://github.com/apache/doris-operator/pull/234)
+- 将计算组标识符改为新 SQL 接口使用的 
`UniqueId`。[#239](https://github.com/apache/doris-operator/pull/239)
+- 增加 FE SQL 镜像 entrypoint 和集群 ID 
哈希值。[#249](https://github.com/apache/doris-operator/pull/249)
+- 将 DDC 操作从 HTTP 接口迁移到 SQL 
接口。[#254](https://github.com/apache/doris-operator/pull/254)
+- 为 Pod liveness probe 增加 
`timeoutSeconds`。[#257](https://github.com/apache/doris-operator/pull/257)
+- 增加 `logNotStore`,使 FE 可以跳过创建日志 
PVC。[#266](https://github.com/apache/doris-operator/pull/266)
+- 更新 DDC 示例和文档。[#268](https://github.com/apache/doris-operator/pull/268)
+
+#### DorisCluster
+
+- 为 Pod liveness probe 增加 
`timeoutSeconds`。[#257](https://github.com/apache/doris-operator/pull/257)
+
+#### 其他变更
+
+- 增加公共工具函数单元测试。[#226](https://github.com/apache/doris-operator/pull/226)
+- 增加 resource model 和 controller model 
单元测试。[#232](https://github.com/apache/doris-operator/pull/232)
+- 更新用于 Artifact Hub 的 Helm chart 
配置。[#244](https://github.com/apache/doris-operator/pull/244)
+- 将组织名称从 SelectDB 改为 
Apache。[#247](https://github.com/apache/doris-operator/pull/247)
+
+### Bug 修复
+
+#### DorisDisaggregatedCluster
+
+- 修复 Pod affinity 和 StatefulSet PVC 
指针处理问题。[#209](https://github.com/apache/doris-operator/pull/209)
+- 修正 BE 默认存储路径。[#243](https://github.com/apache/doris-operator/pull/243)
+- 修复首次部署期间重复的 `ms_token` 环境变量导致 Pod 
重启的问题。[#259](https://github.com/apache/doris-operator/pull/259)
+- 修复镜像 entrypoint 使用的 BE ConfigMap 
路径。[#261](https://github.com/apache/doris-operator/pull/261)
+- 修复 `electionNumber` 为 nil 时的部署问题,并避免 Service 
持续更新。[#262](https://github.com/apache/doris-operator/pull/262) 
[#266](https://github.com/apache/doris-operator/pull/266)
+- 修复重复 reconcile 问题。[#263](https://github.com/apache/doris-operator/pull/263) 
[#265](https://github.com/apache/doris-operator/pull/265)
+- 修正 BE 默认缓存路径。[#266](https://github.com/apache/doris-operator/pull/266)
+
+#### DorisCluster
+
+- 避免升级 Operator 时重启 Doris 
Pod。[#226](https://github.com/apache/doris-operator/pull/226)
+- 合并共享 Pod 
环境变量数组时使用深拷贝。[#236](https://github.com/apache/doris-operator/pull/236)
+- 修复跨 namespace 缩容 FE 时 MySQL Client 
失败的问题。[#240](https://github.com/apache/doris-operator/pull/240)
+- 修复 `electionNumber` 为 nil 
时的部署失败问题。[#260](https://github.com/apache/doris-operator/pull/260)
+
+#### 其他变更
+
+- 修复 StatefulSet 的 resource model 
单元测试。[#252](https://github.com/apache/doris-operator/pull/252)
+
+### 致谢
+
+- [intelligentfu8](https://github.com/intelligentfu8)
+- [catpineapple](https://github.com/catpineapple)
+- [hechao-ustc](https://github.com/hechao-ustc)
diff --git a/releasenotes/ecosystem/doris-operator.md 
b/releasenotes/ecosystem/doris-operator.md
index 79e4f570bb0..d482bd2e2d5 100644
--- a/releasenotes/ecosystem/doris-operator.md
+++ b/releasenotes/ecosystem/doris-operator.md
@@ -54,6 +54,126 @@ Refer to the image repository description for image formats.
 - [gohalo](https://github.com/gohalo)
 - [catpineapple](https://github.com/catpineapple)
 
+## 25.7.0
+
+Source: [Release Notes 
25.7.0](https://github.com/apache/doris-operator/issues/423)
+
+This version improves drop-node compatibility and debug image builds. It also 
fixes DDC pod information mounts, PVC tests, and event handling.
+
+### Features and Improvements
+
+- Made drop-node operations compatible with renamed compute groups. 
[#417](https://github.com/apache/doris-operator/pull/417)
+- Upgraded the Go version used to build the debug image. 
[#424](https://github.com/apache/doris-operator/pull/424)
+
+### Bug Fixes
+
+- Corrected spelling errors. 
[#413](https://github.com/apache/doris-operator/pull/413)
+- Fixed missing pod information mounts for DDC containers. 
[#415](https://github.com/apache/doris-operator/pull/415)
+- Fixed failing PVC construction unit tests. 
[#420](https://github.com/apache/doris-operator/pull/420)
+- Prevented a nil pointer error when `EventString` is nil. 
[#422](https://github.com/apache/doris-operator/pull/422)
+
+### Thanks
+
+- [intelligentfu8](https://github.com/intelligentfu8)
+- [ztonny](https://github.com/ztonny)
+
+## 25.6.0
+
+Source: [Release Notes 
25.6.0](https://github.com/apache/doris-operator/issues/414)
+
+This version extends `dorisctl` to storage-compute decoupled clusters and 
fixes PVC creation during initial deployment.
+
+### Features and Improvements
+
+- Supported using `dorisctl` to manage storage-compute decoupled Doris 
clusters. [#412](https://github.com/apache/doris-operator/pull/412)
+
+### Bug Fixes
+
+- Fixed PVCs not being created during initial deployment. 
[#410](https://github.com/apache/doris-operator/pull/410)
+
+### Thanks
+
+- [intelligentfu8](https://github.com/intelligentfu8)
+
+## 25.5.3
+
+Source: [Release Notes 
25.5.3](https://github.com/apache/doris-operator/issues/408)
+
+This version improves default images and documentation for DDC deployments, 
and prevents an internal reconciliation annotation from appearing in custom 
resources.
+
+### Features and Improvements
+
+- Used the BE image as the default init container image. 
[#405](https://github.com/apache/doris-operator/pull/405)
+- Added two feature descriptions to the README. 
[#406](https://github.com/apache/doris-operator/pull/406)
+- Added FoundationDB usage examples for different scenarios. 
[#407](https://github.com/apache/doris-operator/pull/407)
+
+### Bug Fixes
+
+- Prevented an annotation used only for reconciliation status checks from 
appearing in custom resources. 
[#404](https://github.com/apache/doris-operator/pull/404)
+
+### Thanks
+
+- [intelligentfu8](https://github.com/intelligentfu8)
+
+## 25.5.2
+
+Source: [Release Notes 
25.5.2](https://github.com/apache/doris-operator/issues/403)
+
+This version improves DDC reconciliation and debugging behavior.
+
+### Features and Improvements
+
+- Avoided redundant reconciliation when the `DorisDisaggregatedCluster` status 
is already consistent. [#399](https://github.com/apache/doris-operator/pull/399)
+- Added the `apache.com.doris/runmode` annotation for entering debug mode. 
[#400](https://github.com/apache/doris-operator/pull/400)
+- Made `DorisDisaggregatedCluster` reconciliation the default mode. 
[#402](https://github.com/apache/doris-operator/pull/402)
+
+### Thanks
+
+- [intelligentfu8](https://github.com/intelligentfu8)
+
+## 25.5.1
+
+Source: [Release Notes 
25.5.1](https://github.com/apache/doris-operator/issues/398)
+
+This version adds Kerberos support for DDC and aligns disaggregated release 
versions with the Operator version.
+
+### Features and Improvements
+
+- Added Kerberos support for DDC. 
[#396](https://github.com/apache/doris-operator/pull/396)
+
+### Bug Fixes
+
+- Aligned the disaggregated release version with the Operator version. 
[#395](https://github.com/apache/doris-operator/pull/395)
+
+### Thanks
+
+- [intelligentfu8](https://github.com/intelligentfu8)
+
+## 25.5.0
+
+Source: [Release Notes 
25.5.0](https://github.com/apache/doris-operator/issues/394)
+
+This version adds workload group and Helm chart support for storage-compute 
decoupled clusters. It also improves DDC initialization and fixes image, 
permission, and MetaService configuration issues.
+
+### Features and Improvements
+
+- Added workload group support for storage-compute decoupled Doris clusters. 
[#378](https://github.com/apache/doris-operator/pull/378)
+- Added `DorisDisaggregatedCluster` resource reconciliation. 
[#379](https://github.com/apache/doris-operator/pull/379)
+- Added Helm chart support for storage-compute decoupled Doris clusters. 
[#379](https://github.com/apache/doris-operator/pull/379) 
[#386](https://github.com/apache/doris-operator/pull/386) 
[#388](https://github.com/apache/doris-operator/pull/388) 
[#393](https://github.com/apache/doris-operator/pull/393)
+- Allowed DDC to skip the default system initialization check. 
[#389](https://github.com/apache/doris-operator/pull/389)
+
+### Bug Fixes
+
+- Adjusted the default Operator image. 
[#377](https://github.com/apache/doris-operator/pull/377)
+- Added an aggregated `ClusterRole`. 
[#380](https://github.com/apache/doris-operator/pull/380)
+- Fixed the MetaService replica count for disaggregated clusters. 
[#382](https://github.com/apache/doris-operator/pull/382)
+
+### Thanks
+
+- [wdxxl](https://github.com/wdxxl)
+- [catpineapple](https://github.com/catpineapple)
+- [intelligentfu8](https://github.com/intelligentfu8)
+
 ## 25.4.0
 
 Source: [Release Notes 
25.4.0](https://github.com/apache/doris-operator/issues/376)
@@ -97,6 +217,28 @@ This version improves PersistentVolume capabilities for 
`DorisCluster` and `Dori
 - [catpineapple](https://github.com/catpineapple)
 - [intelligentfu8](https://github.com/intelligentfu8)
 
+## 25.2.1
+
+Source: [Release Notes 
25.2.1](https://github.com/apache/doris-operator/issues/360)
+
+This version adds disaggregated cluster resources to the Helm chart, improves 
release-time version replacement and image repositories, and fixes Helm chart 
issues.
+
+### Features and Improvements
+
+- Added disaggregated custom resources to the Helm chart for deploying 
disaggregated clusters. 
[#355](https://github.com/apache/doris-operator/pull/355)
+- Made version fields replaceable variables in the release process. 
[#354](https://github.com/apache/doris-operator/pull/354)
+- Migrated images from the SelectDB repository to the Apache repository. 
[#357](https://github.com/apache/doris-operator/pull/357)
+
+### Bug Fixes
+
+- Reverted selected changes from PR 354. 
[#358](https://github.com/apache/doris-operator/pull/358)
+- Fixed the Helm chart `apiVersion`. 
[#359](https://github.com/apache/doris-operator/pull/359)
+
+### Thanks
+
+- [xiacongling](https://github.com/xiacongling)
+- [intelligentfu8](https://github.com/intelligentfu8)
+
 ## 25.2.0
 
 Source: [Release Notes 
25.2.0](https://github.com/apache/doris-operator/issues/351)
@@ -128,3 +270,175 @@ This version adds support for accessing 
Kerberos-protected data systems, upgrade
 
 - [catpineapple](https://github.com/catpineapple)
 - [intelligentfu8](https://github.com/intelligentfu8)
+
+## 25.1.0
+
+Source: [Release Notes 
25.1.0](https://github.com/apache/doris-operator/issues/333)
+
+This version improves BE scheduling and configuration updates, adds controller 
tests, fixes StatefulSet preparation, and migrates image tags to the Apache 
repository.
+
+### Features and Improvements
+
+- Added BE-to-FE affinity so the Operator prefers to schedule BEs on nodes 
that run FEs. [#328](https://github.com/apache/doris-operator/pull/328)
+- Watched ConfigMap changes and restarted Doris when startup configuration 
changed. [#331](https://github.com/apache/doris-operator/pull/331)
+- Allowed BEs to skip default system initialization. 
[#321](https://github.com/apache/doris-operator/pull/321)
+- Added controller unit tests. 
[#322](https://github.com/apache/doris-operator/pull/322)
+
+### Bug Fixes
+
+- Fixed parameters passed to `prepareStatefulsetApply`. 
[#326](https://github.com/apache/doris-operator/pull/326)
+
+### Other Changes
+
+- Migrated all image tags from the SelectDB repository to the Apache 
repository. [#329](https://github.com/apache/doris-operator/pull/329)
+
+### Thanks
+
+- [catpineapple](https://github.com/catpineapple)
+- [intelligentfu8](https://github.com/intelligentfu8)
+
+## 24.2.0
+
+Source: [Release Note 
24.2.0](https://github.com/apache/doris-operator/issues/319)
+
+This version adds multi-secret support for `DorisDisaggregatedCluster` and 
decommission-based BE scale-down for compute groups. It also improves Arrow 
Flight SQL exposure, resource cleanup, tests, documentation, and examples.
+
+### Features and Improvements
+
+- Supported scaling down BEs in DDC compute groups through decommissioning. 
[#306](https://github.com/apache/doris-operator/pull/306)
+- Supported username and password configuration and multiple secrets for DDC. 
[#312](https://github.com/apache/doris-operator/pull/312)
+- Exposed Arrow Flight SQL ports as container ports. 
[#295](https://github.com/apache/doris-operator/pull/295)
+- Exposed Arrow Flight SQL ports in disaggregated services. 
[#307](https://github.com/apache/doris-operator/pull/307)
+- Expanded unit test coverage. 
[#315](https://github.com/apache/doris-operator/pull/315)
+- Refactored compute group resource cleanup. 
[#318](https://github.com/apache/doris-operator/pull/318)
+
+### Bug Fixes
+
+- Fixed SQL client behavior when dropping compute groups. 
[#314](https://github.com/apache/doris-operator/pull/314)
+- Fixed service labels. 
[#318](https://github.com/apache/doris-operator/pull/318)
+- Fixed compute group removal when `UniqueId` contains a hyphen. 
[#318](https://github.com/apache/doris-operator/pull/318)
+- Added safety checks for FE scale-down during cluster updates. 
[#320](https://github.com/apache/doris-operator/pull/320)
+
+### Other Changes
+
+- Improved the README. 
[#303](https://github.com/apache/doris-operator/pull/303)
+- Removed unused files, including obsolete Dockerfile and DDM code. 
[#309](https://github.com/apache/doris-operator/pull/309) 
[#314](https://github.com/apache/doris-operator/pull/314)
+- Improved `DorisDisaggregatedCluster` CRD examples. 
[#313](https://github.com/apache/doris-operator/pull/313)
+
+### Thanks
+
+- [jonasbrami](https://github.com/jonasbrami)
+- [hechao-ustc](https://github.com/hechao-ustc)
+- [intelligentfu8](https://github.com/intelligentfu8)
+- [catpineapple](https://github.com/catpineapple)
+
+## 24.1.0
+
+Source: [Release Note 
24.1.0](https://github.com/apache/doris-operator/issues/293)
+
+This version adds workload group support to `DorisCluster`, introduces rolling 
restarts, and fixes FE deployment and access issues.
+
+Workload groups require the official Apache Doris 2.1.7 image or later. For 
earlier Doris versions, build a compatible image manually.
+
+### Features and Improvements
+
+- Added workload group support for Doris BEs. 
[#289](https://github.com/apache/doris-operator/pull/289)
+- Added rolling restarts for Doris clusters. 
[#292](https://github.com/apache/doris-operator/pull/292)
+- Updated the controller-gen version in the Makefile. 
[#275](https://github.com/apache/doris-operator/pull/275)
+- Added license checks to GitHub Actions. 
[#278](https://github.com/apache/doris-operator/pull/278) 
[#279](https://github.com/apache/doris-operator/pull/279) 
[#280](https://github.com/apache/doris-operator/pull/280)
+- Added a default issue template. 
[#288](https://github.com/apache/doris-operator/pull/288)
+
+### Bug Fixes
+
+- Fixed a nil pointer error when FE `electionNumber` is not set in a 
`DorisCluster` resource. 
[#285](https://github.com/apache/doris-operator/pull/285)
+- Fixed the FE access address to use the service name and namespace. 
[#291](https://github.com/apache/doris-operator/pull/291)
+
+### Thanks
+
+- [intelligentfu8](https://github.com/intelligentfu8)
+- [catpineapple](https://github.com/catpineapple)
+
+## 24.0.0
+
+Source: [Release Note 
24.0.0](https://github.com/apache/doris-operator/issues/272)
+
+This version introduces the `DorisDisaggregatedCluster` (DDC) custom resource 
for deploying storage-compute decoupled Apache Doris clusters. It also expands 
support for storage-compute coupled deployments through `DorisCluster` (DCR).
+
+DDC requires Apache Doris 3.0.2 or later.
+
+### New Features
+
+#### DorisDisaggregatedCluster
+
+- Added FoundationDB module access. 
[#186](https://github.com/apache/doris-operator/pull/186)
+- Added MetaService module deployment. 
[#194](https://github.com/apache/doris-operator/pull/194)
+- Added FE module deployment. 
[#199](https://github.com/apache/doris-operator/pull/199)
+- Added compute group module deployment. 
[#185](https://github.com/apache/doris-operator/pull/185) 
[#189](https://github.com/apache/doris-operator/pull/189) 
[#192](https://github.com/apache/doris-operator/pull/192) 
[#197](https://github.com/apache/doris-operator/pull/197)
+- Added image entrypoint support for disaggregated Doris components. 
[#195](https://github.com/apache/doris-operator/pull/195) 
[#196](https://github.com/apache/doris-operator/pull/196)
+- Added FE scale-down. 
[#225](https://github.com/apache/doris-operator/pull/225)
+- Added compute group scale-down and resource cleanup. 
[#238](https://github.com/apache/doris-operator/pull/238)
+- Added FE scale-down through the SQL interface. 
[#255](https://github.com/apache/doris-operator/pull/255)
+- Added compute group scale-down through the SQL interface. 
[#256](https://github.com/apache/doris-operator/pull/256)
+
+#### DorisCluster
+
+- Exposed the Arrow Flight SQL port through external services. 
[#251](https://github.com/apache/doris-operator/pull/251)
+
+### Improvements
+
+#### DorisDisaggregatedCluster
+
+- Supported creating compute groups through `be.conf` and PVC configuration. 
[#198](https://github.com/apache/doris-operator/pull/198)
+- Improved the README and DDC example YAML files. 
[#203](https://github.com/apache/doris-operator/pull/203) 
[#210](https://github.com/apache/doris-operator/pull/210) 
[#211](https://github.com/apache/doris-operator/pull/211) 
[#214](https://github.com/apache/doris-operator/pull/214)
+- Updated README examples to use the latest version. 
[#220](https://github.com/apache/doris-operator/pull/220)
+- Added an Operator switch for enabling DDC deployments. 
[#204](https://github.com/apache/doris-operator/pull/204)
+- Added `SystemInitialization` to prepare system environments. 
[#212](https://github.com/apache/doris-operator/pull/212)
+- Kept compute group terminology aligned with Doris naming changes. 
[#215](https://github.com/apache/doris-operator/pull/215) 
[#245](https://github.com/apache/doris-operator/pull/245)
+- Removed the MetaService replicas CRD. 
[#227](https://github.com/apache/doris-operator/pull/227)
+- Reworked the MetaService CRD into the `DorisDisaggregatedCluster` CRD. 
[#234](https://github.com/apache/doris-operator/pull/234)
+- Changed the compute group identifier to `UniqueId` for the new SQL 
interface. [#239](https://github.com/apache/doris-operator/pull/239)
+- Added an FE SQL image entrypoint and cluster ID hash code. 
[#249](https://github.com/apache/doris-operator/pull/249)
+- Migrated DDC operations from the HTTP interface to the SQL interface. 
[#254](https://github.com/apache/doris-operator/pull/254)
+- Added `timeoutSeconds` for pod liveness probes. 
[#257](https://github.com/apache/doris-operator/pull/257)
+- Added `logNotStore` so FEs can skip log PVC creation. 
[#266](https://github.com/apache/doris-operator/pull/266)
+- Updated DDC examples and documentation. 
[#268](https://github.com/apache/doris-operator/pull/268)
+
+#### DorisCluster
+
+- Added `timeoutSeconds` for pod liveness probes. 
[#257](https://github.com/apache/doris-operator/pull/257)
+
+#### Other Changes
+
+- Added unit tests for common utilities. 
[#226](https://github.com/apache/doris-operator/pull/226)
+- Added unit tests for resource and controller models. 
[#232](https://github.com/apache/doris-operator/pull/232)
+- Updated Helm chart configuration for Artifact Hub. 
[#244](https://github.com/apache/doris-operator/pull/244)
+- Changed the organization name from SelectDB to Apache. 
[#247](https://github.com/apache/doris-operator/pull/247)
+
+### Bug Fixes
+
+#### DorisDisaggregatedCluster
+
+- Fixed pod affinity and StatefulSet PVC pointer handling. 
[#209](https://github.com/apache/doris-operator/pull/209)
+- Corrected the default BE storage path. 
[#243](https://github.com/apache/doris-operator/pull/243)
+- Fixed pod restarts during initial deployment caused by a duplicate 
`ms_token` environment variable. 
[#259](https://github.com/apache/doris-operator/pull/259)
+- Fixed the BE ConfigMap path used by the image entrypoint. 
[#261](https://github.com/apache/doris-operator/pull/261)
+- Fixed deployments with a nil `electionNumber` and stopped services from 
updating continuously. 
[#262](https://github.com/apache/doris-operator/pull/262) 
[#266](https://github.com/apache/doris-operator/pull/266)
+- Fixed repeated reconciliation. 
[#263](https://github.com/apache/doris-operator/pull/263) 
[#265](https://github.com/apache/doris-operator/pull/265)
+- Corrected the default BE cache path. 
[#266](https://github.com/apache/doris-operator/pull/266)
+
+#### DorisCluster
+
+- Prevented Operator upgrades from restarting Doris pods. 
[#226](https://github.com/apache/doris-operator/pull/226)
+- Used deep copies when merging shared pod environment variable arrays. 
[#236](https://github.com/apache/doris-operator/pull/236)
+- Fixed MySQL client failures when scaling down FEs across namespaces. 
[#240](https://github.com/apache/doris-operator/pull/240)
+- Fixed deployment failures when `electionNumber` is nil. 
[#260](https://github.com/apache/doris-operator/pull/260)
+
+#### Other Changes
+
+- Fixed resource model unit tests for StatefulSets. 
[#252](https://github.com/apache/doris-operator/pull/252)
+
+### Thanks
+
+- [intelligentfu8](https://github.com/intelligentfu8)
+- [catpineapple](https://github.com/catpineapple)
+- [hechao-ustc](https://github.com/hechao-ustc)
diff --git a/src/components/download-form-next/DownloadFormNext.tsx 
b/src/components/download-form-next/DownloadFormNext.tsx
index 71720dedbf7..eb87efdf6ab 100644
--- a/src/components/download-form-next/DownloadFormNext.tsx
+++ b/src/components/download-form-next/DownloadFormNext.tsx
@@ -13,7 +13,7 @@ import Link from '@docusaurus/Link';
 import './download-page.scss';
 import LinkWithArrow from '@site/src/components/link-arrow';
 import clsx from 'clsx';
-import { ALL_VERSIONS, TOOL_VERSIONS } from '@site/src/constant/download.data';
+import { ALL_VERSIONS, TOOL_RELEASE_NOTES, TOOL_VERSIONS, ToolsEnum } from 
'@site/src/constant/download.data';
 import * as semver from 'semver';
 import { CheckedIcon } from '@site/src/components/Icons/checked-icon';
 import { LayoutNext } from '@site/src/components/home-next/LayoutNext';
@@ -31,6 +31,7 @@ export default function DownloadFormNext(): JSX.Element {
     const [releaseFlag, setReleaseFlag] = useState<boolean>(true);
     const [downloadType, setDownloadType] = useState(DownloadTypeEnum.Binary);
     const [releaseNote, setReleaseNote] = 
useState('/docs/dev/releasenotes/v4.0/release-4.0.0');
+    const [ecosystemTool, setEcosystemTool] = 
useState<ToolsEnum>(ToolsEnum.Kafka);
 
     const changeVersion = (val: string) => {
         setVersion(val);
@@ -346,8 +347,16 @@ export default function DownloadFormNext(): JSX.Element {
                                         <CheckedIcon />
                                         <span>Doris Streamloader</span>
                                     </li>
+                                    <li>
+                                        <CheckedIcon />
+                                        <span>Doris Operator</span>
+                                    </li>
                                 </ul>
-                                <div>
+                                <div 
className="download-next__ecosystem-links">
+                                    <LinkWithArrow
+                                        to={TOOL_RELEASE_NOTES[ecosystemTool]}
+                                        text="Release Notes"
+                                    />
                                     <LinkWithArrow
                                         
to="/docs/4.x/connection-integration/data-integration/intro"
                                         text="More Tools"
@@ -355,7 +364,7 @@ export default function DownloadFormNext(): JSX.Element {
                                 </div>
                             </div>
                             <div className="download-next__split-card">
-                                <DownloadFormTools data={TOOL_VERSIONS} />
+                                <DownloadFormTools data={TOOL_VERSIONS} 
onToolChange={setEcosystemTool} />
                             </div>
                         </div>
                     </div>
diff --git a/src/components/download-form-next/download-page.scss 
b/src/components/download-form-next/download-page.scss
index f183cdcdda5..44bdab9dc46 100644
--- a/src/components/download-form-next/download-page.scss
+++ b/src/components/download-form-next/download-page.scss
@@ -331,6 +331,13 @@
     }
 }
 
+.download-next__ecosystem-links {
+    display: flex;
+    flex-direction: column;
+    align-items: flex-start;
+    gap: 12px;
+}
+
 // ─── Run anywhere (single CTA card) ────────────────────────────────────────
 
 .download-next__run {
diff --git a/src/components/download-form/download-form-tools.test.js 
b/src/components/download-form/download-form-tools.test.js
new file mode 100644
index 00000000000..813555f576a
--- /dev/null
+++ b/src/components/download-form/download-form-tools.test.js
@@ -0,0 +1,141 @@
+const assert = require('node:assert/strict');
+const fs = require('node:fs');
+const Module = require('node:module');
+const path = require('node:path');
+const test = require('node:test');
+const typescript = require('typescript');
+
+const dataPath = path.join(__dirname, '../../constant/download.data.ts');
+const compiledData = typescript.transpileModule(fs.readFileSync(dataPath, 
'utf8'), {
+    compilerOptions: {
+        module: typescript.ModuleKind.CommonJS,
+        target: typescript.ScriptTarget.ES2020,
+    },
+}).outputText;
+const dataModule = new Module(dataPath, module);
+dataModule.filename = dataPath;
+dataModule.paths = Module._nodeModulePaths(path.dirname(dataPath));
+dataModule._compile(compiledData, dataPath);
+
+const { TOOL_RELEASE_NOTES, TOOL_VERSIONS, ToolsEnum } = dataModule.exports;
+
+const OPERATOR_SOURCE_VERSIONS = [
+    '25.8.0',
+    '25.7.0',
+    '25.6.0',
+    '25.5.3',
+    '25.5.2',
+    '25.5.1',
+    '25.5.0',
+    '25.4.0',
+    '25.3.0',
+    '25.2.1',
+    '25.2.0',
+    '25.1.0',
+    '24.2.0',
+    '24.1.0',
+    '24.0.0',
+];
+
+const OPERATOR_BINARY_VERSIONS = [
+    '25.8.0',
+    '25.7.0',
+    '25.6.0',
+    '25.5.3',
+    '25.5.2',
+    '25.5.1',
+    '25.5.0',
+    '25.4.0',
+    '25.3.0',
+    '25.2.1',
+    '25.2.0',
+    '25.1.0',
+    '24.2.0',
+];
+
+test('every ecosystem download tool maps to its release notes page', () => {
+    assert.deepEqual(TOOL_RELEASE_NOTES, {
+        [ToolsEnum.Kafka]: '/releases/ecosystem/doris-kafka-connector',
+        [ToolsEnum.Flink]: '/releases/ecosystem/doris-flink-connector',
+        [ToolsEnum.Spark]: '/releases/ecosystem/doris-spark-connector',
+        [ToolsEnum.StreamLoader]: '/releases/ecosystem/doris-streamloader',
+        [ToolsEnum.Operator]: '/releases/ecosystem/doris-operator',
+    });
+});
+
+test('the ecosystem release notes link follows the selected download tool', () 
=> {
+    const formSource = fs.readFileSync(path.join(__dirname, 
'download-form-tools.tsx'), 'utf8');
+    const pageSource = fs.readFileSync(path.join(__dirname, 
'../download-form-next/DownloadFormNext.tsx'), 'utf8');
+
+    assert.match(formSource, /onToolChange\?: \(tool: ToolsEnum\) => void/);
+    assert.match(formSource, /onToolChange\?\.\(tool as ToolsEnum\)/);
+    assert.match(
+        pageSource,
+        /const \[ecosystemTool, setEcosystemTool\] = 
useState<ToolsEnum>\(ToolsEnum\.Kafka\)/,
+    );
+    assert.match(pageSource, 
/to=\{TOOL_RELEASE_NOTES\[ecosystemTool\]\}[\s\S]*?text="Release Notes"/);
+    assert.match(pageSource, /<DownloadFormTools data=\{TOOL_VERSIONS\} 
onToolChange=\{setEcosystemTool\} \/>/);
+    assert.ok(
+        pageSource.indexOf('text="Release Notes"') < 
pageSource.indexOf('text="More Tools"'),
+        'Release Notes should appear above More Tools',
+    );
+});
+
+test('Doris Operator exposes every source release and its verification files', 
() => {
+    assert.equal(ToolsEnum.Operator, 'Doris Operator');
+
+    const operator = TOOL_VERSIONS.find(tool => tool.value === 
ToolsEnum.Operator);
+    assert.ok(operator);
+    assert.deepEqual(
+        operator.children.filter(release => release.Source).map(release => 
release.value),
+        OPERATOR_SOURCE_VERSIONS,
+    );
+
+    for (const release of operator.children.filter(release => release.Source)) 
{
+        const source = 
`https://downloads.apache.org/doris/doris-operator/${release.value}/apache-doris-operator-${release.value}-src.tar.gz`;
+        assert.equal(release.Source, source);
+        assert.equal(release.gz, source);
+        assert.equal(release.asc, `${source}.asc`);
+        assert.equal(release.sha512, `${source}.sha512`);
+    }
+});
+
+test('Doris Operator exposes a docker pull command for every published binary 
version', () => {
+    const operator = TOOL_VERSIONS.find(tool => tool.value === 
ToolsEnum.Operator);
+    assert.ok(operator);
+    assert.deepEqual(
+        operator.children.filter(release => release.Binary).map(release => 
release.value),
+        OPERATOR_BINARY_VERSIONS,
+    );
+
+    for (const release of operator.children.filter(release => release.Binary)) 
{
+        assert.equal(release.Binary, `docker pull 
apache/doris:operator-${release.value}`);
+    }
+});
+
+test('the ecosystem form renders Operator binary downloads as a copyable 
command', () => {
+    const formSource = fs.readFileSync(path.join(__dirname, 
'download-form-tools.tsx'), 'utf8');
+    const pageSource = fs.readFileSync(path.join(__dirname, 
'../download-form-next/DownloadFormNext.tsx'), 'utf8');
+
+    assert.match(formSource, /const isOperatorBinary\s*=/);
+    assert.match(formSource, /\{isOperatorBinary\s*\?\s*\(/);
+    assert.match(formSource, /<code/);
+    assert.doesNotMatch(formSource, /<input/);
+    assert.match(formSource, /aria-label="Copy Docker pull command"/);
+    assert.match(formSource, /options\.filter\(option => 
option\[downloadType\]\)/);
+    assert.match(formSource, /bg-black/);
+    assert.match(formSource, /text-\[#49D7AA\]/);
+    assert.match(formSource, /backgroundColor: '#000000'/);
+    assert.match(formSource, /color: '#49D7AA'/);
+    assert.match(formSource, /aria-hidden="true"[\s\S]*?>\s*\$\s*<\/span>/);
+    assert.doesNotMatch(formSource, /event\.currentTarget\.select\(\)/);
+    assert.match(formSource, />\s*Docker command\s*<\/span>/);
+    assert.match(formSource, /whitespace-normal/);
+    assert.match(formSource, /break-all/);
+    assert.doesNotMatch(formSource, /whitespace-nowrap/);
+    assert.ok(
+        formSource.indexOf('aria-label="Copy Docker pull command"') < 
formSource.indexOf('<code'),
+        'Copy action should not consume space on the command line',
+    );
+    assert.match(pageSource, /<span>Doris Operator<\/span>/);
+});
diff --git a/src/components/download-form/download-form-tools.tsx 
b/src/components/download-form/download-form-tools.tsx
index 5c02e1e82de..201269bdb70 100644
--- a/src/components/download-form/download-form-tools.tsx
+++ b/src/components/download-form/download-form-tools.tsx
@@ -9,19 +9,24 @@ import { DownloadIcon } from '../Icons/download-icon';
 
 interface DownloadFormToolsProps {
     data: Option[];
+    onToolChange?: (tool: ToolsEnum) => void;
 }
 export default function DownloadFormTools(props: DownloadFormToolsProps) {
-    const { data } = props;
+    const { data, onToolChange } = props;
     const [form] = useForm();
     const tool = useWatch('tool', form);
     const architecture = useWatch('architecture', form);
     const version = useWatch('version', form);
     const tarBall = useWatch('tarBall', form);
+    const isOperatorBinary = tool === ToolsEnum.Operator && tarBall === 
DownloadTypeEnum.Binary;
 
     const getOptions = useMemo(() => {
         if (!tool) return [];
-        return data.find(item => tool === item.value).children;
-    }, [tool]);
+        const options = data.find(item => tool === item.value).children;
+        if (tool !== ToolsEnum.Operator) return options;
+        const downloadType = tarBall || DownloadTypeEnum.Binary;
+        return options.filter(option => option[downloadType]);
+    }, [tool, tarBall]);
 
     const getArchitectureOptions = useMemo(() => {
         if (!tool || !version || form.getFieldValue('tool') !== 
ToolsEnum.StreamLoader) return [];
@@ -61,34 +66,70 @@ export default function DownloadFormTools(props: 
DownloadFormToolsProps) {
                     .find(item => item.value === version[0])
                     .children.find(child => child.value === version[1]);
             } else {
-                currentVersion = currentTool.find(item => version === 
item.value);
+                const selectedVersion = Array.isArray(version) ? version[0] : 
version;
+                currentVersion = currentTool.find(item => selectedVersion === 
item.value);
             }
-            return !params.type ? `${currentVersion[params.tarBall]}` : 
`${currentVersion[params.tarBall]}.${params.type}`;
+            if (!currentVersion) return '';
+            const downloadLink = currentVersion[params.tarBall];
+            if (!downloadLink) return '';
+            if (!params.type) return `${downloadLink}`;
+            return `${currentVersion[params.type] || 
`${downloadLink}.${params.type}`}`;
         }
     };
 
+    useEffect(() => {
+        if (tool) onToolChange?.(tool as ToolsEnum);
+    }, [tool, onToolChange]);
+
     useEffect(() => {
         if (tool) {
-            if (tool === ToolsEnum.Flink || tool === ToolsEnum.Spark) {
+            if (tool === ToolsEnum.Operator) {
+                const operatorVersions = data
+                    .find(item => item.value === ToolsEnum.Operator)
+                    .children.filter(option => option.Binary);
+                form.setFieldValue('version', operatorVersions[0].value);
+            } else if (tool === ToolsEnum.Flink || tool === ToolsEnum.Spark) {
                 form.setFieldValue('version', [getOptions[0].value, 
getOptions[0].children[0].value]);
             } else {
                 form.setFieldValue('version', getOptions[0].value);
             }
+            form.setFieldValue('tarBall', DownloadTypeEnum.Binary);
         }
     }, [tool]);
 
+    useEffect(() => {
+        if (tool !== ToolsEnum.Operator || !tarBall) return;
+        const options = data
+            .find(item => item.value === ToolsEnum.Operator)
+            .children.filter(option => option[tarBall]);
+        const selectedVersion = Array.isArray(version) ? version[0] : version;
+        if (!options.some(option => option.value === selectedVersion)) {
+            form.setFieldValue('version', options[0].value);
+        }
+    }, [tarBall]);
+
     useEffect(() => {
         if (version && getArchitectureOptions?.length > 0) {
             form.setFieldValue('architecture', 
getArchitectureOptions[0].value);
         }
     }, [version]);
 
+    const operatorBinaryCommand = isOperatorBinary
+        ? getDownloadLinkByCard({
+              version: version,
+              cpu: architecture,
+              tarBall: DownloadTypeEnum.Binary,
+              type: '',
+          })
+        : '';
+
     return (
         <div className="rounded-lg border border-b-[0.375rem] border-primary 
px-8 pt-[3.125rem] pb-[2.1875rem]">
             <div className="mb-8 text-xl font-medium text-left">Downloads</div>
             <Form
                 form={form}
                 onFinish={val => {
+                    if (isOperatorBinary) return;
                     const url = getDownloadLinkByCard({
                         version: version,
                         cpu: architecture,
@@ -133,7 +174,7 @@ export default function DownloadFormTools(props: 
DownloadFormToolsProps) {
                                 <FormSelect
                                     placeholder="Version"
                                     label="Version"
-                                    isCascader={true}
+                                    isCascader={tool !== ToolsEnum.Operator}
                                     options={getOptions}
                                     displayRender={label => {
                                         if (label.length > 1) {
@@ -149,86 +190,129 @@ export default function DownloadFormTools(props: 
DownloadFormToolsProps) {
                         )
                     }
                 </Form.Item>
-                <Form.Item noStyle shouldUpdate>
-                    {({ getFieldValue }) => (
-                        <Form.Item name="tarBall" rules={[{ required: true }]}>
-                            <FormSelect
-                                placeholder="Tarball"
-                                label="Tarball"
-                                isCascader={false}
-                                options={[
-                                    {
-                                        label: DownloadTypeEnum.Binary,
-                                        value: DownloadTypeEnum.Binary,
-                                    },
-                                    {
-                                        label: DownloadTypeEnum.Source,
-                                        value: DownloadTypeEnum.Source,
-                                    },
-                                ]}
-                            />
-                        </Form.Item>
-                    )}
-                </Form.Item>
-                <Form.Item style={{ marginBottom: 0 }} colon={false}>
-                    <button type="submit" className="button-primary w-full 
text-lg">
-                        Download
-                    </button>
+                <Form.Item name="tarBall" rules={[{ required: true }]}>
+                    <FormSelect
+                        placeholder="Tarball"
+                        label="Tarball"
+                        isCascader={false}
+                        options={[
+                            {
+                                label: DownloadTypeEnum.Binary,
+                                value: DownloadTypeEnum.Binary,
+                            },
+                            {
+                                label: DownloadTypeEnum.Source,
+                                value: DownloadTypeEnum.Source,
+                            },
+                        ]}
+                    />
                 </Form.Item>
-                <div
-                    className="flex cursor-pointer text-primary items-center 
mt-4 justify-center"
-                    onClick={() => {
-                        const url = getDownloadLinkByCard({
-                            version: version,
-                            cpu: architecture,
-                            tarBall: tarBall,
-                            type: '',
-                        });
-                        copy(url);
-                        message.success('Copy Successfully!');
-                    }}
-                >
-                    <span className="mr-2">Copy link</span>
-                    <svg xmlns="http://www.w3.org/2000/svg"; width="16" 
height="16" viewBox="0 0 16 16" fill="none">
-                        <rect x="2.5" y="5.5" width="8" height="8" 
rx="0.564706" stroke="#11A679" strokeWidth="1.2" />
-                        <path
-                            fillRule="evenodd"
-                            clipRule="evenodd"
-                            d="M6.0999 1.89996C5.43716 1.89996 4.8999 2.43722 
4.8999 3.09996V5.49995H6.0999V3.09996L12.8999 
3.09996V9.89996H10.5V11.1H12.8999C13.5626 11.1 14.0999 10.5627 14.0999 
9.89996V3.09996C14.0999 2.43722 13.5626 1.89996 12.8999 1.89996H6.0999Z"
-                            fill="#11A679"
-                        />
-                    </svg>
-                </div>
-                <div className="flex justify-center mt-4">
+                {isOperatorBinary ? (
+                    <Form.Item style={{ marginBottom: 0 }} colon={false}>
+                        <div
+                            className="rounded-lg border border-[#49D7AA] 
bg-black p-4"
+                            style={{ backgroundColor: '#000000' }}
+                        >
+                            <div className="mb-3 flex items-center 
justify-between gap-4 border-b border-[#49D7AA]/30 pb-3">
+                                <span className="text-xs font-semibold 
uppercase tracking-[0.12em] text-[#49D7AA]">
+                                    Docker command
+                                </span>
+                                <button
+                                    aria-label="Copy Docker pull command"
+                                    className="shrink-0 rounded-md border 
border-[#49D7AA] bg-black px-3 py-1.5 text-xs font-semibold uppercase 
tracking-[0.08em] text-[#49D7AA] focus-visible:outline-none 
focus-visible:ring-2 focus-visible:ring-[#49D7AA] focus-visible:ring-offset-2 
focus-visible:ring-offset-black disabled:cursor-not-allowed disabled:opacity-50"
+                                    disabled={!operatorBinaryCommand}
+                                    style={{ backgroundColor: '#000000', 
borderColor: '#49D7AA', color: '#49D7AA' }}
+                                    type="button"
+                                    onClick={() => {
+                                        copy(operatorBinaryCommand);
+                                        message.success('Copy Successfully!');
+                                    }}
+                                >
+                                    Copy
+                                </button>
+                            </div>
+                            <div className="flex min-w-0 items-start">
+                                <span
+                                    aria-hidden="true"
+                                    className="mr-3 mt-0.5 select-none 
font-mono text-sm font-semibold text-[#49D7AA]"
+                                >
+                                    $
+                                </span>
+                                <code
+                                    aria-label="Docker pull command"
+                                    className="min-w-0 flex-1 select-text 
whitespace-normal break-all !bg-black !p-0 font-mono text-sm leading-6 
!text-[#49D7AA]"
+                                    style={{ backgroundColor: '#000000', 
color: '#49D7AA' }}
+                                >
+                                    {operatorBinaryCommand}
+                                </code>
+                            </div>
+                        </div>
+                    </Form.Item>
+                ) : (
+                    <Form.Item style={{ marginBottom: 0 }} colon={false}>
+                        <button type="submit" className="button-primary w-full 
text-lg">
+                            Download
+                        </button>
+                    </Form.Item>
+                )}
+                {!isOperatorBinary && (
                     <div
-                        className="inline-flex items-center text-[#8592A6] 
cursor-pointer hover:underline hover:text-primary"
+                        className="flex cursor-pointer text-primary 
items-center mt-4 justify-center"
                         onClick={() => {
                             const url = getDownloadLinkByCard({
                                 version: version,
                                 cpu: architecture,
                                 tarBall: tarBall,
-                                type: 'asc',
+                                type: '',
                             });
-                            window.open(url, '_blank');
+                            copy(url);
+                            message.success('Copy Successfully!');
                         }}
                     >
-                        ASC
+                        <span className="mr-2">Copy link</span>
+                        <svg xmlns="http://www.w3.org/2000/svg"; width="16" 
height="16" viewBox="0 0 16 16" fill="none">
+                            <rect x="2.5" y="5.5" width="8" height="8" 
rx="0.564706" stroke="#11A679" strokeWidth="1.2" />
+                            <path
+                                fillRule="evenodd"
+                                clipRule="evenodd"
+                                d="M6.0999 1.89996C5.43716 1.89996 4.8999 
2.43722 4.8999 3.09996V5.49995H6.0999V3.09996L12.8999 
3.09996V9.89996H10.5V11.1H12.8999C13.5626 11.1 14.0999 10.5627 14.0999 
9.89996V3.09996C14.0999 2.43722 13.5626 1.89996 12.8999 1.89996H6.0999Z"
+                                fill="#11A679"
+                            />
+                        </svg>
                     </div>
-                    <div
-                        className="inline-flex items-center ml-4 
text-[#8592A6] hover:text-primary cursor-pointer hover:underline"
-                        onClick={() => {
-                            const url = getDownloadLinkByCard({
-                                version: version,
-                                cpu: architecture,
-                                tarBall: tarBall,
-                                type: 'sha512',
-                            });
-                            window.open(url, '_blank');
-                        }}
-                    >
-                        SHA-512
+                )}
+                {!isOperatorBinary && (
+                    <div className="flex justify-center mt-4">
+                        <div
+                            className="inline-flex items-center text-[#8592A6] 
cursor-pointer hover:underline hover:text-primary"
+                            onClick={() => {
+                                const url = getDownloadLinkByCard({
+                                    version: version,
+                                    cpu: architecture,
+                                    tarBall: tarBall,
+                                    type: 'asc',
+                                });
+                                window.open(url, '_blank');
+                            }}
+                        >
+                            ASC
+                        </div>
+                        <div
+                            className="inline-flex items-center ml-4 
text-[#8592A6] hover:text-primary cursor-pointer hover:underline"
+                            onClick={() => {
+                                const url = getDownloadLinkByCard({
+                                    version: version,
+                                    cpu: architecture,
+                                    tarBall: tarBall,
+                                    type: 'sha512',
+                                });
+                                window.open(url, '_blank');
+                            }}
+                        >
+                            SHA-512
+                        </div>
                     </div>
-                </div>
+                )}
                 {/* {tool === ToolsEnum.StreamLoader && ( */}
                 {/* <div className="flex justify-center mt-4 
hover:text-primary">
                     <div
diff --git a/src/constant/download.data.ts b/src/constant/download.data.ts
index 980f295fd25..53dafdd422a 100644
--- a/src/constant/download.data.ts
+++ b/src/constant/download.data.ts
@@ -5,6 +5,8 @@ export type Option = {
     asc?: string;
     sha512?: string;
     source?: string;
+    Binary?: string;
+    Source?: string;
     children?: (Option & { version?: string })[];
     majorVersion?: string;
 };
@@ -26,8 +28,17 @@ export enum ToolsEnum {
     Flink = 'Flink Doris Connector',
     Spark = 'Spark Doris Connector',
     StreamLoader = 'Doris Streamloader',
+    Operator = 'Doris Operator',
 }
 
+export const TOOL_RELEASE_NOTES: Record<ToolsEnum, string> = {
+    [ToolsEnum.Kafka]: '/releases/ecosystem/doris-kafka-connector',
+    [ToolsEnum.Flink]: '/releases/ecosystem/doris-flink-connector',
+    [ToolsEnum.Spark]: '/releases/ecosystem/doris-spark-connector',
+    [ToolsEnum.StreamLoader]: '/releases/ecosystem/doris-streamloader',
+    [ToolsEnum.Operator]: '/releases/ecosystem/doris-operator',
+};
+
 export const ORIGIN = 'https://download.selectdb.com/';
 export enum VersionEnum {
     Latest = '4.1.3',
@@ -2754,6 +2765,56 @@ const SPARK_SAME_SOURCE_2520 =
 const SPARK_SAME_SOURCE_2600 =
     
'https://downloads.apache.org/doris/spark-connector/26.0.0/apache-doris-spark-connector-26.0.0-src.tgz';
 
+const DORIS_OPERATOR_SOURCE_VERSIONS = [
+    '25.8.0',
+    '25.7.0',
+    '25.6.0',
+    '25.5.3',
+    '25.5.2',
+    '25.5.1',
+    '25.5.0',
+    '25.4.0',
+    '25.3.0',
+    '25.2.1',
+    '25.2.0',
+    '25.1.0',
+    '24.2.0',
+    '24.1.0',
+    '24.0.0',
+];
+
+const DORIS_OPERATOR_BINARY_VERSIONS = [
+    '25.8.0',
+    '25.7.0',
+    '25.6.0',
+    '25.5.3',
+    '25.5.2',
+    '25.5.1',
+    '25.5.0',
+    '25.4.0',
+    '25.3.0',
+    '25.2.1',
+    '25.2.0',
+    '25.1.0',
+    '24.2.0',
+];
+
+const DORIS_OPERATOR_VERSIONS = DORIS_OPERATOR_SOURCE_VERSIONS.map(version => {
+    const source = 
`https://downloads.apache.org/doris/doris-operator/${version}/apache-doris-operator-${version}-src.tar.gz`;
+
+    return {
+        label: version,
+        value: version,
+        gz: source,
+        Source: source,
+        asc: `${source}.asc`,
+        sha512: `${source}.sha512`,
+        ...(DORIS_OPERATOR_BINARY_VERSIONS.includes(version)
+            ? { Binary: `docker pull apache/doris:operator-${version}` }
+            : {}),
+    };
+});
+
 export const TOOL_VERSIONS = [
     {
         label: ToolsEnum.Kafka,
@@ -3519,6 +3580,11 @@ export const TOOL_VERSIONS = [
             },
         ],
     },
+    {
+        label: ToolsEnum.Operator,
+        value: ToolsEnum.Operator,
+        children: DORIS_OPERATOR_VERSIONS,
+    },
 ];
 
 export const RUN_ANYWHERE = [


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to