Ajouter une extension de tâche de pipelines personnalisée

Azure DevOps Services | Azure DevOps Server 2022 | Azure DevOps Server 2019

Découvrez comment installer des extensions à votre organisation pour des tâches de génération ou de mise en production personnalisées dans Azure DevOps. Pour plus d’informations, consultez Qu’est-ce qu’Azure Pipelines ?

Remarque

Cet article traite des tâches d’agent dans les extensions basées sur l’agent. Pour plus d’informations sur les tâches de serveur et les extensions basées sur le serveur, consultez la documentation GitHub de la tâche serveur.

Prérequis

Pour créer des extensions pour Azure DevOps, vous avez besoin des logiciels et outils suivants.

Logiciel/outil Information
Organisation Azure DevOps Créez une organisation.
Un éditeur de texte Pour de nombreuses procédures, nous utilisons Visual Studio Code, qui fournit une prise en charge intellisense et de débogage. Téléchargez la version la plus récente.
Node.JS Téléchargez la version la plus récente.
npmjs.com 4.0.2 ou version ultérieure Compilateur TypeScript. Téléchargez la version la plus récente.
tfx-cli Empaqueter votre extension avec l’interface CLI multiplateforme pour Azure DevOps. using npm, un composant de Node.js, en exécutant npm i -g tfx-cli.
Kit de développement logiciel (SDK) d’extension Azure DevOps Installez le package azure-devops-extension-sdk.
Répertoire home de votre projet Le home répertoire d’une extension de tâche de génération ou de mise en production doit ressembler à l’exemple suivant après avoir effectué les étapes décrites dans cet article.
|--- README.md    
|--- images                        
    |--- extension-icon.png  
|--- buildandreleasetask            // where your task scripts are placed
|--- vss-extension.json             // extension's manifest

Important

La machine de développement doit exécuter la dernière version de Node pour s’assurer que le code écrit est compatible avec l’environnement de production sur l’agent et la dernière version non préliminaire de azure-pipelines-task-lib. Mettez à jour votre fichier task.json conformément à la commande suivante :

"execution": {
   "Node20_1": {
     "target": "index.js"
   }
 }

1. Créer une tâche personnalisée

Effectuez toutes les parties de cette procédure dans le buildandreleasetask dossier.

Remarque

Cet exemple de procédure pas à pas utilise Windows avec PowerShell. Nous l’avons rendu générique pour toutes les plateformes, mais la syntaxe pour obtenir des variables d’environnement est différente. Si vous utilisez un Mac ou Linux, remplacez toutes les instances de $env:<var>=<val> export <var>=<val>.

Créer une structure de tâche

  1. Créez la structure de dossiers pour la tâche et installez les bibliothèques et dépendances requises.

  2. Ouvrez une fenêtre de commande PowerShell, accédez à votre buildandreleasetask dossier et exécutez la commande suivante.

    npm init --yes
    

    npm init crée le package.json fichier. Nous avons ajouté le --yes paramètre pour accepter toutes les options par défaut npm init .

    Conseil

    L’agent n’installe pas automatiquement les modules requis, car il s’attend à ce que votre dossier de tâches inclue les modules de nœud. Pour atténuer ce problème, copiez la valeur node_modules vers buildandreleasetask. À mesure que votre tâche augmente, il est facile de dépasser la limite de taille (50 Mo) d’un fichier VSIX. Avant de copier le dossier du nœud, vous souhaiterez peut-être exécuter npm install --production ou, ou npm prune --productionvous pouvez écrire un script pour générer et empaquetez tout.

  3. Ajouter azure-pipelines-task-lib à votre bibliothèque.

    npm install azure-pipelines-task-lib --save
    
  4. Vérifiez que les frappes TypeScript sont installées pour les dépendances externes.

    npm install @types/node --save-dev
    npm install @types/q --save-dev
    
  5. Créez un .gitignore fichier et ajoutez-y node_modules. Votre processus de génération doit effectuer une npm install opération et un typings install pour que node_modules soient générées chaque fois et n’ont pas besoin d’être archivés.

    echo node_modules > .gitignore
    
  6. Installez Mocha comme dépendance de développement.

    npm install mocha --save-dev -g
    npm install sync-request --save-dev
    npm install @types/mocha --save-dev
    
  7. Choisissez TypeScript version 2.3.4 ou 4.6.3.

    npm install typescript@4.6.3 -g --save-dev
    

    Remarque

    Assurez-vous que TypeScript est installé globalement avec npm dans votre environnement de développement. La tsc commande est donc disponible. Si vous ignorez cette étape, TypeScript version 2.3.4 est utilisée par défaut et vous devez toujours installer le package globalement pour que la tsc commande soit disponible.

  8. Créez des tsconfig.json options de compilateur. Ce fichier garantit que vos fichiers TypeScript sont compilés en fichiers JavaScript.

    tsc --init --target es2022
    

