Adición de una extensión de tarea de canalizaciones personalizadas
Azure DevOps Services | Azure DevOps Server 2022 | Azure DevOps Server 2019
Aprenda a instalar extensiones en su organización para tareas de compilación o versión personalizadas en Azure DevOps. Para obtener más información, consulte ¿Qué es Azure Pipelines?
Nota:
En este artículo se tratan las tareas del agente en extensiones basadas en agente. Para obtener más información sobre las tareas del servidor y las extensiones basadas en servidor, consulte la documentación de GitHub de tareas del servidor.
Requisitos previos
Para crear extensiones para Azure DevOps, necesita el siguiente software y herramientas.
Software o herramienta | Información |
---|---|
Organización de Azure DevOps | Cree una organización. |
Un editor de texto | Para muchos procedimientos, se usa Visual Studio Code, que proporciona compatibilidad con intellisense y depuración. Descargue la versión más reciente. |
Node.js | Descargue la versión más reciente. |
npmjs.com 4.0.2 o posterior | Compilador de TypeScript. Descargue la versión más reciente. |
tfx-cli | Empaquete la extensión con la CLI multiplataforma para Azure DevOps. mediante npm , un componente de Node.js mediante la ejecución npm i -g tfx-cli de . |
SDK de extensión de Azure DevOps | Instale el paquete azure-devops-extension-sdk. |
Un home directorio para el proyecto |
El home directorio de una extensión de tarea de compilación o versión debe ser similar al ejemplo siguiente después de completar los pasos de este artículo. |
|--- README.md
|--- images
|--- extension-icon.png
|--- buildandreleasetask // where your task scripts are placed
|--- vss-extension.json // extension's manifest
Importante
La máquina de desarrollo debe ejecutar la versión más reciente de Node para asegurarse de que el código escrito es compatible con el entorno de producción en el agente y la versión no preliminar más reciente de azure-pipelines-task-lib
. Actualice el archivo task.json según el siguiente comando:
"execution": {
"Node20_1": {
"target": "index.js"
}
}
1. Crear una tarea personalizada
Realice todas las partes de este procedimiento dentro de la buildandreleasetask
carpeta .
Nota:
En este tutorial de ejemplo se usa Windows con PowerShell. Lo hemos convertido en genérico para todas las plataformas, pero la sintaxis para obtener variables de entorno es diferente. Si usa un equipo Mac o Linux, reemplace las instancias de $env:<var>=<val>
por export <var>=<val>
.
Creación de scaffolding de tareas
Cree la estructura de carpetas para la tarea e instale las bibliotecas y dependencias necesarias.
Abra una ventana de comandos de PowerShell, vaya a la
buildandreleasetask
carpeta y ejecute el siguiente comando.npm init --yes
npm init
crea elpackage.json
archivo . Se ha agregado el--yes
parámetro para aceptar todas las opciones predeterminadasnpm init
.Sugerencia
El agente no instala automáticamente los módulos necesarios porque espera que la carpeta de tareas incluya los módulos de nodo. Para mitigar esto, copie en
node_modules
buildandreleasetask
. A medida que la tarea aumenta, es fácil superar el límite de tamaño (50 MB) de un archivo VSIX. Antes de copiar la carpeta del nodo, es posible que quiera ejecutarnpm install --production
onpm prune --production
, o bien puede escribir un script para compilar y empaquetar todo.Agregue
azure-pipelines-task-lib
a la biblioteca.npm install azure-pipelines-task-lib --save
Asegúrese de que los términos de TypeScript están instalados para las dependencias externas.
npm install @types/node --save-dev npm install @types/q --save-dev
Cree un
.gitignore
archivo y agregue node_modules a él. El proceso de compilación debe realizar unnpm install
y untypings install
para que se compilen node_modules cada vez y no sea necesario que se protejan.echo node_modules > .gitignore
Instale Mocha como dependencia de desarrollo.
npm install mocha --save-dev -g npm install sync-request --save-dev npm install @types/mocha --save-dev
Elija TypeScript versión 2.3.4 o 4.6.3.
npm install typescript@4.6.3 -g --save-dev
Nota:
Asegúrese de que TypeScript está instalado globalmente con npm en el entorno de desarrollo, por lo que el
tsc
comando está disponible. Si omite este paso, TypeScript versión 2.3.4 se usa de forma predeterminada y todavía tiene que instalar el paquete globalmente para que eltsc
comando esté disponible.Cree
tsconfig.json
opciones del compilador. Este archivo garantiza que los archivos TypeScript se compilen en archivos JavaScript.tsc --init --target es2022
Crear la tarea
Ahora que se ha completado el scaffolding, podemos crear nuestra tarea personalizada.
Cree un
task.json
archivo en labuildandreleasetask
carpeta . Eltask.json
archivo describe la tarea de compilación o versión y es lo que usa el sistema de compilación o versión para representar las opciones de configuración al usuario y saber qué scripts se van a ejecutar en tiempo de compilación o lanzamiento.Copie el código siguiente y reemplace por la
{{placeholders}}
información de la tarea. El marcador de posición más importante estaskguid
y debe ser único.{ "$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" } } }
Cree un
index.ts
archivo con el código siguiente como referencia. Este código se ejecuta cuando se llama a 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();
Escriba "tsc" de la
buildandreleasetask
carpeta para compilar unindex.js
archivo desdeindex.ts
.
componentes de task.json
Consulte las descripciones siguientes de algunos de los componentes del task.json
archivo.
Propiedad | Descripción |
---|---|
id |
Un GUID único para la tarea. |
name |
Nombre sin espacios. |
friendlyName |
Nombre descriptivo (espacios permitidos). |
description |
Descripción detallada de lo que hace la tarea. |
author |
Cadena corta que describe la entidad que desarrolla la tarea de compilación o versión, por ejemplo: "Microsoft Corporation". |
instanceNameFormat |
Cómo se muestra la tarea en la lista de pasos de compilación o versión. Puede usar valores de variable mediante $(variablename). |
groups |
Describe la agrupación lógica de propiedades de tarea en la interfaz de usuario. |
inputs |
Entradas que se usarán cuando se ejecute la tarea de compilación o versión. Esta tarea espera una entrada con el nombre samplestring. |
execution |
Opciones de ejecución para esta tarea, incluidos los scripts. |
restrictions |
Las restricciones que se aplican a la tarea sobre los comandos de GitHub Codespaces pueden llamar a y la tarea variables se puede establecer. Se recomienda especificar el modo de restricción para las nuevas tareas. |
Nota:
Cree un id
con el siguiente comando en PowerShell:
(New-Guid).Guid
Para obtener más información, consulte la referencia de la tarea Compilación y versión.
Ejecución de la tarea
Ejecute la tarea con node index.js
desde PowerShell.
En el ejemplo siguiente, se produce un error en la tarea porque no se proporcionaron entradas (samplestring
es una entrada necesaria).
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
Como corrección, podemos establecer la samplestring
entrada y volver a ejecutar la tarea.
$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
Esta vez, la tarea se realizó correctamente porque samplestring
se proporcionó y se ha generado correctamente "Hello Human!"
Sugerencia
Para obtener información sobre varios ejecutores de tareas y cómo incluir la versión más reciente del nodo en la task.json, consulte Guía de actualización del ejecutor de nodos para autores de tareas de Azure Pipelines.
2. Prueba unitaria de los scripts de tareas
Realice pruebas unitarias para probar rápidamente el script de tareas y no las herramientas externas a las que llama. Pruebe todos los aspectos de las rutas de acceso de éxito y error.
Instale las herramientas de prueba. Usamos Mocha como controlador de prueba en este procedimiento.
npm install mocha --save-dev -g npm install sync-request --save-dev npm install @types/mocha --save-dev
Cree una
tests
carpeta que contenga un_suite.ts
archivo con el siguiente contenido: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 }); });
Sugerencia
La carpeta de prueba debe encontrarse en la carpeta buildandreleasetask. Si recibe un error de solicitud de sincronización, puede solucionarlo agregando sync-request a la carpeta buildandreleasetask con el comando
npm i --save-dev sync-request
.Cree un
success.ts
archivo en el directorio de prueba con el siguiente contenido. Esta creación de archivos simula la ejecución de la tarea y simula todas las llamadas a métodos externos.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();
La prueba correcta valida que, con las entradas adecuadas, se realiza correctamente sin errores ni advertencias y devuelve la salida correcta.
Agregue la siguiente prueba de éxito de ejemplo al
_suite.ts
archivo para ejecutar el ejecutor ficticio de la tarea.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 }); });
Cree un
failure.ts
archivo en el directorio de prueba como ejecutor ficticio de tareas con el siguiente contenido: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();
La prueba de error valida que cuando la herramienta recibe una entrada incorrecta o incompleta, se produce un error de la manera esperada con una salida útil.
Agregue el código siguiente al
_suite.ts
archivo para ejecutar el ejecutor ficticio de la tarea.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(); });
Ejecute las pruebas.
tsc mocha tests/_suite.js
Ambas pruebas deben superarse. Si desea ejecutar las pruebas con una salida más detallada (lo que vería en la consola de compilación), establezca la variable de entorno:
TASK_TEST_TRACE=1
.$env:TASK_TEST_TRACE=1
3. Crear el archivo de manifiesto de extensión
El manifiesto de extensión contiene toda la información sobre la extensión. Incluye vínculos a los archivos, incluidas las carpetas de tareas y las carpetas de imágenes. Asegúrese de crear una carpeta images con extension-icon.png. El ejemplo siguiente es un manifiesto de extensión que contiene la tarea de compilación o versión.
Copie el siguiente código .json y guárdelo como vss-extension.json
archivo en el home
directorio.
No cree este archivo en la carpeta 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"
}
}
]
}
Nota:
Cambie el publicador por el nombre del publicador. Para obtener más información, consulte Creación de un publicador.
Contribuciones
Propiedad | Descripción |
---|---|
id |
Identificador de la contribución. Debe ser único dentro de la extensión. No es necesario que coincida con el nombre de la tarea de compilación o versión. Normalmente, el nombre de la tarea de compilación o versión está en el identificador de la contribución. |
type |
Tipo de contribución. Debe ser ms.vss-distributed-task.task. |
targets |
Contribuciones "dirigidas" por esta contribución. Debe ser ms.vss-distributed-task.tasks. |
properties.name |
Nombre de la tarea. Este nombre debe coincidir con el nombre de carpeta de la tarea de canalización de compilación o versión independiente correspondiente. |
Archivos
Propiedad | Descripción |
---|---|
path |
Ruta de acceso del archivo o carpeta en relación con el home directorio. |
Nota:
Para obtener más información sobre el archivo de manifiesto de extensión, como sus propiedades y lo que hacen, vea la referencia del manifiesto de extensión.
4. Empaquetar la extensión
Empaquete todos los archivos juntos para obtener la extensión en Visual Studio Marketplace. Todas las extensiones se empaquetan como archivos .vsix compatibles con VSIX 2.0. Microsoft proporciona una interfaz de línea de comandos (CLI) multiplataforma para empaquetar la extensión.
Una vez que tenga tfx-cli, vaya al directorio principal de la extensión y ejecute el siguiente comando:
tfx extension create --manifest-globs vss-extension.json
Nota:
Se debe incrementar la versión de una extensión o integración en cada actualización.
Al actualizar una extensión existente, actualice la versión en el manifiesto o pase el modificador de --rev-version
línea de comandos. Esto incrementa el número de versión de revisión de la extensión y guarda la nueva versión en el manifiesto.
Debe revisar la versión de la tarea y la versión de la extensión para que se produzca una actualización. tfx extension create --manifest-globs vss-extension.json --rev-version
solo actualiza la versión de la extensión y no la versión de la tarea. Para obtener más información, consulte Tarea de compilación en GitHub.
Una vez que la extensión empaquetada esté en un archivo .vsix, estará listo para publicar la extensión en Marketplace.
5. Publicar la extensión
Para publicar la extensión, primero debe crear el publicador, cargar la extensión y, por último , compartirla.
Creación del publicador
Todas las extensiones, incluidas las extensiones de Microsoft, se identifican como proporcionadas por un publicador. Si aún no es miembro de un publicador existente, cree uno.
- Inicie sesión en el Portal de publicación de Visual Studio Marketplace.
- Si aún no es miembro de un publicador existente, se le pedirá que cree un publicador. Si no se le pide que cree un publicador, desplácese hacia abajo hasta la parte inferior de la página y seleccione Publicar extensiones en Sitios relacionados.
- Especifique un identificador para el publicador, por ejemplo:
mycompany-myteam
.- Este identificador se usa como valor para el atributo en el
publisher
archivo de manifiesto de las extensiones.
- Este identificador se usa como valor para el atributo en el
- Especifique un nombre para mostrar para el publicador, por ejemplo:
My Team
.
- Especifique un identificador para el publicador, por ejemplo:
- Revise el Contrato de publicador de Marketplace y seleccione Crear.
Se define el publicador. En una versión futura, puede conceder permisos para ver y administrar las extensiones del publicador. Es más fácil y seguro publicar extensiones en un publicador común, sin necesidad de compartir un conjunto de credenciales entre los usuarios.
Carga de la extensión
Busque el botón Cargar nueva extensión , vaya al archivo .vsix empaquetado y seleccione Cargar.
También puede cargar la extensión a través de la interfaz de línea de comandos (CLI) mediante el
tfx extension publish
comando en lugar detfx extension create
empaquetar y publicar la extensión en un paso. Opcionalmente, puede usar--share-with
para compartir la extensión con una o varias cuentas después de publicarla.tfx extension publish --manifest-globs your-manifest.json --share-with yourOrganization
Cree un token de acceso personal (PAT).
- Seleccione el ámbito "Marketplace (publicación)". Este ámbito limita el token para que solo pueda publicar extensiones en Marketplace.
Compartir la extensión
Ahora que cargó la extensión, está en Marketplace, pero nadie puede verlo. Compártelo con su organización para poder instalarlo y probarlo.
Seleccione la extensión con el botón derecho y seleccione Compartir y escriba la información de la organización. También puede compartirlo con otras cuentas a las que quiera tener acceso a la extensión.
Importante
Los publicadores deben comprobarse para compartir extensiones públicamente. Para obtener más información, consulte Package/Publish/Install.
Ahora que la extensión se comparte en Marketplace, cualquier persona que quiera usarla debe instalarla.
6. Creación de una canalización de compilación y versión para publicar la extensión en Marketplace
Cree una canalización de compilación y versión en Azure DevOps para ayudar a mantener la tarea personalizada en Marketplace.
Requisitos previos
Software o herramienta
Información
Proyecto de Azure DevOps
Extensión de Azure DevOps Extension Tasks
Instale de forma gratuita tareas de extensión de Azure DevOps en su organización.
Grupo de variables de biblioteca de canalización
Cree un grupo de variables de biblioteca de canalización para contener las variables usadas por la canalización. Para obtener más información, vea Agregar y usar grupos de variables. Puede crear grupos de variables desde la pestaña Biblioteca de Azure DevOps o a través de la CLI. Use las variables de este grupo en la canalización. Además, declare las siguientes variables en el grupo de variables:
publisherId
: identificador del publicador de MarketplaceextensionId
: id. de la extensión, como se declara en el archivo vss-extension.json.extensionName
: nombre de la extensión, como se declara en el archivo vss-extension.jsonartifactName
: nombre del artefacto que se va a crear para el archivo VSIX.
Conexión de servicio
Cree una nueva conexión de servicio de Marketplace y conceda permisos de acceso para todas las canalizaciones.
Canalización YAML
Use el ejemplo siguiente para crear una nueva canalización con YAML. Para más información, consulte Creación de la primera canalización y el esquema 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'
Para obtener más información, consulte Especificación de eventos que desencadenan canalizaciones.
Nota:
Cada trabajo usa un nuevo agente de usuario y requiere que se instalen dependencias.
Etapas de canalización
La siguiente sección le ayuda a comprender cómo funcionan las fases de canalización.
Fase 1: Ejecución y publicación de pruebas unitarias
Esta fase ejecuta pruebas unitarias y publica resultados de pruebas en Azure DevOps.
Para ejecutar pruebas unitarias, agregue un script personalizado al archivo package.json como en el ejemplo siguiente.
"scripts": {
"testScript": "mocha ./TestFile --reporter xunit --reporter-option output=ResultsFile.xml"
},
Agregue "Uso de la CLI de Node para Azure DevOps (tfx-cli)" para instalar tfx-cli en el agente de compilación.
Agregue la tarea "npm" con el comando "install" y dirija la carpeta con el archivo package.json.
Agregue la tarea "Bash" para compilar TypeScript en JavaScript.
Agregue la tarea "npm" con el comando "custom", seleccione la carpeta que contiene las pruebas unitarias y escriba
testScript
como comando. Use las siguientes entradas:- Comando: personalizado
- Carpeta de trabajo que contiene package.json: /TestsDirectory
- Comandos y argumentos:
testScript
Agregue la tarea "Publicar resultados de pruebas". Si usa el periodista de Mocha XUnit, asegúrese de que el formato de resultado es "JUnit" y no "XUnit". Establezca la carpeta de búsqueda en el directorio raíz. Use las siguientes entradas:
- Formato de resultado de la prueba: JUnit
- Archivos de resultados de pruebas: **/ResultsFile.xml
- Carpeta de búsqueda:
$(System.DefaultWorkingDirectory)
Una vez publicados los resultados de la prueba, la salida de la pestaña pruebas debe tener un aspecto similar al del ejemplo siguiente.
Fase 2: Empaquetar la extensión y publicar artefactos de compilación
Agregue "Uso de la CLI de Node para Azure DevOps (tfx-cli)" para instalar tfx-cli en el agente de compilación.
Agregue la tarea "npm" con el comando "install" y dirija la carpeta con el archivo package.json.
Agregue la tarea "Bash" para compilar TypeScript en JavaScript.
Agregue la tarea "Versión de extensión de consulta" para consultar la versión de extensión existente. Use 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: identificador de la extensión en el archivo vss-extension.json
- Aumento de la versión: Revisión
- Variable de salida: Task.Extension.Version
Agregue la tarea "Extensión de paquete" para empaquetar las extensiones basadas en json del manifiesto. Use 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.
- Archivos de manifiesto: vss-extension.json
- Id. de publicador: identificador del publicador de Visual Studio Marketplace
- Id. de extensión: identificador 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.
Agregue la tarea "Copiar archivos" para copiar archivos publicados. Use 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)
Agregue "Publicar artefactos de compilación" para publicar los artefactos para 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)
- Nombre del artefacto: nombre proporcionado al artefacto
- Ubicación de publicación de artefactos: elija "Azure Pipelines" para usar 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
Agregue "Uso de la CLI de Node para Azure DevOps (tfx-cli)" para instalar tfx-cli en el agente de compilación.
Agregue la tarea "Descargar artefactos de compilación" para descargar los artefactos en un nuevo trabajo. Use las siguientes entradas:
- Descargar artefactos generados por: si va a descargar el artefacto en un nuevo trabajo de 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 publicados.
- Nombre del artefacto: nombre del artefacto publicado.
- Directorio de destino: la carpeta donde se deben descargar los archivos.
La última tarea que necesita es 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: identificador 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
Instale una extensión que se comparta con usted en unos pocos pasos:
- En el panel de control de la organización (
https://dev.azure.com/{organization}/_admin
), vaya a la página de administración de la colección de proyectos. - En la pestaña Extensiones , busque la extensión en el grupo "Extensiones compartidas conmigo" y seleccione el vínculo de extensión.
- Instale la extensión.
Si no puede ver la pestaña Extensiones , asegúrese de que está en el panel de control (la página de administración en el nivel de colección de proyectos, https://dev.azure.com/{organization}/_admin
) y no en la página de administración de un proyecto.
Si no ve la pestaña Extensiones , las extensiones no están habilitadas para su organización. Puede obtener acceso anticipado a la característica de extensiones mediante la unión al Programa de partners de Visual Studio.
Para empaquetar y publicar extensiones de Azure DevOps en Visual Studio Marketplace, puede descargar Tareas de extensión de Azure DevOps.
Preguntas más frecuentes
Consulte las siguientes preguntas más frecuentes sobre cómo agregar tareas de compilación o versión personalizadas en extensiones para Azure DevOps.
P: ¿Cómo puedo restringir el uso de comandos de Azure Pipelines para la tarea?
Puede restringir el uso y las variables de comandos de Azure Pipelines, que se establecen por tarea. Esta acción podría ser útil para evitar el acceso sin restricciones a variables o comandos vso para scripts personalizados que se ejecutan tareas. Se recomienda configurarlo para nuevas tareas. Para aplicarlo, es posible que tenga que agregar la siguiente instrucción al archivo task.json:
"restrictions": {
"commands": {
"mode": "restricted"
},
"settableVariables": {
"allowed": ["variable1", "test*"]
}
}
Si restricted
se especifica el valor para mode
, solo puede ejecutar los siguientes comandos mediante la tarea:
logdetail
logissue
complete
setprogress
setsecret
setvariable
debug
settaskvariable
prependpath
publish
Las settableVariables
restricciones permiten pasar una lista de variables permitidas, que se establecen mediante setvariable
comandos o prependpath
. También permite expresiones regulares básicas. Por ejemplo, si la lista de permitidos era: ['abc', 'test*']
, estableciendo abc
, test
o test1
como variables con cualquier valor o pendientes en la ruta de acceso se realizaría correctamente, pero si intenta establecer un proxy de variable, advertiría. La lista vacía significa que ninguna variable cambia por tarea.
Si se omite la settableVariables
clave o commands
, no se aplica la restricción pertinente.
La característica de restricción está disponible en la versión del agente 2.182.1 .
P: ¿Cómo se controla la señal de cancelación por una tarea?
R: El agente de canalización envía SIGINT
señales al SIGTERM
proceso secundario correspondiente. No hay ningún medio explícito en la biblioteca de tareas que se va a procesar. Para obtener más información, consulte Cancelación de trabajos del agente.
P: ¿Cómo puedo quitar la tarea de la colección de proyectos?
R: No se admite la eliminación automática de tareas. La eliminación automática no es segura y interrumpe las canalizaciones existentes que ya usan estas tareas. Sin embargo, puede marcar las tareas como en desuso. Para ello, aumente la versión de la tarea y marque la tarea como en desuso.
P: ¿Cómo puedo actualizar mi tarea personalizada al nodo más reciente?
R: Se recomienda actualizar a la versión más reciente del nodo. Para obtener información de ejemplo, consulte Actualización de tareas a Node 20.
A medida que los agentes hospedados de Microsoft y varias versiones de Azure DevOps Server tienen diferentes ciclos de vida, puede haber diferentes versiones del ejecutor de Node instaladas en función de dónde se ejecute una tarea. Para poder ejecutar la misma tarea en agentes con diferentes versiones del ejecutor de Node, el archivo task.json puede contener varias secciones de ejecución. En el ejemplo siguiente, los agentes de Azure Pipeline que incluyen el ejecutor de Node 20 lo elegirán de forma predeterminada y los que no volverán a la implementación del nodo 10.
"execution": {
"Node10": {
"target": "bash.js",
"argumentFormat": ""
},
"Node20_1": {
"target": "bash.js",
"argumentFormat": ""
}
Para actualizar las tareas:
Pruebe las tareas en las distintas versiones del ejecutor de Node para asegurarse de que el código se comporta según lo previsto.
En la sección ejecución de la tarea, actualice de
Node
oNode10
aNode16
oNode20
.Para admitir versiones anteriores del servidor, debe dejar el
Node
/Node10
destino. 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 se agrega compatibilidad con el ejecutor de Node 20 en las tareas personalizadas, se producirá un error en las tareas en los agentes instalados desde la pipelines-agent-*
fuente de versión.