Skip to content

Commit

Permalink
Calculate GitHub repo slug from URL and remove separate options.
Browse files Browse the repository at this point in the history
Since the gitsha is needed to update status, it never made much sense to
have a separate option for this. Also, commit status updates are now turned
on if you pass --github-context.
  • Loading branch information
bittrance committed Nov 3, 2023
1 parent 79d7a3b commit aad5b5b
Show file tree
Hide file tree
Showing 3 changed files with 25 additions and 19 deletions.
19 changes: 10 additions & 9 deletions src/opts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,16 +40,13 @@ pub struct CliOptions {
/// Environment variable for action
#[clap(long)]
pub environment: Vec<String>,
/// GitHub App ID
/// GitHub App ID for authentication with private repos and commit status updates
#[clap(long)]
pub github_app_id: Option<String>,
/// GitHub App private key file
#[clap(long)]
pub github_private_key_file: Option<PathBuf>,
/// Update GitHub commit status on this repo
#[clap(long)]
pub github_repo_slug: Option<String>,
/// Use this context when updating GitHub commit status
/// Turn on updating GitHub commit status with this context (requires auth flags)
#[clap(long)]
pub github_context: Option<String>,
/// Check repo for changes at this interval (e.g. 1h, 30m, 10s)
Expand Down Expand Up @@ -101,13 +98,17 @@ struct ConfigFile {

fn into_task(mut config: GitTaskConfig, opts: &CliOptions) -> ScheduledTask<GitWorkload> {
let github = config.github.take();
let mut slug = None; // TODO Yuck!
if let Some(ref github) = github {
config
.upgrade_url_provider(|current| GithubUrlProvider::new(current.url().clone(), github));
let provider = GithubUrlProvider::new(config.git.url.url().clone(), github);
slug = Some(provider.repo_slug());
config.upgrade_url_provider(|_| provider);
}
let mut work = GitWorkload::from_config(config, opts);
if let Some(ref github) = github {
work.watch(github_watcher(github.clone()));
if let Some(github) = github {
if github.notify_context.is_some() {
work.watch(github_watcher(slug.unwrap(), github));
}
}
let (tx, rx) = channel();
work.watch(move |event| {
Expand Down
23 changes: 14 additions & 9 deletions src/task/github.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,8 @@ use crate::{errors::GitOpsError, git::UrlProvider, opts::CliOptions, receiver::W
pub struct GithubConfig {
app_id: String,
private_key_file: PathBuf,
notify_slug: Option<String>,
#[serde(default = "GithubConfig::default_context")]
notify_context: Option<String>,
pub notify_context: Option<String>,
}

impl GithubConfig {
Expand All @@ -40,7 +39,6 @@ impl TryFrom<&CliOptions> for Option<GithubConfig> {
(Some(app_id), Some(private_key_file)) => Ok(Some(GithubConfig {
app_id: app_id.clone(),
private_key_file: private_key_file.clone(),
notify_slug: opts.github_repo_slug.clone(),
notify_context: opts.github_context.clone(),
})),
_ => Err(GitOpsError::InvalidNotifyConfig),
Expand All @@ -63,6 +61,10 @@ impl GithubUrlProvider {
private_key_file: config.private_key_file.clone(),
}
}

pub fn repo_slug(&self) -> String {
self.url.path.to_string().replace(".git", "")[1..].to_owned()
}
}

impl UrlProvider for GithubUrlProvider {
Expand All @@ -71,10 +73,9 @@ impl UrlProvider for GithubUrlProvider {
}

fn auth_url(&self) -> Result<Url, GitOpsError> {
let repo_slug = self.url.path.to_string().replace(".git", "")[1..].to_owned();
let client = http_client();
let jwt_token = generate_jwt(&self.app_id, &self.private_key_file)?;
let installation_id = get_installation_id(&repo_slug, &client, &jwt_token)?;
let installation_id = get_installation_id(&self.repo_slug(), &client, &jwt_token)?;
let access_token = get_access_token(installation_id, &client, &jwt_token)?;
// TODO Newer version of gix-url has set_username/set_password
Ok(Url::from_parts(
Expand Down Expand Up @@ -183,6 +184,7 @@ fn get_access_token(
}

pub fn update_commit_status(
repo_slug: &str,
config: &GithubConfig,
sha: &ObjectId,
status: GitHubStatus,
Expand All @@ -191,14 +193,12 @@ pub fn update_commit_status(
let config = config.clone();
let client = http_client();
let jwt_token = generate_jwt(&config.app_id, &config.private_key_file)?;
let installation_id =
get_installation_id(config.notify_slug.as_ref().unwrap(), &client, &jwt_token)?;
let installation_id = get_installation_id(repo_slug, &client, &jwt_token)?;
let access_token = get_access_token(installation_id, &client, &jwt_token)?;

let url = format!(
"https://api.github.com/repos/{}/statuses/{}",
config.notify_slug.unwrap(),
sha
repo_slug, sha
);
let body = serde_json::json!({
"state": status,
Expand All @@ -225,12 +225,14 @@ pub fn update_commit_status(
}

pub fn github_watcher(
repo_slug: String,
config: GithubConfig,
) -> impl Fn(WorkloadEvent) -> Result<(), GitOpsError> + Send + 'static {
move |event| {
match event {
WorkloadEvent::Changes(name, prev_sha, new_sha) => {
update_commit_status(
&repo_slug,
&config,
&new_sha,
GitHubStatus::Pending,
Expand All @@ -239,6 +241,7 @@ pub fn github_watcher(
}
WorkloadEvent::Success(name, new_sha) => {
update_commit_status(
&repo_slug,
&config,
&new_sha,
GitHubStatus::Success,
Expand All @@ -247,6 +250,7 @@ pub fn github_watcher(
}
WorkloadEvent::Failure(task, action, new_sha) => {
update_commit_status(
&repo_slug,
&config,
&new_sha,
GitHubStatus::Failure,
Expand All @@ -255,6 +259,7 @@ pub fn github_watcher(
}
WorkloadEvent::Error(task, action, new_sha) => {
update_commit_status(
&repo_slug,
&config,
&new_sha,
GitHubStatus::Error,
Expand Down
2 changes: 1 addition & 1 deletion src/task/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ where
pub struct GitTaskConfig {
name: String,
pub github: Option<github::GithubConfig>,
git: GitConfig,
pub git: GitConfig,
actions: Vec<Action>,
#[serde(
default = "GitTaskConfig::default_interval",
Expand Down

0 comments on commit aad5b5b

Please sign in to comment.