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"
@@ -160,6 +165,14 @@ func HookPostReceive(ctx *gitea_context.PrivateContext) {
160
165
}
161
166
}
162
167
168
+ // handle pull request merging, a pull request action should push at least 1 commit
169
+ if opts .PushTrigger == repo_module .PushTriggerPRMergeToBase {
170
+ handlePullRequestMerging (ctx , opts , ownerName , repoName , updates )
171
+ if ctx .Written () {
172
+ return
173
+ }
174
+ }
175
+
163
176
isPrivate := opts .GitPushOptions .Bool (private .GitPushOptionRepoPrivate )
164
177
isTemplate := opts .GitPushOptions .Bool (private .GitPushOptionRepoTemplate )
165
178
// Handle Push Options
@@ -174,7 +187,7 @@ func HookPostReceive(ctx *gitea_context.PrivateContext) {
174
187
wasEmpty = repo .IsEmpty
175
188
}
176
189
177
- pusher , err := user_model . GetUserByID (ctx , opts .UserID )
190
+ pusher , err := loadContextCacheUser (ctx , opts .UserID )
178
191
if err != nil {
179
192
log .Error ("Failed to Update: %s/%s Error: %v" , ownerName , repoName , err )
180
193
ctx .JSON (http .StatusInternalServerError , private.HookPostReceiveResult {
@@ -309,3 +322,52 @@ func HookPostReceive(ctx *gitea_context.PrivateContext) {
309
322
RepoWasEmpty : wasEmpty ,
310
323
})
311
324
}
325
+
326
+ func loadContextCacheUser (ctx context.Context , id int64 ) (* user_model.User , error ) {
327
+ return cache .GetWithContextCache (ctx , "hook_post_receive_user" , id , func () (* user_model.User , error ) {
328
+ return user_model .GetUserByID (ctx , id )
329
+ })
330
+ }
331
+
332
+ // handlePullRequestMerging handle pull request merging, a pull request action should push at least 1 commit
333
+ func handlePullRequestMerging (ctx * gitea_context.PrivateContext , opts * private.HookOptions , ownerName , repoName string , updates []* repo_module.PushUpdateOptions ) {
334
+ if len (updates ) == 0 {
335
+ ctx .JSON (http .StatusInternalServerError , private.HookPostReceiveResult {
336
+ Err : fmt .Sprintf ("Pushing a merged PR (pr:%d) no commits pushed " , opts .PullRequestID ),
337
+ })
338
+ return
339
+ }
340
+
341
+ pr , err := issues_model .GetPullRequestByID (ctx , opts .PullRequestID )
342
+ if err != nil {
343
+ log .Error ("GetPullRequestByID[%d]: %v" , opts .PullRequestID , err )
344
+ ctx .JSON (http .StatusInternalServerError , private.HookPostReceiveResult {Err : "GetPullRequestByID failed" })
345
+ return
346
+ }
347
+
348
+ pusher , err := loadContextCacheUser (ctx , opts .UserID )
349
+ if err != nil {
350
+ log .Error ("Failed to Update: %s/%s Error: %v" , ownerName , repoName , err )
351
+ ctx .JSON (http .StatusInternalServerError , private.HookPostReceiveResult {Err : "Load pusher user failed" })
352
+ return
353
+ }
354
+
355
+ pr .MergedCommitID = updates [len (updates )- 1 ].NewCommitID
356
+ pr .MergedUnix = timeutil .TimeStampNow ()
357
+ pr .Merger = pusher
358
+ pr .MergerID = pusher .ID
359
+ err = db .WithTx (ctx , func (ctx context.Context ) error {
360
+ // Removing an auto merge pull and ignore if not exist
361
+ if err := pull_model .DeleteScheduledAutoMerge (ctx , pr .ID ); err != nil && ! db .IsErrNotExist (err ) {
362
+ return fmt .Errorf ("DeleteScheduledAutoMerge[%d]: %v" , opts .PullRequestID , err )
363
+ }
364
+ if _ , err := pr .SetMerged (ctx ); err != nil {
365
+ return fmt .Errorf ("SetMerged failed: %s/%s Error: %v" , ownerName , repoName , err )
366
+ }
367
+ return nil
368
+ })
369
+ if err != nil {
370
+ log .Error ("Failed to update PR to merged: %v" , err )
371
+ ctx .JSON (http .StatusInternalServerError , private.HookPostReceiveResult {Err : "Failed to update PR to merged" })
372
+ }
373
+ }
0 commit comments