Créer une tâche

Maintenant que la structure est terminée, nous pouvons créer notre tâche personnalisée.

  1. Créez un task.json fichier dans le buildandreleasetask dossier. Le task.json fichier décrit la tâche de génération/mise en production et correspond à ce que le système de génération/mise en production utilise pour afficher les options de configuration à l’utilisateur et pour connaître les scripts à exécuter au moment de la génération/mise en production.

  2. Copiez le code suivant et remplacez les {{placeholders}} informations de votre tâche. L’espace réservé le plus important est le taskguid, et il doit être unique.

    {
     "$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. Créez un index.ts fichier à l’aide du code suivant comme référence. Ce code s’exécute lorsque la tâche est appelée.

    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. Entrez « tsc » à partir du buildandreleasetask dossier pour compiler un index.js fichier à partir de index.ts.

composants task.json

Consultez les descriptions suivantes de certains composants du task.json fichier.

Propriété Description
id GUID unique pour votre tâche.
name Nom sans espace.
friendlyName Nom descriptif (espaces autorisés).
description Description détaillée de ce que fait votre tâche.
author Chaîne courte décrivant l’entité qui développe la tâche de génération ou de mise en production, par exemple : « Microsoft Corporation ».
instanceNameFormat Comment la tâche s’affiche dans la liste d’étapes de génération/mise en production. Vous pouvez utiliser des valeurs de variable à l’aide de $(nom_variable).
groups Décrit le regroupement logique des propriétés de tâche dans l’interface utilisateur.
inputs Entrées à utiliser lorsque votre tâche de génération ou de mise en production s’exécute. Cette tâche attend une entrée avec l’exemple de chaîne de nom.
execution Options d’exécution pour cette tâche, y compris les scripts.
restrictions Les restrictions appliquées à la tâche concernant les commandes GitHub Codespaces peuvent appeler et les variables peuvent être définies. Nous vous recommandons de spécifier le mode de restriction pour les nouvelles tâches.

Remarque

Créez une id commande avec la commande suivante dans PowerShell :

(New-Guid).Guid

Pour plus d’informations, consultez la référence de tâche build/mise en production.

Exécuter la tâche

Exécutez la tâche à node index.js partir de PowerShell.

Dans l’exemple suivant, la tâche échoue, car les entrées n’ont pas été fournies (samplestring est une entrée obligatoire).

 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

En guise de correctif, nous pouvons définir l’entrée samplestring et réexécuter la tâche.

$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

Cette fois, la tâche a réussi car samplestring elle a été fournie et elle a correctement généré « Hello Human ! »

Conseil

Pour plus d’informations sur différents exécuteurs de tâches et sur la façon d’inclure la dernière version du nœud dans le task.json, consultez les instructions de mise à jour de l’exécuteur de nœuds pour les auteurs de tâches Azure Pipelines.

2. Test unitaire de vos scripts de tâche

Effectuez des tests unitaires pour tester rapidement le script de tâche, et non les outils externes qu’il appelle. Testez tous les aspects des chemins de réussite et d’échec.

  1. Installez les outils de test. Nous utilisons Mocha comme pilote de test dans cette procédure.

    npm install mocha --save-dev -g
    npm install sync-request --save-dev
    npm install @types/mocha --save-dev
    
  2. Créez un tests dossier contenant un _suite.ts fichier avec le contenu suivant :

    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
        });    
    });
    

    Conseil

    Votre dossier de test doit se trouver dans le dossier buildandreleasetask. Si vous obtenez une erreur de requête de synchronisation, vous pouvez la contourner en ajoutant la requête de synchronisation au dossier buildandreleasetask avec la commande npm i --save-dev sync-request.

  3. Créez un success.ts fichier dans votre répertoire de test avec le contenu suivant. Cette création de fichier simule l’exécution de la tâche et simule tous les appels à des méthodes externes.

    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();
    

    Le test de réussite valide qu’avec les entrées appropriées, il réussit sans erreurs ni avertissements et retourne la sortie correcte.

  4. Ajoutez l’exemple de test de réussite suivant à votre _suite.ts fichier pour exécuter l’exécuteur fictif de tâche.

        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. Créez un failure.ts fichier dans votre répertoire de test en tant qu’exécuteur fictif de tâche avec le contenu suivant :

    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();
    

    Le test d’échec valide que lorsque l’outil obtient une entrée incorrecte ou incomplète, il échoue de la manière attendue avec une sortie utile.

  6. Ajoutez le code suivant à votre _suite.ts fichier pour exécuter l’exécuteur fictif de tâche.

    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. Exécutez les tests.

    tsc
    mocha tests/_suite.js
    

    Les deux tests doivent réussir. Si vous souhaitez exécuter les tests avec une sortie plus détaillée (ce que vous verrez dans la console de build), définissez la variable d’environnement : TASK_TEST_TRACE=1.

    $env:TASK_TEST_TRACE=1
    

3. Créer le fichier manifeste d’extension

Le manifeste d’extension contient toutes les informations relatives à votre extension. Il inclut des liens vers vos fichiers, y compris vos dossiers de tâches et dossiers d’images. Vérifiez que vous avez créé un dossier d’images avec extension-icon.png. L’exemple suivant est un manifeste d’extension qui contient la tâche de génération ou de mise en production.

Copiez le code .json suivant et enregistrez-le sous forme vss-extension.json de fichier dans votre home répertoire.

Ne créez pas ce fichier dans le dossier 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"
            }
        }
    ]
}

Remarque

Remplacez l’éditeur par le nom de votre éditeur. Pour plus d’informations, consultez Créer un éditeur.

Contributions

Propriété Description
id Identificateur de la contribution. Doit être unique dans l’extension. Ne doit pas correspondre au nom de la tâche de génération ou de mise en production. En règle générale, le nom de la tâche de génération ou de mise en production se trouve dans l’ID de la contribution.
type Type de contribution. Doit être ms.vss-distributed-task.task.
targets Contributions « ciblées » par cette contribution. Doit être ms.vss-distributed-task.tasks.
properties.name Nom de la tâche. Ce nom doit correspondre au nom du dossier de la tâche de génération autonome ou de pipeline de mise en production correspondante.

Fichiers

Propriété Description
path Chemin d’accès du fichier ou du dossier par rapport au home répertoire.

Remarque

Pour plus d’informations sur le fichier manifeste d’extension, tels que ses propriétés et ce qu’ils font, consultez la référence du manifeste d’extension.

4. Empaqueter votre extension

Empaqueter tous vos fichiers ensemble pour obtenir votre extension dans Visual Studio Marketplace. Toutes les extensions sont empaquetées en tant que fichiers .vsix compatibles VSIX 2.0. Microsoft fournit une interface de ligne de commande multiplateforme (CLI) pour empaqueter votre extension.

Une fois que vous disposez de tfx-cli, accédez au répertoire de base de votre extension, puis exécutez la commande suivante :

tfx extension create --manifest-globs vss-extension.json

Remarque

Une version d’extension ou d’intégration doit être incrémentée sur chaque mise à jour. Lorsque vous mettez à jour une extension existante, mettez à jour la version dans le manifeste ou passez le commutateur de --rev-version ligne de commande. Cela incrémente le numéro de version de correctif de votre extension et enregistre la nouvelle version dans votre manifeste. Vous devez révérendr la version de la tâche et la version d’extension pour qu’une mise à jour se produise. tfx extension create --manifest-globs vss-extension.json --rev-version met uniquement à jour la version de l’extension et non la version de la tâche. Pour plus d’informations, consultez La tâche de génération dans GitHub.

