Browse Source

Merge pull request #1461 from spastorino/add-top-unattended-prs

Add top unattended prs to prioritization agenda
Santiago Pastorino 3 years ago
parent
commit
d547e8be26
3 changed files with 112 additions and 12 deletions
  1. 68 0
      src/agenda.rs
  2. 39 12
      src/github.rs
  3. 5 0
      templates/prioritization_agenda.tt

+ 68 - 0
src/agenda.rs

@@ -1,5 +1,6 @@
 use crate::actions::{Action, Query, QueryMap, Step};
 use crate::github;
+use std::collections::HashMap;
 
 pub fn prioritization<'a>() -> Box<dyn Action> {
     let mut actions = Vec::new();
@@ -21,6 +22,7 @@ pub fn prioritization<'a>() -> Box<dyn Action> {
                 "t-libs",
                 "t-libs-api",
             ],
+            ordering: HashMap::new(),
         },
     });
 
@@ -38,6 +40,7 @@ pub fn prioritization<'a>() -> Box<dyn Action> {
                 "t-libs",
                 "t-libs-api",
             ],
+            ordering: HashMap::new(),
         },
     });
 
@@ -48,6 +51,7 @@ pub fn prioritization<'a>() -> Box<dyn Action> {
             filters: vec![("state", "open")],
             include_labels: vec!["proposed-final-comment-period"],
             exclude_labels: vec!["t-libs", "t-libs-api"],
+            ordering: HashMap::new(),
         },
     });
     queries.push(QueryMap {
@@ -57,6 +61,7 @@ pub fn prioritization<'a>() -> Box<dyn Action> {
             filters: vec![("state", "open")],
             include_labels: vec!["final-comment-period"],
             exclude_labels: vec!["t-libs", "t-libs-api"],
+            ordering: HashMap::new(),
         },
     });
 
@@ -67,6 +72,7 @@ pub fn prioritization<'a>() -> Box<dyn Action> {
             filters: vec![("state", "all")],
             include_labels: vec!["major-change-accepted", "to-announce"],
             exclude_labels: vec!["t-libs", "t-libs-api"],
+            ordering: HashMap::new(),
         },
     });
 
@@ -81,6 +87,7 @@ pub fn prioritization<'a>() -> Box<dyn Action> {
                 "to-announce",
             ],
             exclude_labels: vec!["t-libs", "t-libs-api"],
+            ordering: HashMap::new(),
         },
     });
 
@@ -98,6 +105,7 @@ pub fn prioritization<'a>() -> Box<dyn Action> {
             filters: vec![("state", "open")],
             include_labels: vec!["proposed-final-comment-period", "T-compiler"],
             exclude_labels: vec!["t-libs", "t-libs-api"],
+            ordering: HashMap::new(),
         },
     });
     queries.push(QueryMap {
@@ -107,6 +115,7 @@ pub fn prioritization<'a>() -> Box<dyn Action> {
             filters: vec![("state", "open")],
             include_labels: vec!["final-comment-period", "T-compiler"],
             exclude_labels: vec!["t-libs", "t-libs-api"],
+            ordering: HashMap::new(),
         },
     });
 
@@ -121,6 +130,7 @@ pub fn prioritization<'a>() -> Box<dyn Action> {
                 "to-announce",
             ],
             exclude_labels: vec!["t-libs", "t-libs-api"],
+            ordering: HashMap::new(),
         },
     });
 
@@ -138,6 +148,7 @@ pub fn prioritization<'a>() -> Box<dyn Action> {
             filters: vec![("state", "open")],
             include_labels: vec!["proposed-final-comment-period"],
             exclude_labels: vec!["t-libs", "t-libs-api"],
+            ordering: HashMap::new(),
         },
     });
     queries.push(QueryMap {
@@ -147,6 +158,7 @@ pub fn prioritization<'a>() -> Box<dyn Action> {
             filters: vec![("state", "open")],
             include_labels: vec!["final-comment-period"],
             exclude_labels: vec!["t-libs", "t-libs-api"],
+            ordering: HashMap::new(),
         },
     });
 
@@ -161,6 +173,7 @@ pub fn prioritization<'a>() -> Box<dyn Action> {
                 "to-announce",
             ],
             exclude_labels: vec!["t-libs", "t-libs-api"],
+            ordering: HashMap::new(),
         },
     });
 
@@ -179,6 +192,7 @@ pub fn prioritization<'a>() -> Box<dyn Action> {
             filters: vec![],
             include_labels: vec!["beta-nominated", "T-compiler"],
             exclude_labels: vec!["beta-accepted"],
+            ordering: HashMap::new(),
         },
     });
 
