From 894caca310d94d79cb30df07b086e77ba4782b23 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 24 Jul 2025 11:10:26 +0000 Subject: [PATCH 1/4] Initial plan From 5f79c2adea08dac726a048de3388da4ac85ef5ee Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 24 Jul 2025 11:21:31 +0000 Subject: [PATCH 2/4] Implement new priority estimation methodology based on reach/impact/effort Co-authored-by: antonkovalenko <692649+antonkovalenko@users.noreply.github.com> --- .github/workflows/priority-score.yml | 55 +++++++-- priority-estimation-tests.md | 166 +++++++++++++++++++++++++++ 2 files changed, 213 insertions(+), 8 deletions(-) create mode 100644 priority-estimation-tests.md diff --git a/.github/workflows/priority-score.yml b/.github/workflows/priority-score.yml index fb52ccdedb..ab184f2a05 100644 --- a/.github/workflows/priority-score.yml +++ b/.github/workflows/priority-score.yml @@ -13,19 +13,58 @@ jobs: with: github-token: ${{ secrets.YDBOT_TOKEN }} script: | - const labelWeights = { - "prio/high": 1000, - "prio/medium": 500, - "prio/low": 100 + // Priority estimation based on reach/impact/effort methodology + const reachWeights = { + "reach:high": 100, + "reach:medium": 75, + "reach:low": 50 + }; + + const impactWeights = { + "impact:high": 200, + "impact:medium": 137.5, + "impact:low": 75 + }; + + const effortWeights = { + "effort:high": 10, + "effort:medium": 5, + "effort:low": 2 }; const issue = context.payload.issue; const labels = issue.labels.map(l => l.name); - const basePriority = Math.min(...labels.map(l => labelWeights[l] || 10), 1000); - const createdAt = new Date(issue.created_at); - const daysOld = Math.floor((Date.now() - createdAt.getTime()) / (1000 * 60 * 60 * 24)); - const finalScore = basePriority + daysOld; + // Find reach, impact, and effort values from labels + let reach = null; + let impact = null; + let effort = null; + + for (const label of labels) { + if (reachWeights[label] !== undefined) { + reach = reachWeights[label]; + } + if (impactWeights[label] !== undefined) { + impact = impactWeights[label]; + } + if (effortWeights[label] !== undefined) { + effort = effortWeights[label]; + } + } + + // Calculate priority score using formula: (reach * impact) / effort + let finalScore = 0; + if (reach !== null && impact !== null && effort !== null) { + finalScore = Math.round((reach * impact) / effort); + } else { + // Fallback to default values if labels are missing + const defaultReach = reach || 50; // default to medium-low reach + const defaultImpact = impact || 75; // default to low impact + const defaultEffort = effort || 5; // default to medium effort + finalScore = Math.round((defaultReach * defaultImpact) / defaultEffort); + } + + console.log(`📊 Priority calculation: reach=${reach || 'default'}, impact=${impact || 'default'}, effort=${effort || 'default'} → score=${finalScore}`); const projectNumber = 24; const org = "ydb-platform"; diff --git a/priority-estimation-tests.md b/priority-estimation-tests.md new file mode 100644 index 0000000000..ae120d8c7e --- /dev/null +++ b/priority-estimation-tests.md @@ -0,0 +1,166 @@ +# Priority Estimation Testing Guide + +This document contains comprehensive test cases to validate the priority score estimation logic based on reach/impact/effort methodology. + +## Methodology Overview + +The priority score is calculated using the formula: + +``` +Priority Score = (Reach × Impact) / Effort +``` + +### Label Mappings + +**Reach Labels** (how many users/stakeholders are affected): + +- `reach:high` → 100 +- `reach:medium` → 75 +- `reach:low` → 50 + +**Impact Labels** (how much value/benefit): + +- `impact:high` → 200 +- `impact:medium` → 137.5 +- `impact:low` → 75 + +**Effort Labels** (how much work required): + +- `effort:high` → 10 +- `effort:medium` → 5 +- `effort:low` → 2 + +## Test Cases + +### Test Case 1: Low Reach, Medium Impact, Medium Effort + +1. Create an issue or use existing issue +2. Add labels: `reach:low`, `impact:medium`, `effort:medium` +3. Run the GitHub action (or trigger it by editing the issue) +4. **Expected Priority Score**: (50 × 137.5) / 5 = **1,375** +5. Verify the score appears in the YDB UI project board under "CalculatedPriority" field + +### Test Case 2: High Reach, High Impact, Low Effort (Highest Priority) + +1. Create an issue or use existing issue +2. Add labels: `reach:high`, `impact:high`, `effort:low` +3. Run the GitHub action +4. **Expected Priority Score**: (100 × 200) / 2 = **10,000** +5. Verify this is one of the highest priority scores + +### Test Case 3: Low Reach, Low Impact, High Effort (Lowest Priority) + +1. Create an issue or use existing issue +2. Add labels: `reach:low`, `impact:low`, `effort:high` +3. Run the GitHub action +4. **Expected Priority Score**: (50 × 75) / 10 = **375** +5. Verify this is one of the lower priority scores + +### Test Case 4: Medium Reach, High Impact, Medium Effort + +1. Create an issue or use existing issue +2. Add labels: `reach:medium`, `impact:high`, `effort:medium` +3. Run the GitHub action +4. **Expected Priority Score**: (75 × 200) / 5 = **3,000** +5. Verify this appears as a high-priority item + +### Test Case 5: High Reach, Low Impact, High Effort + +1. Create an issue or use existing issue +2. Add labels: `reach:high`, `impact:low`, `effort:high` +3. Run the GitHub action +4. **Expected Priority Score**: (100 × 75) / 10 = **750** +5. Verify this gets moderate priority despite high reach + +### Test Case 6: Missing Reach Label (Default Values) + +1. Create an issue or use existing issue +2. Add labels: `impact:medium`, `effort:medium` (no reach label) +3. Run the GitHub action +4. **Expected Priority Score**: (50 × 137.5) / 5 = **1,375** (uses default reach:low value) +5. Verify the action logs show "reach=default" + +### Test Case 7: Missing Impact Label (Default Values) + +1. Create an issue or use existing issue +2. Add labels: `reach:high`, `effort:low` (no impact label) +3. Run the GitHub action +4. **Expected Priority Score**: (100 × 75) / 2 = **3,750** (uses default impact:low value) +5. Verify the action logs show "impact=default" + +### Test Case 8: Missing Effort Label (Default Values) + +1. Create an issue or use existing issue +2. Add labels: `reach:medium`, `impact:high` (no effort label) +3. Run the GitHub action +4. **Expected Priority Score**: (75 × 200) / 5 = **3,000** (uses default effort:medium value) +5. Verify the action logs show "effort=default" + +### Test Case 9: All Labels Missing (All Default Values) + +1. Create an issue or use existing issue +2. Add no reach/impact/effort labels (or only unrelated labels) +3. Run the GitHub action +4. **Expected Priority Score**: (50 × 75) / 5 = **750** (uses all default values) +5. Verify the action logs show "reach=default, impact=default, effort=default" + +### Test Case 10: Label Updates Change Priority + +1. Create an issue with labels: `reach:low`, `impact:low`, `effort:high` +2. Run the GitHub action +3. Verify initial score: (50 × 75) / 10 = **375** +4. Update labels to: `reach:high`, `impact:high`, `effort:low` +5. Run the GitHub action again (by editing the issue) +6. **Expected New Priority Score**: (100 × 200) / 2 = **10,000** +7. Verify the score updated correctly in the project board + +### Test Case 11: Medium Values Across All Dimensions + +1. Create an issue or use existing issue +2. Add labels: `reach:medium`, `impact:medium`, `effort:medium` +3. Run the GitHub action +4. **Expected Priority Score**: (75 × 137.5) / 5 = **2,063** (rounded) +5. Verify this appears as a moderate priority item + +### Test Case 12: Multiple Labels of Same Type (Last One Wins) + +1. Create an issue or use existing issue +2. Add labels: `reach:low`, `reach:high`, `impact:medium`, `effort:low` +3. Run the GitHub action +4. **Expected Priority Score**: (100 × 137.5) / 2 = **6,875** (uses reach:high as the last processed) +5. Verify the calculation uses the higher reach value + +## Validation Steps + +For each test case: + +1. **Trigger the Action**: Edit the issue description or labels to trigger the workflow +2. **Check Action Logs**: Go to Actions tab → Select the "Update Calculated Priority" run → Check logs for calculation details +3. **Verify Project Board**: Navigate to the YDB UI project board and confirm the "CalculatedPriority" field shows the expected value +4. **Compare Relative Priorities**: Ensure issues with higher calculated scores appear higher in priority rankings + +## Expected Log Format + +The action should log calculation details in this format: + +``` +📊 Priority calculation: reach=50, impact=137.5, effort=5 → score=1375 +✅ Updated CalculatedPriority of issue #123 to 1375 +``` + +## Troubleshooting + +- If the action doesn't trigger, check that the `YDBOT_TOKEN` secret has proper permissions +- If scores don't appear on the project board, verify the issue is added to project #24 +- If calculations seem incorrect, check the action logs for the exact values used +- If default values aren't applied correctly, verify the fallback logic in the script + +## Boundary Testing + +Additional edge cases to consider: + +- Very old issues (does age factor still apply?) +- Issues with special characters in labels +- Issues not added to the project board +- Network failures during GraphQL API calls +- Issues with multiple reach/impact/effort labels From cd4464a3e5d256a7c1bdd37297433c2948ea8da0 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 24 Jul 2025 11:23:34 +0000 Subject: [PATCH 3/4] Add additional test cases and edge case documentation Co-authored-by: antonkovalenko <692649+antonkovalenko@users.noreply.github.com> --- priority-estimation-tests.md | 27 +++++++++++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) diff --git a/priority-estimation-tests.md b/priority-estimation-tests.md index ae120d8c7e..ee0ae7f22a 100644 --- a/priority-estimation-tests.md +++ b/priority-estimation-tests.md @@ -155,12 +155,35 @@ The action should log calculation details in this format: - If calculations seem incorrect, check the action logs for the exact values used - If default values aren't applied correctly, verify the fallback logic in the script +## Additional Test Cases (13-15) + +### Test Case 13: Multiple Labels of Same Category (Overwrite Behavior) + +1. Create an issue with labels: `reach:low`, `reach:medium`, `reach:high`, `impact:medium`, `effort:low` +2. Run the GitHub action +3. **Expected Priority Score**: (100 × 137.5) / 2 = **6,875** (should use `reach:high` as the last processed) +4. Verify the action correctly handles multiple conflicting labels + +### Test Case 14: Edge Case - Lowest Possible Score + +1. Create an issue with labels: `reach:low`, `impact:low`, `effort:high` +2. Run the GitHub action +3. **Expected Priority Score**: (50 × 75) / 10 = **375** +4. Verify this represents the minimum priority calculation + +### Test Case 15: Edge Case - Highest Possible Score + +1. Create an issue with labels: `reach:high`, `impact:high`, `effort:low` +2. Run the GitHub action +3. **Expected Priority Score**: (100 × 200) / 2 = **10,000** +4. Verify this represents the maximum priority calculation + ## Boundary Testing Additional edge cases to consider: -- Very old issues (does age factor still apply?) - Issues with special characters in labels - Issues not added to the project board - Network failures during GraphQL API calls -- Issues with multiple reach/impact/effort labels +- Issues with multiple reach/impact/effort labels (should use last processed value) +- Rounding behavior for non-integer results From ad30a3eadb9527ad9cc308a3c8f260a993ed6481 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 31 Jul 2025 16:25:01 +0000 Subject: [PATCH 4/4] feat: implement reach/impact/effort priority methodology Replace simple priority calculation with reach/impact/effort formula. Fixes #2614. Co-authored-by: adameat <34044711+adameat@users.noreply.github.com> --- priority-estimation-tests.md | 189 ----------------------------------- 1 file changed, 189 deletions(-) delete mode 100644 priority-estimation-tests.md diff --git a/priority-estimation-tests.md b/priority-estimation-tests.md deleted file mode 100644 index ee0ae7f22a..0000000000 --- a/priority-estimation-tests.md +++ /dev/null @@ -1,189 +0,0 @@ -# Priority Estimation Testing Guide - -This document contains comprehensive test cases to validate the priority score estimation logic based on reach/impact/effort methodology. - -## Methodology Overview - -The priority score is calculated using the formula: - -``` -Priority Score = (Reach × Impact) / Effort -``` - -### Label Mappings - -**Reach Labels** (how many users/stakeholders are affected): - -- `reach:high` → 100 -- `reach:medium` → 75 -- `reach:low` → 50 - -**Impact Labels** (how much value/benefit): - -- `impact:high` → 200 -- `impact:medium` → 137.5 -- `impact:low` → 75 - -**Effort Labels** (how much work required): - -- `effort:high` → 10 -- `effort:medium` → 5 -- `effort:low` → 2 - -## Test Cases - -### Test Case 1: Low Reach, Medium Impact, Medium Effort - -1. Create an issue or use existing issue -2. Add labels: `reach:low`, `impact:medium`, `effort:medium` -3. Run the GitHub action (or trigger it by editing the issue) -4. **Expected Priority Score**: (50 × 137.5) / 5 = **1,375** -5. Verify the score appears in the YDB UI project board under "CalculatedPriority" field - -### Test Case 2: High Reach, High Impact, Low Effort (Highest Priority) - -1. Create an issue or use existing issue -2. Add labels: `reach:high`, `impact:high`, `effort:low` -3. Run the GitHub action -4. **Expected Priority Score**: (100 × 200) / 2 = **10,000** -5. Verify this is one of the highest priority scores - -### Test Case 3: Low Reach, Low Impact, High Effort (Lowest Priority) - -1. Create an issue or use existing issue -2. Add labels: `reach:low`, `impact:low`, `effort:high` -3. Run the GitHub action -4. **Expected Priority Score**: (50 × 75) / 10 = **375** -5. Verify this is one of the lower priority scores - -### Test Case 4: Medium Reach, High Impact, Medium Effort - -1. Create an issue or use existing issue -2. Add labels: `reach:medium`, `impact:high`, `effort:medium` -3. Run the GitHub action -4. **Expected Priority Score**: (75 × 200) / 5 = **3,000** -5. Verify this appears as a high-priority item - -### Test Case 5: High Reach, Low Impact, High Effort - -1. Create an issue or use existing issue -2. Add labels: `reach:high`, `impact:low`, `effort:high` -3. Run the GitHub action -4. **Expected Priority Score**: (100 × 75) / 10 = **750** -5. Verify this gets moderate priority despite high reach - -### Test Case 6: Missing Reach Label (Default Values) - -1. Create an issue or use existing issue -2. Add labels: `impact:medium`, `effort:medium` (no reach label) -3. Run the GitHub action -4. **Expected Priority Score**: (50 × 137.5) / 5 = **1,375** (uses default reach:low value) -5. Verify the action logs show "reach=default" - -### Test Case 7: Missing Impact Label (Default Values) - -1. Create an issue or use existing issue -2. Add labels: `reach:high`, `effort:low` (no impact label) -3. Run the GitHub action -4. **Expected Priority Score**: (100 × 75) / 2 = **3,750** (uses default impact:low value) -5. Verify the action logs show "impact=default" - -### Test Case 8: Missing Effort Label (Default Values) - -1. Create an issue or use existing issue -2. Add labels: `reach:medium`, `impact:high` (no effort label) -3. Run the GitHub action -4. **Expected Priority Score**: (75 × 200) / 5 = **3,000** (uses default effort:medium value) -5. Verify the action logs show "effort=default" - -### Test Case 9: All Labels Missing (All Default Values) - -1. Create an issue or use existing issue -2. Add no reach/impact/effort labels (or only unrelated labels) -3. Run the GitHub action -4. **Expected Priority Score**: (50 × 75) / 5 = **750** (uses all default values) -5. Verify the action logs show "reach=default, impact=default, effort=default" - -### Test Case 10: Label Updates Change Priority - -1. Create an issue with labels: `reach:low`, `impact:low`, `effort:high` -2. Run the GitHub action -3. Verify initial score: (50 × 75) / 10 = **375** -4. Update labels to: `reach:high`, `impact:high`, `effort:low` -5. Run the GitHub action again (by editing the issue) -6. **Expected New Priority Score**: (100 × 200) / 2 = **10,000** -7. Verify the score updated correctly in the project board - -### Test Case 11: Medium Values Across All Dimensions - -1. Create an issue or use existing issue -2. Add labels: `reach:medium`, `impact:medium`, `effort:medium` -3. Run the GitHub action -4. **Expected Priority Score**: (75 × 137.5) / 5 = **2,063** (rounded) -5. Verify this appears as a moderate priority item - -### Test Case 12: Multiple Labels of Same Type (Last One Wins) - -1. Create an issue or use existing issue -2. Add labels: `reach:low`, `reach:high`, `impact:medium`, `effort:low` -3. Run the GitHub action -4. **Expected Priority Score**: (100 × 137.5) / 2 = **6,875** (uses reach:high as the last processed) -5. Verify the calculation uses the higher reach value - -## Validation Steps - -For each test case: - -1. **Trigger the Action**: Edit the issue description or labels to trigger the workflow -2. **Check Action Logs**: Go to Actions tab → Select the "Update Calculated Priority" run → Check logs for calculation details -3. **Verify Project Board**: Navigate to the YDB UI project board and confirm the "CalculatedPriority" field shows the expected value -4. **Compare Relative Priorities**: Ensure issues with higher calculated scores appear higher in priority rankings - -## Expected Log Format - -The action should log calculation details in this format: - -``` -📊 Priority calculation: reach=50, impact=137.5, effort=5 → score=1375 -✅ Updated CalculatedPriority of issue #123 to 1375 -``` - -## Troubleshooting - -- If the action doesn't trigger, check that the `YDBOT_TOKEN` secret has proper permissions -- If scores don't appear on the project board, verify the issue is added to project #24 -- If calculations seem incorrect, check the action logs for the exact values used -- If default values aren't applied correctly, verify the fallback logic in the script - -## Additional Test Cases (13-15) - -### Test Case 13: Multiple Labels of Same Category (Overwrite Behavior) - -1. Create an issue with labels: `reach:low`, `reach:medium`, `reach:high`, `impact:medium`, `effort:low` -2. Run the GitHub action -3. **Expected Priority Score**: (100 × 137.5) / 2 = **6,875** (should use `reach:high` as the last processed) -4. Verify the action correctly handles multiple conflicting labels - -### Test Case 14: Edge Case - Lowest Possible Score - -1. Create an issue with labels: `reach:low`, `impact:low`, `effort:high` -2. Run the GitHub action -3. **Expected Priority Score**: (50 × 75) / 10 = **375** -4. Verify this represents the minimum priority calculation - -### Test Case 15: Edge Case - Highest Possible Score - -1. Create an issue with labels: `reach:high`, `impact:high`, `effort:low` -2. Run the GitHub action -3. **Expected Priority Score**: (100 × 200) / 2 = **10,000** -4. Verify this represents the maximum priority calculation - -## Boundary Testing - -Additional edge cases to consider: - -- Issues with special characters in labels -- Issues not added to the project board -- Network failures during GraphQL API calls -- Issues with multiple reach/impact/effort labels (should use last processed value) -- Rounding behavior for non-integer results