Une fois que votre extension empaquetée se trouve dans un fichier .vsix, vous êtes prêt à publier votre extension sur la Place de marché.

5. Publier votre extension

Pour publier votre extension, vous créez d’abord votre éditeur, puis chargez votre extension, puis partagez-la.

Créer votre éditeur

Toutes les extensions, y compris les extensions de Microsoft, sont identifiées comme étant fournies par un éditeur. Si vous n’êtes pas déjà membre d’un éditeur existant, vous en créez un.

  1. Connectez-vous au portail de publication visual Studio Marketplace.
  2. Si vous n’êtes pas déjà membre d’un éditeur existant, vous êtes invité à créer un éditeur. Si vous n’êtes pas invité à créer un éditeur, faites défiler vers le bas de la page et sélectionnez Publier des extensions sous Sites connexes.
    • Spécifiez un identificateur pour votre éditeur, par exemple : mycompany-myteam.
      • Cet identificateur est utilisé comme valeur de l’attribut dans le publisher fichier manifeste de vos extensions.
    • Spécifiez un nom complet pour votre éditeur, par exemple : My Team.
  3. Passez en revue le Contrat d’éditeur de la Place de marché, puis sélectionnez Créer.

Votre éditeur est défini. Dans une version ultérieure, vous pouvez accorder des autorisations pour afficher et gérer les extensions de votre éditeur. Il est plus facile et plus sécurisé de publier des extensions sous un éditeur commun, sans avoir à partager un ensemble d’informations d’identification entre les utilisateurs.

Charger votre extension

Recherchez le bouton Charger une nouvelle extension , accédez à votre fichier .vsix empaqueté, puis sélectionnez Charger.

  1. Vous pouvez également charger votre extension via l’interface de ligne de commande (CLI) à l’aide de la tfx extension publish commande au lieu de tfx extension create empaqueter et de publier votre extension en une seule étape. Vous pouvez éventuellement utiliser --share-with pour partager votre extension avec un ou plusieurs comptes après sa publication.

    tfx extension publish --manifest-globs your-manifest.json --share-with yourOrganization
    
  2. Créez un jeton d’accès personnel (PAT).

    • Sélectionnez l’étendue « Place de marché (publication) ». Cette étendue limite le jeton à la seule possibilité de publier des extensions sur la Place de marché.

Partager votre extension

Maintenant que vous avez chargé votre extension, elle se trouve sur la Place de marché, mais personne ne peut la voir. Partagez-le avec votre organisation pour pouvoir l’installer et le tester.

Sélectionnez avec le bouton droit votre extension, puis sélectionnez Partager, puis entrez les informations de votre organisation. Vous pouvez également le partager avec d’autres comptes que vous souhaitez avoir accès à votre extension.

Important

Les serveurs de publication doivent être vérifiés pour partager des extensions publiquement. Pour plus d’informations, consultez Package/Publish/Install.

Maintenant que votre extension est partagée dans la Place de marché, toute personne qui souhaite l’utiliser doit l’installer.

6. Créer un pipeline de build et de mise en production pour publier l’extension sur La Place de marché

Créez un pipeline de build et de mise en production sur Azure DevOps pour aider à gérer la tâche personnalisée sur la Place de marché.

Prérequis

Logiciel/outil

Informations

Azure DevOps Projects

Extension Tâches d’extension Azure DevOps

Installez gratuitement les tâches d’extension Azure DevOps dans votre organisation.

Groupe de variables de bibliothèque de pipelines

Créez un groupe de variables de bibliothèque de pipelines pour contenir les variables utilisées par le pipeline. Pour plus d’informations, consultez Ajouter et utiliser des groupes de variables. Vous pouvez créer des groupes de variables à partir de l’onglet Bibliothèque Azure DevOps ou via l’interface CLI. Utilisez les variables de ce groupe dans votre pipeline. Déclarez également les variables suivantes dans le groupe de variables :

  • publisherId: ID de votre éditeur de la Place de marché
  • extensionId: ID de votre extension, comme déclaré dans le fichier vss-extension.json
  • extensionName: Nom de votre extension, comme déclaré dans le fichier vss-extension.json
  • artifactName: nom de l’artefact créé pour le fichier VSIX

