Skip to content

Commit c035f14

Browse files
committed
feat: add time in draft tracking to main and markdown_writer functions and tests
1 parent 4b6b4bc commit c035f14

File tree

3 files changed

+77
-21
lines changed

3 files changed

+77
-21
lines changed

issue_metrics.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -244,6 +244,7 @@ def main(): # pragma: no cover
244244
average_time_to_first_response=None,
245245
average_time_to_close=None,
246246
average_time_to_answer=None,
247+
average_time_in_draft=None,
247248
average_time_in_labels=None,
248249
num_issues_opened=None,
249250
num_issues_closed=None,
@@ -268,6 +269,7 @@ def main(): # pragma: no cover
268269
average_time_to_first_response=None,
269270
average_time_to_close=None,
270271
average_time_to_answer=None,
272+
average_time_in_draft=None,
271273
average_time_in_labels=None,
272274
num_issues_opened=None,
273275
num_issues_closed=None,
@@ -329,6 +331,7 @@ def main(): # pragma: no cover
329331
average_time_to_first_response=stats_time_to_first_response,
330332
average_time_to_close=stats_time_to_close,
331333
average_time_to_answer=stats_time_to_answer,
334+
average_time_in_draft=stats_time_in_draft,
332335
average_time_in_labels=stats_time_in_labels,
333336
num_issues_opened=num_issues_open,
334337
num_issues_closed=num_issues_closed,

markdown_writer.py

Lines changed: 39 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,10 @@ def get_non_hidden_columns(labels) -> List[str]:
7171
if not hide_time_to_answer:
7272
columns.append("Time to answer")
7373

