Skip to content

Commit 5f79c2a

Browse files
Implement new priority estimation methodology based on reach/impact/effort
Co-authored-by: antonkovalenko <[email protected]>
1 parent 894caca commit 5f79c2a

File tree

2 files changed

+213
-8
lines changed

2 files changed

+213
-8
lines changed

.github/workflows/priority-score.yml

Lines changed: 47 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -13,19 +13,58 @@ jobs:
1313
with:
1414
github-token: ${{ secrets.YDBOT_TOKEN }}
1515
script: |
16-
const labelWeights = {
17-
"prio/high": 1000,
18-
"prio/medium": 500,
19-
"prio/low": 100
16+
// Priority estimation based on reach/impact/effort methodology
17+
const reachWeights = {
18+
"reach:high": 100,
19+
"reach:medium": 75,
20+
"reach:low": 50
21+
};
22+
23+
const impactWeights = {
24+
"impact:high": 200,
25+
"impact:medium": 137.5,
26+
"impact:low": 75
27+
};
28+
29+
const effortWeights = {
30+
"effort:high": 10,
31+
"effort:medium": 5,
32+
"effort:low": 2
2033
};
2134
2235
const issue = context.payload.issue;
2336
const labels = issue.labels.map(l => l.name);
24-
const basePriority = Math.min(...labels.map(l => labelWeights[l] || 10), 1000);
2537
26-
const createdAt = new Date(issue.created_at);
27-
const daysOld = Math.floor((Date.now() - createdAt.getTime()) / (1000 * 60 * 60 * 24));
28-
const finalScore = basePriority + daysOld;
38+
// Find reach, impact, and effort values from labels
39+
let reach = null;
40+
let impact = null;
41+
let effort = null;
42+
43+
for (const label of labels) {
44+
if (reachWeights[label] !== undefined) {
45+
reach = reachWeights[label];
46+
}
47+
if (impactWeights[label] !== undefined) {
48+
impact = impactWeights[label];
49+
}
50+
if (effortWeights[label] !== undefined) {
51+
effort = effortWeights[label];
52+
}
53+
}
54+
55+
// Calculate priority score using formula: (reach * impact) / effort
56+
let finalScore = 0;
57+
if (reach !== null && impact !== null && effort !== null) {
58+
finalScore = Math.round((reach * impact) / effort);
59+
} else {
60+
// Fallback to default values if labels are missing
61+
const defaultReach = reach || 50; // default to medium-low reach
62+
const defaultImpact = impact || 75; // default to low impact
63+
const defaultEffort = effort || 5; // default to medium effort
64+
finalScore = Math.round((defaultReach * defaultImpact) / defaultEffort);
65+
}
66+
67+
console.log(`📊 Priority calculation: reach=${reach || 'default'}, impact=${impact || 'default'}, effort=${effort || 'default'} → score=${finalScore}`);
2968
3069
const projectNumber = 24;
3170
const org = "ydb-platform";

priority-estimation-tests.md

Lines changed: 166 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,166 @@
1+
# Priority Estimation Testing Guide
2+
3+
This document contains comprehensive test cases to validate the priority score estimation logic based on reach/impact/effort methodology.
4+
5+
## Methodology Overview
6+
7+
The priority score is calculated using the formula:
8+
9+
```
10+
Priority Score = (Reach × Impact) / Effort
11+
```
12+
13+
### Label Mappings
14+
15+
**Reach Labels** (how many users/stakeholders are affected):
16+
17+
- `reach:high` → 100
18+
- `reach:medium` → 75
19+
- `reach:low` → 50
20+
21+
**Impact Labels** (how much value/benefit):
22+
23+
- `impact:high` → 200
24+
- `impact:medium` → 137.5
25+
- `impact:low` → 75
26+
27+
**Effort Labels** (how much work required):
28+
29+
- `effort:high` → 10
30+
- `effort:medium` → 5
31+
- `effort:low` → 2
32+
33+
## Test Cases
34+
35+
### Test Case 1: Low Reach, Medium Impact, Medium Effort
36+
37+
1. Create an issue or use existing issue
38+
2. Add labels: `reach:low`, `impact:medium`, `effort:medium`
39+
3. Run the GitHub action (or trigger it by editing the issue)
40+
4. **Expected Priority Score**: (50 × 137.5) / 5 = **1,375**
41+
5. Verify the score appears in the YDB UI project board under "CalculatedPriority" field
42+
43+
### Test Case 2: High Reach, High Impact, Low Effort (Highest Priority)
44+
45+
1. Create an issue or use existing issue
46+
2. Add labels: `reach:high`, `impact:high`, `effort:low`
47+
3. Run the GitHub action
48+
4. **Expected Priority Score**: (100 × 200) / 2 = **10,000**
49+
5. Verify this is one of the highest priority scores
50+
51+
### Test Case 3: Low Reach, Low Impact, High Effort (Lowest Priority)
52+
53+
1. Create an issue or use existing issue
54+
2. Add labels: `reach:low`, `impact:low`, `effort:high`
55+
3. Run the GitHub action
56+
4. **Expected Priority Score**: (50 × 75) / 10 = **375**
57+
5. Verify this is one of the lower priority scores
58+
59+
### Test Case 4: Medium Reach, High Impact, Medium Effort
60+
61+
1. Create an issue or use existing issue
62+
2. Add labels: `reach:medium`, `impact:high`, `effort:medium`
63+
3. Run the GitHub action
64+
4. **Expected Priority Score**: (75 × 200) / 5 = **3,000**
65+
5. Verify this appears as a high-priority item
66+
67+
### Test Case 5: High Reach, Low Impact, High Effort
68+
69+
1. Create an issue or use existing issue
70+
2. Add labels: `reach:high`, `impact:low`, `effort:high`
71+
3. Run the GitHub action
72+
4. **Expected Priority Score**: (100 × 75) / 10 = **750**
73+
5. Verify this gets moderate priority despite high reach
74+
75+
### Test Case 6: Missing Reach Label (Default Values)
76+
77+
1. Create an issue or use existing issue
78+
2. Add labels: `impact:medium`, `effort:medium` (no reach label)
79+
3. Run the GitHub action
80+
4. **Expected Priority Score**: (50 × 137.5) / 5 = **1,375** (uses default reach:low value)
81+
5. Verify the action logs show "reach=default"
82+
83+
### Test Case 7: Missing Impact Label (Default Values)
84+
85+
1. Create an issue or use existing issue
86+
2. Add labels: `reach:high`, `effort:low` (no impact label)
87+
3. Run the GitHub action
88+
4. **Expected Priority Score**: (100 × 75) / 2 = **3,750** (uses default impact:low value)
89+
5. Verify the action logs show "impact=default"
90+
91+
### Test Case 8: Missing Effort Label (Default Values)
92+
93+
1. Create an issue or use existing issue
94+
2. Add labels: `reach:medium`, `impact:high` (no effort label)
95+
3. Run the GitHub action
96+
4. **Expected Priority Score**: (75 × 200) / 5 = **3,000** (uses default effort:medium value)
97+
5. Verify the action logs show "effort=default"
98+
99+
### Test Case 9: All Labels Missing (All Default Values)
100+
101+
1. Create an issue or use existing issue
102+
2. Add no reach/impact/effort labels (or only unrelated labels)
103+
3. Run the GitHub action
104+
4. **Expected Priority Score**: (50 × 75) / 5 = **750** (uses all default values)
105+
5. Verify the action logs show "reach=default, impact=default, effort=default"
106+
107+
### Test Case 10: Label Updates Change Priority
108+
109+
1. Create an issue with labels: `reach:low`, `impact:low`, `effort:high`
110+
2. Run the GitHub action
111+
3. Verify initial score: (50 × 75) / 10 = **375**
112+
4. Update labels to: `reach:high`, `impact:high`, `effort:low`
113+
5. Run the GitHub action again (by editing the issue)
114+
6. **Expected New Priority Score**: (100 × 200) / 2 = **10,000**
115+
7. Verify the score updated correctly in the project board
116+
117+
### Test Case 11: Medium Values Across All Dimensions
118+
119+
1. Create an issue or use existing issue
120+
2. Add labels: `reach:medium`, `impact:medium`, `effort:medium`
121+
3. Run the GitHub action
122+
4. **Expected Priority Score**: (75 × 137.5) / 5 = **2,063** (rounded)
123+
5. Verify this appears as a moderate priority item
124+
125+
### Test Case 12: Multiple Labels of Same Type (Last One Wins)
126+
127+
1. Create an issue or use existing issue
128+
2. Add labels: `reach:low`, `reach:high`, `impact:medium`, `effort:low`
129+
3. Run the GitHub action
130+
4. **Expected Priority Score**: (100 × 137.5) / 2 = **6,875** (uses reach:high as the last processed)
131+
5. Verify the calculation uses the higher reach value
132+
133+
## Validation Steps
134+
135+
For each test case:
136+
137+
1. **Trigger the Action**: Edit the issue description or labels to trigger the workflow
138+
2. **Check Action Logs**: Go to Actions tab → Select the "Update Calculated Priority" run → Check logs for calculation details
139+
3. **Verify Project Board**: Navigate to the YDB UI project board and confirm the "CalculatedPriority" field shows the expected value
140+
4. **Compare Relative Priorities**: Ensure issues with higher calculated scores appear higher in priority rankings
141+
142+
## Expected Log Format
143+
144+
The action should log calculation details in this format:
145+
146+
```
147+
📊 Priority calculation: reach=50, impact=137.5, effort=5 → score=1375
148+
✅ Updated CalculatedPriority of issue #123 to 1375
149+
```
150+
151+
## Troubleshooting
152+
153+
- If the action doesn't trigger, check that the `YDBOT_TOKEN` secret has proper permissions
154+
- If scores don't appear on the project board, verify the issue is added to project #24
155+
- If calculations seem incorrect, check the action logs for the exact values used
156+
- If default values aren't applied correctly, verify the fallback logic in the script
157+
158+
## Boundary Testing
159+
160+
Additional edge cases to consider:
161+
162+
- Very old issues (does age factor still apply?)
163+
- Issues with special characters in labels
164+
- Issues not added to the project board
165+
- Network failures during GraphQL API calls
166+
- Issues with multiple reach/impact/effort labels

0 commit comments

Comments
 (0)