@@ -48,7 +48,60 @@ pub async fn updates(
48
48
49
49
let mut output = String :: new ( ) ;
50
50
51
- for ( title, issue) in issues {
51
+ writeln ! ( output, "INTRO" ) ?;
52
+
53
+ // First process the flagship goals. These are handled differently.
54
+ writeln ! ( output, "## Flagship goals" ) ?;
55
+ for ( title, issue) in & issues {
56
+ if !issue. has_flagship_label ( ) {
57
+ continue ;
58
+ }
59
+
60
+ progress_bar:: print_progress_bar_info (
61
+ & format ! ( "Issue #{number}" , number = issue. number) ,
62
+ & title,
63
+ progress_bar:: Color :: Green ,
64
+ progress_bar:: Style :: Bold ,
65
+ ) ;
66
+
67
+ let issue_id = IssueId {
68
+ repository : repository. clone ( ) ,
69
+ number : issue. number ,
70
+ } ;
71
+
72
+ writeln ! ( output, "### {title}" ) ?;
73
+ writeln ! (
74
+ output,
75
+ "**Tracked in [#{number}]({url}); assigned to {assignees}" ,
76
+ number = issue. number,
77
+ url = issue_id. url( ) ,
78
+ assignees = comma( & issue. assignees) ,
79
+ ) ?;
80
+
81
+ let mut comments = issue. comments . clone ( ) ;
82
+ comments. sort_by_key ( |c| c. created_at . clone ( ) ) ;
83
+ comments. retain ( |c| filter. matches ( c) ) ;
84
+
85
+ for comment in comments {
86
+ writeln ! (
87
+ output,
88
+ "Update by {author} on [{date}]({url}):\n \n {body}" ,
89
+ author = comment. author,
90
+ date = comment. created_at_date( ) . format( "%m %d" ) ,
91
+ body = comment. body,
92
+ url = comment. url,
93
+ ) ?;
94
+ }
95
+ }
96
+
97
+ // Next process the remaining goals, for which we generate a table.
98
+ writeln ! ( output, "## Other goals" ) ?;
99
+ writeln ! ( output, "<table>" ) ?;
100
+ for ( title, issue) in & issues {
101
+ if issue. has_flagship_label ( ) {
102
+ continue ;
103
+ }
104
+
52
105
progress_bar:: print_progress_bar_info (
53
106
& format ! ( "Issue #{number}" , number = issue. number) ,
54
107
& title,
@@ -59,9 +112,10 @@ pub async fn updates(
59
112
let prompt = format ! (
60
113
"The following comments are updates to a project goal entitled '{title}'. \
61
114
The goal is assigned to {people} ({assignees}). \
62
- Please create a 1 paragraph summary of these updates. \
63
- Do not restate the goal title or give a generic introduction. \
115
+ Summarize the updates with a list of one or two bullet points, each one sentence. \
64
116
Write the update in the third person. \
117
+ Format the bullet points as markdown with each bullet point beginning with `* `. \
118
+ Do not respond with anything but the bullet points. \
65
119
",
66
120
people = if issue. assignees. len( ) == 1 {
67
121
"1 person" . to_string( )
@@ -79,10 +133,7 @@ pub async fn updates(
79
133
let ( completed, total) = progress. completed_total ( ) ;
80
134
let status_badge = match issue. state {
81
135
ExistingIssueState :: Open => {
82
- format ! (
83
- "" ,
84
- percent = completed * 100 / total
85
- )
136
+ format!( "<progress value=" { completed} " max=" { total} ")
86
137
}
87
138
ExistingIssueState::Closed if completed == total => {
88
139
format!(" ![ Status : Complete ] ( https: //img.shields.io/badge/Status-Completed-green)")
@@ -97,35 +148,40 @@ pub async fn updates(
97
148
number: issue. number,
98
149
} ;
99
150
100
- writeln ! ( output) ?;
101
- writeln ! ( output) ?;
102
- writeln ! ( output) ?;
151
+ writeln!( output, "<tr>" ) ?;
152
+ writeln!( output, "<th>" ) ?;
153
+ writeln!( output, "[#{number}]({url}" , number = issue. number, url = issue_id. url( ) ) ?;
154
+ writeln!( output, "</th>" ) ?;
155
+ writeln!( output, "<th>" ) ?;
156
+ writeln!( output, "{title}" ) ;
157
+ writeln!( output, "</th>" ) ?;
158
+ writeln!( output, "<th>" ) ?;
159
+ writeln!( output, "{status_badge}" ) ;
160
+ writeln!( output, "</th>" ) ?;
161
+ writeln!( output, "</tr>" ) ?;
162
+ writeln!( output, "<tr>" ) ?;
163
+ writeln!( output, "<td colspan='3'>" ) ?;
103
164
writeln!(
104
165
output,
105
- "# [Issue #{number}]({url}): {title} {status_badge}" ,
106
- number = issue. number,
107
- url = issue_id. url( ) ,
108
- ) ?;
109
- writeln ! ( output) ?;
110
- writeln ! (
111
- output,
112
- "* Assigned to: {assignees}" ,
166
+ "Assigned to: {assignees}" ,
113
167
assignees = comma( & issue. assignees)
114
168
) ?;
115
- writeln ! ( output) ?;
116
-
169
+ writeln!( output, "</td>" ) ?;
170
+ writeln!( output, "</tr>" ) ?;
171
+ writeln!( output, "<tr>" ) ?;
117
172
if comments. len( ) > 0 {
118
173
let updates: String = comments. iter( ) . map( |c| format!( "\n {}\n " , c. body) ) . collect( ) ;
119
174
let summary = llm. query( & prompt, & updates) . await ?;
120
- writeln ! ( output) ?;
121
175
writeln!( output, "{}" , summary) ?;
122
176
} else {
123
177
writeln!( output) ?;
124
- writeln ! ( output, "No updates in this period." ) ?;
178
+ writeln!( output, "* No updates in this period." ) ?;
125
179
}
180
+ writeln!( output, "</tr>" ) ?;
126
181
127
182
progress_bar:: inc_progress_bar( ) ;
128
183
}
184
+ writeln!( output, "</table>" ) ?;
129
185
130
186
std:: fs:: write( & output_file, output)
131
187
. with_context( || format!( "failed to write to `{}`" , output_file. display( ) ) ) ?;
0 commit comments