rustc_commits.rs 2.8 KB

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