Compare commits

..

60 Commits

Author SHA1 Message Date
Xavi Lacasa
24fb9cb337 Add email verification when updating user email 2024-01-22 23:38:26 +01:00
Leon Sorokin
68664f00b6 [v10.2.x] Partial revert of #81417 (#81420)
Revert "Chore: Fix some Explore deprecations (#80076)"

This reverts commit 6ad28d5e4c.
2024-01-26 18:05:20 -07:00
grafana-delivery-bot[bot]
6288bb1479 [v10.2.x] Field: Fix perf regression in getUniqueFieldName() (#81417)
* Field: Fix perf regression in getUniqueFieldName() (#81323)

Co-authored-by: nmarrs <nathanielmarrs@gmail.com>
(cherry picked from commit 0530021396)

* Chore: Fix some Explore deprecations (#80076)

* lint

---------

Co-authored-by: Leon Sorokin <leeoniya@gmail.com>
Co-authored-by: Giordano Ricci <me@giordanoricci.com>
2024-01-26 17:41:33 -06:00
grafana-delivery-bot[bot]
602fc141d7 [v10.2.x] Docs: add saved dashboard guidance (#81410)
Docs: add saved dashboard guidance (#81406)

* Added saved dashboard guidance

* Ran prettier

(cherry picked from commit 42c9b582e0)

Co-authored-by: Isabel <76437239+imatwawana@users.noreply.github.com>
2024-01-26 16:30:33 -05:00
grafana-delivery-bot[bot]
c5c6228697 [v10.2.x] Docs: fix broken link (#81288)
Docs: fix broken link (#81285)

Fixed broken link

(cherry picked from commit a9731846cc)

Co-authored-by: Isabel <76437239+imatwawana@users.noreply.github.com>
2024-01-25 12:06:55 -05:00
grafana-delivery-bot[bot]
85bcc1f503 [v10.2.x] Update make docs procedure (#81181)
Co-authored-by: grafanabot <bot@grafana.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2024-01-24 17:13:18 +00:00
grafana-delivery-bot[bot]
90106217e1 [v10.2.x] docs: add grafana video to install grafana page (#81179)
docs: add grafana video to install grafana page (#80237)

(cherry picked from commit f3bb16c598)

Co-authored-by: Marie Cruz <mdcruz@users.noreply.github.com>
2024-01-24 18:01:44 +02:00
grafana-delivery-bot[bot]
f4d9001b57 [v10.2.x] Stop README being built into website (#81172)
Co-authored-by: Jack Baldry <jack.baldry@grafana.com>
2024-01-24 15:41:40 +00:00
grafana-delivery-bot[bot]
6ae7c7e4a0 [v10.2.x] DashboardSchema: Add options to VariableModel (#81107)
DashboardSchema: Add options to VariableModel (#79236)

* Add includeAll and regex fields to VariableModel  #67639

* Add allValue option to VariableModel

(cherry picked from commit f7fd8e6cd1)

Co-authored-by: Denis <7009699+someden@users.noreply.github.com>
2024-01-23 17:30:36 +01:00
grafana-delivery-bot[bot]
abeb0353a4 [v10.2.x] Tempo TraceQl Editor update request #8382 (#81092)
Tempo TraceQl Editor update request #8382 (#80112)

* Tempo TraceQl Editor update request #8382

* Docs: Typo

* Docs: Typo 2 codespell lint

* Update docs/sources/shared/datasources/tempo-editor-traceql.md

* Update docs/sources/shared/datasources/tempo-editor-traceql.md

* Update docs/sources/shared/datasources/tempo-editor-traceql.md

---------

Co-authored-by: Eve Meelan <81647476+Eve832@users.noreply.github.com>
(cherry picked from commit c14ef43691)

Co-authored-by: Jara Suárez de Puga García <jara.suarezdepuga@grafana.com>
2024-01-23 07:08:38 -08:00
grafana-delivery-bot[bot]
365843586c [v10.2.x] Docs: configure grafana database configuration MYSQL (#81086)
Docs: configure grafana database configuration MYSQL  (#80939)

* Docs database max_open_conn MYSQL

* Docs: suggestion max_connections

Co-authored-by: Christopher Moyer <35463610+chri2547@users.noreply.github.com>

---------

Co-authored-by: Christopher Moyer <35463610+chri2547@users.noreply.github.com>
(cherry picked from commit 8435e16215)

Co-authored-by: Jara Suárez de Puga García <jara.suarezdepuga@grafana.com>
2024-01-23 08:22:49 -06:00
grafana-delivery-bot[bot]
4e5b8513e9 [v10.2.x] Alerting docs: updates eval group and provisioning topics for support (#81074)
Alerting docs: updates eval group and provisioning topics for support (#81066)

(cherry picked from commit f9486ad2ee)

Co-authored-by: brendamuir <100768211+brendamuir@users.noreply.github.com>
2024-01-23 14:28:25 +01:00
grafana-delivery-bot[bot]
c754c6f009 [v10.2.x] Docs: update per Support request (#81015)
Docs: update per Support request (#80845)

* update per support request, additional enhancements

* ran prettier

(cherry picked from commit 7375e64275)

Co-authored-by: lwandz13 <126723338+lwandz13@users.noreply.github.com>
2024-01-22 13:37:47 -06:00
Dimitris Sotirakis
5423a7f66a [v10.2.x] ImagePullSecrets: Add GAR secret to image_pull_secret in .drone.yml (#80918)
`ImagePullSecrets`: Add `GAR` secret to `image_pull_secret` in `.drone.yml` (#80912)

* Add GAR secret to image_pull_secret

* Fix starlark fmt

(cherry picked from commit 65104a7efa)
2024-01-19 19:56:59 +02:00
grafana-delivery-bot[bot]
64d9d77638 [v10.2.x] Update make docs procedure (#80864)
Co-authored-by: grafanabot <bot@grafana.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2024-01-19 10:42:39 +01:00
grafana-delivery-bot[bot]
a7ae7cd935 [v10.2.x] Alerting: Fix Graphite subqueries (#80816)
Alerting: Fix Graphite subqueries (#80744)

(cherry picked from commit 8a4bd85efd)

Co-authored-by: Gilles De Mey <gilles.de.mey@gmail.com>
2024-01-18 16:24:21 +01:00
grafana-delivery-bot[bot]
6d67f0646f [v10.2.x] Update _index.md (#80811)
Update _index.md (#79606)

Just suggesting a typo fix - change "an telemetry" to "a telemetry"

(cherry picked from commit 9f2775e771)

Co-authored-by: aalapk <32711124+aalapk@users.noreply.github.com>
2024-01-18 08:13:51 -06:00
grafana-delivery-bot[bot]
e876af4927 [v10.2.x] Docs: Updated anon user and dashboard access (#80686)
Docs:  Updated anon user and dashboard access (#80400)

* Clarified anon user and viewer role, style updates.

* fixed spelling error

(cherry picked from commit 00b954203d)

Co-authored-by: lwandz13 <126723338+lwandz13@users.noreply.github.com>
2024-01-16 17:22:36 -06:00
grafana-delivery-bot[bot]
9738c6c237 [v10.2.x] Annotations: Split cleanup into separate queries and deletes to avoid deadlocks on MySQL (#80485)
* Annotations: Split cleanup into separate queries and deletes to avoid deadlocks on MySQL (#80329)

* Split subquery when cleaning annotations

* update comment

* Raise batch size, now that we pay attention to it

* Iterate in batches

* Separate cancellable batch implementation to allow for multi-statement callbacks, add overload for single-statement use

* Use split-out utility in outer batching loop so it respects context cancellation

* guard against empty queries

* Use SQL parameters

* Use same approach for tags

* drop unused function

* Work around parameter limit on sqlite for large batches

* Bulk insert test data in DB

* Refactor test to customise test data creation

* Add test for catching SQLITE_MAX_VARIABLE_NUMBER limit

* Turn annotation cleanup test to integration tests

* lint

---------

Co-authored-by: Sofia Papagiannaki <1632407+papagian@users.noreply.github.com>
(cherry picked from commit 81c45bfe44)

* Fix interval, drop messages per backport

---------

Co-authored-by: Alexander Weaver <weaver.alex.d@gmail.com>
2024-01-16 15:39:11 -06:00
grafana-delivery-bot[bot]
80d2ff63f3 [v10.2.x] updated grafana docker video timestamp (#80662)
updated grafana docker video timestamp (#80659)

Update the documentation page:

https://grafana.com/docs/grafana/latest/setup-grafana/installation/docker/

Added the time when the actual demo starts.

(cherry picked from commit 739cba6eb9)

Co-authored-by: Usman Ahmad <usman.ahmad@grafana.com>
2024-01-16 11:36:08 -06:00
grafana-delivery-bot[bot]
b90b547d07 [v10.2.x] Update _index.md with the correct number of bullets. (#80657)
Update _index.md with the correct number of bullets. (#80382)

There are 4 bullets but the text mentions 3.

(cherry picked from commit 3aa228f50c)

Co-authored-by: Levent Tutar <ltutar@xebia.com>
2024-01-16 11:15:17 -06:00
grafana-delivery-bot[bot]
aa3f9b9042 [v10.2.x] Update Grafana Kubernetes installation page (#80647)
Update Grafana Kubernetes installation page (#80569)

Removed the Vimeo and added the YouTube link after an internal discussion with the team.

(cherry picked from commit 0f093c1463)

Co-authored-by: Usman Ahmad <usman.ahmad@grafana.com>
2024-01-16 10:44:28 -06:00
grafana-delivery-bot[bot]
2160c73fbd [v10.2.x] Docs: add more time zone guidance (#80636)
Docs: add more time zone guidance (#79595)

* Created report time zone section with added guidance

* Added more information

* Updated from review suggestions

* Update docs/sources/dashboards/create-reports/index.md

Co-authored-by: Agnès Toulet <35176601+AgnesToulet@users.noreply.github.com>

* Ran prettier

---------

Co-authored-by: Agnès Toulet <35176601+AgnesToulet@users.noreply.github.com>
(cherry picked from commit f9dcc9ff90)

Co-authored-by: Isabel <76437239+imatwawana@users.noreply.github.com>
2024-01-16 10:59:27 -05:00
Ashley Harrison
8fff5e7bd7 [v10.2.x] Release: Deprecate latest.json and replace with api call to grafana.com (#80603)
Release: Deprecate latest.json and replace with api call to grafana.com (#80537)

* remove latest.json and replace with api call to grafana.com

* remove latest.json

* Revert "remove latest.json"

This reverts commit bcff43d898.

* Revert "remove latest.json and replace with api call to grafana.com"

This reverts commit 02b867d84e.

* add deprecation message to latest.json

(cherry picked from commit 127decee1e)
2024-01-16 12:09:29 +00:00
Ashley Harrison
1c3981e5ab [v10.2.x] NestedFolderPicker: separate toggle to force enable picker without (#80550)
* NestedFolderPicker: separate toggle to force enable picker without `nestedFolders` (#80461)

* separate nestedFolderPickerOverride toggle to force enable it without nestedFolders

* let's call it newFolderPicker

* update unit tests and keyboard handling

* reduce spacing when no folder open chevron

---------

Co-authored-by: Josh Hunt <joshhunt@users.noreply.github.com>
(cherry picked from commit ec53487c99)

* add config import to NestedFolderPicker
2024-01-16 11:39:28 +00:00
grafana-delivery-bot[bot]
c573c3c6f4 [v10.2.x] Alerting docs: changes wrong label on configure alert state history doc (#80451)
Alerting docs: changes wrong label on configure alert state history doc (#80438)

(cherry picked from commit d50abe2ea2)

Co-authored-by: brendamuir <100768211+brendamuir@users.noreply.github.com>
2024-01-12 16:32:59 +01:00
grafana-delivery-bot[bot]
ca744064b0 [v10.2.x] Service Accounts: Add deprecation message for apikeys (#80360)
Co-authored-by: Eric Leijonmarck <eric.leijonmarck@gmail.com>
2024-01-12 09:40:55 +00:00
grafana-delivery-bot[bot]
a787208f48 [v10.2.x] updated Grafana Open Source documentation (#80395)
updated Grafana Open Source documentation (#80357)

Added missing installation section to run Grafana on Kubernetes

(cherry picked from commit 4e6b0fd9ce)

Co-authored-by: Usman Ahmad <usman.ahmad@grafana.com>
2024-01-11 10:14:18 -08:00
grafana-delivery-bot[bot]
6077f6b614 [v10.2.x] Update rasp pi install tutorial, correct APT install steps (#80386)
Update rasp pi install tutorial, correct APT install steps (#80236)

* Update the Linux install steps

* Minor updates to text

(cherry picked from commit d68bf3d715)

Co-authored-by: Clayton Cornell <131809008+clayton-cornell@users.noreply.github.com>
2024-01-11 09:45:40 -08:00
grafana-delivery-bot[bot]
4c64aa6bcd [v10.2.x] Loki: Fix bug duplicating parsed labels across multiple log lines (#80368)
Loki: Fix bug duplicating parsed labels across multiple log lines (#80292)

(cherry picked from commit e1aa8a95d9)

Co-authored-by: Sven Grossmann <sven.grossmann@grafana.com>
2024-01-11 16:22:39 +02:00
grafana-delivery-bot[bot]
e6a70ccf9a [v10.2.x] Alerting: Fix NoData & Error alerts not resolving when rule is reset (#80241)
Alerting: Fix NoData & Error alerts not resolving when rule is reset (#80184)

* Alerting: Fix NoData & Error alerts not resolving when rule is reset

On rule reset, when creating the PostableAlerts StateToPostableAlert did not
attach the correct NoData/Error alertname and rulename labels to expire/resolve
the active alerts when the previous cached state was NoData/Error.

(cherry picked from commit 1d4419fbe4)

Co-authored-by: Matthew Jacobson <matthew.jacobson@grafana.com>
2024-01-09 15:04:07 -05:00
grafana-delivery-bot[bot]
715aaed12c [v10.2.x] Auth: Fix a panic during logout when OAuth provider is not set (#80221)
Auth: check that oauthProvider is not nil in Logout() func (#79271)

check that oauthProvider is not nil

(cherry picked from commit bff2ac3627)

Co-authored-by: Mihai Doarna <mihai.doarna@grafana.com>
2024-01-09 16:31:02 +02:00
Misi
1b3d09fdda [v10.2.x] Auth: Use cfg.Raw in OAuthStrategy for loading settings (#80157)
Auth: Use cfg.Raw in OAuthStrategy for loading settings (#80136)

Use cfg.Raw in OAuthStrategy, remove unnecessary tests

(cherry picked from commit eae6adf002)
2024-01-08 16:40:39 +01:00
grafana-delivery-bot[bot]
74c0546233 [v10.2.x] Docs: remove tooltip-mode information (#80044)
Docs: remove tooltip-mode information (#79985)

Removed tooltip-mode shared file link

(cherry picked from commit 6da0ce5e01)

Co-authored-by: Isabel <76437239+imatwawana@users.noreply.github.com>
2024-01-04 14:42:02 -05:00
grafana-delivery-bot[bot]
c0ee1499c5 [v10.2.x] Adding the link to the E2C migration guide (#80027)
Adding the link to the E2C migration guide (#79868)

* Adding the link to the E2C migration guide

* Update docs/sources/introduction/grafana-enterprise.md

Co-authored-by: Christopher Moyer <35463610+chri2547@users.noreply.github.com>

---------

Co-authored-by: Christopher Moyer <35463610+chri2547@users.noreply.github.com>
(cherry picked from commit e508c83538)

Co-authored-by: Ishan Jain <51803183+ishanjainn@users.noreply.github.com>
2024-01-04 17:55:05 +02:00
grafana-delivery-bot[bot]
1767ac647a [v10.2.x] AccessControl: Add safety valve truncation for long user defined scopes (#79879)
AccessControl: Add safety valve truncation for long user defined scopes  (#79854)

* fix migrator bootloop by invalidating permissions

* add test for scope truncation

* lint

* fix max size scope

(cherry picked from commit 3bcde852ac)

Co-authored-by: Jo <joao.guerreiro@grafana.com>
2024-01-03 14:16:03 +01:00
grafana-delivery-bot[bot]
36c07522cf [v10.2.x] Gauges: Fixing broken auto sizing (#79940)
Gauges: Fixing broken auto sizing (#79926)

(cherry picked from commit 9126dbceaf)

Co-authored-by: Torkel Ödegaard <torkel@grafana.com>
2024-01-03 01:40:39 +02:00
grafana-delivery-bot[bot]
568ea044c7 [v10.2.x] ServerLock: Rework serverlock to use raw SQL and not depend on id (#79877)
* ServerLock: Rework serverlock to use raw SQL and not depend on id (#79859)

* rework SQL to use raw sql and more resistant to DBs that do not return ID

* rework SQL to return ID in all DBs. Avoid using ID as operator

(cherry picked from commit a595353d57)

* remove print statement

* fix missing return ID for postgres

(cherry picked from commit eb9c7fea07)

---------

Co-authored-by: Jo <joao.guerreiro@grafana.com>
Co-authored-by: jguer <me@jguer.space>
2023-12-28 11:57:43 +01:00
Andreas Christou
fd6da421a5 [v10.2.x] Update CHANGELOG (#79818)
* Changelog: Updated changelog for 10.2.3 (#79811)

* Changelog: Updated changelog for 10.2.3

* Fix changelog

---------

Co-authored-by: grafanabot <bot@grafana.com>
Co-authored-by: Andreas Christou <andreas.christou@grafana.com>
(cherry picked from commit 07025d91ec)

* Update yarn.lock

* Fix lint

* Fix lerna

* Fix drone

---------

Co-authored-by: grafana-delivery-bot[bot] <132647405+grafana-delivery-bot[bot]@users.noreply.github.com>
2023-12-21 16:50:44 -07:00
grafana-delivery-bot[bot]
a132e961ad [v10.2.x] Anonymous: Add documentation for anonymous devices (#79796)
Anonymous: Add documentation for anonymous devices (#79740)

* initial commit for docs

* fmt

* Update docs/sources/setup-grafana/configure-security/configure-authentication/grafana/index.md

Co-authored-by: lwandz13 <126723338+lwandz13@users.noreply.github.com>

* Update docs/sources/setup-grafana/configure-security/configure-authentication/grafana/index.md

Co-authored-by: lwandz13 <126723338+lwandz13@users.noreply.github.com>

* Update docs/sources/setup-grafana/configure-security/configure-authentication/grafana/index.md

Co-authored-by: lwandz13 <126723338+lwandz13@users.noreply.github.com>

* Update docs/sources/setup-grafana/configure-security/configure-authentication/grafana/index.md

Co-authored-by: lwandz13 <126723338+lwandz13@users.noreply.github.com>

* Update docs/sources/setup-grafana/configure-security/configure-authentication/grafana/index.md

Co-authored-by: lwandz13 <126723338+lwandz13@users.noreply.github.com>

---------

Co-authored-by: lwandz13 <126723338+lwandz13@users.noreply.github.com>
(cherry picked from commit 12e473892f)

Co-authored-by: Eric Leijonmarck <eric.leijonmarck@gmail.com>
(cherry picked from commit 7a1341eabe)
2023-12-21 20:54:44 +00:00
Andreas Christou
c4fcc5ebb2 [v10.2.x] Chore: Update grabpl to v3.0.47 (#79790)
Chore: Update `grabpl` (#79758)

Update grabpl

(cherry picked from commit 7ba930b135)

# Conflicts:
#	.drone.yml

Co-authored-by: Dimitris Sotirakis <dimitrios.sotirakis@grafana.com>
(cherry picked from commit 897efd0e14)
2023-12-21 20:54:39 +00:00
grafana-delivery-bot[bot]
ba9af66c95 [v10.2.x] Anonymous: Fix anonymous access needs anonymousEnabled in config to show in UI (#79747)
Anonymous: Fix anonymous access needs anonymousEnabled in config to show in UI (#79738)

* fix: anonymous access needs anonymousEnabled in config to show

* add enabled to tests

(cherry picked from commit ae3cb8231b)

Co-authored-by: Eric Leijonmarck <eric.leijonmarck@gmail.com>
(cherry picked from commit d1bb2b6efb)
2023-12-21 20:54:34 +00:00
grafana-delivery-bot[bot]
e2f07b2d0b Release: Bump version to 10.2.4 (#79684)
"Release: Updated versions in package to 10.2.4"

Co-authored-by: grafana-delivery-bot[bot] <132647405+grafana-delivery-bot[bot]@users.noreply.github.com>
(cherry picked from commit b27bbadce7)

# Conflicts:
#	lerna.json
#	yarn.lock
2023-12-21 20:54:29 +00:00
grafana-delivery-bot[bot]
3c66221866 [v10.2.x] Changelog: Updated changelog for 10.2.3 (#79683)
Changelog: Updated changelog for 10.2.3 (#79682)

Co-authored-by: grafanabot <bot@grafana.com>
(cherry picked from commit 217084941d)

Co-authored-by: grafana-delivery-bot[bot] <132647405+grafana-delivery-bot[bot]@users.noreply.github.com>
(cherry picked from commit 80b3d28f6e)
2023-12-21 20:48:23 +00:00
Eric Leijonmarck
395816aec5 Anonymous: Add device limits to stats (#79494) (#79650)
* add device limits

* feat: tabs the anon and session stats w. highlight

(cherry picked from commit 57ca8fa368)
(cherry picked from commit ed2722e3e6)

# Conflicts:
#	public/app/features/admin/ServerStats.tsx
#	public/app/features/admin/ServerStatsCard.tsx
2023-12-21 20:48:21 +00:00
grafana-delivery-bot[bot]
c933b0f404 [v10.2.x] Docs: Added data source requirement for built-in annotation query (#79657)
Docs: Added data source requirement for built-in annotation query (#78860)

* Docs: Added data source requirement for built-in annotation query

* Fixed wording

* Added more detailed explanation per feedback

(cherry picked from commit 11b2f41a15)

Co-authored-by: Isabel <76437239+imatwawana@users.noreply.github.com>
(cherry picked from commit 2986abd121)
2023-12-21 20:44:15 +00:00
grafana-delivery-bot[bot]
71a23a5546 [v10.2.x] Docs: add description for refresh and regex options in templating (#79649)
Docs: add description for refresh and regex options in templating (#79441)

(cherry picked from commit e6f7ad143a)

Co-authored-by: Denis <7009699+someden@users.noreply.github.com>
(cherry picked from commit 7de0a33772)
2023-12-21 20:44:09 +00:00
Victor Marin
90c979beb0 [v10.2.x] Re-add arm32 builds (#79619)
Re-add arm32 builds (#79496)

* Re-add arm32 builds

* update grabpl version

* make drone

* make drone

* format drone

(cherry picked from commit 9dc015b595)
(cherry picked from commit 8b7b34dd6a)
2023-12-21 20:44:03 +00:00
Timur Olzhabayev
e8afeb5579 [v10.2.x] Chore: Upgrade Go to 1.21.5 (#79560)
Chore: Upgrade Go to 1.21.5 (#79329)

* bumping grafanas go version to 1.21.5

* adding how to upgrade go doc

* removing the whole ci-build and corresponding pipelines

* clarifying that we have to run make drone

* fixing starlark linter and removing unused code

* Adding note about enterprise

* trying to change the underyling image to avoid musl issues

* only need to golang one

(cherry picked from commit 4991e71b85)
(cherry picked from commit 70629d8865)

# Conflicts:
#	.drone.yml
#	.github/workflows/alerting-swagger-gen.yml
#	.github/workflows/codeql-analysis.yml
#	.github/workflows/pr-codeql-analysis-go.yml
#	.github/workflows/publish-kinds-next.yml
#	.github/workflows/publish-kinds-release.yml
#	.github/workflows/verify-kinds.yml
#	Dockerfile
#	Makefile
#	scripts/build/ci-build/Dockerfile
2023-12-21 20:43:52 +00:00
grafana-delivery-bot[bot]
ec59cf72cd [v10.2.x] Docs: add missing alt text (#79539)
Docs: add missing alt text (#79537)

Added missing alt text

(cherry picked from commit cefd95f06e)

Co-authored-by: Isabel <76437239+imatwawana@users.noreply.github.com>
(cherry picked from commit e4c2e0d1a6)
2023-12-21 20:38:31 +00:00
grafana-delivery-bot[bot]
82ae879cf7 [v10.2.x] Templating: Json interpolation of single-value default selection does not create valid json (#79503)
Templating: Json interpolation of single-value default selection does not create valid json (#79137)

(cherry picked from commit 31d79c0502)

Co-authored-by: kay delaney <45561153+kaydelaney@users.noreply.github.com>
(cherry picked from commit fe27d4835e)
2023-12-21 20:38:26 +00:00
grafana-delivery-bot[bot]
51cc8f6c3f [v10.2.x] Tempo: Fix cache in TraceQL editor (#79471)
Tempo: Fix cache in TraceQL editor (#79468)

Fix 77380

(cherry picked from commit 70b980e47f)

Co-authored-by: Andre Pereira <adrapereira@gmail.com>
(cherry picked from commit cd3dbc81f7)
2023-12-21 20:38:20 +00:00
Isabel
2bbd6699a7 [v10.2.x] Docs: add missing alt text 10.2 (3/3) (#79354)
Added missing alt text

(cherry picked from commit b39cdb33e3)

# Conflicts:
#	docs/sources/panels-visualizations/query-transform-data/transform-data/index.md
2023-12-21 20:38:12 +00:00
grafana-delivery-bot[bot]
040f891d24 [v10.2.x] Docs: Update list of open source projects (#79462)
Docs: Update list of open source projects (#79432)

* Docs: Update list of open source projects

Update to change Phlare to Pyroscope, add Faro, Beyla, Agent, k6, OnCall

* Ran prettier

---------

Co-authored-by: Isabel Matwawana <isabel.matwawana@grafana.com>
(cherry picked from commit 19aceb988a)

Co-authored-by: Fiona Artiaga <89225282+GrafanaWriter@users.noreply.github.com>
(cherry picked from commit 3936c75952)
2023-12-21 20:32:58 +00:00
grafana-delivery-bot[bot]
de3c59d48c [v10.2.x] update angular plugin list (#79416)
update angular plugin list (#79380)

* rm scadavis

* add deprecation advice

* rm cloudflare

* rm opennms-helm

* rm other plugins

* update deprecation link

* make prettier happy

* Update docs/sources/developers/angular_deprecation/angular-plugins.md

* Update docs/sources/developers/angular_deprecation/angular-plugins.md

---------

Co-authored-by: Joseph Perez <45749060+josmperez@users.noreply.github.com>
(cherry picked from commit 0918d000bf)

Co-authored-by: David Harris <david.harris@grafana.com>
(cherry picked from commit 4a44ad6072)
2023-12-21 20:32:51 +00:00
Sonia Aguilar
2f814bb786 [v10.2.x] Alerting: Fix for data source filter on cloud rules. (#79327) (#79350)
Alerting: Fix for data source filter on cloud rules. (#79327)

* fix data source filter not worling for cloud rules

* Add test

(cherry picked from commit e6f2de51a3)
(cherry picked from commit b1cb170fa1)
2023-12-21 20:32:45 +00:00
grafana-delivery-bot[bot]
e1e5fc90ad [v10.2.x] InspectDataTab: Use templateSrv.replace with getProcessedData (#79317)
InspectDataTab: Use templateSrv.replace with getProcessedData (#79113)

(cherry picked from commit c80b14951d)

Co-authored-by: kay delaney <45561153+kaydelaney@users.noreply.github.com>
(cherry picked from commit 8b6f0513cc)
2023-12-21 20:32:39 +00:00
grafana-delivery-bot[bot]
54f963dedc [v10.2.x] Auth: Fix anonymous user table useragent not parsable (#79319)
Auth: Fix anonymous user table useragent not parsable (#79307)

fix for useragent not parsable

(cherry picked from commit 2447e90be9)

Co-authored-by: Eric Leijonmarck <eric.leijonmarck@gmail.com>
(cherry picked from commit 943d5eadd7)
2023-12-21 20:32:15 +00:00
Andreas Christou
1e84fede54 Chore: Update what's new URL (#64) 2023-12-18 14:03:01 +00:00
Andreas Christou
148448b00a Release: Bump version to 10.2.3 (#63) 2023-12-18 12:28:14 +00:00
8112 changed files with 250398 additions and 444817 deletions

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -5,25 +5,19 @@ import path from 'path';
import { glob } from 'glob';
// Why are we ignoring these?
// They're all deprecated/being removed so doesn't make sense to fix types
// They're all deprecated/being removed soon so doesn't make sense to fix types
const eslintPathsToIgnore = [
'packages/grafana-e2e', // deprecated.
'public/app/angular', // will be removed in Grafana 11
'public/app/plugins/panel/graph', // will be removed alongside angular
'public/app/plugins/panel/table-old', // will be removed alongside angular
];
// Avoid using functions that report the position of the issues, as this causes a lot of merge conflicts
export default {
'better eslint': () =>
countEslintErrors()
.include('**/*.{ts,tsx}')
.exclude(new RegExp(eslintPathsToIgnore.join('|'))),
'no undocumented stories': () => countUndocumentedStories().include('**/!(*.internal).story.tsx'),
'no gf-form usage': () =>
regexp(
/gf-form/gm,
'gf-form usage has been deprecated. Use a component from @grafana/ui or custom CSS instead.'
).include('**/*.{ts,tsx,html}'),
};
function countUndocumentedStories() {
@@ -31,16 +25,9 @@ function countUndocumentedStories() {
await Promise.all(
filePaths.map(async (filePath) => {
// look for .mdx import in the story file
const mdxImportRegex = new RegExp("^import.*\\.mdx';$", 'gm');
// Looks for the "autodocs" string in the file
const autodocsStringRegex = /autodocs/;
const regex = new RegExp("^import.*.mdx';$", 'gm');
const fileText = await fs.readFile(filePath, 'utf8');
const hasMdxImport = mdxImportRegex.test(fileText);
const hasAutodocsString = autodocsStringRegex.test(fileText);
// If both .mdx import and autodocs string are missing, add an issue
if (!hasMdxImport && !hasAutodocsString) {
if (!regex.test(fileText)) {
// In this case the file contents don't matter:
const file = fileTestResult.addFile(filePath, '');
// Add the issue to the first character of the file:
@@ -51,111 +38,70 @@ function countUndocumentedStories() {
});
}
/**
* Generic regexp pattern matcher, similar to @betterer/regexp.
* The only difference is that the positions of the errors are not reported, as this may cause a lot of merge conflicts.
*/
function regexp(pattern: RegExp, issueMessage: string) {
return new BettererFileTest(async (filePaths, fileTestResult) => {
await Promise.all(
filePaths.map(async (filePath) => {
const fileText = await fs.readFile(filePath, 'utf8');
const matches = fileText.match(pattern);
if (matches) {
// File contents doesn't matter, since we're not reporting the position
const file = fileTestResult.addFile(filePath, '');
matches.forEach(() => {
file.addIssue(0, 0, issueMessage);
});
}
})
);
});
}
function countEslintErrors() {
return new BettererFileTest(async (filePaths, fileTestResult, resolver) => {
// Just bail early if there's no files to test. Prevents trying to get the base config from failing
if (filePaths.length === 0) {
return;
}
const { baseDirectory } = resolver;
const cli = new ESLint({ cwd: baseDirectory });
// Get the base config to set up parsing etc correctly
// this is by far the slowest part of this code. It takes eslint about 2 seconds just to find the config
const baseConfig = await cli.calculateConfigForFile(filePaths[0]);
const eslintConfigFiles = await glob('**/.eslintrc');
const eslintConfigMainPaths = eslintConfigFiles.map((file) => path.resolve(path.dirname(file)));
const baseRules: Partial<Linter.RulesRecord> = {
'@emotion/syntax-preference': [2, 'object'],
'@typescript-eslint/no-explicit-any': 'error',
'@grafana/no-aria-label-selectors': 'error',
'no-restricted-imports': [
'error',
{
patterns: [
{
group: ['@grafana/ui*', '*/Layout/*'],
importNames: ['Layout', 'HorizontalGroup', 'VerticalGroup'],
message: 'Use Stack component instead.',
},
],
},
],
};
const config: Linter.Config = {
...baseConfig,
rules: baseRules,
// Be careful when specifying overrides for the same rules as in baseRules - it will... override
// the same rule, not merge them with different configurations
overrides: [
{
files: ['**/*.{ts,tsx}'],
excludedFiles: ['*.{test,spec}.{ts,tsx}', '**/__mocks__/**', '**/public/test/**'],
rules: {
'@typescript-eslint/consistent-type-assertions': ['error', { assertionStyle: 'never' }],
},
},
{
files: ['public/app/**/*.{ts,tsx}'],
rules: {
'no-barrel-files/no-barrel-files': 'error',
},
},
{
files: ['public/**/*.tsx', 'packages/grafana-ui/**/*.tsx'],
excludedFiles: [
'public/app/plugins/**',
'*.story.tsx',
'*.{test,spec}.{ts,tsx}',
'**/__mocks__/**',
'public/test/**',
],
rules: {
'@grafana/no-untranslated-strings': 'error',
},
},
],
const nonTestFilesRules: Partial<Linter.RulesRecord> = {
...baseRules,
'@typescript-eslint/consistent-type-assertions': ['error', { assertionStyle: 'never' }],
};
const runner = new ESLint({
baseConfig: config,
useEslintrc: false,
cwd: baseDirectory,
});
// group files by eslint config file
// this will create two file groups for each eslint config file
// one for test files and one for non-test files
const fileGroups: Record<string, string[]> = {};
const lintResults = await runner.lintFiles(Array.from(filePaths));
lintResults
.filter((lintResult) => lintResult.source)
.forEach(({ messages, filePath }) => {
const file = fileTestResult.addFile(filePath, '');
messages.forEach((message, index) => {
file.addIssue(0, 0, message.message, `${index}`);
});
for (const filePath of filePaths) {
let configPath = eslintConfigMainPaths.find((configPath) => filePath.startsWith(configPath)) ?? '';
const isTestFile =
filePath.endsWith('.test.tsx') ||
filePath.endsWith('.test.ts') ||
filePath.includes('__mocks__') ||
filePath.includes('public/test/');
if (isTestFile) {
configPath += '-test';
}
if (!fileGroups[configPath]) {
fileGroups[configPath] = [];
}
fileGroups[configPath].push(filePath);
}
for (const configPath of Object.keys(fileGroups)) {
const rules = configPath.endsWith('-test') ? baseRules : nonTestFilesRules;
// this is by far the slowest part of this code. It takes eslint about 2 seconds just to find the config
const linterOptions = (await cli.calculateConfigForFile(fileGroups[configPath][0])) as Linter.Config;
const runner = new ESLint({
baseConfig: {
...linterOptions,
rules: rules,
},
useEslintrc: false,
cwd: baseDirectory,
});
const lintResults = await runner.lintFiles(fileGroups[configPath]);
lintResults
.filter((lintResult) => lintResult.source)
.forEach((lintResult) => {
const { messages } = lintResult;
const filePath = lintResult.filePath;
const file = fileTestResult.addFile(filePath, '');
messages.forEach((message, index) => {
file.addIssue(0, 0, message.message, `${index}`);
});
});
}
});
}

View File

@@ -1,8 +1,13 @@
# Auto generated binary variables helper managed by https://github.com/bwplotka/bingo v0.9. DO NOT EDIT.
# Auto generated binary variables helper managed by https://github.com/bwplotka/bingo v0.8. DO NOT EDIT.
# All tools are designed to be build inside $GOBIN.
BINGO_DIR := $(dir $(lastword $(MAKEFILE_LIST)))
GOPATH ?= $(shell go env GOPATH)
GOBIN ?= $(firstword $(subst :, ,${GOPATH}))/bin
ifeq ($(OS),Windows_NT)
PATHSEP := $(if $(COMSPEC),;,:)
GOBIN ?= $(firstword $(subst $(PATHSEP), ,$(subst \,/,${GOPATH})))/bin
else
GOBIN ?= $(firstword $(subst :, ,${GOPATH}))/bin
endif
GO ?= $(shell which go)
# Below generated variables ensure that every time a tool under each variable is invoked, the correct version
@@ -35,11 +40,11 @@ $(DRONE): $(BINGO_DIR)/drone.mod
@echo "(re)installing $(GOBIN)/drone-v1.5.0"
@cd $(BINGO_DIR) && GOWORK=off CGO_ENABLED=0 $(GO) build -mod=mod -modfile=drone.mod -o=$(GOBIN)/drone-v1.5.0 "github.com/drone/drone-cli/drone"
GOLANGCI_LINT := $(GOBIN)/golangci-lint-v1.59.0
GOLANGCI_LINT := $(GOBIN)/golangci-lint-v1.53.3
$(GOLANGCI_LINT): $(BINGO_DIR)/golangci-lint.mod
@# Install binary/ries using Go 1.14+ build command. This is using bwplotka/bingo-controlled, separate go module with pinned dependencies.
@echo "(re)installing $(GOBIN)/golangci-lint-v1.59.0"
@cd $(BINGO_DIR) && GOWORK=off $(GO) build -mod=mod -modfile=golangci-lint.mod -o=$(GOBIN)/golangci-lint-v1.59.0 "github.com/golangci/golangci-lint/cmd/golangci-lint"
@echo "(re)installing $(GOBIN)/golangci-lint-v1.53.3"
@cd $(BINGO_DIR) && GOWORK=off $(GO) build -mod=mod -modfile=golangci-lint.mod -o=$(GOBIN)/golangci-lint-v1.53.3 "github.com/golangci/golangci-lint/cmd/golangci-lint"
JB := $(GOBIN)/jb-v0.5.1
$(JB): $(BINGO_DIR)/jb.mod
@@ -53,11 +58,15 @@ $(LEFTHOOK): $(BINGO_DIR)/lefthook.mod
@echo "(re)installing $(GOBIN)/lefthook-v1.4.8"
@cd $(BINGO_DIR) && GOWORK=off $(GO) build -mod=mod -modfile=lefthook.mod -o=$(GOBIN)/lefthook-v1.4.8 "github.com/evilmartians/lefthook"
# swagger 0.30.5 isn't compatibile with go 1.22 yet so pinning to a specific commit until there's a new release
# https://github.com/go-swagger/go-swagger/issues/3070
SWAGGER := $(GOBIN)/swagger-db51e79a0e37c572d8b59ae0c58bf2bbbbe53285
SWAGGER := $(GOBIN)/swagger-v0.30.2
$(SWAGGER): $(BINGO_DIR)/swagger.mod
@# Install binary/ries using Go 1.14+ build command. This is using bwplotka/bingo-controlled, separate go module with pinned dependencies.
@echo "(re)installing $(GOBIN)/swagger-db51e79a0e37c572d8b59ae0c58bf2bbbbe53285"
@cd $(BINGO_DIR) && GOWORK=off $(GO) build -mod=mod -modfile=swagger.mod -o=$(GOBIN)/swagger-db51e79a0e37c572d8b59ae0c58bf2bbbbe53285 "github.com/go-swagger/go-swagger/cmd/swagger"
@echo "(re)installing $(GOBIN)/swagger-v0.30.2"
@cd $(BINGO_DIR) && GOWORK=off $(GO) build -mod=mod -modfile=swagger.mod -o=$(GOBIN)/swagger-v0.30.2 "github.com/go-swagger/go-swagger/cmd/swagger"
WIRE := $(GOBIN)/wire-v0.5.0
$(WIRE): $(BINGO_DIR)/wire.mod
@# Install binary/ries using Go 1.14+ build command. This is using bwplotka/bingo-controlled, separate go module with pinned dependencies.
@echo "(re)installing $(GOBIN)/wire-v0.5.0"
@cd $(BINGO_DIR) && GOWORK=off $(GO) build -mod=mod -modfile=wire.mod -o=$(GOBIN)/wire-v0.5.0 "github.com/google/wire/cmd/wire"

View File

@@ -46,6 +46,7 @@ github.com/Microsoft/go-winio v0.4.16-0.20201130162521-d1ffc52c7331/go.mod h1:XB
github.com/Microsoft/go-winio v0.4.16/go.mod h1:XB6nPKklQyQ7GC9LdcBEcBl8PF76WugXOPRXwdLnMv0=
github.com/Microsoft/go-winio v0.4.17-0.20210211115548-6eac466e5fa3/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84=
github.com/Microsoft/go-winio v0.4.17-0.20210324224401-5516f17a5958/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84=
github.com/Microsoft/go-winio v0.4.17 h1:iT12IBVClFevaf8PuVyi3UmZOVh4OqnaLxDTW2O6j3w=
github.com/Microsoft/go-winio v0.4.17/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84=
github.com/Microsoft/hcsshim v0.8.6/go.mod h1:Op3hHsoHPAvb6lceZHDtd9OkTew38wNoXnJs8iY7rUg=
github.com/Microsoft/hcsshim v0.8.7-0.20190325164909-8abdbb8205e4/go.mod h1:Op3hHsoHPAvb6lceZHDtd9OkTew38wNoXnJs8iY7rUg=
@@ -878,6 +879,7 @@ google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7
google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0=
google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
google.golang.org/appengine v1.6.6 h1:lMO5rYAqUxkmaj76jAkRUvt5JZgFymx/+Q5Mzfivuhc=
google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
google.golang.org/cloud v0.0.0-20151119220103-975617b05ea8/go.mod h1:0H1ncTHf11KCFhTc/+EFRbzSCOZx+VUbRMk55Yv5MYk=
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=

View File

@@ -1,7 +1,5 @@
module _ // Auto generated by https://github.com/bwplotka/bingo. DO NOT EDIT
go 1.22
go 1.20
toolchain go1.22.4
require github.com/golangci/golangci-lint v1.59.0 // cmd/golangci-lint
require github.com/golangci/golangci-lint v1.53.3 // cmd/golangci-lint

File diff suppressed because it is too large Load Diff

View File

@@ -2,4 +2,4 @@ module _ // Auto generated by https://github.com/bwplotka/bingo. DO NOT EDIT
go 1.18
require github.com/go-swagger/go-swagger v0.30.6-0.20240310114303-db51e79a0e37 // cmd/swagger
require github.com/go-swagger/go-swagger v0.30.2 // cmd/swagger

View File

@@ -42,13 +42,8 @@ github.com/Masterminds/goutils v1.1.1 h1:5nUrii3FMTL5diU80unEVvNevw1nH4+ZV4DSLVJ
github.com/Masterminds/goutils v1.1.1/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU=
github.com/Masterminds/semver/v3 v3.1.1 h1:hLg3sBzpNErnxhQtUy/mmLR2I9foDujNK030IGemrRc=
github.com/Masterminds/semver/v3 v3.1.1/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs=
github.com/Masterminds/semver/v3 v3.2.0/go.mod h1:qvl/7zhW3nngYb5+80sSMF+FG2BjYrf8m9wsX0PNOMQ=
github.com/Masterminds/semver/v3 v3.2.1 h1:RN9w6+7QoMeJVGyfmbcgs28Br8cvmnucEXnY0rYXWg0=
github.com/Masterminds/semver/v3 v3.2.1/go.mod h1:qvl/7zhW3nngYb5+80sSMF+FG2BjYrf8m9wsX0PNOMQ=
github.com/Masterminds/sprig/v3 v3.2.2 h1:17jRggJu518dr3QaafizSXOjKYp94wKfABxUmyxvxX8=
github.com/Masterminds/sprig/v3 v3.2.2/go.mod h1:UoaO7Yp8KlPnJIYWTFkMaqPUYKTfGFPhxNuwnnxkKlk=
github.com/Masterminds/sprig/v3 v3.2.3 h1:eL2fZNezLomi0uOLqjQoN6BfsDD+fyLtgbJMAj9n6YA=
github.com/Masterminds/sprig/v3 v3.2.3/go.mod h1:rXcFaZ2zZbLRJv/xSysmlgIM1u11eBaRMhvYXJNkGuM=
github.com/PuerkitoBio/purell v1.1.1 h1:WEQqlqaGbrPkxLJWfBwQmfEAE1Z7ONdDLqrN38tNFfI=
github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 h1:d+Bc7a5rLufV/sSk/8dngufqelfh6jnri85riMAaF/M=
@@ -56,8 +51,6 @@ github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdko
github.com/asaskevich/govalidator v0.0.0-20200907205600-7a23bdc65eef/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw=
github.com/asaskevich/govalidator v0.0.0-20210307081110-f21760c49a8d h1:Byv0BzEl3/e6D5CLfI0j/7hiIEtvGVFPCZ7Ei2oq8iQ=
github.com/asaskevich/govalidator v0.0.0-20210307081110-f21760c49a8d/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw=
github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 h1:DklsrG3dyBCFEj5IhUbnKptjxatkF07cF2ak3yi77so=
github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw=
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
@@ -80,13 +73,9 @@ github.com/felixge/httpsnoop v1.0.1/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSw
github.com/felixge/httpsnoop v1.0.2 h1:+nS9g82KMXccJ/wp0zyRW9ZBHFETmMGtkk+2CTTrW4o=
github.com/felixge/httpsnoop v1.0.3 h1:s/nj+GCswXYzN5v2DpNMuMQYe+0DDwt5WVCU6CWBdXk=
github.com/felixge/httpsnoop v1.0.3/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg=
github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
github.com/fsnotify/fsnotify v1.5.1 h1:mZcQUHVQUQWoPXXtuf9yuEXKudkV2sx1E06UadKWpgI=
github.com/fsnotify/fsnotify v1.5.4 h1:jRbGcIw6P2Meqdwuo0H1p6JVLbL5DHKAKlYndzMwVZI=
github.com/fsnotify/fsnotify v1.5.4/go.mod h1:OVB6XrOHzAwXMpEM7uPOzcehqUV2UqJxmVXmkdnm1bU=
github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA=
github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM=
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
@@ -94,71 +83,49 @@ github.com/go-openapi/analysis v0.21.2 h1:hXFrOYFHUAMQdu6zwAiKKJHJQ8kqZs1ux/ru1P
github.com/go-openapi/analysis v0.21.2/go.mod h1:HZwRk4RRisyG8vx2Oe6aqeSQcoxRp47Xkp3+K6q+LdY=
github.com/go-openapi/analysis v0.21.4 h1:ZDFLvSNxpDaomuCueM0BlSXxpANBlFYiBvr+GXrvIHc=
github.com/go-openapi/analysis v0.21.4/go.mod h1:4zQ35W4neeZTqh3ol0rv/O8JBbka9QyAgQRPp9y3pfo=
github.com/go-openapi/analysis v0.23.0 h1:aGday7OWupfMs+LbmLZG4k0MYXIANxcuBTYUC03zFCU=
github.com/go-openapi/analysis v0.23.0/go.mod h1:9mz9ZWaSlV8TvjQHLl2mUW2PbZtemkE8yA5v22ohupo=
github.com/go-openapi/errors v0.19.8/go.mod h1:cM//ZKUKyO06HSwqAelJ5NsEMMcpa6VpXe8DOa1Mi1M=
github.com/go-openapi/errors v0.19.9/go.mod h1:cM//ZKUKyO06HSwqAelJ5NsEMMcpa6VpXe8DOa1Mi1M=
github.com/go-openapi/errors v0.20.2 h1:dxy7PGTqEh94zj2E3h1cUmQQWiM1+aeCROfAr02EmK8=
github.com/go-openapi/errors v0.20.2/go.mod h1:cM//ZKUKyO06HSwqAelJ5NsEMMcpa6VpXe8DOa1Mi1M=
github.com/go-openapi/errors v0.20.3 h1:rz6kiC84sqNQoqrtulzaL/VERgkoCyB6WdEkc2ujzUc=
github.com/go-openapi/errors v0.20.3/go.mod h1:Z3FlZ4I8jEGxjUK+bugx3on2mIAk4txuAOhlsB1FSgk=
github.com/go-openapi/errors v0.22.0 h1:c4xY/OLxUBSTiepAg3j/MHuAv5mJhnf53LLMWFB+u/w=
github.com/go-openapi/errors v0.22.0/go.mod h1:J3DmZScxCDufmIMsdOuDHxJbdOGC0xtUynjIx092vXE=
github.com/go-openapi/inflect v0.19.0 h1:9jCH9scKIbHeV9m12SmPilScz6krDxKRasNNSNPXu/4=
github.com/go-openapi/inflect v0.19.0/go.mod h1:lHpZVlpIQqLyKwJ4N+YSc9hchQy/i12fJykb83CRBH4=
github.com/go-openapi/inflect v0.21.0 h1:FoBjBTQEcbg2cJUWX6uwL9OyIW8eqc9k4KhN4lfbeYk=
github.com/go-openapi/inflect v0.21.0/go.mod h1:INezMuUu7SJQc2AyR3WO0DqqYUJSj8Kb4hBd7WtjlAw=
github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg=
github.com/go-openapi/jsonpointer v0.19.5 h1:gZr+CIYByUqjcgeLXnQu2gHYQC9o73G2XUeOFYEICuY=
github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg=
github.com/go-openapi/jsonpointer v0.21.0 h1:YgdVicSA9vH5RiHs9TZW5oyafXZFc6+2Vc1rr/O9oNQ=
github.com/go-openapi/jsonpointer v0.21.0/go.mod h1:IUyH9l/+uyhIYQ/PXVA41Rexl+kOkAPDdXEYns6fzUY=
github.com/go-openapi/jsonreference v0.19.6 h1:UBIxjkht+AWIgYzCDSv2GN+E/togfwXUJFRTWhl2Jjs=
github.com/go-openapi/jsonreference v0.19.6/go.mod h1:diGHMEHg2IqXZGKxqyvWdfWU/aim5Dprw5bqpKkTvns=
github.com/go-openapi/jsonreference v0.20.0 h1:MYlu0sBgChmCfJxxUKZ8g1cPWFOB37YSZqewK7OKeyA=
github.com/go-openapi/jsonreference v0.20.0/go.mod h1:Ag74Ico3lPc+zR+qjn4XBUmXymS4zJbYVCZmcgkasdo=
github.com/go-openapi/jsonreference v0.21.0 h1:Rs+Y7hSXT83Jacb7kFyjn4ijOuVGSvOdF2+tg1TRrwQ=
github.com/go-openapi/jsonreference v0.21.0/go.mod h1:LmZmgsrTkVg9LG4EaHeY8cBDslNPMo06cago5JNLkm4=
github.com/go-openapi/loads v0.21.0 h1:jYtUO4wwP7psAweisP/MDoOpdzsYEESdoPcsWjHDR68=
github.com/go-openapi/loads v0.21.1/go.mod h1:/DtAMXXneXFjbQMGEtbamCZb+4x7eGwkvZCvBmwUG+g=
github.com/go-openapi/loads v0.21.2 h1:r2a/xFIYeZ4Qd2TnGpWDIQNcP80dIaZgf704za8enro=
github.com/go-openapi/loads v0.21.2/go.mod h1:Jq58Os6SSGz0rzh62ptiu8Z31I+OTHqmULx5e/gJbNw=
github.com/go-openapi/loads v0.22.0 h1:ECPGd4jX1U6NApCGG1We+uEozOAvXvJSF4nnwHZ8Aco=
github.com/go-openapi/loads v0.22.0/go.mod h1:yLsaTCS92mnSAZX5WWoxszLj0u+Ojl+Zs5Stn1oF+rs=
github.com/go-openapi/runtime v0.21.1 h1:/KIG00BzA2x2HRStX2tnhbqbQdPcFlkgsYCiNY20FZs=
github.com/go-openapi/runtime v0.24.1 h1:Sml5cgQKGYQHF+M7yYSHaH1eOjvTykrddTE/KtQVjqo=
github.com/go-openapi/runtime v0.24.1/go.mod h1:AKurw9fNre+h3ELZfk6ILsfvPN+bvvlaU/M9q/r9hpk=
github.com/go-openapi/runtime v0.28.0 h1:gpPPmWSNGo214l6n8hzdXYhPuJcGtziTOgUpvsFWGIQ=
github.com/go-openapi/runtime v0.28.0/go.mod h1:QN7OzcS+XuYmkQLw05akXk0jRH/eZ3kb18+1KwW9gyc=
github.com/go-openapi/spec v0.20.4 h1:O8hJrt0UMnhHcluhIdUgCLRWyM2x7QkBXRvOs7m+O1M=
github.com/go-openapi/spec v0.20.4/go.mod h1:faYFR1CvsJZ0mNsmsphTMSoRrNV3TEDoAM7FOEWeq8I=
github.com/go-openapi/spec v0.20.6/go.mod h1:2OpW+JddWPrpXSCIX8eOx7lZ5iyuWj3RYR6VaaBKcWA=
github.com/go-openapi/spec v0.20.7 h1:1Rlu/ZrOCCob0n+JKKJAWhNWMPW8bOZRg8FJaY+0SKI=
github.com/go-openapi/spec v0.20.7/go.mod h1:2OpW+JddWPrpXSCIX8eOx7lZ5iyuWj3RYR6VaaBKcWA=
github.com/go-openapi/spec v0.21.0 h1:LTVzPc3p/RzRnkQqLRndbAzjY0d0BCL72A6j3CdL9ZY=
github.com/go-openapi/spec v0.21.0/go.mod h1:78u6VdPw81XU44qEWGhtr982gJ5BWg2c0I5XwVMotYk=
github.com/go-openapi/strfmt v0.21.0/go.mod h1:ZRQ409bWMj+SOgXofQAGTIo2Ebu72Gs+WaRADcS5iNg=
github.com/go-openapi/strfmt v0.21.1 h1:G6s2t5V5kGCHLVbSdZ/6lI8Wm4OzoPFkc3/cjAsKQrM=
github.com/go-openapi/strfmt v0.21.1/go.mod h1:I/XVKeLc5+MM5oPNN7P6urMOpuLXEcNrCX/rPGuWb0k=
github.com/go-openapi/strfmt v0.21.2/go.mod h1:I/XVKeLc5+MM5oPNN7P6urMOpuLXEcNrCX/rPGuWb0k=
github.com/go-openapi/strfmt v0.21.3 h1:xwhj5X6CjXEZZHMWy1zKJxvW9AfHC9pkyUjLvHtKG7o=
github.com/go-openapi/strfmt v0.21.3/go.mod h1:k+RzNO0Da+k3FrrynSNN8F7n/peCmQQqbbXjtDfvmGg=
github.com/go-openapi/strfmt v0.23.0 h1:nlUS6BCqcnAk0pyhi9Y+kdDVZdZMHfEKQiS4HaMgO/c=
github.com/go-openapi/strfmt v0.23.0/go.mod h1:NrtIpfKtWIygRkKVsxh7XQMDQW5HKQl6S5ik2elW+K4=
github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk=
github.com/go-openapi/swag v0.19.15 h1:D2NRCBzS9/pEY3gP9Nl8aDqGUcPFrwG2p+CNFrLyrCM=
github.com/go-openapi/swag v0.19.15/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ=
github.com/go-openapi/swag v0.21.1/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ=
github.com/go-openapi/swag v0.22.3 h1:yMBqmnQ0gyZvEb/+KzuWZOXgllrXT4SADYbvDaXHv/g=
github.com/go-openapi/swag v0.22.3/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14=
github.com/go-openapi/swag v0.23.0 h1:vsEVJDUo2hPJ2tu0/Xc+4noaxyEffXNIs3cOULZ+GrE=
github.com/go-openapi/swag v0.23.0/go.mod h1:esZ8ITTYEsH1V2trKHjAN8Ai7xHb8RV+YSZ577vPjgQ=
github.com/go-openapi/validate v0.20.3 h1:GZPPhhKSZrE8HjB4eEkoYAZmoWA4+tCemSgINH1/vKw=
github.com/go-openapi/validate v0.21.0/go.mod h1:rjnrwK57VJ7A8xqfpAOEKRH8yQSGUriMu5/zuPSQ1hg=
github.com/go-openapi/validate v0.22.0 h1:b0QecH6VslW/TxtpKgzpO1SNG7GU2FsaqKdP1E2T50Y=
github.com/go-openapi/validate v0.22.0/go.mod h1:rjnrwK57VJ7A8xqfpAOEKRH8yQSGUriMu5/zuPSQ1hg=
github.com/go-openapi/validate v0.24.0 h1:LdfDKwNbpB6Vn40xhTdNZAnfLECL81w+VX3BumrGD58=
github.com/go-openapi/validate v0.24.0/go.mod h1:iyeX1sEufmv3nPbBdX3ieNviWnOZaJ1+zquzJEf2BAQ=
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
github.com/go-stack/stack v1.8.1 h1:ntEHSVwIt7PNXNpgPmVfMrNhLtgjlmnZha2kOpuRiDw=
github.com/go-stack/stack v1.8.1/go.mod h1:dcoOX6HbPZSZptuspn9bctJ+N/CnF5gGygcUP3XYfe4=
@@ -166,10 +133,6 @@ github.com/go-swagger/go-swagger v0.29.0 h1:z3YoZtLvS1Y8TE/PCat1VypcZxM0IgKLt0Nv
github.com/go-swagger/go-swagger v0.29.0/go.mod h1:Z4GJzI+bHKKkGB2Ji1rawpi3/ldXX8CkzGIa9HAC5EE=
github.com/go-swagger/go-swagger v0.30.2 h1:23odPUyQZdkNFZZSBJ3mqYYcdh+LnuReEbdWN18OMRo=
github.com/go-swagger/go-swagger v0.30.2/go.mod h1:neDPes8r8PCz2JPvHRDj8BTULLh4VJUt7n6MpQqxhHM=
github.com/go-swagger/go-swagger v0.30.6-0.20240310114303-db51e79a0e37 h1:KFcZmKdZmapAog2+eL1buervAYrYolBZk7fMecPPDmo=
github.com/go-swagger/go-swagger v0.30.6-0.20240310114303-db51e79a0e37/go.mod h1:i1/E+d8iPNReSE7y04FaVu5OPKB3il5cn+T1Egogg3I=
github.com/go-swagger/go-swagger v0.30.6-0.20240418033037-c46c303aaa02 h1:J6YiT/eg3gAfKMdVCkWXe6khsO+nxa8W4URZ4AUqzbA=
github.com/go-swagger/go-swagger v0.30.6-0.20240418033037-c46c303aaa02/go.mod h1:i1/E+d8iPNReSE7y04FaVu5OPKB3il5cn+T1Egogg3I=
github.com/gobuffalo/attrs v0.0.0-20190224210810-a9411de4debd/go.mod h1:4duuawTqi2wkkpB4ePgWMaai6/Kc6WEz83bhFwpHzj0=
github.com/gobuffalo/depgen v0.0.0-20190329151759-d478694a28d3/go.mod h1:3STtPUQYuzV0gBVOY3vy6CfMm/ljR4pABfrTeHNLHUY=
github.com/gobuffalo/depgen v0.1.0/go.mod h1:+ifsuy7fhi15RWncXQQKjWS9JPkdah5sZvtHc2RXGlg=
@@ -248,15 +211,11 @@ github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm4
github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.1.2 h1:EVhdT+1Kseyi1/pUmXKaFxYsDNy9RQYkMWRH68J/W7Y=
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
github.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g=
github.com/gorilla/handlers v1.5.1 h1:9lRY6j8DEeeBT10CvO9hGW0gmky0BprnvDI5vfhUHH4=
github.com/gorilla/handlers v1.5.1/go.mod h1:t8XrUpc4KVXb7HGyJ4/cEnwQiaxrX/hz1Zv/4g96P1Q=
github.com/gorilla/handlers v1.5.2 h1:cLTUSsNkgcwhgRqvCNmdbRWG0A3N4F+M2nWKdScwyEE=
github.com/gorilla/handlers v1.5.2/go.mod h1:dX+xVpaxdSw+q0Qek8SSsl3dfMk3jNddUkMzo0GtH0w=
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4=
@@ -264,16 +223,11 @@ github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T
github.com/huandu/xstrings v1.3.1/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE=
github.com/huandu/xstrings v1.3.2 h1:L18LIDzqlW6xN2rEkpdV8+oL/IXWJ1APd+vsdYy4Wdw=
github.com/huandu/xstrings v1.3.2/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE=
github.com/huandu/xstrings v1.3.3/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE=
github.com/huandu/xstrings v1.4.0 h1:D17IlohoQq4UcpqD7fDk80P7l+lwAmlFaBHgOipl2FU=
github.com/huandu/xstrings v1.4.0/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE=
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
github.com/imdario/mergo v0.3.11/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA=
github.com/imdario/mergo v0.3.12 h1:b6R2BslTbIEToALKP7LxUvijTsNI9TAe80pLWN2g/HU=
github.com/imdario/mergo v0.3.12/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA=
github.com/imdario/mergo v0.3.16 h1:wwQJbIsHYGMUyLSPrEq1CT16AhnhNJQ51+4fdHUnCl4=
github.com/imdario/mergo v0.3.16/go.mod h1:WBLT9ZmE3lPoWsEzCh9LPo3TiwVN+ZKEjmz+hD27ysY=
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
github.com/jessevdk/go-flags v1.5.0 h1:1jKYvbxEjfUl0fmqTCOfonvskHHXMjBySTLW4y9LFvc=
github.com/jessevdk/go-flags v1.5.0/go.mod h1:Fw0T6WPc1dYxT4mKEZRfG5kJhaTDP9pj1c2EWnYs/m4=
@@ -292,8 +246,6 @@ github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0=
github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk=
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
@@ -301,8 +253,6 @@ github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/magiconair/properties v1.8.5 h1:b6kJs+EmPFMYGkow9GiUyCyOvIwYetYJ3fSaWak/Gls=
github.com/magiconair/properties v1.8.6 h1:5ibWZ6iY0NctNGWo87LalDlEZ6R41TqbbDamhfG/Qzo=
github.com/magiconair/properties v1.8.6/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60=
github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY=
github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0=
github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
github.com/mailru/easyjson v0.7.6/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
@@ -333,9 +283,6 @@ github.com/pelletier/go-toml v1.9.5 h1:4yBQzkHv+7BHq2PQUZF3Mx0IYxG7LsP222s7Agd3v
github.com/pelletier/go-toml v1.9.5/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c=
github.com/pelletier/go-toml/v2 v2.0.1 h1:8e3L2cCQzLFi2CR4g7vGFuFxX7Jl1kKX8gW+iV0GUKU=
github.com/pelletier/go-toml/v2 v2.0.1/go.mod h1:r9LEWfGN8R5k0VXJ+0BkIe7MYkRdwZOjgMj2KwnJFUo=
github.com/pelletier/go-toml/v2 v2.1.1 h1:LWAJwfNvjQZCFIDKWYQaM62NcYeYViCmWIwmOStowAI=
github.com/pelletier/go-toml/v2 v2.1.1/go.mod h1:tJU2Z3ZkXwnxa4DPO899bsyIoywizdUvyaeZurnPPDc=
github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA=
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
@@ -350,32 +297,18 @@ github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTE
github.com/rogpeppe/go-internal v1.8.1 h1:geMPLpDpQOgVyCg5z5GoRwLHepNdb71NXb67XFkP+Eg=
github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8=
github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs=
github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8=
github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4=
github.com/sagikazarmark/locafero v0.4.0 h1:HApY1R9zGo4DBgr7dqsTH/JJxLTTsOt7u6keLGt6kNQ=
github.com/sagikazarmark/locafero v0.4.0/go.mod h1:Pe1W6UlPYUk/+wc/6KFhbORCfqzgYEpgQ3O5fPuL3H4=
github.com/sagikazarmark/slog-shim v0.1.0 h1:diDBnUNK9N/354PgrxMywXnAwEr1QZcOr6gto+ugjYE=
github.com/sagikazarmark/slog-shim v0.1.0/go.mod h1:SrcSrq8aKtyuqEI1uvTDTK1arOWRIczQRv+GVI1AkeQ=
github.com/shopspring/decimal v1.2.0 h1:abSATXmQEYyShuxI4/vyW3tV1MrKAJzCZ/0zLUXYbsQ=
github.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o=
github.com/shopspring/decimal v1.3.1 h1:2Usl1nmF/WZucqkFZhnfFYxxxu8LG21F6nPQBE5gKV8=
github.com/shopspring/decimal v1.3.1/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o=
github.com/sirupsen/logrus v1.4.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q=
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
github.com/sourcegraph/conc v0.3.0 h1:OQTbbt6P72L20UqAkXXuLOj79LfEanQ+YQFNpLA9ySo=
github.com/sourcegraph/conc v0.3.0/go.mod h1:Sdozi7LEKbFPqYX2/J+iBAM6HpqSLTASQIKqDmF7Mt0=
github.com/spf13/afero v1.8.0 h1:5MmtuhAgYeU6qpa7w7bP0dv6MBYuup0vekhSpSkoq60=
github.com/spf13/afero v1.8.2 h1:xehSyVa0YnHWsJ49JFljMpg1HX19V6NDZ1fkm1Xznbo=
github.com/spf13/afero v1.8.2/go.mod h1:CtAatgMJh6bJEIs48Ay/FOnkljP3WeGUG0MC1RfAqwo=
github.com/spf13/afero v1.11.0 h1:WJQKhtpdm3v2IzqG8VMqrr6Rf3UYpEF239Jy9wNepM8=
github.com/spf13/afero v1.11.0/go.mod h1:GH9Y3pIexgf1MTIWtNGyogA5MwRIDXGUr+hbWNoBjkY=
github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
github.com/spf13/cast v1.4.1 h1:s0hze+J0196ZfEMTs80N7UlFt0BDuQ7Q+JDnHiMWKdA=
github.com/spf13/cast v1.5.0 h1:rj3WzYc11XZaIZMPKmwP96zkFEnnAmV8s6XbB2aY32w=
github.com/spf13/cast v1.5.0/go.mod h1:SpXXQ5YoyJw6s3/6cMTQuxvgRl3PCJiyaX9p6b155UU=
github.com/spf13/cast v1.6.0 h1:GEiTHELF+vaR5dhz3VqZfFSzZjYbgeKDpBxQVS4GYJ0=
github.com/spf13/cast v1.6.0/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo=
github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ=
github.com/spf13/jwalterweatherman v1.1.0 h1:ue6voC5bR5F8YxI5S67j9i582FU4Qvo2bmqnqMYADFk=
github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo=
@@ -385,12 +318,9 @@ github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An
github.com/spf13/viper v1.10.1 h1:nuJZuYpG7gTj/XqiUwg8bA0cp1+M2mC3J4g5luUYBKk=
github.com/spf13/viper v1.12.0 h1:CZ7eSOd3kZoaYDLbXnmzgQI5RlciuXBMA+18HwHRfZQ=
github.com/spf13/viper v1.12.0/go.mod h1:b6COn30jlNxbm/V2IqWiNWkJ+vZNiMNksliPCiuKtSI=
github.com/spf13/viper v1.18.2 h1:LUXCnvUvSM6FXAsj6nnfc8Q2tp1dIgUfY9Kc8GsSOiQ=
github.com/spf13/viper v1.18.2/go.mod h1:EKmWIqdnk5lOcmR72yw6hS+8OPYcwD0jteitLMVB+yk=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
@@ -399,12 +329,9 @@ github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
github.com/subosito/gotenv v1.2.0 h1:Slr1R9HxAlEKefgq5jn9U+DnETlIUa6HfgEzj0g5d7s=
github.com/subosito/gotenv v1.3.0 h1:mjC+YW8QpAdXibNi+vNWgzmgBH4+5l5dCXv8cNysBLI=
github.com/subosito/gotenv v1.3.0/go.mod h1:YzJjq/33h7nrwdY+iHMhEOEEbW0ovIz0tB6t6PwAXzs=
github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8=
github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU=
github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk=
github.com/toqueteos/webbrowser v1.2.0 h1:tVP/gpK69Fx+qMJKsLE7TD8LuGWPnEV71wBN9rrstGQ=
github.com/toqueteos/webbrowser v1.2.0/go.mod h1:XWoZq4cyp9WeUeak7w7LXRUQf1F1ATJMir8RTqb4ayM=
@@ -418,7 +345,6 @@ github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
go.mongodb.org/mongo-driver v1.7.3/go.mod h1:NqaYOwnXWr5Pm7AOpO5QFxKJ503nbMse/R79oO62zWg=
go.mongodb.org/mongo-driver v1.7.5/go.mod h1:VXEWRZ6URJIkUq2SCAyapmhH0ZLRBP+FT4xhp5Zvxng=
go.mongodb.org/mongo-driver v1.8.2 h1:8ssUXufb90ujcIvR6MyE1SchaNj0SFxsakiZgxIyrMk=
@@ -426,16 +352,12 @@ go.mongodb.org/mongo-driver v1.8.3/go.mod h1:0sQWfOeY63QTntERDJJ/0SuKK0T1uVSgKCu
go.mongodb.org/mongo-driver v1.10.0/go.mod h1:wsihk0Kdgv8Kqu1Anit4sfK+22vSFbUrAVEYRhCXrA8=
go.mongodb.org/mongo-driver v1.10.1 h1:NujsPveKwHaWuKUer/ceo9DzEe7HIj1SlJ6uvXZG0S4=
go.mongodb.org/mongo-driver v1.10.1/go.mod h1:z4XpeoU6w+9Vht+jAFyLgVrD+jGSQQe0+CBWFHNiHt8=
go.mongodb.org/mongo-driver v1.14.0 h1:P98w8egYRjYe3XDjxhYJagTokP/H6HzlsnojRgZRd80=
go.mongodb.org/mongo-driver v1.14.0/go.mod h1:Vzb0Mk/pa7e6cWw85R4F/endUC3u0U9jGcNU603k65c=
go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=
go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk=
go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0=
go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20190422162423-af44ce270edf/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE=
@@ -447,14 +369,10 @@ golang.org/x/crypto v0.0.0-20200414173820-0848c9571904/go.mod h1:LzIPMQfyMNhhGPh
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20201216223049-8b5274cf687f/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/crypto v0.0.0-20220829220503-c86fa9a7ed90 h1:Y/gsMcFOcR+6S6f3YeMKl5g+dZMEWqcz5Czj/GWYbkM=
golang.org/x/crypto v0.0.0-20220829220503-c86fa9a7ed90/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/crypto v0.3.0/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4=
golang.org/x/crypto v0.21.0 h1:X31++rzVUdKhX5sWmSOFZxx8UW/ldWx55cbf08iNAMA=
golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
@@ -465,8 +383,6 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0
golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM=
golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU=
golang.org/x/exp v0.0.0-20240222234643-814bf88cf225 h1:LfspQV/FYTatPTr/3HzIcmiUFH7PGP+OQ6mgDYo3yuQ=
golang.org/x/exp v0.0.0-20240222234643-814bf88cf225/go.mod h1:CxmFvTBINI24O/j8iY7H1xHzx2i4OsyguNBmN/uPtqc=
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
@@ -493,8 +409,6 @@ golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.5.1 h1:OJxoQ/rynoF0dcCdI7cLPktw/hR2cueqYfjm43oqK38=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 h1:6zppjxzCulZykYSLyVDYbneBfbaBIQPYMevg0bEwv2s=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
golang.org/x/mod v0.16.0 h1:QX4fJ0Rr5cPQCF7O9lh9Se4pmwfwskqZfq5moyldzic=
golang.org/x/mod v0.16.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
@@ -530,8 +444,6 @@ golang.org/x/net v0.0.0-20210421230115-4e50805a0758/go.mod h1:72T/g9IO56b78aLF+1
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20220121210141-e204ce36a2ba h1:6u6sik+bn/y7vILcYkK3iwTBWN7WtBvB0+SZswQnbf8=
golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
@@ -553,9 +465,6 @@ golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJ
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.6.0 h1:5BMeUDZ7vkXGfEr1x9B4bRcTH4lpkTkpdh0T/J+qjbQ=
golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
@@ -602,17 +511,11 @@ golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220114195835-da31bd327af9 h1:XfKQ4OlFl8okEOr5UvAqFRVj8pY/4yfcXrddB8qAbU0=
golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220829200755-d48e67d00261 h1:v6hYoSR9T5oet+pMXwUWkbiVqx/63mlHjefrHmxwfeY=
golang.org/x/sys v0.0.0-20220829200755-d48e67d00261/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.18.0 h1:DBdB3niSjOA/O0blCZBqDefyWNYveAYMNF1Wum0DYQ4=
golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc=
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
@@ -623,9 +526,6 @@ golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
@@ -683,8 +583,6 @@ golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0=
golang.org/x/tools v0.1.8 h1:P1HhGGuLW4aAclzjtmJdf0mJOjVUZUzOTqkAkWL+l6w=
golang.org/x/tools v0.1.12 h1:VveCTK38A2rkS8ZqFY25HIDFscX5X9OoEhJd3quQmXU=
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
golang.org/x/tools v0.19.0 h1:tfGCXNR1OsFG+sVdLAitlpjAvD/I6dHDKnYrpEZUHkw=
golang.org/x/tools v0.19.0/go.mod h1:qoJWxmGSIBmAeriMx19ogtrEPrGtDbPK634QFIcLAhc=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
@@ -785,8 +683,6 @@ gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
gopkg.in/ini.v1 v1.66.3 h1:jRskFVxYaMGAMUbN0UZ7niA9gzL9B49DOqE78vg0k3w=
gopkg.in/ini.v1 v1.66.4 h1:SsAcf+mM7mRZo2nJNGt8mZCjG8ZRaNGMURJw7BsIST4=
gopkg.in/ini.v1 v1.66.4/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA=
gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=

View File

@@ -1,4 +1,4 @@
# Auto generated binary variables helper managed by https://github.com/bwplotka/bingo v0.9. DO NOT EDIT.
# Auto generated binary variables helper managed by https://github.com/bwplotka/bingo v0.8. DO NOT EDIT.
# All tools are designed to be build inside $GOBIN.
# Those variables will work only until 'bingo get' was invoked, or if tools were installed via Makefile's Variables.mk.
GOBIN=${GOBIN:=$(go env GOBIN)}
@@ -14,11 +14,13 @@ CUE="${GOBIN}/cue-v0.5.0"
DRONE="${GOBIN}/drone-v1.5.0"
GOLANGCI_LINT="${GOBIN}/golangci-lint-v1.59.0"
GOLANGCI_LINT="${GOBIN}/golangci-lint-v1.53.3"
JB="${GOBIN}/jb-v0.5.1"
LEFTHOOK="${GOBIN}/lefthook-v1.4.8"
SWAGGER="${GOBIN}/swagger-v0.30.6-0.20240310114303-db51e79a0e37"
SWAGGER="${GOBIN}/swagger-v0.30.2"
WIRE="${GOBIN}/wire-v0.5.0"

5
.bingo/wire.mod Normal file
View File

@@ -0,0 +1,5 @@
module _ // Auto generated by https://github.com/bwplotka/bingo. DO NOT EDIT
go 1.16
require github.com/google/wire v0.5.0 // cmd/wire

13
.bingo/wire.sum Normal file
View File

@@ -0,0 +1,13 @@
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
github.com/google/subcommands v1.0.1 h1:/eqq+otEXm5vhfBrbREPCSVQbvofip6kIz+mX5TUH7k=
github.com/google/subcommands v1.0.1/go.mod h1:ZjhPrFU+Olkh9WazFPsl27BQ4UPiG37m3yTrtFlrHVk=
github.com/google/wire v0.5.0 h1:I7ELFeVBr3yfPIcc8+MWvrjk+3VjbcSzoXm3JVa+jD8=
github.com/google/wire v0.5.0/go.mod h1:ngWDr9Qvq3yZA10YrxfyGELY/AFWGVpy9c1LTRi1EoU=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/tools v0.0.0-20190422233926-fe54fb35175b h1:NVD8gBK33xpdqCaZVVtd6OFJp+3dxkXuz7+U7KaVN6s=
golang.org/x/tools v0.0.0-20190422233926-fe54fb35175b/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=

View File

@@ -105,7 +105,7 @@
- Notice to makers/users of custom data sources, there is a minor breaking change in 2.2 that
require an update to custom data sources for them to work in 2.2. [Read this doc](https://github.com/grafana/grafana/tree/master/docs/sources/datasources/plugin_api.md) for more on the
data source api change.
- Data source api changes, [PLUGIN_CHANGES.md](https://github.com/grafana/grafana/blob/main/public/app/plugins/PLUGIN_CHANGES.md)
- Data source api changes, [PLUGIN_CHANGES.md](https://github.com/grafana/grafana/blob/master/public/app/plugins/PLUGIN_CHANGES.md)
- The duplicate query function used in data source editors is changed, and moveMetricQuery function was renamed
**Tech (Note for devs)**

View File

@@ -198,7 +198,7 @@ slack channel (link to slack channel in readme).
### Breaking changes
- **Plugin API**: Both data source and panel plugin api (and plugin.json schema) have been updated, requiring an update to plugins. See [plugin api](https://github.com/grafana/grafana/blob/main/public/app/plugins/plugin_api.md) for more info.
- **Plugin API**: Both data source and panel plugin api (and plugin.json schema) have been updated, requiring an update to plugins. See [plugin api](https://github.com/grafana/grafana/blob/master/public/app/plugins/plugin_api.md) for more info.
- **InfluxDB 0.8.x** The data source for the old version of influxdb (0.8.x) is no longer included in default builds, but can easily be installed via improved plugin system, closes [#3523](https://github.com/grafana/grafana/issues/3523)
- **KairosDB** The data source is no longer included in default builds, but can easily be installed via improved plugin system, closes [#3524](https://github.com/grafana/grafana/issues/3524)
- **Templating**: Templating value formats (glob/regex/pipe etc) are now handled automatically and not specified by the user, this makes variable values possible to reuse in many contexts. It can in some edge cases break existing dashboards that have template variables that do not reload on dashboard load. To fix any issue just go into template variable options and update the variable (so it's values are reloaded.).

View File

@@ -100,7 +100,7 @@ See [security announcement](https://community.grafana.com/t/grafana-5-2-3-and-4-
## Tech
- **Go**: Grafana is now built using golang 1.9
- **Webpack**: Changed from systemjs to webpack (see readme or building from source guide for new build instructions). Systemjs is still used to load plugins but now plugins can only import a limited set of dependencies. See [PLUGIN_DEV.md](https://github.com/grafana/grafana/blob/main/PLUGIN_DEV.md) for more details on how this can effect some plugins.
- **Webpack**: Changed from systemjs to webpack (see readme or building from source guide for new build instructions). Systemjs is still used to load plugins but now plugins can only import a limited set of dependencies. See [PLUGIN_DEV.md](https://github.com/grafana/grafana/blob/master/PLUGIN_DEV.md) for more details on how this can effect some plugins.
# 4.5.2 (2017-09-22)

View File

@@ -1291,4 +1291,4 @@ repo on July 1st. Make sure you have switched to the new repo by then. The new r
- **Text Panel**: The text panel does no longer by default allow unsanitized HTML. [#4117](https://github.com/grafana/grafana/issues/4117). This means that if you have text panels with scripts tags they will no longer work as before. To enable unsafe javascript execution in text panels enable the settings `disable_sanitize_html` under the section `[panels]` in your Grafana ini file, or set env variable `GF_PANELS_DISABLE_SANITIZE_HTML=true`.
- **Dashboard**: Panel property `minSpan` replaced by `maxPerRow`. Dashboard migration will automatically migrate all dashboard panels using the `minSpan` property to the new `maxPerRow` property [#12991](https://github.com/grafana/grafana/pull/12991)
For older release notes, refer to the [CHANGELOG_ARCHIVE.md](https://github.com/grafana/grafana/blob/main/CHANGELOG_ARCHIVE.md)
For older release notes, refer to the [CHANGELOG_ARCHIVE.md](https://github.com/grafana/grafana/blob/master/CHANGELOG_ARCHIVE.md)

View File

@@ -544,7 +544,7 @@ Issue [#29407](https://github.com/grafana/grafana/issues/29407)
We have upgraded AngularJS from version 1.6.6 to 1.8.2. Due to this upgrade some old angular plugins might stop working and will require a small update. This is due to the deprecation and removal of pre-assigned bindings. So if your custom angular controllers expect component bindings in the controller constructor you need to move this code to an `$onInit` function. For more details on how to migrate AngularJS code open the [migration guide](https://docs.angularjs.org/guide/migration) and search for **pre-assigning bindings**.
In order not to break all angular panel plugins and data sources we have some custom [angular inject behavior](https://github.com/grafana/grafana/blob/main/public/app/core/injectorMonkeyPatch.ts) that makes sure that bindings for these controllers are still set before constructor is called so many old angular panels and data source plugins will still work. Issue [#28736](https://github.com/grafana/grafana/issues/28736)
In order not to break all angular panel plugins and data sources we have some custom [angular inject behavior](https://github.com/grafana/grafana/blob/master/public/app/core/injectorMonkeyPatch.ts) that makes sure that bindings for these controllers are still set before constructor is called so many old angular panels and data source plugins will still work. Issue [#28736](https://github.com/grafana/grafana/issues/28736)
### Deprecations
@@ -1288,8 +1288,8 @@ This option to group query variable values into groups by tags has been an exper
- **Datasource/Loki**: Support for [deprecated Loki endpoints](https://github.com/grafana/loki/blob/master/docs/api.md#lokis-http-api) has been removed.
- **Backend plugins**: Grafana now requires backend plugins to be signed, otherwise Grafana will not load/start them. This is an additional security measure to make sure backend plugin binaries and files haven't been tampered with. Refer to [Upgrade Grafana](https://grafana.com/docs/grafana/latest/installation/upgrading/#upgrading-to-v7-0) for more information.
- **Docker**: Our Ubuntu based images have been upgraded to Ubuntu [20.04 LTS](https://releases.ubuntu.com/20.04/).
- **@grafana/ui**: Forms migration notice, see [@grafana/ui changelog](https://github.com/grafana/grafana/blob/main/packages/grafana-ui/CHANGELOG.md)
- **@grafana/ui**: Select API change for creating custom values, see [@grafana/ui changelog](https://github.com/grafana/grafana/blob/main/packages/grafana-ui/CHANGELOG.md)
- **@grafana/ui**: Forms migration notice, see [@grafana/ui changelog](https://github.com/grafana/grafana/blob/master/packages/grafana-ui/CHANGELOG.md)
- **@grafana/ui**: Select API change for creating custom values, see [@grafana/ui changelog](https://github.com/grafana/grafana/blob/master/packages/grafana-ui/CHANGELOG.md)
**Deprecation warnings**
@@ -1304,7 +1304,7 @@ Not just visualizing data from anywhere, in Grafana 7 you can transform it too.
Data transformations will provide a common set of data operations that were previously duplicated as custom features in many panels or data sources but are now an integral part of the Grafana data processing pipeline and something all data sources and panels can take advantage of.
In Grafana 7.0 we have a shared data model for both time series and table data that we call [DataFrame](https://github.com/grafana/grafana/blob/main/docs/sources/plugins/developing/dataframe.md). A DataFrame is like a table with columns but we refer to columns as fields. A time series is simply a DataFrame with two fields (time & value).
In Grafana 7.0 we have a shared data model for both time series and table data that we call [DataFrame](https://github.com/grafana/grafana/blob/master/docs/sources/plugins/developing/dataframe.md). A DataFrame is like a table with columns but we refer to columns as fields. A time series is simply a DataFrame with two fields (time & value).
**Transformations shipping in 7.0**
@@ -1414,7 +1414,7 @@ We have also extended the time zone options so you can select any of the standar
### Features / Enhancements
- **Docker**: Upgrade to Alpine 3.11. [#24056](https://github.com/grafana/grafana/pull/24056), [@aknuds1](https://github.com/aknuds1)
- **Forms**: Remove Forms namespace [BREAKING]. Will cause all `Forms` imports to stop working. See migration guide in [@grafana/ui changelog](https://github.com/grafana/grafana/blob/main/packages/grafana-ui/CHANGELOG.md)[#24378](https://github.com/grafana/grafana/pull/24378), [@tskarhed](https://github.com/tskarhed)
- **Forms**: Remove Forms namespace [BREAKING]. Will cause all `Forms` imports to stop working. See migration guide in [@grafana/ui changelog](https://github.com/grafana/grafana/blob/master/packages/grafana-ui/CHANGELOG.md)[#24378](https://github.com/grafana/grafana/pull/24378), [@tskarhed](https://github.com/tskarhed)
### Bug Fixes
@@ -1429,7 +1429,7 @@ We have also extended the time zone options so you can select any of the standar
- **Removed PhantomJS**: PhantomJS was deprecated in [Grafana v6.4](https://grafana.com/docs/grafana/latest/guides/whats-new-in-v6-4/#phantomjs-deprecation) and starting from Grafana v7.0.0, all PhantomJS support has been removed. This means that Grafana no longer ships with a built-in image renderer, and we advise you to install the [Grafana Image Renderer plugin](https://grafana.com/grafana/plugins/grafana-image-renderer).
- **Docker**: Our Ubuntu based images have been upgraded to Ubuntu [20.04 LTS](https://releases.ubuntu.com/20.04/).
- **Dashboard**: A global minimum dashboard refresh interval is now enforced and defaults to 5 seconds.
- **@grafana/ui**: Forms migration notice, see [@grafana/ui changelog](https://github.com/grafana/grafana/blob/main/packages/grafana-ui/CHANGELOG.md)
- **@grafana/ui**: Forms migration notice, see [@grafana/ui changelog](https://github.com/grafana/grafana/blob/master/packages/grafana-ui/CHANGELOG.md)
- **Interval calculation**: There is now a new option `Max data points` that controls the auto interval `$__interval` calculation. Interval was previously calculated by dividing the panel width by the time range. With the new max data points option it is now easy to set `$__interval` to a dynamic value that is time range agnostic. For example if you set `Max data points` to 10 Grafana will dynamically set `$__interval` by dividing the current time range by 10.
- **Datasource/Loki**: Support for [deprecated Loki endpoints](https://github.com/grafana/loki/blob/master/docs/api.md#lokis-http-api) has been removed.
@@ -1484,8 +1484,8 @@ We have also extended the time zone options so you can select any of the standar
- **Removed PhantomJS**: PhantomJS was deprecated in [Grafana v6.4](https://grafana.com/docs/grafana/latest/guides/whats-new-in-v6-4/#phantomjs-deprecation) and starting from Grafana v7.0.0, all PhantomJS support has been removed. This means that Grafana no longer ships with a built-in image renderer, and we advise you to install the [Grafana Image Renderer plugin](https://grafana.com/grafana/plugins/grafana-image-renderer).
- **Docker**: Our Ubuntu based images have been upgraded to Ubuntu [20.04 LTS](https://releases.ubuntu.com/20.04/).
- **Dashboard**: A global minimum dashboard refresh interval is now enforced and defaults to 5 seconds.
- **@grafana/ui**: Forms migration notice, see [@grafana/ui changelog](https://github.com/grafana/grafana/blob/main/packages/grafana-ui/CHANGELOG.md)
- **@grafana/ui**: Select API change for creating custom values, see [@grafana/ui changelog](https://github.com/grafana/grafana/blob/main/packages/grafana-ui/CHANGELOG.md)
- **@grafana/ui**: Forms migration notice, see [@grafana/ui changelog](https://github.com/grafana/grafana/blob/master/packages/grafana-ui/CHANGELOG.md)
- **@grafana/ui**: Select API change for creating custom values, see [@grafana/ui changelog](https://github.com/grafana/grafana/blob/master/packages/grafana-ui/CHANGELOG.md)
- **Interval calculation**: There is now a new option `Max data points` that controls the auto interval `$__interval` calculation. Interval was previously calculated by dividing the panel width by the time range. With the new max data points option it is now easy to set `$__interval` to a dynamic value that is time range agnostic. For example if you set `Max data points` to 10 Grafana will dynamically set `$__interval` by dividing the current time range by 10.
- **Datasource/Loki**: Support for [deprecated Loki endpoints](https://github.com/grafana/loki/blob/master/docs/api.md#lokis-http-api) has been removed.

1169
.drone.yml

File diff suppressed because it is too large Load Diff

103
.eslintrc
View File

@@ -1,14 +1,13 @@
{
"extends": ["@grafana/eslint-config"],
"root": true,
"plugins": ["@emotion", "lodash", "jest", "import", "jsx-a11y", "@grafana", "no-barrel-files"],
"plugins": ["@emotion", "lodash", "jest", "import", "jsx-a11y", "@grafana"],
"settings": {
"import/internal-regex": "^(app/)|(@grafana)",
"import/external-module-folders": ["node_modules", ".yarn"],
"import/external-module-folders": ["node_modules", ".yarn"]
},
"rules": {
"@grafana/no-border-radius-literal": "error",
"@grafana/no-unreduced-motion": "error",
"react/prop-types": "off",
// need to ignore emotion's `css` prop, see https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/no-unknown-property.md#rule-options
"react/no-unknown-property": ["error", { "ignore": ["css"] }],
@@ -20,8 +19,8 @@
{
"groups": [["builtin", "external"], "internal", "parent", "sibling", "index"],
"newlines-between": "always",
"alphabetize": { "order": "asc" },
},
"alphabetize": { "order": "asc" }
}
],
"no-restricted-imports": [
"error",
@@ -30,43 +29,47 @@
{
"name": "react-redux",
"importNames": ["useDispatch", "useSelector"],
"message": "Please import from app/types instead.",
"message": "Please import from app/types instead."
},
{
"name": "react-i18next",
"importNames": ["Trans", "t"],
"message": "Please import from app/core/internationalization instead",
"message": "Please import from app/core/internationalization instead"
},
],
},
{
"name": "@grafana/e2e",
"message": "@grafana/e2e is deprecated. Please import from ./e2e/utils instead"
}
]
}
],
// Use typescript's no-redeclare for compatibility with overrides
"no-redeclare": "off",
"@typescript-eslint/no-redeclare": ["error"],
"@typescript-eslint/no-redeclare": ["error"]
},
"overrides": [
{
"files": ["packages/grafana-ui/src/components/uPlot/**/*.{ts,tsx}"],
"rules": {
"react-hooks/rules-of-hooks": "off",
"react-hooks/exhaustive-deps": "off",
},
"react-hooks/exhaustive-deps": "off"
}
},
{
"files": ["packages/grafana-ui/src/components/ThemeDemos/**/*.{ts,tsx}"],
"rules": {
"@emotion/jsx-import": "off",
"react/jsx-uses-react": "off",
"react/react-in-jsx-scope": "off",
},
"react/react-in-jsx-scope": "off"
}
},
{
"files": ["public/dashboards/scripted*.js"],
"rules": {
"no-redeclare": "error",
"@typescript-eslint/no-redeclare": "off",
},
"@typescript-eslint/no-redeclare": "off"
}
},
{
"extends": ["plugin:jsx-a11y/recommended"],
@@ -79,57 +82,29 @@
"jsx-a11y/no-autofocus": [
"error",
{
"ignoreNonDOM": true,
},
"ignoreNonDOM": true
}
],
"jsx-a11y/label-has-associated-control": [
"error",
{
"controlComponents": ["NumberInput"],
"depth": 2,
},
],
},
"depth": 2
}
]
}
},
{
"files": [
"public/app/plugins/datasource/azuremonitor/*.{ts,tsx}",
"public/app/plugins/datasource/azuremonitor/**/*.{ts,tsx}",
"public/app/plugins/datasource/cloud-monitoring/*.{ts,tsx}",
"public/app/plugins/datasource/cloud-monitoring/**/*.{ts,tsx}",
"public/app/plugins/datasource/elasticsearch/*.{ts,tsx}",
"public/app/plugins/datasource/elasticsearch/**/*.{ts,tsx}",
"public/app/plugins/datasource/grafana-postgresql-datasource/*.{ts,tsx}",
"public/app/plugins/datasource/grafana-postgresql-datasource/**/*.{ts,tsx}",
"public/app/plugins/datasource/grafana-pyroscope-datasource/*.{ts,tsx}",
"public/app/plugins/datasource/grafana-pyroscope-datasource/**/*.{ts,tsx}",
"public/app/plugins/datasource/grafana-testdata-datasource/*.{ts,tsx}",
"public/app/plugins/datasource/grafana-testdata-datasource/**/*.{ts,tsx}",
"public/app/plugins/datasource/jaeger/*.{ts,tsx}",
"public/app/plugins/datasource/jaeger/**/*.{ts,tsx}",
"public/app/plugins/datasource/loki/*.{ts,tsx}",
"public/app/plugins/datasource/loki/**/*.{ts,tsx}",
"public/app/plugins/datasource/mysql/*.{ts,tsx}",
"public/app/plugins/datasource/mysql/**/*.{ts,tsx}",
"public/app/plugins/datasource/parca/*.{ts,tsx}",
"public/app/plugins/datasource/parca/**/*.{ts,tsx}",
"public/app/plugins/datasource/tempo/*.{ts,tsx}",
"public/app/plugins/datasource/tempo/**/*.{ts,tsx}",
"public/app/plugins/datasource/loki/*.{ts,tsx}",
"public/app/plugins/datasource/loki/**/*.{ts,tsx}",
"public/app/plugins/datasource/elasticsearch/*.{ts,tsx}",
"public/app/plugins/datasource/elasticsearch/**/*.{ts,tsx}",
"public/app/plugins/datasource/cloudwatch/*.{ts,tsx}",
"public/app/plugins/datasource/cloudwatch/**/*.{ts,tsx}",
"public/app/plugins/datasource/zipkin/*.{ts,tsx}",
"public/app/plugins/datasource/zipkin/**/*.{ts,tsx}",
"public/app/plugins/datasource/grafana-testdata-datasource/**/*.{ts,tsx}"
],
"settings": {
"import/resolver": {
"node": {
"extensions": [".ts", ".tsx"],
},
},
"extensions": [".ts", ".tsx"]
}
}
},
"rules": {
"import/no-restricted-paths": [
@@ -138,14 +113,14 @@
"zones": [
{
"target": "./public/app/plugins",
"from": "./public",
"except": ["./app/plugins"],
"message": "Core plugins are not allowed to depend on Grafana core packages",
},
],
},
],
},
},
],
"from": "./public/app",
"except": ["./plugins"],
"message": "Core plugins are not allowed to depend on Grafana core packages"
}
]
}
]
}
}
]
}

404
.github/CODEOWNERS vendored
View File

@@ -13,11 +13,13 @@
# Documentation
/.changelog-archive @grafana/grafana-release-guild
/.codespellignore @grafana/docs-tooling
/CHANGELOG.md @grafana/grafana-release-guild
/CODE_OF_CONDUCT.md @grafana/grafana-community-support
/CONTRIBUTING.md @grafana/grafana-community-support
/GOVERNANCE.md @RichiH
/HALL_OF_FAME.md @grafana/grafana-community-support
/ISSUE_TRIAGE.md @grafana/grafana-community-support
/LICENSE @torkelo
/LICENSING.md @torkelo
/MAINTAINERS.md @RichiH
@@ -26,135 +28,132 @@
/ROADMAP.md @torkelo
/SECURITY.md @grafana/security-team
/SUPPORT.md @torkelo
/UPGRADING_DEPENDENCIES.md @grafana/docs-grafana
/WORKFLOW.md @torkelo
/contribute/ @grafana/grafana-community-support
/contribute/UPGRADING_DEPENDENCIES.md @grafana/docs-grafana
/devenv/README.md @grafana/docs-grafana
# START Technical documentation
# Technical documentation
# `make docs` procedure and related workflows are owned @grafana/docs-tooling. Slack #docs.
/docs/ @grafana/docs-tooling
/docs/.codespellignore @grafana/docs-tooling
/docs/sources/ @Eve832
/docs/sources/administration/ @jdbaldry
/docs/sources/alerting/ @brendamuir
/docs/sources/dashboards/ @imatwawana
/docs/sources/datasources/ @jdbaldry
/docs/sources/explore/ @grafana/explore-squad @lwandz13
/docs/sources/fundamentals @chri2547
/docs/sources/getting-started/ @chri2547
/docs/sources/introduction/ @chri2547
/docs/sources/panels-visualizations/ @imatwawana
/docs/sources/release-notes/ @Eve832 @GrafanaWriter
/docs/sources/setup-grafana/ @chri2547
/docs/sources/upgrade-guide/ @imatwawana
/docs/sources/whatsnew/ @imatwawana
/docs/sources/developers/plugins/ @Eve832 @josmperez @grafana/plugins-platform-frontend @grafana/plugins-platform-backend
# Documentation sources might have different owners.
/docs/ @grafana/docs-tooling
/docs/sources/ @Eve832
/docs/sources/administration/ @jdbaldry
/docs/sources/alerting/ @brendamuir
/docs/sources/dashboards/ @imatwawana
/docs/sources/datasources/ @lwandz13
/docs/sources/explore/ @grafana/explore-squad
/docs/sources/fundamentals @chri2547
/docs/sources/getting-started/ @chri2547
/docs/sources/introduction/ @chri2547
/docs/sources/old-alerting/ @brendamuir
/docs/sources/panels-visualizations/ @imatwawana
/docs/sources/panels-visualizations/query-transform-data/transform-data/index.md @imatwawana @baldm0mma
# END Technical documentation
/docs/sources/release-notes/ @Eve832 @GrafanaWriter
/docs/sources/setup-grafana/ @chri2547
/docs/sources/upgrade-guide/ @imatwawana
/docs/sources/whatsnew/ @imatwawana
/docs/sources/developers/plugins/ @Eve832 @josmperez @grafana/plugins-platform-frontend @grafana/plugins-platform-backend
# Backend code
/go.mod @grafana/grafana-backend-group
/go.sum @grafana/grafana-backend-group
/go.work @grafana/grafana-app-platform-squad
/go.work.sum @grafana/grafana-app-platform-squad
/.bingo/ @grafana/grafana-backend-group
/pkg/README.md @grafana/grafana-backend-group
/pkg/ruleguard.rules.go @grafana/grafana-backend-group
/.bra.toml @grafana/grafana-backend-group
/.golangci.toml @grafana/grafana-backend-group
/build.go @grafana/grafana-backend-services-squad
/scripts/modowners/ @grafana/grafana-backend-services-squad
/go.mod @grafana/backend-platform
/go.sum @grafana/backend-platform
/.bingo/ @grafana/backend-platform
/pkg/README.md @grafana/backend-platform
/pkg/ruleguard.rules.go @grafana/backend-platform
/.bra.toml @grafana/backend-platform
/.golangci.toml @grafana/backend-platform
/build.go @grafana/backend-platform
/scripts/modowners/ @grafana/backend-platform
/hack/ @grafana/grafana-app-platform-squad
/pkg/api/ @grafana/grafana-backend-group
/pkg/api/ @grafana/backend-platform
/pkg/apis/ @grafana/grafana-app-platform-squad
/pkg/bus/ @grafana/grafana-search-and-storage
/pkg/cmd/ @grafana/grafana-backend-group
/pkg/bus/ @grafana/backend-platform
/pkg/cmd/ @grafana/backend-platform
/pkg/cmd/grafana/apiserver @grafana/grafana-app-platform-squad
/pkg/components/apikeygen/ @grafana/identity-access-team
/pkg/components/satokengen/ @grafana/identity-access-team
/pkg/components/dashdiffs/ @grafana/grafana-app-platform-squad
/pkg/components/imguploader/ @grafana/grafana-backend-group
/pkg/components/loki/ @grafana/grafana-backend-group
/pkg/components/null/ @grafana/grafana-backend-group
/pkg/components/simplejson/ @grafana/grafana-backend-group
/pkg/events/ @grafana/grafana-backend-group
/pkg/extensions/ @grafana/grafana-backend-group
/pkg/ifaces/ @grafana/grafana-backend-group
/pkg/infra/appcontext/ @grafana/grafana-backend-group
/pkg/infra/db/ @grafana/grafana-backend-group
/pkg/infra/localcache/ @grafana/grafana-backend-group
/pkg/infra/log/ @grafana/grafana-backend-group
/pkg/infra/metrics/ @grafana/grafana-backend-group
/pkg/infra/network/ @grafana/grafana-backend-group
/pkg/infra/process/ @grafana/grafana-backend-group
/pkg/infra/remotecache/ @grafana/grafana-backend-group
/pkg/infra/serverlock/ @grafana/grafana-backend-group
/pkg/infra/slugify/ @grafana/grafana-backend-group
/pkg/infra/tracing/ @grafana/grafana-backend-group
/pkg/infra/usagestats/ @grafana/grafana-backend-group
/pkg/middleware/ @grafana/grafana-backend-group
/pkg/mocks/ @grafana/grafana-backend-group
/pkg/models/ @grafana/grafana-backend-group
/pkg/server/ @grafana/grafana-backend-group
/pkg/apiserver @grafana/grafana-app-platform-squad
/pkg/apimachinery @grafana/grafana-app-platform-squad
/pkg/promlib @grafana/observability-metrics
/pkg/services/annotations/ @grafana/grafana-search-and-storage
/pkg/components/dashdiffs/ @grafana/backend-platform
/pkg/components/imguploader/ @grafana/backend-platform
/pkg/components/loki/ @grafana/backend-platform
/pkg/components/null/ @grafana/backend-platform
/pkg/components/simplejson/ @grafana/backend-platform
/pkg/events/ @grafana/backend-platform
/pkg/extensions/ @grafana/backend-platform
/pkg/ifaces/ @grafana/backend-platform
/pkg/infra/appcontext/ @grafana/backend-platform
/pkg/infra/db/ @grafana/backend-platform
/pkg/infra/grn/ @grafana/backend-platform
/pkg/infra/localcache/ @grafana/backend-platform
/pkg/infra/log/ @grafana/backend-platform
/pkg/infra/metrics/ @grafana/backend-platform
/pkg/infra/network/ @grafana/backend-platform
/pkg/infra/process/ @grafana/backend-platform
/pkg/infra/remotecache/ @grafana/backend-platform
/pkg/infra/serverlock/ @grafana/backend-platform
/pkg/infra/slugify/ @grafana/backend-platform
/pkg/infra/tracing/ @grafana/backend-platform
/pkg/infra/usagestats/ @grafana/backend-platform
/pkg/middleware/ @grafana/backend-platform
/pkg/mocks/ @grafana/backend-platform
/pkg/models/ @grafana/backend-platform
/pkg/server/ @grafana/backend-platform
/pkg/services/annotations/ @grafana/backend-platform
/pkg/services/apikey/ @grafana/identity-access-team
/pkg/services/cleanup/ @grafana/grafana-backend-group
/pkg/services/contexthandler/ @grafana/grafana-backend-group
/pkg/services/cleanup/ @grafana/backend-platform
/pkg/services/contexthandler/ @grafana/backend-platform
/pkg/services/correlations/ @grafana/explore-squad
/pkg/services/dashboardimport/ @grafana/grafana-backend-group
/pkg/services/dashboards/ @grafana/grafana-app-platform-squad
/pkg/services/dashboardversion/ @grafana/grafana-backend-group
/pkg/services/encryption/ @grafana/grafana-operator-experience-squad
/pkg/services/folder/ @grafana/grafana-search-and-storage
/pkg/services/apiserver @grafana/grafana-app-platform-squad
/pkg/services/hooks/ @grafana/grafana-backend-group
/pkg/services/kmsproviders/ @grafana/grafana-operator-experience-squad
/pkg/services/licensing/ @grafana/grafana-operator-experience-squad
/pkg/services/navtree/ @grafana/grafana-backend-group
/pkg/services/notifications/ @grafana/grafana-backend-group
/pkg/services/org/ @grafana/grafana-backend-group
/pkg/services/dashboardimport/ @grafana/backend-platform
/pkg/services/dashboards/ @grafana/backend-platform
/pkg/services/dashboardversion/ @grafana/backend-platform
/pkg/services/encryption/ @grafana/backend-platform
/pkg/services/folder/ @grafana/backend-platform
/pkg/services/grafana-apiserver @grafana/grafana-app-platform-squad
/pkg/services/hooks/ @grafana/backend-platform
/pkg/services/kmsproviders/ @grafana/backend-platform
/pkg/services/licensing/ @grafana/backend-platform
/pkg/services/navtree/ @grafana/backend-platform
/pkg/services/notifications/ @grafana/backend-platform
/pkg/services/org/ @grafana/backend-platform
/pkg/services/playlist/ @grafana/grafana-app-platform-squad
/pkg/services/preference/ @grafana/grafana-backend-group
/pkg/services/provisioning/ @grafana/grafana-search-and-storage
/pkg/services/query/ @grafana/grafana-app-platform-squad
/pkg/services/queryhistory/ @grafana/grafana-app-platform-squad
/pkg/services/quota/ @grafana/grafana-search-and-storage
/pkg/services/screenshot/ @grafana/grafana-backend-group
/pkg/services/search/ @grafana/grafana-search-and-storage
/pkg/services/searchusers/ @grafana/grafana-search-and-storage
/pkg/services/secrets/ @grafana/grafana-operator-experience-squad
/pkg/services/shorturls/ @grafana/grafana-backend-group
/pkg/services/sqlstore/ @grafana/grafana-search-and-storage
/pkg/services/preference/ @grafana/backend-platform
/pkg/services/provisioning/ @grafana/backend-platform
/pkg/services/query/ @grafana/backend-platform
/pkg/services/queryhistory/ @grafana/backend-platform
/pkg/services/quota/ @grafana/backend-platform
/pkg/services/rendering/ @grafana/backend-platform
/pkg/services/screenshot/ @grafana/backend-platform
/pkg/services/search/ @grafana/backend-platform
/pkg/services/searchusers/ @grafana/backend-platform
/pkg/services/secrets/ @grafana/backend-platform
/pkg/services/shorturls/ @grafana/backend-platform
/pkg/services/sqlstore/ @grafana/backend-platform
/pkg/services/ssosettings/ @grafana/identity-access-team
/pkg/services/star/ @grafana/grafana-search-and-storage
/pkg/services/stats/ @grafana/grafana-backend-group
/pkg/services/tag/ @grafana/grafana-search-and-storage
/pkg/services/star/ @grafana/backend-platform
/pkg/services/stats/ @grafana/backend-platform
/pkg/services/tag/ @grafana/backend-platform
/pkg/services/team/ @grafana/identity-access-team
/pkg/services/temp_user/ @grafana/grafana-backend-group
/pkg/services/updatechecker/ @grafana/grafana-backend-group
/pkg/services/temp_user/ @grafana/backend-platform
/pkg/services/updatechecker/ @grafana/backend-platform
/pkg/services/user/ @grafana/identity-access-team
/pkg/services/validations/ @grafana/grafana-backend-group
/pkg/setting/ @grafana/grafana-backend-services-squad
/pkg/tests/ @grafana/grafana-backend-services-squad
/pkg/services/validations/ @grafana/backend-platform
/pkg/setting/ @grafana/backend-platform
/pkg/tests/ @grafana/backend-platform
/pkg/tests/apis/ @grafana/grafana-app-platform-squad
/pkg/tests/api/correlations/ @grafana/explore-squad
/pkg/tsdb/grafanads/ @grafana/grafana-backend-group
/pkg/tsdb/opentsdb/ @grafana/grafana-backend-group
/pkg/util/ @grafana/grafana-backend-group
/pkg/web/ @grafana/grafana-backend-group
/pkg/tsdb/grafanads/ @grafana/backend-platform
/pkg/tsdb/intervalv2/ @grafana/backend-platform
/pkg/tsdb/legacydata/ @grafana/backend-platform
/pkg/tsdb/opentsdb/ @grafana/backend-platform
/pkg/tsdb/sqleng/ @grafana/partner-datasources @grafana/oss-big-tent
/pkg/tsdb/sqleng/proxyutil @grafana/hosted-grafana-team
/pkg/util/ @grafana/backend-platform
/pkg/web/ @grafana/backend-platform
/pkg/infra/kvstore/ @grafana/grafana-backend-group
/pkg/infra/fs/ @grafana/grafana-backend-group
/pkg/infra/x/ @grafana/grafana-backend-group
/pkg/infra/kvstore/ @grafana/backend-platform
/pkg/infra/fs/ @grafana/backend-platform
/pkg/infra/x/ @grafana/backend-platform
# devenv
@@ -168,14 +167,14 @@
/devenv/bulk-dashboards/ @grafana/dashboards-squad
/devenv/bulk-folders/ @grafana/grafana-frontend-platform
/devenv/create_docker_compose.sh @grafana/grafana-backend-services-squad
/devenv/alert_rules.yaml @grafana/alerting-backend
/devenv/bulk_alerting_dashboards/ @grafana/alerting-backend-product
/devenv/create_docker_compose.sh @grafana/backend-platform
/devenv/dashboards.yaml @grafana/dashboards-squad
/devenv/datasources.yaml @grafana/grafana-backend-group
/devenv/datasources_docker.yaml @grafana/grafana-backend-group
/devenv/datasources.yaml @grafana/backend-platform
/devenv/datasources_docker.yaml @grafana/backend-platform
/devenv/dev-dashboards-without-uid/ @grafana/dashboards-squad
/devenv/dev-dashboards/ @grafana/dashboards-squad
/devenv/docker/blocks/alert_webhook_listener/ @grafana/alerting-backend
/devenv/docker/blocks/alert_webhook_listener/ @grafana/alerting-backend-product
/devenv/docker/blocks/clickhouse/ @grafana/partner-datasources
/devenv/docker/blocks/collectd/ @grafana/observability-metrics
/devenv/docker/blocks/etcd @grafana/grafana-app-platform-squad
@@ -187,13 +186,13 @@
/devenv/docker/blocks/influxdb1/ @grafana/observability-metrics
/devenv/docker/blocks/jaeger/ @grafana/observability-traces-and-profiling
/devenv/docker/blocks/maildev/ @grafana/alerting-frontend
/devenv/docker/blocks/mariadb/ @grafana/oss-big-tent
/devenv/docker/blocks/memcached/ @grafana/grafana-backend-group
/devenv/docker/blocks/mimir_backend/ @grafana/alerting-backend
/devenv/docker/blocks/mssql/ @grafana/partner-datasources
/devenv/docker/blocks/mssql_arm64/ @grafana/partner-datasources
/devenv/docker/blocks/mssql_tests/ @grafana/partner-datasources
/devenv/docker/blocks/mssql_tls/ @grafana/partner-datasources
/devenv/docker/blocks/mariadb/ @grafana/grafana-bi-squad
/devenv/docker/blocks/memcached/ @grafana/backend-platform
/devenv/docker/blocks/mimir_backend/ @grafana/alerting-backend-product
/devenv/docker/blocks/mssql/ @grafana/grafana-bi-squad
/devenv/docker/blocks/mssql_arm64/ @grafana/grafana-bi-squad
/devenv/docker/blocks/mssql_tests/ @grafana/grafana-bi-squad
/devenv/docker/blocks/mssql_tls/ @grafana/grafana-bi-squad
/devenv/docker/blocks/mysql/ @grafana/oss-big-tent
/devenv/docker/blocks/mysql_exporter/ @grafana/oss-big-tent
/devenv/docker/blocks/mysql_opendata/ @grafana/oss-big-tent
@@ -205,24 +204,24 @@
/devenv/docker/blocks/prometheus_random_data/ @grafana/observability-metrics
/devenv/docker/blocks/pyroscope/ @grafana/observability-traces-and-profiling
/devenv/docker/blocks/redis/ @bergquist
/devenv/docker/blocks/sensugo/ @grafana/grafana-backend-group
/devenv/docker/blocks/sensugo/ @grafana/backend-platform
/devenv/docker/blocks/slow_proxy/ @bergquist
/devenv/docker/blocks/smtp/ @bergquist
/devenv/docker/blocks/tempo/ @grafana/observability-traces-and-profiling
/devenv/docker/blocks/traefik/ @mckn
/devenv/docker/blocks/zipkin/ @grafana/observability-traces-and-profiling
/devenv/docker/blocks/webdav/ @grafana/alerting-backend
/devenv/docker/blocks/webdav/ @grafana/alerting-backend-product
/devenv/docker/buildcontainer/ @bergquist
/devenv/docker/compose_header.yml @grafana/grafana-backend-services-squad
/devenv/docker/compose_header.yml @grafana/backend-platform
/devenv/docker/debtest/ @bergquist
/devenv/docker/ha-test-unified-alerting/ @grafana/alerting-backend
/devenv/docker/ha_test/ @grafana/grafana-backend-services-squad
/devenv/docker/loadtest/ @grafana/grafana-backend-services-squad
/devenv/docker/rpmtest/ @grafana/grafana-backend-services-squad
/devenv/docker/ha-test-unified-alerting/ @grafana/alerting-backend-product
/devenv/docker/ha_test/ @grafana/backend-platform
/devenv/docker/loadtest/ @grafana/backend-platform
/devenv/docker/rpmtest/ @grafana/backend-platform
/devenv/jsonnet/ @grafana/dataviz-squad
/devenv/local-npm/ @grafana/frontend-ops
/devenv/vscode/ @grafana/frontend-ops
/devenv/setup.sh @grafana/grafana-backend-services-squad
/devenv/setup.sh @grafana/backend-platform
# Emails
/emails/ @grafana/alerting-frontend
@@ -265,28 +264,29 @@
/pkg/tsdb/mssql/ @grafana/partner-datasources
# Database migrations
/pkg/services/sqlstore/migrations/ @grafana/grafana-search-and-storage
*_mig.go @grafana/grafana-search-and-storage
/pkg/services/sqlstore/migrations/ @grafana/backend-platform @grafana/hosted-grafana-team
*_mig.go @grafana/backend-platform @grafana/hosted-grafana-team
# Grafana app platform
/pkg/services/live/ @grafana/grafana-app-platform-squad
/pkg/services/searchV2/ @grafana/grafana-app-platform-squad
/pkg/services/store/ @grafana/grafana-app-platform-squad
/pkg/infra/filestorage/ @grafana/grafana-app-platform-squad
/pkg/util/converter/ @grafana/grafana-app-platform-squad
/pkg/modules/ @grafana/grafana-app-platform-squad
/pkg/services/grpcserver/ @grafana/grafana-search-and-storage
/pkg/generated @grafana/grafana-app-platform-squad
/pkg/kindsysreport/ @grafana/grafana-app-platform-squad
/pkg/services/grpcserver/ @grafana/grafana-app-platform-squad
# Alerting
/pkg/services/ngalert/ @grafana/alerting-backend
/pkg/services/sqlstore/migrations/ualert/ @grafana/alerting-backend
/pkg/tests/api/alerting/ @grafana/alerting-backend
/pkg/services/ngalert/ @grafana/alerting-backend-product
/pkg/services/sqlstore/migrations/ualert/ @grafana/alerting-backend-product
/pkg/services/alerting/ @grafana/alerting-backend-product
/pkg/tests/api/alerting/ @grafana/alerting-backend-product
/public/app/features/alerting/ @grafana/alerting-frontend
/public/app/features/gops/ @grafana/alerting-frontend
# Library Services
/pkg/services/libraryelements/ @grafana/dashboards-squad
/pkg/services/librarypanels/ @grafana/dashboards-squad
/pkg/services/libraryelements/ @grafana/grafana-frontend-platform
/pkg/services/librarypanels/ @grafana/grafana-frontend-platform
# Plugins
/pkg/api/pluginproxy/ @grafana/plugins-platform-backend
@@ -302,7 +302,7 @@
/pkg/services/plugindashboards/ @grafana/plugins-platform-backend
# Backend code docs
/contribute/backend/ @grafana/grafana-backend-group
/contribute/backend/ @grafana/backend-platform
/crowdin.yml @grafana/grafana-frontend-platform
@@ -310,14 +310,14 @@
/public/app/core/internationalization/ @grafana/grafana-frontend-platform
/e2e/ @grafana/grafana-frontend-platform
/e2e/cloud-plugins-suite/ @grafana/partner-datasources
/e2e/plugin-e2e/plugin-e2e-api-tests/ @grafana/plugins-platform-frontend
/packages/ @grafana/grafana-frontend-platform @grafana/plugins-platform-frontend
/packages/grafana-e2e-selectors/ @grafana/grafana-frontend-platform
/packages/grafana-e2e/ @grafana/grafana-frontend-platform
/packages/grafana-ui/.storybook/ @grafana/plugins-platform-frontend
/packages/grafana-ui/src/components/ @grafana/grafana-frontend-platform
/packages/grafana-ui/src/components/DateTimePickers/ @grafana/grafana-frontend-platform
/packages/grafana-ui/src/components/Table/ @grafana/dataviz-squad
/packages/grafana-ui/src/components/Table/SparklineCell.tsx @grafana/dataviz-squad @grafana/app-o11y-visualizations
/packages/grafana-ui/src/components/Table/ @grafana/grafana-bi-squad
/packages/grafana-ui/src/components/Table/SparklineCell.tsx @grafana/grafana-bi-squad @grafana/app-o11y-visualizations
/packages/grafana-ui/src/components/Gauge/ @grafana/dataviz-squad
/packages/grafana-ui/src/components/BarGauge/ @grafana/dataviz-squad
/packages/grafana-ui/src/components/uPlot/ @grafana/dataviz-squad
@@ -332,23 +332,18 @@
/packages/grafana-ui/src/graveyard/GraphNG/ @grafana/dataviz-squad
/packages/grafana-ui/src/graveyard/TimeSeries/ @grafana/dataviz-squad
/packages/grafana-ui/src/utils/storybook/ @grafana/plugins-platform-frontend
/packages/grafana-data/src/transformations/ @grafana/dataviz-squad
/packages/grafana-data/src/transformations/ @grafana/grafana-bi-squad
/packages/grafana-data/src/**/*logs* @grafana/observability-logs
/packages/grafana-schema/src/**/*tempo* @grafana/observability-traces-and-profiling
/packages/grafana-schema/src/**/*canvas* @grafana/dataviz-squad
/packages/grafana-flamegraph/ @grafana/observability-traces-and-profiling
/plugins-bundled/ @grafana/plugins-platform-frontend
/packages/grafana-plugin-configs/ @grafana/plugins-platform-frontend
/packages/grafana-prometheus/ @grafana/observability-metrics
/packages/grafana-o11y-ds-frontend/ @grafana/observability-logs @grafana/observability-traces-and-profiling
/packages/grafana-sql/ @grafana/partner-datasources @grafana/oss-big-tent
# root files, mostly frontend
/.browserslistrc @grafana/frontend-ops
/package.json @grafana/frontend-ops
/nx.json @grafana/frontend-ops
/project.json @grafana/frontend-ops
/tsconfig.json @grafana/frontend-ops
.browserslistrc @grafana/frontend-ops
package.json @grafana/frontend-ops
tsconfig.json @grafana/frontend-ops
/.editorconfig @grafana/frontend-ops
/.eslintignore @grafana/frontend-ops
/.gitattributes @grafana/frontend-ops
@@ -358,38 +353,34 @@
/.yarn @grafana/frontend-ops
/.yarnrc.yml @grafana/frontend-ops
/yarn.lock @grafana/frontend-ops
/lerna.json @grafana/frontend-ops
/babel.config.json @grafana/frontend-ops
lerna.json @grafana/frontend-ops
/.prettierrc.js @grafana/frontend-ops
/.eslintrc @grafana/frontend-ops
/.vim @zoltanbedi
/jest.config.js @grafana/frontend-ops
/latest.json @grafana/frontend-ops
/metadata.md @grafana/plugins-platform
/stylelint.config.js @grafana/frontend-ops
/tools/ @grafana/frontend-ops
/lefthook.yml @grafana/frontend-ops
/lefthook.rc @grafana/frontend-ops
/.husky/pre-commit @grafana/frontend-ops
/cypress.config.js @grafana/grafana-frontend-platform
/.levignore.js @grafana/plugins-platform-frontend
playwright.config.ts @grafana/plugins-platform-frontend
.husky/pre-commit @grafana/frontend-ops
cypress.config.js @grafana/grafana-frontend-platform
.levignore.js @grafana/plugins-platform-frontend
# public folder
/public/app/core/ @grafana/grafana-frontend-platform
/public/app/core/components/TimePicker/ @grafana/grafana-frontend-platform
/public/app/core/components/Layers/ @grafana/dataviz-squad
/public/app/core/components/TraceToLogs @grafana/observability-traces-and-profiling
/public/app/core/components/GraphNG/ @grafana/dataviz-squad
/public/app/core/components/TimeSeries/ @grafana/dataviz-squad
/public/app/core/components/TimelineChart/ @grafana/dataviz-squad
/public/app/core/components/Form/ @grafana/grafana-frontend-platform
/public/app/core/history/ @grafana/explore-squad
/public/app/features/all.ts @grafana/grafana-frontend-platform
/public/app/features/admin/ @grafana/identity-access-team
# Temp owners until Enterprise team takes over
/public/app/features/migrate-to-cloud @grafana/grafana-frontend-platform
/public/app/features/auth-config/ @grafana/identity-access-team
/public/app/features/annotations/ @grafana/dashboards-squad
/public/app/features/annotations/ @grafana/grafana-frontend-platform
/public/app/features/api-keys/ @grafana/identity-access-team
/public/app/features/canvas/ @grafana/dataviz-squad
/public/app/features/geo/ @grafana/dataviz-squad
@@ -398,32 +389,31 @@ playwright.config.ts @grafana/plugins-platform-frontend
/public/app/features/connections/ @grafana/plugins-platform-frontend @mikkancso
/public/app/features/correlations/ @grafana/explore-squad
/public/app/features/dashboard/ @grafana/dashboards-squad
/public/app/features/dashboard/components/TransformationsEditor/ @grafana/dataviz-squad
/public/app/features/dashboard/components/TransformationsEditor/ @grafana/grafana-bi-squad
/public/app/features/dashboard-scene/ @grafana/dashboards-squad
/public/app/features/datasources/ @grafana/plugins-platform-frontend @mikkancso
/public/app/features/dimensions/ @grafana/dataviz-squad
/public/app/features/dataframe-import/ @grafana/dataviz-squad
/public/app/features/dataframe-import/ @grafana/grafana-bi-squad
/public/app/features/explore/ @grafana/explore-squad
/public/app/features/expressions/ @grafana/observability-metrics
/public/app/features/folders/ @grafana/grafana-frontend-platform
/public/app/features/inspector/ @grafana/dashboards-squad
/public/app/features/invites/ @grafana/grafana-frontend-platform
/public/app/features/library-panels/ @grafana/dashboards-squad
/public/app/features/library-panels/ @grafana/grafana-frontend-platform
/public/app/features/logs/ @grafana/observability-logs
/public/app/features/live/ @grafana/grafana-app-platform-squad
/public/app/features/apiserver/ @grafana/grafana-app-platform-squad
/public/app/features/manage-dashboards/ @grafana/dashboards-squad
/public/app/features/manage-dashboards/RecentlyDeletedPage.tsx @grafana/grafana-frontend-platform
/public/app/features/notifications/ @grafana/grafana-frontend-platform
/public/app/features/org/ @grafana/grafana-frontend-platform
/public/app/features/panel/ @grafana/dashboards-squad
/public/app/features/playlist/ @grafana/dashboards-squad
/public/app/features/plugins/ @grafana/plugins-platform-frontend
/public/app/features/plugins/sql/ @grafana/partner-datasources @grafana/oss-big-tent
/public/app/features/profile/ @grafana/grafana-frontend-platform
/public/app/features/query-library/ @grafana/explore-squad
/public/app/features/runtime/ @ryantxu
/public/app/features/query/ @grafana/dashboards-squad
/public/app/features/sandbox/ @grafana/grafana-frontend-platform
/public/app/features/scenes/ @grafana/dashboards-squad
/public/app/features/browse-dashboards/ @grafana/grafana-frontend-platform
/public/app/features/search/ @grafana/grafana-frontend-platform
/public/app/features/serviceaccounts/ @grafana/identity-access-team
@@ -431,17 +421,18 @@ playwright.config.ts @grafana/plugins-platform-frontend
/public/app/features/teams/ @grafana/identity-access-team
/public/app/features/templating/ @grafana/dashboards-squad
/public/app/features/trails/ @torkelo
/public/app/features/transformers/ @grafana/dataviz-squad
/public/app/features/transformers/timeSeriesTable/ @grafana/dataviz-squad @grafana/app-o11y-visualizations
/public/app/features/transformers/ @grafana/grafana-bi-squad
/public/app/features/transformers/timeSeriesTable/ @grafana/grafana-bi-squad @grafana/app-o11y-visualizations
/public/app/features/users/ @grafana/identity-access-team
/public/app/features/variables/ @grafana/dashboards-squad
/public/app/plugins/panel/alertGroups/ @grafana/alerting-frontend
/public/app/plugins/panel/alertlist/ @grafana/alerting-frontend
/public/app/plugins/panel/annolist/ @grafana/grafana-frontend-platform
/public/app/plugins/panel/barchart/ @grafana/dataviz-squad
/public/app/plugins/panel/bargauge/ @grafana/dataviz-squad
/public/app/plugins/panel/dashlist/ @grafana/grafana-frontend-platform
/public/app/plugins/panel/debug/ @ryantxu
/public/app/plugins/panel/datagrid/ @grafana/dataviz-squad
/public/app/plugins/panel/datagrid/ @grafana/grafana-bi-squad
/public/app/plugins/panel/gauge/ @grafana/dataviz-squad
/public/app/plugins/panel/gettingstarted/ @grafana/grafana-frontend-platform
/public/app/plugins/panel/graph/ @grafana/dataviz-squad
@@ -454,9 +445,9 @@ playwright.config.ts @grafana/plugins-platform-frontend
/public/app/plugins/panel/piechart/ @grafana/dataviz-squad
/public/app/plugins/panel/state-timeline/ @grafana/dataviz-squad
/public/app/plugins/panel/status-history/ @grafana/dataviz-squad
/public/app/plugins/panel/table/ @grafana/dataviz-squad
/public/app/plugins/panel/table/cells/SparklineCellOptionsEditor.tsx @grafana/dataviz-squad @grafana/app-o11y-visualizations
/public/app/plugins/panel/table-old/ @grafana/dataviz-squad
/public/app/plugins/panel/table/ @grafana/grafana-bi-squad
/public/app/plugins/panel/table/cells/SparklineCellOptionsEditor.tsx @grafana/grafana-bi-squad @grafana/app-o11y-visualizations
/public/app/plugins/panel/table-old/ @grafana/grafana-bi-squad
/public/app/plugins/panel/timeseries/ @grafana/dataviz-squad
/public/app/plugins/panel/trend/ @grafana/dataviz-squad
/public/app/plugins/panel/geomap/ @grafana/dataviz-squad
@@ -472,21 +463,19 @@ playwright.config.ts @grafana/plugins-platform-frontend
/public/app/routes/ @grafana/grafana-frontend-platform
/public/app/store/ @grafana/grafana-frontend-platform
/public/app/types/ @grafana/grafana-frontend-platform
/public/app/types/alerting.ts @grafana/alerting-frontend
/public/app/types/unified-alerting-dto.ts @grafana/alerting-frontend
/public/dashboards/ @grafana/dashboards-squad
/public/fonts/ @grafana/alerting-frontend
/public/gazetteer/ @ryantxu
/public/img/ @grafana/grafana-frontend-platform
/public/lib/ @grafana/grafana-frontend-platform
/public/lib/monaco-languages/kusto.ts @grafana/partner-datasources
/public/maps/ @ryantxu
/public/robots.txt @grafana/frontend-ops
/public/fonts/ @grafana/grafana-frontend-platform
/public/sass/ @grafana/grafana-frontend-platform
/public/test/ @grafana/grafana-frontend-platform
/public/test/helpers/alertingRuleEditor.tsx @grafana/alerting-frontend
/public/views/ @grafana/grafana-frontend-platform
/public/views/swagger.html @grafana/grafana-backend-group
/public/views/swagger.html @grafana/backend-platform
/public/app/features/explore/Logs/ @grafana/observability-logs
@@ -496,9 +485,9 @@ playwright.config.ts @grafana/plugins-platform-frontend
/public/app/features/explore/FlameGraph/ @grafana/observability-traces-and-profiling
/public/app/features/explore/TraceView/ @grafana/observability-traces-and-profiling
/public/api-merged.json @grafana/grafana-backend-group
/public/api-enterprise-spec.json @grafana/grafana-backend-group
/public/openapi3.json @grafana/grafana-backend-group
/public/api-merged.json @grafana/backend-platform
/public/api-enterprise-spec.json @grafana/backend-platform
/public/openapi3.json @grafana/backend-platform
/public/app/angular/ @torkelo
/public/app/app.ts @grafana/frontend-ops
/public/app/dev.ts @grafana/frontend-ops
@@ -516,7 +505,7 @@ playwright.config.ts @grafana/plugins-platform-frontend
/scripts/circle-* @grafana/grafana-release-guild
/scripts/publish-npm-packages.sh @grafana/grafana-release-guild @grafana/plugins-platform-frontend
/scripts/validate-npm-packages.sh @grafana/grafana-release-guild @grafana/plugins-platform-frontend
/scripts/ci-frontend-metrics.sh @grafana/grafana-frontend-platform @grafana/plugins-platform-frontend @grafana/dataviz-squad
/scripts/ci-frontend-metrics.sh @grafana/grafana-frontend-platform @grafana/plugins-platform-frontend @grafana/grafana-bi-squad
/scripts/cli/ @grafana/grafana-frontend-platform
/scripts/clean-git-or-error.sh @grafana/grafana-as-code
/scripts/grafana-server/ @grafana/grafana-frontend-platform
@@ -533,18 +522,14 @@ playwright.config.ts @grafana/plugins-platform-frontend
/scripts/trigger_windows_build.sh @grafana/grafana-release-guild
/scripts/cleanup-husky.sh @grafana/frontend-ops
/scripts/verify-repo-update/ @grafana/grafana-release-guild
/scripts/generate-icon-bundle.js @grafana/plugins-platform-frontend @grafana/grafana-frontend-platform
/scripts/generate-rtk-apis.ts @grafana/grafana-frontend-platform
/scripts/levitate-parse-json-report.js @grafana/plugins-platform-frontend
/scripts/codemods/explicit-barrel-imports.cjs @grafana/frontend-ops
scripts/generate-icon-bundle.js @grafana/plugins-platform-frontend @grafana/grafana-frontend-platform
/scripts/**/generate-transformations* @grafana/dataviz-squad
/scripts/docs/generate-transformations.ts @grafana/grafana-bi-squad
/scripts/webpack/ @grafana/frontend-ops
/scripts/generate-a11y-report.sh @grafana/grafana-frontend-platform
.pa11yci.conf.js @grafana/grafana-frontend-platform
.pa11yci-pr.conf.js @grafana/grafana-frontend-platform
.betterer.results @grafanabot
.betterer.results.json @grafanabot
.betterer.ts @grafana/grafana-frontend-platform
# @grafana/ui component documentation
@@ -565,7 +550,7 @@ playwright.config.ts @grafana/plugins-platform-frontend
/public/app/plugins/datasource/jaeger/ @grafana/observability-traces-and-profiling
/public/app/plugins/datasource/loki/ @grafana/observability-logs
/public/app/plugins/datasource/mixed/ @grafana/dashboards-squad
/public/app/plugins/datasource/mssql/ @grafana/partner-datasources
/public/app/plugins/datasource/mssql/ @grafana/grafana-bi-squad
/public/app/plugins/datasource/mysql/ @grafana/oss-big-tent
/public/app/plugins/datasource/opentsdb/ @grafana/observability-metrics
/public/app/plugins/datasource/grafana-postgresql-datasource/ @grafana/oss-big-tent
@@ -582,16 +567,14 @@ playwright.config.ts @grafana/plugins-platform-frontend
/public/app/features/manage-dashboards/components/PublicDashboardListTable/ @grafana/sharing-squad
/public/app/features/dashboard/containers/PublicDashboardPage.tsx @grafana/sharing-squad
/public/app/features/manage-dashboards/components/SnapshotListTable.tsx @grafana/sharing-squad
/pkg/api/render.go @grafana/sharing-squad
/pkg/services/dashboardsnapshots/ @grafana/sharing-squad
/pkg/services/publicdashboards/ @grafana/sharing-squad
/pkg/services/rendering/ @grafana/sharing-squad
# SSE - Server Side Expressions
/pkg/expr/ @grafana/observability-metrics
# Cloud middleware
/grafana-mixin/ @grafana/grafana-backend-services-squad
/grafana-mixin/ @grafana/hosted-grafana-team
# Grafana authentication and authorization
/pkg/login/ @grafana/identity-access-team
@@ -609,20 +592,16 @@ playwright.config.ts @grafana/plugins-platform-frontend
/pkg/services/extsvcauth/ @grafana/identity-access-team
/pkg/services/oauthtoken/ @grafana/identity-access-team
/pkg/services/serviceaccounts/ @grafana/identity-access-team
/public/app/core/components/RolePicker/ @grafana/identity-access-team
# Support bundles
/public/app/features/support-bundles/ @grafana/identity-access-team
/pkg/services/supportbundles/ @grafana/identity-access-team
# Grafana Operator Experience Team
/pkg/infra/httpclient/httpclientprovider/sigv4_middleware.go @grafana/grafana-operator-experience-squad
/pkg/infra/httpclient/httpclientprovider/sigv4_middleware_test.go @grafana/grafana-operator-experience-squad
/pkg/services/caching/ @grafana/grafana-operator-experience-squad
/pkg/services/cloudmigration/ @grafana/grafana-operator-experience-squad
/pkg/services/gcom/ @grafana/grafana-operator-experience-squad
# Feature toggles
/pkg/services/featuremgmt/ @grafana/grafana-backend-services-squad
/pkg/services/featuremgmt/ @grafana/grafana-operator-experience-squad
# Kind definitions
/kinds/dashboard @grafana/dashboards-squad
@@ -631,12 +610,12 @@ playwright.config.ts @grafana/plugins-platform-frontend
# Kind system and code generation
embed.go @grafana/grafana-as-code
/pkg/kinds/ @grafana/grafana-as-code
/pkg/cuectx/ @grafana/grafana-as-code
/pkg/registry/ @grafana/grafana-as-code
/pkg/registry/apis/ @grafana/grafana-app-platform-squad
/pkg/codegen/ @grafana/grafana-as-code
/pkg/codegen/generators @grafana/grafana-as-code
/pkg/kinds/*/*_gen.go @grafana/grafana-as-code
/pkg/registry/schemas/ @grafana/grafana-as-code
/pkg/registry/corekind/ @grafana/grafana-as-code
/public/app/plugins/*gen.go @grafana/grafana-as-code
/cue.mod/ @grafana/grafana-as-code
@@ -653,13 +632,11 @@ embed.go @grafana/grafana-as-code
/.github/pr-commands.json @marefr
/.github/renovate.json5 @grafana/frontend-ops
/.github/teams.yml @armandgrillet
/.github/workflows/alerting-swagger-gen.yml @grafana/alerting-backend
/.github/workflows/alerting-swagger-gen.yml @grafana/alerting-backend-product
/.github/workflows/auto-milestone.yml @grafana/grafana-release-guild
/.github/workflows/backport.yml @grafana/grafana-release-guild
/.github/workflows/bump-version.yml @grafana/grafana-release-guild
/.github/workflows/close-milestone.yml @grafana/grafana-release-guild
/.github/workflows/release-pr.yml @grafana/grafana-release-guild
/.github/workflows/release-comms.yml @grafana/grafana-release-guild
/.github/workflows/codeowners-validator.yml @tolzhabayev
/.github/workflows/codeql-analysis.yml @DanCech
/.github/workflows/commands.yml @torkelo
@@ -689,20 +666,16 @@ embed.go @grafana/grafana-as-code
/.github/workflows/update-changelog.yml @grafana/grafana-release-guild
/.github/workflows/update-make-docs.yml @grafana/docs-tooling
/.github/workflows/snyk.yml @grafana/security-team
/.github/workflows/scripts/kinds/verify-kinds.go @grafana/platform-cat
/.github/workflows/publish-kinds-next.yml @grafana/platform-cat
/.github/workflows/publish-kinds-release.yml @grafana/platform-cat
/.github/workflows/verify-kinds.yml @grafana/platform-cat
/.github/workflows/scripts/kinds/verify-kinds.go @grafana/grafana-as-code
/.github/workflows/publish-kinds-next.yml @grafana/grafana-as-code
/.github/workflows/publish-kinds-release.yml @grafana/grafana-as-code
/.github/workflows/verify-kinds.yml @grafana/grafana-as-code
/.github/workflows/dashboards-issue-add-label.yml @grafana/dashboards-squad
/.github/workflows/ephemeral-instances-pr-comment.yml @grafana/grafana-operator-experience-squad
/.github/workflows/ephemeral-instances-pr-opened-closed.yml @grafana/grafana-operator-experience-squad
/.github/workflows/create-security-patch-from-security-mirror.yml @grafana/grafana-release-guild
/.github/workflows/core-plugins-build-and-release.yml @grafana/plugins-platform-frontend @grafana/plugins-platform-backend
/.github/workflows/i18n-crowdin-upload.yml @grafana/grafana-frontend-platform
/.github/workflows/i18n-crowdin-download.yml @grafana/grafana-frontend-platform
/.github/workflows/pr-go-workspace-check.yml @grafana/grafana-app-platform-squad
/.github/workflows/run-scenes-e2e.yml @grafana/dashboards-squad
/.github/workflows/go_lint.yml @grafana/grafana-backend-services-squad
/.github/workflows/i18n-crowdin-fix-files.yml @grafana/grafana-frontend-platform
# Generated files not requiring owner approval
/packages/grafana-data/src/types/featureToggles.gen.ts @grafanabot
@@ -717,7 +690,8 @@ embed.go @grafana/grafana-as-code
/conf/ldap.toml @grafana/identity-access-team
/conf/ldap_multiple.toml @grafana/identity-access-team
/conf/provisioning/access-control/ @grafana/identity-access-team
/conf/provisioning/alerting/ @grafana/alerting-backend
/conf/provisioning/alerting/ @grafana/alerting-backend-product
/conf/provisioning/dashboards/ @grafana/dashboards-squad
/conf/provisioning/datasources/ @grafana/plugins-platform-backend
/conf/provisioning/notifiers/ @bergquist
/conf/provisioning/plugins/ @grafana/plugins-platform-backend

8
.github/bot.md vendored
View File

@@ -4,13 +4,13 @@ The bot is configured via [commands.json](https://github.com/grafana/grafana/blo
Comment commands:
* Write the word `/duplicate #<number>` anywhere in a comment and the bot will add the correct label and standard message.
* Write the word `/needsMoreInfo` anywhere in a comment and the bot will add the correct label and standard message.
* Write the word `/duplicate #<number>` anywhere in a comment and the bot will add the correct label and standard message.
* Write the word `/needsMoreInfo` anywhere in a comment and the bot will add the correct label and standard message.
Label commands:
* Add label `bot/question` the bot will close with standard question message and add label `type/question`
* Add label `bot/duplicate` the bot will close with standard duplicate message and add label `type/duplicate`
* Add label `bot/question` the the bot will close with standard question message and add label `type/question`
* Add label `bot/duplicate` the the bot will close with standard duplicate message and add label `type/duplicate`
* Add label `bot/needs more info` for bot to request more info (or use comment command mentioned above)
* Add label `bot/close feature request` for bot to close a feature request with standard message and adds label `not implemented`
* Add label `bot/no new info` for bot to close an issue where we asked for more info but has not received any updates in at least 14 days.

View File

@@ -23,6 +23,7 @@
"package.json",
"tsconfig.json",
"lerna.json",
".babelrc",
".prettierrc.js",
".eslintrc",
"**/*.mdx"
@@ -118,7 +119,7 @@
},
{
"type": "changedfiles",
"matches": [ "public/app/plugins/datasource/jaeger/**/*"],
"matches": [ "public/app/plugins/datasource/jaeger"],
"action": "updateLabel",
"addLabel": "datasource/Jaeger"
},
@@ -146,18 +147,6 @@
"action": "updateLabel",
"addLabel": "datasource/OpenTSDB"
},
{
"type": "changedfiles",
"matches": [ "public/app/plugins/datasource/parca/**/*"],
"action": "updateLabel",
"addLabel": "datasource/Parca"
},
{
"type": "changedfiles",
"matches": [ "public/app/plugins/datasource/grafana-pyroscope-datasource/**/*", "pkg/tsdb/grafana-pyroscope-datasource/**/*"],
"action": "updateLabel",
"addLabel": "datasource/grafana-pyroscope"
},
{
"type": "changedfiles",
"matches": [ "public/app/plugins/datasource/grafana-postgresql-datasource/**/*", "pkg/tsdb/grafana-postgresql-datasource/**/*"],

View File

@@ -4,28 +4,21 @@
],
"enabledManagers": ["npm"],
"ignoreDeps": [
"@types/history", // this can be removed entirely when we upgrade history since v5 exposes types directly
"history", // we should bump this together with react-router-dom (see https://github.com/grafana/grafana/issues/76744)
"react-router-dom", // we should bump this together with history (see https://github.com/grafana/grafana/issues/76744)
"loader-utils", // v3 requires upstream changes in ngtemplate-loader. ignore, and remove when we remove angular.
"monaco-editor", // due to us exposing this via @grafana/ui/CodeEditor's props bumping can break plugins
"@fingerprintjs/fingerprintjs", // we don't want to bump to v4 due to licensing changes
"@swc/core", // versions ~1.4.5 contain multiple bugs related to baseUrl resolution breaking builds.
"slate", // we don't want to continue using this on the long run, use Monaco editor instead of Slate
"slate-react", // we don't want to continue using this on the long run, use Monaco editor instead of Slate
"@types/slate-react", // we don't want to continue using this on the long run, use Monaco editor instead of Slate
"@types/slate" // we don't want to continue using this on the long run, use Monaco editor instead of Slate
"react-hook-form", // due to us exposing these hooks via @grafana/ui form components bumping can break plugins
],
"includePaths": ["package.json", "packages/**", "public/app/plugins/**"],
"ignorePaths": ["emails/**", "plugins-bundled/**", "**/mocks/**"],
"ignorePaths": ["emails/**", "plugins-bundled/**", "**/mocks/**", "packages/grafana-e2e/**"],
"labels": ["area/frontend", "dependencies", "no-changelog"],
"postUpdateOptions": ["yarnDedupeHighest"],
"packageRules": [
{
"automerge": true,
"matchCurrentVersion": "!/^0/",
"matchUpdateTypes": ["patch"],
"excludePackagePatterns": ["^@?storybook", "^@locker"]
"excludePackagePatterns": ["^@?storybook", "^@locker"],
"extends": ["schedule:monthly"],
"groupName": "Monthly patch updates"
},
{
"matchPackagePatterns": ["^@?storybook"],

View File

@@ -1,22 +0,0 @@
name: Changelog generator
description: Generates and publishes a changelog for the given release version
inputs:
target:
description: Target tag, branch or commit hash for the changelog
required: true
previous:
description: Previous tag, branch or commit hash to start changelog from
required: false
github_token:
description: GitHub token with read/write access to all necessary repositories
required: true
output_file:
description: A file to store resulting changelog markdown
required: false
outputs:
changelog:
description: Changelog contents between the two given versions in Markdown format
runs:
using: 'node20'
main: 'index.js'

View File

@@ -1,319 +0,0 @@
import { appendFileSync, writeFileSync } from 'fs';
import { exec as execCallback } from 'node:child_process';
import { promisify } from 'node:util';
//
// Github Action core utils: logging (notice + debug log levels), must escape
// newlines and percent signs
//
const escapeData = (s) => s.replace(/%/g, '%25').replace(/\r/g, '%0D').replace(/\n/g, '%0A');
const LOG = (msg) => console.log(`::notice::${escapeData(msg)}`);
//
// Semver utils: parse, compare, sort etc (using official regexp)
// https://regex101.com/r/Ly7O1x/3/
//
const semverRegExp =
/^v?(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$/;
const semverParse = (tag) => {
const m = tag.match(semverRegExp);
if (!m) {
return;
}
const [_, major, minor, patch, prerelease] = m;
return [+major, +minor, +patch, prerelease, tag];
};
// semverCompare takes two parsed semver tags and comparest them more or less
// according to the semver specs
const semverCompare = (a, b) => {
for (let i = 0; i < 3; i++) {
if (a[i] !== b[i]) {
return a[i] < b[i] ? 1 : -1;
}
}
if (a[3] !== b[3]) {
return a[3] < b[3] ? 1 : -1;
}
return 0;
};
// Using `git tag -l` output find the tag (version) that goes semantically
// right before the given version. This might not work correctly with some
// pre-release versions, which is why it's possible to pass previous version
// into this action explicitly to avoid this step.
const getPreviousVersion = async (version) => {
const exec = promisify(execCallback);
const { stdout } = await exec('git tag -l');
const prev = stdout
.split('\n')
.map(semverParse)
.filter((tag) => tag)
.sort(semverCompare)
.find((tag) => semverCompare(tag, semverParse(version)) > 0);
if (!prev) {
throw `Could not find previous git tag for ${version}`;
}
return prev[4];
};
// A helper for Github GraphQL API endpoint
const graphql = async (ghtoken, query, variables) => {
const { env } = process;
const results = await fetch('https://api.github.com/graphql', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
Authorization: `Bearer ${ghtoken}`,
},
body: JSON.stringify({ query, variables }),
});
const { data } = await results.json();
return data;
};
// Using Github GraphQL API find the timestamp for the given tag/commit hash.
// This is required for PR listing, because Github API only takes date/time as
// a "since" parameter while listing. Currently there is no way to provide two
// "commitish" items and get a list of PRs in between them.
const getCommitishDate = async (name, owner, target) => {
const result = await graphql(
ghtoken,
`
query getCommitDate($owner: String!, $name: String!, $target: String!) {
repository(owner: $owner, name: $name) {
object(expression: $target) {
... on Commit {
committedDate
}
}
}
}
`,
{ name, owner, target }
);
return result.repository.object.committedDate;
};
// Using Github GraphQL API get a list of PRs between the two "commitish" items.
// This resoves the "since" item's timestamp first and iterates over all PRs
// till "target" using naïve pagination.
const getHistory = async (name, owner, target, sinceDate) => {
LOG(`Fetching ${owner}/${name} PRs since ${sinceDate} till ${target}`);
const query = `
query findCommitsWithAssociatedPullRequests(
$name: String!
$owner: String!
$target: String!
$sinceDate: GitTimestamp
$cursor: String
) {
repository(name: $name, owner: $owner) {
object(expression: $target) {
... on Commit {
history(first: 50, since: $sinceDate, after: $cursor) {
totalCount
pageInfo {
hasNextPage
endCursor
}
nodes {
id
associatedPullRequests(first: 1) {
nodes {
title
number
labels(first: 10) {
nodes {
name
}
}
commits(first: 1) {
nodes {
commit {
author {
user {
login
}
}
}
}
}
}
}
}
}
}
}
}
}`;
let cursor;
let nodes = [];
for (;;) {
const result = await graphql(ghtoken, query, {
name,
owner,
target,
sinceDate,
cursor,
});
LOG(`GraphQL: ${JSON.stringify(result)}`);
nodes = [...nodes, ...result.repository.object.history.nodes];
const { hasNextPage, endCursor } = result.repository.object.history.pageInfo;
if (!hasNextPage) {
break;
}
cursor = endCursor;
}
return nodes;
};
// The main function for this action: given two "commitish" items it gets a
// list of PRs between them and filters/groups the PRs by category (bugfix,
// feature, deprecation, breaking change and plugin fixes/enhancements).
//
// PR grouping relies on Github labels only, not on the PR contents.
const getChangeLogItems = async (name, owner, sinceDate, to) => {
// check if a node contains a certain label
const hasLabel = ({ labels }, label) => labels.nodes.some(({ name }) => name === label);
// get all the PRs between the two "commitish" items
const history = await getHistory(name, owner, to, sinceDate);
const items = history.flatMap((node) => {
// discard PRs without a "changelog" label
const changes = node.associatedPullRequests.nodes.filter((PR) => hasLabel(PR, 'add to changelog'));
if (changes.length === 0) {
return [];
}
const item = changes[0];
const { number, url, labels } = item;
const title = item.title.replace(/^\[[^\]]+\]:?\s*/, '');
// for changelog PRs try to find a suitable category.
// Note that we can not detect "deprecation notices" like that
// as there is no suitable label yet.
const isBug = /fix/i.test(title) || hasLabel({ labels }, 'type/bug');
const isBreaking = hasLabel({ labels }, 'breaking change');
const isPlugin =
hasLabel({ labels }, 'area/grafana/ui') ||
hasLabel({ labels }, 'area/grafana/toolkit') ||
hasLabel({ labels }, 'area/grafana/runtime');
const author = item.commits.nodes[0].commit.author.user.login;
return {
repo: name,
number,
title,
author,
isBug,
isPlugin,
isBreaking,
};
});
return items;
};
// ======================================================
// GENERATE CHANGELOG
// ======================================================
LOG(`Changelog action started`);
const ghtoken = process.env.GITHUB_TOKEN || process.env.INPUT_GITHUB_TOKEN;
if (!ghtoken) {
throw 'GITHUB_TOKEN is not set and "github_token" input is empty';
}
const target = process.argv[2] || process.env.INPUT_TARGET;
LOG(`Target tag/branch/commit: ${target}`);
const previous = process.argv[3] || process.env.INPUT_PREVIOUS || (await getPreviousVersion(target));
LOG(`Previous tag/commit: ${previous}`);
const sinceDate = await getCommitishDate('grafana', 'grafana', previous);
LOG(`Previous tag/commit timestamp: ${sinceDate}`);
// Get all changelog items from Grafana OSS
const oss = await getChangeLogItems('grafana', 'grafana', sinceDate, target);
// Get all changelog items from Grafana Enterprise
const entr = await getChangeLogItems('grafana-enterprise', 'grafana', sinceDate, target);
LOG(`Found OSS PRs: ${oss.length}`);
LOG(`Found Enterprise PRs: ${entr.length}`);
// Sort PRs and categorise them into sections
const changelog = [...oss, ...entr]
.sort((a, b) => (a.title < b.title ? -1 : 1))
.reduce(
(changelog, item) => {
if (item.isPlugin) {
changelog.plugins.push(item);
} else if (item.isBug) {
changelog.bugfixes.push(item);
} else if (item.isBreaking) {
changelog.breaking.push(item);
} else {
changelog.features.push(item);
}
return changelog;
},
{
breaking: [],
plugins: [],
bugfixes: [],
features: [],
}
);
// Convert PR numbers to Github links
const pullRequestLink = (n) => `[#${n}](https://github.com/grafana/grafana/pull/${n})`;
// Convert Github user IDs to Github links
const userLink = (u) => `[@${u}](https://github.com/${u})`;
// Now that we have a changelog - we can render some markdown as an output
const markdown = (changelog) => {
// This convers a list of changelog items into a markdown section with a list of titles/links
const section = (title, items) =>
items.length === 0
? ''
: `### ${title}
${items
.map(
(item) =>
`- ${item.title.replace(/^([^:]*:)/gm, '**$1**')} ${
item.repo === 'grafana-enterprise'
? '(Enterprise)'
: `${pullRequestLink(item.number)}, ${userLink(item.author)}`
}`
)
.join('\n')}
`;
// Render all present sections for the given changelog
return `${section('Features and enhancements', changelog.features)}
${section('Bug fixes', changelog.bugfixes)}
${section('Breaking changes', changelog.breaking)}
${section('Plugin development fixes & changes', changelog.plugins)}
`;
};
const md = markdown(changelog);
// Print changelog, mostly for debugging
LOG(`Resulting markdown: ${md}`);
// Save changelog as an output for this action
if (process.env.GITHUB_OUTPUT) {
LOG(`Output to ${process.env.GITHUB_OUTPUT}`);
appendFileSync(process.env.GITHUB_OUTPUT, `changelog<<EOF\n${escapeData(md)}\nEOF`);
} else {
LOG('GITHUB_OUTPUT is not set');
}
// Save changelog as an output file (if requested)
if (process.env.INPUT_OUTPUT_FILE) {
LOG(`Output to ${process.env.INPUT_OUTPUT_FILE}`);
writeFileSync(process.env.INPUT_OUTPUT_FILE, md);
}

View File

@@ -16,7 +16,7 @@ jobs:
- name: Set go version
uses: actions/setup-go@v4
with:
go-version-file: go.mod
go-version: '1.21.5'
- name: Build swagger
run: |
make -C pkg/services/ngalert/api/tooling post.json api.json
@@ -32,6 +32,6 @@ jobs:
branch: update-alerting-swagger-spec
delete-branch: true
labels: 'area/alerting,type/docs,no-changelog'
team-reviewers: 'grafana/alerting-backend'
team-reviewers: 'grafana/alerting-backend-product'
draft: false

View File

@@ -5,39 +5,74 @@ on:
version:
description: 'Needs to match, exactly, the name of a milestone. The version to be released please respect: major.minor.patch, major.minor.patch-preview or major.minor.patch-preview<number> format. example: 7.4.3, 7.4.3-preview or 7.4.3-preview1'
required: true
push:
default: true
required: false
dry_run:
default: false
required: false
env:
YARN_ENABLE_IMMUTABLE_INSTALLS: false
jobs:
main:
runs-on: ubuntu-latest
steps:
- name: Checkout Grafana
uses: actions/checkout@v4
- name: Update package.json versions
uses: ./pkg/build/actions/bump-version
# This is a basic workflow to help you get started with Actions
- uses: actions-ecosystem/action-regex-match@v2.0.2
if: ${{ github.event.inputs.version != '' }}
id: regex-match
with:
version: ${{ inputs.version }}
- if: ${{ inputs.push }}
name: Generate token
text: ${{ github.event.inputs.version }}
regex: '^(\d+.\d+).\d+(?:-(?:(preview\d?)|(pre)))?$'
- uses: actions-ecosystem/action-regex-match@v2.0.2
if: ${{ inputs.version_call != '' }}
id: regex-match-version-call
with:
text: ${{ inputs.version_call }}
regex: '^(\d+.\d+).\d+(?:-(?:(preview\d?)|(pre)))?$'
- name: Validate input version
if: ${{ steps.regex-match.outputs.match == '' && github.event.inputs.version != '' }}
run: |
echo "The input version format is not correct, please respect:\
major.minor.patch, major.minor.patch-preview or major.minor.patch-preview<number> format. \
example: 7.4.3, 7.4.3-preview or 7.4.3-preview1"
exit 1
- name: Validate input version call
if: ${{ inputs.version_call != '' && steps.regex-match-version-call.outputs.match == '' }}
run: |
echo "The input version format is not correct, please respect:\
major.minor.patch, major.minor.patch-preview or major.minor.patch-preview<number> format. \
example: 7.4.3, 7.4.3-preview or 7.4.3-preview1"
exit 1
- uses: actions/checkout@v4
- name: Set intermedia variables
id: intermedia
run: |
echo "short_ref=${GITHUB_REF#refs/*/}" >> $GITHUB_OUTPUT
echo "check_passed=false" >> $GITHUB_OUTPUT
echo "branch_name=v${{steps.regex-match.outputs.group1}}" >> $GITHUB_OUTPUT
echo "branch_exist=$(git ls-remote --heads https://github.com/grafana/grafana.git v${{ steps.regex-match.outputs.group1 }}.x | wc -l)" >> $GITHUB_OUTPUT
- name: Checkout Actions
uses: actions/checkout@v4
with:
repository: "grafana/grafana-github-actions"
path: ./actions
ref: main
# Go is required for also updating the schema versions as part of the precommit hook:
- uses: actions/setup-go@v4
with:
go-version: '1.20'
- uses: actions/setup-node@v4
with:
node-version: '16'
- name: Install Actions
run: npm install --production --prefix ./actions
- name: "Generate token"
id: generate_token
uses: tibdex/github-app-token@b62528385c34dbc9f38e5f4225ac829252d1ea92
with:
app_id: ${{ secrets.GRAFANA_DELIVERY_BOT_APP_ID }}
private_key: ${{ secrets.GRAFANA_DELIVERY_BOT_APP_PEM }}
- if: ${{ inputs.push }}
name: Push & Create PR
run: |
git config --local user.name "github-actions[bot]"
git config --local user.email "github-actions[bot]@users.noreply.github.com"
git config --local --add --bool push.autoSetupRemote true
git checkout -b "bump-version/${{ github.run_id }}/${{ inputs.version }}"
git add .
git commit -m "bump version ${{ inputs.version }}"
git push
gh pr create --dry-run=${{ inputs.dry_run }} -l "type/ci" -l "no-changelog" -B "${{ github.ref_name }}" --title "Release: Bump version to ${{ inputs.version }}" --body "Updated version to ${{ inputs.version }}"
env:
GH_TOKEN: ${{ steps.generate_token.outputs.token }}
- name: Run bump version (manually invoked)
uses: ./actions/bump-version
with:
token: ${{ steps.generate_token.outputs.token }}
metricsWriteAPIKey: ${{ secrets.GRAFANA_MISC_STATS_API_KEY }}
precommit_make_target: gen-cue

View File

@@ -1,130 +0,0 @@
name: Generate changelog
on:
workflow_call:
inputs:
version:
type: string
required: true
description: 'Target release version (semver, git tag, branch or commit)'
target:
required: true
type: string
description: 'The base branch that these changes are being merged into'
dry_run:
required: false
default: false
type: boolean
latest:
required: false
default: false
type: boolean
secrets:
GRAFANA_DELIVERY_BOT_APP_ID:
required: true
GRAFANA_DELIVERY_BOT_APP_PEM:
required: true
workflow_dispatch:
inputs:
version:
type: string
required: true
description: 'Target release version (semver, git tag, branch or commit)'
target:
required: true
type: string
description: 'The base branch that these changes are being merged into'
dry_run:
required: false
default: false
type: boolean
latest:
required: false
default: false
type: boolean
permissions:
contents: write
pull-requests: write
jobs:
main:
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- name: "Generate token"
id: generate_token
uses: tibdex/github-app-token@b62528385c34dbc9f38e5f4225ac829252d1ea92
with:
app_id: ${{ secrets.GRAFANA_DELIVERY_BOT_APP_ID }}
private_key: ${{ secrets.GRAFANA_DELIVERY_BOT_APP_PEM }}
- name: "Checkout Grafana repo"
uses: "actions/checkout@v4"
with:
ref: main
sparse-checkout: |
.github/workflows
CHANGELOG.md
fetch-depth: 0
fetch-tags: true
- name: "Configure git user"
run: |
git config --local user.name "github-actions[bot]"
git config --local user.email "github-actions[bot]@users.noreply.github.com"
git config --local --add --bool push.autoSetupRemote true
- name: "Create branch"
run: git checkout -b "changelog/${{ github.run_id }}/${{ inputs.version }}"
- name: "Generate changelog"
id: changelog
uses: ./.github/workflows/actions/changelog
with:
github_token: ${{ steps.generate_token.outputs.token }}
target: v${{ inputs.version }}
output_file: changelog_items.md
- name: "Patch CHANGELOG.md"
run: |
# Prepare CHANGELOG.md content with version delimiters
(
echo
echo "# ${{ inputs.version}} ($(date '+%F'))"
echo
cat changelog_items.md
) > CHANGELOG.part
# Check if a version exists in the changelog
if grep -q "<!-- ${{ inputs.version}} START" CHANGELOG.md ; then
# Replace the content between START and END delimiters
echo "Version ${{ inputs.version }} is found in the CHANGELOG.md, patching contents..."
sed -i -e '/${{ inputs.version }} START/,/${{ inputs.version }} END/{//!d;}' \
-e '/${{ inputs.version }} START/r CHANGELOG.part' CHANGELOG.md
else
# Prepend changelog part to the main changelog file
echo "Version ${{ inputs.version }} not found in the CHANGELOG.md"
(
echo "<!-- ${{ inputs.version }} START -->"
cat CHANGELOG.part
echo "<!-- ${{ inputs.version }} END -->"
cat CHANGELOG.md
) > CHANGELOG.tmp
mv CHANGELOG.tmp CHANGELOG.md
fi
git diff CHANGELOG.md
git add CHANGELOG.md
- name: "Commit changelog changes"
run: git commit --allow-empty -m "Update changelog" CHANGELOG.md
- name: "git push"
if: ${{ inputs.dry_run }} != true
run: git push
- name: "Create changelog PR"
run: >
gh pr create \
--dry-run=${{ inputs.dry_run }} \
--label "no-backport" \
--label "no-changelog" \
-B "${{ inputs.target }}" \
--title "Release: update changelog for ${{ inputs.version }}" \
--body "Changelog changes for release ${{ inputs.version }}"
env:
GH_TOKEN: ${{ steps.generate_token.outputs.token }}

View File

@@ -25,7 +25,6 @@ jobs:
analyze:
name: Analyze
runs-on: ubuntu-latest
if: github.repository == 'grafana/grafana'
strategy:
fail-fast: false
@@ -48,7 +47,7 @@ jobs:
name: Set go version
uses: actions/setup-go@v4
with:
go-version-file: go.mod
go-version: '1.21.5'
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL

View File

@@ -1,46 +1,25 @@
name: Create community release post
on:
workflow_call:
inputs:
version:
type: string
required: true
description: 'Needs to match, exactly, the name of a milestone. The version to be released please respect: major.minor.patch, major.minor.patch-preview or major.minor.patch-preview<number> format. example: 7.4.3, 7.4.3-preview or 7.4.3-preview1'
dry_run:
type: boolean
required: false
default: false
description: When enabled, this workflow will print a preview instead of creating an actual post.
secrets:
GRAFANA_MISC_STATS_API_KEY:
required: true
GRAFANABOT_FORUM_KEY:
required: true
workflow_dispatch:
inputs:
version:
type: string
required: true
description: 'Needs to match, exactly, the name of a milestone. The version to be released please respect: major.minor.patch, major.minor.patch-preview or major.minor.patch-preview<number> format. example: 7.4.3, 7.4.3-preview or 7.4.3-preview1'
dry_run:
type: boolean
required: false
default: false
description: When enabled, this workflow will print a preview instead of creating an actual post.
permissions:
contents: read
jobs:
main:
runs-on: ubuntu-latest
steps:
- name: "Generate token"
id: generate_token
uses: tibdex/github-app-token@b62528385c34dbc9f38e5f4225ac829252d1ea92
with:
app_id: ${{ secrets.GRAFANA_DELIVERY_BOT_APP_ID }}
private_key: ${{ secrets.GRAFANA_DELIVERY_BOT_APP_PEM }}
- name: Run community-release (manually invoked)
uses: grafana/grafana-github-actions-go/community-release@main
with:
token: ${{ secrets.GITHUB_TOKEN }}
token: ${{ steps.generate_token.outputs.token }}
version: ${{ inputs.version }}
metrics_api_key: ${{ secrets.GRAFANA_MISC_STATS_API_KEY }}
community_api_key: ${{ secrets.GRAFANABOT_FORUM_KEY }}
community_api_username: grafanabot
dry_run: ${{ inputs.dry_run }}

View File

@@ -1,5 +1,3 @@
name: Build and release core plugins
on:
workflow_dispatch:
inputs:
@@ -8,14 +6,7 @@ on:
required: true
type: choice
options:
- grafana-azure-monitor-datasource
- grafana-pyroscope-datasource
- grafana-testdata-datasource
- jaeger
- parca
- stackdriver
- tempo
- zipkin
concurrency:
group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}-${{ inputs.plugin_id }}
@@ -58,7 +49,7 @@ jobs:
with:
credentials_json: '${{ env.PLUGINS_GOOGLE_CREDENTIALS }}'
- name: 'Set up Cloud SDK'
uses: 'google-github-actions/setup-gcloud@v2'
uses: 'google-github-actions/setup-gcloud@v1'
- name: Setup nodejs environment
uses: actions/setup-node@v4
with:
@@ -68,12 +59,7 @@ jobs:
shell: bash
id: get_dir
run: |
dir=$(dirname \
$(egrep -lir --include=plugin.json --exclude-dir=dist \
'"id": "${{ inputs.plugin_id }}"' \
public/app/plugins \
) \
)
dir=$(find public/app/plugins -name ${{ inputs.plugin_id }} -print -quit)
echo "dir=${dir}" >> $GITHUB_OUTPUT
- name: Install frontend dependencies
shell: bash
@@ -91,7 +77,7 @@ jobs:
id: check_backend
shell: bash
run: |
if egrep -qr --include=main.go 'datasource.Manage\("${{ inputs.plugin_id }}"' pkg/tsdb; then
if [ -d ./pkg/tsdb/${{ inputs.plugin_id }} ]; then
echo "has_backend=true" >> $GITHUB_OUTPUT
else
echo "has_backend=false" >> $GITHUB_OUTPUT
@@ -186,7 +172,7 @@ jobs:
exit 1
fi
- name: store build artifacts
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v3
with:
name: build-artifacts
path: ${{ steps.get_dir.outputs.dir }}/ci/packages/*.zip
@@ -202,7 +188,6 @@ jobs:
gsutil -m cp -r ci/packages/*darwin* gs://${{ env.GCP_BUCKET }}/${{ inputs.plugin_id }}/release/${VERSION}/darwin
gsutil -m cp -r ci/packages/*any* gs://${{ env.GCP_BUCKET }}/${{ inputs.plugin_id }}/release/${VERSION}/any
- name: Publish new plugin version on grafana.com
if: steps.check_backend.outputs.has_backend == 'true'
working-directory: ${{ steps.get_dir.outputs.dir }}
env:
GCOM_TOKEN: ${{ env.PLUGINS_GCOM_TOKEN }}
@@ -243,27 +228,4 @@ jobs:
echo "Failed to publish plugin version. Got:"
echo $result
exit 1
fi
- name: Publish new plugin version on grafana.com (frontend only)
if: steps.check_backend.outputs.has_backend == 'false'
working-directory: ${{ steps.get_dir.outputs.dir }}
env:
GCOM_TOKEN: ${{ env.PLUGINS_GCOM_TOKEN }}
VERSION: ${{ steps.build_frontend.outputs.version }}
run: |
echo "Publish new plugin version on grafana.com:"
echo "Plugin version: ${VERSION}"
result=`curl -H "Authorization: Bearer $GCOM_TOKEN" -H "Content-Type: application/json" ${{ env.GCOM_API}}/api/plugins -d "{
\"url\": \"https://github.com/grafana/grafana/tree/main/${{ steps.get_dir.outputs.dir }}\",
\"download\": {
\"any\": {
\"url\": \"https://storage.googleapis.com/${{ env.GCP_BUCKET }}/${{ inputs.plugin_id }}/release/${VERSION}/any/${{ inputs.plugin_id }}-${VERSION}.any.zip\",
\"md5\": \"$(cat ci/packages/info-any.json | jq -r .plugin.md5)\"
}
}
}"`
if [[ "$(echo $result | jq -r .version)" == "null" ]]; then
echo "Failed to publish plugin version. Got:"
echo $result
exit 1
fi
fi

View File

@@ -1,5 +1,5 @@
# Owned by grafana-release-guild
# Intended to be dropped into the base repo (Ex: grafana/grafana) for use in the security mirror.
# Owned by grafana-delivery-squad
# Intended to be dropped into the base repo (Ex: grafana/grafana) for use in the security mirror.
name: Create security patch
run-name: create-security-patch
on:
@@ -17,7 +17,7 @@ jobs:
trigger_downstream_create_security_patch:
concurrency: create-patch-${{ github.ref_name }}
uses: grafana/security-patch-actions/.github/workflows/create-patch.yml@main
if: github.repository == 'grafana/grafana-security-mirror'
if: github.repository == 'grafana/grafana-security-mirror'
with:
repo: "${{ github.repository }}"
src_ref: "${{ github.head_ref }}" # this is the source branch name, Ex: "feature/newthing"

View File

@@ -0,0 +1,34 @@
# Workflow for skipping the Levitate detection
# (This is needed because workflows that are skipped due to path filtering will show up as pending in Github.
# As this has the same name as the one in detect-breaking-changes-build.yml it will take over in these cases and succeed quickly.)
name: Levitate / Detect breaking changes
on:
pull_request:
paths-ignore:
- "packages/**"
branches:
- 'main'
jobs:
detect:
name: Detect breaking changes
runs-on: ubuntu-latest
steps:
- name: Skipping
run: echo "No modifications in the public API (packages/), skipping."
# Build and persist output as a JSON (we need to tell the report workflow that the check has been skipped)
- name: Persisting the check output
run: |
mkdir -p ./levitate
echo "{ \"shouldSkip\": true }" > ./levitate/result.json
# Upload artifact (so it can be used in the more privileged "report" workflow)
- name: Upload check output as artifact
uses: actions/upload-artifact@v3
with:
name: levitate
path: levitate/

View File

@@ -0,0 +1,163 @@
# Only runs if anything under the packages/ directory changes.
# (Otherwise detect-breaking-changes-build-skip.yml takes over)
name: Levitate / Detect breaking changes
on:
pull_request:
paths:
- 'packages/**'
branches:
- 'main'
jobs:
buildPR:
name: Build PR
runs-on: ubuntu-latest
defaults:
run:
working-directory: './pr'
steps:
- uses: actions/checkout@v4
with:
path: './pr'
- uses: actions/setup-node@v4
with:
node-version: 20.9.0
- name: Get yarn cache directory path
id: yarn-cache-dir-path
run: echo "dir=$(yarn config get cacheFolder)" >> $GITHUB_OUTPUT
- name: Restore yarn cache
uses: actions/cache@v3.3.1
id: yarn-cache
with:
path: ${{ steps.yarn-cache-dir-path.outputs.dir }}
key: yarn-cache-folder-${{ hashFiles('**/yarn.lock', '.yarnrc.yml') }}
restore-keys: |
yarn-cache-folder-
- name: Install dependencies
run: yarn install --immutable
- name: Build packages
run: yarn packages:build
- name: Pack packages
run: yarn packages:pack --out ./%s.tgz
- name: Zip built tarballed packages
run: zip -r ./pr_built_packages.zip ./packages/**/*.tgz
- name: Upload build output as artifact
uses: actions/upload-artifact@v3
with:
name: buildPr
path: './pr/pr_built_packages.zip'
buildBase:
name: Build Base
runs-on: ubuntu-latest
defaults:
run:
working-directory: './base'
steps:
- uses: actions/checkout@v4
with:
path: './base'
ref: ${{ github.event.pull_request.base.ref }}
- uses: actions/setup-node@v4
with:
node-version: 20.9.0
- name: Get yarn cache directory path
id: yarn-cache-dir-path
run: echo "dir=$(yarn config get cacheFolder)" >> $GITHUB_OUTPUT
- name: Restore yarn cache
uses: actions/cache@v3.3.1
id: yarn-cache
with:
path: ${{ steps.yarn-cache-dir-path.outputs.dir }}
key: yarn-cache-folder-${{ hashFiles('**/yarn.lock', '.yarnrc.yml') }}
restore-keys: |
yarn-cache-folder-
- name: Install dependencies
run: yarn install --immutable
- name: Build packages
run: yarn packages:build
- name: Pack packages
run: yarn packages:pack --out ./%s.tgz
- name: Zip built tarballed packages
run: zip -r ./base_built_packages.zip ./packages/**/*.tgz
- name: Upload build output as artifact
uses: actions/upload-artifact@v3
with:
name: buildBase
path: './base/base_built_packages.zip'
Detect:
name: Detect breaking changes
runs-on: ubuntu-latest
needs: ['buildPR', 'buildBase']
env:
GITHUB_STEP_NUMBER: 8
steps:
- uses: actions/checkout@v4
- name: Get built packages from pr
uses: actions/download-artifact@v3
with:
name: buildPr
- name: Get built packages from base
uses: actions/download-artifact@v3
with:
name: buildBase
- name: Unzip artifact from pr
run: unzip -j pr_built_packages.zip -d ./pr && rm pr_built_packages.zip
- name: Unzip artifact from base
run: unzip -j base_built_packages.zip -d ./base && rm base_built_packages.zip
- name: Get link for the Github Action job
id: job
uses: actions/github-script@v6
with:
script: |
const name = 'Detect breaking changes';
const script = require('./.github/workflows/scripts/pr-get-job-link.js')
await script({name, github, context, core})
- name: Detect breaking changes
id: breaking-changes
run: ./scripts/check-breaking-changes.sh
env:
FORCE_COLOR: 3
GITHUB_JOB_LINK: ${{ steps.job.outputs.link }}
- name: Persisting the check output
run: |
mkdir -p ./levitate
echo "{ \"exit_code\": ${{ steps.breaking-changes.outputs.is_breaking }}, \"message\": \"${{ steps.breaking-changes.outputs.message }}\", \"job_link\": \"${{ steps.job.outputs.link }}#step:${GITHUB_STEP_NUMBER}:1\", \"pr_number\": \"${{ github.event.pull_request.number }}\" }" > ./levitate/result.json
- name: Upload check output as artifact
uses: actions/upload-artifact@v3
with:
name: levitate
path: levitate/
- name: Exit
run: exit ${{ steps.breaking-changes.outputs.is_breaking }}
shell: bash

View File

@@ -1,340 +0,0 @@
# Only runs if anything under the packages/ directory changes.
---
name: Levitate / Detect breaking changes in PR
on:
pull_request:
paths:
- 'packages/**'
branches:
- 'main'
jobs:
buildPR:
name: Build PR
runs-on: ubuntu-latest
defaults:
run:
working-directory: './pr'
steps:
- uses: actions/checkout@v4
with:
path: './pr'
- uses: actions/setup-node@v4
with:
node-version: 20.9.0
- name: Get yarn cache directory path
id: yarn-cache-dir-path
run: echo "dir=$(yarn config get cacheFolder)" >> $GITHUB_OUTPUT
- name: Restore yarn cache
uses: actions/cache@v4
id: yarn-cache
with:
path: ${{ steps.yarn-cache-dir-path.outputs.dir }}
key: yarn-cache-folder-${{ hashFiles('**/yarn.lock', '.yarnrc.yml') }}
restore-keys: |
yarn-cache-folder-
- name: Install dependencies
run: yarn install --immutable
- name: Build packages
run: yarn packages:build
- name: Pack packages
run: yarn packages:pack --out ./%s.tgz
- name: Zip built tarballed packages
run: zip -r ./pr_built_packages.zip ./packages/**/*.tgz
- name: Upload build output as artifact
uses: actions/upload-artifact@v4
with:
name: buildPr
path: './pr/pr_built_packages.zip'
buildBase:
name: Build Base
runs-on: ubuntu-latest
defaults:
run:
working-directory: './base'
steps:
- uses: actions/checkout@v4
with:
path: './base'
ref: ${{ github.event.pull_request.base.ref }}
- uses: actions/setup-node@v4
with:
node-version: 20.9.0
- name: Get yarn cache directory path
id: yarn-cache-dir-path
run: echo "dir=$(yarn config get cacheFolder)" >> $GITHUB_OUTPUT
- name: Restore yarn cache
uses: actions/cache@v4
id: yarn-cache
with:
path: ${{ steps.yarn-cache-dir-path.outputs.dir }}
key: yarn-cache-folder-${{ hashFiles('**/yarn.lock', '.yarnrc.yml') }}
restore-keys: |
yarn-cache-folder-
- name: Install dependencies
run: yarn install --immutable
- name: Build packages
run: yarn packages:build
- name: Pack packages
run: yarn packages:pack --out ./%s.tgz
- name: Zip built tarballed packages
run: zip -r ./base_built_packages.zip ./packages/**/*.tgz
- name: Upload build output as artifact
uses: actions/upload-artifact@v4
with:
name: buildBase
path: './base/base_built_packages.zip'
Detect:
name: Detect breaking changes
runs-on: ubuntu-latest
needs: ['buildPR', 'buildBase']
env:
GITHUB_STEP_NUMBER: 8
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 20.9.0
- name: Get built packages from pr
uses: actions/download-artifact@v4
with:
name: buildPr
- name: Get built packages from base
uses: actions/download-artifact@v4
with:
name: buildBase
- name: Unzip artifact from pr
run: unzip -j pr_built_packages.zip -d ./pr && rm pr_built_packages.zip
- name: Unzip artifact from base
run: unzip -j base_built_packages.zip -d ./base && rm base_built_packages.zip
- name: Get link for the Github Action job
id: job
uses: actions/github-script@v6
with:
script: |
const name = 'Detect breaking changes';
const script = require('./.github/workflows/scripts/pr-get-job-link.js')
await script({name, github, context, core})
- name: Detect breaking changes
id: breaking-changes
run: ./scripts/check-breaking-changes.sh
env:
FORCE_COLOR: 3
GITHUB_JOB_LINK: ${{ steps.job.outputs.link }}
- name: Persisting the check output
run: |
mkdir -p ./levitate
echo "{ \"exit_code\": ${{ steps.breaking-changes.outputs.is_breaking }}, \"message\": \"${{ steps.breaking-changes.outputs.message }}\", \"job_link\": \"${{ steps.job.outputs.link }}#step:${GITHUB_STEP_NUMBER}:1\", \"pr_number\": \"${{ github.event.pull_request.number }}\" }" > ./levitate/result.json
- name: Upload check output as artifact
uses: actions/upload-artifact@v4
with:
name: levitate
path: levitate/
Report:
name: Report breaking changes in PR
runs-on: ubuntu-latest
needs: ['Detect']
steps:
- name: "Generate token"
id: generate_token
uses: tibdex/github-app-token@b62528385c34dbc9f38e5f4225ac829252d1ea92
with:
app_id: ${{ secrets.GRAFANA_PR_AUTOMATION_APP_ID }}
private_key: ${{ secrets.GRAFANA_PR_AUTOMATION_APP_PEM }}
- uses: actions/checkout@v4
- name: 'Download artifact'
uses: actions/download-artifact@v4
with:
name: levitate
- name: Parsing levitate result
uses: actions/github-script@v6
id: levitate-run
with:
script: |
const filePath = 'result.json';
const script = require('./.github/workflows/scripts/json-file-to-job-output.js');
await script({ core, filePath });
# Check if label exists
- name: Check if "levitate breaking change" label exists
id: does-label-exist
uses: actions/github-script@v6
env:
PR_NUMBER: ${{ github.event.pull_request.number }}
with:
script: |
const { data } = await github.rest.issues.listLabelsOnIssue({
issue_number: process.env.PR_NUMBER,
owner: context.repo.owner,
repo: context.repo.repo,
});
const labels = data.map(({ name }) => name);
const doesExist = labels.includes('levitate breaking change');
return doesExist ? 1 : 0;
# put the markdown into a variable
- name: Levitate Markdown
id: levitate-markdown
run: |
if [ -f "levitate.md" ]; then
{
echo 'levitate_markdown<<EOF'
cat levitate.md
echo EOF
} >> $GITHUB_OUTPUT
else
echo "levitate_markdown=No breaking changes detected" >> $GITHUB_OUTPUT
fi
# Comment on the PR
- name: Comment on PR
if: steps.levitate-run.outputs.exit_code == 1
uses: marocchino/sticky-pull-request-comment@v2
with:
header: levitate-breaking-change-comment
number: ${{ github.event.pull_request.number }}
message: |
⚠️ &nbsp;&nbsp;**Possible breaking changes (md version)**&nbsp;&nbsp; ⚠️
${{ steps.levitate-markdown.outputs.levitate_markdown }}
[Read our guideline](https://github.com/grafana/grafana/blob/main/contribute/breaking-changes-guide/breaking-changes-guide.md)
[Console output](${{ steps.levitate-run.outputs.job_link }})
GITHUB_TOKEN: ${{ steps.generate_token.outputs.token }}
# Remove comment from the PR (no more breaking changes)
- name: Remove comment from PR
if: steps.levitate-run.outputs.exit_code == 0
uses: marocchino/sticky-pull-request-comment@v2
with:
header: levitate-breaking-change-comment
number: ${{ github.event.pull_request.number }}
delete: true
GITHUB_TOKEN: ${{ steps.generate_token.outputs.token }}
# Posts a notification to Slack if a PR has a breaking change and it did not have a breaking change before
- name: Post to Slack
id: slack
if: steps.levitate-run.outputs.exit_code == 1 && steps.does-label-exist.outputs.result == 0 && env.HAS_SECRETS
uses: slackapi/slack-github-action@v1.26.0
with:
payload: |
{
"pr_link": "https://github.com/grafana/grafana/pull/${{ steps.levitate-run.outputs.pr_number }}",
"pr_number": "${{ steps.levitate-run.outputs.pr_number }}",
"job_link": "${{ steps.levitate-run.outputs.job_link }}",
"reporting_job_link": "${{ github.event.workflow_run.html_url }}",
"message": "${{ steps.levitate-run.outputs.message }}"
}
env:
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_LEVITATE_WEBHOOK_URL }}
HAS_SECRETS: ${{ (github.repository == 'grafana/grafana' || secrets.SLACK_LEVITATE_WEBHOOK_URL != '') || '' }}
# Add the label
- name: Add "levitate breaking change" label
if: steps.levitate-run.outputs.exit_code == 1 && steps.does-label-exist.outputs.result == 0
uses: actions/github-script@v6
env:
PR_NUMBER: ${{ steps.levitate-run.outputs.pr_number }}
with:
github-token: ${{ steps.generate_token.outputs.token }}
script: |
await github.rest.issues.addLabels({
issue_number: process.env.PR_NUMBER,
owner: context.repo.owner,
repo: context.repo.repo,
labels: ['levitate breaking change']
})
# Remove label (no more breaking changes)
- name: Remove "levitate breaking change" label
if: steps.levitate-run.outputs.exit_code == 0 && steps.does-label-exist.outputs.result == 1
uses: actions/github-script@v6
env:
PR_NUMBER: ${{ steps.levitate-run.outputs.pr_number }}
with:
github-token: ${{ steps.generate_token.outputs.token }}
script: |
await github.rest.issues.removeLabel({
issue_number: process.env.PR_NUMBER,
owner: context.repo.owner,
repo: context.repo.repo,
name: 'levitate breaking change'
})
# Add reviewers
# This is very weird, the actual request goes through (comes back with a 201), but does not assign the team.
# Related issue: https://github.com/renovatebot/renovate/issues/1908
- name: Add "grafana/plugins-platform-frontend" as a reviewer
if: steps.levitate-run.outputs.exit_code == 1
uses: actions/github-script@v6
env:
PR_NUMBER: ${{ steps.levitate-run.outputs.pr_number }}
with:
github-token: ${{ steps.generate_token.outputs.token }}
script: |
await github.rest.pulls.requestReviewers({
pull_number: process.env.PR_NUMBER,
owner: context.repo.owner,
repo: context.repo.repo,
reviewers: [],
team_reviewers: ['plugins-platform-frontend']
});
# Remove reviewers (no more breaking changes)
- name: Remove "grafana/plugins-platform-frontend" from the list of reviewers
if: steps.levitate-run.outputs.exit_code == 0
uses: actions/github-script@v6
env:
PR_NUMBER: ${{ steps.levitate-run.outputs.pr_number }}
with:
github-token: ${{ steps.generate_token.outputs.token }}
script: |
await github.rest.pulls.removeRequestedReviewers({
pull_number: process.env.PR_NUMBER,
owner: context.repo.owner,
repo: context.repo.repo,
reviewers: [],
team_reviewers: ['plugins-platform-frontend']
});
- name: Exit
run: exit ${{ steps.levitate-run.outputs.exit_code }}
shell: bash

View File

@@ -0,0 +1,209 @@
name: Levitate / Report breaking changes
on:
workflow_run:
workflows: ["Levitate / Detect breaking changes"]
types: [completed]
permissions:
pull-requests: write
jobs:
notify:
name: Report
runs-on: ubuntu-latest
env:
ARTIFACT_NAME: 'levitate' # The name of the artifact that we would like to download
ARTIFACT_FOLDER: '${{ github.workspace }}/tmp' # The name of the folder where we will download the artifact to
permissions:
contents: read
issues: write
pull-requests: write
steps:
- uses: actions/checkout@v4
# Download artifact (as a .zip archive)
- name: 'Download artifact'
uses: actions/github-script@v6
env:
RUN_ID: ${{ github.event.workflow_run.id }}
with:
script: |
const fs = require('fs');
const { owner, repo } = context.repo;
const runId = process.env.RUN_ID;
const artifactName = process.env.ARTIFACT_NAME;
const artifactFolder = process.env.ARTIFACT_FOLDER;
const artifacts = await github.rest.actions.listWorkflowRunArtifacts({
owner,
repo,
run_id: runId,
});
const artifact = artifacts.data.artifacts.find(a => a.name === artifactName);
if (!artifact) {
throw new Error(`Could not find artifact ${ artifactName } in workflow (${ runId })`);
}
const download = await github.rest.actions.downloadArtifact({
owner,
repo,
artifact_id: artifact.id,
archive_format: 'zip',
});
fs.mkdirSync(artifactFolder, { recursive: true });
fs.writeFileSync(`${ artifactFolder }/${ artifactName }.zip`, Buffer.from(download.data));
# Unzip artifact
- name: Unzip artifact
run: unzip "${ARTIFACT_FOLDER}/${ARTIFACT_NAME}.zip" -d "${ARTIFACT_FOLDER}"
# Parse the artifact and register fields as step output variables
# (All fields in the JSON will be available as ${{ steps.levitate-run.outputs.<field-name> }}
- name: Parsing levitate result
uses: actions/github-script@v6
id: levitate-run
with:
script: |
const filePath = `${ process.env.ARTIFACT_FOLDER }/result.json`;
const script = require('./.github/workflows/scripts/json-file-to-job-output.js');
await script({ core, filePath });
# Skip - print a message if the "Detect" workflow was skipped
- name: Check if the workflow should be skipped
if: steps.levitate-run.outputs.shouldSkip == 'true'
run: echo "Skipping."
# Check if label exists
- name: Check if "levitate breaking change" label exists
id: does-label-exist
if: steps.levitate-run.outputs.shouldSkip != 'true'
uses: actions/github-script@v6
env:
PR_NUMBER: ${{ github.event.workflow_run.pull_requests[0].number }}
with:
script: |
const { data } = await github.rest.issues.listLabelsOnIssue({
issue_number: process.env.PR_NUMBER,
owner: context.repo.owner,
repo: context.repo.repo,
});
const labels = data.map(({ name }) => name);
const doesExist = labels.includes('levitate breaking change');
return doesExist ? 1 : 0;
# Comment on the PR
- name: Comment on PR
if: steps.levitate-run.outputs.exit_code == 1 && steps.levitate-run.outputs.shouldSkip != 'true'
uses: marocchino/sticky-pull-request-comment@v2
with:
number: ${{ steps.levitate-run.outputs.pr_number }}
message: |
⚠️ &nbsp;&nbsp;**Possible breaking changes**
_(Open the links below in a new tab to go to the correct steps)_
${{ steps.levitate-run.outputs.message }}
[Console output](${{ steps.levitate-run.outputs.job_link }})
[Read our guideline](https://github.com/grafana/grafana/blob/main/contribute/breaking-changes-guide/breaking-changes-guide.md)
# Remove comment from the PR (no more breaking changes)
- name: Remove comment from PR
if: steps.levitate-run.outputs.exit_code == 0 && steps.levitate-run.outputs.shouldSkip != 'true'
uses: marocchino/sticky-pull-request-comment@v2
with:
number: ${{ steps.levitate-run.outputs.pr_number }}
delete: true
# Posts a notification to Slack if a PR has a breaking change and it did not have a breaking change before
- name: Post to Slack
id: slack
if: steps.levitate-run.outputs.exit_code == 1 && steps.does-label-exist.outputs.result == 0 && steps.levitate-run.outputs.shouldSkip != 'true' && env.HAS_SECRETS
uses: slackapi/slack-github-action@v1.24.0
with:
payload: |
{
"pr_link": "https://github.com/grafana/grafana/pull/${{ steps.levitate-run.outputs.pr_number }}",
"pr_number": "${{ steps.levitate-run.outputs.pr_number }}",
"job_link": "${{ steps.levitate-run.outputs.job_link }}",
"reporting_job_link": "${{ github.event.workflow_run.html_url }}",
"message": "${{ steps.levitate-run.outputs.message }}"
}
env:
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_LEVITATE_WEBHOOK_URL }}
HAS_SECRETS: ${{ (github.repository == 'grafana/grafana' || secrets.SLACK_LEVITATE_WEBHOOK_URL != '') || '' }}
# Add the label
- name: Add "levitate breaking change" label
if: steps.levitate-run.outputs.exit_code == 1 && steps.does-label-exist.outputs.result == 0 && steps.levitate-run.outputs.shouldSkip != 'true'
uses: actions/github-script@v6
env:
PR_NUMBER: ${{ steps.levitate-run.outputs.pr_number }}
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
await github.rest.issues.addLabels({
issue_number: process.env.PR_NUMBER,
owner: context.repo.owner,
repo: context.repo.repo,
labels: ['levitate breaking change']
})
# Remove label (no more breaking changes)
- name: Remove "levitate breaking change" label
if: steps.levitate-run.outputs.exit_code == 0 && steps.does-label-exist.outputs.result == 1 && steps.levitate-run.outputs.shouldSkip != 'true'
uses: actions/github-script@v6
env:
PR_NUMBER: ${{ steps.levitate-run.outputs.pr_number }}
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
await github.rest.issues.removeLabel({
issue_number: process.env.PR_NUMBER,
owner: context.repo.owner,
repo: context.repo.repo,
name: 'levitate breaking change'
})
# Add reviewers
# This is very weird, the actual request goes through (comes back with a 201), but does not assign the team.
# Related issue: https://github.com/renovatebot/renovate/issues/1908
- name: Add "grafana/plugins-platform-frontend" as a reviewer
if: steps.levitate-run.outputs.exit_code && steps.levitate-run.outputs.shouldSkip != 'true'
uses: actions/github-script@v6
env:
PR_NUMBER: ${{ steps.levitate-run.outputs.pr_number }}
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
await github.rest.pulls.requestReviewers({
pull_number: process.env.PR_NUMBER,
owner: context.repo.owner,
repo: context.repo.repo,
reviewers: [],
team_reviewers: ['grafana/plugins-platform-frontend']
});
# Remove reviewers (no more breaking changes)
- name: Remove "grafana/plugins-platform-frontend" from the list of reviewers
if: steps.levitate-run.outputs.exit_code == 0 && steps.levitate-run.outputs.shouldSkip != 'true'
uses: actions/github-script@v6
env:
PR_NUMBER: ${{ steps.levitate-run.outputs.pr_number }}
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
await github.rest.pulls.removeRequestedReviewers({
pull_number: process.env.PR_NUMBER,
owner: context.repo.owner,
repo: context.repo.repo,
reviewers: [],
team_reviewers: ['grafana/plugins-platform-frontend']
});

View File

@@ -7,7 +7,7 @@ jobs:
doc-validator:
runs-on: "ubuntu-latest"
container:
image: "grafana/doc-validator:v5.0.0"
image: "grafana/doc-validator:v4.0.0"
steps:
- name: "Checkout code"
uses: "actions/checkout@v4"

View File

@@ -4,11 +4,7 @@ on:
types: [created]
jobs:
config:
if: github.event.sender.type == 'User' &&
github.event.issue.pull_request &&
startsWith(github.event.comment.body, '/deploy-to-hg')
runs-on:
labels: ubuntu-latest-8-cores
runs-on: "ubuntu-latest"
outputs:
has-secrets: ${{ steps.check.outputs.has-secrets }}
steps:
@@ -37,6 +33,11 @@ jobs:
labels: ubuntu-latest-8-cores
continue-on-error: true
steps:
- name: Setup Go
uses: actions/setup-go@v4
with:
go-version: '>=1.20'
- name: Generate a GitHub app installation token
id: generate_token
uses: tibdex/github-app-token@b62528385c34dbc9f38e5f4225ac829252d1ea92
@@ -52,28 +53,15 @@ jobs:
ref: main
path: ephemeral
- name: Setup Go
uses: actions/setup-go@v4
with:
go-version-file: ephemeral/go.mod
- name: Get latest grafana version number
run: |
# if package.json contains e.g. 11.0.0-pre, this writes 11.0.0 to version.txt
curl https://raw.githubusercontent.com/grafana/grafana/main/package.json | jq -r .version | grep -o '^[0-9\.]*' > version.txt
- name: Run action
env:
GITHUB_EVENT: ${{ toJson(github.event)}}
run: |
# Create a prerelease version number using the latest version from the package.json in the grafana repo.
export GRAFANA_VERSION="$(cat version.txt)"
echo "${GRAFANA_VERSION}"
GRAFANA_VERSION=10.1.0
cd $GITHUB_WORKSPACE/ephemeral/src
go run . \
-GITHUB_TOKEN="${{ steps.generate_token.outputs.token }}" \
-GITHUB_WORKFLOW_RUN_ID="${{ github.run_id }}" \
-GITHUB_EVENT="$GITHUB_EVENT" \
-GITHUB_TRIGGERING_ACTOR="${{ github.triggering_actor }}" \
-GCOM_HOST="${{ secrets.EI_GCOM_HOST }}" \

View File

@@ -29,6 +29,11 @@ jobs:
runs-on: ubuntu-latest
continue-on-error: true
steps:
- name: Setup Go
uses: actions/setup-go@v4
with:
go-version: '>=1.20'
- name: Generate a GitHub app installation token
id: generate_token
uses: tibdex/github-app-token@b62528385c34dbc9f38e5f4225ac829252d1ea92
@@ -44,28 +49,15 @@ jobs:
ref: main
path: ephemeral
- name: Setup Go
uses: actions/setup-go@v4
with:
go-version-file: ephemeral/go.mod
- name: Get latest grafana version number
run: |
# if package.json contains e.g. 11.0.0-pre, this writes 11.0.0 to version.txt
curl https://raw.githubusercontent.com/grafana/grafana/main/package.json | jq -r .version | grep -o '^[0-9\.]*' > version.txt
- name: Run action
env:
GITHUB_EVENT: ${{ toJson(github.event)}}
run: |
# Create a prerelease version number using the latest version from the package.json in the grafana repo.
export GRAFANA_VERSION="$(cat version.txt)"
echo "${GRAFANA_VERSION}"
GRAFANA_VERSION=10.1.0
cd $GITHUB_WORKSPACE/ephemeral/src
go run . \
-GITHUB_TOKEN="${{ steps.generate_token.outputs.token }}" \
-GITHUB_WORKFLOW_RUN_ID="${{ github.run_id }}" \
-GITHUB_EVENT="$GITHUB_EVENT" \
-GITHUB_TRIGGERING_ACTOR="${{ github.triggering_actor }}" \
-GCOM_HOST="${{ secrets.EI_GCOM_HOST }}" \

View File

@@ -1,48 +1,27 @@
name: Create or update GitHub release
on:
workflow_call:
inputs:
version:
required: true
description: Needs to match, exactly, the name of a milestone (NO v prefix)
type: string
latest:
required: false
default: false
description: Mark this release as latest (`1`) or not (`0`, default)
type: string
dry_run:
required: false
default: false
type: boolean
workflow_dispatch:
inputs:
version:
required: true
description: Needs to match, exactly, the name of a milestone (NO v prefix)
type: string
latest:
required: false
description: Mark this release as latest (`1`) or not (`0`, default)
type: string
dry_run:
required: false
default: false
type: boolean
permissions:
# contents: write allows the action(s) to create github releases
contents: write
jobs:
main:
runs-on: ubuntu-latest
steps:
- name: "Generate token"
id: generate_token
uses: tibdex/github-app-token@b62528385c34dbc9f38e5f4225ac829252d1ea92
with:
app_id: ${{ secrets.GRAFANA_DELIVERY_BOT_APP_ID }}
private_key: ${{ secrets.GRAFANA_DELIVERY_BOT_APP_PEM }}
- name: Create GitHub release (manually invoked)
uses: grafana/grafana-github-actions-go/github-release@main
with:
token: ${{ secrets.GITHUB_TOKEN }}
token: ${{ steps.generate_token.outputs.token }}
version: ${{ inputs.version }}
metrics_api_key: ${{ secrets.GRAFANA_MISC_STATS_API_KEY }}
latest: ${{ inputs.latest }}
dry_run: ${{ inputs.dry_run }}

View File

@@ -1,33 +0,0 @@
name: golangci-lint
on:
push:
paths:
- pkg/**
- .github/workflows/go_lint.yml
- go.*
branches:
- main
pull_request:
permissions:
contents: read
jobs:
lint-go:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-go@v5
with:
go-version-file: ./go.mod
- run: CODEGEN_VERIFY=1 make gen-cue
- run: make gen-go
- name: golangci-lint
uses: golangci/golangci-lint-action@v5
with:
version: v1.59.0
args: |
--config .golangci.toml --max-same-issues=0 --max-issues-per-linter=0 --verbose ./pkg/... ./pkg/apimachinery/... ./pkg/apiserver/... ./pkg/build/wire/... ./pkg/promlib/... ./pkg/util/xorm/...
only-new-issues: true
skip-cache: true
install-mode: binary

View File

@@ -1,122 +0,0 @@
name: Crowdin Download Action
on:
workflow_dispatch:
schedule:
- cron: "0 * * * *"
jobs:
download-sources-from-crowdin:
runs-on: ubuntu-latest
permissions:
contents: write # needed to commit changes into the PR
pull-requests: write # needed to update PR description, labels, etc
steps:
- uses: actions/checkout@v4
with:
ref: ${{ github.head_ref }}
- name: Download sources
id: crowdin-download
uses: crowdin/github-action@v1
with:
upload_sources: false
upload_translations: false
download_sources: false
download_translations: true
export_only_approved: true
localization_branch_name: i18n_crowdin_translations
create_pull_request: true
pull_request_title: 'I18n: Download translations from Crowdin'
pull_request_body: |
:robot: Automatic download of translations from Crowdin.
Steps for merging:
1. A quick sanity check of the changes and approve. Things to look out for:
- No changes in the English file. The source of truth is in the main branch, NOT in Crowdin.
- Translations maybe be removed if the English phrase was removed, but there should not be many of these
- Anything else that looks 'funky'. Ask if you're not sure.
2. Approve & (Auto-)merge. :tada:
If there's a conflict, close the pull request and **delete the branch**. A GH action will recreate the pull request.
Remember, the longer this pull request is open, the more likely it is that it'll get conflicts.
pull_request_labels: 'area/frontend, area/internationalization, no-changelog, no-backport'
pull_request_reviewers: 'grafana-frontend-platform'
pull_request_base_branch_name: 'main'
base_url: 'https://grafana.api.crowdin.com'
config: 'crowdin.yml'
source: 'public/locales/en-US/grafana.json'
translation: 'public/locales/%locale%/%original_file_name%'
# Magic details of the github-actions bot user, to pass CLA checks
github_user_name: "github-actions[bot]"
github_user_email: "41898282+github-actions[bot]@users.noreply.github.com"
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
CROWDIN_PROJECT_ID: ${{ secrets.CROWDIN_PROJECT_ID }}
CROWDIN_PERSONAL_TOKEN: ${{ secrets.CROWDIN_PERSONAL_TOKEN }}
- name: Generate token
if: steps.crowdin-download.outputs.pull_request_url
id: generate_token
uses: tibdex/github-app-token@b62528385c34dbc9f38e5f4225ac829252d1ea92
with:
app_id: ${{ secrets.GRAFANA_PR_AUTOMATION_APP_ID }}
private_key: ${{ secrets.GRAFANA_PR_AUTOMATION_APP_PEM }}
- name: Get pull request ID
if: steps.crowdin-download.outputs.pull_request_url
shell: bash
# Crowdin action returns us the URL of the pull request, but we need an ID for the GraphQL API
# that looks like 'PR_kwDOAOaWjc5mP_GU'
run: |
pr_id=$(gh pr view ${{ steps.crowdin-download.outputs.pull_request_url }} --json id -q .id)
echo "PULL_REQUEST_ID=$pr_id" >> "$GITHUB_ENV"
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Get project board ID
uses: octokit/graphql-action@v2.x
id: get-project-id
if: steps.crowdin-download.outputs.pull_request_url
with:
# Frontend Platform project - https://github.com/orgs/grafana/projects/78
org: grafana
project_number: 78
query: |
query getProjectId($org: String!, $project_number: Int!){
organization(login: $org) {
projectV2(number: $project_number) {
title
id
}
}
}
env:
GITHUB_TOKEN: ${{ steps.generate_token.outputs.token }}
- name: Add to project board
uses: octokit/graphql-action@v2.x
if: steps.crowdin-download.outputs.pull_request_url
with:
projectid: ${{ fromJson(steps.get-project-id.outputs.data).organization.projectV2.id }}
prid: ${{ env.PULL_REQUEST_ID }}
query: |
mutation addPullRequestToProject($projectid: ID!, $prid: ID!){
addProjectV2ItemById(input: {projectId: $projectid, contentId: $prid}) {
item {
id
}
}
}
env:
GITHUB_TOKEN: ${{ steps.generate_token.outputs.token }}
- name: Run auto-milestone
uses: grafana/grafana-github-actions-go/auto-milestone@main
if: steps.crowdin-download.outputs.pull_request_url
with:
pr: ${{ steps.crowdin-download.outputs.pull_request_number }}
token: ${{ secrets.GITHUB_TOKEN }}

View File

@@ -0,0 +1,67 @@
# When Crowdin creates a pull request from the crowdin-service-branch branch,
# run `yarn i18n:extract` and commit the changed grafana.json files back into the PR
# to reformat crowdin's changes to prevent conflicts with our CI checks.
name: Fix Crowdin I18n files
on:
pull_request:
paths:
- 'public/locales/*/grafana.json'
branches:
- main # Only run on pull requests *target* main (will be merged into main)
jobs:
fix-files:
# Only run on pull requests *from* the crowdin-service-branch branch
if: github.head_ref == 'crowdin-service-branch'
name: Fix files
runs-on: ubuntu-latest
permissions:
contents: write # needed to commit changes back into the PR
pull-requests: write # needed to update PR description
steps:
- uses: actions/checkout@v4
with:
ref: ${{ github.head_ref }}
- uses: actions/setup-node@v4
with:
node-version: 20.9.0
cache: 'yarn'
- name: Install dependencies
run: yarn install
- name: Extract I18n files
run: yarn i18n:extract
- name: Commit changes
uses: stefanzweifel/git-auto-commit-action@8756aa072ef5b4a080af5dc8fef36c5d586e521d # v5.0.0
with:
commit_message: "Github Action: Auto-fix i18n files"
file_pattern: public/locales/*/grafana.json
- name: Update PR description
uses: devindford/Append_PR_Comment@32dd2619cd96ac8da9907c416c992fe265233ca8 # v1.1.3
if: ${{ ! contains(github.event.pull_request.body, 'Steps for merging') }}
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}
body-update-action: prefix
body-template: |
:robot: Automatic sync of translations from Crowdin.
Steps for merging:
1. Wait for the "Github Action: Auto-fix i18n files" commit that may be required for CI to pass.
2. A quick sanity check of the changes and approve. Things to look out for:
- No changes to the English strings. The source of truth is already in the main branch, NOT Crowdin.
- Translations maybe be removed if the English phrase was removed, but there should not be many of these
- Anything else that looks 'funky'. Ask if you're not sure.
3. Approve & (Auto-)merge. :tada:
If there's a conflict, close the pull request and **delete the branch**. Crowdin will recreate the pull request eventually.
Remember, the longer this pull request is open, the more likely it is that it'll get conflicts.

View File

@@ -1,33 +0,0 @@
name: Crowdin Upload Action
on:
workflow_dispatch:
push:
paths:
- 'public/locales/en-US/grafana.json'
branches:
- main
jobs:
upload-sources-to-crowdin:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Upload sources
uses: crowdin/github-action@v1
with:
upload_sources: true
upload_sources_args: '--dest=public/locales/en-US/grafana.json'
upload_translations: false
download_translations: false
create_pull_request: false
base_url: 'https://grafana.api.crowdin.com'
config: 'crowdin.yml'
source: 'public/locales/en-US/grafana.json'
translation: 'public/locales/%locale%/%original_file_name%'
env:
CROWDIN_PROJECT_ID: ${{ secrets.CROWDIN_PROJECT_ID }}
CROWDIN_PERSONAL_TOKEN: ${{ secrets.CROWDIN_PERSONAL_TOKEN }}

View File

@@ -53,7 +53,7 @@ jobs:
echo "TEAM=${TEAM}" >> $GITHUB_ENV
- name: "Prepare payload"
uses: frabert/replace-string-action@v2.5
uses: frabert/replace-string-action@v2.0
id: preparePayload
with:
# replace double quotes with single quotes to avoid breaking the JSON payload sent to Slack
@@ -64,7 +64,7 @@ jobs:
- name: Get Token
id: get_workflow_token
uses: peter-murray/workflow-application-token-action@v3
uses: peter-murray/workflow-application-token-action@v2
with:
application_id: ${{ secrets.APP_GRAFANA_TEAM_CHECKER_ID }}
application_private_key: ${{ secrets.APP_GRAFANA_TEAM_CHECKER_KEY }}
@@ -86,7 +86,7 @@ jobs:
- name: "Send Slack notification"
if: ${{ (env.CHANNEL != 'null') && ((env.USER_FOUND == 'false') || (env.TEAM != 'null')) }}
uses: slackapi/slack-github-action@v1.26.0
uses: slackapi/slack-github-action@v1.24.0
with:
payload: >
{

View File

@@ -25,7 +25,7 @@ jobs:
id: check
shell: bash
run: |
if [ -n "${{ (secrets.GRAFANA_MISC_STATS_API_KEY != '') || '' }}" ]; then
if [ -n "${{ (secrets.GRAFANA_MISC_STATS_API_KEY != '' && secrets.GH_BOT_ACCESS_TOKEN != '') || '' }}" ]; then
echo "has-secrets=1" >> "$GITHUB_OUTPUT"
fi
@@ -46,5 +46,5 @@ jobs:
uses: ./actions/metrics-collector
with:
metricsWriteAPIKey: ${{secrets.GRAFANA_MISC_STATS_API_KEY}}
token: ${{secrets.GITHUB_TOKEN}}
token: ${{secrets.GH_BOT_ACCESS_TOKEN}}
configPath: "metrics-collector"

View File

@@ -9,7 +9,6 @@ on:
- labeled
- unlabeled
- edited
- auto_merge_enabled
issues:
types:
- milestoned

View File

@@ -14,29 +14,19 @@ jobs:
analyze:
name: Analyze
runs-on: ubuntu-latest
if: github.repository == 'grafana/grafana'
steps:
- name: "Generate token"
id: generate_token
continue-on-error: true
uses: tibdex/github-app-token@3beb63f4bd073e61482598c45c71c1019b59b73a
with:
app_id: ${{ secrets.GRAFANA_DELIVERY_BOT_APP_ID }}
private_key: ${{ secrets.GRAFANA_DELIVERY_BOT_APP_PEM }}
- name: Checkout repository
uses: actions/checkout@v4
with:
# We must fetch at least the immediate parents so that if this is
# a pull request then we can checkout the head.
fetch-depth: 2
token: ${{ steps.generate_token.outputs.token }}
- name: Set go version
uses: actions/setup-go@v4
with:
go-version-file: go.mod
go-version: '1.21.5'
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL

View File

@@ -16,7 +16,6 @@ jobs:
analyze:
name: Analyze
runs-on: ubuntu-latest
if: github.repository == 'grafana/grafana'
steps:
- name: Checkout repository

View File

@@ -14,7 +14,6 @@ jobs:
analyze:
name: Analyze
runs-on: ubuntu-latest
if: github.repository == 'grafana/grafana'
steps:
- name: Checkout repository

View File

@@ -1,51 +0,0 @@
name: "Go Workspace Check"
on:
workflow_dispatch:
pull_request:
branches: [main]
paths:
- '**/go.work'
- '**/go.work.sum'
- '**/go.mod'
- '**/go.sum'
jobs:
check:
name: Go Workspace Check
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Set go version
uses: actions/setup-go@v4
with:
go-version-file: go.mod
- name: Workspace Sync
run: go work sync
- name: Check for go mod & workspace changes
run: |
if ! git diff --exit-code --quiet; then
echo "Changes detected:"
git diff
echo "Please run 'go work sync' and commit the changes."
echo "If there is a change in enterprise dependencies, please update pkg/extensions/main.go."
exit 1
fi
- name: Build
run: make build-go
- name: Check for go workspace changes
run: |
if ! git diff --exit-code --quiet; then
echo "Changes detected:"
git diff
echo "Please run 'make build-go' and commit the changes."
echo "If there is a change in enterprise dependencies, please update pkg/extensions/main.go."
exit 1
fi

View File

@@ -1,4 +1,4 @@
# Owned by grafana-release-guild
# Owned by grafana-delivery-squad
# Intended to be dropped into the base repo Ex: grafana/grafana
name: Check for patch conflicts
run-name: check-patch-conflicts-${{ github.base_ref }}-${{ github.head_ref }}
@@ -18,7 +18,6 @@ on:
jobs:
trigger_downstream_patch_check:
uses: grafana/security-patch-actions/.github/workflows/test-patches.yml@main
if: github.repository == 'grafana/grafana'
with:
src_repo: "${{ github.repository }}"
src_ref: "${{ github.head_ref }}" # this is the source branch name, Ex: "feature/newthing"

View File

@@ -36,7 +36,7 @@ jobs:
- name: "Setup Go"
uses: "actions/setup-go@v4"
with:
go-version-file: go.mod
go-version: '1.21.5'
- name: "Verify kinds"
run: go run .github/workflows/scripts/kinds/verify-kinds.go

View File

@@ -39,7 +39,7 @@ jobs:
- name: "Setup Go"
uses: "actions/setup-go@v4"
with:
go-version-file: go.mod
go-version: '1.21.5'
- name: "Verify kinds"
run: go run .github/workflows/scripts/kinds/verify-kinds.go

View File

@@ -55,7 +55,7 @@ jobs:
# Tags aren't necessarily made to the HEAD of the version branch.
# The documentation to be published is always on the HEAD of the version branch.
if: "steps.has-matching-release-tag.outputs.bool == 'true' && github.ref_type == 'tag'"
run: "git switch --detach origin/${{ steps.target.outputs.target }}.x"
run: "git switch --detach origin/${{ steps.target.output.target }}.x"
- name: "Publish to website repository (release)"
if: "steps.has-matching-release-tag.outputs.bool == 'true'"

View File

@@ -1,78 +0,0 @@
# This workflow runs whenever the release PR is merged. It includes post-release communication processes like
# posting to slack, the website, community forums, etc.
# Only things that happen after a release is completed and all of the necessary code changes (like the changelog) are made.
name: Post-release
on:
workflow_dispatch:
inputs:
dry_run:
required: false
default: true
version:
required: true
latest:
type: bool
default: false
pull_request:
types:
- closed
branches:
- 'main'
- 'v*.*.*'
jobs:
setup:
if: ${{ github.event_name == 'workflow_dispatch' || (github.event.pull_request.merged == true && startsWith(github.head_ref, 'release/')) }}
name: Setup and establish latest
outputs:
version: ${{ steps.output.outputs.version }}
dry_run: ${{ steps.output.outputs.dry_run }}
latest: ${{ steps.output.outputs.latest }}
runs-on: ubuntu-latest
steps:
- if: ${{ github.event_name == 'workflow_dispatch' }}
run: |
echo setting up GITHUB_ENV for ${{ github.event_name }}
echo "VERSION=${{ inputs.version }}" >> $GITHUB_ENV
echo "DRY_RUN=${{ inputs.dry_run }}" >> $GITHUB_ENV
echo "LATEST=${{ inputs.latest }}" >> $GITHUB_ENV
- if: ${{ github.event.pull_request.merged == true && startsWith(github.head_ref, 'release/') }}
run: |
echo "VERSION=$(echo ${{ github.head_ref }} | sed -e 's/release\/.*\///g')" >> $GITHUB_ENV
echo "DRY_RUN=${{ contains(github.event.pull_request.labels.*.name, 'release/dry-run') }}" >> $GITHUB_ENV
echo "LATEST=${{ contains(github.event.pull_request.labels.*.name, 'release/latest') }}" >> $GITHUB_ENV
- id: output
run: |
echo "dry_run: $DRY_RUN"
echo "latest: $LATEST"
echo "version: $VERSION"
echo "dry_run=$DRY_RUN" >> "$GITHUB_OUTPUT"
echo "latest=$LATEST" >> "$GITHUB_OUTPUT"
echo "version=$VERSION" >> "$GITHUB_OUTPUT"
post_changelog_on_forum:
needs: setup
uses: ./.github/workflows/community-release.yml
secrets:
GRAFANA_MISC_STATS_API_KEY: ${{ secrets.GRAFANA_MISC_STATS_API_KEY }}
GRAFANABOT_FORUM_KEY: ${{ secrets.GRAFANABOT_FORUM_KEY }}
with:
version: ${{ needs.setup.outputs.version }}
dry_run: ${{ needs.setup.outputs.dry_run == 'true' }}
create_github_release:
# a github release requires a git tag
# The github-release action retrieves the changelog using the /repos/grafana/grafana/contents/CHANGELOG.md API
# endpoint.
needs: setup
uses: ./.github/workflows/github-release.yml
with:
version: ${{ needs.setup.outputs.version }}
dry_run: ${{ needs.setup.outputs.dry_run == 'true' }}
latest: ${{ needs.setup.outputs.latest }}
post_on_slack:
needs: setup
runs-on: ubuntu-latest
steps:
- run: |
echo announce on slack that ${{ needs.setup.outputs.version }} has been released
echo dry run: ${{ needs.setup.outputs.dry_run }}

View File

@@ -1,161 +0,0 @@
# This workflow creates a new PR in Grafana which is triggered after a release is completed.
# It should include all code changes that are needed after a release is done. This includes the changelog update and
# version bumps, but could include more in the future.
# Please refrain from including any processes that do not result in code changes in this workflow. Instead, they should
# either be triggered in the release promotion process or in the release comms process (that is triggered by merging
# this PR).
name: Complete a Grafana release
on:
workflow_dispatch:
inputs:
version:
required: true
type: string
description: The version of Grafana that is being released
target:
required: true
type: string
description: The base branch that these changes are being merged into
backport:
required: false
type: string
description: Branch to backport these changes to
dry_run:
required: false
default: false
type: boolean
latest:
required: false
default: false
type: boolean
permissions:
contents: write
pull-requests: write
jobs:
push-changelog-to-main:
name: Create PR to main to update the changelog
uses: ./.github/workflows/changelog.yml
with:
version: ${{ inputs.version }}
latest: ${{ inputs.latest }}
dry_run: ${{ inputs.dry_run }}
target: main
secrets:
GRAFANA_DELIVERY_BOT_APP_ID: ${{ secrets.GRAFANA_DELIVERY_BOT_APP_ID }}
GRAFANA_DELIVERY_BOT_APP_PEM: ${{ secrets.GRAFANA_DELIVERY_BOT_APP_PEM }}
create-prs:
name: Create Release PR
runs-on: ubuntu-latest
if: github.repository == 'grafana/grafana'
steps:
- name: Generate bot token
id: generate_token
uses: tibdex/github-app-token@b62528385c34dbc9f38e5f4225ac829252d1ea92
with:
app_id: ${{ secrets.GRAFANA_DELIVERY_BOT_APP_ID }}
private_key: ${{ secrets.GRAFANA_DELIVERY_BOT_APP_PEM }}
- name: Checkout Grafana
uses: actions/checkout@v4
with:
ref: ${{ inputs.target }}
fetch-depth: 0
fetch-tags: true
- name: Checkout Grafana (main)
uses: actions/checkout@v4
with:
ref: main
fetch-depth: '0'
fetch-tags: 'false'
path: .grafana-main
- name: Configure git user
run: |
git config --local user.name "github-actions[bot]"
git config --local user.email "github-actions[bot]@users.noreply.github.com"
git config --local --add --bool push.autoSetupRemote true
- name: Create branch
run: git checkout -b "release/${{ github.run_id }}/${{ inputs.version }}"
- name: Generate changelog
id: changelog
uses: ./.grafana-main/.github/workflows/actions/changelog
with:
github_token: ${{ steps.generate_token.outputs.token }}
target: v${{ inputs.version }}
output_file: changelog_items.md
- name: Patch CHANGELOG.md
run: |
# Prepare CHANGELOG.md content with version delimiters
(
echo
echo "# ${{ inputs.version}} ($(date '+%F'))"
echo
cat changelog_items.md
) > CHANGELOG.part
# Check if a version exists in the changelog
if grep -q "<!-- ${{ inputs.version}} START" CHANGELOG.md ; then
# Replace the content between START and END delimiters
echo "Version ${{ inputs.version }} is found in the CHANGELOG.md, patching contents..."
sed -i -e '/${{ inputs.version }} START/,/${{ inputs.version }} END/{//!d;}' \
-e '/${{ inputs.version }} START/r CHANGELOG.part' CHANGELOG.md
else
# Prepend changelog part to the main changelog file
echo "Version ${{ inputs.version }} not found in the CHANGELOG.md"
(
echo "<!-- ${{ inputs.version }} START -->"
cat CHANGELOG.part
echo "<!-- ${{ inputs.version }} END -->"
cat CHANGELOG.md
) > CHANGELOG.tmp
mv CHANGELOG.tmp CHANGELOG.md
fi
rm -f CHANGELOG.part changelog_items.md
git diff CHANGELOG.md
- name: Commit CHANGELOG.md changes
run: git add CHANGELOG.md && git commit --allow-empty -m "Update changelog" CHANGELOG.md
- name: Update package.json versions
uses: ./.grafana-main/pkg/build/actions/bump-version
with:
version: 'patch'
- name: Add package.json changes
run: |
git add package.json lerna.json yarn.lock packages public
git commit -m "Update version to ${{ inputs.version }}"
- name: Git push
if: ${{ inputs.dry_run }} != true
run: git push --set-upstream origin release/${{ github.run_id }}/${{ inputs.version }}
- name: Create PR without backports
if: "${{ inputs.backport == '' }}"
run: >
gh pr create \
$( [ "x${{ inputs.latest }}" == "xtrue" ] && printf %s '-l "release/latest"') \
-l "no-changelog" \
--dry-run=${{ inputs.dry_run }} \
-B "${{ inputs.target }}" \
--title "Release: ${{ inputs.version }}" \
--body "These code changes must be merged after a release is complete"
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Create PR with backports
if: "${{ inputs.backport != '' }}"
run: >
gh pr create \
$( [ "x${{ inputs.latest }}" == "xtrue" ] && printf %s '-l "release/latest"') \
-l "product-approved" \
-l "no-changelog" \
--dry-run=${{ inputs.dry_run }} \
-B "${{ inputs.target }}" \
--title "Release: ${{ inputs.version }}" \
--body "These code changes must be merged after a release is complete"
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}

View File

@@ -1,47 +0,0 @@
name: Run dashboard scenes e2e
on:
schedule:
- cron: "0 8 * * 1-5" # every day at 08:00UTC on weekdays
# push # uncomment for test run during PR
env:
ARCH: linux-amd64
jobs:
dashboard-scenes-e2e:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Pin Go version to mod file
uses: actions/setup-go@v5
with:
go-version-file: 'go.mod'
- run: go version
- uses: actions/setup-node@v4
with:
node-version: 20
- name: Install dependencies
run: yarn install --immutable
- name: Build grafana
run: make build
- name: Install Cypress dependencies
uses: cypress-io/github-action@v6
with:
runTests: false
- name: Run dashboard scenes e2e
run: yarn e2e:scenes
- name: "Send Slack notification"
if: ${{ failure() }}
uses: slackapi/slack-github-action@v1.26.0
with:
payload: >
{
"icon_emoji": ":this-is-fine-fire:",
"username": "Dashboard scenes e2e tests failed",
"text": "Link to run: https://github.com/${{github.repository}}/actions/runs/${{github.run_id}}",
"channel": "#grafana-dashboards-squad"
}
env:
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}

View File

@@ -1,111 +1,121 @@
package main
import (
"archive/zip"
"context"
"errors"
"fmt"
"golang.org/x/text/cases"
"golang.org/x/text/language"
"io"
"net/http"
"os"
"path/filepath"
"regexp"
"strconv"
"strings"
"testing/fstest"
"cuelang.org/go/cue"
cueformat "cuelang.org/go/cue/format"
"github.com/google/go-github/github"
"github.com/grafana/codejen"
"github.com/grafana/grafana/pkg/registry/schemas"
"github.com/grafana/grafana/pkg/codegen"
"github.com/grafana/grafana/pkg/cuectx"
"github.com/grafana/grafana/pkg/plugins/pfs"
"github.com/grafana/grafana/pkg/plugins/pfs/corelist"
"github.com/grafana/grafana/pkg/registry/corekind"
"github.com/grafana/kindsys"
"github.com/grafana/thema"
"golang.org/x/oauth2"
)
var nonAlphaNumRegex = regexp.MustCompile("[^a-zA-Z0-9 ]+")
const (
GITHUB_OWNER = "grafana"
GITHUB_REPO = "kind-registry"
)
// main This script verifies that stable kinds are not updated once published (new schemas
// can be added but existing ones cannot be updated).
// It generates kind files into a local "next" folder, ready to be published in the kind-registry repo.
// If the env variable CODEGEN_VERIFY is not present, this also generates kind files into a
// local "next" folder, ready to be published in the kind-registry repo.
// If kind names are given as parameters, the script will make the above actions only for the
// given kinds.
func main() {
var corek []kindsys.Kind
var compok []kindsys.Composable
kindRegistry, err := NewKindRegistry()
defer kindRegistry.cleanUp()
if err != nil {
die(err)
}
// Search for the latest version directory present in the kind-registry repo
latestRegistryDir, err := kindRegistry.findLatestDir()
if err != nil {
die(fmt.Errorf("failed to get latest directory for published kinds: %s", err))
}
errs := make([]error, 0)
// Kind verification
for _, kind := range corekind.NewBase(nil).All() {
name := kind.Props().Common().MachineName
err := verifyKind(kindRegistry, kind, name, "core", latestRegistryDir)
if err != nil {
errs = append(errs, err)
continue
}
corek = append(corek, kind)
}
for _, pp := range corelist.New(nil) {
for _, kind := range pp.ComposableKinds {
si, err := kindsys.FindSchemaInterface(kind.Def().Properties.SchemaInterface)
if err != nil {
errs = append(errs, err)
continue
}
name := strings.ToLower(fmt.Sprintf("%s/%s", strings.TrimSuffix(kind.Lineage().Name(), si.Name()), si.Name()))
err = verifyKind(kindRegistry, kind, name, "composable", latestRegistryDir)
if err != nil {
errs = append(errs, err)
continue
}
compok = append(compok, kind)
}
}
die(errs...)
if _, set := os.LookupEnv("CODEGEN_VERIFY"); set {
os.Exit(0)
}
// File generation
jfs := codejen.NewFS()
outputPath := filepath.Join(".github", "workflows", "scripts", "kinds")
corekinds, err := schemas.GetCoreKinds()
die(err)
composableKinds, err := schemas.GetComposableKinds()
die(err)
coreJennies := codejen.JennyList[schemas.CoreKind]{}
coreJennies := codejen.JennyList[kindsys.Kind]{}
coreJennies.Append(
CoreKindRegistryJenny(outputPath),
KindRegistryJenny(outputPath),
)
corefs, err := coreJennies.GenerateFS(corekinds...)
corefs, err := coreJennies.GenerateFS(corek...)
die(err)
die(jfs.Merge(corefs))
composableJennies := codejen.JennyList[schemas.ComposableKind]{}
composableJennies := codejen.JennyList[kindsys.Composable]{}
composableJennies.Append(
ComposableKindRegistryJenny(outputPath),
)
composablefs, err := composableJennies.GenerateFS(composableKinds...)
composablefs, err := composableJennies.GenerateFS(compok...)
die(err)
die(jfs.Merge(composablefs))
if err = jfs.Write(context.Background(), ""); err != nil {
die(fmt.Errorf("error while writing generated code to disk:\n%s", err))
}
if err := copyCueSchemas("packages/grafana-schema/src/common", filepath.Join(outputPath, "next")); err != nil {
die(fmt.Errorf("error while copying the grafana-schema/common package:\n%s", err))
}
}
func copyCueSchemas(fromDir string, toDir string) error {
baseTargetDir := filepath.Base(fromDir)
return filepath.Walk(fromDir, func(path string, info os.FileInfo, err error) error {
if err != nil {
return err
}
targetPath := filepath.Join(
toDir,
baseTargetDir,
strings.TrimPrefix(path, fromDir),
)
if info.IsDir() {
return ensureDirectoryExists(targetPath, info.Mode())
}
if !strings.HasSuffix(path, ".cue") {
return nil
}
return copyFile(path, targetPath, info.Mode())
})
}
func copyFile(from string, to string, mode os.FileMode) error {
input, err := os.ReadFile(from)
if err != nil {
return err
}
return os.WriteFile(to, input, mode)
}
func ensureDirectoryExists(directory string, mode os.FileMode) error {
_, err := os.Stat(directory)
if errors.Is(err, os.ErrNotExist) {
if err = os.Mkdir(directory, mode); err != nil {
return err
}
} else if err != nil {
return err
}
return os.Chmod(directory, mode)
}
func die(errs ...error) {
@@ -117,8 +127,101 @@ func die(errs ...error) {
}
}
// CoreKindRegistryJenny generates kind files into the "next" folder of the local kind registry.
func CoreKindRegistryJenny(path string) codejen.OneToOne[schemas.CoreKind] {
// verifyKind verifies that stable kinds are not updated once published (new schemas
// can be added but existing ones cannot be updated)
func verifyKind(registry *kindRegistry, kind kindsys.Kind, name string, category string, latestRegistryDir string) error {
oldKindString, err := registry.getPublishedKind(name, category, latestRegistryDir)
if err != nil {
return err
}
var oldKind kindsys.Kind
if oldKindString != "" {
switch category {
case "core":
oldKind, err = loadCoreKind(name, oldKindString)
case "composable":
oldKind, err = loadComposableKind(name, oldKindString)
default:
return fmt.Errorf("kind can only be core or composable")
}
}
if err != nil {
return err
}
// Kind is new - no need to compare it
if oldKind == nil {
return nil
}
// Check that maturity isn't downgraded
if kind.Maturity().Less(oldKind.Maturity()) {
return fmt.Errorf("kind maturity can't be downgraded once a kind is published")
}
if oldKind.Maturity().Less(kindsys.MaturityStable) {
return nil
}
// Check that old schemas do not contain updates
err = thema.IsAppendOnly(oldKind.Lineage(), kind.Lineage())
if err != nil {
return fmt.Errorf("existing schemas in lineage %s cannot be modified: %w", name, err)
}
return nil
}
func isLess(v1 []uint64, v2 []uint64) bool {
if len(v1) == 1 || len(v2) == 1 {
return v1[0] < v2[0]
}
return v1[0] < v2[0] || (v1[0] == v2[0] && isLess(v1[2:], v2[2:]))
}
func loadCoreKind(name string, kind string) (kindsys.Kind, error) {
fs := fstest.MapFS{
fmt.Sprintf("%s.cue", name): &fstest.MapFile{
Data: []byte(kind),
},
}
rt := cuectx.GrafanaThemaRuntime()
def, err := cuectx.LoadCoreKindDef(fmt.Sprintf("%s.cue", name), rt.Context(), fs)
if err != nil {
return nil, fmt.Errorf("%s is not a valid kind: %w", name, err)
}
return kindsys.BindCore(rt, def)
}
func loadComposableKind(name string, kind string) (kindsys.Kind, error) {
parts := strings.Split(name, "/")
if len(parts) > 1 {
name = parts[1]
}
fs := fstest.MapFS{
fmt.Sprintf("%s.cue", name): &fstest.MapFile{
Data: []byte(kind),
},
}
rt := cuectx.GrafanaThemaRuntime()
def, err := pfs.LoadComposableKindDef(fs, rt, fmt.Sprintf("%s.cue", name))
if err != nil {
return nil, fmt.Errorf("%s is not a valid kind: %w", name, err)
}
return kindsys.BindComposable(rt, def)
}
// KindRegistryJenny generates kind files into the "next" folder of the local kind registry.
func KindRegistryJenny(path string) codegen.OneToOne {
return &kindregjenny{
path: path,
}
@@ -132,46 +235,22 @@ func (j *kindregjenny) JennyName() string {
return "KindRegistryJenny"
}
func (j *kindregjenny) Generate(kind schemas.CoreKind) (*codejen.File, error) {
newKindBytes, err := kindToBytes(kind.CueFile)
func (j *kindregjenny) Generate(kind kindsys.Kind) (*codejen.File, error) {
name := kind.Props().Common().MachineName
core, ok := kind.(kindsys.Core)
if !ok {
return nil, fmt.Errorf("kind sent to KindRegistryJenny must be a core kind")
}
newKindBytes, err := kindToBytes(core.Def().V)
if err != nil {
return nil, err
}
path := filepath.Join(j.path, "next", "core", kind.Name, kind.Name+".cue")
path := filepath.Join(j.path, "next", "core", name, name+".cue")
return codejen.NewFile(path, newKindBytes, j), nil
}
// ComposableKindRegistryJenny generates kind files into the "next" folder of the local kind registry.
func ComposableKindRegistryJenny(path string) codejen.OneToOne[schemas.ComposableKind] {
return &ckrJenny{
path: path,
}
}
type ckrJenny struct {
path string
}
func (j *ckrJenny) JennyName() string {
return "ComposableKindRegistryJenny"
}
func (j *ckrJenny) Generate(k schemas.ComposableKind) (*codejen.File, error) {
name := strings.ToLower(fmt.Sprintf("%s/%s", k.Name, k.Filename))
v := fixComposableKindFormat(k)
newKindBytes, err := kindToBytes(v)
if err != nil {
return nil, err
}
newKindBytes = []byte(fmt.Sprintf("package grafanaplugin\n\n%s", newKindBytes))
return codejen.NewFile(filepath.Join(j.path, "next", "composable", name), newKindBytes, j), nil
}
// kindToBytes converts a kind cue value to a .cue file content
func kindToBytes(kind cue.Value) ([]byte, error) {
node := kind.Syntax(
@@ -183,47 +262,164 @@ func kindToBytes(kind cue.Value) ([]byte, error) {
return cueformat.Node(node)
}
func fixComposableKindFormat(schema schemas.ComposableKind) cue.Value {
variant := "PanelCfg"
if schema.CueFile.LookupPath(cue.ParsePath("composableKinds.DataQuery")).Exists() {
variant = "DataQuery"
// ComposableKindRegistryJenny generates kind files into the "next" folder of the local kind registry.
func ComposableKindRegistryJenny(path string) codejen.OneToOne[kindsys.Composable] {
return &ckrJenny{
path: path,
}
newCue := schema.CueFile.Context().CompileString(
fmt.Sprintf("schemaInterface: %q\n", variant) +
fmt.Sprintf("name: %q + %q\n\n", UpperCamelCase(schema.Name), variant) +
"lineage: _",
)
lineagePath := cue.MakePath(cue.Str("composableKinds"), cue.Str(variant), cue.Str("lineage"))
return newCue.FillPath(cue.MakePath(cue.Str("lineage")), schema.CueFile.LookupPath(lineagePath))
}
func UpperCamelCase(s string) string {
s = LowerCamelCase(s)
// Uppercase the first letter
if len(s) > 0 {
s = strings.ToUpper(s[:1]) + s[1:]
}
return s
type ckrJenny struct {
path string
}
func LowerCamelCase(s string) string {
// Replace all non-alphanumeric characters by spaces
s = nonAlphaNumRegex.ReplaceAllString(s, " ")
func (j *ckrJenny) JennyName() string {
return "ComposableKindRegistryJenny"
}
// Title case s
s = cases.Title(language.AmericanEnglish, cases.NoLower).String(s)
// Remove all spaces
s = strings.ReplaceAll(s, " ", "")
// Lowercase the first letter
if len(s) > 0 {
s = strings.ToLower(s[:1]) + s[1:]
func (j *ckrJenny) Generate(k kindsys.Composable) (*codejen.File, error) {
si, err := kindsys.FindSchemaInterface(k.Def().Properties.SchemaInterface)
if err != nil {
panic(err)
}
return s
name := strings.ToLower(fmt.Sprintf("%s/%s", strings.TrimSuffix(k.Lineage().Name(), si.Name()), si.Name()))
newKindBytes, err := kindToBytes(k.Def().V)
if err != nil {
return nil, err
}
newKindBytes = []byte(fmt.Sprintf("package grafanaplugin\n\n%s", newKindBytes))
return codejen.NewFile(filepath.Join(j.path, "next", "composable", name+".cue"), newKindBytes, j), nil
}
type kindRegistry struct {
zipDir string
zipFile *zip.ReadCloser
}
// NewKindRegistry downloads the archive of the kind-registry GH repository and open it
func NewKindRegistry() (*kindRegistry, error) {
ctx := context.Background()
tc := oauth2.NewClient(ctx, nil)
client := github.NewClient(tc)
// Create a temporary file to store the downloaded archive
file, err := os.CreateTemp("", "*.zip")
if err != nil {
return nil, fmt.Errorf("failed to create temporary file: %w", err)
}
defer file.Close()
// Get the repository archive URL
archiveURL, _, err := client.Repositories.GetArchiveLink(ctx, GITHUB_OWNER, GITHUB_REPO, github.Zipball, &github.RepositoryContentGetOptions{})
if err != nil {
return nil, fmt.Errorf("failed to get archive URL: %w", err)
}
// Download the archive file
httpClient := http.DefaultClient
resp, err := httpClient.Get(archiveURL.String())
if err != nil {
return nil, fmt.Errorf("failed to download archive: %w", err)
}
defer resp.Body.Close()
// Save the downloaded archive to the temporary file
_, err = io.Copy(file, resp.Body)
if err != nil {
return nil, fmt.Errorf("failed to save archive: %w", err)
}
// Open the zip file for reading
zipDir := file.Name()
zipFile, err := zip.OpenReader(zipDir)
if err != nil {
return nil, fmt.Errorf("failed to open zip file %s: %w", zipDir, err)
}
return &kindRegistry{
zipDir: zipDir,
zipFile: zipFile,
}, nil
}
// cleanUp removes the archive from the temporary files and closes the zip reader
func (registry *kindRegistry) cleanUp() {
if registry.zipDir != "" {
err := os.Remove(registry.zipDir)
if err != nil {
fmt.Fprint(os.Stderr, fmt.Errorf("failed to remove zip archive: %w", err))
}
}
if registry.zipFile != nil {
err := registry.zipFile.Close()
if err != nil {
fmt.Fprint(os.Stderr, fmt.Errorf("failed to close zip file reader: %w", err))
}
}
}
// findLatestDir get the latest version directory published in the kind registry
func (registry *kindRegistry) findLatestDir() (string, error) {
re := regexp.MustCompile(`([0-9]+)\.([0-9]+)\.([0-9]+)`)
latestVersion := []uint64{0, 0, 0}
latestDir := ""
for _, file := range registry.zipFile.File {
if !file.FileInfo().IsDir() {
continue
}
parts := re.FindStringSubmatch(file.Name)
if parts == nil || len(parts) < 4 {
continue
}
version := make([]uint64, len(parts)-1)
for i := 1; i < len(parts); i++ {
version[i-1], _ = strconv.ParseUint(parts[i], 10, 32)
}
if isLess(latestVersion, version) {
latestVersion = version
latestDir = file.Name
}
}
return latestDir, nil
}
// getPublishedKind retrieves the latest published kind from the kind registry
func (registry *kindRegistry) getPublishedKind(name string, category string, latestRegistryDir string) (string, error) {
if latestRegistryDir == "" {
return "", nil
}
var cueFilePath string
switch category {
case "core":
cueFilePath = fmt.Sprintf("%s/%s.cue", name, name)
case "composable":
cueFilePath = fmt.Sprintf("%s.cue", name)
default:
return "", fmt.Errorf("kind can only be core or composable")
}
kindPath := filepath.Join(latestRegistryDir, category, cueFilePath)
file, err := registry.zipFile.Open(kindPath)
if err != nil {
return "", fmt.Errorf("failed to open file: %w", err)
}
defer file.Close()
data, err := io.ReadAll(file)
if err != nil {
return "", fmt.Errorf("failed to read file: %w", err)
}
return string(data), nil
}

View File

@@ -4,39 +4,33 @@ on:
- cron: '30 1 * * *'
permissions:
issues: write
pull-requests: write
jobs:
stale:
runs-on: ubuntu-latest
steps:
- uses: actions/stale@v9
- uses: actions/stale@v8
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}
operations-per-run: 750
# start from the oldest issues/PRs when performing stale operations
ascending: true
days-before-issue-stale: 365
days-before-issue-close: 30
stale-issue-label: stale
exempt-issue-labels: no stalebot,type/epic
stale-issue-message: >
This issue has been automatically marked as stale because it has not had
activity in the last year. It will be closed in 30 days if no further activity occurs. Please
feel free to leave a comment if you believe the issue is still relevant.
Thank you for your contributions!
close-issue-message: >
This issue has been automatically closed because it has not had any further
activity in the last 30 days. Thank you for your contributions!
days-before-pr-stale: 30
days-before-pr-close: 14
stale-pr-label: stale
# Number of days of inactivity before a stale Issue or Pull Request is closed.
# Set to -1 to disable. If disabled, issues still need to be closed manually, but will remain marked as stale.
days-before-close: 14
# Number of days of inactivity before an Issue or Pull Request becomes stale
days-before-stale: 30
# We don't want any Issues to be marked as stale for now.
days-before-issue-stale: -1
exempt-issue-labels: no stalebot
exempt-pr-labels: no stalebot
operations-per-run: 500
stale-issue-label: stale
stale-pr-label: stale
stale-pr-message: >
This pull request has been automatically marked as stale because it has not had
activity in the last 30 days. It will be closed in 2 weeks if no further activity occurs. Please
feel free to give a status update or ping for review. Thank you for your contributions!
feel free to give a status update now, ping for review, or re-open when it's ready.
Thank you for your contributions!
close-pr-message: >
This pull request has been automatically closed because it has not had any further
activity in the last 2 weeks. Thank you for your contributions!
This pull request has been automatically closed because it has not had
activity in the last 2 weeks. Please feel free to give a status update now, ping for review, or re-open when it's ready.
Thank you for your contributions!

View File

@@ -1,4 +1,4 @@
# Owned by grafana-release-guild
# Owned by grafana-delivery-squad
# Intended to be dropped into the base repo, Ex: grafana/grafana
name: Sync to mirror
run-name: sync-to-mirror-${{ github.ref_name }}

View File

@@ -12,8 +12,8 @@ jobs:
- uses: grafana/writers-toolkit/update-make-docs@update-make-docs/v1
with:
pr_options: >
--label 'backport v10.0.x'
--label 'backport v10.1.x'
--label 'backport v10.2.x'
--label 'backport v10.3.x'
--label no-changelog
--label type/docs

View File

@@ -4,7 +4,7 @@ on:
pull_request:
branches: [ main ]
paths:
- '**/*.cue'
- '**/*.cue'
jobs:
main:
@@ -18,9 +18,10 @@ jobs:
- name: "Setup Go"
uses: "actions/setup-go@v4"
with:
go-version-file: go.mod
go-version: '1.21.5'
- name: "Verify kinds"
run: go run .github/workflows/scripts/kinds/verify-kinds.go
env:
CODEGEN_VERIFY: 1
GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}}

17
.gitignore vendored
View File

@@ -24,6 +24,9 @@ __debug_bin*
!.yarn/plugins
!.yarn/sdks
!.yarn/versions
# we temporarily commit this file because yarn downloading it
# somehow produces different checksum values
!.yarn/cache/pa11y-ci-https-1e9675e9e1-668c9119bd.zip
.pnp.*
# Enterprise emails
@@ -131,7 +134,9 @@ pkg/services/quota/quotaimpl/storage/storage.json
/devenv/bulk-dashboards/*.json
/devenv/bulk-folders/*/*.json
/devenv/bulk_alerting_dashboards/*.json
/devenv/datasources_bulk.yaml
/devenv/bulk_alerting_dashboards/bulk_alerting_datasources.yaml
/scripts/build/release_publisher/release_publisher
*.patch
@@ -169,11 +174,6 @@ compilation-stats.json
/e2e/build_results.zip
/e2e/extensions
/e2e/extensions-suite
/test-results/
/playwright-report/
/blob-report/
/playwright/.cache/
/playwright/.auth/
# grafana server
/scripts/grafana-server/server.log
@@ -202,7 +202,6 @@ public/api-spec.json
deployment_tools_config.json
.betterer.cache
.nx
# Temporary file for backporting PRs
.pr-body.txt
@@ -213,9 +212,3 @@ public/app/plugins/**/dist/
# Ignore transpiled JavaScript resulting from the generate-transformations.ts script.
/public/app/features/transformers/docs/*.js
/scripts/docs/generate-transformations.js
# Go coverage files created with go test -cover -coverprogile=something.out ...
*.out
# Locally enabling the Go race detector until we can globally do so
.go-race-enabled-locally

View File

@@ -1,6 +1,9 @@
[run]
timeout = "10m"
concurrency = 10
[linters-settings.goconst]
min-len = 5
min-occurrences = 5
[linters-settings.exhaustive]
default-signifies-exhaustive = true
@@ -18,7 +21,6 @@ deny = [
{ pkg = "github.com/pkg/errors", desc = "Deprecated: Go 1.13 supports the functionality provided by pkg/errors in the standard library." },
{ pkg = "github.com/xorcare/pointer", desc = "Use pkg/util.Pointer instead, which is a generic one-liner alternative" },
{ pkg = "github.com/gofrs/uuid", desc = "Use github.com/google/uuid instead, which we already depend on." },
{ pkg = "github.com/bmizerany/assert", desc = "Use github.com/stretchr/testify/assert instead, which we already depend on." },
]
[linters-settings.depguard.rules.coreplugins]
@@ -50,70 +52,10 @@ deny = [
{ pkg = "github.com/grafana/grafana/pkg/server", desc = "Core plugins are not allowed to depend on Grafana core packages" },
{ pkg = "github.com/grafana/grafana/pkg/tests", desc = "Core plugins are not allowed to depend on Grafana core packages" },
{ pkg = "github.com/grafana/grafana/pkg/web", desc = "Core plugins are not allowed to depend on Grafana core packages" },
{ pkg = "github.com/grafana/grafana/pkg/tsdb/intervalv2", desc = "Core plugins are not allowed to depend on Grafana core packages" },
]
files = [
"**/pkg/tsdb/grafana-pyroscope-datasource/*",
"**/pkg/tsdb/grafana-pyroscope-datasource/**/*",
"**/pkg/tsdb/grafana-testdata-datasource/*",
"**/pkg/tsdb/grafana-testdata-datasource/**/*",
"**/pkg/tsdb/azuremonitor/*",
"**/pkg/tsdb/azuremonitor/**/*",
"**/pkg/tsdb/cloud-monitoring/*",
"**/pkg/tsdb/cloud-monitoring/**/*",
"**/pkg/tsdb/mysql/*",
"**/pkg/tsdb/mysql/**/*",
"**/pkg/tsdb/parca/*",
"**/pkg/tsdb/parca/**/*",
"**/pkg/tsdb/tempo/*",
"**/pkg/tsdb/tempo/**/*",
"**/pkg/tsdb/cloudwatch/*",
"**/pkg/tsdb/cloudwatch/**/*",
]
[linters-settings.depguard.rules.apiserver]
list-mode = "lax"
allow = [
"github.com/grafana/grafana/pkg/apimachinery",
"github.com/grafana/grafana/pkg/apiserver",
"github.com/grafana/grafana/pkg/services/apiserver/utils",
"github.com/grafana/grafana/pkg/services/featuremgmt",
"github.com/grafana/grafana/pkg/infra/kvstore",
"github.com/grafana/grafana/pkg/services/apiserver/options",
"github.com/grafana/grafana/pkg/apis/playlist/v0alpha1",
]
deny = [
{ pkg = "github.com/grafana/grafana/pkg", desc = "apiserver is not allowed to import grafana core" }
]
files = [
"**/pkg/apiserver/*",
"**/pkg/apiserver/**/*"
]
[linters-settings.depguard.rules.apimachinery]
list-mode = "lax"
allow = [
"github.com/grafana/grafana/pkg/apimachinery",
]
deny = [
{ pkg = "github.com/grafana/grafana/pkg", desc = "apimachinery is not allowed to import grafana core" }
]
files = [
"**/pkg/apimachinery/*",
"**/pkg/apimachinery/**/*"
]
[linters-settings.depguard.rules.promlib]
list-mode = "lax" # allow unless explicitely denied
deny = [
{ pkg = "github.com/grafana/grafana/pkg", desc = "promlib is not allowed to import grafana core" }
]
allow = [
"github.com/grafana/grafana/pkg/promlib"
]
files = [
"**/pkg/promlib/*",
"**/pkg/promlib/**/*"
]
[linters-settings.gocritic]
@@ -121,9 +63,6 @@ enabled-checks = ["ruleguard"]
[linters-settings.gocritic.settings.ruleguard]
rules = "pkg/ruleguard.rules.go"
[linters-settings.misspell]
ignore-words = ["Unknwon", "Creater"]
[linters-settings.nakedret]
max-func-lines = 60
@@ -135,7 +74,7 @@ enable = [
"dogsled",
"errcheck",
# "gochecknoinits",
# "goconst",
"goconst",
# "gocritic", # Temporarily disabled on 2022-09-09, running into weird bug "ruleguard: execution error: used Run() with an empty rule set; forgot to call Load() first?"
"goimports",
"goprintffuncname",
@@ -166,7 +105,6 @@ enable = [
[issues]
exclude-use-default = false
max-same-issues = 0
# Enable when appropriate
# Poorly chosen identifier
@@ -192,13 +130,6 @@ text = "SA1019: http.CloseNotifier"
linters = ["staticcheck"]
text = "SA1019: strings.Title"
# go.opentelemetry.io/otel/exporters/jaeger" is deprecated: This module is no longer supported. OpenTelemetry dropped support for Jaeger exporter in July 2023.
# Jaeger officially accepts and recommends using OTLP.
# Use [go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp] or [go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc] instead.
[[issues.exclude-rules]]
linters = ["staticcheck"]
text = "SA1019: \"go.opentelemetry.io/otel/exporters/jaeger\""
[[issues.exclude-rules]]
linters = ["staticcheck"]
text = "use fake service and real access control evaluator instead"
@@ -239,6 +170,10 @@ text = "501"
linters = ["gosec"]
text = "404"
[[issues.exclude-rules]]
linters = ["misspell"]
text = "Unknwon` is a misspelling of `Unknown"
[[issues.exclude-rules]]
linters = ["errorlint"]
text = "non-wrapping format verb for fmt.Errorf"
@@ -257,10 +192,3 @@ text = "ST1020"
[[issues.exclude-rules]]
linters = ["stylecheck"]
text = "ST1021"
# Remove this when we have go v1.22 in place
# https://stackoverflow.com/a/68247837/767660
[[issues.exclude-rules]]
linters = ["gosec"]
path = '(.+)_test\.go'
text = "G601"

View File

@@ -34,7 +34,7 @@ var dashboardSettings = [
wait: 500,
rootElement: '.main-view',
// TODO: improve the accessibility of the permission tab https://github.com/grafana/grafana/issues/77203
threshold: 5,
threshold: 11,
},
{
url: '${HOST}/d/O6f11TZWk/panel-tests-bar-gauge?orgId=1&editview=dashboard_json',
@@ -64,7 +64,7 @@ var config = {
url: '${HOST}/login',
wait: 500,
rootElement: '.main-view',
threshold: 0,
threshold: 13,
},
{
url: '${HOST}/login',
@@ -76,13 +76,13 @@ var config = {
"click element button[data-testid='data-testid Login button']",
"wait for element button[data-testid='data-testid Skip change password button'] to be visible",
],
threshold: 2,
threshold: 15,
rootElement: '.main-view',
},
{
url: '${HOST}/?orgId=1',
wait: 500,
threshold: 0,
threshold: 3,
},
{
url: '${HOST}/d/O6f11TZWk/panel-tests-bar-gauge',
@@ -95,7 +95,7 @@ var config = {
url: '${HOST}/?orgId=1&search=open',
wait: 500,
rootElement: '.main-view',
threshold: 0,
threshold: 3,
},
{
url: '${HOST}/alerting/list',
@@ -103,49 +103,49 @@ var config = {
rootElement: '.main-view',
// the unified alerting promotion alert's content contrast is too low
// see https://github.com/grafana/grafana/pull/41829
threshold: 7,
threshold: 6,
},
{
url: '${HOST}/datasources',
wait: 500,
rootElement: '.main-view',
threshold: 0,
threshold: 3,
},
{
url: '${HOST}/org/users',
wait: 500,
rootElement: '.main-view',
threshold: 0,
threshold: 1,
},
{
url: '${HOST}/org/teams',
wait: 500,
rootElement: '.main-view',
threshold: 0,
threshold: 1,
},
{
url: '${HOST}/plugins',
wait: 500,
rootElement: '.main-view',
threshold: 0,
threshold: 3,
},
{
url: '${HOST}/org',
wait: 500,
rootElement: '.main-view',
threshold: 0,
threshold: 1,
},
{
url: '${HOST}/org/apikeys',
wait: 500,
rootElement: '.main-view',
threshold: 2,
threshold: 4,
},
{
url: '${HOST}/dashboards',
wait: 500,
rootElement: '.main-view',
threshold: 0,
threshold: 1,
},
],
};

View File

@@ -12,13 +12,16 @@ node_modules
pkg
public/lib/monaco
public/sass/*.generated.scss
scripts/cli/bettererIssueTemplate.md
scripts/grafana-server/tmp
vendor
# TS generate from cue by cuetsy
**/*.gen.ts
# Auto-generated internationalization files
public/locales/_build/
public/locales/**/*.js
# Auto-generated theme files
theme.light.generated.json
theme.dark.generated.json
@@ -28,5 +31,10 @@ public/api-merged.json
public/api-enterprise-spec.json
public/openapi3.json
# Crowdin files
public/locales/**/*.json
# Generated Kinds report
kinds/report.json
# Generated schema docs
docs/sources/developers/kinds/
scripts/cli/bettererIssueTemplate.md

47
.vscode/launch.json vendored
View File

@@ -12,51 +12,14 @@
"args": ["server", "--homepath", "${workspaceFolder}", "--packaging", "dev"]
},
{
"name": "Run API Server (testdata)",
"name": "Run API Server (k8s)",
"type": "go",
"request": "launch",
"mode": "auto",
"program": "${workspaceFolder}/pkg/cmd/grafana/",
"env": {},
"cwd": "${workspaceFolder}",
"args": ["apiserver", "--secure-port=8443", "--runtime-config=testdata.datasource.grafana.app/v0alpha1=true"]
},
{
"name": "Run API Server (query-localhost)",
"type": "go",
"request": "launch",
"mode": "auto",
"program": "${workspaceFolder}/pkg/cmd/grafana/",
"env": {},
"cwd": "${workspaceFolder}",
"args": [
"apiserver",
"--secure-port=8443",
"--runtime-config=query.grafana.app/v0alpha1=true",
"--grafana.authn.signing-keys-url=http://localhost:3000/api/signing-keys/keys",
"--hg-url=http://localhost:3000",
"--hg-key=$HGAPIKEY"
]
},
{
"name": "Run Server (query GRPC Storage Server)",
"type": "go",
"request": "launch",
"mode": "auto",
"program": "${workspaceFolder}/pkg/cmd/grafana/",
"env": {"GF_GRAFANA_APISERVER_STORAGE_TYPE": "unified-grpc"},
"cwd": "${workspaceFolder}",
"args": ["server", "--homepath", "${workspaceFolder}", "--packaging", "dev"]
},
{
"name": "Run Storage Server",
"type": "go",
"request": "launch",
"mode": "auto",
"program": "${workspaceFolder}/pkg/cmd/grafana/",
"env": {"GF_DEFAULT_TARGET": "storage-server","GF_SERVER_HTTP_PORT": "3001"},
"cwd": "${workspaceFolder}",
"args": ["server", "target", "--homepath", "${workspaceFolder}", "--packaging", "dev"]
"args": ["apiserver", "example.grafana.app"]
},
{
"name": "Attach to Chrome",
@@ -66,16 +29,14 @@
"webRoot": "${workspaceFolder}"
},
{
"name": "Debug UI test",
"name": "Debug Jest test",
"type": "node",
"request": "launch",
"runtimeExecutable": "yarn",
"runtimeArgs": ["run", "jest", "--runInBand", "${file}"],
"console": "integratedTerminal",
"internalConsoleOptions": "neverOpen",
"env": {
"NODE_ENV": "test"
}
"port": 9229
},
{
"name": "Debug Go test",

Binary file not shown.

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -1,121 +0,0 @@
diff --git a/build/GridItem.js b/build/GridItem.js
index 0a700da9f1180ca532e32e04dc7ea50f2e67b96c..a2e4673fa1133aeaa4018cc01312ca386c3395f5 100644
--- a/build/GridItem.js
+++ b/build/GridItem.js
@@ -5,6 +5,7 @@ Object.defineProperty(exports, "__esModule", {
});
exports.default = void 0;
var _react = _interopRequireDefault(require("react"));
+var _reactDOM = require("react-dom");
var _propTypes = _interopRequireDefault(require("prop-types"));
var _reactDraggable = require("react-draggable");
var _reactResizable = require("react-resizable");
@@ -147,8 +148,10 @@ class GridItem extends _react.default.Component /*:: <Props, State>*/{
const pTop = parentRect.top / transformScale;
newPosition.left = cLeft - pLeft + offsetParent.scrollLeft;
newPosition.top = cTop - pTop + offsetParent.scrollTop;
- this.setState({
- dragging: newPosition
+ _reactDOM.flushSync(() => {
+ this.setState({
+ dragging: newPosition
+ });
});
// Call callback with this data
@@ -213,8 +216,10 @@ class GridItem extends _react.default.Component /*:: <Props, State>*/{
top,
left
};
- this.setState({
- dragging: newPosition
+ _reactDOM.flushSync(() => {
+ this.setState({
+ dragging: newPosition
+ });
});
// Call callback with this data
@@ -261,8 +266,10 @@ class GridItem extends _react.default.Component /*:: <Props, State>*/{
top,
left
};
- this.setState({
- dragging: null
+ _reactDOM.flushSync(() => {
+ this.setState({
+ dragging: null
+ });
});
const {
x,
@@ -485,8 +492,10 @@ class GridItem extends _react.default.Component /*:: <Props, State>*/{
let updatedSize = size;
if (node) {
updatedSize = (0, _utils.resizeItemInDirection)(handle, position, size, containerWidth);
- this.setState({
- resizing: handlerName === "onResizeStop" ? null : updatedSize
+ _reactDOM.flushSync(() => {
+ this.setState({
+ resizing: handlerName === "onResizeStop" ? null : updatedSize
+ });
});
}
diff --git a/lib/GridItem.jsx b/lib/GridItem.jsx
index dbe41f92388f19d3e476690fa0ee5584ab9d5bb4..1e4713667cd7dadd6618fe06176804a02ee3ccc2 100644
--- a/lib/GridItem.jsx
+++ b/lib/GridItem.jsx
@@ -1,5 +1,6 @@
// @flow
import React from "react";
+import { flushSync } from "react-dom";
import PropTypes from "prop-types";
import { DraggableCore } from "react-draggable";
import { Resizable } from "react-resizable";
@@ -459,7 +460,9 @@ export default class GridItem extends React.Component<Props, State> {
const pTop = parentRect.top / transformScale;
newPosition.left = cLeft - pLeft + offsetParent.scrollLeft;
newPosition.top = cTop - pTop + offsetParent.scrollTop;
- this.setState({ dragging: newPosition });
+ flushSync(() => {
+ this.setState({ dragging: newPosition });
+ });
// Call callback with this data
const { x, y } = calcXY(
@@ -516,7 +519,9 @@ export default class GridItem extends React.Component<Props, State> {
}
const newPosition: PartialPosition = { top, left };
- this.setState({ dragging: newPosition });
+ flushSync(() => {
+ this.setState({ dragging: newPosition });
+ });
// Call callback with this data
const { containerPadding } = this.props;
@@ -549,7 +554,9 @@ export default class GridItem extends React.Component<Props, State> {
const { w, h, i, containerPadding } = this.props;
const { left, top } = this.state.dragging;
const newPosition: PartialPosition = { top, left };
- this.setState({ dragging: null });
+ flushSync(() => {
+ this.setState({ dragging: null });
+ });
const { x, y } = calcXY(
this.getPositionParams(),
@@ -605,8 +612,10 @@ export default class GridItem extends React.Component<Props, State> {
size,
containerWidth
);
- this.setState({
- resizing: handlerName === "onResizeStop" ? null : updatedSize
+ flushSync(() => {
+ this.setState({
+ resizing: handlerName === "onResizeStop" ? null : updatedSize
+ });
});
}

893
.yarn/releases/yarn-4.0.0.cjs vendored Executable file

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

20
.yarn/sdks/eslint/bin/eslint.js vendored Executable file
View File

@@ -0,0 +1,20 @@
#!/usr/bin/env node
const {existsSync} = require(`fs`);
const {createRequire} = require(`module`);
const {resolve} = require(`path`);
const relPnpApiPath = "../../../../.pnp.cjs";
const absPnpApiPath = resolve(__dirname, relPnpApiPath);
const absRequire = createRequire(absPnpApiPath);
if (existsSync(absPnpApiPath)) {
if (!process.versions.pnp) {
// Setup the environment to be able to require eslint/bin/eslint.js
require(absPnpApiPath).setup();
}
}
// Defer to the real eslint/bin/eslint.js your application uses
module.exports = absRequire(`eslint/bin/eslint.js`);

20
.yarn/sdks/eslint/lib/api.js vendored Normal file
View File

@@ -0,0 +1,20 @@
#!/usr/bin/env node
const {existsSync} = require(`fs`);
const {createRequire} = require(`module`);
const {resolve} = require(`path`);
const relPnpApiPath = "../../../../.pnp.cjs";
const absPnpApiPath = resolve(__dirname, relPnpApiPath);
const absRequire = createRequire(absPnpApiPath);
if (existsSync(absPnpApiPath)) {
if (!process.versions.pnp) {
// Setup the environment to be able to require eslint
require(absPnpApiPath).setup();
}
}
// Defer to the real eslint your application uses
module.exports = absRequire(`eslint`);

14
.yarn/sdks/eslint/package.json vendored Normal file
View File

@@ -0,0 +1,14 @@
{
"name": "eslint",
"version": "8.52.0-sdk",
"main": "./lib/api.js",
"type": "commonjs",
"bin": {
"eslint": "./bin/eslint.js"
},
"exports": {
"./package.json": "./package.json",
".": "./lib/api.js",
"./use-at-your-own-risk": "./lib/unsupported-api.js"
}
}

6
.yarn/sdks/integrations.yml vendored Normal file
View File

@@ -0,0 +1,6 @@
# This file is automatically generated by @yarnpkg/sdks.
# Manual changes might be lost!
integrations:
- vscode
- vim

7
.yarn/sdks/prettier/package.json vendored Normal file
View File

@@ -0,0 +1,7 @@
{
"name": "prettier",
"version": "3.0.0-sdk",
"main": "./index.cjs",
"type": "commonjs",
"bin": "./bin/prettier.cjs"
}

20
.yarn/sdks/typescript/bin/tsc vendored Executable file
View File

@@ -0,0 +1,20 @@
#!/usr/bin/env node
const {existsSync} = require(`fs`);
const {createRequire} = require(`module`);
const {resolve} = require(`path`);
const relPnpApiPath = "../../../../.pnp.cjs";
const absPnpApiPath = resolve(__dirname, relPnpApiPath);
const absRequire = createRequire(absPnpApiPath);
if (existsSync(absPnpApiPath)) {
if (!process.versions.pnp) {
// Setup the environment to be able to require typescript/bin/tsc
require(absPnpApiPath).setup();
}
}
// Defer to the real typescript/bin/tsc your application uses
module.exports = absRequire(`typescript/bin/tsc`);

20
.yarn/sdks/typescript/bin/tsserver vendored Executable file
View File

@@ -0,0 +1,20 @@
#!/usr/bin/env node
const {existsSync} = require(`fs`);
const {createRequire} = require(`module`);
const {resolve} = require(`path`);
const relPnpApiPath = "../../../../.pnp.cjs";
const absPnpApiPath = resolve(__dirname, relPnpApiPath);
const absRequire = createRequire(absPnpApiPath);
if (existsSync(absPnpApiPath)) {
if (!process.versions.pnp) {
// Setup the environment to be able to require typescript/bin/tsserver
require(absPnpApiPath).setup();
}
}
// Defer to the real typescript/bin/tsserver your application uses
module.exports = absRequire(`typescript/bin/tsserver`);

20
.yarn/sdks/typescript/lib/tsc.js vendored Normal file
View File

@@ -0,0 +1,20 @@
#!/usr/bin/env node
const {existsSync} = require(`fs`);
const {createRequire} = require(`module`);
const {resolve} = require(`path`);
const relPnpApiPath = "../../../../.pnp.cjs";
const absPnpApiPath = resolve(__dirname, relPnpApiPath);
const absRequire = createRequire(absPnpApiPath);
if (existsSync(absPnpApiPath)) {
if (!process.versions.pnp) {
// Setup the environment to be able to require typescript/lib/tsc.js
require(absPnpApiPath).setup();
}
}
// Defer to the real typescript/lib/tsc.js your application uses
module.exports = absRequire(`typescript/lib/tsc.js`);

225
.yarn/sdks/typescript/lib/tsserver.js vendored Normal file
View File

@@ -0,0 +1,225 @@
#!/usr/bin/env node
const {existsSync} = require(`fs`);
const {createRequire} = require(`module`);
const {resolve} = require(`path`);
const relPnpApiPath = "../../../../.pnp.cjs";
const absPnpApiPath = resolve(__dirname, relPnpApiPath);
const absRequire = createRequire(absPnpApiPath);
const moduleWrapper = tsserver => {
if (!process.versions.pnp) {
return tsserver;
}
const {isAbsolute} = require(`path`);
const pnpApi = require(`pnpapi`);
const isVirtual = str => str.match(/\/(\$\$virtual|__virtual__)\//);
const isPortal = str => str.startsWith("portal:/");
const normalize = str => str.replace(/\\/g, `/`).replace(/^\/?/, `/`);
const dependencyTreeRoots = new Set(pnpApi.getDependencyTreeRoots().map(locator => {
return `${locator.name}@${locator.reference}`;
}));
// VSCode sends the zip paths to TS using the "zip://" prefix, that TS
// doesn't understand. This layer makes sure to remove the protocol
// before forwarding it to TS, and to add it back on all returned paths.
function toEditorPath(str) {
// We add the `zip:` prefix to both `.zip/` paths and virtual paths
if (isAbsolute(str) && !str.match(/^\^?(zip:|\/zip\/)/) && (str.match(/\.zip\//) || isVirtual(str))) {
// We also take the opportunity to turn virtual paths into physical ones;
// this makes it much easier to work with workspaces that list peer
// dependencies, since otherwise Ctrl+Click would bring us to the virtual
// file instances instead of the real ones.
//
// We only do this to modules owned by the the dependency tree roots.
// This avoids breaking the resolution when jumping inside a vendor
// with peer dep (otherwise jumping into react-dom would show resolution
// errors on react).
//
const resolved = isVirtual(str) ? pnpApi.resolveVirtual(str) : str;
if (resolved) {
const locator = pnpApi.findPackageLocator(resolved);
if (locator && (dependencyTreeRoots.has(`${locator.name}@${locator.reference}`) || isPortal(locator.reference))) {
str = resolved;
}
}
str = normalize(str);
if (str.match(/\.zip\//)) {
switch (hostInfo) {
// Absolute VSCode `Uri.fsPath`s need to start with a slash.
// VSCode only adds it automatically for supported schemes,
// so we have to do it manually for the `zip` scheme.
// The path needs to start with a caret otherwise VSCode doesn't handle the protocol
//
// Ref: https://github.com/microsoft/vscode/issues/105014#issuecomment-686760910
//
// 2021-10-08: VSCode changed the format in 1.61.
// Before | ^zip:/c:/foo/bar.zip/package.json
// After | ^/zip//c:/foo/bar.zip/package.json
//
// 2022-04-06: VSCode changed the format in 1.66.
// Before | ^/zip//c:/foo/bar.zip/package.json
// After | ^/zip/c:/foo/bar.zip/package.json
//
// 2022-05-06: VSCode changed the format in 1.68
// Before | ^/zip/c:/foo/bar.zip/package.json
// After | ^/zip//c:/foo/bar.zip/package.json
//
case `vscode <1.61`: {
str = `^zip:${str}`;
} break;
case `vscode <1.66`: {
str = `^/zip/${str}`;
} break;
case `vscode <1.68`: {
str = `^/zip${str}`;
} break;
case `vscode`: {
str = `^/zip/${str}`;
} break;
// To make "go to definition" work,
// We have to resolve the actual file system path from virtual path
// and convert scheme to supported by [vim-rzip](https://github.com/lbrayner/vim-rzip)
case `coc-nvim`: {
str = normalize(resolved).replace(/\.zip\//, `.zip::`);
str = resolve(`zipfile:${str}`);
} break;
// Support neovim native LSP and [typescript-language-server](https://github.com/theia-ide/typescript-language-server)
// We have to resolve the actual file system path from virtual path,
// everything else is up to neovim
case `neovim`: {
str = normalize(resolved).replace(/\.zip\//, `.zip::`);
str = `zipfile://${str}`;
} break;
default: {
str = `zip:${str}`;
} break;
}
} else {
str = str.replace(/^\/?/, process.platform === `win32` ? `` : `/`);
}
}
return str;
}
function fromEditorPath(str) {
switch (hostInfo) {
case `coc-nvim`: {
str = str.replace(/\.zip::/, `.zip/`);
// The path for coc-nvim is in format of /<pwd>/zipfile:/<pwd>/.yarn/...
// So in order to convert it back, we use .* to match all the thing
// before `zipfile:`
return process.platform === `win32`
? str.replace(/^.*zipfile:\//, ``)
: str.replace(/^.*zipfile:/, ``);
} break;
case `neovim`: {
str = str.replace(/\.zip::/, `.zip/`);
// The path for neovim is in format of zipfile:///<pwd>/.yarn/...
return str.replace(/^zipfile:\/\//, ``);
} break;
case `vscode`:
default: {
return str.replace(/^\^?(zip:|\/zip(\/ts-nul-authority)?)\/+/, process.platform === `win32` ? `` : `/`)
} break;
}
}
// Force enable 'allowLocalPluginLoads'
// TypeScript tries to resolve plugins using a path relative to itself
// which doesn't work when using the global cache
// https://github.com/microsoft/TypeScript/blob/1b57a0395e0bff191581c9606aab92832001de62/src/server/project.ts#L2238
// VSCode doesn't want to enable 'allowLocalPluginLoads' due to security concerns but
// TypeScript already does local loads and if this code is running the user trusts the workspace
// https://github.com/microsoft/vscode/issues/45856
const ConfiguredProject = tsserver.server.ConfiguredProject;
const {enablePluginsWithOptions: originalEnablePluginsWithOptions} = ConfiguredProject.prototype;
ConfiguredProject.prototype.enablePluginsWithOptions = function() {
this.projectService.allowLocalPluginLoads = true;
return originalEnablePluginsWithOptions.apply(this, arguments);
};
// And here is the point where we hijack the VSCode <-> TS communications
// by adding ourselves in the middle. We locate everything that looks
// like an absolute path of ours and normalize it.
const Session = tsserver.server.Session;
const {onMessage: originalOnMessage, send: originalSend} = Session.prototype;
let hostInfo = `unknown`;
Object.assign(Session.prototype, {
onMessage(/** @type {string | object} */ message) {
const isStringMessage = typeof message === 'string';
const parsedMessage = isStringMessage ? JSON.parse(message) : message;
if (
parsedMessage != null &&
typeof parsedMessage === `object` &&
parsedMessage.arguments &&
typeof parsedMessage.arguments.hostInfo === `string`
) {
hostInfo = parsedMessage.arguments.hostInfo;
if (hostInfo === `vscode` && process.env.VSCODE_IPC_HOOK) {
const [, major, minor] = (process.env.VSCODE_IPC_HOOK.match(
// The RegExp from https://semver.org/ but without the caret at the start
/(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$/
) ?? []).map(Number)
if (major === 1) {
if (minor < 61) {
hostInfo += ` <1.61`;
} else if (minor < 66) {
hostInfo += ` <1.66`;
} else if (minor < 68) {
hostInfo += ` <1.68`;
}
}
}
}
const processedMessageJSON = JSON.stringify(parsedMessage, (key, value) => {
return typeof value === 'string' ? fromEditorPath(value) : value;
});
return originalOnMessage.call(
this,
isStringMessage ? processedMessageJSON : JSON.parse(processedMessageJSON)
);
},
send(/** @type {any} */ msg) {
return originalSend.call(this, JSON.parse(JSON.stringify(msg, (key, value) => {
return typeof value === `string` ? toEditorPath(value) : value;
})));
}
});
return tsserver;
};
if (existsSync(absPnpApiPath)) {
if (!process.versions.pnp) {
// Setup the environment to be able to require typescript/lib/tsserver.js
require(absPnpApiPath).setup();
}
}
// Defer to the real typescript/lib/tsserver.js your application uses
module.exports = moduleWrapper(absRequire(`typescript/lib/tsserver.js`));

View File

@@ -0,0 +1,225 @@
#!/usr/bin/env node
const {existsSync} = require(`fs`);
const {createRequire} = require(`module`);
const {resolve} = require(`path`);
const relPnpApiPath = "../../../../.pnp.cjs";
const absPnpApiPath = resolve(__dirname, relPnpApiPath);
const absRequire = createRequire(absPnpApiPath);
const moduleWrapper = tsserver => {
if (!process.versions.pnp) {
return tsserver;
}
const {isAbsolute} = require(`path`);
const pnpApi = require(`pnpapi`);
const isVirtual = str => str.match(/\/(\$\$virtual|__virtual__)\//);
const isPortal = str => str.startsWith("portal:/");
const normalize = str => str.replace(/\\/g, `/`).replace(/^\/?/, `/`);
const dependencyTreeRoots = new Set(pnpApi.getDependencyTreeRoots().map(locator => {
return `${locator.name}@${locator.reference}`;
}));
// VSCode sends the zip paths to TS using the "zip://" prefix, that TS
// doesn't understand. This layer makes sure to remove the protocol
// before forwarding it to TS, and to add it back on all returned paths.
function toEditorPath(str) {
// We add the `zip:` prefix to both `.zip/` paths and virtual paths
if (isAbsolute(str) && !str.match(/^\^?(zip:|\/zip\/)/) && (str.match(/\.zip\//) || isVirtual(str))) {
// We also take the opportunity to turn virtual paths into physical ones;
// this makes it much easier to work with workspaces that list peer
// dependencies, since otherwise Ctrl+Click would bring us to the virtual
// file instances instead of the real ones.
//
// We only do this to modules owned by the the dependency tree roots.
// This avoids breaking the resolution when jumping inside a vendor
// with peer dep (otherwise jumping into react-dom would show resolution
// errors on react).
//
const resolved = isVirtual(str) ? pnpApi.resolveVirtual(str) : str;
if (resolved) {
const locator = pnpApi.findPackageLocator(resolved);
if (locator && (dependencyTreeRoots.has(`${locator.name}@${locator.reference}`) || isPortal(locator.reference))) {
str = resolved;
}
}
str = normalize(str);
if (str.match(/\.zip\//)) {
switch (hostInfo) {
// Absolute VSCode `Uri.fsPath`s need to start with a slash.
// VSCode only adds it automatically for supported schemes,
// so we have to do it manually for the `zip` scheme.
// The path needs to start with a caret otherwise VSCode doesn't handle the protocol
//
// Ref: https://github.com/microsoft/vscode/issues/105014#issuecomment-686760910
//
// 2021-10-08: VSCode changed the format in 1.61.
// Before | ^zip:/c:/foo/bar.zip/package.json
// After | ^/zip//c:/foo/bar.zip/package.json
//
// 2022-04-06: VSCode changed the format in 1.66.
// Before | ^/zip//c:/foo/bar.zip/package.json
// After | ^/zip/c:/foo/bar.zip/package.json
//
// 2022-05-06: VSCode changed the format in 1.68
// Before | ^/zip/c:/foo/bar.zip/package.json
// After | ^/zip//c:/foo/bar.zip/package.json
//
case `vscode <1.61`: {
str = `^zip:${str}`;
} break;
case `vscode <1.66`: {
str = `^/zip/${str}`;
} break;
case `vscode <1.68`: {
str = `^/zip${str}`;
} break;
case `vscode`: {
str = `^/zip/${str}`;
} break;
// To make "go to definition" work,
// We have to resolve the actual file system path from virtual path
// and convert scheme to supported by [vim-rzip](https://github.com/lbrayner/vim-rzip)
case `coc-nvim`: {
str = normalize(resolved).replace(/\.zip\//, `.zip::`);
str = resolve(`zipfile:${str}`);
} break;
// Support neovim native LSP and [typescript-language-server](https://github.com/theia-ide/typescript-language-server)
// We have to resolve the actual file system path from virtual path,
// everything else is up to neovim
case `neovim`: {
str = normalize(resolved).replace(/\.zip\//, `.zip::`);
str = `zipfile://${str}`;
} break;
default: {
str = `zip:${str}`;
} break;
}
} else {
str = str.replace(/^\/?/, process.platform === `win32` ? `` : `/`);
}
}
return str;
}
function fromEditorPath(str) {
switch (hostInfo) {
case `coc-nvim`: {
str = str.replace(/\.zip::/, `.zip/`);
// The path for coc-nvim is in format of /<pwd>/zipfile:/<pwd>/.yarn/...
// So in order to convert it back, we use .* to match all the thing
// before `zipfile:`
return process.platform === `win32`
? str.replace(/^.*zipfile:\//, ``)
: str.replace(/^.*zipfile:/, ``);
} break;
case `neovim`: {
str = str.replace(/\.zip::/, `.zip/`);
// The path for neovim is in format of zipfile:///<pwd>/.yarn/...
return str.replace(/^zipfile:\/\//, ``);
} break;
case `vscode`:
default: {
return str.replace(/^\^?(zip:|\/zip(\/ts-nul-authority)?)\/+/, process.platform === `win32` ? `` : `/`)
} break;
}
}
// Force enable 'allowLocalPluginLoads'
// TypeScript tries to resolve plugins using a path relative to itself
// which doesn't work when using the global cache
// https://github.com/microsoft/TypeScript/blob/1b57a0395e0bff191581c9606aab92832001de62/src/server/project.ts#L2238
// VSCode doesn't want to enable 'allowLocalPluginLoads' due to security concerns but
// TypeScript already does local loads and if this code is running the user trusts the workspace
// https://github.com/microsoft/vscode/issues/45856
const ConfiguredProject = tsserver.server.ConfiguredProject;
const {enablePluginsWithOptions: originalEnablePluginsWithOptions} = ConfiguredProject.prototype;
ConfiguredProject.prototype.enablePluginsWithOptions = function() {
this.projectService.allowLocalPluginLoads = true;
return originalEnablePluginsWithOptions.apply(this, arguments);
};
// And here is the point where we hijack the VSCode <-> TS communications
// by adding ourselves in the middle. We locate everything that looks
// like an absolute path of ours and normalize it.
const Session = tsserver.server.Session;
const {onMessage: originalOnMessage, send: originalSend} = Session.prototype;
let hostInfo = `unknown`;
Object.assign(Session.prototype, {
onMessage(/** @type {string | object} */ message) {
const isStringMessage = typeof message === 'string';
const parsedMessage = isStringMessage ? JSON.parse(message) : message;
if (
parsedMessage != null &&
typeof parsedMessage === `object` &&
parsedMessage.arguments &&
typeof parsedMessage.arguments.hostInfo === `string`
) {
hostInfo = parsedMessage.arguments.hostInfo;
if (hostInfo === `vscode` && process.env.VSCODE_IPC_HOOK) {
const [, major, minor] = (process.env.VSCODE_IPC_HOOK.match(
// The RegExp from https://semver.org/ but without the caret at the start
/(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$/
) ?? []).map(Number)
if (major === 1) {
if (minor < 61) {
hostInfo += ` <1.61`;
} else if (minor < 66) {
hostInfo += ` <1.66`;
} else if (minor < 68) {
hostInfo += ` <1.68`;
}
}
}
}
const processedMessageJSON = JSON.stringify(parsedMessage, (key, value) => {
return typeof value === 'string' ? fromEditorPath(value) : value;
});
return originalOnMessage.call(
this,
isStringMessage ? processedMessageJSON : JSON.parse(processedMessageJSON)
);
},
send(/** @type {any} */ msg) {
return originalSend.call(this, JSON.parse(JSON.stringify(msg, (key, value) => {
return typeof value === `string` ? toEditorPath(value) : value;
})));
}
});
return tsserver;
};
if (existsSync(absPnpApiPath)) {
if (!process.versions.pnp) {
// Setup the environment to be able to require typescript/lib/tsserverlibrary.js
require(absPnpApiPath).setup();
}
}
// Defer to the real typescript/lib/tsserverlibrary.js your application uses
module.exports = moduleWrapper(absRequire(`typescript/lib/tsserverlibrary.js`));

20
.yarn/sdks/typescript/lib/typescript.js vendored Normal file
View File

@@ -0,0 +1,20 @@
#!/usr/bin/env node
const {existsSync} = require(`fs`);
const {createRequire} = require(`module`);
const {resolve} = require(`path`);
const relPnpApiPath = "../../../../.pnp.cjs";
const absPnpApiPath = resolve(__dirname, relPnpApiPath);
const absRequire = createRequire(absPnpApiPath);
if (existsSync(absPnpApiPath)) {
if (!process.versions.pnp) {
// Setup the environment to be able to require typescript
require(absPnpApiPath).setup();
}
}
// Defer to the real typescript your application uses
module.exports = absRequire(`typescript`);

10
.yarn/sdks/typescript/package.json vendored Normal file
View File

@@ -0,0 +1,10 @@
{
"name": "typescript",
"version": "5.2.2-sdk",
"main": "./lib/typescript.js",
"type": "commonjs",
"bin": {
"tsc": "./bin/tsc",
"tsserver": "./bin/tsserver"
}
}

View File

@@ -4,12 +4,12 @@ enableGlobalCache: false
enableTelemetry: false
nodeLinker: node-modules
nodeLinker: pnp
packageExtensions:
'croact-css-styled@1.1.9':
"@storybook/core-common@7.4.5":
dependencies:
croact: 1.0.4
'@storybook/react-webpack5': 7.4.5
doctrine@3.0.0:
dependencies:
assert: 2.0.0
@@ -21,16 +21,25 @@ packageExtensions:
peerDependencies:
react: 17.0.1
react-dom: 17.0.1
react-compat-css-styled@1.0.8:
dependencies:
react-simple-compat: 1.2.2
react-icons@2.2.7:
peerDependencies:
prop-types: "*"
react-resizable@3.0.4:
peerDependencies:
react-dom: 17.0.1
plugins:
- path: .yarn/plugins/@yarnpkg/plugin-outdated.cjs
spec: 'https://mskelton.dev/yarn-outdated/v2'
spec: "https://mskelton.dev/yarn-outdated/v2"
yarnPath: .yarn/releases/yarn-4.2.2.cjs
yarnPath: .yarn/releases/yarn-4.0.0.cjs
# Uncomment the following lines if you want to use Verdaccio local npm registry. Read more at packages/README.md
#npmScopes:
# grafana:
# npmRegistryServer: http://localhost:4873
#
#unsafeHttpWhitelist:
# - 'localhost'
# npmScopes:
# grafana:
# npmRegistryServer: http://localhost:4873
# unsafeHttpWhitelist:
# - 'localhost'

File diff suppressed because it is too large Load Diff

View File

@@ -1,9 +1,9 @@
# syntax=docker/dockerfile:1
ARG BASE_IMAGE=alpine:3.19.1
ARG JS_IMAGE=node:20-alpine
ARG BASE_IMAGE=alpine:3.18.3
ARG JS_IMAGE=node:20-alpine3.18
ARG JS_PLATFORM=linux/amd64
ARG GO_IMAGE=golang:1.22.4-alpine
ARG GO_IMAGE=golang:1.21.5-alpine3.18
ARG GO_SRC=go-builder
ARG JS_SRC=js-builder
@@ -14,18 +14,16 @@ ENV NODE_OPTIONS=--max_old_space_size=8000
WORKDIR /tmp/grafana
COPY package.json project.json nx.json yarn.lock .yarnrc.yml ./
COPY package.json yarn.lock .yarnrc.yml ./
COPY .yarn .yarn
COPY packages packages
COPY plugins-bundled plugins-bundled
COPY public public
COPY LICENSE ./
RUN apk add --no-cache make build-base python3
RUN yarn install --immutable
COPY tsconfig.json .eslintrc .editorconfig .browserslistrc .prettierrc.js ./
COPY tsconfig.json .eslintrc .editorconfig .browserslistrc .prettierrc.js babel.config.json ./
COPY public public
COPY scripts scripts
COPY emails emails
@@ -40,13 +38,10 @@ ARG GO_BUILD_TAGS="oss"
ARG WIRE_TAGS="oss"
ARG BINGO="true"
# Install build dependencies
RUN if grep -i -q alpine /etc/issue; then \
apk add --no-cache \
# This is required to allow building on arm64 due to https://github.com/golang/go/issues/22040
binutils-gold \
# Install build dependencies
gcc g++ make git; \
fi
apk add --no-cache gcc g++ make git; \
fi
WORKDIR /tmp/grafana
@@ -55,16 +50,12 @@ COPY .bingo .bingo
# Include vendored dependencies
COPY pkg/util/xorm/go.* pkg/util/xorm/
COPY pkg/apiserver/go.* pkg/apiserver/
COPY pkg/apimachinery/go.* pkg/apimachinery/
COPY pkg/build/wire/go.* pkg/build/wire/
COPY pkg/promlib/go.* pkg/promlib/
RUN go mod download
RUN if [[ "$BINGO" = "true" ]]; then \
go install github.com/bwplotka/bingo@latest && \
bingo get -v; \
fi
go install github.com/bwplotka/bingo@latest && \
bingo get -v; \
fi
COPY embed.go Makefile build.go package.json ./
COPY cue.mod cue.mod
@@ -77,6 +68,7 @@ COPY pkg pkg
COPY scripts scripts
COPY conf conf
COPY .github .github
COPY LICENSE ./
ENV COMMIT_SHA=${COMMIT_SHA}
ENV BUILD_BRANCH=${BUILD_BRANCH}
@@ -107,78 +99,78 @@ ARG GF_UID="472"
ARG GF_GID="0"
ENV PATH="/usr/share/grafana/bin:$PATH" \
GF_PATHS_CONFIG="/etc/grafana/grafana.ini" \
GF_PATHS_DATA="/var/lib/grafana" \
GF_PATHS_HOME="/usr/share/grafana" \
GF_PATHS_LOGS="/var/log/grafana" \
GF_PATHS_PLUGINS="/var/lib/grafana/plugins" \
GF_PATHS_PROVISIONING="/etc/grafana/provisioning"
GF_PATHS_CONFIG="/etc/grafana/grafana.ini" \
GF_PATHS_DATA="/var/lib/grafana" \
GF_PATHS_HOME="/usr/share/grafana" \
GF_PATHS_LOGS="/var/log/grafana" \
GF_PATHS_PLUGINS="/var/lib/grafana/plugins" \
GF_PATHS_PROVISIONING="/etc/grafana/provisioning"
WORKDIR $GF_PATHS_HOME
# Install dependencies
RUN if grep -i -q alpine /etc/issue; then \
apk add --no-cache ca-certificates bash curl tzdata musl-utils && \
apk info -vv | sort; \
elif grep -i -q ubuntu /etc/issue; then \
DEBIAN_FRONTEND=noninteractive && \
apt-get update && \
apt-get install -y ca-certificates curl tzdata musl && \
apt-get autoremove -y && \
rm -rf /var/lib/apt/lists/*; \
else \
echo 'ERROR: Unsupported base image' && /bin/false; \
fi
apk add --no-cache ca-certificates bash curl tzdata musl-utils && \
apk info -vv | sort; \
elif grep -i -q ubuntu /etc/issue; then \
DEBIAN_FRONTEND=noninteractive && \
apt-get update && \
apt-get install -y ca-certificates curl tzdata musl && \
apt-get autoremove -y && \
rm -rf /var/lib/apt/lists/*; \
else \
echo 'ERROR: Unsupported base image' && /bin/false; \
fi
# glibc support for alpine x86_64 only
RUN if grep -i -q alpine /etc/issue && [ `arch` = "x86_64" ]; then \
wget -q -O /etc/apk/keys/sgerrand.rsa.pub https://alpine-pkgs.sgerrand.com/sgerrand.rsa.pub && \
wget https://github.com/sgerrand/alpine-pkg-glibc/releases/download/2.35-r0/glibc-2.35-r0.apk \
-O /tmp/glibc-2.35-r0.apk && \
wget https://github.com/sgerrand/alpine-pkg-glibc/releases/download/2.35-r0/glibc-bin-2.35-r0.apk \
-O /tmp/glibc-bin-2.35-r0.apk && \
apk add --force-overwrite --no-cache /tmp/glibc-2.35-r0.apk /tmp/glibc-bin-2.35-r0.apk && \
rm -f /lib64/ld-linux-x86-64.so.2 && \
ln -s /usr/glibc-compat/lib64/ld-linux-x86-64.so.2 /lib64/ld-linux-x86-64.so.2 && \
rm -f /tmp/glibc-2.35-r0.apk && \
rm -f /tmp/glibc-bin-2.35-r0.apk && \
rm -f /lib/ld-linux-x86-64.so.2 && \
rm -f /etc/ld.so.cache; \
fi
wget -q -O /etc/apk/keys/sgerrand.rsa.pub https://alpine-pkgs.sgerrand.com/sgerrand.rsa.pub && \
wget https://github.com/sgerrand/alpine-pkg-glibc/releases/download/2.35-r0/glibc-2.35-r0.apk \
-O /tmp/glibc-2.35-r0.apk && \
wget https://github.com/sgerrand/alpine-pkg-glibc/releases/download/2.35-r0/glibc-bin-2.35-r0.apk \
-O /tmp/glibc-bin-2.35-r0.apk && \
apk add --force-overwrite --no-cache /tmp/glibc-2.35-r0.apk /tmp/glibc-bin-2.35-r0.apk && \
rm -f /lib64/ld-linux-x86-64.so.2 && \
ln -s /usr/glibc-compat/lib64/ld-linux-x86-64.so.2 /lib64/ld-linux-x86-64.so.2 && \
rm -f /tmp/glibc-2.35-r0.apk && \
rm -f /tmp/glibc-bin-2.35-r0.apk && \
rm -f /lib/ld-linux-x86-64.so.2 && \
rm -f /etc/ld.so.cache; \
fi
COPY --from=go-src /tmp/grafana/conf ./conf
RUN if [ ! $(getent group "$GF_GID") ]; then \
if grep -i -q alpine /etc/issue; then \
addgroup -S -g $GF_GID grafana; \
else \
addgroup --system --gid $GF_GID grafana; \
fi; \
fi && \
GF_GID_NAME=$(getent group $GF_GID | cut -d':' -f1) && \
mkdir -p "$GF_PATHS_HOME/.aws" && \
if grep -i -q alpine /etc/issue; then \
adduser -S -u $GF_UID -G "$GF_GID_NAME" grafana; \
else \
adduser --system --uid $GF_UID --ingroup "$GF_GID_NAME" grafana; \
fi && \
mkdir -p "$GF_PATHS_PROVISIONING/datasources" \
"$GF_PATHS_PROVISIONING/dashboards" \
"$GF_PATHS_PROVISIONING/notifiers" \
"$GF_PATHS_PROVISIONING/plugins" \
"$GF_PATHS_PROVISIONING/access-control" \
"$GF_PATHS_PROVISIONING/alerting" \
"$GF_PATHS_LOGS" \
"$GF_PATHS_PLUGINS" \
"$GF_PATHS_DATA" && \
cp conf/sample.ini "$GF_PATHS_CONFIG" && \
cp conf/ldap.toml /etc/grafana/ldap.toml && \
chown -R "grafana:$GF_GID_NAME" "$GF_PATHS_DATA" "$GF_PATHS_HOME/.aws" "$GF_PATHS_LOGS" "$GF_PATHS_PLUGINS" "$GF_PATHS_PROVISIONING" && \
chmod -R 777 "$GF_PATHS_DATA" "$GF_PATHS_HOME/.aws" "$GF_PATHS_LOGS" "$GF_PATHS_PLUGINS" "$GF_PATHS_PROVISIONING"
if grep -i -q alpine /etc/issue; then \
addgroup -S -g $GF_GID grafana; \
else \
addgroup --system --gid $GF_GID grafana; \
fi; \
fi && \
GF_GID_NAME=$(getent group $GF_GID | cut -d':' -f1) && \
mkdir -p "$GF_PATHS_HOME/.aws" && \
if grep -i -q alpine /etc/issue; then \
adduser -S -u $GF_UID -G "$GF_GID_NAME" grafana; \
else \
adduser --system --uid $GF_UID --ingroup "$GF_GID_NAME" grafana; \
fi && \
mkdir -p "$GF_PATHS_PROVISIONING/datasources" \
"$GF_PATHS_PROVISIONING/dashboards" \
"$GF_PATHS_PROVISIONING/notifiers" \
"$GF_PATHS_PROVISIONING/plugins" \
"$GF_PATHS_PROVISIONING/access-control" \
"$GF_PATHS_PROVISIONING/alerting" \
"$GF_PATHS_LOGS" \
"$GF_PATHS_PLUGINS" \
"$GF_PATHS_DATA" && \
cp conf/sample.ini "$GF_PATHS_CONFIG" && \
cp conf/ldap.toml /etc/grafana/ldap.toml && \
chown -R "grafana:$GF_GID_NAME" "$GF_PATHS_DATA" "$GF_PATHS_HOME/.aws" "$GF_PATHS_LOGS" "$GF_PATHS_PLUGINS" "$GF_PATHS_PROVISIONING" && \
chmod -R 777 "$GF_PATHS_DATA" "$GF_PATHS_HOME/.aws" "$GF_PATHS_LOGS" "$GF_PATHS_PLUGINS" "$GF_PATHS_PROVISIONING"
COPY --from=go-src /tmp/grafana/bin/grafana* /tmp/grafana/bin/*/grafana* ./bin/
COPY --from=js-src /tmp/grafana/public ./public
COPY --from=js-src /tmp/grafana/LICENSE ./
COPY --from=go-src /tmp/grafana/LICENSE ./
EXPOSE 3000

View File

@@ -173,7 +173,7 @@ Supermajority votes must be called explicitly in a separate thread on the approp
Votes may take the form of a single proposal, with the option to vote yes or no, or the form of multiple alternatives.
A vote on a single proposal is considered successful if at least two thirds of those eligible to vote in favor.
A vote on a single proposal is considered successful if at least two thirds of those eligible to vote vote in favor.
If there are multiple alternatives, members may vote for one or more alternatives, or vote “no” to object to all alternatives. A vote on multiple alternatives is considered decided in favor of one alternative if it has received the most votes in favor, and a vote from at least two thirds of those eligible to vote. Should no alternative reach this quorum, another vote on a reduced number of options may be called separately.

View File

@@ -2,4 +2,4 @@
List of previous team members that have had a big impact on the company or the product and contributed during a long period of time.
- Hugo Häggmark ([Björn Lundén](https://www.bjornlunden.se/))
- Hugo Häggmark ([School of applied technology](https://salt.study))

364
ISSUE_TRIAGE.md Normal file
View File

@@ -0,0 +1,364 @@
# Triage issues
The main goal of issue triage is to categorize all incoming Grafana issues and make sure each issue has all basic information needed for anyone else to understand and be able to start working on it.
> **Note:** This information is for Grafana project Maintainers, Owners, and Admins. If you are a Contributor, then you will not be able to perform most of the tasks in this topic.
The core maintainers of the Grafana project are responsible for categorizing all incoming issues and delegating any critical or important issue to other maintainers. Currently one maintainer each week is responsible. Besides that part, triage provides an important way to contribute to an open source project.
Triage helps ensure issues resolve quickly by:
- Ensuring the issue's intent and purpose is conveyed precisely. This is necessary because it can be difficult for an issue to explain how an end user experiences a problem and what actions they took.
- Giving a contributor the information they need before they commit to resolving an issue.
- Lowering the issue count by preventing duplicate issues.
- Streamlining the development process by preventing duplicate discussions.
If you don't have the knowledge or time to code, consider helping with triage. The community will thank you for saving them time by spending some of yours.
## Simplified flowchart diagram of the issue triage process
<!-- https://textik.com/#610afa78553def29 -->
```
+-------------------+
| |
| new issue/ | +
| more info added |
| |
+---------|---------+
|
+-------------|-----------+
| |
NO +------- all info needed to ------+ YES
| | categorize the issue? | |
| | | |
| +-------------------------+ |
+------|-----------+ +------------|----------+
| | | |
| label: | | label: type/* |
| needs more info | | label: area/* |
| | | label: datasource/* |
+------------------+ | | |
+------------|----------+
|
+--------|-------+
| |
NO +---------- is duplicate? --------------------+ YES
| | | |
| +----------------+ |
| +----------------|---------------+
+------|-----+ | |
| | | add comment: |
NO +------------ can repro? ------------+ YES | |
| | | | | /duplicate of #<issue number> |
| +------------+ | | |
| | +--------------------------------+
+-------------|-------------+ |
| | +--------|---------+
| label: | | |
| triage/needs-confirmation | NO +-------- needs priority? ------+ YES
| | | | | |
+-------------|-------------+ | +------------------+ |
| | |
+-------------|------+ +-------|--------+ +----------|---------+
| | | | | |
| Assign to project ------ Done -------------- label: priority/* |
| | | | | |
+--------------------+ +----------------+ +--------------------+
```
## 1. Find uncategorized issues
To get started with issue triage and finding issues that haven't been triaged you have two alternatives.
### Browse unlabeled issues
The easiest and straight forward way of getting started and finding issues that haven't been triaged is to browse [unlabeled issues](https://github.com/grafana/grafana/issues?q=is%3Aopen+is%3Aissue+no%3Alabel) and starting from the bottom and working yourself to the top.
### Subscribe to all notifications
The more advanced, but recommended way is to subscribe to all notifications from this repository which means that all new issues, pull requests, comments and important status changes are sent to your configured email address. Read this [guide](https://help.github.com/en/articles/watching-and-unwatching-repositories#watching-a-single-repository) for help with setting this up.
It's highly recommended that you setup filters to automatically remove emails from the inbox and label/categorize them accordingly to make it easy for you to understand when you need to act upon a notification or where to look for finding issues that haven't been triaged etc.
Instructions for setting up filters in Gmail can be found [here](#setting-up-gmail-filters). Another alternative is to use [Trailer](https://github.com/ptsochantaris/trailer) or similar software.
## 2. Ensure the issue contains basic information
Before triaging an issue very far, make sure that the issue's author provided the standard issue information. This will help you make an educated recommendation on how to categorize the issue. The Grafana project utilizes [GitHub issue templates](https://docs.github.com/en/communities/using-templates-to-encourage-useful-issues-and-pull-requests/configuring-issue-templates-for-your-repository) to guide contributors to provide standard information that must be included for each type of template or type of issue.
### Standard issue information that must be included
Given a certain [issue template](https://github.com/grafana/grafana/issues/new/choose) have been used by the issue author or depending how the issue is perceived by the issue triage responsible, the following should help you understand what standard issue information that must be included.
#### Bug reports
Should explain what happened, what was expected and how to reproduce it together with any additional information that may help giving a complete picture of what happened such as screenshots, [query inspector](https://community.grafana.com/t/using-grafanas-query-inspector-to-troubleshoot-issues/2630) output and any environment related information that's applicable and/or maybe related to the reported problem:
- Grafana version:
- Data source type & version:
- OS Grafana is installed on:
- User OS & Browser:
- Grafana plugins:
- Others:
#### Enhancement requests
Prior to August, 2023, community-submitted feature requests were submitted as [Github discussions](https://github.com/grafana/grafana/discussions). These are now submitted using the [feature request issue template](https://github.com/grafana/grafana/issues/new?assignees=&labels=type%2Ffeature-request&projects=&template=1-feature_requests.md).
When submitting an enhancement request we ask that users focus on the problem they'd like to solve and why its a problem rather than focusing on the solution itself. To facilitate this the feature requests template includes the following:
- What would you like to be added?:
- Why is this needed (describe your use case and goals)\*\*?:
#### Accessibility issues
This is a mix between a bug report and enhancement request but focused on accessibility issues to help make Grafana improve keyboard navigation, screen-reader support and being accessible to everyone. The report should include relevant [WCAG criteria](https://www.w3.org/WAI/WCAG21/quickref/?versions=2.0), if applicable.
Grafana Labs is dedicated to improving our graphical user interfaces and overall experience so that our product becomes usable and accessible for people with disabilities as well as anyone else. Learn more about Grafana's commitment to [A11y](https://grafana.com/accessibility/) (accessibility).
#### Support requests
In general, if the issue description and title is perceived as a question no more information is needed. See how to categorize these requests [here](#support-requests-1).
### Good practices
To make it easier for everyone to understand and find issues they're searching for it's suggested as a general rule of thumbs to:
- Make sure that issue titles are named to explain the subject of the issue, has a correct spelling and doesn't include irrelevant information and/or sensitive information.
- Make sure that issue descriptions doesn't include irrelevant information, information from template that haven't been filled out and/or sensitive information.
- Do your best effort to change title and description or request suggested changes by adding a comment.
> **Note:** Above rules is applicable to both new and existing issues of the Grafana project.
### Do you have all the information needed to categorize an issue?
Depending on the issue, you might not feel all this information is needed. Use your best judgement. If you cannot triage an issue using what its author provided, explain kindly to the author that they must provide the above information to clarify the problem. Label issue with `needs more info` and add any related `area/*` or `datasource/*` labels. Alternatively, use `bot/needs more info` label and the Grafana bot will request it for you.
If the author provides the standard information but you are still unable to triage the issue, request additional information. Do this kindly and politely because you are asking for more of the author's time.
If the author does not respond to the requested information within the timespan of a week, close the issue with a kind note stating that the author can request for the issue to be reopened when the necessary information is provided.
When you feel you have all the information needed you're ready to [categorizing the issue](#3-categorizing-an-issue).
If you receive a notification with additional information provided but you are not anymore on issue triage and you feel you do not have time to handle it, you should delegate it to the current person on issue triage.
## 3. Categorizing an issue
An issue can have multiple of the following labels. Typically, a properly categorized issue should at least have:
- One label identifying its type (`type/*`).
- One or multiple labels identifying the functional areas of interest or component (`area/*`) and/or data source (`datasource/*`), if applicable.
| Label | Description |
| ------------------------ | ------------------------------------------------------------------------- |
| `type/bug` | A feature isn't working as expected given design or documentation. |
| `type/feature-request` | Request for a new feature or enhancement. |
| `type/docs` | Documentation problem or enhancement. |
| `type/accessibility` | Accessibility problem or enhancement. |
| `type/question` | Issue is a question or is perceived as such. |
| `type/duplicate` | An existing issue of the same subject/request have already been reported. |
| `type/works-as-intended` | A reported bug works as intended/by design. |
| `type/build-packaging` | Build or packaging problem or enhancement. |
| `area/*` | Subject is related to a functional area of interest or component. |
| `datasource/*` | Subject is related to a core data source plugin. |
### Duplicate issues
Make sure it's not a duplicate by searching existing issues using related terms from the issue title and description. If you think you know there is an existing issue, but can't find it, please reach out to one of the maintainers and ask for help. If you identify that the issue is a duplicate of an existing issue:
1. Add a comment `/duplicate of #<issue number>`. GitHub will recognize this and add some additional context to the issue activity.
2. The Grafana bot will do the rest, adding the correct label and closing comment
3. Add `type/duplicate` label. Optionally add any related `area/*` or `datasource/*` labels.
### Bug reports
If it's not perfectly clear that it's an actual bug, quickly try to reproduce it.
**It's a bug/it can be reproduced:**
1. Add a comment describing detailed steps for how to reproduce it, if applicable.
2. Label the issue `type/bug` and at least one `area/*` or `datasource/*` label.
3. If you know that maintainers wont be able to put any resources into it for some time then label the issue with `help wanted` and optionally `beginner friendly` together with pointers on which code to update to fix the bug. This should signal to the community that we would appreciate any help we can get to resolve this.
4. Move on to [prioritizing the issue](#4-prioritization-of-issues).
**It can't be reproduced:**
1. Either [ask for more information](#2-ensure-the-issue-contains-basic-information) needed to investigate it more thoroughly.
2. Either [delegate further investigations](#investigation-of-issues) to someone else.
**It works as intended/by design:**
1. Kindly and politely add a comment explaining briefly why we think it works as intended and close the issue.
2. Label the issue `type/works-as-intended`.
### Enhancement/feature?
1. Label the issue `type/feature-request` and add at least one `area/*` or `datasource/*` label.
2. Make sure the submitter has justified why this feature requests is important.
### Documentation issue?
First, evaluate if the documentation makes sense to be included in the Grafana project:
- Is this something we want/can maintain as a project?
- Is this referring to usage of some specific integration/tool and in that case is that a popular use case in combination with Grafana?
- If unsure, kindly and politely add a comment explaining that we would need [upvotes](https://github.blog/2016-03-10-add-reactions-to-pull-requests-issues-and-comments) to identify that lots of other users want/need this.
Second, label the issue `type/docs` and at least one `area/*` or `datasource/*` label.
**Minor typo/error/lack of information:**
There's a minor typo/error/lack of information that adds a lot of confusion for users and given the amount of work is a big win to make sure fixing it:
1. Either update the documentation yourself and open a pull request.
2. Either delegate the work to someone else by assigning that person to the issue and add the issue to next major/minor milestone.
**Major error/lack of information:**
1. Label the issue with `help wanted` and `beginner friendly`, if applicable, to signal that we find this important to fix and we would appreciate any help we can get from the community.
2. Move on to [prioritizing the issue](#4-prioritization-of-issues).
### Accessibility issues
1. Label the issue `type/accessibility` and at least one `area/*` or `datasource/*` label.
### Support requests
1. Kindly and politely direct the issue author to the [community site](https://community.grafana.com/) and explain that GitHub is mainly used for tracking bugs and feature requests. If possible, it's usually a good idea to add some pointers to the issue author's question.
2. Label the issue with `bot/question`. The Grafana bot will automatically close the issue, and it will add the type/question label for you.
## 4. Prioritization of issues
In general bugs and enhancement issues should be labeled with a priority.
This is the most difficult thing with triaging issues since it requires a lot of knowledge, context and experience before being able to think of and start feel comfortable adding a certain priority label.
The key here is asking for help and discuss issues to understand how more experienced project members think and reason. By doing that you learn more and eventually be more and more comfortable with prioritizing issues.
In case there is an uncertainty around the prioritization of an issue, please ask the maintainers for help.
| Label | Description |
| --------------------------------- | ------------------------------------------------------------------------------------------------------------------------ |
| `priority/critical` | Highest priority. Must be actively worked on as someone's top priority right now. |
| `priority/support-subscription` | This is important for one or several customers having a paid Grafana support subscription. |
| `priority/important-soon` | Must be staffed and worked on either currently, or very soon, ideally in time for the next release. |
| `priority/important-longterm` | Important over the long term, but may not be staffed and/or may need multiple releases to complete. |
| `priority/nice-to-have` | It's a good idea, but not scheduled for any release. |
| `priority/awaiting-more-evidence` | Lowest priority. Possibly useful, but not yet enough interest in it. |
| `priority/unscheduled` | Something to look into before and to be discussed during the planning of the next (upcoming) major/minor stable release. |
**Critical bugs**
1. If a bug has been categorized and any of the following criteria apply, the bug should be labeled as critical and must be actively worked on as someone's top priority right now.
- Results in any data loss
- Critical security or performance issues
- Problem that makes a feature unusable
- Multiple users experience a severe problem affecting their business, users etc.
2. Label the issue `priority/critical`.
3. If applicable, label the issue `priority/support-subscription`.
4. Add the issue to the next upcoming patch release milestone. Create a new milestone if there are none.
5. Escalate the problem to the maintainers.
6. Assign or ask a maintainer for help assigning someone to make this issue their top priority right now.
**Important short-term**
1. Label the issue `priority/important-soon`.
2. If applicable, label the issue `priority/support-subscription`.
3. Add the issue to the next upcoming patch or major/minor stable release milestone. Ask maintainers for help if unsure if it's a patch or not. Create a new milestone if there are none.
4. Make sure to add the issue to a suitable backlog of a GitHub project and prioritize it or assign someone to work on it now or very soon.
5. Consider requesting [help from the community](#5-requesting-help-from-the-community), even though it may be problematic given a short amount of time until it should be released.
**Important long-term**
1. Label the issue `priority/important-longterm`.
2. Consider requesting [help from the community](#5-requesting-help-from-the-community).
**Nice to have**
1. Label the issue `priority/nice-to-have`.
2. Consider requesting [help from the community](#5-requesting-help-from-the-community).
**Not critical, but unsure?**
1. Label the issue `priority/unscheduled`.
2. Consider requesting [help from the community](#5-requesting-help-from-the-community).
## 5. Requesting help from the community
Depending on the issue and/or priority, it's always a good idea to consider signalling to the community that help from community is appreciated and needed in case an issue is not prioritized to be worked on by maintainers. Use your best judgement. In general, requesting help from the community means that a contribution has a good chance of getting accepted and merged.
In many cases the issue author or community as a whole is more suitable to contribute changes since they're experts in their domain. It's also quite common that someone has tried to get something to work using the documentation without success and made an effort to get it to work and/or reached out to the [community site](https://community.grafana.com/) to get the missing information. Particularly in these areas it's more likely that there exist experts in their own domain and it is usually a good idea to request help from contributors:
- Database setups
- Authentication like OAuth providers and LDAP setups
- Platform specific things
- Reverse proxy setups
- Alert notifiers
1. Kindly and politely add a comment to signal to users subscribed to updates of the issue.
- Explain that the issue would be nice to get resolved, but it isn't prioritized to work on by maintainers for an unforeseen future.
- If possible or applicable, try to help contributors getting starting by adding pointers and references to what code/files need to be changed and/or ideas of a good way to solve/implement the issue.
2. Label the issue with `help wanted`.
3. If applicable, label the issue with `beginner friendly` to denote that the issue is suitable for a beginner to work on.
4. If possible, try to estimate the amount of work by adding `effort/small`, `effort/medium` or `effort/large`.
## Investigation of issues
When an issue has all basic information provided, but the triage responsible haven't been able to reproduce the reported problem at a first glance, the issue is labeled [`triage/needs-confirmation`](https://github.com/grafana/grafana/labels/triage%2Fneeds-confirmation). Depending on the perceived severity and/or number of [upvotes](https://github.blog/2016-03-10-add-reactions-to-pull-requests-issues-and-comments), the investigation will either be delegated to another maintainer for further investigation or put on hold until someone else (maintainer or contributor) picks it up and eventually starts investigating it.
Investigating issues can be a very time consuming task, especially for the maintainers, given the huge number of combinations of plugins, data sources, platforms, databases, browsers, tools, hardware, integrations, versions and cloud services, etc that are being used with Grafana. There is a certain number of combinations that are more common than others, and these are in general easier for maintainers to investigate.
For some other combinations it may not be possible at all for a maintainer to setup a proper test environment to investigate the issue. In these cases we really appreciate any help we can get from the community. Otherwise the issue is highly likely to be closed.
Even if you don't have the time or knowledge to investigate an issue we highly recommend that you [upvote](https://github.blog/2016-03-10-add-reactions-to-pull-requests-issues-and-comments) the issue if you happen to have the same problem. If you have further details that may help investigating the issue please provide as much information as possible.
## Automation
We have some automation that triggers on comments or labels being added to issues. Many of these automated behaviors are defined in [commands.json](https://github.com/grafana/grafana/blob/main/.github/commands.json). Or in other [GitHub Actions](https://github.com/grafana/grafana/tree/main/.github/workflows)
[Read more on bot actions](https://github.com/grafana/grafana/blob/main/.github/bot.md)
## External PRs
Part of issue triage should also be triaging of external PRs. Main goal should be to make sure PRs from external contributors have an owner/reviewer and are not forgotten.
1. Check new external PRs which do not have a reviewer. You can easily search for pull requests made by external contributors by using the label: `pr/external` in your [query search](https://github.com/grafana/grafana/pulls?q=is%3Aopen+is%3Apr+label%3Apr%2Fexternal) Note: external PRs are automatically labeled with `pr/external` upon creation.
2. Check if there is a link to an existing issue. The link to a existing issue should be in the description section, underneath “Which issue(s) does this PR fix?:”.
3. If not and you know which issue it is solving, add the link yourself, otherwise ask the author to link the issue or create one.
4. Assign a reviewer based on who was handling the linked issue or what code or feature does the PR touches (look at who was the last to make changes there if all else fails).
## Appendix
### Setting up Gmail filters
If you're using Gmail it's highly recommended that you setup filters to automatically remove email from the inbox and label them accordingly to make it easy for you to understand when you need to act upon a notification or process all incoming issues that haven't been triaged.
This may be setup by personal preference, but here's a working configuration for reference.
1. Follow instructions in [gist](https://gist.github.com/marefr/9167c2e31466f6316c1cba118874e74f)
2. In Gmail, go to Settings -> Filters and Blocked Addresses
3. Import filters -> select xml file -> Open file
4. Review filters
5. Optional, Check Apply new filters to existing email
6. Create filters
This will give you a structure of labels in the sidebar similar to the following:
```
- Inbox
...
- GitHub (mine)
- activity
- assigned
- mentions
- GitHub (other)
- Grafana
```
- All notifications youll need to read/take action on show up as unread in GitHub (mine) and its sub-labels.
- All other notifications you dont need to take action on show up as unread in GitHub (other) and its sub-labels
- This is convenient for issue triage and to follow the activity in the Grafana project.

View File

@@ -10,6 +10,7 @@ The following directories and their subdirectories are licensed under Apache-2.0
```
packages/grafana-data/
packages/grafana-e2e/
packages/grafana-e2e-selectors/
packages/grafana-runtime/
packages/grafana-ui/
@@ -17,7 +18,7 @@ packaging/
kinds/
pkg/kinds/
pkg/kindsys/
pkg/registry/schemas/
pkg/registry/corekind/
grafana-mixin/
public/app/plugins/datasource/tempo
public/app/features/explore/TraceView/components

149
Makefile
View File

@@ -7,37 +7,29 @@ WIRE_TAGS = "oss"
-include local/Makefile
include .bingo/Variables.mk
.PHONY: all deps-go deps-js deps build-go build-backend build-server build-cli build-js build build-docker-full build-docker-full-ubuntu lint-go golangci-lint test-go test-js gen-ts test run run-frontend clean devenv devenv-down protobuf drone help gen-go gen-cue fix-cue
GO = go
GO_VERSION = 1.22.4
GO_FILES ?= ./pkg/... ./pkg/apiserver/... ./pkg/apimachinery/... ./pkg/promlib/...
GO_FILES ?= ./pkg/...
SH_FILES ?= $(shell find ./scripts -name *.sh)
GO_RACE := $(shell [ -n "$(GO_RACE)" -o -e ".go-race-enabled-locally" ] && echo 1 )
GO_RACE_FLAG := $(if $(GO_RACE),-race)
GO_BUILD_FLAGS += $(if $(GO_BUILD_DEV),-dev)
GO_BUILD_FLAGS += $(if $(GO_BUILD_TAGS),-build-tags=$(GO_BUILD_TAGS))
GO_BUILD_FLAGS += $(GO_RACE_FLAG)
targets := $(shell echo '$(sources)' | tr "," " ")
GO_INTEGRATION_TESTS := $(shell find ./pkg -type f -name '*_test.go' -exec grep -l '^func TestIntegration' '{}' '+' | grep -o '\(.*\)/' | sort -u)
.PHONY: all
all: deps build
##@ Dependencies
.PHONY: deps-go
deps-go: ## Install backend dependencies.
$(GO) run $(GO_RACE_FLAG) build.go setup
$(GO) run build.go setup
.PHONY: deps-js
deps-js: node_modules ## Install frontend dependencies.
.PHONY: deps
deps: deps-js ## Install all dependencies.
.PHONY: node_modules
node_modules: package.json yarn.lock ## Install node modules.
@echo "install frontend dependencies"
YARN_ENABLE_PROGRESS_BARS=false yarn install --immutable
@@ -53,13 +45,12 @@ $(NGALERT_SPEC_TARGET):
$(MERGED_SPEC_TARGET): swagger-oss-gen swagger-enterprise-gen $(NGALERT_SPEC_TARGET) $(SWAGGER) ## Merge generated and ngalert API specs
# known conflicts DsPermissionType, AddApiKeyCommand, Json, Duration (identical models referenced by both specs)
$(SWAGGER) mixin -q $(SPEC_TARGET) $(ENTERPRISE_SPEC_TARGET) $(NGALERT_SPEC_TARGET) --ignore-conflicts -o $(MERGED_SPEC_TARGET)
$(SWAGGER) mixin $(SPEC_TARGET) $(ENTERPRISE_SPEC_TARGET) $(NGALERT_SPEC_TARGET) --ignore-conflicts -o $(MERGED_SPEC_TARGET)
.PHONY: swagger-oss-gen
swagger-oss-gen: $(SWAGGER) ## Generate API Swagger specification
@echo "re-generating swagger for OSS"
rm -f $(SPEC_TARGET)
SWAGGER_GENERATE_EXTENSION=false $(SWAGGER) generate spec -q -m -w pkg/server -o $(SPEC_TARGET) \
SWAGGER_GENERATE_EXTENSION=false $(SWAGGER) generate spec -m -w pkg/server -o $(SPEC_TARGET) \
-x "github.com/grafana/grafana/pkg/services/ngalert/api/tooling/definitions" \
-x "github.com/prometheus/alertmanager" \
-i pkg/api/swagger_tags.json \
@@ -67,7 +58,6 @@ swagger-oss-gen: $(SWAGGER) ## Generate API Swagger specification
--exclude-tag=enterprise
# this file only exists if enterprise is enabled
.PHONY: swagger-enterprise-gen
ENTERPRISE_EXT_FILE = pkg/extensions/ext.go
ifeq ("$(wildcard $(ENTERPRISE_EXT_FILE))","") ## if enterprise is not enabled
swagger-enterprise-gen:
@@ -76,7 +66,7 @@ else
swagger-enterprise-gen: $(SWAGGER) ## Generate API Swagger specification
@echo "re-generating swagger for enterprise"
rm -f $(ENTERPRISE_SPEC_TARGET)
SWAGGER_GENERATE_EXTENSION=false $(SWAGGER) generate spec -q -m -w pkg/server -o $(ENTERPRISE_SPEC_TARGET) \
SWAGGER_GENERATE_EXTENSION=false $(SWAGGER) generate spec -m -w pkg/server -o $(ENTERPRISE_SPEC_TARGET) \
-x "github.com/grafana/grafana/pkg/services/ngalert/api/tooling/definitions" \
-x "github.com/prometheus/alertmanager" \
-i pkg/api/swagger_tags.json \
@@ -84,14 +74,11 @@ swagger-enterprise-gen: $(SWAGGER) ## Generate API Swagger specification
--include-tag=enterprise
endif
.PHONY: swagger-gen
swagger-gen: gen-go $(MERGED_SPEC_TARGET) swagger-validate
.PHONY: swagger-validate
swagger-validate: $(MERGED_SPEC_TARGET) $(SWAGGER) ## Validate API spec
$(SWAGGER) validate --skip-warnings $(<)
$(SWAGGER) validate $(<)
.PHONY: swagger-clean
swagger-clean:
rm -f $(SPEC_TARGET) $(MERGED_SPEC_TARGET) $(OAPI_SPEC_TARGET)
@@ -110,92 +97,57 @@ lefthook-uninstall: $(LEFTHOOK)
##@ OpenAPI 3
OAPI_SPEC_TARGET = public/openapi3.json
.PHONY: openapi3-gen
openapi3-gen: swagger-gen ## Generates OpenApi 3 specs from the Swagger 2 already generated
$(GO) run $(GO_RACE_FLAG) scripts/openapi3/openapi3conv.go $(MERGED_SPEC_TARGET) $(OAPI_SPEC_TARGET)
##@ Internationalisation
.PHONY: i18n-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
i18n-extract-enterprise:
@echo "Extracting i18n strings for Enterprise"
yarn run i18next --config public/locales/i18next-parser-enterprise.config.cjs
node ./public/locales/pseudo.mjs --mode enterprise
endif
.PHONY: i18n-extract
i18n-extract: i18n-extract-enterprise
@echo "Extracting i18n strings for OSS"
yarn run i18next --config public/locales/i18next-parser.config.cjs
node ./public/locales/pseudo.mjs --mode oss
$(GO) run scripts/openapi3/openapi3conv.go $(MERGED_SPEC_TARGET) $(OAPI_SPEC_TARGET)
##@ Building
.PHONY: gen-cue
gen-cue: ## Do all CUE/Thema code generation
@echo "generate code from .cue files"
go generate ./pkg/plugins/plugindef
go generate ./kinds/gen.go
go generate ./public/app/plugins/gen.go
go generate ./pkg/kindsysreport/codegen/report.go
.PHONY: gen-feature-toggles
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"
go test -v ./pkg/services/featuremgmt/... > /dev/null 2>&1; \
if [ $$? -eq 0 ]; then \
echo "feature toggles already up-to-date"; \
else \
go test -v ./pkg/services/featuremgmt/...; \
fi
.PHONY: gen-go
gen-go:
gen-go: $(WIRE)
@echo "generate go files"
$(GO) run $(GO_RACE_FLAG) ./pkg/build/wire/cmd/wire/main.go gen -tags $(WIRE_TAGS) ./pkg/server
$(WIRE) gen -tags $(WIRE_TAGS) ./pkg/server
.PHONY: fix-cue
fix-cue: $(CUE)
@echo "formatting cue files"
$(CUE) fix kinds/**/*.cue
$(CUE) fix public/app/plugins/**/**/*.cue
.PHONY: gen-jsonnet
gen-jsonnet:
go generate ./devenv/jsonnet
.PHONY: build-go
build-go: gen-go ## Build all Go binaries.
@echo "build go files"
$(GO) run build.go $(GO_BUILD_FLAGS) build
.PHONY: build-backend
build-backend: ## Build Grafana backend.
@echo "build backend"
$(GO) run build.go $(GO_BUILD_FLAGS) build-backend
.PHONY: build-server
build-server: ## Build Grafana server.
@echo "build server"
$(GO) run build.go $(GO_BUILD_FLAGS) build-server
.PHONY: build-cli
build-cli: ## Build Grafana CLI application.
@echo "build grafana-cli"
$(GO) run build.go $(GO_BUILD_FLAGS) build-cli
.PHONY: build-js
build-js: ## Build frontend assets.
@echo "build frontend"
yarn run build
yarn run plugins:build-bundled
build-plugins-go: ## Build decoupled plugins
@echo "build plugins"
@cd pkg/tsdb; \
mage -v
PLUGIN_ID ?=
.PHONY: build-plugin-go
build-plugin-go: ## Build decoupled plugins
@echo "build plugin $(PLUGIN_ID)"
@cd pkg/tsdb; \
@@ -205,19 +157,11 @@ build-plugin-go: ## Build decoupled plugins
fi; \
mage -v buildplugin $(PLUGIN_ID)
.PHONY: build
build: build-go build-js ## Build backend and frontend.
.PHONY: run
run: $(BRA) ## Build and run web server on filesystem changes.
$(BRA) run
.PHONY: run-go
run-go: ## Build and run web server immediately.
$(GO) run -race $(if $(GO_BUILD_TAGS),-build-tags=$(GO_BUILD_TAGS)) \
./pkg/cmd/grafana -- server -packaging=dev cfg:app_mode=development
.PHONY: run-frontend
run-frontend: deps-js ## Fetch js dependencies and watch frontend for rebuild
yarn start
@@ -229,67 +173,61 @@ test-go: test-go-unit test-go-integration
.PHONY: test-go-unit
test-go-unit: ## Run unit tests for backend with flags.
@echo "test backend unit tests"
go list -f '{{.Dir}}/...' -m | xargs \
$(GO) test $(GO_RACE_FLAG) -short -covermode=atomic -timeout=30m
$(GO) test -short -covermode=atomic -timeout=30m ./pkg/...
.PHONY: test-go-integration
test-go-integration: ## Run integration tests for backend with flags.
@echo "test backend integration tests"
$(GO) test $(GO_RACE_FLAG) -count=1 -run "^TestIntegration" -covermode=atomic -timeout=5m $(GO_INTEGRATION_TESTS)
$(GO) test -count=1 -run "^TestIntegration" -covermode=atomic -timeout=5m $(GO_INTEGRATION_TESTS)
.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
AM_URL=http://localhost:8080 AM_TENANT_ID=test \
$(GO) test $(GO_RACE_FLAG) -count=1 -run "^TestIntegrationRemoteAlertmanager" -covermode=atomic -timeout=5m ./pkg/services/ngalert/...
$(GO) test -count=1 -run "^TestIntegrationRemoteAlertmanager" -covermode=atomic -timeout=5m ./pkg/services/ngalert/...
.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
GRAFANA_TEST_DB=postgres \
$(GO) test $(GO_RACE_FLAG) -p=1 -count=1 -run "^TestIntegration" -covermode=atomic -timeout=10m $(GO_INTEGRATION_TESTS)
$(GO) test -p=1 -count=1 -run "^TestIntegration" -covermode=atomic -timeout=10m $(GO_INTEGRATION_TESTS)
.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"
GRAFANA_TEST_DB=mysql \
$(GO) test $(GO_RACE_FLAG) -p=1 -count=1 -run "^TestIntegration" -covermode=atomic -timeout=10m $(GO_INTEGRATION_TESTS)
$(GO) test -p=1 -count=1 -run "^TestIntegration" -covermode=atomic -timeout=10m $(GO_INTEGRATION_TESTS)
.PHONY: test-go-integration-redis
test-go-integration-redis: ## Run integration tests for redis cache.
@echo "test backend integration redis tests"
$(GO) clean -testcache
REDIS_URL=localhost:6379 $(GO) test $(GO_RACE_FLAG) -run IntegrationRedis -covermode=atomic -timeout=2m $(GO_INTEGRATION_TESTS)
REDIS_URL=localhost:6379 $(GO) test -run IntegrationRedis -covermode=atomic -timeout=2m $(GO_INTEGRATION_TESTS)
.PHONY: test-go-integration-memcached
test-go-integration-memcached: ## Run integration tests for memcached cache.
@echo "test backend integration memcached tests"
$(GO) clean -testcache
MEMCACHED_HOSTS=localhost:11211 $(GO) test $(GO_RACE_FLAG) -run IntegrationMemcached -covermode=atomic -timeout=2m $(GO_INTEGRATION_TESTS)
MEMCACHED_HOSTS=localhost:11211 $(GO) test -run IntegrationMemcached -covermode=atomic -timeout=2m $(GO_INTEGRATION_TESTS)
.PHONY: test-js
test-js: ## Run tests for frontend.
@echo "test frontend"
yarn test
.PHONY: test
test: test-go test-js ## Run all tests.
##@ Linting
.PHONY: golangci-lint
golangci-lint: $(GOLANGCI_LINT)
@echo "lint via golangci-lint"
$(GOLANGCI_LINT) run \
--config .golangci.toml \
$(GO_FILES)
.PHONY: lint-go
lint-go: golangci-lint ## Run all code checks for backend. You can use GO_FILES to specify exact files to check
# with disabled SC1071 we are ignored some TCL,Expect `/usr/bin/env expect` scripts
.PHONY: shellcheck
shellcheck: $(SH_FILES) ## Run checks for shell scripts.
@docker run --rm -v "$$PWD:/mnt" koalaman/shellcheck:stable \
$(SH_FILES) -e SC1071 -e SC2162
@@ -299,7 +237,6 @@ shellcheck: $(SH_FILES) ## Run checks for shell scripts.
TAG_SUFFIX=$(if $(WIRE_TAGS)!=oss,-$(WIRE_TAGS))
PLATFORM=linux/amd64
.PHONY: build-docker-full
build-docker-full: ## Build Docker image for development.
@echo "build docker container"
tar -ch . | \
@@ -313,7 +250,6 @@ build-docker-full: ## Build Docker image for development.
--tag grafana/grafana$(TAG_SUFFIX):dev \
$(DOCKER_BUILD_ARGS)
.PHONY: build-docker-full-ubuntu
build-docker-full-ubuntu: ## Build Docker image based on Ubuntu for development.
@echo "build docker container"
tar -ch . | \
@@ -325,7 +261,7 @@ build-docker-full-ubuntu: ## Build Docker image based on Ubuntu for development.
--build-arg COMMIT_SHA=$$(git rev-parse HEAD) \
--build-arg BUILD_BRANCH=$$(git rev-parse --abbrev-ref HEAD) \
--build-arg BASE_IMAGE=ubuntu:22.04 \
--build-arg GO_IMAGE=golang:$(GO_VERSION) \
--build-arg GO_IMAGE=golang:1.21.5 \
--tag grafana/grafana$(TAG_SUFFIX):dev-ubuntu \
$(DOCKER_BUILD_ARGS)
@@ -333,7 +269,6 @@ build-docker-full-ubuntu: ## Build Docker image based on Ubuntu for development.
# create docker-compose file with provided sources and start them
# example: make devenv sources=postgres,auth/openldap
.PHONY: devenv
ifeq ($(sources),)
devenv:
@printf 'You have to define sources for this command \nexample: make devenv sources=postgres,openldap\n'
@@ -347,18 +282,15 @@ devenv: devenv-down ## Start optional services, e.g. postgres, prometheus, and e
docker-compose up -d --build
endif
.PHONY: devenv-down
devenv-down: ## Stop optional services.
@cd devenv; \
test -f docker-compose.yaml && \
docker-compose down || exit 0;
.PHONY: devenv-postgres
devenv-postgres:
@cd devenv; \
sources=postgres_tests
.PHONY: devenv-mysql
devenv-mysql:
@cd devenv; \
sources=mysql_tests
@@ -370,23 +302,19 @@ devenv-mysql:
# go-gettable dependency and so getting it installed can be inconvenient.
#
# If you are working on changes to protobuf interfaces you may either use
# this target or run the individual scripts below directly
.PHONY: protobuf
# this target or run the individual scripts below directly.
protobuf: ## Compile protobuf definitions
bash scripts/protobuf-check.sh
go install google.golang.org/protobuf/cmd/protoc-gen-go
go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@latest
buf generate pkg/plugins/backendplugin/pluginextensionv2 --template pkg/plugins/backendplugin/pluginextensionv2/buf.gen.yaml
buf generate pkg/plugins/backendplugin/secretsmanagerplugin --template pkg/plugins/backendplugin/secretsmanagerplugin/buf.gen.yaml
buf generate pkg/services/store/entity --template pkg/services/store/entity/buf.gen.yaml
bash pkg/plugins/backendplugin/pluginextensionv2/generate.sh
bash pkg/plugins/backendplugin/secretsmanagerplugin/generate.sh
bash pkg/services/store/entity/generate.sh
bash pkg/infra/grn/generate.sh
.PHONY: clean
clean: ## Clean up intermediate build artifacts.
@echo "cleaning"
rm -rf node_modules
rm -rf public/build
.PHONY: gen-ts
gen-ts:
@echo "generating TypeScript definitions"
go get github.com/tkrajina/typescriptify-golang-structs/typescriptify@v0.1.7
@@ -396,34 +324,17 @@ gen-ts:
# This repository's configuration is protected (https://readme.drone.io/signature/).
# Use this make target to regenerate the configuration YAML files when
# you modify starlark files.
.PHONY: drone
drone: $(DRONE)
bash scripts/drone/env-var-check.sh
$(DRONE) starlark --format
$(DRONE) lint .drone.yml --trusted
$(DRONE) --server https://drone.grafana.net sign --save grafana/grafana
# Generate an Emacs tags table (https://www.gnu.org/software/emacs/manual/html_node/emacs/Tags-Tables.html) for Starlark files.
.PHONY: scripts/drone/TAGS
scripts/drone/TAGS: $(shell find scripts/drone -name '*.star')
etags --lang none --regex="/def \(\w+\)[^:]+:/\1/" --regex="/\s*\(\w+\) =/\1/" $^ -o $@
.PHONY: format-drone
format-drone:
buildifier --lint=fix -r scripts/drone
.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
.PHONY: help
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)

110
UPGRADING_DEPENDENCIES.md Normal file
View File

@@ -0,0 +1,110 @@
# Guide to upgrading dependencies
Upgrading Go or Node.js requires making changes in many different files. See below for a list and explanation for each.
## Go
- Drone
- `grafana/build-container`
- Appveyor
- Dockerfile
## Node.js
- Drone
- `grafana/build-container`
- Appveyor
- Dockerfile
- `.github/workflows/publish.yml`
## Go dependencies
The Grafana project uses [Go modules](https://golang.org/cmd/go/#hdr-Modules__module_versions__and_more) to manage dependencies on external packages. This requires a working Go environment with version 1.11 or greater installed.
To add or update a new dependency, use the `go get` command:
```bash
go get example.com/some/module/pkg
# Pick a specific version.
go get example.com/some/module/pkg@vX.Y.Z
```
Tidy up the `go.mod` and `go.sum` files:
```bash
go mod tidy
```
You have to commit the changes to `go.mod` and `go.sum` before submitting the pull request.
To understand what the actual dependencies of `grafana-server` are, one could run it with `-vv` flag. This might produce an output, different from `go.mod` contents and `-vv` option is the source of truth here. It lists the modules _compiled_ into the executable, while `go.mod` lists also test and weak transitive dependencies (modules, used in some package, which is not in use by itself). If you are interested in reporting a vulnerability in a dependency module - please consult `-vv` output, maybe the "dependency" is not a dependency as such.
### Upgrading dependencies
If you need to upgrade a direct or indirect dependency, you can do it like so, $MODULE being the dependency in question: `go get -u $MODULE`. The corresponding entry in go.mod should then have the version you specified; if it's an indirect dependency, the entry should have the `// indirect` comment. Follow this by executing `go mod tidy`, to ensure that go.mod and go.sum are up to date. If the indirect dependency turns out to not be used (transitively) by any of our packages, `go mod tidy` will actually strip it from go.mod. In that case, you can just ignore it since it isn't used in the end.
## Node.js dependencies
Updated using `yarn`.
- `package.json`
## Where to make changes
### Drone
Our CI builds run on Drone.
#### Files
- `.circleci/config.yml`.
#### Dependencies
- nodejs
- golang
- grafana/build-container (our custom docker build container)
### grafana/build-container
The main build steps (in Drone) happen using a custom Docker image that comes pre-baked with some of the necessary dependencies.
Link: [grafana/build-container](https://github.com/grafana/grafana/tree/main/scripts/build/ci-build)
#### Dependencies
- fpm
- nodejs
- golang
- crosscompiling (several compilers)
### Appveyor
Main and release builds trigger test runs on Appveyors build environment so that tests will run on Windows.
#### Files:
- `appveyor.yml`
#### Dependencies
- nodejs
- golang
### Dockerfile
There is a Docker build for Grafana in the root of the project that allows anyone to build Grafana just using Docker.
#### Files
- `Dockerfile`
#### Dependencies
- nodejs
- golang
### Local developer environments
Please send out a notice in the grafana-dev slack channel when updating Go or Node.js to make it easier for everyone to update their local developer environments.

View File

@@ -14,7 +14,7 @@ Team members and their access to repositories is maintained through [GitHub team
Examples of proposed changes are overarching architecture, component design, and specific code or graphical elements. Proposed changes SHOULD cover the big picture and intention, but individual parts SHOULD be split into the smallest possible changes. Changes SHOULD be based on and target the main branch. Depending on size of the proposed change, each change SHOULD be discussed, in increasing order of change size and complexity:
- Directly in a PR (Pull Request) - this MAY be done, but SHOULD not be the common case.
- Directly in a RR (Pull Request) - this MAY be done, but SHOULD not be the common case.
- Issue
- Developer mailing list
- Design document, shared via Google Docs, accessible to at least all team members.
@@ -44,7 +44,7 @@ Once a PR is approved as per above, any team member MAY merge the PR.
## Backporting a PR
Critical bug fixes needed for a previous minor release should be backported to the respective release branches after coordinating with the delivery team.
Please see the [contribution guide](./contribute/merge-pull-request.md#should-the-pull-request-be-backported) for further details.
Please see the [contibution guide](./contribute/merge-pull-request.md#should-the-pull-request-be-backported) for further details.
# Release workflow

60
babel.config.json Normal file
View File

@@ -0,0 +1,60 @@
{
"babelrc": false,
// Note: order is bottom-to-top and/or right-to-left
"presets": [
[
"@babel/preset-env",
{
"bugfixes": true,
"browserslistEnv": "dev"
}
],
[
"@babel/preset-typescript",
{
"allowNamespaces": true,
"allowDeclareFields": true
}
],
[
"@babel/preset-react",
{
"runtime": "automatic"
}
]
],
"plugins": [
[
"@babel/plugin-transform-typescript",
{
"allowNamespaces": true,
"allowDeclareFields": true
}
],
// added to mitigate https://github.com/babel/babel/issues/14289
// package (and following line) can be removed once the issue is fixed and released
"@babel/plugin-proposal-class-properties",
["@babel/plugin-proposal-object-rest-spread", { "loose": true }],
"@babel/plugin-transform-react-constant-elements",
"@babel/plugin-proposal-nullish-coalescing-operator",
"@babel/plugin-proposal-optional-chaining",
"@babel/plugin-syntax-dynamic-import", // needed for `() => import()` in routes.ts
"angularjs-annotate",
"macros"
],
"env": {
"production": {
"presets": [
[
"@babel/preset-env",
{
"browserslistEnv": "production"
}
]
]
},
"hot": {
"plugins": ["react-refresh/babel"]
}
}
}

View File

@@ -9,6 +9,10 @@ app_mode = production
# instance name, defaults to HOSTNAME environment variable value or hostname if HOSTNAME var is empty
instance_name = ${HOSTNAME}
# force migration will run migrations that might cause dataloss
# Deprecated, use clean_upgrade option in [unified_alerting.upgrade] instead.
force_migration = false
#################################### Paths ###############################
[paths]
# Path to where grafana can store temp files, sessions, and the sqlite3 db (if that is used)
@@ -66,9 +70,6 @@ enable_gzip = false
cert_file =
cert_key =
# Certificates file watch interval
certs_watch_interval =
# Unix socket gid
# Changing the gid of a file without privileges requires that the target group is in the group of the process and that the process is the file owner
# It is recommended to set the gid as http server user gid
@@ -93,10 +94,6 @@ read_timeout = 0
#exampleHeader1 = exampleValue1
#exampleHeader2 = exampleValue2
[environment]
# Sets whether the local file system is available for Grafana to use. Default is true for backward compatibility.
local_file_system_available = true
#################################### GRPC Server #########################
[grpc_server]
network = "tcp"
@@ -104,14 +101,6 @@ address = "127.0.0.1:10000"
use_tls = false
cert_file =
key_file =
# this will log the request and response for each unary gRPC call
enable_logging = false
# Maximum size of a message that can be received in bytes. If not set, uses the gRPC default (4MiB).
max_recv_msg_size =
# Maximum size of a message that can be sent in bytes. If not set, uses the gRPC default (unlimited).
max_send_msg_size =
#################################### Database ############################
[database]
@@ -145,9 +134,6 @@ log_queries =
# For "mysql", use either "true", "false", or "skip-verify".
ssl_mode = disable
# For "postgres", use either "1" to enable or "0" to disable SNI
ssl_sni =
# Database drivers may support different transaction isolation levels.
# Currently, only "mysql" driver supports isolation levels.
# If the value is empty - driver's default isolation level is applied.
@@ -168,10 +154,7 @@ cache_mode = private
# For "sqlite3" only. Enable/disable Write-Ahead Logging, https://sqlite.org/wal.html. Default is false.
wal = false
# For "mysql" and "postgres". Lock the database for the migrations, default is true.
migration_locking = true
# For "mysql" and "postgres" only if migrationLocking is set. How many seconds to wait before failing to lock the database for the migrations, default is 0.
# For "mysql" only if migrationLocking feature toggle is set. How many seconds to wait before failing to lock the database for the migrations, default is 0.
locking_attempt_timeout_sec = 0
# For "sqlite" only. How many times to retry query in case of database is locked failures. Default is 0 (disabled).
@@ -393,8 +376,8 @@ content_security_policy_report_only = false
# $ROOT_PATH is server.root_url without the protocol.
content_security_policy_report_only_template = """script-src 'self' 'unsafe-eval' 'unsafe-inline' 'strict-dynamic' $NONCE;object-src 'none';font-src 'self';style-src 'self' 'unsafe-inline' blob:;img-src * data:;base-uri 'self';connect-src 'self' grafana.com ws://$ROOT_PATH wss://$ROOT_PATH;manifest-src 'self';media-src 'none';form-action 'self';"""
# Controls if old angular plugins are supported or not.
angular_support_enabled = false
# Controls if old angular plugins are supported or not. This will be disabled by default in future release
angular_support_enabled = true
# The CSRF check will be executed even if the request has no login cookie.
csrf_always_check = false
@@ -446,11 +429,6 @@ default_home_dashboard_path =
# Upper limit of data sources that Grafana will return. This limit is a temporary configuration and it will be deprecated when pagination will be introduced on the list data sources API.
datasource_limit = 5000
# Number of queries to be executed concurrently. Only for the datasource supports concurrency.
# For now only Loki and InfluxDB (with influxql) are supporting concurrency behind the feature flags.
# Check datasource documentations for enabling concurrency.
concurrent_query_count = 10
################################### SQL Data Sources #####################
[sql_datasources]
@@ -486,12 +464,9 @@ auto_assign_org_role = Viewer
# Require email validation before sign up completes
verify_email_enabled = false
# Redirect to default OrgId after login
login_default_org_id =
# Background text for the user field on the login page
login_hint =
password_hint =
login_hint = email or username
password_hint = password
# Default UI theme ("dark" or "light" or "system")
default_theme = dark
@@ -516,9 +491,6 @@ editors_can_admin = false
# The duration in time a user invitation remains valid before expiring. This setting should be expressed as a duration. Examples: 6h (hours), 2d (days), 1w (week). Default is 24h (24 hours). The minimum supported duration is 15m (15 minutes).
user_invite_max_lifetime_duration = 24h
# The duration in time a verification email, used to update the email address of a user, remains valid before expiring. This setting should be expressed as a duration. Examples: 6h (hours), 2d (days), 1w (week). Default is 1h (1 hour).
verification_email_max_lifetime_duration = 1h
# Enter a comma-separated list of usernames to hide them in the Grafana UI. These users are shown to Grafana admins and to themselves.
hidden_users =
@@ -575,6 +547,10 @@ oauth_auto_login = false
# OAuth state max age cookie duration in seconds. Defaults to 600 seconds.
oauth_state_cookie_max_age = 600
# Skip forced assignment of OrgID 1 or 'auto_assign_org_id' for social logins
# Deprecated, use skip_org_role_sync option for specific provider instead.
oauth_skip_org_role_update_sync = false
# limit of api_key seconds to live before expiration
api_key_max_seconds_to_live = -1
@@ -601,16 +577,6 @@ id_response_header_prefix = X-Grafana
# The header value will encode the namespace ("user:<id>", "api-key:<id>", "service-account:<id>")
id_response_header_namespaces = user api-key service-account
#################################### SSO Settings ###########################
[sso_settings]
# interval for reloading the SSO Settings from the database
# useful in high availability setups running multiple Grafana instances
# set to 0 to disable this feature
reload_interval = 1m
# List of providers that can be configured through the SSO Settings API and UI.
configurable_providers = github gitlab google generic_oauth azuread okta
#################################### Anonymous Auth ######################
[auth.anonymous]
# enable anonymous access
@@ -626,7 +592,7 @@ org_role = Viewer
hide_version = false
# number of devices in total
device_limit =
device_limit =
#################################### GitHub Auth #########################
[auth.github]
@@ -647,7 +613,6 @@ team_ids =
allowed_organizations =
role_attribute_path =
role_attribute_strict = false
org_mapping =
allow_assign_grafana_admin = false
skip_org_role_sync = false
tls_skip_verify_insecure = false
@@ -675,7 +640,6 @@ allowed_domains =
allowed_groups =
role_attribute_path =
role_attribute_strict = false
org_mapping =
allow_assign_grafana_admin = false
skip_org_role_sync = false
tls_skip_verify_insecure = false
@@ -700,12 +664,10 @@ token_url = https://oauth2.googleapis.com/token
api_url = https://openidconnect.googleapis.com/v1/userinfo
signout_redirect_url =
allowed_domains =
validate_hd = true
hosted_domain =
allowed_groups =
role_attribute_path =
role_attribute_strict = false
org_mapping =
allow_assign_grafana_admin = false
skip_org_role_sync = true
tls_skip_verify_insecure = false
@@ -784,8 +746,6 @@ allowed_domains =
allowed_groups =
role_attribute_path =
role_attribute_strict = false
org_attribute_path =
org_mapping =
allow_assign_grafana_admin = false
skip_org_role_sync = false
tls_skip_verify_insecure = false
@@ -812,8 +772,6 @@ login_attribute_path =
name_attribute_path =
role_attribute_path =
role_attribute_strict = false
org_attribute_path =
org_mapping =
groups_attribute_path =
id_token_attribute_name =
team_ids_attribute_path =
@@ -839,14 +797,6 @@ use_refresh_token = false
#################################### Basic Auth ##########################
[auth.basic]
enabled = true
# This setting will enable a stronger password policy for user's password under basic auth.
# The password will need to comply with the following password policy
# 1. Have a minimum of 12 characters
# 2. Composed by at least 1 uppercase character
# 3. Composed by at least 1 lowercase character
# 4. Composed by at least 1 digit character
# 5. Composed by at least 1 symbol character
password_policy = false
#################################### Auth Proxy ##########################
[auth.proxy]
@@ -854,7 +804,7 @@ enabled = false
header_name = X-WEBAUTH-USER
header_property = username
auto_sign_up = true
sync_ttl = 15
sync_ttl = 60
whitelist =
headers =
headers_encoded = false
@@ -867,8 +817,6 @@ enable_login_token = false
header_name =
email_claim =
username_claim =
email_attribute_path =
username_attribute_path =
jwk_set_url =
jwk_set_file =
cache_ttl = 60m
@@ -877,11 +825,11 @@ key_file =
key_id =
role_attribute_path =
role_attribute_strict = false
groups_attribute_path =
auto_sign_up = false
url_login = false
allow_assign_grafana_admin = false
skip_org_role_sync = false
signout_redirect_url =
#################################### Auth LDAP ###########################
[auth.ldap]
@@ -895,7 +843,7 @@ skip_org_role_sync = false
sync_cron = "0 1 * * *"
active_sync_enabled = true
#################################### AWS #####################################
#################################### AWS ###########################
[aws]
# Enter a comma-separated list of allowed AWS authentication providers.
# Options are: default (AWS SDK Default), keys (Access && secret key), credentials (Credentials field), ec2_iam_role (EC2 IAM Role)
@@ -911,14 +859,6 @@ list_metrics_page_limit = 500
# Experimental, for use in Grafana Cloud only. Please do not set.
external_id =
# Sets the expiry duration of an assumed role.
# This setting should be expressed as a duration. Examples: 6h (hours), 10d (days), 2w (weeks), 1M (month).
session_duration = "15m"
# Set the plugins that will receive AWS settings for each request (via plugin context)
# By default this will include all Grafana Labs owned AWS plugins, or those that make use of AWS settings (ElasticSearch, Prometheus).
forward_settings_to_plugins = cloudwatch, grafana-athena-datasource, grafana-redshift-datasource, grafana-x-ray-datasource, grafana-timestream-datasource, grafana-iot-sitewise-datasource, grafana-iot-twinmaker-app, grafana-opensearch-datasource, aws-datasource-provisioner, elasticsearch, prometheus
#################################### Azure ###############################
[azure]
# Azure cloud environment where Grafana is hosted
@@ -926,10 +866,6 @@ forward_settings_to_plugins = cloudwatch, grafana-athena-datasource, grafana-red
# Default value is AzureCloud (i.e. public cloud)
cloud = AzureCloud
# A customized list of Azure cloud settings and properties, used by data sources which need this information when run in non-standard azure environments
# When specified, this list will replace the default cloud list of AzureCloud, AzureChinaCloud, AzureUSGovernment and AzureGermanCloud
clouds_config =
# Specifies whether Grafana hosted in Azure service with Managed Identity configured (e.g. Azure Virtual Machines instance)
# If enabled, the managed identity can be used for authentication of Grafana in Azure services
# Disabled by default, needs to be explicitly enabled
@@ -962,13 +898,6 @@ workload_identity_token_file =
# Disabled by default, needs to be explicitly enabled
user_identity_enabled = false
# Specifies whether user identity authentication fallback credentials should be enabled in data sources
# Enabling this allows data source creators to provide fallback credentials for backend initiated requests
# e.g. alerting, recorded queries etc.
# Enabled by default, needs to be explicitly disabled
# Will not have any effect if user identity is disabled above
user_identity_fallback_credentials_enabled = true
# Override token URL for Azure Active Directory
# By default is the same as token URL configured for AAD authentication settings
user_identity_token_url =
@@ -981,15 +910,6 @@ user_identity_client_id =
# By default is the same as used in AAD authentication or can be set to another application (for OBO flow)
user_identity_client_secret =
# Allows the usage of a custom token request assertion when Grafana is behind an authentication proxy
# In most cases this will not need to be used. To enable this set the value to "username"
# The default is empty and any other value will not enable this functionality
username_assertion =
# Set the plugins that will receive Azure settings for each request (via plugin context)
# By default this will include all Grafana Labs owned Azure plugins, or those that make use of Azure settings (Azure Monitor, Azure Data Explorer, Prometheus, MSSQL).
forward_settings_to_plugins = grafana-azure-monitor-datasource, prometheus, grafana-azure-data-explorer-datasource, mssql
#################################### Role-based Access Control ###########
[rbac]
# If enabled, cache permissions in a in memory cache
@@ -1016,10 +936,6 @@ from_address = admin@grafana.localhost
from_name = Grafana
ehlo_identity =
startTLS_policy =
enable_tracing = false
[smtp.static_headers]
# Include custom static headers in all outgoing emails
[emails]
welcome_email_on_sign_up = false
@@ -1108,11 +1024,6 @@ instrumentations_console_enabled = false
# Should webvitals instrumentation be enabled, only affects Grafana Javascript Agent
instrumentations_webvitals_enabled = false
# level of internal logging for debugging Grafana Javascript Agent.
# possible values are: 0 = OFF, 1 = ERROR, 2 = WARN, 3 = INFO, 4 = VERBOSE
# more details: https://github.com/grafana/faro-web-sdk/blob/v1.3.7/docs/sources/tutorials/quick-start-browser.md#how-to-activate-debugging
internal_logger_level = 0
# Api Key, only applies to Grafana Javascript Agent provider
api_key =
@@ -1163,13 +1074,9 @@ global_file = 1000
# global limit of correlations
global_correlations = -1
# Limit of the number of alert rules per rule group.
# This is not strictly enforced yet, but will be enforced over time.
alerting_rule_group_rules = 100
#################################### Unified Alerting ####################
[unified_alerting]
# Enable the Alerting sub-system and interface.
# Enable the Unified Alerting sub-system and interface. When enabled we'll migrate all of your alert rules and notification channels to the new system. New alert rules will be created and your notification channels will be converted into an Alertmanager configuration. Previous data is preserved to enable backwards compatibility but new data is removed when switching. When this configuration section and flag are not defined, the state is defined at runtime. See the documentation for more details.
enabled =
# Comma-separated list of organization IDs for which to disable unified alerting. Only supported if unified alerting is enabled.
@@ -1183,12 +1090,7 @@ admin_config_poll_interval = 60s
# The interval string is a possibly signed sequence of decimal numbers, followed by a unit suffix (ms, s, m, h, d), e.g. 30s or 1m.
alertmanager_config_poll_interval = 60s
# Set to true when using redis in cluster mode.
ha_redis_cluster_mode_enabled = false
# The redis server address(es) that should be connected to.
# Can either be a single address, or if using redis in cluster mode,
# the cluster configuration address or a comma-separated list of addresses.
# The redis server address that should be connected to.
ha_redis_address =
# The username that should be used to authenticate with the redis server.
@@ -1211,34 +1113,6 @@ ha_redis_peer_name =
# The maximum number of simultaneous redis connections.
ha_redis_max_conns = 5
# Enable TLS on the client used to communicate with the redis server. This should be set to true
# if using any of the other ha_redis_tls_* fields.
ha_redis_tls_enabled = false
# Path to the PEM-encoded TLS client certificate file used to authenticate with the redis server.
# Required if using Mutual TLS.
ha_redis_tls_cert_path =
# Path to the PEM-encoded TLS private key file. Also requires the client certificate to be configured.
# Required if using Mutual TLS.
ha_redis_tls_key_path =
# Path to the PEM-encoded CA certificates file. If not set, the host's root CA certificates are used.
ha_redis_tls_ca_path =
# Overrides the expected name of the redis server certificate.
ha_redis_tls_server_name =
# Skips validating the redis server certificate.
ha_redis_tls_insecure_skip_verify =
# Overrides the default TLS cipher suite list.
ha_redis_tls_cipher_suites =
# Overrides the default minimum TLS version.
# Allowed values: VersionTLS10, VersionTLS11, VersionTLS12, VersionTLS13
ha_redis_tls_min_version =
# Listen address/hostname and port to receive unified alerting messages for other Grafana instances. The port is used for both TCP and UDP. It is assumed other Grafana instances are also running on the same port.
ha_listen_address = "0.0.0.0:9094"
@@ -1269,17 +1143,17 @@ ha_gossip_interval = 200ms
# The interval string is a possibly signed sequence of decimal numbers, followed by a unit suffix (ms, s, m, h, d), e.g. 30s or 1m.
ha_push_pull_interval = 60s
# Enable or disable alerting rule execution. The alerting UI remains visible.
# Enable or disable alerting rule execution. The alerting UI remains visible. This option has a legacy version in the `[alerting]` section that takes precedence.
execute_alerts = true
# Alert evaluation timeout when fetching data from the datasource.
# Alert evaluation timeout when fetching data from the datasource. This option has a legacy version in the `[alerting]` section that takes precedence.
# The timeout string is a possibly signed sequence of decimal numbers, followed by a unit suffix (ms, s, m, h, d), e.g. 30s or 1m.
evaluation_timeout = 30s
# Number of times we'll attempt to evaluate an alert rule before giving up on that evaluation. The default value is 1.
max_attempts = 1
# Minimum interval to enforce between rule evaluations. Rules will be adjusted if they are less than this value or if they are not multiple of the scheduler interval (10s). Higher values can help with resource management as we'll schedule fewer evaluations over time.
# Minimum interval to enforce between rule evaluations. Rules will be adjusted if they are less than this value or if they are not multiple of the scheduler interval (10s). Higher values can help with resource management as we'll schedule fewer evaluations over time. This option has a legacy version in the `[alerting]` section that takes precedence.
# The interval string is a possibly signed sequence of decimal numbers, followed by a unit suffix (ms, s, m, h, d), e.g. 30s or 1m.
min_interval = 10s
@@ -1288,17 +1162,6 @@ min_interval = 10s
# (concurrent queries per rule disabled).
max_state_save_concurrency = 1
# If the feature flag 'alertingSaveStatePeriodic' is enabled, this is the interval that is used to persist the alerting instances to the database.
# The interval string is a possibly signed sequence of decimal numbers, followed by a unit suffix (ms, s, m, h, d), e.g. 30s or 1m.
state_periodic_save_interval = 5m
# Disables the smoothing of alert evaluations across their evaluation window.
# Rules will evaluate in sync.
disable_jitter = false
# Retention period for Alertmanager notification log entries.
notification_log_retention = 5d
[unified_alerting.screenshots]
# Enable screenshots in notifications. You must have either installed the Grafana image rendering
# plugin, or set up Grafana to use a remote rendering service.
@@ -1372,10 +1235,6 @@ loki_basic_auth_username =
# Optional password for basic authentication on requests sent to Loki. Can be left blank.
loki_basic_auth_password =
# For "loki" only.
# Optional max query length for queries sent to Loki. Default is 721h which matches the default Loki value.
loki_max_query_length = 721h
[unified_alerting.state_history.external_labels]
# Optional extra labels to attach to outbound state history records or log streams.
# Any number of label key-value-pairs can be provided.
@@ -1383,16 +1242,12 @@ loki_max_query_length = 721h
# ex.
# mylabelkey = mylabelvalue
[unified_alerting.state_history.annotations]
# Controls retention of annotations automatically created while evaluating alert rules.
# Alert state history backend must be configured to be annotations (see setting [unified_alerting.state_history].backend).
# Configures how long alert annotations are stored for. Default is 0, which keeps them forever.
# This setting should be expressed as a duration. Ex 6h (hours), 10d (days), 2w (weeks), 1M (month).
max_age =
# Configures max number of alert annotations that Grafana stores. Default value is 0, which keeps all alert annotations.
max_annotations_to_keep =
[unified_alerting.upgrade]
# If set to true when upgrading from legacy alerting to Unified Alerting, grafana will first delete all existing
# Unified Alerting resources, thus re-upgrading all organizations from scratch. If false or unset, organizations that
# have previously upgraded will not lose their existing Unified Alerting data when switching between legacy and
# Unified Alerting. Should be kept false when not needed as it may cause unintended data-loss if left enabled.
clean_upgrade = false
# NOTE: this configuration options are not used yet.
[remote.alertmanager]
@@ -1402,19 +1257,53 @@ max_annotations_to_keep =
enabled = false
# URL of the remote Alertmanager that will replace the internal one.
# This URL should be the root path, Grafana will automatically append an "/alertmanager" suffix for certain HTTP calls.
# Required if `enabled` is set to `true`.
url =
# Tenant ID to use in requests to the Alertmanager.
# It will also be used for the basic auth username if a password is configured.
# It will also be used for the basic auth username.
tenant =
# Optional password for basic authentication.
# If not present, the tenant ID will be set in the X-Scope-OrgID header.
password =
sync_interval = 5m
#################################### Alerting ############################
[alerting]
# Enable the legacy alerting sub-system and interface. If Unified Alerting is already enabled and you try to go back to legacy alerting, all data that is part of Unified Alerting will be deleted. When this configuration section and flag are not defined, the state is defined at runtime. See the documentation for more details.
enabled =
# Makes it possible to turn off alert execution but alerting UI is visible
execute_alerts = true
# Default setting for new alert rules. Defaults to categorize error and timeouts as alerting. (alerting, keep_state)
error_or_timeout = alerting
# Default setting for how Grafana handles nodata or null values in alerting. (alerting, no_data, keep_state, ok)
nodata_or_nullvalues = no_data
# Alert notifications can include images, but rendering many images at the same time can overload the server
# This limit will protect the server from render overloading and make sure notifications are sent out quickly
concurrent_render_limit = 5
# Default setting for alert calculation timeout. Default value is 30
evaluation_timeout_seconds = 30
# Default setting for alert notification timeout. Default value is 30
notification_timeout_seconds = 30
# Default setting for max attempts to sending alert notifications. Default value is 3
max_attempts = 3
# Makes it possible to enforce a minimal interval between evaluations, to reduce load on the backend
min_interval_seconds = 1
# Configures for how long alert annotations are stored. Default is 0, which keeps them forever.
# This setting should be expressed as an duration. Ex 6h (hours), 10d (days), 2w (weeks), 1M (month).
max_annotation_age =
# Configures max number of alert annotations that Grafana stores. Default value is 0, which keeps all alert annotations.
max_annotations_to_keep =
#################################### Annotations #########################
[annotations]
@@ -1476,11 +1365,6 @@ concurrent_query_limit =
# Enable the Query history
enabled = true
#################################### Short Links #############################
[short_links]
# Short links which are never accessed will be deleted as cleanup. Time is in days. Default is 7 days. Max is 365. 0 means they will be deleted approximately every 10 minutes.
expire_time = 7
#################################### Internal Grafana Metrics ############
# Metrics available at HTTP URL /metrics and /metrics/plugins/:pluginId
[metrics]
@@ -1514,7 +1398,6 @@ url = https://grafana.com
[grafana_com]
url = https://grafana.com
api_url = https://grafana.com/api
sso_api_token = ""
#################################### Distributed tracing ############
# Opentracing is deprecated use opentelemetry instead
@@ -1625,12 +1508,6 @@ concurrent_render_request_limit = 30
# Default is 5m. This should be more than enough for most deployments.
# Change the value only if image rendering is failing and you see `Failed to get the render key from cache` in Grafana logs.
render_key_lifetime = 5m
# Default width for panel screenshot
default_image_width = 1000
# Default height for panel screenshot
default_image_height = 500
# Default scale for panel screenshot
default_image_scale = 1
[panels]
# here for to support old env variables, can remove after a few months
@@ -1659,10 +1536,6 @@ public_key_retrieval_on_startup = false
disable_plugins =
# Auth token for plugin installations and removal in managed instances
install_token =
# Comma separated list of plugin ids for which angular deprecation UI should be disabled
hide_angular_deprecation =
# Comma separated list of plugin ids for which environment variables should be forwarded. Used only when feature flag pluginsSkipHostEnvVars is enabled.
forward_host_env_vars =
#################################### Grafana Live ##########################################
[live]
@@ -1858,8 +1731,6 @@ server_name =
proxy_address =
# Determines if the secure socks proxy should be shown on the datasources page, defaults to true if the feature is enabled
show_ui = true
# Disables TLS in the secure socks proxy
allow_insecure = false
################################## Feature Management ##############################################
# Options to configure the experimental Feature Toggle Admin Page feature, which is behind the `featureToggleAdminPage` feature toggle. Use at your own risk.
@@ -1878,25 +1749,3 @@ hidden_toggles =
# Disables updating specific feature toggles in the feature management page
read_only_toggles =
#################################### Public Dashboards #####################################
[public_dashboards]
# Set to false to disable public dashboards
enabled = true
###################################### Cloud Migration ######################################
[cloud_migration]
# Set to true to enable target-side migration UI
is_target = false
# Token used to send requests to grafana com
gcom_api_token = ""
# How long to wait for a request to fetch an instance to complete
fetch_instance_timeout = 5s
# How long to wait for a request to create an access policy to complete
create_access_policy_timeout = 5s
# How long to wait for a request to create to fetch an access policy to complete
fetch_access_policy_timeout = 5s
# How long to wait for a request to create to delete an access policy to complete
delete_access_policy_timeout = 5s
# The domain name used to access cms
domain = grafana-dev.net

View File

@@ -67,45 +67,6 @@ apiVersion: 1
# labels:
# team: sre_team_1
# isPaused: false
# # optional settings that let configure notification settings applied to alerts created by this rule
# notification_settings:
# # <string> name of the receiver (contact-point) that should be used for this route
# receiver: grafana-default-email
# # <list<string>> The labels by which incoming alerts are grouped together. For example,
# # multiple alerts coming in for cluster=A and alertname=LatencyHigh would
# # be batched into a single group.
# #
# # To aggregate by all possible labels, use the special value '...' as
# # the sole label name, for example:
# # group_by: ['...']
# # This effectively disables aggregation entirely, passing through all
# # alerts as-is. This is unlikely to be what you want, unless you have
# # a very low alert volume or your upstream notification system performs
# # its own grouping.
# # If defined, must contain the labels 'alertname' and 'grafana_folder', except when contains '...'
# group_by: ["alertname", "grafana_folder", "region"]
# # <list> Times when the route should be muted. These must match the name of a
# # mute time interval.
# # Additionally, the root node cannot have any mute times.
# # When a route is muted it will not send any notifications, but
# # otherwise acts normally (including ending the route-matching process
# # if the `continue` option is not set)
# mute_time_intervals:
# - abc
# # <duration> How long to initially wait to send a notification for a group
# # of alerts. Allows to collect more initial alerts for the same group.
# # (Usually ~0s to few minutes).
# # If not specified, the corresponding setting of the default policy is used.
# group_wait: 30s
# # <duration> How long to wait before sending a notification about new alerts that
# # are added to a group of alerts for which an initial notification has
# # already been sent. (Usually ~5m or more).
# # If not specified, the corresponding setting of the default policy is used.
# group_interval: 5m
# # <duration> How long to wait before sending a notification again if it has already
# # been sent successfully for an alert. (Usually ~3h or more)
# # If not specified, the corresponding setting of the default policy is used.
# repeat_interval: 4h
# # List of alert rule UIDs that should be deleted
# deleteRules:
@@ -191,7 +152,7 @@ apiVersion: 1
# - orgID: 1
# # <string, required> name of the template, must be unique
# name: my_first_template
# # <string, required> content of the template
# # <string, required> content of the the template
# template: Alerting with a custome text template
# # List of templates that should be deleted

Some files were not shown because too many files have changed in this diff Show More