diff --git a/app/models/ci/commit.rb b/app/models/ci/commit.rb index 623ff619c49..201b6f62b86 100644 --- a/app/models/ci/commit.rb +++ b/app/models/ci/commit.rb @@ -106,50 +106,47 @@ module Ci end def refs - statuses.pluck(:ref).compact.uniq + statuses.order(:ref).pluck(:ref).uniq end - def statuses_for_ref(ref = nil) - if ref - statuses.for_ref(ref) - else - statuses - end + def latest_statuses + @latest_statuses ||= statuses.latest.to_a end - def builds_without_retry(ref = nil) - if ref - builds.for_ref(ref).latest - else - builds.latest - end + def builds_without_retry + @builds_without_retry ||= builds.latest.to_a + end + + def builds_without_retry_for_ref(ref) + builds_without_retry.select { |build| build.ref == ref } end def retried @retried ||= (statuses.order(id: :desc) - statuses.latest) end - def status(ref = nil) + def status if yaml_errors.present? return 'failed' end - latest_statuses = statuses.latest.to_a - latest_statuses.reject! { |status| status.try(&:allow_failure?) } - latest_statuses.select! { |status| status.ref.nil? || status.ref == ref } if ref + @status ||= begin + latest = latest_statuses + latest.reject! { |status| status.try(&:allow_failure?) } - if latest_statuses.none? - return 'skipped' - elsif latest_statuses.all?(&:success?) - 'success' - elsif latest_statuses.all?(&:pending?) - 'pending' - elsif latest_statuses.any?(&:running?) || latest_statuses.any?(&:pending?) - 'running' - elsif latest_statuses.all?(&:canceled?) - 'canceled' - else - 'failed' + if latest.none? + 'skipped' + elsif latest.all?(&:success?) + 'success' + elsif latest.all?(&:pending?) + 'pending' + elsif latest.any?(&:running?) || latest.any?(&:pending?) + 'running' + elsif latest.all?(&:canceled?) + 'canceled' + else + 'failed' + end end end @@ -173,8 +170,9 @@ module Ci status == 'canceled' end - def duration(ref = nil) - statuses_for_ref(ref).latest.select(&:duration).sum(&:duration).to_i + def duration + duration_array = latest_statuses.map(&:duration).compact + duration_array.reduce(:+).to_i end def finished_at @@ -190,8 +188,8 @@ module Ci end end - def matrix?(ref) - builds_without_retry(ref).pluck(:id).size > 1 + def matrix_for_ref?(ref) + builds_without_retry_for_ref(ref).size > 1 end def config_processor diff --git a/app/models/commit_status.rb b/app/models/commit_status.rb index b6234c896e3..b4d91b1b0c3 100644 --- a/app/models/commit_status.rb +++ b/app/models/commit_status.rb @@ -16,8 +16,9 @@ class CommitStatus < ActiveRecord::Base scope :success, -> { where(status: 'success') } scope :failed, -> { where(status: 'failed') } scope :running_or_pending, -> { where(status:[:running, :pending]) } - scope :latest, -> { where(id: unscope(:select).select('max(id)').group(:name, :ref)).order(stage_idx: :asc) } - scope :for_ref, ->(ref) { where(ref: [ref, nil]) } + scope :latest, -> { where(id: unscope(:select).select('max(id)').group(:name, :ref)) } + scope :ordered, -> { order(:ref, :stage_idx, :name) } + scope :for_ref, ->(ref) { where(ref: ref) } scope :running_or_pending, -> { where(status: [:running, :pending]) } state_machine :status, initial: :pending do diff --git a/app/views/projects/builds/show.html.haml b/app/views/projects/builds/show.html.haml index 66e668f3771..b561078e8c7 100644 --- a/app/views/projects/builds/show.html.haml +++ b/app/views/projects/builds/show.html.haml @@ -7,9 +7,9 @@ %code #{@build.ref} #up-build-trace - - if @commit.matrix?(@build.ref) + - if @commit.matrix_for_ref?(@build.ref) %ul.center-top-menu.build-top-menu - - @commit.builds_without_retry(@build.ref).each do |build| + - @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) @@ -20,7 +20,7 @@ = build.id - - unless @commit.builds_without_retry(@build.ref).include?(@build) + - unless @commit.builds_without_retry_for_ref(@build.ref).include?(@build) %li.active %a Build ##{@build.id} diff --git a/app/views/projects/commit/ci.html.haml b/app/views/projects/commit/ci.html.haml index 7f106631cac..585f012fe04 100644 --- a/app/views/projects/commit/ci.html.haml +++ b/app/views/projects/commit/ci.html.haml @@ -20,49 +20,28 @@ .bs-callout.bs-callout-warning \.gitlab-ci.yml not found in this commit -- if @ci_commit.refs.blank? - .gray-content-block.second-block - Latest builds - - if @ci_commit.duration > 0 - %small.pull-right - %i.fa.fa-time - #{time_interval_in_words @ci_commit.duration} +.gray-content-block.second-block + Latest + - if @ci_commit.duration > 0 + %small.pull-right + %i.fa.fa-time + #{time_interval_in_words @ci_commit.duration} - %table.table.builds - %thead - %tr - %th Status - %th Build ID - %th Stage - %th Name - %th Duration - %th Finished at - - if @ci_project && @ci_project.coverage_enabled? - %th Coverage - %th - = render partial: "projects/commit_statuses/commit_status", collection: @ci_commit.statuses.latest, coverage: @ci_project.try(:coverage_enabled?), controls: true - -- @ci_commit.refs.sort.each do |ref| - .gray-content-block.second-block - Builds for #{ref} - - if @ci_commit.duration(ref) > 0 - %small.pull-right - %i.fa.fa-time - #{time_interval_in_words @ci_commit.duration(ref)} - - %table.table.builds - %thead - %tr - %th Status - %th Build ID - %th Stage - %th Name - %th Duration - %th Finished at - - if @ci_project && @ci_project.coverage_enabled? - %th Coverage - %th - = render partial: "projects/commit_statuses/commit_status", collection: @ci_commit.statuses.for_ref(ref).latest, coverage: @ci_project.try(:coverage_enabled?), controls: true +%table.table.builds + %thead + %tr + %th Status + %th Build ID + %th Ref + %th Stage + %th Name + %th Duration + %th Finished at + - if @ci_project && @ci_project.coverage_enabled? + %th Coverage + %th + - @ci_commit.refs.each do |ref| + = render partial: "projects/commit_statuses/commit_status", collection: @ci_commit.statuses.for_ref(ref).latest.ordered, coverage: @ci_project.try(:coverage_enabled?), controls: true - if @ci_commit.retried.any? .gray-content-block.second-block @@ -81,4 +60,4 @@ - if @ci_project && @ci_project.coverage_enabled? %th Coverage %th - = render partial: "projects/commit_statuses/commit_status", collection: @ci_commit.retried, coverage: @ci_project.try(:coverage_enabled?), ref: true + = render partial: "projects/commit_statuses/commit_status", collection: @ci_commit.retried, coverage: @ci_project.try(:coverage_enabled?) diff --git a/app/views/projects/commit_statuses/_commit_status.html.haml b/app/views/projects/commit_statuses/_commit_status.html.haml index 14b814bb0d6..e3a17faf0bd 100644 --- a/app/views/projects/commit_statuses/_commit_status.html.haml +++ b/app/views/projects/commit_statuses/_commit_status.html.haml @@ -9,9 +9,8 @@ - else %strong Build ##{commit_status.id} - - if defined?(ref) && ref - %td - = commit_status.ref + %td + = commit_status.ref %td = commit_status.stage diff --git a/lib/api/commit_statuses.rb b/lib/api/commit_statuses.rb index 2a005d6a9f7..50ca89079e0 100644 --- a/lib/api/commit_statuses.rb +++ b/lib/api/commit_statuses.rb @@ -53,7 +53,7 @@ module API name = params[:name] || params[:context] status = GenericCommitStatus.running_or_pending.find_by(commit: ci_commit, name: name, ref: params[:ref]) - status = GenericCommitStatus.new(commit: ci_commit, user: current_user) unless status + status ||= GenericCommitStatus.new(commit: ci_commit, user: current_user) status.update(attrs) case params[:state].to_s