項目結構
該代碼托管在Github上 ,并提供一個Gradle構建,該構建可在本地下載并啟動Jenkins(或Hudson)服務器以執行測試。 服務器設置為使用Gradle構建目錄作為其工作目錄,因此只需執行gradle clean即可將其刪除。 我使用所需庫的Jenkins版本和Hudson版本進行了嘗試,除了兩個CLI實現之間的一些古怪之處外,它們的功能仍然相同。 如果要使用Hudson而不是Jenkins進行嘗試,請傳遞命令標志-Pswitch,并將使用適當的war和庫。 該項目旨在與Gradle 1.0-milestone-8一起運行,并帶有該版本的Gradle包裝器 。 自原始文章以來,大多數代碼都保持不變,但是對Jenkins和Hudson的較新版本進行了一些增強和更改。
該項目產生的庫以Maven工件的形式發布,稍后我將確切描述如何實現。 還包括一些示例,這些示例演示了在Gradle或Maven項目中以及在Grapes的Groovy腳本中如何使用該庫。 我們使用Groovy 1.8.6,Gradle 1.0-milestone-8和Maven 3.0.3構建所有內容。
充分利用CLI
作為api的替代方法,CLI jar是一種非常強大的與構建服務器進行交互的方式。 除了各種內置命令之外,Groovy腳本還可以遠程執行,而我們只需付出一點努力就可以輕松地序列化響應,以處理服務器上提取的數據。 作為執行環境,服務器提供Groovysh Shell并為hudson.model包存儲導入。 該包中的Jenkins / Hudson單例對象的實例也傳遞給Binding 。 在這些示例中,我使用的是向后兼容的Hudson版本,因為該代碼旨在在兩種服務器上均可運行。
可用命令
內置命令種類繁多,所有這些命令均在hudson.cli包中實現。 以下是正在運行的應用程序的CLI頁面上列出的內容:
- build:構建作業,并且可以選擇等待直到完成。
- cancel-quiet-down:取消“ quiet-down”命令的效果。
- clear-queue:清除構建隊列
- connect-node:重新連接到節點
- 復制作業:復制一份工作。
- create-job:通過讀取stdin作為配置XML文件來創建新作業。
- delete-builds:刪除構建記錄。
- delete-job:刪除工作
- delete-node:刪除節點
- disable-job:禁用工作
- 斷開節點:與節點斷開連接
- enable-job:啟用工作
- get-job:將作業定義XML轉儲到stdout
- groovy:執行指定的Groovy腳本。
- groovysh:運行交互式groovy shell。
- help:列出所有可用的命令。
- install-plugin:從文件,URL或從更新中心安裝插件。
- install-tool:執行自動工具安裝,并將其位置打印到stdout。 只能從
內部版本。 - keep-build:標記該構建以永久保留該構建。
- list-changes:轉儲指定構建的變更日志。
- login:保存當前憑證,以允許將來的命令在沒有顯式憑證信息的情況下運行。
- 注銷:刪除使用登錄命令存儲的憑證。
- 郵件:讀取stdin并將其作為電子郵件發送出去。
- offline-node:停止使用臨時執行構建的節點,直到下一個“ online-node”命令。
- online-node:在線使用節點執行構建,以取消先前的“ offline-node”命令。
- 安靜:安靜下詹金斯,為重新啟動做準備。 不要開始任何構建。
- 重新加載配置:丟棄內存中所有已加載的數據,然后從文件系統重新加載所有內容。 有用的時候
您直接在磁盤上修改了配置文件。 - 重新啟動:重新啟動詹金斯
- 安全重啟:安全重啟詹金斯
- 安全關閉:將Jenkins置于安靜模式,等待現有構建完成,然后關閉
詹金斯 - set-build-description:設置構建的描述。
- set-build-display-name:設置構建的displayName
- set-build-result:設置當前構建的結果。 僅當從內部調用時才有效。
- shutdown:立即關閉Jenkins服務器
- update-job:從stdin更新作業定義XML。 與get-job命令相反
- version:輸出當前版本。
- wait-node-offline:等待節點脫機
- wait-node-online:等待節點聯機
- 我是誰:報告您的憑據和權限
目前尚不清楚每個參數都需要什么參數,但是在不帶參數調用時,它們幾乎普遍遵循打印使用情況詳細信息的CLI模式。 例如,當您不帶任何參數調用build命令時,以下是您在錯誤流中返回的內容:
參數“ JOB”為必填項
java -jar jenkins-cli.jar建立args…
開始構建,然后選擇等待完成。 除了一般的腳本使用之外,該命令可以是 用于從一個作業的構建中調用另一個作業。 使用-s選項,此命令將根據以下命令更改退出代碼 構建的結果(退出代碼0表示成功。) 使用-c選項,只有在存在 SCM變更 職位:要建立的工作名稱 -c:在開始構建之前檢查SCM更改,如果沒有,請檢查 更改,不進行構建即退出 -p:以鍵=值格式指定構建參數。 -s:等待命令完成/中止
從系統中取出數據
與遠程系統的所有交互都由流處理,編寫腳本非常容易,這些腳本將使用內置的Groovy工具以易于解析的String格式返回數據。 從理論上講,您也應該能夠封送更復雜的對象,但是現在讓我們保持簡單。 這是一個Groovy腳本,該腳本僅將所有作業名稱提取到List中,并調用Groovy inspect方法引用所有值。
@GrabResolver(name = 'glassfish', root = 'http://maven.glassfish.org/content/groups/public/')
@GrabResolver(name = "github", root = "http://kellyrob99.github.com/Jenkins-api-tour/repository")
@Grab('org.kar:hudson-api:0.2-SNAPSHOT')
@GrabExclude('org.codehaus.groovy:groovy')
import org.kar.hudson.api.cli.HudsonCliApiString rootUrl = 'http://localhost:8080'
HudsonCliApi cliApi = new HudsonCliApi()
OutputStream out = new ByteArrayOutputStream()
cliApi.runCliCommand(rootUrl, ['groovysh', 'hudson.jobNames.inspect()'], System.in, out, System.err)
List allJobs = Eval.me(cliApi.parseResponse(out.toString()))
println allJobs
收到響應后,我們將做一些整理工作以刪除String開頭的一些多余字符,并使用Eval.me將String轉換為List。 Groovy提供了多種將文本轉換為代碼的方法,因此,如果您的使用情況比這種簡單情況復雜,則可以使用GroovyShell和Binding或其他替代方法將結果解析為有用的東西。 這種簡單的技術也擴展到了Maps和其他類型,從而使得處理從服務器發送回的數據變得簡單。
一些有用的例子
查找具有更新的插件并更新所有插件
這是一個使用Groovy腳本查找所有具有可用更新的插件,然后將結果返回給調用者,然后在所有插件上調用CLI'install-plugin'命令的示例。 方便地,此命令將安裝插件(如果尚未安裝)或將其更新到最新版本(如果已安裝)。
def findPluginsWithUpdates = '''
Hudson.instance.pluginManager.plugins.inject([]) { List toUpdate, plugin ->if(plugin.hasUpdate()){toUpdate << plugin.shortName}toUpdate
}.inspect()
'''
OutputStream updateablePlugins = new ByteArrayOutputStream()
cliApi.runCliCommand(rootUrl, ['groovysh', findPluginsWithUpdates], System.in, updateablePlugins, System.err)def listOfPlugins = Eval.me(parseOutput(updateablePlugins.toString()))
listOfPlugins.each{ plugin ->cliApi.runCliCommand(rootUrl, ['install-plugin', plugin])
}
一次安裝或升級一套插件
使用“管理插件” UI絕對可以勝任,并且是冪等的,因此多次運行它只會導致可能升級已安裝的插件。 這套插件可能有些過分,但是我最近調查了一些插件以供使用。
@GrabResolver(name='glassfish', root='http://maven.glassfish.org/content/groups/public/')
@GrabResolver(name="github", root="http://kellyrob99.github.com/Jenkins-api-tour/repository")
@Grab('org.kar:hudson-api:0.2-SNAPSHOT')
@GrabExclude('org.codehaus.groovy:groovy')
import static java.net.HttpURLConnection.*
import org.kar.hudson.api.*
import org.kar.hudson.api.cli.HudsonCliApiString rootUrl = 'http://localhost:8080'
HudsonCliApi cliApi = new HudsonCliApi()['groovy', 'gradle', 'chucknorris', 'greenballs', 'github', 'analysis-core', 'analysis-collector', 'cobertura','project-stats-plugin','audit-trail', 'view-job-filters', 'disk-usage', 'global-build-stats','radiatorviewplugin', 'violations', 'build-pipeline-plugin', 'monitoring', 'dashboard-view','iphoneview', 'jenkinswalldisplay'].each{ plugin ->cliApi.runCliCommand(rootUrl, ['install-plugin', plugin])
}// Restart a node, required for newly installed plugins to be made available.
cliApi.runCliCommand(rootUrl, 'safe-restart')
查找所有失敗的構建并觸發它們
網絡問題或基礎設施事件可能導致大量構建一次全部失敗,這并非罕見。 解決問題后,該腳本可用于驗證構建是否均正常工作。
@GrabResolver(name = 'glassfish', root = 'http://maven.glassfish.org/content/groups/public/')
@GrabResolver(name = "github", root = "http://kellyrob99.github.com/Jenkins-api-tour/repository")
@Grab('org.kar:hudson-api:0.2-SNAPSHOT')
@GrabExclude('org.codehaus.groovy:groovy')
import org.kar.hudson.api.cli.HudsonCliApiString rootUrl = 'http://localhost:8080'
HudsonCliApi cliApi = new HudsonCliApi()
OutputStream out = new ByteArrayOutputStream()
def script = '''hudson.items.findAll{ job ->job.isBuildable() && job.lastBuild && job.lastBuild.result == Result.FAILURE
}.collect{it.name}.inspect()
'''
cliApi.runCliCommand(rootUrl, ['groovysh', script], System.in, out, System.err)
List failedJobs = Eval.me(cliApi.parseResponse(out.toString()))
failedJobs.each{ job ->cliApi.runCliCommand(rootUrl, ['build', job])
}
打開一個交互式Groovy Shell
如果您確實想在服務器上戳戳,則可以啟動一個交互式外殼程序以檢查狀態并執行命令。 綁定了System.in流,并立即回顯了來自服務器的響應。
@GrabResolver(name = 'glassfish', root = 'http://maven.glassfish.org/content/groups/public/')
@GrabResolver(name = "github", root = "http://kellyrob99.github.com/Jenkins-api-tour/repository")
@Grab('org.kar:hudson-api:0.2-SNAPSHOT')
@GrabExclude('org.codehaus.groovy:groovy')
import org.kar.hudson.api.cli.HudsonCliApi
/*** Open an interactive Groovy shell that imports the hudson.model.* classes and exposes* a 'hudson' and/or 'jenkins' object in the Binding which is an instance of hudson.model.Hudson*/
HudsonCliApi cliApi = new HudsonCliApi()
String rootUrl = args ? args[0] :'http://localhost:8080'
cliApi.runCliCommand(rootUrl, 'groovysh')
項目更新
去年發生了很多事情,所有項目依賴項都需要更新。 特別是,對Groovy,Gradle和Spock進行了一些非常不錯的改進。 最值得注意的是,自0.9.2版以來,Gradle已經走了很長一段路。 Groovy 1.8中添加的JSON支持也很方便。 Spock在使用@Unroll時需要進行一些小的調整才能在測試報告中呈現動態內容,但這對于“老”方法和“ 鏈式存根 ”之類的功能來說是一筆不小的代價。 本質上,為了響應Groovy 1.8+中的更改,Spock @Unroll注釋需要從以下更改:
@Unroll('querying of #rootUrl should match #xmlResponse')
閉包封裝的GString表達式:
@Unroll({'querying of $rootUrl should match $xmlResponse'})
聽起來語法還在不斷變化,很高興我在網上找到了關于這個問題的討論 。
在Github上托管Maven存儲庫
也許您從前面的腳本示例中注意到了,我們正在引用一個已發布的庫來獲取HudsonCliApi類。 上周 ,我讀了一篇有趣的文章 ,描述了如何使用內置的Github Pages發布Maven存儲庫。 盡管它的功能不如Nexus或Artifactory這樣的存儲庫,但足以以標準方式將一些二進制文件提供給大多數常見的構建工具。 只需在標準Maven回購布局中發布二進制文件以及相關的Pom,即可開始比賽! 每個依賴關系管理系統都有其怪癖(我在看著您Ivy!),但是它們很容易解決,因此這里是Gradle,Maven和Groovy Grapes使用此項目代碼生成的庫的示例。 請注意,Jenkins / Hudson所需的某些依賴項在Maven中央存儲庫中不可用,因此我們從Glassfish存儲庫中獲取它們。
搖籃
很簡單,這適用于最新版本的Gradle,并假定您使用的是Groovy插件。
repositories {mavenCentral()maven {url 'http://maven.glassfish.org/content/groups/public/'}maven {url 'http://kellyrob99.github.com/Jenkins-api-tour/repository'}
}
dependencies {groovy 'org.codehaus.groovy:groovy-all:${versions.groovy}'compile 'org.kar:hudson-api:0.2-SNAPSHOT'
}
馬文
xml中的內容基本上相同,在這種情況下,假設您使用的是GMaven插件
<repositories><repository><id>glassfish</id><name>glassfish</name><url>http://maven.glassfish.org/content/groups/public/</url></repository><repository><id>github</id><name>Jenkins-api-tour maven repo on github</name><url>http://kellyrob99.github.com/Jenkins-api-tour/repository</url></repository>
</repositories><dependencies><dependency><groupId>org.codehaus.groovy</groupId><artifactId>groovy-all</artifactId><version>${groovy.version}</version></dependency><dependency><groupId>org.kar</groupId><artifactId>hudson-api</artifactId><version>0.2-SNAPSHOT</version></dependency>
</dependencies>
葡萄
在這種情況下,解決舊版本Groovy的某些傳遞依賴關系似乎存在問題,這就是為什么對此有顯式排除的原因。
@GrabResolver(name='glassfish', root='http://maven.glassfish.org/content/groups/public/')
@GrabResolver(name='github', root='http://kellyrob99.github.com/Jenkins-api-tour/repository')
@Grab('org.kar:hudson-api:0.2-SNAPSHOT')
@GrabExclude('org.codehaus.groovy:groovy')
鏈接
- Github Jenkins-api-tour項目頁面
- Github上的Maven存儲庫
- 腳本程序示例Groovy腳本
- Jenkins CLI文檔
相關文章:
- 接觸Jenkins(Hudson)API
- 使用Groovy腳本可以做的五件事
- Grails應用程序演示StackExchange API
參考:在Japkin上的“ ...”博客上 ,我們的JCG合作伙伴 Kelly Robinson 著手研究 Jenkins(Hudson)API,第2部分 。
翻譯自: https://www.javacodegeeks.com/2012/08/hooking-into-jenkins-hudson-api-part-2.html