From cad9adeff41595ea32281dbc2918e653c3e3a839 Mon Sep 17 00:00:00 2001
From: KN4CK3R <admin@oldschoolhack.me>
Date: Sun, 16 Oct 2022 18:22:34 +0200
Subject: [PATCH] Display total commit count in hook message (#21400)

Fixes #21379

The commits are capped by `setting.UI.FeedMaxCommitNum` so
`len(commits)` is not the correct number. So this PR adds a new
`TotalCommits` field.

Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
---
 modules/notification/webhook/webhook.go | 38 +++++++++++++------------
 modules/structs/hook.go                 | 19 +++++++------
 routers/api/v1/repo/hook.go             | 19 +++++++------
 routers/web/repo/webhook.go             | 19 +++++++------
 services/webhook/dingtalk.go            |  8 +++---
 services/webhook/dingtalk_test.go       |  2 +-
 services/webhook/discord.go             |  4 +--
 services/webhook/general_test.go        | 13 +++++----
 services/webhook/matrix.go              |  4 +--
 services/webhook/msteams.go             |  6 ++--
 services/webhook/slack.go               |  4 +--
 services/webhook/telegram.go            |  4 +--
 services/webhook/wechatwork.go          |  2 +-
 13 files changed, 74 insertions(+), 68 deletions(-)

diff --git a/modules/notification/webhook/webhook.go b/modules/notification/webhook/webhook.go
index 0eb2099a20..b93e90368a 100644
--- a/modules/notification/webhook/webhook.go
+++ b/modules/notification/webhook/webhook.go
@@ -645,15 +645,16 @@ func (m *webhookNotifier) NotifyPushCommits(pusher *user_model.User, repo *repo_
 	}
 
 	if err := webhook_services.PrepareWebhooks(repo, webhook.HookEventPush, &api.PushPayload{
-		Ref:        opts.RefFullName,
-		Before:     opts.OldCommitID,
-		After:      opts.NewCommitID,
-		CompareURL: setting.AppURL + commits.CompareURL,
-		Commits:    apiCommits,
-		HeadCommit: apiHeadCommit,
-		Repo:       convert.ToRepo(repo, perm.AccessModeOwner),
-		Pusher:     apiPusher,
-		Sender:     apiPusher,
+		Ref:          opts.RefFullName,
+		Before:       opts.OldCommitID,
+		After:        opts.NewCommitID,
+		CompareURL:   setting.AppURL + commits.CompareURL,
+		Commits:      apiCommits,
+		TotalCommits: commits.Len,
+		HeadCommit:   apiHeadCommit,
+		Repo:         convert.ToRepo(repo, perm.AccessModeOwner),
+		Pusher:       apiPusher,
+		Sender:       apiPusher,
 	}); err != nil {
 		log.Error("PrepareWebhooks: %v", err)
 	}
@@ -875,15 +876,16 @@ func (m *webhookNotifier) NotifySyncPushCommits(pusher *user_model.User, repo *r
 	}
 
 	if err := webhook_services.PrepareWebhooks(repo, webhook.HookEventPush, &api.PushPayload{
-		Ref:        opts.RefFullName,
-		Before:     opts.OldCommitID,
-		After:      opts.NewCommitID,
-		CompareURL: setting.AppURL + commits.CompareURL,
-		Commits:    apiCommits,
-		HeadCommit: apiHeadCommit,
-		Repo:       convert.ToRepo(repo, perm.AccessModeOwner),
-		Pusher:     apiPusher,
-		Sender:     apiPusher,
+		Ref:          opts.RefFullName,
+		Before:       opts.OldCommitID,
+		After:        opts.NewCommitID,
+		CompareURL:   setting.AppURL + commits.CompareURL,
+		Commits:      apiCommits,
+		TotalCommits: commits.Len,
+		HeadCommit:   apiHeadCommit,
+		Repo:         convert.ToRepo(repo, perm.AccessModeOwner),
+		Pusher:       apiPusher,
+		Sender:       apiPusher,
 	}); err != nil {
 		log.Error("PrepareWebhooks: %v", err)
 	}
diff --git a/modules/structs/hook.go b/modules/structs/hook.go
index 132b24b856..8321a15a8f 100644
--- a/modules/structs/hook.go
+++ b/modules/structs/hook.go
@@ -267,15 +267,16 @@ func (p *ReleasePayload) JSONPayload() ([]byte, error) {
 
 // PushPayload represents a payload information of push event.
 type PushPayload struct {
-	Ref        string           `json:"ref"`
-	Before     string           `json:"before"`
-	After      string           `json:"after"`
-	CompareURL string           `json:"compare_url"`
-	Commits    []*PayloadCommit `json:"commits"`
-	HeadCommit *PayloadCommit   `json:"head_commit"`
-	Repo       *Repository      `json:"repository"`
-	Pusher     *User            `json:"pusher"`
-	Sender     *User            `json:"sender"`
+	Ref          string           `json:"ref"`
+	Before       string           `json:"before"`
+	After        string           `json:"after"`
+	CompareURL   string           `json:"compare_url"`
+	Commits      []*PayloadCommit `json:"commits"`
+	TotalCommits int              `json:"total_commits"`
+	HeadCommit   *PayloadCommit   `json:"head_commit"`
+	Repo         *Repository      `json:"repository"`
+	Pusher       *User            `json:"pusher"`
+	Sender       *User            `json:"sender"`
 }
 
 // JSONPayload FIXME
diff --git a/routers/api/v1/repo/hook.go b/routers/api/v1/repo/hook.go
index b17142c0f6..86361817cb 100644
--- a/routers/api/v1/repo/hook.go
+++ b/routers/api/v1/repo/hook.go
@@ -169,15 +169,16 @@ func TestHook(ctx *context.APIContext) {
 
 	commitID := ctx.Repo.Commit.ID.String()
 	if err := webhook_service.PrepareWebhook(hook, ctx.Repo.Repository, webhook.HookEventPush, &api.PushPayload{
-		Ref:        ref,
-		Before:     commitID,
-		After:      commitID,
-		CompareURL: setting.AppURL + ctx.Repo.Repository.ComposeCompareURL(commitID, commitID),
-		Commits:    []*api.PayloadCommit{commit},
-		HeadCommit: commit,
-		Repo:       convert.ToRepo(ctx.Repo.Repository, perm.AccessModeNone),
-		Pusher:     convert.ToUserWithAccessMode(ctx.Doer, perm.AccessModeNone),
-		Sender:     convert.ToUserWithAccessMode(ctx.Doer, perm.AccessModeNone),
+		Ref:          ref,
+		Before:       commitID,
+		After:        commitID,
+		CompareURL:   setting.AppURL + ctx.Repo.Repository.ComposeCompareURL(commitID, commitID),
+		Commits:      []*api.PayloadCommit{commit},
+		TotalCommits: 1,
+		HeadCommit:   commit,
+		Repo:         convert.ToRepo(ctx.Repo.Repository, perm.AccessModeNone),
+		Pusher:       convert.ToUserWithAccessMode(ctx.Doer, perm.AccessModeNone),
+		Sender:       convert.ToUserWithAccessMode(ctx.Doer, perm.AccessModeNone),
 	}); err != nil {
 		ctx.Error(http.StatusInternalServerError, "PrepareWebhook: ", err)
 		return
diff --git a/routers/web/repo/webhook.go b/routers/web/repo/webhook.go
index a8939e72bd..425198ce24 100644
--- a/routers/web/repo/webhook.go
+++ b/routers/web/repo/webhook.go
@@ -668,15 +668,16 @@ func TestWebhook(ctx *context.Context) {
 
 	commitID := commit.ID.String()
 	p := &api.PushPayload{
-		Ref:        git.BranchPrefix + ctx.Repo.Repository.DefaultBranch,
-		Before:     commitID,
-		After:      commitID,
-		CompareURL: setting.AppURL + ctx.Repo.Repository.ComposeCompareURL(commitID, commitID),
-		Commits:    []*api.PayloadCommit{apiCommit},
-		HeadCommit: apiCommit,
-		Repo:       convert.ToRepo(ctx.Repo.Repository, perm.AccessModeNone),
-		Pusher:     apiUser,
-		Sender:     apiUser,
+		Ref:          git.BranchPrefix + ctx.Repo.Repository.DefaultBranch,
+		Before:       commitID,
+		After:        commitID,
+		CompareURL:   setting.AppURL + ctx.Repo.Repository.ComposeCompareURL(commitID, commitID),
+		Commits:      []*api.PayloadCommit{apiCommit},
+		TotalCommits: 1,
+		HeadCommit:   apiCommit,
+		Repo:         convert.ToRepo(ctx.Repo.Repository, perm.AccessModeNone),
+		Pusher:       apiUser,
+		Sender:       apiUser,
 	}
 	if err := webhook_service.PrepareWebhook(w, ctx.Repo.Repository, webhook.HookEventPush, p); err != nil {
 		ctx.Flash.Error("PrepareWebhook: " + err.Error())
diff --git a/services/webhook/dingtalk.go b/services/webhook/dingtalk.go
index 5112bdb347..e047e994c2 100644
--- a/services/webhook/dingtalk.go
+++ b/services/webhook/dingtalk.go
@@ -67,14 +67,14 @@ func (d *DingtalkPayload) Push(p *api.PushPayload) (api.Payloader, error) {
 	)
 
 	var titleLink, linkText string
-	if len(p.Commits) == 1 {
+	if p.TotalCommits == 1 {
 		commitDesc = "1 new commit"
 		titleLink = p.Commits[0].URL
-		linkText = fmt.Sprintf("view commit %s", p.Commits[0].ID[:7])
+		linkText = "view commit"
 	} else {
-		commitDesc = fmt.Sprintf("%d new commits", len(p.Commits))
+		commitDesc = fmt.Sprintf("%d new commits", p.TotalCommits)
 		titleLink = p.CompareURL
-		linkText = fmt.Sprintf("view commit %s...%s", p.Commits[0].ID[:7], p.Commits[len(p.Commits)-1].ID[:7])
+		linkText = "view commits"
 	}
 	if titleLink == "" {
 		titleLink = p.Repo.HTMLURL + "/src/" + util.PathEscapeSegments(branchName)
diff --git a/services/webhook/dingtalk_test.go b/services/webhook/dingtalk_test.go
index efc9601c12..fc15380f4d 100644
--- a/services/webhook/dingtalk_test.go
+++ b/services/webhook/dingtalk_test.go
@@ -82,7 +82,7 @@ func TestDingTalkPayload(t *testing.T) {
 
 		assert.Equal(t, "[2020558](http://localhost:3000/test/repo/commit/2020558fe2e34debb818a514715839cabd25e778) commit message - user1\r\n[2020558](http://localhost:3000/test/repo/commit/2020558fe2e34debb818a514715839cabd25e778) commit message - user1", pl.(*DingtalkPayload).ActionCard.Text)
 		assert.Equal(t, "[test/repo:test] 2 new commits", pl.(*DingtalkPayload).ActionCard.Title)
-		assert.Equal(t, "view commit 2020558...2020558", pl.(*DingtalkPayload).ActionCard.SingleTitle)
+		assert.Equal(t, "view commits", pl.(*DingtalkPayload).ActionCard.SingleTitle)
 		assert.Equal(t, "http://localhost:3000/test/repo/src/test", parseRealSingleURL(pl.(*DingtalkPayload).ActionCard.SingleURL))
 	})
 
diff --git a/services/webhook/discord.go b/services/webhook/discord.go
index 7b6f0f0b1d..22d75db893 100644
--- a/services/webhook/discord.go
+++ b/services/webhook/discord.go
@@ -142,11 +142,11 @@ func (d *DiscordPayload) Push(p *api.PushPayload) (api.Payloader, error) {
 	)
 
 	var titleLink string
-	if len(p.Commits) == 1 {
+	if p.TotalCommits == 1 {
 		commitDesc = "1 new commit"
 		titleLink = p.Commits[0].URL
 	} else {
-		commitDesc = fmt.Sprintf("%d new commits", len(p.Commits))
+		commitDesc = fmt.Sprintf("%d new commits", p.TotalCommits)
 		titleLink = p.CompareURL
 	}
 	if titleLink == "" {
diff --git a/services/webhook/general_test.go b/services/webhook/general_test.go
index 4acf51ac71..da3123d3ab 100644
--- a/services/webhook/general_test.go
+++ b/services/webhook/general_test.go
@@ -82,12 +82,13 @@ func pushTestPayload() *api.PushPayload {
 	}
 
 	return &api.PushPayload{
-		Ref:        "refs/heads/test",
-		Before:     "2020558fe2e34debb818a514715839cabd25e777",
-		After:      "2020558fe2e34debb818a514715839cabd25e778",
-		CompareURL: "",
-		HeadCommit: commit,
-		Commits:    []*api.PayloadCommit{commit, commit},
+		Ref:          "refs/heads/test",
+		Before:       "2020558fe2e34debb818a514715839cabd25e777",
+		After:        "2020558fe2e34debb818a514715839cabd25e778",
+		CompareURL:   "",
+		HeadCommit:   commit,
+		Commits:      []*api.PayloadCommit{commit, commit},
+		TotalCommits: 2,
 		Repo: &api.Repository{
 			HTMLURL:  "http://localhost:3000/test/repo",
 			Name:     "repo",
diff --git a/services/webhook/matrix.go b/services/webhook/matrix.go
index 59eae48307..6bbae70422 100644
--- a/services/webhook/matrix.go
+++ b/services/webhook/matrix.go
@@ -161,10 +161,10 @@ func (m *MatrixPayloadUnsafe) Release(p *api.ReleasePayload) (api.Payloader, err
 func (m *MatrixPayloadUnsafe) Push(p *api.PushPayload) (api.Payloader, error) {
 	var commitDesc string
 
-	if len(p.Commits) == 1 {
+	if p.TotalCommits == 1 {
 		commitDesc = "1 commit"
 	} else {
-		commitDesc = fmt.Sprintf("%d commits", len(p.Commits))
+		commitDesc = fmt.Sprintf("%d commits", p.TotalCommits)
 	}
 
 	repoLink := MatrixLinkFormatter(p.Repo.HTMLURL, p.Repo.FullName)
diff --git a/services/webhook/msteams.go b/services/webhook/msteams.go
index 1406004781..bf9e95edc5 100644
--- a/services/webhook/msteams.go
+++ b/services/webhook/msteams.go
@@ -125,11 +125,11 @@ func (m *MSTeamsPayload) Push(p *api.PushPayload) (api.Payloader, error) {
 	)
 
 	var titleLink string
-	if len(p.Commits) == 1 {
+	if p.TotalCommits == 1 {
 		commitDesc = "1 new commit"
 		titleLink = p.Commits[0].URL
 	} else {
-		commitDesc = fmt.Sprintf("%d new commits", len(p.Commits))
+		commitDesc = fmt.Sprintf("%d new commits", p.TotalCommits)
 		titleLink = p.CompareURL
 	}
 	if titleLink == "" {
@@ -156,7 +156,7 @@ func (m *MSTeamsPayload) Push(p *api.PushPayload) (api.Payloader, error) {
 		text,
 		titleLink,
 		greenColor,
-		&MSTeamsFact{"Commit count:", fmt.Sprintf("%d", len(p.Commits))},
+		&MSTeamsFact{"Commit count:", fmt.Sprintf("%d", p.TotalCommits)},
 	), nil
 }
 
diff --git a/services/webhook/slack.go b/services/webhook/slack.go
index 63cc6f8ca2..f5c69d74b6 100644
--- a/services/webhook/slack.go
+++ b/services/webhook/slack.go
@@ -179,10 +179,10 @@ func (s *SlackPayload) Push(p *api.PushPayload) (api.Payloader, error) {
 		commitString string
 	)
 
-	if len(p.Commits) == 1 {
+	if p.TotalCommits == 1 {
 		commitDesc = "1 new commit"
 	} else {
-		commitDesc = fmt.Sprintf("%d new commits", len(p.Commits))
+		commitDesc = fmt.Sprintf("%d new commits", p.TotalCommits)
 	}
 	if len(p.CompareURL) > 0 {
 		commitString = SlackLinkFormatter(p.CompareURL, commitDesc)
diff --git a/services/webhook/telegram.go b/services/webhook/telegram.go
index 13471d864e..7ca5f61062 100644
--- a/services/webhook/telegram.go
+++ b/services/webhook/telegram.go
@@ -89,11 +89,11 @@ func (t *TelegramPayload) Push(p *api.PushPayload) (api.Payloader, error) {
 	)
 
 	var titleLink string
-	if len(p.Commits) == 1 {
+	if p.TotalCommits == 1 {
 		commitDesc = "1 new commit"
 		titleLink = p.Commits[0].URL
 	} else {
-		commitDesc = fmt.Sprintf("%d new commits", len(p.Commits))
+		commitDesc = fmt.Sprintf("%d new commits", p.TotalCommits)
 		titleLink = p.CompareURL
 	}
 	if titleLink == "" {
diff --git a/services/webhook/wechatwork.go b/services/webhook/wechatwork.go
index bd4c3e0851..5344ccaa22 100644
--- a/services/webhook/wechatwork.go
+++ b/services/webhook/wechatwork.go
@@ -93,7 +93,7 @@ func (f *WechatworkPayload) Push(p *api.PushPayload) (api.Payloader, error) {
 	for i, commit := range p.Commits {
 		var authorName string
 		if commit.Author != nil {
-			authorName = "Author:" + commit.Author.Name
+			authorName = "Author: " + commit.Author.Name
 		}
 
 		message := strings.ReplaceAll(commit.Message, "\n\n", "\r\n")