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