什麼是持續整合?

Tybyq發表於2018-11-16

在過去幾年中,很難找到與軟體世界相關的術語,而不是與 持續整合 (CI)和 持續交付 持續部署 (CD) 密切相關的實踐,這些實踐 通常被稱為CI / CD。 世界各地的組織,從一人開發商店到跨國公司,都在為他們的軟體產品實施CI和CD。

在本文中,我們將描述CI,簡要提及CD,並瞭解如何有效地使用它們。 我們將評估空間中可用的一些流行工具和系統,使您能夠快速啟動並執行開發工作流程。

持續整合:自動化開發流程和最佳實踐

為了說明持續整合在現代環境中的適用範圍,讓我們簡要介紹一下典型的軟體開發工作流程。 大多數現代軟體專案,無論是網站,智慧手機應用程式還是桌面應用程式,通常都遵循以下高階過程:

  1. 開發人員編寫一些程式碼,通常稱為 變更集 補丁 ,代表對專案程式碼庫的更改(例如,新增新功能或修復錯誤)。

  2. 他們 更改 整合 (或 合併 )到該專案的集中權威程式碼儲存庫(例如,GitHub上的儲存庫)。

  3. 如果與程式語言或應用程式相關,則 編譯 專案原始碼 ,然後將其 構建 為可部署版本(通常稱為 工件 )。

