添加自定义管道任务扩展
Azure DevOps Services | Azure DevOps Server 2022 - Azure DevOps Server 2019
了解如何在 Azure DevOps 中为组织的自定义生成或发布任务安装扩展。 有关详细信息,请参阅什么是 Azure Pipelines?
注意
本文介绍基于代理的扩展中的代理任务。 有关服务器任务和基于服务器的扩展的详细信息,请参阅 服务器任务 GitHub 文档。
先决条件
若要为 Azure DevOps 创建扩展,需要以下软件和工具。
软件/工具 | 信息 |
---|---|
Azure DevOps 组织 | 创建一个组织。 |
文本编辑器 | 对于许多过程,我们使用 Visual Studio Code,它提供 Intellisense 和调试支持。 下载最新版本。 |
Node.js | 下载最新版本。 |
npmjs.com 4.0.2 或更高版本 | TypeScript 编译器。 下载最新版本。 |
tfx-cli | 使用 适用于 Azure DevOps 的跨平台 CLI 打包扩展。 using,Node.js npm 的组件,通过运行 npm i -g tfx-cli 。 |
Azure DevOps 扩展 SDK | 安装 azure-devops-extension-sdk 包。 |
home 项目的目录 |
home 完成本文中的步骤后,生成或发布任务扩展的目录应如以下示例所示。 |
|--- 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
文件夹中执行此过程的每个部分。
注意
此示例演练将 Windows 与 PowerShell 配合使用。 我们对所有平台进行了通用化,但用于获取环境变量的语法不同。 如果使用 Mac 或 Linux,请将任何实例 $env:<var>=<val>
替换为 export <var>=<val>
。
创建任务基架
为任务创建文件夹结构,并安装所需的库和依赖项。
打开 PowerShell 命令窗口,转到文件夹
buildandreleasetask
,然后运行以下命令。npm init --yes
npm init
package.json
创建文件。 添加了参数--yes
以接受所有默认npm init
选项。提示
代理不会自动安装所需的模块,因为任务文件夹需要包含节点模块。 若要缓解此问题,请复制到
node_modules
buildandreleasetask
. 随着任务变大,很容易超过 VSIX 文件的大小限制(50MB)。 在复制节点文件夹之前,可能需要运行npm install --production
或npm prune --production
编写脚本来生成和打包所有内容。添加到
azure-pipelines-task-lib
库。npm install azure-pipelines-task-lib --save
确保为外部依赖项安装 TypeScript 键入。
npm install @types/node --save-dev npm install @types/q --save-dev
创建文件
.gitignore
并向其添加node_modules。 生成过程应执行一个和一个npm install
typings install
操作,以便每次生成node_modules,无需签入。echo node_modules > .gitignore
将 Mocha 安装为开发依赖项。
npm install mocha --save-dev -g npm install sync-request --save-dev npm install @types/mocha --save-dev
选择 TypeScript 版本 2.3.4 或 4.6.3。
npm install typescript@4.6.3 -g --save-dev
注意
请确保在开发环境中使用 npm 全局安装 TypeScript,以便
tsc
命令可用。 如果跳过此步骤,则默认情况下使用 TypeScript 版本 2.3.4,并且仍需全局安装包,才能让tsc
命令可用。创建
tsconfig.json
编译器选项。 此文件可确保 TypeScript 文件编译为 JavaScript 文件。tsc --init --target es2022
创建任务
现在基架已完成,我们可以创建自定义任务。
在
buildandreleasetask
文件夹中创建task.json
文件。 该文件task.json
描述生成/发布任务,以及生成/发布系统用于向用户呈现配置选项以及知道在生成/发布时要执行的脚本。复制以下代码,并将其替换为
{{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" } } }
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();
从
buildandreleasetask
文件夹中输入“tsc”以从index.ts
中编译index.js
文件。
task.json组件
请参阅文件的一些组件的 task.json
以下说明。
properties | 说明 |
---|---|
id |
任务的唯一 GUID。 |
name |
不带空格的名称。 |
friendlyName |
描述性名称(允许空格)。 |
description |
任务用途的详细说明。 |
author |
描述开发生成或发布任务的实体的简短字符串,例如:“Microsoft Corporation”。 |
instanceNameFormat |
任务在生成/发布步骤列表中显示的方式。 可以使用 $(variablename)来使用变量值。 |
groups |
描述 UI 中任务属性的逻辑分组。 |
inputs |
生成或发布任务运行时要使用的输入。 此任务需要具有名称 samplestring 的输入。 |
execution |
此任务的执行选项,包括脚本。 |
restrictions |
应用于有关 GitHub Codespaces 命令 任务可以调用的任务的限制,变量任务可以设置。 建议为新任务指定限制模式。 |
运行任务
使用 node index.js
PowerShell 运行任务。
在以下示例中,任务失败,因为未提供输入(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中包含最新节点版本的信息,请参阅 Azure Pipelines 任务作者的节点运行程序更新指南。
2.对任务脚本进行单元测试
执行单元测试以快速测试任务脚本,而不是它调用的外部工具。 测试成功路径和失败路径的各个方面。
安装测试工具。 在此过程中,我们使用 Mocha 作为测试驱动程序。
npm install mocha --save-dev -g npm install sync-request --save-dev npm install @types/mocha --save-dev
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 文件夹中。 如果收到同步请求错误,可以通过使用命令
npm i --save-dev sync-request
将 sync-request 添加到 buildandreleasetask 文件夹来解决此问题。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();
成功测试验证是否使用适当的输入,它成功且没有错误或警告,并返回正确的输出。
将以下示例成功测试添加到
_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 }); });
在测试目录中创建一个
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();
失败测试验证当工具收到错误或不完整的输入时,它会以预期方式失败,并得到有用的输出。
将以下代码添加到
_suite.ts
文件以运行任务模拟运行程序。it('it should fail if tool returns 1', function(done: Mocha.Done) { this.timeout(1000); let tp = path.join(__dirname, 'failure.js'); let tr: ttm.MockTestRunner = new ttm.MockTestRunner(tp); tr.run(); 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(); });
运行测试。
tsc mocha tests/_suite.js
这两个测试都应通过。 如果要使用更详细的输出(在生成控制台中看到的内容)运行测试,请设置环境变量:
TASK_TEST_TRACE=1
$env:TASK_TEST_TRACE=1
3.创建扩展清单文件
扩展清单包含有关扩展的所有信息。 它包括指向文件的链接,包括任务文件夹和图像文件夹。 确保已创建包含extension-icon.png的图像文件夹。 以下示例是包含生成或发布任务的扩展清单。
复制以下.json代码,并将其另存为 vss-extension.json
目录中的文件 home
。
请勿在 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"
}
}
]
}
注意
将 发布者更改为发布者 名称。 有关详细信息,请参阅 “创建发布者”。
发布内容
properties | 说明 |
---|---|
id |
贡献的标识符。 在扩展中必须是唯一的。 不需要与生成或发布任务的名称匹配。 通常,生成或发布任务名称位于参与的 ID 中。 |
type |
贡献的类型。 应为 ms.vss-distributed-task.task。 |
targets |
此贡献的“目标”贡献。 应为 ms.vss-distributed-task.tasks。 |
properties.name |
任务的名称。 此名称必须与相应的自包含生成或发布管道任务的文件夹名称匹配。 |
文件
属性 | 说明 |
---|---|
path |
相对于 home 目录的文件或文件夹的路径。 |
注意
有关扩展清单文件(例如其属性及其用途)的详细信息,请参阅 扩展清单参考。
4.打包扩展
将所有文件打包在一起,将扩展引入 Visual Studio 市场。 所有扩展都打包为 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 文件中后,即可将扩展发布到市场。
5.发布扩展
若要发布扩展,请先创建发布者,然后上传扩展,最后共享该扩展。
创建发布者
所有扩展(包括 Microsoft 的扩展)都标识为由发布者提供。 如果还没有现有发布者的成员,请创建一个。
- 登录到 Visual Studio Marketplace 发布门户。
- 如果还没有现有发布者的成员,系统会提示你创建发布者。 如果未提示创建发布者,请向下滚动到页面底部,然后选择“相关网站”下的“发布扩展”。
- 为发布者指定标识符,例如:
mycompany-myteam
- 此标识符用作扩展清单文件中属性的值
publisher
。
- 此标识符用作扩展清单文件中属性的值
- 为发布者指定显示名称,例如:
My Team
- 为发布者指定标识符,例如:
- 查看市场发布者协议,然后选择“创建”。
你的发布者已定义。 在将来的版本中,可以授予查看和管理发布者扩展的权限。 在通用发布者下发布扩展更容易且更安全,无需跨用户共享一组凭据。
上传扩展
找到“上传新扩展”按钮,转到打包的 .vsix 文件,然后选择“上传”。
还可以使用
tfx extension publish
命令(CLI)通过命令行接口(CLI)上传扩展,而不是tfx extension create
在一个步骤中打包和发布扩展。 可以选择在--share-with
扩展发布后与一个或多个帐户共享扩展。tfx extension publish --manifest-globs your-manifest.json --share-with yourOrganization
-
- 选择“市场(发布)”范围。 此范围将令牌限制为仅能够将扩展发布到市场。
共享扩展
上传扩展后,它位于市场中,但没有人可以看到它。 与组织共享它,以便你可以安装和测试它。
右键单击扩展并选择“共享”,然后输入组织信息。 也可以与想要访问扩展的其他帐户共享它。
重要
必须验证发布者才能公开共享扩展。 有关详细信息,请参阅 包/发布/安装。
在市场中共享扩展后,任何想要使用它的人都必须安装它。
6. 创建生成和发布管道以将扩展发布到市场
在 Azure DevOps 上创建生成和发布管道,以帮助维护市场上的自定义任务。
先决条件
软件/工具
信息
Azure DevOps 项目
创建项目。
Azure DevOps 扩展任务扩展
管道库变量组
创建管道库变量组以保存管道使用的变量。 有关详细信息,请参阅 “添加和使用变量组”。 可以从 Azure DevOps 库选项卡或通过 CLI 生成变量组。 在管道中使用此组中的变量 。 此外,在变量组中声明以下变量:
publisherId
:市场发布者的 IDextensionId
:扩展的 ID,如vss-extension.json文件中声明的那样extensionName
:扩展的名称,如vss-extension.json文件中声明的那样artifactName
:为 VSIX 文件创建的项目的名称
服务连接
创建新的市场服务连接并为所有管道授予访问权限。
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"
},
添加“将 Node CLI 用于 Azure DevOps(tfx-cli)”,将 tfx-cli 安装到生成代理。
使用“install”命令添加“npm”任务,并将文件夹与package.json文件为目标。
添加“Bash”任务以将 TypeScript 编译为 JavaScript。
使用“custom”命令添加“npm”任务,以包含单元测试的文件夹为目标,并将输入作为命令添加
testScript
。 使用以下输入:- 命令:自定义
- 包含package.json的工作文件夹:/TestsDirectory
- 命令和参数:
testScript
添加“发布测试结果”任务。 如果使用 Mocha XUnit 记者,请确保结果格式为“JUnit”而不是“XUnit”。将搜索文件夹设置为根目录。 使用以下输入:
- 测试结果格式:JUnit
- 测试结果文件:**/ResultsFile.xml
- 搜索文件夹:
$(System.DefaultWorkingDirectory)
发布测试结果后,“测试”选项卡下的输出应如以下示例所示。
阶段 2:打包扩展并发布生成项目
添加“将 Node CLI 用于 Azure DevOps(tfx-cli)”,将 tfx-cli 安装到生成代理。
使用“install”命令添加“npm”任务,并将文件夹与package.json文件为目标。
添加“Bash”任务以将 TypeScript 编译为 JavaScript。
添加“查询扩展版本”任务以查询现有扩展版本。 使用以下输入:
- 连接到:Visual Studio Marketplace
- Visual Studio Marketplace (服务连接):服务连接
- 发布者 ID:Visual Studio Marketplace 发布者的 ID
- 扩展 ID:vss-extension.json文件中扩展的 ID
- 增加版本:修补程序
- 输出变量:Task.Extension.Version
添加“包扩展”任务,以基于清单 Json 打包扩展。 使用以下输入:
- 根清单文件夹:指向包含清单文件的根目录。 例如,$(System.DefaultWorkingDirectory)是根目录
- 清单文件(s): vss-extension.json
- 发布者 ID:Visual Studio Marketplace 发布者的 ID
- 扩展 ID:vss-extension.json文件中扩展的 ID
- 扩展名:vss-extension.json 文件中扩展名的名称
- 扩展版本:$(Task.Extension.Version)
- 替代任务版本:已选中(true)
- 替代类型:仅替换修补程序(1.0.r)
- 扩展可见性:如果扩展仍在开发中,请将该值设置为私有。 若要将扩展发布到公共,请将值设置为公共
添加“复制文件”任务以复制已发布的文件。 使用以下输入:
- 内容:要复制的所有文件以将其发布为项目
- 目标文件夹:文件复制到的文件夹
- 例如:$(Build.ArtifactStagingDirectory)
添加“发布生成项目”以发布项目以供其他作业或管道使用。 使用以下输入:
- 发布路径:包含要发布的文件的文件夹的路径
- 例如:$(Build.ArtifactStagingDirectory)
- 项目名称:为项目提供的名称
- 项目发布位置:选择“Azure Pipelines”,以便在将来的作业中使用项目
- 发布路径:包含要发布的文件的文件夹的路径
阶段 3:下载生成项目并发布扩展
添加“将 Node CLI 用于 Azure DevOps(tfx-cli)”,将 tfx-cli 安装到生成代理。
添加“下载生成项目”任务,将项目下载到新作业。 使用以下输入:
- 下载生成的项目:如果要从同一管道在新作业上下载项目,请选择“当前生成”。如果要在新管道上下载,请选择“特定生成”。
- 下载类型:选择“特定项目”以下载已发布的所有文件。
- 项目名称:已发布的项目名称。
- 目标目录:应下载文件的文件夹。
需要的最后一个任务是“发布扩展”任务。 使用以下输入:
- 连接到:Visual Studio Marketplace
- Visual Studio Marketplace 连接:ServiceConnection
- 输入文件类型:VSIX 文件
- VSIX 文件:/Publisher.*.vsix
- 发布者 ID:Visual Studio Marketplace 发布者的 ID
- 扩展 ID:vss-extension.json文件中扩展的 ID
- 扩展名:vss-extension.json 文件中扩展名的名称
- 扩展可见性:专用或公共
可选:安装和测试扩展
只需执行几个步骤即可安装与你共享的扩展:
- 从组织控制面板(
https://dev.azure.com/{organization}/_admin
)转到项目集合管理页面。 - 在“扩展”选项卡中,在“与我共享的扩展”组中找到扩展,然后选择扩展链接。
- 安装扩展。
如果看不到“ 扩展 ”选项卡,请确保位于控制面板(项目集合级别的管理页), https://dev.azure.com/{organization}/_admin
而不是项目的管理页。
如果未看到“ 扩展 ”选项卡,则不会为组织启用扩展。 可以通过加入 Visual Studio 合作伙伴计划来提前访问扩展功能。
若要打包 Azure DevOps Extensions 并将其发布到 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
限制允许传入变量的允许列表,这些变量由 setvariable
或 prependpath
命令设置。 它还允许基本正则表达式。 例如,如果允许列表是:['abc', 'test*']
、设置abc
test
或test1
作为具有任何值的变量,或者将其追加到路径前会成功,但如果尝试设置变量代理,则会发出警告。 空列表意味着任务不会更改任何变量。
settableVariables
如果省略或commands
密钥,则不会应用相关限制。
限制功能可从 2.182.1 代理版本获取。
问:如何由任务处理取消信号?
答:管道代理向相关子进程发送 SIGINT
并 SIGTERM
发出信号。 任务库中没有要处理的显式手段。 有关详细信息,请参阅 代理作业取消。
问:如何从项目集合中删除任务?
答:不支持自动删除任务。 自动删除不安全,会中断已使用此类任务的现有管道。 但是,可以将任务标记为已弃用。 为此, 请颠簸任务版本 并将 任务标记为已弃用。
问:如何将自定义任务升级到最新的节点?
答:建议升级到 最新的 Node 版本。 有关示例信息,请参阅 将任务升级到 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": ""
}
升级任务:
在各种 Node 运行程序版本上测试任务,以确保代码按预期方式运行。
在任务的执行部分中,从
Node
或Node10
更新到或Node20
更新Node16
。若要支持较旧的服务器版本,应保留目标
Node
/Node10
。 旧版 Azure DevOps Server 可能不包含最新的 Node 运行程序版本。可以选择共享目标中定义的入口点,或者将目标优化到使用的 Node 版本。
"execution": { "Node10": { "target": "bash10.js", "argumentFormat": "" }, "Node16": { "target": "bash16.js", "argumentFormat": "" }, "Node20_1": { "target": "bash20.js", "argumentFormat": "" }
重要
在自定义任务上不添加对 Node 20 运行程序的支持将导致从pipelines-agent-*
发布源安装的代理上任务失败。