pipeline {
  agent any

  options {
    ansiColor('xterm')
    timestamps()
    timeout(time: 1, unit: 'HOURS')
    // Keep the 10 most recent builds
    buildDiscarder(logRotator(numToKeepStr: '10'))

    gitLabConnection('Gitlab')
    gitlabBuilds(builds: ['Lint', 'Linters', 'Test results', 'Coverage'])
  }
  environment {
     Python = "3.9"
  }

  stages {
    stage ("Code pull"){
      steps{
        // make sure any earlier build is canceled
        milestone label: '', ordinal:  Integer.parseInt(env.BUILD_ID) - 1
        milestone label: '', ordinal:  Integer.parseInt(env.BUILD_ID)

        checkout scm
        sh 'cp /etc/ssl/certs/govcertCA.pem .'
      }
    }

    stage('Lint') {
      when {
        not {
          tag pattern: "v\\d+\\.\\d+\\.\\d+", comparator: "REGEXP"
        }
      }

      steps {
        gitlabCommitStatus('Lint') {
            script {
              try {
                docker.image('python:' + Python).inside("--tmpfs /.local --tmpfs /.cache") {
                  sh '''
                        export
                        export HTTP_PROXY="${PROXY}"
                        export HTTPS_PROXY="${PROXY}"
                        export NO_PROXY=localhost,127.0.0.1,.govcert.etat.lu
                        export HOME=${PWD}
                        export PYTHONUSERBASE=.py_${Python}

                        python -m venv .py_${Python}
                        source .py_${Python}/bin/activate
                        pip install -U pip tox

                        tox
                      '''
                }
              } catch (err) {
              }
            }
        }
      }
    }

    stage('Analysis') {
      when {
        not {
          tag pattern: "v\\d+\\.\\d+\\.\\d+", comparator: "REGEXP"
        }
      }

      parallel {
        stage('Linters') {
          steps {
            gitlabCommitStatus('Linters') {
                recordIssues(tools: [pyLint(pattern: "pylint_${Python}.log",
                                            id: "Python_${Python}_pylint",
                                            name: "Py-${Python} Pylint"),
                                     myPy(pattern: "mypy_${Python}.log",
                                          id: "Python_${Python}_mypy",
                                          name: "Py-${Python} MyPy"),
                                     flake8(pattern: "flake8_${Python}.log",
                                            id: "Python_${Python}_flake8",
                                            name: "Py-${Python} Flake8")
                                     ])
            }
          }
        }

        stage('Test results') {
          steps {
            gitlabCommitStatus('Test results') {
                xunit (
                    thresholds: [ skipped(failureThreshold: '0'), failed(failureThreshold: '0') ],
                    tools: [ JUnit(pattern: "**/junit_${Python}.xml") ]
                    )
            }
          }
        }

        stage('Coverage') {
          steps {
            gitlabCommitStatus('Coverage') {
                cobertura(autoUpdateHealth: false,
                          autoUpdateStability: false,
                          coberturaReportFile: "**/coverage_${Python}.xml",
                          failUnhealthy: false,
                          failUnstable: false,
                          maxNumberOfBuilds: 20,
                          onlyStable: false,
                          sourceEncoding: 'ASCII',
                          zoomCoverageChart: false
                )
            }
          }
        }

      }
    }

    stage('Build package') {
      when {
        allOf {
          tag pattern: "v\\d+\\.\\d+\\.\\d+.*", comparator: "REGEXP"
          expression {
            currentBuild.result == null || currentBuild.result == 'SUCCESS'
          }
        }
      }
      steps {
          withCredentials([usernamePassword(credentialsId: 'apps1-pypiserver-jenkins', usernameVariable: 'TWINE_USERNAME', passwordVariable: 'TWINE_PASSWORD')]) {
            script {
              try {
                docker.image('python:' + Python).inside("--tmpfs /.local --tmpfs /.cache") {
                  sh '''cat govcertCA.pem /etc/ssl/certs/ca-certificates.crt > ssl_cas.pem
                        export
                        export HTTP_PROXY="http://proxy.int.govcert.etat.lu:8080"
                        export HTTPS_PROXY="http://proxy.int.govcert.etat.lu:8080"
                        export NO_PROXY=localhost,127.0.0.1,.govcert.etat.lu
                        export HOME=${PWD}
                        export PIP_CERT=${PWD}/ssl_cas.pem
                        export PATH=${PATH}:${PWD}/.local/bin
                        export TWINE_CERT=${PWD}/ssl_cas.pem

                        python3 -m pip install --upgrade build twine
                        python3 -m build -o dist/ .
                        twine upload dist/*.whl
                      '''
                }
              } catch (err) {
              }
            }

            updateGitlabCommitStatus name: 'Lint', state: 'canceled'
            updateGitlabCommitStatus name: 'Linters', state: 'canceled'
            updateGitlabCommitStatus name: 'Test results', state: 'canceled'
            updateGitlabCommitStatus name: 'Coverage', state: 'canceled'
          }
      }
    }
  }

  post {
    failure {
      script {
        def commitemail = sh(script:'cd ${WORKSPACE}; git log -1 --pretty=format:"%ce"', returnStdout:true).trim()

        emailext body: "${currentBuild.currentResult}: Job ${env.JOB_NAME} build ${env.BUILD_NUMBER}\n More info at: ${env.BUILD_URL}",
            to: commitemail, subject: "Jenkins Build ${currentBuild.currentResult}: Job ${env.JOB_NAME}"
      }

      updateGitlabCommitStatus name: 'build', state: 'failed'
    }

    success {
      updateGitlabCommitStatus name: 'build', state: 'success'
    }
  }

}