Skip to content

Prevent double counting and rollup tasks weights

euko requested to merge 381879-resolve into master

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:

Screenshot

image

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 use SnapshotBuilder 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 using BurnchartDataPoint (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

  1. Create an issue and add some task to it. Weigh them.

  2. Create a milestone or iteration.

  3. Add the issue and the task to the same milestone or iteration.

  4. Observe the double counting.

  5. The updated feature is gated behind a feature flag. You should enable :rollup_timebox_chart to test the update.

Do not rely on the summary stats appearing above the chart. The summary stats are generated on the frontend and should be updated separately.

Before After
image image

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.

Edited by euko

Merge request reports