手摸手教你搭建 Travis CI 持續集成和自動化部署

很早以前我就在用 Travis CI 作持續集成了,雖然只是停留在 zhuang bi 的階段,但或多或少也保證了代碼的提交質量。最近在寫一個 《JavaScript API 全解析》系列的 Book,須要常常把文章部署到服務器上,手動部署實在是煩,索性花了一天時間研究了一下自動化部署。這篇文章是對 Travis CI 持續集成和自動化部署的總結,以饗社區。

前戲

Travis CI 目前有兩個網站,一個是 travis-ci.com,另外一個是 travis-ci.org. 前者用於企業級和私有倉庫,後者用於開源的公有倉庫。實際上 free plan 也可使用 travis-ci.com,但優先級很低,跑個自動化動輒兩個小時,所以咱們使用 travis-ci.org.node

首先打開 Travis CI 官網,並用 GitHub 帳號登陸,受權後 Travis CI 會同步你的倉庫信息。接下來把須要作自動化的工程受權給 Travis CI.c++

受權倉庫信息

最好有一臺 Linux 的服務器,個人是 Cent OS 7.6.x 64bit.git

咱們點開一個工程,再切到設置,能夠看到在 push 代碼和 PR 時都會觸發持續集成,固然能夠根據需求手動配置。github

設置頁面

持續集成

爲了讓持續集成像那麼回事兒,咱們先在 master 上切一個 develop 分支,再在 develop 上切一個 featur/ci 分支。sql

接着咱們再用 Jest 寫幾個測試用例,注意若是項目中沒有測試腳本而 .travis.yml 文件裏面包含 yarn test,自動化 必定 報錯。關於 Jest 這裏不詳細說,只貼出幾個示例代碼。shell

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,並複製下面的代碼。centos

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 緩存起來(你懂的),最後安裝依賴、跑測試腳本、在沙箱部署。api

所以,理論上只要跑通這套流程,咱們就能夠放心的部署到真實環境了。緩存

提交一下代碼,並 pull request 到 develop 分支。在此過程當中咱們觸發了 push 和 PR,因此會跑兩個 CI。待到兩個都成功跑完後,咱們就能夠放心的合到 develop 分支了。(這裏我還作了代碼質量檢測,有興趣能夠戳 Codacyruby

跑 CI

最後咱們回到 Travis CI 的官網,能夠看到一套完整的構建流程:安裝依賴 -> 測試 -> 沙箱部署

CI 結果

持續部署

建立 rsa 對,並給予權限

首先登陸你的服務器,通常來說咱們不會直接在 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 權限

將生成的公鑰添加到受信列表

進入到 .ssh 文件夾裏,執行下面的命令,能夠看到公鑰被添加到受信列表。

$ cat id_rsa.pub >> authorized_keys

$ cat authorized_keys

測試登陸

.ssh 目錄下建立一個文件 config,輸入以下代碼並保存。

Host test
HostName 當前服務器的IP
User 當前用戶名
IdentitiesOnly yes
IdentityFile ~/.ssh/id_rsa

由於 authorized_keysconfig 文件都是新增的,它們還沒被賦予 600 權限,因此從新執行一遍 sudo chmod 600 ~/.ssh/*.

而後咱們輸入 ssh test,不出意外會從新登陸 ssh。若是你的公鑰歷來沒有被使用過,會提示 Are you sure you want to continue connecting (yes/no)? ,輸入 yes 後也會正常從新登陸,而且在.ssh 文件夾下還會生成一個 known_hosts 文件.

安裝 Ruby

由於 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 [https://rvm.io/] 的字樣證實安裝成功。

最後安裝 Ruby,這裏選擇 v2.4.1 版本,安裝須要一段時間,完成後記得將此版本設爲默認。

$ rvm install 2.4.1

$ rvm 2.4.1 --default

執行一下 ruby -vgem -v,若是和下圖差很少證實安裝成功。

安裝 ruby 成功

安裝 Travis 客戶端

執行下面的命令以安裝 Travis 客戶端。

$ gem install travis

安裝完成後執行 travis,它會讓你安裝相應的 Shell, 輸入 yes 便可。

安裝 shell

配置免密登陸

將你的工程克隆下來,並進入到工程目錄,而後登陸你的 GitHub 帳號。

$ travis login --auto

登陸 GitHub

執行下面這句,它會利用服務器的私鑰加密成一個叫作 id_rsa.enc 的文件,這個文件被用於 travis 登陸你服務器的憑證,從而達到免密的目的。

$ travis encrypt-file ~/.ssh/id_rsa --add

生成 id_rsa.enc 文件

咱們執行一下 ll,能夠看到根目錄下多出一個 id_rsa.enc 文件來,而且 cat .travis.yml,發現多出了 before_install.

爲了更好地組織代碼,咱們在項目的根目錄新建一個文件夾 .travis,而後將 id_rsa.enc 放到裏面。

添加了 before_install 鉤子

配置 after_success 鉤子

在寫這一小節以前,咱們先看一看 Travis 的生命週期:

  1. before_install 安裝依賴前
  2. install 安裝依賴時
  3. before_script 執行腳本前
  4. script 執行腳本時
  5. after_success 或 after_failure 執行腳本成功(失敗)後
  6. before_deploy 部署前
  7. deploy 部署時
  8. after_deploy 部署後
  9. after_script 執行腳本後

所以 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 持續集成和自動化部署就算完成了,可能不太嚴謹,但基本是這麼一個思路。下面咱們梳理一遍流程。

  1. 咱們先在 feature/ci 分支修改一段代碼,提交分支,並 PR 到 develop,此時會運行兩個 CI。當兩個 CI 都跑通了,咱們能夠放心的 merge request 到 develop 分支。
  2. 接下來讓 develop PR 到 master,此時會運行兩個 CI(一個是 develop 分支,一個是測試合併到 master 的 CI)。當兩個 CI 都跑通了,咱們能夠放心的 merge request 到 master 分支。
  3. merge request 以後會跑最後一個流程, 也就是自動部署,部署成功後線上代碼就會更新了。

加入徽章

別忘了把 build passing 徽章添加到你的 README.md 文件中。

badge

最後

不知道你有沒有發現,Travis CI 支持 LGBT...

LGBT

以上、よろしく。

參考

How to Encrypt/Decrypt SSH Keys for Deployment

Travis-CI 自動化測試並部署至本身的 CentOS 服務器

CentOS 7 使用 rvm 安裝 ruby 搭建 jekyll 環境

相關文章
相關標籤/搜索