+135 410 16684Mon. - Fri. 10:00-22:00

使用 Docker、GitHub Flow、CircleCI、AWS Elastic Beanstalk 與 Slack 來完成持續整合與持續交付的開發流程

使用 Docker、GitHub Flow、CircleCI、AWS Elastic Beanstalk 與 Slack 來完成持續整合與持續交付的開發流程

使用 Docker、GitHub Flow、CircleCI、AWS Elastic Beanstalk 與 Slack 來完成持續整合與持續交付的開發流程

DevOps:持續整合&持續交付(Docker、CircleCI、AWS)

687474703a2f2f332e62702e626c6f6773706f742e636f6d2f2d4b67777732504e5234526f2f5654704f4974746d6452492f41414141414141416b62772f78586c35317a477a6c36512f73313630302f636f7665722e706e6

這篇文章將一步一步介紹如何使用 Docker、GitHub Flow、CircleCI、AWS Elastic Beanstalk 與 Slack 來完成持續整合持續交付的開發流程。

前言

什麼是持續整合&持續交付?

持續整合&持續交付(Continuous Integration & Continous Delivery),簡稱 CI & CD,具體介紹可以參考「山姆鍋對持續整合、持續部署、持續交付的定義」這篇文章。

簡單來說就是盡量減少手動人力,將一些日常工作交給自動化工具。例如:環境建置、單元測試、日誌紀錄、產品部署。

我使用了哪些工具?

看完這篇你可以學到什麼?

  • 瞭解 GiHub 的工作流程(GitHub Flow),利用 Pull Request 以及分支來完成代碼審查(Code Review)與環境配置,例如:開發版(development)、測試版(testing/QA)、上線產品(staging/production)。
  • 使用 Docker,統一開發者、測試人員、以及產品的執行環境。
  • 使用 EB CLI 將應用程式部署到 AWS Elastic Beanstalk 平台上。
  • 使用 CircleCI 將以上工作全部自動化。偵測 GitHub 分支上的程式碼,若有更新則觸發:建置 Docker 環境、單元測試、然後自動部署新版本到 AWS EB。
  • 使用 Slack,讓團隊成員能夠即時接收 GitHub 與 CircleCI 每一項動作的通知。

687474703a2f2f312e62702e626c6f6773706f742e636f6d2f2d61794d50555969704159492f565470505754456c6a58492f41414141414141416b62382f767077352d77722d426a512f73313630302f73657175656e63652d6469616772616d2e706e6

內容大綱

Node.js

687474703a2f2f342e62702e626c6f6773706f742e636f6d2f2d47567335784c4a783937632f56547051765544786244492f41414141414141416b63592f4d706c307775326e41366b2f73313630302f6e6f64652e706e6

安裝:

這篇文章以 Node.js 的應用程式作為範例,其他語言(Ruby on Rails、Python、PHP)也同樣適用此工作流程。

建立新專案

  1. 建立一個專案資料夾(這裡以 hello-ci-workflow 為例):
$ mkdir hello-ci-workflow
$ cd hello-ci-workflow

在本地端執行 Node.js

  1. 初始化 Node.js 的環境,填寫一些資料之後會在目錄下產生一個 package.json 的檔案:
$ npm init
  1. 安裝 Node.js 的 web framework,以 Express 為例:
$ npm install express --save

--save: 寫入 package.json 的 dependencies。

  1. 完成之後,package.json 大概會長這個樣子:
// package.json
{
  "name": "hello-ci-workflow",
  "main": "index.js",
  "dependencies": {
    "express": "^4.12.3"
  },
  "scripts": {
    "start": "node index.js"
  }
}
  1. index.js 裡寫一段簡單的 Hello World! 的程式:
// index.js
var express = require('express');
var app = express();

app.get('/', function (req, res) {
  res.send('Hello World!');
});

var server = app.listen(3000, function () {

  var host = server.address().address;
  var port = server.address().port;

  console.log('Example app listening at http://%s:%s', host, port);

});
  1. 執行 npm startnode index.js
$ npm start
  1. 打開瀏覽器 http://localhost:3000 看結果:

