1 // Licensed to the Apache Software Foundation (ASF) under one
2 // or more contributor license agreements. See the NOTICE file
3 // distributed with this work for additional information
4 // regarding copyright ownership. The ASF licenses this file
5 // to you under the Apache License, Version 2.0 (the
6 // "License"); you may not use this file except in compliance
7 // with the License. You may obtain a copy of the License at
9 // http://www.apache.org/licenses/LICENSE-2.0
11 // Unless required by applicable law or agreed to in writing,
12 // software distributed under the License is distributed on an
13 // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14 // KIND, either express or implied. See the License for the
15 // specific language governing permissions and limitations
27 buildDiscarder(logRotator(numToKeepStr: '30'))
28 timeout (time: 9, unit: 'HOURS')
33 YETUS_RELEASE = '0.7.0'
34 // where we'll write everything from different steps. Need a copy here so the final step can check for success/failure.
35 OUTPUT_DIR_RELATIVE_GENERAL = 'output-general'
36 OUTPUT_DIR_RELATIVE_JDK7 = 'output-jdk7'
37 OUTPUT_DIR_RELATIVE_HADOOP2 = 'output-jdk8-hadoop2'
38 OUTPUT_DIR_RELATIVE_HADOOP3 = 'output-jdk8-hadoop3'
41 PROJECT_PERSONALITY = 'https://raw.githubusercontent.com/apache/hbase/master/dev-support/hbase-personality.sh'
42 PERSONALITY_FILE = 'tools/personality.sh'
43 // This section of the docs tells folks not to use the javadoc tag. older branches have our old version of the check for said tag.
44 AUTHOR_IGNORE_LIST = 'src/main/asciidoc/_chapters/developer.adoc,dev-support/test-patch.sh'
45 WHITESPACE_IGNORE_LIST = '.*/generated/.*'
46 // output from surefire; sadly the archive function in yetus only works on file names.
47 ARCHIVE_PATTERN_LIST = 'TEST-*.xml,org.apache.h*.txt,*.dumpstream,*.dump'
48 // These tests currently have known failures. Once they burn down to 0, remove from here so that new problems will cause a failure.
49 TESTS_FILTER = 'cc,checkstyle,javac,javadoc,pylint,shellcheck,whitespace,perlcritic,ruby-lint,rubocop,mvnsite'
50 // Flaky urls for different branches. Replace '-' and '.' in branch name by '_' because those
51 // characters are not allowed in bash variable name.
52 // Not excluding flakies from the nightly build for now.
53 // EXCLUDE_TESTS_URL_master = 'https://builds.apache.org/job/HBase-Find-Flaky-Tests/lastSuccessfulBuild/artifact/excludes/'
54 // EXCLUDE_TESTS_URL_branch_2 = 'https://builds.apache.org/job/HBase-Find-Flaky-Tests-branch2.0/lastSuccessfulBuild/artifact/excludes/'
57 booleanParam(name: 'USE_YETUS_PRERELEASE', defaultValue: false, description: '''Check to use the current HEAD of apache/yetus rather than our configured release.
59 Should only be used manually when e.g. there is some non-work-aroundable issue in yetus we are checking a fix for.''')
60 booleanParam(name: 'DEBUG', defaultValue: false, description: 'Produce a lot more meta-information.')
63 stage ('yetus install') {
65 sh '''#!/usr/bin/env bash
66 echo "Ensure we have a copy of Apache Yetus."
67 if [[ true != "${USE_YETUS_PRERELEASE}" ]]; then
68 YETUS_DIR="${WORKSPACE}/yetus-${YETUS_RELEASE}"
69 echo "Checking for Yetus ${YETUS_RELEASE} in '${YETUS_DIR}'"
70 if [ ! -d "${YETUS_DIR}" ]; then
71 echo "New download of Apache Yetus version ${YETUS_RELEASE}."
72 rm -rf "${WORKSPACE}/.gpg"
73 mkdir -p "${WORKSPACE}/.gpg"
74 chmod -R 700 "${WORKSPACE}/.gpg"
76 echo "install yetus project KEYS"
77 curl -L --fail -o "${WORKSPACE}/KEYS_YETUS" https://dist.apache.org/repos/dist/release/yetus/KEYS
78 gpg --homedir "${WORKSPACE}/.gpg" --import "${WORKSPACE}/KEYS_YETUS"
80 echo "download yetus release ${YETUS_RELEASE}"
81 curl -L --fail -O "https://dist.apache.org/repos/dist/release/yetus/${YETUS_RELEASE}/yetus-${YETUS_RELEASE}-bin.tar.gz"
82 curl -L --fail -O "https://dist.apache.org/repos/dist/release/yetus/${YETUS_RELEASE}/yetus-${YETUS_RELEASE}-bin.tar.gz.asc"
83 echo "verifying yetus release"
84 gpg --homedir "${WORKSPACE}/.gpg" --verify "yetus-${YETUS_RELEASE}-bin.tar.gz.asc"
85 mv "yetus-${YETUS_RELEASE}-bin.tar.gz" yetus.tar.gz
87 echo "Reusing cached download of Apache Yetus version ${YETUS_RELEASE}."
90 YETUS_DIR="${WORKSPACE}/yetus-git"
92 echo "downloading from github"
93 curl -L --fail https://api.github.com/repos/apache/yetus/tarball/HEAD -o yetus.tar.gz
95 if [ ! -d "${YETUS_DIR}" ]; then
96 echo "unpacking yetus into '${YETUS_DIR}'"
97 mkdir -p "${YETUS_DIR}"
98 gunzip -c yetus.tar.gz | tar xpf - -C "${YETUS_DIR}" --strip-components 1
101 // Set up the file we need at PERSONALITY_FILE location
103 sh """#!/usr/bin/env bash
104 echo "Downloading Project personality."
105 curl -L -o personality.sh "${env.PROJECT_PERSONALITY}"
108 stash name: 'yetus', includes: "yetus-*/*,yetus-*/**/*,tools/personality.sh"
111 stage ('init health results') {
113 // stash with given name for all tests we might run, so that we can unstash all of them even if
114 // we skip some due to e.g. branch-specific JDK or Hadoop support
115 stash name: 'general-result', allowEmpty: true, includes: "${OUTPUT_DIR_RELATIVE_GENERAL}/doesn't-match"
116 stash name: 'jdk7-result', allowEmpty: true, includes: "${OUTPUT_DIR_RELATIVE_JDK7}/doesn't-match"
117 stash name: 'hadoop2-result', allowEmpty: true, includes: "${OUTPUT_DIR_RELATIVE_HADOOP2}/doesn't-match"
118 stash name: 'hadoop3-result', allowEmpty: true, includes: "${OUTPUT_DIR_RELATIVE_HADOOP3}/doesn't-match"
119 stash name: 'srctarball-result', allowEmpty: true, includes: "output-srctarball/doesn't-match"
122 stage ('health checks') {
124 stage ('yetus general check') {
131 BASEDIR = "${env.WORKSPACE}/component"
132 // TODO does hadoopcheck need to be jdk specific?
133 // Should be things that work with multijdk
134 TESTS = 'all,-unit,-findbugs'
135 // on branches that don't support jdk7, this will already be JAVA_HOME, so we'll end up not
136 // doing multijdk there.
137 MULTIJDK = '/usr/lib/jvm/java-8-openjdk-amd64'
138 OUTPUT_DIR_RELATIVE = "${env.OUTPUT_DIR_RELATIVE_GENERAL}"
139 OUTPUT_DIR = "${env.WORKSPACE}/${env.OUTPUT_DIR_RELATIVE_GENERAL}"
146 sh '''#!/usr/bin/env bash
147 rm -rf "${OUTPUT_DIR}" && mkdir "${OUTPUT_DIR}"
148 rm -rf "${OUTPUT_DIR}/machine" && mkdir "${OUTPUT_DIR}/machine"
149 "${BASEDIR}/dev-support/gather_machine_environment.sh" "${OUTPUT_DIR_RELATIVE}/machine"
151 // TODO roll this into the hbase_nightly_yetus script
152 sh '''#!/usr/bin/env bash
153 rm -rf "${OUTPUT_DIR}/commentfile}"
155 if "${BASEDIR}/dev-support/hbase_nightly_yetus.sh" ; then
156 echo '(/) {color:green}+1 general checks{color}' >> "${OUTPUT_DIR}/commentfile"
158 echo '(x) {color:red}-1 general checks{color}' >> "${OUTPUT_DIR}/commentfile"
161 echo "-- For more information [see general report|${BUILD_URL}/General_Nightly_Build_Report/]" >> "${OUTPUT_DIR}/commentfile"
167 stash name: 'general-result', includes: "${OUTPUT_DIR_RELATIVE}/commentfile"
168 // Has to be relative to WORKSPACE.
169 archive "${env.OUTPUT_DIR_RELATIVE}/*"
170 archive "${env.OUTPUT_DIR_RELATIVE}/**/*"
171 publishHTML target: [
174 alwaysLinkToLastBuild: true,
175 // Has to be relative to WORKSPACE
176 reportDir: "${env.OUTPUT_DIR_RELATIVE}",
177 reportFiles: 'console-report.html',
178 reportName: 'General Nightly Build Report'
183 stage ('yetus jdk7 checks') {
193 BASEDIR = "${env.WORKSPACE}/component"
194 TESTS = 'mvninstall,compile,javac,unit,htmlout'
195 OUTPUT_DIR_RELATIVE = "${env.OUTPUT_DIR_RELATIVE_JDK7}"
196 OUTPUT_DIR = "${env.WORKSPACE}/${env.OUTPUT_DIR_RELATIVE_JDK7}"
197 // On branches where we do jdk7 checks, jdk7 will be JAVA_HOME already.
204 sh '''#!/usr/bin/env bash
205 rm -rf "${OUTPUT_DIR}" && mkdir "${OUTPUT_DIR}"
206 rm -rf "${OUTPUT_DIR}/machine" && mkdir "${OUTPUT_DIR}/machine"
207 "${BASEDIR}/dev-support/gather_machine_environment.sh" "${OUTPUT_DIR_RELATIVE}/machine"
209 sh '''#!/usr/bin/env bash
210 rm -rf "${OUTPUT_DIR}/commentfile}"
212 if "${BASEDIR}/dev-support/hbase_nightly_yetus.sh" ; then
213 echo '(/) {color:green}+1 jdk7 checks{color}' >> "${OUTPUT_DIR}/commentfile"
215 echo '(x) {color:red}-1 jdk7 checks{color}' >> "${OUTPUT_DIR}/commentfile"
218 echo "-- For more information [see jdk7 report|${BUILD_URL}/JDK7_Nightly_Build_Report/]" >> "${OUTPUT_DIR}/commentfile"
224 stash name: 'jdk7-result', includes: "${OUTPUT_DIR_RELATIVE}/commentfile"
225 junit testResults: "${env.OUTPUT_DIR_RELATIVE}/**/target/**/TEST-*.xml", allowEmptyResults: true
226 // zip surefire reports.
228 if [ -d "${OUTPUT_DIR}/archiver" ]; then
229 count=$(find "${OUTPUT_DIR}/archiver" -type f | wc -l)
230 if [[ 0 -ne ${count} ]]; then
231 echo "zipping ${count} archived files"
232 zip -q -m -r "${OUTPUT_DIR}/test_logs.zip" "${OUTPUT_DIR}/archiver"
234 echo "No archived files, skipping compressing."
237 echo "No archiver directory, skipping compressing."
240 // Has to be relative to WORKSPACE.
241 archive "${env.OUTPUT_DIR_RELATIVE}/*"
242 archive "${env.OUTPUT_DIR_RELATIVE}/**/*"
243 publishHTML target: [
246 alwaysLinkToLastBuild: true,
247 // Has to be relative to WORKSPACE.
248 reportDir : "${env.OUTPUT_DIR_RELATIVE}",
249 reportFiles : 'console-report.html',
250 reportName : 'JDK7 Nightly Build Report'
255 stage ('yetus jdk8 hadoop2 checks') {
262 BASEDIR = "${env.WORKSPACE}/component"
263 TESTS = 'mvninstall,compile,javac,unit,findbugs,htmlout'
264 OUTPUT_DIR_RELATIVE = "${env.OUTPUT_DIR_RELATIVE_HADOOP2}"
265 OUTPUT_DIR = "${env.WORKSPACE}/${env.OUTPUT_DIR_RELATIVE_HADOOP2}"
266 // This isn't strictly needed on branches that only support jdk8, but doesn't hurt
267 // and is needed on branches that do both jdk7 and jdk8
268 SET_JAVA_HOME = '/usr/lib/jvm/java-8-openjdk-amd64'
275 sh '''#!/usr/bin/env bash
276 rm -rf "${OUTPUT_DIR}" && mkdir "${OUTPUT_DIR}"
277 rm -rf "${OUTPUT_DIR}/machine" && mkdir "${OUTPUT_DIR}/machine"
278 "${BASEDIR}/dev-support/gather_machine_environment.sh" "${OUTPUT_DIR_RELATIVE}/machine"
280 sh '''#!/usr/bin/env bash
281 rm -rf "${OUTPUT_DIR}/commentfile}"
283 if "${BASEDIR}/dev-support/hbase_nightly_yetus.sh" ; then
284 echo '(/) {color:green}+1 jdk8 hadoop2 checks{color}' >> "${OUTPUT_DIR}/commentfile"
286 echo '(x) {color:red}-1 jdk8 hadoop2 checks{color}' >> "${OUTPUT_DIR}/commentfile"
289 echo "-- For more information [see jdk8 (hadoop2) report|${BUILD_URL}/JDK8_Nightly_Build_Report_(Hadoop2)/]" >> "${OUTPUT_DIR}/commentfile"
295 stash name: 'hadoop2-result', includes: "${OUTPUT_DIR_RELATIVE}/commentfile"
296 junit testResults: "${env.OUTPUT_DIR_RELATIVE}/**/target/**/TEST-*.xml", allowEmptyResults: true
297 // zip surefire reports.
299 if [ -d "${OUTPUT_DIR}/archiver" ]; then
300 count=$(find "${OUTPUT_DIR}/archiver" -type f | wc -l)
301 if [[ 0 -ne ${count} ]]; then
302 echo "zipping ${count} archived files"
303 zip -q -m -r "${OUTPUT_DIR}/test_logs.zip" "${OUTPUT_DIR}/archiver"
305 echo "No archived files, skipping compressing."
308 echo "No archiver directory, skipping compressing."
311 // Has to be relative to WORKSPACE.
312 archive "${env.OUTPUT_DIR_RELATIVE}/*"
313 archive "${env.OUTPUT_DIR_RELATIVE}/**/*"
314 publishHTML target: [
317 alwaysLinkToLastBuild: true,
318 // Has to be relative to WORKSPACE.
319 reportDir : "${env.OUTPUT_DIR_RELATIVE}",
320 reportFiles : 'console-report.html',
321 reportName : 'JDK8 Nightly Build Report (Hadoop2)'
326 stage ('yetus jdk8 hadoop3 checks') {
338 BASEDIR = "${env.WORKSPACE}/component"
339 TESTS = 'mvninstall,compile,javac,unit,htmlout'
340 OUTPUT_DIR_RELATIVE = "${env.OUTPUT_DIR_RELATIVE_HADOOP3}"
341 OUTPUT_DIR = "${env.WORKSPACE}/${env.OUTPUT_DIR_RELATIVE_HADOOP3}"
342 // This isn't strictly needed on branches that only support jdk8, but doesn't hurt
343 // and is needed on branches that do both jdk7 and jdk8
344 SET_JAVA_HOME = '/usr/lib/jvm/java-8-openjdk-amd64'
345 // Activates hadoop 3.0 profile in maven runs.
346 HADOOP_PROFILE = '3.0'
353 sh '''#!/usr/bin/env bash
354 rm -rf "${OUTPUT_DIR}" && mkdir "${OUTPUT_DIR}"
355 rm -rf "${OUTPUT_DIR}/machine" && mkdir "${OUTPUT_DIR}/machine"
356 "${BASEDIR}/dev-support/gather_machine_environment.sh" "${OUTPUT_DIR_RELATIVE}/machine"
358 sh '''#!/usr/bin/env bash
359 rm -rf "${OUTPUT_DIR}/commentfile}"
361 if "${BASEDIR}/dev-support/hbase_nightly_yetus.sh" ; then
362 echo '(/) {color:green}+1 jdk8 hadoop3 checks{color}' >> "${OUTPUT_DIR}/commentfile"
364 echo '(x) {color:red}-1 jdk8 hadoop3 checks{color}' >> "${OUTPUT_DIR}/commentfile"
367 echo "-- For more information [see jdk8 (hadoop3) report|${BUILD_URL}/JDK8_Nightly_Build_Report_(Hadoop3)/]" >> "${OUTPUT_DIR}/commentfile"
373 stash name: 'hadoop3-result', includes: "${OUTPUT_DIR_RELATIVE}/commentfile"
374 // Not sure how two junit test reports will work. Disabling this for now.
375 // junit testResults: "${env.OUTPUT_DIR_RELATIVE}/**/target/**/TEST-*.xml", allowEmptyResults: true
376 // zip surefire reports.
378 if [ -d "${OUTPUT_DIR}/archiver" ]; then
379 count=$(find "${OUTPUT_DIR}/archiver" -type f | wc -l)
380 if [[ 0 -ne ${count} ]]; then
381 echo "zipping ${count} archived files"
382 zip -q -m -r "${OUTPUT_DIR}/test_logs.zip" "${OUTPUT_DIR}/archiver"
384 echo "No archived files, skipping compressing."
387 echo "No archiver directory, skipping compressing."
390 // Has to be relative to WORKSPACE.
391 archive "${env.OUTPUT_DIR_RELATIVE}/*"
392 archive "${env.OUTPUT_DIR_RELATIVE}/**/*"
393 publishHTML target: [
396 alwaysLinkToLastBuild: true,
397 // Has to be relative to WORKSPACE.
398 reportDir : "${env.OUTPUT_DIR_RELATIVE}",
399 reportFiles : 'console-report.html',
400 reportName : 'JDK8 Nightly Build Report (Hadoop3)'
405 // This is meant to mimic what a release manager will do to create RCs.
406 // See http://hbase.apache.org/book.html#maven.release
407 stage ('create source tarball') {
409 maven 'Maven (latest)'
410 // this needs to be set to the jdk that ought to be used to build releases on the branch the Jenkinsfile is stored in.
411 jdk "JDK 1.8 (latest)"
414 BASEDIR = "${env.WORKSPACE}/component"
418 echo "Setting up directories"
419 rm -rf "output-srctarball" && mkdir "output-srctarball"
420 rm -rf "unpacked_src_tarball" && mkdir "unpacked_src_tarball"
421 rm -rf ".m2-for-repo" && mkdir ".m2-for-repo"
422 rm -rf ".m2-for-src" && mkdir ".m2-for-src"
427 sh '''#!/usr/bin/env bash
428 rm -rf "output-srctarball/machine" && mkdir "output-srctarball/machine"
429 "${BASEDIR}/dev-support/gather_machine_environment.sh" "output-srctarball/machine"
432 if "${env.BASEDIR}/dev-support/hbase_nightly_source-artifact.sh" \
433 --intermediate-file-dir output-srctarball \
434 --unpack-temp-dir unpacked_src_tarball \
435 --maven-m2-initial .m2-for-repo \
436 --maven-m2-src-build .m2-for-src \
437 --clean-source-checkout \
438 "${env.BASEDIR}" ; then
439 echo '(/) {color:green}+1 source release artifact{color}\n-- See build output for details.' >output-srctarball/commentfile
441 echo '(x) {color:red}-1 source release artifact{color}\n-- See build output for details.' >output-srctarball/commentfile
447 stash name: 'srctarball-result', includes: "output-srctarball/commentfile"
448 archive 'output-srctarball/*'
459 unstash 'general-result'
460 unstash 'jdk7-result'
461 unstash 'hadoop2-result'
462 unstash 'hadoop3-result'
463 unstash 'srctarball-result'
465 def results = ["${env.OUTPUT_DIR_RELATIVE_GENERAL}/commentfile",
466 "${env.OUTPUT_DIR_RELATIVE_JDK7}/commentfile",
467 "${env.OUTPUT_DIR_RELATIVE_HADOOP2}/commentfile",
468 "${env.OUTPUT_DIR_RELATIVE_HADOOP3}/commentfile",
469 'output-srctarball/commentfile']
472 echo currentBuild.result
473 echo currentBuild.durationString
474 def comment = "Results for branch ${env.BRANCH_NAME}\n"
475 comment += "\t[build ${currentBuild.displayName} on builds.a.o|${env.BUILD_URL}]: "
476 if (currentBuild.result == "SUCCESS") {
477 comment += "(/) *{color:green}+1 overall{color}*\n"
479 comment += "(x) *{color:red}-1 overall{color}*\n"
480 // Ideally get the committer our of the change and @ mention them in the per-jira comment
482 comment += "----\ndetails (if available):\n\n"
484 echo "[DEBUG] trying to aggregate step-wise results"
485 comment += results.collect { fileExists(file: it) ? readFile(file: it) : "" }.join("\n\n")
486 echo "[INFO] Comment:"
489 echo "[INFO] There are ${currentBuild.changeSets.size()} change sets."
490 getJirasToComment(currentBuild).each { currentIssue ->
491 jiraComment issueKey: currentIssue, body: comment
493 } catch (Exception exception) {
494 echo "Got exception: ${exception}"
495 echo " ${exception.getStackTrace()}"
501 import org.jenkinsci.plugins.workflow.support.steps.build.RunWrapper
503 List<String> getJirasToComment(RunWrapper thisBuild) {
505 thisBuild.changeSets.each { cs ->
506 cs.getItems().each { change ->
507 CharSequence msg = change.msg
508 echo "change: ${change}"
510 echo " ${change.commitId}"
511 echo " ${change.author}"
513 msg.eachMatch("HBASE-[0-9]+") { currentIssue ->
514 echo "[DEBUG] found jira key: ${currentIssue}"
515 if (currentIssue in seenJiras) {
516 echo "[DEBUG] already commented on ${currentIssue}."
518 echo "[INFO] commenting on ${currentIssue}."
519 seenJiras << currentIssue