Skip to content

Commit

Permalink
redraft
Browse files Browse the repository at this point in the history
  • Loading branch information
epompeii committed Sep 14, 2023
1 parent cb7b983 commit c1d26ef
Show file tree
Hide file tree
Showing 5 changed files with 144 additions and 137 deletions.
1 change: 1 addition & 0 deletions services/api/src/bin/api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ async fn run(
loop {
let config = Config::load_or_default(log).await?;
if let Some(apm) = config.as_ref().apm.as_ref() {
#[allow(unused_variables)]
match &apm {
JsonApm::Sentry { dsn } => {
#[cfg(feature = "sentry")]
Expand Down
3 changes: 2 additions & 1 deletion services/api/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,11 @@ use dropshot::HttpError;
use http::StatusCode;
use thiserror::Error;

#[cfg(feature = "plus")]
use crate::model::organization::OrganizationId;
use crate::{
endpoints::Endpoint,
model::{
organization::OrganizationId,
project::{branch::BranchId, testbed::TestbedId, ProjectId},
user::{auth::AuthUser, UserId},
},
Expand Down
1 change: 1 addition & 0 deletions services/api/src/model/project/visibility.rs
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,7 @@ where
) -> diesel::serialize::Result {
match self {
Self::Public => PUBLIC_INT.to_sql(out),
#[cfg(feature = "plus")]
Self::Private => PRIVATE_INT.to_sql(out),
}
}
Expand Down
107 changes: 48 additions & 59 deletions services/cli/src/bencher/sub/project/run/ci.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,14 +25,24 @@ pub enum GitHubError {
BadEventPath(String, std::io::Error),
#[error("Failed to parse GitHub Action event ({0}): {1}")]
BadEvent(String, serde_json::Error),
#[error("GitHub Action running on event ({0}) but event type is {1:?}")]
BadEventType(String, octocrab::models::events::EventType),
#[error("GitHub Action event ({0}) missing payload")]
NoEventPayload(String),
#[error("GitHub Action event ({0}) has the wrong payload")]
BadEventPayload(String),
#[error("GitHub repository is not in the form `owner/repo` ({0})")]
Repository(String),
#[error("GitHub Action event ({0}) PR number is missing")]
NoPRNumber(String),
#[error("GitHub Action event ({0}) PR number is invalid")]
BadPRNumber(String),
#[error("GitHub Action event workflow run is missing")]
NoWorkFlowRun,
#[error("GitHub Action event workflow run pull requests is missing")]
NoPullRequests,
#[error("GitHub Action event workflow run pull requests is empty")]
EmptyPullRequests,
#[error("GitHub Action event repository is missing")]
NoRepository,
#[error("GitHub Action event repository full name is missing")]
NoFullName,
#[error("GitHub Action event repository full name is invalid")]
BadFullName,
#[error("GitHub Action event repository full name is not of the form `owner/repo`: ({0})")]
InvalidFullName(String),
#[error("Failed to authenticate as GitHub Action: {0}")]
Auth(octocrab::Error),
#[error("Failed to list GitHub PR comments: {0}")]
Expand Down Expand Up @@ -121,69 +131,38 @@ impl GitHubActions {
};
let event_str = std::fs::read_to_string(&github_event_path)
.map_err(|e| GitHubError::BadEventPath(github_event_path, e))?;
let event: octocrab::models::events::Event = serde_json::from_str(&event_str)
// The event JSON does not match the GitHub API event JSON schema used by Octocrab
// Therefore we use serde_json::Value to parse the event
let event: serde_json::Value = serde_json::from_str(&event_str)
.map_err(|e| GitHubError::BadEvent(event_str.clone(), e))?;

const NUMBER_KEY: &str = "number";
// The name of the event that triggered the workflow. For example, `workflow_dispatch`.
let issue_number = match std::env::var("GITHUB_EVENT_NAME").ok().as_deref() {
// https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#pull_request
// https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#pull_request_target
Some(event_name @ ("pull_request" | "pull_request_target")) => {
if event.r#type != octocrab::models::events::EventType::PullRequestEvent {
return Err(GitHubError::BadEventType(event_name.into(), event.r#type));
}

let payload = event
.payload
.ok_or_else(|| GitHubError::NoEventPayload(event_name.into()))?
.specific
.ok_or_else(|| GitHubError::NoEventPayload(event_name.into()))?;

if let octocrab::models::events::payload::EventPayload::PullRequestEvent(payload) =
payload
{
payload.number
} else {
return Err(GitHubError::BadEventPayload(event_name.into()));
}
// https://docs.github.com/en/webhooks/webhook-events-and-payloads#pull_request
event
.get(NUMBER_KEY)
.ok_or_else(|| GitHubError::NoPRNumber(event_name.into()))?
.as_u64()
.ok_or_else(|| GitHubError::BadPRNumber(event_name.into()))?
},
// https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#workflow_run
Some(event_name @ "workflow_run") => {
if event.r#type != octocrab::models::events::EventType::WorkflowRunEvent {
return Err(GitHubError::BadEventType(event_name.into(), event.r#type));
}

// TODO upstream a fix for: https://github.com/XAMPPRocky/octocrab/pull/162
let event: serde_json::Value = serde_json::from_str(&event_str)
.map_err(|e| GitHubError::BadEvent(event_str, e))?;

// https://docs.github.com/en/webhooks/webhook-events-and-payloads#workflow_run
let pull_requests = "pull_requests";
let index = 0;
let number = "number";
event
.get(event_name)
.ok_or_else(|| GitHubError::NoEventPayload(event_name.into()))?
.get(pull_requests)
.ok_or_else(|| {
GitHubError::NoEventPayload(format!("{event_name}/{pull_requests}"))
})?
.get(index)
.ok_or_else(|| {
GitHubError::NoEventPayload(format!("{event_name}/{pull_requests}/{index}"))
})?
.get(number)
.ok_or_else(|| {
GitHubError::NoEventPayload(format!(
"{event_name}/{pull_requests}/{index}/{number}"
))
})?
.ok_or(GitHubError::NoWorkFlowRun)?
.get("pull_requests")
.ok_or(GitHubError::NoPullRequests)?
.get(0)
.ok_or(GitHubError::EmptyPullRequests)?
.get(NUMBER_KEY)
.ok_or_else(|| GitHubError::NoPRNumber(event_name.into()))?
.as_u64()
.ok_or_else(|| {
GitHubError::BadEventPayload(format!(
"{event_name}/{pull_requests}/{index}/{number}"
))
})?
.ok_or_else(|| GitHubError::BadPRNumber(event_name.into()))?
},
_ => {
cli_println!(
Expand All @@ -193,11 +172,21 @@ impl GitHubActions {
},
};

// Use the full name instead of getting the owner and repo names separately
// because the owner name values in the API are nullable
// https://docs.github.com/en/rest/repos/repos#get-a-repository
let full_name = event
.get("repository")
.ok_or(GitHubError::NoRepository)?
.get("full_name")
.ok_or(GitHubError::NoFullName)?
.as_str()
.ok_or(GitHubError::BadFullName)?;
// The owner and repository name. For example, octocat/Hello-World.
let (owner, repo) = if let Some((owner, repo)) = event.repo.name.split_once('/') {
let (owner, repo) = if let Some((owner, repo)) = full_name.split_once('/') {
(owner.to_owned(), repo.to_owned())
} else {
return Err(GitHubError::Repository(event.repo.name));
return Err(GitHubError::InvalidFullName(full_name.into()));
};

let github_client = Octocrab::builder()
Expand Down
Loading

0 comments on commit c1d26ef

Please sign in to comment.