Skip to content

Commit 83e7c77

Browse files
authored
Merge pull request #116 from vohoanglong0107/refactor-split-webhook
refactor: split webhook parser to multiple function
2 parents dd3f8a3 + bf5cd2e commit 83e7c77

File tree

1 file changed

+121
-111
lines changed

1 file changed

+121
-111
lines changed

src/github/webhook.rs

Lines changed: 121 additions & 111 deletions
Original file line numberDiff line numberDiff line change
@@ -148,127 +148,137 @@ fn parse_webhook_event(request: Parts, body: &[u8]) -> anyhow::Result<Option<Bor
148148
);
149149

150150
match event_type.as_bytes() {
151-
b"issue_comment" => {
152-
let repository: WebhookRepository = serde_json::from_slice(body)?;
153-
let repository_name = parse_repository_name(&repository.repository)?;
154-
155-
let event: IssueCommentEventPayload = serde_json::from_slice(body)?;
156-
if event.action == IssueCommentEventAction::Created {
157-
let comment = parse_pr_comment(repository_name, event)
158-
.map(BorsRepositoryEvent::Comment)
159-
.map(BorsEvent::Repository);
160-
Ok(comment)
161-
} else {
162-
Ok(None)
163-
}
164-
}
165-
b"pull_request_review" => {
166-
let payload: WebhookPullRequestReviewEvent = serde_json::from_slice(body)?;
167-
if payload.action == "submitted" {
168-
let comment = parse_comment_from_pr_review(payload)?;
169-
Ok(Some(BorsEvent::Repository(BorsRepositoryEvent::Comment(
170-
comment,
171-
))))
172-
} else {
173-
Ok(None)
174-
}
175-
}
176-
b"pull_request_review_comment" => {
177-
let repository: WebhookRepository = serde_json::from_slice(body)?;
178-
let repository_name = parse_repository_name(&repository.repository)?;
179-
180-
let payload: PullRequestReviewCommentEventPayload = serde_json::from_slice(body)?;
181-
if payload.action == PullRequestReviewCommentEventAction::Created {
182-
let comment = parse_pr_review_comment(repository_name, payload);
183-
Ok(Some(BorsEvent::Repository(BorsRepositoryEvent::Comment(
184-
comment,
185-
))))
186-
} else {
187-
Ok(None)
188-
}
189-
}
151+
b"issue_comment" => parse_issue_comment_event(body),
152+
b"pull_request_review" => parse_pull_request_review_events(body),
153+
b"pull_request_review_comment" => parse_pull_request_review_comment_events(body),
190154
b"installation_repositories" | b"installation" => Ok(Some(BorsEvent::Global(
191155
BorsGlobalEvent::InstallationsChanged,
192156
))),
193-
b"workflow_run" => {
194-
let payload: WebhookWorkflowRun = serde_json::from_slice(body)?;
195-
let repository_name = parse_repository_name(&payload.repository)?;
196-
let result = match payload.action {
197-
"requested" => Some(BorsEvent::Repository(BorsRepositoryEvent::WorkflowStarted(
198-
WorkflowStarted {
199-
repository: repository_name,
200-
name: payload.workflow_run.name,
201-
branch: payload.workflow_run.head_branch,
202-
commit_sha: CommitSha(payload.workflow_run.head_sha),
203-
run_id: RunId(payload.workflow_run.id.0),
204-
workflow_type: WorkflowType::Github,
205-
url: payload.workflow_run.html_url.into(),
206-
},
207-
))),
208-
"completed" => Some(BorsEvent::Repository(
209-
BorsRepositoryEvent::WorkflowCompleted(WorkflowCompleted {
210-
repository: repository_name,
211-
branch: payload.workflow_run.head_branch,
212-
commit_sha: CommitSha(payload.workflow_run.head_sha),
213-
run_id: RunId(payload.workflow_run.id.0),
214-
status: match payload.workflow_run.conclusion.unwrap_or_default().as_str() {
215-
"success" => WorkflowStatus::Success,
216-
_ => WorkflowStatus::Failure,
217-
},
218-
}),
219-
)),
220-
_ => None,
221-
};
222-
Ok(result)
223-
}
224-
b"check_run" => {
225-
let payload: WebhookCheckRun = serde_json::from_slice(body).unwrap();
226-
227-
// We are only interested in check runs from external CI services.
228-
// These basically correspond to workflow runs from GHA.
229-
if payload.check_run.app.owner.login == "github" {
230-
return Ok(None);
231-
}
232-
233-
let repository_name = parse_repository_name(&payload.repository)?;
234-
if payload.action == "created" {
235-
Ok(Some(BorsEvent::Repository(
236-
BorsRepositoryEvent::WorkflowStarted(WorkflowStarted {
237-
repository: repository_name,
238-
name: payload.check_run.name.to_string(),
239-
branch: payload.check_run.check_suite.head_branch,
240-
commit_sha: CommitSha(payload.check_run.check_suite.head_sha),
241-
run_id: RunId(payload.check_run.check_run.id.map(|v| v.0).unwrap_or(0)),
242-
workflow_type: WorkflowType::External,
243-
url: payload.check_run.check_run.html_url.unwrap_or_default(),
244-
}),
245-
)))
246-
} else {
247-
Ok(None)
248-
}
249-
}
250-
b"check_suite" => {
251-
let payload: WebhookCheckSuite = serde_json::from_slice(body)?;
252-
let repository_name = parse_repository_name(&payload.repository)?;
253-
if payload.action == "completed" {
254-
Ok(Some(BorsEvent::Repository(
255-
BorsRepositoryEvent::CheckSuiteCompleted(CheckSuiteCompleted {
256-
repository: repository_name,
257-
branch: payload.check_suite.head_branch,
258-
commit_sha: CommitSha(payload.check_suite.head_sha),
259-
}),
260-
)))
261-
} else {
262-
Ok(None)
263-
}
264-
}
157+
b"workflow_run" => parse_workflow_run_events(body),
158+
b"check_run" => parse_check_run_events(body),
159+
b"check_suite" => parse_check_suite_events(body),
265160
_ => {
266161
tracing::debug!("Ignoring unknown event type {:?}", event_type.to_str());
267162
Ok(None)
268163
}
269164
}
270165
}
271166

