gitea源码

commit_status_summary.go 2.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. // Copyright 2024 Gitea. All rights reserved.
  2. // SPDX-License-Identifier: MIT
  3. package git
  4. import (
  5. "context"
  6. "code.gitea.io/gitea/models/db"
  7. "code.gitea.io/gitea/modules/commitstatus"
  8. "code.gitea.io/gitea/modules/setting"
  9. "xorm.io/builder"
  10. )
  11. // CommitStatusSummary holds the latest commit Status of a single Commit
  12. type CommitStatusSummary struct {
  13. ID int64 `xorm:"pk autoincr"`
  14. RepoID int64 `xorm:"INDEX UNIQUE(repo_id_sha)"`
  15. SHA string `xorm:"VARCHAR(64) NOT NULL INDEX UNIQUE(repo_id_sha)"`
  16. State commitstatus.CommitStatusState `xorm:"VARCHAR(7) NOT NULL"`
  17. TargetURL string `xorm:"TEXT"`
  18. }
  19. func init() {
  20. db.RegisterModel(new(CommitStatusSummary))
  21. }
  22. type RepoSHA struct {
  23. RepoID int64
  24. SHA string
  25. }
  26. func GetLatestCommitStatusForRepoAndSHAs(ctx context.Context, repoSHAs []RepoSHA) ([]*CommitStatus, error) {
  27. cond := builder.NewCond()
  28. for _, rs := range repoSHAs {
  29. cond = cond.Or(builder.Eq{"repo_id": rs.RepoID, "sha": rs.SHA})
  30. }
  31. var summaries []CommitStatusSummary
  32. if err := db.GetEngine(ctx).Where(cond).Find(&summaries); err != nil {
  33. return nil, err
  34. }
  35. commitStatuses := make([]*CommitStatus, 0, len(repoSHAs))
  36. for _, summary := range summaries {
  37. commitStatuses = append(commitStatuses, &CommitStatus{
  38. RepoID: summary.RepoID,
  39. SHA: summary.SHA,
  40. State: summary.State,
  41. TargetURL: summary.TargetURL,
  42. })
  43. }
  44. return commitStatuses, nil
  45. }
  46. func UpdateCommitStatusSummary(ctx context.Context, repoID int64, sha string) error {
  47. commitStatuses, err := GetLatestCommitStatus(ctx, repoID, sha, db.ListOptionsAll)
  48. if err != nil {
  49. return err
  50. }
  51. // it guarantees that commitStatuses is not empty because this function is always called after a commit status is created
  52. if len(commitStatuses) == 0 {
  53. setting.PanicInDevOrTesting("no commit statuses found for repo %d and sha %s", repoID, sha)
  54. }
  55. state := CalcCommitStatus(commitStatuses) // non-empty commitStatuses is guaranteed
  56. // mysql will return 0 when update a record which state hasn't been changed which behaviour is different from other database,
  57. // so we need to use insert in on duplicate
  58. if setting.Database.Type.IsMySQL() {
  59. _, err := db.GetEngine(ctx).Exec("INSERT INTO commit_status_summary (repo_id,sha,state,target_url) VALUES (?,?,?,?) ON DUPLICATE KEY UPDATE state=?",
  60. repoID, sha, state.State, state.TargetURL, state.State)
  61. return err
  62. }
  63. if cnt, err := db.GetEngine(ctx).Where("repo_id=? AND sha=?", repoID, sha).
  64. Cols("state, target_url").
  65. Update(&CommitStatusSummary{
  66. State: state.State,
  67. TargetURL: state.TargetURL,
  68. }); err != nil {
  69. return err
  70. } else if cnt == 0 {
  71. _, err = db.GetEngine(ctx).Insert(&CommitStatusSummary{
  72. RepoID: repoID,
  73. SHA: sha,
  74. State: state.State,
  75. TargetURL: state.TargetURL,
  76. })
  77. return err
  78. }
  79. return nil
  80. }