分享方式:


新增自定義管線任務擴充功能

Azure DevOps Services |Azure DevOps Server 2022 - Azure DevOps Server 2019

本文說明如何在 Azure DevOps 中為自定義組建或發行工作安裝延伸模組至您的組織。 如需詳細資訊,請參閱 什麼是 Azure Pipelines?

注意

本文涵蓋代理程式型擴充功能中的代理工作。 如需伺服器工作和伺服器型延伸模組的詳細資訊,請參閱 伺服器工作撰寫

必要條件

  • Azure DevOps 中的組織。 建立組織

  • 文字編輯器。 針對許多教學課程,我們使用 Visual StudioCode,其提供Intellisense和偵錯支援。

  • 最新版 Node.js

  • npmjs.com 4.0.2 或更新。 安裝這個 TypeScript 編譯程式的 最新版本

  • 適用於 Azure DevOps 的跨平臺 CLI (tfx-cli) 可封裝您的延伸模組。

    • 您可以使用 npm 來安裝 tfx-cli,這是 Node.js的元件,只需執行 npm i -g tfx-cli
  • Azure DevOps 擴充功能 SDK。 安裝 azure-devops-extension-sdk 套件。

  • 你的專案目錄homehome完成本文中的步驟之後,組建或發行工作延伸模組的目錄應該具有下列結構:

    |--- README.md    
    |--- images                        
        |--- extension-icon.png  
    |--- buildandreleasetask            // where your task scripts are placed
    |--- vss-extension.json             // extension's manifest
    

重要

開發計算機必須執行 最新版的 Node ,以確保撰寫的程式代碼與代理程式上的生產環境相容,以及的最新非預覽版本 azure-pipelines-task-lib。 根據下列命令更新您的 task.json 檔案:

"execution": {
   "Node20_1": {
     "target": "index.js"
   }
 }

1.建立自定義工作

buildandreleasetask目錄中的home資料夾內執行這個程序的每個部分。

注意

本範例逐步解說使用 Windows 搭配 PowerShell。 這些步驟適用於所有平臺,但取得環境變數的語法不同。 如果您使用 Mac 或 Linux,請將 的任何實體 $env:<var>=<val> 取代為 export <var>=<val>

建立任務架構

  1. 建立工作的資料夾結構,並安裝必要的連結庫和相依性。

  2. 開啟 PowerShell 命令視窗,移至您的 buildandreleasetask 資料夾,然後執行下列命令。

    npm init --yes
    

    npm init 建立package.json 檔案。 我們已新增 --yes 參數以接受所有預設 npm init 選項。

    提示

    代理程式不會自動安裝必要的模組,因為它預期您的工作資料夾包含節點模組。 若要緩和,請將 node_modules 複製到 buildandreleasetask。 當您的工作變大時,很容易超過 VSIX 檔案的大小限制 (50 MB)。 複製節點資料夾之前,您可能想要執行 npm install --productionnpm prune --production,也可以撰寫腳本來建置和封裝所有專案。

  3. 新增 azure-pipelines-task-lib 至您的連結庫。

    npm install azure-pipelines-task-lib --save
    
  4. 請確保已安裝外部依賴項的 TypeScript 類型。

    npm install @types/node --save-dev
    npm install @types/q --save-dev
    
  5. 建立檔案 .gitignore ,並將node_modules新增至檔案。 您的建置程式應該執行 npm installtypings install ,以便每次建置node_modules,且不需要簽入。

    echo node_modules > .gitignore
    
  6. Mocha 安裝為開發相依性。

    npm install mocha --save-dev -g
    npm install sync-request --save-dev
    npm install @types/mocha --save-dev
    
  7. 選擇 TypeScript 2.3.4 版或 4.6.3 版。

    npm install typescript@4.6.3 -g --save-dev
    

    注意

    請確定在開發環境中全域安裝 npm TypeScript,讓 tsc 命令可供使用。 如果您略過此步驟,預設會使用 TypeScript 2.3.4 版,而且您仍然需要全域安裝套件,才能使用 tsc 命令。

  8. 建立 tsconfig.json 編譯程序選項。 此檔案可確保您的 TypeScript 檔案會編譯成 JavaScript 檔案。

    tsc --init --target es2022
    

建立任務