Connexion du service

Créez une connexion de service de la Place de marché et accordez des autorisations d’accès pour tous les pipelines.

Pipeline YAML

Utilisez l’exemple suivant pour créer un pipeline avec YAML. Pour plus d’informations, consultez Créer votre premier pipeline et schéma 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'

Pour plus d’informations, consultez Spécifier des événements qui déclenchent des pipelines.

Remarque

Chaque travail utilise un nouvel agent utilisateur et nécessite l’installation de dépendances.

Étapes de canalisation

La section suivante vous aide à comprendre le fonctionnement des étapes du pipeline.

Étape 1 : Exécuter et publier des tests unitaires

Cette étape exécute des tests unitaires et publie les résultats des tests dans Azure DevOps.

Pour exécuter des tests unitaires, ajoutez un script personnalisé au fichier package.json comme dans l’exemple suivant.

"scripts": {
    "testScript": "mocha ./TestFile --reporter xunit --reporter-option output=ResultsFile.xml"
},
  1. Ajoutez « Utiliser Node CLI pour Azure DevOps (tfx-cli) » pour installer tfx-cli sur votre agent de build.

  2. Ajoutez la tâche « npm » avec la commande « install » et ciblez le dossier avec le fichier package.json.

  3. Ajoutez la tâche « Bash » pour compiler le TypeScript en JavaScript.

  4. Ajoutez la tâche « npm » avec la commande « custom », ciblez le dossier qui contient les tests unitaires et entrez testScript la commande. Utilisez les entrées suivantes :

    • Commande : personnalisée
    • Dossier de travail contenant package.json : /TestsDirectory
    • Commande et arguments : testScript
  5. Ajoutez la tâche « Publier les résultats des tests ». Si vous utilisez le journaliste Mocha XUnit, assurez-vous que le format de résultat est « JUnit » et non « XUnit ». Définissez le dossier de recherche sur le répertoire racine. Utilisez les entrées suivantes :

    • Format de résultat de test : JUnit
    • Fichiers de résultats des tests : **/ResultsFile.xml
    • Dossier de recherche : $(System.DefaultWorkingDirectory)

    Une fois les résultats de test publiés, la sortie sous l’onglet tests doit ressembler à l’exemple suivant.

    Capture d’écran de l’exemple de résultat de test.

Étape 2 : Empaqueter l’extension et publier des artefacts de build

  1. Ajoutez « Utiliser Node CLI pour Azure DevOps (tfx-cli) » pour installer tfx-cli sur votre agent de build.

  2. Ajoutez la tâche « npm » avec la commande « install » et ciblez le dossier avec le fichier package.json.

  3. Ajoutez la tâche « Bash » pour compiler le TypeScript en JavaScript.

  4. Ajoutez la tâche « Version de l’extension de requête » pour interroger la version d’extension existante. Utilisez les entrées suivantes :

    • Se connecter à : Visual Studio Marketplace
    • Visual Studio Marketplace (connexion de service) : Connexion de service
    • ID de l’éditeur : ID de votre éditeur visual Studio Marketplace
    • ID d’extension : ID de votre extension dans le fichier vss-extension.json
    • Augmenter la version : Correctif
    • Variable de sortie : Task.Extension.Version
  5. Ajoutez la tâche « Extension de package » pour empaqueter les extensions en fonction du manifeste Json. Utilisez les entrées suivantes :

    • Dossier manifestes racines : pointe vers le répertoire racine qui contient le fichier manifeste. Par exemple, $(System.DefaultWorkingDirectory) est le répertoire racine
    • Fichier(s) manifeste(s) : vss-extension.json
    • ID de l’éditeur : ID de votre éditeur visual Studio Marketplace
    • ID d’extension : ID de votre extension dans le fichier vss-extension.json
    • Nom de l’extension : nom de votre extension dans le fichier vss-extension.json
    • Version de l’extension : $(Task.Extension.Version)
    • Remplacer la version des tâches : cochée (true)
    • Type de remplacement : Remplacer uniquement le correctif (1.0.r)
    • Visibilité de l’extension : si l’extension est toujours en cours de développement, définissez la valeur sur privée. Pour libérer l’extension sur le public, définissez la valeur sur public
  6. Ajoutez la tâche « Copier des fichiers » pour copier des fichiers publiés. Utilisez les entrées suivantes :

    • Contenu : tous les fichiers à copier pour les publier en tant qu’artefact
    • Dossier cible : dossier dans lequel les fichiers sont copiés
      • Par exemple : $(Build.ArtifactStagingDirectory)
  7. Ajoutez « Publier des artefacts de build » pour publier les artefacts à utiliser dans d’autres travaux ou pipelines. Utilisez les entrées suivantes :

    • Chemin d’accès à la publication : chemin d’accès au dossier qui contient les fichiers en cours de publication
      • Par exemple : $(Build.ArtifactStagingDirectory)
    • Nom de l’artefact : nom donné à l’artefact
    • Emplacement de publication des artefacts : choisissez « Azure Pipelines » pour utiliser l’artefact dans les travaux futurs

