From ec4a6235d43561ab3be3d8d683ecf56cadae4d8b Mon Sep 17 00:00:00 2001 From: Julien Tant <785518+JulienTant@users.noreply.github.com> Date: Wed, 27 Aug 2025 13:07:31 -0700 Subject: [PATCH] MM-64518: Update Playbooks license requirements from Enterprise to Professional+ and unprepackage playbooks v1 (#31323) * Remove TestPlaybooksLicenseChecking test function Co-Authored-By: Claude * fix test * Remove playbooks v1 from prepackaged plugins - Remove mattermost-plugin-playbooks-v1.41.1 from Makefile - Remove license-based logic for choosing between playbooks v1/v2 - Remove obsolete test TestGetPrepackagedPlaybooksPluginIn - Clean up transitionally prepackaged plugins logic - Only ship playbooks v2.3.0 as regular prepackaged plugin * Fix formatting with gofmt * Fix linting issues - Fix formatting in plugin_test.go - Remove unnecessary blank line in plugin.go - Use slices.Contains instead of manual loop --------- Co-authored-by: Claude Co-authored-by: Mattermost Build --- server/Makefile | 2 - server/channels/api4/plugin_test.go | 74 ----------------------------- server/channels/app/plugin.go | 67 +------------------------- 3 files changed, 2 insertions(+), 141 deletions(-) diff --git a/server/Makefile b/server/Makefile index 857ab6e573b..11944ddf9cd 100644 --- a/server/Makefile +++ b/server/Makefile @@ -146,8 +146,6 @@ PLUGIN_PACKAGES += mattermost-plugin-calls-v1.10.0 PLUGIN_PACKAGES += mattermost-plugin-github-v2.4.0 PLUGIN_PACKAGES += mattermost-plugin-gitlab-v1.10.0 PLUGIN_PACKAGES += mattermost-plugin-jira-v4.3.0 -# We need to prepackage both versions of playbooks and install the correct one based on the server license. See MM-60025. -PLUGIN_PACKAGES += mattermost-plugin-playbooks-v1.41.1 PLUGIN_PACKAGES += mattermost-plugin-playbooks-v2.4.0 PLUGIN_PACKAGES += mattermost-plugin-servicenow-v2.3.4 PLUGIN_PACKAGES += mattermost-plugin-zoom-v1.8.0 diff --git a/server/channels/api4/plugin_test.go b/server/channels/api4/plugin_test.go index 1cfb883f287..77016b1101d 100644 --- a/server/channels/api4/plugin_test.go +++ b/server/channels/api4/plugin_test.go @@ -1331,80 +1331,6 @@ func TestGetPrepackagedPluginInMarketplace(t *testing.T) { }) } -func TestGetPrepackagedPlaybooksPluginIn(t *testing.T) { - mainHelper.Parallel(t) - th := Setup(t) - defer th.TearDown() - - testServer := httptest.NewServer(http.HandlerFunc(func(res http.ResponseWriter, req *http.Request) { - res.WriteHeader(http.StatusOK) - json, err := json.Marshal([]*model.MarketplacePlugin{}) - require.NoError(t, err) - _, err = res.Write(json) - require.NoError(t, err) - })) - defer testServer.Close() - - prepackagePlugins := []*plugin.PrepackagedPlugin{ - { - Manifest: &model.Manifest{ - Version: "1.40.0", - Id: "playbooks", - }, - }, - { - Manifest: &model.Manifest{ - Version: "2.0.1", - Id: "playbooks", - }, - }, - } - env := th.App.GetPluginsEnvironment() - env.SetPrepackagedPlugins(prepackagePlugins, nil) - - th.App.UpdateConfig(func(cfg *model.Config) { - *cfg.PluginSettings.Enable = true - *cfg.PluginSettings.EnableMarketplace = true - *cfg.PluginSettings.MarketplaceURL = testServer.URL - }) - - t.Run("playbooks v1 is returned if not licensed", func(t *testing.T) { - plugins, _, err := th.SystemAdminClient.GetMarketplacePlugins(context.Background(), &model.MarketplacePluginFilter{}) - require.NoError(t, err) - - expectedPlugins := prepackagePlugins[0] - - require.Equal(t, expectedPlugins.Manifest.Version, plugins[0].Manifest.Version) - require.Len(t, plugins, 1) - }) - - t.Run("playbooks v2 is returned if Enterprise licensed", func(t *testing.T) { - lic := th.App.Srv().License() - th.App.Srv().SetLicense(model.NewTestLicenseSKU("enterprise")) - defer th.App.Srv().SetLicense(lic) - - plugins, _, err := th.SystemAdminClient.GetMarketplacePlugins(context.Background(), &model.MarketplacePluginFilter{}) - require.NoError(t, err) - - expectedPlugins := prepackagePlugins[1] - require.Equal(t, expectedPlugins.Manifest.Version, plugins[0].Manifest.Version) - require.Len(t, plugins, 1) - }) - - t.Run("playbooks v1 is returned if professional licensed", func(t *testing.T) { - lic := th.App.Srv().License() - th.App.Srv().SetLicense(model.NewTestLicenseSKU("professional")) - defer th.App.Srv().SetLicense(lic) - - plugins, _, err := th.SystemAdminClient.GetMarketplacePlugins(context.Background(), &model.MarketplacePluginFilter{}) - require.NoError(t, err) - - expectedPlugins := prepackagePlugins[0] - require.Equal(t, expectedPlugins.Manifest.Version, plugins[0].Manifest.Version) - require.Len(t, plugins, 1) - }) -} - func TestInstallMarketplacePlugin(t *testing.T) { path, _ := fileutils.FindDir("tests") diff --git a/server/channels/app/plugin.go b/server/channels/app/plugin.go index f9ce0633ca8..fdf414b8af1 100644 --- a/server/channels/app/plugin.go +++ b/server/channels/app/plugin.go @@ -11,6 +11,7 @@ import ( "os" "path/filepath" "runtime" + "slices" "sort" "strings" "sync" @@ -679,22 +680,6 @@ func (a *App) mergePrepackagedPlugins(remoteMarketplacePlugins map[string]*model }, } - // If not enterprise, check version. - // Playbooks is not listed in the marketplace, this only handles prepackaged. - if !model.MinimumEnterpriseLicense(a.License()) { - if prepackaged.Manifest.Id == model.PluginIdPlaybooks { - version, err := semver.Parse(prepackaged.Manifest.Version) - if err != nil { - mlog.Error("Unable to verify prepackaged playbooks version", mlog.Err(err)) - continue - } - // Do not show playbooks >=v2 if we do not have an enterprise license - if version.GTE(SemVerV2) { - continue - } - } - } - // If not available in marketplace, add the prepackaged if remoteMarketplacePlugins[prepackaged.Manifest.Id] == nil { remoteMarketplacePlugins[prepackaged.Manifest.Id] = prepackagedMarketplace @@ -1000,8 +985,6 @@ func (ch *Channels) processPrepackagedPlugins(prepackagedPluginsDir string) erro return nil } -var SemVerV2 = semver.MustParse("2.0.0") - // processPrepackagedPlugin will return the prepackaged plugin metadata and will also // install the prepackaged plugin if it had been previously enabled and AutomaticPrepackagedPlugins is true. func (ch *Channels) processPrepackagedPlugin(pluginPath *pluginSignaturePath) (*plugin.PrepackagedPlugin, error) { @@ -1031,27 +1014,6 @@ func (ch *Channels) processPrepackagedPlugin(pluginPath *pluginSignaturePath) (* logger = logger.With(mlog.String("plugin_id", plugin.Manifest.Id)) - if plugin.Manifest.Id == model.PluginIdPlaybooks { - version, err := semver.Parse(plugin.Manifest.Version) - if err != nil { - return nil, errors.Wrapf(err, "Unable to verify prepackaged playbooks version") - } - - hasEnterpriseLicense := model.MinimumEnterpriseLicense(ch.License()) - - // Do not install playbooks >=v2 if we do not have an enterprise license - if version.GTE(SemVerV2) && !hasEnterpriseLicense { - logger.Info("Skip installing prepackaged playbooks >=v2 because the license does not allow it") - return plugin, nil - } - - // Do not install playbooks