From d3fef0fb18759076ae6d189437b323aadd03fcf1 Mon Sep 17 00:00:00 2001
From: Timothy Andrew <mail@timothyandrew.net>
Date: Thu, 25 Aug 2016 14:09:48 +0530
Subject: [PATCH] Add the "Staging" cycle analytics section.

---
 app/models/cycle_analytics.rb                 | 11 ++++++++--
 app/models/cycle_analytics/queries.rb         | 22 +++++++++++++++++++
 .../projects/cycle_analytics/show.html.haml   |  7 ++++++
 3 files changed, 38 insertions(+), 2 deletions(-)

diff --git a/app/models/cycle_analytics.rb b/app/models/cycle_analytics.rb
index 16072c35b64..8ba275dd13a 100644
--- a/app/models/cycle_analytics.rb
+++ b/app/models/cycle_analytics.rb
@@ -15,18 +15,25 @@ class CycleAnalytics
   def code
     issues = Issue.all.to_a
     start_time_fn = -> (merge_request) { merge_request.created_at }
-    calculate_metric(issues.map { |issue| issue.closed_by_merge_requests(nil, check_if_open: false) }.flatten,
+    calculate_metric(Queries::merge_requests_closing_issues(issues),
                      start_time_fn,
                      Queries::mr_wip_flag_removed_or_assigned_to_user_other_than_author_time)
   end
 
   def review
     issues = Issue.all.to_a
-    calculate_metric(issues.map { |issue| issue.closed_by_merge_requests(nil, check_if_open: false) }.flatten,
+    calculate_metric(Queries::merge_requests_closing_issues(issues),
                      Queries::mr_wip_flag_removed_or_assigned_to_user_other_than_author_time,
                      Queries::mr_first_closed_or_merged_at)
   end
 
+  def staging
+    issues = Issue.all.to_a
+    calculate_metric(Queries::merge_requests_closing_issues(issues),
+                     Queries::mr_merged_at,
+                     Queries::mr_deployed_to_any_environment_at)
+  end
+
   private
 
   def calculate_metric(data, start_time_fn, end_time_fn)
diff --git a/app/models/cycle_analytics/queries.rb b/app/models/cycle_analytics/queries.rb
index 41081a4e08c..9970941837d 100644
--- a/app/models/cycle_analytics/queries.rb
+++ b/app/models/cycle_analytics/queries.rb
@@ -1,6 +1,10 @@
 class CycleAnalytics
   module Queries
     class << self
+      def merge_requests_closing_issues(issues)
+        issues.map { |issue| issue.closed_by_merge_requests(nil, check_if_open: false) }.flatten
+      end
+
       def issue_first_associated_with_milestone_or_first_added_to_list_label_time
         lambda do |issue|
           if issue.metrics.present?
@@ -18,6 +22,24 @@ class CycleAnalytics
         end
       end
 
+      def mr_merged_at
+        lambda do |merge_request|
+          if merge_request.metrics.present?
+            merge_request.metrics.merged_at
+          end
+        end
+      end
+
+      def mr_deployed_to_any_environment_at
+        lambda do |merge_request|
+          if merge_request.metrics.present?
+            deployments = Deployment.where(ref: merge_request.target_branch).where("created_at > ?", merge_request.metrics.merged_at)
+            deployment = deployments.order(:created_at).first
+            deployment.created_at if deployment
+          end
+        end
+      end
+
       def issue_closing_merge_request_opened_time
         lambda do |issue|
           merge_requests = issue.closed_by_merge_requests(nil, check_if_open: false)
diff --git a/app/views/projects/cycle_analytics/show.html.haml b/app/views/projects/cycle_analytics/show.html.haml
index 271aae5d5fd..e1c13b3c7a5 100644
--- a/app/views/projects/cycle_analytics/show.html.haml
+++ b/app/views/projects/cycle_analytics/show.html.haml
@@ -26,3 +26,10 @@
       = distance_of_time_in_words review
     - else
       = "<Not enough data>"
+
+  %li.list-group-item
+    Staging:
+    - if staging = @cycle_analytics.staging.presence
+      = distance_of_time_in_words staging
+    - else
+      = "<Not enough data>"
-- 
GitLab