現在鷹架已完成,您可以建立自訂工作。

  1. task.json 資料夾中建立buildandreleasetask檔案。 此 task.json 檔案描述建置/發行工作,並且建置/發行系統用來顯示配置選項給使用者,並以確定在建置/發行時執行哪些腳本。

  2. 複製下列程式碼,並以您的任務資訊替換{{placeholders}}。 最重要的佔位元是 taskguid,而且必須是唯一的。

    {
     "$schema": "https://raw.githubusercontent.com/Microsoft/azure-pipelines-task-lib/master/tasks.schema.json",
     "id": "{{taskguid}}",
     "name": "{{taskname}}",
     "friendlyName": "{{taskfriendlyname}}",
     "description": "{{taskdescription}}",
     "helpMarkDown": "",
     "category": "Utility",
     "author": "{{taskauthor}}",
     "version": {
         "Major": 0,
         "Minor": 1,
         "Patch": 0
     },
     "instanceNameFormat": "Echo $(samplestring)",
     "inputs": [
         {
             "name": "samplestring",
             "type": "string",
             "label": "Sample String",
             "defaultValue": "",
             "required": true,
             "helpMarkDown": "A sample string"
         }
     ],
     "execution": {
         "Node20_1": {
             "target": "index.js"
         }
     }
     }
    
  3. 使用下列程式碼作為參考來建立index.ts檔案。 此程式代碼會在呼叫工作時執行。

    import tl = require('azure-pipelines-task-lib/task');
    
     async function run() {
         try {
             const inputString: string | undefined = tl.getInput('samplestring', true);
             if (inputString == 'bad') {
                 tl.setResult(tl.TaskResult.Failed, 'Bad input was given');
                 return;
             }
             console.log('Hello', inputString);
         }
         catch (err:any) {
             tl.setResult(tl.TaskResult.Failed, err.message);
         }
     }
    
     run();
    
  4. 若要從 index.js編譯 index.ts 檔案,請從 tsc 資料夾輸入 buildandreleasetask

task.json 元件

請參閱下列檔案部分元件 task.json 的描述。

財產 說明
id 您任務的唯一全域唯一識別碼 (GUID)。
name 沒有空格的名稱。
friendlyName 描述性名稱(允許空格)。
description 任務執行內容的詳細說明。
author 描述開發組建或發行工作的實體的簡短字串,例如: Microsoft Corporation
instanceNameFormat 任務在編譯/發行步驟清單中的顯示樣式。 您可以使用 $(variablename)來使用變數值。
groups 描述UI中工作屬性的邏輯群組。
inputs 建置或發行工作執行時要使用的輸入。 此工作預期具有名稱 samplestring 的輸入。
execution 此工作有多個執行選項,包括文稿,例如 NodePowerShellPowerShell3Process
restrictions 限制是套用到任務本身,涉及任務可以調用的 GitHub Codespaces 命令 和可以設定的變數。 建議您為新工作指定限制模式。

注意

使用下列指令在 PowerShell 中建立id

(New-Guid).Guid

如需詳細資訊,請參閱 建置/發行工作參考

執行這項工作

在 PowerShell 中使用 node index.js 執行工作。

在下列範例中,工作會失敗,因為未提供輸入 (samplestring 是必要的輸入)。

 node index.js
 ##vso[task.debug]agent.workFolder=undefined
 ##vso[task.debug]loading inputs and endpoints
 ##vso[task.debug]loaded 0
 ##vso[task.debug]task result: Failed
 ##vso[task.issue type=error;]Input required: samplestring
 ##vso[task.complete result=Failed;]Input required: samplestring

要解決問題,請設定samplestring輸入,然後再次執行任務。

$env:INPUT_SAMPLESTRING="Human"
node index.js
##vso[task.debug]agent.workFolder=undefined
##vso[task.debug]loading inputs and endpoints
##vso[task.debug]loading INPUT_SAMPLESTRING
##vso[task.debug]loaded 1
##vso[task.debug]Agent.ProxyUrl=undefined
##vso[task.debug]Agent.CAInfo=undefined
##vso[task.debug]Agent.ClientCert=undefined
##vso[task.debug]Agent.SkipCertValidation=undefined
##vso[task.debug]samplestring=Human
Hello Human

這次,工作會成功,因為 samplestring 已提供,而且它正確地輸出 Hello Human!