上面的步驟是許多現實設定的簡化檢視,省略了分支策略等考慮因素。 在考慮這個過程並思考每個階段的責任時,會出現兩個關鍵問題:

  1. 我們怎麼知道開發人員的變更集(來自第1步)是否可以整合到專案中?

  • 更改不得破壞現有程式碼庫, 例如 它們不會引入新的錯誤

  • 變化需要 具有足夠好的 質量。 “足夠好”的確切級別取決於上下文:負責人類生活的應用程式(如醫療應用程式)與遊戲沒有相同的期望。

  • 誰(或什麼)負責執行步驟2-3?

  • 在非CI開發模型中,第一個問題的答案可能包括 “點選合併和希望最好” “希望開發人員執行測試”

    同時,問題2傾向於由開發人員或操作手動完成,或者可能透過指令碼部分自動完成。

    持續整合採用不同的方法。 它試圖自動化這兩個問題的答案。

    看看上面的高階工作流程,持續整合側重於第2步和第3步。它驗證了開發人員的更改是否可以整合到主程式碼庫中,並且團隊仍然可以成功構建專案並執行相關的測試。

    在理想的CI環境中,每個程式碼更改都會在開發時進行整合。 一般來說,建議每次整合幾次,甚至更好。

    什麼是持續交付和持續部署?

    持續交付和持續部署使自動化更進一步,直到您的最新提交自動分發整個新版本的軟體。

    持續交付 意味著構建工件並準備好部署。 但如果沒有人類的人工決定,它們就不會被部署。

    持續部署 意味著所有流程都是自動化的,並且單個提交會觸發自動化管道,最終將您的應用程式的新版本帶到生產環境,而無需任何人為干預。

    雖然許多公司實行持續交付,但很少有公司接受持續部署。 持續部署存在風險,因為任何人都可以透過簡單的提交將錯誤引入生產,並且您需要引入流程來降低此風險。

    持續整合的好處

    這種對自動化整合的強調提供了超越傳統開發工作流程的另一個重要優勢

    利用現代版本控制大多數軟體專案使用 主幹 分支(也稱為 幹線 )。

    在非CI環境中,開發人員通常會在 此主幹的 分支 上長時間處理功能 隨著時間的推移,隨著其他開發人員整合他們的變化,這些分支往往越來越偏離主線。

    整合功能分支可能是一個費力的過程,以確保所有更改仍然相容。 這是一個開發人員非常害怕的過程,他們創造了“整合地獄”這個短語。 CI工作流程可以幫助您避免這個問題,因為它們強調簡單和定期的整合。

    持續整合不僅可以節省開發人員的時間,還可以避免他們不得不手動整合更改,而且還可以提高軟體的可靠性。 團隊可以放心地新增新功能,並透過編寫程式碼(和相關測試)自動將其釋出給使用者。

    持續整合實踐的要求

    持續整合工作流程有一些硬性要求。

    1. 版本控制系統工具

    2. 構建工具

    3. Artifacts Repository Manager

    持續整合依賴於版本控制系統

    最重要的要求是程式碼庫必須受版本控制。 應用於程式碼庫的每個更改都必須安全地儲存在專用版本控制系統(VCS)中。 程式碼受版本控制後,CI工具可以訪問它。

    市場上有幾種工具,Git可能是目前最廣泛使用的CVS工具,因此值得簡短描述。

    最初由Linus Torvalds建立的用於開發Linux核心的Git基於3個主要原則:

    1. 以併發版本系統(CVS)為例,說明不該做什麼

    2. 支援分散式工作流程

    3. 包括非常強大的防止腐敗的保護措施,無論是偶然的還是惡意的

    主要的Git特徵包括:

    • 支援非線性開發:與CVS相比,分支(和合並)非常快。 雖然CVS分支是在伺服器端進行的,但Git上的分支是在開發人員機器上進行的。

    • 分散式開發:每個開發人員都擁有整個儲存庫歷史記錄的本地副本。

    • 高效處理大型專案:效能測試表明即使處理大型程式碼庫,Git也很快。

    • 使用者身份驗證:提交可以加密簽名,確保提交的作者是其聲稱的人。

    • 歷史記錄的加密認證:與區塊鏈一樣,特定提交的ID取決於其祖先的內容。 更改歷史記錄將更改提交ID。

    • 垃圾收集:不必要的物件將在某些時候自動進行垃圾收集。 當需要空間時,也可以顯式呼叫垃圾收集來打包Git儲存庫。

    實現持續整合的構建工具

    CI的第二個要求是構建工具:這樣的工具將處理應用程式的源,並將以自動方式生成所需的軟體。

    一個軟體的構建步驟以及構建工具取決於所選擇的技術堆疊。 作為說明,這裡是Java應用程式的構建步驟列表:

    1. 如有必要, .java 從配置 生成 檔案

    2. 將原始碼( .java 檔案) 編譯 為位元組碼( .class 檔案)

    3. 將測試程式碼編譯為位元組碼

    4. 執行單元測試

    5. 如果有,執行整合測試

    6. .class 檔案 打包 到JAR存檔中

    7. 如有必要,將JAR儲存在Artifact Repository Manager中(見下文)

    8. 如有必要,請在控制版本系統中相應地標記程式碼

    要實現我們示例的操作鏈,可以使用幾種構建工具, 例如

    • Ant,所有Java構建工具的基於XML的跨平臺祖先

    • Maven,一種基於XML的廣泛宣告,偏向於約定優於配置

    構建工具和過程,無論它們是什麼,都允許可重現的構建。

    可重現構建的思想意味著同一組原始碼應該產生一組相同的輸出構件。 在開發人員的膝上型電腦或CI系統上構建的程式碼庫應該會產生相同的結果。 這提供了幾個好處:

    • 首先,當某人的膝上型電腦上的程式碼最終出現在資料中心的伺服器上時,開發人員環境與生產中執行的內容之間的奇偶校驗可以減少意外問題。 或者用你可能聽過或說過的流行短語,“它可以在我的機器上執行!”。

    • 同樣,如果CI系統中的測試透過,它可以最大限度地減少生產中斷的可能性,因為您可以確信它們執行相同的程式碼。

    • 最後,如果它們可以以一致且可重現的方式構建,則它允許在各階段之間有效地快取工件和共享二進位制檔案。

    用於儲存持續整合過程結果的工件儲存庫管理器

    正如原始碼需要儲存在VCS中一樣,構建過程產生的工件也需要儲存。 此類工件可以儲存在遠端檔案系統中,但與VCS一樣,管理工件的專用軟體提供了更多附加值:這是 二進位制儲存庫管理器 的角色 ,或者在限制較少的定義中,是 工件儲存庫管理器

    維基百科提供以下定義:

    二進位制儲存庫管理器是一種軟體工具,旨在最佳化軟體開發中使用和生成的二進位制檔案的下載和儲存。 它集中管理組織生成和使用的所有二進位制工件,以克服二進位制工件型別的多樣性,它們在整個工作流中的位置以及它們之間的依賴性所帶來的複雜性。

    工件儲存庫管理器提供以下主要功能:

    • 快取 :因為儲存庫管理器安裝在公司的邊界內,所以開發人員訪問它的速度比遠端訪問者快。 透過將其用作代理,它可以快取下載的第三方工件並加快對它們的訪問。

    • 保留策略 :repo管理器可以自動清除未使用的工件,並回收寶貴的空間。

    • 高可用性 :可以在叢集中設定repo管理器,以便開發人員以及CI工具可以隨時訪問它。 回購經理的停機時間肯定會影響所有企業版本的平穩執行。

    • 使用者限制 :最後但並非最不重要的是,repo管理器可以根據使用者限制對特定工件或其組的訪問許可權。

    一個簡單的CI工作流程,從開發到真實構建

    CI工作流程與開發最佳實踐密切相關。 根據您的軟體,堆疊和用例,可能存在大量可能的CI工作流程。 讓我們看一個簡化的工作流程作為一個例子,從開發到真正的構建自動化。

    分枝

    獲取程式碼庫的最新副本。 這裡有兩種可能性:如果它是第一次被訪問,則需要“下載”它。 使用Git,這是透過 git clone 命令 實現的,該 命令將在本地複製遠端程式碼庫。

    或者,如果程式碼庫已經存在於本地,則只需要與遠端儲存庫同步,您可以執行此操作, 例如 :使用該 git pull 命令。

    在版本控制系統中,有一個專用分支指向軟體的最新穩定版本(通常 master ),這應該是應該釋出到生產中的。

    為了保護這個黃金標準免受盡可能多的錯誤,不應該直接在其上寫任何東西。 因此,每個開發都應該從master建立一個專用分支開始。

    為了保持組織的事情,有可能採用的命名方案為分支:流行的採用字首一樣 develop feature release hotfix ,等。

    測試

    現在可以開始正確的開發,無論是跨越一個或多個衝刺的全面功能開發還是快速生產錯誤修復。

    根據一個人的上下文,可以在之前(這是:測試驅動設計)或編寫程式碼之後編寫測試。 但是,在之前或之後,需要編寫測試,以確保程式碼正常工作,測試工具將捕獲可能的未來回歸。

    測試程式碼的覆蓋範圍也取決於一個人的背景:對於負責人類生命的軟體,例如平面導航或輔助手術,需要檢查每行程式碼(甚至是雙重或三重檢查)。 在其他情況下,測試的投資回報可能不那麼重要。

    拉請求

    請記住,更改不是直接在master上進行的,而是在專用分支上進行的。 開發完成後,是時候向團隊成員詢問這些更改是否可以合併到主分支中。

    這是 拉取請求 的目標 :您基本上要求您的團隊接受黃金標準的更改並開啟您的 補丁 以進行同行評審。

    一旦 PR 已經開啟,分支可以自動使用專案的構建工具,以確保我們的修改不會破壞我們的主分支的修改建。

    質量保證

    通常,還會發生其他步驟。 其中一個步驟是對已提交程式碼的自動稽核:稽核範圍可能與安全性,程式碼質量,文件標準等有關。

    在程式碼質量領域,很難不提及 SonarQube ,這是該領域領先的OpenSource平臺之一。 SonarQube與主要CI工具整合,可在一個程式碼庫上執行已配置的檢查。 這就是持續檢查的全部內容:

    SonarQube不僅能夠顯示應用程式的執行狀況,還能夠突出顯示新引入的問題。 透過質量門,您可以修復洩漏,從而系統地提高程式碼質量。

    建設

    一旦PR開啟,自動構建就會自動啟動,使用一個可用的CI工具,這些工具將完成所有構建步驟:編譯,測試,打包等。如果一個(或多個)自動構建步驟觸發了故障,我們說構建破了。

    在大多數CI工具中,損壞的構建以紅色顯示,而傳遞的構建以綠色顯示。 因此,您可能會聽到人們將傳遞構建稱為“綠色構建”。 如果構建被破壞,無論出於何種原因,由PR的起源處的開發人員來解決它。 在這個階段,構建應該透過。

    程式碼審查

    自動化是偉大的,沒有它,開發人員將無法達到他們今天所做的。 然而,它並非沒有限制。

    雖然諸如SonarQube一個工具可以檢測一個簡單的錯誤模式( 雙重檢查鎖定模式 ),它不能檢測出無限多種可能的錯誤,只有另一個人的心靈可以這樣做。

    出於這個原因,程式碼更改之前的最後一步可以合併到master中,是由其他團隊成員進行的手動程式碼審查(這是 PR的 用途!)。

    可能有很多方法可以進行程式碼審查,因為有開發人員! 我只想說你可能需要找到一個基礎的,例如 在Code Review中尋找 的優秀內容 並根據自己的需要進行調整。

    標記,版本控制和儲存構建的工件

    在這個階段,變化可以(最終)合併到主人。

    通常,這表示釋出或生產熱修復。 為了確保一切正常,CI工具應該再次重放構建,這次在主分支上進行合併更改。
    但是,還有其他操作。

    首先,VCS需要相應地標記版本,以便將其標記為這樣。
    命名為標記和版本也存在,為分支,但經常與一個更有創意的扭曲約定:經常專案選擇喜歡的主題 山名,湖名或 蛋糕的名字 ,僅舉幾例Exoscale內部使用。

    但是,雖然“Placid Pangolin”(Ubuntu)或“Oreo”(Android)是值得記住的偉大營銷名稱,但軟體開發人員應該並行使用標準版本控制方案(使用數字)。 建議遵循關於major,minor和bugfix版本的語義版本規則。 更多資訊可以在 semver.org 找到

    其次,構建結果工件需要儲存在Artifacts Repository Manager中。 這樣,如果發生意外情況並且需要執行回滾,則可以使用以前的工作版本,而無需再次從源構建。

    持續整合工具:概述

    隨著持續整合的使用越來越廣泛,有一個成熟的工具生態系統可以開始使用。 下面我們來看一下目前使用的一些最流行和最常見的CI / CD系統,從完全在雲中執行的初創企業到在內部執行自己的複雜CI平臺的大型企業組織。

    詹金斯

    Jenkins 是持續整合領域最古老的開源專案之一,仍然是最廣泛使用的專案之一。

    這麼長的遺產有上升空間和缺點。 多年來,核心架構已經在從小規模部署到 世界上 一些 最大公司的 生產環境中經過了長時間的測試 ,並且有一個充滿活力的Jenkins使用者線上社群,可以幫助您解決可能遇到的問題。

    但是,大型遺留程式碼庫和向後相容性要求意味著它的內部抽象通常過時 - 而且這些常常會洩漏給不同場景下的使用者。

    此外,雖然Jenkins擁有廣泛的外掛生態系統,可提供許多現代功能,但這些外掛通常是社群開發的,可以在質量和可靠性方面有所不同。

    近年來,Jenkins獲得了一種新語言,用於描述稱為 管道的 持續整合工作流程 這些允許開發人員宣告和描述構建和部署過程。 Jenkins還允許您建立可以在不同專案中重用的模組,以標準化和簡化常見流程。

    簡而言之,Jenkins擁有悠久的開發和使用歷史,一個龐大而活躍的社群,並且具有高度可定製性。 也許出於這些原因,你可以說,“沒有人因為選擇詹金斯而被解僱。”

    特拉維斯CI

    Travis CI 幾乎和Jenkins一樣令人尊敬,雖然它的許多元件都是開源的,但如果沒有企業帳戶,就不可能自行託管。 但是,使用任何開源專案執行Travis都是免費的。

    您希望Travis執行的每個任務都包含在 程式碼旁邊 .travis.yml 檔案中,這也意味著您可以從儲存庫的不同分支執行不同的任務。

    Travis旨在簡化,直接從GitHub託管的儲存庫工作,並維護許多應用程式中常見的服務庫。 但是,如果您不使用GitHub或需要更多控制,那麼其他選項可能更適合您。

    Travis的一個有用功能是能夠在多個作業系統上執行,這意味著您可以在不同目標上測試程式碼,而無需維護機器或虛擬映像。

    GitLab持續整合/持續交付

    GitLab最初是一個原始碼託管服務,類似於GitHub,但也有開源版本。 與GitHub不同,GitLab現在包含一個 內建於其平臺 的高階CI / CD實現(稱為 AutoDevOps )。

    對於那些已經使用GitLab儲存原始碼的人來說,這種緊密整合是GitLab CI / CD產品最有用的方面之一。 您可以透過將.gitlab-ci.yml配置檔案新增到原始碼儲存庫的根目錄來啟用它。

    您可以將GitLab CI / CD與GitHub儲存庫整合。

    Bamboo是Atlassian的持續整合/持續交付產品,Atlassian是一家在大多數軟體環境中為其JIRA錯誤跟蹤軟體而聞名的公司。

    Bamboo的主要優勢之一是它與已經執行這些系統的其他Atlassian產品(如JIRA和Bitbucket)緊密整合。 它還有一個大型附加元件市場。

    在缺點方面,Bamboo擁有較小的使用者社群,因此使用者可能更依賴於Atlassian的支援。

    CircleCI

    CircleCI是一種現代線上服務(也可作為託管版本提供),旨在提供強大的CI平臺。 CircleCI將其平臺集中在容器周圍,併為測試提供快速啟動時間。 工作流功能允許使用者定義CI和CD作業的序列,即使對於最複雜的專案也是如此。

    CircleCI的主要優勢在於它是一個完全託管的CI解決方案,可以減少終端使用者投入系統維護的時間。

    結論

    儘管持續整合最佳實踐和工具對於實現正確性非常重要,但它們往往不足以使組織走上CI路徑。 對於許多傳統軟體組織而言,從傳統的手動步驟切換到CI流程需要對軟體團隊協同工作的方式進行深刻的改變。

    為了能夠成功地將變更集整合到程式碼庫中,團隊必須就工作模式和規範集合達成一致並堅持下去。 實現可靠的構建步驟有時需要進行嚴格的重構,並且不斷地部署到生產中會開啟團隊需要圍繞和處理的問題的全新視野。

    但是,當一起考慮時,採用持續整合實踐為軟體組織帶來的好處是不可否認的。 現在,這已成為軟體世界的一個新常態,CI實踐的採用增長只會在未來加速。


    來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/31557424/viewspace-2220399/,如需轉載,請註明出處,否則將追究法律責任。

    相關文章