Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
G
gitlab-ce
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
1
Merge Requests
1
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
gitlab-ce
Commits
f5e0d0d8
Commit
f5e0d0d8
authored
Oct 30, 2020
by
Lee Tickett
Committed by
Thong Kuah
Oct 30, 2020
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Show build status in tag list
parent
26087e16
Changes
8
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
322 additions
and
19 deletions
+322
-19
app/controllers/projects/branches_controller.rb
app/controllers/projects/branches_controller.rb
+1
-12
app/controllers/projects/tags_controller.rb
app/controllers/projects/tags_controller.rb
+1
-0
app/finders/ci/commit_statuses_finder.rb
app/finders/ci/commit_statuses_finder.rb
+40
-0
app/views/projects/tags/_tag.html.haml
app/views/projects/tags/_tag.html.haml
+7
-0
changelogs/unreleased/show_build_status_in_tag_list.yml
changelogs/unreleased/show_build_status_in_tag_list.yml
+5
-0
spec/controllers/projects/tags_controller_spec.rb
spec/controllers/projects/tags_controller_spec.rb
+65
-7
spec/finders/ci/commit_statuses_finder_spec.rb
spec/finders/ci/commit_statuses_finder_spec.rb
+178
-0
spec/views/projects/tags/index.html.haml_spec.rb
spec/views/projects/tags/index.html.haml_spec.rb
+25
-0
No files found.
app/controllers/projects/branches_controller.rb
View file @
f5e0d0d8
...
@@ -27,7 +27,7 @@ class Projects::BranchesController < Projects::ApplicationController
...
@@ -27,7 +27,7 @@ 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
@branch_pipeline_statuses
=
Ci
::
CommitStatusesFinder
.
new
(
@project
,
repository
,
current_user
,
@branches
).
execute
# https://gitlab.com/gitlab-org/gitlab/-/issues/22851
# https://gitlab.com/gitlab-org/gitlab/-/issues/22851
Gitlab
::
GitalyClient
.
allow_n_plus_1_calls
do
Gitlab
::
GitalyClient
.
allow_n_plus_1_calls
do
...
@@ -197,15 +197,4 @@ class Projects::BranchesController < Projects::ApplicationController
...
@@ -197,15 +197,4 @@ 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
app/controllers/projects/tags_controller.rb
View file @
f5e0d0d8
...
@@ -24,6 +24,7 @@ class Projects::TagsController < Projects::ApplicationController
...
@@ -24,6 +24,7 @@ class Projects::TagsController < Projects::ApplicationController
tag_names
=
@tags
.
map
(
&
:name
)
tag_names
=
@tags
.
map
(
&
:name
)
@tags_pipelines
=
@project
.
ci_pipelines
.
latest_successful_for_refs
(
tag_names
)
@tags_pipelines
=
@project
.
ci_pipelines
.
latest_successful_for_refs
(
tag_names
)
@releases
=
project
.
releases
.
where
(
tag:
tag_names
)
@releases
=
project
.
releases
.
where
(
tag:
tag_names
)
@tag_pipeline_statuses
=
Ci
::
CommitStatusesFinder
.
new
(
@project
,
@repository
,
current_user
,
@tags
).
execute
respond_to
do
|
format
|
respond_to
do
|
format
|
format
.
html
format
.
html
...
...
app/finders/ci/commit_statuses_finder.rb
0 → 100644
View file @
f5e0d0d8
# frozen_string_literal: true
module
Ci
class
CommitStatusesFinder
include
::
Gitlab
::
Utils
::
StrongMemoize
def
initialize
(
project
,
repository
,
current_user
,
refs
)
@project
=
project
@repository
=
repository
@current_user
=
current_user
@refs
=
refs
end
def
execute
return
[]
unless
Ability
.
allowed?
(
@current_user
,
:read_pipeline
,
@project
)
commit_statuses
end
private
def
latest_commits
strong_memoize
(
:latest_commits
)
do
refs
.
map
do
|
ref
|
[
ref
.
name
,
@repository
.
commit
(
ref
.
dereferenced_target
).
sha
]
end
.
to_h
end
end
def
commit_statuses
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
attr_reader
:project
,
:repository
,
:current_user
,
:refs
end
end
app/views/projects/tags/_tag.html.haml
View file @
f5e0d0d8
-
commit
=
@repository
.
commit
(
tag
.
dereferenced_target
)
-
commit
=
@repository
.
commit
(
tag
.
dereferenced_target
)
-
release
=
@releases
.
find
{
|
release
|
release
.
tag
==
tag
.
name
}
-
release
=
@releases
.
find
{
|
release
|
release
.
tag
==
tag
.
name
}
-
commit_status
=
@tag_pipeline_statuses
[
tag
.
name
]
unless
@tag_pipeline_statuses
.
nil?
%li
.flex-row.allow-wrap.js-tag-list
%li
.flex-row.allow-wrap.js-tag-list
.row-main-content
.row-main-content
...
@@ -34,6 +35,12 @@
...
@@ -34,6 +35,12 @@
-
if
tag
.
has_signature?
-
if
tag
.
has_signature?
=
render
partial:
'projects/commit/signature'
,
object:
tag
.
signature
=
render
partial:
'projects/commit/signature'
,
object:
tag
.
signature
-
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
@tag_pipeline_statuses
&&
@tag_pipeline_statuses
.
any?
.gl-display-inline-flex.gl-vertical-align-middle.gl-mr-5
%svg
.s24
=
render
'projects/buttons/download'
,
project:
@project
,
ref:
tag
.
name
,
pipeline:
@tags_pipelines
[
tag
.
name
]
=
render
'projects/buttons/download'
,
project:
@project
,
ref:
tag
.
name
,
pipeline:
@tags_pipelines
[
tag
.
name
]
-
if
can?
(
current_user
,
:admin_tag
,
@project
)
-
if
can?
(
current_user
,
:admin_tag
,
@project
)
...
...
changelogs/unreleased/show_build_status_in_tag_list.yml
0 → 100644
View file @
f5e0d0d8
---
title
:
Show build status in tag list
merge_request
:
34307
author
:
Lee Tickett
type
:
added
spec/controllers/projects/tags_controller_spec.rb
View file @
f5e0d0d8
...
@@ -9,18 +9,75 @@ RSpec.describe Projects::TagsController do
...
@@ -9,18 +9,75 @@ RSpec.describe Projects::TagsController do
let
(
:user
)
{
create
(
:user
)
}
let
(
:user
)
{
create
(
:user
)
}
describe
'GET index'
do
describe
'GET index'
do
before
do
subject
{
get
:index
,
params:
{
namespace_id:
project
.
namespace
.
to_param
,
project_id:
project
}
}
get
:index
,
params:
{
namespace_id:
project
.
namespace
.
to_param
,
project_id:
project
}
end
it
'returns the tags for the page'
do
it
'returns the tags for the page'
do
subject
expect
(
assigns
(
:tags
).
map
(
&
:name
)).
to
include
(
'v1.1.0'
,
'v1.0.0'
)
expect
(
assigns
(
:tags
).
map
(
&
:name
)).
to
include
(
'v1.1.0'
,
'v1.0.0'
)
end
end
it
'returns releases matching those tags'
do
it
'returns releases matching those tags'
do
subject
expect
(
assigns
(
:releases
)).
to
include
(
release
)
expect
(
assigns
(
:releases
)).
to
include
(
release
)
expect
(
assigns
(
:releases
)).
not_to
include
(
invalid_release
)
expect
(
assigns
(
:releases
)).
not_to
include
(
invalid_release
)
end
end
context
'@tag_pipeline_status'
do
context
'when no pipelines exist'
do
it
'is empty'
do
subject
expect
(
assigns
(
:tag_pipeline_statuses
)).
to
be_empty
end
end
context
'when multiple tags exist'
do
before
do
create
(
:ci_pipeline
,
project:
project
,
ref:
'v1.1.0'
,
sha:
project
.
commit
(
'v1.1.0'
).
sha
,
status: :running
)
create
(
:ci_pipeline
,
project:
project
,
ref:
'v1.0.0'
,
sha:
project
.
commit
(
'v1.0.0'
).
sha
,
status: :success
)
end
it
'all relevant commit statuses are received'
do
subject
expect
(
assigns
(
:tag_pipeline_statuses
)[
'v1.1.0'
].
group
).
to
eq
(
"running"
)
expect
(
assigns
(
:tag_pipeline_statuses
)[
'v1.0.0'
].
group
).
to
eq
(
"success"
)
end
end
context
'when a tag has multiple pipelines'
do
before
do
create
(
:ci_pipeline
,
project:
project
,
ref:
'v1.0.0'
,
sha:
project
.
commit
(
'v1.0.0'
).
sha
,
status: :running
,
created_at:
6
.
months
.
ago
)
create
(
:ci_pipeline
,
project:
project
,
ref:
'v1.0.0'
,
sha:
project
.
commit
(
'v1.0.0'
).
sha
,
status: :success
,
created_at:
2
.
months
.
ago
)
end
it
'chooses the latest to determine status'
do
subject
expect
(
assigns
(
:tag_pipeline_statuses
)[
'v1.0.0'
].
group
).
to
eq
(
"success"
)
end
end
end
end
end
describe
'GET show'
do
describe
'GET show'
do
...
@@ -70,7 +127,8 @@ RSpec.describe Projects::TagsController do
...
@@ -70,7 +127,8 @@ RSpec.describe Projects::TagsController do
end
end
let
(
:release_description
)
{
nil
}
let
(
:release_description
)
{
nil
}
let
(
:request
)
do
subject
(
:request
)
do
post
(
:create
,
params:
{
post
(
:create
,
params:
{
namespace_id:
project
.
namespace
.
to_param
,
namespace_id:
project
.
namespace
.
to_param
,
project_id:
project
,
project_id:
project
,
...
@@ -81,7 +139,7 @@ RSpec.describe Projects::TagsController do
...
@@ -81,7 +139,7 @@ RSpec.describe Projects::TagsController do
end
end
it
'creates tag'
do
it
'creates tag'
do
reques
t
subjec
t
expect
(
response
).
to
have_gitlab_http_status
(
:found
)
expect
(
response
).
to
have_gitlab_http_status
(
:found
)
expect
(
project
.
repository
.
find_tag
(
'1.0'
)).
to
be_present
expect
(
project
.
repository
.
find_tag
(
'1.0'
)).
to
be_present
...
@@ -92,7 +150,7 @@ RSpec.describe Projects::TagsController do
...
@@ -92,7 +150,7 @@ RSpec.describe Projects::TagsController do
let
(
:release_description
)
{
'some release description'
}
let
(
:release_description
)
{
'some release description'
}
it
'creates tag and release'
do
it
'creates tag and release'
do
reques
t
subjec
t
expect
(
response
).
to
have_gitlab_http_status
(
:found
)
expect
(
response
).
to
have_gitlab_http_status
(
:found
)
expect
(
project
.
repository
.
find_tag
(
'1.0'
)).
to
be_present
expect
(
project
.
repository
.
find_tag
(
'1.0'
)).
to
be_present
...
@@ -118,7 +176,7 @@ RSpec.describe Projects::TagsController do
...
@@ -118,7 +176,7 @@ RSpec.describe Projects::TagsController do
expect
(
service
).
to
receive
(
:execute
).
and_call_original
expect
(
service
).
to
receive
(
:execute
).
and_call_original
end
end
reques
t
subjec
t
aggregate_failures
do
aggregate_failures
do
expect
(
response
).
to
have_gitlab_http_status
(
:found
)
expect
(
response
).
to
have_gitlab_http_status
(
:found
)
...
...
spec/finders/ci/commit_statuses_finder_spec.rb
0 → 100644
View file @
f5e0d0d8
# frozen_string_literal: true
require
'spec_helper'
RSpec
.
describe
Ci
::
CommitStatusesFinder
,
'#execute'
do
let_it_be
(
:project
)
{
create
(
:project
,
:public
,
:repository
)
}
let_it_be
(
:release
)
{
create
(
:release
,
project:
project
)
}
let_it_be
(
:user
)
{
create
(
:user
)
}
context
'tag refs'
do
let_it_be
(
:tags
)
{
TagsFinder
.
new
(
project
.
repository
,
{}).
execute
}
let
(
:subject
)
{
described_class
.
new
(
project
,
project
.
repository
,
user
,
tags
).
execute
}
context
'no pipelines'
do
it
'returns nil'
do
expect
(
subject
).
to
be_blank
end
end
context
'when multiple tags exist'
do
before
do
create
(
:ci_pipeline
,
project:
project
,
ref:
'v1.1.0'
,
sha:
project
.
commit
(
'v1.1.0'
).
sha
,
status: :running
)
create
(
:ci_pipeline
,
project:
project
,
ref:
'v1.0.0'
,
sha:
project
.
commit
(
'v1.0.0'
).
sha
,
status: :success
)
end
it
'all relevant commit statuses are received'
do
expect
(
subject
[
'v1.1.0'
].
group
).
to
eq
(
"running"
)
expect
(
subject
[
'v1.0.0'
].
group
).
to
eq
(
"success"
)
end
end
context
'when a tag has multiple pipelines'
do
before
do
create
(
:ci_pipeline
,
project:
project
,
ref:
'v1.0.0'
,
sha:
project
.
commit
(
'v1.0.0'
).
sha
,
status: :running
,
created_at:
6
.
months
.
ago
)
create
(
:ci_pipeline
,
project:
project
,
ref:
'v1.0.0'
,
sha:
project
.
commit
(
'v1.0.0'
).
sha
,
status: :success
,
created_at:
2
.
months
.
ago
)
end
it
'chooses the latest to determine status'
do
expect
(
subject
[
'v1.0.0'
].
group
).
to
eq
(
"success"
)
end
end
end
context
'branch refs'
do
let
(
:subject
)
{
described_class
.
new
(
project
,
project
.
repository
,
user
,
branches
).
execute
}
before
do
project
.
add_developer
(
user
)
end
context
'no pipelines'
do
let
(
:branches
)
{
BranchesFinder
.
new
(
project
.
repository
,
{}).
execute
}
it
'returns nil'
do
expect
(
subject
).
to
be_blank
end
end
context
'when a branch has multiple pipelines'
do
let
(
:branches
)
{
BranchesFinder
.
new
(
project
.
repository
,
{}).
execute
}
before
do
sha
=
project
.
repository
.
create_file
(
user
,
generate
(
:branch
),
'content'
,
message:
'message'
,
branch_name:
'master'
)
create
(
:ci_pipeline
,
project:
project
,
user:
user
,
ref:
"master"
,
sha:
sha
,
status: :running
,
created_at:
6
.
months
.
ago
)
create
(
:ci_pipeline
,
project:
project
,
user:
user
,
ref:
"master"
,
sha:
sha
,
status: :success
,
created_at:
2
.
months
.
ago
)
end
it
'chooses the latest to determine status'
do
expect
(
subject
[
"master"
].
group
).
to
eq
(
"success"
)
end
end
context
'when multiple branches exist'
do
let
(
:branches
)
{
BranchesFinder
.
new
(
project
.
repository
,
{}).
execute
}
before
do
master_sha
=
project
.
repository
.
create_file
(
user
,
generate
(
:branch
),
'content'
,
message:
'message'
,
branch_name:
'master'
)
create
(
:ci_pipeline
,
project:
project
,
user:
user
,
ref:
"master"
,
sha:
master_sha
,
status: :running
,
created_at:
6
.
months
.
ago
)
test_sha
=
project
.
repository
.
create_file
(
user
,
generate
(
:branch
),
'content'
,
message:
'message'
,
branch_name:
'test'
)
create
(
:ci_pipeline
,
project:
project
,
user:
user
,
ref:
"test"
,
sha:
test_sha
,
status: :success
,
created_at:
2
.
months
.
ago
)
end
it
'all relevant commit statuses are received'
do
expect
(
subject
[
"master"
].
group
).
to
eq
(
"running"
)
expect
(
subject
[
"test"
].
group
).
to
eq
(
"success"
)
end
end
end
context
'CI pipelines visible to'
do
let_it_be
(
:tags
)
{
TagsFinder
.
new
(
project
.
repository
,
{}).
execute
}
let
(
:subject
)
{
described_class
.
new
(
project
,
project
.
repository
,
user
,
tags
).
execute
}
before
do
create
(
:ci_pipeline
,
project:
project
,
ref:
'v1.1.0'
,
sha:
project
.
commit
(
'v1.1.0'
).
sha
,
status: :running
)
end
context
'everyone'
do
it
'returns something'
do
expect
(
subject
).
not_to
be_blank
end
end
context
'project members only'
do
before
do
project
.
project_feature
.
update!
(
builds_access_level:
ProjectFeature
::
PRIVATE
)
end
it
'returns nil'
do
expect
(
subject
).
to
be_empty
end
end
context
'when not a member of a private project'
do
let
(
:private_project
)
{
create
(
:project
,
:private
,
:repository
)
}
let
(
:private_tags
)
{
TagsFinder
.
new
(
private_tags
.
repository
,
{}).
execute
}
let
(
:private_subject
)
{
described_class
.
new
(
private_project
,
private_project
.
repository
,
user
,
tags
).
execute
}
before
do
create
(
:ci_pipeline
,
project:
private_project
,
ref:
'v1.1.0'
,
sha:
private_project
.
commit
(
'v1.1.0'
).
sha
,
status: :running
)
end
it
'returns nil'
do
expect
(
private_subject
).
to
be_empty
end
end
end
end
spec/views/projects/tags/index.html.haml_spec.rb
View file @
f5e0d0d8
...
@@ -57,4 +57,29 @@ RSpec.describe 'projects/tags/index.html.haml' do
...
@@ -57,4 +57,29 @@ RSpec.describe 'projects/tags/index.html.haml' do
expect
(
rendered
).
not_to
have_link
(
href:
latest_succeeded_project_artifacts_path
(
project
,
"
#{
pipeline
.
ref
}
/download"
,
job:
'test'
))
expect
(
rendered
).
not_to
have_link
(
href:
latest_succeeded_project_artifacts_path
(
project
,
"
#{
pipeline
.
ref
}
/download"
,
job:
'test'
))
end
end
end
end
context
'build stats'
do
let
(
:tag
)
{
'v1.0.0'
}
let
(
:page
)
{
Capybara
::
Node
::
Simple
.
new
(
rendered
)
}
it
'shows build status or placeholder when pipelines present'
do
create
(
:ci_pipeline
,
project:
project
,
ref:
tag
,
sha:
project
.
commit
(
tag
).
sha
,
status: :success
)
assign
(
:tag_pipeline_statuses
,
Ci
::
CommitStatusesFinder
.
new
(
project
,
project
.
repository
,
project
.
namespace
.
owner
,
tags
).
execute
)
render
expect
(
page
.
find
(
'.tags .content-list li'
,
text:
tag
)).
to
have_css
'a.ci-status-icon-success'
expect
(
page
.
all
(
'.tags .content-list li'
)).
to
all
(
have_css
(
'svg.s24'
))
end
it
'shows no build status or placeholder when no pipelines present'
do
render
expect
(
page
.
all
(
'.tags .content-list li'
)).
not_to
have_css
'svg.s24'
end
end
end
end
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment