forked from MovingBlocks/Terasology
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Jenkinsfile
201 lines (188 loc) · 9.42 KB
/
Jenkinsfile
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
// Minor housekeeping logic
boolean specialBranch = env.BRANCH_NAME.equals("master") || env.BRANCH_NAME.equals("develop")
// String to use in a property that determines artifact pruning (has to be a String not a number)
String artifactBuildsToKeep = "1"
if (specialBranch) {
artifactBuildsToKeep = "10"
}
properties([
// Needed due to the Copy Artifact plugin deciding to implement an obnoxious security feature
// that can't simply be turned off
copyArtifactPermission('*'),
// Flag for Jenkins to discard attached artifacts after x builds
buildDiscarder(logRotator(artifactNumToKeepStr: artifactBuildsToKeep)),
// configure Jenkins to abort a build if a new one is triggered for the same branch
disableConcurrentBuilds(abortPrevious: true)
])
/**
* Main pipeline definition for building the engine.
*
* It uses the Declarative Pipeline Syntax.
* See https://www.jenkins.io/doc/book/pipeline/syntax
*
* This pipeline uses Jenkins plugins to collect and report additional information about the build.
*
* - Warnings Next Generation Plugin (https://plugins.jenkins.io/warnings-ng/)
* To record issues from code scans and static analysis tools, e.g., CheckStyle or Spotbugs.
* - Git Forensics Plugin (https://plugins.jenkins.io/git-forensics/)
* To compare code scans and static analysis against a reference build from the base branch.
* - JUnit Plugin (https://plugins.jenkins.io/junit/)
* To record the results of our test suites from JUnit format.
*
*/
pipeline {
agent {
label 'ts-engine && heavy && java17'
}
stages {
// declarative pipeline does `checkout scm` automatically when hitting first stage
stage('Setup') {
steps {
echo 'Automatically checked out the things!'
sh 'chmod +x gradlew'
sh './gradlew --version'
}
}
stage('Build') {
steps {
// Jenkins sometimes doesn't run Gradle automatically in plain console mode, so make it explicit
sh './gradlew --console=plain clean extractConfig extractNatives distForLauncher testDist'
archiveArtifacts '''
gradlew,
gradle/wrapper/*,
templates/build.gradle,
templates/module.logback-test.xml,
config/**,
facades/PC/build/distributions/Terasology.zip,
engine/build/resources/main/org/terasology/engine/version/versionInfo.properties,
natives/**,
build-logic/src/**,
build-logic/*.kts
'''
}
}
stage('Unit Tests') {
steps {
sh './gradlew --console=plain unitTest'
}
post {
always {
// Gradle generates both a HTML report of the unit tests to `build/reports/tests/*`
// and XML reports to `build/test-results/*`.
// We need to upload the XML reports for visualization in Jenkins.
//
// See https://docs.gradle.org/current/userguide/java_testing.html#test_reporting
junit testResults: '**/build/test-results/unitTest/*.xml'
// Jenkins truncates large test outputs, so archive it as well.
tar file: 'build/unitTest-results.tgz', archive: true, compress: true, overwrite: true,
glob: '**/build/test-results/unitTest/*.xml'
}
}
}
stage('Publish') {
when {
expression {
specialBranch
}
}
steps {
withCredentials([usernamePassword(credentialsId: 'artifactory-gooey', \
usernameVariable: 'artifactoryUser', \
passwordVariable: 'artifactoryPass')]) {
sh '''./gradlew \\
--console=plain \\
-Dorg.gradle.internal.publish.checksums.insecure=true \\
publish \\
-PmavenUser=${artifactoryUser} \\
-PmavenPass=${artifactoryPass}
'''
}
script {
// Trigger the Omega dist job to repackage a game zip with modules
if (env.JOB_NAME.equals("Terasology/engine/develop")) {
build job: 'Terasology/Omega/develop', wait: false
} else if (env.JOB_NAME.equals("Terasology/engine/master")) {
build job: 'Terasology/Omega/master', wait: false
} else if (env.JOB_NAME.equals("Nanoware/Terasology/develop")) {
build job: 'Nanoware/Omega/develop', wait: false
} else if (env.JOB_NAME.equals("Nanoware/Terasology/master")) {
build job: 'Nanoware/Omega/master', wait: false
}
}
}
}
stage('Analytics') {
steps {
sh './gradlew --console=plain check -x test -x pmdMain -x pmdTest -x pmdJmh' // TODO: Probably more cleanly remove PMD overall if no use?
}
post {
always {
// the default resolution when omitting `defaultBranch` is to `master`
// this is wrong in our case, so explicitly set `develop` as default
// TODO: does this also work for PRs with different base branch?
discoverGitReferenceBuild(defaultBranch: 'develop')
recordIssues(skipBlames: true, enabledForFailure: true,
tool: checkStyle(pattern: '**/build/reports/checkstyle/*.xml'),
qualityGates: [
[threshold: 1, type: 'NEW_HIGH', unstable: false], // mark stage "failed" on new high findings
[threshold: 1, type: 'NEW_NORMAL', unstable: false], // mark stage "failed" on new normal findings
[threshold: 1, type: 'TOTAL_HIGH', unstable: true], // mark stage "unstable" on existing high findings
[threshold: 1, type: 'TOTAL_NORMAL', unstable: true] // mark stage "unstable" on existing normal findings
])
recordIssues(skipBlames: true, enabledForFailure: true,
tools: [
spotBugs(pattern: '**/build/reports/spotbugs/*.xml', useRankAsPriority: true)
])
recordIssues(skipBlames: true, enabledForFailure: true,
tool: taskScanner(includePattern: '**/*.java,**/*.groovy,**/*.gradle', \
lowTags: 'WIBNIF', normalTags: 'TODO', highTags: 'ASAP'))
}
}
}
stage('Documentation') {
steps {
sh './gradlew --console=plain javadoc'
step([$class: 'JavadocArchiver', javadocDir: 'engine/build/docs/javadoc', keepAll: false])
recordIssues skipBlames: true, tool: javaDoc()
}
}
stage('Integration Tests (without flaky tests)') {
steps {
sh './gradlew --console=plain integrationTest'
}
post {
always {
// Gradle generates both a HTML report of the unit tests to `build/reports/tests/*`
// and XML reports to `build/test-results/*`.
// We need to upload the XML reports for visualization in Jenkins.
//
// See https://docs.gradle.org/current/userguide/java_testing.html#test_reporting
junit testResults: '**/build/test-results/integrationTest/*.xml', allowEmptyResults: true
// Jenkins truncates large test outputs, so archive it as well.
tar file: 'build/integrationTest-results.tgz', archive: true, compress: true, overwrite: true,
glob: '**/build/test-results/integrationTest/*.xml'
}
}
}
stage('Integration Tests (flaky tests only)') {
steps {
warnError("Integration Tests Failed") { // if this errs, mark the build unstable, not failed.
sh './gradlew --console=plain integrationTestFlaky'
}
}
post {
always {
// Gradle generates both a HTML report of the unit tests to `build/reports/tests/*`
// and XML reports to `build/test-results/*`.
// We need to upload the XML reports for visualization in Jenkins.
//
// See https://docs.gradle.org/current/userguide/java_testing.html#test_reporting
junit testResults: '**/build/test-results/integrationTestFlaky/*.xml', allowEmptyResults: true
// Jenkins truncates large test outputs, so archive it as well.
tar file: 'build/integrationTestFlaky-results.tgz', archive: true, compress: true, overwrite: true,
glob: '**/build/test-results/integrationTestFlaky/*.xml'
}
}
}
}
}