Skip to content

Commit 3633d25

Browse files
committed
Finalizing PR
- translation of junit into annotation is now done in Gradle - update wrapper to 9.1.0 for Java 25 support - rebase on main - put checkstyle markdown report into separate file
1 parent c0bfc7b commit 3633d25

File tree

8 files changed

+128
-60
lines changed

8 files changed

+128
-60
lines changed

.github/junit2annotations.py

Lines changed: 0 additions & 25 deletions
This file was deleted.

.github/workflows/code_quality.yml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,12 +56,11 @@ jobs:
5656
- name: Build with Gradle
5757
run: ./gradlew --parallel --continue checkstyleMain
5858

59-
- name: Copy Sarif
59+
- name: Merge sarif files into single file.
6060
run: ./gradlew --parallel --continue sarifCopy
6161

6262
- run: "ls build/sarif-results/*"
6363

64-
6564
- name: "Job summary"
6665
run: "cat */build/reports/checkstyle/main.md >> $GITHUB_STEP_SUMMARY"
6766

.github/workflows/tests.yml

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,9 @@ jobs:
7373
- name: Upload coverage reports to Codecov
7474
uses: codecov/codecov-action@v5
7575

76+
- name: JUnit into Github Annotations
77+
run: ./gradlew junitAsAnnotations
78+
7679
integration-tests:
7780
env:
7881
GH_TOKEN: ${{ github.token }}
@@ -110,4 +113,7 @@ jobs:
110113
**/build/test-results/*/*.xml
111114
key.core/build/reports/runallproofs/*
112115
**/build/reports/
113-
- run: "python .github/junit2annotations.py"
116+
117+
- name: JUnit into Github Annotations
118+
run: ./gradlew junitAsAnnotations
119+

build.gradle

