敏捷開發(fā)
- 敏捷開發(fā)以用戶的需求進(jìn)化為核心,采用迭代、循序漸進(jìn)的方法進(jìn)行軟件開發(fā)。 在敏捷開發(fā)中,軟件項(xiàng)目在構(gòu)建初期被切分成多個(gè)子項(xiàng)目,各個(gè)子項(xiàng)目的成果都經(jīng)過(guò)測(cè)試,具備可視、可集成和可運(yùn)行使用的特征。
持續(xù)集成
Travis CI 提供的是持續(xù)集成服務(wù)(Continuous Integration,簡(jiǎn)稱 CI)。它綁定 Github 上面的項(xiàng)目,只要有新的代碼,就會(huì)自動(dòng)抓取。然后,提供一個(gè)運(yùn)行環(huán)境,執(zhí)行測(cè)試,完成構(gòu)建,還能部署到服務(wù)器。
持續(xù)集成指的是只要代碼有變更,就自動(dòng)運(yùn)行構(gòu)建和測(cè)試,反饋運(yùn)行結(jié)果。確保符合預(yù)期以后,再將新代碼"集成"到主干。
持續(xù)集成的好處在于,每次代碼的小幅變更,就能看到運(yùn)行結(jié)果,從而不斷累積小的變更,而不是在開發(fā)周期結(jié)束時(shí),一下子合并一大塊代碼。
Travis CI
Travis-CI是一個(gè)開源的持續(xù)構(gòu)建項(xiàng)目,能夠測(cè)試和部署;Travis-CI會(huì)同步你在GitHub上托管的項(xiàng)目,每當(dāng)你Commit Push之后,就會(huì)在幾分鐘內(nèi)開始按照你的要求測(cè)試部署你的項(xiàng)目。
-
注意:Travis CI分為
- Github公開項(xiàng)目:http://travis-ci.org/
- Github私有付費(fèi)項(xiàng)目(私有庫(kù)):http://travis-ci.com/
官方文檔可查看https://docs.travis-ci.com/
本博客主要針對(duì)私有項(xiàng)目
使用 Travis CI
- 登錄Travis-CI,使用自己的GIthub賬號(hào)即可,確認(rèn)接收訪問(wèn)Github的權(quán)限

- 登錄之后,Travis-CI就會(huì)同步你GitHub賬號(hào)的倉(cāng)庫(kù)。然后打開個(gè)人頁(yè)面并給你想要構(gòu)建的項(xiàng)目啟用Travis-CI。
選擇需要進(jìn)行測(cè)試的私有項(xiàng)目,然后在github上開放權(quán)限。

然后就可以看到該項(xiàng)目的build界面了:

現(xiàn)在就完成了創(chuàng)建工作,接下來(lái)需要編輯.travis.yml文件
.travis.yml文件
Travis 要求項(xiàng)目的根目錄下面,必須有一個(gè)
.travis.yml文件。這是配置文件,指定了 Travis 的行為。該文件必須保存在 Github 倉(cāng)庫(kù)里面,一旦代碼倉(cāng)庫(kù)有新的 Commit,Travis 就會(huì)去找這個(gè)文件,執(zhí)行里面的命令。這個(gè)文件采用 YAML 格式。如果需要系統(tǒng)地學(xué)習(xí),官方文檔是個(gè)好選擇,本博客只介紹通常會(huì)使用的語(yǔ)法,而且由于本博客是基于django項(xiàng)目,因此yml文件也是提供給python環(huán)境的。
運(yùn)行流程
- Travis 的運(yùn)行流程很簡(jiǎn)單,任何項(xiàng)目都會(huì)經(jīng)過(guò)兩個(gè)階段。
- install 階段:安裝依賴,用來(lái)指定安裝腳本。
install:
- command1
- command2
注:
如果command1失敗了,整個(gè)構(gòu)建就會(huì)停下來(lái),不再往下進(jìn)行;
如果不需要安裝,即跳過(guò)安裝階段,就直接設(shè)為true。
install: true
- script 階段:運(yùn)行腳本,用來(lái)指定構(gòu)建或測(cè)試腳本。
script:
- command1
- command2
注:script與install不一樣,如果command1失敗,command2會(huì)繼續(xù)執(zhí)行。但是,整個(gè)構(gòu)建階段的狀態(tài)是失敗。
如果command2只有在command1成功后才能執(zhí)行,就要寫成下面這樣。
script: command1 && command2
Travis鉤子
- Travis 為上面這些階段提供了7個(gè)鉤子。
- before_install:install 階段之前執(zhí)行
- before_script:script 階段之前執(zhí)行
- after_failure:script 階段失敗時(shí)執(zhí)行
- after_success:script 階段成功時(shí)執(zhí)行
- before_deploy:deploy 步驟之前執(zhí)行
- after_deploy:deploy 步驟之后執(zhí)行
- after_script:script 階段之后執(zhí)行
- 完整的生命周期,從開始到結(jié)束是下面的流程。
- before_install
- install
- before_script
- script
- aftersuccess or afterfailure
- [OPTIONAL] before_deploy
- [OPTIONAL] deploy
- [OPTIONAL] after_deploy
- after_script
運(yùn)行狀態(tài)
- Travis 每次運(yùn)行,可能會(huì)返回四種狀態(tài)
- passed:運(yùn)行成功,所有步驟的退出碼都是0
- canceled:用戶取消執(zhí)行
- errored:before_install、install、before_script有非零退出碼,運(yùn)行會(huì)立即停止
- failed :script有非零狀態(tài)碼 ,會(huì)繼續(xù)運(yùn)行
環(huán)境變量
env:
- DJANGO_VERSION=1.9.5 DB=mysql
有些環(huán)境變量(比如用戶名和密碼)不能公開,這時(shí)可以通過(guò) Travis 網(wǎng)站,寫在每個(gè)倉(cāng)庫(kù)的設(shè)置頁(yè)里面,Travis 會(huì)自動(dòng)把它們加入環(huán)境變量。這樣一來(lái),腳本內(nèi)部依然可以使用這些環(huán)境變量,但是只有管理員才能看到變量的值。
一般不推薦在travis上使用項(xiàng)目真實(shí)的config配置文件,如果非得使用,需要進(jìn)行加密操作。
例子
以下是我們項(xiàng)目的例子,使用的python環(huán)境是3.5,需要安裝django,django的數(shù)據(jù)庫(kù)指定為mysql,另外在requirements.txt放置python依賴的包,在test之前進(jìn)行數(shù)據(jù)庫(kù)的初始化操作。
configs.json是我們的本地配置文件,而configs.example.json是測(cè)試配置文件(這種方式得感謝一位同學(xué)的幫助,我們之前是通過(guò)對(duì)config.json進(jìn)行加密從而完成配置的。),因此這樣測(cè)試環(huán)境和運(yùn)行環(huán)境實(shí)際上是完全獨(dú)立的。
language: python
sudo: required
python:
- '3.5'
services:
- mysql
env:
- DJANGO_VERSION=1.9.5 DB=mysql
#branchs:
# only:
# - master
install:
- pip install -r requirements.txt
- mv configs.example.json configs.json
before_script:
- mysql -e "create database IF NOT EXISTS wechat_ticket;"
- python manage.py makemigrations
- python manage.py migrate
script:
- python manage.py test
如果build成功,則會(huì)顯示這樣的圖標(biāo):

