很早以前我就在用 Travis CI 作持續集成了,雖然只是停留在 zhuang bi 的階段,但或多或少也保證了代碼的提交質量。最近在寫一個 《JavaScript API 全解析》系列的 Book,須要常常把文章部署到服務器上,手動部署實在是煩,索性花了一天時間研究了一下自動化部署。這篇文章是對 Travis CI 持續集成和自動化部署的總結,以饗社區。node
Travis CI 目前有兩個網站,一個是 travis-ci.com,另外一個是 travis-ci.org. 前者用於企業級和私有倉庫,後者用於開源的公有倉庫。實際上 free plan 也可使用 travis-ci.com,但優先級很低,跑個自動化動輒兩個小時,所以咱們使用 travis-ci.org.c++
首先打開 Travis CI 官網,並用 GitHub 帳號登陸,受權後 Travis CI 會同步你的倉庫信息。接下來把須要作自動化的工程受權給 Travis CI.git
最好有一臺 Linux 的服務器,個人是 Cent OS 7.6.x 64bit.github
咱們點開一個工程,再切到設置,能夠看到在 push 代碼和 PR 時都會觸發持續集成,固然能夠根據需求手動配置。sql
爲了讓持續集成像那麼回事兒,咱們先在 master 上切一個 develop 分支,再在 develop 上切一個 featur/ci 分支。shell
接着咱們再用 Jest 寫幾個測試用例,注意若是項目中沒有測試腳本而 .travis.yml
文件裏面包含 yarn test
,自動化 必定 報錯。關於 Jest 這裏不詳細說,只貼出幾個示例代碼。centos
import * as utils from '../utils/util';
test('should get right date', () => {
expect(utils.formatJSONDate('2019-03-10T04:15:40.629Z')).toBe(
'2019-03-10 12:15:40',
);
});
test('should get right string', () => {
expect(utils.upperFirstLetter('AFTERNOON')).toBe('Afternoon');
expect(utils.upperFirstLetter('YANCEY_LEO')).toBe('Yancey Leo');
});
複製代碼
而後咱們在工程的根目錄下新建一個文件 .travis.yml
,並複製下面的代碼。api
language: node_js
node_js:
- 8
branchs:
only:
- master
cache:
directories:
- node_modules
install:
- yarn install
scripts:
- yarn test
- yarn build
複製代碼
簡單解釋一下,工程使用 Node.js 8.x,而且只在 master
分支有變更時觸發 自動化部署(正常的提交、PR 都會正常走持續集成),接着將 node_modules 緩存起來(你懂的),最後安裝依賴、跑測試腳本、在沙箱部署。緩存
所以,理論上只要跑通這套流程,咱們就能夠放心的部署到真實環境了。ruby
提交一下代碼,並 pull request 到 develop 分支。在此過程當中咱們觸發了 push 和 PR,因此會跑兩個 CI。待到兩個都成功跑完後,咱們就能夠放心的合到 develop 分支了。(這裏我還作了代碼質量檢測,有興趣能夠戳 Codacy)
最後咱們回到 Travis CI 的官網,能夠看到一套完整的構建流程:安裝依賴 -> 測試 -> 沙箱部署
首先登陸你的服務器,通常來說咱們不會直接在 root 上操做,因此這裏新增一個 caddy 的用戶 。具體怎樣在 Linux 新建用戶請自行谷歌。
接下來 cd 到 ~/.ssh,看看有沒有一對 id_rsa 和 id_rsa.pub,若是沒有就用 ssh-keygen
生成。
給予 .ssh 文件夾 700 權限,給予 .ssh 裏的文件 600 權限。(看下面這張圖,你的文件夾裏可能暫時沒有 authorized_keys、 known_host、config 這三個文件,後面會說到。)
$ sudo chmod 700 ~/.ssh/
$ sudo chmod 600 ~/.ssh/*
複製代碼
進入到 .ssh
文件夾裏,執行下面的命令,能夠看到公鑰被添加到受信列表。
$ cat id_rsa.pub >> authorized_keys
$ cat authorized_keys
複製代碼
在 .ssh
目錄下建立一個文件 config
,輸入以下代碼並保存。
Host test
HostName 當前服務器的IP
User 當前用戶名
IdentitiesOnly yes
IdentityFile ~/.ssh/id_rsa
複製代碼
由於 authorized_keys
和 config
文件都是新增的,它們還沒被賦予 600 權限,因此從新執行一遍 sudo chmod 600 ~/.ssh/*
.
而後咱們輸入 ssh test
,不出意外會從新登陸 ssh。若是你的公鑰歷來沒有被使用過,會提示 Are you sure you want to continue connecting (yes/no)?
,輸入 yes 後也會正常從新登陸,而且在.ssh
文件夾下還會生成一個 known_hosts
文件.
由於 Travis 客戶端是用 Ruby 寫的,因此咱們得先安裝 Ruby.
首先安裝須要的依賴包:
$ yum install gcc-c++ patch readline readline-devel zlib zlib-devel \
libyaml-devel libffi-devel openssl-devel make \
bzip2 autoconf automake libtool bison iconv-devel sqlite-devel
複製代碼
接下來安裝 RVM,並載入 RVM 環境。RVM 是 Ruby 的版本管理工具,相似於 Node 的 NVM.
$ gpg --keyserver hkp://keys.gnupg.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3
$ \curl -sSL https://get.rvm.io | bash -s stable
# 載入 rvm 環境
$ source ~/.rvm/scripts/rvm
複製代碼
安裝完以後輸入 rvm -v
作下檢查,若是有 rvm 1.29.1 (latest) by Michal Papis, Piotr Kuczynski, Wayne E. Seguin [rvm.io/] 的字樣證實安裝成功。
最後安裝 Ruby,這裏選擇 v2.4.1 版本,安裝須要一段時間,完成後記得將此版本設爲默認。
$ rvm install 2.4.1
$ rvm 2.4.1 --default
複製代碼
執行一下 ruby -v
和 gem -v
,若是和下圖差很少證實安裝成功。
執行下面的命令以安裝 Travis 客戶端。
$ gem install travis
複製代碼
安裝完成後執行 travis
,它會讓你安裝相應的 Shell, 輸入 yes 便可。
將你的工程克隆下來,並進入到工程目錄,而後登陸你的 GitHub 帳號。
$ travis login --auto
複製代碼
執行下面這句,它會利用服務器的私鑰加密成一個叫作 id_rsa.enc
的文件,這個文件被用於 travis 登陸你服務器的憑證,從而達到免密的目的。
$ travis encrypt-file ~/.ssh/id_rsa --add
複製代碼
咱們執行一下 ll
,能夠看到根目錄下多出一個 id_rsa.enc
文件來,而且 cat .travis.yml
,發現多出了 before_install
.
爲了更好地組織代碼,咱們在項目的根目錄新建一個文件夾 .travis
,而後將 id_rsa.enc
放到裏面。
在寫這一小節以前,咱們先看一看 Travis 的生命週期:
所以 after_success
可用在成功經過測試腳本以後執行部署相關的腳本。固然細一點可使用 deploy 相關的鉤子,這裏不作太複雜。
打開 .travis.yml
文件,直接上所有代碼。
language: node_js
sudo: true
node_js:
- 8
branchs:
only:
- master
# 這裏填寫服務器的ip,若端口號不是22,後面要註明端口號
addons:
ssh_known_hosts:
- 你的服務器IP
cache:
directories:
- node_modules
before_install:
# 由於咱們把 id_rsa.enc 移到了.travis 文件夾下,因此 -in 後面要改爲 .travis/id_rsa.enc
# 其次,-out 後面自動生成的是 ~\/.ssh/id_rsa,要把 \ 去掉,不然會編譯失敗
- openssl aes-256-cbc -K $encrypted_XXXXXXXXXXXX_key -iv $encrypted_XXXXXXXXXXXX_iv -in .travis/id_rsa.enc -out ~/.ssh/id_rsa -d
# 開啓 ssh-agent,即容許使用 ssh 命令
- eval "$(ssh-agent -s)"
# 給予 id_rsa 文件權限,避免警告
- chmod 600 ~/.ssh/id_rsa
# 將私鑰添加到 ssh
- ssh-add ~/.ssh/id_rsa
install:
- yarn install
scripts:
- yarn test
- yarn build
after_success:
# 登陸服務器,執行部署腳本,其實最好把後面一串寫成 shell 文件
- ssh caddy@你的服務器IP -o StrictHostKeyChecking=no 'cd /var/www/jsapi/JavaScript-APIs-Set && git pull && yarn install && yarn build'
複製代碼
至此,搭建 Travis CI 持續集成和自動化部署就算完成了,可能不太嚴謹,但基本是這麼一個思路。下面咱們梳理一遍流程。
咱們先在 feature/ci 分支修改一段代碼,提交分支,並 PR 到 develop,此時會運行兩個 CI。當兩個 CI 都跑通了,咱們能夠放心的 merge request 到 develop 分支。
接下來讓 develop PR 到 master,此時會運行兩個 CI(一個是 develop 分支,一個是測試合併到 master 的 CI)。當兩個 CI 都跑通了,咱們能夠放心的 merge request 到 master 分支。
merge request 以後會跑最後一個流程, 也就是自動部署,部署成功後線上代碼就會更新了。
別忘了把 build passing 徽章添加到你的 README.md 文件中。
不知道你有沒有發現,Travis CI 支持 LGBT...
以上、よろしく。
How to Encrypt/Decrypt SSH Keys for Deployment