在Python Web項目中使用Jenkins進行持續集成


在一個項目的開發過程中,往往會有一些需要反復執行的操作,比如編譯、測試、部署。具體於Flask項目,我一般使用nose執行單元測試、fabric進行部署、pylint執行代碼質量檢測等。這些頻繁需要執行的步驟,是非常枯燥的,那何不交給機器來自動執行呢?最近,我參與的一個校內團隊也遇到了類似的問題,於是打算調研一下相關的工具。

還是習慣性地查閱了下Kenneth Reitz大神的python-guide,果然找到了關於CI的章節。選來選去,最終沒有選擇Python Stack的Buildbot,而是更加成熟的Jenkins。Jenkins基於Java開發,是業界使用得最多的一款持續集成系統,市場份額占到了70%

關於Jenkins,官方的介紹如下:

monitors executions of repeated jobs, such as building a software project or jobs run by cron。

文檔中也說目前Jenkins專注於以下2個點:

  • Building/testing software projects continuously
  • Monitoring executions of externally-run jobs

其實Jenkins能夠做的遠不止這兩點,你可以把它理解成可以自動執行任務(類似cron)並收集報告的基礎工具。再加上它有着非常豐富的插件庫,所以使用起來應該是很靈活的。

下面記錄一些在Python Web項目中應用Jenkins的經驗。

安裝

Installing Jenkins。它也支持通過Docker安裝,真的是緊跟潮流!

需要提的一點是Jenkins比較耗內存,不運行任何構建任務的情況下就吃掉了300多M,再加上構建任務時會占用更多,所以建議服務器的內存至少有1G,512M的話很可能在執行構建任務的時候內存不夠用。

訪問控制

安裝后默認所有人都可以訪問,故需要更改訪問控制策略,具體見Standard Security Setup

插件清單

下面是我用到的一些插件:

  • Git Plugin:使用Git作為源代碼管理
  • SSH plugin:遠程ssh登錄server執行命令
  • Parameterized Trigger Plugin:觸發其他的job
  • Cobertura Plugin:代碼測試覆蓋率報告
  • Task Scanner Plugin:檢測代碼中出現的特殊標記(如TODO等)
  • Violations:代碼質量檢測,支持pylint、jslint等
  • ThinBackup:用於備份Jenkins
  • SCM Sync configuration plugin:將Jenkens的配置變更同步到SCM中

這里只是集中地列舉一下,具體的使用會在下面穿插介紹。

測試、Staging部署、Production部署流程

根據本項目的需要,在Jenkins中建立了3個任務:

  • tm_test:用於執行測試、代碼質量檢測等
  • tm_staging_deploy:用於在staging服務器上deploy代碼
  • tm_deploy:用於在production服務器上deploy代碼

Image Title

其中staging服務器用於進行線上測試,staging服務器和production服務器的環境必須保持完全相同(當然,staging服務器配置可以低一些)。

具體的開發、測試、部署流程是:

  • 在開發新功能/修復bug的時候,一般是開新分支;但如果是那種很小的修改,則直接在master上改,這樣比較省事兒
  • 新功能開發完成/bug修復后,進行單元測試+人工測試,如果通過,合並到master
  • 每次master有變動后,觸發tm_test任務,執行集成的單元測試和代碼質量檢測,如果OK,則自動觸發tm_staging_deploy,部署到staging服務器上
  • 若tm_staging_deploy成功,則登陸到運行在staging服務器的測試網站上,人工測試新功能是否OK/bug是否已修復;若tm_staging_deploy失敗,檢查失敗原因,進行修復,直至成功
  • 若staging人工測試通過,則手動觸發tm_deploy,部署到生產服務器上
  • 登錄到生產服務器上進行人工測試,若出現問題,進行修復;同時密切關注Sentry發送的告警郵件,爭取在第一時間修復錯誤

比較簡單,沒有采用Git-Flow/GitHub-Flow,單元測試寫得很淺,也沒有做代碼審查。不過團隊規模小,從目前來看,上面的流程是夠用的。

下面對這三個任務做較為詳細的介紹。

tm_test

該任務用於執行測試、代碼質量檢測等。

push觸發構建

每當項目倉庫的master分支有變動時,即會觸發tm_test。要做這一點,需要如下步驟:

  • 設置tm_test的Build Triggers為Poll SCM,但不填Schedule
  • 為項目倉庫添加Web Hook,URL填寫http://<Jenkins URL>/git/notifyCommit?url=<URL of the Git repository>

參考Stack Overflow

使用virtualenv配置測試環境

執行測試之前,需要確定Python版本(一般是2.7),然后根據此版本初始化virtualenv。

在構建中添加Execute shell項:

if [ ! -d "venv" ]; then  virtualenv -p /usr/bin/python2.7 venv fi . venv/bin/activate pip install -i http://pypi.douban.com/simple -r requirements.txt 

