From eabe11d0f4b9578acd9e4e4cb440db56b01543a6 Mon Sep 17 00:00:00 2001 From: Aashish Radhakrishnan Date: Thu, 7 Sep 2023 10:15:37 -0400 Subject: [PATCH] jobs: Add a bump-jenkins job bump-jenkins job added to periodically update the jenkins plugins to latest version Ref: https://github.com/coreos/fedora-coreos-pipeline/issues/562 --- jobs/bump-jenkins.Jenkinsfile | 223 ++++++++++++++++++++++++++++++++++ 1 file changed, 223 insertions(+) create mode 100644 jobs/bump-jenkins.Jenkinsfile diff --git a/jobs/bump-jenkins.Jenkinsfile b/jobs/bump-jenkins.Jenkinsfile new file mode 100644 index 000000000..f1117e79d --- /dev/null +++ b/jobs/bump-jenkins.Jenkinsfile @@ -0,0 +1,223 @@ +import groovy.json.* +node { + checkout scm + // these are script global vars + pipeutils = load("utils.groovy") + pipecfg = pipeutils.load_pipecfg() +} + +properties([ + pipelineTriggers([ + // check once a week every Monday + pollSCM('H H * * 1') + ]), + parameters([ + choice(name: 'STREAM', + choices: pipeutils.streams_of_type(pipecfg, 'development'), + description: 'CoreOS development stream to bump'), + string(name: 'SKIP_TESTS_ARCHES', + description: 'Space-separated list of architectures to skip tests on', + defaultValue: "", + trim: true), + string(name: 'COREOS_ASSEMBLER_IMAGE', + description: 'Override coreos-assembler image to use', + defaultValue: "", + trim: true), + booleanParam(name: 'ALLOW_KOLA_UPGRADE_FAILURE', + defaultValue: false, + description: "Don't error out if upgrade tests fail (temporary)"), + ]), + buildDiscarder(logRotator( + numToKeepStr: '100', + artifactNumToKeepStr: '100' + )), + durabilityHint('PERFORMANCE_OPTIMIZED') +]) + +// runtime parameter always wins +def cosa_img = params.COREOS_ASSEMBLER_IMAGE +cosa_img = cosa_img ?: pipeutils.get_cosa_img(pipecfg, params.STREAM) + + +// Keep in sync with build.Jenkinsfile +def cosa_memory_request_mb = 10.5 * 1024 as Integer +def ncpus = ((cosa_memory_request_mb - 512) / 1536) as Integer + + +def getPluginLatestURL(pluginName) { + def pluginsUpdate + node { + pluginsUpdate = shwrapCapture("curl -Ls -o /dev/null -w '%{url_effective}' https://updates.jenkins.io/download/plugins/${pluginName}/latest/${pluginName}.hpi") + } + return pluginsUpdate +} + +def getPluginLatestVersion(pluginsUpdate) { + // Extract the plugin version from the URL + def versionPattern = /\/([^\/]+)\/([^\/]+)\/([^\/]+)\.hpi/ + def matcher = (pluginsUpdate =~ versionPattern) + def pluginVersion + + if (matcher.find()) { + def groupId = matcher.group(1) + pluginVersion = matcher.group(2) + println "Group ID: ${groupId}" + println "Plugin Version: ${pluginVersion}" + } else { + println "Unable to extract plugin version from the URL." + } + return pluginVersion +} + +lock(resource: "bump-jenkins") { + cosaPod(image: cosa_img, + cpu: "${ncpus}", memory: "${cosa_memory_request_mb}Mi", + serviceAccount: "jenkins") { + timeout(time: 180, unit: 'MINUTES') { + try { + + currentBuild.description = "[${params.STREAM}] Running" + + // add any additional root CA cert before we do anything that fetches + pipeutils.addOptionalRootCA() + + // set up git user upfront + shwrap(""" + git config --global user.name "CoreOS Bot" + git config --global user.email "coreosbot@fedoraproject.org" + """) + + def pluginslist + def pluginsToUpdate = [:] + def haveChanges=false + def branch = params.STREAM + def repo = "coreos/fedora-coreos-pipeline" + + stage("Read plugins.txt") { + node { + shwrapCapture(""" + if [[ -d fedora-coreos-pipeline ]]; then + rm -rf fedora-coreos-pipeline + fi + git clone --branch jp https://github.com/aaradhak/fedora-coreos-pipeline.git + """) + } + def plugins_lockfile = "jenkins/controller/plugins.txt" + node { + pluginslist = shwrapCapture("cat $plugins_lockfile | grep -v ^#").split('\n') + } + } + + stage("Check for plugin updates") { + def pluginsUpdate + pluginslist.each { plugin -> + def parts = plugin.split(':') + if (parts.size() == 2) { + def pluginName = parts[0] + def currentVersion = parts[1] + println ("pluginName:${pluginName}") + println ("currentVersion:${currentVersion}") + pluginsUpdate = getPluginLatestURL(pluginName) + def latestVersion = getPluginLatestVersion(pluginsUpdate) + println ("latestVersion:${latestVersion}") + if (latestVersion.toString() != currentVersion.toString()) { + haveChanges = true + pluginsToUpdate["${pluginName}"] = [currentVersion, latestVersion] + println("Plugin: ${pluginName} current version is ${currentVersion}, it will be updated to latest version: ${latestVersion}") + } + else { + println("The latest version of ${pluginName} is already installed: ${currentVersion}") + } + } + else { + println("ERROR: unexpected") + } + } + } + + stage("update plugins") { + println("Plugins to update:") + for (p in pluginsToUpdate) { + println("Will update ${p.key} from version ${p.value[0]} to version ${p.value[1]}") + } + } + + + stage("modify plugins.txt"){ + def modifiedlist = [] + pluginslist.each { plug -> + def parts = plug.split(':') + if (parts.size() == 2) { + def pluginName = parts[0] + def pluginVersion = parts[1] + if (pluginsToUpdate.containsKey(pluginName)) { + modifiedlist << "${pluginName}:${pluginsToUpdate[pluginName][1]}" + println("Updated ${pluginName} from ${pluginVersion} to ${pluginsToUpdate[pluginName][1]}") + } else { + + modifiedlist << plug + } + } else { + println("ERROR: unexpected format for plugin ${plug}") + } + } + + println("Modified List:") + modifiedlist.each { println(it) } + + node{ + writeFile file: "jenkins/controller/plugins.txt", text: modifiedlist.join('\n') + } + } + + stage("Push") { + if (haveCHanges){ + def message = "bump jenkins plugin version" + shwrap("git -C add jenkins/controller/plugins.txt") + shwrap("git -C commit -m '${message}' -m 'Job URL: ${env.BUILD_URL}' -m 'Job definition: https://github.com/coreos/fedora-coreos-pipeline/blob/main/jobs/bump-jenkins.Jenkinsfile'") + withCredentials([usernamePassword(credentialsId: botCreds, + usernameVariable: 'GHUSER', + passwordVariable: 'GHTOKEN')]) { + // gracefully handle race conditions + sh(""" + rev=\$(git -C src/config rev-parse origin/${branch}) + if ! git -C src/config push https://\${GHUSER}:\${GHTOKEN}@github.com/${repo} ${branch}; then + git -C src/config fetch origin + if [ "\$rev" != \$(git -C src/config rev-parse origin/${branch}) ]; then + touch ${env.WORKSPACE}/rerun + else + exit 1 + fi + fi + """) + } + + } + } + + } catch (e) { + currentBuild.result = 'FAILURE' + throw e + } finally { + if (currentBuild.result != 'SUCCESS') { + pipeutils.trySlackSend(message: "bump-lockfile #${env.BUILD_NUMBER} <${env.BUILD_URL}|:jenkins:> <${env.RUN_DISPLAY_URL}|:ocean:> [${params.STREAM}]") + } + } +}}} +/* + + //def message="lockfiles: bump to latest" + //if (!haveChanges && forceTimestamp) { + // message="lockfiles: bump timestamp" + //} + + + /*node{ + shwrapCapture( """ + git config --global user.name "CoreOS Bot" + git config --global user.email "coreosbot@fedoraproject.org" + git add jenkins/controller/plugins.txt + git commit -m "Updated plugin versions" + git push origin main + """) + }*/