Nota:
El acceso a esta página requiere autorización. Puede intentar iniciar sesión o cambiar directorios.
El acceso a esta página requiere autorización. Puede intentar cambiar los directorios.
Azure DevOps Services | Azure DevOps Server | Azure DevOps Server 2022 | Azure DevOps Server 2020
En esta guía se explica cómo crear, probar y publicar tareas personalizadas de compilación o versión como extensiones de Azure DevOps. Las tareas de canalización personalizadas permiten ampliar Azure DevOps con funcionalidad especializada adaptada a los flujos de trabajo de su equipo, desde utilidades sencillas hasta integraciones complejas con sistemas externos.
Obtenga información sobre cómo realizar las siguientes tareas:
- Configuración del entorno de desarrollo y la estructura del proyecto
- Creación de lógica de tareas mediante TypeScript y la biblioteca de tareas de Azure Pipelines
- Implementación de pruebas unitarias completas con marcos ficticios
- Empaquetar la extensión para la distribución
- Publicación en Visual Studio Marketplace
- Configuración de canalizaciones automatizadas de CI/CD para el mantenimiento de extensiones
Para más información sobre Azure Pipelines, consulte ¿Qué es Azure Pipelines?
Nota:
En este artículo se tratan las tareas del agente en extensiones basadas en agente. Para obtener información sobre las tareas de servidor y las extensiones basadas en servidor, vea Creación de tareas de servidor.
Requisitos previos
Antes de comenzar, asegúrese de que tiene los siguientes requisitos:
| Componente | Requisito | Descripción |
|---|---|---|
| Organización de Azure DevOps | Obligatorio | Cree una organización si no tiene una |
| Editor de texto | Recomendado | Compatibilidad con Visual Studio Code para IntelliSense y depuración |
| Node.js | Obligatorio | Instale la versión más reciente (se recomiendaNode.js 20 o posterior) |
| Compilador de TypeScript | Obligatorio | Instale la versión más reciente (versión 4.6.3 o posterior) |
| CLI de Azure DevOps (tfx-cli) | Obligatorio | Instalación mediante npm i -g tfx-cli para empaquetar extensiones |
| SDK de extensión de Azure DevOps | Obligatorio | Instalación del paquete azure-devops-extension-sdk |
| Marco de pruebas | Obligatorio | Mocha para pruebas unitarias (instaladas durante la instalación) |
Estructura de proyecto
Cree un home directorio para el proyecto. Después de completar este tutorial, la extensión debe tener la estructura siguiente:
|--- README.md
|--- images
|--- extension-icon.png
|--- buildandreleasetask // Task scripts location
|--- task.json // Task definition
|--- index.ts // Main task logic
|--- package.json // Node.js dependencies
|--- tests/ // Unit tests
|--- _suite.ts
|--- success.ts
|--- failure.ts
|--- vss-extension.json // Extension manifest
Importante
La máquina de desarrollo debe ejecutar la versión más reciente de Node.js para garantizar la compatibilidad con el entorno de producción. Actualice el task.json archivo para usar Node 20:
"execution": {
"Node20_1": {
"target": "index.js"
}
}
1. Crear una tarea personalizada
Esta sección le guía a través de la creación de la estructura básica y la implementación de la tarea personalizada. Todos los archivos de este paso se deben crear dentro de la buildandreleasetask carpeta dentro del directorio del home proyecto.
Nota:
En este tutorial se usa Windows con PowerShell. Los pasos funcionan en todas las plataformas, pero la sintaxis de las variables de entorno difiere. En Mac o Linux, reemplace por $env:<var>=<val>export <var>=<val>.
Configuración del scaffolding de tareas
Cree la estructura básica del proyecto e instale las dependencias necesarias:
Para inicializar el proyecto de Node.js, abra PowerShell, vaya a la
buildandreleasetaskcarpeta y ejecute:npm init --yesEl
package.jsonarchivo se crea con la configuración predeterminada. La--yesmarca acepta automáticamente todas las opciones predeterminadas.Sugerencia
Los agentes de Azure Pipelines esperan que las carpetas de tareas incluyan módulos de nodo. Copie
node_modulesen labuildandreleasetaskcarpeta. Para administrar el tamaño del archivo VSIX (límite de 50 MB), considere la posibilidad de ejecutarnpm install --productiononpm prune --productionantes del empaquetado.Instale la biblioteca de tareas de Azure Pipelines:
npm install azure-pipelines-task-lib --saveInstale definiciones de tipos de TypeScript:
npm install @types/node --save-dev npm install @types/q --save-devConfiguración de exclusiones de control de versiones
echo node_modules > .gitignoreEl proceso de compilación debe ejecutarse para recompilar
npm installnode_modules cada vez.Instalar dependencias de prueba:
npm install mocha --save-dev -g npm install sync-request --save-dev npm install @types/mocha --save-devInstale el compilador de TypeScript:
npm install typescript@4.6.3 -g --save-devNota:
Instale TypeScript globalmente para asegurarse de que el
tsccomando está disponible. Sin él, TypeScript 2.3.4 se usa de forma predeterminada.Configurar la compilación de TypeScript:
tsc --init --target es2022El
tsconfig.jsonarchivo se crea con la configuración de destino ES2022.
Implementación de la lógica de tareas
Con la scaffolding completa, cree los archivos de tareas principales que definen la funcionalidad y los metadatos:
Cree el archivo de definición de tarea: cree
task.jsonen labuildandreleasetaskcarpeta . En este archivo se describe la tarea en el sistema de Azure Pipelines, la definición de entradas, la configuración de ejecución y la presentación de la interfaz de usuario.{ "$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" } } }Nota:
Reemplace por
{{placeholders}}la información real de la tarea.taskguiddebe ser único. Genere uno mediante PowerShell:(New-Guid).GuidPara implementar la lógica de tareas, cree
index.tscon la funcionalidad principal de la tarea: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();Compile TypeScript en JavaScript:
tscEl
index.jsarchivo se crea a partir del origen de TypeScript.
Descripción de los componentes de task.json
El task.json archivo es el corazón de la definición de la tarea. Estas son las propiedades clave:
| Propiedad | Descripción | Ejemplo |
|---|---|---|
id |
Identificador GUID único de la tarea | Generado mediante (New-Guid).Guid |
name |
Nombre de tarea sin espacios (se usa internamente) | MyCustomTask |
friendlyName |
Nombre para mostrar que se muestra en la interfaz de usuario | My Custom Task |
description |
Descripción detallada de la funcionalidad de tareas | Performs custom operations on files |
author |
Nombre del publicador o autor | My Company |
instanceNameFormat |
Cómo aparece la tarea en los pasos de la canalización | Process $(inputFile) |
inputs |
Matriz de parámetros de entrada | Consulte los siguientes tipos de entrada. |
execution |
Especificación del entorno de ejecución |
Node20_1, PowerShell3, etc. |
restrictions |
Restricciones de seguridad para comandos y variables | Recomendado para nuevas tareas |
Restricciones de seguridad
En el caso de las tareas de producción, agregue restricciones de seguridad para limitar el uso de comandos y el acceso a variables:
"restrictions": {
"commands": {
"mode": "restricted"
},
"settableVariables": {
"allowed": ["variable1", "test*"]
}
}
El modo restringido solo permite estos comandos:
-
logdetail,logissue, ,complete,setprogress -
setsecret,setvariable, ,debug,settaskvariable -
prependpath,publish
Controles de lista de permitidos de variables que se pueden establecer mediante setvariable o prependpath. Admite patrones regex básicos.
Nota:
Esta característica requiere la versión del agente 2.182.1 o posterior.
Tipos y ejemplos de entrada
Tipos de entrada comunes para parámetros de tarea:
"inputs": [
{
"name": "stringInput",
"type": "string",
"label": "Text Input",
"defaultValue": "",
"required": true,
"helpMarkDown": "Enter a text value"
},
{
"name": "boolInput",
"type": "boolean",
"label": "Enable Feature",
"defaultValue": "false",
"required": false
},
{
"name": "picklistInput",
"type": "pickList",
"label": "Select Option",
"options": {
"option1": "First Option",
"option2": "Second Option"
},
"defaultValue": "option1"
},
{
"name": "fileInput",
"type": "filePath",
"label": "Input File",
"required": true,
"helpMarkDown": "Path to the input file"
}
]
Prueba local de la tarea
Antes de empaquetar, pruebe la tarea para asegurarse de que funciona correctamente:
Prueba con entrada que falta (debe producir un error):
node index.jsResultado esperado:
##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: samplestringPrueba con entrada válida (debe realizarse correctamente):
$env:INPUT_SAMPLESTRING="World" node index.jsResultado esperado:
##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]samplestring=World Hello WorldControl de errores de prueba:
$env:INPUT_SAMPLESTRING="bad" node index.jsEsta acción debe desencadenar la ruta de acceso de control de errores en el código.
Sugerencia
Para obtener información sobre los ejecutores de tareas y las versiones de Node.js, consulte Guía de actualización del ejecutor de nodos.
Para obtener más información, consulte la referencia de tareas de compilación/lanzamiento.
2. Implementar pruebas unitarias completas
Probar la tarea exhaustivamente garantiza la confiabilidad y ayuda a detectar problemas antes de la implementación en canalizaciones de producción.
Instalación de dependencias de prueba
Instale las herramientas de prueba necesarias:
npm install mocha --save-dev -g
npm install sync-request --save-dev
npm install @types/mocha --save-dev
Creación de pruebas
Cree una carpeta en el
testsdirectorio de tareas que contenga un_suite.tsarchivo: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() { // Setup before tests }); after(() => { // Cleanup after tests }); it('should succeed with simple inputs', function(done: Mocha.Done) { // Success test implementation }); it('should fail if tool returns 1', function(done: Mocha.Done) { // Failure test implementation }); });Sugerencia
La carpeta de prueba debe encontrarse en la carpeta de tareas (por ejemplo,
buildandreleasetask). Si se produce un error de solicitud de sincronización, instálelo en la carpeta de tareas:npm i --save-dev sync-request.Cree
success.tsen el directorio de prueba para simular la ejecución correcta de tareas: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); // Set valid input for success scenario tmr.setInput('samplestring', 'human'); tmr.run();Agregue la prueba correcta al
_suite.tsarchivo: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.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 }); });Cree
failure.tsen el directorio de prueba para probar el control de errores: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); // Set invalid input to trigger failure tmr.setInput('samplestring', 'bad'); tmr.run();Agregue la prueba de error al
_suite.tsarchivo: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(); }); });
Ejecutar las pruebas
Ejecute el conjunto de pruebas:
# Compile TypeScript
tsc
# Run tests
mocha tests/_suite.js
Ambas pruebas deben superarse. Para obtener una salida detallada (similar a la salida de la consola de compilación), establezca la variable de entorno de seguimiento:
$env:TASK_TEST_TRACE=1
mocha tests/_suite.js
Procedimientos recomendados de cobertura de pruebas
- Probar todas las combinaciones de entrada: entradas válidas, entradas no válidas, entradas que faltan
- Escenarios de error de prueba: errores de red, errores del sistema de archivos, problemas de permisos
- Dependencias externas simuladas: no se basan en servicios externos en pruebas unitarias
- Validar salidas: comprobar la salida de la consola, los resultados de la tarea y los artefactos generados
- Pruebas de rendimiento: considere la posibilidad de agregar pruebas para tareas que procesan archivos grandes
Procedimientos recomendados de seguridad
- Validación de entrada: valide y sane siempre las entradas.
-
Control de secretos: uso
setSecretde datos confidenciales - Restricciones de comandos: Implementar restricciones de comandos para tareas de producción
- Permisos mínimos: solicite solo los permisos necesarios.
- Actualizaciones periódicas: mantener las dependencias y las versiones de Node.js actuales
Después de probar la tarea localmente e implementar pruebas unitarias completas, empaquetela en una extensión para Azure DevOps.
Instalación de herramientas de empaquetado
Instale la interfaz de la línea de comandos multiplataforma (tfx-cli):
npm install -g tfx-cli
Creación del manifiesto de extensión
El manifiesto de extensión (vss-extension.json) contiene toda la información sobre la extensión, incluidas las referencias a las carpetas de tareas e imágenes.
Creación de una carpeta images con un
extension-icon.pngarchivoCree
vss-extension.jsonen el directorio raíz de la extensión (no en la carpeta de tareas):{ "manifestVersion": 1, "id": "my-custom-tasks", "name": "My Custom Tasks", "version": "1.0.0", "publisher": "your-publisher-id", "targets": [ { "id": "Microsoft.VisualStudio.Services" } ], "description": "Custom build and release tasks for Azure DevOps", "categories": [ "Azure Pipelines" ], "icons": { "default": "images/extension-icon.png" }, "files": [ { "path": "MyCustomTask" } ], "contributions": [ { "id": "my-custom-task", "type": "ms.vss-distributed-task.task", "targets": [ "ms.vss-distributed-task.tasks" ], "properties": { "name": "MyCustomTask" } } ] }
Propiedades del manifiesto de clave
| Propiedad | Descripción |
|---|---|
publisher |
Identificador del publicador de Marketplace |
contributions.id |
Identificador único dentro de la extensión |
contributions.properties.name |
Debe coincidir con el nombre de la carpeta de tareas. |
files.path |
Ruta de acceso a la carpeta de tareas relativa al manifiesto |
Nota:
Cambie el valor del publicador por el nombre del publicador. Para obtener información sobre cómo crear un publicador, consulte Creación del publicador.
Empaqueta tu extensión
Empaquete la extensión en un archivo .vsix:
tfx extension create --manifest-globs vss-extension.json
Administración de versiones
-
Versión de la extensión: incremente la versión de
vss-extension.jsonpara cada actualización. -
Versión de la tarea: incremente la versión de
task.jsonpara cada actualización de tarea. -
Incremento automático: se usa
--rev-versionpara incrementar automáticamente la versión de revisión
tfx extension create --manifest-globs vss-extension.json --rev-version
Importante
Tanto la versión de la tarea como la versión de la extensión deben actualizarse para que los cambios surtan efecto en Azure DevOps.
Estrategia de control de versiones
Siga los principios de control de versiones semánticos para las actualizaciones de tareas:
- Versión principal: Cambios importantes en las entradas y salidas
- Versión secundaria: nuevas características compatibles con versiones anteriores
- Versión de revisión: correcciones de errores solo
Proceso de actualización:
- Versión de actualización
task.json - Versión de actualización
vss-extension.json - Prueba exhaustiva en una organización de prueba
- Publicación y supervisión de problemas
Publicación en Visual Studio Marketplace
1. Creación del publicador
- Inicio de sesión en el Portal de publicación de Visual Studio Marketplace
- Cree un nuevo publicador si se le solicita:
-
Identificador del publicador: se usa en el manifiesto de extensión (por ejemplo,
mycompany-myteam) -
Nombre para mostrar: nombre público que se muestra en Marketplace (por ejemplo,
My Team)
-
Identificador del publicador: se usa en el manifiesto de extensión (por ejemplo,
- Revisión y aceptación del Contrato de publicador de Marketplace
2. Cargar la extensión
Método de interfaz web:
- Seleccione Upload new extension (Cargar nueva extensión)
- Elección del archivo empaquetado
.vsix - Haga clic en Cargar.
Método de línea de comandos:
tfx extension publish --manifest-globs vss-extension.json --share-with yourOrganization
3. Compartir la extensión
- Haga clic con el botón derecho en la extensión en Marketplace.
- Seleccione Compartir.
- Escriba el nombre de la organización.
- Incorporación de más organizaciones según sea necesario
Importante
Los publicadores deben comprobarse para compartir extensiones públicamente. Para obtener más información, consulte Package/Publish/Install.
4. Instalar en su organización
Después del uso compartido, instale la extensión en la organización de Azure DevOps:
- Vaya a Extensiones de configuración de> la organización.
- Busque la extensión.
- Seleccione Obtenerlo gratis e instalarlo .
3. Empaquetar y publicar la extensión
Comprobación de la extensión
Después de la instalación, compruebe que la tarea funciona correctamente:
- Cree o edite una canalización.
- Agregue la tarea personalizada:
- Seleccione Agregar tarea en el editor de canalizaciones.
- Buscar la tarea personalizada por nombre
- Agréguelo a la canalización
- Configurar parámetros de tarea:
- Establecimiento de entradas necesarias
- Configuración de valores opcionales
- Ejecución de la canalización para probar la funcionalidad
- Supervisión de la ejecución:
- Comprobación de los registros de tareas para una ejecución adecuada
- Comprobación de las salidas esperadas
- Asegúrese de que no hay errores ni advertencias
4. Automatizar la publicación de extensiones con CI/CD
Para mantener la tarea personalizada de forma eficaz, cree canalizaciones de compilación y versión automatizadas que controlen las pruebas, el empaquetado y la publicación.
Requisitos previos para la automatización
- Tareas de extensión de Azure DevOps: instale la extensión de forma gratuita.
-
Grupo de variables: cree un grupo de variables de biblioteca de canalización con estas variables:
-
publisherId: identificador del publicador de Marketplace -
extensionId: identificador de extensión de vss-extension.json -
extensionName: nombre de extensión de vss-extension.json -
artifactName: nombre del artefacto VSIX
-
- Conexión de servicio: creación de una conexión de servicio de Marketplace con permisos de acceso de canalización
Canalización completa de CI/CD
Cree una canalización de YAML con fases completas para probar, empaquetar y publicar:
trigger:
- main
pool:
vmImage: "ubuntu-latest"
variables:
- group: extension-variables # Your variable group name
stages:
- stage: Test_and_validate
displayName: 'Run Tests and Validate Code'
jobs:
- job: RunTests
displayName: 'Execute unit tests'
steps:
- task: TfxInstaller@4
displayName: 'Install TFX CLI'
inputs:
version: "v0.x"
- task: Npm@1
displayName: 'Install task dependencies'
inputs:
command: 'install'
workingDir: '/MyCustomTask' # Update to your task directory
- task: Bash@3
displayName: 'Compile TypeScript'
inputs:
targetType: "inline"
script: |
cd MyCustomTask # Update to your task directory
tsc
- task: Npm@1
displayName: 'Run unit tests'
inputs:
command: 'custom'
workingDir: '/MyCustomTask' # Update to your task directory
customCommand: 'test' # Ensure this script exists in package.json
- task: PublishTestResults@2
displayName: 'Publish test results'
inputs:
testResultsFormat: 'JUnit'
testResultsFiles: '**/test-results.xml'
searchFolder: '$(System.DefaultWorkingDirectory)'
- stage: Package_extension
displayName: 'Package Extension'
dependsOn: Test_and_validate
condition: succeeded()
jobs:
- job: PackageExtension
displayName: 'Create VSIX package'
steps:
- task: TfxInstaller@4
displayName: 'Install TFX CLI'
inputs:
version: "v0.x"
- task: Npm@1
displayName: 'Install dependencies'
inputs:
command: 'install'
workingDir: '/MyCustomTask'
- task: Bash@3
displayName: 'Compile TypeScript'
inputs:
targetType: "inline"
script: |
cd MyCustomTask
tsc
- task: QueryAzureDevOpsExtensionVersion@4
name: QueryVersion
displayName: 'Query current extension version'
inputs:
connectTo: 'VsTeam'
connectedServiceName: 'marketplace-connection'
publisherId: '$(publisherId)'
extensionId: '$(extensionId)'
versionAction: 'Patch'
- task: PackageAzureDevOpsExtension@4
displayName: 'Package extension'
inputs:
rootFolder: '$(System.DefaultWorkingDirectory)'
publisherId: '$(publisherId)'
extensionId: '$(extensionId)'
extensionName: '$(extensionName)'
extensionVersion: '$(QueryVersion.Extension.Version)'
updateTasksVersion: true
updateTasksVersionType: 'patch'
extensionVisibility: 'private'
extensionPricing: 'free'
- task: PublishBuildArtifacts@1
displayName: 'Publish VSIX artifact'
inputs:
PathtoPublish: '$(System.DefaultWorkingDirectory)/*.vsix'
ArtifactName: '$(artifactName)'
publishLocation: 'Container'
- stage: Publish_to_marketplace
displayName: 'Publish to Marketplace'
dependsOn: Package_extension
condition: and(succeeded(), eq(variables['Build.SourceBranch'], 'refs/heads/main'))
jobs:
- deployment: PublishExtension
displayName: 'Deploy to marketplace'
environment: 'marketplace-production'
strategy:
runOnce:
deploy:
steps:
- task: TfxInstaller@4
displayName: 'Install TFX CLI'
inputs:
version: "v0.x"
- task: PublishAzureDevOpsExtension@4
displayName: 'Publish to marketplace'
inputs:
connectTo: 'VsTeam'
connectedServiceName: 'marketplace-connection'
fileType: 'vsix'
vsixFile: '$(Pipeline.Workspace)/$(artifactName)/*.vsix'
publisherId: '$(publisherId)'
extensionId: '$(extensionId)'
extensionName: '$(extensionName)'
updateTasksVersion: false
extensionVisibility: 'private'
extensionPricing: 'free'
Configuración de package.json para pruebas
Agregue scripts de prueba a package.json:
{
"scripts": {
"test": "mocha tests/_suite.js --reporter xunit --reporter-option output=test-results.xml",
"test-verbose": "cross-env TASK_TEST_TRACE=1 npm test"
}
}
Desglose de la fase de canalización
Fase 1: Prueba y validación
- Propósito: Garantizar la calidad y la funcionalidad del código
- Acciones: Instalar dependencias, compilar TypeScript, ejecutar pruebas unitarias, publicar resultados
- Validación: todas las pruebas deben pasar para continuar
Fase 2: Extensión de paquete
- Propósito: Creación de un paquete VSIX que se puede implementar
- Acciones: Consultar la versión actual, incrementar la versión, la extensión del paquete, publicar artefactos
- Control de versiones: controla automáticamente los incrementos de versión.
Fase 3: Publicación en Marketplace
- Propósito: Implementar en Visual Studio Marketplace
- Condiciones: solo se ejecuta en la rama principal después del empaquetado correcto
- Entorno: usa el entorno de implementación para las puertas de aprobación
Procedimientos recomendados para CI/CD
- Protección de rama: solo publicar desde ramas principales o de versión
- Puertas de entorno: uso de entornos de implementación para versiones de producción
- Administración de versiones: automatización de incrementos de versión para evitar conflictos
- Cobertura de pruebas: asegúrese de una cobertura completa de pruebas antes del empaquetado.
- Seguridad: usar conexiones de servicio en lugar de credenciales codificadas de forma codificada
- Supervisión: configuración de alertas para implementaciones con errores
En el caso de las canalizaciones de compilación clásicas, siga estos pasos para configurar el empaquetado y la publicación de extensiones:
Agregue la
Bashtarea para compilar TypeScript en JavaScript.Para consultar la versión existente, agregue la tarea Versión de extensión de consulta mediante las siguientes entradas:
- Conexión a: Visual Studio Marketplace
- Visual Studio Marketplace (conexión de servicio): conexión de servicio
- Id. de publicador: identificador del publicador de Visual Studio Marketplace
- Id. de extensión: Id. de la extensión en el archivo
vss-extension.json - Aumento de la versión: Revisión
- Variable de salida:
Task.Extension.Version
Para empaquetar las extensiones basadas en JSON de manifiesto, agregue la tarea Package Extension mediante las siguientes entradas:
- Carpeta manifiestos raíz: apunta al directorio raíz que contiene el archivo de manifiesto. Por ejemplo,
$(System.DefaultWorkingDirectory)es el directorio raíz. - Archivo de manifiesto:
vss-extension.json - Id. de publicador: identificador del publicador de Visual Studio Marketplace
- Id. de extensión: Id. de la extensión en el archivo
vss-extension.json - Nombre de la extensión: nombre de la extensión en el archivo
vss-extension.json - Versión de la extensión:
$(Task.Extension.Version) - Invalidar la versión de tareas: activada (true)
- Tipo de invalidación: Reemplazar solo revisión (1.0.r)
- Visibilidad de la extensión: si la extensión todavía está en desarrollo, establezca el valor en privado. Para liberar la extensión al público, establezca el valor en público.
- Carpeta manifiestos raíz: apunta al directorio raíz que contiene el archivo de manifiesto. Por ejemplo,
Para copiar en archivos publicados, agregue la tarea Copiar archivos mediante las siguientes entradas:
- Contenido: todos los archivos que se van a copiar para publicarlos como un artefacto
- Carpeta de destino: la carpeta en la que se copian los archivos.
- Por ejemplo:
$(Build.ArtifactStagingDirectory)
- Por ejemplo:
Agregue Publicar artefactos de compilación para publicar los artefactos y usarlos en otros trabajos o canalizaciones. Use las siguientes entradas:
- Ruta de acceso para publicar: ruta de acceso a la carpeta que contiene los archivos que se están publicando.
- Por ejemplo:
$(Build.ArtifactStagingDirectory)
- Por ejemplo:
- Nombre del artefacto: nombre proporcionado al artefacto
- Ubicación de publicación de artefactos: elija Azure Pipelines para utilizar el artefacto en trabajos futuros.
- Ruta de acceso para publicar: ruta de acceso a la carpeta que contiene los archivos que se están publicando.
Fase 3: Descarga de artefactos de compilación y publicación de la extensión
Para instalar tfx-cli en el agente de compilación, agregue Use Node CLI for Azure DevOps (tfx-cli) (Uso de la CLI de Node para Azure DevOps [tfx-cli]).
Para descargar los artefactos en un nuevo trabajo, agregue la tarea Descargar artefactos de compilación mediante las siguientes entradas:
- Descargar artefactos generados por: si va a descargar el artefacto en un nuevo trabajo desde la misma canalización, seleccione Compilación actual. Si va a descargar en una nueva canalización, seleccione Compilación específica.
- Tipo de descarga: elija Artefacto específico para descargar todos los archivos que se publicaron.
- Nombre del artefacto: el nombre del artefacto publicado
- Directorio de destino: la carpeta donde se deben descargar los archivos.
Para obtener la tarea Publicar extensión , use las siguientes entradas:
- Conexión a: Visual Studio Marketplace
- Conexión de Visual Studio Marketplace: ServiceConnection
- Tipo de archivo de entrada: archivo VSIX
- Archivo VSIX:
/Publisher.*.vsix - Id. de publicador: identificador del publicador de Visual Studio Marketplace
- Id. de extensión: Id. de la extensión en el archivo
vss-extension.json - Nombre de la extensión: nombre de la extensión en el archivo
vss-extension.json - Visibilidad de la extensión: privada o pública
Opcional: Instalar y probar la extensión
Después de publicar la extensión, debe instalarse en organizaciones de Azure DevOps.
Instalación de la extensión en la organización
Instale la extensión compartida en algunos pasos:
Vaya a Configuración de la organización y seleccione Extensiones.
Busque la extensión en la sección Extensiones compartidas conmigo :
- Seleccione el vínculo de extensión.
- Seleccione Obtenerlo gratis o Instalar.
Compruebe que la extensión aparece en la lista Extensiones instaladas :
- Confirme que está disponible en la biblioteca de tareas de canalización.
Nota:
Si no ve la pestaña Extensiones , asegúrese de que está en el nivel de administración de la organización (https://dev.azure.com/{organization}/_admin) y no en el nivel de proyecto.
Pruebas integrales
Después de la instalación, realice pruebas completas:
Cree una canalización de prueba:
- Adición de la tarea personalizada a una nueva canalización
- Configuración de todos los parámetros de entrada
- Prueba con varias combinaciones de entrada
Validar la funcionalidad:
- Ejecución de la canalización y supervisión de la ejecución
- Comprobación de salidas y registros de tareas
- Comprobación del control de errores con entradas no válidas
Rendimiento de la prueba:
- Prueba con archivos de entrada grandes (si procede)
- Supervisión del uso de recursos
- Validación del comportamiento del tiempo de espera
Preguntas más frecuentes
P: ¿Cómo se controla la cancelación de tareas?
R: El agente de canalización envía SIGINT señales SIGTERM y a los procesos de tareas. Aunque la biblioteca de tareas no proporciona un control explícito de cancelación, la tarea puede implementar controladores de señal. Para obtener más información, consulte Cancelación de trabajos del agente.
P: ¿Cómo puedo quitar una tarea de mi organización?
R: No se admite la eliminación automática , ya que interrumpiría las canalizaciones existentes. En lugar de:
- En desuso de la tarea: marque la tarea como en desuso.
- Administración de versiones: aumentar la versión de la tarea
- Comunicación: notificar a los usuarios sobre la escala de tiempo de desuso
P: ¿Cómo puedo actualizar mi tarea a la versión de Node.js más reciente?
R: Actualice a la versión más reciente del nodo para mejorar el rendimiento y la seguridad. Para obtener instrucciones de migración, consulte Actualización de tareas a Node 20.
Compatibilidad con varias versiones de Node mediante la inclusión de varias secciones de ejecución en task.json:
"execution": {
"Node20_1": {
"target": "index.js"
},
"Node10": {
"target": "index.js"
}
}
Los agentes con Node 20 usan la versión preferida, mientras que los agentes anteriores vuelven al nodo 10.
Para actualizar las tareas:
Para asegurarse de que el código se comporta según lo previsto, pruebe las tareas en las distintas versiones del ejecutor de Node.
En la sección ejecución de la tarea, actualice de
NodeoNode10aNode16oNode20.Para admitir versiones anteriores del servidor, debe dejar el
Node/Node10destino. Es posible que las versiones anteriores de Azure DevOps Server no tengan incluida la versión más reciente del ejecutor de Node.Puede elegir compartir el punto de entrada definido en el destino o tener destinos optimizados para la versión de Node usada.
"execution": { "Node10": { "target": "bash10.js", "argumentFormat": "" }, "Node16": { "target": "bash16.js", "argumentFormat": "" }, "Node20_1": { "target": "bash20.js", "argumentFormat": "" } }
Importante
Si no agregas compatibilidad con el ejecutor de Node 20 a las tareas personalizadas, fallarán en los agentes instalados desde el feed de la versión de pipelines-agent-*.