Skip to content

Commit a9a340a

Browse files
authored
[HUD] Add average PR landing time metric (#6956)
Adds a hud metric to track the average pull request landing time for the PyTorch repository. Specifically, it tracks the time from the initial merge attempt to the first successful merge (only considers merged PRs). Query perf: ``` +------+----------+-----------+ | Test | Avg Time | Avg Mem | +------+----------+-----------+ | 0 | 1215 | 264834466 | | 1 | 1268 | 272445089 | | 2 | 1076 | 267499089 | +------+----------+-----------+ ``` ### Testing: Locally. See the preview.
1 parent e085fb7 commit a9a340a

File tree

3 files changed

+93
-0
lines changed

3 files changed

+93
-0
lines changed
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
{
2+
"params": {
3+
"startTime": "DateTime64(3)",
4+
"stopTime": "DateTime64(3)"
5+
},
6+
"tests": [
7+
{
8+
"startTime": "2024-12-20T00:00:00.000",
9+
"stopTime": "2024-12-27T00:00:00.000"
10+
},
11+
{
12+
"startTime": "2024-12-01T00:00:00.000",
13+
"stopTime": "2024-12-31T23:59:59.999"
14+
},
15+
{
16+
"startTime": "2024-11-01T00:00:00.000",
17+
"stopTime": "2024-11-30T23:59:59.999"
18+
}
19+
]
20+
}
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
-- Query to calculate average PR landing time for recent period
2+
-- Landing time = time from first "Merge started" comment to when PR was merged
3+
WITH
4+
-- Find the first "Merge started" comment for each PR
5+
merge_started AS (
6+
SELECT
7+
toUInt32(extractGroups(issue_url, 'issues/([0-9]+)')[1]) AS pr_number,
8+
MIN(created_at) AS first_merge_attempt
9+
FROM default.issue_comment
10+
WHERE
11+
dynamoKey LIKE 'pytorch/pytorch%'
12+
AND user.login = 'pytorchmergebot'
13+
AND body LIKE '%Merge started%'
14+
AND created_at >= {startTime: DateTime64(3)}
15+
AND created_at <= {stopTime: DateTime64(3)}
16+
GROUP BY pr_number
17+
),
18+
19+
-- Find when PRs were merged (closed with Merged label)
20+
merged_prs AS (
21+
SELECT
22+
number AS pr_number,
23+
parseDateTimeBestEffort(closed_at) AS merge_time
24+
FROM default.pull_request
25+
WHERE
26+
dynamoKey LIKE 'pytorch/pytorch%'
27+
AND state = 'closed'
28+
AND arrayExists(x -> x.'name' = 'Merged', labels)
29+
AND closed_at != ''
30+
AND parseDateTimeBestEffort(closed_at) >= {startTime: DateTime64(3)}
31+
AND parseDateTimeBestEffort(closed_at) <= {stopTime: DateTime64(3)}
32+
),
33+
34+
-- Calculate landing time for each PR
35+
pr_landing_times AS (
36+
SELECT
37+
ms.pr_number,
38+
DATE_DIFF('minute', ms.first_merge_attempt, mp.merge_time)
39+
/ 60.0 AS landing_time_hours
40+
FROM merge_started ms
41+
INNER JOIN merged_prs mp ON ms.pr_number = mp.pr_number
42+
WHERE
43+
-- Ensure merge happened after merge attempt
44+
mp.merge_time > ms.first_merge_attempt
45+
AND landing_time_hours < 168 -- Exclude outliers > 1 week
46+
AND landing_time_hours > 0 -- Exclude negative times
47+
)
48+
49+
-- Return average landing time in hours
50+
SELECT ROUND(AVG(landing_time_hours), 2) AS avg_hours
51+
FROM pr_landing_times

torchci/pages/metrics.tsx

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -752,6 +752,28 @@ export default function Page() {
752752
</Stack>
753753
</Grid2>
754754

755+
<Grid2
756+
container
757+
size={{ xs: 6, md: 3, lg: 2 }}
758+
justifyContent={"stretch"}
759+
>
760+
<Stack
761+
justifyContent={"space-between"}
762+
flexGrow={1}
763+
flexWrap="wrap"
764+
spacing={1}
765+
>
766+
<ScalarPanel
767+
title={"PR landing time (avg)"}
768+
queryName={"pr_landing_time_avg"}
769+
metricName={"avg_hours"}
770+
valueRenderer={(value) => value.toFixed(1) + "h"}
771+
queryParams={timeParams}
772+
badThreshold={(value) => value > 24} // 24 hours
773+
/>
774+
</Stack>
775+
</Grid2>
776+
755777
<Grid2
756778
container
757779
size={{ xs: 6, md: 3, lg: 2 }}

0 commit comments

Comments
 (0)