Skip to content

Commit 33f2ad0

Browse files
authored
[HUD] Add merge retry rate calculation metric (#6957)
Adds the metric that calculates the average number of merge attempts it takes to merge the PR in. Only counts attempts up to when the PR was closed/merged the first time (for simplicity). Excludes pytorchupdatebot PRs. ### Testing * locally * query perf: ``` +------+----------+-----------+ | Test | Avg Time | Avg Mem | +------+----------+-----------+ | 0 | 2201 | 280219309 | | 1 | 1290 | 275053899 | | 2 | 1215 | 283963827 | +------+----------+-----------+ ```
1 parent b8b2d9b commit 33f2ad0

File tree

3 files changed

+92
-0
lines changed

3 files changed

+92
-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: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
-- Query to calculate average merge retry rate for recent period
2+
-- Merge retry rate = average number of merge attempts before first successful merge
3+
-- Only counts attempts up to when the PR was closed/merged (proxy for dev friction)
4+
-- Filters by PR creation date
5+
-- Excludes pytorchupdatebot PRs to avoid skewing metrics with stuck bot updates
6+
WITH
7+
merged_prs AS (
8+
SELECT
9+
number AS pr_number,
10+
parseDateTimeBestEffort(closed_at) AS merge_time,
11+
parseDateTimeBestEffort(created_at) AS created_time,
12+
user.login AS author
13+
FROM default.pull_request
14+
WHERE
15+
dynamoKey LIKE 'pytorch/pytorch%'
16+
AND state = 'closed'
17+
AND arrayExists(x -> x.'name' = 'Merged', labels)
18+
AND closed_at != ''
19+
-- Filter by PR creation date
20+
AND parseDateTimeBestEffort(created_at) >= {startTime: DateTime64(3)}
21+
AND parseDateTimeBestEffort(created_at) <= {stopTime: DateTime64(3)}
22+
-- Exclude pytorchupdatebot PRs (often stuck with many attempts)
23+
AND user.login != 'pytorchupdatebot'
24+
),
25+
26+
all_merge_attempts AS (
27+
SELECT
28+
toUInt32(extractGroups(issue_url, 'issues/([0-9]+)')[1]) AS pr_number,
29+
created_at
30+
FROM default.issue_comment
31+
WHERE
32+
dynamoKey LIKE 'pytorch/pytorch%'
33+
AND user.login = 'pytorchmergebot'
34+
AND body LIKE '%Merge started%'
35+
),
36+
37+
attempts_per_pr AS (
38+
SELECT
39+
mp.pr_number,
40+
COUNT(*) AS attempt_count
41+
FROM merged_prs mp
42+
CROSS JOIN all_merge_attempts ama
43+
WHERE
44+
ama.pr_number = mp.pr_number
45+
AND ama.created_at <= mp.merge_time
46+
GROUP BY mp.pr_number
47+
)
48+
49+
SELECT ROUND(AVG(attempt_count), 2) AS avg_retry_rate
50+
FROM attempts_per_pr

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={"Merge retry rate (avg)"}
768+
queryName={"merge_retry_rate"}
769+
metricName={"avg_retry_rate"}
770+
valueRenderer={(value) => value.toFixed(2) + "x"}
771+
queryParams={timeParams}
772+
badThreshold={(value) => value > 2.0} // 2.0 average retries
773+
/>
774+
</Stack>
775+
</Grid2>
776+
755777
<Grid2
756778
container
757779
size={{ xs: 6, md: 3, lg: 2 }}

0 commit comments

Comments
 (0)