source: Jenkinsfile @ 6e31c43

aaron-thesisarm-ehcleanup-dtorsdeferred_resndemanglerjacob/cs343-translationjenkins-sandboxnew-astnew-ast-unique-exprno_listpersistent-indexer
Last change on this file since 6e31c43 was 6e31c43, checked in by Thierry Delisle <tdelisle@…>, 3 years ago

Jenkins now passes target directory as argument

  • Property mode set to 100644
File size: 11.3 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=${Settings.GitNewRef} 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 GitLogMessage() {
181        if (!Settings || !Settings.GitOldRef || !Settings.GitNewRef) return "\nERROR retrieveing git information!\n"
182
183        sh "${SrcDir}/tools/PrettyGitLogs.sh ${BuildDir} ${Settings.GitOldRef} ${Settings.GitNewRef}"
184
185        def gitUpdate = readFile("${BuildDir}/GIT_TYPE").trim()
186        def gitLog    = readFile("${BuildDir}/GIT_LOG").trim()
187        def gitDiff   = readFile("${BuildDir}/GIT_DIFF").trim()
188
189        return """
190The branch ${env.BRANCH_NAME} has been updated.
191${gitUpdate}
192
193Check console output at ${env.BUILD_URL} to view the results.
194
195- Status --------------------------------------------------------------
196
197BUILD# ${env.BUILD_NUMBER} - ${currentBuild.result}
198
199- Log -----------------------------------------------------------------
200${gitLog}
201-----------------------------------------------------------------------
202Summary of changes:
203${gitDiff}
204"""
205}
206
207//Standard build email notification
208def email(boolean log, boolean bIsSandbox) {
209        //Since tokenizer doesn't work, figure stuff out from the environnement variables and command line
210        //Configurations for email format
211        echo 'Notifying users of result'
212
213        def project_name = (env.JOB_NAME =~ /(.+)\/.+/)[0][1].toLowerCase()
214        def email_subject = "[${project_name} git][BUILD# ${env.BUILD_NUMBER} - ${currentBuild.result}] - branch ${env.BRANCH_NAME}"
215        def email_body = """This is an automated email from the Jenkins build machine. It was
216generated because of a git hooks/post-receive script following
217a ref change which was pushed to the Cforall repository.
218""" + GitLogMessage()
219
220        def email_to = "cforall@lists.uwaterloo.ca"
221
222        if( Settings && !Settings.IsSandbox ) {
223                //send email notification
224                emailext body: email_body, subject: email_subject, to: email_to, attachLog: log
225        } else {
226                echo "Would send email to: ${email_to}"
227                echo "With title: ${email_subject}"
228                echo "Content: \n${email_body}"
229        }
230}
231
232//===========================================================================================================
233// Helper classes/variables/routines
234//===========================================================================================================
235//Description of a compiler (Must be serializable since pipelines are persistent)
236class CC_Desc implements Serializable {
237        public String cc_name
238        public String cpp_cc
239        public String cfa_cc
240
241        CC_Desc(String cc_name, String cpp_cc, String cfa_cc) {
242                this.cc_name = cc_name
243                this.cpp_cc = cpp_cc
244                this.cfa_cc = cfa_cc
245        }
246}
247
248//Description of an architecture (Must be serializable since pipelines are persistent)
249class Arch_Desc implements Serializable {
250        public String name
251        public String flags
252
253        Arch_Desc(String name, String flags) {
254                this.name  = name
255                this.flags = flags
256        }
257}
258
259class BuildSettings implements Serializable {
260        public final CC_Desc Compiler
261        public final Arch_Desc Architecture
262        public final Boolean RunAllTests
263        public final Boolean RunBenchmark
264        public final Boolean BuildDocumentation
265        public final Boolean Publish
266        public final Boolean Silent
267        public final Boolean IsSandbox
268        public final String DescLong
269        public final String DescShort
270
271        public String GitNewRef
272        public String GitOldRef
273
274        BuildSettings(java.util.Collections$UnmodifiableMap param, String branch) {
275                switch( param.Compiler ) {
276                        case 'gcc-6':
277                                this.Compiler = new CC_Desc('gcc-6', 'g++-6', 'gcc-6')
278                        break
279                        case 'gcc-5':
280                                this.Compiler = new CC_Desc('gcc-5', 'g++-5', 'gcc-5')
281                        break
282                        case 'gcc-4.9':
283                                this.Compiler = new CC_Desc('gcc-4.9', 'g++-4.9', 'gcc-4.9')
284                        break
285                        case 'clang':
286                                this.Compiler = new CC_Desc('clang', 'clang++', 'gcc-6')
287                        break
288                        default :
289                                error "Unhandled compiler : ${cc}"
290                }
291
292                switch( param.Architecture ) {
293                        case 'x64':
294                                this.Architecture = new Arch_Desc('x64', '--host=x86_64')
295                        break
296                        case 'x86':
297                                this.Architecture = new Arch_Desc('x86', '--host=i386')
298                        break
299                        default :
300                                error "Unhandled architecture : ${arch}"
301                }
302
303                this.RunAllTests        = param.RunAllTests
304                this.RunBenchmark       = param.RunBenchmark
305                this.BuildDocumentation = param.BuildDocumentation
306                this.Publish            = param.Publish
307                this.Silent             = param.Silent
308                this.IsSandbox          = (branch == "jenkins-sandbox")
309
310                def full = param.RunAllTests ? " (Full)" : ""
311                this.DescShort = "${ this.Compiler.cc_name }:${ this.Architecture.name }${full}"
312
313                this.DescLong = """Compiler              : ${ this.Compiler.cc_name } (${ this.Compiler.cpp_cc }/${ this.Compiler.cfa_cc })
314Architecture            : ${ this.Architecture.name }
315Arc Flags               : ${ this.Architecture.flags }
316Run All Tests           : ${ this.RunAllTests.toString() }
317Run Benchmark           : ${ this.RunBenchmark.toString() }
318Build Documentation     : ${ this.BuildDocumentation.toString() }
319Publish                 : ${ this.Publish.toString() }
320Silent                  : ${ this.Silent.toString() }
321"""
322
323                this.GitNewRef = ''
324                this.GitOldRef = ''
325        }
326}
327
328def prepare_build() {
329        // prepare the properties
330        properties ([                                                                                                   \
331                [$class: 'ParametersDefinitionProperty',                                                                \
332                        parameterDefinitions: [                                                                         \
333                                [$class: 'ChoiceParameterDefinition',                                           \
334                                        description: 'Which compiler to use',                                   \
335                                        name: 'Compiler',                                                                       \
336                                        choices: 'gcc-6\ngcc-5\ngcc-4.9\nclang',                                        \
337                                        defaultValue: 'gcc-6',                                                          \
338                                ],                                                                                              \
339                                [$class: 'ChoiceParameterDefinition',                                           \
340                                        description: 'The target architecture',                                 \
341                                        name: 'Architecture',                                                           \
342                                        choices: 'x64\nx86',                                                            \
343                                        defaultValue: 'x64',                                                            \
344                                ],                                                                                              \
345                                [$class: 'BooleanParameterDefinition',                                                  \
346                                        description: 'If false, only the quick test suite is ran',              \
347                                        name: 'RunAllTests',                                                            \
348                                        defaultValue: false,                                                            \
349                                ],                                                                                              \
350                                [$class: 'BooleanParameterDefinition',                                                  \
351                                        description: 'If true, jenkins also runs benchmarks',           \
352                                        name: 'RunBenchmark',                                                           \
353                                        defaultValue: false,                                                            \
354                                ],                                                                                              \
355                                [$class: 'BooleanParameterDefinition',                                                  \
356                                        description: 'If true, jenkins also builds documentation',              \
357                                        name: 'BuildDocumentation',                                                     \
358                                        defaultValue: true,                                                             \
359                                ],                                                                                              \
360                                [$class: 'BooleanParameterDefinition',                                                  \
361                                        description: 'If true, jenkins also publishes results',                 \
362                                        name: 'Publish',                                                                        \
363                                        defaultValue: false,                                                            \
364                                ],                                                                                              \
365                                [$class: 'BooleanParameterDefinition',                                                  \
366                                        description: 'If true, jenkins will not send emails',           \
367                                        name: 'Silent',                                                                         \
368                                        defaultValue: false,                                                            \
369                                ],                                                                                              \
370                        ],
371                ]])
372
373        final settings = new BuildSettings(params, env.BRANCH_NAME)
374
375        currentBuild.description = settings.DescShort
376        echo                       settings.DescLong
377
378        return settings
379}
380
381def build_stage(String name, Closure block ) {
382        StageName = name
383        echo " -------- ${StageName} -------- "
384        stage(name, block)
385}
386
387def notify_server(int wait) {
388        sh """curl --silent --show-error --data "wait=${wait}" -X POST https://cforall.uwaterloo.ca:8082/jenkins/notify > /dev/null || true"""
389        return
390}
391
392def make_doc() {
393        def err = null
394        try {
395                sh 'make clean > /dev/null'
396                sh 'make > /dev/null 2>&1'
397        }
398        catch (Exception caughtError) {
399                err = caughtError //rethrow error later
400                sh 'cat *.log'
401        }
402        finally {
403                if (err) throw err // Must re-throw exception to propagate error
404        }
405}
Note: See TracBrowser for help on using the repository browser.