| @Library('jenkins-pipeline-shared-libraries')_ |
| |
| helper = null |
| |
| commitDone = false |
| |
| pipeline { |
| agent { |
| docker { |
| image env.AGENT_DOCKER_BUILDER_IMAGE |
| args env.AGENT_DOCKER_BUILDER_ARGS |
| } |
| } |
| |
| options { |
| timeout(time: 10, unit: 'HOURS') |
| timestamps() |
| } |
| |
| environment { |
| KOGITO_CI_EMAIL_TO = credentials("${JENKINS_EMAIL_CREDS_ID}") |
| |
| PR_BRANCH_HASH = "${util.generateHash(10)}" |
| |
| IMAGE_BUILD_PLATFORMS = 'linux/amd64,linux/arm64' |
| |
| CONTAINER_ENGINE = 'docker' |
| } |
| |
| stages { |
| stage('Setup pipeline') { |
| steps { |
| script { |
| helper = load '.ci/jenkins/scripts/helper.groovy' |
| helper.initPipeline() |
| } |
| } |
| } |
| stage('Initialize') { |
| steps { |
| script { |
| helper.cleanGoPath() |
| |
| helper.updateDisplayName() |
| helper.checkoutRepo() |
| |
| if (helper.isRelease()) { |
| // Verify version is set and if on right release branch |
| assert helper.getProjectVersion() |
| assert helper.getBuildBranch() == util.getReleaseBranchFromVersion(helper.getProjectVersion()) |
| } |
| |
| // Login to final registry |
| helper.loginRegistry() |
| |
| // Prepare for multiplatform build |
| int freePort = cloud.findFreePort() |
| env.localRegistryUrl = cloud.startLocalRegistry(freePort) |
| |
| // TODO docker buildx could be preinstalled onto the docker image |
| cloud.prepareForDockerMultiplatformBuild([env.localRegistryUrl],[cloud.getDockerIOMirrorRegistryConfig()], false) |
| } |
| } |
| post { |
| success { |
| script { |
| properties.add('git.branch', helper.getBuildBranch()) |
| properties.add('git.author', helper.getGitAuthor()) |
| properties.add('project.version', helper.getProjectVersion()) |
| properties.add('release', helper.isRelease()) |
| } |
| } |
| } |
| } |
| |
| stage('Prepare for PR') { |
| when { |
| expression { return helper.isRelease() } |
| } |
| steps { |
| script { |
| if (githubscm.isBranchExist('origin', helper.getPRBranch())) { |
| githubscm.removeRemoteBranch('origin', helper.getPRBranch(), helper.getGitAuthorPushCredsId()) |
| } |
| githubscm.createBranch(helper.getPRBranch()) |
| } |
| } |
| } |
| |
| stage('Update version') { |
| when { |
| expression { return helper.getProjectVersion() } |
| } |
| steps { |
| script { |
| runPythonCommand("make bump-version new_version=${helper.getProjectVersion()}") |
| |
| githubscm.setUserConfigFromCreds(getGitAuthorPushCredsId()) |
| // Commit changes |
| githubscm.commitChanges(getCommitMessage(), { |
| sh ''' |
| git add . |
| git reset -- go.mod |
| git reset -- go.sum |
| ''' |
| }) |
| commitDone = true |
| } |
| } |
| } |
| |
| stage('Test Operator') { |
| when { |
| expression { |
| return helper.shouldLaunchTests() |
| } |
| } |
| steps { |
| runPythonCommand('make test') |
| } |
| post { |
| unsuccessful { |
| script { |
| util.archiveConsoleLog() |
| } |
| } |
| } |
| } |
| |
| stage('Build Operator') { |
| steps { |
| script { |
| String tempBuiltImageTag = getTempBuiltImageTag() |
| |
| // Generate the Dockerfile |
| runPythonCommand("make container-build BUILDER=${env.CONTAINER_ENGINE} IMG=${tempBuiltImageTag} ignore_tag=true build_options='--dry-run'") |
| |
| // Build multiplatform from generated Dockerfile |
| dir('target/image') { |
| cloud.dockerBuildMultiPlatformImages(tempBuiltImageTag, getImageBuildPlatforms(), true, 'Kogito Serverless Operator squashed image') |
| } |
| } |
| } |
| post { |
| unsuccessful { |
| script { |
| util.archiveConsoleLog() |
| } |
| } |
| } |
| } |
| |
| stage('Push to registry') { |
| steps { |
| script { |
| // If not release, push built image |
| // So the user using the `operator.yaml on branch can use an existing image` |
| if (!helper.isRelease()) { |
| pushFinalImage(getTempBuiltImageTag(), getBuiltImage()) |
| } |
| |
| // Tag with given parameter tag |
| pushFinalImage(getTempBuiltImageTag(), helper.getImageFullTag(env.OPERATOR_IMAGE_NAME)) |
| |
| try { |
| pushFinalImage(getTempBuiltImageTag(), helper.getImageReducedTag(env.OPERATOR_IMAGE_NAME)) |
| } catch (err) { |
| echo 'Reduced tag cannot be applied' |
| } |
| |
| // Tag with `latest` tag if asked for as parameter |
| if (helper.isDeployLatestTag()) { |
| pushFinalImage(getTempBuiltImageTag(), helper.getImageFullTag(env.OPERATOR_IMAGE_NAME, defaultImageParamsPrefix, 'latest')) |
| } |
| |
| // Store image deployment information |
| properties.add(helper.getImageRegistryProperty(), helper.getImageRegistry()) |
| properties.add(helper.getImageNamespaceProperty(), helper.getImageNamespace()) |
| properties.add(helper.getImageNamePrefixProperty(), helper.getImageNamePrefix()) |
| properties.add(helper.getImageNameSuffixProperty(), helper.getImageNameSuffix()) |
| properties.add(helper.getImageTagProperty(), helper.getImageTag()) |
| } |
| } |
| } |
| |
| stage('Run e2e tests') { |
| when { |
| expression { |
| return helper.shouldLaunchTests() |
| } |
| } |
| parallel { |
| stage('Run tests on Minikube') { |
| steps { |
| script { |
| launchE2ETestsJob('minikube') |
| } |
| } |
| } |
| } |
| } |
| |
| stage('Create PR') { |
| when { |
| expression { return commitDone } |
| } |
| steps { |
| script { |
| githubscm.pushObject('origin', helper.getPRBranch(), helper.getGitAuthorPushCredsId()) |
| |
| def prMsg = getCommitMessage() |
| def prBody = "Generated by build ${BUILD_TAG}: ${BUILD_URL}.\nPlease do not merge, it shoud be merged automatically." |
| String prLink = githubscm.createPR(prMsg, prBody, helper.getBuildBranch(), helper.getGitAuthorPushCredsId()) |
| properties.add("${helper.getRepoName()}.pr.link", prLink) |
| |
| properties.add("${helper.getRepoName()}.pr.source.uri", "https://github.com/${helper.getGitAuthor()}/${helper.getRepoName()}") |
| properties.add("${helper.getRepoName()}.pr.source.ref", helper.getPRBranch()) |
| properties.add("${helper.getRepoName()}.pr.target.uri", "https://github.com/${helper.getGitAuthor()}/${helper.getRepoName()}") |
| properties.add("${helper.getRepoName()}.pr.target.ref", helper.getBuildBranch()) |
| } |
| } |
| } |
| } |
| post { |
| always { |
| script { |
| properties.writeToFile(env.PROPERTIES_FILE_NAME) |
| archiveArtifacts(artifacts: env.PROPERTIES_FILE_NAME) |
| } |
| } |
| unsuccessful { |
| sendNotification() |
| } |
| cleanup { |
| script { |
| helper.cleanGoPath() |
| util.cleanNode(env.CONTAINER_ENGINE) |
| cloud.cleanDockerMultiplatformBuild() |
| } |
| } |
| } |
| } |
| |
| void sendNotification() { |
| if (params.SEND_NOTIFICATION) { |
| mailer.sendMarkdownTestSummaryNotification('Deploy', "[${helper.getBuildBranch()}] Kogito Serverless Operator", [env.KOGITO_CI_EMAIL_TO]) |
| } else { |
| echo 'No notification sent per configuration' |
| } |
| } |
| |
| String getOperatorVersion() { |
| return sh(script: 'source ./hack/env.sh > /dev/null && echo $(getOperatorVersion)', returnStdout: true).trim() |
| } |
| |
| String getOperatorImageName() { |
| return sh(script: 'source ./hack/env.sh > /dev/null && echo $(getOperatorImageName)', returnStdout: true).trim() |
| } |
| |
| String getBuiltImage() { |
| return "${getOperatorImageName()}:${getOperatorVersion()}" |
| } |
| |
| String getTempBuiltImageTag() { |
| return "${env.localRegistryUrl}/kogito-serverless-operator:${getOperatorVersion()}" |
| } |
| |
| void runPythonCommand(String cmd, boolean stdout = false) { |
| return sh(returnStdout: stdout, script: cmd) |
| } |
| |
| void pushFinalImage(String oldImageName, String newImageName) { |
| cloud.skopeoCopyRegistryImages(oldImageName, newImageName, Integer.parseInt(env.MAX_REGISTRY_RETRIES)) |
| } |
| |
| String getCommitMessage() { |
| return "[${helper.getBuildBranch()}] Update project version to ${helper.getProjectVersion()}" |
| } |
| |
| void launchE2ETestsJob(String clusterName) { |
| String jobName = "kogito-serverless-operator.e2e.${clusterName}" |
| def buildParams = [ |
| string(name: 'DISPLAY_NAME', value: params.DISPLAY_NAME), |
| string(name: 'BUILD_BRANCH_NAME', value: params.BUILD_BRANCH_NAME), |
| string(name: 'TEST_IMAGE_FULL_TAG', value: helper.getImageFullTag(env.OPERATOR_IMAGE_NAME)) |
| ] |
| echo "Build ${jobName} with params ${buildParams}" |
| def job = build(job: "${jobName}", wait: true, parameters: buildParams, propagate: false) |
| if (job.result != 'SUCCESS') { |
| unstable("Tests on cluster ${clusterName} finished with result ${job.result}") |
| } |
| } |
| |
| List getImageBuildPlatforms() { |
| return "${IMAGE_BUILD_PLATFORMS}".split(',') as List |
| } |