github.com/verrazzano/verrazzano@v1.7.0/ci/a-la-carte/JenkensfileALaCarteTriggered (about)

     1  // Copyright (c) 2023, Oracle and/or its affiliates.
     2  // Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl.
     3  
     4  pipeline {
     5      options {
     6          skipDefaultCheckout true
     7          timestamps ()
     8      }
     9  
    10      agent {
    11         docker {
    12              image "${RUNNER_DOCKER_IMAGE}"
    13              args "${RUNNER_DOCKER_ARGS}"
    14              registryUrl "${RUNNER_DOCKER_REGISTRY_URL}"
    15              registryCredentialsId 'ocir-pull-and-push-account'
    16              label "pipeline-job-large"
    17          }
    18      }
    19  
    20      parameters {
    21          choice (name: 'KUBERNETES_CLUSTER_VERSION',
    22                  description: 'Kubernetes Version for KinD Cluster',
    23                  // 1st choice is the default value
    24                  choices: [ "1.27", "1.26", "1.25", "1.24" ])
    25          string (name: 'GIT_COMMIT_TO_USE',
    26                  defaultValue: 'NONE',
    27                  description: 'This is the full git commit hash from the source build to be used for all jobs',
    28                  trim: true)
    29          string (name: 'VERRAZZANO_OPERATOR_IMAGE',
    30                  defaultValue: 'NONE',
    31                  description: 'Verrazzano platform operator image name (in ghcr.io repo).  If not specified, the operator.yaml from Verrazzano repo will be used to create Verrazzano platform operator',
    32                  trim: true)
    33          booleanParam (description: 'Whether to capture full cluster snapshot on test failure', name: 'CAPTURE_FULL_CLUSTER', defaultValue: false)
    34      }
    35  
    36      environment {
    37          CLEAN_BRANCH_NAME = "${env.BRANCH_NAME.replace("/", "%2F")}"
    38          GOPATH = '/home/opc/go'
    39          GO_REPO_PATH = "${GOPATH}/src/github.com/verrazzano"
    40          SERVICE_KEY = credentials('PAGERDUTY_SERVICE_KEY')
    41  
    42          OCI_CLI_AUTH="instance_principal"
    43          OCI_OS_NAMESPACE = credentials('oci-os-namespace')
    44          OCI_OS_BUCKET="verrazzano-builds"
    45      }
    46  
    47      stages {
    48          stage('Clean workspace and checkout') {
    49              steps {
    50                  script {
    51                      if (params.GIT_COMMIT_TO_USE == "NONE") {
    52                          echo "Specific GIT commit was not specified, use current head"
    53                          def scmInfo = checkout([
    54                              $class: 'GitSCM',
    55                              branches: [[name: env.BRANCH_NAME]],
    56                              doGenerateSubmoduleConfigurations: false,
    57                              extensions: [],
    58                              submoduleCfg: [],
    59                              userRemoteConfigs: [[url: env.SCM_VERRAZZANO_GIT_URL]]])
    60                          env.GIT_COMMIT = scmInfo.GIT_COMMIT
    61                          env.GIT_BRANCH = scmInfo.GIT_BRANCH
    62                      } else {
    63                          echo "SCM checkout of ${params.GIT_COMMIT_TO_USE}"
    64                          def scmInfo = checkout([
    65                              $class: 'GitSCM',
    66                              branches: [[name: params.GIT_COMMIT_TO_USE]],
    67                              doGenerateSubmoduleConfigurations: false,
    68                              extensions: [],
    69                              submoduleCfg: [],
    70                              userRemoteConfigs: [[url: env.SCM_VERRAZZANO_GIT_URL]]])
    71                          env.GIT_COMMIT = scmInfo.GIT_COMMIT
    72                          env.GIT_BRANCH = scmInfo.GIT_BRANCH
    73                          // If the commit we were handed is not what the SCM says we are using, fail
    74                          if (!env.GIT_COMMIT.equals(params.GIT_COMMIT_TO_USE)) {
    75                              echo "SCM didn't checkout the commit we expected. Expected: ${params.GIT_COMMIT_TO_USE}, Found: ${scmInfo.GIT_COMMIT}"
    76                              exit 1
    77                          }
    78                      }
    79                      echo "SCM checkout of ${env.GIT_BRANCH} at ${env.GIT_COMMIT}"
    80                  }
    81  
    82                  script {
    83                      def props = readProperties file: '.verrazzano-development-version'
    84                      VERRAZZANO_DEV_VERSION = props['verrazzano-development-version']
    85                      TIMESTAMP = sh(returnStdout: true, script: "date +%Y%m%d%H%M%S").trim()
    86                      SHORT_COMMIT_HASH = sh(returnStdout: true, script: "git rev-parse --short=8 HEAD").trim()
    87  
    88                      // update the description with some meaningful info
    89                      currentBuild.description = SHORT_COMMIT_HASH + " : " + env.GIT_COMMIT + " : " + params.GIT_COMMIT_TO_USE
    90                      def currentCommitHash = env.GIT_COMMIT
    91                      def commitList = getCommitList()
    92                      withCredentials([file(credentialsId: 'jenkins-to-slack-users', variable: 'JENKINS_TO_SLACK_JSON')]) {
    93                          def userMappings = readJSON file: JENKINS_TO_SLACK_JSON
    94                          SUSPECT_LIST = getSuspectList(commitList, userMappings)
    95                          echo "Suspect list: ${SUSPECT_LIST}"
    96                      }
    97                  }
    98              }
    99          }
   100  
   101          stage ('Kick off a-la-carte tests') {
   102              parallel {
   103                  stage('Wildcard DNS, Default CA, Cert-Manager default clusterResourceNamespace') {
   104                      steps {
   105                          retry(count: JOB_PROMOTION_RETRIES) {
   106                              script {
   107                                  build job: "/verrazzano-a-la-carte/${CLEAN_BRANCH_NAME}",
   108                                      parameters: [
   109                                          string(name: 'KUBERNETES_CLUSTER_VERSION', value: params.KUBERNETES_CLUSTER_VERSION),
   110                                          string(name: 'GIT_COMMIT_TO_USE', value: params.GIT_COMMIT_TO_USE),
   111                                          string(name: 'VERRAZZANO_OPERATOR_IMAGE', value: params.VERRAZZANO_OPERATOR_IMAGE),
   112                                          booleanParam(name: 'CAPTURE_FULL_CLUSTER', value: params.CAPTURE_FULL_CLUSTER),
   113                                          string(name: 'CLUSTER_RESOURCE_NAMESPACE', value: "my-cert-manager"),
   114                                          string(name: 'DNS_TYPE', value: "wildcard"),
   115                                          string(name: 'CERTIFICATE_TYPE', value: "default"),
   116                                      ], wait: true
   117                              }
   118                          }
   119                      }
   120                  }
   121                  stage('OCIDNS, Default CA, Cert-Manager default clusterResourceNamespace') {
   122                      steps {
   123                          retry(count: JOB_PROMOTION_RETRIES) {
   124                              script {
   125                                  build job: "/verrazzano-a-la-carte/${CLEAN_BRANCH_NAME}",
   126                                      parameters: [
   127                                          string(name: 'KUBERNETES_CLUSTER_VERSION', value: params.KUBERNETES_CLUSTER_VERSION),
   128                                          string(name: 'GIT_COMMIT_TO_USE', value: params.GIT_COMMIT_TO_USE),
   129                                          string(name: 'VERRAZZANO_OPERATOR_IMAGE', value: params.VERRAZZANO_OPERATOR_IMAGE),
   130                                          booleanParam(name: 'CAPTURE_FULL_CLUSTER', value: params.CAPTURE_FULL_CLUSTER),
   131                                          string(name: 'CLUSTER_RESOURCE_NAMESPACE', value: "my-cert-manager"),
   132                                          string(name: 'DNS_TYPE', value: "ocidns"),
   133                                          string(name: 'CERTIFICATE_TYPE', value: "default"),
   134                                      ], wait: true
   135                              }
   136                          }
   137                      }
   138                  }
   139                  stage('OCIDNS, LetEncypt staging, Cert-Manager default clusterResourceNamespace') {
   140                      steps {
   141                          retry(count: JOB_PROMOTION_RETRIES) {
   142                              script {
   143                                  build job: "/verrazzano-a-la-carte/${CLEAN_BRANCH_NAME}",
   144                                      parameters: [
   145                                          string(name: 'KUBERNETES_CLUSTER_VERSION', value: params.KUBERNETES_CLUSTER_VERSION),
   146                                          string(name: 'GIT_COMMIT_TO_USE', value: params.GIT_COMMIT_TO_USE),
   147                                          string(name: 'VERRAZZANO_OPERATOR_IMAGE', value: params.VERRAZZANO_OPERATOR_IMAGE),
   148                                          booleanParam(name: 'CAPTURE_FULL_CLUSTER', value: params.CAPTURE_FULL_CLUSTER),
   149                                          string(name: 'CLUSTER_RESOURCE_NAMESPACE', value: "my-cert-manager"),
   150                                          string(name: 'DNS_TYPE', value: "ocidns"),
   151                                          string(name: 'CERTIFICATE_TYPE', value: "letsEncrypt"),
   152                                      ], wait: true
   153                              }
   154                          }
   155                      }
   156                  }
   157                  stage('Wildcard DNS, Default CA, Cert-Manager custom clusterResourceNamespace') {
   158                      steps {
   159                          retry(count: JOB_PROMOTION_RETRIES) {
   160                              script {
   161                                  build job: "/verrazzano-a-la-carte/${CLEAN_BRANCH_NAME}",
   162                                      parameters: [
   163                                          string(name: 'KUBERNETES_CLUSTER_VERSION', value: params.KUBERNETES_CLUSTER_VERSION),
   164                                          string(name: 'GIT_COMMIT_TO_USE', value: params.GIT_COMMIT_TO_USE),
   165                                          string(name: 'VERRAZZANO_OPERATOR_IMAGE', value: params.VERRAZZANO_OPERATOR_IMAGE),
   166                                          booleanParam(name: 'CAPTURE_FULL_CLUSTER', value: params.CAPTURE_FULL_CLUSTER),
   167                                          string(name: 'CLUSTER_RESOURCE_NAMESPACE', value: "my-cluster-resource"),
   168                                          string(name: 'DNS_TYPE', value: "wildcard"),
   169                                          string(name: 'CERTIFICATE_TYPE', value: "default"),
   170                                      ], wait: true
   171                              }
   172                          }
   173                      }
   174                  }
   175                  stage('OCIDNS, Default CA, Cert-Manager custom clusterResourceNamespace') {
   176                      steps {
   177                          retry(count: JOB_PROMOTION_RETRIES) {
   178                              script {
   179                                  build job: "/verrazzano-a-la-carte/${CLEAN_BRANCH_NAME}",
   180                                      parameters: [
   181                                          string(name: 'KUBERNETES_CLUSTER_VERSION', value: params.KUBERNETES_CLUSTER_VERSION),
   182                                          string(name: 'GIT_COMMIT_TO_USE', value: params.GIT_COMMIT_TO_USE),
   183                                          string(name: 'VERRAZZANO_OPERATOR_IMAGE', value: params.VERRAZZANO_OPERATOR_IMAGE),
   184                                          booleanParam(name: 'CAPTURE_FULL_CLUSTER', value: params.CAPTURE_FULL_CLUSTER),
   185                                          string(name: 'CLUSTER_RESOURCE_NAMESPACE', value: "my-cluster-resource"),
   186                                          string(name: 'DNS_TYPE', value: "ocidns"),
   187                                          string(name: 'CERTIFICATE_TYPE', value: "default"),
   188                                      ], wait: true
   189                              }
   190                          }
   191                      }
   192                  }
   193                  stage('OCIDNS, LetEncypt staging, Cert-Manager custom clusterResourceNamespace') {
   194                      steps {
   195                          retry(count: JOB_PROMOTION_RETRIES) {
   196                              script {
   197                                  build job: "/verrazzano-a-la-carte/${CLEAN_BRANCH_NAME}",
   198                                      parameters: [
   199                                          string(name: 'KUBERNETES_CLUSTER_VERSION', value: params.KUBERNETES_CLUSTER_VERSION),
   200                                          string(name: 'GIT_COMMIT_TO_USE', value: params.GIT_COMMIT_TO_USE),
   201                                          string(name: 'VERRAZZANO_OPERATOR_IMAGE', value: params.VERRAZZANO_OPERATOR_IMAGE),
   202                                          booleanParam(name: 'CAPTURE_FULL_CLUSTER', value: params.CAPTURE_FULL_CLUSTER),
   203                                          string(name: 'CLUSTER_RESOURCE_NAMESPACE', value: "my-cluster-resource"),
   204                                          string(name: 'DNS_TYPE', value: "ocidns"),
   205                                          string(name: 'CERTIFICATE_TYPE', value: "letsEncrypt"),
   206                                      ], wait: true
   207                              }
   208                          }
   209                      }
   210                  }
   211              }
   212          }
   213      }
   214      post {
   215          failure {
   216              script {
   217                  if (env.JOB_NAME == "verrazzano-a-la-carte-triggered/master" || env.JOB_NAME ==~ "errazzano-a-la-carte-triggered/release-1.*") {
   218                      if (isPagerDutyEnabled()) {
   219                          pagerduty(resolve: false, serviceKey: "$SERVICE_KEY", incDescription: "Verrazzano: ${env.JOB_NAME} - Failed", incDetails: "Job Failed - \"${env.JOB_NAME}\" build: ${env.BUILD_NUMBER}\n\nView the log at:\n ${env.BUILD_URL}\n\nBlue Ocean:\n${env.RUN_DISPLAY_URL}")
   220                      }
   221                      slackSend ( channel: "$SLACK_ALERT_CHANNEL", message: "Job Failed - \"${env.JOB_NAME}\" build: ${env.BUILD_NUMBER}\n\nView the log at:\n ${env.BUILD_URL}\n\nBlue Ocean:\n${env.RUN_DISPLAY_URL}\n\nSuspects:\n${SUSPECT_LIST}" )
   222                  }
   223              }
   224          }
   225      }
   226  }
   227  
   228  def isPagerDutyEnabled() {
   229      // this controls whether PD alerts are enabled
   230      if (NOTIFY_PAGERDUTY_TRIGGERED_FAILURES.equals("true")) {
   231          echo "Pager-Duty notifications enabled via global override setting"
   232          return true
   233      }
   234      return false
   235  }
   236  
   237  
   238  // Called in Stage Clean workspace and checkout steps
   239  @NonCPS
   240  def getCommitList() {
   241      echo "Checking for change sets"
   242      def commitList = []
   243      def changeSets = currentBuild.changeSets
   244      for (int i = 0; i < changeSets.size(); i++) {
   245          echo "get commits from change set"
   246          def commits = changeSets[i].items
   247          for (int j = 0; j < commits.length; j++) {
   248              def commit = commits[j]
   249              def id = commit.commitId
   250              echo "Add commit id: ${id}"
   251              commitList.add(id)
   252          }
   253      }
   254      return commitList
   255  }
   256  
   257  def trimIfGithubNoreplyUser(userIn) {
   258      if (userIn == null) {
   259          echo "Not a github noreply user, not trimming: ${userIn}"
   260          return userIn
   261      }
   262      if (userIn.matches(".*\\+.*@users.noreply.github.com.*")) {
   263          def userOut = userIn.substring(userIn.indexOf("+") + 1, userIn.indexOf("@"))
   264          return userOut;
   265      }
   266      if (userIn.matches(".*<.*@users.noreply.github.com.*")) {
   267          def userOut = userIn.substring(userIn.indexOf("<") + 1, userIn.indexOf("@"))
   268          return userOut;
   269      }
   270      if (userIn.matches(".*@users.noreply.github.com")) {
   271          def userOut = userIn.substring(0, userIn.indexOf("@"))
   272          return userOut;
   273      }
   274      echo "Not a github noreply user, not trimming: ${userIn}"
   275      return userIn
   276  }
   277  
   278  def getSuspectList(commitList, userMappings) {
   279      def retValue = ""
   280      def suspectList = []
   281      if (commitList == null || commitList.size() == 0) {
   282          echo "No commits to form suspect list"
   283      } else {
   284          for (int i = 0; i < commitList.size(); i++) {
   285              def id = commitList[i]
   286              try {
   287                  def gitAuthor = sh(
   288                      script: "git log --format='%ae' '$id^!'",
   289                      returnStdout: true
   290                  ).trim()
   291                  if (gitAuthor != null) {
   292                      def author = trimIfGithubNoreplyUser(gitAuthor)
   293                      echo "DEBUG: author: ${gitAuthor}, ${author}, id: ${id}"
   294                      if (userMappings.containsKey(author)) {
   295                          def slackUser = userMappings.get(author)
   296                          if (!suspectList.contains(slackUser)) {
   297                              echo "Added ${slackUser} as suspect"
   298                              retValue += " ${slackUser}"
   299                              suspectList.add(slackUser)
   300                          }
   301                      } else {
   302                          // If we don't have a name mapping use the commit.author, at least we can easily tell if the mapping gets dated
   303                          if (!suspectList.contains(author)) {
   304                              echo "Added ${author} as suspect"
   305                              retValue += " ${author}"
   306                              suspectList.add(author)
   307                          }
   308                      }
   309                  } else {
   310                      echo "No author returned from git"
   311                  }
   312              } catch (Exception e) {
   313                  echo "INFO: Problem processing commit ${id}, skipping commit: " + e.toString()
   314              }
   315          }
   316      }
   317      def startedByUser = "";
   318      def causes = currentBuild.getBuildCauses()
   319      echo "causes: " + causes.toString()
   320      for (cause in causes) {
   321          def causeString = cause.toString()
   322          echo "current cause: " + causeString
   323          def causeInfo = readJSON text: causeString
   324          if (causeInfo.userId != null) {
   325              startedByUser = causeInfo.userId
   326          }
   327      }
   328  
   329      if (startedByUser.length() > 0) {
   330          echo "Build was started by a user, adding them to the suspect notification list: ${startedByUser}"
   331          def author = trimIfGithubNoreplyUser(startedByUser)
   332          echo "DEBUG: author: ${startedByUser}, ${author}"
   333          if (userMappings.containsKey(author)) {
   334              def slackUser = userMappings.get(author)
   335              if (!suspectList.contains(slackUser)) {
   336                  echo "Added ${slackUser} as suspect"
   337                  retValue += " ${slackUser}"
   338                  suspectList.add(slackUser)
   339              }
   340          } else {
   341              // If we don't have a name mapping use the commit.author, at least we can easily tell if the mapping gets dated
   342              if (!suspectList.contains(author)) {
   343                 echo "Added ${author} as suspect"
   344                 retValue += " ${author}"
   345                 suspectList.add(author)
   346              }
   347          }
   348      } else {
   349          echo "Build not started by a user, not adding to notification list"
   350      }
   351      echo "returning suspect list: ${retValue}"
   352      return retValue
   353  }
   354  
   355  def getCronSchedule() {
   356      if (env.BRANCH_NAME.equals("master")) {
   357          return "H */2 * * *"
   358      } else if (env.BRANCH_NAME.startsWith("release-1")) {
   359          return "@daily"
   360      }
   361      return ""
   362  }