Implemented head_commit for webhooks (#16282)
* Removed Len field. * Added head_commit webhook field. * Added comment for returns.
This commit is contained in:
		
							parent
							
								
									579fcad8cd
								
							
						
					
					
						commit
						aac663e0da
					
				
					 7 changed files with 129 additions and 97 deletions
				
			
		|  | @ -562,7 +562,7 @@ func (m *webhookNotifier) NotifyIssueChangeMilestone(doer *models.User, issue *m | ||||||
| 
 | 
 | ||||||
| func (m *webhookNotifier) NotifyPushCommits(pusher *models.User, repo *models.Repository, opts *repository.PushUpdateOptions, commits *repository.PushCommits) { | func (m *webhookNotifier) NotifyPushCommits(pusher *models.User, repo *models.Repository, opts *repository.PushUpdateOptions, commits *repository.PushCommits) { | ||||||
| 	apiPusher := convert.ToUser(pusher, nil) | 	apiPusher := convert.ToUser(pusher, nil) | ||||||
| 	apiCommits, err := commits.ToAPIPayloadCommits(repo.RepoPath(), repo.HTMLURL()) | 	apiCommits, apiHeadCommit, err := commits.ToAPIPayloadCommits(repo.RepoPath(), repo.HTMLURL()) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		log.Error("commits.ToAPIPayloadCommits failed: %v", err) | 		log.Error("commits.ToAPIPayloadCommits failed: %v", err) | ||||||
| 		return | 		return | ||||||
|  | @ -574,6 +574,7 @@ func (m *webhookNotifier) NotifyPushCommits(pusher *models.User, repo *models.Re | ||||||
| 		After:      opts.NewCommitID, | 		After:      opts.NewCommitID, | ||||||
| 		CompareURL: setting.AppURL + commits.CompareURL, | 		CompareURL: setting.AppURL + commits.CompareURL, | ||||||
| 		Commits:    apiCommits, | 		Commits:    apiCommits, | ||||||
|  | 		HeadCommit: apiHeadCommit, | ||||||
| 		Repo:       convert.ToRepo(repo, models.AccessModeOwner), | 		Repo:       convert.ToRepo(repo, models.AccessModeOwner), | ||||||
| 		Pusher:     apiPusher, | 		Pusher:     apiPusher, | ||||||
| 		Sender:     apiPusher, | 		Sender:     apiPusher, | ||||||
|  | @ -790,7 +791,7 @@ func (m *webhookNotifier) NotifyDeleteRelease(doer *models.User, rel *models.Rel | ||||||
| 
 | 
 | ||||||
| func (m *webhookNotifier) NotifySyncPushCommits(pusher *models.User, repo *models.Repository, opts *repository.PushUpdateOptions, commits *repository.PushCommits) { | func (m *webhookNotifier) NotifySyncPushCommits(pusher *models.User, repo *models.Repository, opts *repository.PushUpdateOptions, commits *repository.PushCommits) { | ||||||
| 	apiPusher := convert.ToUser(pusher, nil) | 	apiPusher := convert.ToUser(pusher, nil) | ||||||
| 	apiCommits, err := commits.ToAPIPayloadCommits(repo.RepoPath(), repo.HTMLURL()) | 	apiCommits, apiHeadCommit, err := commits.ToAPIPayloadCommits(repo.RepoPath(), repo.HTMLURL()) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		log.Error("commits.ToAPIPayloadCommits failed: %v", err) | 		log.Error("commits.ToAPIPayloadCommits failed: %v", err) | ||||||
| 		return | 		return | ||||||
|  | @ -802,6 +803,7 @@ func (m *webhookNotifier) NotifySyncPushCommits(pusher *models.User, repo *model | ||||||
| 		After:      opts.NewCommitID, | 		After:      opts.NewCommitID, | ||||||
| 		CompareURL: setting.AppURL + commits.CompareURL, | 		CompareURL: setting.AppURL + commits.CompareURL, | ||||||
| 		Commits:    apiCommits, | 		Commits:    apiCommits, | ||||||
|  | 		HeadCommit: apiHeadCommit, | ||||||
| 		Repo:       convert.ToRepo(repo, models.AccessModeOwner), | 		Repo:       convert.ToRepo(repo, models.AccessModeOwner), | ||||||
| 		Pusher:     apiPusher, | 		Pusher:     apiPusher, | ||||||
| 		Sender:     apiPusher, | 		Sender:     apiPusher, | ||||||
|  |  | ||||||
|  | @ -28,8 +28,8 @@ type PushCommit struct { | ||||||
| 
 | 
 | ||||||
| // PushCommits represents list of commits in a push operation.
 | // PushCommits represents list of commits in a push operation.
 | ||||||
| type PushCommits struct { | type PushCommits struct { | ||||||
| 	Len        int |  | ||||||
| 	Commits    []*PushCommit | 	Commits    []*PushCommit | ||||||
|  | 	HeadCommit *PushCommit | ||||||
| 	CompareURL string | 	CompareURL string | ||||||
| 
 | 
 | ||||||
| 	avatars    map[string]string | 	avatars    map[string]string | ||||||
|  | @ -44,16 +44,9 @@ func NewPushCommits() *PushCommits { | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // ToAPIPayloadCommits converts a PushCommits object to
 | // toAPIPayloadCommit converts a single PushCommit to an api.PayloadCommit object.
 | ||||||
| // api.PayloadCommit format.
 | func (pc *PushCommits) toAPIPayloadCommit(repoPath, repoLink string, commit *PushCommit) (*api.PayloadCommit, error) { | ||||||
| func (pc *PushCommits) ToAPIPayloadCommits(repoPath, repoLink string) ([]*api.PayloadCommit, error) { |  | ||||||
| 	commits := make([]*api.PayloadCommit, len(pc.Commits)) |  | ||||||
| 
 |  | ||||||
| 	if pc.emailUsers == nil { |  | ||||||
| 		pc.emailUsers = make(map[string]*models.User) |  | ||||||
| 	} |  | ||||||
| 	var err error | 	var err error | ||||||
| 	for i, commit := range pc.Commits { |  | ||||||
| 	authorUsername := "" | 	authorUsername := "" | ||||||
| 	author, ok := pc.emailUsers[commit.AuthorEmail] | 	author, ok := pc.emailUsers[commit.AuthorEmail] | ||||||
| 	if !ok { | 	if !ok { | ||||||
|  | @ -84,7 +77,7 @@ func (pc *PushCommits) ToAPIPayloadCommits(repoPath, repoLink string) ([]*api.Pa | ||||||
| 		return nil, fmt.Errorf("FileStatus [commit_sha1: %s]: %v", commit.Sha1, err) | 		return nil, fmt.Errorf("FileStatus [commit_sha1: %s]: %v", commit.Sha1, err) | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 		commits[i] = &api.PayloadCommit{ | 	return &api.PayloadCommit{ | ||||||
| 		ID:      commit.Sha1, | 		ID:      commit.Sha1, | ||||||
| 		Message: commit.Message, | 		Message: commit.Message, | ||||||
| 		URL:     fmt.Sprintf("%s/commit/%s", repoLink, commit.Sha1), | 		URL:     fmt.Sprintf("%s/commit/%s", repoLink, commit.Sha1), | ||||||
|  | @ -102,9 +95,37 @@ func (pc *PushCommits) ToAPIPayloadCommits(repoPath, repoLink string) ([]*api.Pa | ||||||
| 		Removed:   fileStatus.Removed, | 		Removed:   fileStatus.Removed, | ||||||
| 		Modified:  fileStatus.Modified, | 		Modified:  fileStatus.Modified, | ||||||
| 		Timestamp: commit.Timestamp, | 		Timestamp: commit.Timestamp, | ||||||
|  | 	}, nil | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // ToAPIPayloadCommits converts a PushCommits object to api.PayloadCommit format.
 | ||||||
|  | // It returns all converted commits and, if provided, the head commit or an error otherwise.
 | ||||||
|  | func (pc *PushCommits) ToAPIPayloadCommits(repoPath, repoLink string) ([]*api.PayloadCommit, *api.PayloadCommit, error) { | ||||||
|  | 	commits := make([]*api.PayloadCommit, len(pc.Commits)) | ||||||
|  | 	var headCommit *api.PayloadCommit | ||||||
|  | 
 | ||||||
|  | 	if pc.emailUsers == nil { | ||||||
|  | 		pc.emailUsers = make(map[string]*models.User) | ||||||
|  | 	} | ||||||
|  | 	for i, commit := range pc.Commits { | ||||||
|  | 		apiCommit, err := pc.toAPIPayloadCommit(repoPath, repoLink, commit) | ||||||
|  | 		if err != nil { | ||||||
|  | 			return nil, nil, err | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		commits[i] = apiCommit | ||||||
|  | 		if pc.HeadCommit != nil && pc.HeadCommit.Sha1 == commits[i].ID { | ||||||
|  | 			headCommit = apiCommit | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 	return commits, nil | 	if pc.HeadCommit != nil && headCommit == nil { | ||||||
|  | 		var err error | ||||||
|  | 		headCommit, err = pc.toAPIPayloadCommit(repoPath, repoLink, pc.HeadCommit) | ||||||
|  | 		if err != nil { | ||||||
|  | 			return nil, nil, err | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	return commits, headCommit, nil | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // AvatarLink tries to match user in database with e-mail
 | // AvatarLink tries to match user in database with e-mail
 | ||||||
|  | @ -157,13 +178,9 @@ func CommitToPushCommit(commit *git.Commit) *PushCommit { | ||||||
| // ListToPushCommits transforms a list.List to PushCommits type.
 | // ListToPushCommits transforms a list.List to PushCommits type.
 | ||||||
| func ListToPushCommits(l *list.List) *PushCommits { | func ListToPushCommits(l *list.List) *PushCommits { | ||||||
| 	var commits []*PushCommit | 	var commits []*PushCommit | ||||||
| 	var actEmail string |  | ||||||
| 	for e := l.Front(); e != nil; e = e.Next() { | 	for e := l.Front(); e != nil; e = e.Next() { | ||||||
| 		commit := e.Value.(*git.Commit) | 		commit := CommitToPushCommit(e.Value.(*git.Commit)) | ||||||
| 		if actEmail == "" { | 		commits = append(commits, commit) | ||||||
| 			actEmail = commit.Committer.Email |  | ||||||
| 	} | 	} | ||||||
| 		commits = append(commits, CommitToPushCommit(commit)) | 	return &PushCommits{commits, nil, "", make(map[string]string), make(map[string]*models.User)} | ||||||
| 	} |  | ||||||
| 	return &PushCommits{l.Len(), commits, "", make(map[string]string), make(map[string]*models.User)} |  | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -46,12 +46,13 @@ func TestPushCommits_ToAPIPayloadCommits(t *testing.T) { | ||||||
| 			Message:        "good signed commit", | 			Message:        "good signed commit", | ||||||
| 		}, | 		}, | ||||||
| 	} | 	} | ||||||
| 	pushCommits.Len = len(pushCommits.Commits) | 	pushCommits.HeadCommit = &PushCommit{Sha1: "69554a6"} | ||||||
| 
 | 
 | ||||||
| 	repo := models.AssertExistsAndLoadBean(t, &models.Repository{ID: 16}).(*models.Repository) | 	repo := models.AssertExistsAndLoadBean(t, &models.Repository{ID: 16}).(*models.Repository) | ||||||
| 	payloadCommits, err := pushCommits.ToAPIPayloadCommits(repo.RepoPath(), "/user2/repo16") | 	payloadCommits, headCommit, err := pushCommits.ToAPIPayloadCommits(repo.RepoPath(), "/user2/repo16") | ||||||
| 	assert.NoError(t, err) | 	assert.NoError(t, err) | ||||||
| 	assert.Len(t, payloadCommits, 3) | 	assert.Len(t, payloadCommits, 3) | ||||||
|  | 	assert.NotNil(t, headCommit) | ||||||
| 
 | 
 | ||||||
| 	assert.Equal(t, "69554a6", payloadCommits[0].ID) | 	assert.Equal(t, "69554a6", payloadCommits[0].ID) | ||||||
| 	assert.Equal(t, "not signed commit", payloadCommits[0].Message) | 	assert.Equal(t, "not signed commit", payloadCommits[0].Message) | ||||||
|  | @ -85,6 +86,17 @@ func TestPushCommits_ToAPIPayloadCommits(t *testing.T) { | ||||||
| 	assert.EqualValues(t, []string{"readme.md"}, payloadCommits[2].Added) | 	assert.EqualValues(t, []string{"readme.md"}, payloadCommits[2].Added) | ||||||
| 	assert.EqualValues(t, []string{}, payloadCommits[2].Removed) | 	assert.EqualValues(t, []string{}, payloadCommits[2].Removed) | ||||||
| 	assert.EqualValues(t, []string{}, payloadCommits[2].Modified) | 	assert.EqualValues(t, []string{}, payloadCommits[2].Modified) | ||||||
|  | 
 | ||||||
|  | 	assert.Equal(t, "69554a6", headCommit.ID) | ||||||
|  | 	assert.Equal(t, "not signed commit", headCommit.Message) | ||||||
|  | 	assert.Equal(t, "/user2/repo16/commit/69554a6", headCommit.URL) | ||||||
|  | 	assert.Equal(t, "User2", headCommit.Committer.Name) | ||||||
|  | 	assert.Equal(t, "user2", headCommit.Committer.UserName) | ||||||
|  | 	assert.Equal(t, "User2", headCommit.Author.Name) | ||||||
|  | 	assert.Equal(t, "user2", headCommit.Author.UserName) | ||||||
|  | 	assert.EqualValues(t, []string{}, headCommit.Added) | ||||||
|  | 	assert.EqualValues(t, []string{}, headCommit.Removed) | ||||||
|  | 	assert.EqualValues(t, []string{"readme.md"}, headCommit.Modified) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func TestPushCommits_AvatarLink(t *testing.T) { | func TestPushCommits_AvatarLink(t *testing.T) { | ||||||
|  | @ -109,7 +121,6 @@ func TestPushCommits_AvatarLink(t *testing.T) { | ||||||
| 			Message:        "message2", | 			Message:        "message2", | ||||||
| 		}, | 		}, | ||||||
| 	} | 	} | ||||||
| 	pushCommits.Len = len(pushCommits.Commits) |  | ||||||
| 
 | 
 | ||||||
| 	assert.Equal(t, | 	assert.Equal(t, | ||||||
| 		"https://secure.gravatar.com/avatar/ab53a2911ddf9b4817ac01ddcd3d975f?d=identicon&s=112", | 		"https://secure.gravatar.com/avatar/ab53a2911ddf9b4817ac01ddcd3d975f?d=identicon&s=112", | ||||||
|  | @ -177,7 +188,6 @@ func TestListToPushCommits(t *testing.T) { | ||||||
| 	}) | 	}) | ||||||
| 
 | 
 | ||||||
| 	pushCommits := ListToPushCommits(l) | 	pushCommits := ListToPushCommits(l) | ||||||
| 	assert.Equal(t, 2, pushCommits.Len) |  | ||||||
| 	if assert.Len(t, pushCommits.Commits, 2) { | 	if assert.Len(t, pushCommits.Commits, 2) { | ||||||
| 		assert.Equal(t, "Message1", pushCommits.Commits[0].Message) | 		assert.Equal(t, "Message1", pushCommits.Commits[0].Message) | ||||||
| 		assert.Equal(t, hexString1, pushCommits.Commits[0].Sha1) | 		assert.Equal(t, hexString1, pushCommits.Commits[0].Sha1) | ||||||
|  |  | ||||||
|  | @ -140,13 +140,14 @@ func TestHook(ctx *context.APIContext) { | ||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | 	commit := convert.ToPayloadCommit(ctx.Repo.Repository, ctx.Repo.Commit) | ||||||
|  | 
 | ||||||
| 	if err := webhook.PrepareWebhook(hook, ctx.Repo.Repository, models.HookEventPush, &api.PushPayload{ | 	if err := webhook.PrepareWebhook(hook, ctx.Repo.Repository, models.HookEventPush, &api.PushPayload{ | ||||||
| 		Ref:        git.BranchPrefix + ctx.Repo.Repository.DefaultBranch, | 		Ref:        git.BranchPrefix + ctx.Repo.Repository.DefaultBranch, | ||||||
| 		Before:     ctx.Repo.Commit.ID.String(), | 		Before:     ctx.Repo.Commit.ID.String(), | ||||||
| 		After:      ctx.Repo.Commit.ID.String(), | 		After:      ctx.Repo.Commit.ID.String(), | ||||||
| 		Commits: []*api.PayloadCommit{ | 		Commits:    []*api.PayloadCommit{commit}, | ||||||
| 			convert.ToPayloadCommit(ctx.Repo.Repository, ctx.Repo.Commit), | 		HeadCommit: commit, | ||||||
| 		}, |  | ||||||
| 		Repo:       convert.ToRepo(ctx.Repo.Repository, models.AccessModeNone), | 		Repo:       convert.ToRepo(ctx.Repo.Repository, models.AccessModeNone), | ||||||
| 		Pusher:     convert.ToUserWithAccessMode(ctx.User, models.AccessModeNone), | 		Pusher:     convert.ToUserWithAccessMode(ctx.User, models.AccessModeNone), | ||||||
| 		Sender:     convert.ToUserWithAccessMode(ctx.User, models.AccessModeNone), | 		Sender:     convert.ToUserWithAccessMode(ctx.User, models.AccessModeNone), | ||||||
|  |  | ||||||
|  | @ -1085,12 +1085,8 @@ func TestWebhook(ctx *context.Context) { | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	apiUser := convert.ToUserWithAccessMode(ctx.User, models.AccessModeNone) | 	apiUser := convert.ToUserWithAccessMode(ctx.User, models.AccessModeNone) | ||||||
| 	p := &api.PushPayload{ | 
 | ||||||
| 		Ref:    git.BranchPrefix + ctx.Repo.Repository.DefaultBranch, | 	apiCommit := &api.PayloadCommit{ | ||||||
| 		Before: commit.ID.String(), |  | ||||||
| 		After:  commit.ID.String(), |  | ||||||
| 		Commits: []*api.PayloadCommit{ |  | ||||||
| 			{ |  | ||||||
| 		ID:      commit.ID.String(), | 		ID:      commit.ID.String(), | ||||||
| 		Message: commit.Message(), | 		Message: commit.Message(), | ||||||
| 		URL:     ctx.Repo.Repository.HTMLURL() + "/commit/" + commit.ID.String(), | 		URL:     ctx.Repo.Repository.HTMLURL() + "/commit/" + commit.ID.String(), | ||||||
|  | @ -1102,8 +1098,14 @@ func TestWebhook(ctx *context.Context) { | ||||||
| 			Name:  commit.Committer.Name, | 			Name:  commit.Committer.Name, | ||||||
| 			Email: commit.Committer.Email, | 			Email: commit.Committer.Email, | ||||||
| 		}, | 		}, | ||||||
| 			}, | 	} | ||||||
| 		}, | 
 | ||||||
|  | 	p := &api.PushPayload{ | ||||||
|  | 		Ref:        git.BranchPrefix + ctx.Repo.Repository.DefaultBranch, | ||||||
|  | 		Before:     commit.ID.String(), | ||||||
|  | 		After:      commit.ID.String(), | ||||||
|  | 		Commits:    []*api.PayloadCommit{apiCommit}, | ||||||
|  | 		HeadCommit: apiCommit, | ||||||
| 		Repo:       convert.ToRepo(ctx.Repo.Repository, models.AccessModeNone), | 		Repo:       convert.ToRepo(ctx.Repo.Repository, models.AccessModeNone), | ||||||
| 		Pusher:     apiUser, | 		Pusher:     apiUser, | ||||||
| 		Sender:     apiUser, | 		Sender:     apiUser, | ||||||
|  |  | ||||||
|  | @ -95,7 +95,6 @@ func pushUpdates(optsList []*repo_module.PushUpdateOptions) error { | ||||||
| 		if opts.IsNewRef() && opts.IsDelRef() { | 		if opts.IsNewRef() && opts.IsDelRef() { | ||||||
| 			return fmt.Errorf("Old and new revisions are both %s", git.EmptySHA) | 			return fmt.Errorf("Old and new revisions are both %s", git.EmptySHA) | ||||||
| 		} | 		} | ||||||
| 		var commits = &repo_module.PushCommits{} |  | ||||||
| 		if opts.IsTag() { // If is tag reference
 | 		if opts.IsTag() { // If is tag reference
 | ||||||
| 			if pusher == nil || pusher.ID != opts.PusherID { | 			if pusher == nil || pusher.ID != opts.PusherID { | ||||||
| 				var err error | 				var err error | ||||||
|  | @ -192,7 +191,8 @@ func pushUpdates(optsList []*repo_module.PushUpdateOptions) error { | ||||||
| 					} | 					} | ||||||
| 				} | 				} | ||||||
| 
 | 
 | ||||||
| 				commits = repo_module.ListToPushCommits(l) | 				commits := repo_module.ListToPushCommits(l) | ||||||
|  | 				commits.HeadCommit = repo_module.CommitToPushCommit(newCommit) | ||||||
| 
 | 
 | ||||||
| 				if err := repofiles.UpdateIssuesCommit(pusher, repo, commits.Commits, refName); err != nil { | 				if err := repofiles.UpdateIssuesCommit(pusher, repo, commits.Commits, refName); err != nil { | ||||||
| 					log.Error("updateIssuesCommit: %v", err) | 					log.Error("updateIssuesCommit: %v", err) | ||||||
|  |  | ||||||
|  | @ -101,7 +101,7 @@ | ||||||
| 										</li> | 										</li> | ||||||
| 									{{end}} | 									{{end}} | ||||||
| 								{{end}} | 								{{end}} | ||||||
| 								{{if and (gt $push.Len 1) $push.CompareURL}}<li><a href="{{AppSubUrl}}/{{$push.CompareURL}}">{{$.i18n.Tr "action.compare_commits" $push.Len}} »</a></li>{{end}} | 								{{if and (gt (len $push.Commits) 1) $push.CompareURL}}<li><a href="{{AppSubUrl}}/{{$push.CompareURL}}">{{$.i18n.Tr "action.compare_commits" (len $push.Commits)}} »</a></li>{{end}} | ||||||
| 							</ul> | 							</ul> | ||||||
| 						</div> | 						</div> | ||||||
| 					{{else if eq .GetOpType 6}} | 					{{else if eq .GetOpType 6}} | ||||||
|  |  | ||||||
		Loading…
	
		Reference in a new issue