過去三年,對CI/CD自動化的關注持續增長,2025年單年「CI/CD流水線配置」的搜尋量就增加了34%。儘管如此,英國大多數開發機構仍然透過手動SSH工作階段或臨時指令稿進行部署。這一差距代表著顯著的競爭劣勢:擁有成熟CI/CD流水線的團隊發布頻率大約高出五倍,並且能在修復成本比部署後補救便宜十倍的階段發現缺陷。
本指南涵蓋了2026年英國開發團隊建立CI/CD流水線的實際情況:選擇平台、正確構建流水線階段、整合安全掃描,以及處理在生產環境中真正有效的部署策略。
摘要
- CI自動建置和測試每次提交;CD在沒有人工干預的情況下將經過驗證的程式碼交付到暫存或生產環境
- GitHub Actions是2026年大多數英國團隊的正確預設選擇;如果需要自託管執行器或更強的稽核控制,GitLab CI是更好的選擇
- 生產就緒的流水線從建置到部署後監控有十一個階段,而不僅僅是建置和測試
- 安全掃描屬於流水線內部,而不是事後新增:SAST、相依性稽核和金鑰掃描應在每次提取請求時執行
CI/CD實際上是什麼
這個術語使用得比較寬泛,因此值得精確定義。持續整合(CI)意味著對共享分支的每次提交都會觸發一個自動化序列:在接受變更之前,程式碼會被建置、lint檢查和測試。目標是在上下文還新鮮時立即發現整合問題,而不是在sprint結束時合併一週的分歧分支時才發現。
持續交付(CD)擴展了這種自動化,使經過驗證的程式碼可以以最少或零手動步驟發布到暫存或生產環境。持續部署(更強的版本)意味著每條成功的流水線都會自動部署到生產環境。大多數團隊從持續交付開始,在生產部署前新增人工審批門,並在對測試覆蓋率和復原機制有足夠信心後轉向完整的持續部署。
實際結果是,CI/CD將部署從高度緊張的多小時事件轉變為每週發生數十次的常規後台流程。
選擇平台
平台選擇很重要,但不是永久性的。如果需要,以後再遷移,但現在為你的具體情況選擇正確的預設值:
GitHub Actions 是2026年大多數英國開發團隊啟動新專案的正確選擇。它與GitHub深度整合,擁有最大的可重用action生態系統,公共儲存庫有慷慨的免費時間,以及文件完善的配置格式。託管的執行器涵蓋Linux、Windows和macOS。對於已經在GitHub上的團隊來說,最小阻力路徑的優勢是真實存在的。
GitLab CI 是更好的選擇,如果你需要自託管執行器(出於監管原因或存取私有網路資源)、更強的稽核日誌,或者你的團隊更希望有一個用於原始碼控制、CI、容器登錄和部署的單一平台。GitLab的.gitlab-ci.yml格式成熟且廣為人知。
CircleCI 具有強大的平行性和Docker支援,其配置易於閱讀。它是GitHub Actions之前的市場領導者,許多英國機構仍在使用它。如果現有的CircleCI配置執行良好,沒有緊迫理由遷移。
Jenkins 是遺留系統。它可以執行,許多大型組織成功運營它,但對於2026年的新專案,維護Jenkins伺服器的營運開銷不值得。如果你繼承了Jenkins,在長期承諾之前評估遷移成本。
Bitbucket Pipelines 在你的團隊嵌入Atlassian堆疊且無法更改原始碼控制時可以接受。功能集落後於GitHub Actions,但涵蓋了基礎功能。
流水線階段:應包含什麼以及原因
完整的生產就緒流水線比大多數教程涵蓋的階段更多。以下是每個階段背後推理的完整序列:
階段1:建置
編譯或轉譯原始碼,安裝相依性,並產生建置產物。對於Node.js專案,這意味著npm ci(不是npm install,因為ci精確使用鎖定檔案)和你的建置步驟。對於Python服務,這意味著建立虛擬環境並從requirements.txt安裝。輸出是版本化的產物:編譯的二進位檔案、轉譯的JS套件或wheel檔案。
在這裡積極快取你的相依性。以package-lock.json為鍵的快取與npm ci配合意味著未更改相依性的後續流水線執行完全跳過下載。
階段2:Lint和靜態分析
ESLint、flake8、mypy、嚴格模式下的Pylance,或適合你語言的等價工具。這個階段很快,通常在30秒以內,並在測試執行之前捕獲大量問題。靜態類型檢查(Python的mypy,JS/TS的TypeScript tsc --noEmit)對於捕獲單元測試經常遺漏的介面不符合特別有價值。
在這裡快速失敗。如果程式碼不通過lint,就沒有必要執行十分鐘的測試套件。
階段3:單元測試
執行你的單元測試套件。單元測試應該快速。如果完整的單元測試執行超過五分鐘,拆分套件或調查原因。在測試執行器支援的地方跨測試檔案平行化(Jest關閉--runInBand,Python使用pytest-xdist)。
關鍵點:單元測試對外部服務使用mock。CI環境在此階段不應有真實的資料庫憑證或外部API金鑰。
階段4:整合測試
整合測試針對真實服務執行:測試資料庫、Redis執行個體、本地訊息佇列。大多數CI平台為此支援服務容器。在GitHub Actions中,你在作業旁邊宣告一個services區塊,在測試執行期間啟動PostgreSQL或MySQL容器。
這是捕獲單元測試遺漏的錯誤的階段:語義錯誤的ORM查詢、交易隔離問題、外鍵約束失敗。針對真實資料庫執行整合測試,而不是mock。
階段5:安全掃描
安全掃描屬於流水線,而不是季度計劃掃描。這個階段有三個組成部分:
SAST(靜態應用程式安全測試)。 Semgrep是多語言團隊最實用的選擇;它有Python、JavaScript、TypeScript、Go、Java等的規則。特別針對Python,Bandit捕獲常見的安全反模式。GitHub的CodeQL對公共儲存庫免費,捕獲與模式比對工具不同類別的漏洞。每次提取請求至少執行其中一個。
相依性稽核。 Node.js專案使用npm audit --audit-level=high,Python使用pip-audit。這些工具根據OSV(開源漏洞)資料庫檢查你安裝的相依性。高危和嚴重發現時阻止流水線;中等發現標記供人工審查而不是阻止。
金鑰掃描。 Gitleaks掃描提交歷史記錄中意外提交的憑證、API金鑰和令牌。這是金鑰到達遠端之前的最後一道防線。GitHub內建的金鑰掃描也值得啟用,但流水線中的Gitleaks在推送之前而不是之後捕獲問題。
階段6:建置和推送Docker映像
如果你的部署目標是容器,在這裡建置Docker映像並推送到你的登錄。用提交SHA標記,而不僅僅是latest。不可變標籤意味著你始終可以準確識別哪個提交在生產環境中執行。推送到GitHub Container Registry(ghcr.io)、AWS ECR或你選擇的登錄。
在推送之前對已建置的映像執行容器映像掃描(Trivy或Grype)。這會捕獲相依性稽核遺漏的基礎映像中的作業系統級CVE。
階段7:部署到暫存環境
將經過驗證的產物部署到反映生產環境的暫存環境。基礎設施即程式碼(Terraform、Pulumi)意味著你的暫存環境與生產環境定義相同。部署步驟應該是冪等的:執行兩次不應導致問題。
階段8:針對暫存環境的煙霧測試
部署到暫存環境後,執行最小的端到端檢查:應用程式能啟動嗎,健康端點是否返回200,基本登入流程是否有效?這些測試應在兩分鐘內執行。目標不是全面覆蓋,而是捕獲隔離測試不會捕獲的部署失敗。
階段9:人工審批門
在部署到生產環境之前,暫停等待人工審批。在GitHub Actions中,這是一個帶有必需審閱者的環境保護規則。在GitLab CI中,這是一個手動作業觸發器。這個門應該是輕量級的:一個審閱者確認暫存環境看起來正確,而不是漫長的簽字流程。
對於向持續部署邁進的團隊,一旦部署頻率和測試覆蓋率足夠高,就可以自動化這個門,但從有門開始是更安全的預設值。
階段10:部署到生產環境
與暫存環境相同的部署步驟,指向生產環境。有了以提交SHA標記的不可變產物,生產部署是確定性的。
階段11:部署後監控檢查
生產部署後,流水線應驗證監控是否正常:錯誤率沒有升高,健康端點正在回應,沒有延遲峰值。對可觀測性平台(Datadog、Grafana或甚至基本HTTP健康檢查)的簡單檢查為你提供自動化訊號,表明部署成功或觸發復原的警示。
實際的GitHub Actions配置
以下是Node.js應用程式的簡化但實際的流水線結構:
1name: CI/CD Pipeline
2
3on:
4 push:
5 branches: [main, develop]
6 pull_request:
7 branches: [main]
8
9jobs:
10 build-and-lint:
11 runs-on: ubuntu-latest
12 steps:
13 - uses: actions/checkout@v4
14 - uses: actions/setup-node@v4
15 with:
16 node-version: '20'
17 cache: 'npm'
18 - run: npm ci
19 - run: npm run lint
20 - run: npx tsc --noEmit
21
22 unit-tests:
23 needs: build-and-lint
24 runs-on: ubuntu-latest
25 steps:
26 - uses: actions/checkout@v4
27 - uses: actions/setup-node@v4
28 with:
29 node-version: '20'
30 cache: 'npm'
31 - run: npm ci
32 - run: npm test -- --coverage
33
34 integration-tests:
35 needs: build-and-lint
36 runs-on: ubuntu-latest
37 services:
38 postgres:
39 image: postgres:16
40 env:
41 POSTGRES_PASSWORD: testpass
42 POSTGRES_DB: testdb
43 options: >-
44 --health-cmd pg_isready
45 --health-interval 10s
46 --health-timeout 5s
47 --health-retries 5
48 steps:
49 - uses: actions/checkout@v4
50 - uses: actions/setup-node@v4
51 with:
52 node-version: '20'
53 cache: 'npm'
54 - run: npm ci
55 - run: npm run test:integration
56 env:
57 DATABASE_URL: postgres://postgres:testpass@localhost:5432/testdb
58
59 security-scan:
60 needs: build-and-lint
61 runs-on: ubuntu-latest
62 steps:
63 - uses: actions/checkout@v4
64 with:
65 fetch-depth: 0
66 - uses: actions/setup-node@v4
67 with:
68 node-version: '20'
69 cache: 'npm'
70 - run: npm ci
71 - run: npm audit --audit-level=high
72 - uses: semgrep/semgrep-action@v1
73 - name: Run Gitleaks
74 uses: gitleaks/gitleaks-action@v2
75
76 deploy-staging:
77 needs: [unit-tests, integration-tests, security-scan]
78 runs-on: ubuntu-latest
79 environment: staging
80 if: github.ref == 'refs/heads/main'
81 steps:
82 - uses: actions/checkout@v4
83 - name: Deploy to staging
84 run: ./scripts/deploy.sh staging
85
86 deploy-production:
87 needs: deploy-staging
88 runs-on: ubuntu-latest
89 environment: production
90 steps:
91 - uses: actions/checkout@v4
92 - name: Deploy to production
93 run: ./scripts/deploy.sh production
unit-tests、integration-tests和security-scan作業在build-and-lint作業通過後平行執行。這種結構在不犧牲覆蓋率的情況下減少了總流水線時間。
部署策略
如何部署與是否部署同等重要。三種策略涵蓋了大多數英國團隊的需求:
滾動部署。 逐一替換執行個體。使用大多數協調器(Kubernetes、ECS)實作簡單。風險:如果新版本有缺陷,在發布窗口期間部分使用者存取舊執行個體,部分使用者存取新執行個體。對低流量應用程式來說是很好的預設選擇。
藍綠部署。 維護兩個相同的生產環境。流量從藍色原子性地切換到綠色。如果新版本有缺陷,在幾秒鐘內切換回來。代價是同時執行兩個環境,對於資料庫來說這不是小事。最適合停機不可接受且復原速度至關重要的應用程式。
金絲雀發布。 將一小部分流量(5%或10%)路由到新版本,在定義的時間段內觀察錯誤率和效能,然後將金絲雀提升到100%。對於想要在完整推出之前獲得真實生產回饋的高流量應用程式來說非常出色。需要你的負載平衡器或服務網格支援流量分割。
大多數英國團隊應該從滾動部署開始,在流量和關鍵性證明合理時新增藍綠,並在每天多次發布且每一步都需要經過驗證的生產回饋時考慮金絲雀發布。
金鑰管理
金鑰不屬於程式碼、配置檔案或提交到原始碼控制的環境特定.env檔案。正確的方法:
GitHub Secrets / GitLab CI變數 用於流水線作業需要的金鑰。這些在靜止時加密,在日誌中被遮罩,並透過環境變數對作業可用。
環境特定的金鑰 在部署目標層級配置:AWS Parameter Store、Azure Key Vault、Google Secret Manager,或對於需求更複雜的團隊使用HashiCorp Vault。應用程式在啟動時從金鑰存放區讀取金鑰,而不是從透過流水線傳遞的環境變數讀取。
輪換。 API金鑰、資料庫密碼和服務憑證應按計劃輪換。CI/CD流水線使輪換更容易,因為在一個地方(金鑰存放區或CI環境)更新金鑰會在下次部署時自動傳播。
流水線中的Gitleaks是當開發人員意外提交金鑰時的安全網。已提交金鑰的補救措施是立即使其無效,然後清理git歷史;Gitleaks警示告訴你這個過程現在就需要開始,而不是等到有人利用它時。
流水線效能
慢流水線是被忽視的流水線。如果開發人員等待十五分鐘才能獲得每次推送的回饋,他們就會停止推送小提交並開始批次處理工作,這違背了CI的目的。
保持流水線快速的實用步驟:
快取相依性安裝。對於npm,將快取鍵設定為package-lock.json。對於pip,使用以requirements.txt為鍵的pip快取action。熱快取將兩分鐘的安裝變成五秒的恢復。
平行執行獨立作業。建置、lint、單元測試、整合測試和安全掃描並不都相互依賴。結構良好的流水線在公共建置步驟之後將它們作為平行作業執行,顯著減少總的掛鐘時間。
使用路徑篩選器。如果你有包含多個服務的monorepo,只在服務目錄中的檔案變更時觸發相關的流水線階段。GitHub Actions支援推送觸發器上的paths篩選器。
設定逾時。卡住的作業不應在預設的六小時逾時內占用執行器。為每個階段設定適當的作業級逾時:lint五分鐘,單元測試十五分鐘,整合測試三十分鐘。
關鍵要點
- CI/CD將部署從高風險事件轉變為常規自動化流程;大多數英國團隊最大的瓶頸不是工具,而是根本沒有結構化的流水線。
- GitHub Actions是新專案的正確起點;GitLab CI適用於需要自託管執行器或單一整合平台的團隊。
- 生產級流水線有十一個階段。大多數教程停留在三個階段。你跳過的階段是生產事故的起源。
- 安全掃描(SAST、相依性稽核、金鑰掃描)屬於每次提取請求的流水線,而不是月度計劃掃描。
- 部署策略不可互換:簡單性用滾動部署,零停機關鍵性用藍綠,需要生產驗證的高頻發布用金絲雀。
- 慢流水線與沒有流水線一樣有害。積極快取,平行化獨立作業,並對每個作業設定硬逾時。
常見問題解答(FAQ)
CI/CD流水線執行應該花多長時間? 目標是從推送到暫存部署的關鍵路徑在十分鐘以內。lint和單元測試應在五分鐘以內完成。如果你的流水線經常花更長時間,請調查快取、平行化,以及測試套件是否積累了屬於獨立、較不頻繁執行的慢測試。
我應該在每次提交時執行完整測試套件,還是只在向main的提取請求時執行? 每次推送時執行快速檢查(lint、單元測試、安全掃描)。在向main的提取請求和合併到main時執行整合測試和暫存部署。這在回饋速度與資源成本和執行器分鐘數之間取得平衡。
CI和CD有什麼區別? CI(持續整合)意味著每次提交都會觸發自動建置和測試序列。CD(持續交付)擴展了該自動化,將經過驗證的程式碼部署到暫存或生產環境。它們通常一起實作,但代表不同的實踐。
我需要暫存環境嗎? 是的,對於任何有真實使用者的應用程式。暫存是你捕獲特定於部署的失敗、環境之間的配置差異以及不會出現在單元測試或整合測試中的煙霧測試問題的地方。直接在生產環境中測試是CI/CD存在以消除的風險。
在CI/CD流水線中處理資料庫移轉的最佳方法是什麼? 作為部署步驟的一部分執行移轉,在新應用程式版本開始接收流量之前。確保移轉與先前的應用程式版本向後相容,這樣復原就不會破壞結構描述。避免在使用它們的功能的同一次移轉中進行破壞性結構描述變更(欄刪除、類型變更)。
如何說服英國機構或客戶CI/CD投資值得? 最有力的論據是財務方面的:在CI中捕獲的錯誤修復成本大約比部署後發現的錯誤便宜十倍。運轉良好的流水線還能降低每次發布的風險和壓力,這直接改善了團隊留存率和速度。大多數英國機構在採用CI/CD的第一季度內就看到了下班時間緊急部署的可測量減少。
評論