diff --git a/CHANGELOG b/CHANGELOG
index 0400dbfabeccce85609985dbe26bc9f393a6cae0..388fa2f89666c8ef3822dad70aeb460bef82930c 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -32,6 +32,7 @@ v 8.1.0 (unreleased)
   - Fix User Identities API. It now allows you to properly create or update user's identities.
   - Add user preference to change layout width (Peter Göbel)
   - Use commit status in merge request widget as preffered source of CI status
+  - Integrate CI commit and build pages into project pages
 
 v 8.0.4
   - Fix Message-ID header to be RFC 2111-compliant to prevent e-mails being dropped (Stan Hu)
diff --git a/app/assets/stylesheets/ci/builds.scss b/app/assets/stylesheets/ci/builds.scss
index a11a935b54dab46e41c45e6a86cb960e6533adfd..a27dd0db58167339bfca48556ceae9ab5d31f122 100644
--- a/app/assets/stylesheets/ci/builds.scss
+++ b/app/assets/stylesheets/ci/builds.scss
@@ -1,4 +1,4 @@
-.ci-body {
+.build-page {
   pre.trace {
     background: #111111;
     color: #fff;
@@ -67,4 +67,10 @@
       color: #3084bb !important;
     }
   }
+
+  .build-top-menu {
+    margin-top: 0;
+    margin-bottom: 2px;
+  }
 }
