From ca936d2784773652530e7b02af40b925ca45a4d6 Mon Sep 17 00:00:00 2001
From: Dmitriy Zaporozhets <dmitriy.zaporozhets@gmail.com>
Date: Tue, 11 Dec 2012 06:14:05 +0300
Subject: [PATCH] Improve CI integration for merge requests

---
 app/assets/javascripts/merge_requests.js      | 11 ++++++
 .../stylesheets/sections/merge_requests.scss  |  6 ----
 app/controllers/merge_requests_controller.rb  |  9 ++++-
 app/helpers/merge_requests_helper.rb          |  4 +--
 app/models/gitlab_ci_service.rb               | 18 ++++++++++
 app/models/merge_request.rb                   |  4 +++
 app/views/merge_requests/_show.html.haml      |  4 +++
 .../merge_requests/show/_mr_box.html.haml     |  3 --
 .../merge_requests/show/_mr_ci.html.haml      | 35 +++++++++++++++++++
 config/routes.rb                              |  1 +
 10 files changed, 83 insertions(+), 12 deletions(-)
 create mode 100644 app/views/merge_requests/show/_mr_ci.html.haml

diff --git a/app/assets/javascripts/merge_requests.js b/app/assets/javascripts/merge_requests.js
index 170a0479de..ee714f9cab 100644
--- a/app/assets/javascripts/merge_requests.js
+++ b/app/assets/javascripts/merge_requests.js
@@ -26,6 +26,12 @@ var MergeRequest = {
           self.showState(data.state);
         }, "json");
       }
+
+      if(self.opts.ci_enable){
+        $.get(self.opts.url_to_ci_check, function(data){
+          self.showCiState(data.status);
+        }, "json");
+      }
     },
 
   initTabs:
@@ -79,6 +85,11 @@ var MergeRequest = {
       $(".automerge_widget." + state).show();
     },
 
+  showCiState:
+    function(state){
+      $(".ci_widget").hide();
+      $(".ci_widget.ci-" + state).show();
+    },
 
   loadDiff:
     function() { 
diff --git a/app/assets/stylesheets/sections/merge_requests.scss b/app/assets/stylesheets/sections/merge_requests.scss
index a5ec1756e5..4808117d02 100644
--- a/app/assets/stylesheets/sections/merge_requests.scss
+++ b/app/assets/stylesheets/sections/merge_requests.scss
@@ -136,9 +136,3 @@ li.merge_request {
     }
   }
 }
-
-.status-badge {
-  height: 32px;
-  width: 100%;
-  @include border-radius(5px);
-}
diff --git a/app/controllers/merge_requests_controller.rb b/app/controllers/merge_requests_controller.rb
index 362962707f..72f6445a59 100644
--- a/app/controllers/merge_requests_controller.rb
+++ b/app/controllers/merge_requests_controller.rb
@@ -1,6 +1,6 @@
 class MergeRequestsController < ProjectResourceController
   before_filter :module_enabled
-  before_filter :merge_request, only: [:edit, :update, :destroy, :show, :commits, :diffs, :automerge, :automerge_check]
+  before_filter :merge_request, only: [:edit, :update, :destroy, :show, :commits, :diffs, :automerge, :automerge_check, :ci_status]
   before_filter :validates_merge_request, only: [:show, :diffs]
   before_filter :define_show_vars, only: [:show, :diffs]
 
@@ -103,6 +103,13 @@ class MergeRequestsController < ProjectResourceController
     @commit = CommitDecorator.decorate(@commit)
   end
 
+  def ci_status
+    status = project.gitlab_ci_service.commit_status(merge_request.last_commit.sha)
+    response = { status: status }
+
+    render json: response
+  end
+
   protected
 
   def merge_request
diff --git a/app/helpers/merge_requests_helper.rb b/app/helpers/merge_requests_helper.rb
index b23c4a8f0d..d03fbadff9 100644
--- a/app/helpers/merge_requests_helper.rb
+++ b/app/helpers/merge_requests_helper.rb
@@ -39,7 +39,7 @@ module MergeRequestsHelper
     classes
   end
 
-  def ci_status_path
-    @project.gitlab_ci_service.commit_badge_path(@merge_request.last_commit.sha)
+  def ci_build_details_path merge_request
+    merge_request.project.gitlab_ci_service.build_page(merge_request.last_commit.sha)
   end
 end
diff --git a/app/models/gitlab_ci_service.rb b/app/models/gitlab_ci_service.rb
index 24b7032309..a2f5634a86 100644
--- a/app/models/gitlab_ci_service.rb
+++ b/app/models/gitlab_ci_service.rb
@@ -36,4 +36,22 @@ class GitlabCiService < Service
   def commit_badge_path sha
     project_url + "/status?sha=#{sha}"
   end
