Procházet zdrojové kódy

Merge pull request #1692 from tmandry/triage-meeting-project

Use project to get scheduled meetings
Mark Rousskov před 1 rokem
rodič
revize
b96677b606
4 změnil soubory, kde provedl 74 přidání a 29 odebrání
  1. 32 5
      github-graphql/src/lib.rs
  2. 5 5
      src/agenda.rs
  3. 35 19
      src/github.rs
  4. 2 0
      templates/lang_agenda.tt

+ 32 - 5
github-graphql/src/lib.rs

@@ -7,8 +7,10 @@
 pub mod queries {
     use super::schema;
 
+    pub type Date = chrono::NaiveDate;
     pub type DateTime = chrono::DateTime<chrono::Utc>;
 
+    cynic::impl_scalar!(Date, schema::Date);
     cynic::impl_scalar!(DateTime, schema::DateTime);
 
     #[derive(cynic::QueryVariables, Debug, Clone)]
@@ -272,8 +274,8 @@ mod schema {
 }
 
 #[cynic::schema_for_derives(file = "src/github.graphql", module = "schema")]
-pub mod project_items_by_status {
-    use super::queries::{PageInfo, Uri};
+pub mod project_items {
+    use super::queries::{Date, PageInfo, Uri};
     use super::schema;
 
     #[derive(cynic::QueryVariables, Debug, Clone)]
@@ -312,13 +314,25 @@ pub mod project_items_by_status {
     #[derive(cynic::QueryFragment, Debug)]
     pub struct ProjectV2Item {
         pub content: Option<ProjectV2ItemContent>,
+
+        // Currently we hard code the field names we care about here.
+        #[cynic(rename = "fieldValueByName")]
         #[arguments(name = "Status")]
-        pub field_value_by_name: Option<ProjectV2ItemFieldValue>,
+        pub status: Option<ProjectV2ItemFieldValue>,
+        #[cynic(rename = "fieldValueByName")]
+        #[arguments(name = "Date")]
+        pub date: Option<ProjectV2ItemFieldValue>,
     }
 
     impl ProjectV2Item {
-        pub fn status(&self) -> &Option<ProjectV2ItemFieldValue> {
-            &self.field_value_by_name
+        pub fn status(&self) -> Option<&str> {
+            let Some(ref status) = self.status else { return None };
+            status.as_str()
+        }
+
+        pub fn date(&self) -> Option<Date> {
+            let Some(ref date) = self.date else { return None };
+            date.as_date()
         }
     }
 
@@ -333,6 +347,7 @@ pub mod project_items_by_status {
     #[derive(cynic::InlineFragments, Debug)]
     pub enum ProjectV2ItemFieldValue {
         ProjectV2ItemFieldSingleSelectValue(ProjectV2ItemFieldSingleSelectValue),
+        ProjectV2ItemFieldDateValue(ProjectV2ItemFieldDateValue),
 
         #[cynic(fallback)]
         Other,
@@ -345,6 +360,13 @@ pub mod project_items_by_status {
                 _ => return None,
             })
         }
+
+        pub fn as_date(&self) -> Option<Date> {
+            match self {
+                Self::ProjectV2ItemFieldDateValue(val) => val.date,
+                _ => None,
+            }
+        }
     }
 
     #[derive(cynic::QueryFragment, Debug)]
@@ -358,4 +380,9 @@ pub mod project_items_by_status {
     pub struct ProjectV2ItemFieldSingleSelectValue {
         pub name: Option<String>,
     }
+
+    #[derive(cynic::QueryFragment, Debug)]
+    pub struct ProjectV2ItemFieldDateValue {
+        pub date: Option<Date>,
+    }
 }

+ 5 - 5
src/agenda.rs

@@ -475,10 +475,8 @@ pub fn lang<'a>() -> Box<dyn Action + Send + Sync> {
                     QueryMap {
                         name: "scheduled_meetings",
                         kind: QueryKind::List,
-                        query: Arc::new(github::Query {
-                            filters: vec![("state", "open"), ("is", "issue")],
-                            include_labels: vec!["meeting-proposal", "meeting-scheduled"],
-                            exclude_labels: vec![],
+                        query: Arc::new(github::DesignMeetings {
+                            with_status: github::DesignMeetingStatus::Scheduled,
                         }),
                     },
                 ],
@@ -596,7 +594,9 @@ pub fn lang_planning<'a>() -> Box<dyn Action + Send + Sync> {
                     QueryMap {
                         name: "proposed_meetings",
                         kind: QueryKind::List,
-                        query: Arc::new(github::ProposedDesignMeetings),
+                        query: Arc::new(github::DesignMeetings {
+                            with_status: github::DesignMeetingStatus::Proposed,
+                        }),
                     },
                 ],
             },

+ 35 - 19
src/github.rs

@@ -2168,23 +2168,23 @@ impl IssuesQuery for LeastRecentlyReviewedPullRequests {
 async fn project_items_by_status(
     client: &GithubClient,
     status_filter: impl Fn(Option<&str>) -> bool,
-) -> anyhow::Result<Vec<github_graphql::project_items_by_status::ProjectV2ItemContent>> {
+) -> anyhow::Result<Vec<github_graphql::project_items::ProjectV2Item>> {
     use cynic::QueryBuilder;
-    use github_graphql::project_items_by_status;
+    use github_graphql::project_items;
 
     const DESIGN_MEETING_PROJECT: i32 = 31;
-    let mut args = project_items_by_status::Arguments {
+    let mut args = project_items::Arguments {
         project_number: DESIGN_MEETING_PROJECT,
         after: None,
     };
 
     let mut all_items = vec![];
     loop {
-        let query = project_items_by_status::Query::build(args.clone());
+        let query = project_items::Query::build(args.clone());
         let req = client.post(Repository::GITHUB_GRAPHQL_API_URL);
         let req = req.json(&query);
 
-        let data: cynic::GraphQlResponse<project_items_by_status::Query> = client.json(req).await?;
+        let data: cynic::GraphQlResponse<project_items::Query> = client.json(req).await?;
         if let Some(errors) = data.errors {
             anyhow::bail!("There were graphql errors. {:?}", errors);
         }
@@ -2201,14 +2201,7 @@ async fn project_items_by_status(
             .ok_or_else(|| anyhow!("Malformed response."))?
             .into_iter()
             .flatten()
-            .filter(|item| {
-                status_filter(
-                    item.field_value_by_name
-                        .as_ref()
-                        .and_then(|status| status.as_str()),
-                )
-            })
-            .flat_map(|item| item.content);
+            .filter(|item| status_filter(item.status()));
         all_items.extend(filtered);
 
         let page_info = items.page_info;
@@ -2218,26 +2211,49 @@ async fn project_items_by_status(
         args.after = page_info.end_cursor;
     }
 
+    all_items.sort_by_key(|item| item.date());
     Ok(all_items)
 }
 
-pub struct ProposedDesignMeetings;
+pub enum DesignMeetingStatus {
+    Proposed,
+    Scheduled,
+    Done,
+    Empty,
+}
+
+impl DesignMeetingStatus {
+    fn query_str(&self) -> Option<&str> {
+        match self {
+            DesignMeetingStatus::Proposed => Some("Needs triage"),
+            DesignMeetingStatus::Scheduled => Some("Scheduled"),
+            DesignMeetingStatus::Done => Some("Done"),
+            DesignMeetingStatus::Empty => None,
+        }
+    }
+}
+
+pub struct DesignMeetings {
+    pub with_status: DesignMeetingStatus,
+}
+
 #[async_trait]
-impl IssuesQuery for ProposedDesignMeetings {
+impl IssuesQuery for DesignMeetings {
     async fn query<'a>(
         &'a self,
         _repo: &'a Repository,
         _include_fcp_details: bool,
         client: &'a GithubClient,
     ) -> anyhow::Result<Vec<crate::actions::IssueDecorator>> {
-        use github_graphql::project_items_by_status::ProjectV2ItemContent;
+        use github_graphql::project_items::ProjectV2ItemContent;
 
         let items =
-            project_items_by_status(client, |status| status == Some("Needs triage")).await?;
+            project_items_by_status(client, |status| status == self.with_status.query_str())
+                .await?;
         Ok(items
             .into_iter()
-            .flat_map(|item| match item {
-                ProjectV2ItemContent::Issue(issue) => Some(crate::actions::IssueDecorator {
+            .flat_map(|item| match item.content {
+                Some(ProjectV2ItemContent::Issue(issue)) => Some(crate::actions::IssueDecorator {
                     assignees: String::new(),
                     number: issue.number.try_into().unwrap(),
                     fcp_details: None,

+ 2 - 0
templates/lang_agenda.tt

@@ -24,6 +24,8 @@ tags: triage-meeting
 
 {{-issues::render(issues=scheduled_meetings, indent="", empty="No pending proposals this time.")}}
 
+Edit the schedule here: https://github.com/orgs/rust-lang/projects/31/views/7.
+
 ## Announcements or custom items
 
 (Meeting attendees, feel free to add items here!)