Prevent double counting and rollup tasks weights
What does this MR do and why?
Related to #381879
Task, a type of work item, was introduced for finer-grained planning capability. You might break down an issue into several tasks during planning:
- Issue: "Support emoji reaction"
- Task: "Create an emoji component (frontend)" (weight 2)
- Task: "Create an emoji endpoint (backend)" (weight 2)
The introduction of Task broke the timebox reporting feature in a way because now any burndown/up chart (sample: https://gitlab.com/gitlab-org/gitlab/-/cadences/28324/iterations/1292151) could count an issue and its tasks as separate entities instead of a single entity.
There were thornier questions. What if a parent issue also had its own weight? The product requirements in #381879 define how such situations should be handled in detail and this MR implements some of the requirements. To be precise, this MR seeks to update the burnup/down chart highlighted in red:
How timebox reporting works today
The burndown chart shown in a milestone/iteration (called timebox) report is generated using resource event records:
-
ResourceMilestoneEvent
: Issue 1 was added to Milestone A on Date X at 00:00 -
ResourceStateEvent
: Issue 1 was closed on Date X at 01:00 -
ResourceStateEvent
: Issue 1 was reopened on Date X at 02:00
TimeboxReportService
is the service currently responsible for fetching resource events and generating the data points needed to plot a chart.
The frontend application will issue a GraphQL query and a resolver will use TimeboxReportService
to return the necessary burnup/down chart data.
Timebox::ReportService
Timebox::ReportService
(ee/app/services/timebox/report_service.rb) is a clone, an exact copy of TimeboxReportService
(ee/app/services/timebox_report_service.rb) I created a copy because refactoring and updating TimeboxReportService
in place seemed more difficult.
In this MR, Timebox::ReportService
is updated to use newly created/factored-out services and utilities.
-
Timebox::ReportService
is updated to useSnapshotBuilder
added in !148225 (merged), a utility for constructing historical snapshots of issues/tasks belonging to a timebox. -
Timebox::ReportService
is updated to turn the snapshots into data points usingBurnchartDataPoint
(ee/lib/gitlab/timebox/burnchart_data_point.rb)
BurnchartDataPoint
BurnchartDataPoint
is the new logic responsible for calculating the data points used to plot a burnup/down chart. Each snapshot can be turned into a data point or an instance of BurnchartDataPoint
.
BurnchartDataPoint
comes with a class method that can turn a collection of snapshots into a collection of its own instances (.build_data
)
How to set up and validate locally
-
Create an issue and add some task to it. Weigh them.
-
Create a milestone or iteration.
-
Add the issue and the task to the same milestone or iteration.
-
Observe the double counting.
-
The updated feature is gated behind a feature flag. You should enable
:rollup_timebox_chart
to test the update.
Before | After |
---|---|
In the above comparison, the After screenshot correctly counts an issue and its task as one.
The actual rules are laid out in #381879. In particular, the table in https://gitlab.com/gitlab-org/gitlab/-/issues/381879#note_1775483668 lists some scenarios you can use to test the updated feature.