Nelze vybrat více než 25 témat Téma musí začínat písmenem nebo číslem, může obsahovat pomlčky („-“) a může být dlouhé až 35 znaků.

commit_status.go 3.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. // Copyright 2019 The Gitea Authors.
  2. // All rights reserved.
  3. // Use of this source code is governed by a MIT-style
  4. // license that can be found in the LICENSE file.
  5. package pull
  6. import (
  7. "code.gitea.io/gitea/models"
  8. "code.gitea.io/gitea/modules/git"
  9. "code.gitea.io/gitea/modules/structs"
  10. "github.com/pkg/errors"
  11. )
  12. // MergeRequiredContextsCommitStatus returns a commit status state for given required contexts
  13. func MergeRequiredContextsCommitStatus(commitStatuses []*models.CommitStatus, requiredContexts []string) structs.CommitStatusState {
  14. if len(requiredContexts) == 0 {
  15. status := models.CalcCommitStatus(commitStatuses)
  16. if status != nil {
  17. return status.State
  18. }
  19. return structs.CommitStatusSuccess
  20. }
  21. var returnedStatus = structs.CommitStatusSuccess
  22. for _, ctx := range requiredContexts {
  23. var targetStatus structs.CommitStatusState
  24. for _, commitStatus := range commitStatuses {
  25. if commitStatus.Context == ctx {
  26. targetStatus = commitStatus.State
  27. break
  28. }
  29. }
  30. if targetStatus == "" {
  31. targetStatus = structs.CommitStatusPending
  32. commitStatuses = append(commitStatuses, &models.CommitStatus{
  33. State: targetStatus,
  34. Context: ctx,
  35. Description: "Pending",
  36. })
  37. }
  38. if targetStatus.NoBetterThan(returnedStatus) {
  39. returnedStatus = targetStatus
  40. }
  41. }
  42. return returnedStatus
  43. }
  44. // IsCommitStatusContextSuccess returns true if all required status check contexts succeed.
  45. func IsCommitStatusContextSuccess(commitStatuses []*models.CommitStatus, requiredContexts []string) bool {
  46. // If no specific context is required, require that last commit status is a success
  47. if len(requiredContexts) == 0 {
  48. status := models.CalcCommitStatus(commitStatuses)
  49. if status == nil || status.State != structs.CommitStatusSuccess {
  50. return false
  51. }
  52. return true
  53. }
  54. for _, ctx := range requiredContexts {
  55. var found bool
  56. for _, commitStatus := range commitStatuses {
  57. if commitStatus.Context == ctx {
  58. if commitStatus.State != structs.CommitStatusSuccess {
  59. return false
  60. }
  61. found = true
  62. break
  63. }
  64. }
  65. if !found {
  66. return false
  67. }
  68. }
  69. return true
  70. }
  71. // IsPullCommitStatusPass returns if all required status checks PASS
  72. func IsPullCommitStatusPass(pr *models.PullRequest) (bool, error) {
  73. if err := pr.LoadProtectedBranch(); err != nil {
  74. return false, errors.Wrap(err, "GetLatestCommitStatus")
  75. }
  76. if pr.ProtectedBranch == nil || !pr.ProtectedBranch.EnableStatusCheck {
  77. return true, nil
  78. }
  79. state, err := GetPullRequestCommitStatusState(pr)
  80. if err != nil {
  81. return false, err
  82. }
  83. return state.IsSuccess(), nil
  84. }
  85. // GetPullRequestCommitStatusState returns pull request merged commit status state
  86. func GetPullRequestCommitStatusState(pr *models.PullRequest) (structs.CommitStatusState, error) {
  87. // Ensure HeadRepo is loaded
  88. if err := pr.LoadHeadRepo(); err != nil {
  89. return "", errors.Wrap(err, "LoadHeadRepo")
  90. }
  91. // check if all required status checks are successful
  92. headGitRepo, err := git.OpenRepository(pr.HeadRepo.RepoPath())
  93. if err != nil {
  94. return "", errors.Wrap(err, "OpenRepository")
  95. }
  96. defer headGitRepo.Close()
  97. if !headGitRepo.IsBranchExist(pr.HeadBranch) {
  98. return "", errors.New("Head branch does not exist, can not merge")
  99. }
  100. sha, err := headGitRepo.GetBranchCommitID(pr.HeadBranch)
  101. if err != nil {
  102. return "", errors.Wrap(err, "GetBranchCommitID")
  103. }
  104. if err := pr.LoadBaseRepo(); err != nil {
  105. return "", errors.Wrap(err, "LoadBaseRepo")
  106. }
  107. commitStatuses, err := models.GetLatestCommitStatus(pr.BaseRepo, sha, 0)
  108. if err != nil {
  109. return "", errors.Wrap(err, "GetLatestCommitStatus")
  110. }
  111. return MergeRequiredContextsCommitStatus(commitStatuses, pr.ProtectedBranch.StatusCheckContexts), nil
  112. }