Microsoft 如何使用 DevOps 進行開發

Microsoft 致力於使用 一個工程系統 來建置和部署所有 Microsoft 產品,其具有以 Git 分支和發行流程為中心的穩固 DevOps 程式。 本文強調實際實作、系統如何從小型服務調整到大規模的平台開發需求,以及從跨各種 Microsoft 小組使用系統所學到的教訓。

採用標準化的發展過程是一項雄心勃勃的事業。 不同 Microsoft 組織的需求有很大的差異,而且組織內不同小組的需求會隨著大小和複雜度而調整。 為了解決這些不同的需求,Microsoft 使用 主幹式分支策略 來協助快速開發產品、定期部署產品,以及安全地將變更傳遞給生產環境。

Microsoft 也會使用 平臺工程原則 作為其 One Engineering System 的一部分。

Microsoft 發行流程

每個組織都應該解決標準程式代碼發行程式,以確保小組之間的一致性。 Microsoft 發行流程包含從開發到發行的 DevOps 程式。 發行流程的基本步驟包含分支、推送、提取要求和合併。

分支

若要修正 Bug 或實作功能,開發人員會從主要整合分支建立新的分支。 Git 輕量型分支模型會為每個程式代碼貢獻建立這些短期 主題 分支。 開發人員會提早認可並避免長時間執行的功能分支,方法是使用 功能旗標

推送

當開發人員準備好將變更整合到小組的其餘部分時,他們會將其本機分支推送至伺服器上的分支,然後開啟提取要求。 在多個分支中工作的數百名開發人員的存放庫會使用伺服器分支的命名慣例,以減輕混淆和 分支激增。 開發人員通常會建立名為 users/<username>/feature的分支,其中 <username> 是其帳戶名稱。

提取要求

提取要求控制主題分支會合併到主要分支,並確保符合分支原則。 提取要求程式會建置建議的變更,並執行快速測試階段。 第一層和第二層測試套件在不到五分鐘內執行大約 60,000 個測試。 這不是完整的 Microsoft 測試矩陣,但足以快速提供提取要求的信心。

接下來,小組的其他成員會檢閱程式代碼並核准變更。 程式代碼檢閱會挑選自動化測試的離開位置,特別適合用來找出架構問題。 手動程式代碼檢閱可確保小組中的其他工程師能夠了解變更,且程式代碼品質仍然很高。

合併

提取要求滿足所有建置原則和檢閱者已註銷之後,主題分支就會合併至主要整合分支,且提取要求已完成。

合併之後,其他驗收測試會執行,需要更多時間才能完成。 這些傳統的簽核后測試會執行更徹底的驗證。 此測試程式可在提取要求檢閱期間快速測試,以及在發行前完成測試涵蓋範圍之間提供良好的平衡。

GitHub Flow 的差異

GitHub Flow 是熱門 主幹型開發 發行流程,可讓組織實作 Git 的可調整方法。 不過,有些組織發現,隨著其需求的增長,他們必須從 GitHub Flow 的部分區隔開。

例如,通常忽略 GitHub Flow 的一部分是提取要求必須部署到生產環境進行測試,才能合併至主要分支。 此程式表示所有提取要求都會在部署佇列中等候合併。

有些小組有數百名開發人員經常在單一存放庫中工作,他們每天可以完成超過 200 個提取要求到主要分支。 如果每個提取要求都需要部署至全球各地的多個 Azure 資料中心進行測試,開發人員會花時間等待分支合併,而不是撰寫軟體。

相反地,Microsoft 小組會繼續在主要分支中開發,並將部署批處理成定時版本,通常與三周 的短期衝刺 步調一致。

實作詳細資料

以下是 Microsoft 發行流程的一些重要實作詳細數據:

Git 存放庫策略

不同的小組有不同的策略來管理其 Git 存放庫。 有些小組會將大部分的程式代碼保留在一個 Git 存放庫中。 程序代碼分成元件,每個元件都位於其本身的根層級資料夾中。 大型元件,尤其是較舊的元件,可能會有多個子元件,這些子元件在父元件內有個別的子元件。

Screenshot showing a Git repository structure.

輔助存放庫

有些小組也會管理附屬存放庫。 例如,建置和發行代理程式和工作VS Code 延伸模組開放原始碼專案是在 GitHub 上開發。 組態變更會簽入個別存放庫。 小組相依的其他套件來自其他地方,並透過 NuGet 取用。

Mono 存放庫或多重存放庫

