Github和TravisCI的聯(lián)動實現(xiàn)和使用代碼觸發(fā)CI/CD-創(chuàng)新互聯(lián)

這期內(nèi)容當中小編將會給大家?guī)碛嘘P(guān)Github和Travis CI的聯(lián)動實現(xiàn)和使用代碼觸發(fā)CI/CD,以專業(yè)的角度為大家分析和敘述,閱讀完這篇文章希望大家可以有所收獲。

發(fā)展壯大離不開廣大客戶長期以來的信賴與支持,我們將始終秉承“誠信為本、服務至上”的服務理念,堅持“二合一”的優(yōu)良服務模式,真誠服務每家企業(yè),認真做好每個細節(jié),不斷完善自我,成就企業(yè),實現(xiàn)共贏。行業(yè)涉及木屋等,在成都網(wǎng)站建設網(wǎng)絡營銷推廣、WAP手機網(wǎng)站、VI設計、軟件開發(fā)等項目上具有豐富的設計經(jīng)驗。

首先介紹下在本文出現(xiàn)的幾個比較重要的概念:

函數(shù)計算(Function Compute):函數(shù)計算是一個事件驅(qū)動的服務,通過函數(shù)計算,用戶無需管理服務器等運行情況,只需編寫代碼并上傳。函數(shù)計算準備計算資源,并以彈性伸縮的方式運行用戶代碼,而用戶只需根據(jù)實際代碼運行所消耗的資源進行付費。函數(shù)計算更多信息參考。
Funcraft:Funcraft 是一個用于支持 Serverless 應用部署的工具,能幫助您便捷地管理函數(shù)計算、API 網(wǎng)關(guān)、日志服務等資源。它通過一個資源配置文件(template.yml),協(xié)助您進行開發(fā)、構(gòu)建、部署操作。Fun 的更多文檔參考。
OSS: 對象存儲。海量、安全、低成本、高可靠的云存儲服務,提供99.9999999999%的數(shù)據(jù)可靠性。使用RESTful API 可以在互聯(lián)網(wǎng)任何位置存儲和訪問,容量和處理能力彈性擴展,多種存儲類型供選擇全面優(yōu)化存儲成本。
ROS:資源編排(ROS)是一種簡單易用的云計算資源管理和自動化運維服務。用戶通過模板描述多個云計算資源的依賴關(guān)系、配置等,并自動完成所有資源的創(chuàng)建和配置,以達到自動化部署、運維等目的。編排模板同時也是一種標準化的資源和應用交付方式,并且可以隨時編輯修改,使基礎(chǔ)設施即代碼(Infrastructure as Code)成為可能。
CI/CD: CI/CD 是一種通過在應用開發(fā)階段引入自動化來頻繁向客戶交付應用的方法。CI/CD 的核心概念是持續(xù)集成、持續(xù)交付和持續(xù)部署。
Github和Travis CI的聯(lián)動實現(xiàn)和使用代碼觸發(fā)CI/CD

目標

本文打算以一個簡單的函數(shù)計算項目為例,在此基礎(chǔ)上編寫測試用例,進行配置,讓其支持 CI/CD 工作流程。實現(xiàn)如下四個小目標:

  1. CI 被 git commit 提交觸發(fā)
  2. 執(zhí)行測試(單元、集成和端對端)
  3. 函數(shù)打包上傳到 OSS
  4. 通過 ROS 部署函數(shù)到 Staging 環(huán)境

工作流程圖

Github和Travis CI的聯(lián)動實現(xiàn)和使用代碼觸發(fā)CI/CD

這里以大家熟悉的 Github 倉庫為例,并結(jié)合 Travis CI 。當用戶往示例項目 push 或者 PR(Pull Request)時,會自動觸發(fā) Travis CI 的工作任務,進行單元測試、構(gòu)建打包和部署發(fā)布。

示例項目

示例項目地址為:https://github.com/vangie/tz-time ,該項目是基于 FC Http trigger 實現(xiàn)的簡單 web 函數(shù),訪問放函數(shù)是會返回指定時區(qū)的當前時間。項目目錄結(jié)構(gòu)如下

tz-time
├── .funignore
├── .travis.yml
├── Makefile
├── bin
│  ├── delRosStack.sh
│  ├── deployE2EStack.sh
│  └── waitForServer.sh
├── deploy.log
├── index.e2e-test.js
├── index.integration-test.js
├── index.js
├── index.test.js
├── jest.config.e2e.js
├── jest.config.integration.js
├── package-lock.json
├── package.json
└── template.yml

部分文件作用介紹:

  • .funignore  - Funcraft 部署時忽然的文件清單
  • .travis.yml - Travis CI 配置文件
  • index.js - 函數(shù)入口文件
  • *.test.js - 單元測試相關(guān)文件
  • *.integraion-test.js - 集成測試相關(guān)文件
  • *.e23-test.js - 端對端測試相關(guān)文件
  • template.yml - ROS 描述文件,用于描述函數(shù)和其他云服務

