#!groovy
//
//
// Licensed 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.

// Erlang version embedded in binary packages
ERLANG_VERSION = '24.3.4.9'

// Erlang version used for rebar in release process. CouchDB will not build from
// the release tarball on Erlang versions older than this
MINIMUM_ERLANG_VERSION = '23.3.4.18'

// We create parallel build / test / package stages for each OS using the metadata
// in this map. Adding a new OS should ideally only involve adding a new entry here.
meta = [
  'centos7': [
    name: 'CentOS 7',
    spidermonkey_vsn: '1.8.5',
    image: "apache/couchdbci-centos:7-erlang-${ERLANG_VERSION}"
  ],

  'centos8': [
    name: 'CentOS 8',
    spidermonkey_vsn: '60',
    image: "apache/couchdbci-centos:8-erlang-${ERLANG_VERSION}"
  ],

  'bionic': [
    name: 'Ubuntu 18.04',
    spidermonkey_vsn: '1.8.5',
    image: "apache/couchdbci-ubuntu:bionic-erlang-${ERLANG_VERSION}"
  ],

  'focal': [
    name: 'Ubuntu 20.04',
    spidermonkey_vsn: '68',
    image: "apache/couchdbci-ubuntu:focal-erlang-${ERLANG_VERSION}"
  ],

  'jammy': [
    name: 'Ubuntu 22.04',
    spidermonkey_vsn: '91',
    image: "apache/couchdbci-ubuntu:jammy-erlang-${ERLANG_VERSION}"
  ],

  'buster': [
    name: 'Debian 10',
    spidermonkey_vsn: '60',
    image: "apache/couchdbci-debian:buster-erlang-${ERLANG_VERSION}"
  ],

  'bullseye-arm64': [
    name: 'Debian 11 ARM',
    spidermonkey_vsn: '78',
    image: "apache/couchdbci-debian:bullseye-erlang-${ERLANG_VERSION}",
    node_label: 'arm64v8'
  ],

  'bullseye-ppc64': [
    name: 'Debian 11 POWER',
    spidermonkey_vsn: '78',
    image: "apache/couchdbci-debian:bullseye-erlang-${ERLANG_VERSION}",
    node_label: 'ppc64le'
  ],

  'bullseye': [
    name: 'Debian 11',
    spidermonkey_vsn: '78',
    image: "apache/couchdbci-debian:bullseye-erlang-${ERLANG_VERSION}"
  ],

  // Skip freebsd builds for now as adviced by node owner
  // 'freebsd': [
  //   name: 'FreeBSD',
  //   spidermonkey_vsn: '1.8.5',
  //   gnu_make: 'gmake'
  // ],

 'macos': [
    name: 'macOS',
    spidermonkey_vsn: '91',
    gnu_make: 'make'
  ]
]

// Credit to https://stackoverflow.com/a/69222555 for this technique.
// We can use the scripted pipeline syntax to dynamically generate stages,
// and inject them into a map that we pass to the `parallel` step in a script.
// While the scripting approach is very flexible, it's not able to use some
// functionality specific to Declarative Pipelines, like the `agent` and `post`
// directives, so you'll see alternatives like try-catch-finally used for flow
// control and the nested `node` and `docker` blocks in the container stage to
// configure the worker environment.

// Returns a build stage suitable for non-containerized environments (currently
// macOS and FreeBSD). Coincidentally we do not currently support automated
// package generation on these platforms. This method in invoked when we create
// `parallelStagesMap` below.
def generateNativeStage(platform) {
  return {
    stage(platform) {
      node(platform) {
        timeout(time: 90, unit: "MINUTES") {
          try {
            // deleteDir is OK here because we're not inside of a Docker container!
            deleteDir()
            unstash 'tarball'
            withEnv([
              'HOME='+pwd(),
              'PATH+USRLOCAL=/usr/local/bin',
              'MAKE='+meta[platform].gnu_make
            ]) {
              sh( script: "mkdir -p ${platform}/build", label: 'Create build directories' )
              sh( script: "tar -xf apache-couchdb-*.tar.gz -C ${platform}/build --strip-components=1", label: 'Unpack release' )
              dir( "${platform}/build" ) {
                sh "./configure --skip-deps --spidermonkey-version ${meta[platform].spidermonkey_vsn}"
                sh '$MAKE'
                sh '$MAKE eunit'
                sh '$MAKE elixir-suite'
                sh '$MAKE exunit'
                sh '$MAKE mango-test'
                sh '$MAKE weatherreport-test'
              }
            }
          }
          catch (err) {
            sh 'ls -l ${WORKSPACE}'
            withEnv([
              'HOME='+pwd(),
              'PATH+USRLOCAL=/usr/local/bin',
              'MAKE='+meta[platform].gnu_make
            ]) {
              dir( "${platform}/build" ) {
                sh 'ls -l'
                sh '${MAKE} build-report'
              }
            }
            error("Build step failed with error: ${err.getMessage()}")
          }
          finally {
            junit '**/.eunit/*.xml, **/_build/*/lib/couchdbtest/*.xml, **/src/mango/nosetests.xml, **/test/javascript/junit.xml'
            sh 'killall -9 beam.smp || true'
            sh 'rm -rf ${WORKSPACE}/*'
          }
        }
      }
    }
  }
}

// Returns a build stage suitable for container-based deployments. This method
// is invoked when we create the `parallelStagesMap` in the pipeline below.
def generateContainerStage(platform) {
  return {
    // Important: the stage name here must match the parallelStagesMap key for the
    // Jenkins UI to render the pipeline stages correctly. Don't ask why. -APK
    stage(platform) {
      node(meta[platform].get('node_label', 'docker')) {
        docker.withRegistry('https://docker.io/', 'dockerhub_creds') {
          docker.image(meta[platform].image).inside("${DOCKER_ARGS}") {
            timeout(time: 90, unit: "MINUTES") {
              stage("${meta[platform].name} - build & test") {
                try {
                  sh( script: "rm -rf ${platform} apache-couchdb-*", label: 'Clean workspace' )
                  unstash 'tarball'
                  sh( script: "mkdir -p ${platform}/build", label: 'Create build directories' )
                  sh( script: "tar -xf apache-couchdb-*.tar.gz -C ${platform}/build --strip-components=1", label: 'Unpack release' )
                  dir( "${platform}/build" ) {
                    sh "./configure --skip-deps --spidermonkey-version ${meta[platform].spidermonkey_vsn}"
                    sh 'make'
                    sh 'make eunit'
                    sh 'make elixir-suite'
                    sh 'make exunit'
                    sh 'make mango-test'
                    sh 'make weatherreport-test'
                  }
                }
                catch (err) {
                  sh 'ls -l ${WORKSPACE}'
                  dir( "${platform}/build" ) {
                    sh 'ls -l'
                    sh 'make build-report'
                  }
                  error("Build step failed with error: ${err.getMessage()}")
                }
                finally {
                  junit '**/.eunit/*.xml, **/_build/*/lib/couchdbtest/*.xml, **/src/mango/nosetests.xml, **/test/javascript/junit.xml'
                  sh 'rm -rf ${WORKSPACE}/*'
                }
              }

              stage("${meta[platform].name} - package") {
                try {
                  unstash 'tarball'
                  sh( script: "mkdir -p ${platform}/couchdb", label: 'Create build directory' )
                  sh( script: "tar -xf apache-couchdb-*.tar.gz -C ${platform}/couchdb", label: 'Unpack release' )
                  sh( script: "cd ${platform} && git clone https://github.com/apache/couchdb-pkg", label: 'Clone packaging helper repo' )
                  dir( "${platform}/couchdb-pkg" ) {
                    sh( script: 'make', label: 'Build packages' )
                  }
                  sh( label: 'Stage package artifacts for archival', script: """
                    rm -rf pkgs/${platform}
                    mkdir -p pkgs/${platform}
                    mv ${platform}/rpmbuild/RPMS/\$(arch)/*rpm pkgs/${platform} || true
                    mv ${platform}/couchdb/*.deb pkgs/${platform} || true
                  """ )
                  archiveArtifacts artifacts: 'pkgs/**', fingerprint: true, onlyIfSuccessful: true
                }
                catch (err) {
                  sh 'ls -l ${WORKSPACE}'
                  error("Build step failed with error: ${err.getMessage()}")
                }
                finally {
                  sh 'rm -rf ${WORKSPACE}/*'
                }
              }
            }
          }
        }
      }
    }
  }
}

