source: Jenkinsfile @ 18e2758

aaron-thesisarm-ehcleanup-dtorsctordeferred_resndemanglerenumforall-pointer-decaygc_noraiijacob/cs343-translationjenkins-sandboxmemorynew-astnew-ast-unique-exprnew-envno_listpersistent-indexerpthread-emulationqualifiedEnumresolv-newwith_gc
Last change on this file since 18e2758 was 18e2758, checked in by Thierry Delisle <tdelisle@…>, 6 years ago

Jenkinsfile now builds documentation as well

  • Property mode set to 100644
File size: 8.9 KB
Line 
1#!groovy
2
3//===========================================================================================================
4// Main compilation routine
5//===========================================================================================================
6//Compilation script is done here but environnement set-up and error handling is done in main loop
7def cfa_build(boolean full_build) {
8        build_stage 'Checkout'
9                def install_dir = pwd tmp: true
10                //checkout the source code and clean the repo
11                checkout scm
12
13                //Clean all temporary files to make sure no artifacts of the previous build remain
14                sh 'git clean -fdqx'
15
16                //Reset the git repo so no local changes persist
17                sh 'git reset --hard'
18
19        build_stage 'Build'
20
21                //Configure the conpilation (Output is not relevant)
22                //Use the current directory as the installation target so nothing
23                //escapes the sandbox
24                //Also specify the compiler by hand
25                sh "./configure CXX=${currentCC.cpp_cc} --with-backend-compiler=${currentCC.cfa_backend_cc} --prefix=${install_dir} --enable-silent-rules --quiet"
26
27                //Compile the project
28                sh 'make -j 8 --no-print-directory V=0 install'
29
30        build_stage 'Test'
31
32                //Run the tests from the tests directory
33                dir ('src/tests') {
34                        if (full_build) {
35                                sh 'python test.py --all'
36                        }
37                        else {
38                                sh './runTests.sh'
39                        }
40                }
41
42        build_stage 'Cleanup'
43
44                //do a maintainer-clean to make sure we need to remake from scratch
45                sh 'make maintainer-clean > /dev/null'
46}
47
48def doc_build() {
49        build_stage 'Documentation'
50
51                dir ('doc/user') {
52                        sh 'make clean'
53                        sh 'make'
54                }
55
56                dir ('doc/refrat') {
57                        sh 'make clean'
58                        sh 'make'
59                }
60}
61
62def push_build() {
63        //Don't use the build_stage function which outputs the compiler
64        stage 'Push'
65
66                status_prefix = 'Push'
67
68                def out_dir = pwd tmp: true
69                sh "mkdir -p ${out_dir}"
70
71                //parse git logs to find what changed
72                sh "git remote > ${out_dir}/GIT_REMOTE"
73                git_remote = readFile("${out_dir}/GIT_REMOTE")
74                remoteDoLangExists = git_remote.contains("DoLang")
75
76                if( !remoteDoLangExists ) {
77                        sh 'git remote add DoLang git@gitlab.do-lang.org:internal/cfa-cc.git'
78                }
79
80                sh "git push DoLang ${gitRefNewValue}:master"
81}
82
83//===========================================================================================================
84// Helper classes/variables/routines to make the status and stage name easier to use
85//===========================================================================================================
86//Description of a compiler (Must be serializable since pipelines are persistent)
87class CC_Desc implements Serializable {
88        public String cc_name
89        public String cpp_cc
90        public String cfa_backend_cc
91
92        CC_Desc(String cc_name, String cpp_cc, String cfa_backend_cc) {
93                this.cc_name = cc_name
94                this.cpp_cc = cpp_cc
95                this.cfa_backend_cc = cfa_backend_cc
96        }
97}
98
99//Global Variables defining the compiler and at which point in the build we are
100// These variables are used but can't be declared before hand because of wierd scripting rules
101// @Field String currentCC
102// @Field String status_prefix
103
104//Wrapper to sync stage name and status name
105def build_stage(String name) {
106        def stage_name = "${currentCC.cc_name} ${name}".trim()
107        stage stage_name
108
109                status_prefix = stage_name
110}
111
112//Helper routine to collect information about the git history
113def collect_git_info() {
114
115        //create the temporary output directory in case it doesn't already exist
116        def out_dir = pwd tmp: true
117        sh "mkdir -p ${out_dir}"
118
119        //parse git logs to find what changed
120        gitRefName = env.BRANCH_NAME
121        dir("../${gitRefName}@script") {
122                sh "git reflog > ${out_dir}/GIT_COMMIT"
123        }
124        git_reflog = readFile("${out_dir}/GIT_COMMIT")
125        gitRefOldValue = (git_reflog =~ /moving from (.+) to (.+)/)[0][1]
126        gitRefNewValue = (git_reflog =~ /moving from (.+) to (.+)/)[0][2]
127}
128
129//===========================================================================================================
130// Main loop of the compilation
131//===========================================================================================================
132node ('master'){
133
134        boolean doPromoteBuild2DoLang
135        def err = null
136        def log_needed = false
137        currentBuild.result = "SUCCESS"
138        status_prefix = ''
139
140        try {
141                //Prevent the build from exceeding 30 minutes
142                timeout(60) {
143
144                        //Wrap build to add timestamp to command line
145                        wrap([$class: 'TimestamperBuildWrapper']) {
146
147                                collect_git_info()
148
149                                properties ([                                                                   \
150                                        [$class: 'ParametersDefinitionProperty',                                \
151                                                parameterDefinitions: [                                         \
152                                                [$class: 'BooleanParameterDefinition',                          \
153                                                  defaultValue: false,                                          \
154                                                  description: 'If true, the build will be promoted to the do-lang git repository (on successful builds only)', \
155                                                  name: 'promoteBuild2DoLang'                           \
156                                                ]]                                                                      \
157                                        ]])
158
159                                doPromoteBuild2DoLang = promoteBuild2DoLang == 'true'
160
161                                echo "FULL BUILD = ${doPromoteBuild2DoLang}"
162
163                                //Compile using gcc-4.9
164                                currentCC = new CC_Desc('gcc-4.9', 'g++-4.9', 'gcc-4.9')
165                                cfa_build(doPromoteBuild2DoLang)
166
167                                //Compile using gcc-5
168                                currentCC = new CC_Desc('gcc-5', 'g++-5', 'gcc-5')
169                                cfa_build(doPromoteBuild2DoLang)
170
171                                //Compile using gcc-4.9
172                                currentCC = new CC_Desc('gcc-6', 'g++-6', 'gcc-6')
173                                cfa_build(doPromoteBuild2DoLang)
174
175                                //Compile latex documentation
176                                doc_build()
177
178                                if( doPromoteBuild2DoLang ) {
179                                        push_build()
180                                }
181                        }
182                }
183        }
184
185        //If an exception is caught we need to change the status and remember to
186        //attach the build log to the email
187        catch (Exception caughtError) {
188                //rethrow error later
189                err = caughtError
190
191                //An error has occured, the build log is relevent
192                log_needed = true
193
194                //Store the result of the build log
195                currentBuild.result = "${status_prefix} FAILURE".trim()
196        }
197
198        finally {
199                //Send email with final results
200                notify_result(doPromoteBuild2DoLang, err, currentBuild.result, log_needed)
201
202                /* Must re-throw exception to propagate error */
203                if (err) {
204                        throw err
205                }
206        }
207}
208
209//===========================================================================================================
210//Routine responsible of sending the email notification once the build is completed
211//===========================================================================================================
212def notify_result(boolean promote, Exception err, String status, boolean log) {
213        echo 'Build completed, sending result notification'
214        if(promote)     {
215                if( err ) {
216                        promote_email(status)
217                }
218        }
219        else {
220                email(status, log)
221        }
222}
223
224//Email notification on a full build failure
225def promote_email(String status) {
226        //Since tokenizer doesn't work, figure stuff out from the environnement variables and command line
227        //Configurations for email format
228        def email_subject = "[cforall git][PROMOTE - FAILURE]"
229        def email_body = """This is an automated email from the Jenkins build machine. It was
230generated because of a git hooks/post-receive script following
231a ref change was pushed to the repository containing
232the project "UNNAMED PROJECT".
233
234Check console output at ${env.BUILD_URL} to view the results.
235
236- Status --------------------------------------------------------------
237
238PROMOTE FAILURE - ${status}
239"""
240
241        def email_to = "pabuhr@uwaterloo.ca, rschlunt@uwaterloo.ca, a3moss@uwaterloo.ca, tdelisle@uwaterloo.ca, brice.dobry@huawei.com"
242
243        //send email notification
244        emailext body: email_body, subject: email_subject, to: email_to, attachLog: true
245}
246
247//Standard build email notification
248def email(String status, boolean log) {
249        //Since tokenizer doesn't work, figure stuff out from the environnement variables and command line
250        //Configurations for email format
251        def project_name = (env.JOB_NAME =~ /(.+)\/.+/)[0][1].toLowerCase()
252
253        def gitLog = 'Error retrieving git logs'
254        def gitDiff = 'Error retrieving git diff'
255
256        try {
257
258                sh "git rev-list --format=short ${gitRefOldValue}...${gitRefNewValue} > GIT_LOG"
259                gitLog = readFile('GIT_LOG')
260
261                sh "git diff --stat ${gitRefNewValue} ${gitRefOldValue} > GIT_DIFF"
262                gitDiff = readFile('GIT_DIFF')
263        }
264        catch (Exception error) {}
265
266        def email_subject = "[${project_name} git][BUILD# ${env.BUILD_NUMBER} - ${status}] - branch ${env.BRANCH_NAME}"
267        def email_body = """This is an automated email from the Jenkins build machine. It was
268generated because of a git hooks/post-receive script following
269a ref change was pushed to the repository containing
270the project "UNNAMED PROJECT".
271
272The branch ${env.BRANCH_NAME} has been updated.
273   via  ${gitRefOldValue} (commit)
274  from  ${gitRefNewValue} (commit)
275
276Check console output at ${env.BUILD_URL} to view the results.
277
278- Status --------------------------------------------------------------
279
280BUILD# ${env.BUILD_NUMBER} - ${status}
281
282- Log -----------------------------------------------------------------
283${gitLog}
284-----------------------------------------------------------------------
285Summary of changes:
286${gitDiff}
287"""
288
289        def email_to = "pabuhr@uwaterloo.ca, rschlunt@uwaterloo.ca, a3moss@uwaterloo.ca, tdelisle@uwaterloo.ca, brice.dobry@huawei.com"
290
291        //send email notification
292        emailext body: email_body, subject: email_subject, to: email_to, attachLog: log
293}
Note: See TracBrowser for help on using the repository browser.