74+
enable_time_in_draft = env_vars.draft_pr_tracking
75+
if enable_time_in_draft:
76+
columns.append("Time in draft")
77+
7478
hide_label_metrics = env_vars.hide_label_metrics
7579
if not hide_label_metrics and labels:
7680
for label in labels:
@@ -84,6 +88,7 @@ def write_to_markdown(
8488
average_time_to_first_response: Union[dict[str, timedelta], None],
8589
average_time_to_close: Union[dict[str, timedelta], None],
8690
average_time_to_answer: Union[dict[str, timedelta], None],
91+
average_time_in_draft: Union[dict[str, timedelta], None],
8792
average_time_in_labels: Union[dict, None],
8893
num_issues_opened: Union[int, None],
8994
num_issues_closed: Union[int, None],
@@ -104,6 +109,7 @@ def write_to_markdown(
104109
response for the issues.
105110
average_time_to_close (datetime.timedelta): The average time to close for the issues.
106111
average_time_to_answer (datetime.timedelta): The average time to answer the discussions.
112+
average_time_in_draft (datetime.timedelta): The average time spent in draft for the issues.
107113
average_time_in_labels (dict): A dictionary containing the average time spent in each label.
108114
file (file object, optional): The file object to write to. If not provided,
109115
a file named "issue_metrics.md" will be created.
@@ -112,9 +118,12 @@ def write_to_markdown(
112118
num_mentor_count (int): The number of very active commentors.
113119
labels (List[str]): A list of the labels that are used in the issues.
114120
search_query (str): The search query used to find the issues.
115-
hide_label_metrics (bool): Represents whether the user has chosen to hide label metrics in the output
116-
hide_items_closed_count (bool): Represents whether the user has chosen to hide the number of items closed
117-
non_mentioning_links (bool): Represents whether links do not cause a notification in the desitnation repository
121+
hide_label_metrics (bool): Represents whether the user has chosen to hide label
122+
metrics in the output
123+
hide_items_closed_count (bool): Represents whether the user has chosen to hide
124+
the number of items closed
125+
non_mentioning_links (bool): Represents whether links do not cause a notification
126+
in the destination repository
118127
report_title (str): The title of the report
119128
output_file (str): The name of the file to write the report to
120129
@@ -131,7 +140,8 @@ def write_to_markdown(
131140
if not issues_with_metrics or len(issues_with_metrics) == 0:
132141
file.write("no issues found for the given search criteria\n\n")
133142
file.write(
134-
"\n_This report was generated with the [Issue Metrics Action](https://github.com/github/issue-metrics)_\n"
143+
"\n_This report was generated with the \
144+
[Issue Metrics Action](https://github.com/github/issue-metrics)_\n"
135145
)
136146
if search_query:
137147
file.write(f"Search query used to find these items: `{search_query}`\n")
@@ -143,6 +153,7 @@ def write_to_markdown(
143153
average_time_to_first_response,
144154
average_time_to_close,
145155
average_time_to_answer,
156+
average_time_in_draft,
146157
average_time_in_labels,
147158
num_issues_opened,
148159
num_issues_closed,
@@ -189,13 +200,16 @@ def write_to_markdown(
189200
file.write(f" {issue.time_to_close} |")
190201
if "Time to answer" in columns:
191202
file.write(f" {issue.time_to_answer} |")
203+
if "Time in draft" in columns:
204+
file.write(f" {issue.time_in_draft} |")
192205
if labels and issue.label_metrics:
193206
for label in labels:
194207
if f"Time spent in {label}" in columns:
195208
file.write(f" {issue.label_metrics[label]} |")
196209
file.write("\n")
197210
file.write(
198-
"\n_This report was generated with the [Issue Metrics Action](https://github.com/github/issue-metrics)_\n"
211+
"\n_This report was generated with the \
212+
[Issue Metrics Action](https://github.com/github/issue-metrics)_\n"
199213
)
200214
if search_query:
201215
file.write(f"Search query used to find these items: `{search_query}`\n")
@@ -208,6 +222,7 @@ def write_overall_metrics_tables(
208222
stats_time_to_first_response,
209223
stats_time_to_close,
210224
stats_time_to_answer,
225+
average_time_in_draft,
211226
stats_time_in_labels,
212227
num_issues_opened,
213228
num_issues_closed,
@@ -219,12 +234,15 @@ def write_overall_metrics_tables(
219234
hide_items_closed_count=False,
220235
):
221236
"""Write the overall metrics tables to the markdown file."""
222-
if (
223-
"Time to first response" in columns
224-
or "Time to close" in columns
225-
or "Time to answer" in columns
226-
or (hide_label_metrics is False and len(labels) > 0)
227-
):
237+
if any(
238+
column in columns
239+
for column in [
240+
"Time to first response",
241+
"Time to close",
242+
"Time to answer",
243+
"Time in draft",
244+
]
245+
) or (hide_label_metrics is False and len(labels) > 0):
228246
file.write("| Metric | Average | Median | 90th percentile |\n")
229247
file.write("| --- | --- | --- | ---: |\n")
230248
if "Time to first response" in columns:
@@ -257,6 +275,16 @@ def write_overall_metrics_tables(
257275
)
258276
else:
259277
file.write("| Time to answer | None | None | None |\n")
278+
if "Time in draft" in columns:
279+
if average_time_in_draft is not None:
280+
file.write(
281+
f"| Time in draft "
282+
f"| {average_time_in_draft['avg']} "
283+
f"| {average_time_in_draft['med']} "
284+
f"| {average_time_in_draft['90p']} |\n"
285+
)
286+
else:
287+
file.write("| Time in draft | None | None | None |\n")
260288
if labels and stats_time_in_labels:
261289
for label in labels:
262290
if (

test_markdown_writer.py

Lines changed: 35 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,11 @@
1818

1919
@patch.dict(
2020
os.environ,
21-
{"SEARCH_QUERY": "is:open repo:user/repo", "GH_TOKEN": "test_token"},
21+
{
22+
"SEARCH_QUERY": "is:open repo:user/repo",
23+
"GH_TOKEN": "test_token",
24+
"DRAFT_PR_TRACKING": "True",
25+
},
2226
)
2327
class TestWriteToMarkdown(unittest.TestCase):
2428
"""Test the write_to_markdown function."""
@@ -43,7 +47,8 @@ def test_write_to_markdown(self):
4347
time_to_first_response=timedelta(days=1),
4448
time_to_close=timedelta(days=2),
4549
time_to_answer=timedelta(days=3),
46-
labels_metrics={"bug": timedelta(days=1)},
50+
time_in_draft=timedelta(days=1),
51+
labels_metrics={"bug": timedelta(days=4)},
4752
),
4853
IssueWithMetrics(
4954
title="Issue 2\r",
@@ -52,6 +57,7 @@ def test_write_to_markdown(self):
5257
time_to_first_response=timedelta(days=3),
5358
time_to_close=timedelta(days=4),
5459
time_to_answer=timedelta(days=5),
60+
time_in_draft=timedelta(days=1),
5561
labels_metrics={"bug": timedelta(days=2)},
5662
),
5763
]
@@ -70,6 +76,11 @@ def test_write_to_markdown(self):
7076
"med": timedelta(days=4),
7177
"90p": timedelta(days=4),
7278
}
79+
time_in_draft = {
80+
"avg": timedelta(days=1),
81+
"med": timedelta(days=1),
82+
"90p": timedelta(days=1),
83+
}
7384
time_in_labels = {
7485
"avg": {"bug": "1 day, 12:00:00"},
7586
"med": {"bug": "1 day, 12:00:00"},
@@ -86,6 +97,7 @@ def test_write_to_markdown(self):
8697
average_time_to_first_response=time_to_first_response,
8798
average_time_to_close=time_to_close,
8899
average_time_to_answer=time_to_answer,
100+
average_time_in_draft=time_in_draft,
89101
average_time_in_labels=time_in_labels,
90102
num_issues_opened=num_issues_opened,
91103
num_issues_closed=num_issues_closed,
@@ -106,6 +118,7 @@ def test_write_to_markdown(self):
106118
"| Time to first response | 2 days, 0:00:00 | 2 days, 0:00:00 | 2 days, 0:00:00 |\n"
107119
"| Time to close | 3 days, 0:00:00 | 3 days, 0:00:00 | 3 days, 0:00:00 |\n"
108120
"| Time to answer | 4 days, 0:00:00 | 4 days, 0:00:00 | 4 days, 0:00:00 |\n"
121+
"| Time in draft | 1 day, 0:00:00 | 1 day, 0:00:00 | 1 day, 0:00:00 |\n"
109122
"| Time spent in bug | 1 day, 12:00:00 | 1 day, 12:00:00 | 1 day, 12:00:00 |\n"
110123
"\n"
111124
"| Metric | Count |\n"
@@ -115,12 +128,12 @@ def test_write_to_markdown(self):
115128
"| Number of most active mentors | 5 |\n"
116129
"| Total number of items created | 2 |\n\n"
117130
"| Title | URL | Author | Time to first response | Time to close |"
118-
" Time to answer | Time spent in bug |\n"
119-
"| --- | --- | --- | --- | --- | --- | --- |\n"
131+
" Time to answer | Time in draft | Time spent in bug |\n"
132+
"| --- | --- | --- | --- | --- | --- | --- | --- |\n"
120133
"| Issue 1 | https://github.com/user/repo/issues/1 | [alice](https://github.com/alice) | 1 day, 0:00:00 | "
121-
"2 days, 0:00:00 | 3 days, 0:00:00 | 1 day, 0:00:00 |\n"
134+
"2 days, 0:00:00 | 3 days, 0:00:00 | 1 day, 0:00:00 | 4 days, 0:00:00 |\n"
122135
"| Issue 2 | https://github.com/user/repo/issues/2 | [bob](https://github.com/bob) | 3 days, 0:00:00 | "
123-
"4 days, 0:00:00 | 5 days, 0:00:00 | 2 days, 0:00:00 |\n\n"
136+
"4 days, 0:00:00 | 5 days, 0:00:00 | 1 day, 0:00:00 | 2 days, 0:00:00 |\n\n"
124137
"_This report was generated with the [Issue Metrics Action](https://github.com/github/issue-metrics)_\n"
125138
"Search query used to find these items: `is:issue is:open label:bug`\n"
126139
)
@@ -145,6 +158,7 @@ def test_write_to_markdown_with_vertical_bar_in_title(self):
145158
time_to_first_response=timedelta(days=1),
146159
time_to_close=timedelta(days=2),
147160
time_to_answer=timedelta(days=3),
161+
time_in_draft=timedelta(days=1),
148162
labels_metrics={"bug": timedelta(days=1)},
149163
),
150164
IssueWithMetrics(
@@ -172,6 +186,11 @@ def test_write_to_markdown_with_vertical_bar_in_title(self):
172186
"med": timedelta(days=4),
173187
"90p": timedelta(days=4),
174188
}
189+
average_time_in_draft = {
190+
"avg": timedelta(days=1),
191+
"med": timedelta(days=1),
192+
"90p": timedelta(days=1),
193+
}
175194
average_time_in_labels = {
176195
"avg": {"bug": "1 day, 12:00:00"},
177196
"med": {"bug": "1 day, 12:00:00"},
@@ -188,6 +207,7 @@ def test_write_to_markdown_with_vertical_bar_in_title(self):
188207
average_time_to_first_response=average_time_to_first_response,
189208
average_time_to_close=average_time_to_close,
190209
average_time_to_answer=average_time_to_answer,
210+
average_time_in_draft=average_time_in_draft,
191211
average_time_in_labels=average_time_in_labels,
192212
num_issues_opened=num_issues_opened,
193213
num_issues_closed=num_issues_closed,
@@ -207,6 +227,7 @@ def test_write_to_markdown_with_vertical_bar_in_title(self):
207227
"| Time to first response | 2 days, 0:00:00 | 2 days, 0:00:00 | 2 days, 0:00:00 |\n"
208228
"| Time to close | 3 days, 0:00:00 | 3 days, 0:00:00 | 3 days, 0:00:00 |\n"
209229
"| Time to answer | 4 days, 0:00:00 | 4 days, 0:00:00 | 4 days, 0:00:00 |\n"
230+
"| Time in draft | 1 day, 0:00:00 | 1 day, 0:00:00 | 1 day, 0:00:00 |\n"
210231
"| Time spent in bug | 1 day, 12:00:00 | 1 day, 12:00:00 | 1 day, 12:00:00 |\n"
211232
"\n"
212233
"| Metric | Count |\n"
@@ -216,12 +237,12 @@ def test_write_to_markdown_with_vertical_bar_in_title(self):
216237
"| Number of most active mentors | 5 |\n"
217238
"| Total number of items created | 2 |\n\n"
218239
"| Title | URL | Author | Time to first response | Time to close |"
219-
" Time to answer | Time spent in bug |\n"
220-
"| --- | --- | --- | --- | --- | --- | --- |\n"
240+
" Time to answer | Time in draft | Time spent in bug |\n"
241+
"| --- | --- | --- | --- | --- | --- | --- | --- |\n"
221242
"| Issue 1 | https://github.com/user/repo/issues/1 | [alice](https://github.com/alice) | 1 day, 0:00:00 | "
222-
"2 days, 0:00:00 | 3 days, 0:00:00 | 1 day, 0:00:00 |\n"
243+
"2 days, 0:00:00 | 3 days, 0:00:00 | 1 day, 0:00:00 | 1 day, 0:00:00 |\n"
223244
"| feat| Issue 2 | https://github.com/user/repo/issues/2 | [bob](https://github.com/bob) | 3 days, 0:00:00 | "
224-
"4 days, 0:00:00 | 5 days, 0:00:00 | 2 days, 0:00:00 |\n\n"
245+
"4 days, 0:00:00 | 5 days, 0:00:00 | None | 2 days, 0:00:00 |\n\n"
225246
"_This report was generated with the [Issue Metrics Action](https://github.com/github/issue-metrics)_\n"
226247
)
227248
self.assertEqual(content, expected_content)
@@ -240,6 +261,7 @@ def test_write_to_markdown_no_issues(self):
240261
None,
241262
None,
242263
None,
264+
None,
243265
report_title="Issue Metrics",
244266
)
245267

@@ -289,6 +311,7 @@ def test_writes_markdown_file_with_non_hidden_columns_only(self):
289311
time_to_first_response=timedelta(minutes=10),
290312
time_to_close=timedelta(days=1),
291313
time_to_answer=timedelta(hours=2),
314+
time_in_draft=timedelta(days=1),
292315
labels_metrics={
293316
"label1": timedelta(days=1),
294317
},
@@ -308,6 +331,7 @@ def test_writes_markdown_file_with_non_hidden_columns_only(self):
308331
average_time_to_first_response = timedelta(minutes=15)
309332
average_time_to_close = timedelta(days=1.5)
310333
average_time_to_answer = timedelta(hours=3)
334+
average_time_in_draft = timedelta(days=1)
311335
average_time_in_labels = {
312336
"label1": timedelta(days=1),
313337
}
@@ -322,6 +346,7 @@ def test_writes_markdown_file_with_non_hidden_columns_only(self):
322346
average_time_to_close=average_time_to_close,
323347
average_time_to_answer=average_time_to_answer,
324348
average_time_in_labels=average_time_in_labels,
349+
average_time_in_draft=average_time_in_draft,
325350
num_issues_opened=num_issues_opened,
326351
num_issues_closed=num_issues_closed,
327352
num_mentor_count=num_mentor_count,

0 commit comments

Comments
 (0)