feat: [CODE-2966]: add commit url to webhook (#3659)

* feat: [CODE-2966]: add commit url to commit ops
* Merge remote-tracking branch 'origin' into abhinav/CODE-2966
* feat: [CODE-2966]: add commit url to webhook
* feat: [CODE-2966]: add commit url to webhook
This commit is contained in:
Abhinav Singh 2025-04-14 21:23:12 +00:00 committed by Harness
parent e03b053205
commit d5f1f27c34
5 changed files with 53 additions and 19 deletions

View File

@ -19,6 +19,7 @@ import (
"fmt" "fmt"
gitevents "github.com/harness/gitness/app/events/git" gitevents "github.com/harness/gitness/app/events/git"
"github.com/harness/gitness/app/url"
"github.com/harness/gitness/errors" "github.com/harness/gitness/errors"
"github.com/harness/gitness/events" "github.com/harness/gitness/events"
"github.com/harness/gitness/git" "github.com/harness/gitness/git"
@ -44,7 +45,7 @@ func (s *Service) handleEventBranchCreated(ctx context.Context,
return s.triggerForEventWithRepo(ctx, enum.WebhookTriggerBranchCreated, return s.triggerForEventWithRepo(ctx, enum.WebhookTriggerBranchCreated,
event.ID, event.Payload.PrincipalID, event.Payload.RepoID, event.ID, event.Payload.PrincipalID, event.Payload.RepoID,
func(principal *types.Principal, repo *types.Repository) (any, error) { func(principal *types.Principal, repo *types.Repository) (any, error) {
commitInfo, err := s.fetchCommitInfoForEvent(ctx, repo.GitUID, event.Payload.SHA) commitInfo, err := s.fetchCommitInfoForEvent(ctx, repo.GitUID, repo.Path, event.Payload.SHA, s.urlProvider)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -83,7 +84,7 @@ func (s *Service) handleEventBranchUpdated(ctx context.Context,
event.ID, event.Payload.PrincipalID, event.Payload.RepoID, event.ID, event.Payload.PrincipalID, event.Payload.RepoID,
func(principal *types.Principal, repo *types.Repository) (any, error) { func(principal *types.Principal, repo *types.Repository) (any, error) {
commitsInfo, totalCommits, err := s.fetchCommitsInfoForEvent(ctx, repo.GitUID, commitsInfo, totalCommits, err := s.fetchCommitsInfoForEvent(ctx, repo.GitUID,
event.Payload.OldSHA, event.Payload.NewSHA) repo.Path, event.Payload.OldSHA, event.Payload.NewSHA, s.urlProvider)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -151,7 +152,13 @@ func (s *Service) handleEventBranchDeleted(ctx context.Context,
}) })
} }
func (s *Service) fetchCommitInfoForEvent(ctx context.Context, repoUID string, commitSHA string) (CommitInfo, error) { func (s *Service) fetchCommitInfoForEvent(
ctx context.Context,
repoUID string,
repoPath string,
commitSHA string,
urlProvider url.Provider,
) (CommitInfo, error) {
out, err := s.git.GetCommit(ctx, &git.GetCommitParams{ out, err := s.git.GetCommit(ctx, &git.GetCommitParams{
ReadParams: git.ReadParams{ ReadParams: git.ReadParams{
RepoUID: repoUID, RepoUID: repoUID,
@ -169,14 +176,16 @@ func (s *Service) fetchCommitInfoForEvent(ctx context.Context, repoUID string, c
return CommitInfo{}, fmt.Errorf("failed to get commit with targetSha '%s': %w", commitSHA, err) return CommitInfo{}, fmt.Errorf("failed to get commit with targetSha '%s': %w", commitSHA, err)
} }
return commitInfoFrom(out.Commit), nil return commitInfoFrom(ctx, repoPath, out.Commit, urlProvider), nil
} }
func (s *Service) fetchCommitsInfoForEvent( func (s *Service) fetchCommitsInfoForEvent(
ctx context.Context, ctx context.Context,
repoUID string, repoUID string,
repoPath string,
oldSHA string, oldSHA string,
newSHA string, newSHA string,
urlProvider url.Provider,
) ([]CommitInfo, int, error) { ) ([]CommitInfo, int, error) {
listCommitsParams := git.ListCommitsParams{ listCommitsParams := git.ListCommitsParams{
ReadParams: git.ReadParams{RepoUID: repoUID}, ReadParams: git.ReadParams{RepoUID: repoUID},
@ -202,5 +211,5 @@ func (s *Service) fetchCommitsInfoForEvent(
return nil, 0, fmt.Errorf("no commit found between %s and %s", oldSHA, newSHA) return nil, 0, fmt.Errorf("no commit found between %s and %s", oldSHA, newSHA)
} }
return commitsInfoFrom(listCommitsOutput.Commits), listCommitsOutput.TotalCommits, nil return commitsInfoFrom(ctx, repoPath, listCommitsOutput.Commits, urlProvider), listCommitsOutput.TotalCommits, nil
} }

View File

@ -48,7 +48,8 @@ func (s *Service) handleEventPullReqCreated(
return s.triggerForEventWithPullReq(ctx, enum.WebhookTriggerPullReqCreated, return s.triggerForEventWithPullReq(ctx, enum.WebhookTriggerPullReqCreated,
event.ID, event.Payload.PrincipalID, event.Payload.PullReqID, event.ID, event.Payload.PrincipalID, event.Payload.PullReqID,
func(principal *types.Principal, pr *types.PullReq, targetRepo, sourceRepo *types.Repository) (any, error) { func(principal *types.Principal, pr *types.PullReq, targetRepo, sourceRepo *types.Repository) (any, error) {
commitInfo, err := s.fetchCommitInfoForEvent(ctx, sourceRepo.GitUID, event.Payload.SourceSHA) commitInfo, err := s.fetchCommitInfoForEvent(ctx, sourceRepo.GitUID, sourceRepo.Path,
event.Payload.SourceSHA, s.urlProvider)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -98,7 +99,8 @@ func (s *Service) handleEventPullReqReopened(
return s.triggerForEventWithPullReq(ctx, enum.WebhookTriggerPullReqReopened, return s.triggerForEventWithPullReq(ctx, enum.WebhookTriggerPullReqReopened,
event.ID, event.Payload.PrincipalID, event.Payload.PullReqID, event.ID, event.Payload.PrincipalID, event.Payload.PullReqID,
func(principal *types.Principal, pr *types.PullReq, targetRepo, sourceRepo *types.Repository) (any, error) { func(principal *types.Principal, pr *types.PullReq, targetRepo, sourceRepo *types.Repository) (any, error) {
commitInfo, err := s.fetchCommitInfoForEvent(ctx, sourceRepo.GitUID, event.Payload.SourceSHA) commitInfo, err := s.fetchCommitInfoForEvent(ctx, sourceRepo.GitUID, sourceRepo.Path,
event.Payload.SourceSHA, s.urlProvider)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -155,8 +157,8 @@ func (s *Service) handleEventPullReqBranchUpdated(
return s.triggerForEventWithPullReq(ctx, enum.WebhookTriggerPullReqBranchUpdated, return s.triggerForEventWithPullReq(ctx, enum.WebhookTriggerPullReqBranchUpdated,
event.ID, event.Payload.PrincipalID, event.Payload.PullReqID, event.ID, event.Payload.PrincipalID, event.Payload.PullReqID,
func(principal *types.Principal, pr *types.PullReq, targetRepo, sourceRepo *types.Repository) (any, error) { func(principal *types.Principal, pr *types.PullReq, targetRepo, sourceRepo *types.Repository) (any, error) {
commitsInfo, totalCommits, err := s.fetchCommitsInfoForEvent(ctx, sourceRepo.GitUID, commitsInfo, totalCommits, err := s.fetchCommitsInfoForEvent(ctx, sourceRepo.GitUID, sourceRepo.Path,
event.Payload.OldSHA, event.Payload.NewSHA) event.Payload.OldSHA, event.Payload.NewSHA, s.urlProvider)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -217,7 +219,8 @@ func (s *Service) handleEventPullReqClosed(
return s.triggerForEventWithPullReq(ctx, enum.WebhookTriggerPullReqClosed, return s.triggerForEventWithPullReq(ctx, enum.WebhookTriggerPullReqClosed,
event.ID, event.Payload.PrincipalID, event.Payload.PullReqID, event.ID, event.Payload.PrincipalID, event.Payload.PullReqID,
func(principal *types.Principal, pr *types.PullReq, targetRepo, sourceRepo *types.Repository) (any, error) { func(principal *types.Principal, pr *types.PullReq, targetRepo, sourceRepo *types.Repository) (any, error) {
commitInfo, err := s.fetchCommitInfoForEvent(ctx, sourceRepo.GitUID, event.Payload.SourceSHA) commitInfo, err := s.fetchCommitInfoForEvent(ctx, sourceRepo.GitUID, sourceRepo.Path,
event.Payload.SourceSHA, s.urlProvider)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -270,7 +273,8 @@ func (s *Service) handleEventPullReqMerged(
return s.triggerForEventWithPullReq(ctx, enum.WebhookTriggerPullReqMerged, return s.triggerForEventWithPullReq(ctx, enum.WebhookTriggerPullReqMerged,
event.ID, event.Payload.PrincipalID, event.Payload.PullReqID, event.ID, event.Payload.PrincipalID, event.Payload.PullReqID,
func(principal *types.Principal, pr *types.PullReq, targetRepo, sourceRepo *types.Repository) (any, error) { func(principal *types.Principal, pr *types.PullReq, targetRepo, sourceRepo *types.Repository) (any, error) {
commitInfo, err := s.fetchCommitInfoForEvent(ctx, sourceRepo.GitUID, event.Payload.SourceSHA) commitInfo, err := s.fetchCommitInfoForEvent(ctx, sourceRepo.GitUID, sourceRepo.Path,
event.Payload.SourceSHA, s.urlProvider)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -334,7 +338,8 @@ func (s *Service) handleEventPullReqComment(
err, err,
) )
} }
commitInfo, err := s.fetchCommitInfoForEvent(ctx, sourceRepo.GitUID, event.Payload.SourceSHA) commitInfo, err := s.fetchCommitInfoForEvent(ctx, sourceRepo.GitUID, sourceRepo.Path,
event.Payload.SourceSHA, s.urlProvider)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -725,7 +730,8 @@ func (s *Service) handleEventPullReqTargetBranchChanged(
pr *types.PullReq, pr *types.PullReq,
targetRepo, sourceRepo *types.Repository, targetRepo, sourceRepo *types.Repository,
) (any, error) { ) (any, error) {
commitInfo, err := s.fetchCommitInfoForEvent(ctx, sourceRepo.GitUID, event.Payload.SourceSHA) commitInfo, err := s.fetchCommitInfoForEvent(ctx, sourceRepo.GitUID, sourceRepo.Path,
event.Payload.SourceSHA, s.urlProvider)
if err != nil { if err != nil {
return nil, err return nil, err
} }

View File

@ -30,7 +30,7 @@ func (s *Service) handleEventTagCreated(ctx context.Context,
return s.triggerForEventWithRepo(ctx, enum.WebhookTriggerTagCreated, return s.triggerForEventWithRepo(ctx, enum.WebhookTriggerTagCreated,
event.ID, event.Payload.PrincipalID, event.Payload.RepoID, event.ID, event.Payload.PrincipalID, event.Payload.RepoID,
func(principal *types.Principal, repo *types.Repository) (any, error) { func(principal *types.Principal, repo *types.Repository) (any, error) {
commitInfo, err := s.fetchCommitInfoForEvent(ctx, repo.GitUID, event.Payload.SHA) commitInfo, err := s.fetchCommitInfoForEvent(ctx, repo.GitUID, repo.Path, event.Payload.SHA, s.urlProvider)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -68,8 +68,8 @@ func (s *Service) handleEventTagUpdated(ctx context.Context,
return s.triggerForEventWithRepo(ctx, enum.WebhookTriggerTagUpdated, return s.triggerForEventWithRepo(ctx, enum.WebhookTriggerTagUpdated,
event.ID, event.Payload.PrincipalID, event.Payload.RepoID, event.ID, event.Payload.PrincipalID, event.Payload.RepoID,
func(principal *types.Principal, repo *types.Repository) (any, error) { func(principal *types.Principal, repo *types.Repository) (any, error) {
commitsInfo, totalCommits, err := s.fetchCommitsInfoForEvent(ctx, repo.GitUID, commitsInfo, totalCommits, err := s.fetchCommitsInfoForEvent(ctx, repo.GitUID, repo.Path,
event.Payload.OldSHA, event.Payload.NewSHA) event.Payload.OldSHA, event.Payload.NewSHA, s.urlProvider)
if err != nil { if err != nil {
return nil, err return nil, err
} }

View File

@ -224,6 +224,7 @@ type CommitInfo struct {
Message string `json:"message"` Message string `json:"message"`
Author SignatureInfo `json:"author"` Author SignatureInfo `json:"author"`
Committer SignatureInfo `json:"committer"` Committer SignatureInfo `json:"committer"`
URL string `json:"url"`
Added []string `json:"added"` Added []string `json:"added"`
Removed []string `json:"removed"` Removed []string `json:"removed"`
@ -231,7 +232,12 @@ type CommitInfo struct {
} }
// commitInfoFrom gets the CommitInfo from a git.Commit. // commitInfoFrom gets the CommitInfo from a git.Commit.
func commitInfoFrom(commit git.Commit) CommitInfo { func commitInfoFrom(
ctx context.Context,
repoPath string,
commit git.Commit,
urlProvider url.Provider,
) CommitInfo {
added := []string{} added := []string{}
removed := []string{} removed := []string{}
modified := []string{} modified := []string{}
@ -258,6 +264,7 @@ func commitInfoFrom(commit git.Commit) CommitInfo {
Message: commit.Message, Message: commit.Message,
Author: signatureInfoFrom(commit.Author), Author: signatureInfoFrom(commit.Author),
Committer: signatureInfoFrom(commit.Committer), Committer: signatureInfoFrom(commit.Committer),
URL: urlProvider.GenerateUIRefURL(ctx, repoPath, commit.SHA.String()),
Added: added, Added: added,
Removed: removed, Removed: removed,
Modified: modified, Modified: modified,
@ -265,10 +272,15 @@ func commitInfoFrom(commit git.Commit) CommitInfo {
} }
// commitsInfoFrom gets the ExtendedCommitInfo from a []git.Commit. // commitsInfoFrom gets the ExtendedCommitInfo from a []git.Commit.
func commitsInfoFrom(commits []git.Commit) []CommitInfo { func commitsInfoFrom(
ctx context.Context,
repoPath string,
commits []git.Commit,
urlProvider url.Provider,
) []CommitInfo {
commitsInfo := make([]CommitInfo, len(commits)) commitsInfo := make([]CommitInfo, len(commits))
for i, commit := range commits { for i, commit := range commits {
commitsInfo[i] = commitInfoFrom(commit) commitsInfo[i] = commitInfoFrom(ctx, repoPath, commit, urlProvider)
} }
return commitsInfo return commitsInfo
} }

View File

@ -67,6 +67,9 @@ type Provider interface {
// GenerateUICompareURL returns the url for the UI screen comparing two references. // GenerateUICompareURL returns the url for the UI screen comparing two references.
GenerateUICompareURL(ctx context.Context, repoPath string, ref1 string, ref2 string) string GenerateUICompareURL(ctx context.Context, repoPath string, ref1 string, ref2 string) string
// GenerateUIRefURL returns the url for the UI screen for given ref.
GenerateUIRefURL(ctx context.Context, repoPath string, ref string) string
// GetAPIHostname returns the host for the api endpoint. // GetAPIHostname returns the host for the api endpoint.
GetAPIHostname(ctx context.Context) string GetAPIHostname(ctx context.Context) string
@ -231,6 +234,10 @@ func (p *provider) GenerateUICompareURL(_ context.Context, repoPath string, ref1
return p.uiURL.JoinPath(repoPath, "pulls/compare", ref1+"..."+ref2).String() return p.uiURL.JoinPath(repoPath, "pulls/compare", ref1+"..."+ref2).String()
} }
func (p *provider) GenerateUIRefURL(_ context.Context, repoPath string, ref string) string {
return p.uiURL.JoinPath(repoPath, "commit", ref).String()
}
func (p *provider) GetAPIHostname(context.Context) string { func (p *provider) GetAPIHostname(context.Context) string {
return p.apiURL.Hostname() return p.apiURL.Hostname()
} }