mirror of
https://github.com/grafana/grafana.git
synced 2025-02-03 20:21:01 -06:00
Code: codeownership for feature toggles (#64266)
* ownership for feature toggles v2 * add traceqlSearch * MT -> app platform * assign publicdashboards --------- Co-authored-by: Ryan McKinley <ryantxu@gmail.com>
This commit is contained in:
parent
1c2e3993f6
commit
13650f3dc0
15
pkg/services/featuremgmt/codeowners.go
Normal file
15
pkg/services/featuremgmt/codeowners.go
Normal file
@ -0,0 +1,15 @@
|
||||
package featuremgmt
|
||||
|
||||
// codeowner string that references a GH team or user
|
||||
// the value must match the format used in the CODEOWNERS file
|
||||
type codeowner string
|
||||
|
||||
const (
|
||||
grafanaAppPlatformSquad codeowner = "@grafana/grafana-app-platform-squad"
|
||||
grafanaDashboardsSquad codeowner = "@grafana/dashboards-squad"
|
||||
grafanaBiSquad codeowner = "@grafana/grafana-bi-squad"
|
||||
grafanaDatavizSquad codeowner = "@grafana/dataviz-squad"
|
||||
grafanaUserEssentialsSquad codeowner = "@grafana/user-essentials"
|
||||
grafanaBackendPlatformSquad codeowner = "@grafana/backend-platform"
|
||||
grafanaPluginsPlatformSquad codeowner = "@grafana/plugins-platform-backend"
|
||||
)
|
@ -85,6 +85,9 @@ type FeatureFlag struct {
|
||||
State FeatureFlagState `json:"state,omitempty"`
|
||||
DocsURL string `json:"docsURL,omitempty"`
|
||||
|
||||
// Owner person or team that owns this feature flag
|
||||
Owner codeowner `json:"-"`
|
||||
|
||||
// CEL-GO expression. Using the value "true" will mean this is on by default
|
||||
Expression string `json:"expression,omitempty"`
|
||||
|
||||
|
@ -33,28 +33,33 @@ var (
|
||||
Name: "dashboardPreviews",
|
||||
Description: "Create and show thumbnails for dashboard search results",
|
||||
State: FeatureStateAlpha,
|
||||
Owner: grafanaAppPlatformSquad,
|
||||
},
|
||||
{
|
||||
Name: "live-pipeline",
|
||||
Description: "Enable a generic live processing pipeline",
|
||||
State: FeatureStateAlpha,
|
||||
Owner: grafanaAppPlatformSquad,
|
||||
},
|
||||
{
|
||||
Name: "live-service-web-worker",
|
||||
Description: "This will use a webworker thread to processes events rather than the main thread",
|
||||
State: FeatureStateAlpha,
|
||||
FrontendOnly: true,
|
||||
Owner: grafanaAppPlatformSquad,
|
||||
},
|
||||
{
|
||||
Name: "queryOverLive",
|
||||
Description: "Use Grafana Live WebSocket to execute backend queries",
|
||||
State: FeatureStateAlpha,
|
||||
FrontendOnly: true,
|
||||
Owner: grafanaAppPlatformSquad,
|
||||
},
|
||||
{
|
||||
Name: "panelTitleSearch",
|
||||
Description: "Search for dashboards using panel title",
|
||||
State: FeatureStateBeta,
|
||||
Owner: grafanaAppPlatformSquad,
|
||||
},
|
||||
{
|
||||
Name: "prometheusAzureOverrideAudience",
|
||||
@ -65,6 +70,7 @@ var (
|
||||
Name: "publicDashboards",
|
||||
Description: "Enables public access to dashboards",
|
||||
State: FeatureStateAlpha,
|
||||
Owner: grafanaDashboardsSquad,
|
||||
},
|
||||
{
|
||||
Name: "publicDashboardsEmailSharing",
|
||||
@ -72,11 +78,13 @@ var (
|
||||
State: FeatureStateAlpha,
|
||||
RequiresLicense: true,
|
||||
RequiresDevMode: true,
|
||||
Owner: grafanaDashboardsSquad,
|
||||
},
|
||||
{
|
||||
Name: "lokiLive",
|
||||
Description: "Support WebSocket streaming for loki (early prototype)",
|
||||
State: FeatureStateAlpha,
|
||||
Owner: grafanaAppPlatformSquad,
|
||||
},
|
||||
{
|
||||
Name: "lokiDataframeApi",
|
||||
@ -92,11 +100,13 @@ var (
|
||||
Name: "dashboardComments",
|
||||
Description: "Enable dashboard-wide comments",
|
||||
State: FeatureStateAlpha,
|
||||
Owner: grafanaAppPlatformSquad,
|
||||
},
|
||||
{
|
||||
Name: "annotationComments",
|
||||
Description: "Enable annotation comments",
|
||||
State: FeatureStateAlpha,
|
||||
Owner: grafanaAppPlatformSquad,
|
||||
},
|
||||
{
|
||||
Name: "migrationLocking",
|
||||
@ -107,18 +117,21 @@ var (
|
||||
Name: "storage",
|
||||
Description: "Configurable storage for dashboards, datasources, and resources",
|
||||
State: FeatureStateAlpha,
|
||||
Owner: grafanaAppPlatformSquad,
|
||||
},
|
||||
{
|
||||
Name: "k8s",
|
||||
Description: "Explore native k8s integrations",
|
||||
State: FeatureStateAlpha,
|
||||
RequiresDevMode: true,
|
||||
Owner: grafanaAppPlatformSquad,
|
||||
},
|
||||
{
|
||||
Name: "dashboardsFromStorage",
|
||||
Description: "Load dashboards from the generic storage interface",
|
||||
State: FeatureStateAlpha,
|
||||
RequiresDevMode: true, // Also a gate on automatic git storage (for now)
|
||||
Owner: grafanaAppPlatformSquad,
|
||||
},
|
||||
{
|
||||
Name: "exploreMixedDatasource",
|
||||
@ -153,6 +166,7 @@ var (
|
||||
Name: "datasourceQueryMultiStatus",
|
||||
Description: "Introduce HTTP 207 Multi Status for api/ds/query",
|
||||
State: FeatureStateAlpha,
|
||||
Owner: grafanaPluginsPlatformSquad,
|
||||
},
|
||||
{
|
||||
Name: "traceToMetrics",
|
||||
@ -164,6 +178,7 @@ var (
|
||||
Name: "newDBLibrary",
|
||||
Description: "Use jmoiron/sqlx rather than xorm for a few backend services",
|
||||
State: FeatureStateBeta,
|
||||
Owner: grafanaBackendPlatformSquad,
|
||||
},
|
||||
{
|
||||
Name: "validateDashboardsOnSave",
|
||||
@ -176,6 +191,7 @@ var (
|
||||
Description: "Replace the angular graph panel with timeseries",
|
||||
State: FeatureStateBeta,
|
||||
FrontendOnly: true,
|
||||
Owner: grafanaDatavizSquad,
|
||||
},
|
||||
{
|
||||
Name: "prometheusWideSeries",
|
||||
@ -187,12 +203,14 @@ var (
|
||||
Description: "Allow elements nesting",
|
||||
State: FeatureStateAlpha,
|
||||
FrontendOnly: true,
|
||||
Owner: grafanaDatavizSquad,
|
||||
},
|
||||
{
|
||||
Name: "scenes",
|
||||
Description: "Experimental framework to build interactive dashboards",
|
||||
State: FeatureStateAlpha,
|
||||
FrontendOnly: true,
|
||||
Owner: grafanaDashboardsSquad,
|
||||
},
|
||||
{
|
||||
Name: "disableSecretsCompatibility",
|
||||
@ -215,23 +233,27 @@ var (
|
||||
Description: "Enables internationalization",
|
||||
State: FeatureStateStable,
|
||||
Expression: "true", // enabled by default
|
||||
Owner: grafanaUserEssentialsSquad,
|
||||
},
|
||||
{
|
||||
Name: "topnav",
|
||||
Description: "Displays new top nav and page layouts",
|
||||
State: FeatureStateBeta,
|
||||
Owner: grafanaUserEssentialsSquad,
|
||||
},
|
||||
{
|
||||
Name: "grpcServer",
|
||||
Description: "Run GRPC server",
|
||||
State: FeatureStateAlpha,
|
||||
RequiresDevMode: true,
|
||||
Owner: grafanaAppPlatformSquad,
|
||||
},
|
||||
{
|
||||
Name: "entityStore",
|
||||
Description: "SQL-based entity store (requires storage flag also)",
|
||||
State: FeatureStateAlpha,
|
||||
RequiresDevMode: true,
|
||||
Owner: grafanaAppPlatformSquad,
|
||||
},
|
||||
{
|
||||
Name: "cloudWatchCrossAccountQuerying",
|
||||
@ -262,6 +284,7 @@ var (
|
||||
Description: "Reusable query library",
|
||||
State: FeatureStateAlpha,
|
||||
RequiresDevMode: true,
|
||||
Owner: grafanaAppPlatformSquad,
|
||||
},
|
||||
{
|
||||
Name: "showDashboardValidationWarnings",
|
||||
@ -324,6 +347,7 @@ var (
|
||||
Description: "Enables drag and drop for CSV and Excel files",
|
||||
FrontendOnly: true,
|
||||
State: FeatureStateAlpha,
|
||||
Owner: grafanaBiSquad,
|
||||
},
|
||||
{
|
||||
Name: "alertingNoNormalState",
|
||||
@ -361,6 +385,7 @@ var (
|
||||
Description: "Changes the user experience for data source selection to a drawer.",
|
||||
State: FeatureStateAlpha,
|
||||
FrontendOnly: true,
|
||||
Owner: grafanaBiSquad,
|
||||
},
|
||||
{
|
||||
Name: "traceqlSearch",
|
||||
|
@ -41,6 +41,69 @@ func TestFeatureToggleFiles(t *testing.T) {
|
||||
}
|
||||
})
|
||||
|
||||
ownerlessFeatures := map[string]bool{
|
||||
"alertingBigTransactions": true,
|
||||
"trimDefaults": true,
|
||||
"disableEnvelopeEncryption": true,
|
||||
"database_metrics": true,
|
||||
"prometheusAzureOverrideAudience": true,
|
||||
"lokiDataframeApi": true,
|
||||
"featureHighlights": true,
|
||||
"migrationLocking": true,
|
||||
"exploreMixedDatasource": true,
|
||||
"tracing": true,
|
||||
"newTraceView": true,
|
||||
"correlations": true,
|
||||
"cloudWatchDynamicLabels": true,
|
||||
"traceToMetrics": true,
|
||||
"validateDashboardsOnSave": true,
|
||||
"prometheusWideSeries": true,
|
||||
"disableSecretsCompatibility": true,
|
||||
"logRequestsInstrumentedAsUnknown": true,
|
||||
"dataConnectionsConsole": true,
|
||||
"cloudWatchCrossAccountQuerying": true,
|
||||
"redshiftAsyncQueryDataSupport": true,
|
||||
"athenaAsyncQueryDataSupport": true,
|
||||
"newPanelChromeUI": true,
|
||||
"showDashboardValidationWarnings": true,
|
||||
"mysqlAnsiQuotes": true,
|
||||
"accessControlOnCall": true,
|
||||
"nestedFolders": true,
|
||||
"accessTokenExpirationCheck": true,
|
||||
"elasticsearchBackendMigration": true,
|
||||
"datasourceOnboarding": true,
|
||||
"secureSocksDatasourceProxy": true,
|
||||
"authnService": true,
|
||||
"disablePrometheusExemplarSampling": true,
|
||||
"alertingBacktesting": true,
|
||||
"alertingNoNormalState": true,
|
||||
"logsSampleInExplore": true,
|
||||
"logsContextDatasourceUi": true,
|
||||
"lokiQuerySplitting": true,
|
||||
"individualCookiePreferences": true,
|
||||
"traceqlSearch": true,
|
||||
}
|
||||
|
||||
t.Run("all new features should have an owner", func(t *testing.T) {
|
||||
for _, flag := range standardFeatureFlags {
|
||||
if flag.Owner == "" {
|
||||
if _, ok := ownerlessFeatures[flag.Name]; !ok {
|
||||
t.Errorf("feature %s does not have an owner", flag.Name)
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("features with assigned owner should not be on the ownerless list", func(t *testing.T) {
|
||||
for _, flag := range standardFeatureFlags {
|
||||
if flag.Owner != "" {
|
||||
if _, ok := ownerlessFeatures[flag.Name]; ok {
|
||||
t.Errorf("feature %s should be removed from the ownerless list", flag.Name)
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("verify files", func(t *testing.T) {
|
||||
// Typescript files
|
||||
verifyAndGenerateFile(t,
|
||||
|
Loading…
Reference in New Issue
Block a user