source: Jenkinsfile @ 7efec15

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

Fix naming

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