687474703a2f2f312e62702e626c6f6773706f742e636f6d2f2d316f705f565f50574749492f56547055664f50796f67492f41414141414141416b65772f69576453534d2d453648592f73313630302f30312e706e6

在本地端測試 Node.js

  1. 安裝 Node.js 的單元測試,以 Mocha 為例:
$ npm install mocha --save-dev

--save-dev: 寫入 package.json 的 devDependencies,正式上線環境不會被安裝。

// package.json
{
  "name": "hello-ci-workflow",
  "main": "index.js",
  "dependencies": {
    "express": "^4.12.3"
  },
  "devDependencies": {
    "mocha": "^2.2.4"
  },
  "scripts": {
    "start": "node index.js"
  }
}
  1. 根目錄 test 資料夾,並新增一個測試腳本 test.js
$ mkdir test
$ cd test
$ touch test.js
  1. 加入一筆錯誤的測試 assert.equal(1, [1,2,3].indexOf(0))
// test/test.js
var assert = require("assert")
describe('Array', function(){
  describe('#indexOf()', function(){
    it('should return -1 when the value is not present', function(){
      assert.equal(1, [1,2,3].indexOf(0));
    })
  })
})
  1. 執行 mocha 測試:
$ ./node_modules/.bin/mocha


  Array
    #indexOf()
      1) should return -1 when the value is not present


  0 passing (9ms)
  1 failing

結果顯示 1 failing,測試沒通過,因為 [1,2,3].indexOf(0) 回傳的值不等於 -1

  1. test.js 的測試修正:
// test/test.js
assert.equal(-1, [1,2,3].indexOf(0));
  1. 再次執行 mocha 測試:
$ ./node_modules/.bin/mocha


  Array
    #indexOf()
      ✓ should return -1 when the value is not present


  1 passing (6ms)

結果顯示 1 passing,通過測試。

GitHub

687474703a2f2f332e62702e626c6f6773706f742e636f6d2f2d736142616235336e3135772f56547051765149376636492f41414141414141416b63552f46703865346161467938452f73313630302f6769746875622e706e6

安裝:

帳號:

  1. 初始化 git 環境:
$ git init .
  1. 輸入 git status 會顯示目前哪些檔案有過更動:
$ git status
On branch master

Initial commit

Untracked files:
  (use "git add <file>..." to include in what will be committed)

  index.js
  node_modules/
  package.json
  test/
  1. node_modules 加到 .gitignore 黑名單,因為這個資料夾是由 npm install 自動產生的,不需要放到 GitHub 上:
# .gitignore

# Dependency directory
# https://www.npmjs.org/doc/misc/npm-faq.html#should-i-check-my-node_modules-folder-into-git
node_modules
  1. 將更動 commit:
$ git add .
$ git commit -m "first commit"
  1. 打開 GitHub,新增一個 repository:

687474703a2f2f322e62702e626c6f6773706f742e636f6d2f2d2d4a2d36343130534e74342f5654705566423150452d492f41414141414141416b65732f4e5a4476386d436e6661342f73313630302f30322e706e6

  1. 輸入 repository 的名稱,以 hello-ci-workflow 為例:

687474703a2f2f332e62702e626c6f6773706f742e636f6d2f2d4a7973694f3946663435492f56547055664166674532492f41414141414141416b65302f42465947614d5a394d55302f73313630302f30332e706e6

  1. 使用 git remote add 將新創建的 GitHub repository 加入到 remote:
$ git remote add origin https://github.com/<USER_NAME>/hello-ci-workflow.git

<USER_NAME> 改成自己的帳號。

  1. 使用 git push 將程式碼傳到 GitHub:
$ git push -u origin master

成功之後前往 https://github.com/<USER_NAME>/hello-ci-workflow 就可以看到剛才上傳的檔案:

687474703a2f2f332e62702e626c6f6773706f742e636f6d2f2d4c6642586942516b654e632f56547055666c6e683367492f41414141414141416b65342f634b316c703537725a79632f73313630302f30342e706e6

CircleCI

687474703a2f2f322e62702e626c6f6773706f742e636f6d2f2d555466506b66356b5171302f56547051753441425969492f41414141414141416b634d2f4d6a6577393739315a7a672f73313630302f636972636c6563692e706e6

帳號:

加入 GitHub repository

  1. 點選左邊欄的 Add Projects 按鈕:

687474703a2f2f312e62702e626c6f6773706f742e636f6d2f2d37725766746e676c5f53632f56547055663743494b4c492f41414141414141416b66492f67326264753834777a65632f73313630302f30352e706e6

  1. 選擇自己的 GitHub 帳號:

687474703a2f2f332e62702e626c6f6773706f742e636f6d2f2d34376b685743594648766b2f56547055663636374249492f41414141414141416b66412f3230614c6d7a484d6f67512f73313630302f30362e706e6

  1. 搜尋要加入的 GitHub repository,然後點選 Build project 按鈕,以 hello-ci-workflow 為例:

687474703a2f2f332e62702e626c6f6773706f742e636f6d2f2d73444630306c78386361492f565470556e684e6c4739492f41414141414141416b686b2f50425669354952556676452f73313630302f30372e706e6

  1. 完成之後 CircleCI 就會自動執行第一次的建構,不過因為還沒加入測試腳本,所以建構結果會顯示 no test:

687474703a2f2f322e62702e626c6f6773706f742e636f6d2f2d34364c78483678636f744d2f56547055677335734a56492f41414141414141416b664d2f396b3056394869476b35412f73313630302f30382e706e6

在 CircleCI 測試 Node.js

  1. 在專案根目錄底下建立一個 circle.yml,並加入 mocha test:
# circle.yml
machine:
  node:
    version: 0.10

test:
  override:
    - ./node_modules/.bin/mocha
  1. 完成之後將檔案 push 上 GitHub:
$ git add circle.yml
$ git cimmit "add circle.yml"
$ git push
  1. Push 成功之後,CircleCI 會自動觸發建構和測試:

687474703a2f2f322e62702e626c6f6773706f742e636f6d2f2d47674d44483277596f5f672f56547055673877733434492f41414141414141416b66552f7a5431686f346c76546d382f73313630302f30392e706e6

  1. 測試通過,建置成功:

687474703a2f2f312e62702e626c6f6773706f742e636f6d2f2d456c4d57747638537534492f565470556845325f4c4d492f41414141414141416b66592f51346b5a6c3544377172672f73313630302f31302e706e6

代碼審查(Code Review)with GitHub Flow

目前開發中比較常用的 workflow 有 Git flowGitHub flow 兩種,可以參考以下幾篇文章:

Git flow:

GitHub flow:

這裡我們使用 GitHub flow,它的核心精神是:

  • 所有在 master 分支上的程式都一定要是通過測試,可以部署的產品版本。
  • 要開發功能、修復 Bug、做任何事情,都要從 master 開一條新的分支。
  • 隨時 commit 和 push 你的程式碼到 GitHub 上,與大家討論。
  • 功能完成時,使用 pull request 讓大家作 code review。
  • 確認沒問題之後才可以 merge 回 master,並且部屬新版本到線上。

建立一條分支

  1. 為了確保 master 這條主線上的程式碼都是穩定的,所以建議開發者依照不同的功能、建立不同的分支,這裡以 test-github-flow 為例,使用 git branch 新增分支、然後 git checkout 切換分支:
$ git branch test-github-flow
$ git checkout test-github-flow

加入 commits

  1. test.js 裡加入一行錯誤的測試 assert.equal(3, [1,2,3].indexOf(5))
// test/test.js
// ...
assert.equal(3, [1,2,3].indexOf(5));
$ git add test/test.js
$ git commit -m "add a error test case"

新增一個 Pull Request

  1. Push 到 GitHub 的 test-github-flow 分支:
$ git push -u origin test-github-flow
  1. 打開 GitHub 之後,會出現 test-github-flow 分支的 push commits,點選旁邊的 Compare & pull request 按鈕:

687474703a2f2f342e62702e626c6f6773706f742e636f6d2f2d3358664e484e4a485f76382f56547055694f727a456f492f41414141414141416b66302f6a385665765951437944672f73313630302f31332e706e6

  1. 點選之後會進入 Open a pull request 的填寫頁面,選擇想要 merge 的分支、輸入描述之後,點選 Create pull request 按鈕:

687474703a2f2f332e62702e626c6f6773706f742e636f6d2f2d736645574f6e4f665747592f5654705569515a763571492f41414141414141416b66342f65387772416871544736512f73313630302f31342e706e6

檢視&討論你的程式碼

  1. 新增一個 pull request 之後,其他人就會在 GitHub 上出現通知:

687474703a2f2f312e62702e626c6f6773706f742e636f6d2f2d4f393436777849474c696b2f5654705569393557376e492f41414141414141416b67452f454a354543344f677464732f73313630302f31352e706e6

  1. 點進去之後可以看見相關的 commits 與留言,但是下面有一個紅紅大大的叉叉;因為每次 GitHub 只要有新的 push,就會觸發 CircleCI 的自動建置和測試,並且顯示結果在 GitHub 上:

687474703a2f2f332e62702e626c6f6773706f742e636f6d2f2d76337677694a59344759342f565470556a44714c6777492f41414141414141416b67492f57627850704769395069342f73313630302f31382e706e6

  1. 點選叉叉,前往 CircleCI 查看錯誤原因:

687474703a2f2f332e62702e626c6f6773706f742e636f6d2f2d6172664e434532504e6a492f565470556a744b7a7042492f41414141414141416b67512f4a55396f6a63342d5630452f73313630302f31392e706e6

  1. 就會發現剛剛 push 到 test-github-flow 的測試沒通過:

687474703a2f2f342e62702e626c6f6773706f742e636f6d2f2d432d71756474766c6a556b2f565470556872504b6d6c492f41414141414141416b666f2f664c52495566694b615a772f73313630302f31322e706e6

687474703a2f2f312e62702e626c6f6773706f742e636f6d2f2d2d49783939655738646e412f56547055687253714a41492f41414141414141416b666b2f30617048456a33685a30632f73313630302f31312e706e6

回到 GitHub,因為測試沒通過,所以審查者不能讓這筆 pull request 被 merge 回 master。

  1. 找到剛剛 commit 的那段程式碼,留言告知請開發者修正錯誤之後,再重新 commit push 上來:

687474703a2f2f332e62702e626c6f6773706f742e636f6d2f2d4d466a385073454a2d68672f565470556a3644386c78492f41414141414141416b67592f347a644a76316a417945492f73313630302f32312e706e6

687474703a2f2f332e62702e626c6f6773706f742e636f6d2f2d7253585f7a6d4c3542386b2f565470556b595f343662492f41414141414141416b67632f6632303541376a445043452f73313630302f32322e706e6

687474703a2f2f322e62702e626c6f6773706f742e636f6d2f2d7a5154654271794e446d552f565470556b713566424b492f41414141414141416b676b2f36653653435453784474672f73313630302f32332e706e6

  1. 修正 test.js 的測試腳本:
// test/test.js
// ...
assert.equal(-1, [1,2,3].indexOf(5));
  1. 再次 commit & push:
$ git add test/test.js
$ git commit -m "fix error test case"
$ git push
  1. 回到 GitHub 的 pull request 頁面,可以看到最新一筆的 commit 成功通過 CircleCI 的測試了:

687474703a2f2f342e62702e626c6f6773706f742e636f6d2f2d773856576934434d51424d2f565470556c5164655878492f41414141414141416b67342f65794f736b3254314e68302f73313630302f32362e706e6

687474703a2f2f322e62702e626c6f6773706f742e636f6d2f2d4b2d71506431356d7049772f565470556b324b6e7356492f41414141414141416b676f2f33744c6b74485a494778772f73313630302f32342e706e6

687474703a2f2f312e62702e626c6f6773706f742e636f6d2f2d7874335859616c446d6a512f565470556c4a61797749492f41414141414141416b67302f6c306f44385969454b5a592f73313630302f32352e706e6

Merge&部署

  1. 審查之後,確定沒有問題,就可以點選 Merge pull request 的按鈕,將 test-github-flow 的程式碼 merge 回主線 master

687474703a2f2f342e62702e626c6f6773706f742e636f6d2f2d695a7353466776494b58772f565470556c796e715877492f41414141414141416b68412f4f73723949657778657a492f73313630302f32372e706e6

687474703a2f2f312e62702e626c6f6773706f742e636f6d2f2d70326731666a5a66416c492f565470556d5070523652492f41414141414141416b68452f3063642d506b63544c30592f73313630302f32382e706e6

687474703a2f2f312e62702e626c6f6773706f742e636f6d2f2d726a7a37474a7a665a6c412f565470556d6149617a68492f41414141414141416b684d2f744f655937536f325964732f73313630302f32392e706e6

Docker

687474703a2f2f322e62702e626c6f6773706f742e636f6d2f2d7a426a6f4a4c4c6a7255302f56547051753752433841492f41414141414141416b63492f6b324e45733437595f4d492f73313630302f646f636b65722e706e6

安裝:

什麼是 Docker?為什麼要用它?

因為 Docker 最近很火,所以網路上不缺關於介紹它的文章,原諒我這裡只稍微提一下:

以往開發人員面對開發環境不同的問題,常常出現「明明在我的電腦上可以跑」的囧境,所以為了解決這類問題,通常會使用虛擬機器(VM)搭配一些工具(VagrantChef)來協助統一開發人員、測試人員、上線產品的執行環境。

687474703a2f2f332e62702e626c6f6773706f742e636f6d2f2d3564735356592d492d4e512f5654706263466c47564e492f41414141414141416b6b732f4546596f546a6774786d512f73313630302f766d2d76732d646f636b65722e706e6

Docker 也是類似的解決方案,不同於 VM 的是,Docker 運行起來更輕巧、可攜度更高。配置好一份設定之後,就可以讓大家馬上進入開發狀況,減少不必要的環境問題,提升效率。

在 Docker 執行 Node.js

  1. 在專案根目錄底下建立一個 Dockerfile
# Dockerfile

# 從 [Docker Hub](https://hub.docker.com/) 安裝 Node.js image。
FROM node:0.10

# 設定 container 的預設目錄位置
WORKDIR /hello-ci-workflow

# 將專案根目錄的檔案加入至 container
# 安裝 npm package
ADD . /hello-ci-workflow
RUN npm install

# 開放 container 的 3000 port
EXPOSE 3000
CMD npm start
  1. 使用 docker build 建構您的 image:
$ docker build -t hello-ci-workflow .

-t hello-ci-workflow 是 image 名稱。

  1. 使用 docker run 執行您的 image:
$ docker run -p 3000:3000 -d hello-ci-workflow

-d 在背景執行 node,可以使用 docker logs 看執行結果。

  1. 打開瀏覽器 http://localhost:3000 看結果:

687474703a2f2f312e62702e626c6f6773706f742e636f6d2f2d316f705f565f50574749492f56547055664f50796f67492f41414141414141416b65772f69576453534d2d453648592f73313630302f30312e706e67

其實每一次都要 buildrun 還蠻麻煩的,推薦可以試試 Docker Compose,用起來有點像 Vagrant

在 CircleCI 測試 Docker

  1. 修改 circle.yml
# circle.yml
machine:
  # 環境改成 docker
  services:
    - docker

dependencies:
  override:
    # 建構方式使用 docker build
    - docker build -t hello-ci-workflow .

test:
  override:
    - ./node_modules/.bin/mocha
    # 使用 curl 測試 docker 是否有順利執行 node
    - docker run -d -p 3000:3000 hello-ci-workflow; sleep 10
    - curl --retry 10 --retry-delay 5 -v http://localhost:3000
  1. Push 更新到 GitHub:
$ git add Dockerfile circle.yml
$ git commit -m "add Docker"
$ git push
  1. 查看 CircleCI 建構&測試結果:

687474703a2f2f342e62702e626c6f6773706f742e636f6d2f2d694264624c33546b4d624d2f565470556d6d4e4a6d31492f41414141414141416b68552f7473514d642d696b61776f2f73313630302f33302e706e6

AWS Elastic Beanstalk

687474703a2f2f342e62702e626c6f6773706f742e636f6d2f2d784375514a6233395a32732f56547054317871345a5a492f41414141414141416b656b2f7452452d545f306d7950452f73313630302f6265616e7374616c6b2e706e6

帳號:

安裝:

最後要將程式上線啦!現在 PaaS 雲端平台的選擇非常多(HerokuGoogle App EngineAzureOpenShiftLinode),這裡我選擇 Amazon 推出的 Elastic Beanstalk 當作範例,以下是它的特色:

  • 支援的開發環境多(Java、.NET、PHP、Node.js、Python、Ruby、GO),重點是有支援 Docker!
  • 只需要上傳程式碼,Elastic Beanstalk 即可幫你完成從容量配置、負載均衡(load balancing)、自動擴展(auto scaling)到應用程式的運行狀況監控的部署。

687474703a2f2f322e62702e626c6f6773706f742e636f6d2f2d455658386f4c4c753958772f565470634c776f385776492f41414141414141416b6b302f487a7555433277365562592f73313630302f6177732d65622e706e6

  1. 初始化 EB 環境:
$ eb init -p docker

-p 可以指定 EB 的應用平台,例如 php 之類;這裡使用 docker。

該命令將提示您配置各種設置。 按 Enter 鍵接受預設值。

如果你已經存有一組 AWS EB 權限的憑證,該命令會自動使用它。 否則,它會提示您輸入 Access key IDSecret access key,必須前往 AWS IAM 建立一組。

  1. 初始化成功之後,可以使用 eb create 快速建立各種不同的環境,例如:development, staging, production;這裡我們以 env-development 為例:
$ eb create env-development

等待 Elastic Beanstalk 完成環境的建立。 當它完成之後,您的應用已經備有負載均衡(load-balancing)與自動擴展(autoscaling)的功能了。

687474703a2f2f312e62702e626c6f6773706f742e636f6d2f2d555743795f7342635776342f565470556d3276355946492f41414141414141416b68632f727362472d4d5f4958466f2f73313630302f33312e706e6

  1. 使用 eb open 前往目前版本的執行結果:
$ eb open env-development

687474703a2f2f322e62702e626c6f6773706f742e636f6d2f2d334631586d454e575230732f565470556e587a4e5835492f41414141414141416b68672f4b745671356a6e546c31512f73313630302f33322e706e6

在本地端部署 AWS

  1. 稍微修改 index.js
// index.js
// ...
app.get('/', function (req, res) {
  res.send('Hello env-development!');
});
// ...
  1. 執行 eb deploy 部署新版本到 AWS Elastic Beanstalk:
$ eb deploy env-development

687474703a2f2f332e62702e626c6f6773706f742e636f6d2f2d4f42364d644d6b6c7072672f5654705576712d597963492f41414141414141416b6b4d2f52426973343739336274632f73313630302f33342e706e6

  1. 部署完成之後,執行 eb open 打開網頁:
$ eb open env-development

687474703a2f2f342e62702e626c6f6773706f742e636f6d2f2d69636e30397167564961512f565470556e7a696a7364492f41414141414141416b68732f664b5541305048435a7a672f73313630302f33332e706e6

env-development 上的應用程式更新完成。

在 CircleCI 部署 AWS

  1. git checkout 將分支切換回主線 master:
$ git checkout master
  1. eb create 新增一組新的環境,作為產品上線用,命名為 env-production
$ eb create env-production
$ eb open env-production

687474703a2f2f322e62702e626c6f6773706f742e636f6d2f2d636e4f4e667977414d54512f565470556f664a36656a492f41414141414141416b68772f6d304173684841356e524d2f73313630302f33352e706e6

這樣就成功啟動第二組機器了,目前我們有 env-developmentenv-production 兩組環境。

前往 AWS IAM 新增一組帳號給 CircleCI 使用:

  1. Dashboard > Users
  2. Create New Users
  3. Enter User Names: CircleCI > Create
  4. Download Credentials
  5. Dashboard > Users > CircleCI
  6. Attach Pollcy
  7. AWSElasticBeanstalkFullAccess > Attach Pollcy

前往 CircleCI,設定您的 AWS 權限:

  1. Project Settings
  2. Permissions > AWS Permissions
  3. 打開剛才下載的 credentials.csv,輸入 Access Key ID & Secret Access Key
  4. Save AWS keys
  5. .elasticbeanstalk 目錄底下,建立 config.global.yml
# .elasticbeanstalk/config.global.yml
global:
  application_name: hello-ci-workflow
  default_region: us-west-2 # EB 所在的 region,預設是 us-west-2
  1. 修改 circle.yml
# circle.yml
machine:
  # 安裝 eb 需要 python
  python:
    version: 2.7
  services:
    - docker

dependencies:
  pre:
    # 安裝 eb
    - sudo pip install awsebcli
  override:
    - docker build -t hello-ci-workflow .

test:
  override:
    - npm test
    - docker run -d -p 3000:3000 hello-ci-workflow; sleep 10
    - curl --retry 10 --retry-delay 5 -v http://localhost:3000

# 新增一筆部署腳本
deployment:
  production:
    branch: master
    commands:
      - eb deploy env-production

這樣就能在 GitHub 的 master 支線有更新時,觸發 CircleCI 的自動建置、測試、然後部署。

  1. 接下來馬上來試試看流程,修改 index.js
// index.js
// ...
app.get('/', function (req, res) {
  res.send('Hello env-production!');
});
// ...
  1. Commit & Push:
$ git add .
$ git cimmit "test deploy production"
$ git push
  1. 前往 CircleCI 看結果:

687474703a2f2f332e62702e626c6f6773706f742e636f6d2f2d333156596e4b726e5a5f672f565470556f6879575442492f41414141414141416b68342f70696f43374162314765732f73313630302f33362e706e6

  1. 部署成功,eb open 打開瀏覽器來看看結果:
$ eb open env-production

687474703a2f2f322e62702e626c6f6773706f742e636f6d2f2d456f705179646e757872552f565470556f2d72597873492f41414141414141416b68382f584137736b506b744151412f73313630302f33372e706e6

Slack

687474703a2f2f342e62702e626c6f6773706f742e636f6d2f2d61367938543547665330492f5654705176365370615f492f41414141414141416b63672f567242693661527a366a632f73313630302f736c61636b2e706e6

帳號:

到這邊其實已經差不多結束了,最後來講講 Slack 吧。

Slack 是一款給團隊使用的即時溝通工具,類似的產品還有 GitterHipChat

至於跟 Skype、Lync 這些軟體有什麼不一樣的地方呢?

它們整合了許多開發工具(GitHub、CircleCI)的服務,例如 GitHub 有新的 push、pull request、issue;CircleCI 的單元測試沒有通過之類的通知,會即時出現在你的團隊的 Slack 上面,既然我們已經將大部分的工作自動化,勢必需要讓相關人員知道這些工具發生了哪些事情,所以使用 Slack 是必要的。

  1. 登入 Slack 頁面
  2. 點選 Configure Integrations > CircleCI

687474703a2f2f312e62702e626c6f6773706f742e636f6d2f2d64555f5549556e757231412f56547055705245614c4c492f41414141414141416b69492f67613447547853786b36512f73313630302f33382e706e6

687474703a2f2f312e62702e626c6f6773706f742e636f6d2f2d3148714b4a69353056514d2f565470557056335f504d492f41414141414141416b694d2f665a706d35567a48396f4d2f73313630302f33392e706e6

  1. 選擇要接收 CircleCI 通知的 channel
  2. 點選 Add CircleCI Integration 按鈕
  3. 複製畫面上的 webhook URL

687474703a2f2f322e62702e626c6f6773706f742e636f6d2f2d764f74756f31593048346b2f5654705571466e7a5177492f41414141414141416b69552f7478366739686f4a6778732f73313630302f34302e706e6

687474703a2f2f322e62702e626c6f6773706f742e636f6d2f2d63567852614c2d76434f672f5654705572666e4a3354492f41414141414141416b69772f5a796f324762307a79306f2f73313630302f34342e706e6

  1. 返回 CircleCI
  2. 點選 Project settings > Chat Notifications
  3. 貼上將複製的 Webhook URL > Save

687474703a2f2f322e62702e626c6f6773706f742e636f6d2f2d4d34304773505f696b39512f56547055714f41516c67492f41414141414141416b69592f31556f54417573534279342f73313630302f34312e706e6

687474703a2f2f342e62702e626c6f6773706f742e636f6d2f2d70416e74524e30694252632f565470557171504a6479492f41414141414141416b69732f496e517278586c4a436d302f73313630302f34322e706e6

687474703a2f2f322e62702e626c6f6773706f742e636f6d2f2d76337161332d786b3341512f565470557139364f6952492f41414141414141416b696b2f635139436759396c3058772f73313630302f34332e706e6

  1. 類似的步驟,將 GitHub 的通知加入 Slack:

687474703a2f2f342e62702e626c6f6773706f742e636f6d2f2d5a426d55686a595535586f2f565470557277546e3758492f41414141414141416b6a452f6b617837544264465668412f73313630302f34352e706e6

687474703a2f2f332e62702e626c6f6773706f742e636f6d2f2d6f79475a51765442484c382f56547055723879697935492f41414141414141416b69382f6d595f525561547266706b2f73313630302f34362e706e6

687474703a2f2f342e62702e626c6f6773706f742e636f6d2f2d706a6d686a6347656268512f5654705573556f547877492f41414141414141416b6a492f30516f6671664e6b5566342f73313630302f34372e706e6

687474703a2f2f312e62702e626c6f6773706f742e636f6d2f2d315451324558564556764d2f56547055733254327576492f41414141414141416b6a512f526e3561567359665553412f73313630302f34382e706e6

  1. 測試 Slack 通知,是否能夠順利運作,新增一條 test-slack 分支:
$ git branch test-slack
$ git checkout test-slack
  1. 修改 index.js
// index.js
// ...
app.get('/', function (req, res) {
  res.send('Hello Slack!');
});
// ...
  1. Commit & Push:
$ git add index.js
$ git commit -m "index.js: update to test slack"
$ git push -u origin test-slack
  1. CircleCI 通過測試,開啟一個 Pull Request
  2. test-slack merge 回 master,觸發 CircleCI 自動部署

687474703a2f2f342e62702e626c6f6773706f742e636f6d2f2d795a376f566f6854426f452f56547055745a6936506e492f41414141414141416b6a672f47345f4464567465444b672f73313630302f35302e706e6

687474703a2f2f312e62702e626c6f6773706f742e636f6d2f2d43376b5051362d5a376b6f2f56547055743855494d46492f41414141414141416b6a6f2f4a66724a4232554c45486f2f73313630302f35312e706e6

That’s it! On your next build, you’ll start seeing CircleCI build notifications in your Slack chatroom.

結束!可以看見 Slack channel 會顯示每一個步驟的通知過程:

687474703a2f2f332e62702e626c6f6773706f742e636f6d2f2d4e71796a57466f317245452f56547055744578583343492f41414141414141416b6a592f47537943665037777735732f73313630302f34392e706e6

eb open 打開瀏覽器查看結果,成功自動部署新版本:

$ eb open env-production

687474703a2f2f312e62702e626c6f6773706f742e636f6d2f2d654a7367563843654430342f565470557544466c7237492f41414141414141416b6a732f666131785759656b7849732f73313630302f35322e706e6

結語

「書山有路勤為徑,學海無涯苦作舟。」——韓愈

DevOps 的開發流程與工具每天都在不斷推陳出新,請站在巨人的肩膀上、保持一顆「活到老、學到老」的心。

我將這個範例的程式碼放在 GitHub 上,有興趣的人可以參考看看。

文章若有需要改進的地方,還請不吝指教,感激不盡。

參考