提示

如需各種工作執行器及如何在task.json中包含最新 Node.js 版本的資訊,請參閱 Azure Pipelines 任務作者的節點執行器更新指引

2.單元測試您的工作腳本

執行單元測試以快速測試工作腳本,而不是其呼叫的外部工具。 測試成功和失敗路徑的所有層面。

  1. 安裝測試工具。 我們在此程式中使用 Mocha 作為測試驅動程式。

    npm install mocha --save-dev -g
    npm install sync-request --save-dev
    npm install @types/mocha --save-dev
    
  2. 建立 tests 包含 _suite.ts 下列內容之檔案的資料夾:

    import * as path from 'path';
    import * as assert from 'assert';
    import * as ttm from 'azure-pipelines-task-lib/mock-test';
    
    describe('Sample task tests', function () {
    
        before( function() {
    
        });
    
        after(() => {
    
        });
    
        it('should succeed with simple inputs', function(done: Mocha.Done) {
            // Add success test here
        });
    
        it('it should fail if tool returns 1', function(done: Mocha.Done) {
            // Add failure test here
        });    
    });
    

    提示

    您的測試資料夾應該位於 buildandreleasetask 資料夾中。 如果您收到同步要求錯誤,您可以使用 命令buildandreleasetask將 sync-request 新增至npm i --save-dev sync-request資料夾,以解決此問題。

  3. 使用下列內容在測試目錄中建立 success.ts 檔案。 此檔案的建立會模擬執行任務,並模擬所有對外部方法的呼叫。

    import ma = require('azure-pipelines-task-lib/mock-answer');
    import tmrm = require('azure-pipelines-task-lib/mock-run');
    import path = require('path');
    
    let taskPath = path.join(__dirname, '..', 'index.js');
    let tmr: tmrm.TaskMockRunner = new tmrm.TaskMockRunner(taskPath);
    
    tmr.setInput('samplestring', 'human');
    
    tmr.run();
    

    成功測試會驗證使用適當的輸入,它成功且沒有任何錯誤或警告,並傳回正確的輸出。

  4. 若要執行工作模擬執行器,請將下列範例成功測試新增至您的 _suite.ts 檔案。

         it('should succeed with simple inputs', function(done: Mocha.Done) {
         this.timeout(1000);
    
         let tp: string = path.join(__dirname, 'success.js');
         let tr: ttm.MockTestRunner = new ttm.MockTestRunner(tp);
    
         // tr.run(); //current, old function.
         tr.runAsync().then(() => {
             console.log(tr.succeeded);
             assert.equal(tr.succeeded, true, 'should have succeeded');
             assert.equal(tr.warningIssues.length, 0, "should have no warnings");
             assert.equal(tr.errorIssues.length, 0, "should have no errors");
             console.log(tr.stdout);
             assert.equal(tr.stdout.indexOf('Hello human') >= 0, true, "should display Hello human");
             done();
         }).catch((error) => {
             done(error); // Ensure the test case fails if there's an error
         });
     });
    
  5. 使用下列內容,在測試目錄中建立 failure.ts 檔案作為工作模擬執行器:

    import ma = require('azure-pipelines-task-lib/mock-answer');
    import tmrm = require('azure-pipelines-task-lib/mock-run');
    import path = require('path');
    
    let taskPath = path.join(__dirname, '..', 'index.js');
    let tmr: tmrm.TaskMockRunner = new tmrm.TaskMockRunner(taskPath);
    
    tmr.setInput('samplestring', 'bad');
    
    tmr.run();
    

    失敗測試會驗證當工具輸入不正確或不完整時,它會以預期的方式失敗,併產生有用的輸出。

  6. 若要執行工作模擬執行器,請將下列程式代碼新增至您的 _suite.ts 檔案。

    it('should fail if tool returns 1', function(done: Mocha.Done) {
        this.timeout(1000);
    
        const tp = path.join(__dirname, 'failure.js');
        const tr: ttm.MockTestRunner = new ttm.MockTestRunner(tp);
    
        tr.runAsync().then(() => {
            console.log(tr.succeeded);
            assert.equal(tr.succeeded, false, 'should have failed');
            assert.equal(tr.warningIssues.length, 0, 'should have no warnings');
            assert.equal(tr.errorIssues.length, 1, 'should have 1 error issue');
            assert.equal(tr.errorIssues[0], 'Bad input was given', 'error issue output');
            assert.equal(tr.stdout.indexOf('Hello bad'), -1, 'Should not display Hello bad');
            done();
        });
    });
    
  7. 執行測試。

    tsc
    mocha tests/_suite.js
    

    這兩個測試都應該通過。 如果您想要以更詳細的輸出執行測試(您在組建控制台中看到的內容),請設定環境變數: TASK_TEST_TRACE=1

    $env:TASK_TEST_TRACE=1
    

