Nerd

那些你們看起來很 Nerd 的事。

前言

最近這幾週抽了些時間,還有找一些白老鼠,開始做幾個小時的「教學的動作」,雖然成效目前看起來不是很好,但的確會發現某些在工程師圈子可能是習以為常的東西,但在一般人眼中就是個 Nerd 才會做的事情。

但我這個人的缺點就是臉皮薄,十分在意旁人投以詭異眼神,所以還是把這些事情好好的解釋一下,這次想聊的就是經常出現而且都是縮寫的 CI 與 CD,不過因為每間公司、每個專案都有不同的背景跟歷史共業,所以我講述的可能也是錯的,就自行斟酌囉!

CI

Continuous IntegrationContinuous delivery,翻譯成中文的話應該是「持續集成」跟「持續交付」,望文生義,就是一直做一直做集成與交付,好的,結束。

事情當然沒有這麼簡單,我們先回歸本質,理解這些東西存在的意義是什麼?

最終的目的當然都是將完整的產品(程式碼)交予給客戶,

傳統的開發方式是每個人都在自己的機器上實作功能,等到最後在統整起來,這用聽的就感覺起來很不牢靠,整合越多人寫的程式碼,困難度可以說是指數值的成長,如果最後合併起來出了什麼問題,要除錯也是個大工程,不僅耗時而且傷神。遇到了幾次之後,工程師們開始著手找出解決的方法。

「既然寫得多到最後在合併很困難,那我就每天都合併就好了啊?」

Monkey in BoJack Horseman

所以我們寫出程式碼之後天天合併,甚至一天合併十幾次,我們在這樣小而短的開發循環中,可以即時的發現錯誤且快速修正,並在這樣的循環內一步一步確認開發結果符合需求,防止開發方向偏離。這就是 Continuous Integration 持續集成的概念。

CD

在 CI 這樣的概念下開發,工程師們就發現有些東西實在太繁瑣了,我每次開發一個功能,都要先本機端測試,然後合併前還要給其他人審核(Review),合併之後說不定跟別人的 code 還會衝到要修,修好了還要自己部署到 staging server,之後還要再通知人去 staging server 測試,然後測試沒問題了最後才會放上正式的環境 Production Server,這一切實在太麻煩了。

當然,工程師就是懶,某些工具便被做出來簡化這些流程。

Tools for CI/CD

像是多人開發的一定會用到的分散式版本管理 Git,Git 的託管平台 GitHub,基於 Git 產生的多人協作開發原則 Git Flow / GitHub Flow,使用 Jenkins、Circle CI 或是 Travis CI 來輔助 Code 整合的繁複操作,使用 Docker 統一開發人員、測試人員、正式產品的環境建置,使用 Slack 進行團隊溝通已經訊息中心等等。

其實相似的概念在現實生活中就是產線的自動化,一切一切都是基於縮短開發過程中重複的時間,減少操作步驟可能導致的人為疏失,將人的產能應用在最需要的地方,並持續的將產品往正確的方向堆砌。

所以我們使用了這些工具協助我們整合程式碼,讓程式碼隨時處於一個不會錯誤、可以交付的狀態,這就叫做 Continuous delivery 持續交付。

那也因為程式碼是隨時可交付的狀態,所以我們可以讓程式碼在整合成功確認沒問題時,借助工具自動幫我們部署(Deploy)上正式環境提供給使用者使用,於是就稱作 Continuous Deployment 持續部署。

簡單的譬如說

我們現在有三個工程師K、V、M好了,他們共同維護一個全國最大線上不知道什麼中心的網站。

KVM

我們先請工程師V把 CI/CD 的環境都架好了,真的超強。

Setting Up

接著呢,工程師M開了個分支(branch)把 Code 寫完了,使用 Git Commit 之後,推上 GitHub 送出 Pull Request 在線等待合併(Merge),而 CI 工具此時發現有分支,就會開始自動做一些已經V設定好的測試,並且將結果報告至 GitHub。

Branch OK

報告表示此分支沒有問題時,工程師K就會上來看看有沒有什麼更動(Review),K覺得沒有問題就會按下 Merge 合併的按鈕,於是這個分支的 Code 就被合併至 develop 這個大分支中。

此時 CI 工具同時發現這個 develop 分支有變動,就會開始啟動部署程序(deploy),將 develop 部署至 staging 測試機器上,並且在 Slack 上通知其他QA人員來測試。

Merge in to develop

如果沒有問題,過了幾次這樣循環後到了一個階段結束,工程師V就會將 develop 分支合併到 master,此時 CI 工具發現 master 分支有變動,於是將 master 部署至正式環境 production server 給使用者使用。此時工程師M所開發的功能終於呈現給使用者。

CI/CD

這一串過程如果再以前的軟體開發模式下可能需要耗費幾天甚至一週,但在建構好完善的 CI/CD 的環境之下,這樣的一個版本更迭在一天內就會完成,

最後

這篇文章再寫的時候其實刪除了很多部分,像是一些輔助程式碼的工具、紀錄 Log 日誌的工具還有 Docker 也只有提到名字,並不是因為我覺得不重要,而是我認為重要的是理解整個過程,了解為何 CI/CD、這樣做有什麼好處、最基本的情況應該是如何,其他的工具都是某些環節加強而已,也不會顛覆流程,之後碰到再學習就會了。

有些地方可能會將 CI/CD 跟 Agile 還是 Scrum 綁在一起,但我覺得,程式開發將 CI/CD 的地基打好對於其本身一定是有極大益處的,但人的部分反而沒有這麼絕對,就算你只是自己開發或是打發時間的 side project,CI/CD 的投資報酬仍是可觀且必要的。

大概是這樣,謝謝大家!