@@ -8,7 +8,8 @@ use axum::http::{HeaderMap, HeaderValue, StatusCode};
8
8
use axum:: { async_trait, RequestExt } ;
9
9
use hmac:: { Hmac , Mac } ;
10
10
use octocrab:: models:: events:: payload:: {
11
- IssueCommentEventAction , IssueCommentEventPayload , PullRequestReviewCommentEventAction ,
11
+ IssueCommentEventAction , IssueCommentEventPayload , PullRequestEventAction ,
12
+ PullRequestEventChangesFrom , PullRequestReviewCommentEventAction ,
12
13
PullRequestReviewCommentEventPayload ,
13
14
} ;
14
15
use octocrab:: models:: pulls:: { PullRequest , Review } ;
@@ -18,7 +19,7 @@ use sha2::Sha256;
18
19
19
20
use crate :: bors:: event:: {
20
21
BorsEvent , BorsGlobalEvent , BorsRepositoryEvent , CheckSuiteCompleted , PullRequestComment ,
21
- WorkflowCompleted , WorkflowStarted ,
22
+ PullRequestEdited , WorkflowCompleted , WorkflowStarted ,
22
23
} ;
23
24
use crate :: database:: { WorkflowStatus , WorkflowType } ;
24
25
use crate :: github:: server:: ServerStateRef ;
@@ -90,6 +91,26 @@ pub struct WebhookPullRequestReviewEvent<'a> {
90
91
sender : Author ,
91
92
}
92
93
94
+ /// Similar to PullRequestEvent from octocrab, but changes field also includes base sha.
95
+ /// https://docs.github.com/en/webhooks/webhook-events-and-payloads#pull_request
96
+ #[ derive( Debug , serde:: Deserialize ) ]
97
+ struct WebhookPullRequestEvent {
98
+ action : PullRequestEventAction ,
99
+ pull_request : PullRequest ,
100
+ changes : Option < WebhookPullRequestChanges > ,
101
+ repository : Repository ,
102
+ }
103
+
104
+ #[ derive( Debug , serde:: Deserialize ) ]
105
+ struct WebhookPullRequestChanges {
106
+ base : Option < WebhookPullRequestBaseChanges > ,
107
+ }
108
+
109
+ #[ derive( Debug , serde:: Deserialize ) ]
110
+ struct WebhookPullRequestBaseChanges {
111
+ sha : Option < PullRequestEventChangesFrom > ,
112
+ }
113
+
93
114
/// axum extractor for GitHub webhook events.
94
115
#[ derive( Debug ) ]
95
116
pub struct GitHubWebhook ( pub BorsEvent ) ;
@@ -149,6 +170,7 @@ fn parse_webhook_event(request: Parts, body: &[u8]) -> anyhow::Result<Option<Bor
149
170
150
171
match event_type. as_bytes ( ) {
151
172
b"issue_comment" => parse_issue_comment_event ( body) ,
173
+ b"pull_request" => parse_pull_request_events ( body) ,
152
174
b"pull_request_review" => parse_pull_request_review_events ( body) ,
153
175
b"pull_request_review_comment" => parse_pull_request_review_comment_events ( body) ,
154
176
b"installation_repositories" | b"installation" => Ok ( Some ( BorsEvent :: Global (
@@ -179,6 +201,30 @@ fn parse_issue_comment_event(body: &[u8]) -> anyhow::Result<Option<BorsEvent>> {
179
201
}
180
202
}
181
203
204
+ fn parse_pull_request_events ( body : & [ u8 ] ) -> anyhow:: Result < Option < BorsEvent > > {
205
+ let payload: WebhookPullRequestEvent = serde_json:: from_slice ( body) ?;
206
+ let repository_name = parse_repository_name ( & payload. repository ) ?;
207
+ if payload. action == PullRequestEventAction :: Edited {
208
+ let Some ( changes) = payload. changes else {
209
+ return Err ( anyhow:: anyhow!(
210
+ "Edited pull request event should have `changes` field"
211
+ ) ) ;
212
+ } ;
213
+ Ok ( Some ( BorsEvent :: Repository (
214
+ BorsRepositoryEvent :: PullRequestEdited ( PullRequestEdited {
215
+ repository : repository_name,
216
+ pull_request : payload. pull_request . into ( ) ,
217
+ from_base_sha : changes
218
+ . base
219
+ . and_then ( |base| base. sha )
220
+ . map ( |sha| CommitSha ( sha. from ) ) ,
221
+ } ) ,
222
+ ) ) )
223
+ } else {
224
+ Ok ( None )
225
+ }
226
+ }
227
+
182
228
fn parse_pull_request_review_events ( body : & [ u8 ] ) -> anyhow:: Result < Option < BorsEvent > > {
183
229
let payload: WebhookPullRequestReviewEvent = serde_json:: from_slice ( body) ?;
184
230
if payload. action == "submitted" {
0 commit comments