diff --git a/models/action.go b/models/action.go index 59ccdb2d4c871..d6dbcdc6713f6 100644 --- a/models/action.go +++ b/models/action.go @@ -49,6 +49,7 @@ const ( ActionApprovePullRequest // 21 ActionRejectPullRequest // 22 ActionCommentPull // 23 + ActionPublishRelease // 24 ) // Action represents user operation type and other information to diff --git a/models/repo_watch.go b/models/repo_watch.go index 11cfa88918447..6cdf9b2af5f5b 100644 --- a/models/repo_watch.go +++ b/models/repo_watch.go @@ -252,7 +252,7 @@ func notifyWatchers(e Engine, actions ...*Action) error { act.Repo.Units = nil switch act.OpType { - case ActionCommitRepo, ActionPushTag, ActionDeleteTag, ActionDeleteBranch: + case ActionCommitRepo, ActionPushTag, ActionDeleteTag, ActionPublishRelease, ActionDeleteBranch: if !permCode[i] { continue } diff --git a/modules/notification/action/action.go b/modules/notification/action/action.go index 9956940f30b22..040cf3df1030d 100644 --- a/modules/notification/action/action.go +++ b/modules/notification/action/action.go @@ -314,3 +314,22 @@ func (a *actionNotifier) NotifySyncDeleteRef(doer *models.User, repo *models.Rep 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) + } +} diff --git a/modules/templates/helper.go b/modules/templates/helper.go index 8c078a0e825b0..8f3fba618d3e5 100644 --- a/modules/templates/helper.go +++ b/modules/templates/helper.go @@ -640,6 +640,8 @@ func ActionIcon(opType models.ActionType) string { return "check" case models.ActionRejectPullRequest: return "diff" + case models.ActionPublishRelease: + return "tag" default: return "question" } diff --git a/options/locale/locale_en-US.ini b/options/locale/locale_en-US.ini index 7968d00b58276..751cce65835fb 100644 --- a/options/locale/locale_en-US.ini +++ b/options/locale/locale_en-US.ini @@ -2331,6 +2331,7 @@ mirror_sync_create = synced new reference %[2]s to %[2]s at %[3]s from mirror approve_pull_request = `approved %s#%[2]s` reject_pull_request = `suggested changes for %s#%[2]s` +publish_release = `released "%[4]s" at %[3]s` [tool] ago = %s ago diff --git a/routers/api/v1/repo/release.go b/routers/api/v1/repo/release.go index ade82f24cbe26..752b5c76e0805 100644 --- a/routers/api/v1/repo/release.go +++ b/routers/api/v1/repo/release.go @@ -194,8 +194,8 @@ func CreateRelease(ctx *context.APIContext, form api.CreateReleaseOption) { rel.Repo = ctx.Repo.Repository rel.Publisher = ctx.User - if err = releaseservice.UpdateRelease(ctx.User, ctx.Repo.GitRepo, rel, nil); err != nil { - ctx.ServerError("UpdateRelease", err) + if err = releaseservice.UpdateReleaseOrCreatReleaseFromTag(ctx.User, ctx.Repo.GitRepo, rel, nil, true); err != nil { + ctx.ServerError("UpdateReleaseOrCreatReleaseFromTag", err) return } } @@ -266,8 +266,8 @@ func EditRelease(ctx *context.APIContext, form api.EditReleaseOption) { if form.IsPrerelease != nil { rel.IsPrerelease = *form.IsPrerelease } - if err := releaseservice.UpdateRelease(ctx.User, ctx.Repo.GitRepo, rel, nil); err != nil { - ctx.Error(http.StatusInternalServerError, "UpdateRelease", err) + if err := releaseservice.UpdateReleaseOrCreatReleaseFromTag(ctx.User, ctx.Repo.GitRepo, rel, nil, false); err != nil { + ctx.Error(http.StatusInternalServerError, "UpdateReleaseOrCreatReleaseFromTag", err) return } diff --git a/routers/repo/release.go b/routers/repo/release.go index 3b8e55f00246e..02fbcaccafdbd 100644 --- a/routers/repo/release.go +++ b/routers/repo/release.go @@ -223,7 +223,7 @@ func NewReleasePost(ctx *context.Context, form auth.NewReleaseForm) { return } - rel := &models.Release{ + rel = &models.Release{ RepoID: ctx.Repo.Repository.ID, PublisherID: ctx.User.ID, Title: form.Title, @@ -262,9 +262,9 @@ func NewReleasePost(ctx *context.Context, form auth.NewReleaseForm) { rel.PublisherID = ctx.User.ID 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.ServerError("UpdateRelease", err) + ctx.ServerError("UpdateReleaseOrCreatReleaseFromTag", err) return } } @@ -341,7 +341,7 @@ func EditReleasePost(ctx *context.Context, form auth.EditReleaseForm) { rel.Note = form.Content rel.IsDraft = len(form.Draft) > 0 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) return } diff --git a/services/release/release.go b/services/release/release.go index 64d132cd73ad6..2fc3cb199b4df 100644 --- a/services/release/release.go +++ b/services/release/release.go @@ -95,8 +95,8 @@ func CreateRelease(gitRepo *git.Repository, rel *models.Release, attachmentUUIDs return nil } -// UpdateRelease updates information of a release. -func UpdateRelease(doer *models.User, gitRepo *git.Repository, rel *models.Release, attachmentUUIDs []string) (err error) { +// UpdateReleaseOrCreatReleaseFromTag updates information of a release or create release from tag. +func UpdateReleaseOrCreatReleaseFromTag(doer *models.User, gitRepo *git.Repository, rel *models.Release, attachmentUUIDs []string, isCreate bool) (err error) { if err = createTag(gitRepo, rel); err != nil { return err } @@ -110,7 +110,14 @@ func UpdateRelease(doer *models.User, gitRepo *git.Repository, rel *models.Relea log.Error("AddReleaseAttachments: %v", err) } - notification.NotifyUpdateRelease(doer, rel) + if !isCreate { + notification.NotifyUpdateRelease(doer, rel) + return + } + + if !rel.IsDraft { + notification.NotifyNewRelease(rel) + } return err } diff --git a/services/release/release_test.go b/services/release/release_test.go index d5673b73b89a0..f50fca71ec064 100644 --- a/services/release/release_test.go +++ b/services/release/release_test.go @@ -131,7 +131,7 @@ func TestRelease_Update(t *testing.T) { releaseCreatedUnix := release.CreatedUnix time.Sleep(2 * time.Second) // sleep 2 seconds to ensure a different timestamp 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) assert.NoError(t, err) assert.Equal(t, int64(releaseCreatedUnix), int64(release.CreatedUnix)) @@ -153,7 +153,7 @@ func TestRelease_Update(t *testing.T) { releaseCreatedUnix = release.CreatedUnix time.Sleep(2 * time.Second) // sleep 2 seconds to ensure a different timestamp 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) assert.NoError(t, err) 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 release.Title = "Changed title" 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) assert.NoError(t, err) assert.Equal(t, int64(releaseCreatedUnix), int64(release.CreatedUnix)) diff --git a/templates/user/dashboard/feeds.tmpl b/templates/user/dashboard/feeds.tmpl index a67fe54849cdc..5e6d53e18aa58 100644 --- a/templates/user/dashboard/feeds.tmpl +++ b/templates/user/dashboard/feeds.tmpl @@ -70,6 +70,10 @@ {{else if eq .GetOpType 23}} {{ $index := index .GetIssueInfos 0}} {{$.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}}

{{if or (eq .GetOpType 5) (eq .GetOpType 18)}}