<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>服务器安全维护工作室 &#187; AWS Elastic Beanstalk 與 Slack 來完成持續整合與持續交付的開發流程</title>
	<atom:link href="https://www.fuwuqiok.com/tag/aws-elastic-beanstalk-%e8%88%87-slack-%e4%be%86%e5%ae%8c%e6%88%90%e6%8c%81%e7%ba%8c%e6%95%b4%e5%90%88%e8%88%87%e6%8c%81%e7%ba%8c%e4%ba%a4%e4%bb%98%e7%9a%84%e9%96%8b%e7%99%bc%e6%b5%81%e7%a8%8b/feed/" rel="self" type="application/rss+xml" />
	<link>https://www.fuwuqiok.com</link>
	<description></description>
	<lastBuildDate>Sun, 01 Mar 2020 07:28:40 +0000</lastBuildDate>
	<language>zh-CN</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>https://wordpress.org/?v=4.2.26</generator>
	<item>
		<title>使用 Docker、GitHub Flow、CircleCI、AWS Elastic Beanstalk 與 Slack 來完成持續整合與持續交付的開發流程</title>
		<link>https://www.fuwuqiok.com/%e4%bd%bf%e7%94%a8-docker%e3%80%81github-flow%e3%80%81circleci%e3%80%81aws-elastic-beanstalk-%e8%88%87-slack-%e4%be%86%e5%ae%8c%e6%88%90%e6%8c%81%e7%ba%8c%e6%95%b4%e5%90%88%e8%88%87%e6%8c%81%e7%ba%8c/</link>
		<comments>https://www.fuwuqiok.com/%e4%bd%bf%e7%94%a8-docker%e3%80%81github-flow%e3%80%81circleci%e3%80%81aws-elastic-beanstalk-%e8%88%87-slack-%e4%be%86%e5%ae%8c%e6%88%90%e6%8c%81%e7%ba%8c%e6%95%b4%e5%90%88%e8%88%87%e6%8c%81%e7%ba%8c/#comments</comments>
		<pubDate>Tue, 01 Mar 2016 14:00:51 +0000</pubDate>
		<dc:creator><![CDATA[admin]]></dc:creator>
				<category><![CDATA[linux代维]]></category>
		<category><![CDATA[linux服务器代维护]]></category>
		<category><![CDATA[linux服务器维护]]></category>
		<category><![CDATA[linux系统代维]]></category>
		<category><![CDATA[代维]]></category>
		<category><![CDATA[服务器代维]]></category>
		<category><![CDATA[服务器运维]]></category>
		<category><![CDATA[AWS Elastic Beanstalk 與 Slack 來完成持續整合與持續交付的開發流程]]></category>
		<category><![CDATA[CircleCI]]></category>
		<category><![CDATA[GitHub Flow]]></category>
		<category><![CDATA[使用 Docker]]></category>

		<guid isPermaLink="false">https://www.fuwuqiok.com/?p=2972</guid>
		<description><![CDATA[<p>DevOps：持續整合＆持續交付（Docker、CircleCI、AWS） 這篇文章將一步一步介紹如何使用 D [&#8230;]</p>
<p><a rel="nofollow" href="https://www.fuwuqiok.com/%e4%bd%bf%e7%94%a8-docker%e3%80%81github-flow%e3%80%81circleci%e3%80%81aws-elastic-beanstalk-%e8%88%87-slack-%e4%be%86%e5%ae%8c%e6%88%90%e6%8c%81%e7%ba%8c%e6%95%b4%e5%90%88%e8%88%87%e6%8c%81%e7%ba%8c/">使用 Docker、GitHub Flow、CircleCI、AWS Elastic Beanstalk 與 Slack 來完成持續整合與持續交付的開發流程</a>，首发于<a rel="nofollow" href="https://www.fuwuqiok.com">服务器安全维护工作室</a>。</p>
]]></description>
				<content:encoded><![CDATA[<h1>DevOps：持續整合＆持續交付（Docker、CircleCI、AWS）</h1>
<p><a href="https://www.fuwuqiok.com/wp-content/uploads/2016/03/687474703a2f2f332e62702e626c6f6773706f742e636f6d2f2d4b67777732504e5234526f2f5654704f4974746d6452492f41414141414141416b62772f78586c35317a477a6c36512f73313630302f636f7665722e706e67"><img class="attachment-medium" src="https://www.fuwuqiok.com/wp-content/uploads/2016/03/687474703a2f2f332e62702e626c6f6773706f742e636f6d2f2d4b67777732504e5234526f2f5654704f4974746d6452492f41414141414141416b62772f78586c35317a477a6c36512f73313630302f636f7665722e706e67" alt="687474703a2f2f332e62702e626c6f6773706f742e636f6d2f2d4b67777732504e5234526f2f5654704f4974746d6452492f41414141414141416b62772f78586c35317a477a6c36512f73313630302f636f7665722e706e6" width="800" height="375" /></a></p>
<p>這篇文章將一步一步介紹如何使用 Docker、GitHub Flow、CircleCI、AWS Elastic Beanstalk 與 Slack 來完成<strong>持續整合</strong>與<strong>持續交付</strong>的開發流程。</p>
<h2><a id="user-content-前言" class="anchor" href="https://github.com/zeus911/hello-ci-workflow#%E5%89%8D%E8%A8%80"></a>前言</h2>
<h3><a id="user-content-什麼是持續整合持續交付" class="anchor" href="https://github.com/zeus911/hello-ci-workflow#%E4%BB%80%E9%BA%BC%E6%98%AF%E6%8C%81%E7%BA%8C%E6%95%B4%E5%90%88%E6%8C%81%E7%BA%8C%E4%BA%A4%E4%BB%98"></a>什麼是持續整合＆持續交付？</h3>
<p>持續整合＆持續交付（Continuous Integration &amp; Continous Delivery），簡稱 CI &amp; CD，具體介紹可以參考「<a href="http://blog.eavatar.com/post/2013/10/continuous-integration-deployment-delivery/">山姆鍋對持續整合、持續部署、持續交付的定義</a>」這篇文章。</p>
<p>簡單來說就是盡量減少手動人力，將一些日常工作交給自動化工具。例如：環境建置、單元測試、日誌紀錄、產品部署。</p>
<h3><a id="user-content-我使用了哪些工具" class="anchor" href="https://github.com/zeus911/hello-ci-workflow#%E6%88%91%E4%BD%BF%E7%94%A8%E4%BA%86%E5%93%AA%E4%BA%9B%E5%B7%A5%E5%85%B7"></a>我使用了哪些工具？</h3>
<ul>
<li><a href="http://git-scm.com/">Git</a> &#8211; 版本管理</li>
<li><a href="https://github.com/">GitHub</a> &#8211; 程式碼託管、審查</li>
<li><a href="https://circleci.com/">CircleCI</a> &#8211; 自動化建置、測試、部署</li>
<li><a href="https://www.docker.com/">Docker</a> &#8211; 可攜式、輕量級的執行環境</li>
<li><a href="https://aws.amazon.com/elasticbeanstalk/">AWS Elastic Beanstalk</a> &#8211; 雲端平台</li>
<li><a href="https://slack.com/">Slack</a> &#8211; 團隊溝通、日誌、通知</li>
</ul>
<h3><a id="user-content-看完這篇你可以學到什麼" class="anchor" href="https://github.com/zeus911/hello-ci-workflow#%E7%9C%8B%E5%AE%8C%E9%80%99%E7%AF%87%E4%BD%A0%E5%8F%AF%E4%BB%A5%E5%AD%B8%E5%88%B0%E4%BB%80%E9%BA%BC"></a>看完這篇你可以學到什麼？</h3>
<ul>
<li>瞭解 GiHub 的工作流程（<a href="https://guides.github.com/introduction/flow/">GitHub Flow</a>），利用 <strong>Pull Request</strong> 以及<strong>分支</strong>來完成<strong>代碼審查</strong>（Code Review）與<strong>環境配置</strong>，例如：開發版（development）、測試版（testing/QA）、上線產品（staging/production）。</li>
<li>使用 Docker，統一開發者、測試人員、以及產品的執行環境。</li>
<li>使用 EB CLI 將應用程式部署到 AWS Elastic Beanstalk 平台上。</li>
<li>使用 CircleCI 將以上工作全部自動化。偵測 GitHub 分支上的程式碼，若有更新則觸發：建置 Docker 環境、單元測試、然後自動部署新版本到 AWS EB。</li>
<li>使用 Slack，讓團隊成員能夠即時接收 GitHub 與 CircleCI 每一項動作的通知。</li>
</ul>
<p><a href="https://www.fuwuqiok.com/wp-content/uploads/2016/03/687474703a2f2f312e62702e626c6f6773706f742e636f6d2f2d61794d50555969704159492f565470505754456c6a58492f41414141414141416b62382f767077352d77722d426a512f73313630302f73657175656e63652d6469616772616d2e706e67"><img class="attachment-medium" src="https://www.fuwuqiok.com/wp-content/uploads/2016/03/687474703a2f2f312e62702e626c6f6773706f742e636f6d2f2d61794d50555969704159492f565470505754456c6a58492f41414141414141416b62382f767077352d77722d426a512f73313630302f73657175656e63652d6469616772616d2e706e67" alt="687474703a2f2f312e62702e626c6f6773706f742e636f6d2f2d61794d50555969704159492f565470505754456c6a58492f41414141414141416b62382f767077352d77722d426a512f73313630302f73657175656e63652d6469616772616d2e706e6" width="577" height="500" /></a></p>
<h2><a id="user-content-內容大綱" class="anchor" href="https://github.com/zeus911/hello-ci-workflow#%E5%85%A7%E5%AE%B9%E5%A4%A7%E7%B6%B1"></a>內容大綱</h2>
<ul>
<li><a href="https://github.com/zeus911/hello-ci-workflow#node.js">Node.js</a>
<ul>
<li>在本地端執行 Node.js</li>
<li>在本地端測試 Node.js</li>
</ul>
</li>
<li><a href="https://github.com/zeus911/hello-ci-workflow#github">GitHub</a></li>
<li><a href="https://github.com/zeus911/hello-ci-workflow#circleci">CircleCI</a>
<ul>
<li>在 CircleCI 測試 Node.js</li>
</ul>
</li>
<li><a href="https://github.com/zeus911/hello-ci-workflow#code-review-with-github-flow">Code Review with GitHub Flow</a></li>
<li><a href="https://github.com/zeus911/hello-ci-workflow#docker">Docker</a>
<ul>
<li>在 Docker 執行 Node.js</li>
<li>在 CircleCI 測試 Docker</li>
</ul>
</li>
<li><a href="https://github.com/zeus911/hello-ci-workflow#aws-elastic-beanstalk">AWS Elastic Beanstalk</a>
<ul>
<li>在本地端部署 AWS</li>
<li>在 CircleCI 部署 AWS</li>
</ul>
</li>
<li><a href="https://github.com/zeus911/hello-ci-workflow#slack">Slack</a></li>
</ul>
<h2><a id="user-content-nodejs" class="anchor" href="https://github.com/zeus911/hello-ci-workflow#nodejs"></a>Node.js</h2>
<p><a href="https://www.fuwuqiok.com/wp-content/uploads/2016/03/687474703a2f2f342e62702e626c6f6773706f742e636f6d2f2d47567335784c4a783937632f56547051765544786244492f41414141414141416b63592f4d706c307775326e41366b2f73313630302f6e6f64652e706e67"><img class="attachment-medium" src="https://www.fuwuqiok.com/wp-content/uploads/2016/03/687474703a2f2f342e62702e626c6f6773706f742e636f6d2f2d47567335784c4a783937632f56547051765544786244492f41414141414141416b63592f4d706c307775326e41366b2f73313630302f6e6f64652e706e67" alt="687474703a2f2f342e62702e626c6f6773706f742e636f6d2f2d47567335784c4a783937632f56547051765544786244492f41414141414141416b63592f4d706c307775326e41366b2f73313630302f6e6f64652e706e6" width="296" height="80" /></a></p>
<blockquote><p>安裝：</p>
<ul>
<li><a href="https://nodejs.org/">node</a>: 0.10</li>
</ul>
</blockquote>
<p>這篇文章以 Node.js 的應用程式作為範例，其他語言（Ruby on Rails、Python、PHP）也同樣適用此工作流程。</p>
<h3><a id="user-content-建立新專案" class="anchor" href="https://github.com/zeus911/hello-ci-workflow#%E5%BB%BA%E7%AB%8B%E6%96%B0%E5%B0%88%E6%A1%88"></a>建立新專案</h3>
<ol>
<li>建立一個專案資料夾（這裡以 <code>hello-ci-workflow</code> 為例）：</li>
</ol>
<div class="highlight highlight-source-shell">
<pre>$ mkdir hello-ci-workflow
$ <span class="pl-c1">cd</span> hello-ci-workflow</pre>
</div>
<h3><a id="user-content-在本地端執行-nodejs" class="anchor" href="https://github.com/zeus911/hello-ci-workflow#%E5%9C%A8%E6%9C%AC%E5%9C%B0%E7%AB%AF%E5%9F%B7%E8%A1%8C-nodejs"></a>在本地端執行 Node.js</h3>
<ol>
<li>初始化 Node.js 的環境，填寫一些資料之後會在目錄下產生一個 <code>package.json</code> 的檔案：</li>
</ol>
<div class="highlight highlight-source-shell">
<pre>$ npm init</pre>
</div>
<ol>
<li>安裝 Node.js 的 web framework，以 <a href="http://expressjs.com/">Express</a> 為例：</li>
</ol>
<div class="highlight highlight-source-shell">
<pre>$ npm install express --save</pre>
</div>
<blockquote><p><code>--save</code>: 寫入 <code>package.json</code> 的 dependencies。</p></blockquote>
<ol>
<li>完成之後，<code>package.json</code> 大概會長這個樣子：</li>
</ol>
<div class="highlight highlight-source-json">
<pre>// package.json
{
  <span class="pl-s"><span class="pl-pds">"</span>name<span class="pl-pds">"</span></span>: <span class="pl-s"><span class="pl-pds">"</span>hello-ci-workflow<span class="pl-pds">"</span></span>,
  <span class="pl-s"><span class="pl-pds">"</span>main<span class="pl-pds">"</span></span>: <span class="pl-s"><span class="pl-pds">"</span>index.js<span class="pl-pds">"</span></span>,
  <span class="pl-s"><span class="pl-pds">"</span>dependencies<span class="pl-pds">"</span></span>: {
    <span class="pl-s"><span class="pl-pds">"</span>express<span class="pl-pds">"</span></span>: <span class="pl-s"><span class="pl-pds">"</span>^4.12.3<span class="pl-pds">"</span></span>
  },
  <span class="pl-s"><span class="pl-pds">"</span>scripts<span class="pl-pds">"</span></span>: {
    <span class="pl-s"><span class="pl-pds">"</span>start<span class="pl-pds">"</span></span>: <span class="pl-s"><span class="pl-pds">"</span>node index.js<span class="pl-pds">"</span></span>
  }
}</pre>
</div>
<ol>
<li>在 <code>index.js</code> 裡寫一段簡單的 Hello World! 的程式：</li>
</ol>
<div class="highlight highlight-source-js">
<pre><span class="pl-c">// index.js</span>
<span class="pl-k">var</span> express <span class="pl-k">=</span> <span class="pl-c1">require</span>(<span class="pl-s"><span class="pl-pds">'</span>express<span class="pl-pds">'</span></span>);
<span class="pl-k">var</span> app <span class="pl-k">=</span> <span class="pl-en">express</span>();

<span class="pl-smi">app</span>.<span class="pl-en">get</span>(<span class="pl-s"><span class="pl-pds">'</span>/<span class="pl-pds">'</span></span>, <span class="pl-k">function</span> (<span class="pl-smi">req</span>, <span class="pl-smi">res</span>) {
  <span class="pl-smi">res</span>.<span class="pl-c1">send</span>(<span class="pl-s"><span class="pl-pds">'</span>Hello World!<span class="pl-pds">'</span></span>);
});

<span class="pl-k">var</span> server <span class="pl-k">=</span> <span class="pl-smi">app</span>.<span class="pl-en">listen</span>(<span class="pl-c1">3000</span>, <span class="pl-k">function</span> () {

  <span class="pl-k">var</span> host <span class="pl-k">=</span> <span class="pl-smi">server</span>.<span class="pl-en">address</span>().<span class="pl-smi">address</span>;
  <span class="pl-k">var</span> port <span class="pl-k">=</span> <span class="pl-smi">server</span>.<span class="pl-en">address</span>().<span class="pl-c1">port</span>;

  <span class="pl-en">console</span>.<span class="pl-c1">log</span>(<span class="pl-s"><span class="pl-pds">'</span>Example app listening at http://%s:%s<span class="pl-pds">'</span></span>, host, port);

});</pre>
</div>
<ol>
<li>執行 <code>npm start</code> 或 <code>node index.js</code>：</li>
</ol>
<div class="highlight highlight-source-shell">
<pre>$ npm start</pre>
</div>
<ol>
<li>打開瀏覽器 <code>http://localhost:3000</code> 看結果：</li>
</ol>
<p><a href="https://www.fuwuqiok.com/wp-content/uploads/2016/03/687474703a2f2f312e62702e626c6f6773706f742e636f6d2f2d316f705f565f50574749492f56547055664f50796f67492f41414141414141416b65772f69576453534d2d453648592f73313630302f30312e706e67"><img class="attachment-medium" src="https://www.fuwuqiok.com/wp-content/uploads/2016/03/687474703a2f2f312e62702e626c6f6773706f742e636f6d2f2d316f705f565f50574749492f56547055664f50796f67492f41414141414141416b65772f69576453534d2d453648592f73313630302f30312e706e67" alt="687474703a2f2f312e62702e626c6f6773706f742e636f6d2f2d316f705f565f50574749492f56547055664f50796f67492f41414141414141416b65772f69576453534d2d453648592f73313630302f30312e706e6" width="250" height="70" /></a></p>
<h3><a id="user-content-在本地端測試-nodejs" class="anchor" href="https://github.com/zeus911/hello-ci-workflow#%E5%9C%A8%E6%9C%AC%E5%9C%B0%E7%AB%AF%E6%B8%AC%E8%A9%A6-nodejs"></a>在本地端測試 Node.js</h3>
<ol>
<li>安裝 Node.js 的單元測試，以 <a href="http://mochajs.org/">Mocha</a> 為例：</li>
</ol>
<div class="highlight highlight-source-shell">
<pre>$ npm install mocha --save-dev</pre>
</div>
<blockquote><p><code>--save-dev</code>: 寫入 <code>package.json</code> 的 devDependencies，正式上線環境不會被安裝。</p></blockquote>
<div class="highlight highlight-source-json">
<pre>// package.json
{
  <span class="pl-s"><span class="pl-pds">"</span>name<span class="pl-pds">"</span></span>: <span class="pl-s"><span class="pl-pds">"</span>hello-ci-workflow<span class="pl-pds">"</span></span>,
  <span class="pl-s"><span class="pl-pds">"</span>main<span class="pl-pds">"</span></span>: <span class="pl-s"><span class="pl-pds">"</span>index.js<span class="pl-pds">"</span></span>,
  <span class="pl-s"><span class="pl-pds">"</span>dependencies<span class="pl-pds">"</span></span>: {
    <span class="pl-s"><span class="pl-pds">"</span>express<span class="pl-pds">"</span></span>: <span class="pl-s"><span class="pl-pds">"</span>^4.12.3<span class="pl-pds">"</span></span>
  },
  <span class="pl-s"><span class="pl-pds">"</span>devDependencies<span class="pl-pds">"</span></span>: {
    <span class="pl-s"><span class="pl-pds">"</span>mocha<span class="pl-pds">"</span></span>: <span class="pl-s"><span class="pl-pds">"</span>^2.2.4<span class="pl-pds">"</span></span>
  },
  <span class="pl-s"><span class="pl-pds">"</span>scripts<span class="pl-pds">"</span></span>: {
    <span class="pl-s"><span class="pl-pds">"</span>start<span class="pl-pds">"</span></span>: <span class="pl-s"><span class="pl-pds">"</span>node index.js<span class="pl-pds">"</span></span>
  }
}</pre>
</div>
<ol>
<li>根目錄 <code>test</code> 資料夾，並新增一個測試腳本 <code>test.js</code>：</li>
</ol>
<div class="highlight highlight-source-shell">
<pre>$ mkdir <span class="pl-c1">test</span>
$ <span class="pl-c1">cd</span> <span class="pl-c1">test</span>
$ touch <span class="pl-c1">test</span>.js</pre>
</div>
<ol>
<li>加入一筆錯誤的測試 <code>assert.equal(1, [1,2,3].indexOf(0))</code>：</li>
</ol>
<div class="highlight highlight-source-js">
<pre><span class="pl-c">// test/test.js</span>
<span class="pl-k">var</span> assert <span class="pl-k">=</span> <span class="pl-c1">require</span>(<span class="pl-s"><span class="pl-pds">"</span>assert<span class="pl-pds">"</span></span>)
<span class="pl-en">describe</span>(<span class="pl-s"><span class="pl-pds">'</span>Array<span class="pl-pds">'</span></span>, <span class="pl-k">function</span>(){
  <span class="pl-en">describe</span>(<span class="pl-s"><span class="pl-pds">'</span>#indexOf()<span class="pl-pds">'</span></span>, <span class="pl-k">function</span>(){
    <span class="pl-en">it</span>(<span class="pl-s"><span class="pl-pds">'</span>should return -1 when the value is not present<span class="pl-pds">'</span></span>, <span class="pl-k">function</span>(){
      <span class="pl-smi">assert</span>.<span class="pl-en">equal</span>(<span class="pl-c1">1</span>, [<span class="pl-c1">1</span>,<span class="pl-c1">2</span>,<span class="pl-c1">3</span>].<span class="pl-c1">indexOf</span>(<span class="pl-c1">0</span>));
    })
  })
})</pre>
</div>
<ol>
<li>執行 mocha 測試：</li>
</ol>
<div class="highlight highlight-source-shell">
<pre>$ ./node_modules/.bin/mocha


  Array
    <span class="pl-c">#indexOf()</span>
      1) should <span class="pl-k">return</span> -1 when the value is not present


  0 passing (9ms)
  1 failing</pre>
</div>
<p>結果顯示 <code>1 failing</code>，測試沒通過，因為 <code>[1,2,3].indexOf(0)</code> 回傳的值不等於 <code>-1</code>。</p>
<ol>
<li>將 <code>test.js</code> 的測試修正：</li>
</ol>
<div class="highlight highlight-source-js">
<pre><span class="pl-c">// test/test.js</span>
<span class="pl-smi">assert</span>.<span class="pl-en">equal</span>(<span class="pl-k">-</span><span class="pl-c1">1</span>, [<span class="pl-c1">1</span>,<span class="pl-c1">2</span>,<span class="pl-c1">3</span>].<span class="pl-c1">indexOf</span>(<span class="pl-c1">0</span>));</pre>
</div>
<ol>
<li>再次執行 mocha 測試：</li>
</ol>
<div class="highlight highlight-source-shell">
<pre>$ ./node_modules/.bin/mocha


  Array
    <span class="pl-c">#indexOf()</span>
      ✓ should <span class="pl-k">return</span> -1 when the value is not present


  1 passing (6ms)</pre>
</div>
<p>結果顯示 <code>1 passing</code>，通過測試。</p>
<h2><a id="user-content-github" class="anchor" href="https://github.com/zeus911/hello-ci-workflow#github"></a>GitHub</h2>
<p><a href="https://www.fuwuqiok.com/wp-content/uploads/2016/03/687474703a2f2f332e62702e626c6f6773706f742e636f6d2f2d736142616235336e3135772f56547051765149376636492f41414141414141416b63552f46703865346161467938452f73313630302f6769746875622e706e67"><img class="attachment-medium" src="https://www.fuwuqiok.com/wp-content/uploads/2016/03/687474703a2f2f332e62702e626c6f6773706f742e636f6d2f2d736142616235336e3135772f56547051765149376636492f41414141414141416b63552f46703865346161467938452f73313630302f6769746875622e706e67" alt="687474703a2f2f332e62702e626c6f6773706f742e636f6d2f2d736142616235336e3135772f56547051765149376636492f41414141414141416b63552f46703865346161467938452f73313630302f6769746875622e706e6" width="374" height="80" /></a></p>
<blockquote><p>安裝：</p>
<ul>
<li><a href="http://git-scm.com/">git</a>: 2.3</li>
</ul>
<p>帳號：</p>
<ul>
<li><a href="https://github.com/">GitHub</a></li>
</ul>
</blockquote>
<ol>
<li>初始化 git 環境：</li>
</ol>
<div class="highlight highlight-source-shell">
<pre>$ git init <span class="pl-c1">.</span></pre>
</div>
<ol>
<li>輸入 <code>git status</code> 會顯示目前哪些檔案有過更動：</li>
</ol>
<div class="highlight highlight-source-shell">
<pre>$ git status
On branch master

Initial commit

Untracked files:
  (use <span class="pl-s"><span class="pl-pds">"</span>git add &lt;file&gt;...<span class="pl-pds">"</span></span> to include <span class="pl-k">in</span> what will be committed)

  index.js
  node_modules/
  package.json
  test/</pre>
</div>
<ol>
<li>將 <code>node_modules</code> 加到 <code>.gitignore</code> 黑名單，因為這個資料夾是由 <code>npm install</code> 自動產生的，不需要放到 GitHub 上：</li>
</ol>
<div class="highlight highlight-source-yaml">
<pre><span class="pl-c"># .gitignore</span>

<span class="pl-c"># Dependency directory</span>
<span class="pl-c"># https://www.npmjs.org/doc/misc/npm-faq.html#should-i-check-my-node_modules-folder-into-git</span>
node_modules</pre>
</div>
<ol>
<li>將更動 commit：</li>
</ol>
<div class="highlight highlight-source-shell">
<pre>$ git add <span class="pl-c1">.</span>
$ git commit -m <span class="pl-s"><span class="pl-pds">"</span>first commit<span class="pl-pds">"</span></span></pre>
</div>
<ol>
<li>打開 GitHub，新增一個 repository：</li>
</ol>
<p><a href="https://www.fuwuqiok.com/wp-content/uploads/2016/03/687474703a2f2f322e62702e626c6f6773706f742e636f6d2f2d2d4a2d36343130534e74342f5654705566423150452d492f41414141414141416b65732f4e5a4476386d436e6661342f73313630302f30322e706e67"><img class="attachment-medium" src="https://www.fuwuqiok.com/wp-content/uploads/2016/03/687474703a2f2f322e62702e626c6f6773706f742e636f6d2f2d2d4a2d36343130534e74342f5654705566423150452d492f41414141414141416b65732f4e5a4476386d436e6661342f73313630302f30322e706e67" alt="687474703a2f2f322e62702e626c6f6773706f742e636f6d2f2d2d4a2d36343130534e74342f5654705566423150452d492f41414141414141416b65732f4e5a4476386d436e6661342f73313630302f30322e706e6" width="325" height="47" /></a></p>
<ol>
<li>輸入 repository 的名稱，以 <code>hello-ci-workflow</code> 為例：</li>
</ol>
<p><a href="https://www.fuwuqiok.com/wp-content/uploads/2016/03/687474703a2f2f332e62702e626c6f6773706f742e636f6d2f2d4a7973694f3946663435492f56547055664166674532492f41414141414141416b65302f42465947614d5a394d55302f73313630302f30332e706e67"><img class="attachment-medium" src="https://www.fuwuqiok.com/wp-content/uploads/2016/03/687474703a2f2f332e62702e626c6f6773706f742e636f6d2f2d4a7973694f3946663435492f56547055664166674532492f41414141414141416b65302f42465947614d5a394d55302f73313630302f30332e706e67" alt="687474703a2f2f332e62702e626c6f6773706f742e636f6d2f2d4a7973694f3946663435492f56547055664166674532492f41414141414141416b65302f42465947614d5a394d55302f73313630302f30332e706e6" width="430" height="44" /></a></p>
<ol>
<li>使用 <code>git remote add</code> 將新創建的 GitHub repository 加入到 remote：</li>
</ol>
<div class="highlight highlight-source-shell">
<pre>$ git remote add origin https://github.com/<span class="pl-k">&lt;</span>USER_NAME<span class="pl-k">&gt;</span>/hello-ci-workflow.git</pre>
</div>
<blockquote><p><code>&lt;USER_NAME&gt;</code> 改成自己的帳號。</p></blockquote>
<ol>
<li>使用 <code>git push</code> 將程式碼傳到 GitHub：</li>
</ol>
<div class="highlight highlight-source-shell">
<pre>$ git push -u origin master</pre>
</div>
<p>成功之後前往 <code>https://github.com/&lt;USER_NAME&gt;/hello-ci-workflow</code> 就可以看到剛才上傳的檔案：</p>
<p><a href="https://www.fuwuqiok.com/wp-content/uploads/2016/03/687474703a2f2f332e62702e626c6f6773706f742e636f6d2f2d4c6642586942516b654e632f56547055666c6e683367492f41414141414141416b65342f634b316c703537725a79632f73313630302f30342e706e67"><img class="attachment-medium" src="https://www.fuwuqiok.com/wp-content/uploads/2016/03/687474703a2f2f332e62702e626c6f6773706f742e636f6d2f2d4c6642586942516b654e632f56547055666c6e683367492f41414141414141416b65342f634b316c703537725a79632f73313630302f30342e706e67" alt="687474703a2f2f332e62702e626c6f6773706f742e636f6d2f2d4c6642586942516b654e632f56547055666c6e683367492f41414141414141416b65342f634b316c703537725a79632f73313630302f30342e706e6" width="211" height="205" /></a></p>
<h2><a id="user-content-circleci" class="anchor" href="https://github.com/zeus911/hello-ci-workflow#circleci"></a>CircleCI</h2>
<p><a href="https://www.fuwuqiok.com/wp-content/uploads/2016/03/687474703a2f2f322e62702e626c6f6773706f742e636f6d2f2d555466506b66356b5171302f56547051753441425969492f41414141414141416b634d2f4d6a6577393739315a7a672f73313630302f636972636c6563692e706e67"><img class="attachment-medium" src="https://www.fuwuqiok.com/wp-content/uploads/2016/03/687474703a2f2f322e62702e626c6f6773706f742e636f6d2f2d555466506b66356b5171302f56547051753441425969492f41414141414141416b634d2f4d6a6577393739315a7a672f73313630302f636972636c6563692e706e67" alt="687474703a2f2f322e62702e626c6f6773706f742e636f6d2f2d555466506b66356b5171302f56547051753441425969492f41414141414141416b634d2f4d6a6577393739315a7a672f73313630302f636972636c6563692e706e6" width="378" height="80" /></a></p>
<blockquote><p>帳號：</p>
<ul>
<li><a href="https://circleci.com/">CircleCI</a></li>
</ul>
</blockquote>
<h3><a id="user-content-加入-github-repository" class="anchor" href="https://github.com/zeus911/hello-ci-workflow#%E5%8A%A0%E5%85%A5-github-repository"></a>加入 GitHub repository</h3>
<ol>
<li>點選左邊欄的 <code>Add Projects</code> 按鈕：</li>
</ol>
<p><a href="https://www.fuwuqiok.com/wp-content/uploads/2016/03/687474703a2f2f312e62702e626c6f6773706f742e636f6d2f2d37725766746e676c5f53632f56547055663743494b4c492f41414141414141416b66492f67326264753834777a65632f73313630302f30352e706e67"><img class="attachment-medium" src="https://www.fuwuqiok.com/wp-content/uploads/2016/03/687474703a2f2f312e62702e626c6f6773706f742e636f6d2f2d37725766746e676c5f53632f56547055663743494b4c492f41414141414141416b66492f67326264753834777a65632f73313630302f30352e706e67" alt="687474703a2f2f312e62702e626c6f6773706f742e636f6d2f2d37725766746e676c5f53632f56547055663743494b4c492f41414141414141416b66492f67326264753834777a65632f73313630302f30352e706e6" width="195" height="75" /></a></p>
<ol>
<li>選擇自己的 GitHub 帳號：</li>
</ol>
<p><a href="https://www.fuwuqiok.com/wp-content/uploads/2016/03/687474703a2f2f332e62702e626c6f6773706f742e636f6d2f2d34376b685743594648766b2f56547055663636374249492f41414141414141416b66412f3230614c6d7a484d6f67512f73313630302f30362e706e67"><img class="attachment-medium" src="https://www.fuwuqiok.com/wp-content/uploads/2016/03/687474703a2f2f332e62702e626c6f6773706f742e636f6d2f2d34376b685743594648766b2f56547055663636374249492f41414141414141416b66412f3230614c6d7a484d6f67512f73313630302f30362e706e67" alt="687474703a2f2f332e62702e626c6f6773706f742e636f6d2f2d34376b685743594648766b2f56547055663636374249492f41414141414141416b66412f3230614c6d7a484d6f67512f73313630302f30362e706e6" width="250" height="68" /></a></p>
<ol>
<li>搜尋要加入的 GitHub repository，然後點選 <code>Build project</code> 按鈕，以 <code>hello-ci-workflow</code> 為例：</li>
</ol>
<p><a href="https://www.fuwuqiok.com/wp-content/uploads/2016/03/687474703a2f2f332e62702e626c6f6773706f742e636f6d2f2d73444630306c78386361492f565470556e684e6c4739492f41414141414141416b686b2f50425669354952556676452f73313630302f30372e706e67"><img class="attachment-medium" src="https://www.fuwuqiok.com/wp-content/uploads/2016/03/687474703a2f2f332e62702e626c6f6773706f742e636f6d2f2d73444630306c78386361492f565470556e684e6c4739492f41414141414141416b686b2f50425669354952556676452f73313630302f30372e706e67" alt="687474703a2f2f332e62702e626c6f6773706f742e636f6d2f2d73444630306c78386361492f565470556e684e6c4739492f41414141414141416b686b2f50425669354952556676452f73313630302f30372e706e6" width="350" height="94" /></a></p>
<ol>
<li>完成之後 CircleCI 就會自動執行第一次的建構，不過因為還沒加入測試腳本，所以建構結果會顯示 no test：</li>
</ol>
<p><a href="https://www.fuwuqiok.com/wp-content/uploads/2016/03/687474703a2f2f322e62702e626c6f6773706f742e636f6d2f2d34364c78483678636f744d2f56547055677335734a56492f41414141414141416b664d2f396b3056394869476b35412f73313630302f30382e706e67"><img class="attachment-medium" src="https://www.fuwuqiok.com/wp-content/uploads/2016/03/687474703a2f2f322e62702e626c6f6773706f742e636f6d2f2d34364c78483678636f744d2f56547055677335734a56492f41414141414141416b664d2f396b3056394869476b35412f73313630302f30382e706e67" alt="687474703a2f2f322e62702e626c6f6773706f742e636f6d2f2d34364c78483678636f744d2f56547055677335734a56492f41414141414141416b664d2f396b3056394869476b35412f73313630302f30382e706e6" width="269" height="78" /></a></p>
<h3><a id="user-content-在-circleci-測試-nodejs" class="anchor" href="https://github.com/zeus911/hello-ci-workflow#%E5%9C%A8-circleci-%E6%B8%AC%E8%A9%A6-nodejs"></a>在 CircleCI 測試 Node.js</h3>
<ol>
<li>在專案根目錄底下建立一個 <code>circle.yml</code>，並加入 mocha test：</li>
</ol>
<div class="highlight highlight-source-yaml">
<pre><span class="pl-c"># circle.yml</span>
<span class="pl-s"><span class="pl-ent">machine:</span></span>
  <span class="pl-s"><span class="pl-ent">node:</span></span>
    <span class="pl-c1"><span class="pl-ent">version:</span> 0.10</span>

<span class="pl-s"><span class="pl-ent">test:</span></span>
  <span class="pl-s"><span class="pl-ent">override:</span></span>
    <span class="pl-s">- <span class="pl-s">./node_modules/.bin/mocha</span></span></pre>
</div>
<ol>
<li>完成之後將檔案 push 上 GitHub：</li>
</ol>
<div class="highlight highlight-source-shell">
<pre>$ git add circle.yml
$ git cimmit <span class="pl-s"><span class="pl-pds">"</span>add circle.yml<span class="pl-pds">"</span></span>
$ git push</pre>
</div>
<ol>
<li>Push 成功之後，CircleCI 會自動觸發建構和測試：</li>
</ol>
<p><a href="https://www.fuwuqiok.com/wp-content/uploads/2016/03/687474703a2f2f322e62702e626c6f6773706f742e636f6d2f2d47674d44483277596f5f672f56547055673877733434492f41414141414141416b66552f7a5431686f346c76546d382f73313630302f30392e706e67"><img class="attachment-medium" src="https://www.fuwuqiok.com/wp-content/uploads/2016/03/687474703a2f2f322e62702e626c6f6773706f742e636f6d2f2d47674d44483277596f5f672f56547055673877733434492f41414141414141416b66552f7a5431686f346c76546d382f73313630302f30392e706e67" alt="687474703a2f2f322e62702e626c6f6773706f742e636f6d2f2d47674d44483277596f5f672f56547055673877733434492f41414141414141416b66552f7a5431686f346c76546d382f73313630302f30392e706e6" width="500" height="300" /></a></p>
<ol>
<li>測試通過，建置成功：</li>
</ol>
<p><a href="https://www.fuwuqiok.com/wp-content/uploads/2016/03/687474703a2f2f312e62702e626c6f6773706f742e636f6d2f2d456c4d57747638537534492f565470556845325f4c4d492f41414141414141416b66592f51346b5a6c3544377172672f73313630302f31302e706e67"><img class="attachment-medium" src="https://www.fuwuqiok.com/wp-content/uploads/2016/03/687474703a2f2f312e62702e626c6f6773706f742e636f6d2f2d456c4d57747638537534492f565470556845325f4c4d492f41414141414141416b66592f51346b5a6c3544377172672f73313630302f31302e706e67" alt="687474703a2f2f312e62702e626c6f6773706f742e636f6d2f2d456c4d57747638537534492f565470556845325f4c4d492f41414141414141416b66592f51346b5a6c3544377172672f73313630302f31302e706e6" width="210" height="55" /></a></p>
<h2><a id="user-content-代碼審查code-reviewwith-github-flow" class="anchor" href="https://github.com/zeus911/hello-ci-workflow#%E4%BB%A3%E7%A2%BC%E5%AF%A9%E6%9F%A5code-reviewwith-github-flow"></a>代碼審查（Code Review）with GitHub Flow</h2>
<p>目前開發中比較常用的 workflow 有 <a href="http://nvie.com/posts/a-successful-git-branching-model/">Git flow</a> 和 <a href="https://guides.github.com/introduction/flow/">GitHub flow</a> 兩種，可以參考以下幾篇文章：</p>
<p>Git flow：</p>
<ul>
<li><a href="https://ihower.tw/blog/archives/5140">Git flow 開發流程</a></li>
<li><a href="https://danielkummer.github.io/git-flow-cheatsheet/">git-flow cheatsheet</a></li>
<li><a href="http://nvie.com/posts/a-successful-git-branching-model/">A successful Git branching model</a></li>
</ul>
<p>GitHub flow：</p>
<ul>
<li><a href="https://guides.github.com/introduction/flow/">Understanding the GitHub Flow</a></li>
<li><a href="http://www.arthurtoday.com/2015/02/git-flow-vs-github-flow.html">Git Flow 和 Github Flow 的不同</a></li>
<li><a href="http://blog.krdai.info/post/17485259496/github-flow">在 GitHub 當中使用的 work flow</a></li>
</ul>
<p>這裡我們使用 GitHub flow，它的核心精神是：</p>
<ul>
<li>所有在 master 分支上的程式都一定要是通過測試，可以部署的產品版本。</li>
<li>要開發功能、修復 Bug、做任何事情，都要從 master 開一條新的分支。</li>
<li>隨時 commit 和 push 你的程式碼到 GitHub 上，與大家討論。</li>
<li>功能完成時，使用 pull request 讓大家作 code review。</li>
<li>確認沒問題之後才可以 merge 回 master，並且部屬新版本到線上。</li>
</ul>
<h3><a id="user-content-建立一條分支" class="anchor" href="https://github.com/zeus911/hello-ci-workflow#%E5%BB%BA%E7%AB%8B%E4%B8%80%E6%A2%9D%E5%88%86%E6%94%AF"></a>建立一條分支</h3>
<ol>
<li>為了確保 master 這條主線上的程式碼都是穩定的，所以建議開發者依照不同的功能、建立不同的分支，這裡以 <code>test-github-flow</code> 為例，使用 <code>git branch</code> 新增分支、然後 <code>git checkout</code> 切換分支：</li>
</ol>
<div class="highlight highlight-source-shell">
<pre>$ git branch test-github-flow
$ git checkout test-github-flow</pre>
</div>
<h3><a id="user-content-加入-commits" class="anchor" href="https://github.com/zeus911/hello-ci-workflow#%E5%8A%A0%E5%85%A5-commits"></a>加入 commits</h3>
<ol>
<li>在 <code>test.js</code> 裡加入一行錯誤的測試 <code>assert.equal(3, [1,2,3].indexOf(5))</code>：</li>
</ol>
<div class="highlight highlight-source-js">
<pre><span class="pl-c">// test/test.js</span>
<span class="pl-c">// ...</span>
<span class="pl-smi">assert</span>.<span class="pl-en">equal</span>(<span class="pl-c1">3</span>, [<span class="pl-c1">1</span>,<span class="pl-c1">2</span>,<span class="pl-c1">3</span>].<span class="pl-c1">indexOf</span>(<span class="pl-c1">5</span>));</pre>
</div>
<div class="highlight highlight-source-shell">
<pre>$ git add test/test.js
$ git commit -m <span class="pl-s"><span class="pl-pds">"</span>add a error test case<span class="pl-pds">"</span></span></pre>
</div>
<h3><a id="user-content-新增一個-pull-request" class="anchor" href="https://github.com/zeus911/hello-ci-workflow#%E6%96%B0%E5%A2%9E%E4%B8%80%E5%80%8B-pull-request"></a>新增一個 Pull Request</h3>
<ol>
<li>Push 到 GitHub 的 test-github-flow 分支：</li>
</ol>
<div class="highlight highlight-source-shell">
<pre>$ git push -u origin test-github-flow</pre>
</div>
<ol>
<li>打開 GitHub 之後，會出現 <code>test-github-flow</code> 分支的 push commits，點選旁邊的 <code>Compare &amp; pull request</code> 按鈕：</li>
</ol>
<p><a href="https://www.fuwuqiok.com/wp-content/uploads/2016/03/687474703a2f2f342e62702e626c6f6773706f742e636f6d2f2d3358664e484e4a485f76382f56547055694f727a456f492f41414141414141416b66302f6a385665765951437944672f73313630302f31332e706e67"><img class="attachment-medium" src="https://www.fuwuqiok.com/wp-content/uploads/2016/03/687474703a2f2f342e62702e626c6f6773706f742e636f6d2f2d3358664e484e4a485f76382f56547055694f727a456f492f41414141414141416b66302f6a385665765951437944672f73313630302f31332e706e67" alt="687474703a2f2f342e62702e626c6f6773706f742e636f6d2f2d3358664e484e4a485f76382f56547055694f727a456f492f41414141414141416b66302f6a385665765951437944672f73313630302f31332e706e6" width="800" height="120" /></a></p>
<ol>
<li>點選之後會進入 Open a pull request 的填寫頁面，選擇想要 merge 的分支、輸入描述之後，點選 <code>Create pull request</code> 按鈕：</li>
</ol>
<p><a href="https://www.fuwuqiok.com/wp-content/uploads/2016/03/687474703a2f2f332e62702e626c6f6773706f742e636f6d2f2d736645574f6e4f665747592f5654705569515a763571492f41414141414141416b66342f65387772416871544736512f73313630302f31342e706e67"><img class="attachment-medium" src="https://www.fuwuqiok.com/wp-content/uploads/2016/03/687474703a2f2f332e62702e626c6f6773706f742e636f6d2f2d736645574f6e4f665747592f5654705569515a763571492f41414141414141416b66342f65387772416871544736512f73313630302f31342e706e67" alt="687474703a2f2f332e62702e626c6f6773706f742e636f6d2f2d736645574f6e4f665747592f5654705569515a763571492f41414141414141416b66342f65387772416871544736512f73313630302f31342e706e6" width="775" height="540" /></a></p>
<h3><a id="user-content-檢視討論你的程式碼" class="anchor" href="https://github.com/zeus911/hello-ci-workflow#%E6%AA%A2%E8%A6%96%E8%A8%8E%E8%AB%96%E4%BD%A0%E7%9A%84%E7%A8%8B%E5%BC%8F%E7%A2%BC"></a>檢視＆討論你的程式碼</h3>
<ol>
<li>新增一個 pull request 之後，其他人就會在 GitHub 上出現通知：</li>
</ol>
<p><a href="https://www.fuwuqiok.com/wp-content/uploads/2016/03/687474703a2f2f312e62702e626c6f6773706f742e636f6d2f2d4f393436777849474c696b2f5654705569393557376e492f41414141414141416b67452f454a354543344f677464732f73313630302f31352e706e67"><img class="attachment-medium" src="https://www.fuwuqiok.com/wp-content/uploads/2016/03/687474703a2f2f312e62702e626c6f6773706f742e636f6d2f2d4f393436777849474c696b2f5654705569393557376e492f41414141414141416b67452f454a354543344f677464732f73313630302f31352e706e67" alt="687474703a2f2f312e62702e626c6f6773706f742e636f6d2f2d4f393436777849474c696b2f5654705569393557376e492f41414141414141416b67452f454a354543344f677464732f73313630302f31352e706e6" width="170" height="35" /></a></p>
<ol>
<li>點進去之後可以看見相關的 commits 與留言，但是下面有一個紅紅大大的叉叉；因為每次 GitHub 只要有新的 push，就會觸發 CircleCI 的自動建置和測試，並且顯示結果在 GitHub 上：</li>
</ol>
<p><a href="https://www.fuwuqiok.com/wp-content/uploads/2016/03/687474703a2f2f332e62702e626c6f6773706f742e636f6d2f2d76337677694a59344759342f565470556a44714c6777492f41414141414141416b67492f57627850704769395069342f73313630302f31382e706e67"><img class="attachment-medium" src="https://www.fuwuqiok.com/wp-content/uploads/2016/03/687474703a2f2f332e62702e626c6f6773706f742e636f6d2f2d76337677694a59344759342f565470556a44714c6777492f41414141414141416b67492f57627850704769395069342f73313630302f31382e706e67" alt="687474703a2f2f332e62702e626c6f6773706f742e636f6d2f2d76337677694a59344759342f565470556a44714c6777492f41414141414141416b67492f57627850704769395069342f73313630302f31382e706e6" width="770" height="470" /></a></p>
<ol>
<li>點選叉叉，前往 CircleCI 查看錯誤原因：</li>
</ol>
<p><a href="https://www.fuwuqiok.com/wp-content/uploads/2016/03/687474703a2f2f332e62702e626c6f6773706f742e636f6d2f2d6172664e434532504e6a492f565470556a744b7a7042492f41414141414141416b67512f4a55396f6a63342d5630452f73313630302f31392e706e67"><img class="attachment-medium" src="https://www.fuwuqiok.com/wp-content/uploads/2016/03/687474703a2f2f332e62702e626c6f6773706f742e636f6d2f2d6172664e434532504e6a492f565470556a744b7a7042492f41414141414141416b67512f4a55396f6a63342d5630452f73313630302f31392e706e67" alt="687474703a2f2f332e62702e626c6f6773706f742e636f6d2f2d6172664e434532504e6a492f565470556a744b7a7042492f41414141414141416b67512f4a55396f6a63342d5630452f73313630302f31392e706e6" width="700" height="35" /></a></p>
<ol>
<li>就會發現剛剛 push 到 test-github-flow 的測試沒通過：</li>
</ol>
<p><a href="https://www.fuwuqiok.com/wp-content/uploads/2016/03/687474703a2f2f342e62702e626c6f6773706f742e636f6d2f2d432d71756474766c6a556b2f565470556872504b6d6c492f41414141414141416b666f2f664c52495566694b615a772f73313630302f31322e706e67"><img class="attachment-medium" src="https://www.fuwuqiok.com/wp-content/uploads/2016/03/687474703a2f2f342e62702e626c6f6773706f742e636f6d2f2d432d71756474766c6a556b2f565470556872504b6d6c492f41414141414141416b666f2f664c52495566694b615a772f73313630302f31322e706e67" alt="687474703a2f2f342e62702e626c6f6773706f742e636f6d2f2d432d71756474766c6a556b2f565470556872504b6d6c492f41414141414141416b666f2f664c52495566694b615a772f73313630302f31322e706e6" width="210" height="75" /></a></p>
<p><a href="https://www.fuwuqiok.com/wp-content/uploads/2016/03/687474703a2f2f312e62702e626c6f6773706f742e636f6d2f2d2d49783939655738646e412f56547055687253714a41492f41414141414141416b666b2f30617048456a33685a30632f73313630302f31312e706e67"><img class="attachment-medium" src="https://www.fuwuqiok.com/wp-content/uploads/2016/03/687474703a2f2f312e62702e626c6f6773706f742e636f6d2f2d2d49783939655738646e412f56547055687253714a41492f41414141414141416b666b2f30617048456a33685a30632f73313630302f31312e706e67" alt="687474703a2f2f312e62702e626c6f6773706f742e636f6d2f2d2d49783939655738646e412f56547055687253714a41492f41414141414141416b666b2f30617048456a33685a30632f73313630302f31312e706e6" width="580" height="535" /></a></p>
<p>回到 GitHub，因為測試沒通過，所以審查者不能讓這筆 pull request 被 merge 回 master。</p>
<ol>
<li>找到剛剛 commit 的那段程式碼，留言告知請開發者修正錯誤之後，再重新 commit push 上來：</li>
</ol>
<p><a href="https://www.fuwuqiok.com/wp-content/uploads/2016/03/687474703a2f2f332e62702e626c6f6773706f742e636f6d2f2d4d466a385073454a2d68672f565470556a3644386c78492f41414141414141416b67592f347a644a76316a417945492f73313630302f32312e706e67"><img class="attachment-medium" src="https://www.fuwuqiok.com/wp-content/uploads/2016/03/687474703a2f2f332e62702e626c6f6773706f742e636f6d2f2d4d466a385073454a2d68672f565470556a3644386c78492f41414141414141416b67592f347a644a76316a417945492f73313630302f32312e706e67" alt="687474703a2f2f332e62702e626c6f6773706f742e636f6d2f2d4d466a385073454a2d68672f565470556a3644386c78492f41414141414141416b67592f347a644a76316a417945492f73313630302f32312e706e6" width="620" height="200" /></a></p>
<p><a href="https://www.fuwuqiok.com/wp-content/uploads/2016/03/687474703a2f2f332e62702e626c6f6773706f742e636f6d2f2d7253585f7a6d4c3542386b2f565470556b595f343662492f41414141414141416b67632f6632303541376a445043452f73313630302f32322e706e67"><img class="attachment-medium" src="https://www.fuwuqiok.com/wp-content/uploads/2016/03/687474703a2f2f332e62702e626c6f6773706f742e636f6d2f2d7253585f7a6d4c3542386b2f565470556b595f343662492f41414141414141416b67632f6632303541376a445043452f73313630302f32322e706e67" alt="687474703a2f2f332e62702e626c6f6773706f742e636f6d2f2d7253585f7a6d4c3542386b2f565470556b595f343662492f41414141414141416b67632f6632303541376a445043452f73313630302f32322e706e6" width="795" height="285" /></a></p>
<p><a href="https://www.fuwuqiok.com/wp-content/uploads/2016/03/687474703a2f2f322e62702e626c6f6773706f742e636f6d2f2d7a5154654271794e446d552f565470556b713566424b492f41414141414141416b676b2f36653653435453784474672f73313630302f32332e706e67"><img class="attachment-medium" src="https://www.fuwuqiok.com/wp-content/uploads/2016/03/687474703a2f2f322e62702e626c6f6773706f742e636f6d2f2d7a5154654271794e446d552f565470556b713566424b492f41414141414141416b676b2f36653653435453784474672f73313630302f32332e706e67" alt="687474703a2f2f322e62702e626c6f6773706f742e636f6d2f2d7a5154654271794e446d552f565470556b713566424b492f41414141414141416b676b2f36653653435453784474672f73313630302f32332e706e6" width="770" height="255" /></a></p>
<ol>
<li>修正 <code>test.js</code> 的測試腳本：</li>
</ol>
<div class="highlight highlight-source-js">
<pre><span class="pl-c">// test/test.js</span>
<span class="pl-c">// ...</span>
<span class="pl-smi">assert</span>.<span class="pl-en">equal</span>(<span class="pl-k">-</span><span class="pl-c1">1</span>, [<span class="pl-c1">1</span>,<span class="pl-c1">2</span>,<span class="pl-c1">3</span>].<span class="pl-c1">indexOf</span>(<span class="pl-c1">5</span>));</pre>
</div>
<ol>
<li>再次 commit &amp; push：</li>
</ol>
<div class="highlight highlight-source-shell">
<pre>$ git add test/test.js
$ git commit -m <span class="pl-s"><span class="pl-pds">"</span>fix error test case<span class="pl-pds">"</span></span>
$ git push</pre>
</div>
<ol>
<li>回到 GitHub 的 pull request 頁面，可以看到最新一筆的 commit 成功通過 CircleCI 的測試了：</li>
</ol>
<p><a href="https://www.fuwuqiok.com/wp-content/uploads/2016/03/687474703a2f2f342e62702e626c6f6773706f742e636f6d2f2d773856576934434d51424d2f565470556c5164655878492f41414141414141416b67342f65794f736b3254314e68302f73313630302f32362e706e67"><img class="attachment-medium" src="https://www.fuwuqiok.com/wp-content/uploads/2016/03/687474703a2f2f342e62702e626c6f6773706f742e636f6d2f2d773856576934434d51424d2f565470556c5164655878492f41414141414141416b67342f65794f736b3254314e68302f73313630302f32362e706e67" alt="687474703a2f2f342e62702e626c6f6773706f742e636f6d2f2d773856576934434d51424d2f565470556c5164655878492f41414141414141416b67342f65794f736b3254314e68302f73313630302f32362e706e6" width="770" height="475" /></a></p>
<p><a href="https://www.fuwuqiok.com/wp-content/uploads/2016/03/687474703a2f2f322e62702e626c6f6773706f742e636f6d2f2d4b2d71506431356d7049772f565470556b324b6e7356492f41414141414141416b676f2f33744c6b74485a494778772f73313630302f32342e706e67"><img class="attachment-medium" src="https://www.fuwuqiok.com/wp-content/uploads/2016/03/687474703a2f2f322e62702e626c6f6773706f742e636f6d2f2d4b2d71506431356d7049772f565470556b324b6e7356492f41414141414141416b676f2f33744c6b74485a494778772f73313630302f32342e706e67" alt="687474703a2f2f322e62702e626c6f6773706f742e636f6d2f2d4b2d71506431356d7049772f565470556b324b6e7356492f41414141414141416b676f2f33744c6b74485a494778772f73313630302f32342e706e6" width="460" height="295" /></a></p>
<p><a href="https://www.fuwuqiok.com/wp-content/uploads/2016/03/687474703a2f2f312e62702e626c6f6773706f742e636f6d2f2d7874335859616c446d6a512f565470556c4a61797749492f41414141414141416b67302f6c306f44385969454b5a592f73313630302f32352e706e67"><img class="attachment-medium" src="https://www.fuwuqiok.com/wp-content/uploads/2016/03/687474703a2f2f312e62702e626c6f6773706f742e636f6d2f2d7874335859616c446d6a512f565470556c4a61797749492f41414141414141416b67302f6c306f44385969454b5a592f73313630302f32352e706e67" alt="687474703a2f2f312e62702e626c6f6773706f742e636f6d2f2d7874335859616c446d6a512f565470556c4a61797749492f41414141414141416b67302f6c306f44385969454b5a592f73313630302f32352e706e6" width="210" height="75" /></a></p>
<h3><a id="user-content-merge部署" class="anchor" href="https://github.com/zeus911/hello-ci-workflow#merge%E9%83%A8%E7%BD%B2"></a>Merge＆部署</h3>
<ol>
<li>審查之後，確定沒有問題，就可以點選 <code>Merge pull request</code> 的按鈕，將 <code>test-github-flow</code> 的程式碼 merge 回主線 <code>master</code>：</li>
</ol>
<p><a href="https://www.fuwuqiok.com/wp-content/uploads/2016/03/687474703a2f2f342e62702e626c6f6773706f742e636f6d2f2d695a7353466776494b58772f565470556c796e715877492f41414141414141416b68412f4f73723949657778657a492f73313630302f32372e706e67"><img class="attachment-medium" src="https://www.fuwuqiok.com/wp-content/uploads/2016/03/687474703a2f2f342e62702e626c6f6773706f742e636f6d2f2d695a7353466776494b58772f565470556c796e715877492f41414141414141416b68412f4f73723949657778657a492f73313630302f32372e706e67" alt="687474703a2f2f342e62702e626c6f6773706f742e636f6d2f2d695a7353466776494b58772f565470556c796e715877492f41414141414141416b68412f4f73723949657778657a492f73313630302f32372e706e6" width="770" height="170" /></a></p>
<p><a href="https://www.fuwuqiok.com/wp-content/uploads/2016/03/687474703a2f2f312e62702e626c6f6773706f742e636f6d2f2d70326731666a5a66416c492f565470556d5070523652492f41414141414141416b68452f3063642d506b63544c30592f73313630302f32382e706e67"><img class="attachment-medium" src="https://www.fuwuqiok.com/wp-content/uploads/2016/03/687474703a2f2f312e62702e626c6f6773706f742e636f6d2f2d70326731666a5a66416c492f565470556d5070523652492f41414141414141416b68452f3063642d506b63544c30592f73313630302f32382e706e67" alt="687474703a2f2f312e62702e626c6f6773706f742e636f6d2f2d70326731666a5a66416c492f565470556d5070523652492f41414141414141416b68452f3063642d506b63544c30592f73313630302f32382e706e6" width="770" height="200" /></a></p>
<p><a href="https://www.fuwuqiok.com/wp-content/uploads/2016/03/687474703a2f2f312e62702e626c6f6773706f742e636f6d2f2d726a7a37474a7a665a6c412f565470556d6149617a68492f41414141414141416b684d2f744f655937536f325964732f73313630302f32392e706e67"><img class="attachment-medium" src="https://www.fuwuqiok.com/wp-content/uploads/2016/03/687474703a2f2f312e62702e626c6f6773706f742e636f6d2f2d726a7a37474a7a665a6c412f565470556d6149617a68492f41414141414141416b684d2f744f655937536f325964732f73313630302f32392e706e67" alt="687474703a2f2f312e62702e626c6f6773706f742e636f6d2f2d726a7a37474a7a665a6c412f565470556d6149617a68492f41414141414141416b684d2f744f655937536f325964732f73313630302f32392e706e6" width="175" height="70" /></a></p>
<h2><a id="user-content-docker" class="anchor" href="https://github.com/zeus911/hello-ci-workflow#docker"></a>Docker</h2>
<p><a href="https://www.fuwuqiok.com/wp-content/uploads/2016/03/687474703a2f2f322e62702e626c6f6773706f742e636f6d2f2d7a426a6f4a4c4c6a7255302f56547051753752433841492f41414141414141416b63492f6b324e45733437595f4d492f73313630302f646f636b65722e706e67"><img class="attachment-medium" src="https://www.fuwuqiok.com/wp-content/uploads/2016/03/687474703a2f2f322e62702e626c6f6773706f742e636f6d2f2d7a426a6f4a4c4c6a7255302f56547051753752433841492f41414141414141416b63492f6b324e45733437595f4d492f73313630302f646f636b65722e706e67" alt="687474703a2f2f322e62702e626c6f6773706f742e636f6d2f2d7a426a6f4a4c4c6a7255302f56547051753752433841492f41414141414141416b63492f6b324e45733437595f4d492f73313630302f646f636b65722e706e6" width="335" height="80" /></a></p>
<blockquote><p>安裝：</p>
<ul>
<li><a href="https://github.com/boot2docker/boot2docker">boot2docker</a>: 1.5（Mac only）</li>
<li><a href="https://www.docker.com/">docker</a>: 1.5</li>
</ul>
</blockquote>
<p>什麼是 Docker？為什麼要用它？</p>
<p>因為 Docker 最近很火，所以網路上不缺關於介紹它的文章，原諒我這裡只稍微提一下：</p>
<p>以往開發人員面對開發環境不同的問題，常常出現「明明在我的電腦上可以跑」的囧境，所以為了解決這類問題，通常會使用虛擬機器（VM）搭配一些工具（<a href="https://www.vagrantup.com/">Vagrant</a>、<a href="https://www.chef.io/">Chef</a>）來協助統一開發人員、測試人員、上線產品的執行環境。</p>
<p><a href="https://www.fuwuqiok.com/wp-content/uploads/2016/03/687474703a2f2f332e62702e626c6f6773706f742e636f6d2f2d3564735356592d492d4e512f5654706263466c47564e492f41414141414141416b6b732f4546596f546a6774786d512f73313630302f766d2d76732d646f636b65722e706e67"><img class="attachment-medium" src="https://www.fuwuqiok.com/wp-content/uploads/2016/03/687474703a2f2f332e62702e626c6f6773706f742e636f6d2f2d3564735356592d492d4e512f5654706263466c47564e492f41414141414141416b6b732f4546596f546a6774786d512f73313630302f766d2d76732d646f636b65722e706e67" alt="687474703a2f2f332e62702e626c6f6773706f742e636f6d2f2d3564735356592d492d4e512f5654706263466c47564e492f41414141414141416b6b732f4546596f546a6774786d512f73313630302f766d2d76732d646f636b65722e706e6" width="500" height="257" /></a></p>
<p>Docker 也是類似的解決方案，不同於 VM 的是，Docker 運行起來更輕巧、可攜度更高。配置好一份設定之後，就可以讓大家馬上進入開發狀況，減少不必要的環境問題，提升效率。</p>
<h3><a id="user-content-在-docker-執行-nodejs" class="anchor" href="https://github.com/zeus911/hello-ci-workflow#%E5%9C%A8-docker-%E5%9F%B7%E8%A1%8C-nodejs"></a>在 Docker 執行 Node.js</h3>
<ol>
<li>在專案根目錄底下建立一個 <code>Dockerfile</code>：</li>
</ol>
<div class="highlight highlight-source-yaml">
<pre><span class="pl-c"># Dockerfile</span>

<span class="pl-c"># 從 [Docker Hub](https://hub.docker.com/) 安裝 Node.js image。</span>
<span class="pl-ent">FROM node</span>:0.10

<span class="pl-c"># 設定 container 的預設目錄位置</span>
WORKDIR /hello<span class="pl-s">-<span class="pl-s">ci-workflow</span></span>

<span class="pl-c"># 將專案根目錄的檔案加入至 container</span>
<span class="pl-c"># 安裝 npm package</span>
ADD . /hello<span class="pl-s">-<span class="pl-s">ci-workflow</span></span>
RUN npm install

<span class="pl-c"># 開放 container 的 3000 port</span>
EXPOSE 3000
CMD npm start</pre>
</div>
<ol>
<li>使用 <code>docker build</code> 建構您的 image：</li>
</ol>
<div class="highlight highlight-source-shell">
<pre>$ docker build -t hello-ci-workflow <span class="pl-c1">.</span></pre>
</div>
<blockquote><p><code>-t hello-ci-workflow</code> 是 image 名稱。</p></blockquote>
<ol>
<li>使用 <code>docker run</code> 執行您的 image：</li>
</ol>
<div class="highlight highlight-source-shell">
<pre>$ docker run -p 3000:3000 -d hello-ci-workflow</pre>
</div>
<blockquote><p><code>-d</code> 在背景執行 node，可以使用 <code>docker logs</code> 看執行結果。</p></blockquote>
<ol>
<li>打開瀏覽器 <code>http://localhost:3000</code> 看結果：</li>
</ol>
<p><a href="https://www.fuwuqiok.com/wp-content/uploads/2016/03/687474703a2f2f312e62702e626c6f6773706f742e636f6d2f2d316f705f565f50574749492f56547055664f50796f67492f41414141414141416b65772f69576453534d2d453648592f73313630302f30312e706e671"><img class="attachment-medium" src="https://www.fuwuqiok.com/wp-content/uploads/2016/03/687474703a2f2f312e62702e626c6f6773706f742e636f6d2f2d316f705f565f50574749492f56547055664f50796f67492f41414141414141416b65772f69576453534d2d453648592f73313630302f30312e706e671" alt="687474703a2f2f312e62702e626c6f6773706f742e636f6d2f2d316f705f565f50574749492f56547055664f50796f67492f41414141414141416b65772f69576453534d2d453648592f73313630302f30312e706e67" width="250" height="70" /></a></p>
<blockquote><p>其實每一次都要 <code>build</code> 和 <code>run</code> 還蠻麻煩的，推薦可以試試 <a href="https://github.com/docker/compose">Docker Compose</a>，用起來有點像 <a href="https://www.vagrantup.com/">Vagrant</a>。</p></blockquote>
<h3><a id="user-content-在-circleci-測試-docker" class="anchor" href="https://github.com/zeus911/hello-ci-workflow#%E5%9C%A8-circleci-%E6%B8%AC%E8%A9%A6-docker"></a>在 CircleCI 測試 Docker</h3>
<ol>
<li>修改 <code>circle.yml</code>：</li>
</ol>
<div class="highlight highlight-source-yaml">
<pre><span class="pl-c"># circle.yml</span>
<span class="pl-s"><span class="pl-ent">machine:</span></span>
  <span class="pl-c"># 環境改成 docker</span>
  <span class="pl-s"><span class="pl-ent">services:</span></span>
    <span class="pl-s">- <span class="pl-s">docker</span></span>

<span class="pl-s"><span class="pl-ent">dependencies:</span></span>
  <span class="pl-s"><span class="pl-ent">override:</span></span>
    <span class="pl-c"># 建構方式使用 docker build</span>
    <span class="pl-s">- <span class="pl-s">docker build -t hello-ci-workflow .</span></span>

<span class="pl-s"><span class="pl-ent">test:</span></span>
  <span class="pl-s"><span class="pl-ent">override:</span></span>
    <span class="pl-s">- <span class="pl-s">./node_modules/.bin/mocha</span></span>
    <span class="pl-c"># 使用 curl 測試 docker 是否有順利執行 node</span>
    <span class="pl-s">- <span class="pl-s">docker run -d -p 3000:3000 hello-ci-workflow; sleep 10</span></span>
    <span class="pl-s">- <span class="pl-s">curl --retry 10 --retry-delay 5 -v http://localhost:3000</span></span></pre>
</div>
<ol>
<li>Push 更新到 GitHub：</li>
</ol>
<div class="highlight highlight-source-shell">
<pre>$ git add Dockerfile circle.yml
$ git commit -m <span class="pl-s"><span class="pl-pds">"</span>add Docker<span class="pl-pds">"</span></span>
$ git push</pre>
</div>
<ol>
<li>查看 CircleCI 建構＆測試結果：</li>
</ol>
<p><a href="https://www.fuwuqiok.com/wp-content/uploads/2016/03/687474703a2f2f342e62702e626c6f6773706f742e636f6d2f2d694264624c33546b4d624d2f565470556d6d4e4a6d31492f41414141414141416b68552f7473514d642d696b61776f2f73313630302f33302e706e67"><img class="attachment-medium" src="https://www.fuwuqiok.com/wp-content/uploads/2016/03/687474703a2f2f342e62702e626c6f6773706f742e636f6d2f2d694264624c33546b4d624d2f565470556d6d4e4a6d31492f41414141414141416b68552f7473514d642d696b61776f2f73313630302f33302e706e67" alt="687474703a2f2f342e62702e626c6f6773706f742e636f6d2f2d694264624c33546b4d624d2f565470556d6d4e4a6d31492f41414141414141416b68552f7473514d642d696b61776f2f73313630302f33302e706e6" width="498" height="806" /></a></p>
<h2><a id="user-content-aws-elastic-beanstalk" class="anchor" href="https://github.com/zeus911/hello-ci-workflow#aws-elastic-beanstalk"></a>AWS Elastic Beanstalk</h2>
<p><a href="https://www.fuwuqiok.com/wp-content/uploads/2016/03/687474703a2f2f342e62702e626c6f6773706f742e636f6d2f2d784375514a6233395a32732f56547054317871345a5a492f41414141414141416b656b2f7452452d545f306d7950452f73313630302f6265616e7374616c6b2e706e67"><img class="attachment-medium" src="https://www.fuwuqiok.com/wp-content/uploads/2016/03/687474703a2f2f342e62702e626c6f6773706f742e636f6d2f2d784375514a6233395a32732f56547054317871345a5a492f41414141414141416b656b2f7452452d545f306d7950452f73313630302f6265616e7374616c6b2e706e67" alt="687474703a2f2f342e62702e626c6f6773706f742e636f6d2f2d784375514a6233395a32732f56547054317871345a5a492f41414141414141416b656b2f7452452d545f306d7950452f73313630302f6265616e7374616c6b2e706e6" width="300" height="80" /></a></p>
<blockquote><p>帳號：</p>
<ul>
<li><a href="https://aws.amazon.com/">Amazon Web Services</a></li>
</ul>
<p>安裝：</p>
<ul>
<li><a href="http://docs.aws.amazon.com/elasticbeanstalk/latest/dg/eb-cli3-getting-set-up.html#eb_cli3-install-with-pip">AWS EB CLI</a>: 3.x</li>
</ul>
</blockquote>
<p>最後要將程式上線啦！現在 PaaS 雲端平台的選擇非常多（<a href="https://www.heroku.com/">Heroku</a>、<a href="https://cloud.google.com/appengine/">Google App Engine</a>、<a href="http://azure.microsoft.com/z">Azure</a>、<a href="https://www.openshift.com/">OpenShift</a>、<a href="https://www.linode.com/">Linode</a>），這裡我選擇 Amazon 推出的 Elastic Beanstalk 當作範例，以下是它的特色：</p>
<ul>
<li>支援的開發環境多（Java、.NET、PHP、Node.js、Python、Ruby、GO），重點是有支援 Docker！</li>
<li>只需要上傳程式碼，Elastic Beanstalk 即可幫你完成從容量配置、負載均衡（load balancing）、自動擴展（auto scaling）到應用程式的運行狀況監控的部署。</li>
</ul>
<p><a href="https://www.fuwuqiok.com/wp-content/uploads/2016/03/687474703a2f2f322e62702e626c6f6773706f742e636f6d2f2d455658386f4c4c753958772f565470634c776f385776492f41414141414141416b6b302f487a7555433277365562592f73313630302f6177732d65622e706e67"><img class="attachment-medium" src="https://www.fuwuqiok.com/wp-content/uploads/2016/03/687474703a2f2f322e62702e626c6f6773706f742e636f6d2f2d455658386f4c4c753958772f565470634c776f385776492f41414141414141416b6b302f487a7555433277365562592f73313630302f6177732d65622e706e67" alt="687474703a2f2f322e62702e626c6f6773706f742e636f6d2f2d455658386f4c4c753958772f565470634c776f385776492f41414141414141416b6b302f487a7555433277365562592f73313630302f6177732d65622e706e6" width="436" height="393" /></a></p>
<ol>
<li>初始化 EB 環境：</li>
</ol>
<div class="highlight highlight-source-shell">
<pre>$ eb init -p docker</pre>
</div>
<blockquote><p><code>-p</code> 可以指定 EB 的應用平台，例如 php 之類；這裡使用 docker。</p></blockquote>
<p>該命令將提示您配置各種設置。 按 Enter 鍵接受預設值。</p>
<blockquote><p>如果你已經存有一組 AWS EB 權限的憑證，該命令會自動使用它。 否則，它會提示您輸入 <code>Access key ID</code> 和 <code>Secret access key</code>，必須前往 AWS IAM 建立一組。</p></blockquote>
<ol>
<li>初始化成功之後，可以使用 <code>eb create</code> 快速建立各種不同的環境，例如：development, staging, production；這裡我們以 <code>env-development</code> 為例：</li>
</ol>
<div class="highlight highlight-source-shell">
<pre>$ eb create env-development</pre>
</div>
<p>等待 Elastic Beanstalk 完成環境的建立。 當它完成之後，您的應用已經備有負載均衡（load-balancing）與自動擴展（autoscaling）的功能了。</p>
<p><a href="https://www.fuwuqiok.com/wp-content/uploads/2016/03/687474703a2f2f312e62702e626c6f6773706f742e636f6d2f2d555743795f7342635776342f565470556d3276355946492f41414141414141416b68632f727362472d4d5f4958466f2f73313630302f33312e706e67"><img class="attachment-medium" src="https://www.fuwuqiok.com/wp-content/uploads/2016/03/687474703a2f2f312e62702e626c6f6773706f742e636f6d2f2d555743795f7342635776342f565470556d3276355946492f41414141414141416b68632f727362472d4d5f4958466f2f73313630302f33312e706e67" alt="687474703a2f2f312e62702e626c6f6773706f742e636f6d2f2d555743795f7342635776342f565470556d3276355946492f41414141414141416b68632f727362472d4d5f4958466f2f73313630302f33312e706e6" width="485" height="562" /></a></p>
<ol>
<li>使用 <code>eb open</code> 前往目前版本的執行結果：</li>
</ol>
<div class="highlight highlight-source-shell">
<pre>$ eb open env-development</pre>
</div>
<p><a href="https://www.fuwuqiok.com/wp-content/uploads/2016/03/687474703a2f2f322e62702e626c6f6773706f742e636f6d2f2d334631586d454e575230732f565470556e587a4e5835492f41414141414141416b68672f4b745671356a6e546c31512f73313630302f33322e706e67"><img class="attachment-medium" src="https://www.fuwuqiok.com/wp-content/uploads/2016/03/687474703a2f2f322e62702e626c6f6773706f742e636f6d2f2d334631586d454e575230732f565470556e587a4e5835492f41414141414141416b68672f4b745671356a6e546c31512f73313630302f33322e706e67" alt="687474703a2f2f322e62702e626c6f6773706f742e636f6d2f2d334631586d454e575230732f565470556e587a4e5835492f41414141414141416b68672f4b745671356a6e546c31512f73313630302f33322e706e6" width="475" height="70" /></a></p>
<h3><a id="user-content-在本地端部署-aws" class="anchor" href="https://github.com/zeus911/hello-ci-workflow#%E5%9C%A8%E6%9C%AC%E5%9C%B0%E7%AB%AF%E9%83%A8%E7%BD%B2-aws"></a>在本地端部署 AWS</h3>
<ol>
<li>稍微修改 <code>index.js</code>：</li>
</ol>
<div class="highlight highlight-source-js">
<pre><span class="pl-c">// index.js</span>
<span class="pl-c">// ...</span>
<span class="pl-smi">app</span>.<span class="pl-en">get</span>(<span class="pl-s"><span class="pl-pds">'</span>/<span class="pl-pds">'</span></span>, <span class="pl-k">function</span> (<span class="pl-smi">req</span>, <span class="pl-smi">res</span>) {
  <span class="pl-smi">res</span>.<span class="pl-c1">send</span>(<span class="pl-s"><span class="pl-pds">'</span>Hello env-development!<span class="pl-pds">'</span></span>);
});
<span class="pl-c">// ...</span></pre>
</div>
<ol>
<li>執行 <code>eb deploy</code> 部署新版本到 AWS Elastic Beanstalk：</li>
</ol>
<div class="highlight highlight-source-shell">
<pre>$ eb deploy env-development</pre>
</div>
<p><a href="https://www.fuwuqiok.com/wp-content/uploads/2016/03/687474703a2f2f332e62702e626c6f6773706f742e636f6d2f2d4f42364d644d6b6c7072672f5654705576712d597963492f41414141414141416b6b4d2f52426973343739336274632f73313630302f33342e706e67"><img class="attachment-medium" src="https://www.fuwuqiok.com/wp-content/uploads/2016/03/687474703a2f2f332e62702e626c6f6773706f742e636f6d2f2d4f42364d644d6b6c7072672f5654705576712d597963492f41414141414141416b6b4d2f52426973343739336274632f73313630302f33342e706e67" alt="687474703a2f2f332e62702e626c6f6773706f742e636f6d2f2d4f42364d644d6b6c7072672f5654705576712d597963492f41414141414141416b6b4d2f52426973343739336274632f73313630302f33342e706e6" width="341" height="190" /></a></p>
<ol>
<li>部署完成之後，執行 <code>eb open</code> 打開網頁：</li>
</ol>
<div class="highlight highlight-source-shell">
<pre>$ eb open env-development</pre>
</div>
<p><a href="https://www.fuwuqiok.com/wp-content/uploads/2016/03/687474703a2f2f342e62702e626c6f6773706f742e636f6d2f2d69636e30397167564961512f565470556e7a696a7364492f41414141414141416b68732f664b5541305048435a7a672f73313630302f33332e706e67"><img class="attachment-medium" src="https://www.fuwuqiok.com/wp-content/uploads/2016/03/687474703a2f2f342e62702e626c6f6773706f742e636f6d2f2d69636e30397167564961512f565470556e7a696a7364492f41414141414141416b68732f664b5541305048435a7a672f73313630302f33332e706e67" alt="687474703a2f2f342e62702e626c6f6773706f742e636f6d2f2d69636e30397167564961512f565470556e7a696a7364492f41414141414141416b68732f664b5541305048435a7a672f73313630302f33332e706e6" width="471" height="70" /></a></p>
<p><code>env-development</code> 上的應用程式更新完成。</p>
<h3><a id="user-content-在-circleci-部署-aws" class="anchor" href="https://github.com/zeus911/hello-ci-workflow#%E5%9C%A8-circleci-%E9%83%A8%E7%BD%B2-aws"></a>在 CircleCI 部署 AWS</h3>
<ol>
<li><code>git checkout</code> 將分支切換回主線 master：</li>
</ol>
<div class="highlight highlight-source-shell">
<pre>$ git checkout master</pre>
</div>
<ol>
<li><code>eb create</code> 新增一組新的環境，作為產品上線用，命名為 <code>env-production</code>：</li>
</ol>
<div class="highlight highlight-source-shell">
<pre>$ eb create env-production</pre>
</div>
<div class="highlight highlight-source-shell">
<pre>$ eb open env-production</pre>
</div>
<p><a href="https://www.fuwuqiok.com/wp-content/uploads/2016/03/687474703a2f2f322e62702e626c6f6773706f742e636f6d2f2d636e4f4e667977414d54512f565470556f664a36656a492f41414141414141416b68772f6d304173684841356e524d2f73313630302f33352e706e67"><img class="attachment-medium" src="https://www.fuwuqiok.com/wp-content/uploads/2016/03/687474703a2f2f322e62702e626c6f6773706f742e636f6d2f2d636e4f4e667977414d54512f565470556f664a36656a492f41414141414141416b68772f6d304173684841356e524d2f73313630302f33352e706e67" alt="687474703a2f2f322e62702e626c6f6773706f742e636f6d2f2d636e4f4e667977414d54512f565470556f664a36656a492f41414141414141416b68772f6d304173684841356e524d2f73313630302f33352e706e6" width="471" height="70" /></a></p>
<p>這樣就成功啟動第二組機器了，目前我們有 <code>env-development</code> 和 <code>env-production</code> 兩組環境。</p>
<h3><a id="user-content-前往-aws-iam-新增一組帳號給-circleci-使用" class="anchor" href="https://github.com/zeus911/hello-ci-workflow#%E5%89%8D%E5%BE%80-aws-iam-%E6%96%B0%E5%A2%9E%E4%B8%80%E7%B5%84%E5%B8%B3%E8%99%9F%E7%B5%A6-circleci-%E4%BD%BF%E7%94%A8"></a>前往 <a href="https://console.aws.amazon.com/iam/home">AWS IAM</a> 新增一組帳號給 CircleCI 使用：</h3>
<ol>
<li><code>Dashboard</code> &gt; <code>Users</code></li>
<li><code>Create New Users</code></li>
<li>Enter User Names: <strong>CircleCI</strong> &gt; <code>Create</code></li>
<li><code>Download Credentials</code></li>
<li><code>Dashboard</code> &gt; <code>Users</code> &gt; <code>CircleCI</code></li>
<li><code>Attach Pollcy</code></li>
<li><code>AWSElasticBeanstalkFullAccess</code> &gt; <code>Attach Pollcy</code></li>
</ol>
<p>前往 CircleCI，設定您的 AWS 權限：</p>
<ol>
<li><code>Project Settings</code></li>
<li><code>Permissions</code> &gt; <code>AWS Permissions</code></li>
<li>打開剛才下載的 <code>credentials.csv</code>，輸入 <code>Access Key ID</code> &amp; <code>Secret Access Key</code></li>
<li><code>Save AWS keys</code></li>
<li>在 <code>.elasticbeanstalk</code> 目錄底下，建立 <code>config.global.yml</code>：</li>
</ol>
<div class="highlight highlight-source-yaml">
<pre><span class="pl-c"># .elasticbeanstalk/config.global.yml</span>
<span class="pl-s"><span class="pl-ent">global:</span></span>
  <span class="pl-s"><span class="pl-ent">application_name:</span> <span class="pl-s">hello-ci-workflow</span></span>
  <span class="pl-s"><span class="pl-ent">default_region:</span> <span class="pl-s">us-west-2 </span></span><span class="pl-c"># EB 所在的 region，預設是 us-west-2</span></pre>
</div>
<ol>
<li>修改 <code>circle.yml</code>：</li>
</ol>
<div class="highlight highlight-source-yaml">
<pre><span class="pl-c"># circle.yml</span>
<span class="pl-s"><span class="pl-ent">machine:</span></span>
  <span class="pl-c"># 安裝 eb 需要 python</span>
  <span class="pl-s"><span class="pl-ent">python:</span></span>
    <span class="pl-c1"><span class="pl-ent">version:</span> 2.7</span>
  <span class="pl-s"><span class="pl-ent">services:</span></span>
    <span class="pl-s">- <span class="pl-s">docker</span></span>

<span class="pl-s"><span class="pl-ent">dependencies:</span></span>
  <span class="pl-s"><span class="pl-ent">pre:</span></span>
    <span class="pl-c"># 安裝 eb</span>
    <span class="pl-s">- <span class="pl-s">sudo pip install awsebcli</span></span>
  <span class="pl-s"><span class="pl-ent">override:</span></span>
    <span class="pl-s">- <span class="pl-s">docker build -t hello-ci-workflow .</span></span>

<span class="pl-s"><span class="pl-ent">test:</span></span>
  <span class="pl-s"><span class="pl-ent">override:</span></span>
    <span class="pl-s">- <span class="pl-s">npm test</span></span>
    <span class="pl-s">- <span class="pl-s">docker run -d -p 3000:3000 hello-ci-workflow; sleep 10</span></span>
    <span class="pl-s">- <span class="pl-s">curl --retry 10 --retry-delay 5 -v http://localhost:3000</span></span>

<span class="pl-c"># 新增一筆部署腳本</span>
<span class="pl-s"><span class="pl-ent">deployment:</span></span>
  <span class="pl-s"><span class="pl-ent">production:</span></span>
    <span class="pl-s"><span class="pl-ent">branch:</span> <span class="pl-s">master</span></span>
    <span class="pl-s"><span class="pl-ent">commands:</span></span>
      <span class="pl-s">- <span class="pl-s">eb deploy env-production</span></span></pre>
</div>
<p>這樣就能在 GitHub 的 master 支線有更新時，觸發 CircleCI 的自動建置、測試、然後部署。</p>
<ol>
<li>接下來馬上來試試看流程，修改 <code>index.js</code>：</li>
</ol>
<div class="highlight highlight-source-js">
<pre><span class="pl-c">// index.js</span>
<span class="pl-c">// ...</span>
<span class="pl-smi">app</span>.<span class="pl-en">get</span>(<span class="pl-s"><span class="pl-pds">'</span>/<span class="pl-pds">'</span></span>, <span class="pl-k">function</span> (<span class="pl-smi">req</span>, <span class="pl-smi">res</span>) {
  <span class="pl-smi">res</span>.<span class="pl-c1">send</span>(<span class="pl-s"><span class="pl-pds">'</span>Hello env-production!<span class="pl-pds">'</span></span>);
});
<span class="pl-c">// ...</span></pre>
</div>
<ol>
<li>Commit &amp; Push：</li>
</ol>
<div class="highlight highlight-source-shell">
<pre>$ git add <span class="pl-c1">.</span>
$ git cimmit <span class="pl-s"><span class="pl-pds">"</span>test deploy production<span class="pl-pds">"</span></span>
$ git push</pre>
</div>
<ol>
<li>前往 CircleCI 看結果：</li>
</ol>
<p><a href="https://www.fuwuqiok.com/wp-content/uploads/2016/03/687474703a2f2f332e62702e626c6f6773706f742e636f6d2f2d333156596e4b726e5a5f672f565470556f6879575442492f41414141414141416b68342f70696f43374162314765732f73313630302f33362e706e67"><img class="attachment-medium" src="https://www.fuwuqiok.com/wp-content/uploads/2016/03/687474703a2f2f332e62702e626c6f6773706f742e636f6d2f2d333156596e4b726e5a5f672f565470556f6879575442492f41414141414141416b68342f70696f43374162314765732f73313630302f33362e706e67" alt="687474703a2f2f332e62702e626c6f6773706f742e636f6d2f2d333156596e4b726e5a5f672f565470556f6879575442492f41414141414141416b68342f70696f43374162314765732f73313630302f33362e706e6" width="615" height="390" /></a></p>
<ol>
<li>部署成功，<code>eb open</code> 打開瀏覽器來看看結果：</li>
</ol>
<div class="highlight highlight-source-shell">
<pre>$ eb open env-production</pre>
</div>
<p><a href="https://www.fuwuqiok.com/wp-content/uploads/2016/03/687474703a2f2f322e62702e626c6f6773706f742e636f6d2f2d456f705179646e757872552f565470556f2d72597873492f41414141414141416b68382f584137736b506b744151412f73313630302f33372e706e67"><img class="attachment-medium" src="https://www.fuwuqiok.com/wp-content/uploads/2016/03/687474703a2f2f322e62702e626c6f6773706f742e636f6d2f2d456f705179646e757872552f565470556f2d72597873492f41414141414141416b68382f584137736b506b744151412f73313630302f33372e706e67" alt="687474703a2f2f322e62702e626c6f6773706f742e636f6d2f2d456f705179646e757872552f565470556f2d72597873492f41414141414141416b68382f584137736b506b744151412f73313630302f33372e706e6" width="471" height="70" /></a></p>
<h2><a id="user-content-slack" class="anchor" href="https://github.com/zeus911/hello-ci-workflow#slack"></a>Slack</h2>
<p><a href="https://www.fuwuqiok.com/wp-content/uploads/2016/03/687474703a2f2f342e62702e626c6f6773706f742e636f6d2f2d61367938543547665330492f5654705176365370615f492f41414141414141416b63672f567242693661527a366a632f73313630302f736c61636b2e706e67"><img class="attachment-medium" src="https://www.fuwuqiok.com/wp-content/uploads/2016/03/687474703a2f2f342e62702e626c6f6773706f742e636f6d2f2d61367938543547665330492f5654705176365370615f492f41414141414141416b63672f567242693661527a366a632f73313630302f736c61636b2e706e67" alt="687474703a2f2f342e62702e626c6f6773706f742e636f6d2f2d61367938543547665330492f5654705176365370615f492f41414141414141416b63672f567242693661527a366a632f73313630302f736c61636b2e706e6" width="200" height="80" /></a></p>
<blockquote><p>帳號：</p>
<ul>
<li><a href="https://slack.com/">Slack</a></li>
</ul>
</blockquote>
<p>到這邊其實已經差不多結束了，最後來講講 Slack 吧。</p>
<p>Slack 是一款給團隊使用的即時溝通工具，類似的產品還有 <a href="https://gitter.im/">Gitter</a> 與 <a href="https://www.hipchat.com/">HipChat</a>。</p>
<p>至於跟 Skype、Lync 這些軟體有什麼不一樣的地方呢？</p>
<p>它們整合了許多開發工具（GitHub、CircleCI）的服務，例如 GitHub 有新的 push、pull request、issue；CircleCI 的單元測試沒有通過之類的通知，會即時出現在你的團隊的 Slack 上面，既然我們已經將大部分的工作自動化，勢必需要讓相關人員知道這些工具發生了哪些事情，所以使用 Slack 是必要的。</p>
<ol>
<li>登入 Slack 頁面</li>
<li>點選 <code>Configure Integrations</code> &gt; <code>CircleCI</code></li>
</ol>
<p><a href="https://www.fuwuqiok.com/wp-content/uploads/2016/03/687474703a2f2f312e62702e626c6f6773706f742e636f6d2f2d64555f5549556e757231412f56547055705245614c4c492f41414141414141416b69492f67613447547853786b36512f73313630302f33382e706e67"><img class="attachment-medium" src="https://www.fuwuqiok.com/wp-content/uploads/2016/03/687474703a2f2f312e62702e626c6f6773706f742e636f6d2f2d64555f5549556e757231412f56547055705245614c4c492f41414141414141416b69492f67613447547853786b36512f73313630302f33382e706e67" alt="687474703a2f2f312e62702e626c6f6773706f742e636f6d2f2d64555f5549556e757231412f56547055705245614c4c492f41414141414141416b69492f67613447547853786b36512f73313630302f33382e706e6" width="300" height="365" /></a></p>
<p><a href="https://www.fuwuqiok.com/wp-content/uploads/2016/03/687474703a2f2f312e62702e626c6f6773706f742e636f6d2f2d3148714b4a69353056514d2f565470557056335f504d492f41414141414141416b694d2f665a706d35567a48396f4d2f73313630302f33392e706e67"><img class="attachment-medium" src="https://www.fuwuqiok.com/wp-content/uploads/2016/03/687474703a2f2f312e62702e626c6f6773706f742e636f6d2f2d3148714b4a69353056514d2f565470557056335f504d492f41414141414141416b694d2f665a706d35567a48396f4d2f73313630302f33392e706e67" alt="687474703a2f2f312e62702e626c6f6773706f742e636f6d2f2d3148714b4a69353056514d2f565470557056335f504d492f41414141414141416b694d2f665a706d35567a48396f4d2f73313630302f33392e706e6" width="550" height="75" /></a></p>
<ol>
<li>選擇要接收 CircleCI 通知的 channel</li>
<li>點選 <code>Add CircleCI Integration</code> 按鈕</li>
<li>複製畫面上的 <code>webhook URL</code></li>
</ol>
<p><a href="https://www.fuwuqiok.com/wp-content/uploads/2016/03/687474703a2f2f322e62702e626c6f6773706f742e636f6d2f2d764f74756f31593048346b2f5654705571466e7a5177492f41414141414141416b69552f7478366739686f4a6778732f73313630302f34302e706e67"><img class="attachment-medium" src="https://www.fuwuqiok.com/wp-content/uploads/2016/03/687474703a2f2f322e62702e626c6f6773706f742e636f6d2f2d764f74756f31593048346b2f5654705571466e7a5177492f41414141414141416b69552f7478366739686f4a6778732f73313630302f34302e706e67" alt="687474703a2f2f322e62702e626c6f6773706f742e636f6d2f2d764f74756f31593048346b2f5654705571466e7a5177492f41414141414141416b69552f7478366739686f4a6778732f73313630302f34302e706e6" width="602" height="196" /></a></p>
<p><a href="https://www.fuwuqiok.com/wp-content/uploads/2016/03/687474703a2f2f322e62702e626c6f6773706f742e636f6d2f2d63567852614c2d76434f672f5654705572666e4a3354492f41414141414141416b69772f5a796f324762307a79306f2f73313630302f34342e706e67"><img class="attachment-medium" src="https://www.fuwuqiok.com/wp-content/uploads/2016/03/687474703a2f2f322e62702e626c6f6773706f742e636f6d2f2d63567852614c2d76434f672f5654705572666e4a3354492f41414141414141416b69772f5a796f324762307a79306f2f73313630302f34342e706e67" alt="687474703a2f2f322e62702e626c6f6773706f742e636f6d2f2d63567852614c2d76434f672f5654705572666e4a3354492f41414141414141416b69772f5a796f324762307a79306f2f73313630302f34342e706e6" width="654" height="78" /></a></p>
<ol>
<li>返回 CircleCI</li>
<li>點選 <code>Project settings</code> &gt; <code>Chat Notifications</code></li>
<li>貼上將複製的 <code>Webhook URL</code> &gt; <code>Save</code></li>
</ol>
<p><a href="https://www.fuwuqiok.com/wp-content/uploads/2016/03/687474703a2f2f322e62702e626c6f6773706f742e636f6d2f2d4d34304773505f696b39512f56547055714f41516c67492f41414141414141416b69592f31556f54417573534279342f73313630302f34312e706e67"><img class="attachment-medium" src="https://www.fuwuqiok.com/wp-content/uploads/2016/03/687474703a2f2f322e62702e626c6f6773706f742e636f6d2f2d4d34304773505f696b39512f56547055714f41516c67492f41414141414141416b69592f31556f54417573534279342f73313630302f34312e706e67" alt="687474703a2f2f322e62702e626c6f6773706f742e636f6d2f2d4d34304773505f696b39512f56547055714f41516c67492f41414141414141416b69592f31556f54417573534279342f73313630302f34312e706e6" width="207" height="49" /></a></p>
<p><a href="https://www.fuwuqiok.com/wp-content/uploads/2016/03/687474703a2f2f342e62702e626c6f6773706f742e636f6d2f2d70416e74524e30694252632f565470557171504a6479492f41414141414141416b69732f496e517278586c4a436d302f73313630302f34322e706e67"><img class="attachment-medium" src="https://www.fuwuqiok.com/wp-content/uploads/2016/03/687474703a2f2f342e62702e626c6f6773706f742e636f6d2f2d70416e74524e30694252632f565470557171504a6479492f41414141414141416b69732f496e517278586c4a436d302f73313630302f34322e706e67" alt="687474703a2f2f342e62702e626c6f6773706f742e636f6d2f2d70416e74524e30694252632f565470557171504a6479492f41414141414141416b69732f496e517278586c4a436d302f73313630302f34322e706e6" width="220" height="65" /></a></p>
<p><a href="https://www.fuwuqiok.com/wp-content/uploads/2016/03/687474703a2f2f322e62702e626c6f6773706f742e636f6d2f2d76337161332d786b3341512f565470557139364f6952492f41414141414141416b696b2f635139436759396c3058772f73313630302f34332e706e67"><img class="attachment-medium" src="https://www.fuwuqiok.com/wp-content/uploads/2016/03/687474703a2f2f322e62702e626c6f6773706f742e636f6d2f2d76337161332d786b3341512f565470557139364f6952492f41414141414141416b696b2f635139436759396c3058772f73313630302f34332e706e67" alt="687474703a2f2f322e62702e626c6f6773706f742e636f6d2f2d76337161332d786b3341512f565470557139364f6952492f41414141414141416b696b2f635139436759396c3058772f73313630302f34332e706e6" width="300" height="445" /></a></p>
<ol>
<li>類似的步驟，將 GitHub 的通知加入 Slack：</li>
</ol>
<p><a href="https://www.fuwuqiok.com/wp-content/uploads/2016/03/687474703a2f2f342e62702e626c6f6773706f742e636f6d2f2d5a426d55686a595535586f2f565470557277546e3758492f41414141414141416b6a452f6b617837544264465668412f73313630302f34352e706e67"><img class="attachment-medium" src="https://www.fuwuqiok.com/wp-content/uploads/2016/03/687474703a2f2f342e62702e626c6f6773706f742e636f6d2f2d5a426d55686a595535586f2f565470557277546e3758492f41414141414141416b6a452f6b617837544264465668412f73313630302f34352e706e67" alt="687474703a2f2f342e62702e626c6f6773706f742e636f6d2f2d5a426d55686a595535586f2f565470557277546e3758492f41414141414141416b6a452f6b617837544264465668412f73313630302f34352e706e6" width="551" height="71" /></a></p>
<p><a href="https://www.fuwuqiok.com/wp-content/uploads/2016/03/687474703a2f2f332e62702e626c6f6773706f742e636f6d2f2d6f79475a51765442484c382f56547055723879697935492f41414141414141416b69382f6d595f525561547266706b2f73313630302f34362e706e67"><img class="attachment-medium" src="https://www.fuwuqiok.com/wp-content/uploads/2016/03/687474703a2f2f332e62702e626c6f6773706f742e636f6d2f2d6f79475a51765442484c382f56547055723879697935492f41414141414141416b69382f6d595f525561547266706b2f73313630302f34362e706e67" alt="687474703a2f2f332e62702e626c6f6773706f742e636f6d2f2d6f79475a51765442484c382f56547055723879697935492f41414141414141416b69382f6d595f525561547266706b2f73313630302f34362e706e6" width="290" height="160" /></a></p>
<p><a href="https://www.fuwuqiok.com/wp-content/uploads/2016/03/687474703a2f2f342e62702e626c6f6773706f742e636f6d2f2d706a6d686a6347656268512f5654705573556f547877492f41414141414141416b6a492f30516f6671664e6b5566342f73313630302f34372e706e67"><img class="attachment-medium" src="https://www.fuwuqiok.com/wp-content/uploads/2016/03/687474703a2f2f342e62702e626c6f6773706f742e636f6d2f2d706a6d686a6347656268512f5654705573556f547877492f41414141414141416b6a492f30516f6671664e6b5566342f73313630302f34372e706e67" alt="687474703a2f2f342e62702e626c6f6773706f742e636f6d2f2d706a6d686a6347656268512f5654705573556f547877492f41414141414141416b6a492f30516f6671664e6b5566342f73313630302f34372e706e6" width="751" height="77" /></a></p>
<p><a href="https://www.fuwuqiok.com/wp-content/uploads/2016/03/687474703a2f2f312e62702e626c6f6773706f742e636f6d2f2d315451324558564556764d2f56547055733254327576492f41414141414141416b6a512f526e3561567359665553412f73313630302f34382e706e67"><img class="attachment-medium" src="https://www.fuwuqiok.com/wp-content/uploads/2016/03/687474703a2f2f312e62702e626c6f6773706f742e636f6d2f2d315451324558564556764d2f56547055733254327576492f41414141414141416b6a512f526e3561567359665553412f73313630302f34382e706e67" alt="687474703a2f2f312e62702e626c6f6773706f742e636f6d2f2d315451324558564556764d2f56547055733254327576492f41414141414141416b6a512f526e3561567359665553412f73313630302f34382e706e6" width="230" height="155" /></a></p>
<ol>
<li>測試 Slack 通知，是否能夠順利運作，新增一條 <code>test-slack</code> 分支：</li>
</ol>
<div class="highlight highlight-source-shell">
<pre>$ git branch test-slack
$ git checkout test-slack</pre>
</div>
<ol>
<li>修改 <code>index.js</code>：</li>
</ol>
<div class="highlight highlight-source-js">
<pre><span class="pl-c">// index.js</span>
<span class="pl-c">// ...</span>
<span class="pl-smi">app</span>.<span class="pl-en">get</span>(<span class="pl-s"><span class="pl-pds">'</span>/<span class="pl-pds">'</span></span>, <span class="pl-k">function</span> (<span class="pl-smi">req</span>, <span class="pl-smi">res</span>) {
  <span class="pl-smi">res</span>.<span class="pl-c1">send</span>(<span class="pl-s"><span class="pl-pds">'</span>Hello Slack!<span class="pl-pds">'</span></span>);
});
<span class="pl-c">// ...</span></pre>
</div>
<ol>
<li>Commit &amp; Push：</li>
</ol>
<div class="highlight highlight-source-shell">
<pre>$ git add index.js
$ git commit -m <span class="pl-s"><span class="pl-pds">"</span>index.js: update to test slack<span class="pl-pds">"</span></span>
$ git push -u origin test-slack</pre>
</div>
<ol>
<li>CircleCI 通過測試，開啟一個 Pull Request</li>
<li>將 <code>test-slack</code> merge 回 <code>master</code>，觸發 CircleCI 自動部署</li>
</ol>
<p><a href="https://www.fuwuqiok.com/wp-content/uploads/2016/03/687474703a2f2f342e62702e626c6f6773706f742e636f6d2f2d795a376f566f6854426f452f56547055745a6936506e492f41414141414141416b6a672f47345f4464567465444b672f73313630302f35302e706e67"><img class="attachment-medium" src="https://www.fuwuqiok.com/wp-content/uploads/2016/03/687474703a2f2f342e62702e626c6f6773706f742e636f6d2f2d795a376f566f6854426f452f56547055745a6936506e492f41414141414141416b6a672f47345f4464567465444b672f73313630302f35302e706e67" alt="687474703a2f2f342e62702e626c6f6773706f742e636f6d2f2d795a376f566f6854426f452f56547055745a6936506e492f41414141414141416b6a672f47345f4464567465444b672f73313630302f35302e706e6" width="515" height="475" /></a></p>
<p><a href="https://www.fuwuqiok.com/wp-content/uploads/2016/03/687474703a2f2f312e62702e626c6f6773706f742e636f6d2f2d43376b5051362d5a376b6f2f56547055743855494d46492f41414141414141416b6a6f2f4a66724a4232554c45486f2f73313630302f35312e706e67"><img class="attachment-medium" src="https://www.fuwuqiok.com/wp-content/uploads/2016/03/687474703a2f2f312e62702e626c6f6773706f742e636f6d2f2d43376b5051362d5a376b6f2f56547055743855494d46492f41414141414141416b6a6f2f4a66724a4232554c45486f2f73313630302f35312e706e67" alt="687474703a2f2f312e62702e626c6f6773706f742e636f6d2f2d43376b5051362d5a376b6f2f56547055743855494d46492f41414141414141416b6a6f2f4a66724a4232554c45486f2f73313630302f35312e706e6" width="615" height="45" /></a></p>
<p>That’s it! On your next build, you’ll start seeing CircleCI build notifications in your Slack chatroom.</p>
<p>結束！可以看見 Slack channel 會顯示每一個步驟的通知過程：</p>
<p><a href="https://www.fuwuqiok.com/wp-content/uploads/2016/03/687474703a2f2f332e62702e626c6f6773706f742e636f6d2f2d4e71796a57466f317245452f56547055744578583343492f41414141414141416b6a592f47537943665037777735732f73313630302f34392e706e67"><img class="attachment-medium" src="https://www.fuwuqiok.com/wp-content/uploads/2016/03/687474703a2f2f332e62702e626c6f6773706f742e636f6d2f2d4e71796a57466f317245452f56547055744578583343492f41414141414141416b6a592f47537943665037777735732f73313630302f34392e706e67" alt="687474703a2f2f332e62702e626c6f6773706f742e636f6d2f2d4e71796a57466f317245452f56547055744578583343492f41414141414141416b6a592f47537943665037777735732f73313630302f34392e706e6" width="450" height="580" /></a></p>
<p><code>eb open</code> 打開瀏覽器查看結果，成功自動部署新版本：</p>
<div class="highlight highlight-source-shell">
<pre>$ eb open env-production</pre>
</div>
<p><a href="https://www.fuwuqiok.com/wp-content/uploads/2016/03/687474703a2f2f312e62702e626c6f6773706f742e636f6d2f2d654a7367563843654430342f565470557544466c7237492f41414141414141416b6a732f666131785759656b7849732f73313630302f35322e706e67"><img class="attachment-medium" src="https://www.fuwuqiok.com/wp-content/uploads/2016/03/687474703a2f2f312e62702e626c6f6773706f742e636f6d2f2d654a7367563843654430342f565470557544466c7237492f41414141414141416b6a732f666131785759656b7849732f73313630302f35322e706e67" alt="687474703a2f2f312e62702e626c6f6773706f742e636f6d2f2d654a7367563843654430342f565470557544466c7237492f41414141414141416b6a732f666131785759656b7849732f73313630302f35322e706e6" width="471" height="65" /></a></p>
<h2><a id="user-content-結語" class="anchor" href="https://github.com/zeus911/hello-ci-workflow#%E7%B5%90%E8%AA%9E"></a>結語</h2>
<blockquote><p>「書山有路勤為徑，學海無涯苦作舟。」——韓愈</p></blockquote>
<p>DevOps 的開發流程與工具每天都在不斷推陳出新，請站在巨人的肩膀上、保持一顆「活到老、學到老」的心。</p>
<p>我將這個範例的程式碼放在 <a href="https://github.com/amowu/hello-ci-workflow">GitHub</a> 上，有興趣的人可以參考看看。</p>
<p>文章若有需要改進的地方，還請不吝指教，感激不盡。</p>
<h2><a id="user-content-參考" class="anchor" href="https://github.com/zeus911/hello-ci-workflow#%E5%8F%83%E8%80%83"></a>參考</h2>
<ul>
<li><a href="https://en.wikipedia.org/wiki/DevOps">DevOps &#8211; Wikipedia</a> [<a href="https://zh.wikipedia.org/zh/DevOps">中文</a>]</li>
<li><a href="https://en.wikipedia.org/wiki/Continuous_integration">Continuous integration（持續整合）- Wikipedia</a> [<a href="https://zh.wikipedia.org/wiki/%E6%8C%81%E7%BA%8C%E6%95%B4%E5%90%88">中文</a>]</li>
<li><a href="https://en.wikipedia.org/wiki/Continuous_delivery">Continuous delivery（持續交付）- Wikipedia</a></li>
<li><a href="http://blog.eavatar.com/post/2013/10/continuous-integration-deployment-delivery/">山姆鍋對持續整合、持續部署、持續交付的定義</a></li>
<li><a href="http://rettamkrad.blogspot.tw/2014/11/integrate-circleci-with-github.html">Integrate CircleCI with GitHub</a></li>
<li><a href="https://guides.github.com/introduction/flow/">Understanding the GitHub Flow · GitHub Guides</a></li>
<li><a href="https://docs.docker.com/examples/nodejs_web_app">Dockerizing a Node.js Web App</a></li>
<li><a href="https://circleci.com/integrations/docker">Integration with Docker Containers &#8211; CircleCI</a></li>
<li><a href="https://circleci.com/docs/docker">Continuous Integration and Delivery with Docker</a></li>
<li><a href="http://docs.aws.amazon.com/elasticbeanstalk/latest/dg/eb-cli3-getting-started.html">Getting Started with EB CLI 3.x</a></li>
<li><a href="http://blog.circleci.com/slack-integration/">Slack Integration | The Circle Blog</a></li>
<li><a href="https://realpython.com/blog/python/docker-in-action-fitter-happier-more-productive/">Docker in Action &#8211; Fitter, Happier, More Productive</a> [<a href="http://segmentfault.com/a/1190000002598713">中文</a>]</li>
<li><a href="http://qiita.com/sawanoboly/items/28e98827bc044abdc32f">CircleCIからAWS Elastic Beanstalkにpush</a></li>
<li><a href="http://waytothepiratecove.blogspot.tw/2015/03/delivery-pipeline-and-zero-downtime.html">Delivery pipeline and zero downtime release</a></li>
<li><a href="http://sauceio.com/index.php/2014/12/ci-cd-with-docker-beanstalk-circleci-slack-gantree/">Re-Blog: CI &amp; CD With Docker, Beanstalk, CircleCI, Slack, &amp; Gantree</a></li>
<li><a href="http://mherman.org/blog/2015/03/06/node-with-docker-continuous-integration-and-delivery">Node With Docker &#8211; Continuous Integration and Delivery</a></li>
<li><a href="http://www.infoq.com/cn/articles/docker-integrated-test-and-deployment">深入浅出Docker（四）：Docker的集成测试部署之道</a></li>
</ul>
<p><a rel="nofollow" href="https://www.fuwuqiok.com/%e4%bd%bf%e7%94%a8-docker%e3%80%81github-flow%e3%80%81circleci%e3%80%81aws-elastic-beanstalk-%e8%88%87-slack-%e4%be%86%e5%ae%8c%e6%88%90%e6%8c%81%e7%ba%8c%e6%95%b4%e5%90%88%e8%88%87%e6%8c%81%e7%ba%8c/">使用 Docker、GitHub Flow、CircleCI、AWS Elastic Beanstalk 與 Slack 來完成持續整合與持續交付的開發流程</a>，首发于<a rel="nofollow" href="https://www.fuwuqiok.com">服务器安全维护工作室</a>。</p>
]]></content:encoded>
			<wfw:commentRss>https://www.fuwuqiok.com/%e4%bd%bf%e7%94%a8-docker%e3%80%81github-flow%e3%80%81circleci%e3%80%81aws-elastic-beanstalk-%e8%88%87-slack-%e4%be%86%e5%ae%8c%e6%88%90%e6%8c%81%e7%ba%8c%e6%95%b4%e5%90%88%e8%88%87%e6%8c%81%e7%ba%8c/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
