source: Jenkinsfile @ 1947795

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

Move print of changeset to after checkout

  • 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                        echo 'Notifying users of result'
67                        email(currentBuild.result, log_needed, bIsSandbox)
68                }
69
70                echo 'Build Completed'
71
72                /* Must re-throw exception to propagate error */
73                if (err) {
74                        throw err
75                }
76        }
77}
78
79//===========================================================================================================
80// Main compilation routines
81//===========================================================================================================
82def clean() {
83        build_stage('Cleanup') {
84                // clean the build by wipping the build directory
85                dir(BuildDir) {
86                        deleteDir()
87                }
88        }
89}
90
91//Compilation script is done here but environnement set-up and error handling is done in main loop
92def checkout() {
93        build_stage('Checkout') {
94                //checkout the source code and clean the repo
95                checkout scm
96
97                echo "${currentBuild.changeSets}"
98        }
99}
100
101def build() {
102        build_stage('Build') {
103                // Build outside of the src tree to ease cleaning
104                dir (BuildDir) {
105                        //Configure the conpilation (Output is not relevant)
106                        //Use the current directory as the installation target so nothing escapes the sandbox
107                        //Also specify the compiler by hand
108                        targets=""
109                        if( Settings.RunAllTests ) {
110                                targets="--with-target-hosts='host:debug,host:nodebug'"
111                        } else {
112                                targets="--with-target-hosts='host:debug'"
113                        }
114
115                        sh "${SrcDir}/configure CXX=${Settings.Compiler.cpp_cc} ${Settings.Architecture.flags} ${targets} --with-backend-compiler=${Settings.Compiler.cfa_cc} --quiet"
116
117                        //Compile the project
118                        sh 'make -j 8 --no-print-directory'
119                }
120        }
121}
122
123def test() {
124        build_stage('Test') {
125
126                dir (BuildDir) {
127                        //Run the tests from the tests directory
128                        if ( Settings.RunAllTests ) {
129                                sh 'make --no-print-directory -C tests all-tests debug=yes'
130                                sh 'make --no-print-directory -C tests all-tests debug=no '
131                        }
132                        else {
133                                sh 'make --no-print-directory -C tests'
134                        }
135                }
136        }
137}
138
139def benchmark() {
140        build_stage('Benchmark') {
141
142                if( !Settings.RunBenchmark ) return
143
144                dir (BuildDir) {
145                        //Append bench results
146                        sh "make --no-print-directory -C benchmark jenkins githash=${gitRefNewValue} arch=${Settings.Architecture} | tee ${SrcDir}/bench.json"
147                }
148        }
149}
150
151def build_doc() {
152        build_stage('Documentation') {
153
154                if( !Settings.BuildDocumentation ) return
155
156                dir ('doc/user') {
157                        make_doc()
158                }
159
160                dir ('doc/refrat') {
161                        make_doc()
162                }
163        }
164}
165
166def publish() {
167        build_stage('Publish') {
168
169                if( !Settings.Publish ) return
170
171                //Then publish the results
172                sh 'curl --silent --show-error -H \'Content-Type: application/json\' --data @bench.json https://cforall.uwaterloo.ca:8082/jenkins/publish > /dev/null || true'
173        }
174}
175
176//===========================================================================================================
177//Routine responsible of sending the email notification once the build is completed
178//===========================================================================================================
179def gitBranchUpdate(String gitRefOldValue, String gitRefNewValue) {
180        def update = ""
181        sh "git rev-list ${gitRefOldValue}..${gitRefNewValue} > GIT_LOG";
182        readFile('GIT_LOG').eachLine { rev ->
183                sh "git cat-file -t ${rev} > GIT_TYPE"
184                def type = readFile('GIT_TYPE')
185
186                update += "       via  ${rev} (${type})\n"
187        }
188        def rev = gitRefOldValue
189        sh "git cat-file -t ${rev} > GIT_TYPE"
190        def type = readFile('GIT_TYPE')
191
192        update += "      from  ${rev} (${type})\n"
193        return update
194
195        def output=readFile('result').trim()
196        echo "output=$output";
197}
198
199//Standard build email notification
200def email(String status, boolean log, boolean bIsSandbox) {
201        //Since tokenizer doesn't work, figure stuff out from the environnement variables and command line
202        //Configurations for email format
203        def project_name = (env.JOB_NAME =~ /(.+)\/.+/)[0][1].toLowerCase()
204
205        def gitLog = 'Error retrieving git logs'
206        def gitDiff = 'Error retrieving git diff'
207        def gitUpdate = 'Error retrieving update'
208
209        try {
210                final scmVars = checkout(scm)
211
212                gitUpdate = gitBranchUpdate(scmVars.GIT_PREVIOUS_COMMIT, scmVars.GIT_COMMIT)
213
214                sh "git rev-list --format=short ${scmVars.GIT_PREVIOUS_COMMIT}...${scmVars.GIT_COMMIT} > ${BuildDir}/GIT_LOG"
215                gitLog = readFile("${BuildDir}/GIT_LOG")
216
217                sh "git diff --stat ${scmVars.GIT_COMMIT} ${scmVars.GIT_PREVIOUS_COMMIT} > ${BuildDir}/GIT_DIFF"
218                gitDiff = readFile("${BuildDir}/GIT_DIFF")
219        }
220        catch (Exception error) {
221                echo error.toString()
222                echo error.getMessage()
223        }
224
225        def email_subject = "[${project_name} git][BUILD# ${env.BUILD_NUMBER} - ${status}] - branch ${env.BRANCH_NAME}"
226        def email_body = """This is an automated email from the Jenkins build machine. It was
227generated because of a git hooks/post-receive script following
228a ref change was pushed to the repository containing
229the project "UNNAMED PROJECT".
230
231The branch ${env.BRANCH_NAME} has been updated.
232${gitUpdate}
233
234Check console output at ${env.BUILD_URL} to view the results.
235
236- Status --------------------------------------------------------------
237
238BUILD# ${env.BUILD_NUMBER} - ${status}
239
240- Log -----------------------------------------------------------------
241${gitLog}
242-----------------------------------------------------------------------
243Summary of changes:
244${gitDiff}
245"""
246
247        def email_to = "cforall@lists.uwaterloo.ca"
248
249        if( Settings && !Settings.IsSandbox ) {
250                //send email notification
251                emailext body: email_body, subject: email_subject, to: email_to, attachLog: log
252        } else {
253                echo "Would send email to: ${email_to}"
254                echo "With title: ${email_subject}"
255                echo "Content: \n${email_body}"
256        }
257}
258
259//===========================================================================================================
260// Helper classes/variables/routines
261//===========================================================================================================
262//Description of a compiler (Must be serializable since pipelines are persistent)
263class CC_Desc implements Serializable {
264        public String cc_name
265        public String cpp_cc
266        public String cfa_cc
267
268        CC_Desc(String cc_name, String cpp_cc, String cfa_cc) {
269                this.cc_name = cc_name
270                this.cpp_cc = cpp_cc
271                this.cfa_cc = cfa_cc
272        }
273}
274
275//Description of an architecture (Must be serializable since pipelines are persistent)
276class Arch_Desc implements Serializable {
277        public String name
278        public String flags
279
280        Arch_Desc(String name, String flags) {
281                this.name  = name
282                this.flags = flags
283        }
284}
285
286class BuildSettings implements Serializable {
287        public final CC_Desc Compiler
288        public final Arch_Desc Architecture
289        public final Boolean RunAllTests
290        public final Boolean RunBenchmark
291        public final Boolean BuildDocumentation
292        public final Boolean Publish
293        public final Boolean Silent
294        public final Boolean IsSandbox
295        public final String DescLong
296        public final String DescShort
297
298        BuildSettings(java.util.Collections$UnmodifiableMap param, String branch) {
299                switch( param.Compiler ) {
300                        case 'gcc-6':
301                                this.Compiler = new CC_Desc('gcc-6', 'g++-6', 'gcc-6')
302                        break
303                        case 'gcc-5':
304                                this.Compiler = new CC_Desc('gcc-5', 'g++-5', 'gcc-5')
305                        break
306                        case 'gcc-4.9':
307                                this.Compiler = new CC_Desc('gcc-4.9', 'g++-4.9', 'gcc-4.9')
308                        break
309                        case 'clang':
310                                this.Compiler = new CC_Desc('clang', 'clang++', 'gcc-6')
311                        break
312                        default :
313                                error "Unhandled compiler : ${cc}"
314                }
315
316                switch( param.Architecture ) {
317                        case 'x64':
318                                this.Architecture = new Arch_Desc('x64', '--host=x86_64')
319                        break
320                        case 'x86':
321                                this.Architecture = new Arch_Desc('x86', '--host=i386')
322                        break
323                        default :
324                                error "Unhandled architecture : ${arch}"
325                }
326
327                this.RunAllTests        = param.RunAllTests
328                this.RunBenchmark       = param.RunBenchmark
329                this.BuildDocumentation = param.BuildDocumentation
330                this.Publish            = param.Publish
331                this.Silent             = param.Silent
332                this.IsSandbox          = (branch == "jenkins-sandbox")
333
334                def full = param.RunAllTests ? " (Full)" : ""
335                this.DescShort = "${ this.Compiler.cc_name }:${ this.Architecture.name }${full}"
336
337                this.DescLong = """Compiler              : ${ this.Compiler.cc_name } (${ this.Compiler.cpp_cc }/${ this.Compiler.cfa_cc })
338Architecture            : ${ this.Architecture.name }
339Arc Flags               : ${ this.Architecture.flags }
340Run All Tests           : ${ this.RunAllTests.toString() }
341Run Benchmark           : ${ this.RunBenchmark.toString() }
342Build Documentation     : ${ this.BuildDocumentation.toString() }
343Publish                 : ${ this.Publish.toString() }
344Silent                  : ${ this.Silent.toString() }
345"""
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.