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
56943486
Commit
56943486
authored
Mar 18, 2022
by
Albert Salim
Committed by
Marius Bobin
Mar 18, 2022
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Include code_coverage in presented build for runner
Changelog: added
parent
6fe7f25b
Changes
10
Hide whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
203 additions
and
29 deletions
+203
-29
app/assets/javascripts/editor/schema/ci.json
app/assets/javascripts/editor/schema/ci.json
+15
-0
app/presenters/ci/build_runner_presenter.rb
app/presenters/ci/build_runner_presenter.rb
+36
-21
doc/ci/yaml/artifacts_reports.md
doc/ci/yaml/artifacts_reports.md
+29
-2
doc/user/project/merge_requests/test_coverage_visualization.md
...ser/project/merge_requests/test_coverage_visualization.md
+1
-1
lib/api/entities/ci/job_request/artifacts.rb
lib/api/entities/ci/job_request/artifacts.rb
+1
-1
qa/qa/specs/features/browser_ui/4_verify/pipeline/create_and_process_pipeline_spec.rb
..._ui/4_verify/pipeline/create_and_process_pipeline_spec.rb
+12
-1
spec/factories/ci/builds.rb
spec/factories/ci/builds.rb
+16
-0
spec/lib/gitlab/ci/config/entry/reports/coverage_report_spec.rb
...ib/gitlab/ci/config/entry/reports/coverage_report_spec.rb
+1
-1
spec/presenters/ci/build_runner_presenter_spec.rb
spec/presenters/ci/build_runner_presenter_spec.rb
+58
-2
spec/requests/api/ci/runner/jobs_request_post_spec.rb
spec/requests/api/ci/runner/jobs_request_post_spec.rb
+34
-0
No files found.
app/assets/javascripts/editor/schema/ci.json
View file @
56943486
...
...
@@ -187,6 +187,21 @@
}
]
},
"coverage_report"
:
{
"type"
:
"object"
,
"description"
:
"Used to collect coverage reports from the job."
,
"properties"
:
{
"coverage_format"
:
{
"description"
:
"Code coverage format used by the test framework."
,
"enum"
:
[
"cobertura"
]
},
"path"
:
{
"description"
:
"Path to the coverage report file that should be parsed."
,
"type"
:
"string"
,
"minLength"
:
1
}
}
},
"codequality"
:
{
"$ref"
:
"#/definitions/string_file_list"
,
"description"
:
"Path to file or list of files with code quality report(s) (such as Code Climate)."
...
...
app/presenters/ci/build_runner_presenter.rb
View file @
56943486
...
...
@@ -64,35 +64,50 @@ module Ci
def
create_archive
(
artifacts
)
return
unless
artifacts
[
:untracked
]
||
artifacts
[
:paths
]
archive
=
{
artifact_type: :archive
,
artifact_format: :zip
,
name:
artifacts
[
:name
],
untracked:
artifacts
[
:untracked
],
paths:
artifacts
[
:paths
],
when:
artifacts
[
:when
],
expire_in:
artifacts
[
:expire_in
]
}
if
artifacts
.
dig
(
:exclude
).
present?
archive
.
merge
(
exclude:
artifacts
[
:exclude
])
else
archive
BuildArtifact
.
for_archive
(
artifacts
).
to_h
.
tap
do
|
artifact
|
artifact
.
delete
(
:exclude
)
unless
artifact
[
:exclude
].
present?
end
end
def
create_reports
(
reports
,
expire_in
:)
return
unless
reports
&
.
any?
reports
.
map
do
|
report_type
,
report_paths
|
{
artifact_type:
report_type
.
to_sym
,
artifact_format:
::
Ci
::
JobArtifact
::
TYPE_AND_FORMAT_PAIRS
.
fetch
(
report_type
.
to_sym
),
name:
::
Ci
::
JobArtifact
::
DEFAULT_FILE_NAMES
.
fetch
(
report_type
.
to_sym
),
paths:
report_paths
,
reports
.
map
{
|
report
|
BuildArtifact
.
for_report
(
report
,
expire_in
).
to_h
.
compact
}
end
BuildArtifact
=
Struct
.
new
(
:name
,
:untracked
,
:paths
,
:exclude
,
:when
,
:expire_in
,
:artifact_type
,
:artifact_format
,
keyword_init:
true
)
do
def
self
.
for_archive
(
artifacts
)
self
.
new
(
artifact_type: :archive
,
artifact_format: :zip
,
name:
artifacts
[
:name
],
untracked:
artifacts
[
:untracked
],
paths:
artifacts
[
:paths
],
when:
artifacts
[
:when
],
expire_in:
artifacts
[
:expire_in
],
exclude:
artifacts
[
:exclude
]
)
end
def
self
.
for_report
(
report
,
expire_in
)
type
,
params
=
report
if
type
==
:coverage_report
artifact_type
=
params
[
:coverage_format
].
to_sym
paths
=
[
params
[
:path
]]
else
artifact_type
=
type
paths
=
params
end
self
.
new
(
artifact_type:
artifact_type
,
artifact_format:
::
Ci
::
JobArtifact
::
TYPE_AND_FORMAT_PAIRS
.
fetch
(
artifact_type
),
name:
::
Ci
::
JobArtifact
::
DEFAULT_FILE_NAMES
.
fetch
(
artifact_type
),
paths:
paths
,
when:
'always'
,
expire_in:
expire_in
}
)
end
end
...
...
doc/ci/yaml/artifacts_reports.md
View file @
56943486
...
...
@@ -80,9 +80,14 @@ GitLab can display the results of one or more reports in:
-
The
[
security dashboard
](
../../user/application_security/security_dashboard/index.md
)
.
-
The
[
Project Vulnerability report
](
../../user/application_security/vulnerability_report/index.md
)
.
## `artifacts:reports:cobertura`
## `artifacts:reports:cobertura`
(DEPRECATED)
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/3708) in GitLab 12.9.
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/3708) in GitLab 12.9.
> - [Deprecated](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/78132) in GitLab 14.9.
WARNING:
This feature is in its end-of-life process. It is
[
deprecated
](
https://gitlab.com/gitlab-org/gitlab/-/merge_requests/78132
)
for use in GitLab
14.
8 and replaced with
`artifacts:reports:coverage_report`
.
The
`cobertura`
report collects
[
Cobertura coverage XML files
](
../../user/project/merge_requests/test_coverage_visualization.md
)
.
The collected Cobertura coverage reports upload to GitLab as an artifact.
...
...
@@ -93,6 +98,28 @@ GitLab can display the results of one or more reports in the merge request
Cobertura was originally developed for Java, but there are many third-party ports for other languages such as
JavaScript, Python, and Ruby.
## `artifacts:reports:coverage_report`
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/344533) in GitLab 14.9.
Use
`coverage_report`
to collect coverage report in Cobertura format, similar to
`artifacts:reports:cobertura`
.
NOTE:
`artifacts:reports:coverage_report`
cannot be used at the same time with
`artifacts:reports:cobertura`
.
```
yaml
artifacts
:
reports
:
coverage_report
:
coverage_format
:
cobertura
path
:
coverage/cobertura-coverage.xml
```
The collected coverage report is uploaded to GitLab as an artifact.
GitLab can display the results of coverage report in the merge request
[
diff annotations
](
../../user/project/merge_requests/test_coverage_visualization.md
)
.
## `artifacts:reports:codequality`
> [Moved](https://gitlab.com/gitlab-org/gitlab/-/issues/212499) to GitLab Free in 13.2.
...
...
doc/user/project/merge_requests/test_coverage_visualization.md
View file @
56943486
...
...
@@ -28,7 +28,7 @@ between pipeline completion and the visualization loading on the page.
For the coverage analysis to work, you have to provide a properly formatted
[
Cobertura XML
](
https://cobertura.github.io/cobertura/
)
report to
[
`artifacts:reports:cobertura`
](
../../../ci/yaml/artifacts_reports.md#artifactsreportscobertura
)
.
[
`artifacts:reports:cobertura`
](
../../../ci/yaml/artifacts_reports.md#artifactsreportscobertura
-deprecated
)
.
This format was originally developed for Java, but most coverage analysis frameworks
for other languages have plugins to add support for it, like:
...
...
lib/api/entities/ci/job_request/artifacts.rb
View file @
56943486
...
...
@@ -6,7 +6,7 @@ module API
module
JobRequest
class
Artifacts
<
Grape
::
Entity
expose
:name
expose
:untracked
expose
:untracked
,
expose_nil:
false
expose
:paths
expose
:exclude
,
expose_nil:
false
expose
:when
...
...
qa/qa/specs/features/browser_ui/4_verify/pipeline/create_and_process_pipeline_spec.rb
View file @
56943486
...
...
@@ -58,6 +58,16 @@ module QA
artifacts:
paths:
- my-artifacts/
test-coverage-report:
tags:
-
#{
executor
}
script: mkdir coverage; echo "CONTENTS" > coverage/cobertura.xml
artifacts:
reports:
coverage_report:
coverage_format: cobertura
path: coverage/cobertura.xml
YAML
}
]
...
...
@@ -71,7 +81,8 @@ module QA
'test-success'
:
'passed'
,
'test-failure'
:
'failed'
,
'test-tags-mismatch'
:
'pending'
,
'test-artifacts'
:
'passed'
'test-artifacts'
:
'passed'
,
'test-coverage-report'
:
'passed'
}.
each
do
|
job
,
status
|
Page
::
Project
::
Pipeline
::
Show
.
perform
do
|
pipeline
|
pipeline
.
click_job
(
job
)
...
...
spec/factories/ci/builds.rb
View file @
56943486
...
...
@@ -497,6 +497,22 @@ FactoryBot.define do
options
{
{}
}
end
trait
:coverage_report_cobertura
do
options
do
{
artifacts:
{
expire_in:
'7d'
,
reports:
{
coverage_report:
{
coverage_format:
'cobertura'
,
path:
'cobertura.xml'
}
}
}
}
end
end
# TODO: move Security traits to ee_ci_build
# https://gitlab.com/gitlab-org/gitlab/-/issues/210486
trait
:dast
do
...
...
spec/lib/gitlab/ci/config/entry/reports/coverage_report_spec.rb
View file @
56943486
# frozen_string_literal: true
require
'
fast_
spec_helper'
require
'spec_helper'
RSpec
.
describe
Gitlab
::
Ci
::
Config
::
Entry
::
Reports
::
CoverageReport
do
let
(
:entry
)
{
described_class
.
new
(
config
)
}
...
...
spec/presenters/ci/build_runner_presenter_spec.rb
View file @
56943486
...
...
@@ -78,16 +78,72 @@ RSpec.describe Ci::BuildRunnerPresenter do
artifact_format:
Ci
::
JobArtifact
::
TYPE_AND_FORMAT_PAIRS
.
fetch
(
file_type
),
paths:
[
filename
],
when:
'always'
}
}
.
compact
end
it
'presents correct hash'
do
expect
(
presenter
.
artifacts
.
first
).
to
include
(
report_expectation
)
expect
(
presenter
.
artifacts
).
to
contain_exactly
(
report_expectation
)
end
end
end
end
context
'when a specific coverage_report type is given'
do
let
(
:coverage_format
)
{
:cobertura
}
let
(
:filename
)
{
'cobertura-coverage.xml'
}
let
(
:coverage_report
)
{
{
path:
filename
,
coverage_format:
coverage_format
}
}
let
(
:report
)
{
{
coverage_report:
coverage_report
}
}
let
(
:build
)
{
create
(
:ci_build
,
options:
{
artifacts:
{
reports:
report
}
})
}
let
(
:expected_coverage_report
)
do
{
name:
filename
,
artifact_type:
coverage_format
,
artifact_format:
Ci
::
JobArtifact
::
TYPE_AND_FORMAT_PAIRS
.
fetch
(
coverage_format
),
paths:
[
filename
],
when:
'always'
}
end
it
'presents the coverage report hash with the coverage format'
do
expect
(
presenter
.
artifacts
).
to
contain_exactly
(
expected_coverage_report
)
end
end
context
'when a specific coverage_report type is given with another report type'
do
let
(
:coverage_format
)
{
:cobertura
}
let
(
:coverage_filename
)
{
'cobertura-coverage.xml'
}
let
(
:coverage_report
)
{
{
path:
coverage_filename
,
coverage_format:
coverage_format
}
}
let
(
:ds_filename
)
{
'gl-dependency-scanning-report.json'
}
let
(
:report
)
{
{
coverage_report:
coverage_report
,
dependency_scanning:
[
ds_filename
]
}
}
let
(
:build
)
{
create
(
:ci_build
,
options:
{
artifacts:
{
reports:
report
}
})
}
let
(
:expected_coverage_report
)
do
{
name:
coverage_filename
,
artifact_type:
coverage_format
,
artifact_format:
Ci
::
JobArtifact
::
TYPE_AND_FORMAT_PAIRS
.
fetch
(
coverage_format
),
paths:
[
coverage_filename
],
when:
'always'
}
end
let
(
:expected_ds_report
)
do
{
name:
ds_filename
,
artifact_type: :dependency_scanning
,
artifact_format:
Ci
::
JobArtifact
::
TYPE_AND_FORMAT_PAIRS
.
fetch
(
:dependency_scanning
),
paths:
[
ds_filename
],
when:
'always'
}
end
it
'presents both reports'
do
expect
(
presenter
.
artifacts
).
to
contain_exactly
(
expected_coverage_report
,
expected_ds_report
)
end
end
context
"when option has both archive and reports specification"
do
let
(
:report
)
{
{
junit:
[
'junit.xml'
]
}
}
let
(
:build
)
{
create
(
:ci_build
,
options:
{
script:
'echo'
,
artifacts:
{
**
archive
,
reports:
report
}
})
}
...
...
spec/requests/api/ci/runner/jobs_request_post_spec.rb
View file @
56943486
...
...
@@ -611,6 +611,40 @@ RSpec.describe API::Ci::Runner, :clean_gitlab_redis_shared_state do
end
end
context
'when job has code coverage report'
do
let
(
:job
)
do
create
(
:ci_build
,
:pending
,
:queued
,
:coverage_report_cobertura
,
pipeline:
pipeline
,
name:
'spinach'
,
stage:
'test'
,
stage_idx:
0
)
end
let
(
:expected_artifacts
)
do
[
{
'name'
=>
'cobertura-coverage.xml'
,
'paths'
=>
[
'cobertura.xml'
],
'when'
=>
'always'
,
'expire_in'
=>
'7d'
,
"artifact_type"
=>
"cobertura"
,
"artifact_format"
=>
"gzip"
}
]
end
it
'returns job with the correct artifact specification'
,
:aggregate_failures
do
request_job
info:
{
platform: :darwin
,
features:
{
upload_multiple_artifacts:
true
}
}
expect
(
response
).
to
have_gitlab_http_status
(
:created
)
expect
(
response
.
headers
[
'Content-Type'
]).
to
eq
(
'application/json'
)
expect
(
response
.
headers
).
not_to
have_key
(
'X-GitLab-Last-Update'
)
expect
(
runner
.
reload
.
platform
).
to
eq
(
'darwin'
)
expect
(
json_response
[
'id'
]).
to
eq
(
job
.
id
)
expect
(
json_response
[
'token'
]).
to
eq
(
job
.
token
)
expect
(
json_response
[
'job_info'
]).
to
eq
(
expected_job_info
)
expect
(
json_response
[
'git_info'
]).
to
eq
(
expected_git_info
)
expect
(
json_response
[
'artifacts'
]).
to
eq
(
expected_artifacts
)
end
end
context
'when triggered job is available'
do
let
(
:expected_variables
)
do
[{
'key'
=>
'CI_JOB_NAME'
,
'value'
=>
'spinach'
,
'public'
=>
true
,
'masked'
=>
false
},
...
...
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