source: Jenkinsfile @ e0549dba

ADTaaron-thesisarm-ehast-experimentalcleanup-dtorsdeferred_resndemanglerenumforall-pointer-decayjacob/cs343-translationjenkins-sandboxnew-astnew-ast-unique-exprno_listpersistent-indexerpthread-emulationqualifiedEnum
Last change on this file since e0549dba was e0549dba, checked in by Thierry Delisle <tdelisle@…>, 6 years ago

Fix error and print current build

  • Property mode set to 100644
File size: 11.9 KB
Line 
1#!groovy
2
3//===========================================================================================================
4// Main loop of the compilation
5//===========================================================================================================
6node ('master'){
7
8        // Globals
9        BuildDir  = pwd tmp: true
10        SrcDir    = pwd tmp: false
11        Settings  = null
12        StageName = ''
13
14        // Local variables
15        def err = null
16        def log_needed = false
17
18        currentBuild.result = "SUCCESS"
19
20        try {
21                //Wrap build to add timestamp to command line
22                wrap([$class: 'TimestamperBuildWrapper']) {
23
24                        notify_server(0)
25
26                        Settings = prepare_build()
27                        echo "${currentBuild.changeSets}"
28
29                        clean()
30
31                        checkout()
32
33                        notify_server(0)
34
35                        build()
36
37                        test()
38
39                        benchmark()
40
41                        build_doc()
42
43                        publish()
44
45                        notify_server(45)
46                }
47        }
48
49        //If an exception is caught we need to change the status and remember to
50        //attach the build log to the email
51        catch (Exception caughtError) {
52                //rethrow error later
53                err = caughtError
54
55                echo err.toString()
56
57                //An error has occured, the build log is relevent
58                log_needed = true
59
60                //Store the result of the build log
61                currentBuild.result = "${StageName} FAILURE".trim()
62        }
63
64        finally {
65                //Send email with final results if this is not a full build
66                if( Settings && !Settings.Silent ) {
67                        echo 'Notifying users of result'
68                        email(currentBuild.result, log_needed, bIsSandbox)
69                }
70
71                echo 'Build Completed'
72
73                /* Must re-throw exception to propagate error */
74                if (err) {
75                        throw err
76                }
77        }
78}
79
80//===========================================================================================================
81// Main compilation routines
82//===========================================================================================================
83def clean() {
84        build_stage('Cleanup') {
85                // clean the build by wipping the build directory
86                dir(BuildDir) {
87                        deleteDir()
88                }
89        }
90}
91
92//Compilation script is done here but environnement set-up and error handling is done in main loop
93def checkout() {
94        build_stage('Checkout') {
95                //checkout the source code and clean the repo
96                checkout scm
97        }
98}
99
100def build() {
101        build_stage('Build') {
102                // Build outside of the src tree to ease cleaning
103                dir (BuildDir) {
104                        //Configure the conpilation (Output is not relevant)
105                        //Use the current directory as the installation target so nothing escapes the sandbox
106                        //Also specify the compiler by hand
107                        targets=""
108                        if( Settings.RunAllTests ) {
109                                targets="--with-target-hosts='host:debug,host:nodebug'"
110                        } else {
111                                targets="--with-target-hosts='host:debug'"
112                        }
113
114                        sh "${SrcDir}/configure CXX=${Settings.Compiler.cpp_cc} ${Settings.Architecture.flags} ${targets} --with-backend-compiler=${Settings.Compiler.cfa_cc} --quiet"
115
116                        //Compile the project
117                        sh 'make -j 8 --no-print-directory'
118                }
119        }
120}
121
122def test() {
123        build_stage('Test') {
124
125                dir (BuildDir) {
126                        //Run the tests from the tests directory
127                        if ( Settings.RunAllTests ) {
128                                sh 'make --no-print-directory -C tests all-tests debug=yes'
129                                sh 'make --no-print-directory -C tests all-tests debug=no '
130                        }
131                        else {
132                                sh 'make --no-print-directory -C tests'
133                        }
134                }
135        }
136}
137
138def benchmark() {
139        build_stage('Benchmark') {
140
141                if( !Settings.RunBenchmark ) return
142
143                dir (BuildDir) {
144                        //Append bench results
145                        sh "make --no-print-directory -C benchmark jenkins githash=${gitRefNewValue} arch=${Settings.Architecture} | tee ${SrcDir}/bench.json"
146                }
147        }
148}
149
150def build_doc() {
151        build_stage('Documentation') {
152
153                if( !Settings.BuildDocumentation ) return
154
155                dir ('doc/user') {
156                        make_doc()
157                }
158
159                dir ('doc/refrat') {
160                        make_doc()
161                }
162        }
163}
164
165def publish() {
166        build_stage('Publish') {
167
168                if( !Settings.Publish ) return
169
170                //Then publish the results
171                sh 'curl --silent --show-error -H \'Content-Type: application/json\' --data @bench.json https://cforall.uwaterloo.ca:8082/jenkins/publish > /dev/null || true'
172        }
173}
174
175//===========================================================================================================
176//Routine responsible of sending the email notification once the build is completed
177//===========================================================================================================
178def gitBranchUpdate(String gitRefOldValue, String gitRefNewValue) {
179        def update = ""
180        sh "git rev-list ${gitRefOldValue}..${gitRefNewValue} > GIT_LOG";
181        readFile('GIT_LOG').eachLine { rev ->
182                sh "git cat-file -t ${rev} > GIT_TYPE"
183                def type = readFile('GIT_TYPE')
184
185                update += "       via  ${rev} (${type})\n"
186        }
187        def rev = gitRefOldValue
188        sh "git cat-file -t ${rev} > GIT_TYPE"
189        def type = readFile('GIT_TYPE')
190
191        update += "      from  ${rev} (${type})\n"
192        return update
193
194        def output=readFile('result').trim()
195        echo "output=$output";
196}
197
198//Standard build email notification
199def email(String status, boolean log, boolean bIsSandbox) {
200        //Since tokenizer doesn't work, figure stuff out from the environnement variables and command line
201        //Configurations for email format
202        def project_name = (env.JOB_NAME =~ /(.+)\/.+/)[0][1].toLowerCase()
203
204        def gitLog = 'Error retrieving git logs'
205        def gitDiff = 'Error retrieving git diff'
206        def gitUpdate = 'Error retrieving update'
207
208        try {
209                final scmVars = checkout(scm)
210
211                gitUpdate = gitBranchUpdate(scmVars.GIT_PREVIOUS_COMMIT, scmVars.GIT_COMMIT)
212
213                sh "git rev-list --format=short ${scmVars.GIT_PREVIOUS_COMMIT}...${scmVars.GIT_COMMIT} > ${BuildDir}/GIT_LOG"
214                gitLog = readFile("${BuildDir}/GIT_LOG")
215
216                sh "git diff --stat ${scmVars.GIT_COMMIT} ${scmVars.GIT_PREVIOUS_COMMIT} > ${BuildDir}/GIT_DIFF"
217                gitDiff = readFile("${BuildDir}/GIT_DIFF")
218        }
219        catch (Exception error) {
220                echo error.toString()
221                echo error.getMessage()
222        }
223
224        def email_subject = "[${project_name} git][BUILD# ${env.BUILD_NUMBER} - ${status}] - branch ${env.BRANCH_NAME}"
225        def email_body = """This is an automated email from the Jenkins build machine. It was
226generated because of a git hooks/post-receive script following
227a ref change was pushed to the repository containing
228the project "UNNAMED PROJECT".
229
230The branch ${env.BRANCH_NAME} has been updated.
231${gitUpdate}
232
233Check console output at ${env.BUILD_URL} to view the results.
234
235- Status --------------------------------------------------------------
236
237BUILD# ${env.BUILD_NUMBER} - ${status}
238
239- Log -----------------------------------------------------------------
240${gitLog}
241-----------------------------------------------------------------------
242Summary of changes:
243${gitDiff}
244"""
245
246        def email_to = "cforall@lists.uwaterloo.ca"
247
248        if( Settings && !Settings.IsSandbox ) {
249                //send email notification
250                emailext body: email_body, subject: email_subject, to: email_to, attachLog: log
251        } else {
252                echo "Would send email to: ${email_to}"
253                echo "With title: ${email_subject}"
254                echo "Content: \n${email_body}"
255        }
256}
257
258//===========================================================================================================
259// Helper classes/variables/routines
260//===========================================================================================================
261//Description of a compiler (Must be serializable since pipelines are persistent)
262class CC_Desc implements Serializable {
263        public String cc_name
264        public String cpp_cc
265        public String cfa_cc
266
267        CC_Desc(String cc_name, String cpp_cc, String cfa_cc) {
268                this.cc_name = cc_name
269                this.cpp_cc = cpp_cc
270                this.cfa_cc = cfa_cc
271        }
272}
273
274//Description of an architecture (Must be serializable since pipelines are persistent)
275class Arch_Desc implements Serializable {
276        public String name
277        public String flags
278
279        Arch_Desc(String name, String flags) {
280                this.name  = name
281                this.flags = flags
282        }
283}
284
285class BuildSettings implements Serializable {
286        public final CC_Desc Compiler
287        public final Arch_Desc Architecture
288        public final Boolean RunAllTests
289        public final Boolean RunBenchmark
290        public final Boolean BuildDocumentation
291        public final Boolean Publish
292        public final Boolean Silent
293        public final Boolean IsSandbox
294        public final String DescLong
295        public final String DescShort
296
297        BuildSettings(java.util.Collections$UnmodifiableMap param, String branch) {
298                switch( param.Compiler ) {
299                        case 'gcc-6':
300                                this.Compiler = new CC_Desc('gcc-6', 'g++-6', 'gcc-6')
301                        break
302                        case 'gcc-5':
303                                this.Compiler = new CC_Desc('gcc-5', 'g++-5', 'gcc-5')
304                        break
305                        case 'gcc-4.9':
306                                this.Compiler = new CC_Desc('gcc-4.9', 'g++-4.9', 'gcc-4.9')
307                        break
308                        case 'clang':
309                                this.Compiler = new CC_Desc('clang', 'clang++', 'gcc-6')
310                        break
311                        default :
312                                error "Unhandled compiler : ${cc}"
313                }
314
315                switch( param.Architecture ) {
316                        case 'x64':
317                                this.Architecture = new Arch_Desc('x64', '--host=x86_64')
318                        break
319                        case 'x86':
320                                this.Architecture = new Arch_Desc('x86', '--host=i386')
321                        break
322                        default :
323                                error "Unhandled architecture : ${arch}"
324                }
325
326                this.RunAllTests        = param.RunAllTests
327                this.RunBenchmark       = param.RunBenchmark
328                this.BuildDocumentation = param.BuildDocumentation
329                this.Publish            = param.Publish
330                this.Silent             = param.Silent
331                this.IsSandbox          = (branch == "jenkins-sandbox")
332
333                def full = param.RunAllTests ? " (Full)" : ""
334                this.DescShort = "${ this.Compiler.cc_name }:${ this.Architecture.name }${full}"
335
336                this.DescLong = """Compiler              : ${ this.Compiler.cc_name } (${ this.Compiler.cpp_cc }/${ this.Compiler.cfa_cc })
337Architecture            : ${ this.Architecture.name }
338Arc Flags               : ${ this.Architecture.flags }
339Run All Tests           : ${ this.RunAllTests.toString() }
340Run Benchmark           : ${ this.RunBenchmark.toString() }
341Build Documentation     : ${ this.BuildDocumentation.toString() }
342Publish                 : ${ this.Publish.toString() }
343Silent                  : ${ this.Silent.toString() }
344"""
345        }
346}
347
348def prepare_build() {
349        // prepare the properties
350        properties ([                                                                                                   \
351                [$class: 'ParametersDefinitionProperty',                                                                \
352                        parameterDefinitions: [                                                                         \
353                                [$class: 'ChoiceParameterDefinition',                                           \
354                                        description: 'Which compiler to use',                                   \
355                                        name: 'Compiler',                                                                       \
356                                        choices: 'gcc-6\ngcc-5\ngcc-4.9\nclang',                                        \
357                                        defaultValue: 'gcc-6',                                                          \
358                                ],                                                                                              \
359                                [$class: 'ChoiceParameterDefinition',                                           \
360                                        description: 'The target architecture',                                 \
361                                        name: 'Architecture',                                                           \
362                                        choices: 'x64\nx86',                                                            \
363                                        defaultValue: 'x64',                                                            \
364                                ],                                                                                              \
365                                [$class: 'BooleanParameterDefinition',                                                  \
366                                        description: 'If false, only the quick test suite is ran',              \
367                                        name: 'RunAllTests',                                                            \
368                                        defaultValue: false,                                                            \
369                                ],                                                                                              \
370                                [$class: 'BooleanParameterDefinition',                                                  \
371                                        description: 'If true, jenkins also runs benchmarks',           \
372                                        name: 'RunBenchmark',                                                           \
373                                        defaultValue: false,                                                            \
374                                ],                                                                                              \
375                                [$class: 'BooleanParameterDefinition',                                                  \
376                                        description: 'If true, jenkins also builds documentation',              \
377                                        name: 'BuildDocumentation',                                                     \
378                                        defaultValue: true,                                                             \
379                                ],                                                                                              \
380                                [$class: 'BooleanParameterDefinition',                                                  \
381                                        description: 'If true, jenkins also publishes results',                 \
382                                        name: 'Publish',                                                                        \
383                                        defaultValue: false,                                                            \
384                                ],                                                                                              \
385                                [$class: 'BooleanParameterDefinition',                                                  \
386                                        description: 'If true, jenkins will not send emails',           \
387                                        name: 'Silent',                                                                         \
388                                        defaultValue: false,                                                            \
389                                ],                                                                                              \
390                        ],
391                ]])
392
393        final settings = new BuildSettings(params, env.BRANCH_NAME)
394
395        currentBuild.description = settings.DescShort
396        echo                       settings.DescLong
397
398        return settings
399}
400
401def build_stage(String name, Closure block ) {
402        StageName = name
403        echo " -------- ${StageName} -------- "
404        stage(name, block)
405}
406
407def notify_server(int wait) {
408        sh """curl --silent --show-error --data "wait=${wait}" -X POST https://cforall.uwaterloo.ca:8082/jenkins/notify > /dev/null || true"""
409        return
410}
411
412def make_doc() {
413        def err = null
414        try {
415                sh 'make clean > /dev/null'
416                sh 'make > /dev/null 2>&1'
417        }
418        catch (Exception caughtError) {
419                err = caughtError //rethrow error later
420                sh 'cat *.log'
421        }
422        finally {
423                if (err) throw err // Must re-throw exception to propagate error
424        }
425}
Note: See TracBrowser for help on using the repository browser.