#!groovy
/*
 * 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
 *
 *     https://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.
 */

// =================================================================
// https://cwiki.apache.org/confluence/display/LOGGING/Jenkins+Setup
// =================================================================

// general pipeline documentation: https://jenkins.io/doc/book/pipeline/syntax/
pipeline {
    // https://jenkins.io/doc/book/pipeline/syntax/#options
    options {
        // support ANSI colors in stdout/stderr
        ansiColor 'xterm'
        // only keep the latest 10 builds
        buildDiscarder logRotator(numToKeepStr: '10')
        // cancel build if not complete within two hours of scheduling
        timeout time: 2, unit: 'HOURS'
        // fail parallel stages as soon as any of them fail
        parallelsAlwaysFailFast()
    }
    // https://jenkins.io/doc/book/pipeline/syntax/#agent
    agent {
        // https://cwiki.apache.org/confluence/display/INFRA/Jenkins+node+labels
        label 'ubuntu'
    }
    environment {
        LANG = 'C.UTF-8'
    }
    // https://www.jenkins.io/doc/book/pipeline/shared-libraries/
    libraries {
        // shared library reference to vars/
        lib 'logging'
    }
    stages {
        stage('Build') {
            steps {
                cancelPreviousRunningBuilds()
                mvn '-DskipTests clean install'
            }
        }
        stage('Test') {
            // https://jenkins.io/doc/book/pipeline/syntax/#parallel
            parallel {
                stage('Ubuntu') {
                    steps {
                        mvn '-Dmaven.test.failure.ignore=true verify com.github.spotbugs:spotbugs-maven-plugin:spotbugs'
                        junit '**/target/*-reports/TEST-*.xml'
                        // TODO: would be nice to be able to include checkstyle, cpd, and pmd
                        recordIssues sourceCodeEncoding: 'UTF-8',
                                tools: [
                                    mavenConsole(),
                                    errorProne(),
                                    spotBugs(),
                                    taskScanner(highTags: 'FIXME', normalTags: 'TODO', includePattern: '**/*.java', excludePattern: '*/target/**')
                                ]
                    }
                }
                stage('Windows') {
                    agent {
                        // https://cwiki.apache.org/confluence/display/INFRA/Jenkins+node+labels
                        label 'Windows'
                    }
                    steps {
                        // note that previous test runs of log4j-mongodb* may have left behind an embedded mongo folder
                        // also note that we don't need to use the jenkins system property here as it's ubuntu-specific
                        bat 'if exist %userprofile%\\.embedmongo\\ rd /s /q %userprofile%\\.embedmongo'
                        mvn '-Dmaven.test.failure.ignore=true verify'
                        junit '**/target/*-reports/TEST-*.xml'
                    }
                }
            }
        }
        stage('Deploy') {
            // https://www.jenkins.io/doc/book/pipeline/syntax/#when
            when {
                anyOf {
                    branch 'master'
                    branch 'release-2.x'
                }
            }
            steps {
                mvn '-DskipTests deploy'
            }
            post {
                fixed {
                    notifyBuildFixed()
                }
                unstable {
                    notifyBuildUnstable()
                }
                failure {
                    notifyBuildFailed()
                }
            }
        }
    }
}