@@ -189,6 +203,7 @@ pub fn prioritization<'a>() -> Box<dyn Action> {
             filters: vec![],
             include_labels: vec!["beta-nominated", "T-rustdoc"],
             exclude_labels: vec!["beta-accepted"],
+            ordering: HashMap::new(),
         },
     });
 
@@ -200,6 +215,7 @@ pub fn prioritization<'a>() -> Box<dyn Action> {
             filters: vec![],
             include_labels: vec!["stable-nominated", "T-compiler"],
             exclude_labels: vec!["stable-accepted"],
+            ordering: HashMap::new(),
         },
     });
 
@@ -210,6 +226,7 @@ pub fn prioritization<'a>() -> Box<dyn Action> {
             filters: vec![],
             include_labels: vec!["stable-nominated", "T-rustdoc"],
             exclude_labels: vec!["stable-accepted"],
+            ordering: HashMap::new(),
         },
     });
 
@@ -221,6 +238,7 @@ pub fn prioritization<'a>() -> Box<dyn Action> {
             filters: vec![("state", "open")],
             include_labels: vec!["S-waiting-on-team", "T-compiler"],
             exclude_labels: vec![],
+            ordering: HashMap::new(),
         },
     });
 
@@ -232,6 +250,7 @@ pub fn prioritization<'a>() -> Box<dyn Action> {
             filters: vec![("state", "open")],
             include_labels: vec!["T-compiler", "P-critical"],
             exclude_labels: vec![],
+            ordering: HashMap::new(),
         },
     });
 
@@ -242,6 +261,7 @@ pub fn prioritization<'a>() -> Box<dyn Action> {
             filters: vec![("state", "open"), ("no", "assignee")],
             include_labels: vec!["T-compiler", "P-critical"],
             exclude_labels: vec![],
+            ordering: HashMap::new(),
         },
     });
 
@@ -252,6 +272,7 @@ pub fn prioritization<'a>() -> Box<dyn Action> {
             filters: vec![("state", "open")],
             include_labels: vec!["T-compiler", "P-high"],
             exclude_labels: vec![],
+            ordering: HashMap::new(),
         },
     });
 
@@ -262,6 +283,7 @@ pub fn prioritization<'a>() -> Box<dyn Action> {
             filters: vec![("state", "open"), ("no", "assignee")],
             include_labels: vec!["T-compiler", "P-high"],
             exclude_labels: vec![],
+            ordering: HashMap::new(),
         },
     });
 
@@ -272,6 +294,7 @@ pub fn prioritization<'a>() -> Box<dyn Action> {
             filters: vec![("state", "open")],
             include_labels: vec!["regression-from-stable-to-beta", "P-critical"],
             exclude_labels: vec![],
+            ordering: HashMap::new(),
         },
     });
 
@@ -282,6 +305,7 @@ pub fn prioritization<'a>() -> Box<dyn Action> {
             filters: vec![("state", "open")],
             include_labels: vec!["regression-from-stable-to-beta", "P-high"],
             exclude_labels: vec![],
+            ordering: HashMap::new(),
         },
     });
 
@@ -292,6 +316,7 @@ pub fn prioritization<'a>() -> Box<dyn Action> {
             filters: vec![("state", "open")],
             include_labels: vec!["regression-from-stable-to-beta", "P-medium"],
             exclude_labels: vec![],
+            ordering: HashMap::new(),
         },
     });
 
@@ -302,6 +327,7 @@ pub fn prioritization<'a>() -> Box<dyn Action> {
             filters: vec![("state", "open")],
             include_labels: vec!["regression-from-stable-to-beta", "P-low"],
             exclude_labels: vec![],
+            ordering: HashMap::new(),
         },
     });
 
@@ -312,6 +338,7 @@ pub fn prioritization<'a>() -> Box<dyn Action> {
             filters: vec![("state", "open")],
             include_labels: vec!["regression-from-stable-to-nightly", "P-critical"],
             exclude_labels: vec![],
+            ordering: HashMap::new(),
         },
     });
 
@@ -322,6 +349,7 @@ pub fn prioritization<'a>() -> Box<dyn Action> {
             filters: vec![("state", "open")],
             include_labels: vec!["regression-from-stable-to-nightly", "P-high"],
             exclude_labels: vec![],
+            ordering: HashMap::new(),
         },
     });
 
@@ -332,6 +360,7 @@ pub fn prioritization<'a>() -> Box<dyn Action> {
             filters: vec![("state", "open")],
             include_labels: vec!["regression-from-stable-to-nightly", "P-medium"],
             exclude_labels: vec![],
+            ordering: HashMap::new(),
         },
     });
 
@@ -342,6 +371,7 @@ pub fn prioritization<'a>() -> Box<dyn Action> {
             filters: vec![("state", "open")],
             include_labels: vec!["regression-from-stable-to-nightly", "P-low"],
             exclude_labels: vec![],
+            ordering: HashMap::new(),
         },
     });
 
@@ -352,6 +382,7 @@ pub fn prioritization<'a>() -> Box<dyn Action> {
             filters: vec![("state", "open")],
             include_labels: vec!["regression-from-stable-to-stable", "P-critical"],
             exclude_labels: vec![],
+            ordering: HashMap::new(),
         },
     });
 
@@ -362,6 +393,7 @@ pub fn prioritization<'a>() -> Box<dyn Action> {
             filters: vec![("state", "open")],
             include_labels: vec!["regression-from-stable-to-stable", "P-high"],
             exclude_labels: vec![],
+            ordering: HashMap::new(),
         },
     });
 
@@ -372,6 +404,7 @@ pub fn prioritization<'a>() -> Box<dyn Action> {
             filters: vec![("state", "open")],
             include_labels: vec!["regression-from-stable-to-stable", "P-medium"],
             exclude_labels: vec![],
+            ordering: HashMap::new(),
         },
     });
 
@@ -382,6 +415,7 @@ pub fn prioritization<'a>() -> Box<dyn Action> {
             filters: vec![("state", "open")],
             include_labels: vec!["regression-from-stable-to-stable", "P-low"],
             exclude_labels: vec![],
+            ordering: HashMap::new(),
         },
     });
 
@@ -392,6 +426,7 @@ pub fn prioritization<'a>() -> Box<dyn Action> {
             filters: vec![("state", "open")],
             include_labels: vec!["T-compiler", "P-critical"],
             exclude_labels: vec![],
+            ordering: HashMap::new(),
         },
     });
 
@@ -402,6 +437,7 @@ pub fn prioritization<'a>() -> Box<dyn Action> {
             filters: vec![("state", "open")],
             include_labels: vec!["T-rustdoc", "P-critical"],
             exclude_labels: vec![],
+            ordering: HashMap::new(),
         },
     });
 
@@ -412,6 +448,7 @@ pub fn prioritization<'a>() -> Box<dyn Action> {
             filters: vec![("state", "open")],
             include_labels: vec!["regression-from-stable-to-beta", "P-high"],
             exclude_labels: vec!["T-infra", "T-libs", "T-release", "T-rustdoc", "T-core"],
+            ordering: HashMap::new(),
         },
     });
 
@@ -422,6 +459,7 @@ pub fn prioritization<'a>() -> Box<dyn Action> {
             filters: vec![("state", "open"), ("no", "assignee")],
             include_labels: vec!["regression-from-stable-to-nightly", "P-high"],
             exclude_labels: vec!["T-infra", "T-libs", "T-release", "T-rustdoc", "T-core"],
+            ordering: HashMap::new(),
         },
     });
 
@@ -432,6 +470,22 @@ pub fn prioritization<'a>() -> Box<dyn Action> {
             filters: vec![("state", "open")],
             include_labels: vec!["I-nominated", "T-compiler"],
             exclude_labels: vec![],
+            ordering: HashMap::new(),
+        },
+    });
+
+    let mut ordering = HashMap::new();
+    ordering.insert("sort", "updated");
+    ordering.insert("per_page", "5");
+
+    queries.push(QueryMap {
+        name: "top_unreviewed_prs",
+        query: github::Query {
+            kind: github::QueryKind::List,
+            filters: vec![("state", "open"), ("is", "pull-request"), ("draft", "false")],
+            include_labels: vec!["S-waiting-on-review", "T-compiler"],
+            exclude_labels: vec![],
+            ordering,
         },
     });
 
@@ -452,6 +506,7 @@ pub fn prioritization<'a>() -> Box<dyn Action> {
             filters: vec![("state", "open")],
             include_labels: vec!["T-compiler", "I-nominated"],
             exclude_labels: vec![],
+            ordering: HashMap::new(),
         },
     });
 
@@ -480,6 +535,7 @@ pub fn lang<'a>() -> Box<dyn Action> {
                             filters: vec![("state", "open"), ("is", "issue")],
                             include_labels: vec!["major-change"],
                             exclude_labels: vec!["charter-needed"],
+                            ordering: HashMap::new(),
                         },
                     },
                     QueryMap {
@@ -489,6 +545,7 @@ pub fn lang<'a>() -> Box<dyn Action> {
                             filters: vec![("state", "open"), ("is", "pull-request")],
                             include_labels: vec![],
                             exclude_labels: vec![],
+                            ordering: HashMap::new(),
                         },
                     },
                     QueryMap {
@@ -498,6 +555,7 @@ pub fn lang<'a>() -> Box<dyn Action> {
                             filters: vec![("state", "open"), ("is", "issue")],
                             include_labels: vec!["meeting-proposal", "meeting-scheduled"],
                             exclude_labels: vec![],
+                            ordering: HashMap::new(),
                         },
                     },
                 ],
@@ -515,6 +573,7 @@ pub fn lang<'a>() -> Box<dyn Action> {
                             "T-lang",
                         ],
                         exclude_labels: vec![],
+                        ordering: HashMap::new(),
                     },
                 }],
             },
@@ -533,6 +592,7 @@ pub fn lang<'a>() -> Box<dyn Action> {
                             filters: vec![("state", "open")],
                             include_labels: vec!["T-lang", "P-critical"],
                             exclude_labels: vec![],
+                            ordering: HashMap::new(),
                         },
                     },
                     QueryMap {
@@ -542,6 +602,7 @@ pub fn lang<'a>() -> Box<dyn Action> {
                             filters: vec![("state", "open")],
                             include_labels: vec!["T-lang", "I-nominated"],
                             exclude_labels: vec![],
+                            ordering: HashMap::new(),
                         },
                     },
                     QueryMap {
@@ -551,6 +612,7 @@ pub fn lang<'a>() -> Box<dyn Action> {
                             filters: vec![("state", "open")],
                             include_labels: vec!["T-lang", "proposed-final-comment-period"],
                             exclude_labels: vec!["finished-final-comment-period"],
+                            ordering: HashMap::new(),
                         },
                     },
                     QueryMap {
@@ -560,6 +622,7 @@ pub fn lang<'a>() -> Box<dyn Action> {
                             filters: vec![("state", "open")],
                             include_labels: vec!["T-lang", "final-comment-period"],
                             exclude_labels: vec!["finished-final-comment-period"],
+                            ordering: HashMap::new(),
                         },
                     },
                     QueryMap {
@@ -569,6 +632,7 @@ pub fn lang<'a>() -> Box<dyn Action> {
                             filters: vec![("state", "open")],
                             include_labels: vec!["T-lang", "finished-final-comment-period"],
                             exclude_labels: vec![],
+                            ordering: HashMap::new(),
                         },
                     },
                 ],
@@ -591,6 +655,7 @@ pub fn lang_planning<'a>() -> Box<dyn Action> {
                             filters: vec![("state", "open"), ("is", "issue")],
                             include_labels: vec!["major-change"],
                             exclude_labels: vec!["charter-needed"],
+                            ordering: HashMap::new(),
                         },
                     },
                     QueryMap {
@@ -600,6 +665,7 @@ pub fn lang_planning<'a>() -> Box<dyn Action> {
                             filters: vec![("state", "open"), ("is", "pr")],
                             include_labels: vec![],
                             exclude_labels: vec![],
+                            ordering: HashMap::new(),
                         },
                     },
                     QueryMap {
@@ -609,6 +675,7 @@ pub fn lang_planning<'a>() -> Box<dyn Action> {
                             filters: vec![("state", "open"), ("is", "issue")],
                             include_labels: vec!["meeting-proposal"],
                             exclude_labels: vec!["meeting-scheduled"],
+                            ordering: HashMap::new(),
                         },
                     },
                 ],
@@ -622,6 +689,7 @@ pub fn lang_planning<'a>() -> Box<dyn Action> {
                         filters: vec![("state", "open"), ("is", "issue")],
                         include_labels: vec!["lang-initiative"],
                         exclude_labels: vec![],
+                        ordering: HashMap::new(),
                     },
                 }],
             },

+ 39 - 12
src/github.rs

@@ -8,6 +8,7 @@ use once_cell::sync::OnceCell;
 use reqwest::header::{AUTHORIZATION, USER_AGENT};
 use reqwest::{Client, Request, RequestBuilder, Response, StatusCode};
 use std::{
+    collections::HashMap,
     fmt,
     time::{Duration, SystemTime},
 };
@@ -771,6 +772,7 @@ impl Repository {
             filters,
             include_labels,
             exclude_labels,
+            ordering,
             ..
         } = query;
 
