mirror of
https://github.com/go-gitea/gitea.git
synced 2026-11-01 13:28:14 +00:00
Backport #39930 by @lunny Pages showing commit statuses loaded the repository of every status separately, so a PR with ~75 statuses ran ~75 identical repository queries per merge box render (about 3.4s in a production trace). `statusRepoCanReadActions` only loaded the repository inside the permission cache loader, which never runs once `RepoAssignment` has published the permission. - `CommitStatus.loadRepository` resolves through the request context cache - `statusRepoCanReadActions` loads the repository before the permission lookup - `RepoAssignment` publishes its repository to the context cache next to the permission - `GetCommitActionsStatusMap` drops its own repository map Queries per request with 50 statuses (45 Actions, 5 external) on the head commit, SQLite: | Page | Repository queries | Total queries | |---|---|---| | PR view | 61 → 11 | 157 → 107 | | Commit | 6 → 5 | 24 → 23 | | Branches | 6 → 5 | 33 → 32 | | Commits | 6 → 5 | 23 → 22 | | Repo home | 8 → 7 | 35 → 34 | | `/pulls` | 15 → 15 | 37 → 37 | Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com> Co-authored-by: silverwind <me@silverwind.io>
62 lines
1.8 KiB
Go
62 lines
1.8 KiB
Go
// Copyright 2026 The Gitea Authors. All rights reserved.
|
|
// SPDX-License-Identifier: MIT
|
|
|
|
package actions
|
|
|
|
import (
|
|
"context"
|
|
"maps"
|
|
"slices"
|
|
|
|
actions_model "gitea.dev/models/actions"
|
|
"gitea.dev/models/db"
|
|
git_model "gitea.dev/models/git"
|
|
"gitea.dev/modules/log"
|
|
)
|
|
|
|
// CommitActionsStatusMap maps CommitStatus.ID to the live ActionRunJob status
|
|
// for Gitea Actions rows.
|
|
type CommitActionsStatusMap map[int64]actions_model.Status
|
|
|
|
// IconStatus returns the action status name to route the icon through
|
|
// repo/icons/action_status, or "" when the row isn't from Gitea Actions.
|
|
func (m CommitActionsStatusMap) IconStatus(s *git_model.CommitStatus) string {
|
|
if status, ok := m[s.ID]; ok {
|
|
return status.String()
|
|
}
|
|
return ""
|
|
}
|
|
|
|
// GetCommitActionsStatusMap resolves the live ActionRunJob.Status for every
|
|
// CommitStatus row backed by Gitea Actions. Rows from other sources (external
|
|
// CIs, API) are left untouched and rendered from their stored State.
|
|
func GetCommitActionsStatusMap(ctx context.Context, statuses []*git_model.CommitStatus) CommitActionsStatusMap {
|
|
if len(statuses) == 0 {
|
|
return nil
|
|
}
|
|
statusByJobID := make(map[int64]*git_model.CommitStatus)
|
|
for _, status := range statuses {
|
|
if status == nil || status.TargetURL == "" {
|
|
continue
|
|
}
|
|
if _, jobID, ok := status.ParseGiteaActionsTargetURL(ctx); ok {
|
|
statusByJobID[jobID] = status
|
|
}
|
|
}
|
|
if len(statusByJobID) == 0 {
|
|
return nil
|
|
}
|
|
jobs := make(map[int64]*actions_model.ActionRunJob, len(statusByJobID))
|
|
if err := db.GetEngine(ctx).In("id", slices.Collect(maps.Keys(statusByJobID))).Cols("id", "status").Find(&jobs); err != nil {
|
|
log.Error("db.Find: failed to find action run jobs: %v", err)
|
|
return nil
|
|
}
|
|
info := make(CommitActionsStatusMap, len(jobs))
|
|
for jobID, status := range statusByJobID {
|
|
if job, ok := jobs[jobID]; ok {
|
|
info[status.ID] = job.Status
|
|
}
|
|
}
|
|
return info
|
|
}
|