測試與報告

測試中需要2個庫:nose用於執行單元測試,coverage用於統計測試覆蓋率。

需要在Jenkins中安裝Cobertura Plugin插件,用於生成代碼測試覆蓋率報告。

然后在構建中添加Execute shell項,輸入:

nosetests --with-xunit --with-coverage --cover-package=tm && coverage xml 

其中--with-xunit告訴nose輸出JUnit形式的測試報告,--with-coverage表示同時運行coverage(這個功能相當贊),--cover-package=tm表示僅對指定的package執行測試覆蓋率檢測,后面的coverage xml表示輸出xml格式的coverage報告。

然后在構建后操作中,添加如下2項:

  • Publish JUnit test result report:填寫nosetests.xml
  • Publish Cobertura Coverage Report:填寫coverage.xml

這樣一來,就可以執行測試,並得到測試報告和測試覆蓋率報告啦:

Image Title

上面的圖表都是可點擊的,點進去后有代碼級的詳細報告,非常贊:

Image Title

綠色的代碼行表示已經覆蓋到,紅色則沒有。

代碼質量檢測

Jenkins有一個蠻不錯的代碼質量報告插件:Violations,支持非常多的代碼測試工具。目前項目中使用Pylint做Python代碼質量檢測,使用JSHint做JavaScript代碼質量檢測。

在安裝好Pylint后,運行pylint --generate-rcfile > pylintrc生成配置文件,並將其中的output-format項的值改為parseable

然后在構建中添加2項Execute shell項,

pylint:

pylint tm2 > pylint.xml || exit 0 

jshint:

jshint --reporter=jslint $WORKSPACE/tm2/static/js/ > jslint.xml || exit 0 

其中的exit 0是為了告訴Jenkins該命令執行成功。對於jshint來說,report選擇jslint,然后需要使用$WORKSPACE組成絕對路徑,否則無法看到源碼級的分析報告(是不是一個bug?)。

然后在構建后步驟中添加Violations Report,在對應位置輸入jslint.xml和pylint.xml。

最終的圖形報告如下,可以看到趨勢走向:

Image Title

源碼級別的分析也有:

Image Title

檢測代碼中的特殊標注(如TODO)

團隊中約定,在代碼未完成的地方使用TODO進行標記,因為PyCharm有一個很好的功能就是可以檢測出代碼中的所有TODO信息:

Image Title

Jenkins中也有一個非常棒的插件Task Scanner Plugin用於檢測代碼中出現的特殊標記,當然,這些特殊標記完全是可以自定義的。

安裝完該插件后,在構建后操作中添加一項Scan workspace for open tasks,根據需要填寫配置:

Image Title

然后報告就可以出來啦:

Image Title

郵件告警

如果構建后狀態是unstable或failed,則可以發送郵件告警,及時通知相關負責人進行處理。Jenkins自帶SMTP功能,不過需要你提供SMTP服務器。

我使用的是qq郵箱SMTP服務器,挺好用的,目前沒有發現拒發的情況。有一點需要注意的是,在配置好SMTP的賬戶信息后,還需填寫系統管理員郵件地址,否則會發送失敗,這也是比較容易忽略的地方。

配置好SMTP后,然后在構建后操作中添加E-mail Notification項,填寫負責人的郵箱即可。

觸發下游任務

如果tm_test構建成功,則需要自動觸發tm_staging_deploy任務,這個觸發過程是通過插件Parameterized Trigger Plugin來完成的。

在構建后操作中添加Trigger parameterized build on other projects項,選擇觸發條件為stable,然后填寫待出發的任務名稱即可。

最后的tm_test任務面板如下:

Image Title

界面是挺out的,不過很實用。

tm_staging_deploy

這一個job用於將最新代碼部署到staging服務器上,我采用的部署方法是通過ssh遠程登陸服務器執行命令的方式,需要一個插件SSH plugin。

然后在構建中添加Shell項:

cd /var/www/tm
export MODE=PRODUCTION git reset --hard HEAD git pull -f source venv/bin/activate pip install -r requirements.txt python manage.py db upgrade supervisorctl restart tm 

tm_deploy

此任務和tm_staging_deploy基本差不多,不同的地方有2個:(1)目標服務器不同(2)觸發方式是手動觸發

備份

使用thinBackup進行備份,可設定備份周期。

配置變更同步

除此之外,我還用到了一個很有用的插件SCM Sync configuration plugin,就是把Jenkins的配置(全局配置+各job配置)同步到一個Git倉庫中。這樣的話,每次配置有變動,都會形成一個commit推送到Git倉庫。

這相當於把配置的歷史變遷都記錄下來,如果哪天Jenkins任務掛了,可以看看配置變更進行排錯。

就這些,如果你好的建議,歡迎反饋!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM