編寫程式碼只是軟體開發的一小部分,更多的時間往往花在構建(build)和測試(test)。
為了提高軟體開發的效率,構建和測試的自動化工具層出不窮。Travis CI 就是這類工具之中,市場份額最大的一個。
本文介紹 Travis CI 的基本用法。用好這個工具不僅可以提高效率,還能使開發流程更可靠和專業化,從而提高軟體的價值。而且,它對於開源專案是免費的,不花一分錢,就能幫你做掉很多事情。
一、什麼是持續整合?
Travis CI 提供的是持續整合服務(Continuous Integration,簡稱 CI)。它繫結 Github 上面的專案,只要有新的程式碼,就會自動抓取。然後,提供一個執行環境,執行測試,完成構建,還能部署到伺服器。
持續整合指的是隻要程式碼有變更,就自動執行構建和測試,反饋執行結果。確保符合預期以後,再將新程式碼"整合"到主幹。
持續整合的好處在於,每次程式碼的小幅變更,就能看到執行結果,從而不斷累積小的變更,而不是在開發週期結束時,一下子合併一大塊程式碼。
二、使用準備
Travis CI 只支援 Github,不支援其他程式碼託管服務。這意味著,你必須滿足以下條件,才能使用 Travis CI。
- 擁有 GitHub 帳號
- 該帳號下面有一個專案
- 該專案裡面有可執行的程式碼
- 該專案還包含構建或測試指令碼
如果這些條件都沒問題,就可以開始使用 Travis CI 了。
首先,訪問官方網站 travis-ci.org,點選右上角的個人頭像,使用 Github 賬戶登入 Travis CI。
Travis 會列出 Github 上面你的所有倉庫,以及你所屬於的組織。此時,選擇你需要 Travis 幫你構建的倉庫,開啟倉庫旁邊的開關。一旦啟用了一個倉庫,Travis 會監聽這個倉庫的所有變化。
三、.travis.yml
Travis 要求專案的根目錄下面,必須有一個.travis.yml
檔案。這是配置檔案,指定了 Travis 的行為。該檔案必須儲存在 Github 倉庫裡面,一旦程式碼倉庫有新的 Commit,Travis 就會去找這個檔案,執行裡面的命令。
這個檔案採用 YAML 格式。下面是一個最簡單的 Python 專案的.travis.yml
檔案。
language: python script: true
上面程式碼中,設定了兩個欄位。language
欄位指定了預設執行環境,這裡設定使用 Python 環境。script
欄位指定要執行的指令碼,script: true
表示不執行任何指令碼,狀態直接設為成功。
Travis 預設提供的執行環境,請參考官方文件 。目前一共支援31種語言,以後還會不斷增加。
下面是一個稍微複雜一點的.travis.yml
。
language: python sudo: required before_install: sudo pip install foo script: py.test
上面程式碼中,設定了四個欄位:執行環境是 Python,需要sudo
許可權,在安裝依賴之前需要安裝foo
模組,然後執行指令碼py.test
。
四、執行流程
Travis 的執行流程很簡單,任何專案都會經過兩個階段。
- install 階段:安裝依賴
- script 階段:執行指令碼
4.1 install 欄位
install
欄位用來指定安裝指令碼。
install: ./install-dependencies.sh
如果有多個指令碼,可以寫成下面的形式。
install: - command1 - command2
上面程式碼中,如果command1
失敗了,整個構建就會停下來,不再往下進行。
如果不需要安裝,即跳過安裝階段,就直接設為true
。
install: true
4.2、script 欄位
script
欄位用來指定構建或測試指令碼。
script: bundle exec thor build
如果有多個指令碼,可以寫成下面的形式。
script: - command1 - command2
注意,script
與install
不一樣,如果command1
失敗,command2
會繼續執行。但是,整個構建階段的狀態是失敗。
如果command2
只有在command1
成功後才能執行,就要寫成下面這樣。
script: command1 && command2
4.3 例項:Node 專案
Node 專案的環境需要寫成下面這樣。
language: node_js node_js: - "8"
上面程式碼中,node_js
欄位用來指定 Node 版本。
Node 專案的install
和script
階段都有預設指令碼,可以省略。
install
預設值:npm installscript
預設值:npm test
更多設定請看官方文件。
4.4 部署
script
階段結束以後,還可以設定通知步驟(notification)和部署步驟(deployment),它們不是必須的。
部署的指令碼可以在script
階段執行,也可以使用 Travis 為幾十種常見服務提供的快捷部署功能。比如,要部署到 Github Pages,可以寫成下面這樣。
deploy: provider: pages skip_cleanup: true github_token: $GITHUB_TOKEN # Set in travis-ci.org dashboard on: branch: master
其他部署方式,請看官方文件。
4.5 鉤子方法
Travis 為上面這些階段提供了7個鉤子。
- before_install:install 階段之前執行
- before_script:script 階段之前執行
- after_failure:script 階段失敗時執行
- after_success:script 階段成功時執行
- before_deploy:deploy 步驟之前執行
- after_deploy:deploy 步驟之後執行
- after_script:script 階段之後執行
完整的生命週期,從開始到結束是下面的流程。
- before_install
- install
- before_script
- script
- aftersuccess or afterfailure
- [OPTIONAL] before_deploy
- [OPTIONAL] deploy
- [OPTIONAL] after_deploy
- after_script
下面是一個before_install
鉤子的例子。
before_install: - sudo apt-get -qq update - sudo apt-get install -y libxml2-dev
上面程式碼表示before_install
階段要做兩件事,第一件事是要更新依賴,第二件事是安裝libxml2-dev
。用到的幾個引數的含義如下:-qq
表示減少中間步驟的輸出,-y
表示如果需要使用者輸入,總是輸入yes
。
4.6 執行狀態
最後,Travis 每次執行,可能會返回四種狀態。
- passed:執行成功,所有步驟的退出碼都是
0
- canceled:使用者取消執行
- errored:
before_install
、install
、before_script
有非零退出碼,執行會立即停止- failed :
script
有非零狀態碼 ,會繼續執行
五、使用技巧
5.1 環境變數
.travis.yml
的env
欄位可以定義環境變數。
env: - DB=postgres - SH=bash - PACKAGE_VERSION="1.0.*"
然後,指令碼內部就使用這些變數了。
有些環境變數(比如使用者名稱和密碼)不能公開,這時可以通過 Travis 網站,寫在每個倉庫的設定頁裡面,Travis 會自動把它們加入環境變數。這樣一來,指令碼內部依然可以使用這些環境變數,但是隻有管理員才能看到變數的值。具體操作請看官方文件。
5.2 加密資訊
如果不放心保密資訊明文存在 Travis 的網站,可以使用 Travis 提供的加密功能。
首先,安裝 Ruby 的包travis
。
$ gem install travis
然後,就可以用travis encrypt
命令加密資訊。
在專案的根目錄下,執行下面的命令。
$ travis encrypt SOMEVAR=secretvalue
上面命令中,SOMEVAR
是要加密的變數名,secretvalue
是要加密的變數值。執行以後,螢幕上會輸出如下資訊。
secure: ".... encrypted data ...."
現在,就可以把這一行加入.travis.yml
。
env: global: - secure: ".... encrypted data ...."
然後,指令碼里面就可以使用環境變數$SOMEVAR
了,Travis 會在執行時自動對它解密。
travis encrypt
命令的--add
引數會把輸出自動寫入.travis.yml
,省掉了修改env
欄位的步驟。
$ travis encrypt SOMEVAR=secretvalue --add
詳細資訊請看官方文件。
5.3 加密檔案
如果要加密的是檔案(比如私鑰),Travis 提供了加密檔案功能。
安裝命令列客戶端以後,使用下面的命令登入 Travis CI。
$ travis login
然後,進入專案的根目錄,使用travis encrypt-file
命令加密那些想要加密的檔案。
$ travis encrypt-file bacon.txt encrypting bacon.txt for rkh/travis-encrypt-file-example storing result as bacon.txt.enc storing secure env variables for decryption Please add the following to your build script (before_install stage in your .travis.yml, for instance): openssl aes-256-cbc -K $encrypted_0a6446eb3ae3_key -iv $encrypted_0a6446eb3ae3_key -in bacon.txt.enc -out bacon.txt -d Pro Tip: You can add it automatically by running with --add. Make sure to add bacon.txt.enc to the git repository. Make sure not to add bacon.txt to the git repository. Commit all changes to your .travis.yml.
上面的程式碼對檔案bacon.txt
進行加密,加密後會生成bacon.txt.enc
,該檔案需要提交到程式碼庫。此外,該命令還會生成一個環境變數$encrypted_0a6446eb3ae3_key
,儲存金鑰,儲存在 Travis CI,檔案解密時需要這個環境變數。你需要把解密所需的openssl
命令,寫在.travis.yml
的before_install
欄位裡面。這些都寫在上面的命令列提示裡面。
--add
引數可以自動把環境變數寫入.travis.yml
。
$ travis encrypt-file bacon.txt --add encrypting bacon.txt for rkh/travis-encrypt-file-example storing result as bacon.txt.enc storing secure env variables for decryption Make sure to add bacon.txt.enc to the git repository. Make sure not to add bacon.txt to the git repository. Commit all changes to your .travis.yml.
詳細資訊請看官方文件,實際的例子可以參考下面兩篇文章。
(完)