Post

CI/CD 實戰指南(一):CI/CD 是什麼?如何透過 CI/CD 打造穩定高效的開發團隊?工具選擇?

以 App (iOS) Team 為例,帶您從 0 認識 CI/CD 與導入後能帶來的實質價值。

CI/CD 實戰指南(一):CI/CD 是什麼?如何透過 CI/CD 打造穩定高效的開發團隊?工具選擇?

ℹ️ℹ️ℹ️ Click here to view the English version of this article, translated by OpenAI.


CI/CD 實戰指南(一):CI/CD 是什麼?如何透過 CI/CD 打造穩定高效的開發團隊?工具選擇?

以 App (iOS) Team 為例,帶您從 0 認識 CI/CD 與導入後能帶來的實質價值。

Photo by [Leif Christoph Gottwald](https://unsplash.com/@project2204?utm_content=creditCopyText&utm_medium=referral&utm_source=unsplash){:target="_blank"}

Photo by Leif Christoph Gottwald

前言

歷經了兩次在不同開發團隊建置 App CI/CD 的經驗,最近終於有時間整理這段從「為什麼要做」到「該怎麼做」的心路歷程;不敢保證是最標準的 CI/CD 工作流程,但絕對是一個值得參考的起點,幫助您的團隊開始導入、提升產品穩定性與整體開發效率。

章節

本系列文章會從「CI/CD 是什麼、能帶來哪些價值」開始講起,接著開始手把手實作「如何用 GitHub Actions + self-hosted Runner 搭建 CI/CD 環境」並「以 App 開發為例,實際導入 CI 和 CD」,最後還會介紹如何「使用Google Apps Script Web App 結合 GitHub Actions,打造一個方便跨團隊使用的 App 打包平台」希望這系列內容對你有所幫助。

最終成果

廢話不多說,先上最終結果。

[Demo PR](https://github.com/ZhgChgLi/github-actions-ci-cd-demo/pull/11){:target="_blank"}

Demo PR

[Demo Web App](https://script.google.com/macros/s/AKfycbxk1nYhzfBzqny34rvBlxmcWMEQbWTL5a28mBmYId0NDaCZd0S-U3ytpBoTi2wZp0d6cg/exec){:target="_blank"}

Demo Web App

CI/CD — 全部都使用 GitHub Actions 開發,好維護、好擴充。

CI:

  • 發 PR 自動觸發單元測試
  • 依照改動檔案範圍執行對應測試
  • 測試通過 (passed) 後才能 Merge PR

CD:

  • Google Apps Script Web App (CD 打包介面) 工程師、QA、PM 都可以透過這個網站在電腦或手機上打包 App
  • GitHub Actions Self-hosted Runner 使用自己的機器跑 CI/CD 用量吃到飽
  • 串接 Firebase App Distribution API 直接取得打包的測試版下載連結

Automation :

  • 發 PR 自動 Assign self
  • 發 PR 自動隨機指定 Reviewer
  • 標記 PR Size Label

Demo Web App/Project

Sign in Edit description script.google.com

CI/CD 是什麼?

故事 — 無 CI/CD 的開發流程

在談 CI/CD 究竟是什麼之前我們先拋開「CI/CD」這個詞,先來回想一下一個初創什麼工作流程都沒有導入的開發團隊,會是怎麼工作的,大致簡略為下圖流程:

  1. 產品有一個 Bug,Developer T 從主分支開分支 fix/bug-c 分支進行修正,修正完後 Merge 回主分支。
  2. 緊接著 Developer Z 從主分支開分支 feature/a 做 需求 A,做到一半發現功能怪怪的, 查了一下才發現原來當前功能被改壞、測試也壞了 ,回頭通知 Developer T 進行修正。
  3. 一切開發完畢後,Developer Z 使用他的電腦打包版本給 QA 測試,來來回回修正跟打包 ,最後沒問題後將功能回到主分支。
  4. 很快地也到了 Sprint 尾聲需要打包釋出給使用者;Developer Z 先放下手上工作 ,協助從主分支打包給 QA 進行 Regression 測試,同樣 來來回回修正問題跟重新打包 ,完成後打包送審 App。
  5. Apple/Google 審核完畢後發布給使用者使用。

問題

在以上故事中我們可以歸納出兩個大問題。

Question 1: 對當前正確的功能異動無任何統一檢查機制。

  • 不符合 Coding Style 的程式碼也能 Merge
  • 就算 Build 不起來我也能 Merge
  • 異動後基本的 Unit Tests、重要檢查項目都沒過也能 Merge
  • 我的環境功能正確但其他人不一定正確
  • 影響到其他正在開發的人

Question 2: 耗費大量人力時間在打包工作上。

  • 打包要透過工程師人力打包,中斷當前開發工作
  • 來回在打包與開發之間,心流切換成本極高
  • 打包等待時間無法進行其他開發工作
  • 工程師的時間成本就是金錢
  • 人工操作可能出錯
  • QA 要請工程師打包 (來回溝通)

CI — Continuous Integration 持續整合

對應 Question 1「持續整合」旨在確保所有變動都能自動執行統一環境的 Build & Test 確保進入生產環境之前的改動都通過所有測試案例及符合團隊規範 — 「持續地自動確保正確的程式碼整合到生產環境」。

另外也可以增加 Nightly Build、更多的自動化測試環節,確保穩定性。

CD — Continuous Delivery / Deployment 持續交付/部署

對應 Question 2「持續部署」旨在確保程式碼在 CI 環節無異常之後,將改動結果自動完成打包部署繁瑣流程給內部測試(QA, Debug, Staging, Beta…)或外部上線(Production, Release…)。

  • Continuous Deployment: 全自動直接部署到 Production 環境
  • Continuous Delivery: 只自動部署到 Staging/Debug 環境可,需手動驗證確認沒問題之後才會再部署到 Production 環境

依照 App 開發的場景,比較偏向是 Continuous Delivery 持續交付 ,我們希望 App 最終上線之前是由人工把關確認完全無問題後才發布,確保釋出時間與功能正確性。

故事 — 透過 CI/CD 打造穩定高效的開發團隊

回頭看我們的故事,導入 CI/CD 後:

  • CI 所有人的調整都需要經過 自動化測試驗證通過後才能進入主分支、增加 Nightly Build 定時自動化測試環節提升穩定性。
  • CD 統一都使用 CD 打包,Developer T 和 Developer Z 可以完全專注在業務開發上、減少人工溝通與操作錯誤。

團隊工作效率與產品穩定性 🚀🚀🚀🚀🚀

CI/CD 的價值

結合敏捷開發的核心理念「小步快跑,快速迭代」CI/CD 為其提供了「頻繁持續迭代功能」時的穩定性與工作效率的基石。

自動統一驗證迭代結果

  • 確保所有調整都符合正確的預期結果、不影響其他功能、不影響其他成員

自動執行繁瑣的部署流程

  • 讓團隊成員可以專注在主要業務開發、減少人工操作錯誤

CI/CD 的成效

回顧 2021 年在 Pinkoi 的演講「 2021 Pinkoi Tech Career Talk — 高效率工程團隊大解密 」其實說來說去都是差不多的內容,不外乎就是「自動化、減少人跟人的依賴、專注在主要業務上」導入 CI/CD 也完全符合上述三個方向,藉此我們也可以用同樣的方法來估算成效。

另外有一點需要再次 Highlight 的是 心流切換成本

當我們持續投入工作一段時間後就會進入「心流」狀態,此時的思緒、生產力都達到巔峰,能提供做好最有效的產出;但如果被打斷,要重新回到心流,又會再需要一段時間,這邊以 30 分鐘為例。

在無 CI/CD 的場景中可能是: 花很多時間才發現是被改壞再回頭溝通調整(CI)、QA/PM 來請工程師幫忙打包測試版 App (CD)。

CI/CD 成效估算

團隊人數 6 人 一個月來計算

團隊人數 6 人 / 一個月來計算

這邊我們以每個月為基準,假設在無 CI/CD 流程時,每個月會發生 4 次意外改壞主分支的問題,造成後續修正、溝通的成本,約花費 720 分鐘;加上每個月打包測試版、正式版及因人工操作造成錯誤的可能,總和約 1,010 分鐘;以工程師月薪 8 萬計算,每個月就造成約 1 萬 3 的成本浪費。

CI/CD 建置成本

  • 人力成本: 照本系列文章建置,粗估需投入人力 1 人花費 10 天 = 4,800 分鐘 能完成。(~= NT$36,384 )
  • 設備與執行成本: 使用 GitHub Actions self-hosted Runner 只需在前期採購 1–2 台 Mac-Mini 或直接使用現有汰換的 MacBook Pro 就能當成 CI/CD Runner 提供服務使用。 以 6 人團隊採購一台全新的 Mac Mini 為例:32G RAM M4 Mini (= NT$40,900 )

總花費成本約 NT$80,000 元就能完成建置,約半年後開始享受效益。

聲明: 這裡只是提出一種效益計算的方式,不一定是最準確的;只是給大家一個概念去延伸, 讓管理決策層能看到 CI/CD 的效益 進而授權推動完成整個工作流程。

CI/CD 的工具選擇

雲服務 Bitrise / XCode Cloud

  • Bitrise: 最早期主打提供 App CI/CD 的雲服務,第一次接觸 CI/CD 也是使用 Bitrise,它提供友善直覺的步驟編輯工具,可以很快的設定好 App CI/CD 流程。 缺點: 最早期是 $99 鎂吃到飽,Apple M 系列處理器剛出來的時候一度改成用量計費( 養套殺 ),那時候估團隊用量每個月至少要花 $500 鎂,索性就遷移至 GitHub Actions 了。 但最近看官網,現在有提供 1 App / 1 Concurrent / 吃到飽 / $89 鎂 / 月。
  • XCode Cloud: 100 小時 / 1 個月 / $50 鎂,優點是與 XCode、App 開發高度整合;但缺點同樣是,無法提供 Android 使用、要客製化一些步驟會有些困難;但如果是純 iOS 的小型 App 我會再次考慮直接使用。

實在很怕 雲服務又養套殺 、希望可控性在自己手上,所以改考慮地端服務。

地端服務 Jenkins / GitHub Actions / Gitlab CI/CD

  • Gitlab CI/CD: 比 GitHub Actions 推出的時間更早、功能更完整,但是我們的專案是託管在 GitHub 上所以就不考慮用 Gitlab CI/CD 了;但是兩邊功能類似,本系列文章會以使用 GitHub Actions 為例。
  • GitHub Actions GitHub 2018 年才推出的 CI/CD 服務,跟 GitHub 專案直接綁定,在這幾年持續更新完善功能,有很多封裝好的步驟 ( Marketplace ) 可以直接使用;支援 self-hosted runner 可以使用自己的機器無限使用。(等於混合雲了)
  • Jenkins: 一個專門處理 CI/CD 的開源免費工具、古老但是功能強大;從應用層任務設計、權限管理到底層服務派發執行,Jenkins 全包;同樣有 Plugins 可以直接搭配使用,是早期 DevOps CI/CD 的必備工具。

Jenkins v.s. GitHub Actions

TL;DR

在沒有專門做 DevOps 的 App Team,要 App 開發者從 0 到 1 架設維護 Jenkins 環境門檻太高、會的人也不多還會衍生出網路安全問題;選擇直接用 GitHub Actions,App 開發者只需專注在 CI/CD 流程設計,大概掃一下官方文件怎麼撰寫跟啟動 Runner,就能快速搭建出免費穩定又安全的 CI/CD 服務。

以下僅以 App CI/CD 架設為出發點做比較,並不適用所有技術場景。

架設與維護難易度 Jenkins >>> GitHub Actions

這邊先用一張不是很專業的結構分層圖來說明兩者的差異,Jenkins 如前述是從上到下功能全包,所以在自架上會複雜許多;而 GitHub Actions,GitHub Actions 本身只需要在 GitHub 上撰寫 YAML 工作流程,本地機器只需要註冊好 GitHub self-hosted Runner (5 個指令就完成),GitHub 就會自動派發任務給本地機器執行了,其他包涵 Github Actions/Runner 版本升級或是任務派發問題都是 GitHub 負責維護,我們無需處理。

還有另一個比較麻煩的點是 Jenkins 是獨立於 Git 的服務,之間要透過 API (e.g. GitHub API/WebHook) 進行溝通,設定又更複雜了。

之前也從身邊能接觸到的 iOS 開發者(約 30 位)做過調查,懂 Jenkins 的屈指可數( 2 位) 而有在使用 GitHub Actions 的則超過 (10 位) 畢竟就是寫一寫 YAML 就能完成 CI/CD 任務。

學習難易度 Jenkins »> GitHub Actions

同上只需參考官方文件學習 GitHub Actions 可用 YAML 指令跟如何在本地起自己的 Runner 即可。

穩定性 GitHub Actions > Jenkins

這點我覺得 GitHub Actions 略勝 Jenkins。

Jeknins 有機會因為系統升級或裝到有衝突的 Plugin 導致服務崩潰 (不過如果跑得好好的不去動它基本上沒有問題)。

GitHub Actions 受限於 GitHub 服務狀態 (如果 GitHub 掛也會跟著掛),但是發生頻率不高,平均在線率都能維持在 99.9%;真出問題也不用處理,坐等修復。

安全性 GitHub Actions > Jenkins

考量到 GitHub Actions/Runner 服務本身是 GitHub 在維護跟自動更新這點可能會比 Jenkins 需要手動更新來的更安全。

另外 Jenkins 跟 GitHub 溝通之間需要開 API/WebHook 口相對比較危險,GitHub 與 GitHub Actions 之間是無痛整合、GitHub Actions 與 self-hosted Runner 之間是觀察者模式,self-hosted Runner 會去跟 GitHub 要任務回來做,所以 Runner 本身不需開對外接口。

但如果是全封閉網路環境,Jenkins 會比 GitHub Actions 安全。

權限控管 Jenkins »> GitHub Actions

這點需要特別挑出來比較,Jenkins 可以另外設定帳號登入權限進行控管;GitHub Actions 則直接與 GitHub Repo 進行綁定,要有 Repo 權限的人才能使用。

*因此後面的文章才會又用 GAS Web App 搭建跨團隊的操作平台。

使用廣度 Jenkins »> GitHub Actions

在有完整 DevOps Team 的團隊無庸置疑的應該還是會選擇 Jenkins,畢竟在其他領域 (例如 Web, 後端, Java…) 還是 Jenkins 運行最久、Plugin 做多最好用,並且可以統一建置一套 CI/CD 服務所有團隊使用方便控管,或是後端部署完前端自動部署這種複雜的 CI/CD 場景。

*GitHub Actions 後來也支援跨 Repo Actions/Runner 了。

第三方套件豐富度 Jenkins > GitHub Actions

就數量上 GitHub Actions 大於 Jenkins,但是 Jenkins 理的 CI/CD 功能比較有深度跟強大,GitHub Actions 很多只是自動化的功能。

功能深度 Jenkins »> GitHub Actions

這點沒法比,Jenkins 已做了快 20 年,GitHub Actions 還有很多功能需要再補上;例如:權限管理、Secret 管理(目前只限純文字,密鑰檔案的話要先轉成純文字)、Cache/Artifact 目前只支援 Cloud…等等

擴展上,GitHub Self-hosted Runner 也支援 Docker or k8s

客製化深度 Jenkins »> GitHub Actions

Jenkins 從頭到尾都掌控在自己手上,客製化的權限比較大,可以影響到整個系統,GitHub Actions 只能在應用層客製化不同步驟而已。

例如目前 GitHub Actions 內建的 Artifacts 不支援 self-hosted,那也只能在步驟中改成 sh copy 到其他目錄,無法自行客製化實現 Artifacts。

*App CI/CD 場景也用不到太深度的功能。

易用性 GitHub Actions »> Jenkins

介面上 GitHub Actions 是新的工具在介面使用上比 Jenkins 更容易使用; 腳本設定上 Jenkins 是 Pipeline Script 儲存在 Jenkins 上、GitHub Actions 是 YAML 檔跟著專案 Git 管理,也比 Jenkins 容易設定。

費用風險 Jenkins > GitHub Actions

Jenkins 全開源免費權掌握在手,GitHub Actions 部分開源但任務派發與執行是 GitHub 封閉的 SAAS 服務;目前政策是 GitHub Actions 完全免費,使用 GitHub Runner 才要錢(Private Repo),使用 self-hosted runner 則不用。

Google Apps Script Web App 的用途與為何選擇

另一個工具選擇是 Google Apps Script Web App,會需要多一個這個的原因是 GitHub Actions 自帶的表單功能過於陽春(介面太工程、只能靜態)並且執行權限跟 GitHub Repo 綁定在一起,如果我們需要提供給其他職能夥伴使用會非常的麻煩。

如下:

CD 打包會希望讓操作人填寫一些資訊,例如 Release Notes。

因此我們需要一個「介面」工具提供給其他夥伴使用或甚至是自己工程師更方便的使用。

所需情境:

在這個比較好用的「介面」上填寫需要的資訊,串接專案管理工具(e.g. Jira, Asana) 取得 Task 或是 GitHub 直接取得 PR 列表,直接下拉選單選擇後送出,再透過 GitHub API 觸發 GitHub Actions 進行打包。

Slack

第一次導入 CI/CD 的時候我們選擇串接 Slack API 達成類似如下效果:

[https://slack.com/intl/zh-tw/blog/productivity/workflow-builder-tools-automation-examples](https://slack.com/intl/zh-tw/blog/productivity/workflow-builder-tools-automation-examples){:target="_blank"}

https://slack.com/intl/zh-tw/blog/productivity/workflow-builder-tools-automation-examples

  • 夥伴可以直接在 Slack 中使用表單填寫資訊、並觸發 CD 打包、收到 Slack 通知

使用操作起來很順暢並且統一在日常的辦公工具上(SSOT) 不需重新學習;但是他背後的問題是 開發跟維護成本非常的高 ,其中有一個原因是 Slack Outgoing-Webhook API 對響應要求非常高 (需要在 3 秒內),因此基本上可以直接排除使用 FAAS 服務簡單串接了 (e.g. Cloud Functions, GAS, Lambda…)。

之前的做法是有一位對自動化跟後端很有興趣的夥伴自己用 Kotlin+ktor 開發了一整套後端服務,然後再 GCP 起伺服器供 Slack 串接使用。

開發與維護成本非常非常高而且很難交接。

Google Apps Script — Web App

之前有分享過「 使用 Google Apps Script Web App 表單串接 Github Action CI/CD 工作 」:

[Demo Web App Form URL](https://script.google.com/macros/s/AKfycbw8SuK7lLLMdY86y3jxMJyzXqa5tdxJryRnteOnNi-lK--j6CmKYXj7UuU58DiS0NSVvA/exec){:target="_blank"}

Demo Web App Form URL

使用 Google Apps Script — Web App 的優勢是:

  • 網站 Web
  • 同 Google Workspace 企業帳號權限管理,可設定只有組織內的 Google 帳號才能存取
  • 完全免費
  • Function as a Service 不需自行架設維護伺服器
  • 較容易維護與交接
  • 手機上可以操作
  • AI Can Help! 不管是 ChatGPT 或其他 AI 工具對 GAS 都非常熟悉,可以直接動口請他幫我們製作打包表單與串接 GitHub API
  • 一樣能串接 Jira,Asana,Slack 通知 API

第二推廣我就改用 GAS Web App 給夥伴使用,同樣得到很好的反響,跟 Slack 差別就只在要多記一個網址到書籤,需要打包的時候打開網址從網頁表單操作打包。

App CI/CD 完整工具流程

這邊先附上完整的工作流程,下篇開始會逐步介紹每個工具如何使用與串接。

工具角色:

  • GitHub Actions : CI/CD 邏輯腳本程式碼
  • GitHub Actions — Self-hosted Runner : CI/CD 實際執行的地方,使用自己架設的 Runner 執行,只需要負擔機器購買成本,就能無限制使用量的執行任務。
  • Google Apps Script Web App : 因打包不一定是工程師負責,需要有一個平台給跨職能夥伴可以使用; GAS Web App 能快速打造一個 Web 工具分享網址給其他人操作使用。
  • Asana/Jira : 專案管理工具,可與 GAS Web App 串接讓 QA/PM 可以直接選擇想把包的 Task 進行打包。
  • Slack : 負責接收執行結果通知

場景:

  • End-User (QA/PM/PD/Developer): 使用 GAS Web App 送出打包表單 (撈取 Jira or Asana 任務單對應的 Branch) -> GAS 打 GitHub API -> 觸發 CD 打包 Github Actions <- GitHub self-hosted runner 監聽到任務拉回機器執行 -> 執行完畢 Slack 通知、更新 GAS Web App 打包狀態。
  • End-User (Developer): 開 PR、Push new commit 到 PR -> 觸發 CI 測試流程 <- GitHub self-hosted runner 監聽到任務拉回機器執行 -> 執行完畢 Comment 測試結果、更新 Checks。

總結

本篇主要是帶大家初步了解 CI/CD 是什麼跟帶來的效益,下一篇開始會進入技術環節,手把手帶您了解、實作 GitHub Actions CI/CD 到最終完成前文的最終成果。

系列文章:

Buy me a coffee

本系列文章花費了大量的時間精力撰寫,如果內容對您有幫助、對您的團隊有實質提升工作效率與產品品質;歡迎請我喝杯咖啡,感謝支持!

[Buy me a coffee](https://www.buymeacoffee.com/zhgchgli){:target="_blank"}

Buy me a coffee

有任何問題及指教歡迎 與我聯絡


本文首次發表於 Medium ➡️ 前往查看

ZMediumToMarkdownMedium-to-jekyll-starter 提供自動轉換與同步技術。

Improve this page on Github.

Buy me a beer

1,114 Total Views
Last Statistics Date: 2025-07-23 | 505 Views on Medium.
This post is licensed under CC BY 4.0 by the author.