Skip to content

Commit

Permalink
Better payload construction
Browse files Browse the repository at this point in the history
  • Loading branch information
aisrael committed Jun 13, 2023
1 parent 4d4d983 commit 9ad8351
Show file tree
Hide file tree
Showing 4 changed files with 81 additions and 23 deletions.
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "ghctl"
version = "0.2.0"
version = "0.2.1"
edition = "2021"
description = "A GitHub command line utility"
documentation = "https://docs.rs/ghctl"
Expand Down
60 changes: 52 additions & 8 deletions src/ghctl/repo/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ use serde::{Deserialize, Serialize};
use std::collections::HashMap;

use crate::github;
use crate::utils::split_some_repo_full_name;
use github::AddRepositoryCollaboratorResult;

/// A struct that represents the ghctl configuration for a GitHub repository
Expand All @@ -27,7 +28,7 @@ pub struct RepoEnvironment {
#[derive(Debug, Serialize, Deserialize)]
pub struct BranchProtectionRule {
pub require_pull_request: Option<RequirePullRequest>,
pub required_status_checks: Option<Vec<String>>,
pub required_status_checks: Option<RequiredStatusChecks>,
}

#[derive(Debug, Serialize, Deserialize)]
Expand All @@ -42,9 +43,36 @@ pub struct RequirePullRequestSettings {
pub required_approving_review_count: Option<u8>,
}

#[derive(Debug, Serialize, Deserialize)]
pub struct RequiredStatusChecks {
pub strict: Option<bool>,
pub contexts: Option<Vec<String>>,
}

/// The `repo config get` command
pub async fn get(_context: &crate::ghctl::Context, repo_full_name: &String) -> Result<()> {
error!("Not yet implemented: repo config get {}", repo_full_name);
pub async fn get(context: &crate::ghctl::Context, repo_full_name: &String) -> Result<()> {
let (owner, repo) = split_some_repo_full_name(repo_full_name)?;

let octocrab = OctocrabBuilder::default()
.personal_token(context.access_token.to_owned())
.add_header(
HeaderName::from_static("accept"),
"application/vnd.github.v3.repository+json".to_string(),
)
.add_header(
HeaderName::from_static("x-github-api-version"),
"2022-11-28".to_string(),
)
.build()?;

match octocrab.repos(owner, repo).get().await {
Ok(repo) => {
println!("{}", serde_json::to_string_pretty(&repo).unwrap());
}
Err(e) => {
error!("Error: {}", e);
}
}

Ok(())
}
Expand Down Expand Up @@ -577,7 +605,7 @@ async fn apply_branch_protection_rule(
branch: &str,
branch_protection_rule: &BranchProtectionRule,
) -> Result<()> {
let mut repository_branch_protection = github::RepositoryBranchProtection::new();
let mut repository_branch_protection = github::RepositoryBranchProtectionRequest::new();

if let Some(require_pull_request) = &branch_protection_rule.require_pull_request {
repository_branch_protection.required_pull_request_reviews = match require_pull_request {
Expand All @@ -604,8 +632,11 @@ async fn apply_branch_protection_rule(

if let Some(required_status_checks) = &branch_protection_rule.required_status_checks {
repository_branch_protection.required_status_checks = Some(github::RequiredStatusChecks {
strict: false,
contexts: required_status_checks.clone(),
strict: required_status_checks.strict.unwrap_or(false),
contexts: match required_status_checks.contexts.as_ref() {
Some(contexts) => contexts.clone(),
None => Vec::new(),
},
enforcement_level: None,
});
}
Expand All @@ -617,8 +648,18 @@ async fn apply_branch_protection_rule(
branch,
&repository_branch_protection,
)
.await?;
println!("{:?}", result);
.await;

match result {
Ok(repository_branch_protection) => debug!("{:?}", repository_branch_protection),
Err(e) => {
debug!(
"{}",
serde_json::to_string_pretty(&repository_branch_protection)?
);
error!("{:?}", e);
}
}

Ok(())
}
Expand Down Expand Up @@ -736,6 +777,9 @@ mod tests {
- gitsudo-io/a-team
branch_protection_rules:
main:
required_status_checks:
contexts:
- "mix/test"
require_pull_request:
required_approving_review_count: 1
"#,
Expand Down
40 changes: 27 additions & 13 deletions src/github.rs
Original file line number Diff line number Diff line change
Expand Up @@ -163,12 +163,28 @@ pub struct RepositoryBranchProtection {
pub required_signatures: Option<RequiredSignatures>,
}

impl RepositoryBranchProtection {
pub fn new() -> RepositoryBranchProtection {
RepositoryBranchProtection {
#[derive(Debug, Serialize, Deserialize)]
pub struct RepositoryBranchProtectionRequest {
#[serde(skip_serializing_if = "Option::is_none")]
pub name: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub required_status_checks: Option<RequiredStatusChecks>,
pub enforce_admins: bool,
#[serde(skip_serializing_if = "Option::is_none")]
pub required_pull_request_reviews: Option<RequiredPullRequestReviews>,
pub restrictions: Option<Restrictions>,
#[serde(skip_serializing_if = "Option::is_none")]
pub required_linear_history: Option<RequiredLinearHistory>,
#[serde(skip_serializing_if = "Option::is_none")]
pub required_signatures: Option<RequiredSignatures>,
}

impl RepositoryBranchProtectionRequest {
pub fn new() -> RepositoryBranchProtectionRequest {
RepositoryBranchProtectionRequest {
name: None,
required_status_checks: None,
enforce_admins: None,
enforce_admins: false,
required_pull_request_reviews: None,
restrictions: None,
required_linear_history: None,
Expand All @@ -181,6 +197,7 @@ impl RepositoryBranchProtection {
pub struct RequiredStatusChecks {
pub strict: bool,
pub contexts: Vec<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub enforcement_level: Option<String>,
}

Expand Down Expand Up @@ -243,18 +260,15 @@ pub async fn update_branch_protection(
owner: &str,
repo: &str,
branch: &str,
repository_branch_protection: &RepositoryBranchProtection,
repository_branch_protection_request: &RepositoryBranchProtectionRequest,
) -> Result<RepositoryBranchProtection> {
let route = format!("/repos/{owner}/{repo}/branches/{branch}/protection");
match octocrab
.put(route, Some(repository_branch_protection))
.put(route, Some(repository_branch_protection_request))
.await
{
Ok(repository_branch_protection) => Ok(repository_branch_protection),
Err(e) => {
error!("Error: {}", e);
Err(anyhow::anyhow!(e))
}
Err(e) => Err(anyhow::anyhow!(e)),
}
}

Expand Down Expand Up @@ -339,10 +353,10 @@ mod tests {
enforcement_level: None,
};

let repository_branch_protection = RepositoryBranchProtection {
let repository_branch_protection_request = RepositoryBranchProtectionRequest {
name: Some(branch.to_owned()),
required_status_checks: Some(required_status_checks),
enforce_admins: None,
enforce_admins: false,
required_pull_request_reviews: None,
restrictions: None,
required_linear_history: None,
Expand All @@ -354,7 +368,7 @@ mod tests {
&owner,
&repo,
&branch,
&repository_branch_protection,
&repository_branch_protection_request,
)
.await;

Expand Down

0 comments on commit 9ad8351

Please sign in to comment.