Refactor pipelines for consistency and use lib
diff --git a/README.md b/README.md
index 68d9239..9de07fb 100644
--- a/README.md
+++ b/README.md
@@ -2,3 +2,5 @@
 
 This repository is a centralized collection of [Jenkins pipelines](https://www.jenkins.io/doc/book/pipeline/) used in the [Apache Logging Services](https://logging.apache.org/) project.
 These pipelines are located on [ci-builds.apache.org](https://ci-builds.apache.org/job/Logging/).
+
+This repository is also a shared library configured as `@Library('logging')` or `lib 'logging'` in pipelines.
diff --git a/audit/Jenkinsfile b/audit/Jenkinsfile
index e84faec..1951848 100644
--- a/audit/Jenkinsfile
+++ b/audit/Jenkinsfile
@@ -17,13 +17,6 @@
  */
 
 pipeline {
-    agent {
-        label 'ubuntu'
-    }
-    tools {
-        maven 'Maven 3 (latest)'
-        jdk 'JDK 1.8 (latest)'
-    }
     options {
         ansiColor 'xterm'
         buildDiscarder logRotator(numToKeepStr: '25')
@@ -33,16 +26,44 @@
         // TODO: this can be removed once gitbox webhooks are re-enabled
         pollSCM '@hourly'
     }
+    agent {
+        label 'ubuntu'
+    }
+    libraries {
+        lib 'logging'
+    }
     stages {
         stage('Build') {
             steps {
-                // https://issues.jenkins-ci.org/browse/JENKINS-43353
-                script {
-                    def buildNumber = BUILD_NUMBER as int
-                    if (buildNumber > 1) milestone(buildNumber - 1)
-                    milestone(buildNumber)
+                cancelPreviousRunningBuilds()
+                mvn '-DskipTests clean install'
+            }
+        }
+        stage('Test') {
+            parallel {
+                stage('Ubuntu') {
+                    steps {
+                        mvn '-Dmaven.test.failure.ignore=true verify'
+                    }
+                    post {
+                        always {
+                            junit '**/*-reports/*.xml'
+                        }
+                    }
                 }
-                sh 'mvn install'
+                stage('Windows') {
+                    agent {
+                        label 'Windows'
+                    }
+                    steps {
+                        mvn '-Dmaven.test.failure.ignore=true verify'
+                    }
+                    post {
+                        always {
+                            junit '**/*-reports/*.xml'
+                        }
+                    }
+                }
             }
         }
         stage('Deploy') {
@@ -50,20 +71,14 @@
                 branch 'master'
             }
             steps {
-                sh 'mvn deploy'
+                mvn '-DskipTests deploy'
             }
             post {
                 fixed {
-                    emailext to: 'notifications@logging.apache.org',
-                        from: 'Mr. Jenkins <jenkins@ci-builds.apache.org>',
-                        subject: "[CI][SUCCESS] ${env.JOB_NAME}#${env.BUILD_NUMBER} back to normal",
-                        body: '${SCRIPT, template="groovy-text.template"}'
+                    notifyBuildFixed()
                 }
                 failure {
-                    emailext to: 'notifications@logging.apache.org',
-                        from: 'Mr. Jenkins <jenkins@ci-builds.apache.org>',
-                        subject: "[CI][FAILURE] ${env.JOB_NAME}#${env.BUILD_NUMBER} has potential issues",
-                        body: '${SCRIPT, template="groovy-text.template"}'
+                    notifyBuildFailed()
                 }
             }
         }
diff --git a/chainsaw/Jenkinsfile b/chainsaw/Jenkinsfile
index 7594eb6..0f8da19 100644
--- a/chainsaw/Jenkinsfile
+++ b/chainsaw/Jenkinsfile
@@ -19,12 +19,6 @@
  */
 
 pipeline {
-    agent {
-        label 'ubuntu'
-    }
-    libraries {
-        lib 'logging'
-    }
     options {
         ansiColor 'xterm'
         buildDiscarder logRotator(numToKeepStr: '25')
@@ -34,13 +28,23 @@
         // TODO: this can be removed once gitbox webhooks are re-enabled
         pollSCM '@hourly'
     }
+    agent {
+        label 'ubuntu'
+    }
+    libraries {
+        lib 'logging'
+    }
     stages {
         stage('Build') {
             steps {
                 cancelPreviousRunningBuilds()
                 mvn '-Pdevelopment site:site'
                 mvn '-Pdevelopment install'
-                junit '**/target/surefire-reports/*.xml'
+            }
+            post {
+                always {
+                    junit '**/target/*-reports/*.xml'
+                }
             }
         }
         stage('Deploy') {
@@ -52,16 +56,10 @@
             }
             post {
                 fixed {
-                    emailext to: 'notifications@logging.apache.org',
-                        from: 'Mr. Jenkins <jenkins@ci-builds.apache.org>',
-                        subject: "[CI][SUCCESS] ${env.JOB_NAME}#${env.BUILD_NUMBER} back to normal",
-                        body: '${SCRIPT, template="groovy-text.template"}'
+                    notifyBuildFixed()
                 }
                 failure {
-                    emailext to: 'notifications@logging.apache.org',
-                        from: 'Mr. Jenkins <jenkins@ci-builds.apache.org>',
-                        subject: "[CI][FAILURE] ${env.JOB_NAME}#${env.BUILD_NUMBER} has potential issues",
-                        body: '${SCRIPT, template="groovy-text.template"}'
+                    notifyBuildFailed()
                 }
             }
         }
diff --git a/kotlin/Jenkinsfile b/kotlin/Jenkinsfile
index e84faec..1951848 100644
--- a/kotlin/Jenkinsfile
+++ b/kotlin/Jenkinsfile
@@ -17,13 +17,6 @@
  */
 
 pipeline {
-    agent {
-        label 'ubuntu'
-    }
-    tools {
-        maven 'Maven 3 (latest)'
-        jdk 'JDK 1.8 (latest)'
-    }
     options {
         ansiColor 'xterm'
         buildDiscarder logRotator(numToKeepStr: '25')
@@ -33,16 +26,44 @@
         // TODO: this can be removed once gitbox webhooks are re-enabled
         pollSCM '@hourly'
     }
+    agent {
+        label 'ubuntu'
+    }
+    libraries {
+        lib 'logging'
+    }
     stages {
         stage('Build') {
             steps {
-                // https://issues.jenkins-ci.org/browse/JENKINS-43353
-                script {
-                    def buildNumber = BUILD_NUMBER as int
-                    if (buildNumber > 1) milestone(buildNumber - 1)
-                    milestone(buildNumber)
+                cancelPreviousRunningBuilds()
+                mvn '-DskipTests clean install'
+            }
+        }
+        stage('Test') {
+            parallel {
+                stage('Ubuntu') {
+                    steps {
+                        mvn '-Dmaven.test.failure.ignore=true verify'
+                    }
+                    post {
+                        always {
+                            junit '**/*-reports/*.xml'
+                        }
+                    }
                 }
-                sh 'mvn install'
+                stage('Windows') {
+                    agent {
+                        label 'Windows'
+                    }
+                    steps {
+                        mvn '-Dmaven.test.failure.ignore=true verify'
+                    }
+                    post {
+                        always {
+                            junit '**/*-reports/*.xml'
+                        }
+                    }
+                }
             }
         }
         stage('Deploy') {
@@ -50,20 +71,14 @@
                 branch 'master'
             }
             steps {
-                sh 'mvn deploy'
+                mvn '-DskipTests deploy'
             }
             post {
                 fixed {
-                    emailext to: 'notifications@logging.apache.org',
-                        from: 'Mr. Jenkins <jenkins@ci-builds.apache.org>',
-                        subject: "[CI][SUCCESS] ${env.JOB_NAME}#${env.BUILD_NUMBER} back to normal",
-                        body: '${SCRIPT, template="groovy-text.template"}'
+                    notifyBuildFixed()
                 }
                 failure {
-                    emailext to: 'notifications@logging.apache.org',
-                        from: 'Mr. Jenkins <jenkins@ci-builds.apache.org>',
-                        subject: "[CI][FAILURE] ${env.JOB_NAME}#${env.BUILD_NUMBER} has potential issues",
-                        body: '${SCRIPT, template="groovy-text.template"}'
+                    notifyBuildFailed()
                 }
             }
         }
diff --git a/log4j/Jenkinsfile b/log4j/Jenkinsfile
index 0726947..40d6c41 100644
--- a/log4j/Jenkinsfile
+++ b/log4j/Jenkinsfile
@@ -37,7 +37,6 @@
         // TODO: this can be removed once gitbox webhooks are re-enabled
         pollSCM 'H/5 * * * *'
     }
-
     // https://jenkins.io/doc/book/pipeline/syntax/#agent
     agent {
         // https://cwiki.apache.org/confluence/display/INFRA/Jenkins+node+labels
@@ -46,8 +45,8 @@
     environment {
         LANG = 'C.UTF-8'
     }
+    // https://www.jenkins.io/doc/book/pipeline/shared-libraries/
     libraries {
-        // https://www.jenkins.io/doc/book/pipeline/shared-libraries/
         // shared library reference to vars/
         lib 'logging'
     }
@@ -111,20 +110,14 @@
             steps {
                 mvn '-DskipTests deploy'
             }
-        }
-    }
-    post {
-        fixed {
-            emailext to: 'notifications@logging.apache.org',
-                from: 'Mr. Jenkins <jenkins@ci-builds.apache.org>',
-                subject: "[CI][SUCCESS] ${env.JOB_NAME}#${env.BUILD_NUMBER} back to normal",
-                body: '${SCRIPT, template="groovy-text.template"}'
-        }
-        failure {
-            emailext to: 'notifications@logging.apache.org',
-                from: 'Mr. Jenkins <jenkins@ci-builds.apache.org>',
-                subject: "[CI][FAILURE] ${env.JOB_NAME}#${env.BUILD_NUMBER} has potential issues",
-                body: '${SCRIPT, template="groovy-text.template"}'
+            post {
+                fixed {
+                    notifyBuildFixed()
+                }
+                failure {
+                    notifyBuildFailed()
+                }
+            }
         }
     }
 }
diff --git a/parent/Jenkinsfile b/parent/Jenkinsfile
index 460d237..b8b1f3e 100644
--- a/parent/Jenkinsfile
+++ b/parent/Jenkinsfile
@@ -19,13 +19,6 @@
  */
 
 pipeline {
-    agent {
-        label 'ubuntu'
-    }
-    tools {
-        maven 'Maven 3 (latest)'
-        jdk 'JDK 1.8 (latest)'
-    }
     options {
         ansiColor 'xterm'
         buildDiscarder logRotator(numToKeepStr: '10')
@@ -35,28 +28,28 @@
         // TODO: this can be removed once gitbox webhooks are re-enabled
         pollSCM '@hourly'
     }
+    agent {
+        label 'ubuntu'
+    }
+    libraries {
+        lib 'logging'
+    }
     stages {
         stage('Deploy') {
             when {
                 branch 'master'
             }
             steps {
-                sh 'mvn deploy'
+                mvn 'deploy'
             }
-        }
-    }
-    post {
-        fixed {
-            emailext to: 'notifications@logging.apache.org',
-                from: 'Mr. Jenkins <jenkins@ci-builds.apache.org>',
-                subject: "[CI][SUCCESS] ${env.JOB_NAME}#${env.BUILD_NUMBER} back to normal",
-                body: '${SCRIPT, template="groovy-text.template"}'
-        }
-        failure {
-            emailext to: 'notifications@logging.apache.org',
-                from: 'Mr. Jenkins <jenkins@ci-builds.apache.org>',
-                subject: "[CI][FAILURE] ${env.JOB_NAME}#${env.BUILD_NUMBER} has potential issues",
-                body: '${SCRIPT, template="groovy-text.template"}'
+            post {
+                fixed {
+                    notifyBuildFixed()
+                }
+                failure {
+                    notifyBuildFailed()
+                }
+            }
         }
     }
 }
diff --git a/scala/Jenkinsfile b/scala/Jenkinsfile
index 7d28dd6..eb29d20 100644
--- a/scala/Jenkinsfile
+++ b/scala/Jenkinsfile
@@ -17,12 +17,6 @@
  */
 
 pipeline {
-    agent {
-        label 'ubuntu'
-    }
-    tools {
-        jdk 'JDK 1.8 (latest)'
-    }
     options {
         ansiColor 'xterm'
         buildDiscarder logRotator(numToKeepStr: '25')
@@ -32,30 +26,36 @@
         // TODO: this can be removed once gitbox webhooks are re-enabled
         pollSCM '@hourly'
     }
+    agent {
+        label 'ubuntu'
+    }
+    libraries {
+        lib 'logging'
+    }
+    tools {
+        jdk 'JDK 1.8 (latest)'
+    }
     stages {
         stage('Build') {
             steps {
-                // https://issues.jenkins-ci.org/browse/JENKINS-43353
-                script {
-                    def buildNumber = BUILD_NUMBER as int
-                    if (buildNumber > 1) milestone(buildNumber - 1)
-                    milestone(buildNumber)
-                }
-                sh './sbt -batch auditCheck'
-                sh './sbt -batch "+ compile"'
+                cancelPreviousRunningBuilds()
+                sh '''
+                ./sbt -batch auditCheck
+                ./sbt -batch "+ compile"
+                '''
             }
         }
         stage('Test') {
             steps {
-                sh './sbt -batch Test/auditCheck'
-                sh './sbt -batch "+ test"'
+                sh '''
+                ./sbt -batch Test/auditCheck
+                ./sbt -batch "+ test"
+                '''
             }
         }
         stage('Deploy') {
             when {
-                anyOf {
-                    branch 'master'
-                }
+                branch 'master'
             }
             environment {
                 NEXUS = credentials('logging-snapshots')
@@ -65,16 +65,10 @@
             }
             post {
                 fixed {
-                    emailext to: 'notifications@logging.apache.org',
-                        from: 'Mr. Jenkins <jenkins@ci-builds.apache.org>',
-                        subject: "[CI][SUCCESS] ${env.JOB_NAME}#${env.BUILD_NUMBER} back to normal",
-                        body: '${SCRIPT, template="groovy-text.template"}'
+                    notifyBuildFixed()
                 }
                 failure {
-                    emailext to: 'notifications@logging.apache.org',
-                        from: 'Mr. Jenkins <jenkins@ci-builds.apache.org>',
-                        subject: "[CI][FAILURE] ${env.JOB_NAME}#${env.BUILD_NUMBER} has potential issues",
-                        body: '${SCRIPT, template="groovy-text.template"}'
+                    notifyBuildFailed()
                 }
             }
         }
diff --git a/vars/notifyBuildFailed.groovy b/vars/notifyBuildFailed.groovy
new file mode 100644
index 0000000..c2be9fd
--- /dev/null
+++ b/vars/notifyBuildFailed.groovy
@@ -0,0 +1,6 @@
+def call() {
+    emailext to: 'notifications@logging.apache.org',
+        from: 'Mr. Jenkins <jenkins@ci-builds.apache.org>',
+        subject: "[CI][FAILURE] ${env.JOB_NAME}#${env.BUILD_NUMBER} has potential issues",
+        body: '${SCRIPT, template="groovy-text.template"}'
+}
diff --git a/vars/notifyBuildFixed.groovy b/vars/notifyBuildFixed.groovy
new file mode 100644
index 0000000..3f4172a
--- /dev/null
+++ b/vars/notifyBuildFixed.groovy
@@ -0,0 +1,6 @@
+def call() {
+    emailext to: 'notifications@logging.apache.org',
+        from: 'Mr. Jenkins <jenkins@ci-builds.apache.org>',
+        subject: "[CI][SUCCESS] ${env.JOB_NAME}#${env.BUILD_NUMBER} back to normal",
+        body: '${SCRIPT, template="groovy-text.template"}'
+}