// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.

pipeline {

    agent {
        label 'hbase'
    }

    options {
        // N.B. this is per-branch, which means per PR
        disableConcurrentBuilds()
        buildDiscarder(logRotator(numToKeepStr: '15'))
        timeout (time: 1, unit: 'HOURS')
        timestamps()
        skipDefaultCheckout()
    }

    environment {
        SRC_REL = 'src'
        PATCH_REL = 'output'
        YETUS_REL = 'yetus'
        // Branch or tag name.  Yetus release tags are 'rel/X.Y.Z'
        YETUS_VERSION = 'rel/0.12.0'
        DOCKERFILE_REL = "${SRC_REL}/dev-support/jenkins/Dockerfile"
        YETUS_DRIVER_REL = "${SRC_REL}/dev-support/jenkins/jenkins_precommit_github_yetus.sh"
        ARCHIVE_PATTERN_LIST = 'TEST-*.xml,org.apache.h*.txt,*.dumpstream,*.dump'
        BUILD_URL_ARTIFACTS = "artifact/${WORKDIR_REL}/${PATCH_REL}"
        SET_JAVA_HOME = '/usr/local/openjdk-8'
        WORKDIR_REL = 'yetus-precommit-check'
        WORKDIR = "${WORKSPACE}/${WORKDIR_REL}"
        SOURCEDIR = "${WORKDIR}/${SRC_REL}"
        PATCHDIR = "${WORKDIR}/${PATCH_REL}"
        DOCKERFILE = "${WORKDIR}/${DOCKERFILE_REL}"
        YETUS_DRIVER = "${WORKDIR}/${YETUS_DRIVER_REL}"
        YETUSDIR = "${WORKDIR}/${YETUS_REL}"
        PLUGINS = 'all'
        PERSONALITY = "${WORKDIR}/${SRC_REL}/dev-support/jenkins/hbase-personality.sh"
    }

    parameters {
        booleanParam(name: 'DEBUG',
               defaultValue: false,
               description: 'Print extra outputs for debugging the jenkins job and yetus')
    }

    stages {
        stage ('precommit checks') {
            steps {
                dir("${SOURCEDIR}") {
                    checkout scm
                }
                dir("${YETUSDIR}") {
                    checkout([
                      $class           : 'GitSCM',
                      branches         : [[name: "${YETUS_VERSION}"]],
                      userRemoteConfigs: [[url: 'https://github.com/apache/yetus.git']]]
                    )
                }
                dir("${WORKDIR}") {
                    withCredentials([
                      usernamePassword(
                        credentialsId: 'apache-hbase-at-github.com',
                        passwordVariable: 'GITHUB_PASSWORD',
                        usernameVariable: 'GITHUB_USER'
                      )]) {
                        sh label: 'test-patch', script: '''#!/bin/bash -e
                            printenv 2>&1 | sort
                            echo "[INFO] Launching Yetus via ${YETUS_DRIVER}"
                            "${YETUS_DRIVER}"
                        '''
                    }
                }
            }
            post {
                always {
                    // Has to be relative to WORKSPACE.
                    archiveArtifacts artifacts: "${WORKDIR_REL}/${PATCH_REL}/*", excludes: "${WORKDIR_REL}/${PATCH_REL}/precommit"
                    archiveArtifacts artifacts: "${WORKDIR_REL}/${PATCH_REL}/**/*", excludes: "${WORKDIR_REL}/${PATCH_REL}/precommit/**/*"
                    publishHTML target: [
                      allowMissing: true,
                      keepAll: true,
                      alwaysLinkToLastBuild: true,
                      // Has to be relative to WORKSPACE
                      reportDir: "${WORKDIR_REL}/${PATCH_REL}",
                      reportFiles: 'report.html',
                      reportName: 'PR General Check Report'
                    ]
                }
                // Jenkins pipeline jobs fill slaves on PRs without this :(
                cleanup() {
                    script {
                        sh label: 'Cleanup workspace', script: '''#!/bin/bash -e
                            # See YETUS-764
                            if [ -f "${PATCHDIR}/pidfile.txt" ]; then
                              echo "test-patch process appears to still be running: killing"
                              kill `cat "${PATCHDIR}/pidfile.txt"` || true
                              sleep 10
                            fi
                            if [ -f "${PATCHDIR}/cidfile.txt" ]; then
                              echo "test-patch container appears to still be running: killing"
                              docker kill `cat "${PATCHDIR}/cidfile.txt"` || true
                            fi
                            # See HADOOP-13951
                            chmod -R u+rxw "${WORKSPACE}"
                        '''
                        dir ("${WORKDIR}") {
                            deleteDir()
                        }
                    }
                }
            }
        }
    }

    post {
        // Jenkins pipeline jobs fill slaves on PRs without this :(
        cleanup() {
            script {
                sh label: 'Cleanup workspace', script: '''#!/bin/bash -e
                    # See HADOOP-13951
                    chmod -R u+rxw "${WORKSPACE}"
                    '''
                deleteDir()
            }
        }
    }
}