2013-09-23 36 views
3

我有以下Groovy腳本,它刪除給定Jenkins作業的所有版本,除了用戶提供的一個版本號想保留)。不要刪除Jenkins版本,如果它被標記爲「永久保留此版本」 - 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。現在


,我想要的是:

  1. 我應該在這個腳本改爲不刪除構建 - 如果構建標記在詹金斯爲「永遠保持這個建」 。我嘗試了這個腳本,並刪除了這個腳本,這個腳本永遠也會保留。假設我在Jenkins中使用「Build name setter plugin」,它可以給我構建我想要的名字,也就是說,不需要像構建#1或#2或#15一樣構建構建名稱,我將構建#2.75.0.1,2.75.0.2,2.75.0.3,.....,2.75.0.15(因爲我將build name/description設置爲使用某個包含2.75.0(作爲一個發佈版本值),並與實際詹金斯作業的版本號,即最後第4位後綴它 - 例如:設置名稱爲:

    ${ENV,var="somepropertyvariable"}.${BUILD_NUMBER} 
    

    在這種情況下,我就開始變得詹金斯構建爲2.75。 0.1到2.75.0.x(其中x是該版本的最後版本號(2.75.0))。同樣,當我將屬性rel緩解版本到下一個即2.75.1或2.76.0,然後相同的詹金斯工作將開始給我建立爲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的所有構建版本),那麼我應該在這個腳本中做什麼更改以包含第三個參數/參數。第三個參數將採用版本/版本值,即2.75.0或2.75.1或2.76.0,然後該腳本應只刪除該版本上的內部版本號(並且不應刪除其他版本的內部版本)。

回答

0

OK - 解決我的問題2是在這裏:我仍然在努力解決的問題1.

http://scriptlerweb.appspot.com/script/show/102001

bulkDeleteJenkinsBuildsExceptOne_OfAGivenRelease。常規

/*** 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 "" 

enter image description here

你也可以通過調用一個詹金斯工作這個腳本(需要3個參數作爲scriptler腳本提到)-OR從瀏覽器中調用它,以及:使用以下鏈接:

的http:// YourJenkinsServerName:PORT /工作/ Some_Jenkins_Job_That_You_Will_Create/buildWithParameters作業名稱= Test_AppSvc & releaseVersion = 2.75.0 & buildNumber = 15

+1

這個腳本將使用Jenkins「Scriptler」插件運行正常。請參閱附件圖像輸出。如果你想從Jenkins作業運行這個腳本,那麼在Build部分下,調用Scriptler腳本,提供位置/文件名,複選框jenkins作業將使用此腳本程序腳本的參數(如上所示),就是這樣。這jenkins作業需要3個參數字符串格式 - jobName,releaseVersion和buildNumber。 –

1

如果你想測試構建是否已被標記永久性的,使用

if (!build.isKeepLog()) { 
    // Build can be deleted 
} else { 
    // Build is marked permanent 
} 

我想你應該能夠使用getName() method每個構建以檢查是否應該刪除一個特定的build 。 API JavaDoc可能相當模糊,所以我經常繼續使用GitHub並查看代碼,以查看正在執行類似於我需要的操作的Jenkins插件。 public Scriptler repository也可能有用。

+0

從我在哪裏得到這個 「構建」(在build.isKeepLo​​g),感謝 –

+0

構建= jij.getLastBuild();如果(!build.isKeepLo​​g())在兩種情況下都返回false - 如果構建被標記爲永久保存 - 或者不是。 –

+0

這聽起來不對,我有腳本使用isKeepLo​​g()來控制構建是否永久,並且它們工作正常。你能把你的整個腳本發佈到什麼地方,我會看看嗎? –

1

最終答案:這包括使用Artifactor的REST API調用從Artifactory中刪除構建工件。這個腳本將刪除給定版本/版本的Jenkins/Artifactory構建/工件(有時候會這樣 - 一個給定的Jenkins作業可以爲例如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 ""