2019-10-22 16:03:22 +02:00
## This is a self-documented Makefile. For usage information, run `make help`:
##
## For more information, refer to https://suva.sh/posts/well-documented-makefiles/
2021-08-25 15:11:22 +02:00
WIRE_TAGS = "oss"
2018-05-07 12:32:18 +02:00
-include local/Makefile
2025-05-21 11:22:24 +02:00
include .citools/Variables.mk
2018-05-07 12:32:18 +02:00
2021-06-29 10:01:21 +02:00
GO = go
2026-07-08 11:59:21 +01:00
GO_VERSION = 1.26.5
2026-03-26 08:17:42 +01:00
GO_HOST_OS := $( shell $( GO) env GOHOSTOS)
GO_HOST_ARCH := $( shell $( GO) env GOHOSTARCH)
2025-09-18 08:07:55 -04:00
GO_LINT_FILES ?= $( shell ./scripts/go-workspace/golangci-lint-includes.sh)
2024-08-09 10:25:27 -04:00
GO_TEST_FILES ?= $( shell ./scripts/go-workspace/test-includes.sh)
2019-07-23 13:12:33 +03:00
SH_FILES ?= $( shell find ./scripts -name *.sh)
2024-06-04 11:02:09 -03:00
GO_RACE := $( shell [ -n " $( GO_RACE) " -o -e ".go-race-enabled-locally" ] && echo 1 )
2024-05-31 12:30:51 -03:00
GO_RACE_FLAG := $(if $( GO_RACE) ,-race)
2026-03-30 14:32:56 +02:00
# Backend build version and ldflags (release / packaging conventions).
2026-03-02 13:41:02 +01:00
BUILD_NUMBER ?= local
BUILD_VERSION := $( shell sed -n 's/.*"version": *"\(.*\)".*/\1/p' package.json | sed 's/-pre/-$(BUILD_NUMBER)/' )
2026-06-08 15:57:19 +02:00
BUILD_COMMIT := $(if $( COMMIT_SHA) ,$( COMMIT_SHA) ,$( shell git rev-parse HEAD 2>/dev/null || echo "unknown" ))
2026-03-12 11:06:33 +01:00
BUILD_BRANCH := $(if $( BUILD_BRANCH) ,$( BUILD_BRANCH) ,$( shell git rev-parse --abbrev-ref HEAD 2>/dev/null || echo "main" ))
2026-06-08 15:57:19 +02:00
BUILD_STAMP := $( or $( SOURCE_DATE_EPOCH) ,$( shell git log -1 --format= %ct 2>/dev/null) ,$( shell date +%s 2>/dev/null))
2026-03-02 13:41:02 +01:00
GO_LDFLAGS = -X main.version= $( BUILD_VERSION) \
-X main.commit= $( BUILD_COMMIT) \
-X main.buildBranch= $( BUILD_BRANCH) \
2026-03-05 12:07:12 +01:00
-X main.buildstamp= $( BUILD_STAMP) \
2026-03-12 11:06:33 +01:00
$(if $( ENTERPRISE_COMMIT_SHA) ,-X main.enterpriseCommit= $( ENTERPRISE_COMMIT_SHA)) \
2026-03-05 12:07:12 +01:00
$(if $( LDFLAGS) ,-extldflags \" $( LDFLAGS) \" )
2025-03-17 10:47:27 +01:00
GO_TEST_FLAGS += $(if $( GO_BUILD_TAGS) ,-tags= $( GO_BUILD_TAGS))
2026-03-27 10:38:05 +01:00
GO_BUILD_DEV_ENABLED := $( filter 1 dev,$( GO_BUILD_DEV))
GO_BUILD_GCFLAGS_EFFECTIVE := $(if $( GO_BUILD_GCFLAGS) ,$( GO_BUILD_GCFLAGS) ,$(if $( GO_BUILD_DEV_ENABLED) ,all= -N -l))
GO_BUILD_TRIMPATH_FLAG := $(if $( GO_BUILD_DEV_ENABLED) ,,-trimpath)
GO_BUILD_ENV = \
$(if $( CGO_ENABLED) ,CGO_ENABLED= $( CGO_ENABLED)) \
GOOS = $( OS) \
GOARCH = $( ARCH) \
$(if $( ARM) ,GOARM= $( ARM))
GO_BUILD_ARGS = \
-buildvcs= false \
$( GO_BUILD_TRIMPATH_FLAG) \
$( GO_RACE_FLAG) \
$(if $( GO_BUILD_TAGS) ,-tags $( GO_BUILD_TAGS)) \
$(if $( GO_BUILD_GCFLAGS_EFFECTIVE) ,-gcflags " $( GO_BUILD_GCFLAGS_EFFECTIVE) " ) \
-ldflags " $( GO_LDFLAGS) " \
2026-04-15 10:24:27 +02:00
-o ./bin/$( OS) /$( ARCH) /grafana$(if $( filter windows,$( OS)) ,.exe) \
2026-03-27 10:38:05 +01:00
./pkg/cmd/grafana
ifeq ( $( filter undefined environment environment \ override ,$( origin OS )) ,)
else
OS := $( or $( GOOS) ,$( shell $( GO) env GOOS))
endif
ifeq ( $( filter undefined environment environment \ override ,$( origin ARCH )) ,)
else
ARCH := $( or $( GOARCH) ,$( shell $( GO) env GOARCH))
endif
ifeq ( $( filter undefined environment environment \ override ,$( origin ARM )) ,)
else
ARM := $( GOARM)
endif
2024-10-09 20:32:23 +00:00
GIT_BASE = remotes/origin/main
2019-03-27 17:53:49 +01:00
2024-10-08 12:47:33 +00:00
# GNU xargs has flag -r, and BSD xargs (e.g. MacOS) has that behaviour by default
XARGSR = $( shell xargs --version 2>& 1 | grep -q GNU && echo xargs -r || echo xargs)
2025-05-13 13:08:19 +02:00
# Test sharding to replicate CI behaviour locally.
SHARD ?= 1
SHARDS ?= 1
2023-02-07 20:34:05 -05:00
2025-05-13 13:08:19 +02:00
targets := $( shell echo '$(sources)' | tr "," " " )
2023-04-17 18:33:43 +02:00
2024-04-01 23:09:17 +08:00
.PHONY : all
2016-04-25 12:44:26 -04:00
all : deps build
2019-10-22 16:03:22 +02:00
##@ Dependencies
2024-04-01 23:09:17 +08:00
.PHONY : deps -go
2019-10-22 16:03:22 +02:00
deps-go : ## Install backend dependencies.
2026-03-02 13:41:02 +01:00
go mod download
2016-10-11 02:51:44 -04:00
2024-04-01 23:09:17 +08:00
.PHONY : deps -js
2019-10-22 16:03:22 +02:00
deps-js : node_modules ## Install frontend dependencies.
2024-04-01 23:09:17 +08:00
.PHONY : deps
2019-10-22 16:03:22 +02:00
deps : deps -js ## Install all dependencies.
2024-04-01 23:09:17 +08:00
.PHONY : node_modules
2019-10-22 16:03:22 +02:00
node_modules : package .json yarn .lock ## Install node modules.
@echo "install frontend dependencies"
2021-10-08 15:19:10 +01:00
YARN_ENABLE_PROGRESS_BARS = false yarn install --immutable
2016-04-25 12:44:26 -04:00
2022-02-08 14:38:43 +02:00
##@ Swagger
SPEC_TARGET = public/api-spec.json
2023-09-25 15:34:57 -04:00
ENTERPRISE_SPEC_TARGET = public/api-enterprise-spec.json
MERGED_SPEC_TARGET = public/api-merged.json
2022-05-23 14:08:27 -05:00
NGALERT_SPEC_TARGET = pkg/services/ngalert/api/tooling/api.json
2022-02-08 14:38:43 +02:00
$(NGALERT_SPEC_TARGET) :
2022-05-23 14:08:27 -05:00
+$( MAKE) -C pkg/services/ngalert/api/tooling api.json
2022-02-08 14:38:43 +02:00
2025-03-20 10:09:00 +01:00
$(MERGED_SPEC_TARGET) : swagger -oss -gen swagger -enterprise -gen $( NGALERT_SPEC_TARGET ) ## Merge generated and ngalert API specs
2022-07-20 16:09:42 +03:00
# known conflicts DsPermissionType, AddApiKeyCommand, Json, Duration (identical models referenced by both specs)
2025-05-21 11:22:24 +02:00
GODEBUG = gotypesalias = 0 $( swagger) mixin -q $( SPEC_TARGET) $( ENTERPRISE_SPEC_TARGET) $( NGALERT_SPEC_TARGET) --ignore-conflicts -o $( MERGED_SPEC_TARGET)
2022-02-08 14:38:43 +02:00
2024-04-01 23:09:17 +08:00
.PHONY : swagger -oss -gen
2025-03-20 10:09:00 +01:00
swagger-oss-gen : ## Generate API Swagger specification
2023-09-25 15:34:57 -04:00
@echo "re-generating swagger for OSS"
rm -f $( SPEC_TARGET)
2025-05-21 11:22:24 +02:00
SWAGGER_GENERATE_EXTENSION = false GODEBUG = gotypesalias = 0 $( swagger) generate spec -q -m -w pkg/server -o $( SPEC_TARGET) \
2022-02-08 14:38:43 +02:00
-x "github.com/grafana/grafana/pkg/services/ngalert/api/tooling/definitions" \
2024-06-13 11:41:35 +02:00
-x "github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-openapiv2/options" \
2022-02-08 14:38:43 +02:00
-x "github.com/prometheus/alertmanager" \
2025-09-10 11:12:23 +01:00
-x "github.com/docker/docker" \
2026-04-24 17:28:38 -04:00
-x "github.com/moby/moby" \
2022-10-14 14:51:05 +01:00
-i pkg/api/swagger_tags.json \
2023-09-25 15:34:57 -04:00
--exclude-tag= alpha \
--exclude-tag= enterprise
# this file only exists if enterprise is enabled
2024-04-01 23:09:17 +08:00
.PHONY : swagger -enterprise -gen
2023-09-25 15:34:57 -04:00
ENTERPRISE_EXT_FILE = pkg/extensions/ext.go
ifeq ( "$(wildcard $(ENTERPRISE_EXT_FILE))" , "" ) ## if enterprise is not enabled
swagger-enterprise-gen :
@echo "skipping re-generating swagger for enterprise: not enabled"
else
2025-03-20 10:09:00 +01:00
swagger-enterprise-gen : ## Generate API Swagger specification
2023-09-25 15:34:57 -04:00
@echo "re-generating swagger for enterprise"
rm -f $( ENTERPRISE_SPEC_TARGET)
2025-05-21 11:22:24 +02:00
SWAGGER_GENERATE_EXTENSION = false GODEBUG = gotypesalias = 0 $( swagger) generate spec -q -m -w pkg/server -o $( ENTERPRISE_SPEC_TARGET) \
2023-09-25 15:34:57 -04:00
-x "github.com/grafana/grafana/pkg/services/ngalert/api/tooling/definitions" \
2024-06-13 11:41:35 +02:00
-x "github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-openapiv2/options" \
2023-09-25 15:34:57 -04:00
-x "github.com/prometheus/alertmanager" \
2025-09-10 11:12:23 +01:00
-x "github.com/docker/docker" \
2026-04-24 17:28:38 -04:00
-x "github.com/moby/moby" \
2023-09-25 15:34:57 -04:00
-i pkg/api/swagger_tags.json \
2025-06-30 16:39:21 +02:00
-t enterprise \
2023-09-25 15:34:57 -04:00
--exclude-tag= alpha \
--include-tag= enterprise
endif
2022-02-08 14:38:43 +02:00
2024-04-01 23:09:17 +08:00
.PHONY : swagger -gen
2023-09-25 15:34:57 -04:00
swagger-gen : gen -go $( MERGED_SPEC_TARGET ) swagger -validate
2022-02-08 14:38:43 +02:00
2024-04-01 23:09:17 +08:00
.PHONY : swagger -validate
2025-03-20 10:09:00 +01:00
swagger-validate : $( MERGED_SPEC_TARGET ) # Validate API spec
2025-05-21 11:22:24 +02:00
GODEBUG = gotypesalias = 0 $( swagger) validate --skip-warnings $( <)
2022-06-14 13:35:22 +03:00
2024-04-01 23:09:17 +08:00
.PHONY : swagger -clean
2023-09-25 15:34:57 -04:00
swagger-clean :
2023-01-31 13:00:45 +02:00
rm -f $( SPEC_TARGET) $( MERGED_SPEC_TARGET) $( OAPI_SPEC_TARGET)
2022-02-08 14:38:43 +02:00
2023-08-17 09:56:52 +00:00
.PHONY : lefthook -install
2026-04-16 11:53:13 +02:00
lefthook-install : # install lefthook for pre-commit hooks
2025-05-21 11:22:24 +02:00
$( lefthook) install -f
2023-08-17 09:56:52 +00:00
.PHONY : lefthook -uninstall
2025-03-17 09:48:41 +01:00
lefthook-uninstall :
2025-05-21 11:22:24 +02:00
$( lefthook) uninstall
2023-08-17 09:56:52 +00:00
2022-08-04 13:51:12 -03:00
##@ OpenAPI 3
OAPI_SPEC_TARGET = public/openapi3.json
2024-04-01 23:09:17 +08:00
.PHONY : openapi 3-gen
2023-09-25 15:34:57 -04:00
openapi3-gen : swagger -gen ## Generates OpenApi 3 specs from the Swagger 2 already generated
2026-02-26 16:03:02 +03:00
$( GO) run $( GO_RACE_FLAG) scripts/openapi3/openapi3conv.go cleanup $( ENTERPRISE_SPEC_TARGET) $( MERGED_SPEC_TARGET)
2024-05-31 12:30:51 -03:00
$( GO) run $( GO_RACE_FLAG) scripts/openapi3/openapi3conv.go $( MERGED_SPEC_TARGET) $( OAPI_SPEC_TARGET)
2016-10-11 02:51:44 -04:00
2026-02-26 08:16:00 +01:00
.PHONY : generate -openapi
generate-openapi : openapi 3-gen
$( GO) test ./pkg/tests/apis || true
yarn workspace @grafana/openapi process-specs
2024-04-18 16:25:27 +01:00
##@ Internationalisation
.PHONY : i 18n -extract -enterprise
ENTERPRISE_FE_EXT_FILE = public/app/extensions/index.ts
ifeq ( "$(wildcard $(ENTERPRISE_FE_EXT_FILE))" , "" ) ## if enterprise is not enabled
i18n-extract-enterprise :
@echo "Skipping i18n extract for Enterprise: not enabled"
else
2024-05-08 14:01:17 +01:00
i18n-extract-enterprise :
2026-01-13 11:13:11 +00:00
@echo "Extracting i18n strings for Enterprise"
2026-02-16 14:24:50 +01:00
cd public/locales/enterprise && LANG = en_US.UTF-8 yarn run i18next-cli extract --sync-primary
2024-04-18 16:25:27 +01:00
endif
.PHONY : i 18n -extract
i18n-extract : i 18n -extract -enterprise
@echo "Extracting i18n strings for OSS"
2026-02-16 14:24:50 +01:00
LANG = en_US.UTF-8 yarn run i18next-cli extract --sync-primary
2025-06-12 10:52:04 +01:00
@echo "Extracting i18n strings for packages"
2026-02-16 14:24:50 +01:00
LANG = en_US.UTF-8 yarn run packages:i18n-extract
2025-05-15 14:31:49 +01:00
@echo "Extracting i18n strings for plugins"
2026-02-16 14:24:50 +01:00
LANG = en_US.UTF-8 yarn run plugin:i18n-extract
2024-04-18 16:25:27 +01:00
2022-08-04 13:51:12 -03:00
##@ Building
2024-04-01 23:09:17 +08:00
.PHONY : gen -cue
2025-10-30 18:21:41 +01:00
gen-cue : ## Do all CUE/Thema code generation
2022-05-26 21:21:37 -04:00
@echo "generate code from .cue files"
2022-11-10 15:36:40 -05:00
go generate ./kinds/gen.go
2022-12-02 08:22:28 +01:00
go generate ./public/app/plugins/gen.go
2026-03-25 08:07:11 -06:00
@echo "// This file is managed by Grafana - DO NOT EDIT MANUALLY" > apps/dashboard/pkg/apis/dashboard/v0alpha1/dashboard_kind.cue
@echo "// Source: kinds/dashboard/dashboard_kind.cue" >> apps/dashboard/pkg/apis/dashboard/v0alpha1/dashboard_kind.cue
@echo "// To sync changes, run: make gen-cue" >> apps/dashboard/pkg/apis/dashboard/v0alpha1/dashboard_kind.cue
@echo "" >> apps/dashboard/pkg/apis/dashboard/v0alpha1/dashboard_kind.cue
@cat kinds/dashboard/dashboard_kind.cue >> apps/dashboard/pkg/apis/dashboard/v0alpha1/dashboard_kind.cue
@cp apps/dashboard/pkg/apis/dashboard/v0alpha1/dashboard_kind.cue apps/dashboard/pkg/apis/dashboard/v1/dashboard_kind.cue
2025-04-11 18:52:46 +02:00
2022-05-26 21:21:37 -04:00
2026-02-04 11:04:49 +03:00
APPS_DIRS = $( shell find ./apps -type d -exec test -f "{}/Makefile" \; -print | sort)
# Alternatively use an explicit list of apps:
# APPS_DIRS := ./apps/dashboard ./apps/folder ./apps/alerting/notifications
2025-03-26 10:49:52 +02:00
2026-02-11 15:11:24 -07:00
# Optional app variable to specify a single app to generate
# Usage: make gen-apps app=dashboard
app ?=
2025-03-26 10:49:52 +02:00
.PHONY : gen -apps
2026-03-25 11:35:52 -06:00
gen-apps : fix -cue do -gen -apps gofmt ## Generate code for Grafana App SDK apps and run gofmt and fix-cue. Use app=<name> to generate for a specific app.
2026-02-10 13:55:07 +03:00
## NOTE: codegen produces some openapi files that result in circular dependencies
2026-02-20 16:09:49 +01:00
## for now, we revert the zz_openapi_gen.go files before comparison
2025-09-24 15:37:57 +03:00
@if [ -n " $$ CODEGEN_VERIFY" ] ; then \
2026-02-10 13:55:07 +03:00
git checkout HEAD -- apps/alerting/rules/pkg/apis/alerting/v0alpha1/zz_openapi_gen.go; \
git checkout HEAD -- apps/iam/pkg/apis/iam/v0alpha1/zz_openapi_gen.go; \
git checkout HEAD -- apps/secret/pkg/apis/secret/v1beta1/zz_openapi_gen.go; \
2025-09-24 15:37:57 +03:00
echo "Verifying generated code is up to date..." ; \
if ! git diff --quiet; then \
2026-02-11 15:11:24 -07:00
echo "Error: Generated code is not up to date. Please run 'make gen-apps' (optionally with app=<name>), 'make gen-cue', and 'make gen-jsonnet' to regenerate." ; \
2025-09-24 15:37:57 +03:00
git diff --name-only; \
exit 1; \
fi ; \
echo "Generated apps code is up to date." ; \
fi
.PHONY : do -gen -apps
do-gen-apps : ## Generate code for Grafana App SDK apps
2026-02-11 15:11:24 -07:00
@if [ -n " $( app) " ] ; then \
app_dir = "./apps/ $( app) " ; \
if [ ! -f " $$ app_dir/Makefile" ] ; then \
echo "Error: App ' $( app) ' not found or does not have a Makefile at $$ app_dir" ; \
exit 1; \
fi ; \
echo "Generating code for app: $( app) " ; \
$( MAKE) -C $$ app_dir generate; \
else \
for dir in $( APPS_DIRS) ; do \
$( MAKE) -C $$ dir generate; \
done ; \
./hack/update-codegen.sh; \
fi
2025-03-26 10:49:52 +02:00
2024-04-01 23:09:17 +08:00
.PHONY : gen -feature -toggles
2024-03-21 12:04:49 +01:00
gen-feature-toggles :
## First go test run fails because it will re-generate the feature toggles.
## Second go test run will compare the generated files and pass.
@echo "generate feature toggles"
2026-04-10 09:50:53 +01:00
go test ./pkg/services/featuremgmt/... > /dev/null 2>& 1; \
2024-03-21 12:04:49 +01:00
if [ $$ ? -eq 0 ] ; then \
echo "feature toggles already up-to-date" ; \
else \
2026-04-10 09:50:53 +01:00
go test ./pkg/services/featuremgmt/...; \
2024-03-21 12:04:49 +01:00
fi
2026-04-10 09:50:53 +01:00
2025-06-30 16:39:21 +02:00
.PHONY : gen -go gen -enterprise -go
ifeq ( "$(wildcard $(ENTERPRISE_EXT_FILE))" , "" ) ## if enterprise is not enabled
gen-enterprise-go :
@echo "skipping re-generating Wire graph for enterprise: not enabled"
else
gen-enterprise-go : ## Generate Wire graph (Enterprise)
@echo "re-generating Wire graph for enterprise"
$( GO) run ./pkg/build/wire/cmd/wire/main.go gen -tags "enterprise" -gen_tags "(enterprise || pro)" -output_file_prefix= "enterprise_" ./pkg/server
endif
gen-go : gen -enterprise -go ## Generate Wire graph
2025-08-22 13:49:44 +02:00
@echo "generating Wire graph"
2026-07-23 11:00:26 -04:00
$( GO) run ./pkg/build/wire/cmd/wire/main.go gen -tags "oss" -gen_tags "(!enterprise && !pro)" ./pkg/server/bootstrap/wire
2025-06-30 16:39:21 +02:00
$( GO) run ./pkg/build/wire/cmd/wire/main.go gen -tags "oss" -gen_tags "(!enterprise && !pro)" ./pkg/server
2021-08-25 15:11:22 +02:00
2026-01-29 15:18:05 +01:00
.PHONY : gen -app -manifests -unistore
gen-app-manifests-unistore : ## Generate unified storage app manifests list
@echo "generating unified storage app manifests"
$( GO) generate ./pkg/storage/unified/resource/app_manifests.go
@if [ -n " $$ CODEGEN_VERIFY" ] ; then \
echo "Verifying generated code is up to date..." ; \
if ! git diff --quiet pkg/storage/unified/resource/app_manifests.go; then \
echo "Error: pkg/storage/unified/resource/app_manifests.go is not up to date. Please run 'make gen-app-manifests-unistore' to regenerate." ; \
git diff pkg/storage/unified/resource/app_manifests.go; \
exit 1; \
fi ; \
echo "Generated app manifests code is up to date." ; \
fi
2024-04-01 23:09:17 +08:00
.PHONY : fix -cue
2026-05-27 12:39:53 +02:00
fix-cue : ## Format and fix CUE files. Use app=<name> to fix a specific app.
2026-03-26 11:01:43 -07:00
@set -e; \
root_dir = "." ; \
2026-03-25 11:35:52 -06:00
if [ -n " $( app) " ] ; then \
root_dir = "./apps/ $( app) " ; \
if [ ! -d " $$ root_dir" ] ; then \
echo "Error: App ' $( app) ' not found at $$ root_dir" ; \
exit 1; \
fi ; \
fi ; \
2026-03-26 11:01:43 -07:00
for mod_dir in $$ ( find " $$ root_dir" -type d -name 'cue.mod' ) ; do \
2026-03-25 10:35:49 -06:00
project_dir = " $$ (dirname $$ mod_dir)" ; \
echo "Fixing: $$ project_dir" ; \
2026-05-27 12:39:53 +02:00
( cd " $$ project_dir" && $( cue) fmt ./...) ; \
( cd " $$ project_dir" && $( cue) fix ./...) ; \
2026-03-26 11:01:43 -07:00
done
2023-01-24 02:36:46 +01:00
2024-04-01 23:09:17 +08:00
.PHONY : gen -jsonnet
2025-10-30 18:21:41 +01:00
gen-jsonnet :
2022-11-11 04:19:29 -05:00
go generate ./devenv/jsonnet
2022-11-03 11:04:39 -04:00
2026-01-13 11:13:11 +00:00
.PHONY : gen -themes
gen-themes :
2026-03-26 08:17:42 +01:00
GOOS = $( GO_HOST_OS) GOARCH = $( GO_HOST_ARCH) $( GO) generate ./pkg/services/preference
2026-01-13 11:13:11 +00:00
2026-03-27 10:38:05 +01:00
pkg/services/preference/themes_generated.go :
$( MAKE) gen-themes
2026-05-04 12:14:24 +02:00
.PHONY : generate -enterprise -imports
ifeq ( "$(wildcard $(ENTERPRISE_EXT_FILE))" , "" ) ## if enterprise is not enabled
generate-enterprise-imports :
@echo "skipping generating enterprise imports file"
else
generate-enterprise-imports : ## Generate Enterprise imports file
@echo "re-generating enterprise imports file"
$( GO) run ./scripts/ci/generate-enterprise-imports/main.go
endif
2024-07-03 12:49:03 -04:00
.PHONY : update -workspace
2026-05-04 12:14:24 +02:00
update-workspace : gen -go generate -enterprise -imports
2024-07-03 12:49:03 -04:00
@echo "updating workspace"
2024-08-08 16:51:17 -04:00
bash scripts/go-workspace/update-workspace.sh
2024-07-03 12:49:03 -04:00
2024-04-01 23:09:17 +08:00
.PHONY : build -go
2026-03-27 10:38:05 +01:00
build-go : pkg /services /preference /themes_generated .go
2026-04-02 17:07:54 +02:00
@echo "compiling backend ( $( OS) / $( ARCH) )"
2026-03-27 10:38:05 +01:00
$( GO_BUILD_ENV) \
$( GO) build $( GO_BUILD_ARGS)
if [ " $( OS) " = " $( GO_HOST_OS) " ] && [ " $( ARCH) " = " $( GO_HOST_ARCH) " ] ; then cp ./bin/$( OS) /$( ARCH) /grafana ./bin/grafana; fi
2026-05-13 18:14:04 +02:00
bin/$(OS)/$(ARCH)/grafana$(if $(filter windows,$(OS)),.exe) :
2026-03-27 10:38:05 +01:00
$( MAKE) build-go
2016-10-11 02:51:44 -04:00
2024-04-01 23:09:17 +08:00
.PHONY : build -backend
2026-03-02 13:41:02 +01:00
build-backend : build -go
2022-11-22 11:53:43 -05:00
2025-09-30 09:49:23 -04:00
.PHONY : build -air
2026-03-02 13:41:02 +01:00
build-air : build -go
2025-09-30 09:49:23 -04:00
@cp ./bin/grafana ./bin/grafana-air
2024-04-01 23:09:17 +08:00
.PHONY : build -js
2019-10-22 16:03:22 +02:00
build-js : ## Build frontend assets.
2026-04-02 17:07:54 +02:00
@echo "building frontend"
2018-03-06 17:59:45 -05:00
yarn run build
2016-04-25 12:44:26 -04:00
2026-03-27 10:38:05 +01:00
public/build :
$( MAKE) build-js
2023-10-23 10:44:38 +02:00
PLUGIN_ID ?=
2024-04-01 23:09:17 +08:00
.PHONY : build -plugin -go
2023-10-23 10:44:38 +02:00
build-plugin-go : ## Build decoupled plugins
@echo "build plugin $( PLUGIN_ID) "
@cd pkg/tsdb; \
if [ -z " $( PLUGIN_ID) " ] ; then \
echo "PLUGIN_ID is not set" ; \
exit 1; \
fi ; \
mage -v buildplugin $( PLUGIN_ID)
2024-04-01 23:09:17 +08:00
.PHONY : build
2019-10-22 16:03:22 +02:00
build : build -go build -js ## Build backend and frontend.
2016-10-11 02:51:44 -04:00
2026-04-02 17:07:54 +02:00
# Packaging variables (artifact / file naming).
2026-03-27 10:38:05 +01:00
TARGZ_PACKAGE_NAME ?= grafana
2026-04-02 17:07:54 +02:00
FPM_LICENSE ?= AGPLv3
ARCH_LABEL := $(if $( ARM) ,$( ARCH) -$( ARM) ,$( ARCH))
2026-04-03 10:24:08 +02:00
# armv6 debs use a -rpi suffix to match daggerbuild behavior (grafana-rpi, grafana-enterprise-rpi).
DEB_PACKAGE_NAME := $(if $( filter 6,$( ARM)) ,$( TARGZ_PACKAGE_NAME) -rpi,$( TARGZ_PACKAGE_NAME))
2026-04-02 17:07:54 +02:00
TARGZ_FILE := dist/$( TARGZ_PACKAGE_NAME) _$( BUILD_VERSION) _$( BUILD_NUMBER) _$( OS) _$( ARCH_LABEL) .tar.gz
2026-04-03 10:24:08 +02:00
DEB_FILE := dist/$( DEB_PACKAGE_NAME) _$( BUILD_VERSION) _$( BUILD_NUMBER) _$( OS) _$( ARCH_LABEL) .deb
2026-04-02 17:07:54 +02:00
RPM_FILE := dist/$( TARGZ_PACKAGE_NAME) _$( BUILD_VERSION) _$( BUILD_NUMBER) _$( OS) _$( ARCH_LABEL) .rpm
2026-05-15 12:41:34 +02:00
SLIM ?= false
SLIM_SUFFIX := $(if $( filter true,$( SLIM)) ,-slim,)
DOCKER_FILE := dist/$( TARGZ_PACKAGE_NAME) _$( BUILD_VERSION) _$( BUILD_NUMBER) _$( OS) _$( ARCH_LABEL)$( SLIM_SUFFIX) .docker.tar.gz
DOCKER_UBUNTU_FILE := dist/$( TARGZ_PACKAGE_NAME) _$( BUILD_VERSION) _$( BUILD_NUMBER) _$( OS) _$( ARCH_LABEL) .ubuntu$( SLIM_SUFFIX) .docker.tar.gz
DOCKER_DISTROLESS_FILE := dist/$( TARGZ_PACKAGE_NAME) _$( BUILD_VERSION) _$( BUILD_NUMBER) _$( OS) _$( ARCH_LABEL) .distroless$( SLIM_SUFFIX) .docker.tar.gz
2026-04-03 10:24:08 +02:00
DOCKER_TAG ?= $( TARGZ_PACKAGE_NAME) :$( BUILD_VERSION)
2026-03-27 10:38:05 +01:00
2026-03-30 14:32:56 +02:00
# Default catalog plugins under data/plugins-bundled. Stamp encodes OS/ARCH so cross-builds refresh.
DATA_PLUGINS_BUNDLED_STAMP := data/plugins-bundled/.platform-$( OS) -$( ARCH) .stamp
$(DATA_PLUGINS_BUNDLED_STAMP) : package .json \
scripts /download -catalog -plugins .sh \
scripts /catalog -plugins -defaults
2026-04-02 17:07:54 +02:00
@echo "bundling plugins ( $( OS) / $( ARCH) )"
2026-03-30 14:32:56 +02:00
@rm -rf data/plugins-bundled
@mkdir -p data/plugins-bundled
@bash scripts/download-catalog-plugins.sh \
--out data/plugins-bundled \
--grafana-version " $( BUILD_VERSION) " \
--os " $( OS) " \
--arch " $( ARCH) "
@touch $( DATA_PLUGINS_BUNDLED_STAMP)
data/plugins-bundled : $( DATA_PLUGINS_BUNDLED_STAMP )
@:
.PHONY : build -catalog -plugins -data
build-catalog-plugins-data : data /plugins -bundled ## Download default catalog plugins into data/plugins-bundled (network; alias).
2026-03-27 10:38:05 +01:00
.PHONY : build -targz
2026-04-02 17:07:54 +02:00
build-targz : $( TARGZ_FILE ) ## Build a tar.gz package (bin, public, conf, plugins-bundled/, data/plugins-bundled from catalog)
2026-05-13 18:14:04 +02:00
$(TARGZ_FILE) : data /plugins -bundled | bin /$( OS ) /$( ARCH ) /grafana $( if $( filter windows ,$( OS )) ,.exe ) public /build
2026-04-02 17:07:54 +02:00
@echo "assembling tar.gz"
2026-03-27 10:38:05 +01:00
TARGZ_PACKAGE_NAME = " $( TARGZ_PACKAGE_NAME) " \
BUILD_VERSION = " $( BUILD_VERSION) " \
BUILD_NUMBER = " $( BUILD_NUMBER) " \
OS = " $( OS) " \
ARCH = " $( ARCH) " \
2026-04-01 11:49:42 +02:00
$(if $( ARM) ,GOARM= " $( ARM) " ) \
2026-03-27 10:38:05 +01:00
GO = " $( GO) " \
bash scripts/build-targz.sh
2026-04-02 17:07:54 +02:00
.PHONY : build -deb
build-deb : $( DEB_FILE ) ## Build a .deb package from a tar.gz (requires fpm)
$(DEB_FILE) : $( TARGZ_FILE )
@echo "building deb"
TARGZ_PACKAGE_NAME = " $( TARGZ_PACKAGE_NAME) " \
BUILD_VERSION = " $( BUILD_VERSION) " \
BUILD_NUMBER = " $( BUILD_NUMBER) " \
OS = " $( OS) " \
ARCH = " $( ARCH) " \
FPM_LICENSE = " $( FPM_LICENSE) " \
$(if $( ARM) ,GOARM= " $( ARM) " ) \
bash scripts/build-deb.sh
.PHONY : build -rpm
build-rpm : $( RPM_FILE ) ## Build an .rpm package from a tar.gz (requires fpm)
$(RPM_FILE) : $( TARGZ_FILE )
@echo "building rpm"
TARGZ_PACKAGE_NAME = " $( TARGZ_PACKAGE_NAME) " \
BUILD_VERSION = " $( BUILD_VERSION) " \
BUILD_NUMBER = " $( BUILD_NUMBER) " \
OS = " $( OS) " \
ARCH = " $( ARCH) " \
FPM_LICENSE = " $( FPM_LICENSE) " \
$(if $( ARM) ,GOARM= " $( ARM) " ) \
bash scripts/build-rpm.sh
2026-04-03 10:24:08 +02:00
.PHONY : build -docker
build-docker : $( DOCKER_FILE ) ## Build a Docker image (alpine) from a tar.gz
$(DOCKER_FILE) : $( TARGZ_FILE )
@echo "building docker image (alpine)"
docker buildx build \
--platform $( OS) /$( ARCH) \
--build-arg GRAFANA_TGZ = $( TARGZ_FILE) \
--build-arg GO_SRC = tgz-builder \
--build-arg JS_SRC = tgz-builder \
2026-06-08 15:57:19 +02:00
--build-arg SOURCE_DATE_EPOCH = $$ ( git log -1 --format= %ct) \
2026-05-15 12:41:34 +02:00
--build-arg SLIM = $( SLIM) \
2026-04-03 10:24:08 +02:00
--target= final-alpine \
--tag $( DOCKER_TAG) \
2026-06-08 15:57:19 +02:00
--output type = docker,dest= $@ ,rewrite-timestamp= true \
2026-04-03 10:24:08 +02:00
.
.PHONY : build -docker -ubuntu
build-docker-ubuntu : $( DOCKER_UBUNTU_FILE ) ## Build a Docker image (ubuntu) from a tar.gz
$(DOCKER_UBUNTU_FILE) : $( TARGZ_FILE )
@echo "building docker image (ubuntu)"
docker buildx build \
--platform $( OS) /$( ARCH) \
--build-arg GRAFANA_TGZ = $( TARGZ_FILE) \
--build-arg GO_SRC = tgz-builder \
--build-arg JS_SRC = tgz-builder \
2026-06-08 15:57:19 +02:00
--build-arg SOURCE_DATE_EPOCH = $$ ( git log -1 --format= %ct) \
2026-05-15 12:41:34 +02:00
--build-arg SLIM = $( SLIM) \
2026-04-03 10:24:08 +02:00
--target= final-ubuntu \
2026-04-03 12:32:05 +02:00
--tag $( DOCKER_TAG) \
2026-06-08 15:57:19 +02:00
--output type = docker,dest= $@ ,rewrite-timestamp= true \
2026-04-03 10:24:08 +02:00
.
2026-05-15 12:41:34 +02:00
.PHONY : build -docker -distroless
build-docker-distroless : $( DOCKER_DISTROLESS_FILE ) ## Build a Docker image (distroless) from a tar.gz
$(DOCKER_DISTROLESS_FILE) : $( TARGZ_FILE )
@echo "building docker image (distroless)"
docker buildx build \
--platform $( OS) /$( ARCH) \
--build-arg GRAFANA_TGZ = $( TARGZ_FILE) \
--build-arg GO_SRC = tgz-builder \
--build-arg JS_SRC = tgz-builder \
2026-06-08 15:57:19 +02:00
--build-arg SOURCE_DATE_EPOCH = $$ ( git log -1 --format= %ct) \
2026-05-15 12:41:34 +02:00
--build-arg SLIM = $( SLIM) \
--target= final-distroless \
--tag $( DOCKER_TAG) \
2026-06-08 15:57:19 +02:00
--output type = docker,dest= $@ ,rewrite-timestamp= true \
2026-05-15 12:41:34 +02:00
.
2026-05-14 13:15:05 +02:00
MSI_FILE := dist/$( TARGZ_PACKAGE_NAME) _$( BUILD_VERSION) _$( BUILD_NUMBER) _$( OS) _$( ARCH_LABEL) .msi
.PHONY : build -msi
build-msi : $( MSI_FILE ) ## Build a Windows MSI installer from a tar.gz (requires Docker + Wine)
$(MSI_FILE) : $( TARGZ_FILE )
TARGZ_PACKAGE_NAME = " $( TARGZ_PACKAGE_NAME) " \
BUILD_VERSION = " $( BUILD_VERSION) " \
BUILD_NUMBER = " $( BUILD_NUMBER) " \
ENTERPRISE = " $(if $( filter grafana-enterprise,$( TARGZ_PACKAGE_NAME)) ,true,false) " \
bash scripts/build-msi.sh
2024-04-01 23:09:17 +08:00
.PHONY : run
2025-07-25 11:32:07 +02:00
run : ## Build and run backend, and watch for changes. See .air.toml for configuration.
$( air) -c .air.toml
2018-04-20 14:28:52 -04:00
2024-05-29 20:34:16 -03:00
.PHONY : run -go
run-go : ## Build and run web server immediately.
$( GO) run -race $(if $( GO_BUILD_TAGS) ,-build-tags= $( GO_BUILD_TAGS)) \
2024-07-03 17:30:41 -04:00
./pkg/cmd/grafana -- server -profile -profile-addr= 127.0.0.1 -profile-port= 6000 -packaging= dev cfg:app_mode= development
2024-05-29 20:34:16 -03:00
2024-04-01 23:09:17 +08:00
.PHONY : run -frontend
2019-11-12 11:08:40 +01:00
run-frontend : deps -js ## Fetch js dependencies and watch frontend for rebuild
yarn start
2025-07-16 18:28:28 +01:00
.PHONY : frontend -service -check
frontend-service-check :
./devenv/frontend-service/local-init.sh
2025-08-20 18:27:04 +01:00
.PHONY : frontend -service
frontend-service : frontend -service -check
bash ./devenv/frontend-service/run.sh
2025-07-16 18:28:28 +01:00
2019-10-22 16:03:22 +02:00
##@ Testing
2022-07-19 04:04:38 -04:00
.PHONY : test -go
test-go : test -go -unit test -go -integration
.PHONY : test -go -unit
test-go-unit : ## Run unit tests for backend with flags.
2025-05-13 13:08:19 +02:00
@echo "backend unit tests ( $( SHARD) / $( SHARDS) )"
$( GO) test $( GO_RACE_FLAG) $( GO_TEST_FLAGS) -v -short -timeout= 30m \
$( shell ./scripts/ci/backend-tests/shard.sh -n$( SHARD) -m$( SHARDS) -s)
2025-03-12 11:00:13 -06:00
2024-08-26 08:32:42 -05:00
.PHONY : test -go -unit -pretty
test-go-unit-pretty : check -tparse
@if [ -z " $( FILES) " ] ; then \
echo "Notice: FILES variable is not set. Try \"make test-go-unit-pretty FILES=./pkg/services/mysvc\"" ; \
exit 1; \
fi
2025-03-17 10:47:27 +01:00
$( GO) test $( GO_RACE_FLAG) $( GO_TEST_FLAGS) -timeout= 10s $( FILES) -json | tparse -all
2024-08-26 08:32:42 -05:00
2022-07-19 04:04:38 -04:00
.PHONY : test -go -integration
test-go-integration : ## Run integration tests for backend with flags.
@echo "test backend integration tests"
2025-05-13 13:08:19 +02:00
$( GO) test $( GO_RACE_FLAG) $( GO_TEST_FLAGS) -count= 1 -run "^TestIntegration" -covermode= atomic -coverprofile= $( GO_INTEGRATION_COVER_PROFILE) -timeout= 5m \
2026-04-07 10:45:22 +02:00
$( shell ./scripts/ci/backend-tests/pkgs-with-tests-named.sh -b TestIntegration | ./scripts/ci/backend-tests/shard.sh -n$( SHARD) -m$( SHARDS) -d - -s)
2022-07-19 04:04:38 -04:00
2023-10-17 12:21:45 +02:00
.PHONY : test -go -integration -alertmanager
test-go-integration-alertmanager : ## Run integration tests for the remote alertmanager (config taken from the mimir_backend block).
@echo "test remote alertmanager integration tests"
$( GO) clean -testcache
2023-11-23 16:59:36 +00:00
AM_URL = http://localhost:8080 AM_TENANT_ID = test \
2024-05-31 12:30:51 -03:00
$( GO) test $( GO_RACE_FLAG) -count= 1 -run "^TestIntegrationRemoteAlertmanager" -covermode= atomic -timeout= 5m ./pkg/services/ngalert/...
2023-10-17 12:21:45 +02:00
2025-02-13 11:36:45 +01:00
.PHONY : test -go -integration -grafana -alertmanager
test-go-integration-grafana-alertmanager : ## Run integration tests for the grafana alertmanager
@echo "test grafana alertmanager integration tests"
@export GRAFANA_VERSION = 11.5.0-81938; \
$( GO) run tools/setup_grafana_alertmanager_integration_test_images.go; \
$( GO) clean -testcache; \
$( GO) test $( GO_RACE_FLAG) -count= 1 -run "^TestAlertmanagerIntegration" -covermode= atomic -timeout= 10m ./pkg/tests/alertmanager/...
2022-07-19 04:04:38 -04:00
.PHONY : test -go -integration -postgres
test-go-integration-postgres : devenv -postgres ## Run integration tests for postgres backend with flags.
@echo "test backend integration postgres tests"
$( GO) clean -testcache
2023-04-17 18:33:43 +02:00
GRAFANA_TEST_DB = postgres \
2025-05-13 13:08:19 +02:00
$( GO) test $( GO_RACE_FLAG) $( GO_TEST_FLAGS) -p= 1 -count= 1 -run "^TestIntegration" -covermode= atomic -timeout= 10m \
2026-04-07 10:45:22 +02:00
$( shell ./scripts/ci/backend-tests/pkgs-with-tests-named.sh -b TestIntegration | ./scripts/ci/backend-tests/shard.sh -n$( SHARD) -m$( SHARDS) -d - -s)
2022-07-19 04:04:38 -04:00
.PHONY : test -go -integration -mysql
test-go-integration-mysql : devenv -mysql ## Run integration tests for mysql backend with flags.
@echo "test backend integration mysql tests"
2023-04-17 18:33:43 +02:00
GRAFANA_TEST_DB = mysql \
2025-05-13 13:08:19 +02:00
$( GO) test $( GO_RACE_FLAG) $( GO_TEST_FLAGS) -p= 1 -count= 1 -run "^TestIntegration" -covermode= atomic -timeout= 10m \
2026-04-07 10:45:22 +02:00
$( shell ./scripts/ci/backend-tests/pkgs-with-tests-named.sh -b TestIntegration | ./scripts/ci/backend-tests/shard.sh -n$( SHARD) -m$( SHARDS) -d - -s)
2016-10-11 02:51:44 -04:00
2023-04-05 11:55:55 +03:00
.PHONY : test -go -integration -redis
test-go-integration-redis : ## Run integration tests for redis cache.
@echo "test backend integration redis tests"
$( GO) clean -testcache
2025-05-13 13:08:19 +02:00
REDIS_URL = localhost:6379 $( GO) test $( GO_TEST_FLAGS) -run IntegrationRedis -covermode= atomic -timeout= 2m \
2026-04-07 10:45:22 +02:00
$( shell ./scripts/ci/backend-tests/pkgs-with-tests-named.sh -b TestIntegration | ./scripts/ci/backend-tests/shard.sh -n$( SHARD) -m$( SHARDS) -d - -s)
2023-04-05 11:55:55 +03:00
.PHONY : test -go -integration -memcached
test-go-integration-memcached : ## Run integration tests for memcached cache.
@echo "test backend integration memcached tests"
$( GO) clean -testcache
2025-05-13 13:08:19 +02:00
MEMCACHED_HOSTS = localhost:11211 $( GO) test $( GO_RACE_FLAG) $( GO_TEST_FLAGS) -run IntegrationMemcached -covermode= atomic -timeout= 2m \
2026-04-07 10:45:22 +02:00
$( shell ./scripts/ci/backend-tests/pkgs-with-tests-named.sh -b TestIntegration | ./scripts/ci/backend-tests/shard.sh -n$( SHARD) -m$( SHARDS) -d - -s)
2025-03-19 12:34:44 +01:00
2024-04-01 23:09:17 +08:00
.PHONY : test -js
2019-10-22 16:03:22 +02:00
test-js : ## Run tests for frontend.
2019-03-27 17:53:49 +01:00
@echo "test frontend"
2018-03-06 17:59:45 -05:00
yarn test
2016-04-25 12:44:26 -04:00
2024-04-01 23:09:17 +08:00
.PHONY : test
2019-10-22 16:03:22 +02:00
test : test -go test -js ## Run all tests.
2016-10-11 02:51:44 -04:00
2019-10-22 16:03:22 +02:00
##@ Linting
2024-04-01 23:09:17 +08:00
.PHONY : golangci -lint
2025-03-17 09:48:41 +01:00
golangci-lint :
2019-10-22 16:03:22 +02:00
@echo "lint via golangci-lint"
2025-05-21 11:22:24 +02:00
$( golangci-lint) run \
2024-11-26 09:19:53 +01:00
--config .golangci.yml \
2025-03-17 10:47:27 +01:00
$(if $( GO_BUILD_TAGS) ,--build-tags $( GO_BUILD_TAGS)) \
2025-09-18 08:07:55 -04:00
$( GO_LINT_FILES)
2019-10-22 16:03:22 +02:00
2024-04-01 23:09:17 +08:00
.PHONY : lint -go
2024-08-09 10:05:02 -04:00
lint-go : golangci -lint ## Run all code checks for backend. You can use GO_LINT_FILES to specify exact files to check
2019-07-02 16:06:59 +03:00
2024-10-08 12:47:33 +00:00
.PHONY : lint -go -diff
2025-03-17 09:48:41 +01:00
lint-go-diff :
2024-10-09 20:32:23 +00:00
git diff --name-only $( GIT_BASE) | \
2024-10-08 12:47:33 +00:00
grep '\.go$$' | \
$( XARGSR) dirname | \
sort -u | \
sed 's,^,./,' | \
2025-05-21 11:22:24 +02:00
$( XARGSR) $( golangci-lint) run --config .golangci.yml
2024-10-08 12:47:33 +00:00
2025-08-26 16:14:03 +02:00
.PHONY : gofmt
gofmt : ## Run gofmt for all Go files.
2025-09-24 15:37:57 +03:00
@go list -m -f '{{.Dir}}' | xargs -I{} sh -c 'test ! -f {}/.nolint && echo {}' | xargs gofmt -s -w 2>& 1 | grep -v '/pkg/build/' || true
2025-08-26 16:14:03 +02:00
2019-07-23 13:12:33 +03:00
# with disabled SC1071 we are ignored some TCL,Expect `/usr/bin/env expect` scripts
2024-04-01 23:09:17 +08:00
.PHONY : shellcheck
2019-10-22 16:03:22 +02:00
shellcheck : $( SH_FILES ) ## Run checks for shell scripts.
2019-07-23 13:12:33 +03:00
@docker run --rm -v " $$ PWD:/mnt" koalaman/shellcheck:stable \
2019-10-02 10:11:15 +02:00
$( SH_FILES) -e SC1071 -e SC2162
2019-07-23 13:12:33 +03:00
2019-10-22 16:03:22 +02:00
##@ Docker
2023-02-28 21:18:00 +01:00
TAG_SUFFIX = $(if $( WIRE_TAGS) != oss,-$( WIRE_TAGS))
PLATFORM = linux/amd64
2025-08-19 14:22:59 -04:00
# default to a production build for frontend
#
DOCKER_JS_NODE_ENV_FLAG = production
DOCKER_JS_YARN_BUILD_FLAG = build
DOCKER_JS_YARN_INSTALL_FLAG = --immutable
#
# if go is in dev mode, also build node in dev mode
2026-03-27 10:38:05 +01:00
ifneq ( $( filter 1 dev ,$( GO_BUILD_DEV )) ,)
2025-08-19 14:22:59 -04:00
DOCKER_JS_NODE_ENV_FLAG = dev
DOCKER_JS_YARN_BUILD_FLAG = dev
DOCKER_JS_YARN_INSTALL_FLAG =
endif
# if NODE_ENV is set in the environment to dev, build frontend in dev mode, and allow go builds to use their default
ifeq (${NODE_ENV}, dev)
DOCKER_JS_NODE_ENV_FLAG = dev
DOCKER_JS_YARN_BUILD_FLAG = dev
DOCKER_JS_YARN_INSTALL_FLAG =
endif
2024-04-01 23:09:17 +08:00
.PHONY : build -docker -full
2019-10-22 16:03:22 +02:00
build-docker-full : ## Build Docker image for development.
2025-08-19 14:22:59 -04:00
@echo "build docker container mode=( $( DOCKER_JS_NODE_ENV_FLAG) )"
2026-03-26 10:28:01 -07:00
docker buildx build \
2023-02-28 21:18:00 +01:00
--platform $( PLATFORM) \
2025-08-19 14:22:59 -04:00
--build-arg NODE_ENV = $( DOCKER_JS_NODE_ENV_FLAG) \
--build-arg JS_NODE_ENV = $( DOCKER_JS_NODE_ENV_FLAG) \
--build-arg JS_YARN_INSTALL_FLAG = $( DOCKER_JS_YARN_INSTALL_FLAG) \
--build-arg JS_YARN_BUILD_FLAG = $( DOCKER_JS_YARN_BUILD_FLAG) \
2023-02-28 21:18:00 +01:00
--build-arg GO_BUILD_TAGS = $( GO_BUILD_TAGS) \
--build-arg WIRE_TAGS = $( WIRE_TAGS) \
2023-09-26 14:15:39 -05:00
--build-arg COMMIT_SHA = $$ ( git rev-parse HEAD) \
2023-04-18 10:03:27 -03:00
--build-arg BUILD_BRANCH = $$ ( git rev-parse --abbrev-ref HEAD) \
2026-06-08 15:57:19 +02:00
--build-arg SOURCE_DATE_EPOCH = $$ ( git log -1 --format= %ct) \
2026-05-15 12:41:34 +02:00
--build-arg SLIM = $( SLIM) \
2026-04-03 10:24:08 +02:00
--target= final-alpine \
2023-02-28 21:18:00 +01:00
--tag grafana/grafana$( TAG_SUFFIX) :dev \
2026-03-26 10:28:01 -07:00
$( DOCKER_BUILD_ARGS) \
.
2019-10-22 16:03:22 +02:00
2024-04-01 23:09:17 +08:00
.PHONY : build -docker -full -ubuntu
2022-02-08 14:38:43 +02:00
build-docker-full-ubuntu : ## Build Docker image based on Ubuntu for development.
2025-08-19 14:22:59 -04:00
@echo "build docker container mode=( $( DOCKER_JS_NODE_ENV_FLAG) )"
2026-03-26 10:28:01 -07:00
docker buildx build \
2023-02-28 21:18:00 +01:00
--platform $( PLATFORM) \
2025-08-19 14:22:59 -04:00
--build-arg NODE_ENV = $( DOCKER_JS_NODE_ENV_FLAG) \
--build-arg JS_NODE_ENV = $( DOCKER_JS_NODE_ENV_FLAG) \
--build-arg JS_YARN_INSTALL_FLAG = $( DOCKER_JS_YARN_INSTALL_FLAG) \
--build-arg JS_YARN_BUILD_FLAG = $( DOCKER_JS_YARN_BUILD_FLAG) \
2023-02-28 21:18:00 +01:00
--build-arg GO_BUILD_TAGS = $( GO_BUILD_TAGS) \
--build-arg WIRE_TAGS = $( WIRE_TAGS) \
2023-09-26 14:15:39 -05:00
--build-arg COMMIT_SHA = $$ ( git rev-parse HEAD) \
2023-04-18 10:03:27 -03:00
--build-arg BUILD_BRANCH = $$ ( git rev-parse --abbrev-ref HEAD) \
2026-06-08 15:57:19 +02:00
--build-arg SOURCE_DATE_EPOCH = $$ ( git log -1 --format= %ct) \
2024-04-24 14:26:14 -04:00
--build-arg GO_IMAGE = golang:$( GO_VERSION) \
2026-05-15 12:41:34 +02:00
--build-arg SLIM = $( SLIM) \
2026-04-03 10:24:08 +02:00
--target= final-ubuntu \
2023-02-28 21:18:00 +01:00
--tag grafana/grafana$( TAG_SUFFIX) :dev-ubuntu \
2026-03-26 10:28:01 -07:00
$( DOCKER_BUILD_ARGS) \
.
2022-02-08 14:38:43 +02:00
2026-05-15 12:41:34 +02:00
.PHONY : build -docker -full -distroless
build-docker-full-distroless : ## Build Docker image based on distroless for development.
@echo "build docker container mode=( $( DOCKER_JS_NODE_ENV_FLAG) )"
docker buildx build \
--platform $( PLATFORM) \
--build-arg NODE_ENV = $( DOCKER_JS_NODE_ENV_FLAG) \
--build-arg JS_NODE_ENV = $( DOCKER_JS_NODE_ENV_FLAG) \
--build-arg JS_YARN_INSTALL_FLAG = $( DOCKER_JS_YARN_INSTALL_FLAG) \
--build-arg JS_YARN_BUILD_FLAG = $( DOCKER_JS_YARN_BUILD_FLAG) \
--build-arg GO_BUILD_TAGS = $( GO_BUILD_TAGS) \
--build-arg WIRE_TAGS = $( WIRE_TAGS) \
--build-arg COMMIT_SHA = $$ ( git rev-parse HEAD) \
--build-arg BUILD_BRANCH = $$ ( git rev-parse --abbrev-ref HEAD) \
2026-06-08 15:57:19 +02:00
--build-arg SOURCE_DATE_EPOCH = $$ ( git log -1 --format= %ct) \
2026-05-15 12:41:34 +02:00
--build-arg SLIM = $( SLIM) \
--target= final-distroless \
--tag grafana/grafana$( TAG_SUFFIX) :dev-distroless \
$( DOCKER_BUILD_ARGS) \
.
2019-10-22 16:03:22 +02:00
##@ Services
2019-07-02 16:06:59 +03:00
2024-09-10 07:36:41 +01:00
COMPOSE := $( shell if docker compose --help >/dev/null 2>& 1; then echo docker compose; else echo docker-compose; fi)
ifeq ( $( COMPOSE ) ,docker-compose)
$(warning From July 2023 Compose V1 (docker-compose) stopped receiving updates. Migrate to Compose V2 (docker compose). https : //docs .docker .com /compose /migrate /)
endif
# Create a Docker Compose file with provided sources and start them.
# For example, `make devenv sources=postgres,auth/openldap`
2024-04-01 23:09:17 +08:00
.PHONY : devenv
2019-05-28 19:32:14 +03:00
ifeq ( $( sources ) ,)
devenv :
2024-09-10 07:36:41 +01:00
@printf 'You have to define sources for this command \nexample: make devenv sources=postgres,auth/openldap\n'
2019-05-28 19:32:14 +03:00
else
2024-09-10 07:36:41 +01:00
devenv : devenv -down ## Start optional services like Postgresql, Prometheus, or Elasticsearch.
2019-05-25 04:38:01 +03:00
@cd devenv; \
2019-05-28 19:32:14 +03:00
./create_docker_compose.sh $( targets) || \
2019-07-16 09:16:11 +03:00
( rm -rf { docker-compose.yaml,conf.tmp,.env} ; exit 1)
2019-05-28 19:32:14 +03:00
@cd devenv; \
2024-09-10 07:36:41 +01:00
$( COMPOSE) up -d --build
2019-05-28 19:32:14 +03:00
endif
2019-05-25 04:38:01 +03:00
2024-04-01 23:09:17 +08:00
.PHONY : devenv -down
2019-10-22 16:03:22 +02:00
devenv-down : ## Stop optional services.
2019-05-28 19:32:14 +03:00
@cd devenv; \
2019-05-28 20:08:27 +03:00
test -f docker-compose.yaml && \
2024-09-10 07:36:41 +01:00
$( COMPOSE) down || exit 0;
2019-10-22 16:03:22 +02:00
2024-04-01 23:09:17 +08:00
.PHONY : devenv -postgres
2022-07-19 04:04:38 -04:00
devenv-postgres :
@cd devenv; \
sources = postgres_tests
2024-04-01 23:09:17 +08:00
.PHONY : devenv -mysql
2022-07-19 04:04:38 -04:00
devenv-mysql :
@cd devenv; \
sources = mysql_tests
2019-10-22 16:03:22 +02:00
##@ Helpers
2020-04-21 16:16:41 +02:00
# We separate the protobuf generation because most development tasks on
# Grafana do not involve changing protobuf files and protoc is not a
# go-gettable dependency and so getting it installed can be inconvenient.
#
# If you are working on changes to protobuf interfaces you may either use
2024-04-01 23:09:17 +08:00
# this target or run the individual scripts below directly
.PHONY : protobuf
2020-04-21 16:16:41 +02:00
protobuf : ## Compile protobuf definitions
bash scripts/protobuf-check.sh
2025-05-15 21:36:52 +02:00
go install google.golang.org/protobuf/cmd/protoc-gen-go@v1.36.5
2024-07-30 13:16:16 +03:00
go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@v1.4.0
2025-07-31 16:05:24 +01:00
buf generate apps/secret --template apps/secret/buf.gen.yaml
2025-05-15 21:36:52 +02:00
buf generate pkg/storage/unified/proto --template pkg/storage/unified/proto/buf.gen.yaml
2024-11-12 10:19:12 +01:00
buf generate pkg/services/authz/proto/v1 --template pkg/services/authz/proto/v1/buf.gen.yaml
2025-01-27 18:47:33 +01:00
buf generate pkg/services/ngalert/store/proto/v1 --template pkg/services/ngalert/store/proto/v1/buf.gen.yaml
2026-03-05 10:42:36 -05:00
buf generate pkg/registry/apps/annotation/proto --template pkg/registry/apps/annotation/proto/buf.gen.yaml
2020-04-21 16:16:41 +02:00
2024-04-01 23:09:17 +08:00
.PHONY : clean
2019-10-22 16:03:22 +02:00
clean : ## Clean up intermediate build artifacts.
@echo "cleaning"
rm -rf node_modules
rm -rf public/build
2024-04-01 23:09:17 +08:00
.PHONY : gen -ts
2021-11-15 22:45:35 +03:00
gen-ts :
@echo "generating TypeScript definitions"
go get github.com/tkrajina/typescriptify-golang-structs/typescriptify@v0.1.7
tscriptify -interface -package= github.com/grafana/grafana/pkg/services/live/pipeline -import= "import { FieldConfig } from '@grafana/data'" -target= public/app/features/live/pipeline/models.gen.ts pkg/services/live/pipeline/config.go
go mod tidy
2024-05-29 20:34:16 -03:00
.PHONY : go -race -is -enabled
go-race-is-enabled :
@if [ -n " $( GO_RACE) " ] ; then \
echo "The Go race detector is enabled locally, yey!" ; \
else \
echo "The Go race detector is NOT enabled locally, boo!" ; \
fi ;
.PHONY : enable -go -race
enable-go-race :
@touch .go-race-enabled-locally
2024-08-26 08:32:42 -05:00
check-tparse :
@command -v tparse >/dev/null 2>& 1 || { \
echo >& 2 "Error: tparse is not installed. Refer to https://github.com/mfridman/tparse" ; \
exit 1; \
}
2024-04-01 23:09:17 +08:00
.PHONY : help
2019-10-22 16:03:22 +02:00
help : ## Display this help.
@awk 'BEGIN {FS = ":.*##"; printf "\nUsage:\n make \033[36m<target>\033[0m\n"} /^[a-zA-Z_-]+:.*?##/ { printf " \033[36m%-15s\033[0m %s\n", $$1, $$2 } /^##@/ { printf "\n\033[1m%s\033[0m\n", substr($$0, 5) } ' $( MAKEFILE_LIST)
2025-06-03 16:55:29 +02:00
# check licenses of used dependencies (can be run using build image using
# container/check-licenses target)
check-licenses :
license_finder --decisions-file .github/license_finder.yaml
2026-04-07 09:50:37 +02:00
GENERATE_POLICY_BOT_CONFIG_SHA := sha256:d05ff5c7d4247da155c85f8c6f1f9f7c6d013d1f3fd9fd9d68eb06f1e7b0393d # v0.2.0
2026-04-07 15:11:33 +02:00
.PHONY : .policy .yml
.policy.yml :
2026-04-07 09:50:37 +02:00
docker run -u " $( shell id -u) : $( shell id -g) " \
--quiet \
--rm \
--volume " $( shell git rev-parse --show-toplevel) " :/work \
--workdir /work \
ghcr.io/grafana/generate-policy-bot-config@${ GENERATE_POLICY_BOT_CONFIG_SHA } \
2026-04-07 15:11:33 +02:00
--output .policy.yml \
2026-04-07 09:50:37 +02:00
--log-level= debug \
--merge-with= .policy.yml.tmpl \
.
2026-04-07 15:11:33 +02:00
# We don't want the patch workflow to be run. This is exclusively useful for the security-mirror. It won't work in OSS.
sed -i.bak '/- Workflow \.github\/workflows\/create-security-patch-from-security-mirror/d' .policy.yml; rm -f .policy.yml.bak
2026-05-07 20:02:40 -04:00
# Make govulncheck non-blocking - accept failure so it doesn't prevent merge
sed -i.bak '/name: Workflow \.github\/workflows\/govulncheck\.yml/,/workflows:/{s/- success/- success\n - failure/;}' .policy.yml; rm -f .policy.yml.bak
2026-05-26 11:49:59 -03:00
# Make check-frontend-test-coverage non-blocking - accept failure so it doesn't prevent merge
sed -i.bak '/name: Workflow \.github\/workflows\/check-frontend-test-coverage\.yml/,/workflows:/{s/- success/- success\n - failure/;}' .policy.yml; rm -f .policy.yml.bak
2026-06-25 15:20:59 +01:00
# Make detect-breaking-changes-levitate non-blocking - accept failure so it doesn't prevent merge
sed -i.bak '/name: Workflow \.github\/workflows\/detect-breaking-changes-levitate\.yml/,/workflows:/{s/- success/- success\n - failure/;}' .policy.yml; rm -f .policy.yml.bak