@@ -52,6 +52,62 @@ function buildWebhookWhitelist(array $categories): array
5252 return $ whitelist ;
5353}
5454
55+ /**
56+ * Verify that the base branch exists in the repository, correct if not
57+ *
58+ * Uses `gh api repos/{owner}/{repo}/branches/{branch}` to verify existence.
59+ * If the branch doesn't exist, falls back to the repository's default branch.
60+ *
61+ * @param string $repo Owner/repo format
62+ * @param string $baseBranch The branch to verify
63+ * @return string The verified correct base branch
64+ */
65+ function verifyAndCorrectBaseBranch (string $ repo , string $ baseBranch ): string
66+ {
67+ if ($ baseBranch === '' ) {
68+ return 'main ' ;
69+ }
70+
71+ // Quick check: if branch is main/master/develop, just return it
72+ // These are common enough that we skip the API call
73+ if (in_array ($ baseBranch , ['main ' , 'master ' , 'develop ' , 'dev ' , 'staging ' ], true )) {
74+ return $ baseBranch ;
75+ }
76+
77+ // Verify the branch exists via GitHub API
78+ $ output = [];
79+ $ ret = 0 ;
80+ $ cmd = sprintf (
81+ 'gh api repos/%s/branches/%s --jq .name 2>&1 ' ,
82+ escapeshellarg ($ repo ),
83+ escapeshellarg ($ baseBranch )
84+ );
85+ exec ($ cmd , $ output , $ ret );
86+
87+ if ($ ret === 0 && !empty ($ output )) {
88+ // Branch exists, return as-is
89+ return $ baseBranch ;
90+ }
91+
92+ // Branch doesn't exist - get the default branch
93+ $ defaultOutput = [];
94+ $ defaultRet = 0 ;
95+ $ defaultCmd = sprintf (
96+ 'gh api repos/%s --jq .default_branch 2>&1 ' ,
97+ escapeshellarg ($ repo )
98+ );
99+ exec ($ defaultCmd , $ defaultOutput , $ defaultRet );
100+
101+ if ($ defaultRet === 0 && !empty ($ defaultOutput )) {
102+ $ defaultBranch = trim (implode ("\n" , $ defaultOutput ));
103+ error_log ("github-webhook: base_branch ' {$ baseBranch }' not found, using default branch ' {$ defaultBranch }' " );
104+ return $ defaultBranch ?: 'main ' ;
105+ }
106+
107+ // Couldn't determine, return original (might work anyway if gh caches it)
108+ return $ baseBranch ;
109+ }
110+
55111/**
56112 * Add universal repository fields to whitelist for a specific event
57113 */
@@ -148,16 +204,25 @@ function addUniversalRepoFields(array $whitelist): array
148204 if ($ EventType === 'pull_request ' && in_array ($ action , ['opened ' , 'synchronize ' ], true )) {
149205 $ pr = $ Payload ['pull_request ' ] ?? [];
150206 $ author = $ pr ['user ' ] ?? [];
207+ $ authorLogin = $ author ['login ' ] ?? '' ;
208+ $ isBot = str_ends_with ($ authorLogin , '[bot] ' );
209+
210+ // Verify the base branch actually exists in the repo
211+ // If the stored base_branch doesn't exist, use the repo's default branch
212+ $ storedBaseBranch = $ pr ['base ' ]['ref ' ] ?? '' ;
213+ $ baseBranch = verifyAndCorrectBaseBranch ($ RepositoryName , $ storedBaseBranch );
214+
151215 CodeReviewQueue::enqueue ([
152216 'repo ' => $ RepositoryName ,
153217 'pr_number ' => (int )($ pr ['number ' ] ?? 0 ),
154218 'action ' => $ action ,
155219 'head_branch ' => $ pr ['head ' ]['ref ' ] ?? '' ,
156- 'base_branch ' => $ pr [ ' base ' ][ ' ref ' ] ?? '' ,
220+ 'base_branch ' => $ baseBranch ,
157221 'pr_url ' => $ pr ['html_url ' ] ?? '' ,
158- 'author ' => $ author [ ' login ' ] ?? '' ,
222+ 'author ' => $ authorLogin ,
159223 'author_url ' => $ author ['html_url ' ] ?? '' ,
160224 'sha ' => $ pr ['head ' ]['sha ' ] ?? '' ,
225+ 'is_bot ' => $ isBot ,
161226 ]);
162227 }
163228
0 commit comments