Compartir a través de


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-clide .
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

  1. Cree la estructura de carpetas para la tarea e instale las bibliotecas y dependencias necesarias.

  2. Abra una ventana de comandos de PowerShell, vaya a la buildandreleasetask carpeta y ejecute el siguiente comando.

    npm init --yes
    

    npm init crea el package.json archivo . Se ha agregado el --yes parámetro para aceptar todas las opciones predeterminadas npm 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 ejecutar npm install --production o npm prune --production, o bien puede escribir un script para compilar y empaquetar todo.

  3. Agregue azure-pipelines-task-lib a la biblioteca.

    npm install azure-pipelines-task-lib --save
    
  4. 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
    
  5. Cree un .gitignore archivo y agregue node_modules a él. El proceso de compilación debe realizar un npm install y un typings install para que se compilen node_modules cada vez y no sea necesario que se protejan.

    echo node_modules > .gitignore
    
  6. Instale Mocha como dependencia de desarrollo.

    npm install mocha --save-dev -g
    npm install sync-request --save-dev
    npm install @types/mocha --save-dev
    
  7. 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 el tsc comando esté disponible.

  8. 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.

  1. Cree un task.json archivo en la buildandreleasetask carpeta . El task.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.

  2. Copie el código siguiente y reemplace por la {{placeholders}} información de la tarea. El marcador de posición más importante es taskguidy 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"
         }
     }
     }
    
  3. 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();
    
  4. Escriba "tsc" de la buildandreleasetask carpeta para compilar un index.js archivo desde index.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.

  1. 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
    
  2. 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.

  3. 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.

  4. 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
        });
    });
    
  5. 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.

  6. 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();
    });
    
  7. 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.

  1. Inicie sesión en el Portal de publicación de Visual Studio Marketplace.
  2. 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.
    • Especifique un nombre para mostrar para el publicador, por ejemplo: My Team.
  3. 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.

  1. 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 de tfx 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
    
  2. 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 Marketplace
  • extensionId: 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.json
  • artifactName: 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"
},
  1. Agregue "Uso de la CLI de Node para Azure DevOps (tfx-cli)" para instalar tfx-cli en el agente de compilación.

  2. Agregue la tarea "npm" con el comando "install" y dirija la carpeta con el archivo package.json.

  3. Agregue la tarea "Bash" para compilar TypeScript en JavaScript.

  4. 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
  5. 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.

    Captura de pantalla del ejemplo de resultado de la prueba.

Fase 2: Empaquetar la extensión y publicar artefactos de compilación

  1. Agregue "Uso de la CLI de Node para Azure DevOps (tfx-cli)" para instalar tfx-cli en el agente de compilación.

  2. Agregue la tarea "npm" con el comando "install" y dirija la carpeta con el archivo package.json.

  3. Agregue la tarea "Bash" para compilar TypeScript en JavaScript.

  4. 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
  5. 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.
  6. 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)
  7. 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.

Fase 3: Descarga de artefactos de compilación y publicación de la extensión

  1. Agregue "Uso de la CLI de Node para Azure DevOps (tfx-cli)" para instalar tfx-cli en el agente de compilación.

  2. 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.
  3. 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:

  1. 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.
  2. En la pestaña Extensiones , busque la extensión en el grupo "Extensiones compartidas conmigo" y seleccione el vínculo de extensión.
  3. 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, testo 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 o Node10 a Node16 o Node20.

  • 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.