diff --git a/src/cli.rs b/src/cli.rs index 4a99df3..957f24e 100644 --- a/src/cli.rs +++ b/src/cli.rs @@ -349,6 +349,8 @@ pub enum GithubCommands { number: u64, #[arg(long)] title: String, + #[arg(long, default_value = "")] + url: String, #[arg(long)] channel: Option, }, diff --git a/src/daemon.rs b/src/daemon.rs index d733497..533d4ca 100644 --- a/src/daemon.rs +++ b/src/daemon.rs @@ -687,6 +687,11 @@ async fn post_github( .and_then(Value::as_str) .unwrap_or("Untitled issue") .to_string(), + payload + .pointer("/issue/html_url") + .and_then(Value::as_str) + .unwrap_or("") + .to_string(), None, ))) } diff --git a/src/events.rs b/src/events.rs index bd8fd55..8d785d3 100644 --- a/src/events.rs +++ b/src/events.rs @@ -280,6 +280,7 @@ impl IncomingEvent { repo: String, number: u64, title: String, + url: String, channel: Option, ) -> Self { Self { @@ -288,7 +289,7 @@ impl IncomingEvent { mention: None, format: None, template: None, - payload: json!({ "repo": repo, "number": number, "title": title }), + payload: json!({ "repo": repo, "number": number, "title": title, "url": url }), } } @@ -297,6 +298,7 @@ impl IncomingEvent { number: u64, title: String, comments: u64, + url: String, channel: Option, ) -> Self { Self { @@ -305,7 +307,7 @@ impl IncomingEvent { mention: None, format: None, template: None, - payload: json!({ "repo": repo, "number": number, "title": title, "comments": comments }), + payload: json!({ "repo": repo, "number": number, "title": title, "comments": comments, "url": url }), } } @@ -313,6 +315,7 @@ impl IncomingEvent { repo: String, number: u64, title: String, + url: String, channel: Option, ) -> Self { Self { @@ -321,7 +324,7 @@ impl IncomingEvent { mention: None, format: None, template: None, - payload: json!({ "repo": repo, "number": number, "title": title }), + payload: json!({ "repo": repo, "number": number, "title": title, "url": url }), } } @@ -1367,7 +1370,7 @@ mod tests { #[test] fn renders_template_from_payload() { - let event = IncomingEvent::github_issue_opened("repo".into(), 42, "broken".into(), None); + let event = IncomingEvent::github_issue_opened("repo".into(), 42, "broken".into(), "https://github.com/repo/issues/42".into(), None); let rendered = render_template("{repo} #{number}: {title}", &event.template_context()); assert_eq!(rendered, "repo #42: broken"); } diff --git a/src/main.rs b/src/main.rs index 4fb2dd8..e0fe754 100644 --- a/src/main.rs +++ b/src/main.rs @@ -133,8 +133,9 @@ async fn real_main(cli: Cli) -> Result<()> { repo, number, title, + url, channel, - } => IncomingEvent::github_issue_opened(repo, number, title, channel), + } => IncomingEvent::github_issue_opened(repo, number, title, url, channel), GithubCommands::PrStatusChanged { repo, number, diff --git a/src/render/default.rs b/src/render/default.rs index e08c56d..6ce14d1 100644 --- a/src/render/default.rs +++ b/src/render/default.rs @@ -73,63 +73,72 @@ impl Renderer for DefaultRenderer { | ("agent.failed", MessageFormat::Raw) => serde_json::to_string_pretty(payload)?, ("github.issue-opened", MessageFormat::Compact) => format!( - "{}#{} opened: {}", + "{}#{} opened: {} 路 {}", string_field(payload, "repo")?, payload.field_u64("number")?, - string_field(payload, "title")? + string_field(payload, "title")?, + string_field(payload, "url")? ), ("github.issue-opened", MessageFormat::Alert) => format!( - "馃毃 GitHub issue opened in {}: #{} {}", + "馃毃 GitHub issue opened in {}: #{} {} 路 {}", string_field(payload, "repo")?, payload.field_u64("number")?, - string_field(payload, "title")? + string_field(payload, "title")?, + string_field(payload, "url")? ), ("github.issue-opened", MessageFormat::Inline) => format!( - "[GitHub] {}#{} {}", + "[GitHub] {}#{} {} 路 {}", string_field(payload, "repo")?, payload.field_u64("number")?, - string_field(payload, "title")? + string_field(payload, "title")?, + string_field(payload, "url")? ), ("github.issue-opened", MessageFormat::Raw) => serde_json::to_string_pretty(payload)?, ("github.issue-commented", MessageFormat::Compact) => format!( - "{}#{} commented ({} comments): {}", + "{}#{} commented ({} comments): {} 路 {}", string_field(payload, "repo")?, payload.field_u64("number")?, payload.field_u64("comments")?, - string_field(payload, "title")? + string_field(payload, "title")?, + string_field(payload, "url")? ), ("github.issue-commented", MessageFormat::Alert) => format!( - "馃毃 GitHub issue commented in {}: #{} {}", + "馃毃 GitHub issue commented in {}: #{} {} 路 {}", string_field(payload, "repo")?, payload.field_u64("number")?, - string_field(payload, "title")? + string_field(payload, "title")?, + string_field(payload, "url")? ), ("github.issue-commented", MessageFormat::Inline) => format!( - "[GitHub comment] {}#{} {}", + "[GitHub comment] {}#{} {} 路 {}", string_field(payload, "repo")?, payload.field_u64("number")?, - string_field(payload, "title")? + string_field(payload, "title")?, + string_field(payload, "url")? ), ("github.issue-commented", MessageFormat::Raw) => { serde_json::to_string_pretty(payload)? } ("github.issue-closed", MessageFormat::Compact) => format!( - "{}#{} closed: {}", + "{}#{} closed: {} 路 {}", string_field(payload, "repo")?, payload.field_u64("number")?, - string_field(payload, "title")? + string_field(payload, "title")?, + string_field(payload, "url")? ), ("github.issue-closed", MessageFormat::Alert) => format!( - "馃毃 GitHub issue closed in {}: #{} {}", + "馃毃 GitHub issue closed in {}: #{} {} 路 {}", string_field(payload, "repo")?, payload.field_u64("number")?, - string_field(payload, "title")? + string_field(payload, "title")?, + string_field(payload, "url")? ), ("github.issue-closed", MessageFormat::Inline) => format!( - "[GitHub closed] {}#{} {}", + "[GitHub closed] {}#{} {} 路 {}", string_field(payload, "repo")?, payload.field_u64("number")?, - string_field(payload, "title")? + string_field(payload, "title")?, + string_field(payload, "url")? ), ("github.issue-closed", MessageFormat::Raw) => serde_json::to_string_pretty(payload)?, @@ -175,27 +184,30 @@ impl Renderer for DefaultRenderer { ("git.branch-changed", MessageFormat::Raw) => serde_json::to_string_pretty(payload)?, ("github.pr-status-changed", MessageFormat::Compact) => format!( - "PR {}#{} {} -> {}: {}", + "PR {}#{} {} -> {}: {} 路 {}", string_field(payload, "repo")?, payload.field_u64("number")?, string_field(payload, "old_status")?, string_field(payload, "new_status")?, - string_field(payload, "title")? + string_field(payload, "title")?, + string_field(payload, "url")? ), ("github.pr-status-changed", MessageFormat::Alert) => format!( - "馃毃 PR status changed in {}: #{} {} -> {} ({})", + "馃毃 PR status changed in {}: #{} {} -> {} ({}) 路 {}", string_field(payload, "repo")?, payload.field_u64("number")?, string_field(payload, "old_status")?, string_field(payload, "new_status")?, - string_field(payload, "title")? + string_field(payload, "title")?, + string_field(payload, "url")? ), ("github.pr-status-changed", MessageFormat::Inline) => format!( - "[PR {}#{}] {} -> {}", + "[PR {}#{}] {} -> {} 路 {}", string_field(payload, "repo")?, payload.field_u64("number")?, string_field(payload, "old_status")?, - string_field(payload, "new_status")? + string_field(payload, "new_status")?, + string_field(payload, "url")? ), ("github.pr-status-changed", MessageFormat::Raw) => { serde_json::to_string_pretty(payload)? diff --git a/src/router.rs b/src/router.rs index de5c5f5..ef2dc13 100644 --- a/src/router.rs +++ b/src/router.rs @@ -1052,7 +1052,7 @@ mod tests { let router = Router::new(Arc::new(config)); let github_event = - IncomingEvent::github_issue_opened("clawhip".into(), 5, "boom".into(), None); + IncomingEvent::github_issue_opened("clawhip".into(), 5, "boom".into(), "https://github.com/clawhip/clawhip/issues/5".into(), None); let (_, _, github_content) = router.preview(&github_event).await.unwrap(); assert!(github_content.starts_with("<@botid> ")); assert!(github_content.contains("boom")); @@ -1539,7 +1539,7 @@ mod tests { ..AppConfig::default() }; let router = Router::new(Arc::new(config)); - let event = IncomingEvent::github_issue_opened("clawhip".into(), 7, "bug".into(), None); + let event = IncomingEvent::github_issue_opened("clawhip".into(), 7, "bug".into(), "https://github.com/clawhip/clawhip/issues/7".into(), None); let (channel, _, _) = router.preview(&event).await.unwrap(); assert_eq!(channel, "repo-b"); } diff --git a/src/source/github.rs b/src/source/github.rs index 033be5d..8787408 100644 --- a/src/source/github.rs +++ b/src/source/github.rs @@ -68,6 +68,7 @@ struct IssueSnapshot { title: String, state: String, comments: u64, + url: String, } #[derive(Clone)] @@ -462,6 +463,7 @@ fn collect_issue_events( repo_name.to_string(), *number, issue.title.clone(), + issue.url.clone(), repo.channel.clone(), ) .with_mention(repo.mention.clone()) @@ -474,6 +476,7 @@ fn collect_issue_events( repo_name.to_string(), *number, issue.title.clone(), + issue.url.clone(), repo.channel.clone(), ) .with_mention(repo.mention.clone()) @@ -487,6 +490,7 @@ fn collect_issue_events( *number, issue.title.clone(), issue.comments, + issue.url.clone(), repo.channel.clone(), ) .with_mention(repo.mention.clone()) @@ -581,6 +585,7 @@ async fn fetch_issues( title: issue.title, state: issue.state, comments: issue.comments, + url: issue.html_url, }, ) }) @@ -800,6 +805,7 @@ struct GitHubIssue { title: String, state: String, comments: u64, + html_url: String, #[serde(default)] pull_request: Option, } @@ -904,6 +910,7 @@ mod tests { title: "live issue".into(), state: "open".into(), comments: 0, + url: "https://github.com/clawhip/clawhip/issues/2".into(), }, )] .into_iter() @@ -956,6 +963,7 @@ mod tests { title: "live issue".into(), state: "open".into(), comments: 0, + url: "https://github.com/clawhip/clawhip/issues/2".into(), }, )] .into_iter() @@ -966,6 +974,7 @@ mod tests { title: "live issue".into(), state: "closed".into(), comments: 1, + url: "https://github.com/clawhip/clawhip/issues/2".into(), }, )] .into_iter()