Skip to content

Commit ca0a046

Browse files
committed
Batch post and pre-receive results
1 parent 2ed8271 commit ca0a046

File tree

5 files changed

+450
-267
lines changed

5 files changed

+450
-267
lines changed

cmd/hook.go

Lines changed: 106 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,10 @@ import (
2121
"github.com/urfave/cli"
2222
)
2323

24+
const (
25+
hookBatchSize = 200
26+
)
27+
2428
var (
2529
// CmdHook represents the available hooks sub-command.
2630
CmdHook = cli.Command{
@@ -75,12 +79,23 @@ Gitea or set your environment appropriately.`, "")
7579
prID, _ := strconv.ParseInt(os.Getenv(models.ProtectedBranchPRID), 10, 64)
7680
isDeployKey, _ := strconv.ParseBool(os.Getenv(models.EnvIsDeployKey))
7781

78-
buf := bytes.NewBuffer(nil)
82+
hookOptions := private.HookOptions{
83+
UserID: userID,
84+
GitAlternativeObjectDirectories: os.Getenv(private.GitAlternativeObjectDirectories),
85+
GitObjectDirectory: os.Getenv(private.GitObjectDirectory),
86+
GitQuarantinePath: os.Getenv(private.GitQuarantinePath),
87+
ProtectedBranchID: prID,
88+
IsDeployKey: isDeployKey,
89+
}
90+
7991
scanner := bufio.NewScanner(os.Stdin)
80-
for scanner.Scan() {
81-
buf.Write(scanner.Bytes())
82-
buf.WriteByte('\n')
8392

93+
oldCommitIDs := make([]string, hookBatchSize)
94+
newCommitIDs := make([]string, hookBatchSize)
95+
refFullNames := make([]string, hookBatchSize)
96+
count := 0
97+
98+
for scanner.Scan() {
8499
// TODO: support news feeds for wiki
85100
if isWiki {
86101
continue
@@ -97,26 +112,40 @@ Gitea or set your environment appropriately.`, "")
97112

98113
// If the ref is a branch, check if it's protected
99114
if strings.HasPrefix(refFullName, git.BranchPrefix) {
100-
statusCode, msg := private.HookPreReceive(username, reponame, private.HookOptions{
101-
OldCommitID: oldCommitID,
102-
NewCommitID: newCommitID,
103-
RefFullName: refFullName,
104-
UserID: userID,
105-
GitAlternativeObjectDirectories: os.Getenv(private.GitAlternativeObjectDirectories),
106-
GitObjectDirectory: os.Getenv(private.GitObjectDirectory),
107-
GitQuarantinePath: os.Getenv(private.GitQuarantinePath),
108-
ProtectedBranchID: prID,
109-
IsDeployKey: isDeployKey,
110-
})
111-
switch statusCode {
112-
case http.StatusInternalServerError:
113-
fail("Internal Server Error", msg)
114-
case http.StatusForbidden:
115-
fail(msg, "")
115+
oldCommitIDs[count] = oldCommitID
116+
newCommitIDs[count] = newCommitID
117+
refFullNames[count] = refFullName
118+
count++
119+
if count >= hookBatchSize {
120+
hookOptions.OldCommitIDs = oldCommitIDs
121+
hookOptions.NewCommitIDs = newCommitIDs
122+
hookOptions.RefFullNames = refFullNames
123+
statusCode, msg := private.HookPreReceive(username, reponame, hookOptions)
124+
switch statusCode {
125+
case http.StatusInternalServerError:
126+
fail("Internal Server Error", msg)
127+
case http.StatusForbidden:
128+
fail(msg, "")
129+
}
130+
count = 0
116131
}
117132
}
118133
}
119134

135+
if count > 0 {
136+
hookOptions.OldCommitIDs = oldCommitIDs[:count]
137+
hookOptions.NewCommitIDs = newCommitIDs[:count]
138+
hookOptions.RefFullNames = refFullNames[:count]
139+
140+
statusCode, msg := private.HookPreReceive(username, reponame, hookOptions)
141+
switch statusCode {
142+
case http.StatusInternalServerError:
143+
fail("Internal Server Error", msg)
144+
case http.StatusForbidden:
145+
fail(msg, "")
146+
}
147+
}
148+
120149
return nil
121150
}
122151

