From 88b2cbf207cdedb1dba25d0cf0c26c5281de87c9 Mon Sep 17 00:00:00 2001 From: Anirudh Oppiliappan Date: Thu, 2 Apr 2026 11:32:36 +0300 Subject: [PATCH] appview/notify: add Clone notifier, enqueue posthog event for clones Signed-off-by: Anirudh Oppiliappan --- appview/notify/db/db.go | 4 ++++ appview/notify/logging_notifier.go | 5 +++++ appview/notify/merged_notifier.go | 4 ++++ appview/notify/notifier.go | 4 ++++ appview/notify/posthog/notifier.go | 11 +++++++++++ appview/notify/webhook_notifier.go | 2 ++ appview/state/git_http.go | 2 ++ 7 files changed, 32 insertions(+) diff --git a/appview/notify/db/db.go b/appview/notify/db/db.go index 429cba56..4079a47f 100644 --- a/appview/notify/db/db.go +++ b/appview/notify/db/db.go @@ -361,6 +361,10 @@ func (n *databaseNotifier) Push(ctx context.Context, repo *models.Repo, ref, old // no-op for now; webhooks are handled by the webhook notifier } +func (n *databaseNotifier) Clone(ctx context.Context, repo *models.Repo) { + // no-op +} + func (n *databaseNotifier) NewIssueState(ctx context.Context, actor syntax.DID, issue *models.Issue) { l := log.FromContext(ctx) diff --git a/appview/notify/logging_notifier.go b/appview/notify/logging_notifier.go index 59234281..ed494894 100644 --- a/appview/notify/logging_notifier.go +++ b/appview/notify/logging_notifier.go @@ -118,3 +118,8 @@ func (l *loggingNotifier) Push(ctx context.Context, repo *models.Repo, ref, oldS ctx = tlog.IntoContext(ctx, tlog.SubLogger(l.logger, "Push")) l.inner.Push(ctx, repo, ref, oldSha, newSha, committerDid) } + +func (l *loggingNotifier) Clone(ctx context.Context, repo *models.Repo) { + ctx = tlog.IntoContext(ctx, tlog.SubLogger(l.logger, "Clone")) + l.inner.Clone(ctx, repo) +} diff --git a/appview/notify/merged_notifier.go b/appview/notify/merged_notifier.go index 666c0a4e..9f97d5a3 100644 --- a/appview/notify/merged_notifier.go +++ b/appview/notify/merged_notifier.go @@ -105,3 +105,7 @@ func (m *mergedNotifier) DeleteString(ctx context.Context, did, rkey string) { func (m *mergedNotifier) Push(ctx context.Context, repo *models.Repo, ref, oldSha, newSha, committerDid string) { m.fanout(func(n Notifier) { n.Push(ctx, repo, ref, oldSha, newSha, committerDid) }) } + +func (m *mergedNotifier) Clone(ctx context.Context, repo *models.Repo) { + m.fanout(func(n Notifier) { n.Clone(ctx, repo) }) +} diff --git a/appview/notify/notifier.go b/appview/notify/notifier.go index 756b622e..3d7a790d 100644 --- a/appview/notify/notifier.go +++ b/appview/notify/notifier.go @@ -35,6 +35,8 @@ type Notifier interface { DeleteString(ctx context.Context, did, rkey string) Push(ctx context.Context, repo *models.Repo, ref, oldSha, newSha, committerDid string) + + Clone(ctx context.Context, repo *models.Repo) } // BaseNotifier is a listener that does nothing @@ -72,3 +74,5 @@ func (m *BaseNotifier) DeleteString(ctx context.Context, did, rkey string) {} func (m *BaseNotifier) Push(ctx context.Context, repo *models.Repo, ref, oldSha, newSha, committerDid string) { } + +func (m *BaseNotifier) Clone(ctx context.Context, repo *models.Repo) {} diff --git a/appview/notify/posthog/notifier.go b/appview/notify/posthog/notifier.go index 2679d946..7fe57255 100644 --- a/appview/notify/posthog/notifier.go +++ b/appview/notify/posthog/notifier.go @@ -180,6 +180,17 @@ func (n *posthogNotifier) NewString(ctx context.Context, string *models.String) } } +func (n *posthogNotifier) Clone(ctx context.Context, repo *models.Repo) { + err := n.client.Enqueue(posthog.Capture{ + DistinctId: repo.Did, + Event: "clone", + Properties: posthog.Properties{"repo": repo.Name, "repo_at": repo.RepoAt()}, + }) + if err != nil { + log.Println("failed to enqueue posthog event:", err) + } +} + func (n *posthogNotifier) NewIssueComment(ctx context.Context, comment *models.IssueComment, mentions []syntax.DID) { err := n.client.Enqueue(posthog.Capture{ DistinctId: comment.Did, diff --git a/appview/notify/webhook_notifier.go b/appview/notify/webhook_notifier.go index 64729d8f..179d0e05 100644 --- a/appview/notify/webhook_notifier.go +++ b/appview/notify/webhook_notifier.go @@ -69,6 +69,8 @@ func (w *WebhookNotifier) Push(ctx context.Context, repo *models.Repo, ref, oldS } } +func (w *WebhookNotifier) Clone(ctx context.Context, repo *models.Repo) {} + // buildPushPayload creates the webhook payload func (w *WebhookNotifier) buildPushPayload(repo *models.Repo, ref, oldSha, newSha, committerDid string) (*models.WebhookPayload, error) { owner := repo.Did diff --git a/appview/state/git_http.go b/appview/state/git_http.go index 8d1fdd6f..7b783bd9 100644 --- a/appview/state/git_http.go +++ b/appview/state/git_http.go @@ -1,6 +1,7 @@ package state import ( + "context" "fmt" "io" "net/http" @@ -51,6 +52,7 @@ func (s *State) InfoRefs(w http.ResponseWriter, r *http.Request) { contentType = "application/x-git-receive-pack-advertisement" default: contentType = "application/x-git-upload-pack-advertisement" + go s.notifier.Clone(context.Background(), repo) } targetURL := fmt.Sprintf("%s://%s/%s/info/refs?%s", scheme, repo.Knot, repo.RepoIdentifier(), r.URL.RawQuery) -- 2.51.2