3.建立延伸模組指令清單檔案

擴充套件清單包含擴充功能的所有資訊。 其中包含檔案的連結,包括您的工作資料夾和影像資料夾。 請確定您已使用 extension-icon.png建立 images 資料夾。 下列範例是包含組建或發行工作的擴充指令清單。

複製下列.json程序代碼,並將它儲存為目錄中的vss-extension.jsonhome檔案。

請勿在 buildandreleasetask 資料夾中建立此檔案。

{
    "manifestVersion": 1,
    "id": "build-release-task",
    "name": "Fabrikam Build and Release Tools",
    "version": "0.0.1",
    "publisher": "fabrikam",
    "targets": [
        {
            "id": "Microsoft.VisualStudio.Services"
        }
    ],    
    "description": "Tools for building/releasing with Fabrikam. Includes one build/release task.",
    "categories": [
        "Azure Pipelines"
    ],
    "icons": {
        "default": "images/extension-icon.png"        
    },
    "files": [
        {
            "path": "buildandreleasetask"
        }
    ],
    "contributions": [
        {
            "id": "custom-build-release-task",
            "type": "ms.vss-distributed-task.task",
            "targets": [
                "ms.vss-distributed-task.tasks"
            ],
            "properties": {
                "name": "buildandreleasetask"
            }
        }
    ]
}

注意

發行者 變更為你的發行者名稱。 如需詳細資訊,請參閱 建立發行者

貢獻

財產 說明
id 貢獻的識別碼。 在延伸模組內必須是唯一的。 不需要比對組建或發行工作的名稱。 構建或發行任務名稱通常包含在參與項的 ID 中。
type 參與的類型。 應該是 ms.vss-distributed-task.task
targets 被此貢獻針對的貢獻。 應該是 ms.vss-distributed-task.tasks
properties.name 工作的名稱。 此名稱必須符合對應獨立組建或發行管線工作的資料夾名稱。

檔案

財產 說明
path 相對於 home 目錄的檔案或資料夾路徑。

如需延伸模組指令清單檔案的詳細資訊,例如其屬性及其用途,請參閱 延伸模組指令清單參考

4.封裝您的擴充套件

將所有檔案封裝在一起,以將延伸模組放入Visual Studio Marketplace。 所有擴充功能都會封裝為 VSIX 2.0 相容的 .vsix 檔案。 Microsoft提供跨平臺命令行介面 (CLI) 來封裝您的延伸模組。

擁有 tfx-cli 之後,請移至延伸模組的主目錄,然後執行下列命令:

tfx extension create --manifest-globs vss-extension.json

注意

擴充功能或整合的版本必須在每次更新時遞增。 當您更新現有的擴充功能時,請更新指令清單中的版本,或傳遞 --rev-version 命令行參數。 這會遞增您擴充功能的修補版本號碼,並將新版本儲存至清單中。 您必須同時更新工作版本和延伸模組版本,才能進行更新。 tfx extension create --manifest-globs vss-extension.json --rev-version 只會更新擴充功能版本,而不是工作版本。 如需詳細資訊,請參閱 GitHub 中的建置工作

一旦封裝的擴展名位於 .vsix 檔案中,您就可以將擴充功能發佈至 Marketplace。

5.發佈您的延伸模組

若要發佈延伸模組,請先 建立您的發行者,然後 上傳您的延伸模組,最後 共用它

建立您的發行者