+
+  def commit_status_path sha
+    project_url + "/builds/#{sha}/status.json?token=#{token}"
+  end
+
+  def commit_status sha
+    response = HTTParty.get(commit_status_path(sha))
+
+    if response.code == 200 and response["status"]
+      response["status"]
+    else
+      :error
+    end
+  end
+
+  def build_page sha
+    project_url + "/builds/#{sha}"
+  end
 end
diff --git a/app/models/merge_request.rb b/app/models/merge_request.rb
index 8039813ad1..2409fb80ac 100644
--- a/app/models/merge_request.rb
+++ b/app/models/merge_request.rb
@@ -220,4 +220,8 @@ class MergeRequest < ActiveRecord::Base
   def to_patch
     project.repo.git.format_patch({timeout: 30, raise: true, stdout: true}, "#{target_branch}..#{source_branch}")
   end
+
+  def last_commit_short_sha
+    @last_commit_short_sha ||= last_commit.sha[0..10]
+  end
 end
diff --git a/app/views/merge_requests/_show.html.haml b/app/views/merge_requests/_show.html.haml
index f1d0c8aaaf..20ba991e79 100644
--- a/app/views/merge_requests/_show.html.haml
+++ b/app/views/merge_requests/_show.html.haml
@@ -2,6 +2,8 @@
 = render "merge_requests/show/how_to_merge"
 = render "merge_requests/show/mr_box"
 = render "merge_requests/show/mr_accept"
+- if @project.gitlab_ci?
+  = render "merge_requests/show/mr_ci"
 = render "merge_requests/show/commits"
 
 - if @commits.present?
@@ -28,6 +30,8 @@
     MergeRequest.init({
       url_to_automerge_check: "#{automerge_check_project_merge_request_path(@project, @merge_request)}",
       check_enable: #{@merge_request.state == MergeRequest::UNCHECKED ? "true" : "false"},
+      url_to_ci_check: "#{ci_status_project_merge_request_path(@project, @merge_request)}",
+      ci_enable: #{@project.gitlab_ci? ? "true" : "false"},
       current_state: "#{@merge_request.human_state}",
       action: "#{controller.action_name}"
     });
diff --git a/app/views/merge_requests/show/_mr_box.html.haml b/app/views/merge_requests/show/_mr_box.html.haml
index b4b4be2980..26636435a0 100644
--- a/app/views/merge_requests/show/_mr_box.html.haml
+++ b/app/views/merge_requests/show/_mr_box.html.haml
@@ -6,9 +6,6 @@
       - else
         .alert-message.success.status_info Open
       = gfm escape_once(@merge_request.title)
-      - if @project.gitlab_ci?
-        .right
-          = image_tag ci_status_path, class: 'status-badge'
 
   .middle_box_content
     %div
diff --git a/app/views/merge_requests/show/_mr_ci.html.haml b/app/views/merge_requests/show/_mr_ci.html.haml
new file mode 100644
index 0000000000..d46b606ef7
--- /dev/null
+++ b/app/views/merge_requests/show/_mr_ci.html.haml
@@ -0,0 +1,35 @@
+- if @merge_request.open? && @commits.any?
+  .ci_widget.ci-success{style: "display:none"}
+    .alert.alert-success
+      %i.icon-ok
+      %strong CI build passed
+      for #{@merge_request.last_commit_short_sha}.
+      = link_to "Build page", ci_build_details_path(@merge_request)
+
+
+  .ci_widget.ci-failed{style: "display:none"}
+    .alert.alert-error
+      %i.icon-remove
+      %strong CI build failed
+      for #{@merge_request.last_commit_short_sha}.
+      = link_to "Build page", ci_build_details_path(@merge_request)
+
+  - [:running, :pending].each do |status|
+    .ci_widget{class: "ci-#{status}", style: "display:none"}
+      .alert
+        %i.icon-time
+        %strong CI build #{status}
+        for #{@merge_request.last_commit_short_sha}.
+        = link_to "Build page", ci_build_details_path(@merge_request)
+
+  .ci_widget
+    .alert-message
+      %strong
+        %i.icon-refresh
+        Checking for CI status for #{@merge_request.last_commit_short_sha}
+
+  .ci_widget.ci-error{style: "display:none"}
+    .alert.alert-error
+      %i.icon-remove
+      %strong Cannot connect to CI server. Please check your setting
+
diff --git a/config/routes.rb b/config/routes.rb
index f1527977c0..6e20ae7739 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -169,6 +169,7 @@ Gitlab::Application.routes.draw do
         get :diffs
         get :automerge
         get :automerge_check
+        get :ci_status
       end
 
       collection do
-- 
2.30.9