Commit ba318f3d authored by Lee Tickett's avatar Lee Tickett Committed by Dylan Griffith

Show build status in branch list

parent 3a082739
...@@ -25,8 +25,9 @@ class Projects::BranchesController < Projects::ApplicationController ...@@ -25,8 +25,9 @@ class Projects::BranchesController < Projects::ApplicationController
@refs_pipelines = @project.ci_pipelines.latest_successful_for_refs(@branches.map(&:name)) @refs_pipelines = @project.ci_pipelines.latest_successful_for_refs(@branches.map(&:name))
@merged_branch_names = repository.merged_branch_names(@branches.map(&:name)) @merged_branch_names = repository.merged_branch_names(@branches.map(&:name))
@branch_pipeline_statuses = branch_pipeline_statuses
# https://gitlab.com/gitlab-org/gitlab-foss/issues/48097 # https://gitlab.com/gitlab-org/gitlab/-/issues/22851
Gitlab::GitalyClient.allow_n_plus_1_calls do Gitlab::GitalyClient.allow_n_plus_1_calls do
render render
end end
...@@ -194,4 +195,15 @@ class Projects::BranchesController < Projects::ApplicationController ...@@ -194,4 +195,15 @@ class Projects::BranchesController < Projects::ApplicationController
confidential_issue_project confidential_issue_project
end end
def branch_pipeline_statuses
latest_commits = @branches.map do |branch|
[branch.name, repository.commit(branch.dereferenced_target).sha]
end.to_h
latest_pipelines = project.ci_pipelines.latest_pipeline_per_commit(latest_commits.values)
latest_commits.transform_values do |commit_sha|
latest_pipelines[commit_sha]&.detailed_status(current_user)
end.compact
end
end end
...@@ -29,6 +29,12 @@ ...@@ -29,6 +29,12 @@
.js-branch-divergence-graph .js-branch-divergence-graph
.controls.d-none.d-md-block< .controls.d-none.d-md-block<
- if commit_status
= render 'ci/status/icon', size: 24, status: commit_status, option_css_classes: 'gl-display-inline-flex gl-vertical-align-middle gl-mr-5'
- elsif show_commit_status
.gl-display-inline-flex.gl-vertical-align-middle.gl-mr-5
%svg.s24
- if merge_project && create_mr_button?(@repository.root_ref, branch.name) - if merge_project && create_mr_button?(@repository.root_ref, branch.name)
= link_to create_mr_path(@repository.root_ref, branch.name), class: 'btn btn-default' do = link_to create_mr_path(@repository.root_ref, branch.name), class: 'btn btn-default' do
= _('Merge request') = _('Merge request')
......
...@@ -12,7 +12,7 @@ ...@@ -12,7 +12,7 @@
= panel_title = panel_title
%ul.content-list.all-branches.qa-all-branches %ul.content-list.all-branches.qa-all-branches
- branches.first(overview_max_branches).each do |branch| - branches.first(overview_max_branches).each do |branch|
= render "projects/branches/branch", branch: branch, merged: project.repository.merged_to_root_ref?(branch) = render "projects/branches/branch", branch: branch, merged: project.repository.merged_to_root_ref?(branch), commit_status: @branch_pipeline_statuses[branch.name], show_commit_status: @branch_pipeline_statuses.any?
- if branches.size > overview_max_branches - if branches.size > overview_max_branches
.card-footer.text-center .card-footer.text-center
= link_to show_more_text, project_branches_filtered_path(project, state: state), id: "state-#{state}", data: { state: state } = link_to show_more_text, project_branches_filtered_path(project, state: state), id: "state-#{state}", data: { state: state }
...@@ -59,7 +59,7 @@ ...@@ -59,7 +59,7 @@
- elsif @branches.any? - elsif @branches.any?
%ul.content-list.all-branches %ul.content-list.all-branches
- @branches.each do |branch| - @branches.each do |branch|
= render "projects/branches/branch", branch: branch, merged: @merged_branch_names.include?(branch.name) = render "projects/branches/branch", branch: branch, merged: @merged_branch_names.include?(branch.name), commit_status: @branch_pipeline_statuses[branch.name], show_commit_status: @branch_pipeline_statuses.any?
= paginate @branches, theme: 'gitlab' = paginate @branches, theme: 'gitlab'
- else - else
.nothing-here-block .nothing-here-block
......
---
title: Show build status on branch list
merge_request: 30948
author: Lee Tickett
type: added
...@@ -487,6 +487,82 @@ RSpec.describe Projects::BranchesController do ...@@ -487,6 +487,82 @@ RSpec.describe Projects::BranchesController do
end end
end end
context 'when a branch has multiple pipelines' do
it 'chooses the latest to determine status' do
sha = project.repository.create_file(developer, generate(:branch), 'content', message: 'message', branch_name: 'master')
create(:ci_pipeline,
project: project,
user: developer,
ref: "master",
sha: sha,
status: :running,
created_at: 6.months.ago)
create(:ci_pipeline,
project: project,
user: developer,
ref: "master",
sha: sha,
status: :success,
created_at: 2.months.ago)
get :index,
format: :html,
params: {
namespace_id: project.namespace,
project_id: project,
state: 'all'
}
expect(controller.instance_variable_get(:@branch_pipeline_statuses)["master"].group).to eq("success")
end
end
context 'when multiple branches exist' do
it 'all relevant commit statuses are received' do
master_sha = project.repository.create_file(developer, generate(:branch), 'content', message: 'message', branch_name: 'master')
create(:ci_pipeline,
project: project,
user: developer,
ref: "master",
sha: master_sha,
status: :running,
created_at: 6.months.ago)
test_sha = project.repository.create_file(developer, generate(:branch), 'content', message: 'message', branch_name: 'test')
create(:ci_pipeline,
project: project,
user: developer,
ref: "test",
sha: test_sha,
status: :success,
created_at: 2.months.ago)
get :index,
format: :html,
params: {
namespace_id: project.namespace,
project_id: project,
state: 'all'
}
expect(controller.instance_variable_get(:@branch_pipeline_statuses)["master"].group).to eq("running")
expect(controller.instance_variable_get(:@branch_pipeline_statuses)["test"].group).to eq("success")
end
end
context 'when a branch contains no pipelines' do
it 'no commit statuses are received' do
get :index,
format: :html,
params: {
namespace_id: project.namespace,
project_id: project,
state: 'all'
}
expect(controller.instance_variable_get(:@branch_pipeline_statuses)).to be_blank
end
end
# We need :request_store because Gitaly only counts the queries whenever # We need :request_store because Gitaly only counts the queries whenever
# `RequestStore.active?` in GitalyClient.enforce_gitaly_request_limits # `RequestStore.active?` in GitalyClient.enforce_gitaly_request_limits
# And the main goal of this test is making sure TooManyInvocationsError # And the main goal of this test is making sure TooManyInvocationsError
......
...@@ -231,6 +231,44 @@ describe 'Branches' do ...@@ -231,6 +231,44 @@ describe 'Branches' do
end end
end end
context 'with one or more pipeline', :js do
before do
sha = create_file(branch_name: "branch")
create(:ci_pipeline,
project: project,
user: user,
ref: "branch",
sha: sha,
status: :success,
created_at: 5.months.ago)
visit project_branches_path(project)
end
it 'shows pipeline status when available' do
page.within first('.all-branches li') do
expect(page).to have_css 'a.ci-status-icon-success'
end
end
it 'displays a placeholder when not available' do
page.all('.all-branches li') do |li|
expect(li).to have_css 'svg.s24'
end
end
end
context 'with no pipelines', :js do
before do
visit project_branches_path(project)
end
it 'does not show placeholder or pipeline status' do
page.all('.all-branches') do |branches|
expect(branches).not_to have_css 'svg.s24'
end
end
end
describe 'comparing branches' do describe 'comparing branches' do
before do before do
sign_in(user) sign_in(user)
......
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