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

hook.go 4.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  1. // Copyright 2019 The Gitea Authors. All rights reserved.
  2. // SPDX-License-Identifier: MIT
  3. package private
  4. import (
  5. "context"
  6. "fmt"
  7. "net/url"
  8. "strconv"
  9. "time"
  10. "code.gitea.io/gitea/modules/setting"
  11. )
  12. // Git environment variables
  13. const (
  14. GitAlternativeObjectDirectories = "GIT_ALTERNATE_OBJECT_DIRECTORIES"
  15. GitObjectDirectory = "GIT_OBJECT_DIRECTORY"
  16. GitQuarantinePath = "GIT_QUARANTINE_PATH"
  17. GitPushOptionCount = "GIT_PUSH_OPTION_COUNT"
  18. )
  19. // GitPushOptions is a wrapper around a map[string]string
  20. type GitPushOptions map[string]string
  21. // GitPushOptions keys
  22. const (
  23. GitPushOptionRepoPrivate = "repo.private"
  24. GitPushOptionRepoTemplate = "repo.template"
  25. )
  26. // Bool checks for a key in the map and parses as a boolean
  27. func (g GitPushOptions) Bool(key string, def bool) bool {
  28. if val, ok := g[key]; ok {
  29. if b, err := strconv.ParseBool(val); err == nil {
  30. return b
  31. }
  32. }
  33. return def
  34. }
  35. // HookOptions represents the options for the Hook calls
  36. type HookOptions struct {
  37. OldCommitIDs []string
  38. NewCommitIDs []string
  39. RefFullNames []string
  40. UserID int64
  41. UserName string
  42. GitObjectDirectory string
  43. GitAlternativeObjectDirectories string
  44. GitQuarantinePath string
  45. GitPushOptions GitPushOptions
  46. PullRequestID int64
  47. DeployKeyID int64 // if the pusher is a DeployKey, then UserID is the repo's org user.
  48. IsWiki bool
  49. ActionPerm int
  50. }
  51. // SSHLogOption ssh log options
  52. type SSHLogOption struct {
  53. IsError bool
  54. Message string
  55. }
  56. // HookPostReceiveResult represents an individual result from PostReceive
  57. type HookPostReceiveResult struct {
  58. Results []HookPostReceiveBranchResult
  59. RepoWasEmpty bool
  60. Err string
  61. }
  62. // HookPostReceiveBranchResult represents an individual branch result from PostReceive
  63. type HookPostReceiveBranchResult struct {
  64. Message bool
  65. Create bool
  66. Branch string
  67. URL string
  68. }
  69. // HookProcReceiveResult represents an individual result from ProcReceive
  70. type HookProcReceiveResult struct {
  71. Results []HookProcReceiveRefResult
  72. Err string
  73. }
  74. // HookProcReceiveRefResult represents an individual result from ProcReceive
  75. type HookProcReceiveRefResult struct {
  76. OldOID string
  77. NewOID string
  78. Ref string
  79. OriginalRef string
  80. IsForcePush bool
  81. IsNotMatched bool
  82. Err string
  83. }
  84. // HookPreReceive check whether the provided commits are allowed
  85. func HookPreReceive(ctx context.Context, ownerName, repoName string, opts HookOptions) ResponseExtra {
  86. reqURL := setting.LocalURL + fmt.Sprintf("api/internal/hook/pre-receive/%s/%s", url.PathEscape(ownerName), url.PathEscape(repoName))
  87. req := newInternalRequest(ctx, reqURL, "POST", opts)
  88. req.SetReadWriteTimeout(time.Duration(60+len(opts.OldCommitIDs)) * time.Second)
  89. _, extra := requestJSONResp(req, &responseText{})
  90. return extra
  91. }
  92. // HookPostReceive updates services and users
  93. func HookPostReceive(ctx context.Context, ownerName, repoName string, opts HookOptions) (*HookPostReceiveResult, ResponseExtra) {
  94. reqURL := setting.LocalURL + fmt.Sprintf("api/internal/hook/post-receive/%s/%s", url.PathEscape(ownerName), url.PathEscape(repoName))
  95. req := newInternalRequest(ctx, reqURL, "POST", opts)
  96. req.SetReadWriteTimeout(time.Duration(60+len(opts.OldCommitIDs)) * time.Second)
  97. return requestJSONResp(req, &HookPostReceiveResult{})
  98. }
  99. // HookProcReceive proc-receive hook
  100. func HookProcReceive(ctx context.Context, ownerName, repoName string, opts HookOptions) (*HookProcReceiveResult, ResponseExtra) {
  101. reqURL := setting.LocalURL + fmt.Sprintf("api/internal/hook/proc-receive/%s/%s", url.PathEscape(ownerName), url.PathEscape(repoName))
  102. req := newInternalRequest(ctx, reqURL, "POST", opts)
  103. req.SetReadWriteTimeout(time.Duration(60+len(opts.OldCommitIDs)) * time.Second)
  104. return requestJSONResp(req, &HookProcReceiveResult{})
  105. }
  106. // SetDefaultBranch will set the default branch to the provided branch for the provided repository
  107. func SetDefaultBranch(ctx context.Context, ownerName, repoName, branch string) ResponseExtra {
  108. reqURL := setting.LocalURL + fmt.Sprintf("api/internal/hook/set-default-branch/%s/%s/%s",
  109. url.PathEscape(ownerName),
  110. url.PathEscape(repoName),
  111. url.PathEscape(branch),
  112. )
  113. req := newInternalRequest(ctx, reqURL, "POST")
  114. _, extra := requestJSONResp(req, &responseText{})
  115. return extra
  116. }
  117. // SSHLog sends ssh error log response
  118. func SSHLog(ctx context.Context, isErr bool, msg string) error {
  119. reqURL := setting.LocalURL + "api/internal/ssh/log"
  120. req := newInternalRequest(ctx, reqURL, "POST", &SSHLogOption{IsError: isErr, Message: msg})
  121. _, extra := requestJSONResp(req, &responseText{})
  122. return extra.Error
  123. }