CI/CD 自動化部署實踐指南 持續整合與交付提升軟體品質

me
林彥成
2022-10-10 | 5 min.
文章目錄
  1. 1. 什麼是 CI/CD?
  2. 2. 什麼是 CI/CD:持續整合與持續交付/部署
    1. 2.1. 排程工作 (Cron Job)
  3. 3. Jenkins:強大的開源自動化伺服器
  4. 4. CircleCI:基於雲端的持續整合服務
  5. 5. GitHub Actions:GitHub 原生 CI/CD 解決方案
  6. 6. 系列文章導覽
  7. 7. FAQ:CI/CD 工具常見問題
    1. 7.1. Q1:我該選擇 Jenkins 還是 GitHub Actions?
    2. 7.2. Q2:CI/CD 過程中的 API Key 或密碼應該放在哪?
    3. 7.3. Q3:自動化測試(CI)失敗時該怎麼辦?

什麼是 CI/CD?

CI (Continuous Integration, 持續整合)CD (Continuous Delivery/Deployment, 持續交付與部署) 是現代軟體開發中一套旨在自動化程式碼交付流程的實踐。CI 的核心在於頻繁將程式碼合併至主幹,並透過自動化測試確保每次合併的穩定性;而 CD 則接續 CI,將通過測試的程式碼自動建置(Build)並發布至測試或正式環境。透過 Jenkins、CircleCI 或 GitHub Actions 等自動化工具,開發團隊能減少人為手動部署的失誤、縮短產品上線週期,並維持高品質的程式碼水準,是 DevOps 文化中最重要的技術基石。


偷吃完都有記得擦嘴嗎?!背地裡在檯面下做了一些事情又不想被發現或影響另一半怎麼辦?!有沒有辦法自動化的把相關痕跡去除或隱藏?!這就是 CI/CD 要解決的問題,它旨在確保程式碼提交後,減少因少部分檯面下的更動影響程式運行的流程,確保程式碼的品質。

什麼是 CI/CD:持續整合與持續交付/部署

CI (Continuous Integration)CD (Continuous Delivery/Deployment) 的目的就是從測試、建置到部署全面自動化,取代原來人工需要做的事情,大幅提升軟體開發效率。

  • CI (Continuous Integration):專注在持續整合,目的是讓經過測試的程式碼用最快的時間回到主幹中,透過程式碼的自動化測試和建置,將穩定品質的程式碼合併。越早頻繁整合,整合難度的就越低,且能確保最新版本是可運行的。常見的流程會是當嘗試將更改推送到 Git Repo 時,Linter 和測試就會運行。
  • CD (Continuous Delivery/Deployment):專注在持續部署和交付,更快速且頻繁的去更新我們的服務,依照需要的環境進行建置和部署。


圖片來源: Tony’s Schema

CI/CD 工具非常多元且通常採用自動化,常見的使用方法都是在專案中加入一個 yaml 設定檔進行配置,在整合過後也會提供一個可以嵌入的 CI/CD 狀態標籤嵌入在網頁或是 README.md 裡面,顯示目前專案的狀態,常見的服務像是:

  • 安裝版:Drone CI、Jenkins。
  • 第三方服務:Travis CI、CircleCI。
  • 版控平台服務:GitHub Actions、GitLab CI。


圖片來源: Hamit SEYREK’s Schema

常見的需求可能會是:

  • 依照條件觸發執行對應任務。
  • 排程工作 (Cron Job):定時執行一些測試任務。

這篇文章接下來會分別用不同的 CI/CD 工具來做示範。

排程工作 (Cron Job)

cron job 的寫法,Linux 設定 crontab 也是一樣的概念,通常有五個數字 分 時 天 周 月 可以填入相關數字或判斷式簡易寫法如下:

  • 每時 0 * * * *
  • 每天 0 0 * * *
  • 每周 0 0 0 * *
  • 每月 0 0 0 0 *

判斷式相關寫法如下:

  • * 任何值都會執行。
  • , 設定多個數字們可以用逗號分隔。
  • - 設定數字區間。
  • / 除法每八小時就可以 */8

Jenkins:強大的開源自動化伺服器

首先介紹需要在本機安裝的 JenkinsJenkins 專注在流程自動化。假設流程是「依照條件觸發執行對應任務」,例如:

  1. 專案有新 commit:需要偵測到有新的 commit。
  2. 專案建置:需要設定建置專案的環境。
  3. FTP 發佈:需要設定 FTP 的相關帳密。

Jenkins 因為用 Java 運行,建議伺服器的記憶體至少有 1G,記憶體較小的主機也建議執行的配置上可以加上限制 -Xmx512

  1. 下載後安裝
  2. 安裝可能會需要的 plugin
  3. 針對 plugin 做相關設置
    • 系統設定 FTP server 帳密
    • 系統設定版控帳密
    • 工具設定 node js 環境

