Commit 5d69f5b4 authored by Kamil Trzcinski's avatar Kamil Trzcinski

Use Ci::Commit as Pipeline

parent 986b4a54
...@@ -94,8 +94,8 @@ class Projects::CommitController < Projects::ApplicationController ...@@ -94,8 +94,8 @@ class Projects::CommitController < Projects::ApplicationController
@commit ||= @project.commit(params[:id]) @commit ||= @project.commit(params[:id])
end end
def ci_commit def ci_commits
@ci_commit ||= project.ci_commit(commit.sha) @ci_commits ||= project.ci_commits.where(sha: commit.sha)
end end
def define_show_vars def define_show_vars
...@@ -108,7 +108,8 @@ class Projects::CommitController < Projects::ApplicationController ...@@ -108,7 +108,8 @@ class Projects::CommitController < Projects::ApplicationController
@diff_refs = [commit.parent || commit, commit] @diff_refs = [commit.parent || commit, commit]
@notes_count = commit.notes.count @notes_count = commit.notes.count
@statuses = ci_commit.statuses if ci_commit @statuses = CommitStatus.where(commit: ci_commits)
@builds = Ci::Build.where(commit: ci_commits)
end end
def assign_revert_commit_vars def assign_revert_commit_vars
......
...@@ -118,6 +118,7 @@ class Projects::MergeRequestsController < Projects::ApplicationController ...@@ -118,6 +118,7 @@ class Projects::MergeRequestsController < Projects::ApplicationController
@diffs = @merge_request.compare.diffs(diff_options) if @merge_request.compare @diffs = @merge_request.compare.diffs(diff_options) if @merge_request.compare
@ci_commit = @merge_request.ci_commit @ci_commit = @merge_request.ci_commit
@ci_commits = [@ci_commit].compact
@statuses = @ci_commit.statuses if @ci_commit @statuses = @ci_commit.statuses if @ci_commit
@note_counts = Note.where(commit_id: @commits.map(&:id)). @note_counts = Note.where(commit_id: @commits.map(&:id)).
...@@ -308,6 +309,7 @@ class Projects::MergeRequestsController < Projects::ApplicationController ...@@ -308,6 +309,7 @@ class Projects::MergeRequestsController < Projects::ApplicationController
@merge_request_diff = @merge_request.merge_request_diff @merge_request_diff = @merge_request.merge_request_diff
@ci_commit = @merge_request.ci_commit @ci_commit = @merge_request.ci_commit
@ci_commits = [@ci_commit].compact
@statuses = @ci_commit.statuses if @ci_commit @statuses = @ci_commit.statuses if @ci_commit
if @merge_request.locked_long_ago? if @merge_request.locked_long_ago?
...@@ -318,6 +320,7 @@ class Projects::MergeRequestsController < Projects::ApplicationController ...@@ -318,6 +320,7 @@ class Projects::MergeRequestsController < Projects::ApplicationController
def define_widget_vars def define_widget_vars
@ci_commit = @merge_request.ci_commit @ci_commit = @merge_request.ci_commit
@ci_commits = [@ci_commit].compact
closes_issues closes_issues
end end
......
module CiStatusHelper module CiStatusHelper
def ci_status_path(ci_commit)
project = ci_commit.project
builds_namespace_project_commit_path(project.namespace, project, ci_commit.sha)
end
def ci_status_icon(ci_commit)
ci_icon_for_status(ci_commit.status)
end
def ci_status_label(ci_commit)
ci_label_for_status(ci_commit.status)
end
def ci_status_with_icon(status, target = nil) def ci_status_with_icon(status, target = nil)
content = ci_icon_for_status(status) + '&nbsp;'.html_safe + ci_label_for_status(status) content = ci_icon_for_status(status) + '&nbsp;'.html_safe + ci_label_for_status(status)
klass = "ci-status ci-#{status}" klass = "ci-status ci-#{status}"
...@@ -47,10 +34,10 @@ module CiStatusHelper ...@@ -47,10 +34,10 @@ module CiStatusHelper
end end
def render_ci_status(ci_commit, tooltip_placement: 'auto left') def render_ci_status(ci_commit, tooltip_placement: 'auto left')
link_to ci_status_icon(ci_commit), link_to ci_icon_for_status(ci_commit.status),
ci_status_path(ci_commit), project_ci_commit_path(ci_commit.project, ci_commit),
class: "ci-status-link ci-status-icon-#{ci_commit.status.dasherize}", class: "ci-status-link ci-status-icon-#{ci_commit.status.dasherize}",
title: "Build #{ci_status_label(ci_commit)}", title: "Build #{ci_label_for_status(ci_commit.status)}",
data: { toggle: 'tooltip', placement: tooltip_placement } data: { toggle: 'tooltip', placement: tooltip_placement }
end end
......
...@@ -25,10 +25,22 @@ module GitlabRoutingHelper ...@@ -25,10 +25,22 @@ module GitlabRoutingHelper
namespace_project_commits_path(project.namespace, project, @ref || project.repository.root_ref) namespace_project_commits_path(project.namespace, project, @ref || project.repository.root_ref)
end end
def project_pipelines_path(project, *args)
namespace_project_pipelines_path(project.namespace, project, *args)
end
def project_builds_path(project, *args) def project_builds_path(project, *args)
namespace_project_builds_path(project.namespace, project, *args) namespace_project_builds_path(project.namespace, project, *args)
end end
def project_commit_path(project, commit)
builds_namespace_project_commit_path(project.namespace, project, commit.id)
end
def project_ci_commit_path(project, ci_commit)
builds_namespace_project_commit_path(project.namespace, project, ci_commit.sha)
end
def activity_project_path(project, *args) def activity_project_path(project, *args)
activity_namespace_project_path(project.namespace, project, *args) activity_namespace_project_path(project.namespace, project, *args)
end end
......
...@@ -50,7 +50,6 @@ module Ci ...@@ -50,7 +50,6 @@ module Ci
scope :unstarted, ->() { where(runner_id: nil) } scope :unstarted, ->() { where(runner_id: nil) }
scope :ignore_failures, ->() { where(allow_failure: false) } scope :ignore_failures, ->() { where(allow_failure: false) }
scope :similar, ->(build) { where(ref: build.ref, tag: build.tag, trigger_request_id: build.trigger_request_id) }
mount_uploader :artifacts_file, ArtifactUploader mount_uploader :artifacts_file, ArtifactUploader
mount_uploader :artifacts_metadata, ArtifactUploader mount_uploader :artifacts_metadata, ArtifactUploader
...@@ -62,6 +61,8 @@ module Ci ...@@ -62,6 +61,8 @@ module Ci
before_destroy { project } before_destroy { project }
after_create :execute_hooks
class << self class << self
def columns_without_lazy def columns_without_lazy
(column_names - LAZY_ATTRIBUTES).map do |column_name| (column_names - LAZY_ATTRIBUTES).map do |column_name|
...@@ -126,12 +127,16 @@ module Ci ...@@ -126,12 +127,16 @@ module Ci
end end
def retried? def retried?
!self.commit.latest_statuses_for_ref(self.ref).include?(self) !self.commit.latest.include?(self)
end
def retry
Ci::Build.retry(self)
end end
def depends_on_builds def depends_on_builds
# Get builds of the same type # Get builds of the same type
latest_builds = self.commit.builds.similar(self).latest latest_builds = self.commit.builds.latest
# Return builds from previous stages # Return builds from previous stages
latest_builds.where('stage_idx < ?', stage_idx) latest_builds.where('stage_idx < ?', stage_idx)
......
...@@ -19,6 +19,7 @@ ...@@ -19,6 +19,7 @@
module Ci module Ci
class Commit < ActiveRecord::Base class Commit < ActiveRecord::Base
extend Ci::Model extend Ci::Model
include CiStatus
belongs_to :project, class_name: '::Project', foreign_key: :gl_project_id belongs_to :project, class_name: '::Project', foreign_key: :gl_project_id
has_many :statuses, class_name: 'CommitStatus' has_many :statuses, class_name: 'CommitStatus'
...@@ -28,12 +29,18 @@ module Ci ...@@ -28,12 +29,18 @@ module Ci
validates_presence_of :sha validates_presence_of :sha
validate :valid_commit_sha validate :valid_commit_sha
# Make sure that status is saved
before_save :status
before_save :started_at
before_save :finished_at
before_save :duration
def self.truncate_sha(sha) def self.truncate_sha(sha)
sha[0...8] sha[0...8]
end end
def to_param def stages
sha statuses.group(:stage).order(:stage_idx).pluck(:stage)
end end
def project_id def project_id
...@@ -68,15 +75,26 @@ module Ci ...@@ -68,15 +75,26 @@ module Ci
nil nil
end end
def stage def branch?
running_or_pending = statuses.latest.running_or_pending.ordered !tag?
running_or_pending.first.try(:stage) end
def retryable?
builds.latest.any? do |build|
build.failed? || build.retryable?
end
end
def invalidate
status = nil
started_at = nil
finished_at = nil
end end
def create_builds(ref, tag, user, trigger_request = nil) def create_builds(user, trigger_request = nil)
return unless config_processor return unless config_processor
config_processor.stages.any? do |stage| config_processor.stages.any? do |stage|
CreateBuildsService.new.execute(self, stage, ref, tag, user, trigger_request, 'success').present? CreateBuildsService.new(self).execute(stage, user, 'success', trigger_request).present?
end end
end end
...@@ -84,7 +102,7 @@ module Ci ...@@ -84,7 +102,7 @@ module Ci
return unless config_processor return unless config_processor
# don't create other builds if this one is retried # don't create other builds if this one is retried
latest_builds = builds.similar(build).latest latest_builds = builds.latest
return unless latest_builds.exists?(build.id) return unless latest_builds.exists?(build.id)
# get list of stages after this build # get list of stages after this build
...@@ -97,26 +115,12 @@ module Ci ...@@ -97,26 +115,12 @@ module Ci
# create builds for next stages based # create builds for next stages based
next_stages.any? do |stage| next_stages.any? do |stage|
CreateBuildsService.new.execute(self, stage, build.ref, build.tag, build.user, build.trigger_request, status).present? CreateBuildsService.new(self).execute(stage, build.user, status, build.trigger_request).present?
end end
end end
def refs def latest
statuses.order(:ref).pluck(:ref).uniq statuses.latest
end
def latest_statuses
@latest_statuses ||= statuses.latest.to_a
end
def latest_statuses_for_ref(ref)
latest_statuses.select { |status| status.ref == ref }
end
def matrix_builds(build = nil)
matrix_builds = builds.latest.ordered
matrix_builds = matrix_builds.similar(build) if build
matrix_builds.to_a
end end
def retried def retried
...@@ -124,56 +128,23 @@ module Ci ...@@ -124,56 +128,23 @@ module Ci
end end
def status def status
if yaml_errors.present? read_attribute(:status) || update_status
return 'failed'
end
@status ||= Ci::Status.get_status(latest_statuses)
end
def pending?
status == 'pending'
end
def running?
status == 'running'
end
def success?
status == 'success'
end
def failed?
status == 'failed'
end
def canceled?
status == 'canceled'
end
def active?
running? || pending?
end
def complete?
canceled? || success? || failed?
end end
def duration def duration
duration_array = statuses.map(&:duration).compact read_attribute(:duration) || update_duration
duration_array.reduce(:+).to_i
end end
def started_at def started_at
@started_at ||= statuses.order('started_at ASC').first.try(:started_at) read_attribute(:started_at) || update_started_at
end end
def finished_at def finished_at
@finished_at ||= statuses.order('finished_at DESC').first.try(:finished_at) read_attribute(:finished_at) || update_finished_at
end end
def coverage def coverage
coverage_array = latest_statuses.map(&:coverage).compact coverage_array = latest.map(&:coverage).compact
if coverage_array.size >= 1 if coverage_array.size >= 1
'%.2f' % (coverage_array.reduce(:+) / coverage_array.size) '%.2f' % (coverage_array.reduce(:+) / coverage_array.size)
end end
...@@ -191,6 +162,7 @@ module Ci ...@@ -191,6 +162,7 @@ module Ci
end end
def ci_yaml_file def ci_yaml_file
return nil if defined?(@ci_yaml_file)
@ci_yaml_file ||= begin @ci_yaml_file ||= begin
blob = project.repository.blob_at(sha, '.gitlab-ci.yml') blob = project.repository.blob_at(sha, '.gitlab-ci.yml')
blob.load_all_data!(project.repository) blob.load_all_data!(project.repository)
...@@ -206,6 +178,32 @@ module Ci ...@@ -206,6 +178,32 @@ module Ci
private private
def update_status
status =
if yaml_errors.present?
'failed'
else
latest.status
end
end
def update_started_at
started_at =
statuses.order(:id).first.try(:started_at)
end
def update_finished_at
finished_at =
statuses.order(id: :desc).first.try(:finished_at)
end
def update_duration
duration = begin
duration_array = latest.map(&:duration).compact
duration_array.reduce(:+).to_i
end
end
def save_yaml_error(error) def save_yaml_error(error)
return if self.yaml_errors? return if self.yaml_errors?
self.yaml_errors = error self.yaml_errors = error
......
...@@ -209,12 +209,13 @@ class Commit ...@@ -209,12 +209,13 @@ class Commit
@raw.short_id(7) @raw.short_id(7)
end end
def ci_commit def ci_commits
project.ci_commit(sha) @ci_commits ||= project.ci_commits.where(sha: sha)
end end
def status def status
ci_commit.try(:status) || :not_found return @status if defined?(@status)
@status ||= ci_commits.status
end end
def revert_branch_name def revert_branch_name
......
...@@ -33,6 +33,8 @@ ...@@ -33,6 +33,8 @@
# #
class CommitStatus < ActiveRecord::Base class CommitStatus < ActiveRecord::Base
include CiStatus
self.table_name = 'ci_builds' self.table_name = 'ci_builds'
belongs_to :project, class_name: '::Project', foreign_key: :gl_project_id belongs_to :project, class_name: '::Project', foreign_key: :gl_project_id
...@@ -40,21 +42,13 @@ class CommitStatus < ActiveRecord::Base ...@@ -40,21 +42,13 @@ class CommitStatus < ActiveRecord::Base
belongs_to :user belongs_to :user
validates :commit, presence: true validates :commit, presence: true
validates :status, inclusion: { in: %w(pending running failed success canceled) }
validates_presence_of :name validates_presence_of :name
alias_attribute :author, :user alias_attribute :author, :user
scope :running, -> { where(status: 'running') } scope :latest, -> { where(id: unscope(:select).select('max(id)').group(:name)) }
scope :pending, -> { where(status: 'pending') }
scope :success, -> { where(status: 'success') }
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 :ordered, -> { order(:ref, :stage_idx, :name) } scope :ordered, -> { order(:ref, :stage_idx, :name) }
scope :for_ref, ->(ref) { where(ref: ref) }
AVAILABLE_STATUSES = ['pending', 'running', 'success', 'failed', 'canceled'] AVAILABLE_STATUSES = ['pending', 'running', 'success', 'failed', 'canceled']
...@@ -87,31 +81,13 @@ class CommitStatus < ActiveRecord::Base ...@@ -87,31 +81,13 @@ class CommitStatus < ActiveRecord::Base
MergeRequests::MergeWhenBuildSucceedsService.new(commit_status.commit.project, nil).trigger(commit_status) MergeRequests::MergeWhenBuildSucceedsService.new(commit_status.commit.project, nil).trigger(commit_status)
end end
state :pending, value: 'pending' after_transition any => any do |commit_status|
state :running, value: 'running' commit_status.commit.invalidate
state :failed, value: 'failed' commit_status.save
state :success, value: 'success' end
state :canceled, value: 'canceled'
end
delegate :sha, :short_sha, to: :commit, prefix: false
# TODO: this should be removed with all references
def before_sha
Gitlab::Git::BLANK_SHA
end
def started?
!pending? && !canceled? && started_at
end
def active?
running? || pending?
end end
def complete? delegate :before_sha, :sha, :short_sha, to: :commit, prefix: false
canceled? || success? || failed?
end
def ignored? def ignored?
allow_failure? && (failed? || canceled?) allow_failure? && (failed? || canceled?)
......
module CiStatus
extend ActiveSupport::Concern
module ClassMethods
def status
objs = all.to_a
if objs.none?
nil
elsif objs.all? { |status| status.success? || status.try(:ignored?) }
'success'
elsif objs.all?(&:pending?)
'pending'
elsif objs.any?(&:running?) || all.any?(&:pending?)
'running'
elsif objs.all?(&:canceled?)
'canceled'
else
'failed'
end
end
def duration
duration_array = all.map(&:duration).compact
duration_array.reduce(:+).to_i
end
end
included do
validates :status, inclusion: { in: %w(pending running failed success canceled) }
state_machine :status, initial: :pending do
state :pending, value: 'pending'
state :running, value: 'running'
state :failed, value: 'failed'
state :success, value: 'success'
state :canceled, value: 'canceled'
end
scope :running, -> { where(status: 'running') }
scope :pending, -> { where(status: 'pending') }
scope :success, -> { where(status: 'success') }
scope :failed, -> { where(status: 'failed') }
scope :running_or_pending, -> { where(status: [:running, :pending]) }
scope :finished, -> { where(status: [:success, :failed, :canceled]) }
end
def started?
!pending? && !canceled? && started_at
end
def active?
running? || pending?
end
def complete?
canceled? || success? || failed?
end
end
\ No newline at end of file
...@@ -589,7 +589,7 @@ class MergeRequest < ActiveRecord::Base ...@@ -589,7 +589,7 @@ class MergeRequest < ActiveRecord::Base
end end
def ci_commit def ci_commit
@ci_commit ||= source_project.ci_commit(last_commit.id) if last_commit && source_project @ci_commit ||= source_project.ci_commit(last_commit.id, source_branch) if last_commit && source_project
end end
def diff_refs def diff_refs
......
...@@ -919,12 +919,12 @@ class Project < ActiveRecord::Base ...@@ -919,12 +919,12 @@ class Project < ActiveRecord::Base
!namespace.share_with_group_lock !namespace.share_with_group_lock
end end
def ci_commit(sha) def ci_commit(sha, ref)
ci_commits.find_by(sha: sha) ci_commits.find_by(sha: sha, ref: ref)
end end
def ensure_ci_commit(sha) def ensure_ci_commit(sha, ref)
ci_commit(sha) || ci_commits.create(sha: sha) ci_commit(sha, ref) || ci_commits.create(sha: sha, ref: ref)
end end
def enable_ci def enable_ci
......
module Ci module Ci
class CreateBuildsService class CreateBuildsService
def execute(commit, stage, ref, tag, user, trigger_request, status) def initialize(commit)
builds_attrs = commit.config_processor.builds_for_stage_and_ref(stage, ref, tag, trigger_request) @commit = commit
end
def execute(stage, user, status, trigger_request = nil)
builds_attrs = config_processor.builds_for_stage_and_ref(stage, @commit.ref, @commit.tag, trigger_request)
# check when to create next build # check when to create next build
builds_attrs = builds_attrs.select do |build_attrs| builds_attrs = builds_attrs.select do |build_attrs|
...@@ -17,7 +21,8 @@ module Ci ...@@ -17,7 +21,8 @@ module Ci
builds_attrs.map do |build_attrs| builds_attrs.map do |build_attrs|
# don't create the same build twice # don't create the same build twice
unless commit.builds.find_by(ref: ref, tag: tag, trigger_request: trigger_request, name: build_attrs[:name]) unless commit.builds.find_by(ref: @commit.ref, tag: @commit.tag,
trigger_request: trigger_request, name: build_attrs[:name])
build_attrs.slice!(:name, build_attrs.slice!(:name,
:commands, :commands,
:tag_list, :tag_list,
...@@ -26,17 +31,21 @@ module Ci ...@@ -26,17 +31,21 @@ module Ci
:stage, :stage,
:stage_idx) :stage_idx)
build_attrs.merge!(ref: ref, build_attrs.merge!(ref: @commit.ref,
tag: tag, tag: @commit.tag,
trigger_request: trigger_request, trigger_request: trigger_request,
user: user, user: user,
project: commit.project) project: @commit.project)
build = commit.builds.create!(build_attrs) @commit.builds.create!(build_attrs)
build.execute_hooks
build
end end
end end
end end
private
def config_processor
@config_processor ||= @commit.config_processor
end
end end
end end
...@@ -7,7 +7,7 @@ module Ci ...@@ -7,7 +7,7 @@ module Ci
# check if ref is tag # check if ref is tag
tag = project.repository.find_tag(ref).present? tag = project.repository.find_tag(ref).present?
ci_commit = project.ensure_ci_commit(commit.sha) ci_commit = project.ci_commits.create(commit.sha, ref)
trigger_request = trigger.trigger_requests.create!( trigger_request = trigger.trigger_requests.create!(
variables: variables, variables: variables,
......
...@@ -2,6 +2,7 @@ class CreateCommitBuildsService ...@@ -2,6 +2,7 @@ class CreateCommitBuildsService
def execute(project, user, params) def execute(project, user, params)
return false unless project.builds_enabled? return false unless project.builds_enabled?
before_sha = params[:checkout_sha] || params[:before]
sha = params[:checkout_sha] || params[:after] sha = params[:checkout_sha] || params[:after]
origin_ref = params[:ref] origin_ref = params[:ref]
...@@ -10,15 +11,16 @@ class CreateCommitBuildsService ...@@ -10,15 +11,16 @@ class CreateCommitBuildsService
end end
ref = Gitlab::Git.ref_name(origin_ref) ref = Gitlab::Git.ref_name(origin_ref)
tag = Gitlab::Git.tag_ref?(origin_ref)
# Skip branch removal # Skip branch removal
if sha == Gitlab::Git::BLANK_SHA if sha == Gitlab::Git::BLANK_SHA
return false return false
end end
commit = project.ci_commit(sha) commit = project.ci_commit(sha, ref)
unless commit unless commit
commit = project.ci_commits.new(sha: sha) commit = project.ci_commits.new(sha: sha, ref: ref, before_sha: before_sha, tag: tag)
# Skip creating ci_commit when no gitlab-ci.yml is found # Skip creating ci_commit when no gitlab-ci.yml is found
unless commit.ci_yaml_file unless commit.ci_yaml_file
...@@ -32,8 +34,7 @@ class CreateCommitBuildsService ...@@ -32,8 +34,7 @@ class CreateCommitBuildsService
# Skip creating builds for commits that have [ci skip] # Skip creating builds for commits that have [ci skip]
unless commit.skip_ci? unless commit.skip_ci?
# Create builds for commit # Create builds for commit
tag = Gitlab::Git.tag_ref?(origin_ref) commit.create_builds(user)
commit.create_builds(ref, tag, user)
end end
commit commit
......
...@@ -117,7 +117,7 @@ ...@@ -117,7 +117,7 @@
%td.build-link %td.build-link
- if project - if project
= link_to ci_status_path(build.commit) do = link_to builds_namespace_project_commit_path(project.namespace, project, build.sha) do
%strong #{build.commit.short_sha} %strong #{build.commit.short_sha}
%td.timestamp %td.timestamp
......
.project-last-commit .project-last-commit
- ci_commit = project.ci_commit(commit.sha) - if commit.status
- if ci_commit = link_to project_commit_path(commit.project, commit), class: "ci-status ci-#{commit.status}" do
= link_to ci_status_path(ci_commit), class: "ci-status ci-#{ci_commit.status}" do = ci_icon_for_status(commit.status)
= ci_status_icon(ci_commit) = ci_label_for_status(commit.status)
= ci_status_label(ci_commit)
= link_to commit.short_id, namespace_project_commit_path(project.namespace, project, commit), class: "commit_short_id" = link_to commit.short_id, namespace_project_commit_path(project.namespace, project, commit), class: "commit_short_id"
= link_to_gfm commit.title, namespace_project_commit_path(project.namespace, project, commit), class: "commit-row-message" = link_to_gfm commit.title, namespace_project_commit_path(project.namespace, project, commit), class: "commit-row-message"
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
.build-page .build-page
.gray-content-block.top-block .gray-content-block.top-block
Build ##{@build.id} for commit Build ##{@build.id} for commit
%strong.monospace= link_to @build.commit.short_sha, ci_status_path(@build.commit) %strong.monospace= link_to @build.commit.short_sha, builds_namespace_project_commit_path(@project.namespace, @project, @build.sha)
from from
= link_to @build.ref, namespace_project_commits_path(@project.namespace, @project, @build.ref) = link_to @build.ref, namespace_project_commits_path(@project.namespace, @project, @build.ref)
- merge_request = @build.merge_request - merge_request = @build.merge_request
...@@ -13,7 +13,7 @@ ...@@ -13,7 +13,7 @@
= link_to "merge request ##{merge_request.iid}", merge_request_path(merge_request) = link_to "merge request ##{merge_request.iid}", merge_request_path(merge_request)
#up-build-trace #up-build-trace
- builds = @build.commit.matrix_builds(@build) - builds = @build.commit.builds.latest.to_a
- if builds.size > 1 - if builds.size > 1
%ul.nav-links.no-top.no-bottom %ul.nav-links.no-top.no-bottom
- builds.each do |build| - builds.each do |build|
...@@ -173,7 +173,7 @@ ...@@ -173,7 +173,7 @@
Commit Commit
.pull-right .pull-right
%small %small
= link_to @build.commit.short_sha, ci_status_path(@build.commit), class: "monospace" = link_to @build.commit.short_sha, builds_namespace_project_commit_path(@project.namespace, @project, @build.sha), class: "monospace"
%p %p
%span.attr-name Branch: %span.attr-name Branch:
= link_to @build.ref, namespace_project_commits_path(@project.namespace, @project, @build.ref) = link_to @build.ref, namespace_project_commits_path(@project.namespace, @project, @build.ref)
...@@ -196,7 +196,7 @@ ...@@ -196,7 +196,7 @@
.build-widget .build-widget
%h4.title #{pluralize(@builds.count(:id), "other build")} for %h4.title #{pluralize(@builds.count(:id), "other build")} for
= succeed ":" do = succeed ":" do
= link_to @build.commit.short_sha, ci_status_path(@build.commit), class: "monospace" = link_to @build.commit.short_sha, builds_namespace_project_commit_path(@project.namespace, @project, build.sha), class: "monospace"
%table.table.builds %table.table.builds
- @builds.each_with_index do |build, i| - @builds.each_with_index do |build, i|
%tr.build %tr.build
......
...@@ -19,11 +19,12 @@ ...@@ -19,11 +19,12 @@
%td %td
= link_to build.short_sha, namespace_project_commit_path(build.project.namespace, build.project, build.sha), class: "monospace" = link_to build.short_sha, namespace_project_commit_path(build.project.namespace, build.project, build.sha), class: "monospace"
%td - if !defined?(ref) || ref
- if build.ref %td
= link_to build.ref, namespace_project_commits_path(build.project.namespace, build.project, build.ref) - if build.ref
- else = link_to build.ref, namespace_project_commits_path(build.project.namespace, build.project, build.ref)
.light none - else
.light none
- if defined?(runner) && runner - if defined?(runner) && runner
%td %td
...@@ -48,6 +49,8 @@ ...@@ -48,6 +49,8 @@
%span.label.label-info triggered %span.label.label-info triggered
- if build.try(:allow_failure) - if build.try(:allow_failure)
%span.label.label-danger allowed to fail %span.label.label-danger allowed to fail
- if defined?(retried) && retried
%span.label.label-warning retried
%td.duration %td.duration
- if build.duration - if build.duration
......
.gray-content-block.middle-block - @ci_commits.each do |ci_commit|
.pull-right = render "ci_commit", ci_commit: ci_commit
- if can?(current_user, :update_build, @ci_commit.project)
- if @ci_commit.builds.latest.failed.any?(&:retryable?)
= link_to "Retry failed", retry_builds_namespace_project_commit_path(@ci_commit.project.namespace, @ci_commit.project, @ci_commit.sha), class: 'btn btn-grouped btn-primary', method: :post
- if @ci_commit.builds.running_or_pending.any?
= link_to "Cancel running", cancel_builds_namespace_project_commit_path(@ci_commit.project.namespace, @ci_commit.project, @ci_commit.sha), data: { confirm: 'Are you sure?' }, class: 'btn btn-grouped btn-danger', method: :post
.oneline
= pluralize @statuses.count(:id), "build"
- if defined?(link_to_commit) && link_to_commit
for commit
= link_to @ci_commit.short_sha, namespace_project_commit_path(@ci_commit.project.namespace, @ci_commit.project, @ci_commit.sha), class: "monospace"
- if @ci_commit.duration > 0
in
= time_interval_in_words @ci_commit.duration
- if @ci_commit.yaml_errors.present?
.bs-callout.bs-callout-danger
%h4 Found errors in your .gitlab-ci.yml:
%ul
- @ci_commit.yaml_errors.split(",").each do |error|
%li= error
You can also test your .gitlab-ci.yml in the #{link_to "Lint", ci_lint_path}
- if @ci_commit.project.builds_enabled? && !@ci_commit.ci_yaml_file
.bs-callout.bs-callout-warning
\.gitlab-ci.yml not found in this commit
.table-holder
%table.table.builds
%thead
%tr
%th Status
%th Build ID
%th Ref
%th Stage
%th Name
%th Duration
%th Finished at
- if @ci_commit.project.build_coverage_enabled?
%th Coverage
%th
- @ci_commit.refs.each do |ref|
- builds = @ci_commit.statuses.for_ref(ref).latest.ordered
= render builds, coverage: @ci_commit.project.build_coverage_enabled?, stage: true, allow_retry: true
- if @ci_commit.retried.any?
.gray-content-block.second-block
Retried builds
.table-holder
%table.table.builds
%thead
%tr
%th Status
%th Build ID
%th Ref
%th Stage
%th Name
%th Duration
%th Finished at
- if @ci_commit.project.build_coverage_enabled?
%th Coverage
%th
= render @ci_commit.retried, coverage: @ci_commit.project.build_coverage_enabled?, stage: true
.gray-content-block.middle-block
.pull-right
- if can?(current_user, :update_build, @project)
- if ci_commit.builds.latest.failed.any?(&:retryable?)
= link_to "Retry failed", retry_builds_namespace_project_commit_path(@project.namespace, @project, @commit.id), class: 'btn btn-grouped btn-primary', method: :post
- if ci_commit.builds.running_or_pending.any?
= link_to "Cancel running", cancel_builds_namespace_project_commit_path(@project.namespace, @project, @commit.id), data: { confirm: 'Are you sure?' }, class: 'btn btn-grouped btn-danger', method: :post
.oneline
= pluralize ci_commit.statuses.count(:id), "build"
- if ci_commit.ref
for
%span.label.label-info
= ci_commit.ref
- if defined?(link_to_commit) && link_to_commit
for commit
= link_to @commit.short_id, namespace_project_commit_path(@project.namespace, @project, @commit.id), class: "monospace"
- if ci_commit.duration > 0
in
= time_interval_in_words ci_commit.duration
- if ci_commit.yaml_errors.present?
.bs-callout.bs-callout-danger
%h4 Found errors in your .gitlab-ci.yml:
%ul
- ci_commit.yaml_errors.split(",").each do |error|
%li= error
You can also test your .gitlab-ci.yml in the #{link_to "Lint", ci_lint_path}
- if @project.builds_enabled? && !ci_commit.ci_yaml_file
.bs-callout.bs-callout-warning
\.gitlab-ci.yml not found in this commit
.table-holder
%table.table.builds
%thead
%tr
%th Status
%th Build ID
%th Stage
%th Name
%th Duration
%th Finished at
- if @project.build_coverage_enabled?
%th Coverage
%th
- builds = ci_commit.statuses.latest.ordered
= render builds, coverage: @project.build_coverage_enabled?, stage: true, ref: false, allow_retry: true
- if ci_commit.retried.any?
.gray-content-block.second-block
Retried builds
.table-holder
%table.table.builds
%thead
%tr
%th Status
%th Build ID
%th Ref
%th Stage
%th Name
%th Duration
%th Finished at
- if @project.build_coverage_enabled?
%th Coverage
%th
= render ci_commit.retried, coverage: @project.build_coverage_enabled?, stage: true, ref: false
...@@ -42,12 +42,12 @@ ...@@ -42,12 +42,12 @@
- @commit.parents.each do |parent| - @commit.parents.each do |parent|
= link_to parent.short_id, namespace_project_commit_path(@project.namespace, @project, parent), class: "monospace" = link_to parent.short_id, namespace_project_commit_path(@project.namespace, @project, parent), class: "monospace"
- if @ci_commit - if @commit.status
.pull-right .pull-right
= link_to ci_status_path(@ci_commit), class: "ci-status ci-#{@ci_commit.status}" do = link_to builds_namespace_project_commit_path(@project.namespace, @project, @commit.id), class: "ci-status ci-#{@commit.status}" do
= ci_status_icon(@ci_commit) = ci_icon_for_status(@commit.status)
build: build:
= ci_status_label(@ci_commit) = ci_label_for_status(@commit.status)
.commit-info-row.branches .commit-info-row.branches
%i.fa.fa-spinner.fa-spin %i.fa.fa-spinner.fa-spin
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
.prepend-top-default .prepend-top-default
= render "commit_box" = render "commit_box"
- if @ci_commit - if @commit.status
= render "ci_menu" = render "ci_menu"
- else - else
%div.block-connector %div.block-connector
......
...@@ -4,9 +4,8 @@ ...@@ -4,9 +4,8 @@
- notes = commit.notes - notes = commit.notes
- note_count = notes.user.count - note_count = notes.user.count
- ci_commit = project.ci_commit(commit.sha)
- cache_key = [project.path_with_namespace, commit.id, current_application_settings, note_count] - cache_key = [project.path_with_namespace, commit.id, current_application_settings, note_count]
- cache_key.push(ci_commit.status) if ci_commit - cache_key.push(commit.status) if commit.status
= cache(cache_key) do = cache(cache_key) do
%li.commit.js-toggle-container{ id: "commit-#{commit.short_id}" } %li.commit.js-toggle-container{ id: "commit-#{commit.short_id}" }
...@@ -17,8 +16,8 @@ ...@@ -17,8 +16,8 @@
%a.text-expander.js-toggle-button ... %a.text-expander.js-toggle-button ...
.pull-right .pull-right
- if ci_commit - if commit.status
= render_ci_status(ci_commit) = render_ci_status(commit)
&nbsp; &nbsp;
= clipboard_button(clipboard_text: commit.id) = clipboard_button(clipboard_text: commit.id)
= link_to commit.short_id, namespace_project_commit_path(project.namespace, project, commit), class: "commit_short_id" = link_to commit.short_id, namespace_project_commit_path(project.namespace, project, commit), class: "commit_short_id"
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
- @related_branches.each do |branch| - @related_branches.each do |branch|
%li %li
- sha = @project.repository.find_branch(branch).target - sha = @project.repository.find_branch(branch).target
- ci_commit = @project.ci_commit(sha) if sha - ci_commit = @project.ci_commit(sha, branch) if sha
- if ci_commit - if ci_commit
%span.related-branch-ci-status %span.related-branch-ci-status
= render_ci_status(ci_commit) = render_ci_status(ci_commit)
......
...@@ -6,9 +6,8 @@ ...@@ -6,9 +6,8 @@
- css_class = '' unless local_assigns[:css_class] - css_class = '' unless local_assigns[:css_class]
- show_last_commit_as_description = false unless local_assigns[:show_last_commit_as_description] == true && project.commit - show_last_commit_as_description = false unless local_assigns[:show_last_commit_as_description] == true && project.commit
- css_class += " no-description" if project.description.blank? && !show_last_commit_as_description - css_class += " no-description" if project.description.blank? && !show_last_commit_as_description
- ci_commit = project.ci_commit(project.commit.sha) if ci && !project.empty_repo? && project.commit
- cache_key = [project.namespace, project, controller.controller_name, controller.action_name, current_application_settings, 'v2.3'] - cache_key = [project.namespace, project, controller.controller_name, controller.action_name, current_application_settings, 'v2.3']
- cache_key.push(ci_commit.status) if ci_commit - cache_key.push(project.commit.status) if project.commit.status
%li.project-row{ class: css_class } %li.project-row{ class: css_class }
= cache(cache_key) do = cache(cache_key) do
...@@ -16,9 +15,9 @@ ...@@ -16,9 +15,9 @@
- if project.main_language - if project.main_language
%span %span
= project.main_language = project.main_language
- if ci_commit - if project.commit.status
%span %span
= render_ci_status(ci_commit) = render_ci_status(project.commit)
- if forks - if forks
%span %span
= icon('code-fork') = icon('code-fork')
......
class AddFieldsToCiCommit < ActiveRecord::Migration
def change
add_column :ci_commits, :status, :string
add_column :ci_commits, :started_at, :timestamp
add_column :ci_commits, :finished_at, :timestamp
end
end
class AddActionToCiCommit < ActiveRecord::Migration
def change
add_column :ci_commits, :action, :string
end
end
class AddDurationToCiCommit < ActiveRecord::Migration
def change
add_column :ci_commits, :duration, :integer
end
end
...@@ -11,7 +11,7 @@ ...@@ -11,7 +11,7 @@
# #
# It's strongly recommended that you check this file into your version control system. # It's strongly recommended that you check this file into your version control system.
ActiveRecord::Schema.define(version: 20160331223143) do ActiveRecord::Schema.define(version: 20160411122626) do
# These are extensions that must be enabled in order to support this database # These are extensions that must be enabled in order to support this database
enable_extension "plpgsql" enable_extension "plpgsql"
...@@ -141,6 +141,7 @@ ActiveRecord::Schema.define(version: 20160331223143) do ...@@ -141,6 +141,7 @@ ActiveRecord::Schema.define(version: 20160331223143) do
t.text "artifacts_metadata" t.text "artifacts_metadata"
t.integer "erased_by_id" t.integer "erased_by_id"
t.datetime "erased_at" t.datetime "erased_at"
t.string "plugin"
end end
add_index "ci_builds", ["commit_id", "stage_idx", "created_at"], name: "index_ci_builds_on_commit_id_and_stage_idx_and_created_at", using: :btree add_index "ci_builds", ["commit_id", "stage_idx", "created_at"], name: "index_ci_builds_on_commit_id_and_stage_idx_and_created_at", using: :btree
...@@ -168,6 +169,11 @@ ActiveRecord::Schema.define(version: 20160331223143) do ...@@ -168,6 +169,11 @@ ActiveRecord::Schema.define(version: 20160331223143) do
t.text "yaml_errors" t.text "yaml_errors"
t.datetime "committed_at" t.datetime "committed_at"
t.integer "gl_project_id" t.integer "gl_project_id"
t.string "status"
t.datetime "started_at"
t.datetime "finished_at"
t.string "action"
t.integer "duration"
end end
add_index "ci_commits", ["gl_project_id"], name: "index_ci_commits_on_gl_project_id", using: :btree add_index "ci_commits", ["gl_project_id"], name: "index_ci_commits_on_gl_project_id", using: :btree
...@@ -306,11 +312,20 @@ ActiveRecord::Schema.define(version: 20160331223143) do ...@@ -306,11 +312,20 @@ ActiveRecord::Schema.define(version: 20160331223143) do
add_index "ci_tags", ["name"], name: "index_ci_tags_on_name", unique: true, using: :btree add_index "ci_tags", ["name"], name: "index_ci_tags_on_name", unique: true, using: :btree
create_table "ci_trigger_requests", force: :cascade do |t| create_table "ci_trigger_requests", force: :cascade do |t|
t.integer "trigger_id", null: false t.integer "trigger_id"
t.text "variables" t.text "variables"
t.datetime "created_at" t.datetime "created_at"
t.datetime "updated_at" t.datetime "updated_at"
t.integer "commit_id" t.integer "commit_id"
t.string "sha"
t.string "before_sha"
t.string "ref"
t.string "action"
t.string "status"
t.datetime "started_at"
t.datetime "finished_at"
t.integer "project_id"
t.string "origin_ref"
end end
create_table "ci_triggers", force: :cascade do |t| create_table "ci_triggers", force: :cascade do |t|
...@@ -731,6 +746,7 @@ ActiveRecord::Schema.define(version: 20160331223143) do ...@@ -731,6 +746,7 @@ ActiveRecord::Schema.define(version: 20160331223143) do
t.boolean "public_builds", default: true, null: false t.boolean "public_builds", default: true, null: false
t.string "main_language" t.string "main_language"
t.integer "pushes_since_gc", default: 0 t.integer "pushes_since_gc", default: 0
t.boolean "images_enabled"
end end
add_index "projects", ["builds_enabled", "shared_runners_enabled"], name: "index_projects_on_builds_enabled_and_shared_runners_enabled", using: :btree add_index "projects", ["builds_enabled", "shared_runners_enabled"], name: "index_projects_on_builds_enabled_and_shared_runners_enabled", using: :btree
......
...@@ -21,7 +21,7 @@ module API ...@@ -21,7 +21,7 @@ module API
authorize!(:read_commit_status, user_project) authorize!(:read_commit_status, user_project)
not_found!('Commit') unless user_project.commit(params[:sha]) not_found!('Commit') unless user_project.commit(params[:sha])
ci_commit = user_project.ci_commit(params[:sha]) ci_commit = user_project.ci_commit(params[:sha], params[:ref])
return [] unless ci_commit return [] unless ci_commit
statuses = ci_commit.statuses statuses = ci_commit.statuses
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment