Skip to content

Commit e3dadf0

Browse files
authored
Generate and upload code coverage report on PRs (#261)
* Adding jacoco plugin for aggregate report generation * running codecov on pr build * Explicitly uploading the coverage report * Adding codecov upload to master build
1 parent f0a3b3a commit e3dadf0

5 files changed

Lines changed: 163 additions & 2 deletions

File tree

.github/workflows/master-build.yml

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,28 +17,48 @@ jobs:
1717
java:
1818
- 8
1919
- 11
20+
include:
21+
- os: ubuntu-latest
22+
java: 11
23+
coverage: true
2024
steps:
2125
- name: Checkout Repository
2226
uses: actions/checkout@v1
27+
2328
- name: Setup java
2429
uses: actions/setup-java@v1
2530
with:
2631
java-version: ${{ matrix.java }}
32+
2733
- name: Cache Gradle Modules
2834
uses: actions/cache@v1
2935
with:
3036
path: ~/.gradle/caches
3137
key: gradle-caches-${{ hashFiles('**/*.gradle.kts') }}
38+
3239
- name: Cache Gradle Wrapper
3340
uses: actions/cache@v1
3441
with:
3542
path: ~/.gradle/wrapper
3643
key: gradle-wrapper-${{ hashFiles('gradle/wrapper/gradle-wrapper.properties') }}
44+
3745
- name: Execute Gradle build
38-
run: ./gradlew build --stacktrace
46+
run: ./gradlew build ${{ matrix.coverage && 'codeCoverageReport' || '' }} --stacktrace
3947
shell: bash
4048
env:
4149
CI: true
50+
51+
- uses: codecov/codecov-action@v1
52+
if: ${{ matrix.coverage }}
53+
with:
54+
files: ./jacoco/build/reports/jacoco/codeCoverageReport/codeCoverageReport.xml
55+
56+
- uses: actions/upload-artifact@v2
57+
if: ${{ matrix.coverage }}
58+
with:
59+
name: coverage-report
60+
path: jacoco/build/reports/jacoco/codeCoverageReport/html
61+
4262
publish:
4363
name: Publish snapshots
4464
runs-on: ubuntu-latest

.github/workflows/pr-build.yml

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,25 +17,44 @@ jobs:
1717
java:
1818
- 8
1919
- 11
20+
include:
21+
- os: ubuntu-latest
22+
java: 11
23+
coverage: true
2024
steps:
2125
- name: Checkout Repository
2226
uses: actions/checkout@v1
27+
2328
- name: Setup java
2429
uses: actions/setup-java@v1
2530
with:
2631
java-version: ${{ matrix.java }}
32+
2733
- name: Cache Gradle Modules
2834
uses: actions/cache@v1
2935
with:
3036
path: ~/.gradle/caches
3137
key: gradle-caches-${{ hashFiles('**/*.gradle.kts') }}
38+
3239
- name: Cache Gradle Wrapper
3340
uses: actions/cache@v1
3441
with:
3542
path: ~/.gradle/wrapper
3643
key: gradle-wrapper-${{ hashFiles('gradle/wrapper/gradle-wrapper.properties') }}
44+
3745
- name: Execute Gradle build
38-
run: ./gradlew build --stacktrace
46+
run: ./gradlew build ${{ matrix.coverage && 'codeCoverageReport' || '' }} --stacktrace
3947
shell: bash
4048
env:
4149
CI: true
50+
51+
- uses: codecov/codecov-action@v1
52+
if: ${{ matrix.coverage }}
53+
with:
54+
files: ./jacoco/build/reports/jacoco/codeCoverageReport/codeCoverageReport.xml
55+
56+
- uses: actions/upload-artifact@v2
57+
if: ${{ matrix.coverage }}
58+
with:
59+
name: coverage-report
60+
path: jacoco/build/reports/jacoco/codeCoverageReport/html

build.gradle.kts

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -302,3 +302,63 @@ allprojects {
302302
}
303303
}
304304
}
305+
306+
subprojects {
307+
group = "com.amazonaws"
308+
309+
plugins.withId("java-library") {
310+
plugins.apply("jacoco")
311+
312+
configure<JacocoPluginExtension> {
313+
toolVersion = "0.8.6"
314+
}
315+
316+
// Do not generate reports for individual projects
317+
tasks.named("jacocoTestReport") {
318+
enabled = false
319+
}
320+
321+
configurations {
322+
val implementation by getting
323+
324+
create("transitiveSourceElements") {
325+
isVisible = false
326+
isCanBeResolved = false
327+
isCanBeConsumed = true
328+
extendsFrom(implementation)
329+
attributes {
330+
attribute(Usage.USAGE_ATTRIBUTE, objects.named(Usage.JAVA_RUNTIME))
331+
attribute(Category.CATEGORY_ATTRIBUTE, objects.named(Category.DOCUMENTATION))
332+
attribute(DocsType.DOCS_TYPE_ATTRIBUTE, objects.named("source-folders"))
333+
}
334+
val mainSources = the<JavaPluginConvention>().sourceSets.getByName(SourceSet.MAIN_SOURCE_SET_NAME)
335+
mainSources.java.srcDirs.forEach {
336+
outgoing.artifact(it)
337+
}
338+
}
339+
340+
create("coverageDataElements") {
341+
isVisible = false
342+
isCanBeResolved = false
343+
isCanBeConsumed = true
344+
extendsFrom(implementation)
345+
attributes {
346+
attribute(Usage.USAGE_ATTRIBUTE, objects.named(Usage.JAVA_RUNTIME))
347+
attribute(Category.CATEGORY_ATTRIBUTE, objects.named(Category.DOCUMENTATION))
348+
attribute(DocsType.DOCS_TYPE_ATTRIBUTE, objects.named("jacoco-coverage-data"))
349+
}
350+
// This will cause the test task to run if the coverage data is requested by the aggregation task
351+
tasks.withType(Test::class) {
352+
outgoing.artifact(extensions.getByType<JacocoTaskExtension>().destinationFile!!)
353+
}
354+
}
355+
356+
configureEach {
357+
resolutionStrategy {
358+
failOnVersionConflict()
359+
preferProjectModules()
360+
}
361+
}
362+
}
363+
}
364+
}

