summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKamil Trzcinski <ayufan@ayufan.eu>2016-04-01 10:10:39 +0200
committerKamil Trzcinski <ayufan@ayufan.eu>2016-04-01 10:10:39 +0200
commitfeec3a45eb517607d96f5553f36e7d35c97520ba (patch)
treedb037849302326f1ecdd2916687fadd00330cdba
parent95b010fb73832b1bcfba884b9bcfd87d2954e44c (diff)
downloadgitlab-ce-ci-changes-refactor.tar.gz
Show pipelinesci-changes-refactor
-rw-r--r--app/controllers/projects/builds_controller.rb28
-rw-r--r--app/controllers/projects/ci_commits_controller.rb63
-rw-r--r--app/controllers/projects/commit_controller.rb5
-rw-r--r--app/models/ability.rb7
-rw-r--r--app/models/ci/build.rb4
-rw-r--r--app/models/ci/commit.rb12
-rw-r--r--app/models/commit_status.rb2
-rw-r--r--app/models/concerns/ci_status.rb11
-rw-r--r--app/views/layouts/nav/_project.html.haml9
-rw-r--r--app/views/projects/ci/commits/_commit.html.haml148
-rw-r--r--app/views/projects/ci_commits/_header_title.html.haml2
-rw-r--r--app/views/projects/ci_commits/index.html.haml36
-rw-r--r--app/views/projects/ci_commits/new.html.haml25
-rw-r--r--app/views/projects/ci_commits/show.html.haml216
-rw-r--r--config/routes.rb8
-rw-r--r--db/migrate/20160331204039_add_action_to_ci_commit.rb5
16 files changed, 228 insertions, 353 deletions
diff --git a/app/controllers/projects/builds_controller.rb b/app/controllers/projects/builds_controller.rb
index f159e169f6d..269c0d3c21f 100644
--- a/app/controllers/projects/builds_controller.rb
+++ b/app/controllers/projects/builds_controller.rb
@@ -20,6 +20,30 @@ class Projects::BuildsController < Projects::ApplicationController
@builds = @builds.page(params[:page]).per(30)
end
+ def commits
+ @scope = params[:scope]
+ @all_commits = project.ci_commits
+ @commits = @all_commits.order(id: :desc)
+ @commits =
+ case @scope
+ when 'latest'
+ @commits
+ when 'branches'
+ refs = project.repository.branches.map(&:name)
+ ids = @all_commits.where(ref: refs).group(:ref).select('max(id)')
+ @commits.where(id: ids)
+ when 'tags'
+ refs = project.repository.tags.map(&:name)
+ ids = @all_commits.where(ref: refs).group(:ref).select('max(id)')
+ @commits.where(id: ids)
+ else
+ @commits
+ end
+ @commits = @commits.page(params[:page]).per(30)
+ end
+
+ private
+
def cancel_all
@project.builds.running_or_pending.each(&:cancel)
redirect_to namespace_project_builds_path(project.namespace, project)
@@ -68,6 +92,10 @@ class Projects::BuildsController < Projects::ApplicationController
@build ||= project.builds.unscoped.find_by!(id: params[:id])
end
+ def ci_commit
+ @ci_commit ||= project.ci_commits.find_by!(id: params[:id])
+ end
+
def build_path(build)
namespace_project_build_path(build.project.namespace, build.project, build)
end
diff --git a/app/controllers/projects/ci_commits_controller.rb b/app/controllers/projects/ci_commits_controller.rb
index e4797833b06..a36e3085e8a 100644
--- a/app/controllers/projects/ci_commits_controller.rb
+++ b/app/controllers/projects/ci_commits_controller.rb
@@ -1,6 +1,8 @@
class Projects::CiCommitsController < Projects::ApplicationController
- before_action :ci_commit, except: [:index]
- before_action :authorize_read_build!
+ before_action :ci_commit, except: [:index, :new, :create]
+ before_action :authorize_read_pipeline!
+ before_action :authorize_create_pipeline!, only: [:new, :create]
+ before_action :authorize_update_pipeline!, only: [:retry, :cancel]
layout 'project'
def index
@@ -11,6 +13,8 @@ class Projects::CiCommitsController < Projects::ApplicationController
case @scope
when 'latest'
@commits
+ when 'running'
+ @commits.running_or_pending
when 'branches'
refs = project.repository.branches.map(&:name)
ids = @all_commits.where(ref: refs).group(:ref).select('max(id)')
@@ -25,6 +29,47 @@ class Projects::CiCommitsController < Projects::ApplicationController
@commits = @commits.page(params[:page]).per(30)
end
+ def new
+ end
+
+ def create
+ ref_names = project.repository.ref_names
+ unless ref_names.include?(params[:ref])
+ @error = 'Reference not found'
+ render action: 'new'
+ return
+ end
+
+ commit = project.commit(params[:ref])
+ unless commit
+ @error = 'Commit not found'
+ render action: 'new'
+ return
+ end
+
+ ci_commit = project.ci_commit(commit.id, params[:ref])
+ if ci_commit
+ @error = 'Pipeline already created'
+ render action: 'new'
+ return
+ end
+
+ # Skip creating ci_commit when no gitlab-ci.yml is found
+ commit = project.ci_commits.new(sha: commit.id, ref: params[:ref], before_sha: Gitlab::Git::BLANK_SHA)
+ unless commit.config_processor
+ @error = commit.yaml_errors || 'Missing .gitlab-ci.yml file'
+ render action: 'new'
+ return
+ end
+
+ Ci::Commit.transaction do
+ commit.save!
+ commit.create_builds(params[:ref], false, current_user)
+ end
+
+ redirect_to builds_namespace_project_commit_path(project.namespace, project, commit.id)
+ end
+
def show
@commit = @ci_commit.commit
@builds = @ci_commit.builds
@@ -35,6 +80,20 @@ class Projects::CiCommitsController < Projects::ApplicationController
end
end
+ def retry
+ ci_commit.builds.latest.failed.select(&:retryable?).each(&:retry)
+
+ redirect_back_or_default default: namespace_project_ci_commits_path(project.namespace, project)
+ end
+
+ def cancel
+ ci_commit.builds.running_or_pending.each(&:cancel)
+
+ redirect_back_or_default default: namespace_project_ci_commits_path(project.namespace, project)
+ end
+
+ def retry_builds
+ end
private
def ci_commit
diff --git a/app/controllers/projects/commit_controller.rb b/app/controllers/projects/commit_controller.rb
index ef20281e82f..623856f282f 100644
--- a/app/controllers/projects/commit_controller.rb
+++ b/app/controllers/projects/commit_controller.rb
@@ -96,6 +96,11 @@ class Projects::CommitController < Projects::ApplicationController
def ci_commits
@ci_commits ||= project.ci_commits.where(sha: commit.sha)
+ if params[:commit_id]
+ @ci_commits.where(id: params[:commit_id].to_i)
+ else
+ @ci_commits
+ end
end
def define_show_vars
diff --git a/app/models/ability.rb b/app/models/ability.rb
index c0bf6def7c5..ec5ac54c277 100644
--- a/app/models/ability.rb
+++ b/app/models/ability.rb
@@ -195,6 +195,7 @@ class Ability
:admin_label,
:read_commit_status,
:read_build,
+ :read_pipeline,
]
end
@@ -206,6 +207,8 @@ class Ability
:update_commit_status,
:create_build,
:update_build,
+ :create_pipeline,
+ :update_pipeline,
:create_merge_request,
:create_wiki,
:push_code
@@ -234,7 +237,8 @@ class Ability
:admin_wiki,
:admin_project,
:admin_commit_status,
- :admin_build
+ :admin_build,
+ :admin_pipeline
]
end
@@ -277,6 +281,7 @@ class Ability
unless project.builds_enabled
rules += named_abilities('build')
+ rules += named_abilities('pipeline')
end
rules
diff --git a/app/models/ci/build.rb b/app/models/ci/build.rb
index c99aeff6f1c..d497cf67cbc 100644
--- a/app/models/ci/build.rb
+++ b/app/models/ci/build.rb
@@ -129,6 +129,10 @@ module Ci
!self.commit.latest.include?(self)
end
+ def retry
+ Ci::Build.retry(self)
+ end
+
def depends_on_builds
# Get builds of the same type
latest_builds = self.commit.builds.latest
diff --git a/app/models/ci/commit.rb b/app/models/ci/commit.rb
index cd9ce0a283d..45309614115 100644
--- a/app/models/ci/commit.rb
+++ b/app/models/ci/commit.rb
@@ -67,6 +67,12 @@ module Ci
.pluck(:stage, :stage_idx).map(&:first)
end
+ def stages
+ statuses
+ .group(:stage, :stage_idx).order(:stage_idx)
+ .pluck(:stage, :stage_idx).map(&:first)
+ end
+
def to_param
sha
end
@@ -115,6 +121,12 @@ module Ci
Gitlab::Git::branch_ref?(origin_ref)
end
+ def retryable?
+ builds.latest.any? do |build|
+ build.failed? || build.retryable?
+ end
+ end
+
def create_builds(ref, tag, user, trigger_request = nil)
return unless config_processor
config_processor.stages.any? do |stage|
diff --git a/app/models/commit_status.rb b/app/models/commit_status.rb
index 3a059f01d49..88cb7e21d66 100644
--- a/app/models/commit_status.rb
+++ b/app/models/commit_status.rb
@@ -53,7 +53,7 @@ class CommitStatus < ActiveRecord::Base
scope :failed, -> { where(status: 'failed') }
scope :running_or_pending, -> { where(status: [:running, :pending]) }
scope :finished, -> { where(status: [:success, :failed, :canceled]) }
- scope :latest, -> { where(id: unscope(:select).select('max(id)').group(:name, :ref)) }
+ scope :latest, -> { where(id: unscope(:select).select('max(id)').group(:name)) }
scope :ordered, -> { order(:ref, :stage_idx, :name) }
scope :for_ref, ->(ref) { where(ref: ref) }
diff --git a/app/models/concerns/ci_status.rb b/app/models/concerns/ci_status.rb
index 494db025048..f7a9af1507d 100644
--- a/app/models/concerns/ci_status.rb
+++ b/app/models/concerns/ci_status.rb
@@ -3,15 +3,16 @@ module CiStatus
module ClassMethods
def status
- if all.none?
+ objs = all.to_a
+ if objs.none?
nil
- elsif all.all? { |status| status.success? || status.ignored? }
+ elsif objs.all? { |status| status.success? || status.ignored? }
'success'
- elsif all.all?(&:pending?)
+ elsif objs.all?(&:pending?)
'pending'
- elsif all.any?(&:running?) || all.any?(&:pending?)
+ elsif objs.any?(&:running?) || all.any?(&:pending?)
'running'
- elsif all.all?(&:canceled?)
+ elsif objs.all?(&:canceled?)
'canceled'
else
'failed'
diff --git a/app/views/layouts/nav/_project.html.haml b/app/views/layouts/nav/_project.html.haml
index bb0bba77fa2..9a3ebaad604 100644
--- a/app/views/layouts/nav/_project.html.haml
+++ b/app/views/layouts/nav/_project.html.haml
@@ -40,19 +40,18 @@
- if project_nav_tab? :builds
= nav_link(controller: %w(ci_commits)) do
- = link_to project_ci_commits_path(@project), title: 'CI', class: 'shortcuts-ci' do
- = icon('cubes fw')
+ = link_to project_ci_commits_path(@project), title: 'Pipelines', class: 'shortcuts-builds' do
+ = icon('ship fw')
%span
- CI
+ Pipelines
%span.count.ci_counter= number_with_delimiter(@project.ci_commits.running_or_pending.count(:all))
- - if project_nav_tab? :builds
= nav_link(controller: %w(builds)) do
= link_to project_builds_path(@project), title: 'Builds', class: 'shortcuts-builds' do
= icon('cubes fw')
%span
Builds
- %span.count.builds_counter= number_with_delimiter(@project.builds.running_or_pending.count(:all))
+ %span.count.ci_counter= number_with_delimiter(@project.builds.running_or_pending.count(:all))
- if project_nav_tab? :graphs
= nav_link(controller: %w(graphs)) do
diff --git a/app/views/projects/ci/commits/_commit.html.haml b/app/views/projects/ci/commits/_commit.html.haml
index 671c5abcbed..8219e7bf701 100644
--- a/app/views/projects/ci/commits/_commit.html.haml
+++ b/app/views/projects/ci/commits/_commit.html.haml
@@ -1,22 +1,14 @@
+- status = commit.status
%tr.commit
%td.commit-link
- - if can?(current_user, :read_commit, commit)
- = link_to namespace_project_commit_url(commit.project.namespace, commit.project, commit) do
- %strong ##{commit.id}
- - else
+ = link_to namespace_project_commit_url(@project.namespace, @project, commit), class: "ci-status ci-#{status}" do
+ = ci_icon_for_status(status)
%strong ##{commit.id}
- %td.status
- %div
- - if can?(current_user, :read_commit, commit)
- = ci_status_with_icon(commit.status, namespace_project_commit_url(commit.project.namespace, commit.project, commit))
- - else
- = ci_status_with_icon(commit.status)
-
%td
%div
- if commit.ref
- = link_to commit.ref, namespace_project_commits_path(commit.project.namespace, commit.project, commit.ref)
+ = link_to commit.ref, namespace_project_commits_path(@project.namespace, @project, commit.ref)
&nbsp;
- if commit.tag?
%span.label.label-primary tag
@@ -35,107 +27,43 @@
%p
Cant find HEAD commit for this branch
+ - stages.each do |stage|
+ %td
+ - status = commit.statuses.latest.where(stage: stage).status
+ - if status
+ = ci_status_with_icon(status)
+ - else
+ = ci_status_with_icon('missing')
+
%td
- %div
- Duration:
- &nbsp;
- - if commit.started_at && commit.finished_at
+ - if commit.started_at && commit.finished_at
+ %p
#{duration_in_words(commit.finished_at, commit.started_at)}
- - else
- \-
+ - if commit.finished_at
%p
- Finished:
- &nbsp;
- - if commit.finished_at
- #{time_ago_with_tooltip(commit.finished_at)}
- - else
- \-
+ #{time_ago_with_tooltip(commit.finished_at)}
%td.content
- .controls.hidden-xs
- = link_to project_builds_path(commit.project), class: 'btn btn-grouped btn-xs' do
- = icon('cubes fw')
- Details
+ .controls.hidden-xs.pull-right
+ - artifacts = commit.builds.latest.select { |status| status.artifacts? }
+ - if artifacts.present?
+ .dropdown.inline
+ %button.dropdown-toggle.btn{type: 'button', 'data-toggle' => 'dropdown'}
+ = icon('download')
+ %b.caret
+ %ul.dropdown-menu.dropdown-menu-align-right
+ - artifacts.each do |build|
+ %li
+ = link_to download_namespace_project_build_artifacts_path(@project.namespace, @project, build), rel: 'nofollow' do
+ %i.fa.fa-download
+ %span #{build.name}
+ &nbsp;
- - @project = commit.project
- - ref = 'master'
- %span.btn-group.btn-grouped
- %a.btn.btn-default.dropdown-toggle{ 'data-toggle' => 'dropdown' }
- %span.caret
- %span.sr-only
- Select Archive Format
- %ul.col-xs-10.dropdown-menu.dropdown-menu-align-right{ role: 'menu' }
- %li
- = link_to archive_namespace_project_repository_path(@project.namespace, @project, ref: ref, format: 'zip'), rel: 'nofollow' do
- %i.fa.fa-download
- %span Download zip
- %li
- = link_to archive_namespace_project_repository_path(@project.namespace, @project, ref: ref, format: 'tar.gz'), rel: 'nofollow' do
- %i.fa.fa-download
- %span Download tar.gz
- %li
- = link_to archive_namespace_project_repository_path(@project.namespace, @project, ref: ref, format: 'tar.bz2'), rel: 'nofollow' do
- %i.fa.fa-download
- %span Download tar.bz2
- %li
- = link_to archive_namespace_project_repository_path(@project.namespace, @project, ref: ref, format: 'tar'), rel: 'nofollow' do
- %i.fa.fa-download
- %span Download tar
--#%tr.commit
--# %td.status
--# - if can?(current_user, :read_commit, commit)
--# = ci_status_with_icon(commit.status, namespace_project_commit_url(commit.project.namespace, commit.project, commit))
--# - else
--# = ci_status_with_icon(commit.status)
--#
--# %td.commit-link
--# - if can?(current_user, :read_commit, commit)
--# = link_to namespace_project_commit_url(commit.project.namespace, commit.project, commit) do
--# %strong ##{commit.id}
--# - else
--# %strong ##{commit.id}
--#
--# - if defined?(commit_sha) && commit_sha
--# %td
--# = link_to commit.short_sha, namespace_project_commit_path(commit.project.namespace, commit.project, commit.sha), class: "monospace"
--#
--# %td
--# - if commit.ref
--# = link_to commit.ref, namespace_project_commits_path(commit.project.namespace, commit.project, commit.ref)
--# - else
--# .light none
--#
--# %td
--# = commit.git_commit_message
--#
--# %td.duration
--# - if commit.started_at && commit.finished_at
--# #{duration_in_words(commit.finished_at, commit.started_at)}
--#
--# %td.timestamp
--# - if commit.finished_at
--# %span #{time_ago_with_tooltip(commit.finished_at)}
--#
--# - if defined?(coverage) && coverage
--# %td.coverage
--# - if commit.try(:coverage)
--# #{commit.coverage}%
--#
--# %td
--# .pull-right
--# - if can?(current_user, :read_commit, commit) && commit.artifacts?
--# = link_to download_namespace_project_commit_artifacts_path(commit.project.namespace, commit.project, commit), title: 'Download artifacts' do
--# %i.fa.fa-download
--# - if can?(current_user, :update_commit, commit)
--# - if commit.active?
--# = link_to cancel_namespace_project_commit_path(commit.project.namespace, commit.project, commit, return_to: request.original_url), method: :post, title: 'Cancel' do
--# %i.fa.fa-remove.cred
--# - elsif defined?(allow_retry) && allow_retry && commit.retryable?
--# = link_to retry_namespace_project_commit_path(commit.project.namespace, commit.project, commit, return_to: request.original_url), method: :post, title: 'Retry' do
--# %i.fa.fa-repeat
--#
--#- if commit.yaml_errors.present?
--# %tr
--# %td{colspan: 7}
--# .light
--# = commit.yaml_errors \ No newline at end of file
+ - if can?(current_user, :update_pipeline, @project)
+ - if commit.retryable?
+ = link_to retry_namespace_project_ci_commit_path(@project.namespace, @project, commit.id), class: 'btn has-tooltip', title: "Retry", method: :post do
+ = icon("repeat")
+ &nbsp;
+ - if commit.active?
+ = link_to cancel_namespace_project_ci_commit_path(@project.namespace, @project, commit.id), class: 'btn btn-remove has-tooltip', title: "Cancel", method: :post do
+ = icon("remove cred")
diff --git a/app/views/projects/ci_commits/_header_title.html.haml b/app/views/projects/ci_commits/_header_title.html.haml
index c04fc6be9f1..27c125ca40f 100644
--- a/app/views/projects/ci_commits/_header_title.html.haml
+++ b/app/views/projects/ci_commits/_header_title.html.haml
@@ -1 +1 @@
-- header_title project_title(@project, "CI", project_ci_commits_path(@project))
+- header_title project_title(@project, "Pipelines", project_ci_commits_path(@project))
diff --git a/app/views/projects/ci_commits/index.html.haml b/app/views/projects/ci_commits/index.html.haml
index 7955e5e9abf..0347c220382 100644
--- a/app/views/projects/ci_commits/index.html.haml
+++ b/app/views/projects/ci_commits/index.html.haml
@@ -1,11 +1,11 @@
-- page_title "CI Changes"
+- page_title "Pipelines"
= render "header_title"
.top-area
%ul.nav-links
- %li{class: ('active' if @scope.nil? || @scope == 'latest')}
- = link_to project_ci_commits_path(@project, scope: :latest) do
- Latest
+ %li{class: ('active' if @scope.nil?)}
+ = link_to project_ci_commits_path(@project) do
+ All
%span.badge.js-totalbuilds-count
= number_with_delimiter(@all_commits.count(:id))
@@ -21,31 +21,45 @@
%span.badge.js-running-count
= number_with_delimiter(@all_commits.running_or_pending.count(:id))
- %li{class: ('active' if @scope == 'failed')}
- = link_to project_ci_commits_path(@project, scope: :failed) do
+ %li{class: ('active' if @scope == 'running')}
+ = link_to project_ci_commits_path(@project, scope: :running) do
Failed
%span.badge.js-running-count
- = number_with_delimiter(@all_commits.finished.count(:id))
+ = number_with_delimiter(@all_commits.running_or_pending.count(:id))
.nav-controls
+ - if can? current_user, :create_pipeline, @project
+ = link_to new_namespace_project_ci_commit_path(@project.namespace, @project), class: 'btn btn-create' do
+ = icon('plus')
+ New
+
- if can?(current_user, :update_build, @project)
- unless @repository.gitlab_ci_yml
- = link_to 'Get started with Builds', help_page_path('ci/quick_start', 'README'), class: 'btn btn-info'
+ = link_to 'Get started with Pipelines', help_page_path('ci/quick_start', 'README'), class: 'btn btn-info'
= link_to ci_lint_path, class: 'btn btn-default' do
= icon('wrench')
%span CI Lint
.gray-content-block
- #{(@scope || 'running').capitalize} changes on this project
+ Pipelines for #{(@scope || 'changes')} on this project
%ul.content-list
+ - stages = @commits.stages
- if @commits.blank?
%li
- .nothing-here-block No commits to show
+ .nothing-here-block No pipelines to show
- else
.table-holder
%table.table.builds
- = render @commits, commit_sha: true, stage: true, allow_retry: true
+ %tbody
+ %th Pipeline ID
+ %th Commit
+ - @commits.stages.each do |stage|
+ %th
+ = stage.titleize
+ %th
+ %th
+ = render @commits.includes(:statuses).includes(:builds), commit_sha: true, stage: true, allow_retry: true, stages: stages
= paginate @commits, theme: 'gitlab'
diff --git a/app/views/projects/ci_commits/new.html.haml b/app/views/projects/ci_commits/new.html.haml
new file mode 100644
index 00000000000..e9a22bbb157
--- /dev/null
+++ b/app/views/projects/ci_commits/new.html.haml
@@ -0,0 +1,25 @@
+- page_title "New Pipeline"
+= render "header_title"
+
+- if @error
+ .alert.alert-danger
+ %button{ type: "button", class: "close", "data-dismiss" => "alert"} &times;
+ = @error
+%h3.page-title
+ New Pipeline
+%hr
+
+= form_tag namespace_project_ci_commits_path, method: :post, id: "new-pipeline-form", class: "form-horizontal js-create-branch-form js-requires-input" do
+ .form-group
+ = label_tag :ref, 'Create for', class: 'control-label'
+ .col-sm-10
+ = text_field_tag :ref, params[:ref] || @project.default_branch, required: true, tabindex: 2, class: 'form-control'
+ .help-block Existing branch name, tag
+ .form-actions
+ = button_tag 'Create pipeline', class: 'btn btn-create', tabindex: 3
+ = link_to 'Cancel', namespace_project_ci_commits_path(@project.namespace, @project), class: 'btn btn-cancel'
+
+:javascript
+ var availableRefs = #{@project.repository.ref_names.to_json};
+
+ new NewBranchForm($('.js-create-branch-form'), availableRefs)
diff --git a/app/views/projects/ci_commits/show.html.haml b/app/views/projects/ci_commits/show.html.haml
deleted file mode 100644
index b02aee3db21..00000000000
--- a/app/views/projects/ci_commits/show.html.haml
+++ /dev/null
@@ -1,216 +0,0 @@
-- page_title "#{@build.name} (##{@build.id})", "Builds"
-= render "header_title"
-
-.build-page
- .gray-content-block.top-block
- Build ##{@build.id} for commit
- %strong.monospace= link_to @build.commit.short_sha, ci_status_path(@build.commit)
- from
- = link_to @build.ref, namespace_project_commits_path(@project.namespace, @project, @build.ref)
- - merge_request = @build.merge_request
- - if merge_request
- via
- = link_to "merge request ##{merge_request.iid}", merge_request_path(merge_request)
-
- #up-build-trace
- - builds = @build.commit.matrix_builds(@build)
- - if builds.size > 1
- %ul.nav-links.no-top.no-bottom
- - builds.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
-
- - if @build.retried?
- %li.active
- %a
- Build ##{@build.id}
- &middot;
- %i.fa.fa-warning
- This build was retried.
-
- .gray-content-block.middle-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
- #{time_ago_with_tooltip(@build.finished_at) if @build.finished_at}
-
- - if @build.stuck?
- - unless @build.any_runners_online?
- .bs-callout.bs-callout-warning
- %p
- - if no_runners_for_project?(@build.project)
- This build is stuck, because the project doesn't have any runners online assigned to it.
- - elsif @build.tags.any?
- This build is stuck, because you don't have any active runners online with any of these tags assigned to them:
- - @build.tags.each do |tag|
- %span.label.label-primary
- = tag
- - else
- This build is stuck, because you don't have any active runners that can run this build.
-
- %br
- Go to
- = link_to namespace_project_runners_path(@build.project.namespace, @build.project) do
- Runners page
-
- .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
- #js-build-scroll.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
-
- - if @build.erased?
- .erased.alert.alert-warning
- - erased_by = "by #{link_to @build.erased_by.name, user_path(@build.erased_by)}" if @build.erased_by
- Build has been erased #{erased_by.html_safe} #{time_ago_with_tooltip(@build.erased_at)}
- - else
- %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}%
-
- - if can?(current_user, :read_build, @project) && @build.artifacts?
- .build-widget.artifacts
- %h4.title Build artifacts
- .center
- .btn-group{ role: :group }
- = link_to download_namespace_project_build_artifacts_path(@project.namespace, @project, @build), class: 'btn btn-sm btn-primary' do
- = icon('download')
- Download
-
- - if @build.artifacts_metadata?
- = link_to browse_namespace_project_build_artifacts_path(@project.namespace, @project, @build), class: 'btn btn-sm btn-primary' do
- = icon('folder-open')
- Browse
-
- .build-widget
- %h4.title
- Build ##{@build.id}
- - if can?(current_user, :update_build, @project)
- .center
- .btn-group{ role: :group }
- - if @build.active?
- = link_to "Cancel", cancel_namespace_project_build_path(@project.namespace, @project, @build), class: 'btn btn-sm btn-danger', method: :post
- - elsif @build.retryable?
- = link_to "Retry", retry_namespace_project_build_path(@project.namespace, @project, @build), class: 'btn btn-sm btn-primary', method: :post
-
- - if @build.erasable?
- = link_to erase_namespace_project_build_path(@project.namespace, @project, @build),
- class: 'btn btn-sm btn-warning', method: :post,
- data: { confirm: 'Are you sure you want to erase this build?' } do
- = icon('eraser')
- Erase
-
- .clearfix
- - if @build.duration
- %p
- %span.attr-name Duration:
- #{duration_in_words(@build.finished_at, @build.started_at)}
- %p
- %span.attr-name Created:
- #{time_ago_with_tooltip(@build.created_at)}
- - if @build.finished_at
- %p
- %span.attr-name Finished:
- #{time_ago_with_tooltip(@build.finished_at)}
- - if @build.erased_at
- %p
- %span.attr-name Erased:
- #{time_ago_with_tooltip(@build.erased_at)}
- %p
- %span.attr-name Runner:
- - if @build.runner && current_user && current_user.admin
- = link_to "##{@build.runner.id}", 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
- = link_to @build.commit.short_sha, ci_status_path(@build.commit), class: "monospace"
- %p
- %span.attr-name Branch:
- = link_to @build.ref, namespace_project_commits_path(@project.namespace, @project, @build.ref)
- %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(:id), "other build")} for
- = succeed ":" do
- = link_to @build.commit.short_sha, ci_status_path(@build.commit), class: "monospace"
- %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
-
-
- :javascript
- new CiBuild("#{namespace_project_build_url(@project.namespace, @project, @build)}", "#{@build.status}")
diff --git a/config/routes.rb b/config/routes.rb
index b5d54871cf7..8e6f7c8d8fa 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -653,10 +653,16 @@ Rails.application.routes.draw do
resource :variables, only: [:show, :update]
resources :triggers, only: [:index, :create, :destroy]
- resources :ci_commits, only: [:index, :show]
+ resources :ci_commits, only: [:index, :new, :create] do
+ member do
+ post :cancel
+ post :retry
+ end
+ end
resources :builds, only: [:index, :show], constraints: { id: /\d+/ } do
collection do
+ get :commits
post :cancel_all
end
diff --git a/db/migrate/20160331204039_add_action_to_ci_commit.rb b/db/migrate/20160331204039_add_action_to_ci_commit.rb
new file mode 100644
index 00000000000..e9f8eb624d6
--- /dev/null
+++ b/db/migrate/20160331204039_add_action_to_ci_commit.rb
@@ -0,0 +1,5 @@
+class AddActionToCiCommit < ActiveRecord::Migration
+ def change
+ add_column :ci_commits, :action, :string
+ end
+end