From f0eacbf6aaf71b2b3dda173dbd21c56b97b0522a Mon Sep 17 00:00:00 2001 From: Klesh Wong Date: Tue, 27 Oct 2026 10:33:30 +0800 Subject: [PATCH] Revert "chore(python): deprecate Python plugin framework (PyDevLake) (#9097)" This reverts commit 869256888618c315fb03f1a267add37bdd662efd. Reverting the Python plugin framework deprecation notices: the DEPRECATED banners, the startup WARN log, the PluginDeprecation backend interface, the `deprecated` field on GET /plugins, and the "Deprecated" badge/alert in the Connections page. Conflicts were resolved against later commits touching the same code; the deprecation alert UI added by #9144 is removed here as well, along with its now-unused DeprecationAlert style and icons. --- backend/core/plugin/plugin_meta.go | 8 ------- backend/core/runner/loader.go | 1 - backend/python/README.md | 22 ----------------- backend/python/plugins/azuredevops/README.md | 15 +----------- backend/server/api/plugininfo/plugininifo.go | 9 ++----- .../services/remote/plugin/plugin_impl.go | 12 ---------- .../src/plugins/register/azure/config.tsx | 3 --- .../src/routes/connection/connections.tsx | 16 ------------- config-ui/src/routes/connection/styled.ts | 24 ------------------- config-ui/src/types/plugin.ts | 2 -- 10 files changed, 3 insertions(+), 109 deletions(-) diff --git a/backend/core/plugin/plugin_meta.go b/backend/core/plugin/plugin_meta.go index 1807f3833b3..4047f7e54d3 100644 --- a/backend/core/plugin/plugin_meta.go +++ b/backend/core/plugin/plugin_meta.go @@ -44,14 +44,6 @@ type PluginIcon interface { SvgIcon() string } -// PluginDeprecation is implemented by plugins that have been deprecated. -// The DeprecationMessage should describe why the plugin is deprecated and -// what users should migrate to. Returns an empty string for non-deprecated -// plugins. -type PluginDeprecation interface { - DeprecationMessage() string -} - // PluginSource abstracts data sources type PluginSource interface { Connection() dal.Tabler diff --git a/backend/core/runner/loader.go b/backend/core/runner/loader.go index 9c6a32af9c5..f05a78632dc 100644 --- a/backend/core/runner/loader.go +++ b/backend/core/runner/loader.go @@ -91,7 +91,6 @@ func LoadGoPlugins(basicRes context.BasicRes) errors.Error { func LoadRemotePlugins(basicRes context.BasicRes) errors.Error { remotePluginDir := basicRes.GetConfig("REMOTE_PLUGIN_DIR") if remotePluginDir != "" { - basicRes.GetLogger().Warn(nil, "DEPRECATION WARNING: The Python plugin framework (PyDevLake) is deprecated and will be removed in 3 months. See https://github.com/apache/devlake/issues/9092 for the deprecation plan and migration guide. Please migrate Python plugins (e.g. azuredevops) to the Go-based equivalents (e.g. azuredevops_go).") basicRes.GetLogger().Info("Loading remote plugins") remote.Init(basicRes) walkErr := filepath.WalkDir(remotePluginDir, func(path string, d fs.DirEntry, err error) error { diff --git a/backend/python/README.md b/backend/python/README.md index 5c2f1288556..17bf0cee7b3 100644 --- a/backend/python/README.md +++ b/backend/python/README.md @@ -16,28 +16,6 @@ limitations under the License. --> # Pydevlake -> **⚠️ DEPRECATED — Scheduled for removal.** -> The Python plugin framework (PyDevLake) is deprecated and will be removed from -> Apache DevLake in 3 months per the deprecation plan in -> [#9092](https://github.com/apache/devlake/issues/9092). -> -> Reasons: -> - Only one plugin (`azuredevops`) ever shipped on this framework; the `dbt` -> plugin was already removed (#8970). -> - No feature/fix commits to Python plugins since Dec 2025; only dependency -> refreshes and runtime bumps land. -> - A fully-featured Go implementation, `azuredevops_go`, now supersedes the -> Python `azuredevops` plugin (including on-premises support, #9014). -> -> **What you should do:** -> - New plugins: write them in **Go**. See `backend/plugins/` for 40+ reference -> implementations. -> - Existing `azuredevops` (Python) users: migrate to `azuredevops_go` (a -> migration guide will be published during the deprecation window). -> -> No new Python plugins will be accepted. Only critical security fixes will land -> during the deprecation window. - Pydevlake is a framework for writing plugins for [DevLake](https://devlake.apache.org/) in Python. The framework source code can be found in [here](./pydevlake). diff --git a/backend/python/plugins/azuredevops/README.md b/backend/python/plugins/azuredevops/README.md index 172bc64f574..ed5366bfa1c 100644 --- a/backend/python/plugins/azuredevops/README.md +++ b/backend/python/plugins/azuredevops/README.md @@ -14,17 +14,4 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. --> -# Azure Devops Python Plugin - -> **⚠️ DEPRECATED — Scheduled for removal in 3 months.** -> This Python `azuredevops` plugin is deprecated in favor of the Go-based -> [`azuredevops_go`](../../plugins/azuredevops_go) plugin, which has broader -> feature coverage (including Azure DevOps Server / on-premises support, #9014). -> -> Please migrate existing connections and scopes to `azuredevops_go`. A migration -> guide will be published during the deprecation window — see -> [#9092](https://github.com/apache/devlake/issues/9092) for the full plan and -> timeline. -> -> No new features or fixes (other than critical security fixes) will be accepted -> on this plugin. \ No newline at end of file +# Azure Devops Python Plugin \ No newline at end of file diff --git a/backend/server/api/plugininfo/plugininifo.go b/backend/server/api/plugininfo/plugininifo.go index 285b6fd2ca2..de32fbc9476 100644 --- a/backend/server/api/plugininfo/plugininifo.go +++ b/backend/server/api/plugininfo/plugininifo.go @@ -75,9 +75,8 @@ type PluginMetric struct { } type PluginMeta struct { - Plugin string `json:"plugin"` - Metric PluginMetric `json:"metric"` - Deprecated bool `json:"deprecated"` + Plugin string `json:"plugin"` + Metric PluginMetric `json:"metric"` } type PluginMetas []PluginMeta @@ -208,10 +207,6 @@ func GetPluginMetas(c *gin.Context) { Plugin: name, } - if dp, ok := p.(plugin.PluginDeprecation); ok { - pluginMeta.Deprecated = dp.DeprecationMessage() != "" - } - // if this plugin has the plugin task info if pt, ok := p.(plugin.PluginMetric); ok { var err1 errors.Error diff --git a/backend/server/services/remote/plugin/plugin_impl.go b/backend/server/services/remote/plugin/plugin_impl.go index fe8e429709a..1cf768305d3 100644 --- a/backend/server/services/remote/plugin/plugin_impl.go +++ b/backend/server/services/remote/plugin/plugin_impl.go @@ -238,16 +238,4 @@ func (p *remotePluginImpl) MigrationScripts() []plugin.MigrationScript { return append(p.migrationScripts, migrationscripts.All(p.name)...) } -// DeprecationMessage implements plugin.PluginDeprecation. All remote (Python) -// plugins are deprecated and scheduled for removal in 3 months per the -// deprecation plan in issue #9092. -func (p *remotePluginImpl) DeprecationMessage() string { - return fmt.Sprintf( - "This Python plugin (%s) is DEPRECATED and will be removed in 3 months. "+ - "Please migrate to the Go-based equivalent. "+ - "See https://github.com/apache/devlake/issues/9092 for the deprecation plan and migration guide.", - p.name, - ) -} - var _ models.RemotePlugin = (*remotePluginImpl)(nil) diff --git a/config-ui/src/plugins/register/azure/config.tsx b/config-ui/src/plugins/register/azure/config.tsx index 28b387babb6..978a6af0934 100644 --- a/config-ui/src/plugins/register/azure/config.tsx +++ b/config-ui/src/plugins/register/azure/config.tsx @@ -28,9 +28,6 @@ export const AzureConfig: IPluginConfig = { name: 'Azure DevOps', icon: ({ color }) => , sort: 2, - isDeprecated: true, - deprecationMessage: - 'Python-based Azure DevOps plugin is DEPRECATED and will be removed in 3 months. Please migrate to the Go-based "Azure DevOps Go" plugin. See https://github.com/apache/devlake/issues/9092 for the deprecation plan and migration guide.', connection: { docLink: DOC_URL.PLUGIN.AZUREDEVOPS.BASIS, initialValues: {}, diff --git a/config-ui/src/routes/connection/connections.tsx b/config-ui/src/routes/connection/connections.tsx index e6bc20b0f4e..ea7af7bfd10 100644 --- a/config-ui/src/routes/connection/connections.tsx +++ b/config-ui/src/routes/connection/connections.tsx @@ -19,7 +19,6 @@ import { useState, useMemo } from 'react'; import { useNavigate } from 'react-router-dom'; import { theme, Badge, Modal } from 'antd'; -import { WarningOutlined } from '@ant-design/icons'; import { selectPlugins, selectAllConnections, selectWebhooks } from '@/features/connections'; import { PATHS } from '@/config'; @@ -57,9 +56,6 @@ export const Connections = () => { const webhooks = useAppSelector(selectWebhooks); const filterWebhookPlugins = plugins.filter((p) => p !== 'webhook'); - const deprecatedPlugin = filterWebhookPlugins - .map((plugin) => getPluginConfig(plugin)) - .find((config) => config?.isDeprecated && config.deprecationMessage); const [firstPlugins, secondPlugins] = useMemo( () => splitPluginsByInitial(filterWebhookPlugins, (plugin) => getPluginConfig(plugin)?.name ?? plugin), @@ -94,16 +90,6 @@ export const Connections = () => {

Data Connections

You can create and manage data connections for the following data sources and use them in your Projects.
- {deprecatedPlugin?.deprecationMessage && ( - } - message="Plugin deprecation notice" - description={deprecatedPlugin.deprecationMessage} - /> - )}

A-N

    {firstPlugins.map((plugin) => { @@ -112,7 +98,6 @@ export const Connections = () => { return (
  • handleShowListDialog(plugin)}> {pluginConfig.isBeta && Beta} - {pluginConfig.isDeprecated && Deprecated} {pluginConfig.icon({ color: colorPrimary })} {pluginConfig.name} @@ -134,7 +119,6 @@ export const Connections = () => { return (
  • handleShowListDialog(plugin)}> {pluginConfig.isBeta && Beta} - {pluginConfig.isDeprecated && Deprecated} {pluginConfig.icon({ color: colorPrimary })} {pluginConfig.name} diff --git a/config-ui/src/routes/connection/styled.ts b/config-ui/src/routes/connection/styled.ts index 35a765b272c..2bc88b8cab3 100644 --- a/config-ui/src/routes/connection/styled.ts +++ b/config-ui/src/routes/connection/styled.ts @@ -17,7 +17,6 @@ */ import styled from 'styled-components'; -import { Alert } from 'antd'; export const Wrapper = styled.div` h2 { @@ -83,17 +82,6 @@ export const Wrapper = styled.div` border-radius: 8px; } - & > .deprecated { - position: absolute; - top: 0; - left: 0; - padding: 4px 8px; - font-size: 12px; - color: ${({ theme }) => theme.colors.textInverse}; - background-color: ${({ theme }) => theme.colors.error}; - border-radius: 8px; - } - & > .logo { width: 60px; height: 60px; @@ -128,18 +116,6 @@ export const Wrapper = styled.div` } `; -export const DeprecationAlert = styled(Alert)` - margin-top: 12px; - - & + h4 { - margin-top: 12px; - } - - .ant-alert-description { - white-space: pre-line; - } -`; - export const ModalTitle = styled.div` display: flex; align-items: center; diff --git a/config-ui/src/types/plugin.ts b/config-ui/src/types/plugin.ts index 3f56c8c958e..a8db35f9dd5 100644 --- a/config-ui/src/types/plugin.ts +++ b/config-ui/src/types/plugin.ts @@ -22,8 +22,6 @@ export interface IPluginConfig { icon: ({ color }: { color: string }) => React.ReactNode; sort: number; isBeta?: boolean; - isDeprecated?: boolean; - deprecationMessage?: string; connection: { docLink: string; initialValues?: Record;