mirror of
				https://gitee.com/gitea/gitea
				synced 2025-11-04 16:40:24 +08:00 
			
		
		
		
	Add action feed for new release (#12324)
* Add action feed for new release Signed-off-by: a1012112796 <1012112796@qq.com> * fix lint * Apply suggestions from code review * Add ReleaseID to the action table * Remove error message * Fold the attachments download list * remove attchment download list * simplify code * fix create release from existing tag * simplify ui * translation change * fix test Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com> Co-authored-by: Lauris BH <lauris@nix.lv> Co-authored-by: techknowlogick <techknowlogick@gitea.io>
This commit is contained in:
		@@ -49,6 +49,7 @@ const (
 | 
				
			|||||||
	ActionApprovePullRequest                       // 21
 | 
						ActionApprovePullRequest                       // 21
 | 
				
			||||||
	ActionRejectPullRequest                        // 22
 | 
						ActionRejectPullRequest                        // 22
 | 
				
			||||||
	ActionCommentPull                              // 23
 | 
						ActionCommentPull                              // 23
 | 
				
			||||||
 | 
						ActionPublishRelease                           // 24
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Action represents user operation type and other information to
 | 
					// Action represents user operation type and other information to
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -252,7 +252,7 @@ func notifyWatchers(e Engine, actions ...*Action) error {
 | 
				
			|||||||
			act.Repo.Units = nil
 | 
								act.Repo.Units = nil
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			switch act.OpType {
 | 
								switch act.OpType {
 | 
				
			||||||
			case ActionCommitRepo, ActionPushTag, ActionDeleteTag, ActionDeleteBranch:
 | 
								case ActionCommitRepo, ActionPushTag, ActionDeleteTag, ActionPublishRelease, ActionDeleteBranch:
 | 
				
			||||||
				if !permCode[i] {
 | 
									if !permCode[i] {
 | 
				
			||||||
					continue
 | 
										continue
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -314,3 +314,22 @@ func (a *actionNotifier) NotifySyncDeleteRef(doer *models.User, repo *models.Rep
 | 
				
			|||||||
		log.Error("notifyWatchers: %v", err)
 | 
							log.Error("notifyWatchers: %v", err)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (a *actionNotifier) NotifyNewRelease(rel *models.Release) {
 | 
				
			||||||
 | 
						if err := rel.LoadAttributes(); err != nil {
 | 
				
			||||||
 | 
							log.Error("NotifyNewRelease: %v", err)
 | 
				
			||||||
 | 
							return
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if err := models.NotifyWatchers(&models.Action{
 | 
				
			||||||
 | 
							ActUserID: rel.PublisherID,
 | 
				
			||||||
 | 
							ActUser:   rel.Publisher,
 | 
				
			||||||
 | 
							OpType:    models.ActionPublishRelease,
 | 
				
			||||||
 | 
							RepoID:    rel.RepoID,
 | 
				
			||||||
 | 
							Repo:      rel.Repo,
 | 
				
			||||||
 | 
							IsPrivate: rel.Repo.IsPrivate,
 | 
				
			||||||
 | 
							Content:   rel.Title,
 | 
				
			||||||
 | 
							RefName:   rel.TagName,
 | 
				
			||||||
 | 
						}); err != nil {
 | 
				
			||||||
 | 
							log.Error("notifyWatchers: %v", err)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -640,6 +640,8 @@ func ActionIcon(opType models.ActionType) string {
 | 
				
			|||||||
		return "check"
 | 
							return "check"
 | 
				
			||||||
	case models.ActionRejectPullRequest:
 | 
						case models.ActionRejectPullRequest:
 | 
				
			||||||
		return "diff"
 | 
							return "diff"
 | 
				
			||||||
 | 
						case models.ActionPublishRelease:
 | 
				
			||||||
 | 
							return "tag"
 | 
				
			||||||
	default:
 | 
						default:
 | 
				
			||||||
		return "question"
 | 
							return "question"
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -2331,6 +2331,7 @@ mirror_sync_create = synced new reference <a href="%s/src/%s">%[2]s</a> to <a hr
 | 
				
			|||||||
mirror_sync_delete = synced and deleted reference <code>%[2]s</code> at <a href="%[1]s">%[3]s</a> from mirror
 | 
					mirror_sync_delete = synced and deleted reference <code>%[2]s</code> at <a href="%[1]s">%[3]s</a> from mirror
 | 
				
			||||||
approve_pull_request = `approved <a href="%s/pulls/%s">%s#%[2]s</a>`
 | 
					approve_pull_request = `approved <a href="%s/pulls/%s">%s#%[2]s</a>`
 | 
				
			||||||
reject_pull_request = `suggested changes for <a href="%s/pulls/%s">%s#%[2]s</a>`
 | 
					reject_pull_request = `suggested changes for <a href="%s/pulls/%s">%s#%[2]s</a>`
 | 
				
			||||||
 | 
					publish_release  = `released <a href="%s/releases/tag/%s"> "%[4]s" </a> at <a href="%[1]s">%[3]s</a>`
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[tool]
 | 
					[tool]
 | 
				
			||||||
ago = %s ago
 | 
					ago = %s ago
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -194,8 +194,8 @@ func CreateRelease(ctx *context.APIContext, form api.CreateReleaseOption) {
 | 
				
			|||||||
		rel.Repo = ctx.Repo.Repository
 | 
							rel.Repo = ctx.Repo.Repository
 | 
				
			||||||
		rel.Publisher = ctx.User
 | 
							rel.Publisher = ctx.User
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if err = releaseservice.UpdateRelease(ctx.User, ctx.Repo.GitRepo, rel, nil); err != nil {
 | 
							if err = releaseservice.UpdateReleaseOrCreatReleaseFromTag(ctx.User, ctx.Repo.GitRepo, rel, nil, true); err != nil {
 | 
				
			||||||
			ctx.ServerError("UpdateRelease", err)
 | 
								ctx.ServerError("UpdateReleaseOrCreatReleaseFromTag", err)
 | 
				
			||||||
			return
 | 
								return
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -266,8 +266,8 @@ func EditRelease(ctx *context.APIContext, form api.EditReleaseOption) {
 | 
				
			|||||||
	if form.IsPrerelease != nil {
 | 
						if form.IsPrerelease != nil {
 | 
				
			||||||
		rel.IsPrerelease = *form.IsPrerelease
 | 
							rel.IsPrerelease = *form.IsPrerelease
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if err := releaseservice.UpdateRelease(ctx.User, ctx.Repo.GitRepo, rel, nil); err != nil {
 | 
						if err := releaseservice.UpdateReleaseOrCreatReleaseFromTag(ctx.User, ctx.Repo.GitRepo, rel, nil, false); err != nil {
 | 
				
			||||||
		ctx.Error(http.StatusInternalServerError, "UpdateRelease", err)
 | 
							ctx.Error(http.StatusInternalServerError, "UpdateReleaseOrCreatReleaseFromTag", err)
 | 
				
			||||||
		return
 | 
							return
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -223,7 +223,7 @@ func NewReleasePost(ctx *context.Context, form auth.NewReleaseForm) {
 | 
				
			|||||||
			return
 | 
								return
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		rel := &models.Release{
 | 
							rel = &models.Release{
 | 
				
			||||||
			RepoID:       ctx.Repo.Repository.ID,
 | 
								RepoID:       ctx.Repo.Repository.ID,
 | 
				
			||||||
			PublisherID:  ctx.User.ID,
 | 
								PublisherID:  ctx.User.ID,
 | 
				
			||||||
			Title:        form.Title,
 | 
								Title:        form.Title,
 | 
				
			||||||
@@ -262,9 +262,9 @@ func NewReleasePost(ctx *context.Context, form auth.NewReleaseForm) {
 | 
				
			|||||||
		rel.PublisherID = ctx.User.ID
 | 
							rel.PublisherID = ctx.User.ID
 | 
				
			||||||
		rel.IsTag = false
 | 
							rel.IsTag = false
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if err = releaseservice.UpdateRelease(ctx.User, ctx.Repo.GitRepo, rel, attachmentUUIDs); err != nil {
 | 
							if err = releaseservice.UpdateReleaseOrCreatReleaseFromTag(ctx.User, ctx.Repo.GitRepo, rel, attachmentUUIDs, true); err != nil {
 | 
				
			||||||
			ctx.Data["Err_TagName"] = true
 | 
								ctx.Data["Err_TagName"] = true
 | 
				
			||||||
			ctx.ServerError("UpdateRelease", err)
 | 
								ctx.ServerError("UpdateReleaseOrCreatReleaseFromTag", err)
 | 
				
			||||||
			return
 | 
								return
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -341,7 +341,7 @@ func EditReleasePost(ctx *context.Context, form auth.EditReleaseForm) {
 | 
				
			|||||||
	rel.Note = form.Content
 | 
						rel.Note = form.Content
 | 
				
			||||||
	rel.IsDraft = len(form.Draft) > 0
 | 
						rel.IsDraft = len(form.Draft) > 0
 | 
				
			||||||
	rel.IsPrerelease = form.Prerelease
 | 
						rel.IsPrerelease = form.Prerelease
 | 
				
			||||||
	if err = releaseservice.UpdateRelease(ctx.User, ctx.Repo.GitRepo, rel, attachmentUUIDs); err != nil {
 | 
						if err = releaseservice.UpdateReleaseOrCreatReleaseFromTag(ctx.User, ctx.Repo.GitRepo, rel, attachmentUUIDs, false); err != nil {
 | 
				
			||||||
		ctx.ServerError("UpdateRelease", err)
 | 
							ctx.ServerError("UpdateRelease", err)
 | 
				
			||||||
		return
 | 
							return
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -95,8 +95,8 @@ func CreateRelease(gitRepo *git.Repository, rel *models.Release, attachmentUUIDs
 | 
				
			|||||||
	return nil
 | 
						return nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// UpdateRelease updates information of a release.
 | 
					// UpdateReleaseOrCreatReleaseFromTag updates information of a release or create release from tag.
 | 
				
			||||||
func UpdateRelease(doer *models.User, gitRepo *git.Repository, rel *models.Release, attachmentUUIDs []string) (err error) {
 | 
					func UpdateReleaseOrCreatReleaseFromTag(doer *models.User, gitRepo *git.Repository, rel *models.Release, attachmentUUIDs []string, isCreate bool) (err error) {
 | 
				
			||||||
	if err = createTag(gitRepo, rel); err != nil {
 | 
						if err = createTag(gitRepo, rel); err != nil {
 | 
				
			||||||
		return err
 | 
							return err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -110,7 +110,14 @@ func UpdateRelease(doer *models.User, gitRepo *git.Repository, rel *models.Relea
 | 
				
			|||||||
		log.Error("AddReleaseAttachments: %v", err)
 | 
							log.Error("AddReleaseAttachments: %v", err)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	notification.NotifyUpdateRelease(doer, rel)
 | 
						if !isCreate {
 | 
				
			||||||
 | 
							notification.NotifyUpdateRelease(doer, rel)
 | 
				
			||||||
 | 
							return
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if !rel.IsDraft {
 | 
				
			||||||
 | 
							notification.NotifyNewRelease(rel)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return err
 | 
						return err
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -131,7 +131,7 @@ func TestRelease_Update(t *testing.T) {
 | 
				
			|||||||
	releaseCreatedUnix := release.CreatedUnix
 | 
						releaseCreatedUnix := release.CreatedUnix
 | 
				
			||||||
	time.Sleep(2 * time.Second) // sleep 2 seconds to ensure a different timestamp
 | 
						time.Sleep(2 * time.Second) // sleep 2 seconds to ensure a different timestamp
 | 
				
			||||||
	release.Note = "Changed note"
 | 
						release.Note = "Changed note"
 | 
				
			||||||
	assert.NoError(t, UpdateRelease(user, gitRepo, release, nil))
 | 
						assert.NoError(t, UpdateReleaseOrCreatReleaseFromTag(user, gitRepo, release, nil, false))
 | 
				
			||||||
	release, err = models.GetReleaseByID(release.ID)
 | 
						release, err = models.GetReleaseByID(release.ID)
 | 
				
			||||||
	assert.NoError(t, err)
 | 
						assert.NoError(t, err)
 | 
				
			||||||
	assert.Equal(t, int64(releaseCreatedUnix), int64(release.CreatedUnix))
 | 
						assert.Equal(t, int64(releaseCreatedUnix), int64(release.CreatedUnix))
 | 
				
			||||||
@@ -153,7 +153,7 @@ func TestRelease_Update(t *testing.T) {
 | 
				
			|||||||
	releaseCreatedUnix = release.CreatedUnix
 | 
						releaseCreatedUnix = release.CreatedUnix
 | 
				
			||||||
	time.Sleep(2 * time.Second) // sleep 2 seconds to ensure a different timestamp
 | 
						time.Sleep(2 * time.Second) // sleep 2 seconds to ensure a different timestamp
 | 
				
			||||||
	release.Title = "Changed title"
 | 
						release.Title = "Changed title"
 | 
				
			||||||
	assert.NoError(t, UpdateRelease(user, gitRepo, release, nil))
 | 
						assert.NoError(t, UpdateReleaseOrCreatReleaseFromTag(user, gitRepo, release, nil, false))
 | 
				
			||||||
	release, err = models.GetReleaseByID(release.ID)
 | 
						release, err = models.GetReleaseByID(release.ID)
 | 
				
			||||||
	assert.NoError(t, err)
 | 
						assert.NoError(t, err)
 | 
				
			||||||
	assert.Less(t, int64(releaseCreatedUnix), int64(release.CreatedUnix))
 | 
						assert.Less(t, int64(releaseCreatedUnix), int64(release.CreatedUnix))
 | 
				
			||||||
@@ -176,7 +176,7 @@ func TestRelease_Update(t *testing.T) {
 | 
				
			|||||||
	time.Sleep(2 * time.Second) // sleep 2 seconds to ensure a different timestamp
 | 
						time.Sleep(2 * time.Second) // sleep 2 seconds to ensure a different timestamp
 | 
				
			||||||
	release.Title = "Changed title"
 | 
						release.Title = "Changed title"
 | 
				
			||||||
	release.Note = "Changed note"
 | 
						release.Note = "Changed note"
 | 
				
			||||||
	assert.NoError(t, UpdateRelease(user, gitRepo, release, nil))
 | 
						assert.NoError(t, UpdateReleaseOrCreatReleaseFromTag(user, gitRepo, release, nil, false))
 | 
				
			||||||
	release, err = models.GetReleaseByID(release.ID)
 | 
						release, err = models.GetReleaseByID(release.ID)
 | 
				
			||||||
	assert.NoError(t, err)
 | 
						assert.NoError(t, err)
 | 
				
			||||||
	assert.Equal(t, int64(releaseCreatedUnix), int64(release.CreatedUnix))
 | 
						assert.Equal(t, int64(releaseCreatedUnix), int64(release.CreatedUnix))
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -70,6 +70,10 @@
 | 
				
			|||||||
						{{else if eq .GetOpType 23}}
 | 
											{{else if eq .GetOpType 23}}
 | 
				
			||||||
							{{ $index := index .GetIssueInfos 0}}
 | 
												{{ $index := index .GetIssueInfos 0}}
 | 
				
			||||||
							{{$.i18n.Tr "action.comment_pull" .GetRepoLink $index .ShortRepoPath | Str2html}}
 | 
												{{$.i18n.Tr "action.comment_pull" .GetRepoLink $index .ShortRepoPath | Str2html}}
 | 
				
			||||||
 | 
											{{else if eq .GetOpType 24}}
 | 
				
			||||||
 | 
												{{ $branchLink := .GetBranch | EscapePound | Escape}}
 | 
				
			||||||
 | 
												{{ $linkText := .Content | RenderEmoji }}
 | 
				
			||||||
 | 
												{{$.i18n.Tr "action.publish_release" .GetRepoLink $branchLink .ShortRepoPath $linkText | Str2html}}
 | 
				
			||||||
						{{end}}
 | 
											{{end}}
 | 
				
			||||||
					</p>
 | 
										</p>
 | 
				
			||||||
					{{if or (eq .GetOpType 5) (eq .GetOpType 18)}}
 | 
										{{if or (eq .GetOpType 5) (eq .GetOpType 18)}}
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user