為了將此圖標(biāo)放置于我們的github上,只需要點(diǎn)擊該圖標(biāo),選擇markdown

最后將其內(nèi)容復(fù)制到Github上的README下即可,最終結(jié)果為:

這樣,就基本完成了Travis CI在Github上的部署,接下來(lái)是一些進(jìn)階操作
Travis使用SSH免密登陸服務(wù)器
此方法來(lái)自于:https://juejin.im/post/5a9e1a5751882555712bd8e1
要想通過(guò)Travis在執(zhí)行服務(wù)器得腳本首先得登陸到我們得服務(wù)器,但是在Travis不像交互式終端。一般利用用戶名和密碼登陸是需要輸入用戶名,密碼的,但是Travis里面沒(méi)有提供與用戶交互的界面,當(dāng)然這也與自動(dòng)化不符,所以我們只有利用其他方式登陸--SSH免密登陸。
SSH的登陸原理大家可以看這個(gè):SSH公鑰登陸原理。大概過(guò)程就是,在客戶端生成一個(gè)公鑰/私鑰對(duì),將公鑰內(nèi)容保存到服務(wù)器 ~/.ssh/authrized_keys 中,然后客戶端發(fā)起連接請(qǐng)求時(shí),服務(wù)器發(fā)送一個(gè)字符串給客戶端,客戶端用本地的私鑰對(duì)字符串進(jìn)行加密然后發(fā)送給服務(wù)器,服務(wù)器將收到的加密字符串用公鑰解密,如果能解密成功就登陸成功。
這里的公鑰/私鑰對(duì)就是登陸的關(guān)鍵,我們不能直接操作Travis服務(wù)器,在上面生成公鑰/私鑰對(duì),所以按照上面正常的流程就走不通,這時(shí)候就需要讓Travis偽裝成一個(gè)受信的客戶端去連接。也就是我們需要有一對(duì)公鑰/私鑰對(duì),公鑰已經(jīng)保存在我們的Linux服務(wù)器中,私鑰保存在某個(gè)Travis能訪問(wèn)到的地方,在必要的時(shí)候用這個(gè)私鑰去連接服務(wù)器,這里我們可以把私鑰放在Git代碼倉(cāng)庫(kù)中,但是直接把私鑰放代碼中不安全,所以Travis提供了對(duì)私鑰進(jìn)行加密的功能,我們可以把私鑰加密之后放在代碼倉(cāng)庫(kù),在登陸的時(shí)候Travis解密該私鑰用于連接。
具體操作可以參考上述鏈接
Travis 加密文件
- 安裝linux客戶端Travis
安裝ruby
> ruby -v
顯示ruby 2.0.0p195 (2013-05-14 revision 40734) [x86_64-darwin12.3.0]以上信息
> sudo gem install travis -v 1.8.9 --no-rdoc --no-ri
如果有報(bào)錯(cuò):mkmf.rb can't find header files for ruby at /usr/lib/ruby/include/ruby.h
運(yùn)行> sudo apt-get install ruby-dev
然后> sudo gem install travis -v 1.8.9 --no-rdoc --no-ri
> travis version
1.8.9
> sudo gem install travis --pre
- 安裝完成后只需要生成對(duì)應(yīng)的私鑰文件了
travis login
travis encrypt-file config.json --add
- --add自動(dòng)將配置信息添加到y(tǒng)ml文件中
- openssl aes-256-cbc -K ****_key -iv _****_iv -in *************
最終的文件:
language: python
sudo: required
python:
- '3.5'
services:
- mysql
env:
- DJANGO=1.9.5 DB=mysql
branchs:
only:
- master
before_install:
- openssl aes-256-cbc -K ****_key -iv _****_iv -in *************
- chmod 600 configs.json
install:
- pip install -r requirements.txt
before_script:
- mysql -e "create database IF NOT EXISTS wechat_ticket;"
- python manage.py makemigrations
- python manage.py migrate
script:
- python manage.py test
- 盡管最終我們沒(méi)采用加密方式,但是這種方式仍然有意義。
- 注意權(quán)限