@@ -156,6 +185,18 @@ Gitea or set your environment appropriately.`, "")
156185
pusherID, _ := strconv.ParseInt(os.Getenv(models.EnvPusherID), 10, 64)
157186
pusherName := os.Getenv(models.EnvPusherName)
158187

188+
hookOptions := private.HookOptions{
189+
UserName: pusherName,
190+
UserID: pusherID,
191+
GitAlternativeObjectDirectories: os.Getenv(private.GitAlternativeObjectDirectories),
192+
GitObjectDirectory: os.Getenv(private.GitObjectDirectory),
193+
GitQuarantinePath: os.Getenv(private.GitQuarantinePath),
194+
}
195+
oldCommitIDs := make([]string, hookBatchSize)
196+
newCommitIDs := make([]string, hookBatchSize)
197+
refFullNames := make([]string, hookBatchSize)
198+
count := 0
199+
159200
buf := bytes.NewBuffer(nil)
160201
scanner := bufio.NewScanner(os.Stdin)
161202
for scanner.Scan() {
@@ -172,33 +213,61 @@ Gitea or set your environment appropriately.`, "")
172213
continue
173214
}
174215

175-
oldCommitID := string(fields[0])
176-
newCommitID := string(fields[1])
177-
refFullName := string(fields[2])
216+
oldCommitIDs[count] = string(fields[0])
217+
newCommitIDs[count] = string(fields[1])
218+
refFullNames[count] = string(fields[2])
219+
count++
178220

179-
res, err := private.HookPostReceive(repoUser, repoName, private.HookOptions{
180-
OldCommitID: oldCommitID,
181-
NewCommitID: newCommitID,
182-
RefFullName: refFullName,
183-
UserID: pusherID,
184-
UserName: pusherName,
185-
})
221+
if count >= hookBatchSize {
222+
hookOptions.OldCommitIDs = oldCommitIDs
223+
hookOptions.NewCommitIDs = newCommitIDs
224+
hookOptions.RefFullNames = refFullNames
225+
resps, err := private.HookPostReceive(repoUser, repoName, hookOptions)
226+
if resps == nil {
227+
fail("Internal Server Error", err)
228+
}
229+
for _, res := range resps {
230+
if !res.Message {
231+
continue
232+
}
186233

187-
if res == nil {
188-
fail("Internal Server Error", err)
234+
fmt.Fprintln(os.Stderr, "")
235+
if res.Create {
236+
fmt.Fprintf(os.Stderr, "Create a new pull request for '%s':\n", res.Branch)
237+
fmt.Fprintf(os.Stderr, " %s\n", res.URL)
238+
} else {
239+
fmt.Fprint(os.Stderr, "Visit the existing pull request:\n")
240+
fmt.Fprintf(os.Stderr, " %s\n", res.URL)
241+
}
242+
fmt.Fprintln(os.Stderr, "")
243+
}
244+
count = 0
189245
}
246+
}
190247

