Skip to content
This repository was archived by the owner on Nov 19, 2024. It is now read-only.

Commit 232fc3d

Browse files
authored
Merge pull request #601 from jenkinsci/record-coverage-again
Record coverage again
2 parents a9cd371 + 10375c7 commit 232fc3d

File tree

1 file changed

+369
-6
lines changed

1 file changed

+369
-6
lines changed

Jenkinsfile

Lines changed: 369 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,375 @@
11
def configurations = [
2-
[ platform: "docker", jdk: "11" ],
3-
[ platform: "windows", jdk: "11" ]
2+
[ platform: "linux", jdk: "17" ],
3+
[ platform: "windows", jdk: "17" ]
44
]
55

6-
buildPlugin(failFast: false, configurations: configurations, timeout: 90,
6+
def params = [
7+
failFast: false,
8+
configurations: configurations,
79
checkstyle: [qualityGates: [[threshold: 1, type: 'NEW', unstable: true]],
8-
filters:[includePackage('io.jenkins.plugins.coverage.metrics')]],
10+
filters:[includePackage('io.jenkins.plugins.coverage.metrics')]],
911
pmd: [qualityGates: [[threshold: 1, type: 'NEW', unstable: true]],
10-
filters:[includePackage('io.jenkins.plugins.coverage.metrics')]],
12+
filters:[includePackage('io.jenkins.plugins.coverage.metrics')]],
1113
spotbugs: [qualityGates: [[threshold: 1, type: 'NEW', unstable: true]],
12-
filters:[includePackage('io.jenkins.plugins.coverage.metrics')]])
14+
filters:[includePackage('io.jenkins.plugins.coverage.metrics')]],
15+
jacoco: [sourceCodeRetention: 'MODIFIED', sourceDirectories: [[path: 'plugin/src/main/java']]]
16+
]
17+
18+
properties([
19+
disableConcurrentBuilds(abortPrevious: true),
20+
buildDiscarder(logRotator(numToKeepStr: '5')),
21+
])
22+
23+
def repo = params.containsKey('repo') ? params.repo : null
24+
def failFast = params.containsKey('failFast') ? params.failFast : true
25+
def timeoutValue = params.containsKey('timeout') ? params.timeout : 60
26+
def gitDefaultBranch = params.containsKey('gitDefaultBranch') ? params.gitDefaultBranch : null
27+
def useArtifactCachingProxy = params.containsKey('useArtifactCachingProxy') ? params.useArtifactCachingProxy : true
28+
29+
def useContainerAgent = params.containsKey('useContainerAgent') ? params.useContainerAgent : false
30+
if (params.containsKey('useAci')) {
31+
infra.publishDeprecationCheck('Replace useAci with useContainerAgent', 'The parameter "useAci" is deprecated. Please use "useContainerAgent" instead as per https://issues.jenkins.io/browse/INFRA-2918.')
32+
useContainerAgent = params.containsKey('useAci')
33+
}
34+
if (timeoutValue > 180) {
35+
echo "Timeout value requested was $timeoutValue, lowering to 180 to avoid Jenkins project's resource abusive consumption"
36+
timeoutValue = 180
37+
}
38+
39+
boolean publishingIncrementals = false
40+
boolean archivedArtifacts = false
41+
Map tasks = [failFast: failFast]
42+
getConfigurations(params).each { config ->
43+
String label = ''
44+
String platform = config.platform
45+
String jdk = config.jdk
46+
String jenkinsVersion = config.jenkins
47+
if (config.containsKey('javaLevel')) {
48+
infra.publishDeprecationCheck('Remove javaLevel', 'Ignoring deprecated "javaLevel" parameter. This parameter should be removed from your "Jenkinsfile".')
49+
}
50+
51+
String stageIdentifier = "${platform}-${jdk}${jenkinsVersion ? '-' + jenkinsVersion : ''}"
52+
boolean first = tasks.size() == 1
53+
boolean skipTests = params?.tests?.skip
54+
boolean addToolEnv = !useContainerAgent
55+
56+
if (useContainerAgent) {
57+
if (platform == 'linux' || platform == 'windows') {
58+
def agentContainerLabel = jdk == '8' ? 'maven' : 'maven-' + jdk
59+
if (platform == 'windows') {
60+
agentContainerLabel += '-windows'
61+
}
62+
label = agentContainerLabel
63+
}
64+
} else {
65+
switch(platform) {
66+
case 'windows':
67+
label = 'docker-windows'
68+
break
69+
case 'linux':
70+
label = 'vm && linux'
71+
break
72+
default:
73+
echo "WARNING: Unknown platform '${platform}'. Agent label set to fallback value 'linux'"
74+
label = 'linux'
75+
}
76+
}
77+
78+
tasks[stageIdentifier] = {
79+
retry(count: 3, conditions: [kubernetesAgent(handleNonKubernetes: true), nonresumable()]) {
80+
node(label) {
81+
try {
82+
timeout(timeoutValue) {
83+
boolean isMaven
84+
// Archive artifacts once with pom declared baseline
85+
boolean doArchiveArtifacts = !jenkinsVersion && !archivedArtifacts
86+
if (doArchiveArtifacts) {
87+
archivedArtifacts = true
88+
}
89+
90+
boolean incrementals // cf. JEP-305
91+
92+
stage("Checkout (${stageIdentifier})") {
93+
infra.checkoutSCM(repo)
94+
isMaven = !fileExists('gradlew')
95+
incrementals = fileExists('.mvn/extensions.xml') &&
96+
readFile('.mvn/extensions.xml').contains('git-changelist-maven-extension')
97+
final String gitUnavailableMessage = '[buildPlugin] Git CLI may not be available'
98+
withEnv(["GITUNAVAILABLEMESSAGE=${gitUnavailableMessage}"]) {
99+
if (incrementals) { // Incrementals needs 'git status -s' to be empty at start of job
100+
if (isUnix()) {
101+
sh 'git clean -xffd || echo "$GITUNAVAILABLEMESSAGE"'
102+
} else {
103+
bat 'git clean -xffd || echo %GITUNAVAILABLEMESSAGE%'
104+
}
105+
}
106+
107+
if (gitDefaultBranch) {
108+
withEnv(["GITDEFAULTBRANCH=${gitDefaultBranch}"]) {
109+
if (isUnix()) {
110+
sh 'git config --global init.defaultBranch "$GITDEFAULTBRANCH" || echo "$GITUNAVAILABLEMESSAGE"'
111+
} else {
112+
bat 'git config --global init.defaultBranch %GITDEFAULTBRANCH% || echo %GITUNAVAILABLEMESSAGE%'
113+
}
114+
}
115+
}
116+
}
117+
}
118+
119+
String changelistF
120+
String m2repo
121+
122+
stage("Build (${stageIdentifier})") {
123+
String command
124+
if (isMaven) {
125+
m2repo = "${pwd tmp: true}/m2repo"
126+
List<String> mavenOptions = [
127+
'--update-snapshots',
128+
"-Dmaven.repo.local=$m2repo",
129+
'-Dmaven.test.failure.ignore',
130+
'-Dspotbugs.failOnError=false',
131+
'-Dcheckstyle.failOnViolation=false',
132+
'-Dcheckstyle.failsOnError=false',
133+
]
134+
// jacoco had file locking issues on Windows, so only running on linux
135+
if (isUnix()) {
136+
mavenOptions += '-Penable-jacoco'
137+
}
138+
if (incrementals) { // set changelist and activate produce-incrementals profile
139+
mavenOptions += '-Dset.changelist'
140+
if (doArchiveArtifacts) { // ask Maven for the value of -rc999.abc123def456
141+
changelistF = "${pwd tmp: true}/changelist"
142+
mavenOptions += "help:evaluate -Dexpression=changelist -Doutput=$changelistF"
143+
}
144+
}
145+
if (jenkinsVersion) {
146+
mavenOptions += "-Djenkins.version=${jenkinsVersion} -Daccess-modifier-checker.failOnError=false"
147+
}
148+
if (skipTests) {
149+
mavenOptions += '-DskipTests'
150+
}
151+
mavenOptions += 'clean install'
152+
try {
153+
infra.runMaven(mavenOptions, jdk, null, null, addToolEnv, useArtifactCachingProxy)
154+
} finally {
155+
if (!skipTests) {
156+
junit('**/target/surefire-reports/**/*.xml,**/target/failsafe-reports/**/*.xml,**/target/invoker-reports/**/*.xml')
157+
if (first) {
158+
discoverReferenceBuild()
159+
// Default configuration for JaCoCo can be overwritten using a `jacoco` parameter (map).
160+
// Configuration see: https://www.jenkins.io/doc/pipeline/steps/code-coverage-api/#recordcoverage-record-code-coverage-results
161+
Map jacocoArguments = [tools: [[parser: 'JACOCO', pattern: '**/jacoco/jacoco.xml']]]
162+
if (params?.jacoco) {
163+
jacocoArguments.putAll(params.jacoco as Map)
164+
}
165+
recordCoverage jacocoArguments
166+
167+
}
168+
}
169+
}
170+
} else {
171+
infra.publishDeprecationCheck('Replace buildPlugin with buildPluginWithGradle', 'Gradle mode for buildPlugin() is deprecated, please use buildPluginWithGradle()')
172+
List<String> gradleOptions = [
173+
'--no-daemon',
174+
'cleanTest',
175+
'build',
176+
]
177+
if (skipTests) {
178+
gradleOptions += '--exclude-task test'
179+
}
180+
command = "gradlew ${gradleOptions.join(' ')}"
181+
if (isUnix()) {
182+
command = './' + command
183+
}
184+
185+
try {
186+
infra.runWithJava(command, jdk, null, addToolEnv)
187+
} finally {
188+
if (!skipTests) {
189+
junit('**/build/test-results/**/*.xml')
190+
}
191+
}
192+
}
193+
}
194+
195+
stage("Archive (${stageIdentifier})") {
196+
if (failFast && currentBuild.result == 'UNSTABLE') {
197+
error 'There were test failures; halting early'
198+
}
199+
200+
if (first) {
201+
if (skipTests) { // otherwise the reference build has been computed already
202+
discoverReferenceBuild()
203+
}
204+
echo "Recording static analysis results on '${stageIdentifier}'"
205+
206+
recordIssues(
207+
enabledForFailure: true,
208+
tool: mavenConsole(),
209+
skipBlames: true,
210+
trendChartType: 'TOOLS_ONLY'
211+
)
212+
recordIssues(
213+
enabledForFailure: true,
214+
tools: [java(), javaDoc()],
215+
filters: [excludeFile('.*Assert.java')],
216+
sourceCodeEncoding: 'UTF-8',
217+
skipBlames: true,
218+
trendChartType: 'TOOLS_ONLY'
219+
)
220+
221+
// Default configuration for SpotBugs can be overwritten using a `spotbugs`, `checkstyle', etc. parameter (map).
222+
// Configuration see: https://github.com/jenkinsci/warnings-ng-plugin/blob/master/doc/Documentation.md#configuration
223+
Map spotbugsArguments = [tool: spotBugs(pattern: '**/target/spotbugsXml.xml,**/target/findbugsXml.xml'),
224+
sourceCodeEncoding: 'UTF-8',
225+
skipBlames: true,
226+
trendChartType: 'TOOLS_ONLY',
227+
qualityGates: [[threshold: 1, type: 'NEW', unstable: true]]]
228+
if (params?.spotbugs) {
229+
spotbugsArguments.putAll(params.spotbugs as Map)
230+
}
231+
recordIssues spotbugsArguments
232+
233+
Map checkstyleArguments = [tool: checkStyle(pattern: '**/target/checkstyle-result.xml'),
234+
sourceCodeEncoding: 'UTF-8',
235+
skipBlames: true,
236+
trendChartType: 'TOOLS_ONLY',
237+
qualityGates: [[threshold: 1, type: 'TOTAL', unstable: true]]]
238+
if (params?.checkstyle) {
239+
checkstyleArguments.putAll(params.checkstyle as Map)
240+
}
241+
recordIssues checkstyleArguments
242+
243+
Map pmdArguments = [tool: pmdParser(pattern: '**/target/pmd.xml'),
244+
sourceCodeEncoding: 'UTF-8',
245+
skipBlames: true,
246+
trendChartType: 'NONE']
247+
if (params?.pmd) {
248+
pmdArguments.putAll(params.pmd as Map)
249+
}
250+
recordIssues pmdArguments
251+
252+
Map cpdArguments = [tool: cpd(pattern: '**/target/cpd.xml'),
253+
sourceCodeEncoding: 'UTF-8',
254+
skipBlames: true,
255+
trendChartType: 'NONE']
256+
if (params?.cpd) {
257+
cpdArguments.putAll(params.cpd as Map)
258+
}
259+
recordIssues cpdArguments
260+
261+
recordIssues(
262+
enabledForFailure: true, tool: taskScanner(
263+
includePattern:'**/*.java',
264+
excludePattern:'**/target/**',
265+
highTags:'FIXME',
266+
normalTags:'TODO'),
267+
sourceCodeEncoding: 'UTF-8',
268+
skipBlames: true,
269+
trendChartType: 'NONE'
270+
)
271+
if (failFast && currentBuild.result == 'UNSTABLE') {
272+
error 'Static analysis quality gates not passed; halting early'
273+
}
274+
} else {
275+
echo "Skipping static analysis results for ${stageIdentifier}"
276+
}
277+
if (doArchiveArtifacts) {
278+
if (incrementals) {
279+
String changelist = readFile(changelistF)
280+
dir(m2repo) {
281+
fingerprint '**/*-rc*.*/*-rc*.*' // includes any incrementals consumed
282+
archiveArtifacts artifacts: "**/*$changelist/*$changelist*",
283+
excludes: '**/*.lastUpdated',
284+
allowEmptyArchive: true // in case we forgot to reincrementalify
285+
}
286+
publishingIncrementals = true
287+
} else {
288+
String artifacts
289+
if (isMaven) {
290+
artifacts = '**/target/*.hpi,**/target/*.jpi,**/target/*.jar'
291+
} else {
292+
artifacts = '**/build/libs/*.hpi,**/build/libs/*.jpi'
293+
}
294+
archiveArtifacts artifacts: artifacts, fingerprint: true
295+
}
296+
}
297+
}
298+
}
299+
} finally {
300+
if (hasDockerLabel()) {
301+
if (isUnix()) {
302+
sh 'docker system prune --force --all || echo "Failed to cleanup docker images"'
303+
} else {
304+
bat 'docker system prune --force --all || echo "Failed to cleanup docker images"'
305+
}
306+
}
307+
}
308+
}
309+
}
310+
}
311+
}
312+
313+
parallel(tasks)
314+
if (publishingIncrementals) {
315+
infra.maybePublishIncrementals()
316+
}
317+
318+
private void discoverReferenceBuild() {
319+
folders = env.JOB_NAME.split('/')
320+
if (folders.length > 1) {
321+
discoverGitReferenceBuild(scm: folders[1])
322+
}
323+
}
324+
325+
boolean hasDockerLabel() {
326+
env.NODE_LABELS?.contains('docker')
327+
}
328+
329+
List<Map<String, String>> getConfigurations(Map params) {
330+
boolean explicit = params.containsKey('configurations') && params.configurations != null
331+
boolean implicit = params.containsKey('platforms') || params.containsKey('jdkVersions') || params.containsKey('jenkinsVersions')
332+
333+
if (explicit && implicit) {
334+
error '"configurations" option can not be used with either "platforms", "jdkVersions" or "jenkinsVersions"'
335+
}
336+
337+
def configs = params.configurations
338+
configs.each { c ->
339+
if (!c.platform) {
340+
error("Configuration field \"platform\" must be specified: $c")
341+
}
342+
if (!c.jdk) {
343+
error("Configuration field \"jdk\" must be specified: $c")
344+
}
345+
}
346+
347+
if (explicit) {
348+
return params.configurations
349+
}
350+
351+
def platforms = params.containsKey('platforms') ? params.platforms : ['linux', 'windows']
352+
def jdkVersions = params.containsKey('jdkVersions') ? params.jdkVersions : ['8']
353+
def jenkinsVersions = params.containsKey('jenkinsVersions') ? params.jenkinsVersions : [null]
354+
355+
def ret = []
356+
for (p in platforms) {
357+
for (jdk in jdkVersions) {
358+
for (jenkins in jenkinsVersions) {
359+
ret << [
360+
'platform': p,
361+
'jdk': jdk,
362+
'jenkins': jenkins,
363+
]
364+
}
365+
}
366+
}
367+
return ret
368+
}
369+
370+
/**
371+
* @deprecated no longer recommended
372+
*/
373+
static List<Map<String, String>> recommendedConfigurations() {
374+
null
375+
}

0 commit comments

Comments
 (0)