自動化測試

測試通常非常如下三類:單元測試、集成測試和 E2E 測試。在函數(shù)計算場景下,這三類測試可以通過如下方法實現(xiàn)。

  • 單元測試 - 使用 Mock 類測試函數(shù),驗證輸入輸出參數(shù)
  • 集成測試 - 使用 fun local invoke/start 模擬運行函數(shù)
  • E2E 測試 - 使用 fun deploy 部署一套 test 環(huán)境,然后通過 fun invoke 進行模擬調(diào)用或者通過 curl 直接發(fā)送

本例子只實現(xiàn)了單元測試,集成測試和 E2E 測試對于 travis 示例來說觸發(fā)方法類似,實現(xiàn)方法可以參見上面的方法提示進行配置。

單元測試

FC 函數(shù)的單元測試和普通的函數(shù)并無二致。采用熟悉的單元測試框架即可,本例中使用了 jest 進行測試。下面看看一個測試用例的代碼片段

jest.mock('moment-timezone');

const { tz } = require('moment-timezone');
const { handler } = require('./index');

const EXPECTED_DATE = '2018-10-01 00:00:00';
const TIMEZONE = 'America/New_York';

describe('when call handle', () => {
   it('Should return the expected date if the provied timezone exists', () => {
     const mockReq = {
       queries: {
         tz: TIMEZONE
       }
     }
     const mockResp = {
       setHeader: jest.fn(),
       send: jest.fn()
     }

     tz.names = () => [TIMEZONE];
     tz.mockImplementation(() => {
       return {
         format: () => EXPECTED_DATE 
       }
     })

     handler(mockReq, mockResp, null);

     expect(mockResp.setHeader.mock.calls.length).toBe(1);
     expect(mockResp.setHeader.mock.calls[0][0]).toBe('content-type');
     expect(mockResp.setHeader.mock.calls[0][1]).toBe('application/json');

     expect(mockResp.send.mock.calls.length).toBe(1);
     expect(mockResp.send.mock.calls[0][0]).toBe(JSON.stringify({
       statusCode: '200',
       message: `The time in ${TIMEZONE} is: ${EXPECTED_DATE}`
     }, null, '   '));

   });
});

通過 jest.mock 對 moment-timezone 進行 mock,讓 tz 被調(diào)用的時候返回預先設定好的值,而不是一個動態(tài)變化的時間。

通常該類單元測試分為三步:

  1. mock 依賴的值或者參數(shù)
  2. 調(diào)用測試函數(shù)
  3. 斷言返回結(jié)果和被調(diào)用的參數(shù)

如果依賴包不存在原生依賴(依賴 linux 下的可執(zhí)行文件或者 so 庫文件)的使用 npm test 觸發(fā)測試即可,如果有原生依賴,那測試需要跑在 fun 提供的 sbox 模擬環(huán)境里,使用如下命令觸發(fā)

fun install sbox -f tz-time --cmd 'npm install'

集成測試

本例子中的集成測試會借助 fun local start 命令把函數(shù)在本地啟動起來,由于函數(shù)配置了 http trigger,所以可以通過 http 請求調(diào)用函數(shù)。

集成測試我們還是才是 jest 框架進行編寫,為了區(qū)別于單元測試文件 *.test.js ,集成測試文件使用 .integration-test.js 文件后綴。為了讓 jest 命令獨立的跑集成測試用例而不是和單元測試混和在一起,需要編撰如下文件 jest.config.integration.js

module.exports = {
   testMatch: ["**/?(*.)integration-test.js"]
};

然后在 package.json 中配置 scripts

"scripts": {
   "integration:test": "jest -c jest.config.integration.js"
}

于是可以通過執(zhí)行 npm run integration:test 來執(zhí)行集成測試。

然后在此基礎(chǔ)上在 Makefile 中添加 integration-test 目標:

funlocal.PID:
   fun local start & echo $$! > $@

integration-test: funlocal.PID 
   bin/waitForServer.sh http://localhost:8000/2016-08-15/proxy/tz-time/tz-time/
   npm run integration:test
   kill -2 `cat $<` && rm $<

integration-test 目標依賴 funlocal.PID 目標,后者負責啟動一個 fun local 進程,該進程會在本地啟動 8000 端口。解讀一下上面的 Makefile 代碼

  • fun local start & echo $$! &gt; $@ 啟動 fun local 進程,并將進程 PID 寫入到目標同名文件 funlocal.PID
  • bin/waitForServer.sh http://localhost:8000/2016-08-15/proxy/tz-time/tz-time/ 通過一個 url 測試 fun local 進程是否啟動完成。
  • kill -2 `cat $&lt;` && rm $&lt; 測試完成以后銷毀 fun local 進程。

npm run integration:test 會啟動若干的測試用例,其中一個測試用例如下:

const request = require('request');

const url = 'http://localhost:8000/2016-08-15/proxy/tz-time/tz-time/';

describe('request url', () => {
   it('without tz', (done) => {
     request(url, (error, response, data) => {
       if (error) {
         fail(error);
       } else {
         const resData = JSON.parse(data);
         expect(resData.statusCode).toBe(200);
         expect(resData.message).toContain('Asia/Shanghai');
       }
       done();
     });
   });
});

端對端測試

端對端測試和集成測試的測試用例非常的類似,區(qū)別在于測試的服務端,端對端測試部署一套真實的環(huán)境,集成測試通過 fun local 本地模擬。

本例中借助 fun deploy --use-ros 部署一套環(huán)境,環(huán)境名稱為 tz-e2e- 前綴帶上時間戳,這樣每次測試都會部署一套新的環(huán)境,不同環(huán)境之間相互不會影響。測試完成再通過 aliyun-cli 工具把 ROS 的 stack 刪除即可。

下面端對端測試的 Makefile 目標:

stack_name := tz-e2e-$(shell date +%s)

e2e-test:
   # deploy e2e 
   bin/deployE2EStack.sh $(stack_name)
   # run test
   npm run e2e:test
   # cleanup
   bin/delRosStack.sh $(stack_name)
  • bin/deployE2EStack.sh $(stack_name) 負責部署一個新的 ROS stack。部署之前需要使用 fun package 構(gòu)建交付物,具體如何構(gòu)建交付物可以參考下一小節(jié)。
  • npm run e2e:test 運行端對端測試
  • bin/delRosStack.sh $(stack_name) 測試完成之后,清理部署的 ROS stack,會釋放掉響應的云資源。

構(gòu)建交付物

fun package 命令可被用于構(gòu)建交付物,fun package 需要指定一個 OSS 的 bucket。fun package 命令會完成如下步驟:

  1. 將代碼編譯打包成 Zip 文件。
  2. 上傳代碼包到 OSS bucket。
  3. 生成新的文件 template.packaged.yml,其中代碼本地地址改為 OSS bucket 地址。

生成的 template.packaged.yml 文件就是最終交付物,可以通過 fun deploy 命名進行部署。

持續(xù)部署

當構(gòu)建環(huán)節(jié)生成了交付物以后,就可以通過 fun deploy 進行部署了。持續(xù)部署需要解決如下兩個問題:

  1. 支持全新部署和升級部署
  2. 一套資源描述支持部署多套,比如 test 環(huán)境、staging 環(huán)境和 production 環(huán)境。

fun deploy 借助于 ROS,可以輕松的解決上述問題。

fun deploy --use-ros --stack-name tz-staging --assume-yes

其中:

  • --use-ros 表示借助于 ROS 進行部署,其工作機制是將 template.yml 推送到 ROS 服務,由 ROS 服務執(zhí)行每個服務的新建和更新操作。如果沒有該參數(shù),fun 就會在本地解析 template.yml,調(diào)用 API 進行資源創(chuàng)建。ROS 有個額外的好處是可以進行部署的回滾,失敗的時候能自動進行回滾。
  • --stack-name 指定一個 stack 的名稱,stack 是 ROS 的概念,可以理解為一套環(huán)境。
  • --assume-yes 用于無人值守模式,跳過確認提示。

注意,此處如果不指定參數(shù) --use-ros ,fun deploy 會采用直接調(diào)用云資源 API 進行部署, 這是 fun deploy 的默認部署方式,雖然也基本實現(xiàn)了冪等部署,但是僅支持部署有限的云資源(FC、OTS、API Gateway等),遠不及 ROS 豐富,而且也沒法做到 ROS 已支持的回滾和一鍵刪除,所以此處不推薦。

以上便是Github和Travis CI的聯(lián)動實現(xiàn)和使用代碼觸發(fā)CI/CD,雖然從篇幅上看很復雜,但是示例代碼非常詳細且容易理解,如果想了解更多相關(guān)內(nèi)容,請關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊。

另外有需要云服務器可以了解下創(chuàng)新互聯(lián)cdcxhl.cn,海內(nèi)外云服務器15元起步,三天無理由+7*72小時售后在線,公司持有idc許可證,提供“云服務器、裸金屬服務器、高防服務器、香港服務器、美國服務器、虛擬主機、免備案服務器”等云主機租用服務以及企業(yè)上云的綜合解決方案,具有“安全穩(wěn)定、簡單易用、服務可用性高、性價比高”等特點與優(yōu)勢,專為企業(yè)上云打造定制,能夠滿足用戶豐富、多元化的應用場景需求。

名稱欄目:Github和TravisCI的聯(lián)動實現(xiàn)和使用代碼觸發(fā)CI/CD-創(chuàng)新互聯(lián)
路徑分享:http://muchs.cn/article18/ejddp.html

成都網(wǎng)站建設公司_創(chuàng)新互聯(lián),為您提供服務器托管、全網(wǎng)營銷推廣標簽優(yōu)化、手機網(wǎng)站建設、電子商務、軟件開發(fā)

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)

成都定制網(wǎng)站建設