blob: d41047a9d6f7dcf8dd0de11c949b643fc081f04f [file] [log] [blame]
@Library('jenkins-pipeline-shared-libraries')_
helper = null
commitDone = false
pipeline {
agent {
docker {
image env.AGENT_DOCKER_BUILDER_IMAGE
args env.AGENT_DOCKER_BUILDER_ARGS
label util.avoidFaultyNodes()
}
}
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 Kind') {
steps {
script {
launchE2ETestsJob('kind')
}
}
}
}
}
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
}