diff --git a/CHANGELOG b/CHANGELOG index db07afb9d966a698977e1b84be20d285992c79fe..d78c51fbbc3d1372aea118e8899008221a048118 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -39,6 +39,7 @@ v 8.11.0 (unreleased) - API: Add deployment endpoints - API: Add Play endpoint on Builds - Fix of 'Commits being passed to custom hooks are already reachable when using the UI' + - Show wall clock time when showing a pipeline. !5734 - Show member roles to all users on members page - Project.visible_to_user is instrumented again - Fix awardable button mutuality loading spinners (ClemMakesApps) diff --git a/app/helpers/time_helper.rb b/app/helpers/time_helper.rb index 790001222f12e92d47de0c72a201652647b08224..271e839692aab9fef18b6daf667020f40c871170 100644 --- a/app/helpers/time_helper.rb +++ b/app/helpers/time_helper.rb @@ -15,20 +15,9 @@ module TimeHelper "#{from.to_s(:short)} - #{to.to_s(:short)}" end - def duration_in_numbers(finished_at, started_at) - interval = interval_in_seconds(started_at, finished_at) - time_format = interval < 1.hour ? "%M:%S" : "%H:%M:%S" + def duration_in_numbers(duration) + time_format = duration < 1.hour ? "%M:%S" : "%H:%M:%S" - Time.at(interval).utc.strftime(time_format) - end - - private - - def interval_in_seconds(started_at, finished_at = nil) - if started_at && finished_at - finished_at.to_i - started_at.to_i - elsif started_at - Time.now.to_i - started_at.to_i - end + Time.at(duration).utc.strftime(time_format) end end diff --git a/app/models/ci/pipeline.rb b/app/models/ci/pipeline.rb index c360a6ff7291962fcb06d5245653ac80fc994e59..0f0bfd4ee315e7b6f16d8cfdd422fe740236fe44 100644 --- a/app/models/ci/pipeline.rb +++ b/app/models/ci/pipeline.rb @@ -78,6 +78,10 @@ module Ci CommitStatus.where(pipeline: pluck(:id)).stages end + def self.total_duration + where.not(duration: nil).sum(:duration) + end + def stages_with_latest_statuses statuses.latest.order(:stage_idx).group_by(&:stage) end @@ -250,7 +254,7 @@ module Ci end def update_duration - self.duration = statuses.latest.duration + self.duration = calculate_duration end def execute_hooks diff --git a/app/models/commit_status.rb b/app/models/commit_status.rb index 703ca90edb6982bee860ca1825bb55d908eaf170..7542399169f36aa85371cc42a0078c4faffca94d 100644 --- a/app/models/commit_status.rb +++ b/app/models/commit_status.rb @@ -21,6 +21,7 @@ class CommitStatus < ActiveRecord::Base where(id: max_id.group(:name, :commit_id)) end + scope :retried, -> { where.not(id: latest) } scope :ordered, -> { order(:name) } scope :ignored, -> { where(allow_failure: true, status: [:failed, :canceled]) } @@ -107,13 +108,7 @@ class CommitStatus < ActiveRecord::Base end def duration - duration = - if started_at && finished_at - finished_at - started_at - elsif started_at - Time.now - started_at - end - duration + calculate_duration end def stuck? diff --git a/app/models/concerns/statuseable.rb b/app/models/concerns/statuseable.rb index 5d4b0a868998c82032f261ea6982cf665b9fef1e..750f937b72407bbdd9e827c41093c4edc86b5bd9 100644 --- a/app/models/concerns/statuseable.rb +++ b/app/models/concerns/statuseable.rb @@ -35,11 +35,6 @@ module Statuseable all.pluck(self.status_sql).first end - def duration - duration_array = all.map(&:duration).compact - duration_array.reduce(:+) - end - def started_at all.minimum(:started_at) end @@ -85,4 +80,14 @@ module Statuseable def complete? COMPLETED_STATUSES.include?(status) end + + private + + def calculate_duration + if started_at && finished_at + finished_at - started_at + elsif started_at + Time.now - started_at + end + end end diff --git a/app/views/admin/builds/_build.html.haml b/app/views/admin/builds/_build.html.haml index 352adbedee4e0a88401c8aed59bac7751537f215..f29d9c94441a96ce91f27cb17830e52f3fc2ef9f 100644 --- a/app/views/admin/builds/_build.html.haml +++ b/app/views/admin/builds/_build.html.haml @@ -51,7 +51,7 @@ - if build.duration %p.duration = custom_icon("icon_timer") - = duration_in_numbers(build.finished_at, build.started_at) + = duration_in_numbers(build.duration) - if build.finished_at %p.finished-at diff --git a/app/views/projects/ci/builds/_build.html.haml b/app/views/projects/ci/builds/_build.html.haml index 91081435220cab25fb66d81b13ca2477c6df1345..1fdf32466f234ac7c99e032935fa185d0be9b59a 100644 --- a/app/views/projects/ci/builds/_build.html.haml +++ b/app/views/projects/ci/builds/_build.html.haml @@ -63,7 +63,7 @@ - if build.duration %p.duration = custom_icon("icon_timer") - = duration_in_numbers(build.finished_at, build.started_at) + = duration_in_numbers(build.duration) - if build.finished_at %p.finished-at = icon("calendar") diff --git a/app/views/projects/ci/pipelines/_pipeline.html.haml b/app/views/projects/ci/pipelines/_pipeline.html.haml index be387201f8dbbb5a6302c1e86d7914b2e8791c73..9a672b23341b872cb749c60ae2d4ec67d3cc8ce1 100644 --- a/app/views/projects/ci/pipelines/_pipeline.html.haml +++ b/app/views/projects/ci/pipelines/_pipeline.html.haml @@ -48,10 +48,10 @@ \- %td - - if pipeline.started_at && pipeline.finished_at + - if pipeline.duration %p.duration = custom_icon("icon_timer") - = duration_in_numbers(pipeline.finished_at, pipeline.started_at) + = duration_in_numbers(pipeline.duration) - if pipeline.finished_at %p.finished-at = icon("calendar") diff --git a/app/views/projects/commit/_commit_box.html.haml b/app/views/projects/commit/_commit_box.html.haml index 14adee7a6e93da1ac87cd1a31568a12ed4e8388f..29d767e776967b2b01d960b1edb512bea203f64e 100644 --- a/app/views/projects/commit/_commit_box.html.haml +++ b/app/views/projects/commit/_commit_box.html.haml @@ -58,9 +58,8 @@ = ci_icon_for_status(@commit.status) %span.ci-status-label = ci_label_for_status(@commit.status) - - if @commit.pipelines.duration - in - = time_interval_in_words @commit.pipelines.duration + in + = time_interval_in_words @commit.pipelines.total_duration .commit-box.content-block %h3.commit-title diff --git a/app/views/projects/pipelines/_info.html.haml b/app/views/projects/pipelines/_info.html.haml index 8289aefcde755c31ecf5bdef79e988a19bae03fb..063e83a407aca98225f8d9a52f2a7cb463305ee4 100644 --- a/app/views/projects/pipelines/_info.html.haml +++ b/app/views/projects/pipelines/_info.html.haml @@ -9,7 +9,7 @@ = link_to @pipeline.ref, namespace_project_commits_path(@project.namespace, @project, @pipeline.ref), class: "monospace" - if @pipeline.duration in - = time_interval_in_words @pipeline.duration + = time_interval_in_words(@pipeline.duration) .pull-right = link_to namespace_project_pipeline_path(@project.namespace, @project, @pipeline), class: "ci-status ci-#{@pipeline.status}" do diff --git a/lib/gitlab/utils.rb b/lib/gitlab/utils.rb index d13fe0ef8a9df2c8ac823caa97d0e5d363ae0f9d..e59ead5d76c6c45cdb91a4c1719073b157d1a9c5 100644 --- a/lib/gitlab/utils.rb +++ b/lib/gitlab/utils.rb @@ -7,7 +7,7 @@ module Gitlab # @param cmd [Array<String>] # @return [Boolean] def system_silent(cmd) - Popen::popen(cmd).last.zero? + Popen.popen(cmd).last.zero? end def force_utf8(str) diff --git a/spec/helpers/time_helper_spec.rb b/spec/helpers/time_helper_spec.rb index bf3ed5c094c3779398955743fce81302455a0a04..21f355853672844661ac90c156333833b6274928 100644 --- a/spec/helpers/time_helper_spec.rb +++ b/spec/helpers/time_helper_spec.rb @@ -19,16 +19,16 @@ describe TimeHelper do describe "#duration_in_numbers" do it "returns minutes and seconds" do - duration_in_numbers = { - [100, 0] => "01:40", - [121, 0] => "02:01", - [3721, 0] => "01:02:01", - [0, 0] => "00:00", - [nil, Time.now.to_i - 42] => "00:42" + durations_and_expectations = { + 100 => "01:40", + 121 => "02:01", + 3721 => "01:02:01", + 0 => "00:00", + 42 => "00:42" } - duration_in_numbers.each do |interval, expectation| - expect(duration_in_numbers(*interval)).to eq(expectation) + durations_and_expectations.each do |duration, expectation| + expect(duration_in_numbers(duration)).to eq(expectation) end end end diff --git a/spec/models/broadcast_message_spec.rb b/spec/models/broadcast_message_spec.rb index 72688137f08f531857a9e6c16cd54683170fec9a..02d6263094aa0d784e3268deef207cd1ffd88880 100644 --- a/spec/models/broadcast_message_spec.rb +++ b/spec/models/broadcast_message_spec.rb @@ -1,8 +1,6 @@ require 'spec_helper' describe BroadcastMessage, models: true do - include ActiveSupport::Testing::TimeHelpers - subject { create(:broadcast_message) } it { is_expected.to be_valid } diff --git a/spec/models/ci/pipeline_spec.rb b/spec/models/ci/pipeline_spec.rb index 8137e9f8f71abddc964c9da950eb975140ef3f31..721b20e0cb28d79c62446c6184e140c4e9bc9a26 100644 --- a/spec/models/ci/pipeline_spec.rb +++ b/spec/models/ci/pipeline_spec.rb @@ -124,17 +124,21 @@ describe Ci::Pipeline, models: true do describe 'state machine' do let(:current) { Time.now.change(usec: 0) } - let(:build) { create :ci_build, name: 'build1', pipeline: pipeline, started_at: current - 60, finished_at: current } - let(:build2) { create :ci_build, name: 'build2', pipeline: pipeline, started_at: current - 60, finished_at: current } + let(:build) { create :ci_build, name: 'build1', pipeline: pipeline } describe '#duration' do before do - build.skip - build2.skip + travel_to(current - 120) do + pipeline.run + end + + travel_to(current) do + pipeline.succeed + end end it 'matches sum of builds duration' do - expect(pipeline.reload.duration).to eq(build.duration + build2.duration) + expect(pipeline.reload.duration).to eq(120) end end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 2e2aa7c4fc04e7681ce6d37d50a0055b23e4064a..c144cd85487f250be31227711bf6be927f853baf 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -33,6 +33,7 @@ RSpec.configure do |config| config.include EmailHelpers config.include TestEnv config.include ActiveJob::TestHelper + config.include ActiveSupport::Testing::TimeHelpers config.include StubGitlabCalls config.include StubGitlabData