+
diff --git a/app/assets/stylesheets/generic/common.scss b/app/assets/stylesheets/generic/common.scss
index 016cc015e9ce5db8568c361897b1606c68ccd34a..45e284542d2261fe28041a2b431688957499d8ff 100644
--- a/app/assets/stylesheets/generic/common.scss
+++ b/app/assets/stylesheets/generic/common.scss
@@ -381,6 +381,10 @@ table {
   &.no-bottom {
     margin-bottom: 0;
   }
+
+  &.no-top {
+    margin-top: 0;
+  }
 }
 
 .dropzone .dz-preview .dz-progress {
diff --git a/app/controllers/ci/builds_controller.rb b/app/controllers/ci/builds_controller.rb
index bf87f81439a24b4d121d82fb737550e43159c0d8..b0b8b62fcedcc550fe410e0c4f7be6aedb0f4bb8 100644
--- a/app/controllers/ci/builds_controller.rb
+++ b/app/controllers/ci/builds_controller.rb
@@ -1,41 +1,11 @@
 module Ci
   class BuildsController < Ci::ApplicationController
-    before_action :authenticate_user!, except: [:status, :show]
-    before_action :authenticate_public_page!, only: :show
+    before_action :authenticate_user!, except: [:status]
     before_action :project
-    before_action :authorize_access_project!, except: [:status, :show]
-    before_action :authorize_manage_project!, except: [:status, :show, :retry, :cancel]
+    before_action :authorize_access_project!, except: [:status]
+    before_action :authorize_manage_project!, except: [:status, :retry, :cancel]
     before_action :authorize_manage_builds!, only: [:retry, :cancel]
-    before_action :build, except: [:show]
-    layout 'ci/build'
-
-    def show
-      if params[:id] =~ /\A\d+\Z/
-        @build = build
-      else
-        # try to find commit by sha
-        commit = commit_by_sha
-
-        if commit
-          # Redirect to commit page
-          redirect_to ci_project_commit_path(@project, @build.commit)
-          return
-        end
-      end
-
-      raise ActiveRecord::RecordNotFound unless @build
-
-      @builds = @project.commits.find_by_sha(@build.sha).builds.order('id DESC')
-      @builds = @builds.where("id not in (?)", @build.id).page(params[:page]).per(20)
-      @commit = @build.commit
-
-      respond_to do |format|
-        format.html
-        format.json do
-          render json: @build.to_json(methods: :trace_html)
-        end
-      end
-    end
+    before_action :build
 
     def retry
       if @build.commands.blank?
@@ -47,7 +17,7 @@ module Ci
       if params[:return_to]
         redirect_to URI.parse(params[:return_to]).path
       else
-        redirect_to ci_project_build_path(project, build)
+        redirect_to build_path(build)
       end
     end
 
@@ -58,7 +28,7 @@ module Ci
     def cancel
       @build.cancel
 
-      redirect_to ci_project_build_path(@project, @build)
+      redirect_to build_path(@build)
     end
 
     protected
@@ -68,11 +38,15 @@ module Ci
     end
 
     def build
-      @build ||= project.builds.unscoped.find_by(id: params[:id])
+      @build ||= project.builds.unscoped.find_by!(id: params[:id])
     end
 
     def commit_by_sha
       @project.commits.find_by(sha: params[:id])
     end
+
+    def build_path(build)
+      namespace_project_build_path(build.gl_project.namespace, build.gl_project, build)
+    end
   end
 end
diff --git a/app/controllers/ci/commits_controller.rb b/app/controllers/ci/commits_controller.rb
index 887e92f84cfa3c5ce884a235a579c988f1a4bb08..7e6705c97028b2d27213e7091a431335dd65c58e 100644
--- a/app/controllers/ci/commits_controller.rb
+++ b/app/controllers/ci/commits_controller.rb
@@ -5,12 +5,6 @@ module Ci
     before_action :project
     before_action :authorize_access_project!, except: [:status, :show, :cancel]
     before_action :authorize_manage_builds!, only: [:cancel]
-    before_action :commit, only: :show
-    layout 'ci/commit'
-
-    def show
-      @builds = @commit.builds
-    end
 
     def status
       commit = Ci::Project.find(params[:project_id]).commits.find_by_sha!(params[:id])
@@ -22,7 +16,7 @@ module Ci
     def cancel
       commit.builds.running_or_pending.each(&:cancel)
 
-      redirect_to ci_project_commits_path(project, commit.sha)
+      redirect_to namespace_project_commit_path(commit.gl_project.namespace, commit.gl_project, commit.sha)
     end
 
     private
diff --git a/app/controllers/projects/builds_controller.rb b/app/controllers/projects/builds_controller.rb
new file mode 100644
index 0000000000000000000000000000000000000000..76c7f31f61b2f04f5f4133add855655e2e51e96a
--- /dev/null
+++ b/app/controllers/projects/builds_controller.rb
@@ -0,0 +1,25 @@
+class Projects::BuildsController < Projects::ApplicationController
+  before_action :ci_project
+  before_action :build
+
+  layout "project"
+
+  def show
+    @builds = @ci_project.commits.find_by_sha(@build.sha).builds.order('id DESC')
+    @builds = @builds.where("id not in (?)", @build.id).page(params[:page]).per(20)
+    @commit = @build.commit
+
+    respond_to do |format|
+      format.html
+      format.json do
+        render json: @build.to_json(methods: :trace_html)
+      end
+    end
+  end
+
+  private
+
+  def build
+    @build ||= ci_project.builds.unscoped.find_by!(id: params[:id])
+  end
+end
diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb
index 3ab44719d9f3269010ba7006a3f222d8824b00f2..cab2278adb7f8fe3c072d378021566082f9c1d42 100644
--- a/app/helpers/application_helper.rb
+++ b/app/helpers/application_helper.rb
@@ -314,4 +314,8 @@ module ApplicationHelper
 
     html.html_safe
   end
+
+  def truncate_first_line(message, length = 50)
+    truncate(message.each_line.first.chomp, length: length) if message
+  end
 end
diff --git a/app/helpers/builds_helper.rb b/app/helpers/builds_helper.rb
index 626f4e2f4c0edae34f0839b9c7df24194281ecb2..1b5a2c31d74660e4fb01931bf5b4aa0135affd23 100644
--- a/app/helpers/builds_helper.rb
+++ b/app/helpers/builds_helper.rb
@@ -8,6 +8,6 @@ module BuildsHelper
   end
 
   def build_url(build)
-    ci_project_build_url(build.project, build)
+    namespace_project_build_path(build.gl_project, build.project, build)
   end
 end
diff --git a/app/helpers/ci/commits_helper.rb b/app/helpers/ci/commits_helper.rb
deleted file mode 100644
index a0df4c3d72d35d599387cb908a1a48c284cb1dab..0000000000000000000000000000000000000000
--- a/app/helpers/ci/commits_helper.rb
+++ /dev/null
@@ -1,24 +0,0 @@
-module Ci
-  module CommitsHelper
-    def ci_commit_path(commit)
-      ci_project_commits_path(commit.project, commit)
-    end
-
-    def commit_link(commit)
-      link_to(commit.short_sha, ci_commit_path(commit))
-    end
-
-    def truncate_first_line(message, length = 50)
-      truncate(message.each_line.first.chomp, length: length) if message
-    end
-
-    def ci_commit_title(commit)
-      content_tag :span do
-        link_to(
-          simple_sanitize(commit.project.name), ci_project_path(commit.project)
-        ) + ' @ ' +
-          gitlab_commit_link(@project, @commit.sha)
-      end
-    end
-  end
-end
diff --git a/app/models/ci/build.rb b/app/models/ci/build.rb
index 3c92710968c881bf049e17092efc1d7197840bb5..5d17f4418ed1dc584540ea652206d2dde932b01c 100644
--- a/app/models/ci/build.rb
+++ b/app/models/ci/build.rb
@@ -144,7 +144,7 @@ module Ci
       state :canceled, value: 'canceled'
     end
 
-    delegate :sha, :short_sha, :project,
+    delegate :sha, :short_sha, :project, :gl_project,
       to: :commit, prefix: false
 
     def before_sha
diff --git a/app/models/project_services/ci/hip_chat_message.rb b/app/models/project_services/ci/hip_chat_message.rb
index 0bf448d47f27f27c37c8b17ddab8dc2e8498f8cd..cbf325cc5255af0193bbb25155db43de7fe91767 100644
--- a/app/models/project_services/ci/hip_chat_message.rb
+++ b/app/models/project_services/ci/hip_chat_message.rb
@@ -11,7 +11,7 @@ module Ci
     def to_s
       lines = Array.new
       lines.push("<a href=\"#{ci_project_url(project)}\">#{project.name}</a> - ")
-      lines.push("<a href=\"#{ci_project_commits_url(project, commit.sha)}\">Commit ##{commit.id}</a></br>")
+      lines.push("<a href=\"#{ci_namespace_project_commit_url(commit.gl_project.namespace, commit.gl_project, commit.sha)}\">Commit ##{commit.id}</a></br>")
       lines.push("#{commit.short_sha} #{commit.git_author_name} - #{commit.git_commit_message}</br>")
       lines.push("#{humanized_status(commit_status)} in #{commit.duration} second(s).")
       lines.join('')
diff --git a/app/models/project_services/ci/slack_message.rb b/app/models/project_services/ci/slack_message.rb
index a89c01517b73e5b2be4d2962c46457627a62674b..5ac8907ecd0de72a58344d62af10e44c9fd5fc96 100644
--- a/app/models/project_services/ci/slack_message.rb
+++ b/app/models/project_services/ci/slack_message.rb
@@ -28,7 +28,7 @@ module Ci
         next unless build.failed?
         fields << {
           title: build.name,
-          value: "Build <#{ci_project_build_url(project, build)}|\##{build.id}> failed in #{build.duration.to_i} second(s)."
+          value: "Build <#{namespace_project_build_url(build.gl_project.namespace, build.gl_project, build)}|\##{build.id}> failed in #{build.duration.to_i} second(s)."
         }
       end
 
@@ -45,7 +45,7 @@ module Ci
 
     def attachment_message
       out = "<#{ci_project_url(project)}|#{project_name}>: "
-      out << "Commit <#{ci_project_commits_url(project, commit.sha)}|\##{commit.id}> "
+      out << "Commit <#{ci_namespace_project_commit_url(commit.gl_project.namespace, commit.gl_project, commit.sha)}|\##{commit.id}> "
       out << "(<#{commit_sha_link}|#{commit.short_sha}>) "
       out << "of <#{commit_ref_link}|#{commit.ref}> "
       out << "by #{commit.git_author_name} " if commit.git_author_name
diff --git a/app/models/project_services/gitlab_ci_service.rb b/app/models/project_services/gitlab_ci_service.rb
index b63a75cf3afb1a0d61f25bba43d7c197dba20320..4dcd16ede3a29d5cb835b51860177747068b316c 100644
--- a/app/models/project_services/gitlab_ci_service.rb
+++ b/app/models/project_services/gitlab_ci_service.rb
@@ -71,7 +71,7 @@ class GitlabCiService < CiService
 
   def build_page(sha, ref)
     if project.gitlab_ci_project.present?
-      ci_project_commits_url(project.gitlab_ci_project, sha)
+      ci_namespace_project_commit_url(project.namespace, project, sha)
     end
   end
 
diff --git a/app/views/ci/admin/builds/_build.html.haml b/app/views/ci/admin/builds/_build.html.haml
index 778d51d03be94e31a7f597e005f79c0fba683fcf..2df5871321404bd3ed5ecb03418e6ef8e2326f7c 100644
--- a/app/views/ci/admin/builds/_build.html.haml
+++ b/app/views/ci/admin/builds/_build.html.haml
@@ -1,14 +1,16 @@
+- gl_project = build.project.gl_project
 - if build.commit && build.project
   %tr.build
     %td.build-link
-      = link_to ci_project_build_url(build.project, build) do
+      = link_to namespace_project_build_path(gl_project.namespace, gl_project, build) do
         %strong #{build.id}
 
     %td.status
       = ci_status_with_icon(build.status)
 
     %td.commit-link
-      = commit_link(build.commit)
+      = link_to ci_status_path(build.commit) do
+        %strong #{build.commit.short_sha}
 
     %td.runner
       - if build.runner
diff --git a/app/views/ci/admin/runners/show.html.haml b/app/views/ci/admin/runners/show.html.haml
index 09905e0eb47d02f9d83418f9ffc48c53c5e75080..5bb442cbf9227a3ca59f1520273b42574d536cf8 100644
--- a/app/views/ci/admin/runners/show.html.haml
+++ b/app/views/ci/admin/runners/show.html.haml
@@ -96,6 +96,7 @@
     %table.builds.runner-builds
       %thead
         %tr
+          %th Build ID
           %th Status
           %th Project
           %th Commit
@@ -103,6 +104,11 @@
 
       - @builds.each do |build|
         %tr.build
+          %td.id
+            - gl_project = build.project.gl_project
+            = link_to namespace_project_build_path(gl_project.namespace, gl_project, build) do
+              = build.id
+
           %td.status
             = ci_status_with_icon(build.status)
 
@@ -110,8 +116,8 @@
             = build.project.name
 
           %td.build-link
-            = link_to ci_project_build_path(build.project, build) do
-              %strong #{build.short_sha}
+            = link_to ci_status_path(build.commit) do
+              %strong #{build.commit.short_sha}
 
           %td.timestamp
             - if build.finished_at
diff --git a/app/views/ci/builds/show.html.haml b/app/views/ci/builds/show.html.haml
deleted file mode 100644
index be33c5e8aa43521ec98cb89b7f1e894a6d2803f4..0000000000000000000000000000000000000000
--- a/app/views/ci/builds/show.html.haml
+++ /dev/null
@@ -1,165 +0,0 @@
-#up-build-trace
-- if @commit.matrix_for_ref?(@build.ref)
-  %ul.center-top-menu
-    - @commit.builds_without_retry_for_ref(@build.ref).each do |build|
-      %li{class: ('active' if build == @build) }
-        = link_to ci_project_build_url(@project, build) do
-          = ci_icon_for_status(build.status)
-          %span
-            - if build.name
-              = build.name
-            - else
-              = build.id
-
-
-    - unless @commit.builds_without_retry_for_ref(@build.ref).include?(@build)
-      %li.active
-        %a
-          Build ##{@build.id}
-          &middot;
-          %i.fa.fa-warning-sign
-          This build was retried.
-
-.gray-content-block
-  .build-head
-    %h4
-      - if @build.commit.tag?
-        Build for tag
-        %code #{@build.ref}
-      - else
-        Build for commit
-        %strong.monospace= commit_link(@build.commit)
-        from
-
-        = link_to ci_project_path(@build.project, ref: @build.ref) do
-          %strong.monospace= "#{@build.ref}"
-
-      - if @build.duration
-        .pull-right
-          %span
-            %i.fa.fa-time
-            #{duration_in_words(@build.finished_at, @build.started_at)}
-
-    .clearfix
-      = ci_status_with_icon(@build.status)
-      .pull-right
-        = @build.updated_at.stamp('19:00 Aug 27')
-
-.row.prepend-top-default
-  .col-md-9
-    .clearfix
-      - if @build.active?
-        .autoscroll-container
-          %button.btn.btn-success.btn-sm#autoscroll-button{:type => "button", :data => {:state => 'disabled'}} enable autoscroll
-        .clearfix
-    .scroll-controls
-      = link_to '#up-build-trace', class: 'btn' do
-        %i.fa.fa-angle-up
-      = link_to '#down-build-trace', class: 'btn' do
-        %i.fa.fa-angle-down
-
-    %pre.trace#build-trace
-      %code.bash
-        = preserve do
-          = raw @build.trace_html
-    %div#down-build-trace
-
-  .col-md-3
-    - if @build.coverage
-      .build-widget
-        %h4.title
-          Test coverage
-        %h1 #{@build.coverage}%
-
-
-    .build-widget
-      %h4.title
-        Build
-        - if current_user && can?(current_user, :manage_builds, gl_project)
-          .pull-right
-            - if @build.active?
-              = link_to "Cancel", cancel_ci_project_build_path(@project, @build), class: 'btn btn-sm btn-danger'
-            - elsif @build.commands.present?
-              = link_to "Retry", retry_ci_project_build_path(@project, @build), class: 'btn btn-sm btn-primary', method: :post
-
-      - if @build.duration
-        %p
-          %span.attr-name Duration:
-          #{duration_in_words(@build.finished_at, @build.started_at)}
-      %p
-        %span.attr-name Created:
-        #{time_ago_in_words(@build.created_at)} ago
-      - if @build.finished_at
-        %p
-          %span.attr-name Finished:
-          #{time_ago_in_words(@build.finished_at)} ago
-      %p
-        %span.attr-name Runner:
-        - if @build.runner && current_user && current_user.admin
-          \#{link_to "##{@build.runner.id}", ci_admin_runner_path(@build.runner.id)}
-        - elsif @build.runner
-          \##{@build.runner.id}
-
-    - if @build.trigger_request
-      .build-widget
-        %h4.title
-          Trigger
-
-        %p
-          %span.attr-name Token:
-          #{@build.trigger_request.trigger.short_token}
-
-        - if @build.trigger_request.variables
-          %p
-            %span.attr-name Variables:
-
-          %code
-            - @build.trigger_request.variables.each do |key, value|
-              #{key}=#{value}
-
-    .build-widget
-      %h4.title
-        Commit
-        .pull-right
-          %small #{build_commit_link @build}
-      %p
-        %span.attr-name Branch:
-        #{build_ref_link @build}
-      %p
-        %span.attr-name Author:
-        #{@build.commit.git_author_name}
-      %p
-        %span.attr-name Message:
-        #{@build.commit.git_commit_message}
-
-    - if @build.tags.any?
-      .build-widget
-        %h4.title
-          Tags
-        - @build.tag_list.each do |tag|
-          %span.label.label-primary
-            = tag
-
-    - if @builds.present?
-      .build-widget
-        %h4.title #{pluralize(@builds.count, "other build")} for #{@build.short_sha}:
-        %table.builds
-          - @builds.each_with_index do |build, i|
-            %tr.build
-              %td
-                = ci_icon_for_status(build.status)
-              %td
-                = link_to ci_project_build_url(@project, build) do
-                  - if build.name
-                    = build.name
-                  - else
-                    %span ##{build.id}
-
-              %td.status= build.status
-
-
-        = paginate @builds
-
-
-:javascript
-  new CiBuild("#{ci_project_build_url(@project, @build)}", "#{@build.status}")
diff --git a/app/views/ci/commits/_commit.html.haml b/app/views/ci/commits/_commit.html.haml
index 6e6cc9b2c3748aaa9379b58f09e2188b0905e4bd..b24a3b826cfb52a0a8a36144d45ccf5d31111763 100644
--- a/app/views/ci/commits/_commit.html.haml
+++ b/app/views/ci/commits/_commit.html.haml
@@ -7,7 +7,7 @@
 
 
   %td.build-link
-    = link_to ci_project_commits_path(commit.project, commit.sha) do
+    = link_to ci_status_path(commit) do
       %strong #{commit.short_sha}
 
   %td.build-message
diff --git a/app/views/ci/commits/show.html.haml b/app/views/ci/commits/show.html.haml
deleted file mode 100644
index 7ebef8c5e06daf23174db4988df2db06043b3496..0000000000000000000000000000000000000000
--- a/app/views/ci/commits/show.html.haml
+++ /dev/null
@@ -1,89 +0,0 @@
-.commit-info
-  .append-bottom-20
-    = ci_status_with_icon(@commit.status)
-
-  .gray-content-block.middle-block
-    %pre.commit-message
-      - if @commit.git_commit_message
-        #{@commit.git_commit_message}
-      - else
-        No commit message
-
-  .gray-content-block.second-block
-    .row
-      .col-sm-6
-        %p
-          %span.attr-name Commit:
-          #{gitlab_commit_link(@project, @commit.sha)}
-        %p
-          - if @commit.refs.present?
-            %span.attr-name Refs:
-            - @commit.refs.each do |ref|
-              #{gitlab_ref_link(@project, ref)}
-      .col-sm-6
-        - if @commit.git_author_name || @commit.git_author_email
-          %p
-            %span.attr-name Author:
-            #{@commit.git_author_name} (#{@commit.git_author_email})
-        - if @commit.created_at
-          %p
-            %span.attr-name Created at:
-            #{@commit.created_at.to_s(:short)}
-
-        - if current_user && can?(current_user, :manage_builds, gl_project)
-          - if @commit.builds.running_or_pending.any?
-            .pull-right
-              = link_to "Cancel", cancel_ci_project_commits_path(@project, @commit), class: 'btn btn-sm btn-danger'
-
-
-- if @commit.yaml_errors.present?
-  .bs-callout.bs-callout-danger
-    %h4 Found errors in your .gitlab-ci.yml:
-    %ul
-      - @commit.yaml_errors.split(",").each do |error|
-        %li= error
-
-- unless @commit.ci_yaml_file
-  .bs-callout.bs-callout-warning
-    \.gitlab-ci.yml not found in this commit
-
-- @commit.refs.each do |ref|
-  %h3
-    Builds for #{gitlab_ref_link(@project, ref)}
-    - if @commit.duration_for_ref(ref) > 0
-      %small.pull-right
-        %i.fa.fa-time
-        #{time_interval_in_words @commit.duration_for_ref(ref)}
-
-  %table.table.builds
-    %thead
-      %tr
-        %th Status
-        %th Build ID
-        %th Stage
-        %th Name
-        %th Duration
-        %th Finished at
-        - if @project.coverage_enabled?
-          %th Coverage
-        %th
-    = render @commit.builds_without_retry.for_ref(ref), controls: true
-
-- if @commit.retried_builds.any?
-  %h3
-    Retried builds
-
-  %table.table.builds
-    %thead
-      %tr
-        %th Status
-        %th Build ID
-        %th Ref
-        %th Stage
-        %th Name
-        %th Duration
-        %th Finished at
-        - if @project.coverage_enabled?
-          %th Coverage
-        %th
-    = render @commit.retried_builds, ref: true
diff --git a/app/views/ci/notify/build_fail_email.html.haml b/app/views/ci/notify/build_fail_email.html.haml
index 4ebdfa1b6c088d884f62efef3dcc7422facb4478..69689a75022fcb6146f40d45ec0d773de49aa207 100644
--- a/app/views/ci/notify/build_fail_email.html.haml
+++ b/app/views/ci/notify/build_fail_email.html.haml
@@ -16,4 +16,4 @@
   Message: #{@build.commit.git_commit_message}
 
 %p
-  Url: #{link_to @build.short_sha, ci_project_build_url(@project, @build)}
+  Url: #{link_to @build.short_sha, namespace_project_build_url(@build.gl_project.namespace, @build.gl_project, @build)}
diff --git a/app/views/ci/notify/build_fail_email.text.erb b/app/views/ci/notify/build_fail_email.text.erb
index 177827f9a3c1c2aa16874f6a840c598aa6c1a685..6de5dc10f179184ffdbf0591ff0380a42739ae0e 100644
--- a/app/views/ci/notify/build_fail_email.text.erb
+++ b/app/views/ci/notify/build_fail_email.text.erb
@@ -6,4 +6,4 @@ Author:   <%= @build.commit.git_author_name %>
 Branch:   <%= @build.ref %>
 Message:  <%= @build.commit.git_commit_message %>
 
-Url:      <%= ci_project_build_url(@build.project, @build) %>
+Url:      <%= namespace_project_build_url(@build.gl_project.namespace, @build.gl_project, @build) %>
diff --git a/app/views/ci/notify/build_success_email.html.haml b/app/views/ci/notify/build_success_email.html.haml
index 7cc43300e883e4a45986a526db88af6b9c1a6922..4e3015a356bea801bea8087a7fe051445167b8be 100644
--- a/app/views/ci/notify/build_success_email.html.haml
+++ b/app/views/ci/notify/build_success_email.html.haml
@@ -17,4 +17,4 @@
   Message: #{@build.commit.git_commit_message}
 
 %p
-  Url: #{link_to @build.short_sha, ci_project_build_url(@project, @build)}
+  Url: #{link_to @build.short_sha, namespace_project_build_url(@build.gl_project.namespace, @build.gl_project, @build)}
diff --git a/app/views/ci/notify/build_success_email.text.erb b/app/views/ci/notify/build_success_email.text.erb
index 4d55c39b0fb7c6e5e5c3481949cf85de57125ec0..d0a43ae1c12915fd47fd85b6d0b14eb25a9b1c70 100644
--- a/app/views/ci/notify/build_success_email.text.erb
+++ b/app/views/ci/notify/build_success_email.text.erb
@@ -6,4 +6,4 @@ Author:   <%= @build.commit.git_author_name %>
 Branch:   <%= @build.ref %>
 Message:  <%= @build.commit.git_commit_message %>
 
-Url:      <%= ci_project_build_url(@build.project, @build) %>
+Url:      <%= namespace_project_build_url(@build.gl_project.namespace, @build.gl_project, @build) %>
diff --git a/app/views/layouts/ci/build.html.haml b/app/views/layouts/ci/build.html.haml
deleted file mode 100644
index a1356f0dc2ea2b802c5c7be62e681769951dba82..0000000000000000000000000000000000000000
--- a/app/views/layouts/ci/build.html.haml
+++ /dev/null
@@ -1,11 +0,0 @@
-!!! 5
-%html{ lang: "en"}
-  = render 'layouts/head'
-  %body{class: "ci-body #{user_application_theme}", 'data-page' => body_data_page}
-    - header_title ci_commit_title(@commit)
-    - if current_user
-      = render "layouts/header/default", title: header_title
-    - else
-      = render "layouts/header/public", title: header_title
-
-    = render 'layouts/ci/page', sidebar: 'nav_project'
diff --git a/app/views/layouts/ci/commit.html.haml b/app/views/layouts/ci/commit.html.haml
deleted file mode 100644
index a1356f0dc2ea2b802c5c7be62e681769951dba82..0000000000000000000000000000000000000000
--- a/app/views/layouts/ci/commit.html.haml
+++ /dev/null
@@ -1,11 +0,0 @@
-!!! 5
-%html{ lang: "en"}
-  = render 'layouts/head'
-  %body{class: "ci-body #{user_application_theme}", 'data-page' => body_data_page}
-    - header_title ci_commit_title(@commit)
-    - if current_user
-      = render "layouts/header/default", title: header_title
-    - else
-      = render "layouts/header/public", title: header_title
-
-    = render 'layouts/ci/page', sidebar: 'nav_project'
diff --git a/app/views/ci/builds/_build.html.haml b/app/views/projects/builds/_build.html.haml
similarity index 91%
rename from app/views/ci/builds/_build.html.haml
rename to app/views/projects/builds/_build.html.haml
index 8ccc0dff2fbf49ae110a42f250ae3d2530ad13cb..21c543b38dd82752861ef4887931a12167606e39 100644
--- a/app/views/ci/builds/_build.html.haml
+++ b/app/views/projects/builds/_build.html.haml
@@ -1,9 +1,10 @@
+- gl_project = build.project.gl_project
 %tr.build
   %td.status
     = ci_status_with_icon(build.status)
 
   %td.build-link
-    = link_to ci_project_build_path(build.project, build) do
+    = link_to namespace_project_build_path(gl_project.namespace, gl_project, build) do
       %strong Build ##{build.id}
 
   - if defined?(ref)
diff --git a/app/views/projects/builds/show.html.haml b/app/views/projects/builds/show.html.haml
new file mode 100644
index 0000000000000000000000000000000000000000..93cd4dcfd93d161c4b95a8475e03ceb96ac410e1
--- /dev/null
+++ b/app/views/projects/builds/show.html.haml
@@ -0,0 +1,159 @@
+.build-page
+  .gray-content-block
+    Build for commit
+    %strong.monospace
+      = link_to @build.commit.short_sha, ci_status_path(@build.commit)
+    from
+    %code #{@build.ref}
+
+  #up-build-trace
+  - if @commit.matrix_for_ref?(@build.ref)
+    %ul.center-top-menu.build-top-menu
+      - @commit.builds_without_retry_for_ref(@build.ref).each do |build|
+        %li{class: ('active' if build == @build) }
+          = link_to namespace_project_build_path(@project.namespace, @project, build) do
+            = ci_icon_for_status(build.status)
+            %span
+              - if build.name
+                = build.name
+              - else
+                = build.id
+
+
+      - unless @commit.builds_without_retry_for_ref(@build.ref).include?(@build)
+        %li.active
+          %a
+            Build ##{@build.id}
+            &middot;
+            %i.fa.fa-warning-sign
+            This build was retried.
+
+  .gray-content-block.second-block
+    .build-head
+      .clearfix
+        = ci_status_with_icon(@build.status)
+        - if @build.duration
+          %span
+            %i.fa.fa-time
+            #{duration_in_words(@build.finished_at, @build.started_at)}
+        .pull-right
+          = @build.updated_at.stamp('19:00 Aug 27')
+
+  .row.prepend-top-default
+    .col-md-9
+      .clearfix
+        - if @build.active?
+          .autoscroll-container
+            %button.btn.btn-success.btn-sm#autoscroll-button{:type => "button", :data => {:state => 'disabled'}} enable autoscroll
+          .clearfix
+      .scroll-controls
+        = link_to '#up-build-trace', class: 'btn' do
+          %i.fa.fa-angle-up
+        = link_to '#down-build-trace', class: 'btn' do
+          %i.fa.fa-angle-down
+
+      %pre.trace#build-trace
+        %code.bash
+          = preserve do
+            = raw @build.trace_html
+      %div#down-build-trace
+
+    .col-md-3
+      - if @build.coverage
+        .build-widget
+          %h4.title
+            Test coverage
+          %h1 #{@build.coverage}%
+
+
+      .build-widget
+        %h4.title
+          Build
+          - if current_user && can?(current_user, :manage_builds, @project)
+            .pull-right
+              - if @build.active?
+                = link_to "Cancel", cancel_ci_project_build_path(@ci_project, @build), class: 'btn btn-sm btn-danger'
+              - elsif @build.commands.present?
+                = link_to "Retry", retry_ci_project_build_path(@ci_project, @build), class: 'btn btn-sm btn-primary', method: :post
+
+        - if @build.duration
+          %p
+            %span.attr-name Duration:
+            #{duration_in_words(@build.finished_at, @build.started_at)}
+        %p
+          %span.attr-name Created:
+          #{time_ago_in_words(@build.created_at)} ago
+        - if @build.finished_at
+          %p
+            %span.attr-name Finished:
+            #{time_ago_in_words(@build.finished_at)} ago
+        %p
+          %span.attr-name Runner:
+          - if @build.runner && current_user && current_user.admin
+            \#{link_to "##{@build.runner.id}", ci_admin_runner_path(@build.runner.id)}
+          - elsif @build.runner
+            \##{@build.runner.id}
+
+      - if @build.trigger_request
+        .build-widget
+          %h4.title
+            Trigger
+
+          %p
+            %span.attr-name Token:
+            #{@build.trigger_request.trigger.short_token}
+
+          - if @build.trigger_request.variables
+            %p
+              %span.attr-name Variables:
+
+            %code
+              - @build.trigger_request.variables.each do |key, value|
+                #{key}=#{value}
+
+      .build-widget
+        %h4.title
+          Commit
+          .pull-right
+            %small #{build_commit_link @build}
+        %p
+          %span.attr-name Branch:
+          #{build_ref_link @build}
+        %p
+          %span.attr-name Author:
+          #{@build.commit.git_author_name}
+        %p
+          %span.attr-name Message:
+          #{@build.commit.git_commit_message}
+
+      - if @build.tags.any?
+        .build-widget
+          %h4.title
+            Tags
+          - @build.tag_list.each do |tag|
+            %span.label.label-primary
+              = tag
+
+      - if @builds.present?
+        .build-widget
+          %h4.title #{pluralize(@builds.count, "other build")} for #{@build.short_sha}:
+          %table.table.builds
+            - @builds.each_with_index do |build, i|
+              %tr.build
+                %td
+                  = ci_icon_for_status(build.status)
+                %td
+                  = link_to namespace_project_build_path(@project.namespace, @project, @build) do
+                    - if build.name
+                      = build.name
+                    - else
+                      %span ##{build.id}
+
+                %td.status= build.status
+
+
+          = paginate @builds
+
+
+  :javascript
+    new CiBuild("#{namespace_project_build_path(@project.namespace, @project, @build)}", "#{@build.status}")
diff --git a/app/views/projects/commit/ci.html.haml b/app/views/projects/commit/ci.html.haml
index bbb41a80268fe194db3110144099e0b9ebd1d713..f4382e88046ebd5072e006d2213bf4d75e8d3577 100644
--- a/app/views/projects/commit/ci.html.haml
+++ b/app/views/projects/commit/ci.html.haml
@@ -40,7 +40,7 @@
         - if @ci_project && @ci_project.coverage_enabled?
           %th Coverage
         %th
-    = render partial: "ci/builds/build", collection: @ci_commit.builds_without_retry.for_ref(ref), controls: true
+    = render partial: "projects/builds/build", collection: @ci_commit.builds_without_retry.for_ref(ref), controls: true
 
 - if @ci_commit.retried_builds.any?
   %h3
@@ -59,4 +59,4 @@
         - if @ci_project && @ci_project.coverage_enabled?
           %th Coverage
         %th
-    = render partial: "ci/builds/build", collection: @ci_commit.retried_builds, ref: true
+    = render partial: "projects/builds/build", collection: @ci_commit.retried_builds, ref: true
diff --git a/config/routes.rb b/config/routes.rb
index beebb3258d1e504edc7458173a2319244cabd22b..ccce40589e711e6d0285e2bca1b2e6cc3d95a183 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -28,16 +28,14 @@ Gitlab::Application.routes.draw do
         end
       end
 
-      resource :charts, only: [:show]
-
-      resources :commits, only: [:show] do
+      resources :commits, only: [] do
         member do
           get :status
           get :cancel
         end
       end
 
-      resources :builds, only: [:show] do
+      resources :builds, only: [] do
         member do
           get :cancel
           get :status
@@ -592,6 +590,8 @@ Gitlab::Application.routes.draw do
           end
         end
 
+        resources :builds, only: [:show]
+
         resources :hooks, only: [:index, :create, :destroy], constraints: { id: /\d+/ } do
           member do
             get :test
diff --git a/spec/features/builds_spec.rb b/spec/features/builds_spec.rb
new file mode 100644
index 0000000000000000000000000000000000000000..d0d60491b65befbfa70dda41d8a3ac17f5a0312f
--- /dev/null
+++ b/spec/features/builds_spec.rb
@@ -0,0 +1,22 @@
+require 'spec_helper'
+
+describe "Builds" do
+
+  before do
+    login_as(:user)
+    @commit = FactoryGirl.create :ci_commit
+    @build = FactoryGirl.create :ci_build, commit: @commit
+    @gl_project = @commit.project.gl_project
+    @gl_project.team << [@user, :master]
+  end
+
+  describe "GET /:project/builds/:id" do
+    before do
+      visit namespace_project_build_path(@gl_project.namespace, @gl_project, @build)
+    end
+
+    it { expect(page).to have_content @commit.sha[0..7] }
+    it { expect(page).to have_content @commit.git_commit_message }
+    it { expect(page).to have_content @commit.git_author_name }
+  end
+end
diff --git a/spec/features/ci/builds_spec.rb b/spec/features/ci/builds_spec.rb
index d65699dbefa7319b2959fcb3fd72e5736578f591..aa0df59c04df2359c44a5570d3e8acafcdb528a4 100644
--- a/spec/features/ci/builds_spec.rb
+++ b/spec/features/ci/builds_spec.rb
@@ -1,61 +1,31 @@
 require 'spec_helper'
 
 describe "Builds" do
-  context :private_project do
-    before do
-      @commit = FactoryGirl.create :ci_commit
-      @build = FactoryGirl.create :ci_build, commit: @commit
-      login_as :user
-      @commit.project.gl_project.team << [@user, :master]
-    end
-
-    describe "GET /:project/builds/:id" do
-      before do
-        visit ci_project_build_path(@commit.project, @build)
-      end
-
-      it { expect(page).to have_content @commit.sha[0..7] }
-      it { expect(page).to have_content @commit.git_commit_message }
-      it { expect(page).to have_content @commit.git_author_name }
-    end
-
-    describe "GET /:project/builds/:id/cancel" do
-      before do
-        @build.run!
-        visit cancel_ci_project_build_path(@commit.project, @build)
-      end
+  before do
+    login_as(:user)
+    @commit = FactoryGirl.create :ci_commit
+    @build = FactoryGirl.create :ci_build, commit: @commit
+    @gl_project = @commit.project.gl_project
+    @gl_project.team << [@user, :master]
+  end
 
-      it { expect(page).to have_content 'canceled' }
-      it { expect(page).to have_content 'Retry' }
+  describe "GET /:project/builds/:id/cancel" do
+    before do
+      @build.run!
+      visit cancel_ci_project_build_path(@commit.project, @build)
     end
 
-    describe "POST /:project/builds/:id/retry" do
-      before do
-        @build.cancel!
-        visit ci_project_build_path(@commit.project, @build)
-        click_link 'Retry'
-      end
-
-      it { expect(page).to have_content 'pending' }
-      it { expect(page).to have_content 'Cancel' }
-    end
+    it { expect(page).to have_content 'canceled' }
+    it { expect(page).to have_content 'Retry' }
   end
 
-  context :public_project do
-    describe "Show page public accessible" do
-      before do
-        @commit = FactoryGirl.create :ci_commit
-        @commit.project.public = true
-        @commit.project.save
-        
-        @runner = FactoryGirl.create :ci_specific_runner
-        @build = FactoryGirl.create :ci_build, commit: @commit, runner: @runner
-
-        stub_gitlab_calls
-        visit ci_project_build_path(@commit.project, @build)
-      end
-
-      it { expect(page).to have_content @commit.sha[0..7] }
+  describe "POST /:project/builds/:id/retry" do
+    before do
+      visit cancel_ci_project_build_path(@commit.project, @build)
+      click_link 'Retry'
     end
+
+    it { expect(page).to have_content 'pending' }
+    it { expect(page).to have_content 'Cancel' }
   end
 end
diff --git a/spec/features/ci/commits_spec.rb b/spec/features/commits_spec.rb
similarity index 53%
rename from spec/features/ci/commits_spec.rb
rename to spec/features/commits_spec.rb
index b4236e1e589626bdf4cf95da32abcaff359c6627..5da220859e37af91b52ae8142679fb9a805ebac4 100644
--- a/spec/features/ci/commits_spec.rb
+++ b/spec/features/commits_spec.rb
@@ -1,14 +1,17 @@
 require 'spec_helper'
 
 describe "Commits" do
-  include Ci::CommitsHelper
+  include CiStatusHelper
 
-  context "Authenticated user" do
+  let(:project) { create(:project) }
+
+  describe "CI" do
     before do
-      @commit = FactoryGirl.create :ci_commit
-      @build = FactoryGirl.create :ci_build, commit: @commit
       login_as :user
-      @commit.project.gl_project.team << [@user, :master]
+      project.team << [@user, :master]
+      @ci_project = project.ensure_gitlab_ci_project
+      @commit = FactoryGirl.create :ci_commit, gl_project: project, sha: project.commit.sha
+      @build = FactoryGirl.create :ci_build, commit: @commit
     end
 
     before do
@@ -17,7 +20,7 @@ describe "Commits" do
 
     describe "GET /:project/commits/:sha" do
       before do
-        visit ci_commit_path(@commit)
+        visit ci_status_path(@commit)
       end
 
       it { expect(page).to have_content @commit.sha[0..7] }
@@ -27,47 +30,23 @@ describe "Commits" do
 
     describe "Cancel commit" do
       it "cancels commit" do
-        visit ci_commit_path(@commit)
+        visit ci_status_path(@commit)
         click_on "Cancel"
-
         expect(page).to have_content "canceled"
       end
     end
 
     describe ".gitlab-ci.yml not found warning" do
       it "does not show warning" do
-        visit ci_commit_path(@commit)
-
+        visit ci_status_path(@commit)
         expect(page).not_to have_content ".gitlab-ci.yml not found in this commit"
       end
 
       it "shows warning" do
         stub_ci_commit_yaml_file(nil)
-
-        visit ci_commit_path(@commit)
-
+        visit ci_status_path(@commit)
         expect(page).to have_content ".gitlab-ci.yml not found in this commit"
       end
     end
   end
-
-  context "Public pages" do
-    before do
-      @commit = FactoryGirl.create :ci_commit
-      @commit.project.public = true
-      @commit.project.save
-
-      @build = FactoryGirl.create :ci_build, commit: @commit
-    end
-
-    describe "GET /:project/commits/:sha" do
-      before do
-        visit ci_commit_path(@commit)
-      end
-
-      it { expect(page).to have_content @commit.sha[0..7] }
-      it { expect(page).to have_content @commit.git_commit_message }
-      it { expect(page).to have_content @commit.git_author_name }
-    end
-  end
 end
diff --git a/spec/models/project_services/gitlab_ci_service_spec.rb b/spec/models/project_services/gitlab_ci_service_spec.rb
index c0b8a144c3add3279e20367f181a29cab2847599..842089ebe0d66b9eae8fffda30c069838931b054 100644
--- a/spec/models/project_services/gitlab_ci_service_spec.rb
+++ b/spec/models/project_services/gitlab_ci_service_spec.rb
@@ -39,8 +39,7 @@ describe GitlabCiService do
     end
 
     describe :build_page do
-      it { expect(@service.build_page("2ab7834c", 'master')).to eq("http://localhost/ci/projects/#{@ci_project.id}/commits/2ab7834c")}
-      it { expect(@service.build_page("issue#2", 'master')).to eq("http://localhost/ci/projects/#{@ci_project.id}/commits/issue%232")}
+      it { expect(@service.build_page("2ab7834c", 'master')).to eq("http://localhost/#{@ci_project.gl_project.path_with_namespace}/commit/2ab7834c/ci")}
     end
 
     describe "execute" do