接著是把流程自動化 commit 專案 -> 專案建置 -> FTP 發佈:

  1. 開始一個 free style 的專案,接著暴力的針對原始碼定期自動掃描:Poll SCM H/10 * * * * (十分鐘一次)。
  2. 設定 Build 的動作:選擇 Windows batch command,並執行 npm installnpm run build
  3. 設定 Post-build Actions:將相關的建置後資料透過 FTP 發佈至伺服器。

推薦外掛:

  1. Startup Trigger:Jenkins 重啟後會自動重新建置。
  2. Workspace Cleanup Plugin:節省空間。

CircleCI:基於雲端的持續整合服務

CircleCI 是能監控程式碼異動後自動做 CI/CD 的工具,可以協助我們將 GitHub 上的專案進行持續整合。免費使用的話,每個月有 1,000 build minutes。

接下來會簡介部落格是怎麼做到自動化建置和發佈網站更新。原來的流程是當我們寫好一篇新的文章後,需要執行以下指令來完成發佈:

  1. hexo clean
  2. hexo generate
  3. hexo deploy

目標是當文章更新時能自動化發佈。Circle 是使用 YAML 檔進行設定的,首先需要在專案中跟目錄建立 .circleci 資料夾,並新增下面的 config.yml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
version: 2
jobs:
build:
docker:
- image: circleci/node:lts-bullseye-browsers-legacy
working_directory: ~/repo
steps:
- checkout
- restore_cache:
keys:
- v1-dependencies-{{ checksum "package.json" }}
- v1-dependencies-
- run: npm install --legacy-peer-deps
- save_cache:
paths:
- node_modules
key: v1-dependencies-{{ checksum "package.json" }}
- run: npm run clean
- run: npm run generate
- deploy:
command: |
git config --global user.email $GH_EMAIL
git config --global user.name $GH_NAME
npm run deploy

注意事項:

  1. 要去專案設定中加入 SSH key,並確認擁有讀寫權限。
  2. 機密個資可以放在 CircleCI 環境變數中,如 $GH_EMAIL
  3. 需要新增 npm script 去取代全域的 hexo 指令。

GitHub Actions:GitHub 原生 CI/CD 解決方案

接下來將提到怎麼透過 GitHub Actions 來執行排程工作 (Cron Job) 自動定期更新疫情地圖資料。

由於武漢肺炎疫情地圖的專案在 GitHub 直覺若要透過第三方服務遠端 Push 新的檔案會有些困難,所以選擇使用 GitHub Action。導入步驟如下:

  • 專案 => 設定 => Secrets => 加入 github-token。
  • /.github/workflows 加入 {name}.yml 檔案。
  • 設定 GitHub Action 的 Cron Job 還有需要更新的分支。
  • 使用 JamesIves/github-pages-deploy-action@v4.2.3 進行部署。
  • 快取 actions/cache 以避免每次執行都重新安裝。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
name: Node CI
on:
schedule:
- cron: "1 2-6/2 * * *"
push:
branches:
- master
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v1
- name: Use Node.js
uses: actions/setup-node@v1
with:
node-version: 16.x
- name: Install and Deploy 🚀
run: |
npm install
npm run generate
npm run build
- name: Deploy
uses: JamesIves/github-pages-deploy-action@v4.2.3
with:
branch: gh-pages
folder: docs

系列文章導覽

在此系列文章中,我們從基礎的網頁構成出發,逐步深入到後端 API 設計、開發工具、專案架構以及自動化部署。以下是系列文章的導覽:

或者您可以參考 前後端如何和平相處系列目錄 以獲取完整列表。


FAQ:CI/CD 工具常見問題

Q1:我該選擇 Jenkins 還是 GitHub Actions?

A:這取決於您的環境。如果您需要完全掌控基礎設施(如:在地端私有雲中運行)且需要高度客製化的外掛,Jenkins 是老牌首選。如果您追求開發效率且程式碼已經託管在 GitHub,GitHub Actions 的原生整合度最高,且幾乎不需要額外維護伺服器。

Q2:CI/CD 過程中的 API Key 或密碼應該放在哪?

A:千萬不要直接寫在 YAML 檔中。 所有的工具(Jenkins, CircleCI, GitHub Actions)都提供專屬的「Secrets」或「Environment Variables」管理介面。您應將金鑰存放在該處,並在 YAML 中透過變數(如 $API_KEY${{ secrets.TOKEN }})調用。

Q3:自動化測試(CI)失敗時該怎麼辦?

A:這是好事!CI 的目的就是「攔截錯誤」。當測試失敗時,系統會阻止程式碼合併至主幹。您應查看 CI 日誌定位問題,修正程式碼後再次推送到 Git,直到 CI 通過(亮綠燈)為止。