191-
if res["message"] == false {
248+
if count == 0 {
249+
return nil
250+
}
251+
252+
hookOptions.OldCommitIDs = oldCommitIDs[:count]
253+
hookOptions.NewCommitIDs = newCommitIDs[:count]
254+
hookOptions.RefFullNames = refFullNames[:count]
255+
resps, err := private.HookPostReceive(repoUser, repoName, hookOptions)
256+
if resps == nil {
257+
fail("Internal Server Error", err)
258+
}
259+
for _, res := range resps {
260+
if !res.Message {
192261
continue
193262
}
194263

195264
fmt.Fprintln(os.Stderr, "")
196-
if res["create"] == true {
197-
fmt.Fprintf(os.Stderr, "Create a new pull request for '%s':\n", res["branch"])
198-
fmt.Fprintf(os.Stderr, " %s\n", res["url"])
265+
if res.Create {
266+
fmt.Fprintf(os.Stderr, "Create a new pull request for '%s':\n", res.Branch)
267+
fmt.Fprintf(os.Stderr, " %s\n", res.URL)
199268
} else {
200269
fmt.Fprint(os.Stderr, "Visit the existing pull request:\n")
201-
fmt.Fprintf(os.Stderr, " %s\n", res["url"])
270+
fmt.Fprintf(os.Stderr, " %s\n", res.URL)
202271
}
203272
fmt.Fprintln(os.Stderr, "")
204273
}

modules/private/hook.go

Lines changed: 27 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,9 @@ const (
2222

2323
// HookOptions represents the options for the Hook calls
2424
type HookOptions struct {
25-
OldCommitID string
26-
NewCommitID string
27-
RefFullName string
25+
OldCommitIDs []string
26+
NewCommitIDs []string
27+
RefFullNames []string
2828
UserID int64
2929
UserName string
3030
GitObjectDirectory string
@@ -34,23 +34,26 @@ type HookOptions struct {
3434
IsDeployKey bool
3535
}
3636

37+
// HookPostReceiveResult represents an individual result from PostReceive
38+
type HookPostReceiveResult struct {
39+
Message bool
40+
Create bool
41+
Branch string
42+
URL string
43+
Err string
44+
}
45+
3746
// HookPreReceive check whether the provided commits are allowed
3847
func HookPreReceive(ownerName, repoName string, opts HookOptions) (int, string) {
39-
reqURL := setting.LocalURL + fmt.Sprintf("api/internal/hook/pre-receive/%s/%s?old=%s&new=%s&ref=%s&userID=%d&gitObjectDirectory=%s&gitAlternativeObjectDirectories=%s&gitQuarantinePath=%s&prID=%d&isDeployKey=%t",
48+
reqURL := setting.LocalURL + fmt.Sprintf("api/internal/hook/pre-receive/%s/%s",
4049
url.PathEscape(ownerName),
4150
url.PathEscape(repoName),
42-
url.QueryEscape(opts.OldCommitID),
43-
url.QueryEscape(opts.NewCommitID),
44-
url.QueryEscape(opts.RefFullName),
45-
opts.UserID,
46-
url.QueryEscape(opts.GitObjectDirectory),
47-
url.QueryEscape(opts.GitAlternativeObjectDirectories),
48-
url.QueryEscape(opts.GitQuarantinePath),
49-
opts.ProtectedBranchID,
50-
opts.IsDeployKey,
5151
)
52-
53-
resp, err := newInternalRequest(reqURL, "GET").Response()
52+
req := newInternalRequest(reqURL, "POST")
53+
req = req.Header("Content-Type", "application/json")
54+
jsonBytes, _ := json.Marshal(opts)
55+
req.Body(jsonBytes)
56+
resp, err := req.Response()
5457
if err != nil {
5558
return http.StatusInternalServerError, fmt.Sprintf("Unable to contact gitea: %v", err.Error())
5659
}
@@ -64,17 +67,17 @@ func HookPreReceive(ownerName, repoName string, opts HookOptions) (int, string)
6467
}
6568

6669
// HookPostReceive updates services and users
67-
func HookPostReceive(ownerName, repoName string, opts HookOptions) (map[string]interface{}, string) {
68-
reqURL := setting.LocalURL + fmt.Sprintf("api/internal/hook/post-receive/%s/%s?old=%s&new=%s&ref=%s&userID=%d&username=%s",
70+
func HookPostReceive(ownerName, repoName string, opts HookOptions) ([]HookPostReceiveResult, string) {
71+
reqURL := setting.LocalURL + fmt.Sprintf("api/internal/hook/post-receive/%s/%s",
6972
url.PathEscape(ownerName),
7073
url.PathEscape(repoName),
71-
url.QueryEscape(opts.OldCommitID),
72-
url.QueryEscape(opts.NewCommitID),
73-
url.QueryEscape(opts.RefFullName),
74-
opts.UserID,
75-
url.QueryEscape(opts.UserName))
74+
)
7675

77-
resp, err := newInternalRequest(reqURL, "GET").Response()
76+
req := newInternalRequest(reqURL, "POST")
77+
req = req.Header("Content-Type", "application/json")
78+
jsonBytes, _ := json.Marshal(opts)
79+
req.Body(jsonBytes)
80+
resp, err := req.Response()
7881
if err != nil {
7982
return nil, fmt.Sprintf("Unable to contact gitea: %v", err.Error())
8083
}
@@ -83,7 +86,7 @@ func HookPostReceive(ownerName, repoName string, opts HookOptions) (map[string]i
8386
if resp.StatusCode != http.StatusOK {
8487
return nil, decodeJSONError(resp).Err
8588
}
86-
res := map[string]interface{}{}
89+
res := []HookPostReceiveResult{}
8790
_ = json.NewDecoder(resp.Body).Decode(&res)
8891

8992
return res, ""

0 commit comments

Comments
 (0)