雖然某些小組選擇擁有單一整合式存放庫, 但單一存放庫,其他 Microsoft 產品會 使用多重存放庫 方法。 例如,Skype 有數百個小型存放庫,這些存放庫會組合在各種組合中,以建立許多不同的客戶端、服務和工具。 特別是對於採用微服務的小組而言,多存放庫可以是正確的方法。 通常,以整合體開頭的較舊產品會尋找單一存放庫方法,以最簡單的方式轉換至 Git,而其程式代碼組織會反映這一點。

發行分支

Microsoft 發行流程會隨時讓主要分支保持可建置。 開發人員會在合併至 main的短期主題分支中工作。 當小組準備好出貨時,無論是短期衝刺結束時還是主要更新,他們就會從主要分支開始新的發行分支。 發行分支永遠不會合併回主要分支,因此可能需要 挑選 櫻桃的重要變更。

下圖顯示藍色的短期分支,並以黑色發行分支。 一個具有需要櫻桃挑選的認可分支會出現在紅色中。

Diagram showing Git release branch structure.

分支原則和許可權

Git 分支原則可協助強制執行發行分支結構,並讓主要分支保持乾淨。 例如,分支原則可以防止直接推送至主要分支。

為了保持分支階層的整齊,小組會使用許可權來封鎖階層根層級的分支建立。 在下列範例中,每個人都可以在使用者/、功能/和 teams/資料夾中建立分支。 只有發行管理員有權在 releases/下建立分支,而某些自動化工具具有 integrations/ 資料夾的許可權

Screenshot that shows branches.

Git 存放庫工作流程

在存放庫和分支結構內,開發人員會執行其日常工作。 工作環境會因小組和個人而有所不同。 有些開發人員偏好命令行,有些像是 Visual Studio,有些則在不同的平台上運作。 Microsoft 存放庫上的結構和原則可確保穩固且一致的基礎。

一般工作流程牽涉到下列一般工作:

建置新功能

建置新功能是軟體開發人員工作的核心。 此程式的非 Git 部分包括查看遙測數據、提出設計和規格,以及撰寫實際程式代碼。 然後,開發人員會藉由同步處理至 上的最新認可 main,開始處理存放庫。 主要分支一律可建置,因此保證是不錯的起點。 開發人員會簽出新的功能分支、進行程式碼變更、認可、推送至伺服器,然後啟動新的提取要求。

使用分支原則和檢查

建立提取要求時,自動化系統會檢查新的程式碼組建、不會中斷任何專案,也不會違反任何安全性或合規性原則。 此程式不會阻止其他工作平行發生。

分支原則和檢查可能需要 成功的組建 ,包括通過的測試、 任何觸控程式代碼的擁有者 簽署,以及數 個外部檢查 來驗證公司原則,才能完成提取要求。

Screenshot showing the checks on a pull request.

與 Microsoft Teams 整合

許多小組會設定 與 Microsoft Teams 的整合,這會向開發人員的小組成員宣佈新的提取要求。 任何觸及的程式代碼擁有者都會自動新增為檢閱者。 Microsoft 小組通常會使用選擇性的檢閱者來撰寫許多人接觸的程式代碼,例如 REST 用戶端產生和共用控件,讓專家能夠關注這些變更。

Screenshot showing Teams integration.

Screenshot showing Teams notification of a pull request.

使用功能旗標進行部署

一旦滿足檢閱者、程式代碼擁有者和自動化,開發人員就可以完成提取要求。 如果有合併衝突,開發人員會取得如何同步至衝突、修正衝突,以及重新推送變更的指示。 自動化會在固定程式代碼上再次執行,但人類不需要再次註銷。

分支會合併至 main,而新的程式碼會在下一個短期衝刺或主要版本中部署。 這並不意味著新功能將立即顯示。 Microsoft 會使用 功能旗標來分離新功能的部署和曝光。

即使功能在準備好炫耀之前需要多一點工作,如果產品建置和部署,還是可以放心地前往 main 。 一旦進入 main,程序代碼就會成為官方組建的一部分,其會再次進行測試、確認以符合原則,並經過數字簽署。

向左移以提前偵測問題

此 Git 工作流程提供數個優點。 首先,從單一主要分支中制定,幾乎可以消除 合併債務。 其次,提取要求流程提供在管線早期強制執行測試、程式代碼檢閱和錯誤偵測的常見點。 此 移位左 移策略有助於縮短開發人員的意見反應週期,因為它可以在幾分鐘內偵測到錯誤,而不是數小時或數天。 此策略也會提供重構的信心,因為所有變更都會持續測試。

目前,具有200個以上提取要求的產品每天可能會產生300個以上的持續整合組建,相當於每24小時執行500個以上的測試回合。 如果沒有以主幹為基礎的分支和發行工作流程,就無法進行這種測試層級。

在短期衝刺里程碑發行

在每個短期衝刺結束時,小組會從主要分支建立發行分支。 例如,在短期衝刺 129 結束時,小組會建立新的發行分支 releases/M129。 小組接著將短期衝刺 129 分支放入生產環境。

發行分支的分支之後,主要分支會保持開放,供開發人員合併變更。 這些變更將在下一個短期衝刺部署中部署三周后。

Illustration of the release branch at sprint 129.

發行 Hotfix

有時候變更需要快速移至生產環境。 Microsoft 通常不會在短期衝刺中間新增新功能,但有時想要快速引進 Bug 修正,以解除封鎖使用者。 問題可能很小,例如錯字,或足以造成可用性問題或 即時網站事件

從一般工作流程開始修正這些問題。 開發人員會從 main建立分支,並檢閱程式代碼,並完成提取要求以合併它。 此程式一律會先進行變更 main 。 這可讓您快速建立修正程式並在本機進行驗證,而不需要切換至發行分支。

遵循此程式也保證變更會進入 main,這很重要。 修正發行分支中的錯誤,而不需要將變更帶回 main ,表示當 Sprint 130 發行分支從 main中時,Bug 會在下一個部署期間重複。 很容易忘記在中斷期間可能發生的混淆和壓力期間更新 main 。 將變更 main 帶入第一個表示在主要分支和發行分支中一律有變更。

Git 功能可啟用此工作流程。 若要立即將變更帶入生產環境,一旦開發人員將提取要求合併至 main,他們就可以使用提取要求頁面將變更切入發行分支。 此程式會建立以發行分支為目標的新提取要求,並將剛合併的內容回傳至 main

Illustration of cherry-picking a hotfix commit into branch 129.

使用櫻桃挑選功能可快速開啟提取要求,以提供分支原則的可追蹤性和可靠性。 採摘作業可能會發生在伺服器上,而不需要將發行分支下載到本機計算機。 進行變更、修正合併衝突,或因兩個分支之間的差異而進行次要變更,都可能發生在伺服器上。 Teams 可以直接從瀏覽器型文本編輯器或透過 提取要求合併衝突延伸模組 來編輯變更,以取得更進階的體驗。

提取要求以發行分支為目標后,小組程式代碼會再次檢閱、評估分支原則、測試提取要求,以及合併它。 合併之後,修正程式會在幾分鐘內部署到伺服器的第一 個通道 。 從該處,小組會使用部署通道,逐漸將修正程式部署到更多帳戶。 當變更部署到更多使用者時,小組會監視成功,並確認變更會修正 Bug,而不會造成任何缺陷或變慢。 修正程序最終會部署到所有 Azure 資料中心。

繼續下一個短期衝刺

在接下來的三周內,小組會完成將功能新增至短期衝刺 130,並準備好部署這些變更。 他們會從 main建立新的發行分支,releases/M130然後部署該分支。

此時,生產環境中實際上有兩個分支。 透過以通道為基礎的部署安全地將變更帶入生產環境,快速通道會取得短期衝刺 130 變更,而慢速通道伺服器則會保留在短期衝刺 129 上,同時在生產環境中驗證新的變更。

在部署中間進行變更的 Hotfix 可能需要 Hotfix 兩個不同的版本:短期衝刺 129 版本和短期衝刺 130 版本。 小組埠並將 Hotfix 部署到這兩個發行分支。 130 分支會使用 Hotfix 重新部署至已升級的通道。 129 分支會使用 Hotfix 重新部署至尚未升級至下一個短期衝刺版本的外部通道。

一旦部署所有通道之後,舊的短期衝刺 129 分支就會被放棄,因為任何變更都已帶入短期衝刺 129 分支,做為 Hotfix。main 因此,這些變更也會在 分支中 releases/M130

Illustration of a release branch at sprint 130.

摘要

發行流程模型是 Microsoft 如何使用 DevOps 進行開發以提供 線上服務 的核心。 此模型會使用簡單且以主幹為基礎的分支策略。 但是,Microsoft 發行流程可讓開發人員繼續運作,而不是讓開發人員停滯在部署佇列中,而等待合併其變更。

儘管 Microsoft 程式代碼基底的大小和在其中工作的開發人員數目,但此發行模型也允許以一般頻率在 Azure 數據中心部署新功能。 此模型也允許快速且有效率地將 Hotfix 帶入生產環境。