Merge branch 'ci-build-page' into 'master'
Move CI build page to CE project * move CI build page to project * cleanup unused code * fix few 500 errors (build cancel and few CI admin pages) Signed-off-by: Dmitriy Zaporozhets <dmitriy.zaporozhets@gmail.com> See merge request !1524
This commit is contained in:
commit
0611a18964
32 changed files with 301 additions and 455 deletions
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -381,6 +381,10 @@ table {
|
|||
&.no-bottom {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
&.no-top {
|
||||
margin-top: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.dropzone .dz-preview .dz-progress {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
25
app/controllers/projects/builds_controller.rb
Normal file
25
app/controllers/projects/builds_controller.rb
Normal file
|
@ -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
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
|
@ -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
|
||||
|
|
|
@ -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('')
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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}
|
||||
·
|
||||
%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}")
|
|
@ -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
|
||||
|
|
|
@ -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
|
|
@ -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)}
|
||||
|
|
|
@ -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) %>
|
||||
|
|
|
@ -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)}
|
||||
|
|
|
@ -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) %>
|
||||
|
|
|
@ -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'
|
|
@ -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'
|
|
@ -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)
|
159
app/views/projects/builds/show.html.haml
Normal file
159
app/views/projects/builds/show.html.haml
Normal file
|
@ -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}
|
||||
·
|
||||
%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}")
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
22
spec/features/builds_spec.rb
Normal file
22
spec/features/builds_spec.rb
Normal file
|
@ -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
|
|
@ -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
|
||||
|
||||
it { expect(page).to have_content 'canceled' }
|
||||
it { expect(page).to have_content 'Retry' }
|
||||
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
|
||||
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
|
||||
|
||||
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 "GET /:project/builds/:id/cancel" do
|
||||
before do
|
||||
@build.run!
|
||||
visit cancel_ci_project_build_path(@commit.project, @build)
|
||||
end
|
||||
|
||||
it { expect(page).to have_content 'canceled' }
|
||||
it { expect(page).to have_content 'Retry' }
|
||||
end
|
||||
|
||||
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
|
||||
|
|
|
@ -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
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue