Microsoft AZ-400: 原始碼控制與儲存庫管理 — 學習指南
屬於 Microsoft DevOps Engineer Expert AZ-400 — 學習指南. 使用經過驗證的解答練習: Microsoft 考試中心, 或參加限時模擬考試: ExamRoll.io.
總覽
現代 DevOps 實務的關鍵在於可預測、協作式的原始碼控制與嚴謹的儲存庫管理。Azure Repos 與 GitHub 提供了互補的功能,涵蓋版本控制、原則強制執行、協作與安全性。精通分支策略、拉取請求工作流程、權限、掛鉤 (hooks)、大型檔案處理、遷移模式、安全性掃描與版本控制,對於建立具備韌性的交付管線與可稽核性至關重要。目標不僅是儲存程式碼,更是要建立一套可強制執行、自動化的控制系統,以便在不犧牲品質的前提下,擴展團隊的產出。
Azure Repos 與 GitHub 中的原始碼控制基礎
Azure Repos 支援 Git 與 Team Foundation Version Control (TFVC)。Git 是分散式的,允許本機提交、輕鬆建立分支,並支援去中心化的工作流程。TFVC 則是集中式的,具備伺服器端版本控制、鎖定簽出(可選用)等功能,非常適合擁有極大二進位資產的舊有解決方案,或習慣集中式工作流程的團隊。新的開發專案應預設使用 Git;但當增量變更控制與中央權限至關重要,且遷移成本過高時,TFVC 仍是可行的選擇。
請審慎選擇分支策略:
- 主幹式開發(Trunk-based development)偏好使用單一、長生命週期的 main 分支,搭配極短生命週期的功能分支與持續整合。這種方式能加速流程、減少合併債務,非常適合擁有強大測試自動化且交付節奏快的團隊。
- GitFlow 使用長生命週期的 develop 和 main(發布)分支,並搭配功能、發布和修補程式(hotfix)分支。它適合有正式發布排程與向後移植(backporting)需求的產品,但會增加協調的額外負擔。
- GitHub Flow 是一個簡化模型,只有一個 main 分支、短生命週期的主題分支、持續部署與頻繁的發布。對於需要持續交付的服務來說,這種方式非常有效。
Monorepo 與 multi-repo 的選擇,主要取決於組織與工具的考量:
- Monorepo 將許多元件整合在單一儲存庫中,有助於跨服務的原子性變更、統一重構與共用工具。但隨著歷史紀錄增長,可能會對 Git 操作造成壓力。緩解技術包括稀疏檢出(sparse checkout)、部分複製(partial clone),以及使用 CI 路徑過濾器來限定建置與測試的範圍。
- Multi-repo 則將所有權、歷史紀錄與權限邊界隔離開來,有助於獨立的版本控制與保留策略。但這可能增加跨儲存庫的協調工作與依賴性漂移(dependency drift)的風險;因此,子模組(submodules)或依賴性管理器,以及發布協調機制就變得至關重要。
透過程式碼所有權宣告,可以讓所有權與變更的路由更加明確。GitHub 的 CODEOWNERS 檔案能自動將路徑對應到必要的審核者。在 Azure Repos 中,則可使用分支原則中的路徑型必要審核者(以及啟用時的 CODEOWNERS)來將審核請求分派給對應的元件團隊。除了所有權之外,還應搭配分支命名慣例、清晰的提交訊息(例如:Conventional Commits)以及儲存庫範本,以確保一致性。
治理:原則、權限與拉取請求
Azure Repos 中的分支原則能將品質閘門程式碼化:
- 必要審核者(Required reviewers)強制要求最少的審核者數量,可包含特定個人/群組,或基於路徑的自動審核者。要求解決留言(Require comment resolution)以確保在合併前,所有實質性的回饋都已處理。
- 建置驗證(Build validation)要求在合併前,必須有一個或多個 CI 管線成功通過。使用路徑過濾器來避免不必要的建置,並設定在新更新時自動觸發。透過狀態原則(status policies)整合外部檢查,例如安全性掃描或效能測試。
- 合併策略(Merge strategies)可以加以限制:Merge (no fast-forward) 會記錄合併歷史;Squash 會將變更壓縮成單一提交,保持歷史紀錄的線性;Rebase and fast-forward 會在 main 之上重寫主題分支,形成一條直線的歷史;Rebase and merge 則會重播提交,並保留個別提交,但不會產生合併提交。請根據稽核需求與下游工具來選擇合適的策略。
- 其他檢查項目包括要求連結工作項目、最少成功投票數,以及當有未解決的留言或待審核者時予以封鎖。
拉取請求(Pull requests)是協調整合過程的對話機制:
- 草稿 PR(Draft PRs)表示工作仍在進行中,並會阻止完成,直到標記為就緒為止。這能鼓勵早期回饋,而不會過早觸發原則。
- 自動完成(Auto-complete)會在所有原則通過後自動合併,減少協調延遲並提升流程效率。
- 繞過原則(Bypass policies)的功能是為緊急情況或自動化帳戶而設。應使用「Bypass policies when completing pull requests」權限將其鎖定,並透過核准與變更管理進行稽核。
- PR 範本能將上下文標準化:測試證據、風險說明、部署步驟與回滾計畫。在 Azure Repos 中,將 pull_request_template.md 檔案放在儲存庫根目錄或 .azuredevops/ 資料夾中。提供安全性、效能與文件化的檢查清單。
權限與受保護的分支是您的最後一道防線:
- 使用 Azure DevOps 的 RBAC 群組(Project Administrators、Contributors、Readers)以及細微的儲存庫權限(Create branch、Create tag、Contribute、Force push、Manage permissions、Bypass policies)。應優先在群組上設定允許/拒絕,而非針對個人。
- 透過拒絕 Force push 與刪除、將 Contribute 權限限制為僅能透過 PR 合併,並啟用要求建置與審核的分支原則,來保護 main 與 release 分支。可考慮使用「Lock」來暫時凍結變更。
- 使用分支層級的權限來限制誰可以針對敏感分支建立或完成 PR,並將開發人員與發布經理的職責分開。
自動化、掛鉤 (Hooks)、大型檔案與安全性
Git hooks 從邊緣強化品質:
- Pre-commit hooks 在開發人員記錄 commit 之前,於本機強制執行程式碼風格檢查 (linting)、格式化、密鑰檢查和單元測試。請保持其快速且具確定性。
- Pre-push hooks 會阻擋未能通過整合測試或政策檢查的程式碼推送。透過工具 (例如,適用於 JavaScript 的 Husky) 提供團隊通用的 hook 指令稿,並記錄選擇性加入 (opt-in) 的方式。
- 受託管服務中的伺服器端 hooks 有所不同:GitHub 支援伺服器 webhooks 和必要狀態檢查;Azure DevOps Services 不允許自訂伺服器端 hooks,但支援分支政策、建置驗證、服務掛鉤 (service hooks) 以及來自外部系統的狀態檢查。在 Azure DevOps Server (on-prem) 中,伺服器端 hooks 是可行的。
大型檔案儲存 (Git LFS) 將大型二進位檔案儲存在 Git 物件資料庫之外,以維持 repo 的高效能:
- 使用
git lfs track "*.psd"或特定二進位檔案類型來追蹤模式。Commit.gitattributes檔案,以便所有貢獻者都能一致地套用 LFS。 - 透過執行帶有路徑篩選器的
git lfs migrate import來遷移歷史記錄,將大型二進位檔案重寫為指標 (pointers)。與團隊協調並暫停推送;謹慎地執行 force-push 並更新 clones。 - 透過避免不必要的 smudging 來管理頻寬。使用
GIT_LFS_SKIP_SMUDGE=1並選擇性地執行git lfs fetch/pull。在 CI 中快取 LFS,並考慮為不需要存放在 Git 中的二進位檔案使用成品儲存庫 (artifact repositories)。
安全性保證應採取左移 (shift-left) 且基於政策的方法:
- GitHub Advanced Security (GHAS) 帶來了密鑰掃描 (包含推送保護)、使用 CodeQL 進行的程式碼掃描,以及依賴性審查,以捕捉外洩的憑證、程式碼漏洞和供應鏈風險。在 PR 上強制執行為必要檢查。對於 Azure Repos,可使用 Advanced Security for Azure DevOps 來實現類似的密鑰掃描、透過 CodeQL 進行的 SAST,以及依賴性洞察。
- 應設定密鑰掃描以阻擋包含高信度密鑰的推送,並向安全應變人員發出警報。支援針對組織特定模式的自訂偵測器。
- CodeQL 程式碼掃描應在
pull_request和排程觸發器上執行,將 SARIF 結果上傳為狀態檢查。調整查詢包 (query packs) 以減少雜訊,並在關鍵路徑上強制執行覆蓋範圍。 - 依賴性審查會在 PR 審查期間揭露版本變更和已知的安全公告;利用此功能來執行修復 SLA 和授權治理。
遷移、版本控制與發布管理
從 TFVC 遷移到 Git 需要根據風險承受度來調整策略和工具:
- 若要進行包含深度歷史紀錄和工作項目連結的高擬真度遷移,請使用 git-tfs 將 TFVC 路徑複製到 Git,以保留變更集並對應使用者。按應用程式或分支進行分割,以保持 Git 儲存庫的易管理性。在遷移期間或之後,使用 LFS 清理大型二進位檔案。
- 若要進行目前狀態的輕量級遷移,請使用 Azure DevOps 匯入工具從 TFVC (或其他 Git 主機) 建立一個新的 Git 儲存庫,並可選擇性地限制歷史紀錄。這能縮短時程和降低風險,但會犧牲深度歷史紀錄的精細度。
- 透過遷移標籤/標記、將 TFVC 分支對應到 Git 分支,並保留一個唯讀的 TFVC 鏡像以供稽核,來維持可追溯性。透過試行專案進行驗證,在切換期間凍結原始碼,並執行驗證矩陣 (建置、測試和部署)。
採用語意化版本控制以提高清晰度和自動化程度:
- 使用 SemVer 2.0.0:MAJOR.MINOR.PATCH,可選用預發行版本 (例如 -rc.1) 和建置中繼資料 (+build.45)。使用附註標籤 (git tag -a v1.4.2 -m “Release 1.4.2”) 來標記發行版本,並簽署標籤以供稽核。
- 在 CI/CD 中自動化版本號提升:
- 透過約定式提交 (Conventional Commits) 和發布工具 (例如 GitVersion 或 semantic-release),根據提交類型和範圍來計算下一個版本號。
- 自動更新建置號碼和套件版本;如果發生版本漂移或標籤衝突,則讓建置失敗。
- 將版本控制與分支策略對齊:
- 主幹式開發:main 分支永遠處於可發布狀態;從 main 建立發布標籤;僅在穩定化階段使用短生命週期的發布分支。
- GitFlow:release/* 分支承載一個凍結的次要版本;從 main 分支建立 hotfix/* 分支以進行緊急修補;合併回 develop 和 main 分支,並在合併完成時加上標籤。
- GitHub Flow:在部署時為 main 分支加上標籤;使用預發行標籤進行金絲雀部署。
將發布自動化與儲存庫策略整合:要求發布管線必須有成功的建置 (green builds),在沒有從提交中產生更新的變更日誌時阻止合併,並在受監管的環境中要求簽署的提交/標籤。
實務問題情境
星巴克必須將多個在 TFVC 中管理的舊有應用程式整合到 Azure Repos Git,同時為其服務和行動應用程式建立一致的治理、安全性掃描和可擴展的工作流程。
- 選擇分支與儲存庫拓撲
- 行動:採用主幹式開發,為共用函式庫建立一個單體儲存庫 (monorepo),並為獨立發布的服務建立幾個專注的服務儲存庫。在開發人員的新進引導腳本中,為 monorepo 啟用稀疏檢出 (sparse checkout)。
- 原因:主幹式開發減少了合併債務並加速整合;monorepo 集中管理共用程式碼並實現原子重構,而稀疏檢出則避免了團隊只接觸部分程式碼時,需要處理完整歷史紀錄和工作目錄的開銷。
- 將 TFVC 專案遷移到 Git,並在有價值的情況下保留歷史紀錄
- 行動:使用 git-tfs 遷移主要的網站和行動應用程式程式碼庫,並保留完整歷史紀錄,在遷移過程中將大型資產路徑對應到 Git LFS。對於小型工具程式,則使用 Azure DevOps 匯入工具僅匯入目前狀態。
- 原因:git-tfs 為旗艦級應用程式保留了關鍵的可追溯性;選擇性地使用匯入工具可加速低風險遷移並縮短專案時程。
- 建立受保護的分支和分支策略
- 行動:保護 main 和 release/* 分支,禁止強制推送/刪除 (Force push/Delete);要求兩位審核者、解決所有留言、連結工作項目,並通過帶有路徑篩選器的建置驗證。對於服務儲存庫,將合併限制為壓縮合併 (Squash);對於 monorepo,則限制為變基與快轉 (Rebase and fast-forward) 以保持線性歷史紀錄。除了少數的發布工程團隊外,禁用「繞過策略」的權限。
- 原因:策略即程式碼 (Policy-as-code) 強化了品質關卡和可稽核性。合併策略反映了團隊的偏好:Squash 簡化了服務的回復 (revert) 和揀選提交 (cherry-pick);monorepo 中的線性歷史紀錄則加速了追溯 (blame) 和二分搜尋 (bisect) 操作。
- 標準化 Pull Request 實務
- 行動:在 .azuredevops/ 下新增 pull_request_template.md,其中包含風險、測試證據、效能影響和回滾計畫等區塊。鼓勵及早建立草稿 PR (Draft PRs);為所有 PR 啟用自動完成 (Auto-complete)。設定基於路徑的必要審核者以模擬程式碼擁有權,並為託管在 GitHub 上的儲存庫新增 CODEOWNERS 檔案。
- 原因:範本提升了審核品質的下限;草稿 PR 促進了早期協作;自動完成消除了閒置時間;擁有權路由能將正確的審核者指派到對應的程式碼差異上。
- 實作掛鉤與 CI 關卡
- 行動:透過儲存庫工具分發 pre-commit/pre-push 掛鉤,以強制執行程式碼風格檢查 (linting)、密鑰檢查和單元測試;並保持執行速度。使用 Azure Pipelines 的建置驗證作為標準的強制執行方式,並從安全性掃描器新增狀態檢查。避免使用自訂的伺服器端掛鉤;改用服務掛鉤來通知外部系統。
- 原因:本地掛鉤能在不阻礙協作的情況下及早發現問題;在 Azure DevOps 中,伺服器端的強制執行最好透過分支策略和狀態檢查來實現,以確保可靠性和可稽核性。
- 使用 Git LFS 管理大型資產
- 行動:使用 git lfs track 追蹤二進位檔案模式 (圖片、設計資產、測試媒體);使用 git lfs migrate import 遷移舊有的二進位檔案。設定 CI 將 GIT_LFS_SKIP_SMUDGE=1 並選擇性地擷取以減少頻寬使用;在建置代理程式上快取 LFS 產物。
- 原因:保持儲存庫的快速,避免過度的網路使用,同時維持可重現的建置。
- 整合 Advanced Security
- 行動:在 GitHub 儲存庫上啟用 GitHub Advanced Security,並在 Azure Repos 上啟用 Advanced Security for Azure DevOps。開啟具有推送保護功能的密鑰掃描 (secret scanning),在 PR 和夜間建置時執行 CodeQL,並啟用相依性審核檢查。當發現高嚴重性問題時,阻止 PR 完成。
- 原因:將安全性左移,防止憑證洩漏和可利用的模式進入 main 分支,並在審核期間提供可行的洞見。
- 自動化語意化版本控制與標記
- 行動:在 Azure Pipelines 中使用 GitVersion,根據分支和提交歷史紀錄計算 SemVer;在發布管線中簽署並推送附註標籤;從約定式提交 (Conventional Commits) 產生發行說明。僅在穩定化階段使用 release/* 分支;從已標記的 main 分支建立緊急修復 (hotfix)。
- 原因:確定性、自動化的版本能改善可追溯性和部署的可重現性,而簽署的標籤則支援合規性要求。
這個順序降低了遷移風險,強制執行一致的品質和安全性,並簡化了交付流程——精確地將儲存庫管理與可擴展的 DevOps 操作對齊。
所有領域 · 使用 Azure Pipelines 的 CI →
練習這些題目 → · 在 ExamRoll.io 上限時練習 →
Pass the whole exam — not just this question
You found this answer. Get every verified question and explanation in one place, and save hours of prep. Free to start.
通過考試 →