4
4
package private
5
5
6
6
import (
7
+ "context"
7
8
"fmt"
8
9
"net/http"
9
10
11
+ "code.gitea.io/gitea/models/db"
10
12
git_model "code.gitea.io/gitea/models/git"
11
13
issues_model "code.gitea.io/gitea/models/issues"
12
14
access_model "code.gitea.io/gitea/models/perm/access"
15
+ pull_model "code.gitea.io/gitea/models/pull"
13
16
repo_model "code.gitea.io/gitea/models/repo"
14
17
user_model "code.gitea.io/gitea/models/user"
18
+ "code.gitea.io/gitea/modules/cache"
15
19
"code.gitea.io/gitea/modules/git"
16
20
"code.gitea.io/gitea/modules/gitrepo"
17
21
"code.gitea.io/gitea/modules/log"
18
22
"code.gitea.io/gitea/modules/private"
19
23
repo_module "code.gitea.io/gitea/modules/repository"
20
24
"code.gitea.io/gitea/modules/setting"
25
+ timeutil "code.gitea.io/gitea/modules/timeutil"
21
26
"code.gitea.io/gitea/modules/util"
22
27
"code.gitea.io/gitea/modules/web"
23
28
gitea_context "code.gitea.io/gitea/services/context"
@@ -158,6 +163,14 @@ func HookPostReceive(ctx *gitea_context.PrivateContext) {
158
163
}
159
164
}
160
165
166
+ // handle pull request merging, a pull request action should push at least 1 commit
167
+ if opts .PushTrigger == repo_module .PushTriggerPRMergeToBase {
168
+ handlePullRequestMerging (ctx , opts , ownerName , repoName , updates )
169
+ if ctx .Written () {
170
+ return
171
+ }
172
+ }
173
+
161
174
isPrivate := opts .GitPushOptions .Bool (private .GitPushOptionRepoPrivate )
162
175
isTemplate := opts .GitPushOptions .Bool (private .GitPushOptionRepoTemplate )
163
176
// Handle Push Options
@@ -172,7 +185,7 @@ func HookPostReceive(ctx *gitea_context.PrivateContext) {
172
185
wasEmpty = repo .IsEmpty
173
186
}
174
187
175
- pusher , err := user_model . GetUserByID (ctx , opts .UserID )
188
+ pusher , err := loadContextCacheUser (ctx , opts .UserID )
176
189
if err != nil {
177
190
log .Error ("Failed to Update: %s/%s Error: %v" , ownerName , repoName , err )
178
191
ctx .JSON (http .StatusInternalServerError , private.HookPostReceiveResult {
@@ -307,3 +320,52 @@ func HookPostReceive(ctx *gitea_context.PrivateContext) {
307
320
RepoWasEmpty : wasEmpty ,
308
321
})
309
322
}
323
+
324
+ func loadContextCacheUser (ctx context.Context , id int64 ) (* user_model.User , error ) {
325
+ return cache .GetWithContextCache (ctx , "hook_post_receive_user" , id , func () (* user_model.User , error ) {
326
+ return user_model .GetUserByID (ctx , id )
327
+ })
328
+ }
329
+
330
+ // handlePullRequestMerging handle pull request merging, a pull request action should push at least 1 commit
331
+ func handlePullRequestMerging (ctx * gitea_context.PrivateContext , opts * private.HookOptions , ownerName , repoName string , updates []* repo_module.PushUpdateOptions ) {
332
+ if len (updates ) == 0 {
333
+ ctx .JSON (http .StatusInternalServerError , private.HookPostReceiveResult {
334
+ Err : fmt .Sprintf ("Pushing a merged PR (pr:%d) no commits pushed " , opts .PullRequestID ),
335
+ })
336
+ return
337
+ }
338
+
339
+ pr , err := issues_model .GetPullRequestByID (ctx , opts .PullRequestID )
340
+ if err != nil {
341
+ log .Error ("GetPullRequestByID[%d]: %v" , opts .PullRequestID , err )
342
+ ctx .JSON (http .StatusInternalServerError , private.HookPostReceiveResult {Err : "GetPullRequestByID failed" })
343
+ return
344
+ }
345
+
346
+ pusher , err := loadContextCacheUser (ctx , opts .UserID )
347
+ if err != nil {
348
+ log .Error ("Failed to Update: %s/%s Error: %v" , ownerName , repoName , err )
349
+ ctx .JSON (http .StatusInternalServerError , private.HookPostReceiveResult {Err : "Load pusher user failed" })
350
+ return
351
+ }
352
+
353
+ pr .MergedCommitID = updates [len (updates )- 1 ].NewCommitID
354
+ pr .MergedUnix = timeutil .TimeStampNow ()
355
+ pr .Merger = pusher
356
+ pr .MergerID = pusher .ID
357
+ err = db .WithTx (ctx , func (ctx context.Context ) error {
358
+ // Removing an auto merge pull and ignore if not exist
359
+ if err := pull_model .DeleteScheduledAutoMerge (ctx , pr .ID ); err != nil && ! db .IsErrNotExist (err ) {
360
+ return fmt .Errorf ("DeleteScheduledAutoMerge[%d]: %v" , opts .PullRequestID , err )
361
+ }
362
+ if _ , err := pr .SetMerged (ctx ); err != nil {
363
+ return fmt .Errorf ("SetMerged failed: %s/%s Error: %v" , ownerName , repoName , err )
364
+ }
365
+ return nil
366
+ })
367
+ if err != nil {
368
+ log .Error ("Failed to update PR to merged: %v" , err )
369
+ ctx .JSON (http .StatusInternalServerError , private.HookPostReceiveResult {Err : "Failed to update PR to merged" })
370
+ }
371
+ }
0 commit comments