@@ -791,11 +793,11 @@ impl Repository {
             || is_pr && !include_labels.is_empty();
 
         let url = if use_search_api {
-            self.build_search_issues_url(filters, include_labels, exclude_labels)
+            self.build_search_issues_url(filters, include_labels, exclude_labels, ordering)
         } else if is_pr {
-            self.build_pulls_url(filters, include_labels)
+            self.build_pulls_url(filters, include_labels, ordering)
         } else {
-            self.build_issues_url(filters, include_labels)
+            self.build_issues_url(filters, include_labels, ordering)
         };
 
         let result = client.get(&url);
@@ -821,12 +823,22 @@ impl Repository {
         Ok(self.get_issues(client, query).await?.len())
     }
 
-    fn build_issues_url(&self, filters: &Vec<(&str, &str)>, include_labels: &Vec<&str>) -> String {
-        self.build_endpoint_url("issues", filters, include_labels)
+    fn build_issues_url(
+        &self,
+        filters: &Vec<(&str, &str)>,
+        include_labels: &Vec<&str>,
+        ordering: &HashMap<&str, &str>,
+    ) -> String {
+        self.build_endpoint_url("issues", filters, include_labels, ordering)
     }
 
-    fn build_pulls_url(&self, filters: &Vec<(&str, &str)>, include_labels: &Vec<&str>) -> String {
-        self.build_endpoint_url("pulls", filters, include_labels)
+    fn build_pulls_url(
+        &self,
+        filters: &Vec<(&str, &str)>,
+        include_labels: &Vec<&str>,
+        ordering: &HashMap<&str, &str>,
+    ) -> String {
+        self.build_endpoint_url("pulls", filters, include_labels, ordering)
     }
 
     fn build_endpoint_url(
@@ -834,6 +846,7 @@ impl Repository {
         endpoint: &str,
         filters: &Vec<(&str, &str)>,
         include_labels: &Vec<&str>,
+        ordering: &HashMap<&str, &str>,
     ) -> String {
         let filters = filters
             .iter()
@@ -843,9 +856,18 @@ impl Repository {
                 include_labels.join(",")
             )))
             .chain(std::iter::once("filter=all".to_owned()))
-            .chain(std::iter::once(format!("sort=created")))
-            .chain(std::iter::once(format!("direction=asc")))
-            .chain(std::iter::once(format!("per_page=100")))
+            .chain(std::iter::once(format!(
+                "sort={}",
+                ordering.get("sort").unwrap_or(&"created")
+            )))
+            .chain(std::iter::once(format!(
+                "direction={}",
+                ordering.get("direction").unwrap_or(&"asc")
+            )))
+            .chain(std::iter::once(format!(
+                "per_page={}",
+                ordering.get("per_page").unwrap_or(&"100")
+            )))
             .collect::<Vec<_>>()
             .join("&");
         format!(
@@ -862,6 +884,7 @@ impl Repository {
         filters: &Vec<(&str, &str)>,
         include_labels: &Vec<&str>,
         exclude_labels: &Vec<&str>,
+        ordering: &HashMap<&str, &str>,
     ) -> String {
         let filters = filters
             .iter()
@@ -881,9 +904,12 @@ impl Repository {
             .collect::<Vec<_>>()
             .join("+");
         format!(
-            "{}/search/issues?q={}&sort=created&order=asc&per_page=100",
+            "{}/search/issues?q={}&sort={}&order={}&per_page={}",
             Repository::GITHUB_API_URL,
-            filters
+            filters,
+            ordering.get("sort").unwrap_or(&"created"),
+            ordering.get("direction").unwrap_or(&"asc"),
+            ordering.get("per_page").unwrap_or(&"100"),
         )
     }
 }
@@ -894,6 +920,7 @@ pub struct Query<'a> {
     pub filters: Vec<(&'a str, &'a str)>,
     pub include_labels: Vec<&'a str>,
     pub exclude_labels: Vec<&'a str>,
+    pub ordering: HashMap<&'a str, &'a str>,
 }
 
 pub enum QueryKind {

+ 5 - 0
templates/prioritization_agenda.tt

@@ -48,6 +48,11 @@ tags: weekly, rustc
 [T-compiler](https://github.com/rust-lang/rust/pulls?utf8=%E2%9C%93&q=is%3Aopen+label%3AS-waiting-on-team+label%3AT-compiler)
 {{-issues::render(issues=prs_waiting_on_team_t_compiler, empty="No PRs waiting on `T-compiler` this time.")}}
 
+### Most recent PRs waiting for review
+
+[T-compiler](https://github.com/rust-lang/rust/pulls?q=is%3Apr+is%3Aopen+sort%3Aupdated-asc+label%3AS-waiting-on-review+draft%3Afalse+label%3AT-compiler)
+{{-issues::render(issues=top_unreviewed_prs, with_age=true, empty="No unreviewed PRs on `T-compiler` this time.")}}
+
 ## Issues of Note
 
 ### Short Summary