Étape 3 : Télécharger les artefacts de build et publier l’extension

  1. Ajoutez « Utiliser Node CLI pour Azure DevOps (tfx-cli) » pour installer tfx-cli sur votre agent de build.

  2. Ajoutez la tâche « Télécharger les artefacts de build » pour télécharger les artefacts dans un nouveau travail. Utilisez les entrées suivantes :

    • Téléchargez les artefacts générés par : si vous téléchargez l’artefact sur un nouveau travail à partir du même pipeline, sélectionnez « Build actuelle ». Si vous téléchargez sur un nouveau pipeline, sélectionnez « Build spécifique ».
    • Type de téléchargement : choisissez « Artefact spécifique » pour télécharger tous les fichiers publiés.
    • Nom de l’artefact : nom de l’artefact publié.
    • Répertoire de destination : dossier dans lequel les fichiers doivent être téléchargés.
  3. La dernière tâche dont vous avez besoin est la tâche « Publier l’extension ». Utilisez les entrées suivantes :

    • Se connecter à : Visual Studio Marketplace
    • Connexion visual Studio Marketplace : ServiceConnection
    • Type de fichier d’entrée : fichier VSIX
    • Fichier VSIX : /Publisher.*.vsix
    • ID de l’éditeur : ID de votre éditeur visual Studio Marketplace
    • ID d’extension : ID de votre extension dans le fichier vss-extension.json
    • Nom de l’extension : nom de votre extension dans le fichier vss-extension.json
    • Visibilité de l’extension : privé ou public

Facultatif : Installer et tester votre extension

