This is an automated email from the ASF dual-hosted git repository.
Startrekzky pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/devlake.git
The following commit(s) were added to refs/heads/main by this push:
new abbff411b Revert "chore(python): deprecate Python plugin framework
(PyDevLake) (#9097)" (#9259)
abbff411b is described below
commit abbff411b7a2de7c1824a7c14f069177c429796e
Author: Klesh Wong <[email protected]>
AuthorDate: Tue Oct 27 18:25:00 2026 +0800
Revert "chore(python): deprecate Python plugin framework (PyDevLake)
(#9097)" (#9259)
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 ++------
.../server/services/remote/plugin/plugin_impl.go | 12 -----------
config-ui/src/plugins/register/azure/config.tsx | 3 ---
config-ui/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 1807f3833..4047f7e54 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 9c6a32af9..f05a78632 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 5c2f12885..17bf0cee7 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 172bc64f5..ed5366bfa 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 285b6fd2c..de32fbc94 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 fe8e42970..1cf768305 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 28b387bab..978a6af09 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 }) => <Icon fill={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 e6bc20b0f..ea7af7bfd 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 = () => {
</h5>
<h2>Data Connections</h2>
<h5>You can create and manage data connections for the following data
sources and use them in your Projects.</h5>
- {deprecatedPlugin?.deprecationMessage && (
- <S.DeprecationAlert
- closable
- showIcon
- type="warning"
- icon={<WarningOutlined />}
- message="Plugin deprecation notice"
- description={deprecatedPlugin.deprecationMessage}
- />
- )}
<h4>A-N</h4>
<ul>
{firstPlugins.map((plugin) => {
@@ -112,7 +98,6 @@ export const Connections = () => {
return (
<li key={plugin} onClick={() => handleShowListDialog(plugin)}>
{pluginConfig.isBeta && <span className="beta">Beta</span>}
- {pluginConfig.isDeprecated && <span
className="deprecated">Deprecated</span>}
<span className="logo">{pluginConfig.icon({ color: colorPrimary
})}</span>
<span className="name">{pluginConfig.name}</span>
<span className="count">
@@ -134,7 +119,6 @@ export const Connections = () => {
return (
<li key={plugin} onClick={() => handleShowListDialog(plugin)}>
{pluginConfig.isBeta && <span className="beta">Beta</span>}
- {pluginConfig.isDeprecated && <span
className="deprecated">Deprecated</span>}
<span className="logo">{pluginConfig.icon({ color: colorPrimary
})}</span>
<span className="name">{pluginConfig.name}</span>
<span className="count">
diff --git a/config-ui/src/routes/connection/styled.ts
b/config-ui/src/routes/connection/styled.ts
index 35a765b27..2bc88b8ca 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 3f56c8c95..a8db35f9d 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<string, any>;