josh_github_graphql/operations/
repo.rs1use crate::connection::GithubApiConnection;
2
3use josh_github_codegen_graphql::{
4 get_default_branch,
5 get_repository_rulesets::{self, RepositoryRulesetTarget, RuleEnforcement},
6 get_ruleset_required_checks::{
7 self, GetRulesetRequiredChecksNode, RequiredStatusChecksInfoParameters,
8 },
9 GetDefaultBranch, GetRepositoryRulesets, GetRulesetRequiredChecks,
10};
11
12#[derive(Debug)]
14pub struct RepositoryRuleset {
15 pub id: String,
16 pub name: String,
17 pub enforcement: RuleEnforcement,
18 pub target: Option<RepositoryRulesetTarget>,
19 pub include_refs: Vec<String>,
20 pub exclude_refs: Vec<String>,
21}
22
23#[derive(Debug, PartialEq, Eq, PartialOrd, Ord)]
25pub struct RequiredStatusCheck {
26 pub context: String,
27 pub integration_id: Option<i64>,
28}
29
30impl GithubApiConnection {
31 pub async fn get_default_branch(
33 &self,
34 owner: &str,
35 name: &str,
36 ) -> anyhow::Result<Option<(String, String)>> {
37 let variables = get_default_branch::Variables {
38 owner: owner.to_string(),
39 name: name.to_string(),
40 };
41
42 let response = self.make_request::<GetDefaultBranch>(variables).await?;
43 let repo = match response.repository {
44 Some(r) => r,
45 None => return Ok(None),
46 };
47 let default_ref = match repo.default_branch_ref {
48 Some(r) => r,
49 None => return Ok(None),
50 };
51
52 let target = match default_ref.target {
53 Some(t) => t,
54 None => return Ok(None),
55 };
56
57 Ok(Some((default_ref.name, target.oid)))
58 }
59
60 pub async fn get_repository_rulesets(
62 &self,
63 owner: &str,
64 name: &str,
65 ) -> anyhow::Result<Vec<RepositoryRuleset>> {
66 let variables = get_repository_rulesets::Variables {
67 owner: owner.to_string(),
68 name: name.to_string(),
69 };
70
71 let response = self
72 .make_request::<GetRepositoryRulesets>(variables)
73 .await?;
74
75 let rulesets = response
76 .repository
77 .and_then(|r| r.rulesets)
78 .and_then(|r| r.nodes)
79 .unwrap_or_default();
80
81 Ok(rulesets
82 .into_iter()
83 .flatten()
84 .map(|node| {
85 let (include_refs, exclude_refs) = match node.conditions.ref_name {
86 Some(ref_name) => (ref_name.include, ref_name.exclude),
87 None => (vec![], vec![]),
88 };
89 RepositoryRuleset {
90 id: node.id,
91 name: node.name,
92 enforcement: node.enforcement,
93 target: node.target,
94 include_refs,
95 exclude_refs,
96 }
97 })
98 .collect())
99 }
100
101 pub async fn get_ruleset_required_checks(
103 &self,
104 ruleset_id: &str,
105 ) -> anyhow::Result<Vec<RequiredStatusCheck>> {
106 let variables = get_ruleset_required_checks::Variables {
107 ruleset_id: ruleset_id.to_string(),
108 };
109
110 let response = self
111 .make_request::<GetRulesetRequiredChecks>(variables)
112 .await?;
113
114 let rules = match response.node {
115 Some(GetRulesetRequiredChecksNode::RepositoryRuleset(ruleset)) => {
116 ruleset.rules.and_then(|r| r.nodes).unwrap_or_default()
117 }
118 _ => return Ok(vec![]),
119 };
120
121 let checks = rules
122 .into_iter()
123 .flatten()
124 .filter_map(|rule| match rule.parameters {
125 Some(RequiredStatusChecksInfoParameters::RequiredStatusChecksParameters(
126 params,
127 )) => Some(params.required_status_checks),
128 _ => None,
129 })
130 .flatten()
131 .map(|check| RequiredStatusCheck {
132 context: check.context,
133 integration_id: check.integration_id,
134 })
135 .collect();
136
137 Ok(checks)
138 }
139}