所有擴充功能,包括來自 Microsoft 的擴充功能,都會被識別為由發行者提供。 如果您還不是現有發行者的成員,請建立一個。

  1. 登入 Visual Studio Marketplace 發佈入口網站

  2. 如果您還不是現有發行者的成員,系統會提示您建立發行者。 如果未提示您建立發行者,請向下捲動至頁面底部,然後在 [相關網站] 下選取 [發佈延伸模組]。

    • 指定發行者的標識碼,例如: mycompany-myteam
      • 此標識碼會作為擴充功能清單檔中屬性publisher的值。
    • 指定發行者的顯示名稱,例如: My Team
  3. 檢閱 Marketplace 發行者合約 ,然後選取 [建立]。

您的發行者已經被設定。 在未來版本中,您可以授予許可權,以檢視和管理發行者的擴充功能。 在一般發行者下發佈延伸模組更容易且更安全,而不需要跨用戶共用一組認證。

上傳您的延伸模組

尋找 [ 上傳新的擴展名] 按鈕,移至已封裝的 .vsix 檔案,然後選取 [ 上傳]。

您也可以透過命令行介面 (CLI) 上傳延伸模組,方法是使用 tfx extension publish 命令,而不是 tfx extension create 在一個步驟中封裝和發佈延伸模組。 您可以選擇性地使用 --share-with ,在擴充功能發佈之後與一或多個帳戶共用。

tfx extension publish --manifest-globs your-manifest.json --share-with yourOrganization

分享您的擴充功能

現在您已上傳延伸模組,它位於 Marketplace 中,但沒有人可以看到它。 與組織共用它,以便安裝及測試它。

以滑鼠右鍵按下您的延伸模組,然後選取 [ 共用],然後輸入您的組織資訊。 您也可以與其他想要存取延伸模組的帳戶共用它。

重要

發行者必須經過驗證,才能公開分享擴充套件。 如需詳細資訊,請參閱 套件/發佈/安裝

在 Marketplace 中共用您的延伸模塊之後,任何想要使用它的人都必須安裝它。

6.建立組建和發行管線,將延伸模塊發佈至 Marketplace

若要在 Marketplace 上維護自定義工作,請在 Azure DevOps 上建立組建和發行管線。

