gates.jenkinsfile 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278
  1. /*
  2. * This pipeline is the "template" for the Asterisk Gate Tests multi-branch
  3. * parent job. Jenkins will automatically scan the branches in the "asterisk"
  4. * or "Security-asterisk" projects in Gerrit and automatically create a branch-
  5. * specific job for each branch it finds this file in.
  6. *
  7. * This file starts as a declarative pipeline because with a declarative
  8. * pipeline, you can define the trigger in the pipeline file. This keeps
  9. * everything in one place. We transition to scripted pipeline later on because
  10. * we need to dynamically determine which docker image we're going to use and
  11. * you can't do that in a delcarative pipeline.
  12. */
  13. def timeoutTime = 60
  14. def timeoutUnits = 'MINUTES'
  15. if (env.TIMEOUT_GATES) {
  16. def _timeout = env.TIMEOUT_GATES.split()
  17. timeoutTime = _timeout[0].toInteger()
  18. timeoutUnits = _timeout[1]
  19. }
  20. pipeline {
  21. options {
  22. timestamps()
  23. timeout(time: timeoutTime, unit: timeoutUnits)
  24. }
  25. triggers {
  26. /*
  27. * This trigger will match either the "asterisk" or "Security-asterisk"
  28. * projects. The branch is taken from the branch this job was created
  29. * for.
  30. */
  31. gerrit customUrl: '',
  32. commentTextParameterMode: 'PLAIN',
  33. commitMessageParameterMode: 'PLAIN',
  34. gerritBuildSuccessfulVerifiedValue: 2,
  35. gerritBuildFailedVerifiedValue: -1,
  36. gerritBuildUnstableVerifiedValue: -1,
  37. gerritProjects: [
  38. [branches: [[compareType: 'PLAIN', pattern: "${BRANCH_NAME}"]],
  39. compareType: 'REG_EXP',
  40. disableStrictForbiddenFileVerification: false,
  41. pattern: '^(Security-)?asterisk.*'
  42. ]
  43. ],
  44. silentMode: false,
  45. triggerOnEvents: [
  46. commentAddedContains('^regate$'),
  47. commentAdded(commentAddedTriggerApprovalValue: '+2', verdictCategory: 'Code-Review'),
  48. ],
  49. skipVote: [
  50. onFailed: false,
  51. onNotBuilt: true,
  52. onSuccessful: false,
  53. onUnstable: false
  54. ]
  55. }
  56. agent {
  57. /* All of the stages need to be performed on a docker host */
  58. label "swdev-docker"
  59. }
  60. stages {
  61. stage ("->") {
  62. /*
  63. * Jenkins will try to automatically rebuild this job when
  64. * the jenkinsfile changes but since this job is dependent on
  65. * Gerrit, we really don't want to do anything in that case.
  66. */
  67. when {
  68. not { environment name: 'GERRIT_CHANGE_NUMBER', value: '' }
  69. not { environment name: 'GERRIT_EVENT_ACCOUNT_NAME', value: 'Jenkins2' }
  70. }
  71. steps {
  72. /* Here's where we switch to scripted pipeline */
  73. script {
  74. manager.build.displayName = "${env.GERRIT_CHANGE_NUMBER}"
  75. manager.createSummary("/plugin/workflow-job/images/48x48/pipelinejob.png").appendText("Docker Host: ${NODE_NAME}", false)
  76. stage ("Checkout") {
  77. sh "sudo chown -R jenkins:users ."
  78. env.GERRIT_PROJECT_URL = env.GERRIT_CHANGE_URL.replaceAll(/\/[0-9]+$/, "/${env.GERRIT_PROJECT}")
  79. /*
  80. * Jenkins has already automatically checked out the base branch
  81. * for this change but we now need to check out the change itself
  82. * and rebase it on the current base branch. If the rebase fails,
  83. * that's an indication to the user that they'll need to sort their
  84. * change out.
  85. *
  86. * The Gerrit Trigger provides all the URLs and refspecs to
  87. * check out the change.
  88. *
  89. * We need to retrieve the jenkins2 gerrit https credentials
  90. * in case this review is in a restricted project.
  91. */
  92. withCredentials([usernamePassword(credentialsId: "${JENKINS_GERRIT_CREDS}",
  93. passwordVariable: 'GERRIT_USER_PW', usernameVariable: 'GERRIT_USER_NAME')]) {
  94. sh "printenv | sort"
  95. checkout scm: [$class: 'GitSCM',
  96. branches: [[name: env.GERRIT_BRANCH ]],
  97. extensions: [
  98. [$class: 'ScmName', name: 'gerrit-public'],
  99. [$class: 'CleanBeforeCheckout'],
  100. [$class: 'PreBuildMerge', options: [
  101. mergeRemote: 'gerrit-public',
  102. fastForwardMode: 'NO_FF',
  103. mergeStrategy: 'RECURSIVE',
  104. mergeTarget: env.GERRIT_BRANCH]],
  105. [$class: 'CloneOption',
  106. honorRefspec: true,
  107. noTags: true,
  108. depth: 10,
  109. shallow: true
  110. ],
  111. [$class: 'PruneStaleBranch'],
  112. [$class: 'BuildChooserSetting',
  113. buildChooser: [$class: 'GerritTriggerBuildChooser']
  114. ]
  115. ],
  116. userRemoteConfigs: [
  117. [
  118. credentialsId: env.JENKINS_GERRIT_CREDS,
  119. name: env.GERRIT_NAME,
  120. refspec: env.GERRIT_REFSPEC,
  121. url: env.GERRIT_PROJECT_URL.replaceAll("http(s)?://", "http\$1://${GERRIT_USER_NAME}@")
  122. ]
  123. ]
  124. ]
  125. }
  126. sh "sudo tests/CI/setupJenkinsEnvironment.sh"
  127. }
  128. def images = env.DOCKER_IMAGES.split(' ')
  129. def r = currentBuild.startTimeInMillis % images.length
  130. def ri = images[(int)r]
  131. def randomImage = env.DOCKER_REGISTRY + "/" + ri
  132. /* FYI... Jenkins takes care of mouting the workspace for the container */
  133. def dockerOptions = "--privileged --ulimit core=0 --ulimit nofile=10240 " +
  134. " --mount type=tmpfs,tmpfs-size=1g,dst=/tmp -v /srv/jenkins:/srv/jenkins:rw -v /srv/cache:/srv/cache:rw " +
  135. " --entrypoint=''"
  136. def bt = env.BUILD_TAG.replaceAll(/[^a-zA-Z0-9_.-]/, '-')
  137. def outputdir = "tests/CI/output/Testsuite"
  138. manager.createSummary("/plugin/workflow-job/images/48x48/pipelinejob.png").appendText("Docker Image: ${randomImage}", false)
  139. def img = docker.image(randomImage)
  140. img.pull()
  141. stage ("Build") {
  142. img.inside(dockerOptions + " --name ${bt}-build") {
  143. echo 'Building..'
  144. env.CCACHE_DIR = "/srv/cache/ccache"
  145. sh "./tests/CI/buildAsterisk.sh --branch-name=${BRANCH_NAME} --output-dir=${outputdir} --cache-dir=/srv/cache"
  146. archiveArtifacts allowEmptyArchive: true, defaultExcludes: false, fingerprint: false,
  147. artifacts: "${outputdir}/*"
  148. }
  149. }
  150. def testGroups = readJSON file: "tests/CI/gateTestGroups.json"
  151. def parallelTasks = [ : ]
  152. for (def testGroup in testGroups) {
  153. /*
  154. * Because each task is a Groovy closure, we need to
  155. * keep local references to some variables.
  156. */
  157. def groupName = testGroup.name
  158. def groupDir = testGroup.dir
  159. def groupTestcmd = testGroup.testcmd
  160. def testsuiteUrl = env.GERRIT_PROJECT_URL.replaceAll(/\/(Security-)?[^\/]+$/, "/\$1testsuite")
  161. parallelTasks[groupName] = {
  162. stage (groupName) {
  163. img.inside("${dockerOptions} --name ${bt}-${groupName}") {
  164. lock("${JOB_NAME}.${NODE_NAME}.installer") {
  165. sh "sudo ./tests/CI/installAsterisk.sh --uninstall-all --branch-name=${BRANCH_NAME} --user-group=jenkins:users"
  166. }
  167. sh "sudo rm -rf ${groupDir} || : "
  168. withCredentials([usernamePassword(credentialsId: "${JENKINS_GERRIT_CREDS}",
  169. passwordVariable: 'GERRIT_USER_PW', usernameVariable: 'GERRIT_USER_NAME')]) {
  170. checkout scm: [$class: 'GitSCM',
  171. branches: [[name: "${BRANCH_NAME}"]],
  172. extensions: [
  173. [$class: 'RelativeTargetDirectory', relativeTargetDir: groupDir],
  174. [$class: 'CloneOption',
  175. noTags: true,
  176. depth: 10,
  177. honorRefspec: true,
  178. shallow: true
  179. ],
  180. ],
  181. userRemoteConfigs: [
  182. [
  183. credentialsId: env.JENKINS_GERRIT_CREDS,
  184. name: env.GERRIT_NAME,
  185. url: testsuiteUrl.replaceAll("http(s)?://", "http\$1://${GERRIT_USER_NAME}@")
  186. ]
  187. ]
  188. ]
  189. }
  190. sh "sudo tests/CI/runTestsuite.sh --testsuite-dir='${groupDir}' --testsuite-command='${groupTestcmd}'"
  191. archiveArtifacts allowEmptyArchive: true, defaultExcludes: false, fingerprint: true,
  192. artifacts: "${groupDir}/asterisk-test-suite-report.xml, ${groupDir}/logs/**, ${groupDir}/core*.txt"
  193. junit testResults: "${groupDir}/asterisk-test-suite-report.xml",
  194. healthScaleFactor: 1.0,
  195. keepLongStdio: true
  196. echo "Group result d: ${currentBuild.currentResult}"
  197. }
  198. echo "Group result s: ${currentBuild.currentResult}"
  199. }
  200. }
  201. }
  202. parallel parallelTasks
  203. }
  204. }
  205. }
  206. }
  207. post {
  208. cleanup {
  209. sh "sudo make distclean >/dev/null 2>&1 || : "
  210. sh "sudo rm -rf tests/CI/output >/dev/null 2>&1 || : "
  211. }
  212. /*
  213. * The Gerrit Trigger will automatically post the "Verified" results back
  214. * to Gerrit but the verification publisher publishes extra stuff in the
  215. * "Code Review" section of the review.
  216. */
  217. always {
  218. script {
  219. def cat
  220. def comment
  221. def rvalue
  222. switch (currentBuild.currentResult) {
  223. case ~/^SUCCESS$/:
  224. cat = "Passed"
  225. comment = ""
  226. rvalue = 2
  227. break
  228. case ~/^FAILURE$/:
  229. cat = "Failed"
  230. comment = "Fatal Error"
  231. rvalue = -1
  232. break
  233. case ~/^UNSTABLE$/:
  234. cat = "Failed"
  235. comment = "Tests Failed"
  236. rvalue = -1
  237. break
  238. }
  239. gerritverificationpublisher verifyStatusValue: rvalue,
  240. verifyStatusCategory: cat, verifyStatusURL: '',
  241. verifyStatusComment: comment, verifyStatusName: '',
  242. verifyStatusReporter: 'Jenkins2', verifyStatusRerun: 'regate'
  243. }
  244. }
  245. success {
  246. echo "Reporting ${currentBuild.currentResult} Passed"
  247. }
  248. failure {
  249. echo "Reporting ${currentBuild.currentResult}: Failed: Fatal Error"
  250. }
  251. unstable {
  252. echo "Reporting ${currentBuild.currentResult}: Failed: Tests Failed"
  253. }
  254. }
  255. }