jacoco/build.gradle.kts

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
plugins {
2+
`java-library`
3+
}
4+
5+
description = "AWS X-Ray SDK Code Coverage"
6+
7+
dependencies {
8+
rootProject.subprojects.forEach { subproject ->
9+
// Generate aggregate coverage report for published modules that enable jacoco.
10+
subproject.plugins.withId("jacoco") {
11+
subproject.plugins.withId("maven-publish") {
12+
implementation(project(subproject.path)) {
13+
isTransitive = false
14+
}
15+
}
16+
}
17+
}
18+
}
19+
20+
val sourcesPath by configurations.creating {
21+
isVisible = false
22+
isCanBeResolved = true
23+
isCanBeConsumed = false
24+
extendsFrom(configurations.implementation.get())
25+
attributes {
26+
attribute(Usage.USAGE_ATTRIBUTE, objects.named(Usage.JAVA_RUNTIME))
27+
attribute(Category.CATEGORY_ATTRIBUTE, objects.named(Category.DOCUMENTATION))
28+
attribute(DocsType.DOCS_TYPE_ATTRIBUTE, objects.named("source-folders"))
29+
}
30+
}
31+
32+
val coverageDataPath by configurations.creating {
33+
isVisible = false
34+
isCanBeResolved = true
35+
isCanBeConsumed = false
36+
extendsFrom(configurations.implementation.get())
37+
attributes {
38+
attribute(Usage.USAGE_ATTRIBUTE, objects.named(Usage.JAVA_RUNTIME))
39+
attribute(Category.CATEGORY_ATTRIBUTE, objects.named(Category.DOCUMENTATION))
40+
attribute(DocsType.DOCS_TYPE_ATTRIBUTE, objects.named("jacoco-coverage-data"))
41+
}
42+
}
43+
44+
// Task to gather code coverage from multiple subprojects
45+
val codeCoverageReport by tasks.registering(JacocoReport::class) {
46+
additionalClassDirs(configurations.runtimeClasspath.get())
47+
additionalSourceDirs(sourcesPath.incoming.artifactView { lenient(true) }.files)
48+
executionData(coverageDataPath.incoming.artifactView { lenient(true) }.files.filter { it.exists() })
49+
50+
reports {
51+
// xml is usually used to integrate code coverage with
52+
// other tools like SonarQube, Coveralls or Codecov
53+
xml.isEnabled = true
54+
55+
// HTML reports can be used to see code coverage
56+
// without any external tools
57+
html.isEnabled = true
58+
}
59+
}
60+

settings.gradle.kts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,3 +28,5 @@ include(":aws-xray-recorder-sdk-metrics")
2828

2929
// Internal project for applying dependency management.
3030
include(":dependencyManagement")
31+
// Project for generating aggregated Jacoco code coverage report.
32+
include(":jacoco")

0 commit comments

Comments
 (0)