發佈的必要條件

  • Azure DevOps 專案。 建立專案

  • Azure DevOps 擴充功能任務擴充套件。 在您的組織中免費安裝。

  • 管線函式庫變數群組。 建立管線連結庫變數群組,以保存管線所使用的變數。 如需詳細資訊,請參閱 新增和使用變數群組。 您可以從 [Azure DevOps 連結庫] 索引標籤或透過 CLI 建立變數群組。 在您的 管線中使用此群組內的變數。 此外,請在變數群組中宣告下列變數:

    • publisherId:Marketplace 發行者的 ID
    • extensionId:擴充功能的識別碼,如在 vss-extension.json 檔案中宣告的。
    • extensionName:擴充功能名稱,如在 vss-extension.json 檔案中所宣告
    • artifactName:為 VSIX 檔案建立的工件名稱
  • 服務連線。 建立新的 Marketplace 服務連線,並授與所有管線的訪問許可權。

  • YAML 管線。 使用下列範例建立具有YAML的新管線。 如需詳細資訊,請參閱 建立您的第一個管線YAML 架構

        trigger: 
        - main
        pool:
          vmImage: "ubuntu-latest"
        variables:
          - group: variable-group # Rename to whatever you named your variable group in the prerequisite stage of step 6
        stages:
          - stage: Run_and_publish_unit_tests
            jobs:
              - job:
                steps:
                  - task: TfxInstaller@4
                    inputs:
                      version: "v0.x"
                  - task: Npm@1
                    inputs:
                      command: 'install'
                      workingDir: '/TaskDirectory' # Update to the name of the directory of your task
                  - task: Bash@3
                    displayName: Compile Javascript
                    inputs:
                      targetType: "inline"
                      script: |
                        cd TaskDirectory # Update to the name of the directory of your task
                        tsc
                  - task: Npm@1
                    inputs:
                      command: 'custom'
                      workingDir: '/TestsDirectory' # Update to the name of the directory of your task's tests
                      customCommand: 'testScript' # See the definition in the explanation section below - it may be called test
                  - task: PublishTestResults@2
                    inputs:
                      testResultsFormat: 'JUnit'
                      testResultsFiles: '**/ResultsFile.xml'
          - stage: Package_extension_and_publish_build_artifacts
            jobs:
              - job:
                steps:
                  - task: TfxInstaller@4
                    inputs:
                      version: "0.x"
                  - task: Npm@1
                    inputs:
                      command: 'install'
                      workingDir: '/TaskDirectory' # Update to the name of the directory of your task
                  - task: Bash@3
                    displayName: Compile Javascript
                    inputs:
                      targetType: "inline"
                      script: |
                        cd TaskDirectory # Update to the name of the directory of your task
                        tsc
                  - task: QueryAzureDevOpsExtensionVersion@4
                    name: QueryVersion
                    inputs:
                      connectTo: 'VsTeam'
                      connectedServiceName: 'ServiceConnection' # Change to whatever you named the service connection
                      publisherId: '$(PublisherID)'
                      extensionId: '$(ExtensionID)'
                      versionAction: 'Patch'
                  - task: PackageAzureDevOpsExtension@4
                    inputs:
                      rootFolder: '$(System.DefaultWorkingDirectory)'
                      publisherId: '$(PublisherID)'
                      extensionId: '$(ExtensionID)'
                      extensionName: '$(ExtensionName)'
                      extensionVersion: '$(QueryVersion.Extension.Version)'
                      updateTasksVersion: true
                      updateTasksVersionType: 'patch'
                      extensionVisibility: 'private' # Change to public if you're publishing to the marketplace
                      extensionPricing: 'free'
                  - task: CopyFiles@2
                    displayName: "Copy Files to: $(Build.ArtifactStagingDirectory)"
                    inputs:
                      Contents: "**/*.vsix"
                      TargetFolder: "$(Build.ArtifactStagingDirectory)"
                  - task: PublishBuildArtifacts@1
                    inputs:
                      PathtoPublish: '$(Build.ArtifactStagingDirectory)'
                      ArtifactName: '$(ArtifactName)'
                      publishLocation: 'Container'
          - stage: Download_build_artifacts_and_publish_the_extension
            jobs:
              - job:
                steps:
                  - task: TfxInstaller@4
                    inputs:
                      version: "v0.x"
                  - task: DownloadBuildArtifacts@0
                    inputs:
                      buildType: "current"
                      downloadType: "single"
                      artifactName: "$(ArtifactName)"
                      downloadPath: "$(System.DefaultWorkingDirectory)"
                  - task: PublishAzureDevOpsExtension@4
                    inputs:
                      connectTo: 'VsTeam'
                      connectedServiceName: 'ServiceConnection' # Change to whatever you named the service connection
                      fileType: 'vsix'
                      vsixFile: '$(PublisherID).$(ExtensionName)/$(PublisherID)..vsix'
                      publisherId: '$(PublisherID)'
                      extensionId: '$(ExtensionID)'
                      extensionName: '$(ExtensionName)'
                      updateTasksVersion: false
                      extensionVisibility: 'private' # Change to public if you're publishing to the marketplace
                      extensionPricing: 'free'
    

如需詳細資訊,請參閱 指定觸發管線的事件

注意

每個作業都會使用新的使用者代理,並且需要安裝所需的依賴項。

管線階段

下一節可協助您瞭解管線階段的運作方式。

階段 1:執行和發佈單元測試

此階段會執行單元測試,並將測試結果發佈至 Azure DevOps。

若要執行單元測試,請將自定義腳本新增至檔案, package.json 如下列範例所示。

"scripts": {
    "testScript": "mocha ./TestFile --reporter xunit --reporter-option output=ResultsFile.xml"
},
  1. 新增 使用 Azure DevOps 的 Node CLI (tfx-cli) 將 tfx-cli 安裝到您的組建代理程式。

  2. 使用 npm 命令新增 install 任務,並以 package.json 檔案為目標資料夾。

  3. 新增工作 Bash 以將 TypeScript 編譯至 JavaScript。

  4. 使用 npm 命令新增custom工作,目標是包含單元測試的資料夾,並輸入testScript作為命令。 使用以下輸入資料:

    • 命令: custom
    • 包含 package.json的工作資料夾: /TestsDirectory
    • 命令與自變數: testScript
  5. 新增 [發佈測試結果] 工作。 如果您使用 Mocha XUnit 記者,請確定結果格式為 JUnit ,而不是 XUnit。 將搜尋資料夾設定為根目錄。 使用以下輸入資料:

    • 測試結果格式: JUnit
    • 測試結果檔案: **/ResultsFile.xml
    • 搜尋資料夾: $(System.DefaultWorkingDirectory)

    在測試結果發佈之後,[測試] 索引標籤下的輸出看起來應該像下列範例。

    測試結果範例的螢幕快照。

