Provisioning: Introduce Repository Factory with extras (#110018)

This commit is contained in:
Roberto Jiménez Sánchez
2025-08-26 10:37:47 +02:00
committed by GitHub
parent 6a050ff551
commit e196f13b2b
37 changed files with 1032 additions and 425 deletions
@@ -9,18 +9,12 @@ import (
"k8s.io/apiserver/pkg/registry/rest"
"k8s.io/kube-openapi/pkg/spec3"
"github.com/grafana/grafana-app-sdk/logging"
provisioning "github.com/grafana/grafana/apps/provisioning/pkg/apis/provisioning/v0alpha1"
provisioningapis "github.com/grafana/grafana/pkg/registry/apis/provisioning"
"github.com/grafana/grafana/pkg/registry/apis/provisioning/controller"
"github.com/grafana/grafana/pkg/registry/apis/provisioning/jobs"
"github.com/grafana/grafana/pkg/registry/apis/provisioning/repository"
"github.com/grafana/grafana/pkg/registry/apis/provisioning/repository/git"
"github.com/grafana/grafana/pkg/registry/apis/provisioning/repository/github"
"github.com/grafana/grafana/pkg/registry/apis/provisioning/resources"
"github.com/grafana/grafana/pkg/registry/apis/provisioning/webhooks/pullrequest"
"github.com/grafana/grafana/pkg/services/apiserver"
"github.com/grafana/grafana/pkg/services/featuremgmt"
"github.com/grafana/grafana/pkg/services/rendering"
"github.com/grafana/grafana/pkg/setting"
"github.com/grafana/grafana/pkg/storage/unified/resource"
@@ -29,8 +23,28 @@ import (
// WebhookExtraBuilder is a function that returns an ExtraBuilder.
// It is used to add additional functionality for webhooks
type WebhookExtraBuilder struct {
// HACK: We need to wrap the builder to please wire so that it can uniquely identify the dependency
provisioningapis.ExtraBuilder
isPublic bool
urlProvider func(namespace string) string
}
func (b *WebhookExtraBuilder) WebhookURL(ctx context.Context, r *provisioning.Repository) string {
if !b.isPublic {
return ""
}
gvr := provisioning.RepositoryResourceInfo.GroupVersionResource()
webhookURL := fmt.Sprintf(
"%sapis/%s/%s/namespaces/%s/%s/%s/webhook",
b.urlProvider(r.GetNamespace()),
gvr.Group,
gvr.Version,
r.GetNamespace(),
gvr.Resource,
r.GetName(),
)
return webhookURL
}
// HACK: assume that the URL is public if it starts with "https://" and does not contain any local IP ranges
@@ -45,19 +59,19 @@ func isPublicURL(url string) bool {
func ProvideWebhooks(
cfg *setting.Cfg,
features featuremgmt.FeatureToggles,
ghFactory *github.Factory,
renderer rendering.Service,
blobstore resource.ResourceClient,
configProvider apiserver.RestConfigProvider,
) WebhookExtraBuilder {
return WebhookExtraBuilder{
ExtraBuilder: func(b *provisioningapis.APIBuilder) provisioningapis.Extra {
urlProvider := func(_ string) string {
return cfg.AppURL
}
) *WebhookExtraBuilder {
urlProvider := func(_ string) string {
return cfg.AppURL
}
isPublic := isPublicURL(urlProvider(""))
isPublic := isPublicURL(urlProvider(""))
return &WebhookExtraBuilder{
isPublic: isPublic,
urlProvider: urlProvider,
ExtraBuilder: func(b *provisioningapis.APIBuilder) provisioningapis.Extra {
clients := resources.NewClientFactory(configProvider)
parsers := resources.NewParserFactory(clients)
@@ -77,10 +91,7 @@ func ProvideWebhooks(
render,
webhook,
urlProvider,
ghFactory,
parsers,
[]jobs.Worker{pullRequestWorker},
isPublic, // Pass the public URL flag
)
},
}
@@ -89,32 +100,21 @@ func ProvideWebhooks(
// WebhookExtra implements the Extra interface for webhooks
// to wrap around
type WebhookExtra struct {
render *renderConnector
webhook *webhookConnector
urlProvider func(namespace string) string
ghFactory *github.Factory
parsers resources.ParserFactory
workers []jobs.Worker
isPublic bool // Flag to determine if webhook-enhanced repositories should be created
render *renderConnector
webhook *webhookConnector
workers []jobs.Worker
}
func NewWebhookExtra(
render *renderConnector,
webhook *webhookConnector,
urlProvider func(namespace string) string,
ghFactory *github.Factory,
parsers resources.ParserFactory,
workers []jobs.Worker,
isPublic bool,
) *WebhookExtra {
return &WebhookExtra{
render: render,
webhook: webhook,
urlProvider: urlProvider,
ghFactory: ghFactory,
parsers: parsers,
workers: workers,
isPublic: isPublic,
render: render,
webhook: webhook,
workers: workers,
}
}
@@ -128,16 +128,12 @@ func (e *WebhookExtra) Authorize(ctx context.Context, a authorizer.Attributes) (
return e.render.Authorize(ctx, a)
}
// Mutators returns the mutators for the webhook extra
func (e *WebhookExtra) Mutators() []controller.Mutator {
return nil
}
// UpdateStorage updates the storage with both render and webhook connectors
func (e *WebhookExtra) UpdateStorage(storage map[string]rest.Storage) error {
if err := e.webhook.UpdateStorage(storage); err != nil {
return err
}
return e.render.UpdateStorage(storage)
}
@@ -154,68 +150,3 @@ func (e *WebhookExtra) PostProcessOpenAPI(oas *spec3.OpenAPI) error {
func (e *WebhookExtra) GetJobWorkers() []jobs.Worker {
return e.workers
}
// AsRepository delegates repository creation to the webhook connector
func (e *WebhookExtra) AsRepository(ctx context.Context, r *provisioning.Repository, secure repository.SecureValues) (repository.Repository, error) {
// Only handle GitHub repositories with webhooks if URL is public
if r.Spec.Type == provisioning.GitHubRepositoryType && e.isPublic {
gvr := provisioning.RepositoryResourceInfo.GroupVersionResource()
webhookURL := fmt.Sprintf(
"%sapis/%s/%s/namespaces/%s/%s/%s/webhook",
e.urlProvider(r.GetNamespace()),
gvr.Group,
gvr.Version,
r.GetNamespace(),
gvr.Resource,
r.GetName(),
)
logger := logging.FromContext(ctx).With("url", r.Spec.GitHub.URL, "branch", r.Spec.GitHub.Branch, "path", r.Spec.GitHub.Path)
logger.Info("Instantiating Github repository with webhooks")
ghCfg := r.Spec.GitHub
if ghCfg == nil {
return nil, fmt.Errorf("github configuration is required for nano git")
}
// Decrypt GitHub token if needed
ghToken, err := secure.Token(ctx)
if err != nil {
return nil, fmt.Errorf("decrypt github token: %w", err)
}
webhookSecret, err := secure.WebhookSecret(ctx)
if err != nil {
return nil, fmt.Errorf("decrypt webhookSecret: %w", err)
}
gitCfg := git.RepositoryConfig{
URL: ghCfg.URL,
Branch: ghCfg.Branch,
Path: ghCfg.Path,
Token: ghToken,
}
gitRepo, err := git.NewGitRepository(ctx, r, gitCfg)
if err != nil {
return nil, fmt.Errorf("error creating git repository: %w", err)
}
basicRepo, err := github.NewGitHub(ctx, r, gitRepo, e.ghFactory, ghToken)
if err != nil {
return nil, fmt.Errorf("error creating github repository: %w", err)
}
return NewGithubWebhookRepository(basicRepo, webhookURL, webhookSecret), nil
}
return nil, nil
}
func (e *WebhookExtra) RepositoryTypes() []provisioning.RepositoryType {
// Only claim to handle GitHub repositories if URL is public
if e.isPublic {
return []provisioning.RepositoryType{
provisioning.GitHubRepositoryType,
}
}
return []provisioning.RepositoryType{}
}
@@ -1,369 +0,0 @@
package webhooks
import (
"context"
"errors"
"fmt"
"log/slog"
"net/http"
"slices"
"github.com/google/go-github/v70/github"
"github.com/google/uuid"
apierrors "k8s.io/apimachinery/pkg/api/errors"
"github.com/grafana/grafana-app-sdk/logging"
provisioning "github.com/grafana/grafana/apps/provisioning/pkg/apis/provisioning/v0alpha1"
common "github.com/grafana/grafana/pkg/apimachinery/apis/common/v0alpha1"
"github.com/grafana/grafana/pkg/registry/apis/provisioning/repository"
pgh "github.com/grafana/grafana/pkg/registry/apis/provisioning/repository/github"
)
var subscribedEvents = []string{"pull_request", "push"} // same order as slices.Sort()
type WebhookRepository interface {
Webhook(ctx context.Context, req *http.Request) (*provisioning.WebhookResponse, error)
}
type GithubWebhookRepository interface {
pgh.GithubRepository
repository.Hooks
WebhookRepository
}
type githubWebhookRepository struct {
pgh.GithubRepository
config *provisioning.Repository
owner string
repo string
secret common.RawSecureValue
gh pgh.Client
webhookURL string
}
func NewGithubWebhookRepository(
basic pgh.GithubRepository,
webhookURL string,
secret common.RawSecureValue,
) GithubWebhookRepository {
return &githubWebhookRepository{
GithubRepository: basic,
config: basic.Config(),
owner: basic.Owner(),
repo: basic.Repo(),
gh: basic.Client(),
webhookURL: webhookURL,
secret: secret,
}
}
// Webhook implements Repository.
func (r *githubWebhookRepository) Webhook(ctx context.Context, req *http.Request) (*provisioning.WebhookResponse, error) {
if r.config.Status.Webhook == nil {
return nil, fmt.Errorf("unexpected webhook request")
}
if r.secret.IsZero() {
return nil, fmt.Errorf("missing webhook secret")
}
payload, err := github.ValidatePayload(req, []byte(r.secret))
if err != nil {
return nil, apierrors.NewUnauthorized("invalid signature")
}
return r.parseWebhook(github.WebHookType(req), payload)
}
// This method does not include context because it does delegate any more requests
func (r *githubWebhookRepository) parseWebhook(messageType string, payload []byte) (*provisioning.WebhookResponse, error) {
event, err := github.ParseWebHook(messageType, payload)
if err != nil {
return nil, apierrors.NewBadRequest("invalid payload")
}
switch event := event.(type) {
case *github.PushEvent:
return r.parsePushEvent(event)
case *github.PullRequestEvent:
return r.parsePullRequestEvent(event)
case *github.PingEvent:
return &provisioning.WebhookResponse{
Code: http.StatusOK,
Message: "ping received",
}, nil
default:
return &provisioning.WebhookResponse{
Code: http.StatusNotImplemented,
Message: fmt.Sprintf("unsupported messageType: %s", messageType),
}, nil
}
}
func (r *githubWebhookRepository) parsePushEvent(event *github.PushEvent) (*provisioning.WebhookResponse, error) {
if event.GetRepo() == nil {
return nil, fmt.Errorf("missing repository in push event")
}
if event.GetRepo().GetFullName() != fmt.Sprintf("%s/%s", r.owner, r.repo) {
return nil, fmt.Errorf("repository mismatch")
}
// No need to sync if not enabled
if !r.config.Spec.Sync.Enabled {
return &provisioning.WebhookResponse{Code: http.StatusOK}, nil
}
// Skip silently if the event is not for the main/master branch
// as we cannot configure the webhook to only publish events for the main branch
if event.GetRef() != fmt.Sprintf("refs/heads/%s", r.config.Spec.GitHub.Branch) {
return &provisioning.WebhookResponse{Code: http.StatusOK}, nil
}
return &provisioning.WebhookResponse{
Code: http.StatusAccepted,
Job: &provisioning.JobSpec{
Repository: r.config.GetName(),
Action: provisioning.JobActionPull,
Pull: &provisioning.SyncJobOptions{
Incremental: true,
},
},
}, nil
}
func (r *githubWebhookRepository) parsePullRequestEvent(event *github.PullRequestEvent) (*provisioning.WebhookResponse, error) {
if event.GetRepo() == nil {
return nil, fmt.Errorf("missing repository in pull request event")
}
cfg := r.config.Spec.GitHub
if cfg == nil {
return nil, fmt.Errorf("missing GitHub config")
}
if event.GetRepo().GetFullName() != fmt.Sprintf("%s/%s", r.owner, r.repo) {
return nil, fmt.Errorf("repository mismatch")
}
pr := event.GetPullRequest()
if pr == nil {
return nil, fmt.Errorf("expected PR in event")
}
if pr.GetBase().GetRef() != r.config.Spec.GitHub.Branch {
return &provisioning.WebhookResponse{
Code: http.StatusOK,
Message: fmt.Sprintf("ignoring pull request event as %s is not the configured branch", pr.GetBase().GetRef()),
}, nil
}
action := event.GetAction()
if action != "opened" && action != "reopened" && action != "synchronize" {
return &provisioning.WebhookResponse{
Code: http.StatusOK, // Nothing needed
Message: fmt.Sprintf("ignore pull request event: %s", action),
}, nil
}
// Queue an async job that will parse files
return &provisioning.WebhookResponse{
Code: http.StatusAccepted, // Nothing needed
Message: fmt.Sprintf("pull request: %s", action),
Job: &provisioning.JobSpec{
Repository: r.config.GetName(),
Action: provisioning.JobActionPullRequest,
PullRequest: &provisioning.PullRequestJobOptions{
URL: pr.GetHTMLURL(),
PR: pr.GetNumber(),
Ref: pr.GetHead().GetRef(),
Hash: pr.GetHead().GetSHA(),
},
},
}, nil
}
// CommentPullRequest adds a comment to a pull request.
func (r *githubWebhookRepository) CommentPullRequest(ctx context.Context, prNumber int, comment string) error {
ctx, _ = r.logger(ctx, "")
return r.gh.CreatePullRequestComment(ctx, r.owner, r.repo, prNumber, comment)
}
func (r *githubWebhookRepository) createWebhook(ctx context.Context) (pgh.WebhookConfig, error) {
secret, err := uuid.NewRandom()
if err != nil {
return pgh.WebhookConfig{}, fmt.Errorf("could not generate secret: %w", err)
}
cfg := pgh.WebhookConfig{
URL: r.webhookURL,
Secret: secret.String(),
ContentType: "json",
Events: subscribedEvents,
Active: true,
}
hook, err := r.gh.CreateWebhook(ctx, r.owner, r.repo, cfg)
if err != nil {
return pgh.WebhookConfig{}, err
}
// HACK: GitHub does not return the secret, so we need to update it manually
hook.Secret = cfg.Secret
logging.FromContext(ctx).Info("webhook created", "url", cfg.URL, "id", hook.ID)
return hook, nil
}
// updateWebhook checks if the webhook needs to be updated and updates it if necessary.
// if the webhook does not exist, it will create it.
func (r *githubWebhookRepository) updateWebhook(ctx context.Context) (pgh.WebhookConfig, bool, error) {
if r.config.Status.Webhook == nil || r.config.Status.Webhook.ID == 0 {
hook, err := r.createWebhook(ctx)
if err != nil {
return pgh.WebhookConfig{}, false, err
}
return hook, true, nil
}
hook, err := r.gh.GetWebhook(ctx, r.owner, r.repo, r.config.Status.Webhook.ID)
switch {
case errors.Is(err, pgh.ErrResourceNotFound):
hook, err := r.createWebhook(ctx)
if err != nil {
return pgh.WebhookConfig{}, false, err
}
return hook, true, nil
case err != nil:
return pgh.WebhookConfig{}, false, fmt.Errorf("get webhook: %w", err)
}
var mustUpdate bool
if hook.URL != r.webhookURL {
mustUpdate = true
hook.URL = r.webhookURL
}
slices.Sort(hook.Events) // consistent order for comparison
if !slices.Equal(hook.Events, subscribedEvents) {
mustUpdate = true
hook.Events = subscribedEvents
}
if !mustUpdate {
return hook, false, nil
}
// Something has changed in the webhook. Let's rotate the secret as well, so as to ensure we end up with a 100% correct webhook.
secret, err := uuid.NewRandom()
if err != nil {
return pgh.WebhookConfig{}, false, fmt.Errorf("could not generate secret: %w", err)
}
hook.Secret = secret.String()
if err := r.gh.EditWebhook(ctx, r.owner, r.repo, hook); err != nil {
return pgh.WebhookConfig{}, false, fmt.Errorf("edit webhook: %w", err)
}
return hook, true, nil
}
func (r *githubWebhookRepository) deleteWebhook(ctx context.Context) error {
logger := logging.FromContext(ctx)
if r.config.Status.Webhook == nil {
return fmt.Errorf("webhook not found")
}
id := r.config.Status.Webhook.ID
if err := r.gh.DeleteWebhook(ctx, r.owner, r.repo, id); err != nil {
return fmt.Errorf("delete webhook: %w", err)
}
logger.Info("webhook deleted", "url", r.config.Status.Webhook.URL, "id", id)
return nil
}
func (r *githubWebhookRepository) OnCreate(ctx context.Context) ([]map[string]interface{}, error) {
if len(r.webhookURL) == 0 {
return nil, nil
}
ctx, _ = r.logger(ctx, "")
hook, err := r.createWebhook(ctx)
if err != nil {
return nil, err
}
return []map[string]interface{}{
{
"op": "replace",
"path": "/status/webhook",
"value": &provisioning.WebhookStatus{
ID: hook.ID,
URL: hook.URL,
SubscribedEvents: hook.Events,
},
},
{
"op": "replace",
"path": "/secure/webhookSecret",
"value": map[string]string{
"create": hook.Secret,
},
},
}, nil
}
func (r *githubWebhookRepository) OnUpdate(ctx context.Context) ([]map[string]interface{}, error) {
if len(r.webhookURL) == 0 {
return nil, nil
}
ctx, _ = r.logger(ctx, "")
hook, changed, err := r.updateWebhook(ctx)
if err != nil || !changed {
return nil, err
}
// update the webhook and secret
return []map[string]any{{
"op": "replace",
"path": "/status/webhook",
"value": &provisioning.WebhookStatus{
ID: hook.ID,
URL: hook.URL,
SubscribedEvents: hook.Events,
},
}, {
"op": "replace",
"path": "/secure/webhookSecret",
"value": map[string]string{
"create": hook.Secret,
},
}}, nil
}
func (r *githubWebhookRepository) OnDelete(ctx context.Context) error {
if r.config.Status.Webhook == nil {
return nil
}
return r.deleteWebhook(ctx)
}
func (r *githubWebhookRepository) logger(ctx context.Context, ref string) (context.Context, logging.Logger) {
logger := logging.FromContext(ctx)
type containsGh int
var containsGhKey containsGh
if ctx.Value(containsGhKey) != nil {
return ctx, logging.FromContext(ctx)
}
if ref == "" {
ref = r.config.Spec.GitHub.Branch
}
logger = logger.With(slog.Group("github_repository", "owner", r.owner, "name", r.repo, "ref", ref))
ctx = logging.Context(ctx, logger)
// We want to ensure we don't add multiple github_repository keys. With doesn't deduplicate the keys...
ctx = context.WithValue(ctx, containsGhKey, true)
return ctx, logger
}
File diff suppressed because it is too large Load Diff
@@ -1,231 +0,0 @@
{
"action": "created",
"issue": {
"id": 2726065547,
"number": 12,
"state": "open",
"locked": false,
"title": "Webhook test PR",
"author_association": "MEMBER",
"user": {
"login": "ryantxu",
"id": 705951,
"node_id": "MDQ6VXNlcjcwNTk1MQ==",
"avatar_url": "https://avatars.githubusercontent.com/u/705951?v=4",
"html_url": "https://github.com/ryantxu",
"gravatar_id": "",
"type": "User",
"site_admin": false,
"url": "https://api.github.com/users/ryantxu",
"events_url": "https://api.github.com/users/ryantxu/events{/privacy}",
"following_url": "https://api.github.com/users/ryantxu/following{/other_user}",
"followers_url": "https://api.github.com/users/ryantxu/followers",
"gists_url": "https://api.github.com/users/ryantxu/gists{/gist_id}",
"organizations_url": "https://api.github.com/users/ryantxu/orgs",
"received_events_url": "https://api.github.com/users/ryantxu/received_events",
"repos_url": "https://api.github.com/users/ryantxu/repos",
"starred_url": "https://api.github.com/users/ryantxu/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/ryantxu/subscriptions"
},
"comments": 1,
"created_at": "2024-12-09T05:53:14Z",
"updated_at": "2024-12-09T06:03:21Z",
"url": "https://api.github.com/repos/grafana/git-ui-sync-demo/issues/12",
"html_url": "https://github.com/grafana/git-ui-sync-demo/pull/12",
"comments_url": "https://api.github.com/repos/grafana/git-ui-sync-demo/issues/12/comments",
"events_url": "https://api.github.com/repos/grafana/git-ui-sync-demo/issues/12/events",
"labels_url": "https://api.github.com/repos/grafana/git-ui-sync-demo/issues/12/labels{/name}",
"repository_url": "https://api.github.com/repos/grafana/git-ui-sync-demo",
"pull_request": {
"url": "https://api.github.com/repos/grafana/git-ui-sync-demo/pulls/12",
"html_url": "https://github.com/grafana/git-ui-sync-demo/pull/12",
"diff_url": "https://github.com/grafana/git-ui-sync-demo/pull/12.diff",
"patch_url": "https://github.com/grafana/git-ui-sync-demo/pull/12.patch"
},
"reactions": {
"total_count": 0,
"+1": 0,
"-1": 0,
"laugh": 0,
"confused": 0,
"heart": 0,
"hooray": 0,
"rocket": 0,
"eyes": 0,
"url": "https://api.github.com/repos/grafana/git-ui-sync-demo/issues/12/reactions"
},
"node_id": "PR_kwDONO4cS86EfDVR",
"draft": false
},
"comment": {
"id": 2527008082,
"node_id": "IC_kwDONO4cS86WnxVS",
"body": "comment in PR",
"user": {
"login": "ryantxu",
"id": 705951,
"node_id": "MDQ6VXNlcjcwNTk1MQ==",
"avatar_url": "https://avatars.githubusercontent.com/u/705951?v=4",
"html_url": "https://github.com/ryantxu",
"gravatar_id": "",
"type": "User",
"site_admin": false,
"url": "https://api.github.com/users/ryantxu",
"events_url": "https://api.github.com/users/ryantxu/events{/privacy}",
"following_url": "https://api.github.com/users/ryantxu/following{/other_user}",
"followers_url": "https://api.github.com/users/ryantxu/followers",
"gists_url": "https://api.github.com/users/ryantxu/gists{/gist_id}",
"organizations_url": "https://api.github.com/users/ryantxu/orgs",
"received_events_url": "https://api.github.com/users/ryantxu/received_events",
"repos_url": "https://api.github.com/users/ryantxu/repos",
"starred_url": "https://api.github.com/users/ryantxu/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/ryantxu/subscriptions"
},
"reactions": {
"total_count": 0,
"+1": 0,
"-1": 0,
"laugh": 0,
"confused": 0,
"heart": 0,
"hooray": 0,
"rocket": 0,
"eyes": 0,
"url": "https://api.github.com/repos/grafana/git-ui-sync-demo/issues/comments/2527008082/reactions"
},
"created_at": "2024-12-09T06:03:19Z",
"updated_at": "2024-12-09T06:03:19Z",
"author_association": "MEMBER",
"url": "https://api.github.com/repos/grafana/git-ui-sync-demo/issues/comments/2527008082",
"html_url": "https://github.com/grafana/git-ui-sync-demo/pull/12#issuecomment-2527008082",
"issue_url": "https://api.github.com/repos/grafana/git-ui-sync-demo/issues/12"
},
"repository": {
"id": 888020043,
"node_id": "R_kgDONO4cSw",
"owner": {
"login": "grafana",
"id": 7195757,
"node_id": "MDEyOk9yZ2FuaXphdGlvbjcxOTU3NTc=",
"avatar_url": "https://avatars.githubusercontent.com/u/7195757?v=4",
"html_url": "https://github.com/grafana",
"gravatar_id": "",
"type": "Organization",
"site_admin": false,
"url": "https://api.github.com/users/grafana",
"events_url": "https://api.github.com/users/grafana/events{/privacy}",
"following_url": "https://api.github.com/users/grafana/following{/other_user}",
"followers_url": "https://api.github.com/users/grafana/followers",
"gists_url": "https://api.github.com/users/grafana/gists{/gist_id}",
"organizations_url": "https://api.github.com/users/grafana/orgs",
"received_events_url": "https://api.github.com/users/grafana/received_events",
"repos_url": "https://api.github.com/users/grafana/repos",
"starred_url": "https://api.github.com/users/grafana/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/grafana/subscriptions"
},
"name": "git-ui-sync-demo",
"full_name": "grafana/git-ui-sync-demo",
"description": "A repository containing Grafana dashboards to demo the Github Sync feature in Grafana.",
"default_branch": "main",
"created_at": "2024-11-13T17:13:33Z",
"pushed_at": "2024-12-09T05:58:00Z",
"updated_at": "2024-12-09T05:58:03Z",
"html_url": "https://github.com/grafana/git-ui-sync-demo",
"clone_url": "https://github.com/grafana/git-ui-sync-demo.git",
"git_url": "git://github.com/grafana/git-ui-sync-demo.git",
"ssh_url": "git@github.com:grafana/git-ui-sync-demo.git",
"svn_url": "https://github.com/grafana/git-ui-sync-demo",
"fork": false,
"forks_count": 0,
"open_issues_count": 9,
"open_issues": 9,
"stargazers_count": 0,
"watchers_count": 0,
"watchers": 0,
"size": 141,
"allow_forking": false,
"web_commit_signoff_required": false,
"archived": false,
"disabled": false,
"private": true,
"has_issues": true,
"has_wiki": true,
"has_pages": false,
"has_projects": true,
"has_downloads": true,
"has_discussions": false,
"is_template": false,
"url": "https://api.github.com/repos/grafana/git-ui-sync-demo",
"archive_url": "https://api.github.com/repos/grafana/git-ui-sync-demo/{archive_format}{/ref}",
"assignees_url": "https://api.github.com/repos/grafana/git-ui-sync-demo/assignees{/user}",
"blobs_url": "https://api.github.com/repos/grafana/git-ui-sync-demo/git/blobs{/sha}",
"branches_url": "https://api.github.com/repos/grafana/git-ui-sync-demo/branches{/branch}",
"collaborators_url": "https://api.github.com/repos/grafana/git-ui-sync-demo/collaborators{/collaborator}",
"comments_url": "https://api.github.com/repos/grafana/git-ui-sync-demo/comments{/number}",
"commits_url": "https://api.github.com/repos/grafana/git-ui-sync-demo/commits{/sha}",
"compare_url": "https://api.github.com/repos/grafana/git-ui-sync-demo/compare/{base}...{head}",
"contents_url": "https://api.github.com/repos/grafana/git-ui-sync-demo/contents/{+path}",
"contributors_url": "https://api.github.com/repos/grafana/git-ui-sync-demo/contributors",
"deployments_url": "https://api.github.com/repos/grafana/git-ui-sync-demo/deployments",
"downloads_url": "https://api.github.com/repos/grafana/git-ui-sync-demo/downloads",
"events_url": "https://api.github.com/repos/grafana/git-ui-sync-demo/events",
"forks_url": "https://api.github.com/repos/grafana/git-ui-sync-demo/forks",
"git_commits_url": "https://api.github.com/repos/grafana/git-ui-sync-demo/git/commits{/sha}",
"git_refs_url": "https://api.github.com/repos/grafana/git-ui-sync-demo/git/refs{/sha}",
"git_tags_url": "https://api.github.com/repos/grafana/git-ui-sync-demo/git/tags{/sha}",
"hooks_url": "https://api.github.com/repos/grafana/git-ui-sync-demo/hooks",
"issue_comment_url": "https://api.github.com/repos/grafana/git-ui-sync-demo/issues/comments{/number}",
"issue_events_url": "https://api.github.com/repos/grafana/git-ui-sync-demo/issues/events{/number}",
"issues_url": "https://api.github.com/repos/grafana/git-ui-sync-demo/issues{/number}",
"keys_url": "https://api.github.com/repos/grafana/git-ui-sync-demo/keys{/key_id}",
"labels_url": "https://api.github.com/repos/grafana/git-ui-sync-demo/labels{/name}",
"languages_url": "https://api.github.com/repos/grafana/git-ui-sync-demo/languages",
"merges_url": "https://api.github.com/repos/grafana/git-ui-sync-demo/merges",
"milestones_url": "https://api.github.com/repos/grafana/git-ui-sync-demo/milestones{/number}",
"notifications_url": "https://api.github.com/repos/grafana/git-ui-sync-demo/notifications{?since,all,participating}",
"pulls_url": "https://api.github.com/repos/grafana/git-ui-sync-demo/pulls{/number}",
"releases_url": "https://api.github.com/repos/grafana/git-ui-sync-demo/releases{/id}",
"stargazers_url": "https://api.github.com/repos/grafana/git-ui-sync-demo/stargazers",
"statuses_url": "https://api.github.com/repos/grafana/git-ui-sync-demo/statuses/{sha}",
"subscribers_url": "https://api.github.com/repos/grafana/git-ui-sync-demo/subscribers",
"subscription_url": "https://api.github.com/repos/grafana/git-ui-sync-demo/subscription",
"tags_url": "https://api.github.com/repos/grafana/git-ui-sync-demo/tags",
"trees_url": "https://api.github.com/repos/grafana/git-ui-sync-demo/git/trees{/sha}",
"teams_url": "https://api.github.com/repos/grafana/git-ui-sync-demo/teams",
"visibility": "internal"
},
"sender": {
"login": "ryantxu",
"id": 705951,
"node_id": "MDQ6VXNlcjcwNTk1MQ==",
"avatar_url": "https://avatars.githubusercontent.com/u/705951?v=4",
"html_url": "https://github.com/ryantxu",
"gravatar_id": "",
"type": "User",
"site_admin": false,
"url": "https://api.github.com/users/ryantxu",
"events_url": "https://api.github.com/users/ryantxu/events{/privacy}",
"following_url": "https://api.github.com/users/ryantxu/following{/other_user}",
"followers_url": "https://api.github.com/users/ryantxu/followers",
"gists_url": "https://api.github.com/users/ryantxu/gists{/gist_id}",
"organizations_url": "https://api.github.com/users/ryantxu/orgs",
"received_events_url": "https://api.github.com/users/ryantxu/received_events",
"repos_url": "https://api.github.com/users/ryantxu/repos",
"starred_url": "https://api.github.com/users/ryantxu/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/ryantxu/subscriptions"
},
"organization": {
"login": "grafana",
"id": 7195757,
"node_id": "MDEyOk9yZ2FuaXphdGlvbjcxOTU3NTc=",
"avatar_url": "https://avatars.githubusercontent.com/u/7195757?v=4",
"description": "Grafana Labs is behind leading open source projects Grafana and Loki, and the creator of the first open \u0026 composable observability platform.",
"url": "https://api.github.com/orgs/grafana",
"events_url": "https://api.github.com/orgs/grafana/events",
"hooks_url": "https://api.github.com/orgs/grafana/hooks",
"issues_url": "https://api.github.com/orgs/grafana/issues",
"members_url": "https://api.github.com/orgs/grafana/members{/member}",
"public_members_url": "https://api.github.com/orgs/grafana/public_members{/member}",
"repos_url": "https://api.github.com/orgs/grafana/repos"
}
}
@@ -1,143 +0,0 @@
{
"zen": "Keep it logically awesome.",
"hook_id": 517704995,
"hook": {
"created_at": "2024-12-09T05:44:20Z",
"updated_at": "2024-12-09T05:44:20Z",
"url": "https://api.github.com/repos/grafana/git-ui-sync-demo/hooks/517704995",
"id": 517704995,
"type": "Repository",
"name": "web",
"test_url": "https://api.github.com/repos/grafana/git-ui-sync-demo/hooks/517704995/test",
"ping_url": "https://api.github.com/repos/grafana/git-ui-sync-demo/hooks/517704995/pings",
"last_response": {
"code": null,
"message": null,
"status": "unused"
},
"config": {
"content_type": "form",
"insecure_ssl": "0",
"url": "https://0b71-216-128-0-90.ngrok-free.app/apis/provisioning.grafana.app/v0alpha1/namespaces/default/repositories/github-example-ryan/webhook",
"secret": "********"
},
"events": [
"*"
],
"active": true
},
"repository": {
"id": 888020043,
"node_id": "R_kgDONO4cSw",
"owner": {
"login": "grafana",
"id": 7195757,
"node_id": "MDEyOk9yZ2FuaXphdGlvbjcxOTU3NTc=",
"avatar_url": "https://avatars.githubusercontent.com/u/7195757?v=4",
"html_url": "https://github.com/grafana",
"gravatar_id": "",
"type": "Organization",
"site_admin": false,
"url": "https://api.github.com/users/grafana",
"events_url": "https://api.github.com/users/grafana/events{/privacy}",
"following_url": "https://api.github.com/users/grafana/following{/other_user}",
"followers_url": "https://api.github.com/users/grafana/followers",
"gists_url": "https://api.github.com/users/grafana/gists{/gist_id}",
"organizations_url": "https://api.github.com/users/grafana/orgs",
"received_events_url": "https://api.github.com/users/grafana/received_events",
"repos_url": "https://api.github.com/users/grafana/repos",
"starred_url": "https://api.github.com/users/grafana/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/grafana/subscriptions"
},
"name": "git-ui-sync-demo",
"full_name": "grafana/git-ui-sync-demo",
"description": "A repository containing Grafana dashboards to demo the Github Sync feature in Grafana.",
"default_branch": "main",
"created_at": "2024-11-13T17:13:33Z",
"pushed_at": "2024-12-08T10:51:24Z",
"updated_at": "2024-11-28T12:53:26Z",
"html_url": "https://github.com/grafana/git-ui-sync-demo",
"clone_url": "https://github.com/grafana/git-ui-sync-demo.git",
"git_url": "git://github.com/grafana/git-ui-sync-demo.git",
"ssh_url": "git@github.com:grafana/git-ui-sync-demo.git",
"svn_url": "https://github.com/grafana/git-ui-sync-demo",
"fork": false,
"forks_count": 0,
"open_issues_count": 8,
"open_issues": 8,
"stargazers_count": 0,
"watchers_count": 0,
"watchers": 0,
"size": 141,
"allow_forking": false,
"web_commit_signoff_required": false,
"archived": false,
"disabled": false,
"private": true,
"has_issues": true,
"has_wiki": true,
"has_pages": false,
"has_projects": true,
"has_downloads": true,
"has_discussions": false,
"is_template": false,
"url": "https://api.github.com/repos/grafana/git-ui-sync-demo",
"archive_url": "https://api.github.com/repos/grafana/git-ui-sync-demo/{archive_format}{/ref}",
"assignees_url": "https://api.github.com/repos/grafana/git-ui-sync-demo/assignees{/user}",
"blobs_url": "https://api.github.com/repos/grafana/git-ui-sync-demo/git/blobs{/sha}",
"branches_url": "https://api.github.com/repos/grafana/git-ui-sync-demo/branches{/branch}",
"collaborators_url": "https://api.github.com/repos/grafana/git-ui-sync-demo/collaborators{/collaborator}",
"comments_url": "https://api.github.com/repos/grafana/git-ui-sync-demo/comments{/number}",
"commits_url": "https://api.github.com/repos/grafana/git-ui-sync-demo/commits{/sha}",
"compare_url": "https://api.github.com/repos/grafana/git-ui-sync-demo/compare/{base}...{head}",
"contents_url": "https://api.github.com/repos/grafana/git-ui-sync-demo/contents/{+path}",
"contributors_url": "https://api.github.com/repos/grafana/git-ui-sync-demo/contributors",
"deployments_url": "https://api.github.com/repos/grafana/git-ui-sync-demo/deployments",
"downloads_url": "https://api.github.com/repos/grafana/git-ui-sync-demo/downloads",
"events_url": "https://api.github.com/repos/grafana/git-ui-sync-demo/events",
"forks_url": "https://api.github.com/repos/grafana/git-ui-sync-demo/forks",
"git_commits_url": "https://api.github.com/repos/grafana/git-ui-sync-demo/git/commits{/sha}",
"git_refs_url": "https://api.github.com/repos/grafana/git-ui-sync-demo/git/refs{/sha}",
"git_tags_url": "https://api.github.com/repos/grafana/git-ui-sync-demo/git/tags{/sha}",
"hooks_url": "https://api.github.com/repos/grafana/git-ui-sync-demo/hooks",
"issue_comment_url": "https://api.github.com/repos/grafana/git-ui-sync-demo/issues/comments{/number}",
"issue_events_url": "https://api.github.com/repos/grafana/git-ui-sync-demo/issues/events{/number}",
"issues_url": "https://api.github.com/repos/grafana/git-ui-sync-demo/issues{/number}",
"keys_url": "https://api.github.com/repos/grafana/git-ui-sync-demo/keys{/key_id}",
"labels_url": "https://api.github.com/repos/grafana/git-ui-sync-demo/labels{/name}",
"languages_url": "https://api.github.com/repos/grafana/git-ui-sync-demo/languages",
"merges_url": "https://api.github.com/repos/grafana/git-ui-sync-demo/merges",
"milestones_url": "https://api.github.com/repos/grafana/git-ui-sync-demo/milestones{/number}",
"notifications_url": "https://api.github.com/repos/grafana/git-ui-sync-demo/notifications{?since,all,participating}",
"pulls_url": "https://api.github.com/repos/grafana/git-ui-sync-demo/pulls{/number}",
"releases_url": "https://api.github.com/repos/grafana/git-ui-sync-demo/releases{/id}",
"stargazers_url": "https://api.github.com/repos/grafana/git-ui-sync-demo/stargazers",
"statuses_url": "https://api.github.com/repos/grafana/git-ui-sync-demo/statuses/{sha}",
"subscribers_url": "https://api.github.com/repos/grafana/git-ui-sync-demo/subscribers",
"subscription_url": "https://api.github.com/repos/grafana/git-ui-sync-demo/subscription",
"tags_url": "https://api.github.com/repos/grafana/git-ui-sync-demo/tags",
"trees_url": "https://api.github.com/repos/grafana/git-ui-sync-demo/git/trees{/sha}",
"teams_url": "https://api.github.com/repos/grafana/git-ui-sync-demo/teams",
"visibility": "internal"
},
"sender": {
"login": "ryantxu",
"id": 705951,
"node_id": "MDQ6VXNlcjcwNTk1MQ==",
"avatar_url": "https://avatars.githubusercontent.com/u/705951?v=4",
"html_url": "https://github.com/ryantxu",
"gravatar_id": "",
"type": "User",
"site_admin": false,
"url": "https://api.github.com/users/ryantxu",
"events_url": "https://api.github.com/users/ryantxu/events{/privacy}",
"following_url": "https://api.github.com/users/ryantxu/following{/other_user}",
"followers_url": "https://api.github.com/users/ryantxu/followers",
"gists_url": "https://api.github.com/users/ryantxu/gists{/gist_id}",
"organizations_url": "https://api.github.com/users/ryantxu/orgs",
"received_events_url": "https://api.github.com/users/ryantxu/received_events",
"repos_url": "https://api.github.com/users/ryantxu/repos",
"starred_url": "https://api.github.com/users/ryantxu/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/ryantxu/subscriptions"
}
}
@@ -1,470 +0,0 @@
{
"action": "opened",
"number": 12,
"pull_request": {
"id": 2222732625,
"number": 12,
"state": "open",
"locked": false,
"title": "Webhook test PR",
"created_at": "2024-12-09T05:53:14Z",
"updated_at": "2024-12-09T05:53:14Z",
"user": {
"login": "ryantxu",
"id": 705951,
"node_id": "MDQ6VXNlcjcwNTk1MQ==",
"avatar_url": "https://avatars.githubusercontent.com/u/705951?v=4",
"html_url": "https://github.com/ryantxu",
"gravatar_id": "",
"type": "User",
"site_admin": false,
"url": "https://api.github.com/users/ryantxu",
"events_url": "https://api.github.com/users/ryantxu/events{/privacy}",
"following_url": "https://api.github.com/users/ryantxu/following{/other_user}",
"followers_url": "https://api.github.com/users/ryantxu/followers",
"gists_url": "https://api.github.com/users/ryantxu/gists{/gist_id}",
"organizations_url": "https://api.github.com/users/ryantxu/orgs",
"received_events_url": "https://api.github.com/users/ryantxu/received_events",
"repos_url": "https://api.github.com/users/ryantxu/repos",
"starred_url": "https://api.github.com/users/ryantxu/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/ryantxu/subscriptions"
},
"draft": false,
"merged": false,
"mergeable_state": "unknown",
"comments": 0,
"commits": 1,
"additions": 1,
"deletions": 0,
"changed_files": 1,
"url": "https://api.github.com/repos/grafana/git-ui-sync-demo/pulls/12",
"html_url": "https://github.com/grafana/git-ui-sync-demo/pull/12",
"issue_url": "https://api.github.com/repos/grafana/git-ui-sync-demo/issues/12",
"statuses_url": "https://api.github.com/repos/grafana/git-ui-sync-demo/statuses/ab5446a53df9e5f8bdeed52250f51fad08e822bc",
"diff_url": "https://github.com/grafana/git-ui-sync-demo/pull/12.diff",
"patch_url": "https://github.com/grafana/git-ui-sync-demo/pull/12.patch",
"commits_url": "https://api.github.com/repos/grafana/git-ui-sync-demo/pulls/12/commits",
"comments_url": "https://api.github.com/repos/grafana/git-ui-sync-demo/issues/12/comments",
"review_comments_url": "https://api.github.com/repos/grafana/git-ui-sync-demo/pulls/12/comments",
"review_comment_url": "https://api.github.com/repos/grafana/git-ui-sync-demo/pulls/comments{/number}",
"review_comments": 0,
"maintainer_can_modify": false,
"author_association": "MEMBER",
"node_id": "PR_kwDONO4cS86EfDVR",
"_links": {
"self": {
"href": "https://api.github.com/repos/grafana/git-ui-sync-demo/pulls/12"
},
"html": {
"href": "https://github.com/grafana/git-ui-sync-demo/pull/12"
},
"issue": {
"href": "https://api.github.com/repos/grafana/git-ui-sync-demo/issues/12"
},
"comments": {
"href": "https://api.github.com/repos/grafana/git-ui-sync-demo/issues/12/comments"
},
"review_comments": {
"href": "https://api.github.com/repos/grafana/git-ui-sync-demo/pulls/12/comments"
},
"review_comment": {
"href": "https://api.github.com/repos/grafana/git-ui-sync-demo/pulls/comments{/number}"
},
"commits": {
"href": "https://api.github.com/repos/grafana/git-ui-sync-demo/pulls/12/commits"
},
"statuses": {
"href": "https://api.github.com/repos/grafana/git-ui-sync-demo/statuses/ab5446a53df9e5f8bdeed52250f51fad08e822bc"
}
},
"head": {
"label": "grafana:dashboard/1733653266690",
"ref": "dashboard/1733653266690",
"sha": "ab5446a53df9e5f8bdeed52250f51fad08e822bc",
"repo": {
"id": 888020043,
"node_id": "R_kgDONO4cSw",
"owner": {
"login": "grafana",
"id": 7195757,
"node_id": "MDEyOk9yZ2FuaXphdGlvbjcxOTU3NTc=",
"avatar_url": "https://avatars.githubusercontent.com/u/7195757?v=4",
"html_url": "https://github.com/grafana",
"gravatar_id": "",
"type": "Organization",
"site_admin": false,
"url": "https://api.github.com/users/grafana",
"events_url": "https://api.github.com/users/grafana/events{/privacy}",
"following_url": "https://api.github.com/users/grafana/following{/other_user}",
"followers_url": "https://api.github.com/users/grafana/followers",
"gists_url": "https://api.github.com/users/grafana/gists{/gist_id}",
"organizations_url": "https://api.github.com/users/grafana/orgs",
"received_events_url": "https://api.github.com/users/grafana/received_events",
"repos_url": "https://api.github.com/users/grafana/repos",
"starred_url": "https://api.github.com/users/grafana/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/grafana/subscriptions"
},
"name": "git-ui-sync-demo",
"full_name": "grafana/git-ui-sync-demo",
"description": "A repository containing Grafana dashboards to demo the Github Sync feature in Grafana.",
"default_branch": "main",
"created_at": "2024-11-13T17:13:33Z",
"pushed_at": "2024-12-08T10:51:24Z",
"updated_at": "2024-11-28T12:53:26Z",
"html_url": "https://github.com/grafana/git-ui-sync-demo",
"clone_url": "https://github.com/grafana/git-ui-sync-demo.git",
"git_url": "git://github.com/grafana/git-ui-sync-demo.git",
"ssh_url": "git@github.com:grafana/git-ui-sync-demo.git",
"svn_url": "https://github.com/grafana/git-ui-sync-demo",
"fork": false,
"forks_count": 0,
"open_issues_count": 9,
"open_issues": 9,
"stargazers_count": 0,
"watchers_count": 0,
"watchers": 0,
"size": 141,
"allow_rebase_merge": true,
"allow_update_branch": false,
"allow_squash_merge": true,
"allow_merge_commit": true,
"allow_auto_merge": false,
"allow_forking": false,
"web_commit_signoff_required": false,
"delete_branch_on_merge": false,
"use_squash_pr_title_as_default": false,
"squash_merge_commit_title": "COMMIT_OR_PR_TITLE",
"squash_merge_commit_message": "COMMIT_MESSAGES",
"merge_commit_title": "MERGE_MESSAGE",
"merge_commit_message": "PR_TITLE",
"archived": false,
"disabled": false,
"private": true,
"has_issues": true,
"has_wiki": true,
"has_pages": false,
"has_projects": true,
"has_downloads": true,
"has_discussions": false,
"is_template": false,
"url": "https://api.github.com/repos/grafana/git-ui-sync-demo",
"archive_url": "https://api.github.com/repos/grafana/git-ui-sync-demo/{archive_format}{/ref}",
"assignees_url": "https://api.github.com/repos/grafana/git-ui-sync-demo/assignees{/user}",
"blobs_url": "https://api.github.com/repos/grafana/git-ui-sync-demo/git/blobs{/sha}",
"branches_url": "https://api.github.com/repos/grafana/git-ui-sync-demo/branches{/branch}",
"collaborators_url": "https://api.github.com/repos/grafana/git-ui-sync-demo/collaborators{/collaborator}",
"comments_url": "https://api.github.com/repos/grafana/git-ui-sync-demo/comments{/number}",
"commits_url": "https://api.github.com/repos/grafana/git-ui-sync-demo/commits{/sha}",
"compare_url": "https://api.github.com/repos/grafana/git-ui-sync-demo/compare/{base}...{head}",
"contents_url": "https://api.github.com/repos/grafana/git-ui-sync-demo/contents/{+path}",
"contributors_url": "https://api.github.com/repos/grafana/git-ui-sync-demo/contributors",
"deployments_url": "https://api.github.com/repos/grafana/git-ui-sync-demo/deployments",
"downloads_url": "https://api.github.com/repos/grafana/git-ui-sync-demo/downloads",
"events_url": "https://api.github.com/repos/grafana/git-ui-sync-demo/events",
"forks_url": "https://api.github.com/repos/grafana/git-ui-sync-demo/forks",
"git_commits_url": "https://api.github.com/repos/grafana/git-ui-sync-demo/git/commits{/sha}",
"git_refs_url": "https://api.github.com/repos/grafana/git-ui-sync-demo/git/refs{/sha}",
"git_tags_url": "https://api.github.com/repos/grafana/git-ui-sync-demo/git/tags{/sha}",
"hooks_url": "https://api.github.com/repos/grafana/git-ui-sync-demo/hooks",
"issue_comment_url": "https://api.github.com/repos/grafana/git-ui-sync-demo/issues/comments{/number}",
"issue_events_url": "https://api.github.com/repos/grafana/git-ui-sync-demo/issues/events{/number}",
"issues_url": "https://api.github.com/repos/grafana/git-ui-sync-demo/issues{/number}",
"keys_url": "https://api.github.com/repos/grafana/git-ui-sync-demo/keys{/key_id}",
"labels_url": "https://api.github.com/repos/grafana/git-ui-sync-demo/labels{/name}",
"languages_url": "https://api.github.com/repos/grafana/git-ui-sync-demo/languages",
"merges_url": "https://api.github.com/repos/grafana/git-ui-sync-demo/merges",
"milestones_url": "https://api.github.com/repos/grafana/git-ui-sync-demo/milestones{/number}",
"notifications_url": "https://api.github.com/repos/grafana/git-ui-sync-demo/notifications{?since,all,participating}",
"pulls_url": "https://api.github.com/repos/grafana/git-ui-sync-demo/pulls{/number}",
"releases_url": "https://api.github.com/repos/grafana/git-ui-sync-demo/releases{/id}",
"stargazers_url": "https://api.github.com/repos/grafana/git-ui-sync-demo/stargazers",
"statuses_url": "https://api.github.com/repos/grafana/git-ui-sync-demo/statuses/{sha}",
"subscribers_url": "https://api.github.com/repos/grafana/git-ui-sync-demo/subscribers",
"subscription_url": "https://api.github.com/repos/grafana/git-ui-sync-demo/subscription",
"tags_url": "https://api.github.com/repos/grafana/git-ui-sync-demo/tags",
"trees_url": "https://api.github.com/repos/grafana/git-ui-sync-demo/git/trees{/sha}",
"teams_url": "https://api.github.com/repos/grafana/git-ui-sync-demo/teams",
"visibility": "internal"
},
"user": {
"login": "grafana",
"id": 7195757,
"node_id": "MDEyOk9yZ2FuaXphdGlvbjcxOTU3NTc=",
"avatar_url": "https://avatars.githubusercontent.com/u/7195757?v=4",
"html_url": "https://github.com/grafana",
"gravatar_id": "",
"type": "Organization",
"site_admin": false,
"url": "https://api.github.com/users/grafana",
"events_url": "https://api.github.com/users/grafana/events{/privacy}",
"following_url": "https://api.github.com/users/grafana/following{/other_user}",
"followers_url": "https://api.github.com/users/grafana/followers",
"gists_url": "https://api.github.com/users/grafana/gists{/gist_id}",
"organizations_url": "https://api.github.com/users/grafana/orgs",
"received_events_url": "https://api.github.com/users/grafana/received_events",
"repos_url": "https://api.github.com/users/grafana/repos",
"starred_url": "https://api.github.com/users/grafana/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/grafana/subscriptions"
}
},
"base": {
"label": "grafana:main",
"ref": "main",
"sha": "6c86a0cdfd220c2fe3518cfaa4a4babf030d9a7a",
"repo": {
"id": 888020043,
"node_id": "R_kgDONO4cSw",
"owner": {
"login": "grafana",
"id": 7195757,
"node_id": "MDEyOk9yZ2FuaXphdGlvbjcxOTU3NTc=",
"avatar_url": "https://avatars.githubusercontent.com/u/7195757?v=4",
"html_url": "https://github.com/grafana",
"gravatar_id": "",
"type": "Organization",
"site_admin": false,
"url": "https://api.github.com/users/grafana",
"events_url": "https://api.github.com/users/grafana/events{/privacy}",
"following_url": "https://api.github.com/users/grafana/following{/other_user}",
"followers_url": "https://api.github.com/users/grafana/followers",
"gists_url": "https://api.github.com/users/grafana/gists{/gist_id}",
"organizations_url": "https://api.github.com/users/grafana/orgs",
"received_events_url": "https://api.github.com/users/grafana/received_events",
"repos_url": "https://api.github.com/users/grafana/repos",
"starred_url": "https://api.github.com/users/grafana/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/grafana/subscriptions"
},
"name": "git-ui-sync-demo",
"full_name": "grafana/git-ui-sync-demo",
"description": "A repository containing Grafana dashboards to demo the Github Sync feature in Grafana.",
"default_branch": "main",
"created_at": "2024-11-13T17:13:33Z",
"pushed_at": "2024-12-08T10:51:24Z",
"updated_at": "2024-11-28T12:53:26Z",
"html_url": "https://github.com/grafana/git-ui-sync-demo",
"clone_url": "https://github.com/grafana/git-ui-sync-demo.git",
"git_url": "git://github.com/grafana/git-ui-sync-demo.git",
"ssh_url": "git@github.com:grafana/git-ui-sync-demo.git",
"svn_url": "https://github.com/grafana/git-ui-sync-demo",
"fork": false,
"forks_count": 0,
"open_issues_count": 9,
"open_issues": 9,
"stargazers_count": 0,
"watchers_count": 0,
"watchers": 0,
"size": 141,
"allow_rebase_merge": true,
"allow_update_branch": false,
"allow_squash_merge": true,
"allow_merge_commit": true,
"allow_auto_merge": false,
"allow_forking": false,
"web_commit_signoff_required": false,
"delete_branch_on_merge": false,
"use_squash_pr_title_as_default": false,
"squash_merge_commit_title": "COMMIT_OR_PR_TITLE",
"squash_merge_commit_message": "COMMIT_MESSAGES",
"merge_commit_title": "MERGE_MESSAGE",
"merge_commit_message": "PR_TITLE",
"archived": false,
"disabled": false,
"private": true,
"has_issues": true,
"has_wiki": true,
"has_pages": false,
"has_projects": true,
"has_downloads": true,
"has_discussions": false,
"is_template": false,
"url": "https://api.github.com/repos/grafana/git-ui-sync-demo",
"archive_url": "https://api.github.com/repos/grafana/git-ui-sync-demo/{archive_format}{/ref}",
"assignees_url": "https://api.github.com/repos/grafana/git-ui-sync-demo/assignees{/user}",
"blobs_url": "https://api.github.com/repos/grafana/git-ui-sync-demo/git/blobs{/sha}",
"branches_url": "https://api.github.com/repos/grafana/git-ui-sync-demo/branches{/branch}",
"collaborators_url": "https://api.github.com/repos/grafana/git-ui-sync-demo/collaborators{/collaborator}",
"comments_url": "https://api.github.com/repos/grafana/git-ui-sync-demo/comments{/number}",
"commits_url": "https://api.github.com/repos/grafana/git-ui-sync-demo/commits{/sha}",
"compare_url": "https://api.github.com/repos/grafana/git-ui-sync-demo/compare/{base}...{head}",
"contents_url": "https://api.github.com/repos/grafana/git-ui-sync-demo/contents/{+path}",
"contributors_url": "https://api.github.com/repos/grafana/git-ui-sync-demo/contributors",
"deployments_url": "https://api.github.com/repos/grafana/git-ui-sync-demo/deployments",
"downloads_url": "https://api.github.com/repos/grafana/git-ui-sync-demo/downloads",
"events_url": "https://api.github.com/repos/grafana/git-ui-sync-demo/events",
"forks_url": "https://api.github.com/repos/grafana/git-ui-sync-demo/forks",
"git_commits_url": "https://api.github.com/repos/grafana/git-ui-sync-demo/git/commits{/sha}",
"git_refs_url": "https://api.github.com/repos/grafana/git-ui-sync-demo/git/refs{/sha}",
"git_tags_url": "https://api.github.com/repos/grafana/git-ui-sync-demo/git/tags{/sha}",
"hooks_url": "https://api.github.com/repos/grafana/git-ui-sync-demo/hooks",
"issue_comment_url": "https://api.github.com/repos/grafana/git-ui-sync-demo/issues/comments{/number}",
"issue_events_url": "https://api.github.com/repos/grafana/git-ui-sync-demo/issues/events{/number}",
"issues_url": "https://api.github.com/repos/grafana/git-ui-sync-demo/issues{/number}",
"keys_url": "https://api.github.com/repos/grafana/git-ui-sync-demo/keys{/key_id}",
"labels_url": "https://api.github.com/repos/grafana/git-ui-sync-demo/labels{/name}",
"languages_url": "https://api.github.com/repos/grafana/git-ui-sync-demo/languages",
"merges_url": "https://api.github.com/repos/grafana/git-ui-sync-demo/merges",
"milestones_url": "https://api.github.com/repos/grafana/git-ui-sync-demo/milestones{/number}",
"notifications_url": "https://api.github.com/repos/grafana/git-ui-sync-demo/notifications{?since,all,participating}",
"pulls_url": "https://api.github.com/repos/grafana/git-ui-sync-demo/pulls{/number}",
"releases_url": "https://api.github.com/repos/grafana/git-ui-sync-demo/releases{/id}",
"stargazers_url": "https://api.github.com/repos/grafana/git-ui-sync-demo/stargazers",
"statuses_url": "https://api.github.com/repos/grafana/git-ui-sync-demo/statuses/{sha}",
"subscribers_url": "https://api.github.com/repos/grafana/git-ui-sync-demo/subscribers",
"subscription_url": "https://api.github.com/repos/grafana/git-ui-sync-demo/subscription",
"tags_url": "https://api.github.com/repos/grafana/git-ui-sync-demo/tags",
"trees_url": "https://api.github.com/repos/grafana/git-ui-sync-demo/git/trees{/sha}",
"teams_url": "https://api.github.com/repos/grafana/git-ui-sync-demo/teams",
"visibility": "internal"
},
"user": {
"login": "grafana",
"id": 7195757,
"node_id": "MDEyOk9yZ2FuaXphdGlvbjcxOTU3NTc=",
"avatar_url": "https://avatars.githubusercontent.com/u/7195757?v=4",
"html_url": "https://github.com/grafana",
"gravatar_id": "",
"type": "Organization",
"site_admin": false,
"url": "https://api.github.com/users/grafana",
"events_url": "https://api.github.com/users/grafana/events{/privacy}",
"following_url": "https://api.github.com/users/grafana/following{/other_user}",
"followers_url": "https://api.github.com/users/grafana/followers",
"gists_url": "https://api.github.com/users/grafana/gists{/gist_id}",
"organizations_url": "https://api.github.com/users/grafana/orgs",
"received_events_url": "https://api.github.com/users/grafana/received_events",
"repos_url": "https://api.github.com/users/grafana/repos",
"starred_url": "https://api.github.com/users/grafana/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/grafana/subscriptions"
}
}
},
"repository": {
"id": 888020043,
"node_id": "R_kgDONO4cSw",
"owner": {
"login": "grafana",
"id": 7195757,
"node_id": "MDEyOk9yZ2FuaXphdGlvbjcxOTU3NTc=",
"avatar_url": "https://avatars.githubusercontent.com/u/7195757?v=4",
"html_url": "https://github.com/grafana",
"gravatar_id": "",
"type": "Organization",
"site_admin": false,
"url": "https://api.github.com/users/grafana",
"events_url": "https://api.github.com/users/grafana/events{/privacy}",
"following_url": "https://api.github.com/users/grafana/following{/other_user}",
"followers_url": "https://api.github.com/users/grafana/followers",
"gists_url": "https://api.github.com/users/grafana/gists{/gist_id}",
"organizations_url": "https://api.github.com/users/grafana/orgs",
"received_events_url": "https://api.github.com/users/grafana/received_events",
"repos_url": "https://api.github.com/users/grafana/repos",
"starred_url": "https://api.github.com/users/grafana/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/grafana/subscriptions"
},
"name": "git-ui-sync-demo",
"full_name": "grafana/git-ui-sync-demo",
"description": "A repository containing Grafana dashboards to demo the Github Sync feature in Grafana.",
"default_branch": "main",
"created_at": "2024-11-13T17:13:33Z",
"pushed_at": "2024-12-08T10:51:24Z",
"updated_at": "2024-11-28T12:53:26Z",
"html_url": "https://github.com/grafana/git-ui-sync-demo",
"clone_url": "https://github.com/grafana/git-ui-sync-demo.git",
"git_url": "git://github.com/grafana/git-ui-sync-demo.git",
"ssh_url": "git@github.com:grafana/git-ui-sync-demo.git",
"svn_url": "https://github.com/grafana/git-ui-sync-demo",
"fork": false,
"forks_count": 0,
"open_issues_count": 9,
"open_issues": 9,
"stargazers_count": 0,
"watchers_count": 0,
"watchers": 0,
"size": 141,
"allow_forking": false,
"web_commit_signoff_required": false,
"archived": false,
"disabled": false,
"private": true,
"has_issues": true,
"has_wiki": true,
"has_pages": false,
"has_projects": true,
"has_downloads": true,
"has_discussions": false,
"is_template": false,
"url": "https://api.github.com/repos/grafana/git-ui-sync-demo",
"archive_url": "https://api.github.com/repos/grafana/git-ui-sync-demo/{archive_format}{/ref}",
"assignees_url": "https://api.github.com/repos/grafana/git-ui-sync-demo/assignees{/user}",
"blobs_url": "https://api.github.com/repos/grafana/git-ui-sync-demo/git/blobs{/sha}",
"branches_url": "https://api.github.com/repos/grafana/git-ui-sync-demo/branches{/branch}",
"collaborators_url": "https://api.github.com/repos/grafana/git-ui-sync-demo/collaborators{/collaborator}",
"comments_url": "https://api.github.com/repos/grafana/git-ui-sync-demo/comments{/number}",
"commits_url": "https://api.github.com/repos/grafana/git-ui-sync-demo/commits{/sha}",
"compare_url": "https://api.github.com/repos/grafana/git-ui-sync-demo/compare/{base}...{head}",
"contents_url": "https://api.github.com/repos/grafana/git-ui-sync-demo/contents/{+path}",
"contributors_url": "https://api.github.com/repos/grafana/git-ui-sync-demo/contributors",
"deployments_url": "https://api.github.com/repos/grafana/git-ui-sync-demo/deployments",
"downloads_url": "https://api.github.com/repos/grafana/git-ui-sync-demo/downloads",
"events_url": "https://api.github.com/repos/grafana/git-ui-sync-demo/events",
"forks_url": "https://api.github.com/repos/grafana/git-ui-sync-demo/forks",
"git_commits_url": "https://api.github.com/repos/grafana/git-ui-sync-demo/git/commits{/sha}",
"git_refs_url": "https://api.github.com/repos/grafana/git-ui-sync-demo/git/refs{/sha}",
"git_tags_url": "https://api.github.com/repos/grafana/git-ui-sync-demo/git/tags{/sha}",
"hooks_url": "https://api.github.com/repos/grafana/git-ui-sync-demo/hooks",
"issue_comment_url": "https://api.github.com/repos/grafana/git-ui-sync-demo/issues/comments{/number}",
"issue_events_url": "https://api.github.com/repos/grafana/git-ui-sync-demo/issues/events{/number}",
"issues_url": "https://api.github.com/repos/grafana/git-ui-sync-demo/issues{/number}",
"keys_url": "https://api.github.com/repos/grafana/git-ui-sync-demo/keys{/key_id}",
"labels_url": "https://api.github.com/repos/grafana/git-ui-sync-demo/labels{/name}",
"languages_url": "https://api.github.com/repos/grafana/git-ui-sync-demo/languages",
"merges_url": "https://api.github.com/repos/grafana/git-ui-sync-demo/merges",
"milestones_url": "https://api.github.com/repos/grafana/git-ui-sync-demo/milestones{/number}",
"notifications_url": "https://api.github.com/repos/grafana/git-ui-sync-demo/notifications{?since,all,participating}",
"pulls_url": "https://api.github.com/repos/grafana/git-ui-sync-demo/pulls{/number}",
"releases_url": "https://api.github.com/repos/grafana/git-ui-sync-demo/releases{/id}",
"stargazers_url": "https://api.github.com/repos/grafana/git-ui-sync-demo/stargazers",
"statuses_url": "https://api.github.com/repos/grafana/git-ui-sync-demo/statuses/{sha}",
"subscribers_url": "https://api.github.com/repos/grafana/git-ui-sync-demo/subscribers",
"subscription_url": "https://api.github.com/repos/grafana/git-ui-sync-demo/subscription",
"tags_url": "https://api.github.com/repos/grafana/git-ui-sync-demo/tags",
"trees_url": "https://api.github.com/repos/grafana/git-ui-sync-demo/git/trees{/sha}",
"teams_url": "https://api.github.com/repos/grafana/git-ui-sync-demo/teams",
"visibility": "internal"
},
"sender": {
"login": "ryantxu",
"id": 705951,
"node_id": "MDQ6VXNlcjcwNTk1MQ==",
"avatar_url": "https://avatars.githubusercontent.com/u/705951?v=4",
"html_url": "https://github.com/ryantxu",
"gravatar_id": "",
"type": "User",
"site_admin": false,
"url": "https://api.github.com/users/ryantxu",
"events_url": "https://api.github.com/users/ryantxu/events{/privacy}",
"following_url": "https://api.github.com/users/ryantxu/following{/other_user}",
"followers_url": "https://api.github.com/users/ryantxu/followers",
"gists_url": "https://api.github.com/users/ryantxu/gists{/gist_id}",
"organizations_url": "https://api.github.com/users/ryantxu/orgs",
"received_events_url": "https://api.github.com/users/ryantxu/received_events",
"repos_url": "https://api.github.com/users/ryantxu/repos",
"starred_url": "https://api.github.com/users/ryantxu/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/ryantxu/subscriptions"
},
"organization": {
"login": "grafana",
"id": 7195757,
"node_id": "MDEyOk9yZ2FuaXphdGlvbjcxOTU3NTc=",
"avatar_url": "https://avatars.githubusercontent.com/u/7195757?v=4",
"description": "Grafana Labs is behind leading open source projects Grafana and Loki, and the creator of the first open \u0026 composable observability platform.",
"url": "https://api.github.com/orgs/grafana",
"events_url": "https://api.github.com/orgs/grafana/events",
"hooks_url": "https://api.github.com/orgs/grafana/hooks",
"issues_url": "https://api.github.com/orgs/grafana/issues",
"members_url": "https://api.github.com/orgs/grafana/members{/member}",
"public_members_url": "https://api.github.com/orgs/grafana/public_members{/member}",
"repos_url": "https://api.github.com/orgs/grafana/repos"
}
}
@@ -1,148 +0,0 @@
{
"ref": "refs/heads/not-main",
"commits": [
{
"message": "Update README.md\n\ntest message",
"author": {
"name": "Ryan McKinley",
"email": "ryantxu@gmail.com",
"username": "ryantxu"
},
"url": "https://github.com/grafana/git-ui-sync-demo/commit/72096e3adc646c5a5b8a91744f962b12bac06045",
"distinct": true,
"id": "72096e3adc646c5a5b8a91744f962b12bac06045",
"tree_id": "03ff034c54bcefae2f96041f3fb8172f2fe93df3",
"timestamp": "2024-12-09T08:58:00+03:00",
"committer": {
"name": "GitHub",
"email": "noreply@github.com",
"username": "web-flow"
},
"modified": [
"README.md"
]
}
],
"before": "6c86a0cdfd220c2fe3518cfaa4a4babf030d9a7a",
"after": "72096e3adc646c5a5b8a91744f962b12bac06045",
"created": false,
"deleted": false,
"forced": false,
"compare": "https://github.com/grafana/git-ui-sync-demo/compare/6c86a0cdfd22...72096e3adc64",
"repository": {
"id": 888020043,
"node_id": "R_kgDONO4cSw",
"name": "git-ui-sync-demo",
"full_name": "grafana/git-ui-sync-demo",
"owner": {
"login": "grafana",
"id": 7195757,
"node_id": "MDEyOk9yZ2FuaXphdGlvbjcxOTU3NTc=",
"avatar_url": "https://avatars.githubusercontent.com/u/7195757?v=4",
"html_url": "https://github.com/grafana",
"gravatar_id": "",
"name": "grafana",
"email": "hello@grafana.com",
"type": "Organization",
"site_admin": false,
"url": "https://api.github.com/users/grafana",
"events_url": "https://api.github.com/users/grafana/events{/privacy}",
"following_url": "https://api.github.com/users/grafana/following{/other_user}",
"followers_url": "https://api.github.com/users/grafana/followers",
"gists_url": "https://api.github.com/users/grafana/gists{/gist_id}",
"organizations_url": "https://api.github.com/users/grafana/orgs",
"received_events_url": "https://api.github.com/users/grafana/received_events",
"repos_url": "https://api.github.com/users/grafana/repos",
"starred_url": "https://api.github.com/users/grafana/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/grafana/subscriptions"
},
"private": true,
"description": "A repository containing Grafana dashboards to demo the Github Sync feature in Grafana.",
"fork": false,
"created_at": "2024-11-13T20:13:33+03:00",
"pushed_at": "2024-12-09T08:58:00+03:00",
"updated_at": "2024-11-28T12:53:26Z",
"pulls_url": "https://api.github.com/repos/grafana/git-ui-sync-demo/pulls{/number}",
"size": 141,
"stargazers_count": 0,
"watchers_count": 0,
"has_issues": true,
"has_downloads": true,
"has_wiki": true,
"has_pages": false,
"forks_count": 0,
"archived": false,
"disabled": false,
"open_issues_count": 9,
"default_branch": "main",
"master_branch": "main",
"organization": "grafana",
"url": "https://github.com/grafana/git-ui-sync-demo",
"archive_url": "https://api.github.com/repos/grafana/git-ui-sync-demo/{archive_format}{/ref}",
"html_url": "https://github.com/grafana/git-ui-sync-demo",
"statuses_url": "https://api.github.com/repos/grafana/git-ui-sync-demo/statuses/{sha}",
"git_url": "git://github.com/grafana/git-ui-sync-demo.git",
"ssh_url": "git@github.com:grafana/git-ui-sync-demo.git",
"clone_url": "https://github.com/grafana/git-ui-sync-demo.git",
"svn_url": "https://github.com/grafana/git-ui-sync-demo"
},
"head_commit": {
"message": "Update README.md\n\ntest message",
"author": {
"name": "Ryan McKinley",
"email": "ryantxu@gmail.com",
"username": "ryantxu"
},
"url": "https://github.com/grafana/git-ui-sync-demo/commit/72096e3adc646c5a5b8a91744f962b12bac06045",
"distinct": true,
"id": "72096e3adc646c5a5b8a91744f962b12bac06045",
"tree_id": "03ff034c54bcefae2f96041f3fb8172f2fe93df3",
"timestamp": "2024-12-09T08:58:00+03:00",
"committer": {
"name": "GitHub",
"email": "noreply@github.com",
"username": "web-flow"
},
"modified": [
"README.md"
]
},
"pusher": {
"name": "ryantxu",
"email": "ryantxu@gmail.com"
},
"sender": {
"login": "ryantxu",
"id": 705951,
"node_id": "MDQ6VXNlcjcwNTk1MQ==",
"avatar_url": "https://avatars.githubusercontent.com/u/705951?v=4",
"html_url": "https://github.com/ryantxu",
"gravatar_id": "",
"type": "User",
"site_admin": false,
"url": "https://api.github.com/users/ryantxu",
"events_url": "https://api.github.com/users/ryantxu/events{/privacy}",
"following_url": "https://api.github.com/users/ryantxu/following{/other_user}",
"followers_url": "https://api.github.com/users/ryantxu/followers",
"gists_url": "https://api.github.com/users/ryantxu/gists{/gist_id}",
"organizations_url": "https://api.github.com/users/ryantxu/orgs",
"received_events_url": "https://api.github.com/users/ryantxu/received_events",
"repos_url": "https://api.github.com/users/ryantxu/repos",
"starred_url": "https://api.github.com/users/ryantxu/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/ryantxu/subscriptions"
},
"organization": {
"login": "grafana",
"id": 7195757,
"node_id": "MDEyOk9yZ2FuaXphdGlvbjcxOTU3NTc=",
"avatar_url": "https://avatars.githubusercontent.com/u/7195757?v=4",
"description": "Grafana Labs is behind leading open source projects Grafana and Loki, and the creator of the first open \u0026 composable observability platform.",
"url": "https://api.github.com/orgs/grafana",
"events_url": "https://api.github.com/orgs/grafana/events",
"hooks_url": "https://api.github.com/orgs/grafana/hooks",
"issues_url": "https://api.github.com/orgs/grafana/issues",
"members_url": "https://api.github.com/orgs/grafana/members{/member}",
"public_members_url": "https://api.github.com/orgs/grafana/public_members{/member}",
"repos_url": "https://api.github.com/orgs/grafana/repos"
}
}
@@ -1,234 +0,0 @@
{
"ref": "refs/heads/main",
"before": "72096e3adc646c5a5b8a91744f962b12bac06045",
"after": "5c816f9812e391c62b0c5555d0b473b296d9179c",
"repository": {
"id": 888020043,
"node_id": "R_kgDONO4cSw",
"name": "git-ui-sync-demo",
"full_name": "grafana/git-ui-sync-demo",
"private": true,
"owner": {
"name": "grafana",
"email": "hello@grafana.com",
"login": "grafana",
"id": 7195757,
"node_id": "MDEyOk9yZ2FuaXphdGlvbjcxOTU3NTc=",
"avatar_url": "https://avatars.githubusercontent.com/u/7195757?v=4",
"gravatar_id": "",
"url": "https://api.github.com/users/grafana",
"html_url": "https://github.com/grafana",
"followers_url": "https://api.github.com/users/grafana/followers",
"following_url": "https://api.github.com/users/grafana/following{/other_user}",
"gists_url": "https://api.github.com/users/grafana/gists{/gist_id}",
"starred_url": "https://api.github.com/users/grafana/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/grafana/subscriptions",
"organizations_url": "https://api.github.com/users/grafana/orgs",
"repos_url": "https://api.github.com/users/grafana/repos",
"events_url": "https://api.github.com/users/grafana/events{/privacy}",
"received_events_url": "https://api.github.com/users/grafana/received_events",
"type": "Organization",
"user_view_type": "public",
"site_admin": false
},
"html_url": "https://github.com/grafana/git-ui-sync-demo",
"description": "A repository containing Grafana dashboards to demo the Github Sync feature in Grafana.",
"fork": false,
"url": "https://github.com/grafana/git-ui-sync-demo",
"forks_url": "https://api.github.com/repos/grafana/git-ui-sync-demo/forks",
"keys_url": "https://api.github.com/repos/grafana/git-ui-sync-demo/keys{/key_id}",
"collaborators_url": "https://api.github.com/repos/grafana/git-ui-sync-demo/collaborators{/collaborator}",
"teams_url": "https://api.github.com/repos/grafana/git-ui-sync-demo/teams",
"hooks_url": "https://api.github.com/repos/grafana/git-ui-sync-demo/hooks",
"issue_events_url": "https://api.github.com/repos/grafana/git-ui-sync-demo/issues/events{/number}",
"events_url": "https://api.github.com/repos/grafana/git-ui-sync-demo/events",
"assignees_url": "https://api.github.com/repos/grafana/git-ui-sync-demo/assignees{/user}",
"branches_url": "https://api.github.com/repos/grafana/git-ui-sync-demo/branches{/branch}",
"tags_url": "https://api.github.com/repos/grafana/git-ui-sync-demo/tags",
"blobs_url": "https://api.github.com/repos/grafana/git-ui-sync-demo/git/blobs{/sha}",
"git_tags_url": "https://api.github.com/repos/grafana/git-ui-sync-demo/git/tags{/sha}",
"git_refs_url": "https://api.github.com/repos/grafana/git-ui-sync-demo/git/refs{/sha}",
"trees_url": "https://api.github.com/repos/grafana/git-ui-sync-demo/git/trees{/sha}",
"statuses_url": "https://api.github.com/repos/grafana/git-ui-sync-demo/statuses/{sha}",
"languages_url": "https://api.github.com/repos/grafana/git-ui-sync-demo/languages",
"stargazers_url": "https://api.github.com/repos/grafana/git-ui-sync-demo/stargazers",
"contributors_url": "https://api.github.com/repos/grafana/git-ui-sync-demo/contributors",
"subscribers_url": "https://api.github.com/repos/grafana/git-ui-sync-demo/subscribers",
"subscription_url": "https://api.github.com/repos/grafana/git-ui-sync-demo/subscription",
"commits_url": "https://api.github.com/repos/grafana/git-ui-sync-demo/commits{/sha}",
"git_commits_url": "https://api.github.com/repos/grafana/git-ui-sync-demo/git/commits{/sha}",
"comments_url": "https://api.github.com/repos/grafana/git-ui-sync-demo/comments{/number}",
"issue_comment_url": "https://api.github.com/repos/grafana/git-ui-sync-demo/issues/comments{/number}",
"contents_url": "https://api.github.com/repos/grafana/git-ui-sync-demo/contents/{+path}",
"compare_url": "https://api.github.com/repos/grafana/git-ui-sync-demo/compare/{base}...{head}",
"merges_url": "https://api.github.com/repos/grafana/git-ui-sync-demo/merges",
"archive_url": "https://api.github.com/repos/grafana/git-ui-sync-demo/{archive_format}{/ref}",
"downloads_url": "https://api.github.com/repos/grafana/git-ui-sync-demo/downloads",
"issues_url": "https://api.github.com/repos/grafana/git-ui-sync-demo/issues{/number}",
"pulls_url": "https://api.github.com/repos/grafana/git-ui-sync-demo/pulls{/number}",
"milestones_url": "https://api.github.com/repos/grafana/git-ui-sync-demo/milestones{/number}",
"notifications_url": "https://api.github.com/repos/grafana/git-ui-sync-demo/notifications{?since,all,participating}",
"labels_url": "https://api.github.com/repos/grafana/git-ui-sync-demo/labels{/name}",
"releases_url": "https://api.github.com/repos/grafana/git-ui-sync-demo/releases{/id}",
"deployments_url": "https://api.github.com/repos/grafana/git-ui-sync-demo/deployments",
"created_at": 1731518013,
"updated_at": "2024-12-09T05:58:03Z",
"pushed_at": 1733731254,
"git_url": "git://github.com/grafana/git-ui-sync-demo.git",
"ssh_url": "git@github.com:grafana/git-ui-sync-demo.git",
"clone_url": "https://github.com/grafana/git-ui-sync-demo.git",
"svn_url": "https://github.com/grafana/git-ui-sync-demo",
"homepage": null,
"size": 142,
"stargazers_count": 0,
"watchers_count": 0,
"language": null,
"has_issues": true,
"has_projects": true,
"has_downloads": true,
"has_wiki": true,
"has_pages": false,
"has_discussions": false,
"forks_count": 0,
"mirror_url": null,
"archived": false,
"disabled": false,
"open_issues_count": 9,
"license": null,
"allow_forking": false,
"is_template": false,
"web_commit_signoff_required": false,
"topics": [
],
"visibility": "internal",
"forks": 0,
"open_issues": 9,
"watchers": 0,
"default_branch": "main",
"stargazers": 0,
"master_branch": "main",
"organization": "grafana",
"custom_properties": {
}
},
"pusher": {
"name": "ryantxu",
"email": "ryantxu@gmail.com"
},
"organization": {
"login": "grafana",
"id": 7195757,
"node_id": "MDEyOk9yZ2FuaXphdGlvbjcxOTU3NTc=",
"url": "https://api.github.com/orgs/grafana",
"repos_url": "https://api.github.com/orgs/grafana/repos",
"events_url": "https://api.github.com/orgs/grafana/events",
"hooks_url": "https://api.github.com/orgs/grafana/hooks",
"issues_url": "https://api.github.com/orgs/grafana/issues",
"members_url": "https://api.github.com/orgs/grafana/members{/member}",
"public_members_url": "https://api.github.com/orgs/grafana/public_members{/member}",
"avatar_url": "https://avatars.githubusercontent.com/u/7195757?v=4",
"description": "Grafana Labs is behind leading open source projects Grafana and Loki, and the creator of the first open & composable observability platform."
},
"enterprise": {
"id": 129980,
"slug": "grafana",
"name": "Grafana Labs Enterprise",
"node_id": "E_kgDOAAH7vA",
"avatar_url": "https://avatars.githubusercontent.com/b/129980?v=4",
"description": "Grafana Labs is behind leading open source projects Grafana and Loki, and the creator of the first open & composable observability platform.",
"website_url": "https://grafana.com",
"html_url": "https://github.com/enterprises/grafana",
"created_at": "2024-02-29T23:01:47Z",
"updated_at": "2024-10-21T08:45:28Z"
},
"sender": {
"login": "ryantxu",
"id": 705951,
"node_id": "MDQ6VXNlcjcwNTk1MQ==",
"avatar_url": "https://avatars.githubusercontent.com/u/705951?v=4",
"gravatar_id": "",
"url": "https://api.github.com/users/ryantxu",
"html_url": "https://github.com/ryantxu",
"followers_url": "https://api.github.com/users/ryantxu/followers",
"following_url": "https://api.github.com/users/ryantxu/following{/other_user}",
"gists_url": "https://api.github.com/users/ryantxu/gists{/gist_id}",
"starred_url": "https://api.github.com/users/ryantxu/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/ryantxu/subscriptions",
"organizations_url": "https://api.github.com/users/ryantxu/orgs",
"repos_url": "https://api.github.com/users/ryantxu/repos",
"events_url": "https://api.github.com/users/ryantxu/events{/privacy}",
"received_events_url": "https://api.github.com/users/ryantxu/received_events",
"type": "User",
"user_view_type": "public",
"site_admin": false
},
"created": false,
"deleted": false,
"forced": false,
"base_ref": null,
"compare": "https://github.com/grafana/git-ui-sync-demo/compare/72096e3adc64...5c816f9812e3",
"commits": [
{
"id": "5c816f9812e391c62b0c5555d0b473b296d9179c",
"tree_id": "97c7ba756b07b6a2b7fd130e59f75deed53fe027",
"distinct": true,
"message": "nested folders",
"timestamp": "2024-12-09T11:00:48+03:00",
"url": "https://github.com/grafana/git-ui-sync-demo/commit/5c816f9812e391c62b0c5555d0b473b296d9179c",
"author": {
"name": "Ryan McKinley",
"email": "ryantxu@gmail.com",
"username": "ryantxu"
},
"committer": {
"name": "Ryan McKinley",
"email": "ryantxu@gmail.com",
"username": "ryantxu"
},
"added": [
"nested-1/README.md",
"nested-1/dash-1.json",
"nested-1/nested-2/README.md",
"nested-1/nested-2/dash-2.json"
],
"removed": [
],
"modified": [
"first-dashboard.json"
]
}
],
"head_commit": {
"id": "5c816f9812e391c62b0c5555d0b473b296d9179c",
"tree_id": "97c7ba756b07b6a2b7fd130e59f75deed53fe027",
"distinct": true,
"message": "nested folders",
"timestamp": "2024-12-09T11:00:48+03:00",
"url": "https://github.com/grafana/git-ui-sync-demo/commit/5c816f9812e391c62b0c5555d0b473b296d9179c",
"author": {
"name": "Ryan McKinley",
"email": "ryantxu@gmail.com",
"username": "ryantxu"
},
"committer": {
"name": "Ryan McKinley",
"email": "ryantxu@gmail.com",
"username": "ryantxu"
},
"added": [
"nested-1/README.md",
"nested-1/dash-1.json",
"nested-1/nested-2/README.md",
"nested-1/nested-2/dash-2.json"
],
"removed": [
],
"modified": [
"first-dashboard.json"
]
}
}
@@ -1,148 +0,0 @@
{
"ref": "refs/heads/main",
"commits": [
{
"message": "Update README.md\n\ntest message",
"author": {
"name": "Ryan McKinley",
"email": "ryantxu@gmail.com",
"username": "ryantxu"
},
"url": "https://github.com/grafana/git-ui-sync-demo/commit/72096e3adc646c5a5b8a91744f962b12bac06045",
"distinct": true,
"id": "72096e3adc646c5a5b8a91744f962b12bac06045",
"tree_id": "03ff034c54bcefae2f96041f3fb8172f2fe93df3",
"timestamp": "2024-12-09T08:58:00+03:00",
"committer": {
"name": "GitHub",
"email": "noreply@github.com",
"username": "web-flow"
},
"modified": [
"README.md"
]
}
],
"before": "6c86a0cdfd220c2fe3518cfaa4a4babf030d9a7a",
"after": "72096e3adc646c5a5b8a91744f962b12bac06045",
"created": false,
"deleted": false,
"forced": false,
"compare": "https://github.com/grafana/git-ui-sync-demo/compare/6c86a0cdfd22...72096e3adc64",
"repository": {
"id": 888020043,
"node_id": "R_kgDONO4cSw",
"name": "git-ui-sync-demo",
"full_name": "grafana/git-ui-sync-demo",
"owner": {
"login": "grafana",
"id": 7195757,
"node_id": "MDEyOk9yZ2FuaXphdGlvbjcxOTU3NTc=",
"avatar_url": "https://avatars.githubusercontent.com/u/7195757?v=4",
"html_url": "https://github.com/grafana",
"gravatar_id": "",
"name": "grafana",
"email": "hello@grafana.com",
"type": "Organization",
"site_admin": false,
"url": "https://api.github.com/users/grafana",
"events_url": "https://api.github.com/users/grafana/events{/privacy}",
"following_url": "https://api.github.com/users/grafana/following{/other_user}",
"followers_url": "https://api.github.com/users/grafana/followers",
"gists_url": "https://api.github.com/users/grafana/gists{/gist_id}",
"organizations_url": "https://api.github.com/users/grafana/orgs",
"received_events_url": "https://api.github.com/users/grafana/received_events",
"repos_url": "https://api.github.com/users/grafana/repos",
"starred_url": "https://api.github.com/users/grafana/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/grafana/subscriptions"
},
"private": true,
"description": "A repository containing Grafana dashboards to demo the Github Sync feature in Grafana.",
"fork": false,
"created_at": "2024-11-13T20:13:33+03:00",
"pushed_at": "2024-12-09T08:58:00+03:00",
"updated_at": "2024-11-28T12:53:26Z",
"pulls_url": "https://api.github.com/repos/grafana/git-ui-sync-demo/pulls{/number}",
"size": 141,
"stargazers_count": 0,
"watchers_count": 0,
"has_issues": true,
"has_downloads": true,
"has_wiki": true,
"has_pages": false,
"forks_count": 0,
"archived": false,
"disabled": false,
"open_issues_count": 9,
"default_branch": "main",
"master_branch": "main",
"organization": "grafana",
"url": "https://github.com/grafana/git-ui-sync-demo",
"archive_url": "https://api.github.com/repos/grafana/git-ui-sync-demo/{archive_format}{/ref}",
"html_url": "https://github.com/grafana/git-ui-sync-demo",
"statuses_url": "https://api.github.com/repos/grafana/git-ui-sync-demo/statuses/{sha}",
"git_url": "git://github.com/grafana/git-ui-sync-demo.git",
"ssh_url": "git@github.com:grafana/git-ui-sync-demo.git",
"clone_url": "https://github.com/grafana/git-ui-sync-demo.git",
"svn_url": "https://github.com/grafana/git-ui-sync-demo"
},
"head_commit": {
"message": "Update README.md\n\ntest message",
"author": {
"name": "Ryan McKinley",
"email": "ryantxu@gmail.com",
"username": "ryantxu"
},
"url": "https://github.com/grafana/git-ui-sync-demo/commit/72096e3adc646c5a5b8a91744f962b12bac06045",
"distinct": true,
"id": "72096e3adc646c5a5b8a91744f962b12bac06045",
"tree_id": "03ff034c54bcefae2f96041f3fb8172f2fe93df3",
"timestamp": "2024-12-09T08:58:00+03:00",
"committer": {
"name": "GitHub",
"email": "noreply@github.com",
"username": "web-flow"
},
"modified": [
"README.md"
]
},
"pusher": {
"name": "ryantxu",
"email": "ryantxu@gmail.com"
},
"sender": {
"login": "ryantxu",
"id": 705951,
"node_id": "MDQ6VXNlcjcwNTk1MQ==",
"avatar_url": "https://avatars.githubusercontent.com/u/705951?v=4",
"html_url": "https://github.com/ryantxu",
"gravatar_id": "",
"type": "User",
"site_admin": false,
"url": "https://api.github.com/users/ryantxu",
"events_url": "https://api.github.com/users/ryantxu/events{/privacy}",
"following_url": "https://api.github.com/users/ryantxu/following{/other_user}",
"followers_url": "https://api.github.com/users/ryantxu/followers",
"gists_url": "https://api.github.com/users/ryantxu/gists{/gist_id}",
"organizations_url": "https://api.github.com/users/ryantxu/orgs",
"received_events_url": "https://api.github.com/users/ryantxu/received_events",
"repos_url": "https://api.github.com/users/ryantxu/repos",
"starred_url": "https://api.github.com/users/ryantxu/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/ryantxu/subscriptions"
},
"organization": {
"login": "grafana",
"id": 7195757,
"node_id": "MDEyOk9yZ2FuaXphdGlvbjcxOTU3NTc=",
"avatar_url": "https://avatars.githubusercontent.com/u/7195757?v=4",
"description": "Grafana Labs is behind leading open source projects Grafana and Loki, and the creator of the first open \u0026 composable observability platform.",
"url": "https://api.github.com/orgs/grafana",
"events_url": "https://api.github.com/orgs/grafana/events",
"hooks_url": "https://api.github.com/orgs/grafana/hooks",
"issues_url": "https://api.github.com/orgs/grafana/issues",
"members_url": "https://api.github.com/orgs/grafana/members{/member}",
"public_members_url": "https://api.github.com/orgs/grafana/public_members{/member}",
"repos_url": "https://api.github.com/orgs/grafana/repos"
}
}
@@ -21,6 +21,10 @@ import (
"github.com/grafana/grafana/pkg/registry/apis/provisioning/webhooks/pullrequest"
)
type WebhookRepository interface {
Webhook(ctx context.Context, req *http.Request) (*provisioning.WebhookResponse, error)
}
// Webhook endpoint max size (25MB)
// See https://docs.github.com/en/webhooks/webhook-events-and-payloads
const webhookMaxBodySize = 25 * 1024 * 1024