-
Notifications
You must be signed in to change notification settings - Fork 27
/
Jenkinsfile
354 lines (340 loc) · 12.7 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
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
#!groovy
// Copyright IBM Corp All Rights Reserved
//
// SPDX-License-Identifier: Apache-2.0
//
// Jenkinfile will get triggered on verify and merge jobs and run basicChecks, docsBuild as a pre-tests
// and call unitTests, fvtTests to run on parallel build nodes.
// along with above mentioned tests, merge job also triggers e2e tests (fabcar, e2e_sdk_node & e2e_sdk_java)
@Library("fabric-ci-lib") _
// global shared library from ci-management repository
// https://github.com/hyperledger/ci-management/tree/master/vars (Global Shared scripts)
timestamps { // set the timestamps on the jenkins console
timeout(120) { // Build timeout set to 120 mins
node ('hyp-x') { // trigger jobs on x86_64 builds nodes
def DOC_CHANGE
def CODE_CHANGE
def failure_stage = "none"
env.MARCH = sh(returnStdout: true, script: "uname -m | sed 's/x86_64/amd64/g'").trim()
buildStages() // call buildStages
} // end node block
} // end timeout block
} // end timestamps block
def buildStages() {
try {
def nodeHome = tool 'nodejs-8.14.0'
def ROOTDIR = pwd()
stage('Clean Environment') {
// delete working directory
deleteDir()
// Clean build environment before start the build
fabBuildLibrary.cleanupEnv()
// Display jenkins environment details
fabBuildLibrary.envOutput()
}
stage('Checkout SCM') {
// Clone changes from gerrit
fabBuildLibrary.cloneRefSpec('fabric-ca')
dir("$ROOTDIR/$BASE_DIR") {
DOC_CHANGE = sh(returnStdout: true, script: "git diff-tree --no-commit-id --name-only -r HEAD | egrep '.md\$|.rst\$|.txt\$|conf.py\$|.png\$|.pptx\$|.css\$|.html\$|.ini\$' | wc -l").trim()
println DOC_CHANGE
CODE_CHANGE = sh(returnStdout: true, script: "git diff-tree --no-commit-id --name-only -r HEAD | egrep -v '.md\$|.rst\$|.txt\$|conf.py\$|.png\$|.pptx\$|.css\$|.html\$|.ini\$' | wc -l").trim()
println CODE_CHANGE
}
// Load properties from ci.properties file
props = fabBuildLibrary.loadProperties()
// Set PATH
env.GOROOT = "/opt/go/go" + props["GO_VER"] + ".linux." + "$MARCH"
env.GOPATH = "$WORKSPACE/gopath"
env.PATH = "$GOROOT/bin:$GOPATH/bin:/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin:${nodeHome}/bin:$PATH"
}
if (DOC_CHANGE > '0' && CODE_CHANGE == '0') {
sh "echo -e \033[1m ONLY DOC BUILD\033[0m"
docsBuild()
} else if (DOC_CHANGE > '0' && CODE_CHANGE > '0') {
sh "echo -e \033[1m CODE AND DOC BUILD\033[0m"
basicChecks()
docsBuild()
runTests()
} else {
sh "echo -e \033[1m CODE BUILD\033[0m"
basicChecks() // basic checks
sh "echo -e \033[1m CODE TESTS\033[0m"
runTests() // e2e on merge and unit, fvt tests on parallel
}
} finally { // post build actions
// Don't fail the build if coverage report is not generated
step([$class: 'CoberturaPublisher', autoUpdateHealth: false, autoUpdateStability: false,
coberturaReportFile: '**/coverage.xml', failUnhealthy: false, failUnstable: false,
failNoReports: false, maxNumberOfBuilds: 0, sourceEncoding: 'ASCII', zoomCoverageChart: false])
// Don't fail the build if doc output is missing
publishHTML([allowMissing: true,
alwaysLinkToLastBuild: true,
keepAll: true,
reportDir: 'html',
reportFiles: 'index.html',
reportName: 'Docs Output'
])
// Don't fail the build if there is no log file
archiveArtifacts allowEmptyArchive: true, artifacts: '**/*.log'
// Send notifications only for merge failures
if (env.JOB_TYPE == "merge") {
if (currentBuild.result == 'FAILURE') {
// Send notification to rocketChat channel
// Send merge build failure email notifications to the submitter
sendNotifications(currentBuild.result, props["CHANNEL_NAME"])
}
}
// Delete all containers
fabBuildLibrary.deleteContainers()
// Delete unused docker images (none,dev,test-vp etc..)
fabBuildLibrary.deleteUnusedImages()
// Delete workspace when build is done
cleanWs notFailBuild: true
} // end finally block
} // end build stages
def docsBuild () {
def ROOTDIR = pwd()
stage("Docs Build") {
wrap([$class: 'AnsiColorBuildWrapper', 'colorMapName': 'xterm']) {
try {
dir("$ROOTDIR/$BASE_DIR") {
sh ''' set +x -ue
echo "-------> tox VERSION"
tox --version
pip freeze
tox -edocs
cp -r docs/_build/html/ $WORKSPACE
'''
}
} catch (err) {
failure_stage = "Docs Build"
currentBuild.result = 'FAILURE'
throw err
}
}
}
}
def basicChecks() {
def ROOTDIR = pwd()
stage("Basic Checks") {
wrap([$class: 'AnsiColorBuildWrapper', 'colorMapName': 'xterm']) {
try {
dir("$ROOTDIR/$BASE_DIR") {
// runs all check conditions (license, format, imports, lint and vet)
sh 'make checks'
}
} catch (err) {
failure_stage = "basicChecks"
currentBuild.result = 'FAILURE'
throw err
}
}
}
}
def fabCar() {
def ROOTDIR = pwd()
stage("Fab Car Tests") {
withEnv(["BASE_FOLDER=${WORKSPACE}/gopath/src/github.com/hyperledger"]) {
wrap([$class: 'AnsiColorBuildWrapper', 'colorMapName': 'xterm']) {
try {
// Clone fabric-samples repository
fabBuildLibrary.cloneScm('fabric-samples', '$GERRIT_BRANCH')
sh 'echo npm version \$(npm -v)'
sh 'echo node version \$(node -v)'
// Delete all containers
fabBuildLibrary.deleteContainers()
// Delete unused docker images (none,dev,test-vp etc..)
fabBuildLibrary.deleteUnusedImages()
dir("$ROOTDIR/gopath/src/github.com/hyperledger/fabric-samples/scripts/Jenkins_Scripts") {
sh './fabcar.sh'
}
} catch (err) {
failure_stage = "fabCar"
currentBuild.result = 'FAILURE'
throw err
}
}
}
}
}
def e2e_sdk_node() {
def ROOTDIR = pwd()
stage("e2e_sdk_node") {
wrap([$class: 'AnsiColorBuildWrapper', 'colorMapName': 'xterm']) {
try {
// Clone fabric-sdk-node repository
fabBuildLibrary.cloneScm('fabric-sdk-node', '$GERRIT_BRANCH')
sh 'echo npm version \$(npm -v)'
sh 'echo node version \$(node -v)'
// Delete all containers
fabBuildLibrary.deleteContainers()
// Delete unused docker images (none,dev,test-vp etc..)
fabBuildLibrary.deleteUnusedImages()
dir("$ROOTDIR/gopath/src/github.com/hyperledger/fabric-sdk-node") {
sh '''set +x -ue
npm install
npm install -g gulp
echo " ==== Run gulp test ==== "
gulp test
'''
}
} catch (err) {
failure_stage = "e2e_sdk_node"
currentBuild.result = 'FAILURE'
throw err
}
}
}
}
def e2e_sdk_java() {
def ROOTDIR = pwd()
stage("e2e_sdk_java") {
wrap([$class: 'AnsiColorBuildWrapper', 'colorMapName': 'xterm']) {
try {
// Clone fabric-sdk-java repository
fabBuildLibrary.cloneScm('fabric-sdk-java', '$GERRIT_BRANCH')
// Delete all containers
fabBuildLibrary.deleteContainers()
// Delete unused docker images (none,dev,test-vp etc..)
fabBuildLibrary.deleteUnusedImages()
dir("$ROOTDIR/gopath/src/github.com/hyperledger/fabric-sdk-java") {
sh '''set +x -ue
export WD=$WORKSPACE/gopath/src/github.com/hyperledger/fabric-sdk-java
export GOPATH=$WD/src/test/fixture
cd $WD/src/test
chmod +x cirun.sh
./cirun.sh
'''
}
} catch (err) {
failure_stage = "e2e_sdk_java"
currentBuild.result = 'FAILURE'
throw err
}
}
}
}
def runTests() {
def ROOTDIR = pwd()
stage ("Tests") {
parallel (
"e2e-Tests" : {
// Run e2e tests only on Merge job
if (env.JOB_TYPE == "merge") {
stage("e2e-Tests") {
wrap([$class: 'AnsiColorBuildWrapper', 'colorMapName': 'xterm']) {
try {
println " ==== Build fabric-ca Images ==== "
// Build fabri-ca docker images and binaries
fabBuildLibrary.fabBuildImages('fabric-ca', 'dist docker')
println " ==== Clone fabric repository ==== "
// Clone fabric repository
fabBuildLibrary.cloneScm('fabric', '$GERRIT_BRANCH')
println " ==== Build fabric Images and Binaries ==== "
// Build fabric images and binaries
fabBuildLibrary.fabBuildImages('fabric', 'dist docker')
println " ==== Pull Thirdparty Images ==== "
// Pull thirdparty images from DockerHub
fabBuildLibrary.pullThirdPartyImages(props["FAB_BASEIMAGE_VERSION"], props["FAB_THIRDPARTY_IMAGES_LIST"])
println " ==== Pull sdk images from Nexus3 ==== "
// Pull latest stable images from nexus3
fabBuildLibrary.pullDockerImages(props["FAB_BASE_VERSION"], props["FAB_IMAGES_LIST"])
println " ==== Run fabcar Tests ==== "
// Test fabcar on fabric-samples
fabCar()
println " ==== Run sdk-node Tests ==== "
// Test e2e tests on sdk-node
e2e_sdk_node()
println " ==== Run sdk-java Tests ==== "
// Test e2e tests on sdk-java
e2e_sdk_java()
} catch (err) {
failure_stage = "e2e-Tests"
currentBuild.result = 'FAILURE'
throw err
}
}
}
}
},
"Unit Tests" : {
node('hyp-x') {
stage("UnitTests") {
wrap([$class: 'AnsiColorBuildWrapper', 'colorMapName': 'xterm']) {
try {
// delete working directory
deleteDir()
// Clean build environment before start the build
fabBuildLibrary.cleanupEnv()
// Clone repository
fabBuildLibrary.cloneRefSpec('fabric-ca')
dir("$ROOTDIR/$BASE_DIR") {
println " ==== RUN UNIT TESTS ===="
// Performs checks first and runs the go-test based unit tests
sh 'make unit-test int-tests docs'
// Stash the coverage report
stash name: "coverageReport", includes: "**/coverage.xml"
}
}
catch (err) {
failure_stage = "UnitTests"
currentBuild.result = 'FAILURE'
throw err
}
}
}
}
},
"FVT Tests" : {
node('hyp-x') {
stage("FVT Tests") {
wrap([$class: 'AnsiColorBuildWrapper', 'colorMapName': 'xterm']) {
try {
// delete working directory
deleteDir()
// Clean build environment before start the build
fabBuildLibrary.cleanupEnv()
// Clone repository
fabBuildLibrary.cloneRefSpec('fabric-ca')
dir("$ROOTDIR/$BASE_DIR") {
if(env.GERRIT_BRANCH == "master") {
println " ==== RUN FVT TESTS ==== "
sh 'make fvt-tests'
} else {
println " ==== RUN FVT TESTS ===="
sh 'make docker-clean docker-fvt'
sh 'docker run -v $PWD:/opt/gopath/src/github.com/hyperledger/fabric-ca hyperledger/fabric-ca-fvt'
}
}
} catch (err) {
failure_stage = "FVT Tests"
currentBuild.result = 'FAILURE'
throw err
}
}
}
}
},
failFast: true ) // Stop the build flow if one job fails
stage("Unstash") {
if (DOC_CHANGE > '0' && CODE_CHANGE == '0') {
// unstash not required for doc only builds
println "Unstash not required"
} else {
try {
dir("$ROOTDIR") {
println "Unstash stashed files"
// unstash coverageReport on main job
unstash 'coverageReport'
}
}
catch (err) {
failure_stage = "unstash"
currentBuild.result = 'FAILURE'
throw err
}
}
}
} // stage parallel
} // runTests