Installez une extension partagée avec vous en quelques étapes :

  1. À partir du panneau de configuration de votre organisation (https://dev.azure.com/{organization}/_admin), accédez à la page d’administration de collection de projets.
  2. Sous l’onglet Extensions , recherchez votre extension dans le groupe « Extensions partagées avec moi », puis sélectionnez le lien d’extension.
  3. Installez l’extension.

Si vous ne voyez pas l’onglet Extensions , vérifiez que vous êtes dans le panneau de configuration (la page d’administration au niveau https://dev.azure.com/{organization}/_adminde la collection de projets) et non la page d’administration d’un projet.

Si vous ne voyez pas l’onglet Extensions , les extensions ne sont pas activées pour votre organisation. Vous pouvez obtenir un accès anticipé à la fonctionnalité d’extensions en joignant le programme partenaire Visual Studio.

Pour empaqueter et publier des extensions Azure DevOps sur Visual Studio Marketplace, vous pouvez télécharger les tâches d’extension Azure DevOps.

FAQ

Consultez les questions fréquemment posées (FAQ) suivantes sur l’ajout de tâches de build ou de mise en production personnalisées dans les extensions pour Azure DevOps.

Q : Comment puis-je restreindre l’utilisation des commandes Azure Pipelines pour la tâche ?

Vous pouvez restreindre l’utilisation et les variables des commandes Azure Pipelines, qui sont définies par tâche. Cette action peut être utile pour empêcher l’accès illimité aux variables/commandes vso pour les scripts personnalisés exécutés par la tâche. Nous vous recommandons de le configurer pour les nouvelles tâches. Pour appliquer, vous devrez peut-être ajouter l’instruction suivante à votre fichier task.json :

  "restrictions": {
    "commands": {
      "mode": "restricted"
    },
    "settableVariables": {
      "allowed": ["variable1", "test*"]
    }
}

Si restricted la valeur est spécifiée pour mode : vous ne pouvez exécuter que les commandes suivantes par la tâche :

  • logdetail
  • logissue
  • complete
  • setprogress
  • setsecret
  • setvariable
  • debug
  • settaskvariable
  • prependpath
  • publish

Les settableVariables restrictions vous permettent de passer une liste verte de variables, qui sont définies par ou prependpath par setvariable commandes. Il permet également des expressions régulières de base. Par exemple, si votre liste verte était : ['abc', 'test*'], paramètre abc, testou test1 en tant que variables avec n’importe quelle valeur ou les précédant sur le chemin d’accès réussirait, mais si vous essayez de définir un proxy de variable, il est averti. La liste vide signifie qu’aucune variable n’est modifiée par tâche.

Si la ou commands la clé est omise, la settableVariables restriction pertinente n’est pas appliquée.

La fonctionnalité de restriction est disponible à partir de la version de l’agent 2.182.1 .

Q : Comment le signal d’annulation est-il géré par une tâche ?

R : L’agent de pipeline envoie et SIGTERM signale SIGINT au processus enfant approprié. Il n’existe aucun moyen explicite dans la bibliothèque de tâches à traiter. Pour plus d’informations, consultez l’annulation des travaux de l’agent.

Q : Comment puis-je supprimer la tâche de la collection de projets ?

R : Nous ne prenons pas en charge la suppression automatique des tâches. La suppression automatique n’est pas sécurisée et interrompt les pipelines existants qui utilisent déjà ces tâches. Toutefois, vous pouvez marquer les tâches comme déconseillées. Pour ce faire, placez la version de la tâche et marquez la tâche comme déconseillée.

Q : Comment puis-je mettre à niveau ma tâche personnalisée vers le dernier nœud ?

R : Nous vous recommandons de procéder à la mise à niveau vers la dernière version de Node. Pour obtenir des exemples d’informations, consultez Mise à niveau des tâches vers le nœud 20.

Étant donné que les agents hébergés Par Microsoft et les différentes versions d’Azure DevOps Server ont des cycles de vie différents, il peut y avoir différentes versions de Node Runner installées en fonction de l’emplacement d’exécution d’une tâche. Pour pouvoir exécuter la même tâche sur les agents avec différentes versions de l’exécuteur de nœud, le fichier task.json peut contenir plusieurs sections d’exécution. Dans l’exemple suivant, les agents Azure Pipeline qui incluent l’exécuteur Node 20 le choisissent par défaut, et ceux qui ne revient pas à l’implémentation de Node 10.

  "execution": {
    "Node10": {
      "target": "bash.js",
      "argumentFormat": ""
    },
    "Node20_1": {
      "target": "bash.js",
      "argumentFormat": ""
    }

Pour mettre à niveau vos tâches :

  • Testez votre ou vos tâches sur les différentes versions de l’exécuteur de nœud pour vous assurer que votre code se comporte comme prévu.

  • Dans la section d’exécution de votre tâche, mettez à jour depuis Node ou Node10 vers ou Node20vers Node16 .

  • Pour prendre en charge les versions antérieures du serveur, vous devez laisser la Node/Node10 cible. Les versions antérieures d’Azure DevOps Server peuvent ne pas avoir la dernière version de Node Runner incluse.

  • Vous pouvez choisir de partager le point d’entrée défini dans la cible ou d’avoir des cibles optimisées pour la version du nœud utilisée.

    "execution": {
       "Node10": {
         "target": "bash10.js",
         "argumentFormat": ""
    },
    "Node16": {
       "target": "bash16.js",
       "argumentFormat": ""
    },
    "Node20_1": {
       "target": "bash20.js",
       "argumentFormat": ""
    }
    

Important

L’ajout de la prise en charge de l’exécuteur Node 20 sur vos tâches personnalisées entraîne l’échec des tâches sur les agents installés à partir du pipelines-agent-* flux de mise en production.