From a08b48454970a0639039b730cbe616686e82bc0f Mon Sep 17 00:00:00 2001
From: Jason Song <i@wolfogre.com>
Date: Mon, 3 Oct 2022 20:05:53 +0800
Subject: [PATCH] Tag list should include draft releases with existing tags
 (#21263)

Before, a tag for a draft release disappeared in the tag list, fix #21262.

Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
---
 models/repo/release.go           |  8 ++++++++
 modules/context/repo.go          |  4 +++-
 routers/web/repo/release.go      | 14 +++++++++++---
 templates/repo/release/list.tmpl |  6 ++----
 4 files changed, 24 insertions(+), 8 deletions(-)

diff --git a/models/repo/release.go b/models/repo/release.go
index 9a4de26c68..2b484c9b84 100644
--- a/models/repo/release.go
+++ b/models/repo/release.go
@@ -200,6 +200,7 @@ type FindReleasesOptions struct {
 	IsPreRelease  util.OptionalBool
 	IsDraft       util.OptionalBool
 	TagNames      []string
+	HasSha1       util.OptionalBool // useful to find draft releases which are created with existing tags
 }
 
 func (opts *FindReleasesOptions) toConds(repoID int64) builder.Cond {
@@ -221,6 +222,13 @@ func (opts *FindReleasesOptions) toConds(repoID int64) builder.Cond {
 	if !opts.IsDraft.IsNone() {
 		cond = cond.And(builder.Eq{"is_draft": opts.IsDraft.IsTrue()})
 	}
+	if !opts.HasSha1.IsNone() {
+		if opts.HasSha1.IsTrue() {
+			cond = cond.And(builder.Neq{"sha1": ""})
+		} else {
+			cond = cond.And(builder.Eq{"sha1": ""})
+		}
+	}
 	return cond
 }
 
diff --git a/modules/context/repo.go b/modules/context/repo.go
index 6a336c45f7..1742683d3c 100644
--- a/modules/context/repo.go
+++ b/modules/context/repo.go
@@ -524,7 +524,9 @@ func RepoAssignment(ctx *Context) (cancel context.CancelFunc) {
 	}
 
 	ctx.Data["NumTags"], err = repo_model.GetReleaseCountByRepoID(ctx.Repo.Repository.ID, repo_model.FindReleasesOptions{
-		IncludeTags: true,
+		IncludeDrafts: true,
+		IncludeTags:   true,
+		HasSha1:       util.OptionalBoolTrue, // only draft releases which are created with existing tags
 	})
 	if err != nil {
 		ctx.ServerError("GetReleaseCountByRepoID", err)
diff --git a/routers/web/repo/release.go b/routers/web/repo/release.go
index 935813051a..1e5710fa98 100644
--- a/routers/web/repo/release.go
+++ b/routers/web/repo/release.go
@@ -117,9 +117,17 @@ func releasesOrTags(ctx *context.Context, isTagList bool) {
 	ctx.Data["CanCreateRelease"] = writeAccess && !ctx.Repo.Repository.IsArchived
 
 	opts := repo_model.FindReleasesOptions{
-		ListOptions:   listOptions,
-		IncludeDrafts: writeAccess && !isTagList,
-		IncludeTags:   isTagList,
+		ListOptions: listOptions,
+	}
+	if isTagList {
+		// for the tags list page, show all releases with real tags (having real commit-id),
+		// the drafts should also be included because a real tag might be used as a draft.
+		opts.IncludeDrafts = true
+		opts.IncludeTags = true
+		opts.HasSha1 = util.OptionalBoolTrue
+	} else {
+		// only show draft releases for users who can write, read-only users shouldn't see draft releases.
+		opts.IncludeDrafts = writeAccess
 	}
 
 	releases, err := repo_model.GetReleasesByRepoID(ctx.Repo.Repository.ID, opts)
diff --git a/templates/repo/release/list.tmpl b/templates/repo/release/list.tmpl
index d87d51f26c..6abb240cc3 100644
--- a/templates/repo/release/list.tmpl
+++ b/templates/repo/release/list.tmpl
@@ -77,14 +77,12 @@
 								<span class="ui green label">{{$.locale.Tr "repo.release.stable"}}</span>
 							{{end}}
 							<span class="tag text blue">
-								<a class="df ac je" href="{{if .IsDraft}}#{{else}}{{$.RepoLink}}/src/tag/{{.TagName | PathEscapeSegments}}{{end}}" rel="nofollow">{{svg "octicon-tag" 16 "mr-2"}}{{.TagName}}</a>
+								<a class="df ac je" href="{{if not .Sha1}}#{{else}}{{$.RepoLink}}/src/tag/{{.TagName | PathEscapeSegments}}{{end}}" rel="nofollow">{{svg "octicon-tag" 16 "mr-2"}}{{.TagName}}</a>
 							</span>
-							{{if not .IsDraft}}
+							{{if .Sha1}}
 								<span class="commit">
 									<a class="mono" href="{{$.RepoLink}}/src/commit/{{.Sha1}}" rel="nofollow">{{svg "octicon-git-commit" 16 "mr-2"}}{{ShortSha .Sha1}}</a>
 								</span>
-							{{end}}
-							{{if .Sha1}}
 								{{template "repo/branch_dropdown" dict "root" $ "release" .}}
 							{{end}}
 						{{end}}