Show commit status for releases (#29149)
Fixes #29082  (cherry picked from commit 7e8ff709401d09467c3eee7c69cd9600d26a97a3)
This commit is contained in:
		
					parent
					
						
							
								b1d66f50fb
							
						
					
				
			
			
				commit
				
					
						369fe56966
					
				
			
		
					 4 changed files with 184 additions and 181 deletions
				
			
		| 
						 | 
					@ -12,6 +12,7 @@ import (
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"code.gitea.io/gitea/models"
 | 
						"code.gitea.io/gitea/models"
 | 
				
			||||||
	"code.gitea.io/gitea/models/db"
 | 
						"code.gitea.io/gitea/models/db"
 | 
				
			||||||
 | 
						git_model "code.gitea.io/gitea/models/git"
 | 
				
			||||||
	repo_model "code.gitea.io/gitea/models/repo"
 | 
						repo_model "code.gitea.io/gitea/models/repo"
 | 
				
			||||||
	"code.gitea.io/gitea/models/unit"
 | 
						"code.gitea.io/gitea/models/unit"
 | 
				
			||||||
	user_model "code.gitea.io/gitea/models/user"
 | 
						user_model "code.gitea.io/gitea/models/user"
 | 
				
			||||||
| 
						 | 
					@ -67,6 +68,88 @@ func calReleaseNumCommitsBehind(repoCtx *context.Repository, release *repo_model
 | 
				
			||||||
	return nil
 | 
						return nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type ReleaseInfo struct {
 | 
				
			||||||
 | 
						Release        *repo_model.Release
 | 
				
			||||||
 | 
						CommitStatus   *git_model.CommitStatus
 | 
				
			||||||
 | 
						CommitStatuses []*git_model.CommitStatus
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func getReleaseInfos(ctx *context.Context, opts *repo_model.FindReleasesOptions) ([]*ReleaseInfo, error) {
 | 
				
			||||||
 | 
						releases, err := db.Find[repo_model.Release](ctx, opts)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return nil, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for _, release := range releases {
 | 
				
			||||||
 | 
							release.Repo = ctx.Repo.Repository
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if err = repo_model.GetReleaseAttachments(ctx, releases...); err != nil {
 | 
				
			||||||
 | 
							return nil, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Temporary cache commits count of used branches to speed up.
 | 
				
			||||||
 | 
						countCache := make(map[string]int64)
 | 
				
			||||||
 | 
						cacheUsers := make(map[int64]*user_model.User)
 | 
				
			||||||
 | 
						if ctx.Doer != nil {
 | 
				
			||||||
 | 
							cacheUsers[ctx.Doer.ID] = ctx.Doer
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						var ok bool
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						canReadActions := ctx.Repo.CanRead(unit.TypeActions)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						releaseInfos := make([]*ReleaseInfo, 0, len(releases))
 | 
				
			||||||
 | 
						for _, r := range releases {
 | 
				
			||||||
 | 
							if r.Publisher, ok = cacheUsers[r.PublisherID]; !ok {
 | 
				
			||||||
 | 
								r.Publisher, err = user_model.GetUserByID(ctx, r.PublisherID)
 | 
				
			||||||
 | 
								if err != nil {
 | 
				
			||||||
 | 
									if user_model.IsErrUserNotExist(err) {
 | 
				
			||||||
 | 
										r.Publisher = user_model.NewGhostUser()
 | 
				
			||||||
 | 
									} else {
 | 
				
			||||||
 | 
										return nil, err
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								cacheUsers[r.PublisherID] = r.Publisher
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							r.Note, err = markdown.RenderString(&markup.RenderContext{
 | 
				
			||||||
 | 
								Links: markup.Links{
 | 
				
			||||||
 | 
									Base: ctx.Repo.RepoLink,
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
								Metas:   ctx.Repo.Repository.ComposeMetas(ctx),
 | 
				
			||||||
 | 
								GitRepo: ctx.Repo.GitRepo,
 | 
				
			||||||
 | 
								Ctx:     ctx,
 | 
				
			||||||
 | 
							}, r.Note)
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								return nil, err
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if !r.IsDraft {
 | 
				
			||||||
 | 
								if err := calReleaseNumCommitsBehind(ctx.Repo, r, countCache); err != nil {
 | 
				
			||||||
 | 
									return nil, err
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							info := &ReleaseInfo{
 | 
				
			||||||
 | 
								Release: r,
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if canReadActions {
 | 
				
			||||||
 | 
								statuses, _, err := git_model.GetLatestCommitStatus(ctx, r.Repo.ID, r.Sha1, db.ListOptions{ListAll: true})
 | 
				
			||||||
 | 
								if err != nil {
 | 
				
			||||||
 | 
									return nil, err
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								info.CommitStatus = git_model.CalcCommitStatus(statuses)
 | 
				
			||||||
 | 
								info.CommitStatuses = statuses
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							releaseInfos = append(releaseInfos, info)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return releaseInfos, nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Releases render releases list page
 | 
					// Releases render releases list page
 | 
				
			||||||
func Releases(ctx *context.Context) {
 | 
					func Releases(ctx *context.Context) {
 | 
				
			||||||
	ctx.Data["PageIsReleaseList"] = true
 | 
						ctx.Data["PageIsReleaseList"] = true
 | 
				
			||||||
| 
						 | 
					@ -91,77 +174,21 @@ func Releases(ctx *context.Context) {
 | 
				
			||||||
	writeAccess := ctx.Repo.CanWrite(unit.TypeReleases)
 | 
						writeAccess := ctx.Repo.CanWrite(unit.TypeReleases)
 | 
				
			||||||
	ctx.Data["CanCreateRelease"] = writeAccess && !ctx.Repo.Repository.IsArchived
 | 
						ctx.Data["CanCreateRelease"] = writeAccess && !ctx.Repo.Repository.IsArchived
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	opts := repo_model.FindReleasesOptions{
 | 
						releases, err := getReleaseInfos(ctx, &repo_model.FindReleasesOptions{
 | 
				
			||||||
		ListOptions: listOptions,
 | 
							ListOptions: listOptions,
 | 
				
			||||||
		// only show draft releases for users who can write, read-only users shouldn't see draft releases.
 | 
							// only show draft releases for users who can write, read-only users shouldn't see draft releases.
 | 
				
			||||||
		IncludeDrafts: writeAccess,
 | 
							IncludeDrafts: writeAccess,
 | 
				
			||||||
		RepoID:        ctx.Repo.Repository.ID,
 | 
							RepoID:        ctx.Repo.Repository.ID,
 | 
				
			||||||
	}
 | 
						})
 | 
				
			||||||
 | 
					 | 
				
			||||||
	releases, err := db.Find[repo_model.Release](ctx, opts)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		ctx.ServerError("GetReleasesByRepoID", err)
 | 
							ctx.ServerError("getReleaseInfos", err)
 | 
				
			||||||
		return
 | 
							return
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	for _, release := range releases {
 | 
					 | 
				
			||||||
		release.Repo = ctx.Repo.Repository
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if err = repo_model.GetReleaseAttachments(ctx, releases...); err != nil {
 | 
					 | 
				
			||||||
		ctx.ServerError("GetReleaseAttachments", err)
 | 
					 | 
				
			||||||
		return
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// Temporary cache commits count of used branches to speed up.
 | 
					 | 
				
			||||||
	countCache := make(map[string]int64)
 | 
					 | 
				
			||||||
	cacheUsers := make(map[int64]*user_model.User)
 | 
					 | 
				
			||||||
	if ctx.Doer != nil {
 | 
					 | 
				
			||||||
		cacheUsers[ctx.Doer.ID] = ctx.Doer
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	var ok bool
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	for _, r := range releases {
 | 
					 | 
				
			||||||
		if r.Publisher, ok = cacheUsers[r.PublisherID]; !ok {
 | 
					 | 
				
			||||||
			r.Publisher, err = user_model.GetUserByID(ctx, r.PublisherID)
 | 
					 | 
				
			||||||
			if err != nil {
 | 
					 | 
				
			||||||
				if user_model.IsErrUserNotExist(err) {
 | 
					 | 
				
			||||||
					r.Publisher = user_model.NewGhostUser()
 | 
					 | 
				
			||||||
				} else {
 | 
					 | 
				
			||||||
					ctx.ServerError("GetUserByID", err)
 | 
					 | 
				
			||||||
					return
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			cacheUsers[r.PublisherID] = r.Publisher
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		r.Note, err = markdown.RenderString(&markup.RenderContext{
 | 
					 | 
				
			||||||
			Links: markup.Links{
 | 
					 | 
				
			||||||
				Base: ctx.Repo.RepoLink,
 | 
					 | 
				
			||||||
			},
 | 
					 | 
				
			||||||
			Metas:   ctx.Repo.Repository.ComposeMetas(ctx),
 | 
					 | 
				
			||||||
			GitRepo: ctx.Repo.GitRepo,
 | 
					 | 
				
			||||||
			Ctx:     ctx,
 | 
					 | 
				
			||||||
		}, r.Note)
 | 
					 | 
				
			||||||
		if err != nil {
 | 
					 | 
				
			||||||
			ctx.ServerError("RenderString", err)
 | 
					 | 
				
			||||||
			return
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		if r.IsDraft {
 | 
					 | 
				
			||||||
			continue
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		if err := calReleaseNumCommitsBehind(ctx.Repo, r, countCache); err != nil {
 | 
					 | 
				
			||||||
			ctx.ServerError("calReleaseNumCommitsBehind", err)
 | 
					 | 
				
			||||||
			return
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	ctx.Data["Releases"] = releases
 | 
						ctx.Data["Releases"] = releases
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	numReleases := ctx.Data["NumReleases"].(int64)
 | 
						numReleases := ctx.Data["NumReleases"].(int64)
 | 
				
			||||||
	pager := context.NewPagination(int(numReleases), opts.PageSize, opts.Page, 5)
 | 
						pager := context.NewPagination(int(numReleases), listOptions.PageSize, listOptions.Page, 5)
 | 
				
			||||||
	pager.SetDefaultParams(ctx)
 | 
						pager.SetDefaultParams(ctx)
 | 
				
			||||||
	ctx.Data["Page"] = pager
 | 
						ctx.Data["Page"] = pager
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -249,15 +276,24 @@ func SingleRelease(ctx *context.Context) {
 | 
				
			||||||
	writeAccess := ctx.Repo.CanWrite(unit.TypeReleases)
 | 
						writeAccess := ctx.Repo.CanWrite(unit.TypeReleases)
 | 
				
			||||||
	ctx.Data["CanCreateRelease"] = writeAccess && !ctx.Repo.Repository.IsArchived
 | 
						ctx.Data["CanCreateRelease"] = writeAccess && !ctx.Repo.Repository.IsArchived
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	release, err := repo_model.GetRelease(ctx, ctx.Repo.Repository.ID, ctx.Params("*"))
 | 
						releases, err := getReleaseInfos(ctx, &repo_model.FindReleasesOptions{
 | 
				
			||||||
 | 
							ListOptions: db.ListOptions{Page: 1, PageSize: 1},
 | 
				
			||||||
 | 
							RepoID:      ctx.Repo.Repository.ID,
 | 
				
			||||||
 | 
							TagNames:    []string{ctx.Params("*")},
 | 
				
			||||||
 | 
							// only show draft releases for users who can write, read-only users shouldn't see draft releases.
 | 
				
			||||||
 | 
							IncludeDrafts: writeAccess,
 | 
				
			||||||
 | 
						})
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		if repo_model.IsErrReleaseNotExist(err) {
 | 
							ctx.ServerError("getReleaseInfos", err)
 | 
				
			||||||
			ctx.NotFound("GetRelease", err)
 | 
					 | 
				
			||||||
		return
 | 
							return
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
		ctx.ServerError("GetReleasesByRepoID", err)
 | 
						if len(releases) != 1 {
 | 
				
			||||||
 | 
							ctx.NotFound("SingleRelease", err)
 | 
				
			||||||
		return
 | 
							return
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						release := releases[0].Release
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ctx.Data["PageIsSingleTag"] = release.IsTag
 | 
						ctx.Data["PageIsSingleTag"] = release.IsTag
 | 
				
			||||||
	if release.IsTag {
 | 
						if release.IsTag {
 | 
				
			||||||
		ctx.Data["Title"] = release.TagName
 | 
							ctx.Data["Title"] = release.TagName
 | 
				
			||||||
| 
						 | 
					@ -265,43 +301,7 @@ func SingleRelease(ctx *context.Context) {
 | 
				
			||||||
		ctx.Data["Title"] = release.Title
 | 
							ctx.Data["Title"] = release.Title
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	release.Repo = ctx.Repo.Repository
 | 
						ctx.Data["Releases"] = releases
 | 
				
			||||||
 | 
					 | 
				
			||||||
	err = repo_model.GetReleaseAttachments(ctx, release)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		ctx.ServerError("GetReleaseAttachments", err)
 | 
					 | 
				
			||||||
		return
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	release.Publisher, err = user_model.GetUserByID(ctx, release.PublisherID)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		if user_model.IsErrUserNotExist(err) {
 | 
					 | 
				
			||||||
			release.Publisher = user_model.NewGhostUser()
 | 
					 | 
				
			||||||
		} else {
 | 
					 | 
				
			||||||
			ctx.ServerError("GetUserByID", err)
 | 
					 | 
				
			||||||
			return
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if !release.IsDraft {
 | 
					 | 
				
			||||||
		if err := calReleaseNumCommitsBehind(ctx.Repo, release, make(map[string]int64)); err != nil {
 | 
					 | 
				
			||||||
			ctx.ServerError("calReleaseNumCommitsBehind", err)
 | 
					 | 
				
			||||||
			return
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	release.Note, err = markdown.RenderString(&markup.RenderContext{
 | 
					 | 
				
			||||||
		Links: markup.Links{
 | 
					 | 
				
			||||||
			Base: ctx.Repo.RepoLink,
 | 
					 | 
				
			||||||
		},
 | 
					 | 
				
			||||||
		Metas:   ctx.Repo.Repository.ComposeMetas(ctx),
 | 
					 | 
				
			||||||
		GitRepo: ctx.Repo.GitRepo,
 | 
					 | 
				
			||||||
		Ctx:     ctx,
 | 
					 | 
				
			||||||
	}, release.Note)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		ctx.ServerError("RenderString", err)
 | 
					 | 
				
			||||||
		return
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	ctx.Data["Releases"] = []*repo_model.Release{release}
 | 
					 | 
				
			||||||
	ctx.HTML(http.StatusOK, tplReleasesList)
 | 
						ctx.HTML(http.StatusOK, tplReleasesList)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -64,6 +64,9 @@ func createCommitStatus(ctx context.Context, job *actions_model.ActionRunJob) er
 | 
				
			||||||
			return fmt.Errorf("head of pull request is missing in event payload")
 | 
								return fmt.Errorf("head of pull request is missing in event payload")
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		sha = payload.PullRequest.Head.Sha
 | 
							sha = payload.PullRequest.Head.Sha
 | 
				
			||||||
 | 
						case webhook_module.HookEventRelease:
 | 
				
			||||||
 | 
							event = string(run.Event)
 | 
				
			||||||
 | 
							sha = run.CommitSHA
 | 
				
			||||||
	default:
 | 
						default:
 | 
				
			||||||
		return nil
 | 
							return nil
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,10 +1,10 @@
 | 
				
			||||||
{{if .Statuses}}
 | 
					{{if .Statuses}}
 | 
				
			||||||
	{{if and (eq (len .Statuses) 1) .Status.TargetURL}}
 | 
						{{if and (eq (len .Statuses) 1) .Status.TargetURL}}
 | 
				
			||||||
		<a class="gt-vm gt-no-underline" data-tippy="commit-statuses" href="{{.Status.TargetURL}}">
 | 
							<a class="gt-vm {{.AdditionalClasses}} gt-no-underline" data-tippy="commit-statuses" href="{{.Status.TargetURL}}">
 | 
				
			||||||
			{{template "repo/commit_status" .Status}}
 | 
								{{template "repo/commit_status" .Status}}
 | 
				
			||||||
		</a>
 | 
							</a>
 | 
				
			||||||
	{{else}}
 | 
						{{else}}
 | 
				
			||||||
		<span class="gt-vm" data-tippy="commit-statuses" tabindex="0">
 | 
							<span class="gt-vm {{.AdditionalClasses}}" data-tippy="commit-statuses" tabindex="0">
 | 
				
			||||||
			{{template "repo/commit_status" .Status}}
 | 
								{{template "repo/commit_status" .Status}}
 | 
				
			||||||
		</span>
 | 
							</span>
 | 
				
			||||||
	{{end}}
 | 
						{{end}}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -5,22 +5,24 @@
 | 
				
			||||||
		{{template "base/alert" .}}
 | 
							{{template "base/alert" .}}
 | 
				
			||||||
		{{template "repo/release_tag_header" .}}
 | 
							{{template "repo/release_tag_header" .}}
 | 
				
			||||||
		<ul id="release-list">
 | 
							<ul id="release-list">
 | 
				
			||||||
			{{range $idx, $release := .Releases}}
 | 
								{{range $idx, $info := .Releases}}
 | 
				
			||||||
 | 
									{{$release := $info.Release}}
 | 
				
			||||||
				<li class="ui grid">
 | 
									<li class="ui grid">
 | 
				
			||||||
					<div class="ui four wide column meta">
 | 
										<div class="ui four wide column meta">
 | 
				
			||||||
							<a class="muted" href="{{if not (and .Sha1 ($.Permission.CanRead $.UnitTypeCode))}}#{{else}}{{$.RepoLink}}/src/tag/{{.TagName | PathEscapeSegments}}{{end}}" rel="nofollow">{{svg "octicon-tag" 16 "gt-mr-2"}}{{.TagName}}</a>
 | 
											<a class="muted" href="{{if not (and $release.Sha1 ($.Permission.CanRead $.UnitTypeCode))}}#{{else}}{{$.RepoLink}}/src/tag/{{$release.TagName | PathEscapeSegments}}{{end}}" rel="nofollow">{{svg "octicon-tag" 16 "gt-mr-2"}}{{$release.TagName}}</a>
 | 
				
			||||||
							{{if and .Sha1 ($.Permission.CanRead $.UnitTypeCode)}}
 | 
											{{if and $release.Sha1 ($.Permission.CanRead $.UnitTypeCode)}}
 | 
				
			||||||
								<a class="muted gt-mono" href="{{$.RepoLink}}/src/commit/{{.Sha1}}" rel="nofollow">{{svg "octicon-git-commit" 16 "gt-mr-2"}}{{ShortSha .Sha1}}</a>
 | 
												<a class="muted gt-mono" href="{{$.RepoLink}}/src/commit/{{$release.Sha1}}" rel="nofollow">{{svg "octicon-git-commit" 16 "gt-mr-2"}}{{ShortSha $release.Sha1}}</a>
 | 
				
			||||||
								{{template "repo/branch_dropdown" dict "root" $ "release" .}}
 | 
												{{template "repo/branch_dropdown" dict "root" $ "release" $release}}
 | 
				
			||||||
						{{end}}
 | 
											{{end}}
 | 
				
			||||||
					</div>
 | 
										</div>
 | 
				
			||||||
					<div class="ui twelve wide column detail">
 | 
										<div class="ui twelve wide column detail">
 | 
				
			||||||
						<div class="gt-df gt-ac gt-sb gt-fw gt-mb-3">
 | 
											<div class="gt-df gt-ac gt-sb gt-fw gt-mb-3">
 | 
				
			||||||
							<h4 class="release-list-title gt-word-break">
 | 
												<h4 class="release-list-title gt-word-break">
 | 
				
			||||||
									<a href="{{$.RepoLink}}/releases/tag/{{.TagName | PathEscapeSegments}}">{{.Title}}</a>
 | 
													<a href="{{$.RepoLink}}/releases/tag/{{$release.TagName | PathEscapeSegments}}">{{$release.Title}}</a>
 | 
				
			||||||
									{{if .IsDraft}}
 | 
													{{template "repo/commit_statuses" dict "Status" $info.CommitStatus "Statuses" $info.CommitStatuses "AdditionalClasses" "gt-df"}}
 | 
				
			||||||
 | 
													{{if $release.IsDraft}}
 | 
				
			||||||
									<span class="ui yellow label">{{ctx.Locale.Tr "repo.release.draft"}}</span>
 | 
														<span class="ui yellow label">{{ctx.Locale.Tr "repo.release.draft"}}</span>
 | 
				
			||||||
									{{else if .IsPrerelease}}
 | 
													{{else if $release.IsPrerelease}}
 | 
				
			||||||
									<span class="ui orange label">{{ctx.Locale.Tr "repo.release.prerelease"}}</span>
 | 
														<span class="ui orange label">{{ctx.Locale.Tr "repo.release.prerelease"}}</span>
 | 
				
			||||||
								{{else}}
 | 
													{{else}}
 | 
				
			||||||
									<span class="ui green label">{{ctx.Locale.Tr "repo.release.stable"}}</span>
 | 
														<span class="ui green label">{{ctx.Locale.Tr "repo.release.stable"}}</span>
 | 
				
			||||||
| 
						 | 
					@ -28,7 +30,7 @@
 | 
				
			||||||
							</h4>
 | 
												</h4>
 | 
				
			||||||
							<div>
 | 
												<div>
 | 
				
			||||||
								{{if $.CanCreateRelease}}
 | 
													{{if $.CanCreateRelease}}
 | 
				
			||||||
										<a class="muted" data-tooltip-content="{{ctx.Locale.Tr "repo.release.edit"}}" href="{{$.RepoLink}}/releases/edit/{{.TagName | PathEscapeSegments}}" rel="nofollow">
 | 
														<a class="muted" data-tooltip-content="{{ctx.Locale.Tr "repo.release.edit"}}" href="{{$.RepoLink}}/releases/edit/{{$release.TagName | PathEscapeSegments}}" rel="nofollow">
 | 
				
			||||||
										{{svg "octicon-pencil"}}
 | 
															{{svg "octicon-pencil"}}
 | 
				
			||||||
									</a>
 | 
														</a>
 | 
				
			||||||
								{{end}}
 | 
													{{end}}
 | 
				
			||||||
| 
						 | 
					@ -36,11 +38,11 @@
 | 
				
			||||||
						</div>
 | 
											</div>
 | 
				
			||||||
						<p class="text grey">
 | 
											<p class="text grey">
 | 
				
			||||||
							<span class="author">
 | 
												<span class="author">
 | 
				
			||||||
								{{if .OriginalAuthor}}
 | 
												{{if $release.OriginalAuthor}}
 | 
				
			||||||
									{{svg (MigrationIcon .Repo.GetOriginalURLHostname) 20 "gt-mr-2"}}{{.OriginalAuthor}}
 | 
													{{svg (MigrationIcon $release.Repo.GetOriginalURLHostname) 20 "gt-mr-2"}}{{$release.OriginalAuthor}}
 | 
				
			||||||
								{{else if .Publisher}}
 | 
												{{else if $release.Publisher}}
 | 
				
			||||||
									{{ctx.AvatarUtils.Avatar .Publisher 20 "gt-mr-2"}}
 | 
													{{ctx.AvatarUtils.Avatar $release.Publisher 20 "gt-mr-2"}}
 | 
				
			||||||
									<a href="{{.Publisher.HomeLink}}">{{.Publisher.GetDisplayName}}</a>
 | 
													<a href="{{$release.Publisher.HomeLink}}">{{$release.Publisher.GetDisplayName}}</a>
 | 
				
			||||||
							{{else}}
 | 
												{{else}}
 | 
				
			||||||
								Ghost
 | 
													Ghost
 | 
				
			||||||
							{{end}}
 | 
												{{end}}
 | 
				
			||||||
| 
						 | 
					@ -48,15 +50,15 @@
 | 
				
			||||||
							<span class="released">
 | 
												<span class="released">
 | 
				
			||||||
								{{ctx.Locale.Tr "repo.released_this"}}
 | 
													{{ctx.Locale.Tr "repo.released_this"}}
 | 
				
			||||||
							</span>
 | 
												</span>
 | 
				
			||||||
								{{if .CreatedUnix}}
 | 
												{{if $release.CreatedUnix}}
 | 
				
			||||||
									<span class="time">{{TimeSinceUnix .CreatedUnix ctx.Locale}}</span>
 | 
													<span class="time">{{TimeSinceUnix $release.CreatedUnix ctx.Locale}}</span>
 | 
				
			||||||
							{{end}}
 | 
												{{end}}
 | 
				
			||||||
								{{if and (not .IsDraft) ($.Permission.CanRead $.UnitTypeCode)}}
 | 
												{{if and (not $release.IsDraft) ($.Permission.CanRead $.UnitTypeCode)}}
 | 
				
			||||||
									| <span class="ahead"><a href="{{$.RepoLink}}/compare/{{.TagName | PathEscapeSegments}}...{{.TargetBehind | PathEscapeSegments}}">{{ctx.Locale.Tr "repo.release.ahead.commits" .NumCommitsBehind | Str2html}}</a> {{ctx.Locale.Tr "repo.release.ahead.target" .TargetBehind}}</span>
 | 
													| <span class="ahead"><a href="{{$.RepoLink}}/compare/{{$release.TagName | PathEscapeSegments}}...{{$release.TargetBehind | PathEscapeSegments}}">{{ctx.Locale.Tr "repo.release.ahead.commits" $release.NumCommitsBehind | Str2html}}</a> {{ctx.Locale.Tr "repo.release.ahead.target" $release.TargetBehind}}</span>
 | 
				
			||||||
							{{end}}
 | 
												{{end}}
 | 
				
			||||||
						</p>
 | 
											</p>
 | 
				
			||||||
						<div class="markup desc">
 | 
											<div class="markup desc">
 | 
				
			||||||
								{{Str2html .Note}}
 | 
												{{Str2html $release.Note}}
 | 
				
			||||||
						</div>
 | 
											</div>
 | 
				
			||||||
						<div class="divider"></div>
 | 
											<div class="divider"></div>
 | 
				
			||||||
						<details class="download" {{if eq $idx 0}}open{{end}}>
 | 
											<details class="download" {{if eq $idx 0}}open{{end}}>
 | 
				
			||||||
| 
						 | 
					@ -64,16 +66,15 @@
 | 
				
			||||||
								{{ctx.Locale.Tr "repo.release.downloads"}}
 | 
													{{ctx.Locale.Tr "repo.release.downloads"}}
 | 
				
			||||||
							</summary>
 | 
												</summary>
 | 
				
			||||||
							<ul class="list">
 | 
												<ul class="list">
 | 
				
			||||||
									{{if and (not $.DisableDownloadSourceArchives) (not .IsDraft) ($.Permission.CanRead $.UnitTypeCode)}}
 | 
													{{if and (not $.DisableDownloadSourceArchives) (not $release.IsDraft) ($.Permission.CanRead $.UnitTypeCode)}}
 | 
				
			||||||
									<li>
 | 
														<li>
 | 
				
			||||||
											<a class="archive-link" href="{{$.RepoLink}}/archive/{{.TagName | PathEscapeSegments}}.zip" rel="nofollow"><strong>{{svg "octicon-file-zip" 16 "gt-mr-2"}}{{ctx.Locale.Tr "repo.release.source_code"}} (ZIP)</strong></a>
 | 
															<a class="archive-link" href="{{$.RepoLink}}/archive/{{$release.TagName | PathEscapeSegments}}.zip" rel="nofollow"><strong>{{svg "octicon-file-zip" 16 "gt-mr-2"}}{{ctx.Locale.Tr "repo.release.source_code"}} (ZIP)</strong></a>
 | 
				
			||||||
									</li>
 | 
														</li>
 | 
				
			||||||
									<li>
 | 
														<li>
 | 
				
			||||||
											<a class="archive-link" href="{{$.RepoLink}}/archive/{{.TagName | PathEscapeSegments}}.tar.gz" rel="nofollow"><strong>{{svg "octicon-file-zip" 16 "gt-mr-2"}}{{ctx.Locale.Tr "repo.release.source_code"}} (TAR.GZ)</strong></a>
 | 
															<a class="archive-link" href="{{$.RepoLink}}/archive/{{$release.TagName | PathEscapeSegments}}.tar.gz" rel="nofollow"><strong>{{svg "octicon-file-zip" 16 "gt-mr-2"}}{{ctx.Locale.Tr "repo.release.source_code"}} (TAR.GZ)</strong></a>
 | 
				
			||||||
									</li>
 | 
														</li>
 | 
				
			||||||
								{{end}}
 | 
													{{end}}
 | 
				
			||||||
									{{if .Attachments}}
 | 
													{{range $release.Attachments}}
 | 
				
			||||||
										{{range .Attachments}}
 | 
					 | 
				
			||||||
									<li>
 | 
														<li>
 | 
				
			||||||
										<a target="_blank" rel="nofollow" href="{{.DownloadURL}}" download>
 | 
															<a target="_blank" rel="nofollow" href="{{.DownloadURL}}" download>
 | 
				
			||||||
											<strong>{{svg "octicon-package" 16 "gt-mr-2"}}{{.Name}}</strong>
 | 
																<strong>{{svg "octicon-package" 16 "gt-mr-2"}}{{.Name}}</strong>
 | 
				
			||||||
| 
						 | 
					@ -86,7 +87,6 @@
 | 
				
			||||||
										</div>
 | 
															</div>
 | 
				
			||||||
									</li>
 | 
														</li>
 | 
				
			||||||
								{{end}}
 | 
													{{end}}
 | 
				
			||||||
									{{end}}
 | 
					 | 
				
			||||||
							</ul>
 | 
												</ul>
 | 
				
			||||||
						</details>
 | 
											</details>
 | 
				
			||||||
						<div class="dot"></div>
 | 
											<div class="dot"></div>
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue