@@ -6,7 +6,7 @@ use crate::jobs::Job;
66use crate :: zulip:: to_zulip_id;
77use anyhow:: Context as _;
88use async_trait:: async_trait;
9- use chrono:: Utc ;
9+ use chrono:: { Datelike , NaiveDate , Utc } ;
1010use tracing:: { self as log} ;
1111
1212use super :: Context ;
@@ -17,7 +17,11 @@ const GOALS_STREAM: u64 = 435869; // #project-goals
1717const C_TRACKING_ISSUE : & str = "C-tracking-issue" ;
1818
1919const MESSAGE : & str = r#"
20- Dear $OWNERS, it's been $DAYS days since the last update to your goal *$GOAL*. Please comment on the github tracking issue goals#$GOALNUM with an update at your earliest convenience. Thanks! <3
20+ Dear $OWNERS, it's been $DAYS days since the last update to your goal *$GOAL*.
21+
22+ We will begin drafting the next blog post collecting goal updates $NEXT_UPDATE.
23+
24+ Please comment on the github tracking issue goals#$GOALNUM before then. Thanks! <3
2125
2226Here is a suggested template for updates (feel free to drop the items that don't apply):
2327
@@ -35,7 +39,7 @@ impl Job for ProjectGoalsUpdateJob {
3539 }
3640
3741 async fn run ( & self , ctx : & super :: Context , _metadata : & serde_json:: Value ) -> anyhow:: Result < ( ) > {
38- ping_project_goals_owners ( & ctx. github , false ) . await
42+ ping_project_goals_owners_automatically ( & ctx. github ) . await
3943 }
4044}
4145
@@ -51,7 +55,40 @@ pub async fn check_project_goal_acl(_gh: &GithubClient, gh_id: u64) -> anyhow::R
5155 Ok ( gh_id == GOAL_OWNER_GH_ID )
5256}
5357
54- pub async fn ping_project_goals_owners ( gh : & GithubClient , dry_run : bool ) -> anyhow:: Result < ( ) > {
58+ async fn ping_project_goals_owners_automatically ( gh : & GithubClient ) -> anyhow:: Result < ( ) > {
59+ // Predicted schedule is to author a blog post on the 3rd week of the month.
60+ // We start pinging when the month starts until we see an update in this month
61+ // or the last 7 days of previous month.
62+ //
63+ // Therefore, we compute:
64+ // * Days since start of this month -- threshold will be this number of days + 7.
65+ // * Date of the 3rd Monday in the month -- this will be the next update (e.g., `on Sep-5`).
66+ let now = Utc :: now ( ) ;
67+
68+ // We want to ping people unless they've written an update since the last week of the previous month.
69+ let days_threshold = now. day ( ) + 7 ;
70+
71+ // Format the 3rd Monday of the month, e.g. "on Sep-5", for inclusion.
72+ let third_monday =
73+ NaiveDate :: from_weekday_of_month_opt ( now. year ( ) , now. month ( ) , chrono:: Weekday :: Mon , 3 )
74+ . unwrap ( )
75+ . format ( "on %b-%d" )
76+ . to_string ( ) ;
77+
78+ ping_project_goals_owners ( gh, false , days_threshold as i64 , & third_monday) . await
79+ }
80+
81+ /// Sends a ping message to all project goal owners if
82+ /// they have not posted an update in the last `days_threshold` days.
83+ ///
84+ /// `next_update` is a human readable description of when the next update
85+ /// will be drafted (e.g., `"on Sep 5"`).
86+ pub async fn ping_project_goals_owners (
87+ gh : & GithubClient ,
88+ dry_run : bool ,
89+ days_threshold : i64 ,
90+ next_update : & str ,
91+ ) -> anyhow:: Result < ( ) > {
5592 let goals_repo = gh. repository ( & RUST_PROJECT_GOALS_REPO ) . await ?;
5693
5794 let tracking_issues_query = github:: Query {
@@ -78,7 +115,7 @@ pub async fn ping_project_goals_owners(gh: &GithubClient, dry_run: bool) -> anyh
78115 days_since_last_comment,
79116 comments,
80117 ) ;
81- if days_since_last_comment < 21 && comments > 1 {
118+ if days_since_last_comment < days_threshold && comments > 1 {
82119 continue ;
83120 }
84121
@@ -99,7 +136,8 @@ pub async fn ping_project_goals_owners(gh: &GithubClient, dry_run: bool) -> anyh
99136 } ,
100137 )
101138 . replace ( "$GOALNUM" , & issue. number . to_string ( ) )
102- . replace ( "$GOAL" , & issue. title ) ;
139+ . replace ( "$GOAL" , & issue. title )
140+ . replace ( "$NEXT_UPDATE" , next_update) ;
103141
104142 let zulip_req = crate :: zulip:: MessageApiRequest {
105143 recipient : crate :: zulip:: Recipient :: Stream {
@@ -115,7 +153,9 @@ pub async fn ping_project_goals_owners(gh: &GithubClient, dry_run: bool) -> anyh
115153 if !dry_run {
116154 zulip_req. send ( & gh. raw ( ) ) . await ?;
117155 } else {
118- log:: debug!( "skipping zulip send because dry run" ) ;
156+ eprintln ! ( ) ;
157+ eprintln ! ( "-- Dry Run ------------------------------------" ) ;
158+ eprintln ! ( "Would send to {zulip_topic_name}: {}" , zulip_req. content) ;
119159 }
120160 }
121161
0 commit comments