GitLab CI/CD Pipeline 是現代軟體開發流程中不可或缺的一環,它自動化了程式碼的建置、測試和佈署流程。理解 Pipeline 的結構對於有效運用 GitLab CI/CD 至關重要。首先,Pipeline 列表提供了一個清晰的介面,展示了每次 Pipeline 執行的狀態、程式碼版本、觸發者以及執行時間等資訊,方便開發者監控和管理 Pipeline 的執行狀況。同時,它也提供了取消和重新執行 Pipeline 的控制功能,提升了開發流程的靈活性。在 CI 階段,GitLab 支援各種測試和掃描,例如功能測試、安全掃描、程式碼品質掃描等,確保程式碼的品質和安全性。透過 CI,團隊可以及早發現和解決問題,實踐「左移」哲學,並促進團隊成員之間的合作。CD 階段則負責將程式碼佈署到不同的環境,例如審核環境、暫存環境和生產環境。GitLab 提供了持續交付和持續佈署兩種模式,前者需要人工批准生產佈署,後者則完全自動化。選擇哪種模式取決於團隊的風險承受能力和 CI 流程的成熟度。無論選擇哪種 CD 模式,都可以幫助團隊更頻繁地釋出程式碼,降低每次變更的風險,並更快地將新功能交付給使用者。
GitLab 的 CI/CD Pipeline 結構深度解析
在理解 GitLab 的 CI/CD Pipeline 結構之前,玄貓首先介紹一下 GitLab 的 Pipeline 列表。這個列表不僅能顯示每次 Pipeline 執行的透過或失敗狀態,還能告訴你是否有任何 Pipeline 卡住或無法執行。它還會顯示每個 Pipeline 執行的程式碼版本、觸發 Pipeline 的提交訊息或 Git 標籤、提交者的身份以及 Pipeline 的開始時間和執行時間(如果已完成)。
Pipeline 列表的功能
Pipeline 列表提供了一些強大的圖形化使用者介面(GUI)控制功能。例如,你可以在 Pipeline 執行中途取消它。對於一些複雜的 Pipeline,這些運作可能需要數分鐘甚至數小時,如果你的專案有限制的 Pipeline 執行時間,你可能會希望取消由一些微不足道的檔案變更觸發的 Pipeline,以節省執行時間。
此外,Pipeline 列表還提供了重新執行任何 Pipeline 的控制功能。如果你懷疑某個 Pipeline 是由於暫時性的網路問題而失敗,這時候重新執行它就很有幫助。
以下是 Hats for Cats 專案的一個 Pipeline 列表範例:
- 已完成且透過:2 個
- 已完成且失敗:1 個
- 正在執行:2 個
這些資訊幫助我們瞭解每個 Pipeline 的執行狀況和歷史記錄。
CI 和 CD 的定義
接下來,玄貓來解釋 CI 和 CD 的定義。
CI(持續整合)
CI 是「Continuous Integration」的縮寫,並非 GitLab 單獨使用的術語,而是大多數軟體公司共同認可的標準術語。CI 的主要目的是確保任何檔案修改都能順利整合到專案的穩定程式碼函式庫中。這意味著當你將功能分支或修復分支合併到預設分支時,是否會出現新問題?CI 處理的是在程式碼被提交到 GitLab 主機上的專案儲存函式庫之前執行測試、掃描和其他檢查,以確保程式碼品質。
以下是一些常見的 CI 消費步驟:
- 功能測試:確保軟體具備預期功能。
- 安全掃描:檢查程式碼是否引入安全漏洞。
- 程式碼品質掃描:確保程式碼符合最佳實踐。
- 效能測試:確保程式碼符合效能期望。
- 許可證掃描:確保所有依賴項使用與主專案相容的許可證。
- 模糊測試:透過異常長字串或範圍外數值來檢查程式碼是否會當機或出現意外錯誤。
GitLab 提供這些檢查的完整支援,因此很容易在 CI Pipeline 中啟用它們。然而,任何可以從命令列執行的工具(無論是商業、開源還是自製),都可以加入到 GitLab Pipeline 中。
CI 的優勢
CI 的主要優勢之一是實作「左移」哲學。越早執行測試,越早發現問題;越早發現問題,修復起來就越輕鬆。將盡可能多的軟體開發任務提前進行,可以帶來巨大收益。
另一個優勢是促進合作。例如,當安全測試頻繁執行時,整個團隊都能掌握專案安全狀況。如果增加了未預期的漏洞,應該如何安排時間和人力來修復?開發人員是否需要調整編寫方式或架構以減少下個月新增功能時引入更多漏洞?如果整個團隊(包括經理、開發人員、QA、UX 和技術作家等)都能看到專案安全狀況,他們就可以直接幫助修復問題或者調整工作方式以避免未來安全問題。
CD(持續交付與持續佈署)
CD 有兩種不同含義:持續交付(Continuous Delivery)和持續佈署(Continuous Deployment)。GitLab 使用 CD 一詞時可能指的是其中之一。這兩者都涉及決定將程式碼佈署到哪個環境並實際執行佈署操作。
各種環境
大多數軟體開發團隊會為佈署程式碼設定多個環境。這些環境有不同的用途:
- 功能測試環境:用於對軟體進行功能測試。
- 效能測試環境:用於進行效能測試。
- 模擬生產環境:用於發現並修復在生產環境中出現的整合錯誤。
- 生產環境:用於實際互動真實使用者。
GitLab 開發的軟體也使用這些環境,而 CD部分則負責決定將程式碼佈署到哪個環境並實際進行佈署。
管道、持續整合及持續交付的定義
在決定將程式碼放置的位置時,需要考慮多種因素。最常見的因素是管道是否針對 Git 分支或 Git 標籤執行,如果是分支,則是分支的名稱。不同公司使用不同的命名方案來命名他們的 Git 分支,以下是 GitLab 管道中持續交付(CD)部分可能如何決定佈署專案程式碼的典型範例。請注意,雖然這是現實的情況,但這並非組態 CD 管道的唯一方法:
- 如果一個管道針對名為
add-login-feature、fix-password-bug或remediate-cross-site-scripting-vuln之類別的分支執行,則將程式碼佈署到審核環境進行測試(關於這些環境的更多資訊將在下一節中介紹)。 - 如果一個管道針對主分支執行,則將該程式碼佈署到暫存(有時稱為預生產)環境。
- 如果一個管道針對生產分支中的 Git 標籤執行,則將程式碼佈署到生產環境。這假設你的團隊為每個打算佈署給使用者的提交新增版本標籤,例如
version-1-0或version-12-2。
瞭解審核環境
任何非平凡的軟體專案至少需要一個測試環境。這是一個開發中的軟體可以佈署到的機器,讓 QA 團隊可以在安全、隔離的地方使用軟體,以確保它滿足功能需求。有些團隊擁有其他專門化的測試環境,專門用於效能測試、負載測試、可擴充套件性測試或其他型別的測試。GitLab 對所有這些測試環境有一個特殊名稱:審核環境。
每個非預設 Git 分支都有一個專門用於該分支的審核環境。只要該分支被合併到儲存穩定程式碼函式庫的預設分支中,GitLab 就會銷毀不再需要的審核環境。
審核環境是 GitLab 最驚人的功能之一。你不需要自己設定這些環境。每當你在 GitLab 主機上的專案儲存函式庫副本中建立一個分支時,一個審核環境就會神奇地出現,準備好供你的 CI/CD 管道佈署。當你完成你的分支並且刪除它或將其合併到穩定程式碼函式庫中時,審核環境也會神奇地消失。這真是 GitLab 最好的和最有幫助的功能之一。
持續交付
我們已經說過 GitLab 對 CD 一詞的一個意義是持續交付。這意味著 GitLab CI/CD 管道會自動將你的程式碼佈署到正確的環境中,根據你組態管道關注的任何因素。但是有一個重要例外:在持續交付中,GitLab 不會自動將你的程式碼佈署到生產環境。相反,它會顯示一個 GUI 控制項,要求人工(通常是發行工程師)手動批准和觸發生產佈署。這是一個最終防止你團隊將有缺陷或錯誤版本的程式碼佈署給實際使用者的一種保障措施。這是 GitLab 使用者最常見的一種 CD 模式。
下圖示
graph TD
A[Git Branch] --> B{Is it a feature branch?}
B -- Yes --> C[Deploy to Review Environment]
B -- No --> D{Is it the main branch?}
D -- Yes --> E[Deploy to Staging Environment]
D -- No --> F{Is it a production tag?}
F -- Yes --> G[Deploy to Production Environment]
F -- No --> H[Error: Invalid Deployment]
內容解密:
- Git Branch 決策點:首先檢查當前執行的是哪個分支。
- 功能分支判斷:如果是功能分支(例如
add-login-feature),則進行佈署到審核環境。 - 主分支判斷:如果不是功能分支且為主分支(通常代表穩定版本),則進行佈署到暫存環境。
- 生產標籤判斷:若非主分支且存在生產標籤(例如
version-1-0),則進行佈署到生產環境。 - 錯誤處理:若上述條件皆不符合,則視為無效佈署並報錯。
持續佈署
CD 的另一種意義是持續佈署。這與持續交付相同,只有一個例外:它取消了最後的人工防止措施。持續佈署完全自動地將程式碼送至生產環境,就像它將程式碼佈署到其他任何環境一樣。移除人工因素可能會被一些組織視為風險較高,但如果你有一個成熟、可靠且經過驗證的 CI 段落部分管理Pipeline處理程式,那麼你可能會認為任何透過測試、掃描及其他檢查後所得到之程式碼足夠好以直接釋出給客戶端使用者。這可以對那些對其 CI 處理Pipeline信任度高之公司成為節省時間的一大助力。
使用 CD 包裝及佈署程式碼
無論 CD 是實作持續交付還是持續佈署——包裝和解決某些問題之前可能需要先將專案程式碼轉換成可供釋出之形式才行使用此Pipeline。稍後我們會談論更多相關資訊;目前只需瞭解到 CD 段落中的Pipeline可能涉及包裝 Java 語言程式碼為 WAR 或 EAR 檔案、包裝 Ruby 語言程式碼為 Gem 檔案、包裝 C 語言程式碼為 Docker 檔案映像、收集專案所有檔案成為 tarball 檔案或依照專案所需語言及釋出策略將專案程式碼封裝成適當形式。
當然也有不需要包裝之情況;例如一些擁有簡單釋出策略之專案可以直接釋出未經封裝之檔案集合。
無論 CD 處理Pipeline是否包裝了您之專案程式碼,它總是需要將軟體送至某處以供執行。這可能包括推播 Docker 檔案映像至公共或由 Gitlab 主機之儲存函式庫、使用命令列工具來釋出至 AWS 之遺體等其餘無數多種特定於作業系統之釋出技術;通常而言此作業是在您之專案處理Pipeline CD 段落中的最後任務(偶爾亦可能成為唯一任務)。
CD 的優點
總結來說,CD 的目的是使發行過程變得「乏味」。如果您之 CD Pipeline在每次提交時都會進行釋出——無論是針對審核環境、暫存環境或生產環境——那麼您就能更頻繁地釋出程式碼給客戶端使用者,並且每次變更越小且風險也越低。
當然客戶看不到您之 CD Pipeline所進行之佈署至審核或暫存環境之程式碼;然而藉由在此等環境中進行釋出及測試您之軟體方式可以讓您團隊對於在商業上合適時候釋放此等程式碼至生產時更加自信心十足;此等非生產發行可以被視作真正行動之前所進行準備之演練;它們可以幫助您提供客戶更頻繁且較小規模之更新次數;這樣做法可以讓您更快地提供特性給客戶端使用者使用、讓客戶能夠提供回饋給此等特性以及減少由於未預期問題而需要回復此等發行次數出現機率。
小段落標題
包裝與佈署程式碼
CD Pipeline——無論它實作的是持續交付還是持續佈署——有時需要在將專案程式碼佈署之前將其轉換成可佈署形式。稍後我們會談論更多具體細節;目前只需知道 CD 段落中的Pipeline可能涉及以下幾種操作:
- Java 語言:包裝 Java 程式碼為 WAR 或 EAR 檔案。
- Ruby 語言:包裝 Ruby 程式碼為 Gem 檔案。
- C 語言:包裝 C 程式碼為 Docker 檔案映像。
- 所有檔案:收集所有專案檔案成為 tarball 檔案。
- 其他語言:依照專案所需語言及釋出策略將專案程式碼封裝成適當形式。
當然也有不需要包裝之情況;例如一些擁有簡單釋出策略之專案可以直接釋出未經封裝之檔案集合。
無論 CD 處理Pipeline是否包裝了您之專案程式碼,它總是需要將軟體送至某處以供執行。以下列舉幾種常見操作:
- 推播 Docker 檔案映像至公共或由 GitLab 主機之儲存函式庫。
- 使用命令列工具來釋出至 AWS 遺體等特定於作業系統之方法。
- 其他無數多種特定於作業系統之釋出技術。
通常而言此作業是在您之專案處理Pipeline CD 段落中的最後任務(偶爾亦可能成為唯一任務)。
持續交付 (CD) 的好處
總結來說,CD 的目的是使發行過程變得「乏味」——即讓發行過程變得常規化和可預測化。如果您之 CD Pipeline在每次提交時都會進行釋出——無論是針對審核環境、暫存環境或生產環境——那麼您就能更頻繁地釋出程式碼給客戶端使用者,並且每次變更越小且風險也越低。
當然客戶看不到您之 CD Pipeline所進行佈署至審核或暫存環境之程式碼;然而藉由在此等非生產發行中進行釋出及測試您之軟體方式,可以讓您團隊對於在商業上合適時候釋放此等程式碼至生產時更加自信心十足。此等非生產發行可以被視作真正行動之前所進行準備之演練;它們可以幫助您提供客戶更頻繁且較小規模之更新次數;這樣做法可以讓您更快地提供特性給客戶端使用者使用、讓客戶能夠提供回饋給此等特性以及減少由於未預期問題而需要回復此等發行次數出現機率。
小段落標題
def deploy_code(branch_name, tag=None):
if branch_name.startswith('add-') or branch_name.startswith('fix-') or branch_name.startswith('remediate-'):
deploy_to('review')
elif branch_name == 'main':
deploy_to('staging')
elif tag and tag.startswith('version'):
deploy_to('production')
else:
raise ValueError("Invalid deployment configuration")
def deploy_to(environment):
# Deployment logic for the specified environment
pass
內容解密:
- 函式
deploy_code:- 接收
branch_name和可選引數tag作為輸入引數。 - 檢查
branch_name是否符合特定模式(如功能開發分支或錯誤修復分支),然後根據結果決定要將程式碼釋出到稽核環境、main分支釋出到暫存環境、production分支釋出到產品環境。 - 若不符合以上條件則丟擲錯誤資訊以指示無效組態項。
- 接收
- 函式
deploy_to:- 接收
environment作為輸入引數並表示將要將軟體釋出到指定環境中去(如稽核環境、main分枝或產品環節)。 - 函式體內沒有具體實作細節但設計用於新增發布邏輯以便將軟體釋出至指定環節。
- 接收
玄貓希望以上內容已完整呈現關於「CI/CD Pipeline」相關知識及技術觀點
