github.com/verrazzano/verrazzano@v1.7.1/ci/generic/Jenkinsfile-singletarget (about) 1 // Copyright (c) 2023, 2024, 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 def DOCKER_IMAGE_TAG 5 def agentLabel = env.JOB_NAME.contains('master') ? "2.0-large-phx" : "2.0-large" 6 def EFFECTIVE_DUMP_K8S_CLUSTER_ON_SUCCESS = false 7 8 pipeline { 9 options { 10 timeout(time: 1, unit: 'HOURS') 11 skipDefaultCheckout true 12 timestamps () 13 } 14 15 agent { 16 docker { 17 image "${RUNNER_DOCKER_IMAGE}" 18 args "${RUNNER_DOCKER_ARGS}" 19 registryUrl "${RUNNER_DOCKER_REGISTRY_URL}" 20 registryCredentialsId 'ocir-pull-and-push-account' 21 label "${agentLabel}" 22 } 23 } 24 25 parameters { 26 choice (name: 'KUBERNETES_CLUSTER_VERSION', 27 description: 'Kubernetes Version for KinD Cluster', 28 // 1st choice is the default value 29 choices: ["1.27", "1.26", "1.25", "1.24" ]) 30 string (name: 'GIT_COMMIT_TO_USE', 31 defaultValue: 'NONE', 32 description: 'This is the full git commit hash from the source build to be used for all jobs', 33 trim: true) 34 string (name: 'TEST_TARGET', 35 defaultValue: 'kind-acceptance-tests', 36 description: 'Test target to execute', 37 trim: true) 38 string (name: 'VERRAZZANO_OPERATOR_IMAGE', 39 defaultValue: 'NONE', 40 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', 41 trim: true) 42 choice (name: 'WILDCARD_DNS_DOMAIN', 43 description: 'This is the wildcard DNS domain', 44 // 1st choice is the default value 45 choices: [ "nip.io", "sslip.io"]) 46 choice (name: 'CRD_API_VERSION', 47 description: 'This is the API crd version.', 48 // 1st choice is the default value 49 choices: [ "v1beta1", "v1alpha1"]) 50 booleanParam (description: 'Whether to create the cluster with Calico for AT testing (defaults to true)', name: 'CREATE_CLUSTER_USE_CALICO', defaultValue: true) 51 booleanParam (description: 'Whether to dump k8s cluster on success (off by default can be useful to capture for comparing to failed cluster)', name: 'DUMP_K8S_CLUSTER_ON_SUCCESS', defaultValue: false) 52 string (name: 'CONSOLE_REPO_BRANCH', 53 defaultValue: '', 54 description: 'The branch to check out after cloning the console repository.', 55 trim: true) 56 booleanParam (description: 'Whether to enable debug logging of the istio envoy in the VZ API pod', name: 'ENABLE_API_ENVOY_LOGGING', defaultValue: true) 57 string (name: 'TAGGED_TESTS', 58 defaultValue: '', 59 description: 'A comma separated list of build tags for tests that should be executed (e.g. unstable_test). Default:', 60 trim: true) 61 string (name: 'INCLUDED_TESTS', 62 defaultValue: '.*', 63 description: 'A regex matching any fully qualified test file that should be executed (e.g. examples/helidon/). Default: .*', 64 trim: true) 65 string (name: 'EXCLUDED_TESTS', 66 defaultValue: '_excluded_test', 67 description: 'A regex matching any fully qualified test file that should not be executed (e.g. multicluster/|_excluded_test). Default: _excluded_test', 68 trim: true) 69 } 70 71 environment { 72 DOCKER_PLATFORM_CI_IMAGE_NAME = 'verrazzano-platform-operator-jenkins' 73 DOCKER_PLATFORM_PUBLISH_IMAGE_NAME = 'verrazzano-platform-operator' 74 GOPATH = '/home/opc/go' 75 GO_REPO_PATH = "${GOPATH}/src/github.com/verrazzano" 76 77 // Env vars for Image pull/docker secrets 78 IMAGE_PULL_SECRET = 'verrazzano-container-registry' 79 DOCKER_CREDS = credentials('github-packages-credentials-rw') 80 DOCKER_EMAIL = credentials('github-packages-email') 81 DOCKER_REPO = 'ghcr.io' 82 OCR_CREDS = credentials('ocr-pull-and-push-account') 83 OCR_REPO = 'container-registry.oracle.com' 84 85 NETRC_FILE = credentials('netrc') 86 87 CLUSTER_NAME = 'verrazzano' 88 KUBECONFIG = "${WORKSPACE}/test_kubeconfig" 89 VERRAZZANO_KUBECONFIG = "${KUBECONFIG}" 90 91 TEST_ROOT = "${WORKSPACE}/tests/e2e" 92 POST_INSTALL_DUMP="true" 93 POST_DUMP_FAILED_FILE = "${WORKSPACE}/post_dump_failed_file.tmp" 94 TESTS_EXECUTED_FILE = "${WORKSPACE}/tests_executed_file.tmp" 95 96 VERRAZZANO_OPERATOR_IMAGE="${params.VERRAZZANO_OPERATOR_IMAGE}" 97 98 INSTALL_PROFILE = "dev" 99 VZ_ENVIRONMENT_NAME = "default" 100 INSTALL_CONFIG_FILE_KIND = "${TEST_SCRIPTS_DIR}/${params.CRD_API_VERSION}/install-verrazzano-kind.yaml" 101 WEBLOGIC_PSW = credentials('weblogic-example-domain-password') // required by WebLogic application and console ingress test 102 DATABASE_PSW = credentials('todo-mysql-password') // required by console ingress test 103 104 // used for console artifact capture on failure 105 JENKINS_READ = credentials('jenkins-auditor') 106 OCI_CLI_AUTH="instance_principal" 107 OCI_OS_NAMESPACE = credentials('oci-os-namespace') 108 OCI_OS_ARTIFACT_BUCKET="build-failure-artifacts" 109 110 // used to emit metrics 111 PROMETHEUS_CREDENTIALS = credentials('prometheus-credentials') 112 TEST_ENV_LABEL = "kind" 113 TEST_ENV = "KIND" 114 K8S_VERSION_LABEL = "${params.KUBERNETES_CLUSTER_VERSION}" 115 } 116 117 stages { 118 stage('Clean workspace and checkout') { 119 steps { 120 pipelineSetup() 121 } 122 } 123 124 stage('Run Acceptance Tests') { 125 environment { 126 KUBERNETES_CLUSTER_VERSION="${params.KUBERNETES_CLUSTER_VERSION}" 127 OCI_CLI_AUTH="instance_principal" 128 OCI_OS_NAMESPACE = credentials('oci-os-namespace') 129 OCI_OS_LOCATION="ephemeral/${env.BRANCH_NAME}/${SHORT_COMMIT_HASH}" 130 } 131 steps { 132 echo "Executing pipeline configuration ${env.PIPELINE_CONFIG}" 133 runMakeCommand(params.TEST_TARGET) 134 } 135 } 136 } 137 post { 138 failure { 139 script { 140 if ( fileExists(env.TESTS_EXECUTED_FILE) ) { 141 dumpK8sCluster('new-kind-acceptance-tests-cluster-snapshot') 142 } 143 postFailureProcessing() 144 } 145 } 146 success { 147 script { 148 if (EFFECTIVE_DUMP_K8S_CLUSTER_ON_SUCCESS == true && fileExists(env.TESTS_EXECUTED_FILE) ) { 149 dumpK8sCluster('new-kind-acceptance-tests-cluster-snapshot') 150 } 151 } 152 } 153 always { 154 archiveArtifacts artifacts: "**/coverage.html,**/logs/**,**/verrazzano_images.txt,**/*cluster-snapshot*/**,**/Screenshot*.png,**/ConsoleLog*.log,**/*${TEST_REPORT}", allowEmptyArchive: true 155 junit testResults: "**/${TEST_REPORT}", allowEmptyResults: true 156 } 157 cleanup { 158 script { 159 runMakeCommand("cleanup") 160 } 161 deleteDir() 162 } 163 } 164 } 165 166 def runTestTarget(testSuitePath, runParallel = "true", randomize = "true") { 167 return script { 168 sh """ 169 export TEST_SUITES="${testSuitePath}/..." 170 export RANDOMIZE_TESTS=${randomize} 171 export RUN_PARALLEL=${runParallel} 172 cd ${GO_REPO_PATH}/verrazzano/ci/generic 173 make test 174 """ 175 } 176 } 177 178 def runMakeCommand(makeTarget) { 179 sh """ 180 cd ${GO_REPO_PATH}/verrazzano/ci/generic 181 make ${makeTarget} 182 """ 183 } 184 185 def pipelineSetup() { 186 sh """ 187 echo "${NODE_LABELS}" 188 """ 189 190 script { 191 EFFECTIVE_DUMP_K8S_CLUSTER_ON_SUCCESS = getEffectiveDumpOnSuccess() 192 if (params.GIT_COMMIT_TO_USE == "NONE") { 193 echo "Specific GIT commit was not specified, use current head" 194 def scmInfo = checkout scm 195 env.GIT_COMMIT = scmInfo.GIT_COMMIT 196 env.GIT_BRANCH = scmInfo.GIT_BRANCH 197 } else { 198 echo "SCM checkout of ${params.GIT_COMMIT_TO_USE}" 199 def scmInfo = checkout([ 200 $class: 'GitSCM', 201 branches: [[name: params.GIT_COMMIT_TO_USE]], 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 // If the commit we were handed is not what the SCM says we are using, fail 209 if (!env.GIT_COMMIT.equals(params.GIT_COMMIT_TO_USE)) { 210 echo "SCM didn't checkout the commit we expected. Expected: ${params.GIT_COMMIT_TO_USE}, Found: ${scmInfo.GIT_COMMIT}" 211 exit 1 212 } 213 } 214 echo "SCM checkout of ${env.GIT_BRANCH} at ${env.GIT_COMMIT}" 215 } 216 217 sh """ 218 cp -f "${NETRC_FILE}" $HOME/.netrc 219 chmod 600 $HOME/.netrc 220 """ 221 222 script { 223 try { 224 sh """ 225 echo "${DOCKER_CREDS_PSW}" | docker login ${env.DOCKER_REPO} -u ${DOCKER_CREDS_USR} --password-stdin 226 """ 227 } catch(error) { 228 echo "docker login failed, retrying after sleep" 229 retry(4) { 230 sleep(30) 231 sh """ 232 echo "${DOCKER_CREDS_PSW}" | docker login ${env.DOCKER_REPO} -u ${DOCKER_CREDS_USR} --password-stdin 233 """ 234 } 235 } 236 } 237 sh """ 238 rm -rf ${GO_REPO_PATH}/verrazzano 239 mkdir -p ${GO_REPO_PATH}/verrazzano 240 tar cf - . | (cd ${GO_REPO_PATH}/verrazzano/ ; tar xf -) 241 """ 242 243 script { 244 def props = readProperties file: '.verrazzano-development-version' 245 VERRAZZANO_DEV_VERSION = props['verrazzano-development-version'] 246 TIMESTAMP = sh(returnStdout: true, script: "date +%Y%m%d%H%M%S").trim() 247 SHORT_COMMIT_HASH = sh(returnStdout: true, script: "git rev-parse --short=8 HEAD").trim() 248 DOCKER_IMAGE_TAG = "${VERRAZZANO_DEV_VERSION}-${TIMESTAMP}-${SHORT_COMMIT_HASH}" 249 // update the description with some meaningful info 250 setDisplayName() 251 currentBuild.description = params.KUBERNETES_CLUSTER_VERSION + " : " + SHORT_COMMIT_HASH + " : " + env.GIT_COMMIT + " : " + params.GIT_COMMIT_TO_USE 252 } 253 } 254 255 def postFailureProcessing() { 256 sh """ 257 curl -k -u ${JENKINS_READ_USR}:${JENKINS_READ_PSW} -o ${WORKSPACE}/build-console-output.log ${BUILD_URL}consoleText 258 """ 259 archiveArtifacts artifacts: '**/build-console-output.log', allowEmptyArchive: true 260 sh """ 261 curl -k -u ${JENKINS_READ_USR}:${JENKINS_READ_PSW} -o archive.zip ${BUILD_URL}artifact/*zip*/archive.zip 262 oci --region us-phoenix-1 os object put --force --namespace ${OCI_OS_NAMESPACE} -bn ${OCI_OS_ARTIFACT_BUCKET} --name ${env.JOB_NAME}/${env.BRANCH_NAME}/${env.BUILD_NUMBER}/archive.zip --file archive.zip 263 rm archive.zip 264 """ 265 script { 266 if (env.BRANCH_NAME == "master" || env.BRANCH_NAME ==~ "release-.*" || env.BRANCH_NAME ==~ "mark/*") { 267 slackSend ( 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}" ) 268 } 269 } 270 } 271 272 def getEffectiveDumpOnSuccess() { 273 def effectiveValue = params.DUMP_K8S_CLUSTER_ON_SUCCESS 274 if (FORCE_DUMP_K8S_CLUSTER_ON_SUCCESS.equals("true") && (env.BRANCH_NAME.equals("master"))) { 275 effectiveValue = true 276 echo "Forcing dump on success based on global override setting" 277 } 278 return effectiveValue 279 } 280 281 def setDisplayName() { 282 echo "Start setDisplayName" 283 def causes = currentBuild.getBuildCauses() 284 echo "causes: " + causes.toString() 285 for (cause in causes) { 286 def causeString = cause.toString() 287 echo "current cause: " + causeString 288 if (causeString.contains("UpstreamCause") && causeString.contains("Started by upstream project")) { 289 echo "This job was caused by " + causeString 290 if (causeString.contains("verrazzano-periodic-triggered-tests")) { 291 currentBuild.displayName = env.BUILD_NUMBER + " : PERIODIC" 292 } else if (causeString.contains("verrazzano-flaky-tests")) { 293 currentBuild.displayName = env.BUILD_NUMBER + " : FLAKY" 294 } 295 } 296 } 297 echo "End setDisplayName" 298 }