Plugins: Always load decoupled frontend assets from builds (#81873)

* Wip

* Wip

* Adapt to load external module

* build: remove cloudmonitoring from built_in_plugins, clean up webpack output

* chore(plugins): remove decoupled plugins from package.json deps

* chore(codeowners): update file for nx.json

* revert(webpack): put back path in config

* build(frontend): use nx to run prod builds of decoupled plugins with yarn build

* style(prometheus): run prettier-write to fix tsconfig.json

* style(backend): remove unused subFile.isDistDir

* revert(locales): remove formatting changes adding new line at end of files

* chore(webpack): clean up dev output

* build(nx): make grafana an nx project, bump lerna and nx

* build(plugin-configs): move cache directory to node_modules

* style(datasource-plugins): add eslint ignore for .gen.ts files

* chore(codeowners): add frontend-ops as owner of project.json

* build(webpack): add getDecoupledPlugins to automatically ignore when watching

* ci(drone): skip nx cache when building frontend packages

* style(ci): fix missing trailing comma

* Revert "style(ci): fix missing trailing comma"

This reverts commit 7520d41576.

* Revert "ci(drone): skip nx cache when building frontend packages"

This reverts commit 46938883ac.

* feat(zipkin): remove from grafana core bundle

* chore(npm): bump nx package to latest 18.0.8

* docs(dev-guide): add a note about what yarn start now builds

---------

Co-authored-by: Andres Martinez <andres.martinez@grafana.com>
This commit is contained in:
Jack Westbrook
2024-03-13 12:40:09 +01:00
committed by GitHub
co-authored by Andres Martinez
parent 75ea33e0cd
commit 6599fa805d
17 changed files with 896 additions and 337 deletions
@@ -10,7 +10,6 @@ import (
"github.com/grafana/grafana/pkg/plugins"
"github.com/grafana/grafana/pkg/plugins/config"
"github.com/grafana/grafana/pkg/plugins/pluginscdn"
"github.com/grafana/grafana/pkg/services/featuremgmt"
)
// Service provides methods for constructing asset paths for plugins.
@@ -58,9 +57,7 @@ func (s *Service) Base(n PluginInfo) (string, error) {
// Module returns the module.js path for the specified plugin.
func (s *Service) Module(n PluginInfo) (string, error) {
if n.class == plugins.ClassCore {
if s.cfg.Features != nil &&
s.cfg.Features.IsEnabledGlobally(featuremgmt.FlagExternalCorePlugins) &&
filepath.Base(n.dir) == "dist" {
if filepath.Base(n.dir) == "dist" {
// The core plugin has been built externally, use the module from the dist folder
} else {
baseDir := getBaseDir(n.dir)
+3 -8
View File
@@ -59,12 +59,7 @@ func (l *Local) Find(ctx context.Context, src plugins.PluginSource) ([]*plugins.
continue
}
followDistFolder := true
if src.PluginClass(ctx) == plugins.ClassCore &&
!l.features.IsEnabledGlobally(featuremgmt.FlagExternalCorePlugins) {
followDistFolder = false
}
paths, err := l.getAbsPluginJSONPaths(path, followDistFolder)
paths, err := l.getAbsPluginJSONPaths(path)
if err != nil {
return nil, err
}
@@ -167,7 +162,7 @@ func (l *Local) readPluginJSON(pluginJSONPath string) (plugins.JSONData, error)
return plugin, nil
}
func (l *Local) getAbsPluginJSONPaths(path string, followDistFolder bool) ([]string, error) {
func (l *Local) getAbsPluginJSONPaths(path string) ([]string, error) {
var pluginJSONPaths []string
var err error
@@ -176,7 +171,7 @@ func (l *Local) getAbsPluginJSONPaths(path string, followDistFolder bool) ([]str
return []string{}, err
}
if err = walk(path, true, true, followDistFolder,
if err = walk(path, true, true,
func(currentPath string, fi os.FileInfo, err error) error {
if err != nil {
if errors.Is(err, os.ErrNotExist) {
@@ -313,7 +313,7 @@ func TestFinder_Find(t *testing.T) {
func TestFinder_getAbsPluginJSONPaths(t *testing.T) {
t.Run("When scanning a folder that doesn't exists shouldn't return an error", func(t *testing.T) {
origWalk := walk
walk = func(path string, followSymlinks, detectSymlinkInfiniteLoop, followDistFolder bool, walkFn util.WalkFunc) error {
walk = func(path string, followSymlinks, detectSymlinkInfiniteLoop bool, walkFn util.WalkFunc) error {
return walkFn(path, nil, os.ErrNotExist)
}
t.Cleanup(func() {
@@ -321,14 +321,14 @@ func TestFinder_getAbsPluginJSONPaths(t *testing.T) {
})
finder := NewLocalFinder(false, featuremgmt.WithFeatures())
paths, err := finder.getAbsPluginJSONPaths("test", true)
paths, err := finder.getAbsPluginJSONPaths("test")
require.NoError(t, err)
require.Empty(t, paths)
})
t.Run("When scanning a folder that lacks permission shouldn't return an error", func(t *testing.T) {
origWalk := walk
walk = func(path string, followSymlinks, detectSymlinkInfiniteLoop, followDistFolder bool, walkFn util.WalkFunc) error {
walk = func(path string, followSymlinks, detectSymlinkInfiniteLoop bool, walkFn util.WalkFunc) error {
return walkFn(path, nil, os.ErrPermission)
}
t.Cleanup(func() {
@@ -336,14 +336,14 @@ func TestFinder_getAbsPluginJSONPaths(t *testing.T) {
})
finder := NewLocalFinder(false, featuremgmt.WithFeatures())
paths, err := finder.getAbsPluginJSONPaths("test", true)
paths, err := finder.getAbsPluginJSONPaths("test")
require.NoError(t, err)
require.Empty(t, paths)
})
t.Run("When scanning a folder that returns a non-handled error should return that error", func(t *testing.T) {
origWalk := walk
walk = func(path string, followSymlinks, detectSymlinkInfiniteLoop, followDistFolder bool, walkFn util.WalkFunc) error {
walk = func(path string, followSymlinks, detectSymlinkInfiniteLoop bool, walkFn util.WalkFunc) error {
return walkFn(path, nil, errors.New("random error"))
}
t.Cleanup(func() {
@@ -351,44 +351,10 @@ func TestFinder_getAbsPluginJSONPaths(t *testing.T) {
})
finder := NewLocalFinder(false, featuremgmt.WithFeatures())
paths, err := finder.getAbsPluginJSONPaths("test", true)
paths, err := finder.getAbsPluginJSONPaths("test")
require.Error(t, err)
require.Empty(t, paths)
})
t.Run("The followDistFolder state controls whether certain folders are followed", func(t *testing.T) {
dir, err := filepath.Abs("../../testdata/pluginRootWithDist")
require.NoError(t, err)
tcs := []struct {
name string
followDist bool
expected []string
}{
{
name: "When followDistFolder is enabled, only the nested dist folder will be followed",
followDist: true,
expected: []string{
filepath.Join(dir, "dist/plugin.json"),
},
},
{
name: "When followDistFolder is disabled, no dist folders will be followed",
followDist: false,
expected: []string{
filepath.Join(dir, "datasource/plugin.json"),
filepath.Join(dir, "panel/src/plugin.json"),
},
},
}
for _, tc := range tcs {
pluginBundles, err := NewLocalFinder(false, featuremgmt.WithFeatures()).getAbsPluginJSONPaths(dir, tc.followDist)
require.NoError(t, err)
sort.Strings(pluginBundles)
require.Equal(t, tc.expected, pluginBundles)
}
})
}
var fsComparer = cmp.Comparer(func(fs1 plugins.FS, fs2 plugins.FS) bool {