167+
fn parse_issue_comment_event(body: &[u8]) -> anyhow::Result<Option<BorsEvent>> {
168+
let repository: WebhookRepository = serde_json::from_slice(body)?;
169+
let repository_name = parse_repository_name(&repository.repository)?;
170+
171+
let event: IssueCommentEventPayload = serde_json::from_slice(body)?;
172+
if event.action == IssueCommentEventAction::Created {
173+
let comment = parse_pr_comment(repository_name, event)
174+
.map(BorsRepositoryEvent::Comment)
175+
.map(BorsEvent::Repository);
176+
Ok(comment)
177+
} else {
178+
Ok(None)
179+
}
180+
}
181+
182+
fn parse_pull_request_review_events(body: &[u8]) -> anyhow::Result<Option<BorsEvent>> {
183+
let payload: WebhookPullRequestReviewEvent = serde_json::from_slice(body)?;
184+
if payload.action == "submitted" {
185+
let comment = parse_comment_from_pr_review(payload)?;
186+
Ok(Some(BorsEvent::Repository(BorsRepositoryEvent::Comment(
187+
comment,
188+
))))
189+
} else {
190+
Ok(None)
191+
}
192+
}
193+
fn parse_pull_request_review_comment_events(body: &[u8]) -> anyhow::Result<Option<BorsEvent>> {
194+
let repository: WebhookRepository = serde_json::from_slice(body)?;
195+
let repository_name = parse_repository_name(&repository.repository)?;
196+
197+
let payload: PullRequestReviewCommentEventPayload = serde_json::from_slice(body)?;
198+
if payload.action == PullRequestReviewCommentEventAction::Created {
199+
let comment = parse_pr_review_comment(repository_name, payload);
200+
Ok(Some(BorsEvent::Repository(BorsRepositoryEvent::Comment(
201+
comment,
202+
))))
203+
} else {
204+
Ok(None)
205+
}
206+
}
207+
208+
fn parse_workflow_run_events(body: &[u8]) -> anyhow::Result<Option<BorsEvent>> {
209+
let payload: WebhookWorkflowRun = serde_json::from_slice(body)?;
210+
let repository_name = parse_repository_name(&payload.repository)?;
211+
let result = match payload.action {
212+
"requested" => Some(BorsEvent::Repository(BorsRepositoryEvent::WorkflowStarted(
213+
WorkflowStarted {
214+
repository: repository_name,
215+
name: payload.workflow_run.name,
216+
branch: payload.workflow_run.head_branch,
217+
commit_sha: CommitSha(payload.workflow_run.head_sha),
218+
run_id: RunId(payload.workflow_run.id.0),
219+
workflow_type: WorkflowType::Github,
220+
url: payload.workflow_run.html_url.into(),
221+
},
222+
))),
223+
"completed" => Some(BorsEvent::Repository(
224+
BorsRepositoryEvent::WorkflowCompleted(WorkflowCompleted {
225+
repository: repository_name,
226+
branch: payload.workflow_run.head_branch,
227+
commit_sha: CommitSha(payload.workflow_run.head_sha),
228+
run_id: RunId(payload.workflow_run.id.0),
229+
status: match payload.workflow_run.conclusion.unwrap_or_default().as_str() {
230+
"success" => WorkflowStatus::Success,
231+
_ => WorkflowStatus::Failure,
232+
},
233+
}),
234+
)),
235+
_ => None,
236+
};
237+
Ok(result)
238+
}
239+
240+
fn parse_check_run_events(body: &[u8]) -> anyhow::Result<Option<BorsEvent>> {
241+
let payload: WebhookCheckRun = serde_json::from_slice(body).unwrap();
242+
243+
// We are only interested in check runs from external CI services.
244+
// These basically correspond to workflow runs from GHA.
245+
if payload.check_run.app.owner.login == "github" {
246+
return Ok(None);
247+
}
248+
249+
let repository_name = parse_repository_name(&payload.repository)?;
250+
if payload.action == "created" {
251+
Ok(Some(BorsEvent::Repository(
252+
BorsRepositoryEvent::WorkflowStarted(WorkflowStarted {
253+
repository: repository_name,
254+
name: payload.check_run.name.to_string(),
255+
branch: payload.check_run.check_suite.head_branch,
256+
commit_sha: CommitSha(payload.check_run.check_suite.head_sha),
257+
run_id: RunId(payload.check_run.check_run.id.map(|v| v.0).unwrap_or(0)),
258+
workflow_type: WorkflowType::External,
259+
url: payload.check_run.check_run.html_url.unwrap_or_default(),
260+
}),
261+
)))
262+
} else {
263+
Ok(None)
264+
}
265+
}
266+
fn parse_check_suite_events(body: &[u8]) -> anyhow::Result<Option<BorsEvent>> {
267+
let payload: WebhookCheckSuite = serde_json::from_slice(body)?;
268+
let repository_name = parse_repository_name(&payload.repository)?;
269+
if payload.action == "completed" {
270+
Ok(Some(BorsEvent::Repository(
271+
BorsRepositoryEvent::CheckSuiteCompleted(CheckSuiteCompleted {
272+
repository: repository_name,
273+
branch: payload.check_suite.head_branch,
274+
commit_sha: CommitSha(payload.check_suite.head_sha),
275+
}),
276+
)))
277+
} else {
278+
Ok(None)
279+
}
280+
}
281+
272282
fn parse_pr_review_comment(
273283
repo: GithubRepoName,
274284
payload: PullRequestReviewCommentEventPayload,

0 commit comments

Comments
 (0)