diff --git a/JenkinsJobs/Releng/prepareNextDevCycle.jenkinsfile b/JenkinsJobs/Releng/prepareNextDevCycle.jenkinsfile index 44946a21b21..d4a517f913d 100644 --- a/JenkinsJobs/Releng/prepareNextDevCycle.jenkinsfile +++ b/JenkinsJobs/Releng/prepareNextDevCycle.jenkinsfile @@ -76,6 +76,7 @@ pipeline { steps { checkout scm script { // Always load the script from the very same state this pipeline is loaded (to ensure consistency) + utilities = load "JenkinsJobs/shared/utilities.groovy" githubAPI = load "JenkinsJobs/shared/githubAPI.groovy" githubAPI.setDryRun(params.DRY_RUN) } @@ -154,7 +155,7 @@ pipeline { "(?# Schedule:.*\\R)(?s).*(?\\R'''\\))" : "\${prefix}${I_BUILD_SCHEDULE}\${suffix}", ]) - commitAllChangesExcludingSubmodules("Update versions to ${NEXT_RELEASE_VERSION} in build scripts") + utilities.commitAllChangesExcludingSubmodules("Update versions to ${NEXT_RELEASE_VERSION} in build scripts") } } stage('Move previous version to current RC') { @@ -182,7 +183,7 @@ pipeline { 'previousReleaseVersion=.*' : "previousReleaseVersion=${PREVIOUS_RELEASE_CANDIDATE_TAG}", 'previousReleaseVersionRepo=.*' : "previousReleaseVersionRepo=${PREVIOUS_RELEASE_VERSION}-I-builds", ]) - commitAllChangesExcludingSubmodules("Move previous version to ${PREVIOUS_RELEASE_CANDIDATE_TAG} in build scripts") + utilities.commitAllChangesExcludingSubmodules("Move previous version to ${PREVIOUS_RELEASE_CANDIDATE_TAG} in build scripts") } } stage('Clear Qualifier-update files') { @@ -242,7 +243,7 @@ pipeline { ]) sh "mv cje-production/streams/repositories_master.txt cje-production/streams/repositories_${MAINTENANCE_BRANCH}.txt" - commitAllChangesExcludingSubmodules("Move ${PREVIOUS_RELEASE_VERSION}-I builds to ${MAINTENANCE_BRANCH} branch") + utilities.commitAllChangesExcludingSubmodules("Move ${PREVIOUS_RELEASE_VERSION}-I builds to ${MAINTENANCE_BRANCH} branch") // Switch back to master for subsequent parts of this pipeline sh 'git checkout master' @@ -441,6 +442,8 @@ pipeline { } } +@groovy.transform.Field +def utilities = null @groovy.transform.Field def githubAPI = null @@ -466,28 +469,9 @@ def parseDate(String dateString) { } def replaceInFile(String filePath, Map replacements) { - replaceAllInFile(filePath, replacements.collectEntries{ k, v -> [java.util.regex.Pattern.quote(k), v] }); + utilities.replaceInFile(filePath, replacements) } def replaceAllInFile(String filePath, Map replacements) { - def content = readFile(filePath) - for (entry in replacements) { - def newContent = content.replaceAll(entry.key, entry.value) - if (newContent == content && !(content =~ entry.key)) { // pattern matches, but the replacement is equal to the current content - error("Pattern not found in file '${filePath}': ${entry.key}") - } - content = newContent - } - writeFile(file:filePath, text: content) -} - -def commitAllChangesExcludingSubmodules(String commitMessage) { - withEnv(["COMMIT_MESSAGE=${commitMessage}"]) { - sh ''' - #Commit all changes, except for the updated sub-modules here - git add --all - git restore --staged $(git submodule foreach --quiet 'echo $sm_path') - git commit --message "${COMMIT_MESSAGE}" - ''' - } + utilities.replaceAllInFile(filePath, replacements) } diff --git a/JenkinsJobs/Releng/promoteBuild.jenkinsfile b/JenkinsJobs/Releng/promoteBuild.jenkinsfile index eb04934ef42..2431e449168 100644 --- a/JenkinsJobs/Releng/promoteBuild.jenkinsfile +++ b/JenkinsJobs/Releng/promoteBuild.jenkinsfile @@ -67,6 +67,7 @@ pipeline { ) // This is DL_DROP_ID for Eclipse and Equinox assignEnvVariable('DL_DROP_ID', "${DL_TYPE}-${DL_LABEL}-${buildTimestamp}") + assignEnvVariable('MAINTENANCE_BRANCH', "R${BUILD_MAJOR}_${BUILD_MINOR}_maintenance") if (!env.SIGNOFF_BUG) { echo '''\ @@ -79,14 +80,20 @@ pipeline { } } } - stage('Checkout Git') { + stage('Checkout SCM') { steps { dir("${WORKSPACE}/repository") { checkout scm script { // Always load the script from the very same state this pipeline is loaded (to ensure consistency) + utilities = load "JenkinsJobs/shared/utilities.groovy" githubAPI = load "JenkinsJobs/shared/githubAPI.groovy" } sh '''#!/bin/bash -xe + git branch --force master HEAD + git fetch origin "refs/heads/${MAINTENANCE_BRANCH}" + git reflog show master + git reflog show "origin/${MAINTENANCE_BRANCH}" + git fetch origin tag "${REPO_ID}" git checkout "${REPO_ID}" # Check out all submodules at the specified REPO_ID @@ -187,6 +194,108 @@ pipeline { ] } } + stage('Update build configurations') { + when { + environment name: 'DL_TYPE', value: 'R' + } + environment { + RELEASE_P2_REPOSITORY = "https://download.eclipse.org/eclipse/updates/${BUILD_MAJOR}.${BUILD_MINOR}/${DL_DROP_ID}/" + } + steps { + dir("${WORKSPACE}/repository") { + script { // Update the master branch + sh 'git checkout master' + sh ''' + mvn -f eclipse-platform-parent/pom.xml org.eclipse.tycho:tycho-versions-plugin:set-property \ + -Dproperties=previous-release.baseline \ + -DnewPrevious-release.baseline="${RELEASE_P2_REPOSITORY}" + ''' + utilities.replaceAllInFile('cje-production/buildproperties.txt', [ + 'BASEBUILDER_TAG=".*?"' : "BASEBUILDER_TAG=\"${BUILD_MAJOR}.${BUILD_MINOR}\"", + 'API_PREV_REF_LABEL=".*?"' : "API_PREV_REF_LABEL=\"${BUILD_MAJOR}.${BUILD_MINOR}\"", + 'PREVIOUS_RELEASE_VER=".*?"' : "PREVIOUS_RELEASE_VER=\"${BUILD_MAJOR}.${BUILD_MINOR}\"", + 'PREVIOUS_RELEASE_REPO_ID=".*?"' : "PREVIOUS_RELEASE_REPO_ID=\"${BUILD_MAJOR}.${BUILD_MINOR}\"", + 'BASEBUILD_ID=".*?"' : "BASEBUILD_ID=\"${DL_DROP_ID}\"", + 'PREVIOUS_RELEASE_ID=".*?"' : "PREVIOUS_RELEASE_ID=\"${DL_DROP_ID}\"", + ]) + utilities.replaceAllInFile('eclipse.platform.releng.tychoeclipsebuilder/eclipse-junit-tests/src/main/resources/equinoxp2tests.properties', [ + 'eclipse-platform-\\d+.\\d+[^-]*?-' : "eclipse-platform-${BUILD_MAJOR}.${BUILD_MINOR}-", + 'org.eclipse.equinox.p2.tests.last.release.build.repo=.*' : "org.eclipse.equinox.p2.tests.last.release.build.repo=https://download.eclipse.org/equinox/drops/${DL_DROP_ID}/", + ]) + utilities.replaceAllInFile('eclipse.platform.releng.tychoeclipsebuilder/eclipse-junit-tests/src/main/resources/label.properties', [ + 'previousReleaseVersion=.*' : "previousReleaseVersion=${BUILD_MAJOR}.${BUILD_MINOR}", + ]) + utilities.replaceAllInFile('eclipse.platform.releng.tychoeclipsebuilder/eclipse-junit-tests/src/main/scripts/getPreviousRelease.sh', [ + 'R\\/R-\\d+.\\d+-\\d{12}' : "R/${DL_DROP_ID}", + '-\\d+.\\d+-linux-gtk-' : "-${BUILD_MAJOR}.${BUILD_MINOR}-linux-gtk-", + ]) + utilities.replaceAllInFile('production/testScripts/configuration/streamSpecific.properties', [ + 'previousReleaseLocation=.*' : 'previousReleaseLocation=https://\\${DOWNLOAD_HOST}/eclipse/downloads/drops4/' + DL_DROP_ID + '/', + 'previousReleaseVersion=.*' : "previousReleaseVersion=${BUILD_MAJOR}.${BUILD_MINOR}", + 'previousReleaseVersionRepo=.*' : "previousReleaseVersionRepo=${BUILD_MAJOR}.${BUILD_MINOR}", + ]) + + utilities.commitAllChangesExcludingSubmodules("Update previous release version to ${BUILD_MAJOR}.${BUILD_MINOR} GA across build scripts") + } + script { // Update the maintenance branch + sh 'git checkout -b updateMaintenance "origin/${MAINTENANCE_BRANCH}"' + def ecjManifest = sh(script: "curl https://raw.githubusercontent.com/eclipse-jdt/eclipse.jdt.core/refs/tags/${REPO_ID}/org.eclipse.jdt.core.compiler.batch/META-INF/MANIFEST.MF", returnStdout: true).trim() + def bundleVersion = readManifest(text: ecjManifest).main['Bundle-Version'] + def ecjVersion = bundleVersion.substring(0, bundleVersion.indexOf('.qualifier')) + sh """ + mvn -f eclipse-platform-parent/pom.xml org.eclipse.tycho:tycho-versions-plugin:set-property \ + -Dproperties=eclipse-sdk-repo,previous-release.baseline,cbi-ecj-version \ + -DnewEclipse-sdk-repo="${RELEASE_P2_REPOSITORY}" \ + -DnewPrevious-release.baseline="${RELEASE_P2_REPOSITORY}" \ + -DnewCbi-ecj-version="${ecjVersion}" + """ + utilities.replaceAllInFile('cje-production/buildproperties.txt', [ + 'ECLIPSE_RUN_REPO="https://download.eclipse.org/eclipse/updates/.*"' : "ECLIPSE_RUN_REPO=\"${RELEASE_P2_REPOSITORY}\"", + ]) + + utilities.commitAllChangesExcludingSubmodules("Update ${MAINTENANCE_BRANCH} branch with release version for ${BUILD_MAJOR}_${BUILD_MINOR}+ changes") + } + // Switch back to master for subsequent parts of this pipeline + sh 'git checkout master' + + // Display created commits + sh '''#!/bin/bash -xe + git log origin/master..master --patch-with-stat --summary + git log origin/${MAINTENANCE_BRANCH}..updateMaintenance --patch-with-stat --summary + ''' + sshagent(['github-bot-ssh']) { + sh '''#!/bin/bash -xe + pushURL=$(git config remote.origin.url) + # Switch to SSH, if the configured URL uses HTTPS (we can only push with SSH) + if [[ "$pushURL" == http* ]]; then + pushURL=$(echo $pushURL|sed --expression 's|https://github.com/|git@github.com:|') + fi + + git push ${pushURL} "master:refs/heads/update-build-to-R${BUILD_MAJOR}.${BUILD_MINOR}" + git push ${pushURL} "updateMaintenance:refs/heads/update-${MAINTENANCE_BRANCH}" + ''' + } + // Create PRs agains the master and maintenance branch + script { withEnv(['GITHUB_BOT_TOKEN=' + credentials('github-bot-token')]) { + def masterPR = githubAPI.createPullRequest('eclipse-platform/eclipse.platform.releng.aggregator', + "Update previous release version to ${BUILD_MAJOR}.${BUILD_MINOR} GA across build scripts", """\ + Update the the `${MAINTENANCE_BRANCH}` branch with final ${BUILD_MAJOR}.${BUILD_MINOR} release version. + + **This should not be submitted before ${BUILD_MAJOR}.${BUILD_MINOR} is finally released.** + """.stripIndent(),"update-build-to-R${BUILD_MAJOR}.${BUILD_MINOR}", 'master') + + githubAPI.createPullRequest('eclipse-platform/eclipse.platform.releng.aggregator', + "Update ${MAINTENANCE_BRANCH} branch with release version for ${BUILD_MAJOR}_${BUILD_MINOR}+ changes", """\ + Update the the `${MAINTENANCE_BRANCH}` branch with final ${BUILD_MAJOR}.${BUILD_MINOR} release version. + This complements: + - ${masterPR} + + **This should not be submitted before ${BUILD_MAJOR}.${BUILD_MINOR} is finally released.** + """.stripIndent(),"update-${MAINTENANCE_BRANCH}", "${MAINTENANCE_BRANCH}") + }} + } + } + } stage('Update acknowledgements') { environment { GITHUB_BOT_TOKEN = credentials('github-bot-token') @@ -292,6 +401,8 @@ EOF """ } +@groovy.transform.Field +def utilities = null @groovy.transform.Field def githubAPI = null diff --git a/JenkinsJobs/shared/githubAPI.groovy b/JenkinsJobs/shared/githubAPI.groovy index 591e824e65b..1246c4d608e 100644 --- a/JenkinsJobs/shared/githubAPI.groovy +++ b/JenkinsJobs/shared/githubAPI.groovy @@ -69,6 +69,9 @@ def queryGithubAPI(String method, String endpoint, Map queryPara query += "-d '" + params + "'" } if (IS_DRY_RUN && !method.isEmpty()) { + if (!env.GITHUB_BOT_TOKEN) { + error 'Required GITHUB_BOT_TOKEN not set' + } echo "Query (not send): ${query}" return null } diff --git a/JenkinsJobs/shared/utilities.groovy b/JenkinsJobs/shared/utilities.groovy new file mode 100644 index 00000000000..90c8f0109ad --- /dev/null +++ b/JenkinsJobs/shared/utilities.groovy @@ -0,0 +1,29 @@ + +def replaceInFile(String filePath, Map replacements) { + replaceAllInFile(filePath, replacements.collectEntries{ k, v -> [java.util.regex.Pattern.quote(k), v] }); +} + +def replaceAllInFile(String filePath, Map replacements) { + def content = readFile(filePath) + for (entry in replacements) { + def newContent = content.replaceAll(entry.key, entry.value) + if (newContent == content && !(content =~ entry.key)) { // pattern matches, but the replacement is equal to the current content + error("Pattern not found in file '${filePath}': ${entry.key}") + } + content = newContent + } + writeFile(file:filePath, text: content) +} + +def commitAllChangesExcludingSubmodules(String commitMessage) { + withEnv(["COMMIT_MESSAGE=${commitMessage}"]) { + sh ''' + #Commit all changes, except for the updated sub-modules here + git add --all + git restore --staged $(git submodule foreach --quiet 'echo $sm_path') + git commit --message "${COMMIT_MESSAGE}" + ''' + } +} + +return this diff --git a/RELEASE.md b/RELEASE.md index 9f9d5b392c6..1e040e7b29c 100644 --- a/RELEASE.md +++ b/RELEASE.md @@ -93,6 +93,8 @@ The actual steps to release * #### **Promote to GA** - After Simrel declares RC2 (usually the Friday before release) run the [Promote Build](https://ci.eclipse.org/releng/job/Releng/job/promoteBuild/) job to promote RC2 (or RC2a). - `DROP_ID`: Final delease candidate's ID, e.g.: `S-4.36RC2-202505281830/` + - This will create pull requests to update the build configuration on the master and corresponding maintenance branch to the promoted release. + - Only submit them AFTER the release was finally published. - You can subscribe to [cross-project-issues](https://accounts.eclipse.org/mailing-list/cross-project-issues-dev) to get the notifications on Simrel releases. * **Contribute to SimRel** - If SimRel is not updated before the I-builds are cleaned up (specifically the build for RC2/GA) it will break. @@ -120,29 +122,11 @@ The release is scheduled for 10AM EST. Typically the jobs are scheduled beforeha - For the Y and P build parameters it's important to know whether or not Y and P builds were run during the release. Since they correspond to java releases on a 6 month cycle, typically they are built in odd-numbered releases. The existing builds are kept for one release, then cleaned up before the next stream that will have Y and P builds. it's convoluted and I dont want to type it out. Remove Y builds on even releases. - If something doesn't get cleaned up properly you can use Use the [list artifacts](https://ci.eclipse.org/releng/view/Cleanup/job/list_artifacts_from_download_server/) job to generate ta list of what's on the download server and either create a new job to clean it up or update and rerun the cleanup job as appropriate. - * **Set Previous Release to GA** - - Everything that was updated to RC2 (see below) should now use the released build. ### **Preparation for the next Release** After RC2 create an issue to track preparation work for the next stream (see [Preparation work for 4.25 (2022-09)](https://github.com/eclipse-platform/eclipse.platform.releng.aggregator/issues/284)). - A script to create this issue exists [here](scripts/newReleasePrep.sh) for those who have the hub cli tool installed. The process has been in flux recently so please update the script if necessary, but it provides a helpful template since most tasks in the previous release's issue become links. -#### **Maintenance Branches:** - * **Update maintenance branch with release version** - - Once the I-build repo is removed for the previous release the maintenance branch will have to use the release location, i.e. any references to `https://download.eclipse.org/eclipse/updates/4.25-I-builds/` will need to be updated to `https://download.eclipse.org/eclipse/updates/4.26/R-4.26-202211231800/` - - Functionally this means: - - Update the ECLIPSE_RUN_REPO in the [cje-production](cje-production) buildproperties.txt files - - Update `eclipse-sdk-repo` in [eclipse-platform-parent/pom.xml](eclipse-platform-parent/pom.xml) - - This step can be prepared ahead of time but can't be merged until the release build has been promoted and the update site exists. - * **Update ECJ compiler** in the platform build (if it needs to be updated). - * To find the new *unqualified* compiler version: - - Go to the update site for the release candidate - - Click `plugins` - - Find the *unqualified* version of the artifact `org.eclipse.jdt.core.complier.batch_${ecjversion}.jar`, i.e. the version consisting only of the _major_._minor_._service_ part, but without qualifier. - It's the version of the `org.eclipse.jdt:ecj` artifact at Maven-Central, about to be relased. - * Update the `cbi-ecj-version` in [eclipse.platform.releng.aggregator/eclipse-platform-parent/pom.xml](https://github.com/eclipse-platform/eclipse.platform.releng.aggregator/blob/master/eclipse-platform-parent/pom.xml) - to the exact version of the to be released`org.eclipse.jdt.core.complier.batch` bundle, e.g.: `3.40.0` - #### **Update the Build Calendar:** - Create an [issue](https://github.com/eclipse-platform/eclipse.platform.releng.aggregator/issues/289) and update the [build calendar](https://calendar.google.com/calendar/u/0?cid=cHJmazI2ZmRtcHJ1MW1wdGxiMDZwMGpoNHNAZ3JvdXAuY2FsZW5kYXIuZ29vZ2xlLmNvbQ) for the next GA release based on the [Simultaneous Release schedule](https://wiki.eclipse.org/Simultaneous_Release). - Each stream has its own [wiki](https://wiki.eclipse.org/Category:SimRel-2022-06) page with a more detailed schedule.