階段 2:封裝延伸模組併發佈組建成品

  1. 新增 使用 Azure DevOps 的 Node CLI (tfx-cli) 將 tfx-cli 安裝到您的組建代理程式。

  2. 使用 npm 命令新增 install 任務,並以 package.json 檔案為目標資料夾。

  3. 新增工作 Bash 以將 TypeScript 編譯至 JavaScript。

  4. 若要查詢現有的版本,請使用下列輸入新增 查詢延伸模組版本 工作:

    • 連線至:Visual Studio Marketplace
    • Visual Studio Marketplace(服務連線):服務連線
    • 發行者 ID:您在 Visual Studio Marketplace 上的發行者 ID
    • 延伸模組識別碼:在 vss-extension.json 檔案中的延伸模組識別碼
    • 版本升級:補丁
    • 輸出變數: Task.Extension.Version
  5. 若要根據 manifest JSON 封裝擴充功能,請使用下列輸入新增 封裝擴充功能 工作:

    • 根指令清單資料夾:指向包含指令清單檔的根目錄。 例如, $(System.DefaultWorkingDirectory) 是根目錄
    • 清單檔: vss-extension.json
    • 發行者 ID:您在 Visual Studio Marketplace 上的發行者 ID
    • 延伸模組識別碼:在 vss-extension.json 檔案中的延伸模組識別碼
    • 擴充套件名稱:在檔案中的 vss-extension.json 处指定的名稱
    • 擴充功能版本: $(Task.Extension.Version)
    • 覆蓋任務版本:已勾選(啟用)
    • 覆寫類型:僅替換補丁(1.0.r)
    • 延伸模組可見度:如果延伸模組仍在開發中,請將值設定為 私用。 若要將擴充功能發行至公用,請將值設定為 public
  6. 若要複製到已發佈的檔案,請使用下列輸入新增 複製檔案 工作:

    • 內容:要複製的所有檔案,以將它們發佈為成品
    • 目標資料夾:檔案複製到的資料夾
      • 例如:$(Build.ArtifactStagingDirectory)
  7. 新增 [發佈組建成品 ] 以發佈成品以供其他作業或管線使用。 使用以下輸入資料:

    • 發佈路徑:包含所發行檔案的資料夾路徑
      • 例如:$(Build.ArtifactStagingDirectory)
    • 文物名稱:指定給文物的名稱
    • 成品發布位置:選擇 Azure Pipelines 以便在未來的任務中使用此成品。

階段 3:下載組建成品併發佈延伸模組

  1. 若要將 tfx-cli 安裝到您的組建代理程式,請新增 使用 Azure DevOps 的 Node CLI (tfx-cli)

  2. 若要將工件下載到新的作業,請使用下列輸入新增 下載建置工件 任務:

    • 下載所產生的成品:如果您要從相同的管線下載新作業上的成品,請選取 [目前組建]。 如果您要在新管線上下載,請選取 [特定組建]
    • 下載類型:選擇 [特定成品 ] 以下載所有已發佈的檔案。
    • 成品名稱:已發佈的成品名稱
    • 目的地目錄:應該下載檔案的資料夾
  3. 若要取得 發佈擴充功能 工作,請使用下列輸入:

    • 連線至:Visual Studio Marketplace
    • Visual Studio Marketplace 連線:"ServiceConnection"
    • 輸入檔案類型:VSIX 檔案
    • VSIX 檔案: /Publisher.*.vsix
    • 發行者 ID:您在 Visual Studio Marketplace 上的發行者 ID
    • 延伸模組識別碼:在 vss-extension.json 檔案中的延伸模組識別碼
    • 擴充套件名稱:在檔案中的 vss-extension.json 处指定的名稱
    • 擴充功能可見性:私有或公開

選擇性:安裝和測試您的延伸模組

