Azure DevOps自定义任务多版本实现:共享源码与版本识别
Azure DevOps自定义任务多版本支持问题解答
问题1:任务运行时如何确定自身版本?是否可在贡献中传递额外属性供运行时读取?是否存在包含任务版本的运行时变量?
- 读取task.json获取版本:这是最直接可靠的方式,借助
azure-pipelines-task-lib的getTaskJsonPath()方法拿到当前任务的task.json路径,读取并解析版本信息。示例代码:
import tl = require("azure-pipelines-task-lib/task"); import fs = require("fs"); async function run() { try { const taskJsonPath = tl.getTaskJsonPath(); const taskJson = JSON.parse(fs.readFileSync(taskJsonPath, "utf8")); const majorVersion = taskJson.version.Major; if (majorVersion === 1) { // 执行V1版本逻辑,读取V1输入 } else { // 执行V2版本逻辑,读取新增输入 } } catch (err) { tl.setResult(tl.TaskResult.Failed, err.message); } } run();
- 贡献属性传递限制:可以在
vss-extension.json的贡献properties字段添加自定义属性,但这些属性无法直接传递到任务运行时环境,不能被任务代码读取,因此不建议用这种方式传递版本信息。 - 内置运行时变量:Azure DevOps没有提供直接包含当前任务版本的内置环境变量,必须通过读取
task.json自行获取。
问题2:需进行哪些改动才能支持两个task.json文件?
要实现一份源码支撑两个任务版本,需按以下步骤调整:
1. 调整文件夹结构
创建独立的版本文件夹存放各自的task.json,核心源码仅保留一份:
/docs /img icon.png /MyTaskNameV1 task.json # V1版本配置(原有内容) index.ts # 核心源码文件 index.js # 编译后的JS文件 /MyTaskNameV2 task.json # V2版本配置(添加新输入选项)
2. 修改vss-extension.json
添加V2版本的贡献配置,同时避免重复打包源码文件:
{ // 省略其他内容 "files": [ { "path": "MyTaskNameV1" }, { "path": "MyTaskNameV2", "exclude": ["**/*.ts", "**/*.js"] // 排除V2文件夹下的源码,避免重复打包 }, { "path": "docs/img", "addressable": "true" } ], "contributions": [ { "id": "mytaskname-v1", "type": "ms.vss-distributed-task.task", "targets": ["ms.vss-distributed-task.tasks"], "properties": { "name": "MyTaskNameV1" } }, { "id": "mytaskname-v2", "type": "ms.vss-distributed-task.task", "targets": ["ms.vss-distributed-task.tasks"], "properties": { "name": "MyTaskNameV2" } } ] }
3. 配置V2版本的task.json
更新版本号、添加新输入选项,指定共享的JS执行入口:
{ // 保持schema配置,此处省略外部URL "id": "unique-task-id-v2", // 使用与V1不同的唯一ID "name": "MyTaskName", "friendlyName": "My Task Name (V2)", // 设置区分性的显示名称 "version": { "Major": 2, "Minor": 0, "Patch": 0 }, "inputs": [ // 保留V1的所有输入配置 // 添加V2专属输入选项 { "name": "newV2Input", "type": "string", "label": "V2专属输入", "required": true } ], "execution": { "Node16": { "target": "../MyTaskNameV1/index.js", // 指向V1文件夹下的共享JS文件 "argumentFormat": "" } } }
可选优化:统一编译输出目录
如果想更清晰管理编译产物,可修改tsconfig.json,将编译后的JS文件输出到公共目录:
{ "compilerOptions": { "target": "es2022", "module": "commonjs", "sourceMap": true, "outDir": "../dist", // 输出到根目录下的dist文件夹 "strict": true, "skipLibCheck": true }, "include": ["MyTaskNameV1/index.ts"] }
调整后,两个版本的task.json的execution.target都指向../dist/index.js,同时在vss-extension.json的files中添加"path": "dist"确保编译产物被打包。
内容的提问来源于stack exchange,提问作者bryanbcook
相关产品推荐
相关产品推荐

