

本文為英文版的機器翻譯版本，如內容有任何歧義或不一致之處，概以英文版為準。

# 完整 CI/CD 程序有何不同
<a name="fully-cicd-process-differences"></a>

CI/CD 管道使用現代*幹線型工作流程*，開發人員會將小型、頻繁的更新合併到透過 CI/CD 管道的 CD 部分建置和測試的主分支 （或*幹*線）。此工作流程已取代 *Gitflow 工作流程*，其中開發和發行分支以發行排程分隔。在許多組織中，Gitflow 仍然是熱門的版本控制和部署方法。不過，它現在被視為舊版，整合到 CI/CD 管道可能具有挑戰性。

對於許多組織而言，從 Gitflow 工作流程到以幹線為基礎的工作流程的轉換尚未完成，結果是它們在過程中卡在某個位置，永遠不會完全遷移到 CI/CD。以某種方式來說，其管道最終會追蹤到舊版工作流程的特定殘差，並卡在過去和現在之間的轉換狀態。檢閱 Git 工作流程中的差異，然後了解使用舊版工作流程如何影響下列項目：
+ [環境完整性](environment-integrity.md)
+ [推出](releases.md)
+ [安全](security.md)

為了更輕鬆地識別現代組態中舊版 Git 工作流程的殘差，讓我們比較 [Gitflow](#gitflow-approach) 與現代、以[幹線為基礎的](#trunk-based-approach)方法。

## Gitflow 方法
<a name="gitflow-approach"></a>

下圖顯示 Gitflow 工作流程。Gitflow 方法使用多個分支來同時追蹤多個不同版本的程式碼。您可以在開發人員仍在處理目前版本的程式碼時，將應用程式的更新版本安排在未來某個時間點。主體型儲存庫可以使用特徵標記來完成此操作，但預設會內建於 Gitflow。



![\[具有功能、開發、發行和 Hotfix 分支的 Gitflow 工作流程\]](http://docs.aws.amazon.com/zh_tw/prescriptive-guidance/latest/strategy-cicd-litmus/images/gitflow-workflow.png)


Gitflow 方法的一個結果是應用程式環境通常不同步。在標準 Gitflow 實作中，開發環境會反映程式碼的目前狀態，而生產前環境和生產環境仍會在最新版本的程式碼基礎狀態上保持凍結狀態。

當瑕疵出現在生產環境中時，這會讓情況更為複雜，因為開發人員在未公開未發行的功能的情況下，無法將執行的程式碼基底合併到生產環境中。Gitflow 處理這種情況的方式是使用 Hotfix。從發行分支建立 Hotfix 分支，然後直接部署到上層環境。然後，Hotfix 分支會合併到開發分支中，以保持程式碼為最新狀態。

## 以主體為基礎的方法
<a name="trunk-based-approach"></a>

下圖顯示以幹線為基礎的工作流程。在以幹線為基礎的工作流程中，開發人員會在本機的特徵分支中建置和測試特徵，然後將這些變更合併到主分支中。然後，主要分支會依序建置到開發環境、生產前環境和生產環境中。單元和整合測試會在每個環境之間進行。



![\[具有特徵分支和主分支的幹線型工作流程。\]](http://docs.aws.amazon.com/zh_tw/prescriptive-guidance/latest/strategy-cicd-litmus/images/trunk-based-workflow.png)


使用此工作流程，所有環境都會操作相同的程式碼基底。上層環境不需要 Hotfix 分支，因為您可以在主要分支中實作變更，而無需公開未發行的功能。主要分支一律假設穩定、沒有瑕疵，並準備好發行。這可協助您將其整合為 CI/CD 管道的來源，以便透過管道中的所有環境自動測試和部署您的程式碼基礎。

# 以幹線為基礎的方法的環境完整性優勢
<a name="environment-integrity"></a>

如同許多開發人員所知道的，程式碼中的一個變更有時可以建立[浮水印效果](https://www.americanscientist.org/article/understanding-the-butterfly-effect) （美國科學家文章），其中看似無關的小偏差會引發鏈式反應，從而導致非預期的結果。開發人員接著必須進行完整調查，以探索根本原因。

當科學家進行實驗時，他們會將測試主體分成兩個群組：實驗群組和控制群組。目的是讓實驗群組和控制群組完全相同，但實驗中測試的物件除外。當實驗群組中發生未發生在控制群組中的事件時，唯一原因可能是要測試的物件。

將部署中的變更視為實驗群組，並將每個環境視為個別的控制群組。只有在控制項與上層環境相同時，在較低環境中進行測試的結果才可靠。環境越偏離，在上層環境中發現瑕疵的機率就越高。換言之，如果程式碼變更將在生產環境中失敗，我們寧願它們先在 Beta 版中失敗，使其永遠不會進入生產環境。因此，應盡一切努力讓每個環境，從最低測試環境到生產本身保持同步。這稱為*環境完整性*。

任何完整 CI/CD 程序的目標是儘早發現問題。使用以幹線為基礎的方法來保留環境完整性，實際上可以消除對 Hotfix 的需求。在以幹線為基礎的工作流程中，問題很少會先出現在生產環境中。

在 Gitflow 方法中，在 Hotfix 直接部署到上層環境之後，它會新增至開發分支。這會保留未來版本的修正。不過，Hotfix 是直接在應用程式的目前狀態之外開發和測試。即使 Hotfix 在生產環境中完美運作，當它與開發分支中較新的功能互動時，仍可能會出現問題。由於通常不需要部署 Hotfix，這會導致開發人員花費額外的時間嘗試將 Hotfix 改造到開發環境中。在許多情況下，這可能會導致重大的技術負債，並減少開發環境的整體穩定性。

當 環境中發生故障時，所有變更都會復原，讓環境回到先前的狀態。程式碼庫的任何變更都應該從第一個階段再次啟動管道。當生產環境中確實發生問題時，修正也應通過整個管道。與使用此方法避免的問題相比，通過較低環境所需的額外時間通常可忽略。由於較低環境的整個目的是在到達生產環境之前攔截錯誤，因此透過 Gitflow 方法繞過這些環境是效率低且不必要的風險。

# 以幹線為基礎的方法的發行優點
<a name="releases"></a>

通常讓 Hotfix 成為必要的因素之一，就是在舊版工作流程中，開發人員正在處理的應用程式狀態可能包含數個尚未發行的功能，這些功能尚未投入生產環境。生產環境和開發環境只有在排程版本發生時才會同步，然後立即開始分歧，直到下一個排程版本為止。

完全 CI/CD 程序中可以有排程版本。您可以使用功能旗標，延遲將程式碼發佈至生產環境。不過，完全 CI/CD 程序可讓排程版本變得不必要的，以提供更多彈性。畢竟，*連續*性是 CI/CD 中的關鍵字，這表示變更會在準備好時發佈。避免維護與較低測試環境幾乎不同步的個別發行環境。

如果管道不是完全 CI/CD，則上下環境之間的差異通常發生在分支層級。開發人員在開發分支中工作，並維護單獨的發行分支，只有在排程版本的時間才會更新。作為發行分支和開發分支的差異，可能會出現其他複雜性。

除了環境不同步之外，隨著開發人員在開發分支上工作，並習慣比生產環境更早的應用程式狀態，每次出現問題時，他們都必須重新適應生產狀態。開發分支的狀態可能是生產前的許多功能。當開發人員每天在該分支中工作時，很難記住什麼是和不發佈到生產環境。這會增加在修復其他錯誤的過程中引入新錯誤的風險。此結果似乎是修復的無限循環，可將時間軸和延遲功能版本延長數週、數月甚至數年。

# 以幹線為基礎的方法的安全優勢
<a name="security"></a>

全 CI/CD 程序提供全自動化的單一事實來源部署方法。管道具有單一進入點。軟體更新會在一開始進入管道，並依原狀從一個環境傳遞到下一個環境。如果在管道的任何階段發現問題，修正問題的程式碼會變更，必須經過相同的程序，並從第一個階段開始。減少管道中的進入點也會減少漏洞可能引入管道的方式。

此外，由於進入點是生產環境最接近的可能點，因此可大幅降低漏洞進入生產環境的可能性。如果您在完全 CI/CD 管道中實作手動核准程序，您仍然可以允許對是否將變更提升到下一個環境進行直接或直接決策。決策者不一定是部署變更的同一個人。這會區隔程式碼變更部署者的責任，以及這些變更的核准者。它也讓較不技術性的組織領導者更能夠執行核准者的角色。

最後，單一進入點可協助您將對生產環境使用者介面 (UI) 主控台的寫入存取權限制為少數甚至零位使用者。透過減少可在 主控台中進行手動變更的使用者數量，您可以降低安全事件的風險。在舊版工作流程中，與 CI/CD 自動化方法相比，在生產環境中手動管理主控台的能力更為必要。這些手動變更較難以追蹤、檢閱和測試。通常會執行它們來節省時間，但從長遠來看，他們會為專案增加大量的技術負債。

主控台安全問題不一定是由不法份子造成。主控台中發生的許多問題都是意外的。意外安全暴露非常常見，並導致零信任安全模型的增加。此模型儲存庫部分而言，當即使內部員工具有盡可能少的存取權，也稱為*最低權限許可*時，安全意外不太可能發生。將所有程序限制為自動化管道，以保持生產環境的完整性，實際上可消除主控台相關安全問題的風險。