1- import { DetailedMergeStatus , GitlabApi , MergeRequest , User } from './GitlabApi' ;
1+ import { DetailedMergeStatus , GitlabApi , MergeRequest , ToDo , User } from './GitlabApi' ;
22import { assignToAuthorAndResetLabels } from './AssignToAuthor' ;
33import { sendNote } from './SendNote' ;
44import {
55 acceptMergeRequest ,
66 AcceptMergeRequestResultKind ,
77 BotLabels ,
8+ containsAssignedUser ,
89 runAcceptingMergeRequest ,
910} from './MergeRequestAcceptor' ;
1011import { resolveMergeRequestResult } from './MergeRequestResultResolver' ;
@@ -18,8 +19,28 @@ export const prepareMergeRequestForMerge = async (
1819 user : User ,
1920 worker : Worker ,
2021 config : Config ,
21- mergeRequest : MergeRequest ,
22+ mergeRequestData :
23+ | {
24+ mergeRequestTodo : ToDo ;
25+ }
26+ | {
27+ mergeRequest : MergeRequest ;
28+ } ,
2229) => {
30+ const { mergeRequest, author } = ( ( ) => {
31+ if ( 'mergeRequestTodo' in mergeRequestData ) {
32+ return {
33+ mergeRequest : mergeRequestData . mergeRequestTodo . target ,
34+ author : mergeRequestData . mergeRequestTodo . author ,
35+ } ;
36+ }
37+
38+ return {
39+ mergeRequest : mergeRequestData . mergeRequest ,
40+ author : null ,
41+ } ;
42+ } ) ( ) ;
43+
2344 const jobId = `accept-merge-${ mergeRequest . id } ` ;
2445 const jobPriority = mergeRequest . labels . includes ( config . HIGH_PRIORITY_LABEL )
2546 ? JobPriority . HIGH
@@ -50,6 +71,64 @@ export const prepareMergeRequestForMerge = async (
5071 return ;
5172 }
5273
74+ if ( ! containsAssignedUser ( mergeRequest , user ) ) {
75+ if ( 'mergeRequestTodo' in mergeRequestData ) {
76+ await gitlabApi . markTodoAsDone ( mergeRequestData . mergeRequestTodo . id ) ;
77+ }
78+
79+ return ;
80+ }
81+
82+ // Validate permissions
83+ if ( author !== null ) {
84+ const protectedBranch = await gitlabApi . getProtectedBranch (
85+ mergeRequest . target_project_id ,
86+ mergeRequest . target_branch ,
87+ ) ;
88+ if ( protectedBranch !== null ) {
89+ const member = await gitlabApi . getMember ( mergeRequest . target_project_id , author . id ) ;
90+ if ( member === null ) {
91+ await Promise . all ( [
92+ assignToAuthorAndResetLabels ( gitlabApi , mergeRequest , user ) ,
93+ sendNote (
94+ gitlabApi ,
95+ mergeRequest ,
96+ `I can't merge it because the merge request was made by ${ author . username } who is unauthorized for this instruction.` ,
97+ ) ,
98+ ] ) ;
99+
100+ return ;
101+ }
102+
103+ const hasAccessLevel = protectedBranch . merge_access_levels . find ( ( mergeAccessLevel ) => {
104+ if ( mergeAccessLevel . user_id !== null && member . id === mergeAccessLevel . user_id ) {
105+ return true ;
106+ }
107+
108+ if (
109+ mergeAccessLevel . access_level !== null &&
110+ member . access_level >= mergeAccessLevel . access_level
111+ ) {
112+ return true ;
113+ }
114+
115+ return false ;
116+ } ) ;
117+ if ( ! hasAccessLevel ) {
118+ await Promise . all ( [
119+ assignToAuthorAndResetLabels ( gitlabApi , mergeRequest , user ) ,
120+ sendNote (
121+ gitlabApi ,
122+ mergeRequest ,
123+ `I can't merge it because the merge request was made by ${ author . username } who doesn't pass the protection of the target branch.` ,
124+ ) ,
125+ ] ) ;
126+
127+ return ;
128+ }
129+ }
130+ }
131+
53132 if ( mergeRequest . detailed_merge_status === DetailedMergeStatus . DraftStatus ) {
54133 console . log ( `[loop][MR][${ mergeRequest . iid } ] Merge request is a draft, assigning back` ) ;
55134
@@ -155,6 +234,9 @@ export const prepareMergeRequestForMerge = async (
155234 }
156235
157236 console . log ( `Finishing job: ${ JSON . stringify ( result ) } ` ) ;
237+ if ( 'mergeRequestTodo' in mergeRequestData ) {
238+ await gitlabApi . markTodoAsDone ( mergeRequestData . mergeRequestTodo . id ) ;
239+ }
158240 success ( ) ;
159241 await resolveMergeRequestResult ( gitlabApi , result ) ;
160242 } ,
0 commit comments