窮人的持續集成與持續交付(下)

jopen 8年前發布 | 12K 次閱讀 持續交付 持續集成 項目構建

客戶端程序的的持續交付

上篇文章介紹了如何使用一些免費的服務來實現服務器端API的持續集成、持續交付環境的搭建。有了服務端,自然需要有消費者,在本文中我們將使用另外一個工具來實現純前端的站點的部署。

其中包括:

  • 持續集成(單元測試,集成測試等)
  • 持續部署/持續交付
  • 靜態站點托管

除此之外,我們還會涉及到:

我們的應用最后看起來是這樣子的。

技術選型

我們在本文中,將采取另外一套免費服務來完成環境的搭建

Snap CI 是一個非常易于使用的持續交付環境,由于很多關于持續集成,持續交付的概念和實踐都跟 ThoughtWorks 有關,所以這個產品對于構建,流水線,部署等等的支持也都做的非常好。

S3 是亞馬遜的云存儲平臺,我們可以將靜態資源完全托管在其上。 S3 的另一個好處是它可以將你的文件變成一個Web Site,比如你的目錄中有 index.html ,這個文件就可以作為你的站點首頁被其他人訪問。這個對于我們這個前后端分離項目來說非常有用,我們的 css , js , font 文件,還有入口文件 index.html 都可以托管于其上。

實例

在本文的例子中,我們將定義3個 stage 。 Snap CI 將一次發布分為若干個 stage ,每個 stage 只做一件事情,如果一個 stage 失敗了,后邊的就不會接著執行。

我們的3個 stage 分別為:

  1. 單元測試
  2. 集成測試
  3. 部署

準備工作

bookmarks-frontend 是一個純前端的應用,它會消費后端提供的API,但是其實它并不知道(也不應該知道)后端的API部署在什么地方:

$(function() {
  var feeds = $.get(config.backend+'/api/feeds');
  var favorite = $.get(config.backend+'/api/fav-feeds/1');

  $.when(feeds, favorite).then(function(feeds, favorite) {
      //...
  });
});

由于我們在本地開發時,需要 backend 指向本地的服務器,而發布之后,則希望它指向上一篇文章中提到的服務器,因此我們需要編寫一點構建腳本來完成這件事兒:

var backend = 'http://quiet-atoll-8237.herokuapp.com';

gulp.task('prepareConfig', function() {
    gulp.src(['assets/templates/config.js'])
    .pipe(replace(/#backend#/g, 'http://localhost:8100'))
    .pipe(gulp.dest('assets/script/'));
});

gulp.task('prepareRelease', function() {
    gulp.src(['assets/templates/config.js'])
    .pipe(replace(/#backend#/g, backend))
    .pipe(gulp.dest('assets/script/'));
});

我們定義了兩個 gulp 的task,本地開發時,使用 prepareConfig ,要發布時,使用 prepareRelease ,然后定義一個簡單的模板文件 config.js :

module.exports = {
  backend: '#backend#'
}

然后可以很簡單的包裝一下,方便本地開發和發布:

gulp.task('dev', ['prepareConfig', 'browserify', 'concatcss']);
gulp.task('build', ['prepareConfig', 'script', 'css']);
gulp.task('release', ['prepareRelease', 'script', 'css']);

這樣,我們在本地開發時,只需要簡單的執行:

$ gulp

即可。而在發布階段,只需要執行:

$ gulp release

單元測試

我們在 Snap CI 上將 github 上的代碼庫關聯起來,然后添加一個名叫 unit-test 的 stage ,指定這個 stage 對應的命令為:

npm install
gulp

這樣,每當我們有新的提交之后, Snap CI 都會拿到新代碼,并執行上述命令,如果執行成功,則本地構建成功。

集成測試

由于采取的是 前后端分離 的策略,我們的應用可以完全獨立與后端進行開發,因此我們設置了一個 fake server ,具體細節可以參考我之前的博客,也可以看源碼。不過這里我們要為集成測試編寫一個腳本,并在 Snap CI 上執行。

#!/bin/bash

export PORT=8100
bundle install

# launch the application
echo "launch the application"
ruby app.rb 2>&1 &
PID=$!

# wait for it to start up
sleep 3

# run the rspec tests and record the status
rspec
RES=$?

# terminate after rspec
echo "terminate the application"
kill -9 $PID

# now we know whether the rspec success or not
exit $RES

這個腳本中,首先安裝所有的 gems ,然后啟動 fake server 并將這個server放置在后臺運行,然后執行 rspec 。當 rspec 測試執行完成之后,我們終止服務進行,然后返回結果狀態碼。

這里使用了 capybara 和 poltergeist 來做UI測試, capybara 會驅動 phantomjs 來在內存中運行瀏覽器,并執行定義好的 UI 測試,比如此處,我們的UI測試:

require 'spec_helper'

describe 'Feeds List Page' do
  let(:list_page) {FeedListPage.new}

  before do
      list_page.load
  end

  it 'user can see a banner and some feeds' do
      expect(list_page).to have_banner
      expect(list_page).to have_feeds
  end

  ##...
end

部署

首先需要在 S3 上創建一個 bucket ,命名為 bookmarks-frontend 。然后為其設置 static website hosting ,這時候 AWS 會assign一個新的域名給你,比如 http://bookmarks-frontend.s3-website-us-west-2.amazonaws.com/ 。

然后你需要將這個 bucket 設置成 public ,這樣其他人才可以訪問你的 bucket 。

有了這個之后,我們來編寫一個小腳本,這個腳本可以將本地的文件上傳至S3。

#!/bin/bash

# install gulp and its dependencies
npm install

# package stuff, and point the server to the right place
gulp release

# upload the whold folder
aws s3 cp public/ s3://bookmarks-frontend \
  --recursive \
  --region us-west-2 \
  --acl public-read

aws 命令是 aws command line 提供的,另外我們需要在環境變量中設置AWS提供給你的token:

AWS_ACCESS_KEY_ID=xxxxxxxxxx
AWS_SECRET_ACCESS_KEY=xxxxxxxxxx

然后我們就可以將本地的 public 目錄遞歸的上傳到S3的對應目錄了!

完整的代碼可以在 此處下載

總結

我們前端的持續交付也介紹完了。現在前后端應用完全獨立,發布也互不影響。不論是服務器端新增加了API,還是添加了新數據,客戶端的發布都不受影響;同樣,修改樣式,添加新的 JavaScript 也完全不會影響后端。更重要的是,所有的發布都是一鍵式的,開發者只需要一個 git push 就可以享受這些免費服務提供的自動構建,自動化測試以及自動部署的功能。

來自: http://icodeit.org/2016/01/a-poor-mans-cd-part2/

 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!