只需幾個步驟,即可安裝與您共用的擴充功能:

  1. 從您的組織控制面板 (https://dev.azure.com/{organization}/_admin), 移至專案集合管理頁面。
  2. 在 [ 延伸模組] 索引標籤中,在 [ 與我共用 的延伸模組] 群組中尋找您的延伸模組,然後選取延伸模組連結。
  3. 安裝延伸項目。

如果您看不到 [ 延伸模組 ] 索引標籤,請確定您位於控制面板(專案集合層級的管理頁面), https://dev.azure.com/{organization}/_admin而不是專案的管理頁面。

如果您沒有看到 [ 延伸模組 ] 索引標籤,則不會為組織啟用延伸模組。 您可以加入 Visual Studio 合作夥伴計畫,以取得延伸模組功能的早期存取權。

若要封裝 Azure DevOps 延伸模組並將其發佈至 Visual Studio Marketplace,您可以下載 Azure DevOps 擴充功能工作

常見問題

請參閱下列有關在 Azure DevOps 的擴充功能中新增自定義組建或發行工作的常見問題。

問:如何限制 Azure Pipelines 任務的命令使用?

您可以限制依工作設定的 Azure Pipelines 命令使用方式和變數。 此操作能有效防止對執行任務的自定義腳本中的變數或 vso 命令進行不受限制的訪問。 建議您針對新工作進行設定。 若要套用,您可能需要將下列語句新增至檔案 task.json

"restrictions": {
  "commands": {
    "mode": "restricted"
  },
  "settableVariables": {
    "allowed": ["variable1", "test*"]
  }
}

如果為 restricted 指定了 mode 值,則您只能由工作執行下列命令:

  • logdetail
  • logissue
  • complete
  • setprogress
  • setsecret
  • setvariable
  • debug
  • settaskvariable
  • prependpath
  • publish

這些settableVariables限制可讓您提供一個變數允許清單,該清單由setvariableprependpath命令設置。 它也允許基本的正則表達式。 例如,如果您的 allowlist 是:['abc', 'test*'],將 abctesttest1 設定為具有任何值的變數,或將它們加到路徑的前面都會成功,但如果您嘗試設定變數 proxy,則會出現警告。 空白清單表示工作不會變更任何變數。

如果省略settableVariablescommands鍵,則不會套用相關的限制。

限制功能可從 代理程式 2.182.1 版取得。

任務如何處理取消訊號?

管線代理程式會將 SIGINTSIGTERM 訊號傳送至相關的子進程。 任務庫中沒有明確的處理方式。 如需詳細資訊,請參閱 代理任務取消

問:如何從專案集合中移除工作?

我們不支援自動刪除工作。 自動刪除並不安全,並中斷已使用這類工作的現有管線。 但是,您可以將工作標示為已被取代。 若要這樣做,請提升工作版本,並將工作標示為已淘汰

問:如何將自定義工作升級至最新的節點?

建議您升級至 最新的 Node 版本。 如需範例資訊,請參閱 將工作升級至節點 20

Microsoft裝載代理程式和各種 Azure DevOps Server 版本有不同的生命週期,因此會根據工作執行所在的位置安裝不同的節點執行器版本。 為了確保與不同節點執行器版本的代理程式相容, task.json 檔案可以包含多個執行區段。 在下列範例中,具有 Node 20 執行器的 Azure Pipeline 代理程式預設會使用它,而沒有它的代理程式會回復到 Node 10 實作。

"execution": {
  "Node10": {
    "target": "bash.js",
    "argumentFormat": ""
  },
  "Node20_1": {
    "target": "bash.js",
    "argumentFormat": ""
  }
}

若要升級您的任務:

  • 若要確保您的程式代碼如預期般運作,請在各種節點執行器版本上測試您的工作。

  • 在工作的執行區段中,從 NodeNode10 更新為 Node16Node20

  • 若要支援較舊的伺服器版本,您應該保留 Node/Node10 目標。 較舊的 Azure DevOps Server 版本可能未包含最新的節點執行器版本。

  • 您可以選擇共享目標中定義的進入點,或將目標優化至所使用的節點版本。

    "execution": {
       "Node10": {
         "target": "bash10.js",
         "argumentFormat": ""
       },
       "Node16": {
         "target": "bash16.js",
         "argumentFormat": ""
       },
       "Node20_1": {
         "target": "bash20.js",
         "argumentFormat": ""
       }
    }
    

重要

如果您未將 Node 20 執行器的支援新增至您的自定義工作,它們就會在從 pipelines-agent-*發行摘要安裝的代理程式上失敗。