Commit f3c2855f authored by Grzegorz Bizon's avatar Grzegorz Bizon

Merge branch 'show-commit-status-from-latest-pipeline' into 'master'

Show commit status from latest pipeline

Show commit status from latest pipeline rather than compound status from all pipelines.

Closes #20560

See merge request !7333
parents 4530e68c d9000184
...@@ -88,8 +88,24 @@ module Ci ...@@ -88,8 +88,24 @@ module Ci
end end
# ref can't be HEAD or SHA, can only be branch/tag name # ref can't be HEAD or SHA, can only be branch/tag name
scope :latest, ->(ref = nil) do
max_id = unscope(:select)
.select("max(#{quoted_table_name}.id)")
.group(:ref, :sha)
if ref
where(id: max_id, ref: ref)
else
where(id: max_id)
end
end
def self.latest_status(ref = nil)
latest(ref).status
end
def self.latest_successful_for(ref) def self.latest_successful_for(ref)
where(ref: ref).order(id: :desc).success.first success.latest(ref).first
end end
def self.truncate_sha(sha) def self.truncate_sha(sha)
......
...@@ -228,13 +228,9 @@ class Commit ...@@ -228,13 +228,9 @@ class Commit
def status(ref = nil) def status(ref = nil)
@statuses ||= {} @statuses ||= {}
if @statuses.key?(ref) return @statuses[ref] if @statuses.key?(ref)
@statuses[ref]
elsif ref @statuses[ref] = pipelines.latest_status(ref)
@statuses[ref] = pipelines.where(ref: ref).status
else
@statuses[ref] = pipelines.status
end
end end
def revert_branch_name def revert_branch_name
...@@ -270,7 +266,7 @@ class Commit ...@@ -270,7 +266,7 @@ class Commit
@merged_merge_request_hash ||= Hash.new do |hash, user| @merged_merge_request_hash ||= Hash.new do |hash, user|
hash[user] = merged_merge_request_no_cache(user) hash[user] = merged_merge_request_no_cache(user)
end end
@merged_merge_request_hash[current_user] @merged_merge_request_hash[current_user]
end end
......
module Ci module Ci
class ImageForBuildService class ImageForBuildService
def execute(project, opts) def execute(project, opts)
sha = opts[:sha] || ref_sha(project, opts[:ref]) ref = opts[:ref]
sha = opts[:sha] || ref_sha(project, ref)
pipelines = project.pipelines.where(sha: sha) pipelines = project.pipelines.where(sha: sha)
pipelines = pipelines.where(ref: opts[:ref]) if opts[:ref]
image_name = image_for_status(pipelines.status)
image_name = image_for_status(pipelines.latest_status(ref))
image_path = Rails.root.join('public/ci', image_name) image_path = Rails.root.join('public/ci', image_name)
OpenStruct.new(path: image_path, name: image_name) OpenStruct.new(path: image_path, name: image_name)
end end
......
---
title: Show commit status from latest pipeline
merge_request: 7333
author:
...@@ -20,8 +20,8 @@ module Gitlab ...@@ -20,8 +20,8 @@ module Gitlab
def status def status
@project.pipelines @project.pipelines
.where(sha: @sha, ref: @ref) .where(sha: @sha)
.status || 'unknown' .latest_status(@ref) || 'unknown'
end end
def metadata def metadata
......
...@@ -69,8 +69,8 @@ describe Gitlab::Badge::Build::Status do ...@@ -69,8 +69,8 @@ describe Gitlab::Badge::Build::Status do
new_build.success! new_build.success!
end end
it 'reports the compound status' do it 'does not take outdated pipeline into account' do
expect(badge.status).to eq 'failed' expect(badge.status).to eq 'success'
end end
end end
end end
......
...@@ -381,6 +381,65 @@ describe Ci::Pipeline, models: true do ...@@ -381,6 +381,65 @@ describe Ci::Pipeline, models: true do
end end
end end
shared_context 'with some outdated pipelines' do
before do
create_pipeline(:canceled, 'ref', 'A')
create_pipeline(:success, 'ref', 'A')
create_pipeline(:failed, 'ref', 'B')
create_pipeline(:skipped, 'feature', 'C')
end
def create_pipeline(status, ref, sha)
create(:ci_empty_pipeline, status: status, ref: ref, sha: sha)
end
end
describe '.latest' do
include_context 'with some outdated pipelines'
context 'when no ref is specified' do
let(:pipelines) { described_class.latest.all }
it 'returns the latest pipeline for the same ref and different sha' do
expect(pipelines.map(&:sha)).to contain_exactly('A', 'B', 'C')
expect(pipelines.map(&:status)).
to contain_exactly('success', 'failed', 'skipped')
end
end
context 'when ref is specified' do
let(:pipelines) { described_class.latest('ref').all }
it 'returns the latest pipeline for ref and different sha' do
expect(pipelines.map(&:sha)).to contain_exactly('A', 'B')
expect(pipelines.map(&:status)).
to contain_exactly('success', 'failed')
end
end
end
describe '.latest_status' do
include_context 'with some outdated pipelines'
context 'when no ref is specified' do
let(:latest_status) { described_class.latest_status }
it 'returns the latest status for the same ref and different sha' do
expect(latest_status).to eq(described_class.latest.status)
expect(latest_status).to eq('failed')
end
end
context 'when ref is specified' do
let(:latest_status) { described_class.latest_status('ref') }
it 'returns the latest status for ref and different sha' do
expect(latest_status).to eq(described_class.latest_status('ref'))
expect(latest_status).to eq('failed')
end
end
end
describe '#status' do describe '#status' do
let!(:build) { create(:ci_build, :created, pipeline: pipeline, name: 'test') } let!(:build) { create(:ci_build, :created, pipeline: pipeline, name: 'test') }
......
...@@ -213,23 +213,19 @@ eos ...@@ -213,23 +213,19 @@ eos
end end
describe '#status' do describe '#status' do
context 'without arguments for compound status' do context 'without ref argument' do
shared_examples 'giving the status from pipeline' do before do
it do %w[success failed created pending].each do |status|
expect(commit.status).to eq(Ci::Pipeline.status) create(:ci_empty_pipeline,
end project: project,
end sha: commit.sha,
status: status)
context 'with pipelines' do
let!(:pipeline) do
create(:ci_empty_pipeline, project: project, sha: commit.sha)
end end
it_behaves_like 'giving the status from pipeline'
end end
context 'without pipelines' do it 'gives compound status from latest pipelines' do
it_behaves_like 'giving the status from pipeline' expect(commit.status).to eq(Ci::Pipeline.latest_status)
expect(commit.status).to eq('pending')
end end
end end
...@@ -255,8 +251,9 @@ eos ...@@ -255,8 +251,9 @@ eos
expect(commit.status('fix')).to eq(pipeline_from_fix.status) expect(commit.status('fix')).to eq(pipeline_from_fix.status)
end end
it 'gives compound status if ref is nil' do it 'gives compound status from latest pipelines if ref is nil' do
expect(commit.status(nil)).to eq(commit.status) expect(commit.status(nil)).to eq(Ci::Pipeline.latest_status)
expect(commit.status(nil)).to eq('failed')
end end
end end
end end
......
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