Lines changed: 11 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
2-
31
plugins {
42
//Support for IntelliJ IDEA
53
//https://docs.gradle.org/current/userguide/idea_plugin.html
@@ -104,7 +102,7 @@ subprojects {
104102
testImplementation("org.junit.jupiter:junit-jupiter-params")
105103
testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine")
106104
testRuntimeOnly("org.junit.platform:junit-platform-launcher")
107-
testImplementation ("org.assertj:assertj-core:3.26.3")
105+
testImplementation("org.assertj:assertj-core:3.26.3")
108106
testImplementation project(':key.util')
109107

110108
// test fixtures
@@ -253,7 +251,7 @@ subprojects {
253251
}
254252

255253
doLast {
256-
checkstyleMarkdownReport(
254+
CheckstyleMarkdownReport.report(
257255
layout.buildDirectory.dir("reports/checkstyle/main.xml").get().asFile,
258256
layout.buildDirectory.dir("reports/checkstyle/main.md").get().asFile)
259257
}
@@ -523,32 +521,15 @@ tasks.register('sarifCopy', SarifJoiner) {
523521
outputFile.set(layout.buildDirectory.file("sarif-results/checkstyle.sarif"))
524522
}
525523

526-
def checkstyleMarkdownReport(File xmlFile, File targetFile) {
527-
if(!xmlFile.exists()) return
528-
def root = new groovy.xml.XmlSlurper().parseText(xmlFile.text)
529-
def out = new PrintWriter(targetFile)
530-
531-
532-
def sha= System.getenv("GITHUB_SHA") ?: "main"
533-
def host = System.getenv("GITHUB_SERVER_URL") ?: "https://github.com"
534-
def repo = System.getenv("GITHUB_REPOSITORY") ?: "keyproject/key"
535-
def baseUrl = "$host/$repo/blob/$sha"
536-
try {
537-
//out.write("### Checkstyle Report\n\n")
538-
out.write("\n\n")
539-
540-
for(xmlFileNode in root.file) {
541-
def f = file(xmlFileNode.@name.toString())
542-
def path = projectDir.relativePath(f)
543-
out.write("#### $path\n\n")
544-
def url="$baseUrl/$path"
545-
for(error in xmlFileNode.error) {
546-
out.write("\n* ${error.@severity} [${error.@message} @${error.@line}:${error.@column}]($url#L${error.@line})")
547-
}
548-
out.write("\n\n")
524+
tasks.register("junitAsAnnotations") {
525+
def source = files(fileTree(dir: '.').matching {
526+
include "*/build/test-results/test/TEST-*xml" }
527+
)
528+
inputs.files(source)
529+
530+
doLast {
531+
source.asList().forEach {
532+
JUnitGithubAnnotations.readAndPrint(it.toPath())
549533
}
550534
}
551-
finally {
552-
out.close()
553-
}
554535
}

buildSrc/build.gradle.kts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ repositories {
1010
}
1111

1212
kotlin {
13-
jvmToolchain(21)
13+
//jvmToolchain(21)
1414
}
1515

1616
dependencies {
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
import org.w3c.dom.Element
2+
import java.io.PrintWriter
3+
import java.nio.file.Path
4+
import java.nio.file.Paths
5+
import javax.xml.parsers.DocumentBuilderFactory
6+
import kotlin.io.path.exists
7+
8+
object CheckstyleMarkdownReport {
9+
@JvmStatic
10+
fun report(xmlFile: Path, targetFile: Path, projectDir: Path) {
11+
if (!xmlFile.exists()) return
12+
13+
// get variables either from the environment
14+
val sha = System.getenv("GITHUB_SHA") ?: "main"
15+
val host = System.getenv("GITHUB_SERVER_URL") ?: "https://github.com"
16+
val repo = System.getenv("GITHUB_REPOSITORY") ?: "keyproject/key"
17+
val baseUrl = "$host/$repo/blob/$sha"
18+
19+
val docBuilder = DocumentBuilderFactory.newInstance().newDocumentBuilder()
20+
val doc = docBuilder.parse(xmlFile.toFile())
21+
doc.documentElement.normalize()
22+
23+
PrintWriter(targetFile.toFile()).use { out ->
24+
out.write("\n\n")
25+
26+
val files = doc.getElementsByTagName("file")
27+
for (i in 0 until files.length) {
28+
val fileNode = files.item(i) as Element
29+
val filePath = Paths.get(fileNode.getAttribute("name"))
30+
val relativePath = projectDir.relativize(filePath).toString()
31+
val url = "$baseUrl/$relativePath"
32+
33+
out.write("#### $relativePath\n\n")
34+
35+
val errors = fileNode.getElementsByTagName("error")
36+
for (j in 0 until errors.length) {
37+
val error = errors.item(j) as Element
38+
val severity = error.getAttribute("severity")
39+
val message = error.getAttribute("message")
40+
val line = error.getAttribute("line")
41+
val column = error.getAttribute("column")
42+
out.write("\n* $severity [$message @$line:$column]")
43+
}
44+
45+
out.write("\n\n")
46+
}
47+
}
48+
}
49+
}
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
import org.w3c.dom.NodeList
2+
import java.nio.file.Path
3+
import javax.xml.parsers.DocumentBuilderFactory
4+
import javax.xml.xpath.XPathConstants
5+
import javax.xml.xpath.XPathFactory
6+
import kotlin.io.path.extension
7+
import kotlin.io.path.name
8+
import kotlin.io.path.walk
9+
10+
object JUnitGithubAnnotations {
11+
private val xqryTestcase by lazy {
12+
val xPath = XPathFactory.newInstance().newXPath()
13+
val expression = "/testsuite/testcase[./failure]"
14+
xPath.compile(expression)
15+
}
16+
17+
private val xqryFailureMessage by lazy {
18+
val xPath = XPathFactory.newInstance().newXPath()
19+
val expression = "./failure/@message"
20+
xPath.compile(expression)
21+
}
22+
23+
@JvmStatic
24+
fun readAndPrint(f: Path) {
25+
val builder = DocumentBuilderFactory.newInstance().newDocumentBuilder()
26+
val doc = builder.parse(f.toFile())
27+
val nodeList = xqryTestcase.evaluate(doc, XPathConstants.NODESET) as NodeList
28+
29+
if (nodeList.length <= 0) {
30+
return
31+
}
32+
33+
34+
// module name assuming <mod>/build/test-results/test/<file>.xml
35+
val base = f.parent.parent.parent.parent.name
36+
for (i in 0 until nodeList.length) {
37+
val node = nodeList.item(i)
38+
// failure in test case
39+
val failure = xqryFailureMessage.evaluate(node, XPathConstants.STRING) as String?
40+
val attributes = node.attributes
41+
val caseName = attributes.getNamedItem("name").textContent
42+
val classname = attributes.getNamedItem("classname").textContent
43+
val filename = "$base/${classname.replace(".", "/")}"
44+
val message = failure?.take(80) ?: ""
45+
// ::error file={name},line={line},endLine={endLine}, ={title}::{message}
46+
print("::error title=Testcase-missed,file=$filename::Error in test case '$caseName' and $message")
47+
}
48+
}
49+
50+
@JvmStatic
51+
fun readAndPrintAll(root: Path) {
52+
val reports = root.fileSystem.getPathMatcher("glob:TEST-*xml")
53+
root.walk()
54+
.filter { it.extension == "xml" }
55+
.filter { reports.matches(it) }
56+
.forEach { readAndPrint(it) }
57+
}
58+
}

gradle/wrapper/gradle-wrapper.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
distributionBase=GRADLE_USER_HOME
22
distributionPath=wrapper/dists
3-
distributionUrl=https\://services.gradle.org/distributions/gradle-9.0.0-bin.zip
3+
distributionUrl=https\://services.gradle.org/distributions/gradle-9.1.0-bin.zip
44
networkTimeout=10000
55
validateDistributionUrl=true
66
zipStoreBase=GRADLE_USER_HOME

0 commit comments

Comments
 (0)