// Finally we have the actual Pipeline. It's mostly a Declarative Pipeline,
// except for the 'Test and Package' stage where we use the `script` step as an
// "escape hatch" to dynamically generate a set of parallel stages to execute.
pipeline {

  // no top-level agent; agents must be declared for each stage
  agent none

  environment {
    // Following fix an issue with git <= 2.6.5 where no committer
    // name or email are present for reflog, required for git clone
    GIT_COMMITTER_NAME = 'Jenkins User'
    GIT_COMMITTER_EMAIL = 'couchdb@apache.org'
    // https://github.com/jenkins-infra/jenkins.io/blob/master/Jenkinsfile#64
    // We need the jenkins user mapped inside of the image
    // npm config cache below deals with /home/jenkins not mapping correctly
    // inside the image
    DOCKER_ARGS = '-e npm_config_cache=npm-cache -e HOME=. -v=/etc/passwd:/etc/passwd -v /etc/group:/etc/group'
  }

  options {
    buildDiscarder(logRotator(numToKeepStr: '10', artifactNumToKeepStr: '10'))
    preserveStashes(buildCount: 10)
    timeout(time: 3, unit: 'HOURS')
    timestamps()
  }

  stages {
    stage('Build Release Tarball') {
      agent {
        docker {
          label 'docker'
          image "apache/couchdbci-debian:bullseye-erlang-${MINIMUM_ERLANG_VERSION}"
          args "${DOCKER_ARGS}"
          registryUrl 'https://docker.io/'
          registryCredentialsId 'dockerhub_creds'
        }
      }
      steps {
        timeout(time: 15, unit: "MINUTES") {
          sh (script: 'rm -rf apache-couchdb-*', label: 'Clean workspace of any previous release artifacts' )
          sh "./configure --spidermonkey-version 78"
          sh 'make dist'
        }
      }
      post {
        success {
          stash includes: 'apache-couchdb-*.tar.gz', name: 'tarball'
          archiveArtifacts artifacts: 'apache-couchdb-*.tar.gz', fingerprint: true
        }
        failure {
          sh 'ls -l ${WORKSPACE}'
        }
        cleanup {
          // UGH see https://issues.jenkins-ci.org/browse/JENKINS-41894
          sh 'rm -rf ${WORKSPACE}/*'
        }
      }
    } // stage Build Release Tarball

    stage('Test and Package') {
      steps {
        script {
          // Including failFast: true in map fails the build immediately if any parallel step fails
          parallelStagesMap = meta.collectEntries( [failFast: false] ) { key, values ->
            if (values.image) {
              ["${key}": generateContainerStage(key)]
            }
            else {
              ["${key}": generateNativeStage(key)]
            }
          }
          parallel parallelStagesMap
        }
      }
    }

    stage('Publish') {

      when {
        expression { return env.BRANCH_NAME ==~ /main|2.*.x|3.*.x|4.*.x|jenkins-.*/ }
      }

      agent {
        docker {
          image "apache/couchdbci-debian:bullseye-erlang-${ERLANG_VERSION}"
          label 'docker'
          args "${DOCKER_ARGS}"
          registryUrl 'https://docker.io/'
          registryCredentialsId 'dockerhub_creds'
        }
      }
      options {
        skipDefaultCheckout()
        timeout(time: 90, unit: "MINUTES")
      }

      steps {
        sh 'rm -rf ${WORKSPACE}/*'
        unstash 'tarball'
        unarchive mapping: ['pkgs/' : '.']

        sh( label: 'Build Debian repo', script: '''
            mkdir -p $BRANCH_NAME/debian $BRANCH_NAME/el7 $BRANCH_NAME/el8 $BRANCH_NAME/source
            git clone https://github.com/apache/couchdb-pkg
            for plat in buster bullseye focal
            do
              reprepro -b couchdb-pkg/repo includedeb $plat pkgs/$plat/*.deb
            done
          ''' )

        sh( label: 'Build CentOS repos', script: '''
            #cp js/centos-7/*rpm pkgs/centos7
            #cp js/centos-8/*rpm pkgs/centos8
            cd pkgs/centos7 && createrepo_c --database .
            cd ../centos8 && createrepo_c --database .
          ''' )

        sh( label: 'Build unified repo', script: '''
            mv couchdb-pkg/repo/pool $BRANCH_NAME/debian
            mv couchdb-pkg/repo/dists $BRANCH_NAME/debian
            mv pkgs/centos7/* $BRANCH_NAME/el7
            mv pkgs/centos8/* $BRANCH_NAME/el8
            mv apache-couchdb-*.tar.gz $BRANCH_NAME/source
            cd $BRANCH_NAME/source
            ls -1tr | head -n -10 | xargs -d '\n' rm -f --
            cd ../..
          ''' )
      } // steps
    } // stage
  } // stages

  post {
    success {
      mail to: 'notifications@couchdb.apache.org',
        replyTo: 'notifications@couchdb.apache.org',
        subject: "[Jenkins] SUCCESS: ${currentBuild.fullDisplayName}",
        body: "Yay, we passed. ${env.RUN_DISPLAY_URL}"
    }
    unstable {
      mail to: 'notifications@couchdb.apache.org',
        replyTo: 'notifications@couchdb.apache.org',
        subject: "[Jenkins] SUCCESS: ${currentBuild.fullDisplayName}",
        body: "Eep! Build is unstable... ${env.RUN_DISPLAY_URL}"
    }
    failure {
      mail to: 'notifications@couchdb.apache.org',
        replyTo: 'notifications@couchdb.apache.org',
        subject: "[Jenkins] FAILURE: ${currentBuild.fullDisplayName}",
        body: "Boo, we failed. ${env.RUN_DISPLAY_URL}"
    }
  }

} // pipeline
