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  }