Skip to content

Commit

Permalink
Draft: add webhook event deserialization
Browse files Browse the repository at this point in the history
This commit will be force pushed regularly, as progressively elements
for which we have example payloads will be more precise than just
`serde_json::Value`. This commit is pushed to enable an initial review
over the architecture/scope of the changes.
  • Loading branch information
gagbo committed Jul 27, 2023
1 parent 7590176 commit 1b74556
Show file tree
Hide file tree
Showing 84 changed files with 5,421 additions and 5 deletions.
2 changes: 2 additions & 0 deletions src/models.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ pub mod reactions;
pub mod repos;
pub mod teams;
pub mod timelines;
pub mod webhook_events;
pub mod workflows;

pub use apps::App;
Expand Down Expand Up @@ -105,6 +106,7 @@ id_type!(
IssueEventId,
IssueId,
JobId,
HookId,
LabelId,
MilestoneId,
NotificationId,
Expand Down
4 changes: 0 additions & 4 deletions src/models/events.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,6 @@ use serde::{de::Error, Deserialize, Serialize};
use url::Url;

/// A GitHub event.
///
/// If you want to deserialize a webhook payload received in a Github Application, you
/// must directly deserialize the body into a [`WrappedEventPayload`](WrappedEventPayload).
/// For webhooks, the event type is stored in the `X-GitHub-Event` header.
#[derive(Debug, Clone, PartialEq, Serialize)]
#[non_exhaustive]
pub struct Event {
Expand Down
2 changes: 1 addition & 1 deletion src/models/reactions.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use super::*;

#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[derive(Debug, Clone, Hash, PartialEq, Eq, Serialize, Deserialize)]
pub enum ReactionContent {
#[serde(rename = "heart")]
Heart,
Expand Down
810 changes: 810 additions & 0 deletions src/models/webhook_events.rs

Large diffs are not rendered by default.

196 changes: 196 additions & 0 deletions src/models/webhook_events/payload.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,196 @@
mod branch_protection_rule;
mod check_run;
mod check_suite;
mod code_scanning_alert;
mod commit_comment;
mod create;
mod delete;
mod dependabot_alert;
mod deploy_key;
mod deployment;
mod deployment_protection_rule;
mod deployment_status;
mod discussion;
mod discussion_comment;
mod fork;
mod github_app_authorization;
mod gollum;
mod installation;
mod installation_repositories;
mod installation_target;
mod issue_comment;
mod issues;
mod label;
mod marketplace_purchase;
mod member;
mod membership;
mod merge_group;
mod meta;
mod milestone;
mod org_block;
mod organization;
mod package;
mod page_build;
mod personal_access_token_request;
mod ping;
mod project;
mod project_card;
mod project_column;
mod projects_v2;
mod projects_v2_item;
mod public;
mod pull_request;
mod pull_request_review;
mod pull_request_review_comment;
mod pull_request_review_thread;
mod push;
mod registry_package;
mod release;
mod repository;
mod repository_advisory;
mod repository_dispatch;
mod repository_import;
mod repository_vulnerability_alert;
mod secret_scanning_alert;
mod secret_scanning_alert_location;
mod security_advisory;
mod security_and_analysis;
mod sponsorship;
mod star;
mod status;
mod team;
mod team_add;
mod watch;
mod workflow_dispatch;
mod workflow_job;
mod workflow_run;

pub use self::{
branch_protection_rule::*, check_run::*, check_suite::*, code_scanning_alert::*,
commit_comment::*, create::*, delete::*, dependabot_alert::*, deploy_key::*, deployment::*,
deployment_protection_rule::*, deployment_status::*, discussion::*, discussion_comment::*,
fork::*, github_app_authorization::*, gollum::*, installation::*, installation_repositories::*,
installation_target::*, issue_comment::*, issues::*, label::*, marketplace_purchase::*,
member::*, membership::*, merge_group::*, meta::*, milestone::*, org_block::*, organization::*,
package::*, page_build::*, personal_access_token_request::*, ping::*, project::*,
project_card::*, project_column::*, projects_v2::*, projects_v2_item::*, public::*,
pull_request::*, pull_request_review::*, pull_request_review_comment::*,
pull_request_review_thread::*, push::*, registry_package::*, release::*, repository::*,
repository_advisory::*, repository_dispatch::*, repository_import::*,
repository_vulnerability_alert::*, secret_scanning_alert::*, secret_scanning_alert_location::*,
security_advisory::*, security_and_analysis::*, sponsorship::*, star::*, status::*, team::*,
team_add::*, watch::*, workflow_dispatch::*, workflow_job::*, workflow_run::*,
};

use serde::{Deserialize, Serialize};

#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[non_exhaustive]
pub enum WebhookEventPayload {
BranchProtectionRuleWebhookEvent(Box<BranchProtectionRuleWebhookEventPayload>),
CheckRunWebhookEvent(Box<CheckRunWebhookEventPayload>),
CheckSuiteWebhookEvent(Box<CheckSuiteWebhookEventPayload>),
CodeScanningAlertWebhookEvent(Box<CodeScanningAlertWebhookEventPayload>),
CommitCommentWebhookEvent(Box<CommitCommentWebhookEventPayload>),
CreateWebhookEvent(Box<CreateWebhookEventPayload>),
DeleteWebhookEvent(Box<DeleteWebhookEventPayload>),
DependabotAlertWebhookEvent(Box<DependabotAlertWebhookEventPayload>),
DeployKeyWebhookEvent(Box<DeployKeyWebhookEventPayload>),
DeploymentWebhookEvent(Box<DeploymentWebhookEventPayload>),
DeploymentProtectionRuleWebhookEvent(Box<DeploymentProtectionRuleWebhookEventPayload>),
DeploymentStatusWebhookEvent(Box<DeploymentStatusWebhookEventPayload>),
DiscussionWebhookEvent(Box<DiscussionWebhookEventPayload>),
DiscussionCommentWebhookEvent(Box<DiscussionCommentWebhookEventPayload>),
ForkWebhookEvent(Box<ForkWebhookEventPayload>),
GithubAppAuthorizationWebhookEvent(Box<GithubAppAuthorizationWebhookEventPayload>),
GollumWebhookEvent(Box<GollumWebhookEventPayload>),
InstallationWebhookEvent(Box<InstallationWebhookEventPayload>),
InstallationRepositoriesWebhookEvent(Box<InstallationRepositoriesWebhookEventPayload>),
InstallationTargetWebhookEvent(Box<InstallationTargetWebhookEventPayload>),
IssueCommentWebhookEvent(Box<IssueCommentWebhookEventPayload>),
IssuesWebhookEvent(Box<IssuesWebhookEventPayload>),
LabelWebhookEvent(Box<LabelWebhookEventPayload>),
MarketplacePurchaseWebhookEvent(Box<MarketplacePurchaseWebhookEventPayload>),
MemberWebhookEvent(Box<MemberWebhookEventPayload>),
MembershipWebhookEvent(Box<MembershipWebhookEventPayload>),
MergeGroupWebhookEvent(Box<MergeGroupWebhookEventPayload>),
MetaWebhookEvent(Box<MetaWebhookEventPayload>),
MilestoneWebhookEvent(Box<MilestoneWebhookEventPayload>),
OrgBlockWebhookEvent(Box<OrgBlockWebhookEventPayload>),
OrganizationWebhookEvent(Box<OrganizationWebhookEventPayload>),
PackageWebhookEvent(Box<PackageWebhookEventPayload>),
PageBuildWebhookEvent(Box<PageBuildWebhookEventPayload>),
PersonalAccessTokenRequestWebhookEvent(Box<PersonalAccessTokenRequestWebhookEventPayload>),
PingWebhookEvent(Box<PingWebhookEventPayload>),
ProjectCardWebhookEvent(Box<ProjectCardWebhookEventPayload>),
ProjectWebhookEvent(Box<ProjectWebhookEventPayload>),
ProjectColumnWebhookEvent(Box<ProjectColumnWebhookEventPayload>),
ProjectsV2WebhookEvent(Box<ProjectsV2WebhookEventPayload>),
ProjectsV2ItemWebhookEvent(Box<ProjectsV2ItemWebhookEventPayload>),
PublicWebhookEvent(Box<PublicWebhookEventPayload>),
PullRequestWebhookEvent(Box<PullRequestWebhookEventPayload>),
PullRequestReviewWebhookEvent(Box<PullRequestReviewWebhookEventPayload>),
PullRequestReviewCommentWebhookEvent(Box<PullRequestReviewCommentWebhookEventPayload>),
PullRequestReviewThreadWebhookEvent(Box<PullRequestReviewThreadWebhookEventPayload>),
PushWebhookEvent(Box<PushWebhookEventPayload>),
RegistryPackageWebhookEvent(Box<RegistryPackageWebhookEventPayload>),
ReleaseWebhookEvent(Box<ReleaseWebhookEventPayload>),
RepositoryAdvisoryWebhookEvent(Box<RepositoryAdvisoryWebhookEventPayload>),
RepositoryWebhookEvent(Box<RepositoryWebhookEventPayload>),
RepositoryDispatchWebhookEvent(Box<RepositoryDispatchWebhookEventPayload>),
RepositoryImportWebhookEvent(Box<RepositoryImportWebhookEventPayload>),
RepositoryVulnerabilityAlertWebhookEvent(Box<RepositoryVulnerabilityAlertWebhookEventPayload>),
SecretScanningAlertWebhookEvent(Box<SecretScanningAlertWebhookEventPayload>),
SecretScanningAlertLocationWebhookEvent(Box<SecretScanningAlertLocationWebhookEventPayload>),
SecurityAdvisoryWebhookEvent(Box<SecurityAdvisoryWebhookEventPayload>),
SecurityAndAnalysisWebhookEvent(Box<SecurityAndAnalysisWebhookEventPayload>),
SponsorshipWebhookEvent(Box<SponsorshipWebhookEventPayload>),
StarWebhookEvent(Box<StarWebhookEventPayload>),
StatusWebhookEvent(Box<StatusWebhookEventPayload>),
TeamAddWebhookEvent(Box<TeamAddWebhookEventPayload>),
TeamWebhookEvent(Box<TeamWebhookEventPayload>),
WatchWebhookEvent(Box<WatchWebhookEventPayload>),
WorkflowDispatchWebhookEvent(Box<WorkflowDispatchWebhookEventPayload>),
WorkflowJobWebhookEvent(Box<WorkflowJobWebhookEventPayload>),
WorkflowRunWebhookEvent(Box<WorkflowRunWebhookEventPayload>),
UnknownWebhookEvent(Box<serde_json::Value>),
}

#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
#[non_exhaustive]
pub enum AuthorAssociation {
Collaborator,
Contributor,
FirstTimer,
FirstTimeContributor,
Mannequin,
Member,
None,
Owner,
}

#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
#[non_exhaustive]
pub enum RefType {
Tag,
Branch,
}

#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
#[non_exhaustive]
pub enum PusherType {
User,
#[serde(untagged)]
DeployKey(String),
}

#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
#[non_exhaustive]
pub enum MembershipScope {
Team,
Organization,
}
18 changes: 18 additions & 0 deletions src/models/webhook_events/payload/branch_protection_rule.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
use serde::{Deserialize, Serialize};

#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[non_exhaustive]
pub struct BranchProtectionRuleWebhookEventPayload {
pub action: BranchProtectionRuleWebhookEventAction,
pub enterprise: Option<serde_json::Value>,
pub rule: serde_json::Value,
}

#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
#[non_exhaustive]
pub enum BranchProtectionRuleWebhookEventAction {
Created,
Deleted,
Edited,
}
18 changes: 18 additions & 0 deletions src/models/webhook_events/payload/check_run.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
use serde::{Deserialize, Serialize};

#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[non_exhaustive]
pub struct CheckRunWebhookEventPayload {
pub action: CheckRunWebhookEventAction,
pub check_run: serde_json::Value,
}

#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
#[non_exhaustive]
pub enum CheckRunWebhookEventAction {
Completed,
Created,
RequestedAction,
Rerequested,
}
18 changes: 18 additions & 0 deletions src/models/webhook_events/payload/check_suite.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
use serde::{Deserialize, Serialize};

#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[non_exhaustive]
pub struct CheckSuiteWebhookEventPayload {
pub action: CheckSuiteWebhookEventAction,
pub enterprise: Option<serde_json::Value>,
pub check_suite: serde_json::Value,
}

#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
#[non_exhaustive]
pub enum CheckSuiteWebhookEventAction {
Completed,
Requested,
Rerequested,
}
25 changes: 25 additions & 0 deletions src/models/webhook_events/payload/code_scanning_alert.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
use serde::{Deserialize, Serialize};

#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[non_exhaustive]
pub struct CodeScanningAlertWebhookEventPayload {
pub action: CodeScanningAlertWebhookEventAction,
pub alert: serde_json::Value,
/// The commit SHA of the code scanning alert. When the action is reopened_by_user or closed_by_user, the event was triggered by the sender and this value will be empty.
pub commit_oid: String,
pub enterprise: Option<serde_json::Value>,
/// The Git reference of the code scanning alert. When the action is reopened_by_user or closed_by_user, the event was triggered by the sender and this value will be empty.
pub r#ref: String,
}

#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
#[non_exhaustive]
pub enum CodeScanningAlertWebhookEventAction {
AppearedInBranch,
ClosedByUser,
Created,
Fixed,
Reopened,
ReopenedByUser,
}
42 changes: 42 additions & 0 deletions src/models/webhook_events/payload/commit_comment.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
use std::collections::HashMap;

use serde::{Deserialize, Serialize};
use url::Url;

use crate::models::{reactions::ReactionContent, Author, CommentId};

use super::AuthorAssociation;

#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[non_exhaustive]
pub struct CommitCommentWebhookEventPayload {
pub action: CommitCommentWebhookEventAction,
pub comment: CommitComment,
}

#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
#[non_exhaustive]
pub enum CommitCommentWebhookEventAction {
Created,
}

#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
#[non_exhaustive]
pub struct CommitComment {
pub author_association: AuthorAssociation,
pub body: String,
pub commit_id: String,
pub created_at: String,
pub html_url: Url,
pub id: CommentId,
pub line: Option<u64>,
pub node_id: String,
pub path: Option<String>,
pub position: Option<u64>,
pub reactions: Option<HashMap<ReactionContent, u64>>,
pub updated_at: String,
pub url: Url,
pub user: Option<Author>,
}
14 changes: 14 additions & 0 deletions src/models/webhook_events/payload/create.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
use serde::{Deserialize, Serialize};

use super::{PusherType, RefType};

#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[non_exhaustive]
pub struct CreateWebhookEventPayload {
pub description: Option<String>,
pub enterprise: Option<serde_json::Value>,
pub master_branch: String,
pub pusher_type: PusherType,
pub r#ref: String,
pub ref_type: RefType,
}
21 changes: 21 additions & 0 deletions src/models/webhook_events/payload/delete.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
use serde::{Deserialize, Serialize};

use super::{PusherType, RefType};

#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[non_exhaustive]
pub struct DeleteWebhookEventPayload {
pub enterprise: Option<serde_json::Value>,
pub pusher_type: PusherType,
pub r#ref: String,
pub ref_type: RefType,
}

#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
#[non_exhaustive]
pub enum DeleteWebhookEventAction {
Created,
Deleted,
Edited,
}
Loading

0 comments on commit 1b74556

Please sign in to comment.