Merge pull request 'Fix missing env var error' (#5) from 1.0.1 into main
ci/woodpecker/tag/release Pipeline was successful

Reviewed-on: #5
This commit was merged in pull request #5.
This commit is contained in:
2026-06-16 22:05:24 +02:00
7 changed files with 32 additions and 22 deletions
+1
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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,
+1 -1
View File
@@ -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
View File
@@ -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
View File
@@ -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)
} }
} }