我有以下Groovy脚本,它删除给定Jenkins作业的所有构建,除了用户提供的一个构建号(即想要保留)。
/*** BEGIN META {
"name" : "Bulk Delete Builds except the given build number",
"comment" : "For a given job and a given build number, delete all build except the user provided one.",
"parameters" : [ 'jobName', 'buildNumber' ],
"core": "1.409",
"authors" : [
{ name : "Arun Sangal" }
]
} END META **/
// NOTE: Uncomment parameters below if not using Scriptler >= 2.0, or if you're just pasting the script in manually.
// ----- Logic in this script takes 5000 as the infinite number, decrease / increase this value from your own experience.
// The name of the job.
//def jobName = "some-job"
// The range of build numbers to delete.
//def buildNumber = "5"
def lastBuildNumber = buildNumber.toInteger() - 1;
def nextBuildNumber = buildNumber.toInteger() + 1;
import jenkins.model.*;
import hudson.model.Fingerprint.RangeSet;
def jij = jenkins.model.Jenkins.instance.getItem(jobName);
println("Keeping Job_Name: ${jobName} and build Number: ${buildNumber}");
println ""
def setBuildRange = "1-${lastBuildNumber}"
def range = RangeSet.fromString(setBuildRange, true);
jij.getBuilds(range).each { it.delete() }
println("Builds have been deleted - Range: " + setBuildRange)
setBuildRange = "${nextBuildNumber}-5000"
range = RangeSet.fromString(setBuildRange, true);
jij.getBuilds(range).each { it.delete() }
println("Builds have been deleted - Range: " + setBuildRange)
这适用于任何Jenkins工作。例如:如果您的Jenkins作业名称是“TestJob”并且您有15个构建,即构建#1以在Jenkins中构建15,并且您想要删除所有但保留构建#13,则此脚本将删除构建(构建#1) -12和14-15 - 即使你将任何构建标记为“永远保持这个构建”)并且只保留构建#13。
现在,我想要的是:
我应该在此脚本中更改为不删除构建 - 如果构建在Jenkins中标记为“永远保留此构建”。我尝试了脚本并将其删除,以便永远保持构建。
让我们说,如果我在Jenkins中使用“Build name setter plugin”,它可以给我构建名称作为我想要的名称,而不是仅仅构建为构建#1或#2,或者# 15,我将构建为构建#2.75.0.1,2.75.0.2,2.75.0.3,.....,2.75.0.15(因为我将构建名称/描述设置为使用包含2.75.0的变量(作为发布版本值)并以实际Jenkins作业的内部编号为后缀,即最后的第4位 - 例如:将名称设置为:
${ENV,var="somepropertyvariable"}.${BUILD_NUMBER}
在这种情况下,我将开始将Jenkins构建为2.75.0.1到2.75.0.x(其中x是该版本的最后构建#(2.75.0))。类似地,当我将属性发布版本更改为下一个版本2.75.1或2.76.0时,相同的Jenkins作业将开始给我构建为2.75.1.0,2.75.1.1,....,2.75.1。 x或2.76.0.1,2.76.0.2,....,2.76.0.x等。在发布版本更改期间,假设我们的构建将从1开始(正如我上面提到的2.75.1和2.76.0发行版本)。
在这种情况下,如果我的Jenkins作业的构建历史记录(显示2.75.0.x,2.75.1.x和2.76.0.x的所有构建版本),那么我应该在此脚本中进行哪些更改以包含第3个参数/参数。第3个参数将采用发布/版本值,即2.75.0或2.75.1或2.76.0,然后此脚本应仅删除该版本上的内部版本号(并且不应删除其他版本的版本)。
答案 0 :(得分:1)
如果要测试构建是否已标记为永久构建,请使用
if (!build.isKeepLog()) {
// Build can be deleted
} else {
// Build is marked permanent
}
我认为您应该能够在每个构建中使用getName() method来检查是否应该删除给定的构建。 API JavaDoc可能相当模糊,因此我经常继续GitHub并查看Jenkins插件的代码,该插件执行类似于我需要的操作。 public Scriptler repository也很有用。
答案 1 :(得分:1)
最终答案:这包括使用Artifactor的REST API调用从Artifactory中删除构建工件。此脚本将删除给定版本/版本的Jenkins / Artifactory构建/工件(有时候会有一段时间 - 给定的Jenkins作业可以为ex:2.75.0.1,2.75.0.2,2.75.0.3创建多个版本/版本构建。 ......,2.75.0.54,2.76.0.1,2.76.0.2,......,2.76.0.16,2.76.1.1,2.76.1.2,......,2.76.1.5)。在这种情况下,对于该作业的每个新版本,我们从1新开始构建#。如果必须删除除一个/甚至所有版本之外的所有版本(根据自己的需要更改脚本)并且不要更改旧版本/其他版本,请使用以下脚本。
Scriptler目录链接:http://scriptlerweb.appspot.com/script/show/103001
享受!
/*** BEGIN META {
"name" : "Bulk Delete Builds except the given build number",
"comment" : "For a given job and a given build numnber, delete all builds of a given release version (M.m.interim) only and except the user provided one. Sometimes a Jenkins job use Build Name setter plugin and same job generates 2.75.0.1 and 2.76.0.43",
"parameters" : [ 'jobName', 'releaseVersion', 'buildNumber' ],
"core": "1.409",
"authors" : [
{ name : "Arun Sangal - Maddys Version" }
]
} END META **/
import groovy.json.*
import jenkins.model.*;
import hudson.model.Fingerprint.RangeSet;
import hudson.model.Job;
import hudson.model.Fingerprint;
//these should be passed in as arguments to the script
if(!artifactoryURL) throw new Exception("artifactoryURL not provided")
if(!artifactoryUser) throw new Exception("artifactoryUser not provided")
if(!artifactoryPassword) throw new Exception("artifactoryPassword not provided")
def authString = "${artifactoryUser}:${artifactoryPassword}".getBytes().encodeBase64().toString()
def artifactorySettings = [artifactoryURL: artifactoryURL, authString: authString]
if(!jobName) throw new Exception("jobName not provided")
if(!buildNumber) throw new Exception("buildNumber not provided")
def lastBuildNumber = buildNumber.toInteger() - 1;
def nextBuildNumber = buildNumber.toInteger() + 1;
def jij = jenkins.model.Jenkins.instance.getItem(jobName);
def promotedBuildRange = new Fingerprint.RangeSet()
promotedBuildRange.add(buildNumber.toInteger())
def promoteBuildsList = jij.getBuilds(promotedBuildRange)
assert promoteBuildsList.size() == 1
def promotedBuild = promoteBuildsList[0]
// The release / version of a Jenkins job - i.e. in case you use "Build name" setter plugin in Jenkins for getting builds like 2.75.0.1, 2.75.0.2, .. , 2.75.0.15 etc.
// and over the time, change the release/version value (2.75.0) to a newer value i.e. 2.75.1 or 2.76.0 and start builds of this new release/version from #1 onwards.
def releaseVersion = promotedBuild.getDisplayName().split("\\.")[0..2].join(".")
println ""
println("- Jenkins Job_Name: ${jobName} -- Version: ${releaseVersion} -- Keep Build Number: ${buildNumber}");
println ""
/** delete the indicated build and its artifacts from artifactory */
def deleteBuildFromArtifactory(String jobName, int deleteBuildNumber, Map<String, String> artifactorySettings){
println " ## Deleting >>>>>>>>>: - ${jobName}:${deleteBuildNumber} from artifactory"
def artifactSearchUri = "api/build/${jobName}?buildNumbers=${deleteBuildNumber}&artifacts=1"
def conn = "${artifactorySettings['artifactoryURL']}/${artifactSearchUri}".toURL().openConnection()
conn.setRequestProperty("Authorization", "Basic " + artifactorySettings['authString']);
conn.setRequestMethod("DELETE")
if( conn.responseCode != 200 ) {
println "Failed to delete the build artifacts from artifactory for ${jobName}/${deleteBuildNumber}: ${conn.responseCode} - ${conn.responseMessage}"
}
}
/** delete all builds in the indicated range that match the releaseVersion */
def deleteBuildsInRange(String buildRange, String releaseVersion, Job theJob, Map<String, String> artifactorySettings){
def range = RangeSet.fromString(buildRange, true);
theJob.getBuilds(range).each {
if ( it.getDisplayName().find(/${releaseVersion}.*/)) {
println " ## Deleting >>>>>>>>>: " + it.getDisplayName();
deleteBuildFromArtifactory(theJob.name, it.number, artifactorySettings)
it.delete();
}
}
}
//delete all the matching builds before the promoted build number
deleteBuildsInRange("1-${lastBuildNumber}", releaseVersion, jij, artifactorySettings)
//delete all the matching builds after the promoted build number
deleteBuildsInRange("${nextBuildNumber}-${jij.nextBuildNumber}", releaseVersion, jij, artifactorySettings)
println ""
println("- Builds have been successfully deleted for the above mentioned release: ${releaseVersion}")
println ""
答案 2 :(得分:0)
好的 - 问题2的解决方案就在这里:我还在努力解决问题1。
http://scriptlerweb.appspot.com/script/show/102001
<强> bulkDeleteJenkinsBuildsExceptOne_OfAGivenRelease.groovy 强>
/*** BEGIN META {
"name" : "Bulk Delete Builds except the given build number",
"comment" : "For a given job and a given build numnber, delete all builds of a given release version (M.m.interim) only and except the user provided one. Sometimes a Jenkins job use Build Name setter plugin and same job generates 2.75.0.1 and 2.76.0.43",
"parameters" : [ 'jobName', 'releaseVersion', 'buildNumber' ],
"core": "1.409",
"authors" : [
{ name : "Arun Sangal" }
]
} END META **/
// NOTE: Uncomment parameters below if not using Scriptler >= 2.0, or if you're just pasting the script in manually.
// ----- Logic in this script takes 5000 as the infinite number, decrease / increase this value from your own experience.
// The name of the job.
//def jobName = "some-job"
// The release / version of a Jenkins job - i.e. in case you use "Build name" setter plugin in Jenkins for getting builds like 2.75.0.1, 2.75.0.2, .. , 2.75.0.15 etc.
// and over the time, change the release/version value (2.75.0) to a newer value i.e. 2.75.1 or 2.76.0 and start builds of this new release/version from #1 onwards.
//def releaseVersion = "2.75.0"
// The range of build numbers to delete.
//def buildNumber = "5"
def lastBuildNumber = buildNumber.toInteger() - 1;
def nextBuildNumber = buildNumber.toInteger() + 1;
import jenkins.model.*;
import hudson.model.Fingerprint.RangeSet;
def jij = jenkins.model.Jenkins.instance.getItem(jobName);
//def build = jij.getLastBuild();
println ""
println("- Jenkins Job_Name: ${jobName} -- Version: ${releaseVersion} -- Keep Build Number: ${buildNumber}");
println ""
println " -- Range before given build number: ${buildNumber}"
println ""
def setBuildRange = "1-${lastBuildNumber}"
def range = RangeSet.fromString(setBuildRange, true);
jij.getBuilds(range).each {
if ( it.getDisplayName().find(/${releaseVersion}.*/)) {
println " ## Deleting >>>>>>>>>: " + it.getDisplayName();
// Trying to find - how to NOT delete a build in Jenkins if it's marked as "keep this build forever". If someone has an idea, please update this script with a newer version in GitHub.
//if ( !build.isKeepLog()) {
it.delete();
//} else {
// println "build -- can't be deleted as :" + build.getWhyKeepLog();
//}
}
}
println ""
println " -- Range after given build number: ${buildNumber}"
println ""
setBuildRange = "${nextBuildNumber}-5000"
range = RangeSet.fromString(setBuildRange, true);
jij.getBuilds(range).each {
if ( it.getDisplayName().find(/${releaseVersion}.*/)) {
println " ## Deleting >>>>>>>>>: " + it.getDisplayName();
it.delete();
}
}
println ""
println("- Builds have been successfully deleted for the above mentioned release: ${releaseVersion}")
println ""
也可以通过Jenkins作业调用此脚本(需要脚本编写器脚本中提到的3个参数) - 或者也可以从浏览器调用它:使用以下链接:
http:// YourJenkinsServerName:PORT / job / Some_Jenkins_Job_That_You_Will_Create / buildWithParameters?jobName = Test_AppSvc&amp; releaseVersion = 2.75.0&amp; buildNumber = 15