Compare commits
5 Commits
d4666fb36e
..
1.0.1
| Author | SHA1 | Date | |
|---|---|---|---|
| 7f24d7657c | |||
| a613fdb99e | |||
| 975581093a | |||
| 00d46ce968 | |||
| 3f6c5b5559 |
@@ -16,3 +16,4 @@ GITEA_TIMEOUT=30
|
|||||||
# Optional
|
# Optional
|
||||||
SENTRY_DSN=
|
SENTRY_DSN=
|
||||||
RUST_LOG=info
|
RUST_LOG=info
|
||||||
|
RUST_BACKTRACE=1
|
||||||
|
|||||||
Generated
+1
-1
@@ -786,7 +786,7 @@ checksum = "ed5909b6e89a2db4456e54cd5f673791d7eca6732202bbf2a9cc504fe2f9b84a"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "herald"
|
name = "herald"
|
||||||
version = "1.0.0"
|
version = "1.0.1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"axum",
|
"axum",
|
||||||
|
|||||||
+6
-3
@@ -1,8 +1,11 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "herald"
|
name = "herald"
|
||||||
version = "1.0.0"
|
version = "1.0.1"
|
||||||
edition = "2024"
|
edition = "2024"
|
||||||
|
|
||||||
|
[profile.release]
|
||||||
|
debug = 1
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
reqwest = { version = "0.12", default-features = false, features = ["json", "rustls-tls"] }
|
reqwest = { version = "0.12", default-features = false, features = ["json", "rustls-tls"] }
|
||||||
tokio = { version = "1.52", features = ["full"] }
|
tokio = { version = "1.52", features = ["full"] }
|
||||||
@@ -12,7 +15,7 @@ futures-util = "0.3"
|
|||||||
serde_json = "1.0"
|
serde_json = "1.0"
|
||||||
serde = { version = "1.0", features = ["derive"] }
|
serde = { version = "1.0", features = ["derive"] }
|
||||||
sentry = { version = "0.48", features = ["tower-axum-matched-path"] }
|
sentry = { version = "0.48", features = ["tower-axum-matched-path"] }
|
||||||
sentry-anyhow = "0.48"
|
sentry-anyhow = { version = "0.48", features = ["backtrace"] }
|
||||||
openrouter-rs = "0.10"
|
openrouter-rs = "0.10"
|
||||||
dotenvy = "0.15"
|
dotenvy = "0.15"
|
||||||
tower = "0.5"
|
tower = "0.5"
|
||||||
@@ -20,7 +23,7 @@ tower-http = {version = "0.6", features = ["trace"] }
|
|||||||
tracing = "0.1"
|
tracing = "0.1"
|
||||||
tracing-subscriber = { version = "0.3", features=["env-filter"] }
|
tracing-subscriber = { version = "0.3", features=["env-filter"] }
|
||||||
axum = "0.8"
|
axum = "0.8"
|
||||||
anyhow = "1.0"
|
anyhow = { version = "1.0", features = ["backtrace"] }
|
||||||
thiserror = "2.0"
|
thiserror = "2.0"
|
||||||
hmac = "0.13"
|
hmac = "0.13"
|
||||||
sha2 = "0.11"
|
sha2 = "0.11"
|
||||||
|
|||||||
+8
-2
@@ -97,9 +97,15 @@ impl Bot {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[instrument(skip(self))]
|
#[instrument(skip(self, webhook), fields(repo, pr))]
|
||||||
pub async fn exec(&self, webhook: WebhookType) {
|
pub async fn exec(&self, webhook: WebhookType) {
|
||||||
tracing::Span::current().record("webhook_type", tracing::field::debug(&webhook));
|
match &webhook {
|
||||||
|
WebhookType::Review(p) => {
|
||||||
|
tracing::Span::current().record("repo", &p.repository.full_name);
|
||||||
|
tracing::Span::current().record("pr", p.pull_request.number);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
let exec_result = match webhook {
|
let exec_result = match webhook {
|
||||||
WebhookType::Review(review_payload) => crate::bot_actions::review::exec_review(
|
WebhookType::Review(review_payload) => crate::bot_actions::review::exec_review(
|
||||||
&self.gitea_api,
|
&self.gitea_api,
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ use crate::{
|
|||||||
open_router::OpenRouterClient,
|
open_router::OpenRouterClient,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[instrument(skip(gitea_api, open_router_client, http_client, review_payload), err)]
|
#[instrument(skip(gitea_api, open_router_client, http_client, review_payload))]
|
||||||
pub async fn exec_review(
|
pub async fn exec_review(
|
||||||
gitea_api: &GiteaAPI,
|
gitea_api: &GiteaAPI,
|
||||||
open_router_client: &OpenRouterClient,
|
open_router_client: &OpenRouterClient,
|
||||||
|
|||||||
+3
-3
@@ -41,13 +41,13 @@ pub fn load_config() -> anyhow::Result<EnvConfig> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn try_get_env(key: &str) -> anyhow::Result<String> {
|
pub fn try_get_env(key: &str) -> anyhow::Result<String> {
|
||||||
let env = std::env::var(key)?;
|
let env_value = std::env::var(key).map_err(|e| anyhow::anyhow!("{}: {}", key, e))?;
|
||||||
|
|
||||||
if env.trim().is_empty() {
|
if env_value.trim().is_empty() {
|
||||||
return Err(anyhow!(format!("env var {} is empty", key)));
|
return Err(anyhow!(format!("env var {} is empty", key)));
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(env)
|
Ok(env_value)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
|||||||
+12
-12
@@ -29,7 +29,7 @@ impl GiteaAPI {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
#[instrument(skip(self), err)]
|
#[instrument(skip(self))]
|
||||||
pub async fn comment(
|
pub async fn comment(
|
||||||
&self,
|
&self,
|
||||||
body: &str,
|
body: &str,
|
||||||
@@ -57,7 +57,7 @@ impl GiteaAPI {
|
|||||||
res.json::<Comment>().await.map_err(anyhow::Error::from)
|
res.json::<Comment>().await.map_err(anyhow::Error::from)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[instrument(skip(self), err)]
|
#[instrument(skip(self))]
|
||||||
pub async fn edit_comment(
|
pub async fn edit_comment(
|
||||||
&self,
|
&self,
|
||||||
body: &str,
|
body: &str,
|
||||||
@@ -85,7 +85,7 @@ impl GiteaAPI {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[instrument(skip(self), err)]
|
#[instrument(skip(self))]
|
||||||
pub async fn delete_comment(&self, full_name: &str, comment_id: u64) -> anyhow::Result<()> {
|
pub async fn delete_comment(&self, full_name: &str, comment_id: u64) -> anyhow::Result<()> {
|
||||||
let url = format!(
|
let url = format!(
|
||||||
"{}/api/v1/repos/{}/issues/comments/{}",
|
"{}/api/v1/repos/{}/issues/comments/{}",
|
||||||
@@ -104,7 +104,7 @@ impl GiteaAPI {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[instrument(skip(self, review_result), err)]
|
#[instrument(skip(self, review_result))]
|
||||||
pub async fn post_pull_request_review(
|
pub async fn post_pull_request_review(
|
||||||
&self,
|
&self,
|
||||||
review_result: &ReviewResult,
|
review_result: &ReviewResult,
|
||||||
@@ -206,14 +206,6 @@ impl WebhookType {
|
|||||||
_ => Err(AppError::UnknownEventErr),
|
_ => Err(AppError::UnknownEventErr),
|
||||||
}?;
|
}?;
|
||||||
|
|
||||||
let pr_body = match &wb {
|
|
||||||
WebhookType::Review(review_payload) => &review_payload.comment.body,
|
|
||||||
};
|
|
||||||
|
|
||||||
if !pr_body.starts_with(&format!("@{}", bot_name)) {
|
|
||||||
return Err(AppError::UnauthorizedUserErr);
|
|
||||||
}
|
|
||||||
|
|
||||||
let action = match &wb {
|
let action = match &wb {
|
||||||
WebhookType::Review(review_payload) => &review_payload.action,
|
WebhookType::Review(review_payload) => &review_payload.action,
|
||||||
};
|
};
|
||||||
@@ -222,6 +214,14 @@ impl WebhookType {
|
|||||||
return Err(AppError::InvalidActionErr);
|
return Err(AppError::InvalidActionErr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let pr_body = match &wb {
|
||||||
|
WebhookType::Review(review_payload) => &review_payload.comment.body,
|
||||||
|
};
|
||||||
|
|
||||||
|
if !pr_body.starts_with(&format!("@{}", bot_name)) {
|
||||||
|
return Err(AppError::UnauthorizedUserErr);
|
||||||
|
}
|
||||||
|
|
||||||
Ok(wb)
|
Ok(wb)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user