持續(xù)集成
持續(xù)集成(Continuous integration,簡稱 CI)
開發(fā)中,我們經(jīng)常遇到一些奇怪問題,比如:
本地可以編譯成功的代碼但是同事們更新代碼后編譯出錯;
在項目有多個Target(目標(biāo))的時候,資源文件只添加到了當(dāng)前的Target,另外一個Target這個時候是不能正常編譯的;
寫的工具類,被同事改了,或者自己有改動,很多地方用到了,怎么保證這個類的行為沒有發(fā)生變化而影響到項目中的其它模塊呢?
諸如此類。
引起各種奇怪問題的原因有很多,比如:
開發(fā)環(huán)境比較復(fù)雜不干凈;
IDE的bug;
提交前有一些必要的檢查需要做,但是開發(fā)時因為各種原因沒做。
那么這些問題可否避免呢?當(dāng)然是可以避免的,如果代碼有新的改動,提交到版本庫中的時候,有一個人幫我們檢查必要事項,然后做做測試。這個當(dāng)然是可以的,前提是老板同意專門招一個這樣的人。
這些機械重復(fù)的事情我們可以找一個工具來幫我們完成,這個工具跑在一個專門的服務(wù)器上,該服務(wù)器環(huán)境相對干凈、可以運行一些自動化操作(自動編譯,代碼檢查,測試等環(huán)節(jié))。那么這種工具,就是接下來講的“持續(xù)集成”。
簡單理解持續(xù)集成
為解決程序代碼提交質(zhì)量低,提交內(nèi)容導(dǎo)致原有系統(tǒng)的bug,按時或按需自動編譯版本,自動進(jìn)行自動化測試。
詳細(xì)理解持續(xù)集成
早集成、頻繁的集成能夠幫助項目開發(fā)者在早期發(fā)現(xiàn)項目風(fēng)險和質(zhì)量問題,越到后期發(fā)現(xiàn)的問題,解決的成本越高,從而有可能導(dǎo)致項目延期或者項目失敗。
持續(xù)集成是一種軟件開發(fā)實踐,即團(tuán)隊開發(fā)成員經(jīng)常集成他們的工作,通過每個成員每天至少集成一次,也就是一個團(tuán)隊每天將集成多次,每次的集成都通過自動化的構(gòu)建(包括編譯,發(fā)布,自動化測試)來驗證。簡單來說,就是持續(xù)的定時的在多個團(tuán)隊成員的工作中進(jìn)行集成,并且給予反饋。
持續(xù)集成的核心價值
持續(xù)集成中重復(fù)的編譯發(fā)布等環(huán)節(jié)都是自動完成的,無需太多的人工干預(yù),有利于減少重復(fù)過程以節(jié)省時間、費用和工作量;
持續(xù)集成保障了每個時間點上團(tuán)隊成員提交的代碼是能成功集成的。換言之,任何時間點都能第一時間發(fā)現(xiàn)軟件的集成問題,使任意時間發(fā)布可部署的軟件成為了可能;
持續(xù)集成還能利于軟件本身的發(fā)展趨勢,這點在需求不明確或是頻繁性變更的情景中尤其重要,持續(xù)集成的質(zhì)量能幫助團(tuán)隊進(jìn)行有效決策,同時建立團(tuán)隊對開發(fā)產(chǎn)品的信心。
業(yè)界普遍認(rèn)同的持續(xù)集成的原則
需要版本控制軟件保障團(tuán)隊成員提交的代碼不會導(dǎo)致集成失敗。常用的版本控制軟件有IBM Rational ClearCase、CVS、Subversion 等;
開發(fā)人員必須及時向版本控制庫中提交代碼,也必須經(jīng)常性地從版本控制庫中更新代碼到本地;
需要有專門的集成服務(wù)器來執(zhí)行集成構(gòu)建。根據(jù)項目的具體實際,集成構(gòu)建可以被軟件的修改來直接觸發(fā),也可以定時啟動,如每半個小時構(gòu)建一次;
必須保證構(gòu)建的成功。如果構(gòu)建失敗,修復(fù)構(gòu)建過程中的錯誤是優(yōu)先級最高的工作。一旦修復(fù),需要手動啟動一次構(gòu)建;
不更新構(gòu)建失敗的代碼。
持續(xù)集成系統(tǒng)的組成
一個自動構(gòu)建過程,包括自動編譯、分發(fā)、部署和測試等。可幫助我們節(jié)省大量時間,完成這個過程的自動化后,在以后的開發(fā)過程中,我們需要做的,就是只是提交代碼到版本庫中,構(gòu)建自動完成,基本不再需要人工干預(yù)。
一個代碼存儲庫,即需要版本控制軟件來保障代碼的可維護(hù)性,同時作為構(gòu)建過程的素材庫。
一個持續(xù)集成服務(wù)器。最好有一臺服務(wù)器單獨作為持續(xù)集成服務(wù)器,一方面保證了環(huán)境的純凈,一方面不影響開發(fā),而且持續(xù)集成服務(wù)器一般是隨時準(zhǔn)備開始構(gòu)建的,所以一般也不關(guān)機。本文中介紹的 Jenkins 就是一個配置簡單和使用方便的持續(xù)集成服務(wù)器。
集成操作步驟
首先要有統(tǒng)一的代碼庫,服務(wù)器不斷從版本控制服務(wù)器上檢查代碼狀態(tài),看代碼是否有更新。如果發(fā)現(xiàn)有代碼更新,那么就從版本控制服務(wù)器下載最新的代碼。等代碼完全更新以后,調(diào)用自動化編譯腳本,進(jìn)行代碼編譯。然后運行所有的自動化測試,并且進(jìn)行代碼分析。如果其中任何一個步驟失敗,就表示build失敗,持續(xù)集成服務(wù)器會給予響應(yīng)的反饋。每次代碼提交之后,都會在持續(xù)集成服務(wù)器上觸發(fā)一個定時構(gòu)建,然后進(jìn)行編譯、部署。
持續(xù)集成利器--Jenkins
提到 Jenkins 就不得不提另一個持續(xù)集成工具——Hudson , Hudson 由 Sun 公司開發(fā),2010 年 Sun 公司被 Oracle 公司收購, oracle 公司聲稱對 hudson 擁有商標(biāo)所有權(quán)。 Jenkins是從 Hudson 中分離出來的一個可擴(kuò)展的持續(xù)集成引擎,并將繼續(xù)走 Open Source 的道路。二者現(xiàn)在由不同的團(tuán)隊在維護(hù)。
Jenkins 在持續(xù)集成領(lǐng)域市場份額中居于主導(dǎo)地位,被各種大小規(guī)模的團(tuán)隊用于用各種語言實現(xiàn)的各類項目中,語言包括.NET、Java、Ruby、Groovy、Grails、PHP 等。
Jenkins是一個獨立的基于Java開發(fā)的一種開源持續(xù)集成工具,用于監(jiān)控持續(xù)重復(fù)的工作,旨在提供一個開放易用的軟件平臺,使軟件的持續(xù)集成變成可能,使開發(fā)者從繁雜的集成中解脫出來,專注于更為重要的業(yè)務(wù)邏輯實現(xiàn)上。可用于自動化各種任務(wù),如構(gòu)建、測試和部署軟件。
Jenkins可以建立一個軟件項目或工作運行的計劃任務(wù)。
Jenkins特點
開源免費。
跨平臺,支持所有的平臺。
安裝配置超級簡單。可以通過本機系統(tǒng)包Docker安裝,甚至可以通過安裝Java Runtime Environment的任何機器獨立運行。
易于使用。web形式的可視化的用戶管理頁面,簡單、直觀、友好,發(fā)布工作人員只需要通過簡單的 UI 操作就可以替代原來繁瑣的發(fā)布工作。
master/slave支持分布式的build。
tips及時快速的幫助。
擁有良好的擴(kuò)展性。已有的200多個開源插件可供使用,而且?guī)缀趺恐軙行碌拈_源插件貢獻(xiàn)進(jìn)來,這些插件的安裝都十分快捷和簡單。
發(fā)展良好。Jenkins 開源社區(qū)的規(guī)模變得越來越大、活躍度也變得越來越高,發(fā)展速度非常快。
Jenkins 的兩個功能
不斷地進(jìn)行項目的構(gòu)建/測試軟件。
監(jiān)控外部運行的作業(yè): 如計劃任務(wù)作業(yè)和 Qrocmail 的工作,即使是那些在遠(yuǎn)程機器上運行的計劃任務(wù)。 Jenkins 生成這些日志并且很容易讓你注意到錯誤的出現(xiàn)。實施監(jiān)控集成中存在的錯誤,提供詳細(xì)的日志文件和提醒功能,還能用圖表的形式形象地展示項目構(gòu)建的趨勢和穩(wěn)定性。
Jenkins的工作步驟
典型的工作流包括以下幾個步驟:
開發(fā)
提交
編譯
測試
發(fā)布
有了Jenkins的幫助,除了第1步,后續(xù)的4步都是自動化完成的。具體的,當(dāng)你完成了提交,Jenkins會自動運行你的編譯腳本,編譯成功后,再運行你的測試腳本,這一步成功后,接著它會幫你把新程序發(fā)布出去,特別的,在最后一步,你可以選擇手動發(fā)布,或自動發(fā)布,畢竟發(fā)布這件事情,還是需要人為的確認(rèn)一下比較好。
Jenkins安裝
安裝過程包含如下幾個方面:(具體安裝方法可以自行百度一下,教程比較豐滿)
1. JDK
2. Jenkins War包
3. Ant
4. Maven
查閱官方文檔:https://jenkins.io/?
Jenkins的啟動和配置
啟動命令如下:sudo service jenkins start
配置文件是/etc/sysconfig/jenkins,修改如下兩項配置(根據(jù)實際需要設(shè)置)
#修改為18080,默認(rèn)是8080
JENKINS_PORT="18080"
#內(nèi)存設(shè)置,我這里設(shè)置成如下配置
JENKINS_JAVA_OPTIONS="-Djava.awt.headless=true -Xms512m -Xmx1024m -XX:MaxNewSize=512m -XX:MaxPermSize=1024m"
初始化和修改工作空間
在瀏覽器中輸入http://localhost:8090(默認(rèn)是使用8080端口)
1. 從主頁面直接到“系統(tǒng)管理>系統(tǒng)配置”,點擊右邊“高級”按鈕,在工作空間目錄”直接修改默認(rèn)工作空間目錄為自定義的/home/jenkins/workspace/${ITEM_FULLNAME}
2.?從主頁面直接到“系統(tǒng)管理>Global Tool Configuration”,點擊右邊“Ant安裝”按鈕,在name中填入名字,可以自己取,這里我填寫成ant(到時Invoke Ant時,需要選擇ant),ANT_HOME填入Ant的環(huán)境變量
3. 全局配置JDK從主頁面直接到“系統(tǒng)管理>Global Tool Configuration”,點擊右邊“JDK安裝”按鈕,在name中填入名字,可以自己取,這里我填寫成ant(到時Invoke Ant時,需要選擇ant),ANT_HOME填入Ant的環(huán)境變量
4.?添加信任證書,因為我的工程的源碼是放在SVN上,所以在這里我們就是要添加SVN的驗證,即SVN的用戶名和密碼。從主頁面左邊菜單點擊到“Credentials”,進(jìn)入到?Credentials列表點擊Name列中即可對Credentials中用戶進(jìn)行修改、新增、刪除操作
建立 Jenkins 自動化持續(xù)集成項目
?新建自由風(fēng)格項目
點擊左側(cè)邊欄的“新建”按鈕,新建一個任務(wù)。
填寫項目的名稱,并選擇一種構(gòu)建的方式,此時我們選擇第一個,構(gòu)建一個自由風(fēng)格的軟件項目,然后點擊“OK”按鈕創(chuàng)建任務(wù),并進(jìn)行詳細(xì)的配置
General
進(jìn)入到主界面
第一步,點擊高級按鈕
第二步,勾選“自定義工作空間”,輸入工作空間路徑
若是只有一個項目,也可以直接到“系統(tǒng)管理>系統(tǒng)配置>工作空間目錄”直接修改默認(rèn)工作空間目錄
源碼管理
因為,我們的代碼是部署在SVN服務(wù)器上的,所以這里有下面三個步驟來配置jenkins監(jiān)控SVN服務(wù)器代碼變化。
第一步,選擇Subversion;
第二步,在Repository URL輸入項目SVN地址;
第三步,在Credentials選擇SVN用戶名和賬號,初次會需要點擊Add添加
構(gòu)建觸發(fā)器
指定的項目完成構(gòu)建后,觸發(fā)此項目的構(gòu)建。
Poll SCM:當(dāng)選擇此選項,您可以指定一個定時作業(yè)表達(dá)式來定義Jenkins每隔多久檢查一下源代碼 倉庫的變化。如果發(fā)現(xiàn)變化,就執(zhí)行一次構(gòu)建。例如,表達(dá)式中填寫H 2 * * *將使Jenkins每隔2分 ? ? ? ? ? ? ? ? ?鐘就檢查一次源碼倉庫的變化。
Build periodically:此選項僅僅通知Jenkins按指定的頻率對項目進(jìn)行構(gòu)建,而不管SCM是否有變化。如果想在這個Job中運行一些測試用例的話,它就很有幫助。
構(gòu)建環(huán)境
略
構(gòu)建
這部分主要是配置構(gòu)建的相關(guān)內(nèi)容,用于定時觸發(fā)構(gòu)建或者手動執(zhí)行構(gòu)建的時候,對代碼檢驗、編譯時進(jìn)行的操作。構(gòu)建概念到處可查到,形象來說,構(gòu)建就是要把代碼從某個地方拷貝過來,編譯,再拷貝到某個地方去等等操作,當(dāng)然不僅與此,但是主要用來干這個。因為我的項目是用ant腳本實現(xiàn)的編譯和打包,所以我選擇的是Invoke Ant,注意不要選擇default喔,那個選擇了沒有用。
增加構(gòu)建步驟:Invoke Ant
Targets:(什么也沒寫,默認(rèn)執(zhí)行根目錄下的build.xml)
如果你的構(gòu)建腳本build.xml不在workspace根目錄、或者說你的構(gòu)建腳本不叫build.xml。那么需要在高級里設(shè)置Build?File選項的路;
build.xml配置文件請查看附件“build.xml說明”,里面有每句配置說明;checkstyleBuild.xml配置文件請查看附件“checkstyleBuild.xml說明”,里面有每句配置說明;findBugsBuild.xml配置文件請查看附件“findBugsBuild.xml說明”,里面有每句配置說明。
構(gòu)建后操作
用于定義當(dāng)前項目構(gòu)建完之后的一些操作,比如構(gòu)建完之后將checkstyle結(jié)果輸出到指定日志文件,重新發(fā)布項目,去執(zhí)行其他項目構(gòu)建等。
注意,首先你必須安裝好Deploy?Plugin插件,然后在tomcat的conf目錄配置tomcat-users.xml文件;
配置完之后一次war包路徑、用戶名、密碼、主機即可配置完之后一次war包路徑、用戶名、密碼、主機即可;
lWAR/EAR files:war文件的存放位置,如:**/build/warDest/ad-gx-admin.war。
lContext path:訪問時需要輸入的內(nèi)容,如ad-gx-admin訪問時如下:?????http://172.16.4.166:10001/?ofCard/ad-gx-admin如果為空,默認(rèn)是war包的名字。
lContainer:選擇你的web容器,如tomca 7.x
lManager user name:填入tomcat-users.xml配置的username內(nèi)容
lManager password:填入tomcat-users.xml配置的password內(nèi)容
lTomcat URL:填入http://192.168.x.x:8080/
lDeploy on failure:構(gòu)建失敗依然部署,一般不選擇
注意:雖然這種部署方法可能會導(dǎo)致tomcat加載時出現(xiàn)卡死的現(xiàn)象。但是也是最簡單的部署方式。如果卡死了重啟下就好了,將tomcat的java內(nèi)存參數(shù)調(diào)高可以解決這個問題。最后不要忘記點擊保存喔。好了!到此一個項目的獲取源碼,打包,遠(yuǎn)程部署構(gòu)建;
checkstyle-result.xml配置文件請查看附件“checkstyle-result.xml說明”,里面有配置說明。所有這些配置多做完之后,在最下方點擊“保存”按鈕,現(xiàn)在回到首頁去進(jìn)行構(gòu)建吧!!!?
監(jiān)控
1、左邊菜單欄
l新建:這里進(jìn)入新建項目。
l用戶:用戶管理模塊,對監(jiān)控系統(tǒng)用戶的增刪改查。
l任務(wù)歷史:以往構(gòu)建過的項目。
l系統(tǒng)管理:進(jìn)去是一些配置方面的東西,進(jìn)入之后幾個主要的子菜單分別是系統(tǒng)設(shè)置、Global Tool ???Configuration、管理插件幾個模塊
lMy Views:當(dāng)前監(jiān)控的項目列表。
lCredentials:添加監(jiān)控源碼的的證書,其實就是SVN用戶名和密碼驗證。
?2、監(jiān)控項目列表?這里主要是Jenkins當(dāng)前正在監(jiān)控的項目列表。點擊進(jìn)去可查看當(dāng)前項目詳細(xì)情況。?
模塊1:
l狀態(tài):最后一次構(gòu)建的狀態(tài);
l修改記錄:代碼修改記錄;
l工作空間:編譯后代碼存放的目錄;
l立即構(gòu)建:單擊此處,可立即進(jìn)行構(gòu)建;
l刪除Project:單擊此處,可刪除該項目;
l配置:配置該項目相關(guān)監(jiān)控信息(工作空間、chestyle規(guī)則等);
lCheckstyle Warnings:當(dāng)前這次構(gòu)建發(fā)現(xiàn)的靜態(tài)警告;
lFindBugs Warnings:當(dāng)前這次構(gòu)建發(fā)現(xiàn)的FindBugs。
模塊2:
這里顯示的最近一次構(gòu)建的相關(guān)信息,是否構(gòu)建成功、構(gòu)建用時等。
模塊3:
lCheckstyle Trend:歷史構(gòu)建完之后的解決的代碼中靜態(tài)警告走勢;
lFindBus Trend:歷史構(gòu)建完之后的解決的代碼中FindBugs走勢。
構(gòu)建狀態(tài)查詢
當(dāng)任務(wù)一旦運行,您將會看到這個任務(wù)正在隊列中的儀表板和當(dāng)前工作主頁上運行。
1、構(gòu)建狀態(tài):????????下圖中分級符號概述了一個Job新近一次構(gòu)建會產(chǎn)生的四種可能的狀態(tài):
Successful:完成構(gòu)建,且被認(rèn)為是穩(wěn)定的。
Unstable:完成構(gòu)建,但被認(rèn)為不穩(wěn)定。
Failed:構(gòu)建失敗。
Disabled:構(gòu)建已禁用。
2. 構(gòu)建穩(wěn)定性:????????當(dāng)一個Job中構(gòu)建已完成并生成了一個未發(fā)布的目標(biāo)構(gòu)件,如果您準(zhǔn)備評估此次構(gòu)建的穩(wěn)定性,Jenkins會基于一些后處理器任務(wù)為構(gòu)建發(fā)布一個穩(wěn)健指數(shù)(從0-100?),這些任務(wù)一般以插件的方式實現(xiàn)。它們可能包括單元測試(JUnit)、覆蓋率(Cobertura?)和靜態(tài)代碼分析(FindBugs)。分?jǐn)?shù)越高,表明構(gòu)建越穩(wěn)定。下圖中分級符號概述了穩(wěn)定性的評分范圍。任何構(gòu)建作業(yè)的狀態(tài)(總分100)低于80分就是不穩(wěn)定的。當(dāng)前作業(yè)主頁上還包含了一些有趣的條目。左側(cè)欄的鏈接主要控制Job的配置、刪除作業(yè)、構(gòu)建作業(yè)。右邊部分的鏈接指向最新的項目報告和構(gòu)件。通過點擊構(gòu)建歷史(Build History)中某個具體的構(gòu)建鏈接,就能跳轉(zhuǎn)到Jenkins為這個構(gòu)建實例而創(chuàng)建的構(gòu)建主頁上。
如果你想通過視圖輸出界面來監(jiān)控當(dāng)前任務(wù)的進(jìn)展情況。你可以單擊Console?Output(控制臺輸出)。如?果工作已完成,這將顯示構(gòu)建腳本產(chǎn)生的靜態(tài)輸出;如果作業(yè)仍然在運行中,Jenkins將不斷刷新網(wǎng)頁的內(nèi)容,以便您可以看到它運行時的輸出
常見錯誤處理
1.??java.lang.UnsupportedClassVersionError
這是因為jenkins和jdk版本不對應(yīng)引起的。我這里用的是jdk1.7,所以下載版本http://pkg.jenkins-ci.org/redhat/jenkins-2.33-1.1.noarch.rpm(jenkins下載地址:http://pkg.jenkins-ci.org/redhat/),? ?原先現(xiàn)在2.5版本以上,版本太高,啟動報“java.lang.UnsupportedClassVersionError”錯,所以要卸載之前安裝的jenkins-2.54-1.1.noarch,使用如下命令
2.?command execution failed.Maybe you need to configure the job to choose one of your Ant installations?
控制臺輸出Started by user?admin[EnvInject] - Loading node environment variables.Building in workspace /home/jenkins/workspace/My_cacheUpdating?https://ip地址/svn/iptv/新業(yè)務(wù)/廣西開機廣告/code/ad-gx-cache?at revision '2017-07-17T14:14:11.377 +0800'Using sole credentials hehaitao/****** in realm ‘<https://ip地址:443> VisualSVN Server’At revision 68144No changes for?https://ip地址/svn/iptv/%E6%96%B0%E4%B8%9A%E5%8A%A1/%E5%B9%BF%E8%A5%BF%E5%BC%80%E6%9C%BA%E5%B9%BF%E5%91%8A/code/ad-gx-cachesince the previous build[workspace]?$ ant -file checkstyleBuild.xml -DBUILD_NUMBER=8ERROR: command execution failed.Maybe you need to configure the job to choose one of your Ant installations?[CHECKSTYLE] Skipping publisher since build result is FAILURE[FINDBUGS] Skipping publisher since build result is FAILURE?Warning: you have no plugins providing access control for builds, so falling back to legacy behavior of permitting any downstream builds to be triggeredFinished: FAILURE”這是由于沒有成功全局配置ant的環(huán)境變量沒有配置成功導(dǎo)致,請確保環(huán)境Ant環(huán)境變量配置成功,并且在Global Tool Configuration正確添加了Ant的路徑
3.?JAVA_HOME is not defined correctly.
控制臺輸出Started by user?admin[EnvInject] - Loading node environment variables.Building in workspace /home/jenkins/workspace/My_cacheUpdating?https://ip地址/svn/iptv/新業(yè)務(wù)/廣西開機廣告/code/ad-gx-cache?at revision '2017-07-17T15:33:26.714 +0800'Using sole credentials hehaitao/****** in realm ‘<https://ip地址:443> VisualSVN Server’At revision 68151[workspace] $ /home/lutong/apache-ant-1.10.3/bin/ant -file checkstyleBuild.xml -DBUILD_NUMBER=11Error: JAVA_HOME is not defined correctly.??We cannot execute javaBuild step 'Invoke Ant' marked build as failure[CHECKSTYLE] Skipping publisher since build result is FAILURE[FINDBUGS] Skipping publisher since build result is FAILUREWarning: you have no plugins providing access control for builds, so falling back to legacy behavior of permitting any downstream builds to be triggeredFinished: FAILURE”?這是由于沒有成功全局配置JDK的環(huán)境變量沒有配置成功導(dǎo)致,請確保環(huán)境Ant環(huán)境變量配置成功,并且在Global Tool Configuration添加的JDK路徑正確
4.?Unable to access the repository?
在配置“源碼管理”時,如果Credentials?不選擇或者選擇了驗證不正確,會出現(xiàn)這個錯誤
Jenkins啟動
首先保證系統(tǒng)中已經(jīng)安裝了jdk,最好是jdk1.5以上。
第一種啟動方法:
切換到j(luò)enkins.jar存放的目錄,輸入如下命令:
$ java -jar jenkins.war
如果需要修改端口可以使用如下命令:
$ java -jar jenkins.war--httpPort=8081
然后在瀏覽器中(推薦用火狐)輸入localhost:8080,localhost可以是本機的ip,也可以是計算機名。就可以打開jenkins。
第二種方法是用tomcat打開
解壓tomcat到某個目錄,如/usr/local,進(jìn)入tomcat下的/bin目錄,啟動tomcat
將jenkins.war文件放入tomcat下的webapps目錄下,啟動tomcat時,會自動在webapps目錄下建立jenkins目錄,在地址欄上需要輸入localhost:8080/jenkins。
Jenkins 的安裝非常簡單,只需要從 Jenkins 的主頁上下載最新的 jenkins.war 文件然后運行java -jar jenkins.war。同時,還可以點擊 Jenkins 頁面上的 launch 按鈕完成下載和運行 Jenkins。