Provisioning: Cleanup folders properly with webhooks (#112031)

This commit is contained in:
Stephanie Hingtgen
2025-10-04 21:17:42 +00:00
committed by GitHub
parent 2486dba881
commit d5d1851bc1
11 changed files with 696 additions and 44 deletions
@@ -7,6 +7,7 @@ import (
"log/slog"
"net/http"
"slices"
"strings"
"github.com/google/go-github/v70/github"
"github.com/google/uuid"
@@ -15,6 +16,7 @@ import (
"github.com/grafana/grafana-app-sdk/logging"
provisioning "github.com/grafana/grafana/apps/provisioning/pkg/apis/provisioning/v0alpha1"
"github.com/grafana/grafana/apps/provisioning/pkg/repository"
"github.com/grafana/grafana/apps/provisioning/pkg/safepath"
common "github.com/grafana/grafana/pkg/apimachinery/apis/common/v0alpha1"
)
@@ -119,13 +121,38 @@ func (r *githubWebhookRepository) parsePushEvent(event *github.PushEvent) (*prov
return &provisioning.WebhookResponse{Code: http.StatusOK}, nil
}
// whenever possible, we want to do incremental syncs to keep things performant.
// however, if we get an event where just a .keep file is being deleted, and no other files in the folder
// are being deleted, the folder could be gone from git, but not from grafana and we do not have a way
// to get the grafana uid to delete the folder. so, instead, we will queue a full sync to clean things up.
dirsWithKeepDeletes := make(map[string]struct{})
dirsWithOtherDeletes := make(map[string]struct{})
for _, change := range event.GetCommits() {
for _, removedFile := range change.Removed {
dir := safepath.Dir(removedFile)
if strings.HasSuffix(removedFile, ".keep") {
dirsWithKeepDeletes[dir] = struct{}{}
} else {
dirsWithOtherDeletes[dir] = struct{}{}
}
}
}
// if there are any keep files deleted that do not have other files deleted in the same folder, we need to queue a full sync
incremental := true
for dir := range dirsWithKeepDeletes {
if _, exists := dirsWithOtherDeletes[dir]; !exists {
incremental = false
break
}
}
return &provisioning.WebhookResponse{
Code: http.StatusAccepted,
Job: &provisioning.JobSpec{
Repository: r.config.GetName(),
Action: provisioning.JobActionPull,
Pull: &provisioning.SyncJobOptions{
Incremental: true,
Incremental: incremental,
},
},
}, nil