diff --git a/.ci/jenkins/Jenkinsfile.deploy b/.ci/jenkins/Jenkinsfile.deploy index e0a621731b7..d4a6ab7fd07 100644 --- a/.ci/jenkins/Jenkinsfile.deploy +++ b/.ci/jenkins/Jenkinsfile.deploy @@ -1,5 +1,6 @@ import org.jenkinsci.plugins.workflow.libs.Library -@Library('jenkins-pipeline-shared-libraries')_ + +@Library('jenkins-pipeline-shared-libraries') _ import org.kie.jenkins.MavenCommand import org.kie.jenkins.MavenStagingHelper @@ -84,20 +85,30 @@ pipeline { stage('Clone repositories') { steps { - checkoutRepo(optaplannerRepository) - checkoutQuickstarts() - checkoutRepo(vehicleRoutingRepository) + script { + checkoutRepo(optaplannerRepository) + // TODO: switch to the 9 stream after quickstarts and the optaweb will have been migrated. + if (isStream8()) { + checkoutQuickstarts() + checkoutRepo(vehicleRoutingRepository) + } + } } } stage('Prepare for PR') { when { - expression { return isRelease() || isCreatePr() } + expression { return isRelease() || isCreatePr() } } steps { - prepareForPR(optaplannerRepository) - prepareForPR(vehicleRoutingRepository) - prepareForPR(quickstartsRepository) + script { + prepareForPR(optaplannerRepository) + // TODO: switch to the 9 stream after quickstarts and the optaweb will have been migrated. + if (isStream8()) { + prepareForPR(vehicleRoutingRepository) + prepareForPR(quickstartsRepository) + } + } } } @@ -115,9 +126,12 @@ pipeline { mavenCleanInstallOptaPlannerParents() - maven.mvnVersionsUpdateParentAndChildModules(getOptawebVehicleRoutingMavenCommand(), getProjectVersion(), !isRelease()) + // TODO: switch to the 9 stream after quickstarts and the optaweb will have been migrated. + if (isStream8()) { + maven.mvnVersionsUpdateParentAndChildModules(getOptawebVehicleRoutingMavenCommand(), getProjectVersion(), !isRelease()) - updateQuickstartsVersions() + updateQuickstartsVersions() + } } } } @@ -146,9 +160,16 @@ pipeline { } stage('Build Quickstarts') { + when { + // TODO: switch to the 9 stream after quickstarts and the optaweb will have been migrated. + expression { return isStream8() } + } steps { script { - getOptaplannerQuickstartsMavenCommand().withProperty('maven.test.failure.ignore', true).skipTests(params.SKIP_TESTS).run('clean install') + getOptaplannerQuickstartsMavenCommand() + .withProperty('maven.test.failure.ignore', true) + .skipTests(params.SKIP_TESTS) + .run('clean install') } } post { @@ -162,6 +183,10 @@ pipeline { } stage('Build Vehicle Routing') { + when { + // TODO: switch to the 9 stream after quickstarts and the optaweb will have been migrated. + expression { return isStream8() } + } steps { script { buildOptaweb(getOptawebVehicleRoutingMavenCommand()) @@ -185,8 +210,11 @@ pipeline { steps { script { runMavenDeploy(getOptaplannerMavenCommand()) - runMavenDeploy(getOptaplannerQuickstartsMavenCommand().withOptions(['-pl', ':optaplanner-distribution'])) - runMavenDeploy(getOptawebVehicleRoutingMavenCommand()) + // TODO: switch to the 9 stream after quickstarts and the optaweb will have been migrated. + if (isStream8()) { + runMavenDeploy(getOptaplannerQuickstartsMavenCommand().withOptions(['-pl', ':optaplanner-distribution'])) + runMavenDeploy(getOptawebVehicleRoutingMavenCommand()) + } } } } @@ -197,7 +225,10 @@ pipeline { steps { script { runMavenDeploy(getOptaplannerMavenCommand(), optaplannerRepository) - runMavenDeploy(getOptawebVehicleRoutingMavenCommand(), vehicleRoutingRepository) + // TODO: switch to the 9 stream after quickstarts and the optaweb will have been migrated. + if (isStream8()) { + runMavenDeploy(getOptawebVehicleRoutingMavenCommand(), vehicleRoutingRepository) + } } } } @@ -209,7 +240,10 @@ pipeline { script { // Deploy to specific repository with credentials maven.uploadLocalArtifacts(env.MAVEN_REPO_CREDS_ID, getLocalDeploymentFolder(optaplannerRepository), getMavenRepoZipUrl()) - maven.uploadLocalArtifacts(env.MAVEN_REPO_CREDS_ID, getLocalDeploymentFolder(vehicleRoutingRepository), getMavenRepoZipUrl()) + // TODO: switch to the 9 stream after quickstarts and the optaweb will have been migrated. + if (isStream8()) { + maven.uploadLocalArtifacts(env.MAVEN_REPO_CREDS_ID, getLocalDeploymentFolder(vehicleRoutingRepository), getMavenRepoZipUrl()) + } } } } @@ -221,7 +255,10 @@ pipeline { script { // Stage release artifacts runMavenStage(getOptaplannerMavenCommand(), optaplannerRepository) - runMavenStage(getOptawebVehicleRoutingMavenCommand(), vehicleRoutingRepository) + // TODO: switch to the 9 stream after quickstarts and the optaweb will have been migrated. + if (isStream8()) { + runMavenStage(getOptawebVehicleRoutingMavenCommand(), vehicleRoutingRepository) + } } } } @@ -231,9 +268,14 @@ pipeline { expression { return isRelease() || isCreatePr() } } steps { - commitAndCreatePR(optaplannerRepository, getBuildBranch()) - commitAndCreatePRIgnoringNpmRegistry(vehicleRoutingRepository, getBuildBranch()) - commitAndCreatePR(quickstartsRepository, getQuickStartsBranch()) + script { + commitAndCreatePR(optaplannerRepository, getBuildBranch()) + // TODO: switch to the 9 stream after quickstarts and the optaweb will have been migrated. + if (isStream8()) { + commitAndCreatePRIgnoringNpmRegistry(vehicleRoutingRepository, getBuildBranch()) + commitAndCreatePR(quickstartsRepository, getQuickStartsBranch()) + } + } } post { success { @@ -254,7 +296,7 @@ pipeline { stage('Push a temporary operator image to a registry') { when { - expression { return isRelease() } + expression { return isRelease() && isStream8() } } steps { script { @@ -589,4 +631,12 @@ void pushOperatorTemporaryImage() { getOperatorImageNamespace(), getOperatorImageName(), temporaryImageTag) imageUtils.tagImage(localImage, temporaryImageFullName) imageUtils.pushImage(temporaryImageFullName) +} + +boolean isStream8() { + return env.OPTAPLANNER_LATEST_STREAM == '8' +} + +boolean isStream9() { + return env.OPTAPLANNER_LATEST_STREAM == '9' } \ No newline at end of file diff --git a/.ci/jenkins/Jenkinsfile.promote b/.ci/jenkins/Jenkinsfile.promote index e045b8ee067..549ec51c03a 100644 --- a/.ci/jenkins/Jenkinsfile.promote +++ b/.ci/jenkins/Jenkinsfile.promote @@ -82,7 +82,8 @@ pipeline { stage('Merge Optaweb Vehicle Routing deploy PR and tag') { when { - expression { return isRelease() } + // TODO: switch to the 9 stream after optaweb will have been migrated. + expression { return isRelease() && isStream8() } } steps { script { @@ -97,7 +98,8 @@ pipeline { stage('Merge OptaPlanner Quickstarts PR and tag') { when { - expression { return isRelease() } + // TODO: switch to the 9 stream after quickstarts and the optaweb will have been migrated. + expression { return isRelease() && isStream8() } } steps { script { @@ -112,11 +114,16 @@ pipeline { stage('Upload OptaPlanner documentation') { when { - expression { return isRelease() } + // TODO: switch to the 9 stream after quickstarts and the optaweb will have been migrated. + expression { return isRelease() && isStream8() } } steps { script { - getMavenCommand().inDirectory(optaplannerRepository).skipTests(true).withProperty('full').run('clean install') + getMavenCommand() + .inDirectory(optaplannerRepository) + .skipTests(true) + .withProperty('full') + .run('clean install') uploadDistribution(optaplannerRepository) } } @@ -124,11 +131,15 @@ pipeline { stage('Upload Vehicle Routing documentation and distribution') { when { - expression { return isRelease() } + // TODO: switch to the 9 stream after quickstarts and the optaweb will have been migrated. + expression { return isRelease() && isStream8() } } steps { script { - getMavenCommand().inDirectory(vehicleRoutingRepository).skipTests(true).run('clean install') + getMavenCommand() + .inDirectory(vehicleRoutingRepository) + .skipTests(true) + .run('clean install') uploadDistribution(vehicleRoutingRepository) } } @@ -162,7 +173,8 @@ pipeline { stage('Set Optaweb Vehicle Routing next snapshot version') { when { - expression { return isRelease() } + // TODO: switch to the 9 stream after quickstarts and the optaweb will have been migrated. + expression { return isRelease() && isStream8() } } steps { script { @@ -185,7 +197,8 @@ pipeline { stage('Set Quickstarts next snapshot version') { when { - expression { return isRelease() } + // TODO: switch to the 9 stream after quickstarts and the optaweb will have been migrated. + expression { return isRelease() && isStream8() } } steps { script { @@ -208,7 +221,7 @@ pipeline { stage('Push the final OptaPlanner operator image') { when { - expression { return isRelease() } + expression { return isRelease() && isStream8() } } steps { script { @@ -497,4 +510,12 @@ void removeOperatorImageTemporaryTag() { error "Cannot remove the OptaPlanner Operator temporary image tag (${temporaryImageName}) from quay.io. " + "The tag should be removed manually." } +} + +boolean isStream8() { + return env.OPTAPLANNER_LATEST_STREAM == '8' +} + +boolean isStream9() { + return env.OPTAPLANNER_LATEST_STREAM == '9' } \ No newline at end of file diff --git a/.ci/jenkins/dsl/jobs.groovy b/.ci/jenkins/dsl/jobs.groovy index 6d9ce5b3978..dfac655b627 100644 --- a/.ci/jenkins/dsl/jobs.groovy +++ b/.ci/jenkins/dsl/jobs.groovy @@ -67,7 +67,8 @@ void createProjectSetupBranchJob() { GIT_BRANCH_NAME: "${GIT_BRANCH}", GIT_AUTHOR: "${GIT_AUTHOR_NAME}", - IS_MAIN_BRANCH: "${Utils.isMainBranch(this)}" + IS_MAIN_BRANCH: "${Utils.isMainBranch(this)}", + OPTAPLANNER_LATEST_STREAM: getOptaPlannerLatestStream() ]) KogitoJobTemplate.createPipelineJob(this, jobParams)?.with { parameters { @@ -84,9 +85,11 @@ void setupProjectNightlyJob() { GIT_BRANCH_NAME: "${GIT_BRANCH}", GIT_AUTHOR: "${GIT_AUTHOR_NAME}", + AUTHOR_CREDS_ID: "${GIT_AUTHOR_CREDENTIALS_ID}", MAVEN_SETTINGS_CONFIG_FILE_ID: "${MAVEN_SETTINGS_FILE_ID}", ARTIFACTS_REPOSITORY: "${MAVEN_ARTIFACTS_REPOSITORY}", + OPTAPLANNER_LATEST_STREAM: getOptaPlannerLatestStream() ]) KogitoJobTemplate.createPipelineJob(this, jobParams)?.with { parameters { @@ -105,6 +108,7 @@ void setupProjectReleaseJob() { DEFAULT_STAGING_REPOSITORY: "${MAVEN_NEXUS_STAGING_PROFILE_URL}", ARTIFACTS_REPOSITORY: "${MAVEN_ARTIFACTS_REPOSITORY}", + OPTAPLANNER_LATEST_STREAM: getOptaPlannerLatestStream() ]) KogitoJobTemplate.createPipelineJob(this, jobParams)?.with { parameters { @@ -135,6 +139,7 @@ void setupProjectPostReleaseJob() { MAVEN_DEPENDENCIES_REPOSITORY: "${MAVEN_ARTIFACTS_REPOSITORY}", GITHUB_CLI_VERSION: '0.11.1', + OPTAPLANNER_LATEST_STREAM: getOptaPlannerLatestStream() ]) KogitoJobTemplate.createPipelineJob(this, jobParams)?.with { parameters { @@ -245,7 +250,8 @@ void createSetupBranchJob() { MAVEN_DEPENDENCIES_REPOSITORY: "${MAVEN_ARTIFACTS_REPOSITORY}", MAVEN_DEPLOY_REPOSITORY: "${MAVEN_ARTIFACTS_REPOSITORY}", - IS_MAIN_BRANCH: "${Utils.isMainBranch(this)}" + IS_MAIN_BRANCH: "${Utils.isMainBranch(this)}", + OPTAPLANNER_LATEST_STREAM: getOptaPlannerLatestStream() ]) KogitoJobTemplate.createPipelineJob(this, jobParams)?.with { parameters { @@ -273,6 +279,7 @@ void setupDeployJob(Folder jobFolder) { JENKINS_EMAIL_CREDS_ID: "${JENKINS_EMAIL_CREDS_ID}", MAVEN_SETTINGS_CONFIG_FILE_ID: "${MAVEN_SETTINGS_FILE_ID}", + OPTAPLANNER_LATEST_STREAM: getOptaPlannerLatestStream() ]) if (jobFolder.isPullRequest()) { jobParams.env.putAll([ @@ -358,6 +365,7 @@ void setupPromoteJob(Folder jobFolder) { PROPERTIES_FILE_NAME: 'deployment.properties', GITHUB_CLI_VERSION: '0.11.1', + OPTAPLANNER_LATEST_STREAM: getOptaPlannerLatestStream() ]) KogitoJobTemplate.createPipelineJob(this, jobParams)?.with { parameters { @@ -398,3 +406,15 @@ void setupOptaPlannerTurtleTestsJob(String constraintStreamImplType) { } } } + +String getOptaPlannerLatestStream() { + String gitMainBranch = "${GIT_MAIN_BRANCH}" + + if (gitMainBranch == 'main') { + return '8' + } else if (gitMainBranch == '9.x') { + return '9' + } else { + return gitMainBranch + } +} \ No newline at end of file diff --git a/.ci/jenkins/project/Jenkinsfile.nightly b/.ci/jenkins/project/Jenkinsfile.nightly index 0ed6342047d..2d2e06517cb 100644 --- a/.ci/jenkins/project/Jenkinsfile.nightly +++ b/.ci/jenkins/project/Jenkinsfile.nightly @@ -1,6 +1,10 @@ import org.jenkinsci.plugins.workflow.libs.Library @Library('jenkins-pipeline-shared-libraries')_ +String optaPlannerRepository = 'optaplanner' +String optaPlannerMainBranch = 'main' +String optaPlanner9xBranch = '9.x' + // Deploy jobs OPTAPLANNER_DEPLOY = 'optaplanner-deploy' @@ -49,13 +53,28 @@ pipeline { } } + // Applies only to the 9.x branch build. The 9.?.x release branches must remain intact. + stage('Migrate to 9') { + when { + expression { return getBuildBranch() == optaPlanner9xBranch } + } + steps { + script { + checkoutNewBranch(optaPlannerRepository, optaPlannerMainBranch, optaPlanner9xBranch) + callMigrationScript(optaPlannerRepository) + forcePushBranch(optaPlannerRepository, optaPlanner9xBranch) + } + } + } + stage('Build & Deploy OptaPlanner') { steps { script { def buildParams = getDefaultBuildParams(getBuildBranch()) addSkipTestsParam(buildParams) addSkipIntegrationTestsParam(buildParams) - def quickstartsBranch = getBuildBranch() == 'main' ? 'development' : getBuildBranch() + def quickstartsBranch = getBuildBranch() == 'main' || getBuildBranch() == '9.x' + ? 'development' : getBuildBranch() addStringParam(buildParams, 'QUICKSTARTS_BUILD_BRANCH_NAME', quickstartsBranch) buildJob(OPTAPLANNER_DEPLOY, buildParams) @@ -169,3 +188,33 @@ String getBuildBranch() { String getGitAuthor() { return env.GIT_AUTHOR } + +String getGitAuthorCredsID() { + return env.AUTHOR_CREDS_ID +} + +void checkoutNewBranch(String repo, String originBranch, String newBranch, String dirName = repo) { + dir(dirName) { + deleteDir() + checkout(githubscm.resolveRepository(repo, getGitAuthor(), originBranch, false)) + sh "git checkout -b ${newBranch}" + } +} + +void forcePushBranch(String dirName, String branch) { + dir(dirName) { + withCredentials([usernamePassword(credentialsId: getGitAuthorCredsID(), usernameVariable: 'GIT_USERNAME', passwordVariable: 'GIT_PASSWORD')]) { + // Please leave the double-quote here. They are mandatory for the shell command to work correctly. + sh """ + git config --local credential.helper \"!f() { echo username=\\$GIT_USERNAME; echo password=\\$GIT_PASSWORD; }; f\" + git push origin ${branch} --force + """ + } + } +} + +void callMigrationScript(String dirName) { + dir(dirName) { + sh "./build/8-to-9-migration/migrate.sh" + } +} \ No newline at end of file diff --git a/.ci/jenkins/project/Jenkinsfile.post-release b/.ci/jenkins/project/Jenkinsfile.post-release index 2faf9380eb9..87540cdbb6c 100644 --- a/.ci/jenkins/project/Jenkinsfile.post-release +++ b/.ci/jenkins/project/Jenkinsfile.post-release @@ -57,6 +57,10 @@ pipeline { } stage('Reset Quickstarts stable branch') { + when { + // TODO: switch to the 9 stream after quickstarts and the optaweb will have been migrated. + expression { return isStream8() } + } steps { script { dir(quickstartsRepository) { @@ -69,6 +73,10 @@ pipeline { } stage('Upload OptaPlanner distribution from Quickstarts') { + when { + // TODO: switch to the 9 stream after quickstarts and the optaweb will have been migrated. + expression { return isStream8() } + } steps { script { dir(optaplannerRepository) { @@ -83,6 +91,10 @@ pipeline { } stage('Update OptaPlanner website') { + when { + // TODO: switch to the 9 stream after quickstarts and the optaweb will have been migrated. + expression { return isStream8() } + } steps { script { final String websiteRepository = 'optaplanner-website' @@ -364,3 +376,11 @@ void assertGithubCLI(String ghPath) { error "gh not found at $ghPath" } } + +boolean isStream8() { + return env.OPTAPLANNER_LATEST_STREAM == '8' +} + +boolean isStream9() { + return env.OPTAPLANNER_LATEST_STREAM == '9' +} \ No newline at end of file diff --git a/build/8-to-9-migration/migrate.sh b/build/8-to-9-migration/migrate.sh index d15a39a53e3..efd0b4cd22d 100755 --- a/build/8-to-9-migration/migrate.sh +++ b/build/8-to-9-migration/migrate.sh @@ -13,7 +13,7 @@ project_version=$(${mvn_cmd} help:evaluate -Dexpression=project.version -q -Dfor ${mvn_cmd} rewrite:run \ -Drewrite.configLocation="${optaplanner_file}" \ -Drewrite.recipeArtifactCoordinates=org.optaplanner:optaplanner-migration:"$project_version" \ - -Drewrite.exclusions=optaplanner-operator/** \ + -Drewrite.exclusions=optaplanner-operator/**,optaplanner-examples/data/** \ -Drewrite.activeRecipes=org.optaplanner.openrewrite.Quarkus3 \ -Dfull \ -Dquickly \