@@ -37,7 +37,25 @@ var tpls embed.FS
3737// runs with `--type=patch` to return the patch schedule
3838func parsePatchSchedule (patchSchedule PatchSchedule ) string {
3939 output := []string {}
40+
41+ if len (patchSchedule .UpcomingReleases ) > 0 {
42+ output = append (output , "### Upcoming Monthly Releases\n " )
43+ tableString := & strings.Builder {}
44+ table := tablewriter .NewWriter (tableString )
45+ table .SetAutoWrapText (false )
46+ table .SetHeader ([]string {"Monthly Patch Release" , "Cherry Pick Deadline" , "Target Date" })
47+ for _ , upcoming := range patchSchedule .UpcomingReleases {
48+ table .Append ([]string {strings .TrimSpace (upcoming .Release ), strings .TrimSpace (upcoming .CherryPickDeadline ), strings .TrimSpace (upcoming .TargetDate )})
49+ }
50+ table .SetBorders (tablewriter.Border {Left : true , Top : false , Right : true , Bottom : false })
51+ table .SetCenterSeparator ("|" )
52+ table .Render ()
53+
54+ output = append (output , tableString .String ())
55+ }
56+
4057 output = append (output , "### Timeline\n " )
58+
4159 for _ , releaseSchedule := range patchSchedule .Schedules {
4260 output = append (output , fmt .Sprintf ("### %s\n " , releaseSchedule .Release ),
4361 fmt .Sprintf ("Next patch release is **%s**\n " , releaseSchedule .Next .Release ),
@@ -207,6 +225,46 @@ func updatePatchSchedule(refTime time.Time, schedule PatchSchedule, filePath str
207225 }
208226 }
209227
228+ newUpcomingReleases := []* PatchRelease {}
229+ latestDate := refTime
230+ for _ , upcomingRelease := range schedule .UpcomingReleases {
231+ upcomingTargetDate , err := time .Parse (refDate , upcomingRelease .TargetDate )
232+ if err != nil {
233+ return fmt .Errorf ("parse upcoming release target date: %w" , err )
234+ }
235+
236+ if refTime .After (upcomingTargetDate ) {
237+ logrus .Infof ("Skipping outdated upcoming release for %s (%s)" , upcomingRelease .Release , upcomingRelease .TargetDate )
238+ continue
239+ }
240+
241+ logrus .Infof ("Using existing upcoming release for %s (%s)" , upcomingRelease .Release , upcomingRelease .TargetDate )
242+ newUpcomingReleases = append (newUpcomingReleases , upcomingRelease )
243+ latestDate = upcomingTargetDate
244+ }
245+ for {
246+ if len (newUpcomingReleases ) >= 3 {
247+ logrus .Infof ("Got 3 new upcoming releases, not adding any more" )
248+ break
249+ }
250+
251+ latestDate = latestDate .AddDate (0 , 1 , 0 )
252+ cherryPickDay := firstFriday (latestDate )
253+ targetDateDay := secondTuesday (latestDate )
254+ nextCherryPickDeadline := time .Date (latestDate .Year (), latestDate .Month (), cherryPickDay , 0 , 0 , 0 , 0 , time .UTC )
255+ nextTargetDate := time .Date (latestDate .Year (), latestDate .Month (), targetDateDay , 0 , 0 , 0 , 0 , time .UTC )
256+
257+ releaseName := nextTargetDate .Format ("January 2006" )
258+ logrus .Infof ("Adding new upcoming release for %s" , releaseName )
259+
260+ newUpcomingReleases = append (newUpcomingReleases , & PatchRelease {
261+ Release : releaseName ,
262+ CherryPickDeadline : nextCherryPickDeadline .Format (refDate ),
263+ TargetDate : nextTargetDate .Format (refDate ),
264+ })
265+ }
266+ schedule .UpcomingReleases = newUpcomingReleases
267+
210268 yamlBytes , err := yaml .Marshal (schedule )
211269 if err != nil {
212270 return fmt .Errorf ("marshal schedule YAML: %w" , err )
0 commit comments