rustc_commits.rs 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. use crate::db::rustc_commits;
  2. use crate::{
  3. github::{self, Event},
  4. handlers::Context,
  5. };
  6. use std::convert::TryInto;
  7. const BORS_GH_ID: i64 = 3372342;
  8. pub async fn handle(ctx: &Context, event: &Event) -> anyhow::Result<()> {
  9. let body = match event.comment_body() {
  10. Some(v) => v,
  11. // Skip events that don't have comment bodies associated
  12. None => return Ok(()),
  13. };
  14. let event = if let Event::IssueComment(e) = event {
  15. if e.action != github::IssueCommentAction::Created {
  16. return Ok(());
  17. }
  18. e
  19. } else {
  20. return Ok(());
  21. };
  22. if !body.contains("Test successful") {
  23. return Ok(());
  24. }
  25. if event.comment.user.id != Some(BORS_GH_ID) {
  26. log::trace!("Ignoring non-bors comment, user: {:?}", event.comment.user);
  27. return Ok(());
  28. }
  29. let repo = event.issue.repository();
  30. if repo.organization != "rust-lang" && repo.repository != "rust" {
  31. return Ok(());
  32. }
  33. let start = "<!-- homu: ";
  34. let start = body.find(start).map(|s| s + start.len());
  35. let end = body.find(" -->");
  36. let (start, end) = if let (Some(start), Some(end)) = (start, end) {
  37. (start, end)
  38. } else {
  39. log::warn!("Unable to extract build completion from comment {:?}", body);
  40. return Ok(());
  41. };
  42. let bors: BorsMessage = match serde_json::from_str(&body[start..end]) {
  43. Ok(bors) => bors,
  44. Err(e) => {
  45. log::error!(
  46. "failed to parse build completion from {:?}: {:?}",
  47. &body[start..end],
  48. e
  49. );
  50. return Ok(());
  51. }
  52. };
  53. if bors.type_ != "BuildCompleted" {
  54. log::trace!("Not build completion? {:?}", bors);
  55. }
  56. if bors.base_ref != "master" {
  57. log::trace!("Ignoring bors merge, not on master");
  58. return Ok(());
  59. }
  60. let sha = bors.merge_sha;
  61. // FIXME: ideally we would pull in all the commits here, but unfortunately
  62. // in rust-lang/rust's case there's bors-authored commits that aren't
  63. // actually from rust-lang/rust as they were merged into the clippy repo.
  64. let mut gc = match ctx.github.rust_commit(&sha).await {
  65. Some(c) => c,
  66. None => {
  67. log::error!("Could not find bors-reported sha: {:?}", sha);
  68. return Ok(());
  69. }
  70. };
  71. let res = rustc_commits::record_commit(
  72. &ctx.db,
  73. rustc_commits::Commit {
  74. sha: gc.sha,
  75. parent_sha: gc.parents.remove(0).sha,
  76. time: gc.commit.author.date,
  77. pr: Some(event.issue.number.try_into().unwrap()),
  78. },
  79. )
  80. .await;
  81. match res {
  82. Ok(()) => {}
  83. Err(e) => {
  84. log::error!("Failed to record commit {:?}", e);
  85. }
  86. }
  87. Ok(())
  88. }
  89. #[derive(Debug, serde::Deserialize)]
  90. struct BorsMessage {
  91. #[serde(rename = "type")]
  92. type_: String,
  93. base_ref: String,
  94. merge_sha: String,
  95. }