Skip to main content

gh_workflow/
event.rs

1#![allow(clippy::needless_update)]
2
3use derive_setters::Setters;
4use indexmap::IndexMap;
5use merge::Merge;
6use serde::{Deserialize, Serialize};
7
8use crate::is_default;
9
10/// Represents all possible webhook events that can trigger a workflow
11/// See: https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows
12#[derive(Default, Debug, Clone, Deserialize, Serialize, Merge, Setters, PartialEq, Eq)]
13#[setters(strip_option, into)]
14pub struct Event {
15    #[serde(skip_serializing_if = "Option::is_none")]
16    #[merge(strategy = merge::option::overwrite_none)]
17    pub branch_protection_rule: Option<BranchProtectionRule>,
18    #[serde(skip_serializing_if = "Option::is_none")]
19    #[merge(strategy = merge::option::overwrite_none)]
20    pub check_run: Option<CheckRun>,
21    #[serde(skip_serializing_if = "Option::is_none")]
22    #[merge(strategy = merge::option::overwrite_none)]
23    pub check_suite: Option<CheckSuite>,
24    #[serde(skip_serializing_if = "Option::is_none")]
25    #[merge(strategy = merge::option::overwrite_none)]
26    pub create: Option<Create>,
27    #[serde(skip_serializing_if = "Option::is_none")]
28    #[merge(strategy = merge::option::overwrite_none)]
29    pub delete: Option<Delete>,
30    #[serde(skip_serializing_if = "Option::is_none")]
31    #[merge(strategy = merge::option::overwrite_none)]
32    pub deployment: Option<Deployment>,
33    #[serde(skip_serializing_if = "Option::is_none")]
34    #[merge(strategy = merge::option::overwrite_none)]
35    pub deployment_status: Option<DeploymentStatus>,
36    #[serde(skip_serializing_if = "Option::is_none")]
37    #[merge(strategy = merge::option::overwrite_none)]
38    pub discussion: Option<Discussion>,
39    #[serde(skip_serializing_if = "Option::is_none")]
40    #[merge(strategy = merge::option::overwrite_none)]
41    pub discussion_comment: Option<DiscussionComment>,
42    #[serde(skip_serializing_if = "Option::is_none")]
43    #[merge(strategy = merge::option::overwrite_none)]
44    pub fork: Option<bool>,
45    #[serde(skip_serializing_if = "Option::is_none")]
46    #[merge(strategy = merge::option::overwrite_none)]
47    pub gollum: Option<bool>,
48    #[serde(skip_serializing_if = "Option::is_none")]
49    #[merge(strategy = merge::option::overwrite_none)]
50    pub issue_comment: Option<IssueComment>,
51    #[serde(skip_serializing_if = "Option::is_none")]
52    #[merge(strategy = merge::option::overwrite_none)]
53    pub issues: Option<Issues>,
54    #[serde(skip_serializing_if = "Option::is_none")]
55    #[merge(strategy = merge::option::overwrite_none)]
56    pub label: Option<Label>,
57    #[serde(skip_serializing_if = "Option::is_none")]
58    #[merge(strategy = merge::option::overwrite_none)]
59    pub merge_group: Option<MergeGroup>,
60    #[serde(skip_serializing_if = "Option::is_none")]
61    #[merge(strategy = merge::option::overwrite_none)]
62    pub milestone: Option<Milestone>,
63    #[serde(skip_serializing_if = "Option::is_none")]
64    #[merge(strategy = merge::option::overwrite_none)]
65    pub page_build: Option<bool>,
66    #[serde(skip_serializing_if = "Option::is_none")]
67    #[merge(strategy = merge::option::overwrite_none)]
68    pub public: Option<bool>,
69    #[serde(skip_serializing_if = "Option::is_none")]
70    #[merge(strategy = merge::option::overwrite_none)]
71    pub pull_request: Option<PullRequest>,
72    #[serde(skip_serializing_if = "Option::is_none")]
73    #[merge(strategy = merge::option::overwrite_none)]
74    pub pull_request_review: Option<PullRequestReview>,
75    #[serde(skip_serializing_if = "Option::is_none")]
76    #[merge(strategy = merge::option::overwrite_none)]
77    pub pull_request_review_comment: Option<PullRequestReviewComment>,
78    #[serde(skip_serializing_if = "Option::is_none")]
79    #[merge(strategy = merge::option::overwrite_none)]
80    pub pull_request_target: Option<PullRequestTarget>,
81    #[serde(skip_serializing_if = "Option::is_none")]
82    #[merge(strategy = merge::option::overwrite_none)]
83    pub push: Option<Push>,
84    #[serde(skip_serializing_if = "Option::is_none")]
85    #[merge(strategy = merge::option::overwrite_none)]
86    pub registry_package: Option<RegistryPackage>,
87    #[serde(skip_serializing_if = "Option::is_none")]
88    #[merge(strategy = merge::option::overwrite_none)]
89    pub release: Option<Release>,
90    #[serde(skip_serializing_if = "Option::is_none")]
91    #[merge(strategy = merge::option::overwrite_none)]
92    pub repository_dispatch: Option<RepositoryDispatch>,
93    #[serde(skip_serializing_if = "Option::is_none")]
94    #[merge(strategy = merge::option::overwrite_none)]
95    pub schedule: Option<Vec<Schedule>>,
96    #[serde(skip_serializing_if = "Option::is_none")]
97    #[merge(strategy = merge::option::overwrite_none)]
98    pub status: Option<bool>,
99    #[serde(skip_serializing_if = "Option::is_none")]
100    #[merge(strategy = merge::option::overwrite_none)]
101    pub watch: Option<Watch>,
102    #[serde(skip_serializing_if = "Option::is_none")]
103    #[merge(strategy = merge::option::overwrite_none)]
104    pub workflow_call: Option<WorkflowCall>,
105    #[serde(skip_serializing_if = "Option::is_none")]
106    #[merge(strategy = merge::option::overwrite_none)]
107    pub workflow_dispatch: Option<WorkflowDispatch>,
108    #[serde(skip_serializing_if = "Option::is_none")]
109    #[merge(strategy = merge::option::overwrite_none)]
110    pub workflow_run: Option<WorkflowRun>,
111}
112
113impl Event {
114    pub fn add_schedule(mut self, schedule: impl Into<Schedule>) -> Self {
115        if let Some(list) = self.schedule.as_mut() {
116            list.push(schedule.into());
117        } else {
118            self.schedule = Some(vec![schedule.into()])
119        }
120
121        self
122    }
123
124    pub fn add_cron_schedule(self, cron: impl ToString) -> Self {
125        self.add_schedule(Schedule::new(cron))
126    }
127}
128
129/// Types of branch protection rule events
130/// See: https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#branch_protection_rule
131#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
132#[serde(rename_all = "snake_case")]
133pub enum BranchProtectionRuleType {
134    /// A branch protection rule was created
135    Created,
136    /// A branch protection rule was edited
137    Edited,
138    /// A branch protection rule was deleted
139    Deleted,
140}
141
142/// Configuration for branch protection rule events
143#[derive(Debug, Clone, Default, Deserialize, Serialize, Setters, PartialEq, Eq)]
144#[setters(strip_option, into)]
145pub struct BranchProtectionRule {
146    #[serde(default, skip_serializing_if = "Vec::is_empty")]
147    pub types: Vec<BranchProtectionRuleType>,
148}
149
150impl BranchProtectionRule {
151    /// Adds a branch protection rule event type to filter on
152    pub fn add_type(mut self, type_: BranchProtectionRuleType) -> Self {
153        self.types.push(type_);
154        self
155    }
156}
157
158/// Types of check run events
159/// See: https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#check_run
160#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
161#[serde(rename_all = "snake_case")]
162pub enum CheckRunType {
163    /// A check run was created
164    Created,
165    /// A check run was requested to be re-run
166    Rerequested,
167    /// A check run was completed
168    Completed,
169    /// A user requested an action from the check run
170    RequestedAction,
171}
172
173#[derive(Debug, Clone, Default, Deserialize, Serialize, Setters, PartialEq, Eq)]
174#[setters(strip_option, into)]
175pub struct CheckRun {
176    #[serde(default, skip_serializing_if = "Vec::is_empty")]
177    pub types: Vec<CheckRunType>,
178}
179
180impl CheckRun {
181    /// Adds a check run event type to filter on
182    pub fn add_type(mut self, type_: CheckRunType) -> Self {
183        self.types.push(type_);
184        self
185    }
186}
187
188/// Types of check suite events
189/// See: https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#check_suite
190#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
191#[serde(rename_all = "snake_case")]
192pub enum CheckSuiteType {
193    /// A check suite has completed
194    Completed,
195}
196
197/// Configuration for check suite events
198
199#[derive(Debug, Clone, Default, Deserialize, Serialize, Setters, PartialEq, Eq)]
200#[setters(strip_option, into)]
201pub struct CheckSuite {
202    #[serde(default, skip_serializing_if = "Vec::is_empty")]
203    pub types: Vec<CheckSuiteType>,
204}
205
206impl CheckSuite {
207    /// Adds a check suite event type to filter on
208    pub fn add_type(mut self, type_: CheckSuiteType) -> Self {
209        self.types.push(type_);
210        self
211    }
212}
213
214/// Configuration for create events (branch or tag creation)
215/// See: https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#create
216#[derive(Debug, Clone, Default, Deserialize, Serialize, Setters, PartialEq, Eq)]
217#[setters(strip_option, into)]
218pub struct Create {
219    /// Filter on specific branch names
220    #[serde(default, skip_serializing_if = "Vec::is_empty")]
221    pub branches: Vec<String>,
222    /// Filter on specific tag names
223    #[serde(default, skip_serializing_if = "Vec::is_empty")]
224    pub tags: Vec<String>,
225}
226
227impl Create {
228    /// Adds a branch name to filter on
229    pub fn add_branch<S: Into<String>>(mut self, branch: S) -> Self {
230        self.branches.push(branch.into());
231        self
232    }
233
234    /// Adds a tag name to filter on
235    pub fn add_tag<S: Into<String>>(mut self, tag: S) -> Self {
236        self.tags.push(tag.into());
237        self
238    }
239}
240
241/// Configuration for delete events (branch or tag deletion)
242/// See: https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#delete
243#[derive(Debug, Clone, Default, Deserialize, Serialize, Setters, PartialEq, Eq)]
244#[setters(strip_option, into)]
245pub struct Delete {
246    /// Filter on specific branch names
247    #[serde(default, skip_serializing_if = "Vec::is_empty")]
248    pub branches: Vec<String>,
249    /// Filter on specific tag names
250    #[serde(default, skip_serializing_if = "Vec::is_empty")]
251    pub tags: Vec<String>,
252}
253
254impl Delete {
255    /// Adds a branch name to filter on
256    pub fn add_branch<S: Into<String>>(mut self, branch: S) -> Self {
257        self.branches.push(branch.into());
258        self
259    }
260
261    /// Adds a tag name to filter on
262    pub fn add_tag<S: Into<String>>(mut self, tag: S) -> Self {
263        self.tags.push(tag.into());
264        self
265    }
266}
267
268/// Types of deployment events
269/// See: https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#deployment
270
271#[derive(Debug, Clone, Default, Deserialize, Serialize, Setters, PartialEq, Eq)]
272#[setters(strip_option, into)]
273pub struct Deployment {
274    /// Filter on specific branch names
275    #[serde(default, skip_serializing_if = "Vec::is_empty")]
276    pub branches: Vec<String>,
277}
278
279impl Deployment {
280    /// Adds a branch name to filter on
281    pub fn add_branch<S: Into<String>>(mut self, branch: S) -> Self {
282        self.branches.push(branch.into());
283        self
284    }
285}
286
287/// Types of deployment status events
288/// See: https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#deployment_status
289
290#[derive(Debug, Clone, Default, Deserialize, Serialize, Setters, PartialEq, Eq)]
291#[setters(strip_option, into)]
292pub struct DeploymentStatus {
293    /// Filter on specific deployment states
294    #[serde(default, skip_serializing_if = "Vec::is_empty")]
295    pub states: Vec<String>,
296}
297
298impl DeploymentStatus {
299    /// Adds a deployment state to filter on
300    pub fn add_state<S: Into<String>>(mut self, state: S) -> Self {
301        self.states.push(state.into());
302        self
303    }
304}
305
306/// Types of discussion events
307/// See: https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#discussion
308#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
309#[serde(rename_all = "snake_case")]
310pub enum DiscussionType {
311    /// A discussion was created
312    Created,
313    /// A discussion was edited
314    Edited,
315    /// A discussion was deleted
316    Deleted,
317    /// A discussion was transferred between repositories
318    Transferred,
319    /// A discussion was pinned
320    Pinned,
321    /// A discussion was unpinned
322    Unpinned,
323    /// A discussion was labeled
324    Labeled,
325    /// A discussion was unlabeled
326    Unlabeled,
327    /// A discussion was locked
328    Locked,
329    /// A discussion was unlocked
330    Unlocked,
331    /// A discussion's category was changed
332    CategoryChanged,
333    /// A discussion was marked as answered
334    Answered,
335    /// A discussion was unmarked as answered
336    Unanswered,
337}
338
339/// Configuration for discussion events
340
341#[derive(Debug, Clone, Default, Deserialize, Serialize, Setters, PartialEq, Eq)]
342pub struct Discussion {
343    /// Filter on specific discussion event types
344    #[serde(default, skip_serializing_if = "Vec::is_empty")]
345    pub types: Vec<DiscussionType>,
346}
347
348impl Discussion {
349    /// Adds a discussion event type to filter on
350    pub fn add_type(mut self, type_: DiscussionType) -> Self {
351        self.types.push(type_);
352        self
353    }
354}
355
356/// Types of discussion comment events
357/// See: https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#discussion_comment
358#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
359#[serde(rename_all = "snake_case")]
360pub enum DiscussionCommentType {
361    /// A discussion comment was created
362    Created,
363    /// A discussion comment was edited
364    Edited,
365    /// A discussion comment was deleted
366    Deleted,
367}
368
369/// Configuration for discussion comment events
370
371#[derive(Debug, Clone, Default, Deserialize, Serialize, Setters, PartialEq, Eq)]
372pub struct DiscussionComment {
373    /// Filter on specific discussion comment event types
374    #[serde(default, skip_serializing_if = "Vec::is_empty")]
375    pub types: Vec<DiscussionCommentType>,
376}
377
378impl DiscussionComment {
379    /// Adds a discussion comment event type to filter on
380    pub fn add_type(mut self, type_: DiscussionCommentType) -> Self {
381        self.types.push(type_);
382        self
383    }
384}
385
386/// Configuration for issue comment events
387/// See: https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#issue_comment
388#[derive(Debug, Clone, Default, Deserialize, Serialize, Setters, PartialEq, Eq)]
389pub struct IssueComment {
390    /// Filter on specific issue comment event types
391    #[serde(default, skip_serializing_if = "Vec::is_empty")]
392    pub types: Vec<IssueCommentType>,
393}
394
395/// Types of issue comment events
396#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
397#[serde(rename_all = "snake_case")]
398pub enum IssueCommentType {
399    /// An issue comment was created
400    Created,
401    /// An issue comment was edited
402    Edited,
403    /// An issue comment was deleted
404    Deleted,
405}
406
407impl IssueComment {
408    /// Adds an issue comment event type to filter on
409    pub fn add_type(mut self, type_: IssueCommentType) -> Self {
410        self.types.push(type_);
411        self
412    }
413}
414
415/// Types of issue events
416/// See: https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#issues
417#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
418#[serde(rename_all = "snake_case")]
419pub enum IssuesType {
420    /// An issue was opened
421    Opened,
422    /// An issue was edited
423    Edited,
424    /// An issue was deleted
425    Deleted,
426    /// An issue was transferred between repositories
427    Transferred,
428    /// An issue was pinned
429    Pinned,
430    /// An issue was unpinned
431    Unpinned,
432    /// An issue was closed
433    Closed,
434    /// A closed issue was reopened
435    Reopened,
436    /// An issue was assigned to a user
437    Assigned,
438    /// An issue was unassigned from a user
439    Unassigned,
440    /// A label was added to an issue
441    Labeled,
442    /// A label was removed from an issue
443    Unlabeled,
444    /// An issue was locked
445    Locked,
446    /// An issue was unlocked
447    Unlocked,
448    /// An issue was added to a milestone
449    Milestoned,
450    /// An issue was removed from a milestone
451    Demilestoned,
452}
453
454/// Configuration for issue events
455
456#[derive(Debug, Clone, Default, Deserialize, Serialize, Setters, PartialEq, Eq)]
457#[setters(strip_option, into)]
458pub struct Issues {
459    /// Filter on specific issue event types
460    #[serde(default, skip_serializing_if = "Vec::is_empty")]
461    pub types: Vec<IssuesType>,
462}
463
464impl Issues {
465    /// Adds an issue event type to filter on
466    pub fn add_type(mut self, type_: IssuesType) -> Self {
467        self.types.push(type_);
468        self
469    }
470}
471
472/// Types of label events
473/// See: https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#label
474#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
475#[serde(rename_all = "snake_case")]
476pub enum LabelType {
477    /// A label was created
478    Created,
479    /// A label was edited
480    Edited,
481    /// A label was deleted
482    Deleted,
483}
484
485/// Configuration for label events
486
487#[derive(Debug, Clone, Default, Deserialize, Serialize, Setters, PartialEq, Eq)]
488#[setters(strip_option, into)]
489pub struct Label {
490    /// Filter on specific label event types
491    #[serde(default, skip_serializing_if = "Vec::is_empty")]
492    pub types: Vec<LabelType>,
493}
494
495impl Label {
496    /// Adds a label event type to filter on
497    pub fn add_type(mut self, type_: LabelType) -> Self {
498        self.types.push(type_);
499        self
500    }
501}
502
503#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
504#[serde(rename_all = "snake_case")]
505pub enum MergeGroupType {
506    ChecksRequested,
507}
508
509#[derive(Debug, Clone, Default, Deserialize, Serialize, Setters, PartialEq, Eq)]
510#[setters(strip_option, into)]
511pub struct MergeGroup {
512    #[serde(default, skip_serializing_if = "Vec::is_empty")]
513    pub types: Vec<MergeGroupType>,
514}
515
516impl MergeGroup {
517    pub fn add_type(mut self, type_: MergeGroupType) -> Self {
518        self.types.push(type_);
519        self
520    }
521}
522
523#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
524#[serde(rename_all = "snake_case")]
525pub enum MilestoneType {
526    Created,
527    Closed,
528    Opened,
529    Edited,
530    Deleted,
531}
532
533#[derive(Debug, Clone, Default, Deserialize, Serialize, Setters, PartialEq, Eq)]
534#[setters(strip_option, into)]
535pub struct Milestone {
536    #[serde(default, skip_serializing_if = "Vec::is_empty")]
537    pub types: Vec<MilestoneType>,
538}
539
540impl Milestone {
541    pub fn add_type(mut self, type_: MilestoneType) -> Self {
542        self.types.push(type_);
543        self
544    }
545}
546
547#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
548#[serde(rename_all = "snake_case")]
549pub enum PullRequestType {
550    Assigned,
551    Unassigned,
552    Labeled,
553    Unlabeled,
554    Opened,
555    Edited,
556    Closed,
557    Reopened,
558    Synchronize,
559    ReadyForReview,
560    Locked,
561    Unlocked,
562    ReviewRequested,
563    ReviewRequestRemoved,
564}
565
566#[derive(Debug, Clone, Default, Deserialize, Serialize, Setters, PartialEq, Eq)]
567#[serde(rename_all = "kebab-case")]
568#[setters(strip_option, into)]
569pub struct PullRequest {
570    #[serde(default, skip_serializing_if = "Vec::is_empty")]
571    pub types: Vec<PullRequestType>,
572    #[serde(default, skip_serializing_if = "Vec::is_empty")]
573    pub branches: Vec<String>,
574    #[serde(default, skip_serializing_if = "Vec::is_empty")]
575    pub paths: Vec<String>,
576    /// Ignore specific file paths
577    #[serde(default, skip_serializing_if = "Vec::is_empty")]
578    pub paths_ignore: Vec<String>,
579}
580
581impl PullRequest {
582    pub fn add_type(mut self, type_: PullRequestType) -> Self {
583        self.types.push(type_);
584        self
585    }
586
587    pub fn add_branch<S: Into<String>>(mut self, branch: S) -> Self {
588        self.branches.push(branch.into());
589        self
590    }
591
592    /// Adds a file path to filter on
593    pub fn add_path<S: Into<String>>(mut self, path: S) -> Self {
594        self.paths.push(path.into());
595        self
596    }
597
598    /// Adds a file path to not trigger on
599    pub fn add_ignored_path<S: Into<String>>(mut self, path: S) -> Self {
600        self.paths_ignore.push(path.into());
601        self
602    }
603}
604
605/// Types of pull request review events
606/// See: https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#pull_request_review
607#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
608#[serde(rename_all = "snake_case")]
609pub enum PullRequestReviewType {
610    /// A review was submitted for a pull request
611    Submitted,
612    /// A review was edited
613    Edited,
614    /// A review was dismissed
615    Dismissed,
616}
617
618/// Configuration for pull request review events
619
620#[derive(Debug, Clone, Default, Deserialize, Serialize, Setters, PartialEq, Eq)]
621#[setters(strip_option, into)]
622pub struct PullRequestReview {
623    /// Filter on specific pull request review event types
624    #[serde(default, skip_serializing_if = "Vec::is_empty")]
625    pub types: Vec<PullRequestReviewType>,
626}
627
628impl PullRequestReview {
629    /// Adds a pull request review event type to filter on
630    pub fn add_type(mut self, type_: PullRequestReviewType) -> Self {
631        self.types.push(type_);
632        self
633    }
634}
635
636/// Types of pull request review comment events
637/// See: https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#pull_request_review_comment
638#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
639#[serde(rename_all = "snake_case")]
640pub enum PullRequestReviewCommentType {
641    /// A review comment was created
642    Created,
643    /// A review comment was edited
644    Edited,
645    /// A review comment was deleted
646    Deleted,
647}
648
649/// Configuration for pull request review comment events
650#[derive(Debug, Clone, Default, Deserialize, Serialize, Setters, PartialEq, Eq)]
651#[setters(strip_option, into)]
652pub struct PullRequestReviewComment {
653    /// Filter on specific pull request review comment event types
654    #[serde(default, skip_serializing_if = "Vec::is_empty")]
655    pub types: Vec<PullRequestReviewCommentType>,
656}
657
658impl PullRequestReviewComment {
659    /// Adds a pull request review comment event type to filter on
660    pub fn add_type(mut self, type_: PullRequestReviewCommentType) -> Self {
661        self.types.push(type_);
662        self
663    }
664}
665
666/// Configuration for pull request target events
667/// See: https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#pull_request_target
668#[derive(Debug, Clone, Default, Deserialize, Serialize, Setters, PartialEq, Eq)]
669#[serde(rename_all = "kebab-case")]
670#[setters(strip_option, into)]
671pub struct PullRequestTarget {
672    /// Filter on specific pull request event types
673    #[serde(default, skip_serializing_if = "Vec::is_empty")]
674    pub types: Vec<PullRequestType>,
675    /// Filter on specific branch names
676    #[serde(default, skip_serializing_if = "Vec::is_empty")]
677    pub branches: Vec<String>,
678    #[serde(default, skip_serializing_if = "Vec::is_empty")]
679    pub paths: Vec<String>,
680    /// Ignore specific file paths
681    #[serde(default, skip_serializing_if = "Vec::is_empty")]
682    pub paths_ignore: Vec<String>,
683}
684
685impl PullRequestTarget {
686    /// Adds a pull request event type to filter on
687    pub fn add_type(mut self, type_: PullRequestType) -> Self {
688        self.types.push(type_);
689        self
690    }
691
692    /// Adds a branch name to filter on
693    pub fn add_branch<S: Into<String>>(mut self, branch: S) -> Self {
694        self.branches.push(branch.into());
695        self
696    }
697
698    /// Adds a file path to filter on
699    pub fn add_path<S: Into<String>>(mut self, path: S) -> Self {
700        self.paths.push(path.into());
701        self
702    }
703
704    /// Adds a file path to not trigger on
705    pub fn add_ignored_path<S: Into<String>>(mut self, path: S) -> Self {
706        self.paths_ignore.push(path.into());
707        self
708    }
709}
710
711/// Configuration for push events
712/// See: https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#push
713#[derive(Debug, Clone, Default, Deserialize, Serialize, Setters, PartialEq, Eq)]
714#[serde(rename_all = "kebab-case")]
715#[setters(strip_option, into)]
716pub struct Push {
717    /// Filter on specific branch names
718    #[serde(default, skip_serializing_if = "Vec::is_empty")]
719    pub branches: Vec<String>,
720    /// Filter on specific file paths
721    #[serde(default, skip_serializing_if = "Vec::is_empty")]
722    pub paths: Vec<String>,
723    /// Ignore specific file paths
724    #[serde(default, skip_serializing_if = "Vec::is_empty")]
725    pub paths_ignore: Vec<String>,
726    /// Filter on specific tags
727    #[serde(default, skip_serializing_if = "Vec::is_empty")]
728    pub tags: Vec<String>,
729}
730
731impl Push {
732    /// Adds a branch name to filter on
733    pub fn add_branch<S: Into<String>>(mut self, branch: S) -> Self {
734        self.branches.push(branch.into());
735        self
736    }
737
738    /// Adds a file path to filter on
739    pub fn add_path<S: Into<String>>(mut self, path: S) -> Self {
740        self.paths.push(path.into());
741        self
742    }
743
744    /// Adds a file path to not trigger on
745    pub fn add_ignored_path<S: Into<String>>(mut self, path: S) -> Self {
746        self.paths_ignore.push(path.into());
747        self
748    }
749
750    /// Adds a tag name to filter on
751    pub fn add_tag<S: Into<String>>(mut self, tag: S) -> Self {
752        self.tags.push(tag.into());
753        self
754    }
755}
756
757/// Types of registry package events
758/// See: https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#registry_package
759#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
760#[serde(rename_all = "snake_case")]
761pub enum RegistryPackageType {
762    /// A package was published
763    Published,
764    /// A package was updated
765    Updated,
766}
767
768/// Configuration for registry package events
769
770#[derive(Debug, Clone, Default, Deserialize, Serialize, Setters, PartialEq, Eq)]
771#[setters(strip_option, into)]
772pub struct RegistryPackage {
773    /// Filter on specific registry package event types
774    #[serde(default, skip_serializing_if = "Vec::is_empty")]
775    pub types: Vec<RegistryPackageType>,
776}
777
778impl RegistryPackage {
779    /// Adds a registry package event type to filter on
780    pub fn add_type(mut self, type_: RegistryPackageType) -> Self {
781        self.types.push(type_);
782        self
783    }
784}
785
786/// Types of release events
787/// See: https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#release
788#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
789#[serde(rename_all = "snake_case")]
790pub enum ReleaseType {
791    /// A release was published
792    Published,
793    /// A release was unpublished
794    Unpublished,
795    /// A release was created
796    Created,
797    /// A release was edited
798    Edited,
799    /// A release was deleted
800    Deleted,
801    /// A release was marked as a pre-release
802    Prereleased,
803    /// A release was released
804    Released,
805}
806
807/// Configuration for release events
808
809#[derive(Debug, Clone, Default, Deserialize, Serialize, Setters, PartialEq, Eq)]
810#[setters(strip_option, into)]
811pub struct Release {
812    /// Filter on specific release event types
813    #[serde(default, skip_serializing_if = "Vec::is_empty")]
814    pub types: Vec<ReleaseType>,
815}
816
817impl Release {
818    /// Adds a release event type to filter on
819    pub fn add_type(mut self, type_: ReleaseType) -> Self {
820        self.types.push(type_);
821        self
822    }
823}
824
825#[derive(Debug, Clone, Default, Deserialize, Serialize, Setters, PartialEq, Eq)]
826#[setters(strip_option, into)]
827pub struct RepositoryDispatch {
828    #[serde(default, skip_serializing_if = "Vec::is_empty")]
829    pub types: Vec<String>,
830}
831
832impl RepositoryDispatch {
833    pub fn add_type<S: Into<String>>(mut self, type_: S) -> Self {
834        self.types.push(type_.into());
835        self
836    }
837}
838
839#[derive(Debug, Clone, Default, Deserialize, Serialize, Setters, PartialEq, Eq)]
840#[setters(strip_option, into)]
841pub struct Schedule {
842    pub cron: String,
843}
844
845impl Schedule {
846    pub fn new(cron: impl ToString) -> Self {
847        Self { cron: cron.to_string() }
848    }
849}
850
851#[derive(Debug, Clone, Default, Deserialize, Serialize, Setters, PartialEq, Eq)]
852#[setters(strip_option, into)]
853pub struct Watch {
854    #[serde(default, skip_serializing_if = "Vec::is_empty")]
855    pub types: Vec<String>,
856}
857
858impl Watch {
859    pub fn add_type<S: Into<String>>(mut self, type_: S) -> Self {
860        self.types.push(type_.into());
861        self
862    }
863}
864
865/// Configuration for workflow call events
866/// See: https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#workflow_call
867#[derive(Debug, Clone, Default, Deserialize, Serialize, Setters, PartialEq, Eq)]
868#[setters(strip_option, into)]
869pub struct WorkflowCall {
870    /// Inputs for the workflow call
871    #[serde(default, skip_serializing_if = "IndexMap::is_empty")]
872    pub inputs: IndexMap<String, WorkflowCallInput>,
873    /// Outputs from the workflow call
874    #[serde(default, skip_serializing_if = "IndexMap::is_empty")]
875    pub outputs: IndexMap<String, WorkflowCallOutput>,
876    /// Secrets for the workflow call
877    #[serde(default, skip_serializing_if = "IndexMap::is_empty")]
878    pub secrets: IndexMap<String, WorkflowCallSecret>,
879}
880
881impl WorkflowCall {
882    pub fn add_input(mut self, name: impl Into<String>, input: WorkflowCallInput) -> Self {
883        self.inputs.insert(name.into(), input);
884        self
885    }
886}
887
888/// Configuration for workflow call input
889#[derive(Debug, Clone, Default, Deserialize, Serialize, PartialEq, Setters, Eq)]
890#[setters(strip_option, into)]
891pub struct WorkflowCallInput {
892    /// Description of the input
893    #[serde(skip_serializing_if = "String::is_empty")]
894    pub description: String,
895    /// Indicates if the input is required
896    #[serde(skip_serializing_if = "is_default")]
897    pub required: bool,
898    /// Type of the input
899    #[serde(rename = "type")]
900    pub input_type: String,
901    /// Default value for the input
902    #[serde(skip_serializing_if = "Option::is_none")]
903    pub default: Option<String>,
904}
905
906/// Configuration for workflow call output
907#[derive(Debug, Clone, Default, Deserialize, Serialize, PartialEq, Setters, Eq)]
908#[setters(strip_option, into)]
909pub struct WorkflowCallOutput {
910    /// Description of the output
911    #[serde(skip_serializing_if = "String::is_empty")]
912    pub description: String,
913    /// Value of the output
914    #[serde(skip_serializing_if = "String::is_empty")]
915    pub value: String,
916}
917
918/// Configuration for workflow call secret
919#[derive(Debug, Clone, Default, Deserialize, Serialize, PartialEq, Setters, Eq)]
920#[setters(strip_option, into)]
921pub struct WorkflowCallSecret {
922    /// Description of the secret
923    #[serde(skip_serializing_if = "String::is_empty")]
924    pub description: String,
925    /// Indicates if the secret is required
926    pub required: bool,
927}
928
929/// Configuration for workflow dispatch events
930/// See: https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#workflow_dispatch
931
932#[derive(Debug, Clone, Default, Deserialize, Serialize, Setters, PartialEq, Eq)]
933#[setters(strip_option, into)]
934pub struct WorkflowDispatch {
935    /// Inputs for the workflow dispatch
936    #[serde(skip_serializing_if = "IndexMap::is_empty")]
937    pub inputs: IndexMap<String, WorkflowDispatchInput>,
938}
939
940/// Configuration for workflow dispatch input
941#[derive(Debug, Clone, Default, Deserialize, Serialize, Setters, PartialEq, Eq)]
942#[setters(strip_option, into)]
943pub struct WorkflowDispatchInput {
944    /// Description of the input
945    #[serde(skip_serializing_if = "String::is_empty")]
946    pub description: String,
947    /// Indicates if the input is required
948    #[serde(skip_serializing_if = "is_default")]
949    pub required: bool,
950    /// Type of the input
951    #[serde(rename = "type")]
952    pub input_type: String,
953    /// Default value for the input
954    #[serde(skip_serializing_if = "Option::is_none")]
955    #[setters(skip)]
956    pub default: Option<String>,
957    /// The options of the dropdown list, if the type is a choice
958    #[serde(skip_serializing_if = "Vec::is_empty")]
959    #[setters(skip)]
960    pub options: Vec<String>,
961}
962
963impl WorkflowDispatchInput {
964    pub fn set_default(self, value: impl Into<String>) -> Self {
965        Self { default: Some(value.into()), ..self }
966    }
967
968    pub fn options<T: ToString, I: IntoIterator<Item = T>>(self, iter: I) -> Self {
969        Self {
970            options: iter.into_iter().map(|v| v.to_string()).collect(),
971            ..self
972        }
973    }
974}
975
976/// Types of workflow run events
977/// See: https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#workflow_run
978#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
979#[serde(rename_all = "snake_case")]
980pub enum WorkflowRunType {
981    /// A workflow run was completed
982    Completed,
983    /// A workflow run was requested
984    Requested,
985    /// A workflow run is in progress
986    InProgress,
987}
988
989/// Configuration for workflow run events
990#[derive(Debug, Clone, Default, Deserialize, Serialize, Setters, PartialEq, Eq)]
991#[setters(strip_option, into)]
992pub struct WorkflowRun {
993    /// Filter on specific workflow run event types
994    #[serde(default, skip_serializing_if = "Vec::is_empty")]
995    pub types: Vec<WorkflowRunType>,
996    /// Filter on specific workflow names
997    #[serde(default, skip_serializing_if = "Vec::is_empty")]
998    pub workflows: Vec<String>,
999    /// Filter on specific branch names
1000    #[serde(default, skip_serializing_if = "Vec::is_empty")]
1001    pub branches: Vec<String>,
1002}
1003
1004impl WorkflowRun {
1005    /// Adds a workflow run event type to filter on
1006    pub fn add_type(mut self, type_: WorkflowRunType) -> Self {
1007        self.types.push(type_);
1008        self
1009    }
1010
1011    /// Adds a workflow name to filter on
1012    pub fn add_workflow<S: Into<String>>(mut self, workflow: S) -> Self {
1013        self.workflows.push(workflow.into());
1014        self
1015    }
1016
1017    /// Adds a branch name to filter on
1018    pub fn add_branch<S: Into<String>>(mut self, branch: S) -> Self {
1019        self.branches.push(branch.into());
1020        self
1021    }
1022}