loading up the forgejo repo on tangled to test page performance
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

Display branch commit status (#25608)

Fix #10388

This PR adds a status icon for every branch which has a status check for
the latest commit on branch list page.

<img width="1313" alt="图片"
src="https://github.com/go-gitea/gitea/assets/81045/727cd540-d03a-40c6-a7dd-e87c118af0ac">

authored by

Lunny Xiao and committed by
GitHub
7735da1c 5b79eeab

+67
+47
models/git/commit_status.go
··· 346 346 return repoStatuses, nil 347 347 } 348 348 349 + // GetLatestCommitStatusForRepoCommitIDs returns all statuses with a unique context for a given list of repo-sha pairs 350 + func GetLatestCommitStatusForRepoCommitIDs(ctx context.Context, repoID int64, commitIDs []string) (map[string][]*CommitStatus, error) { 351 + type result struct { 352 + ID int64 353 + Sha string 354 + } 355 + 356 + results := make([]result, 0, len(commitIDs)) 357 + 358 + sess := db.GetEngine(ctx).Table(&CommitStatus{}) 359 + 360 + // Create a disjunction of conditions for each repoID and SHA pair 361 + conds := make([]builder.Cond, 0, len(commitIDs)) 362 + for _, sha := range commitIDs { 363 + conds = append(conds, builder.Eq{"sha": sha}) 364 + } 365 + sess = sess.Where(builder.Eq{"repo_id": repoID}.And(builder.Or(conds...))). 366 + Select("max( id ) as id, sha"). 367 + GroupBy("context_hash, sha").OrderBy("max( id ) desc") 368 + 369 + err := sess.Find(&results) 370 + if err != nil { 371 + return nil, err 372 + } 373 + 374 + ids := make([]int64, 0, len(results)) 375 + repoStatuses := make(map[string][]*CommitStatus) 376 + for _, result := range results { 377 + ids = append(ids, result.ID) 378 + } 379 + 380 + statuses := make([]*CommitStatus, 0, len(ids)) 381 + if len(ids) > 0 { 382 + err = db.GetEngine(ctx).In("id", ids).Find(&statuses) 383 + if err != nil { 384 + return nil, err 385 + } 386 + 387 + // Group the statuses by repo ID 388 + for _, status := range statuses { 389 + repoStatuses[status.SHA] = append(repoStatuses[status.SHA], status) 390 + } 391 + } 392 + 393 + return repoStatuses, nil 394 + } 395 + 349 396 // FindRepoRecentCommitStatusContexts returns repository's recent commit status contexts 350 397 func FindRepoRecentCommitStatusContexts(ctx context.Context, repoID int64, before time.Duration) ([]string, error) { 351 398 start := timeutil.TimeStampNow().AddDuration(-before)
+18
routers/web/repo/branch.go
··· 57 57 return 58 58 } 59 59 60 + commitIDs := []string{defaultBranch.DBBranch.CommitID} 61 + for _, branch := range branches { 62 + commitIDs = append(commitIDs, branch.DBBranch.CommitID) 63 + } 64 + 65 + commitStatuses, err := git_model.GetLatestCommitStatusForRepoCommitIDs(ctx, ctx.Repo.Repository.ID, commitIDs) 66 + if err != nil { 67 + ctx.ServerError("LoadBranches", err) 68 + return 69 + } 70 + 71 + commitStatus := make(map[string]*git_model.CommitStatus) 72 + for commitID, cs := range commitStatuses { 73 + commitStatus[commitID] = git_model.CalcCommitStatus(cs) 74 + } 75 + 60 76 ctx.Data["Branches"] = branches 77 + ctx.Data["CommitStatus"] = commitStatus 78 + ctx.Data["CommitStatuses"] = commitStatuses 61 79 ctx.Data["DefaultBranchBranch"] = defaultBranch 62 80 pager := context.NewPagination(int(branchesCount), pageSize, page, 5) 63 81 pager.SetDefaultParams(ctx)
+2
templates/repo/branch/list.tmpl
··· 25 25 <div class="gt-df gt-ac"> 26 26 <a class="gt-ellipsis" href="{{.RepoLink}}/src/branch/{{PathEscapeSegments .DefaultBranchBranch.DBBranch.Name}}">{{.DefaultBranchBranch.DBBranch.Name}}</a> 27 27 <button class="btn interact-fg gt-p-3" data-clipboard-text="{{.DefaultBranchBranch.DBBranch.Name}}">{{svg "octicon-copy" 14}}</button> 28 + {{template "repo/commit_statuses" dict "Status" (index $.CommitStatus .DefaultBranchBranch.DBBranch.CommitID) "Statuses" (index $.CommitStatuses .DefaultBranchBranch.DBBranch.CommitID)}} 28 29 </div> 29 30 <p class="info gt-df gt-ac gt-my-2">{{svg "octicon-git-commit" 16 "gt-mr-2"}}<a href="{{.RepoLink}}/commit/{{PathEscape .DefaultBranchBranch.DBBranch.CommitID}}">{{ShortSha .DefaultBranchBranch.DBBranch.CommitID}}</a> · <span class="commit-message">{{RenderCommitMessage $.Context .DefaultBranchBranch.DBBranch.CommitMessage .RepoLink .Repository.ComposeMetas}}</span> · {{.locale.Tr "org.repo_updated"}} {{TimeSince .DefaultBranchBranch.DBBranch.CommitTime.AsTime .locale}}{{if .DefaultBranchBranch.DBBranch.Pusher}} &nbsp;{{template "shared/user/avatarlink" dict "Context" $.Context "user" .DefaultBranchBranch.DBBranch.Pusher}}{{template "shared/user/namelink" .DefaultBranchBranch.DBBranch.Pusher}}{{end}}</p> 30 31 </td> ··· 91 92 <div class="gt-df gt-ac"> 92 93 <a class="gt-ellipsis" href="{{$.RepoLink}}/src/branch/{{PathEscapeSegments .DBBranch.Name}}">{{.DBBranch.Name}}</a> 93 94 <button class="btn interact-fg gt-p-3" data-clipboard-text="{{.DBBranch.Name}}">{{svg "octicon-copy" 14}}</button> 95 + {{template "repo/commit_statuses" dict "Status" (index $.CommitStatus .DBBranch.CommitID) "Statuses" (index $.CommitStatuses .DBBranch.CommitID)}} 94 96 </div> 95 97 <p class="info gt-df gt-ac gt-my-2">{{svg "octicon-git-commit" 16 "gt-mr-2"}}<a href="{{$.RepoLink}}/commit/{{PathEscape .DBBranch.CommitID}}">{{ShortSha .DBBranch.CommitID}}</a> · <span class="commit-message">{{RenderCommitMessage $.Context .DBBranch.CommitMessage $.RepoLink $.Repository.ComposeMetas}}</span> · {{$.locale.Tr "org.repo_updated"}} {{TimeSince .DBBranch.CommitTime.AsTime $.locale}}{{if .DBBranch.Pusher}} &nbsp;{{template "shared/user/avatarlink" dict "Context" $.Context "user" .DBBranch.Pusher}} &nbsp;{{template "shared/user/namelink" .DBBranch.Pusher}}{{end}}</p> 96 98 {{end}}