
簡介這是一份面向 Azure DevOps 用戶的 Azure Pipelines 官方文檔操作手冊適合需要搭建持續(xù)集成與持續(xù)交付流程的開發(fā)、運維及 DevOps 工程師閱讀。內(nèi)容系統(tǒng)覆蓋核心概念與落地操作從代理、條件、表達(dá)式、環(huán)境、作業(yè)、階段、任務(wù)、模板到觸發(fā)器均有說明并針對 GitHub、Azure Repos、Bitbucket 等倉庫集成、多環(huán)境部署、容器構(gòu)建、測試執(zhí)行及代理池管理等場景給出操作指南可幫助讀者快速掌握管道編寫與發(fā)布配置。資源為 1 個 PDF 文件整體大小 106.6MB頁面內(nèi)容為 Azure Pipelines 文檔的中文版節(jié)選既適合新手從零了解 CI/CD 理念也對已使用者查閱具體任務(wù)參數(shù)與排錯思路有參考價值。目前已有 412 人學(xué)習(xí)瀏覽。通過閱讀這份手冊讀者可獲得一份結(jié)構(gòu)完整的 Azure Pipelines 速查資料便于在項目中落地自動化構(gòu)建、測試與部署流程減少摸索時間。1. 從找不到代理開始為什么配置 Azure Pipelines 的第一步就讓人想退坑某次幫同事調(diào)一個 Node.js 項目的持續(xù)集成YAML 文件寫了三行自認(rèn)為沒什么可錯的結(jié)果 pipeline 一跑就報錯No agent found in pool。折騰了兩個小時最后發(fā)現(xiàn)是自托管代理壓根沒裝代理池名字還對不上。這個報錯幾乎每個剛接觸 Azure Pipelines 的人都會遇到——它不會告訴你該裝什么、該配什么只會給你一個毫無頭緒的錯誤信息。Azure Pipelines 是 Azure DevOps 的核心 CI/CD 服務(wù)支持從 GitHub、Azure Repos、Bitbucket 拉代碼在 Windows、Linux、macOS 上并行構(gòu)建把 .NET、Java、Python、Node.js、Go 這類主流生態(tài)全部覆蓋。但它的配置鏈路很長組織、項目、代理、服務(wù)連接、YAML 語法任何一環(huán)斷了都跑不通。這篇筆記就是按我實際裝過的順序從版本選型、注冊組織到寫第一條 YAML、配自托管代理再到排錯清單一步步給你走完一遍。2. 準(zhǔn)備環(huán)境版本選型、免費額度與注冊組織2.1 版本選型Azure DevOps Services、Server 2022 和 TFS 怎么選裝 Azure Pipelines 之前先要分清你用的是哪一套環(huán)境因為注冊方式、功能范圍和踩坑點都不一樣。Azure DevOps Services 是微軟的云服務(wù)版本直接瀏覽器訪問https://dev.azure.com/{你的組織名}就能用。它更新最快YAML 管道、環(huán)境、審批這些新特性都在這個版本上最先落地。私有項目每個月有 1800 分鐘30 小時的免費管道運行時長公共項目可以直接免費跑管道這個額度對個人學(xué)習(xí)和小團(tuán)隊試用完全夠。Azure DevOps Server 是自托管版本對應(yīng) 2019、2022 兩個大版本。它適合代碼必須留在內(nèi)網(wǎng)、不允許出域的場景。注意 Server 版本里某些 YAML 功能是缺失的比如環(huán)境的部署作業(yè)deployment job在 Server 2022 上支持但部分容器作業(yè)能力不如云版本。TFS2018 屬于老古董了除非你被老項目綁死否則不建議新裝因為很多文檔里的新特性它都沒有。判斷方法很簡單你的代碼在 GitHub 或別人的云端倉庫上選 Services代碼只能留在公司內(nèi)網(wǎng)選 Server。我一般建議個人開發(fā)者直接上 Services省掉自己維護(hù)服務(wù)器的成本。Server 版本要額外買許可證五個活躍用戶以內(nèi)用 Express 版是免費的但安裝復(fù)雜度高不少。2.2 注冊與創(chuàng)建組織免費啟動流程無論用 Microsoft 賬戶還是 GitHub 賬戶都能注冊 Azure DevOps。用 GitHub 賬戶注冊有個前提如果 GitHub 郵箱關(guān)聯(lián)的是支持 Azure AD 的組織就必須改用 Azure AD 賬戶登錄否則會卡在授權(quán)那一步。打開 Azure DevOps 官網(wǎng)選擇「免費啟動」會進(jìn)入組織創(chuàng)建頁。需要填三項組織名稱、主機位置、驗證字符。組織名稱就是將來訪問 URL 的一部分比如填devops-learning最終地址就是https://dev.azure.com/devops-learning。主機位置一般選離你最近的數(shù)據(jù)中心國內(nèi)用戶通常選東南亞或東亞區(qū)域網(wǎng)絡(luò)延遲更友好。提示組織名創(chuàng)建后可以改顯示名稱但 URL 的標(biāo)識部分基本定了。起名別太隨意后面所有 SSH 克隆地址、服務(wù)連接、pipeline 配置都會帶上這個標(biāo)識。創(chuàng)建完成后系統(tǒng)會提示創(chuàng)建一個項目。項目有公共和專用兩種可見性CI/CD 學(xué)習(xí)階段選專用就好。項目名最好和倉庫名對應(yīng)后面在 pipeline 里引用時會省事。接著用 Azure CLI 驗證一下環(huán)境是否就緒az login az devops configure --defaults organizationhttps://dev.azure.com/devops-learning projectmy-first-project az devops user show --org https://dev.azure.com/devops-learning第一行是登錄 Azure 賬戶第二行設(shè)置默認(rèn)組織和項目讓后續(xù)命令不用每次都帶--org參數(shù)。第三行如果返回了用戶信息說明命令行工具已經(jīng)能訪問你的 DevOps 組織了這一步可以作為環(huán)境是否配通的快速自檢。2.3 代碼倉庫準(zhǔn)備GitHub 還是 Azure ReposAzure Pipelines 支持的代碼源不少GitHub、Azure Repos Git、Bitbucket Cloud、TFVC、Subversion。絕大多數(shù)新項目用的是 GitHub 或 Azure Repos。選 GitHub 的話pipeline 可以從 GitHub 倉庫拉代碼但需要在 Azure DevOps 里創(chuàng)建一個 GitHub 服務(wù)連接。選 Azure Repos 省掉服務(wù)連接這一步因為同在一個組織里天然打通。從實際操作體驗來說我建議第一個 pipeline 用 Azure Repos 練手。原因有兩點一是少配一層 GitHub 授權(quán)二是 Azure Repos 的 PR 分支策略和 pipeline 觸發(fā)器的聯(lián)動更直接。GitHub 集成可以等把 YAML 語法跑熟之后再加那時候就算遇到授權(quán)問題也知道是哪里斷了。倉庫里至少要先放一個代碼文件。不需要多復(fù)雜一個 README 或者一個簡單的main.py都行。因為后面創(chuàng)建 pipeline 時要能拉到一次代碼空倉庫會導(dǎo)致管道創(chuàng)建失敗。3. 創(chuàng)建第一個管道從 YAML 到第一次綠勾3.1 兩種管道形態(tài)YAML 與經(jīng)典編輯器Azure Pipelines 提供兩種定義方式Y(jié)AML 管道和經(jīng)典管道。YAML 管道的核心是一個azure-pipelines.yml文件放在代碼倉庫根目錄。管道定義跟著代碼走改了文件就是改了管道配置PR 里能看到管道變更的 diff這個特性在排查問題時非常有用。當(dāng)前官方推薦的方式所有新功能基本都優(yōu)先支持 YAML。經(jīng)典管道是在網(wǎng)頁界面上用拖拽表單的方式配置構(gòu)建和發(fā)布配置存在 Azure DevOps 服務(wù)端不跟代碼走。它也有存在價值發(fā)布管道Release Pipeline里的 Gates 功能部署前自動收集外部運行狀況信號只在經(jīng)典發(fā)布管道里可用YAML 里沒有。另外任務(wù)組Task Group這個封裝復(fù)用能力也是經(jīng)典編輯器專屬YAML 里對應(yīng)的是模板Template。如果是新項目直接學(xué) YAML。但要知道經(jīng)典編輯器還活著老項目里大量存在遇到歷史管道維護(hù)時至少得能讀懂。3.2 最小可用的 azure-pipelines.yml逐字段拆解從空倉庫開始第一個目標(biāo)不是復(fù)雜部署而是讓管道跑出一個綠勾。以下是我實際用過的最小 YAMLtrigger: - main pool: vmImage: ubuntu-latest steps: - script: echo Hello, Azure Pipelines! displayName: Print greeting - script: | python -c print(Python is ready) displayName: Check Python第一段trigger定義什么時候觸發(fā)管道m(xù)ain表示推送到 main 分支就跑。第二段pool指定代理池這里用的是微軟托管的 Ubuntu 鏡像不需要自己維護(hù)機器。第三段steps是任務(wù)列表每個script就是一條命令displayName是這個步驟在運行日志里顯示的名字。把默認(rèn)分支改成main然后推到遠(yuǎn)端。推完之后去 Azure DevOps 頁面的 Pipelines 菜單里應(yīng)該能看到這次運行已經(jīng)自動啟動。點擊進(jìn)入運行詳情看到兩個步驟都變成綠色的對勾第一個管道就算跑通了。這里有個細(xì)節(jié)要注意YAML 的縮進(jìn)語法比較嚴(yán)格steps下的每一項都要保持相同的縮進(jìn)層級。我在實際使用中因為displayName縮進(jìn)多了一格導(dǎo)致解析失敗報錯信息非常抽象根本看不出來是縮進(jìn)問題。如果遇到 YAML 解析錯誤優(yōu)先檢查縮進(jìn)和冒號后面有沒有空格。3.3 從模板克隆與自定義頁面上的「創(chuàng)建管道」向?qū)鋵嵅皇菑牧銓?YAML而是基于倉庫類型和語言生成一個模板再讓你在編輯器里改。選擇 GitHub 或 Azure Repos 倉庫后向?qū)呙璐a推薦對應(yīng)模板。Node.js 項目會生成安裝 npm 依賴、跑測試、發(fā)布工件的模板。Python 項目會生成pip install和pytest的模板。從模板起步的好處是官方模板已經(jīng)幫你處理了緩存、依賴安裝、條件執(zhí)行這些細(xì)節(jié)。比如 Node.js 模板里會有- task: NodeTool0 inputs: versionSpec: 20.x displayName: Install Node.js這個NodeTool0任務(wù)專門負(fù)責(zé)在托管代理上安裝指定版本的 Node.js。versionSpec就是版本號可以寫成20.x這樣的通配符。自己寫的話得手動調(diào)apt-get或nvm用任務(wù)更可靠。模板能覆蓋常見語言但一些特殊場景要自己加任務(wù)比如 Android 構(gòu)建要裝 JDK 和 Android SDKiOS 構(gòu)建必須用 macOS 代理。模板只是開始真正生產(chǎn)級的管道基本都要手改。3.4 推送觸發(fā)把第一個管道跑起來創(chuàng)建完 YAML 管道后管道會等代碼推送觸發(fā)。驗證觸發(fā)邏輯是否正常只需要改任意一個文件提交然后在 Pipelines 頁面看運行列表里有沒有新增一條記錄。如果要同時驗證 GitHub 和 Azure Repos 兩種倉庫源GitHub 那邊需要在項目設(shè)置里創(chuàng)建 GitHub 服務(wù)連接。創(chuàng)建過程會引導(dǎo)跳轉(zhuǎn)到 GitHub 授權(quán)頁面授權(quán)時需要選擇倉庫訪問范圍選「僅限選定倉庫」更安全避免把整個 GitHub 賬號暴露給 Azure DevOps。注意服務(wù)連接的名稱會在 YAML 里被引用。我習(xí)慣命名為github-read-only這種帶用途的名字比默認(rèn)的GitHub connection 1直觀得多。我一般會故意把一個錯誤加進(jìn) YAML比如讓腳本退出碼非零確認(rèn)管道確實會失敗并展示紅色狀態(tài)然后再修回來。這一步能同時驗證日志系統(tǒng)、失敗通知和修復(fù)流程是花五分鐘換來后面省半小時的做法。4. 把管道做厚階段、作業(yè)、任務(wù)、模板與自托管代理4.1 階段與作業(yè)從單步構(gòu)建到多環(huán)境部署單個管道要支持多環(huán)境部署靠的是階段stage和作業(yè)job兩層編排。階段是管道里最大的邏輯分組通常對應(yīng)環(huán)境build、test、deploy-dev、deploy-prod。默認(rèn)情況下階段按順序執(zhí)行但可以用dependsOn控制依賴關(guān)系。作業(yè)是階段內(nèi)的執(zhí)行單元一個階段可以跑多個作業(yè)這些作業(yè)可以并行。stages: - stage: build displayName: Build Stage jobs: - job: compile pool: vmImage: ubuntu-latest steps: - script: echo Compiling... displayName: Compile code - stage: deploy_dev displayName: Deploy to Dev dependsOn: build condition: succeeded() jobs: - job: deploy pool: vmImage: ubuntu-latest steps: - script: echo Deploying to dev... displayName: Deploy devdependsOn: build表示這個階段必須等 build 階段跑完condition: succeeded()表示只有前面階段全部成功后才會執(zhí)行。這兩個組合是最常見的部署閘門寫法。condition是一個很關(guān)鍵的表達(dá)式字段。常見的取值有succeeded()、failed()、always()還有基于變量的判斷如eq(variables[build.reason], PullRequest)后者可以區(qū)分推送觸發(fā)的運行和 PR 觸發(fā)的運行。多作業(yè)并行是托管代理最實用的能力。默認(rèn)情況下 Azure DevOps 會給每個作業(yè)分配一個代理實例免費額度是按分鐘計的并行作業(yè)越多消耗越快。自托管代理不會消耗 Microsoft 托管額度這也是很多團(tuán)隊搭自托管代理的原因。4.2 任務(wù)與腳本跑命令、裝依賴、發(fā)工件任務(wù)是管道的最小執(zhí)行單元。Azure Pipelines 內(nèi)置了幾百個任務(wù)常見的有NodeTool0裝 Node、UsePythonVersion0選 Python 版本、DotNetCoreCLI2處理 .NET 命令、CopyFiles2復(fù)制文件和PublishBuildArtifacts1發(fā)布工件。通用任務(wù)無法覆蓋的場景用script直接跑命令行、PowerShell 或 Shell。比如拉依賴和跑測試steps: - checkout: self - script: | python -m venv .venv source .venv/bin/activate pip install -r requirements.txt displayName: Install Python dependencies - script: | source .venv/bin/activate pytest tests/ --junitxmltest-results.xml displayName: Run tests with pytest - task: PublishTestResults2 inputs: testResultsFormat: JUnit testResultsFiles: test-results.xml displayName: Publish test results多行命令用|拼接每行一條命令。checkout: self顯式拉取當(dāng)前倉庫代碼默認(rèn)行為也會拉但寫出來更明確。PublishTestResults2把測試結(jié)果文件發(fā)布到管道運行記錄里這樣頁面上能看到測試通過率、失敗用例列表比只看命令行輸出直觀得多。發(fā)布工件是 CI 和 CD 的銜接點CI 階段產(chǎn)出的文件通過PublishBuildArtifacts1保存CD 階段再用下載任務(wù)取回來。工件有保留期設(shè)置默認(rèn) 30 天生產(chǎn)環(huán)境上會設(shè)為 90 天或更長方便回溯歷史版本。4.3 變量、變量組與運行時參數(shù)寫死配置是管道維護(hù)的災(zāi)難源頭。Azure Pipelines 的三層變量機制能避免這個問題。第一層是管道內(nèi)變量直接在 YAML 里定義variables: buildConfiguration: Release imageName: myapp:${{ parameters.tag }}第二層是變量組Variable Group存在 Azure DevOps 庫Library里可以跨管道共享。適合存不常變的配置比如服務(wù)器地址、告警 Webhook URL。同一個變量組可以被多個管道引用改一處就全部生效。第三層是密鑰變量存在變量組里并標(biāo)記為密鑰運行時在日志里自動打碼。數(shù)據(jù)庫密碼、API Key 這類敏感信息必須用這種方式不能明文寫在 YAML 里。引用變量組的寫法variables: - group: production-config - task: AzureCLI2 inputs: azureSubscription: prod-service-connection scriptType: bash scriptLocation: inlineScript inlineScript: | echo Deploying to $(serverUrl)$(serverUrl)會在運行時從production-config變量組里取值。注意 YAML 里變量引用的兩種語法$(varName)是運行時替換模板里的${{ varName }}是模板展開時替換。前者在任務(wù)執(zhí)行時解析后者在管道編譯階段就定下來了用錯場景會導(dǎo)致取值不對。運行時參數(shù)Runtime Parameters是更靈活的輸入方式parameters: - name: environment displayName: Deployment Target type: string default: dev values: - dev - staging - prod stages: - stage: deploy_${{ parameters.environment }} displayName: Deploy to ${{ parameters.environment }} jobs: - job: deploy_job steps: - script: echo Deploying to ${{ parameters.environment }}運行時參數(shù)可以在手動運行管道時從頁面上選擇也可以被 API 調(diào)用時傳入。values限制了可選范圍避免手滑部署到錯誤環(huán)境。我一般會給所有多環(huán)境部署管道都加這個參數(shù)省得每次改 YAML。4.4 模板與觸發(fā)器告別復(fù)制粘貼兩個以上的管道出現(xiàn)相同的任務(wù)序列時就應(yīng)該抽成模板。模板文件通常放倉庫的pipelines/templates目錄下后綴還是.yml。基礎(chǔ)模板示例# pipelines/templates/build-node.yml parameters: - name: nodeVersion default: 20.x steps: - task: NodeTool0 inputs: versionSpec: ${{ parameters.nodeVersion }} displayName: Install Node ${{ parameters.nodeVersion }} - script: | npm ci npm run test displayName: Install and test引用模板的管道trigger: - main pool: vmImage: ubuntu-latest extends: template: pipelines/templates/build-node.yml parameters: nodeVersion: 22.xextends是模板繼承管道本身不再寫steps全部由模板決定。另一種是steps里局部引用模板steps: - template: templates/build-node.yml parameters: nodeVersion: 20.x兩種方式的選擇標(biāo)準(zhǔn)管道結(jié)構(gòu)和模板完全一致用extends只有部分步驟復(fù)用用- template。模板可以嵌套但要控制層級三層以上排查問題就很痛苦了。觸發(fā)器除了分支觸發(fā)還有計劃觸發(fā)和路徑觸發(fā)trigger: branches: include: - main - release/* paths: exclude: - docs/* schedules: - cron: 0 2 * * * displayName: Daily 2 AM build branches: include: - mainbranches.include是包含模式release/*會匹配所有 release 開頭的分支。paths.exclude排除docs/*目錄文檔變更不觸發(fā)構(gòu)建。schedules是定時觸發(fā)注意計劃觸發(fā)的時區(qū)默認(rèn)是 UTC國內(nèi)團(tuán)隊用的話要減 8 小時換算。PR 觸發(fā)器在 GitHub 場景里很重要pr: - main這個配置讓 PR 創(chuàng)建和更新時自動跑管道驗證防止壞代碼合并進(jìn)主干。4.5 自托管代理從下載、配置到加入代理池微軟托管代理省心但有兩個硬傷自定義軟件裝不了免費分鐘數(shù)有限。跑大型編譯任務(wù)或者需要內(nèi)網(wǎng)資源時自托管代理幾乎是必須的。自托管代理的安裝流程在不同操作系統(tǒng)上一致以 Linux 為例mkdir myagent cd myagent curl -o agent.tar.gz -L https://vstsagentpackage.azureedge.net/agent/3.x/vsts-agent-linux-x64-3.x.tar.gz tar zxvf agent.tar.gz ./config.sh --url https://dev.azure.com/devops-learning --agentpool default --token XXXXX --unattended --acceptteeeula ./run.sh第一步創(chuàng)建目錄并下載代理包。第二步解壓。第三步是配置代理--url指向組織地址--agentpool指定代理池名稱--token用的是個人訪問令牌PAT需要在 Azure DevOps 用戶設(shè)置里生成至少要有 Agent Pools 的讀和管理權(quán)限。--unattended表示非交互模式--acceptteeeula接受許可協(xié)議。最后./run.sh啟動代理。代理啟動后回到 Azure DevOps 頁面在 Project Settings - Agent Pools - Default 里應(yīng)該能看到這臺代理顯示為在線狀態(tài)。此時 YAML 里把pool改成pool: name: default不再寫vmImage管道就會跑到這臺自托管代理上。提示自托管代理的run.sh在終端退出后就停了。生產(chǎn)環(huán)境要用systemd或者注冊成 Windows 服務(wù)讓代理常駐后臺。我一般用 systemd service 管理同時加上Restartalways代理進(jìn)程掛了能自動拉起來。公司網(wǎng)絡(luò)有代理的需要在.env文件里加VSTS_HTTP_PROXY環(huán)境變量指向代理地址否則代理連不上 Azure DevOps。自托管代理的代價是你要為環(huán)境負(fù)責(zé)。托管代理上自帶幾百個預(yù)裝軟件自托管代理默認(rèn)只有基礎(chǔ)環(huán)境缺什么裝什么。我一般會在配置腳本里寫好apt-get install的依賴清單新代理從空白系統(tǒng)開始跑一遍腳本就能達(dá)到可用狀態(tài)。5. 避坑與排查五條最常見的翻車記錄5.1 YAML 解析失敗報錯卻看不出來原因現(xiàn)象管道啟動后立刻失敗錯誤信息是YAML schematic validation failed或者Expecting a mapping不告訴具體哪一行有問題。原因絕大多數(shù)情況是縮進(jìn)錯誤。YAML 對縮進(jìn)極其敏感steps下的每一項必須保持層級一致script: |多行內(nèi)容里的命令如果比父級多縮進(jìn)或少縮進(jìn)解析器會直接報錯。另一種常見原因是冒號后面忘了加空格。解決先把 YAML 丟到本地編輯器里開 YAML 語法檢查配合 Azure DevOps 頁面上的編輯校驗提醒一邊改一邊看。我的習(xí)慣是本地用 VS Code 寫實時標(biāo)錯比到網(wǎng)頁上試錯快得多。另外 YAML 里不要用 Tab 鍵縮進(jìn)統(tǒng)一兩個空格這基本是行業(yè)共識了。5.2 私有項目每月 1800 分鐘額度不夠用現(xiàn)象月中管道就開始排隊運行記錄里顯示No hosted parallelism has been purchased or granted。原因私有項目默認(rèn)每月只送 1800 分鐘30 小時多個并行作業(yè)或者長構(gòu)建任務(wù)很快就會把額度吃完。公共項目可以免費無限時跑管道但如果代碼是私有的這個方案不可行。解決短期做法是把不必要的 PR 觸發(fā)器關(guān)掉減少自動運行次數(shù)。長期做法是搭自托管代理因為自托管代理不占托管額度。我遇到一個跑 Android 構(gòu)建的團(tuán)隊每次構(gòu)建要 25 分鐘一個月 60 多次構(gòu)建托管額度完全不夠換了自托管代理后成本直降為零。5.3 自托管代理連不上一直顯示離線現(xiàn)象Agent Pools 里代理狀態(tài)是 offlinerun.sh啟動時卡在Connecting to server。原因最常見的是公司網(wǎng)絡(luò)出口有防火墻限制代理需要訪問https://dev.azure.com以外的多個域名比如*.vlabs.servicebus.windows.net、*.visualstudio.com這些域名被攔了代理就永遠(yuǎn)處于連接中狀態(tài)。另一個原因是代理版本太老和 Azure DevOps Server 版本不兼容。解決先確認(rèn)網(wǎng)絡(luò)策略可以在代理機上執(zhí)行curl -I https://dev.azure.com驗證能不能通。代理程序的日志在_diag目錄下排查時先看這個文件。網(wǎng)絡(luò)沒問題的話升級代理到最新版再重新config一次。5.4 Azure 資源管理器服務(wù)連接失敗現(xiàn)象AzureCLI2或AzureResourceManagerTemplateDeployment3任務(wù)報錯提示Failed to get Azure Resource Manager service connection或者直接 401。原因服務(wù)連接Service Connection的認(rèn)證憑證過期了或者創(chuàng)建服務(wù)連接時只剩選了資源組級別的權(quán)限。常見的是把服務(wù)連接創(chuàng)建成了「服務(wù)主體認(rèn)證」模式但服務(wù)主體密鑰過期沒有及時輪轉(zhuǎn)。解決檢查項目設(shè)置里的 Service Connections選中對應(yīng)的連接點「Edit」走一遍重新授權(quán)流程。如果是 Azure AD 服務(wù)主體模式去 Azure AD 重新生成客戶端密鑰再回 DevOps 更新連接信息。排查時先確認(rèn)連接權(quán)限范圍給資源組權(quán)限的就別去嘗試列訂閱級別的資源否則會看到權(quán)限不足的假報錯。5.5 經(jīng)典發(fā)布管道和 YAML 管道功能不對稱現(xiàn)象照著文檔寫 YAML 部署發(fā)現(xiàn)在 YAML 里沒有 Gates 功能。看老項目里有任務(wù)組的封裝自己在 YAML 里找不到對應(yīng)概念。原因Azure Pipelines 的兩套體系功能并集才是完整能力YAML 管道的某些能力比如環(huán)境部署作業(yè)是經(jīng)典發(fā)布管道沒有的反之經(jīng)典的 Gates 和任務(wù)組也是 YAML 沒有的。解決新管道優(yōu)先 YAML但碰到老項目或者特定需求比如必須用發(fā)布 Gates就別硬在 YAML 里折騰組件。正確做法是 YAML 管道負(fù)責(zé)構(gòu)建和測試經(jīng)典發(fā)布管道負(fù)責(zé)需要 Gates 的部署環(huán)節(jié)兩者通過工件銜接。架構(gòu)上多一層但每個環(huán)節(jié)用最合適的方式比強行統(tǒng)一省心。6. 裝完怎么驗證一條流水線從提交到上線的完整檢查管道配置完最后的驗證不只是看頁面上的綠色對勾。我從實踐中沉淀了一套檢查清單照著走一遍能確認(rèn)整條鏈路是真的通了而不是表面綠了。第一項檢查提交觸發(fā)。改動代碼推到 main 分支去 Pipelines 頁面的運行列表里看有沒有新增記錄。如果沒觸發(fā)先看 trigger 配置里的分支名對不對再看倉庫的默認(rèn)分支是不是 main。很多從 GitHub 導(dǎo)入的倉庫默認(rèn)分支是 masterYAML 里寫的 main 自然不會觸發(fā)。第二項檢查代理狀態(tài)。跑到自托管代理上的管道在運行詳情里看 Agent 名稱是不是你的那臺機器。如果顯示的是 Microsoft-hosted agent說明 YAML 里pool還是默認(rèn)的azure-pipelines沒切到自托管池。第三項檢查測試報告。管道步驟里加了PublishTestResults2的去運行頁面的 Tests 標(biāo)簽看統(tǒng)計總共多少用例、多少失敗、失敗的具體函數(shù)名。這里能看出測試數(shù)據(jù)有沒有成功采集比終端日志里的輸出更結(jié)構(gòu)化。第四項檢查工件。進(jìn)入運行詳情找 Artifacts 區(qū)域確認(rèn)構(gòu)建產(chǎn)物發(fā)布了多少 MB、文件列表對不對。再點下載解壓后抽查一個文件內(nèi)容是不是最新代碼編譯出來的。這個驗證能提前發(fā)現(xiàn)工件沒更新這種坑人的問題。第五項檢查部署結(jié)果。如果是多環(huán)境管道走到最后確認(rèn)deploy_prod階段的日志里有明確的成功輸出。我會在部署腳本最后加一條驗證請求比如curl -I打到部署后的服務(wù)地址確認(rèn) HTTP 狀態(tài)碼是 200 才返回成功否則讓管道報失敗。最后的技巧是在管道末尾加一個自檢任務(wù)把構(gòu)建時間、提交 SHA、部署目標(biāo)環(huán)境打出來然后跑一次完整的 PR 驗證。我的習(xí)慣是改完azure-pipelines.yml先在本地把 YAML 縮進(jìn)校驗一遍再往一個 topic 分支推一次觸發(fā)完整流程確認(rèn)每個階段都過了一遍才敢把變更移到 main 上。這套儀式感看似笨但已經(jīng)幫我擋過多次回歸事故了——最危險的不是管道失敗而是管道綠了但產(chǎn)品是壞的。希望這些經(jīng)驗?zāi)軒偷侥闵僮邘状螐澛?。本文還有配套的精品資源點擊獲取