Commit cebfe053 authored by Timothy Andrew's avatar Timothy Andrew

CycleAnalytics operates on merge requests that have been deployed.

1. Look for merge requests (and issues that they close) that have been
   deployed to production in the last X days (where X is given by the
   `from` parameter).

2. Cycle analytics queries only operate on this fitered set of merge
   requests and issues.
parent b43214c5
...@@ -15,63 +15,56 @@ class CycleAnalytics ...@@ -15,63 +15,56 @@ class CycleAnalytics
calculate_metric!(:issue, calculate_metric!(:issue,
TableReferences.issues[:created_at], TableReferences.issues[:created_at],
[TableReferences.issue_metrics[:first_associated_with_milestone_at], [TableReferences.issue_metrics[:first_associated_with_milestone_at],
TableReferences.issue_metrics[:first_added_to_board_at]], TableReferences.issue_metrics[:first_added_to_board_at]])
load_merge_requests: false)
end end
def plan def plan
calculate_metric!(:plan, calculate_metric!(:plan,
[TableReferences.issue_metrics[:first_associated_with_milestone_at], [TableReferences.issue_metrics[:first_associated_with_milestone_at],
TableReferences.issue_metrics[:first_added_to_board_at]], TableReferences.issue_metrics[:first_added_to_board_at]],
TableReferences.issue_metrics[:first_mentioned_in_commit_at], TableReferences.issue_metrics[:first_mentioned_in_commit_at])
load_merge_requests: false)
end end
def code def code
calculate_metric!(:code, calculate_metric!(:code,
TableReferences.issue_metrics[:first_mentioned_in_commit_at], TableReferences.issue_metrics[:first_mentioned_in_commit_at],
TableReferences.merge_requests[:created_at], TableReferences.merge_requests[:created_at])
load_merge_requests: true)
end end
def test def test
calculate_metric!(:test, calculate_metric!(:test,
TableReferences.merge_request_metrics[:latest_build_started_at], TableReferences.merge_request_metrics[:latest_build_started_at],
TableReferences.merge_request_metrics[:latest_build_finished_at], TableReferences.merge_request_metrics[:latest_build_finished_at])
load_merge_requests: true)
end end
def review def review
calculate_metric!(:review, calculate_metric!(:review,
TableReferences.merge_requests[:created_at], TableReferences.merge_requests[:created_at],
TableReferences.merge_request_metrics[:merged_at], TableReferences.merge_request_metrics[:merged_at])
load_merge_requests: true)
end end
def staging def staging
calculate_metric!(:staging, calculate_metric!(:staging,
TableReferences.merge_request_metrics[:merged_at], TableReferences.merge_request_metrics[:merged_at],
TableReferences.merge_request_metrics[:first_deployed_to_production_at], TableReferences.merge_request_metrics[:first_deployed_to_production_at])
load_merge_requests: true)
end end
def production def production
calculate_metric!(:production, calculate_metric!(:production,
TableReferences.issues[:created_at], TableReferences.issues[:created_at],
TableReferences.merge_request_metrics[:first_deployed_to_production_at], TableReferences.merge_request_metrics[:first_deployed_to_production_at])
load_merge_requests: true)
end end
private private
def calculate_metric!(name, start_time_attrs, end_time_attrs, load_merge_requests: false) def calculate_metric!(name, start_time_attrs, end_time_attrs)
cte_table = Arel::Table.new("cte_table_for_#{name}") cte_table = Arel::Table.new("cte_table_for_#{name}")
# Add a `SELECT` for (end_time - start-time), and add an alias for it. # Add a `SELECT` for (end_time - start-time), and add an alias for it.
# Note: We use COALESCE to pick up the first non-null column for end_time / start_time. # Note: We use COALESCE to pick up the first non-null column for end_time / start_time.
query = Arel::Nodes::As.new( query = Arel::Nodes::As.new(
cte_table, cte_table,
base_query(load_merge_requests: load_merge_requests).project( base_query.project(
Arel::Nodes::Subtraction.new( Arel::Nodes::Subtraction.new(
Arel::Nodes::NamedFunction.new("COALESCE", Array.wrap(end_time_attrs)), Arel::Nodes::NamedFunction.new("COALESCE", Array.wrap(end_time_attrs)),
Arel::Nodes::NamedFunction.new("COALESCE", Array.wrap(start_time_attrs)) Arel::Nodes::NamedFunction.new("COALESCE", Array.wrap(start_time_attrs))
...@@ -86,20 +79,21 @@ class CycleAnalytics ...@@ -86,20 +79,21 @@ class CycleAnalytics
# closes the given issue) with issue and merge request metrics included. The metrics # closes the given issue) with issue and merge request metrics included. The metrics
# are loaded with an inner join, so issues / merge requests without metrics are # are loaded with an inner join, so issues / merge requests without metrics are
# automatically excluded. # automatically excluded.
def base_query(load_merge_requests:) def base_query
arel_table = TableReferences.merge_requests_closing_issues arel_table = TableReferences.merge_requests_closing_issues
# Load issues
query = arel_table.join(TableReferences.issues).on(TableReferences.issues[:id].eq(arel_table[:issue_id])). query = arel_table.join(TableReferences.issues).on(TableReferences.issues[:id].eq(arel_table[:issue_id])).
join(TableReferences.issue_metrics).on(TableReferences.issues[:id].eq(TableReferences.issue_metrics[:issue_id])). join(TableReferences.issue_metrics).on(TableReferences.issues[:id].eq(TableReferences.issue_metrics[:issue_id])).
where(TableReferences.issues[:project_id].eq(@project.id)). where(TableReferences.issues[:project_id].eq(@project.id)).
where(TableReferences.issues[:deleted_at].eq(nil)). where(TableReferences.issues[:deleted_at].eq(nil)).
where(TableReferences.issues[:created_at].gteq(@from)) where(TableReferences.issues[:created_at].gteq(@from))
if load_merge_requests # Load merge_requests
query.join(TableReferences.merge_requests, Arel::Nodes::OuterJoin).on(TableReferences.merge_requests[:id].eq(arel_table[:merge_request_id])). query = query.join(TableReferences.merge_requests, Arel::Nodes::OuterJoin).on(TableReferences.merge_requests[:id].eq(arel_table[:merge_request_id])).
join(TableReferences.merge_request_metrics).on(TableReferences.merge_requests[:id].eq(TableReferences.merge_request_metrics[:merge_request_id])) join(TableReferences.merge_request_metrics).on(TableReferences.merge_requests[:id].eq(TableReferences.merge_request_metrics[:merge_request_id]))
else
query # Limit to merge requests that have been deployed to production after `@from`
end query.where(TableReferences.merge_request_metrics[:first_deployed_to_production_at].gteq(@from))
end end
end end
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment