You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

hook.go 4.7 kB

3 years ago
3 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  1. // Copyright 2019 The Gitea Authors. All rights reserved.
  2. // Use of this source code is governed by a MIT-style
  3. // license that can be found in the LICENSE file.
  4. package private
  5. import (
  6. "encoding/json"
  7. "fmt"
  8. "net/http"
  9. "net/url"
  10. "time"
  11. "code.gitea.io/gitea/modules/setting"
  12. )
  13. // Git environment variables
  14. const (
  15. GitAlternativeObjectDirectories = "GIT_ALTERNATE_OBJECT_DIRECTORIES"
  16. GitObjectDirectory = "GIT_OBJECT_DIRECTORY"
  17. GitQuarantinePath = "GIT_QUARANTINE_PATH"
  18. )
  19. // HookOptions represents the options for the Hook calls
  20. type HookOptions struct {
  21. OldCommitIDs []string
  22. NewCommitIDs []string
  23. RefFullNames []string
  24. UserID int64
  25. UserName string
  26. GitObjectDirectory string
  27. GitAlternativeObjectDirectories string
  28. GitQuarantinePath string
  29. ProtectedBranchID int64
  30. IsDeployKey bool
  31. }
  32. // HookPostReceiveResult represents an individual result from PostReceive
  33. type HookPostReceiveResult struct {
  34. Results []HookPostReceiveBranchResult
  35. RepoWasEmpty bool
  36. Err string
  37. }
  38. // HookPostReceiveBranchResult represents an individual branch result from PostReceive
  39. type HookPostReceiveBranchResult struct {
  40. Message bool
  41. Create bool
  42. Branch string
  43. URL string
  44. }
  45. // HookEnvResult
  46. type HookEnvResult struct {
  47. Config map[string]string
  48. }
  49. // HookPreReceive check whether the provided commits are allowed
  50. func HookPreReceive(ownerName, repoName string, opts HookOptions) (int, string) {
  51. reqURL := setting.LocalURL + fmt.Sprintf("api/internal/hook/pre-receive/%s/%s",
  52. url.PathEscape(ownerName),
  53. url.PathEscape(repoName),
  54. )
  55. req := newInternalRequest(reqURL, "POST")
  56. req = req.Header("Content-Type", "application/json")
  57. jsonBytes, _ := json.Marshal(opts)
  58. req.Body(jsonBytes)
  59. req.SetTimeout(60*time.Second, time.Duration(60+len(opts.OldCommitIDs))*time.Second)
  60. resp, err := req.Response()
  61. if err != nil {
  62. return http.StatusInternalServerError, fmt.Sprintf("Unable to contact gitea: %v", err.Error())
  63. }
  64. defer resp.Body.Close()
  65. if resp.StatusCode != http.StatusOK {
  66. return resp.StatusCode, decodeJSONError(resp).Err
  67. }
  68. return http.StatusOK, ""
  69. }
  70. // HookPostReceive updates services and users
  71. func HookPostReceive(ownerName, repoName string, opts HookOptions) (*HookPostReceiveResult, string) {
  72. reqURL := setting.LocalURL + fmt.Sprintf("api/internal/hook/post-receive/%s/%s",
  73. url.PathEscape(ownerName),
  74. url.PathEscape(repoName),
  75. )
  76. req := newInternalRequest(reqURL, "POST")
  77. req = req.Header("Content-Type", "application/json")
  78. req.SetTimeout(60*time.Second, time.Duration(60+len(opts.OldCommitIDs))*time.Second)
  79. jsonBytes, _ := json.Marshal(opts)
  80. req.Body(jsonBytes)
  81. resp, err := req.Response()
  82. if err != nil {
  83. return nil, fmt.Sprintf("Unable to contact gitea: %v", err.Error())
  84. }
  85. defer resp.Body.Close()
  86. if resp.StatusCode != http.StatusOK {
  87. return nil, decodeJSONError(resp).Err
  88. }
  89. res := &HookPostReceiveResult{}
  90. _ = json.NewDecoder(resp.Body).Decode(res)
  91. return res, ""
  92. }
  93. // SetDefaultBranch will set the default branch to the provided branch for the provided repository
  94. func SetDefaultBranch(ownerName, repoName, branch string) error {
  95. reqURL := setting.LocalURL + fmt.Sprintf("api/internal/hook/set-default-branch/%s/%s/%s",
  96. url.PathEscape(ownerName),
  97. url.PathEscape(repoName),
  98. url.PathEscape(branch),
  99. )
  100. req := newInternalRequest(reqURL, "POST")
  101. req = req.Header("Content-Type", "application/json")
  102. req.SetTimeout(60*time.Second, 60*time.Second)
  103. resp, err := req.Response()
  104. if err != nil {
  105. return fmt.Errorf("Unable to contact gitea: %v", err)
  106. }
  107. defer resp.Body.Close()
  108. if resp.StatusCode != http.StatusOK {
  109. return fmt.Errorf("Error returned from gitea: %v", decodeJSONError(resp).Err)
  110. }
  111. return nil
  112. }
  113. // GetHookConfig get hook config to set environment for hook script
  114. func GetHookConfig(ownerName, repoName string) (map[string]string, string) {
  115. reqURL := setting.LocalURL + fmt.Sprintf("api/internal/hook/env/%s/%s",
  116. url.PathEscape(ownerName),
  117. url.PathEscape(repoName),
  118. )
  119. req := newInternalRequest(reqURL, "GET")
  120. req = req.Header("Content-Type", "application/json")
  121. req.SetTimeout(60*time.Second, time.Duration(60)*time.Second)
  122. resp, err := req.Response()
  123. if err != nil {
  124. return nil, fmt.Sprintf("Unable to contact gitea: %v", err.Error())
  125. }
  126. defer resp.Body.Close()
  127. if resp.StatusCode != http.StatusOK {
  128. return nil, decodeJSONError(resp).Err
  129. }
  130. res := &HookEnvResult{}
  131. _ = json.NewDecoder(resp.Body).Decode(res)
  132. return res.Config, ""
  133. }