github.com/verrazzano/verrazzano@v1.7.1/ci/cron/JenkinsfileBackend (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  import groovy.transform.Field
     5  
     6  @Field
     7  def GIT_COMMIT_TO_USE = ""
     8  @Field
     9  def LAST_CLEAN_BACKEND_COMMIT = ""
    10  @Field
    11  def backendTestsUpToDate = false // If true, indicates that the backend tests already passed at the latest commit
    12  @Field
    13  def backendTestsUpToDateFailed = false // If true, indicates that the backend tests already ran and failed at the latest commit
    14  
    15  // Non Fields
    16  def branchSpecificSchedule = getCronSchedule()
    17  
    18  pipeline {
    19      options {
    20          timeout(time: 12, unit: 'HOURS')
    21          skipDefaultCheckout true
    22          disableConcurrentBuilds()
    23          timestamps ()
    24      }
    25  
    26      agent {
    27         docker {
    28              image "${RUNNER_DOCKER_IMAGE}"
    29              args "${RUNNER_DOCKER_ARGS}"
    30              registryUrl "${RUNNER_DOCKER_REGISTRY_URL}"
    31              registryCredentialsId 'ocir-pull-and-push-account'
    32              label "pipeline-job-large"
    33          }
    34      }
    35  
    36      triggers {
    37          cron(branchSpecificSchedule)
    38      }
    39  
    40      parameters {
    41              booleanParam (description: 'Skip test execution (for debugging)', name: 'DRY_RUN', defaultValue: false)
    42          }
    43  
    44      environment {
    45          OCI_CLI_AUTH = "instance_principal"
    46          OCI_OS_NAMESPACE = credentials('oci-os-namespace')
    47  
    48          CLEAN_BRANCH_NAME = "${env.BRANCH_NAME.replace("/", "%2F")}"
    49  
    50          STABLE_COMMIT_OS_LOCATION = "${CLEAN_BRANCH_NAME}/last-stable-commit.txt"
    51          LAST_BACKEND_OS_LOCATION = "${CLEAN_BRANCH_NAME}/last-backend-run-commit.txt"
    52          CLEAN_BACKEND_OS_LOCATION = "${CLEAN_BRANCH_NAME}-last-clean-backend-test/verrazzano_backend-commit.txt"
    53  
    54          STABLE_COMMIT_LOCATION = "${WORKSPACE}/last-stable-commit.txt"
    55          LAST_BACKEND_LOCATION = "${WORKSPACE}/last-backend-run-commit.txt"
    56          CLEAN_BACKEND_LOCATION = "${WORKSPACE}/last-clean-backend-commit.txt"
    57  
    58          OCI_OS_REGION = "us-phoenix-1"
    59      }
    60  
    61      stages {
    62  
    63          stage('Check last clean backend') {
    64              steps {
    65                  sh """
    66                      oci --region us-phoenix-1 os object get --namespace ${OCI_OS_NAMESPACE} -bn ${OCI_OS_BUCKET} --name ${STABLE_COMMIT_OS_LOCATION} --file ${STABLE_COMMIT_LOCATION}
    67                  """
    68  
    69                  script {
    70                      // Check if there is already a clean backend run at this commit already, and set the display name if
    71                      // it already is tested, or if doing a special run type (dry run, etc...)
    72                      preliminaryChecks()
    73                  }
    74              }
    75          }
    76  
    77          stage('Clean workspace and checkout') {
    78              when {
    79                  allOf {
    80                      expression { return runPipeline() }
    81                  }
    82              }
    83                  steps {
    84                      script {
    85                          cleanWorkspaceAndCheckout()
    86                      }
    87                  }
    88          }
    89  
    90          stage ('Run Backend Test Suite') {
    91              when {
    92                  allOf {
    93                      expression { return runPipeline() }
    94                  }
    95              }
    96  
    97              steps {
    98                  script {
    99                      echo("Running backend suite with commit ${GIT_COMMIT_TO_USE}")
   100                      build job: "/verrazzano-backend-tests/${CLEAN_BRANCH_NAME}", wait: true
   101                  }
   102              }
   103          }
   104      }
   105  }
   106  
   107  def cleanWorkspaceAndCheckout() {
   108      scmCheckout()
   109      def props = readProperties file: '.verrazzano-development-version'
   110      VERRAZZANO_DEV_VERSION = props['verrazzano-development-version']
   111      TIMESTAMP = sh(returnStdout: true, script: "date +%Y%m%d%H%M%S").trim()
   112      SHORT_COMMIT_HASH = sh(returnStdout: true, script: "git rev-parse --short=8 HEAD").trim()
   113      // update the description with some meaningful info
   114      currentBuild.description = SHORT_COMMIT_HASH + " : " + env.GIT_COMMIT
   115  }
   116  
   117  // Returns the last clean commit for the backends, or null if the commit file does not exist yet.
   118  // - fails the pipeline if any error other than 404 is returned by the OCI CLI
   119  def getLastCleanBackendCommit() {
   120      lastBackendCommitCommandOutput = sh (
   121          label: "Get last clean backend commit ID",
   122          script: "oci --region us-phoenix-1 os object get --namespace ${OCI_OS_NAMESPACE} -bn ${OCI_OS_BUCKET} --name ${CLEAN_BACKEND_OS_LOCATION} --file ${CLEAN_BACKEND_LOCATION} 2>&1 || true",
   123          returnStdout: true
   124          ).trim()
   125      echo "command out: ${lastBackendCommitCommandOutput}"
   126      if (lastBackendCommitCommandOutput.length() > 0) {
   127          // We can get warning messages here as well even when the command succeeded, so be more precise on the checking
   128          if (lastBackendCommitCommandOutput =~ /(.*)status(.*)\d{1,4}(.*)/) {
   129              // If we think we had a status: NNN, we ignore 404 and fail for others
   130              assert lastBackendCommitCommandOutput =~ /(.*)status(.*)404(.*)/ : "An unexpected error occurred getting last backend commit from ObjectStore: ${lastBackendCommitCommandOutput}"
   131          } else {
   132              // If we got here, we have some message that may or may not be an error. If we don't see the file, we assume it was an error
   133              sh """
   134                  if [ ! -f ${CLEAN_BACKEND_LOCATION} ]; then
   135                      echo "An unexpected error occurred getting last backend commit from ObjectStore: ${lastBackendCommitCommandOutput}"
   136                      exit 1
   137                  fi
   138              """
   139          }
   140      }
   141      // Get the commit ID for the last known clean pass of the Backend tests
   142      def cleanBackendsCommitProps = readProperties file: "${CLEAN_BACKEND_LOCATION}"
   143      return cleanBackendsCommitProps['git-commit']
   144  }
   145  
   146  // Returns the last run commit for the Backend, or null if the commit file does not exist yet.
   147  // - fails the pipeline if any error other than 404 is returned by the OCI CLI
   148  def getLastBackendRunCommit() {
   149      lastBackendCommitCommandOutput = sh (
   150          label: "Get last clean backend commit ID",
   151          script: "oci --region us-phoenix-1 os object get --namespace ${OCI_OS_NAMESPACE} -bn ${OCI_OS_BUCKET} --name ${LAST_BACKEND_OS_LOCATION} --file ${LAST_BACKEND_LOCATION} 2>&1 || true",
   152          returnStdout: true
   153          ).trim()
   154      echo "command out: ${lastBackendCommitCommandOutput}"
   155      if (lastBackendCommitCommandOutput.length() > 0) {
   156          // We can get warning messages here as well even when the command succeeded, so be more precise on the checking
   157          if (lastBackendCommitCommandOutput =~ /(.*)status(.*)\d{1,4}(.*)/) {
   158              // If we think we had a status: NNN, we ignore 404 and fail for others
   159              assert lastBackendCommitCommandOutput =~ /(.*)status(.*)404(.*)/ : "An unexpected error occurred getting last backend commit from ObjectStore: ${lastBackendCommitCommandOutput}"
   160          } else {
   161              // If we got here, we have some message that may or may not be an error. If we don't see the file, we assume it was an error
   162              sh """
   163                  if [ ! -f ${LAST_BACKEND_LOCATION} ]; then
   164                      echo "An unexpected error occurred getting last backend run commit from ObjectStore: ${lastBackendCommitCommandOutput}"
   165                      exit 1
   166                  fi
   167              """
   168          }
   169      }
   170      // Get the commit ID for the last known clean pass of the Backend tests
   171      def lastBackendCommitProps = readProperties file: "${LAST_BACKEND_LOCATION}"
   172      return lastBackendCommitProps['git-commit']
   173  }
   174  
   175  // Preliminary job checks and display updates
   176  def preliminaryChecks() {
   177      // Get the last stable commit ID to pass the triggered tests
   178      def stableCommitProps = readProperties file: "${STABLE_COMMIT_LOCATION}"
   179      GIT_COMMIT_TO_USE = stableCommitProps['git-commit']
   180      echo "Last stable commit: ${GIT_COMMIT_TO_USE}"
   181  
   182      LAST_CLEAN_BACKEND_COMMIT=getLastCleanBackendCommit()
   183      echo "Last clean backend commit: ${LAST_CLEAN_BACKEND_COMMIT}"
   184  
   185      if (LAST_CLEAN_BACKEND_COMMIT == GIT_COMMIT_TO_USE) {
   186          backendTestsUpToDate = true
   187      } else {
   188          // Check if we are still at the same commit previously run (if so we know it wasn't clean and it failed in some way)
   189          LAST_BACKEND_RUN_COMMIT=getLastBackendRunCommit()
   190          if (LAST_BACKEND_RUN_COMMIT != null && LAST_BACKEND_RUN_COMMIT == GIT_COMMIT_TO_USE) {
   191              backendTestsUpToDateFailed = true
   192          }
   193      }
   194  }
   195  
   196  def scmCheckout() {
   197      echo "${NODE_LABELS}"
   198      echo "Specific GIT commit was not specified, use current head"
   199      def scmInfo = checkout([
   200          $class: 'GitSCM',
   201          branches: [[name: env.BRANCH_NAME]],
   202          doGenerateSubmoduleConfigurations: false,
   203          extensions: [],
   204          submoduleCfg: [],
   205          userRemoteConfigs: [[url: env.SCM_VERRAZZANO_GIT_URL]]])
   206      env.GIT_COMMIT = scmInfo.GIT_COMMIT
   207      env.GIT_BRANCH = scmInfo.GIT_BRANCH
   208      echo "SCM checkout of ${env.GIT_BRANCH} at ${env.GIT_COMMIT}"
   209  }
   210  
   211  // Checks all the conditions gating test execution and collates the result
   212  def runPipeline() {
   213    return ! backendTestsUpToDate && ! backendTestsUpToDateFailed && ! params.DRY_RUN
   214  }
   215  
   216  def getCronSchedule() {
   217      if (env.BRANCH_NAME.equals("master") || env.BRANCH_NAME.startsWith("release-")) {
   218          return "@weekly"
   219      }
   220      return ""
   221  }