Remarque
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de vous connecter ou de modifier des répertoires.
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de modifier des répertoires.
Azure DevOps Services | Azure DevOps Server | Azure DevOps Server 2022
Ce guide vous guide tout au long de la création, du test et de la publication de tâches de build ou de mise en production personnalisées en tant qu’extensions Azure DevOps. Les tâches de pipeline personnalisées vous permettent d’étendre Azure DevOps avec des fonctionnalités spécialisées adaptées aux flux de travail de votre équipe, des utilitaires simples aux intégrations complexes avec des systèmes externes.
Découvrez comment effectuer les tâches suivantes :
- Configurer l’environnement de développement et la structure de projet
- Créer une logique de tâche à l’aide de TypeScript et de la bibliothèque de tâches Azure Pipelines
- Implémenter des tests unitaires complets avec des frameworks fictifs
- Empaqueter votre extension pour la distribution
- Publier sur Visual Studio Marketplace
- Configurer des pipelines CI/CD automatisés pour la maintenance des extensions
Pour plus d’informations sur Azure Pipelines, 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 serveur et les extensions basées sur le serveur, consultez Création de tâches serveur.
Prérequis
Avant de commencer, vérifiez que vous disposez des exigences suivantes :
| Composant | Besoin | Descriptif |
|---|---|---|
| Organisation Azure DevOps | Obligatoire | Créer une organisation si vous n’en avez pas |
| Éditeur de texte | Recommandé | Prise en charge de Visual Studio Code pour IntelliSense et du débogage |
| Node.JS | Obligatoire | Installez la dernière version (Node.js 20 ou version ultérieure recommandée) |
| Compilateur TypeScript | Obligatoire | Installez la dernière version (version 4.6.3 ou ultérieure) |
| Azure DevOps CLI (tfx-cli) | Obligatoire | Installer à l’aide des npm i -g tfx-cli extensions de package |
| Kit de développement logiciel (SDK) d’extension Azure DevOps | Obligatoire | Installer le package azure-devops-extension-sdk |
| Framework de test | Obligatoire | Mocha pour les tests unitaires (installé pendant l’installation) |
Structure du projet
Créez un home répertoire pour votre projet. Une fois ce tutoriel terminé, votre extension doit avoir la structure suivante :
|--- README.md
|--- images
|--- extension-icon.png
|--- buildandreleasetask // Task scripts location
|--- task.json // Task definition
|--- index.ts // Main task logic
|--- package.json // Node.js dependencies
|--- tests/ // Unit tests
|--- _suite.ts
|--- success.ts
|--- failure.ts
|--- vss-extension.json // Extension manifest
Importante
Votre ordinateur de développement doit exécuter la dernière version de Node.js pour garantir la compatibilité avec l’environnement de production. Mettez à jour votre task.json fichier pour utiliser Node 20 :
"execution": {
"Node20_1": {
"target": "index.js"
}
}
1. Créer une tâche personnalisée
Cette section vous guide tout au long de la création de la structure et de l’implémentation de base de votre tâche personnalisée. Tous les fichiers de cette étape doivent être créés dans le buildandreleasetask dossier du répertoire de home votre projet.
Remarque
Cette procédure pas à pas utilise Windows avec PowerShell. Les étapes fonctionnent sur toutes les plateformes, mais la syntaxe des variables d’environnement diffère. Sur Mac ou Linux, remplacez $env:<var>=<val> par export <var>=<val>.
Configurer la structure des tâches
Créez la structure de projet de base et installez les dépendances requises :
Pour initialiser le projet Node.js, ouvrez PowerShell, accédez à votre
buildandreleasetaskdossier et exécutez :npm init --yesLe
package.jsonfichier est créé avec les paramètres par défaut. L’indicateur--yesaccepte automatiquement toutes les options par défaut.Conseil
Les agents Azure Pipelines s’attendent à ce que les dossiers de tâches incluent des modules de nœud. Copiez
node_modulesdans votrebuildandreleasetaskdossier. Pour gérer la taille de fichier VSIX (limite de 50 Mo), envisagez d’exécuternpm install --productionounpm prune --productionavant l’empaquetage.Installez la bibliothèque de tâches Azure Pipelines :
npm install azure-pipelines-task-lib --saveInstallez les définitions de type TypeScript :
npm install @types/node --save-dev npm install @types/q --save-devConfigurer des exclusions de contrôle de version
echo node_modules > .gitignoreVotre processus de génération doit s’exécuter
npm installpour reconstruire node_modules chaque fois.Installez les dépendances de test :
npm install mocha --save-dev -g npm install sync-request --save-dev npm install @types/mocha --save-devInstallez le compilateur TypeScript :
npm install typescript@4.6.3 -g --save-devRemarque
Installez TypeScript globalement pour vous assurer que la
tsccommande est disponible. Sans cela, TypeScript 2.3.4 est utilisé par défaut.Configurer la compilation TypeScript :
tsc --init --target es2022Le
tsconfig.jsonfichier est créé avec les paramètres cibles ES2022.
Implémenter la logique de tâche
Une fois la structure terminée, créez les fichiers de tâches principaux qui définissent les fonctionnalités et les métadonnées :
Créez le fichier de définition de tâche : créez
task.jsondans lebuildandreleasetaskdossier. Ce fichier décrit votre tâche au système Azure Pipelines, en définissant les entrées, les paramètres d’exécution et la présentation de l’interface utilisateur.{ "$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" } } }Remarque
Remplacez
{{placeholders}}par les informations réelles de votre tâche. L’taskguiddoit être unique. Générez-en une à l’aide de PowerShell :(New-Guid).GuidPour implémenter la logique de tâche, créez
index.tsavec la fonctionnalité principale de votre tâche :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();Compilez TypeScript en JavaScript :
tscLe
index.jsfichier est créé à partir de votre source TypeScript.
Présentation des composants task.json
Le task.json fichier est le cœur de votre définition de tâche. Voici les propriétés clés :
| Propriété | Descriptif | Exemple : |
|---|---|---|
id |
Identificateur GUID unique pour votre tâche | Généré à l’aide de (New-Guid).Guid |
name |
Nom de la tâche sans espaces (utilisé en interne) | MyCustomTask |
friendlyName |
Nom complet affiché dans l’interface utilisateur | My Custom Task |
description |
Description détaillée des fonctionnalités de tâche | Performs custom operations on files |
author |
Nom de l’éditeur ou de l’auteur | My Company |
instanceNameFormat |
Affichage de la tâche dans les étapes du pipeline | Process $(inputFile) |
inputs |
Tableau de paramètres d’entrée | Consultez les types d’entrée suivants |
execution |
Spécification de l’environnement d’exécution |
Node20_1, , PowerShell3etc. |
restrictions |
Restrictions de sécurité pour les commandes et les variables | Recommandé pour les nouvelles tâches |
Restrictions de sécurité
Pour les tâches de production, ajoutez des restrictions de sécurité pour limiter l’utilisation des commandes et l’accès aux variables :
"restrictions": {
"commands": {
"mode": "restricted"
},
"settableVariables": {
"allowed": ["variable1", "test*"]
}
}
Le mode restreint autorise uniquement ces commandes :
-
logdetail,logissuecomplete,setprogress -
setsecret,setvariabledebug,settaskvariable -
prependpath,publish
Variable allowlist contrôle quelles variables peuvent être définies via setvariable ou prependpath. Prend en charge les modèles d’expression régulière de base.
Remarque
Cette fonctionnalité nécessite l’agent version 2.182.1 ou ultérieure.
Types d’entrée et exemples
Types d’entrée courants pour les paramètres de tâche :
"inputs": [
{
"name": "stringInput",
"type": "string",
"label": "Text Input",
"defaultValue": "",
"required": true,
"helpMarkDown": "Enter a text value"
},
{
"name": "boolInput",
"type": "boolean",
"label": "Enable Feature",
"defaultValue": "false",
"required": false
},
{
"name": "picklistInput",
"type": "pickList",
"label": "Select Option",
"options": {
"option1": "First Option",
"option2": "Second Option"
},
"defaultValue": "option1"
},
{
"name": "fileInput",
"type": "filePath",
"label": "Input File",
"required": true,
"helpMarkDown": "Path to the input file"
}
]
Tester votre tâche localement
Avant d’empaqueter, testez votre tâche pour vous assurer qu’elle fonctionne correctement :
Test avec une entrée manquante (doit échouer) :
node index.jsSortie attendue :
##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: samplestringTest avec entrée valide (doit réussir) :
$env:INPUT_SAMPLESTRING="World" node index.jsSortie attendue :
##vso[task.debug]agent.workFolder=undefined ##vso[task.debug]loading inputs and endpoints ##vso[task.debug]loading INPUT_SAMPLESTRING ##vso[task.debug]loaded 1 ##vso[task.debug]samplestring=World Hello WorldGestion des erreurs de test :
$env:INPUT_SAMPLESTRING="bad" node index.jsCette action doit déclencher le chemin de gestion des erreurs dans votre code.
Conseil
Pour plus d’informations sur les exécuteurs de tâches et les versions Node.js, consultez les instructions de mise à jour de l’exécuteur node.
Pour plus d’informations, consultez la référence de tâche de compilation/déploiement.
2. Implémenter des tests unitaires complets
Le test de votre tâche garantit soigneusement la fiabilité et aide à détecter les problèmes avant le déploiement vers des pipelines de production.
Installer les dépendances de test
Installez les outils de test requis :
npm install mocha --save-dev -g
npm install sync-request --save-dev
npm install @types/mocha --save-dev
Créer un test
Créez un
testsdossier dans votre répertoire de tâches contenant un_suite.tsfichier :import * as path from 'path'; import * as assert from 'assert'; import * as ttm from 'azure-pipelines-task-lib/mock-test'; describe('Sample task tests', function () { before( function() { // Setup before tests }); after(() => { // Cleanup after tests }); it('should succeed with simple inputs', function(done: Mocha.Done) { // Success test implementation }); it('should fail if tool returns 1', function(done: Mocha.Done) { // Failure test implementation }); });Conseil
Votre dossier de test doit se trouver dans le dossier des tâches (par exemple).
buildandreleasetaskSi vous rencontrez une erreur de demande de synchronisation, installez-la dans le dossier de tâches :npm i --save-dev sync-request.Créez
success.tsdans votre répertoire de test pour simuler une exécution réussie de la tâche :import ma = require('azure-pipelines-task-lib/mock-answer'); import tmrm = require('azure-pipelines-task-lib/mock-run'); import path = require('path'); let taskPath = path.join(__dirname, '..', 'index.js'); let tmr: tmrm.TaskMockRunner = new tmrm.TaskMockRunner(taskPath); // Set valid input for success scenario tmr.setInput('samplestring', 'human'); tmr.run();Ajoutez le test de réussite à votre
_suite.tsfichier :it('should succeed with simple inputs', function(done: Mocha.Done) { this.timeout(1000); let tp: string = path.join(__dirname, 'success.js'); let tr: ttm.MockTestRunner = new ttm.MockTestRunner(tp); tr.runAsync().then(() => { console.log(tr.succeeded); assert.equal(tr.succeeded, true, 'should have succeeded'); assert.equal(tr.warningIssues.length, 0, "should have no warnings"); assert.equal(tr.errorIssues.length, 0, "should have no errors"); console.log(tr.stdout); assert.equal(tr.stdout.indexOf('Hello human') >= 0, true, "should display Hello human"); done(); }).catch((error) => { done(error); // Ensure the test case fails if there's an error }); });Créez
failure.tsdans votre répertoire de test pour tester la gestion des erreurs :import ma = require('azure-pipelines-task-lib/mock-answer'); import tmrm = require('azure-pipelines-task-lib/mock-run'); import path = require('path'); let taskPath = path.join(__dirname, '..', 'index.js'); let tmr: tmrm.TaskMockRunner = new tmrm.TaskMockRunner(taskPath); // Set invalid input to trigger failure tmr.setInput('samplestring', 'bad'); tmr.run();Ajoutez le test d’échec à votre
_suite.tsfichier :it('should fail if tool returns 1', function(done: Mocha.Done) { this.timeout(1000); const tp = path.join(__dirname, 'failure.js'); const tr: ttm.MockTestRunner = new ttm.MockTestRunner(tp); tr.runAsync().then(() => { console.log(tr.succeeded); assert.equal(tr.succeeded, false, 'should have failed'); assert.equal(tr.warningIssues.length, 0, 'should have no warnings'); assert.equal(tr.errorIssues.length, 1, 'should have 1 error issue'); assert.equal(tr.errorIssues[0], 'Bad input was given', 'error issue output'); assert.equal(tr.stdout.indexOf('Hello bad'), -1, 'Should not display Hello bad'); done(); }); });
Exécuter vos tests
Exécutez la suite de tests :
# Compile TypeScript
tsc
# Run tests
mocha tests/_suite.js
Les deux tests doivent réussir. Pour une sortie détaillée (similaire à la sortie de la console de génération), définissez la variable d’environnement de trace :
$env:TASK_TEST_TRACE=1
mocha tests/_suite.js
Meilleures pratiques relatives à la couverture des tests
- Tester toutes les combinaisons d’entrées : entrées valides, entrées non valides, entrées manquantes requises
- Scénarios d’erreur de test : échecs réseau, erreurs du système de fichiers, problèmes d’autorisation
- Simuler des dépendances externes : ne pas compter sur les services externes dans les tests unitaires
- Valider les sorties : vérifier la sortie de la console, les résultats des tâches et les artefacts générés
- Tests de performances : envisagez d’ajouter des tests pour les tâches qui traitent des fichiers volumineux
Bonnes pratiques de sécurité
- Validation d’entrée : Toujours valider et nettoyer les entrées
-
Gestion des secrets : utilisation
setSecretpour les données sensibles - Restrictions de commande : Implémenter des restrictions de commande pour les tâches de production
- Autorisations minimales : Demander uniquement les autorisations nécessaires
- Mises à jour régulières : Conserver les dépendances et les versions Node.js actuelles
Après avoir testé votre tâche localement et implémenté des tests unitaires complets, empaquetez-la dans une extension pour Azure DevOps.
Installer des outils d’empaquetage
Installez l’interface de ligne de commande multiplateforme (tfx-cli) :
npm install -g tfx-cli
Créer le manifeste d’extension
Le manifeste d’extension (vss-extension.json) contient toutes les informations relatives à votre extension, y compris les références à vos dossiers de tâches et images.
Créer un dossier d’images avec un
extension-icon.pngfichierCréez
vss-extension.jsondans le répertoire racine de votre extension (et non dans le dossier de tâches) :{ "manifestVersion": 1, "id": "my-custom-tasks", "name": "My Custom Tasks", "version": "1.0.0", "publisher": "your-publisher-id", "targets": [ { "id": "Microsoft.VisualStudio.Services" } ], "description": "Custom build and release tasks for Azure DevOps", "categories": [ "Azure Pipelines" ], "icons": { "default": "images/extension-icon.png" }, "files": [ { "path": "MyCustomTask" } ], "contributions": [ { "id": "my-custom-task", "type": "ms.vss-distributed-task.task", "targets": [ "ms.vss-distributed-task.tasks" ], "properties": { "name": "MyCustomTask" } } ] }
Propriétés du manifeste de clé
| Propriété | Descriptif |
|---|---|
publisher |
Identificateur de votre éditeur de la Place de marché |
contributions.id |
Identificateur unique dans l’extension |
contributions.properties.name |
Doit correspondre au nom de votre dossier de tâche |
files.path |
Chemin d’accès à votre dossier de tâches par rapport au manifeste |
Remarque
Remplacez la valeur de l’éditeur par le nom de votre éditeur. Pour plus d’informations sur la création d’un éditeur, consultez Créer votre éditeur.
Emballer votre extension
Empaqueter votre extension dans un fichier .vsix :
tfx extension create --manifest-globs vss-extension.json
Gestion des versions
-
Version de l’extension : incrémenter la version
vss-extension.jsonpour chaque mise à jour -
Version de la tâche : incrémenter la version pour
task.jsonchaque mise à jour de tâche -
Incrément automatique : permet
--rev-versiond’incrémenter automatiquement la version du correctif
tfx extension create --manifest-globs vss-extension.json --rev-version
Importante
La version de tâche et la version d’extension doivent être mises à jour pour que les modifications prennent effet dans Azure DevOps.
Stratégie de contrôle de version
Suivez les principes de gestion de version sémantique pour les mises à jour de vos tâches :
- Version majeure : changements cassants des entrées/sorties
- Version mineure : nouvelles fonctionnalités, rétrocompatibles
- Version du correctif : correctifs de bogues uniquement
Processus de mise à jour :
- Mise à jour de la version
task.json - Mise à jour de la version
vss-extension.json - Tester soigneusement dans une organisation de test
- Publier et surveiller les problèmes
Publier sur Visual Studio Marketplace
1. Créer votre éditeur
- Connectez-vous au portail de publication visual Studio Marketplace
- Créez un serveur de publication si vous y êtes invité :
-
Identificateur de l’éditeur : utilisé dans votre manifeste d’extension (par exemple,
mycompany-myteam) -
Nom complet : Nom public affiché dans la Place de marché (par exemple,
My Team)
-
Identificateur de l’éditeur : utilisé dans votre manifeste d’extension (par exemple,
- Passer en revue et accepter le contrat d’éditeur de la Place de marché
2. Charger votre extension
Méthode d’interface web :
- Sélectionner Charger une nouvelle extension
- Choisir votre fichier empaqueté
.vsix - Sélectionnez Charger.
Méthode de ligne de commande :
tfx extension publish --manifest-globs vss-extension.json --share-with yourOrganization
3. Partager votre extension
- Cliquez avec le bouton droit sur votre extension sur la Place de marché
- Sélectionnez Partager
- Entrez le nom de votre organisation
- Ajouter d’autres organisations en fonction des besoins
Importante
Les éditeurs doivent être vérifiés pour partager des extensions publiquement. Pour plus d’informations, consultez Package/Publish/Install.
4. Installer dans votre organisation
Après le partage, installez l’extension dans votre organisation Azure DevOps :
- Accéder auxextensions> de l’organisation
- Rechercher votre extension
- Sélectionnez Obtenir gratuitement et installer
3. Empaqueter et publier votre extension
Vérifier votre extension
Après l’installation, vérifiez que votre tâche fonctionne correctement :
- Créez ou modifiez un pipeline.
- Ajoutez votre tâche personnalisée :
- Sélectionner Ajouter une tâche dans l’éditeur de pipeline
- Rechercher votre tâche personnalisée par nom
- Ajoutez-le à votre pipeline
- Configurer les paramètres de tâche :
- Définir les entrées requises
- Configurer les paramètres facultatifs
- Exécuter le pipeline pour tester la fonctionnalité
- Surveiller l’exécution :
- Vérifier les journaux des tâches pour une exécution appropriée
- Vérifier les sorties attendues
- Vérifiez qu’aucune erreur ou avertissement n’est en cours
4. Automatiser la publication d’extension avec CI/CD
Pour gérer efficacement votre tâche personnalisée, créez des pipelines de génération et de mise en production automatisés qui gèrent les tests, l’empaquetage et la publication.
Conditions préalables pour l’automatisation
- Tâches d’extension Azure DevOps : installer l’extension gratuitement
-
Groupe de variables : Créez un groupe de variables de bibliothèque de pipelines avec ces variables :
-
publisherId: ID de l’éditeur de la Place de marché -
extensionId: ID d’extension de vss-extension.json -
extensionName: Nom de l’extension de vss-extension.json -
artifactName: Nom de l’artefact VSIX
-
- Connexion de service : créer une connexion de service de la Place de marché avec des autorisations d’accès au pipeline
Pipeline CI/CD complet
Créez un pipeline YAML avec des étapes complètes pour le test, l’empaquetage et la publication :
trigger:
- main
pool:
vmImage: "ubuntu-latest"
variables:
- group: extension-variables # Your variable group name
stages:
- stage: Test_and_validate
displayName: 'Run Tests and Validate Code'
jobs:
- job: RunTests
displayName: 'Execute unit tests'
steps:
- task: TfxInstaller@4
displayName: 'Install TFX CLI'
inputs:
version: "v0.x"
- task: Npm@1
displayName: 'Install task dependencies'
inputs:
command: 'install'
workingDir: '/MyCustomTask' # Update to your task directory
- task: Bash@3
displayName: 'Compile TypeScript'
inputs:
targetType: "inline"
script: |
cd MyCustomTask # Update to your task directory
tsc
- task: Npm@1
displayName: 'Run unit tests'
inputs:
command: 'custom'
workingDir: '/MyCustomTask' # Update to your task directory
customCommand: 'test' # Ensure this script exists in package.json
- task: PublishTestResults@2
displayName: 'Publish test results'
inputs:
testResultsFormat: 'JUnit'
testResultsFiles: '**/test-results.xml'
searchFolder: '$(System.DefaultWorkingDirectory)'
- stage: Package_extension
displayName: 'Package Extension'
dependsOn: Test_and_validate
condition: succeeded()
jobs:
- job: PackageExtension
displayName: 'Create VSIX package'
steps:
- task: TfxInstaller@4
displayName: 'Install TFX CLI'
inputs:
version: "v0.x"
- task: Npm@1
displayName: 'Install dependencies'
inputs:
command: 'install'
workingDir: '/MyCustomTask'
- task: Bash@3
displayName: 'Compile TypeScript'
inputs:
targetType: "inline"
script: |
cd MyCustomTask
tsc
- task: QueryAzureDevOpsExtensionVersion@4
name: QueryVersion
displayName: 'Query current extension version'
inputs:
connectTo: 'VsTeam'
connectedServiceName: 'marketplace-connection'
publisherId: '$(publisherId)'
extensionId: '$(extensionId)'
versionAction: 'Patch'
- task: PackageAzureDevOpsExtension@4
displayName: 'Package extension'
inputs:
rootFolder: '$(System.DefaultWorkingDirectory)'
publisherId: '$(publisherId)'
extensionId: '$(extensionId)'
extensionName: '$(extensionName)'
extensionVersion: '$(QueryVersion.Extension.Version)'
updateTasksVersion: true
updateTasksVersionType: 'patch'
extensionVisibility: 'private'
extensionPricing: 'free'
- task: PublishBuildArtifacts@1
displayName: 'Publish VSIX artifact'
inputs:
PathtoPublish: '$(System.DefaultWorkingDirectory)/*.vsix'
ArtifactName: '$(artifactName)'
publishLocation: 'Container'
- stage: Publish_to_marketplace
displayName: 'Publish to Marketplace'
dependsOn: Package_extension
condition: and(succeeded(), eq(variables['Build.SourceBranch'], 'refs/heads/main'))
jobs:
- deployment: PublishExtension
displayName: 'Deploy to marketplace'
environment: 'marketplace-production'
strategy:
runOnce:
deploy:
steps:
- task: TfxInstaller@4
displayName: 'Install TFX CLI'
inputs:
version: "v0.x"
- task: PublishAzureDevOpsExtension@4
displayName: 'Publish to marketplace'
inputs:
connectTo: 'VsTeam'
connectedServiceName: 'marketplace-connection'
fileType: 'vsix'
vsixFile: '$(Pipeline.Workspace)/$(artifactName)/*.vsix'
publisherId: '$(publisherId)'
extensionId: '$(extensionId)'
extensionName: '$(extensionName)'
updateTasksVersion: false
extensionVisibility: 'private'
extensionPricing: 'free'
Configurer package.json pour les tests
Ajoutez des scripts de test à votre package.json:
{
"scripts": {
"test": "mocha tests/_suite.js --reporter xunit --reporter-option output=test-results.xml",
"test-verbose": "cross-env TASK_TEST_TRACE=1 npm test"
}
}
Répartition des phases de pipeline
Étape 1 : Tester et valider
- Objectif : garantir la qualité et les fonctionnalités du code
- Actions : Installer des dépendances, compiler TypeScript, exécuter des tests unitaires, publier des résultats
- Validation : tous les tests doivent réussir pour continuer
Étape 2 : Extension de package
- Objectif : Créer un package VSIX déployable
- Actions : Interroger la version actuelle, incrémenter la version, l’extension de package, publier des artefacts
- Contrôle de version : gère automatiquement les incréments de version
Étape 3 : Publier sur la Place de marché
- Objectif : Déployer sur Visual Studio Marketplace
- Conditions : s’exécute uniquement sur la branche principale après la réussite de l’empaquetage
- Environnement : utilise l’environnement de déploiement pour les portes d’approbation
Meilleures pratiques pour CI/CD
- Protection des branches : publier uniquement à partir des branches main/release
- Portes d’environnement : utiliser des environnements de déploiement pour les versions de production
- Gestion des versions : Automatiser les incréments de version pour éviter les conflits
- Couverture des tests : garantir une couverture complète des tests avant l’empaquetage
- Sécurité : Utiliser des connexions de service au lieu d’informations d’identification codées en dur
- Surveillance : configurer des alertes pour les déploiements ayant échoué
Pour les pipelines de build classiques, procédez comme suit pour configurer l’empaquetage et la publication d’extensions :
Ajoutez la
Bashtâche pour compiler le TypeScript en JavaScript.Pour interroger la version existante, ajoutez la tâche version de l’extension de requête à l’aide des 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
vss-extension.jsonfichier - Augmenter la version : Correctif
- Variable de sortie :
Task.Extension.Version
Pour empaqueter les extensions en fonction du manifeste Json, ajoutez la tâche d’extension de package à l’aide des entrées suivantes :
- Dossier racine des manifestes : fait référence au répertoire racine qui contient le fichier manifeste. Par exemple,
$(System.DefaultWorkingDirectory)est le répertoire racine - Fichier manifeste :
vss-extension.json - ID de l’éditeur : ID de votre éditeur visual Studio Marketplace
- ID d’extension : ID de votre extension dans le
vss-extension.jsonfichier - Nom de l’extension : nom de votre extension dans le
vss-extension.jsonfichier - 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 rendre l'extension publique, définissez la valeur à public.
- Dossier racine des manifestes : fait référence au répertoire racine qui contient le fichier manifeste. Par exemple,
Pour copier des fichiers publiés, ajoutez la tâche Copier des fichiers à l’aide des 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)
- Par exemple :
Ajoutez Publier les artefacts de build pour qu'ils puissent être utilisés dans d'autres tâches 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)
- Par exemple :
- Nom de l’artefact : nom donné à l’artefact
- Emplacement de publication des artefacts : choisissez Azure Pipelines pour utiliser les artefacts dans les travaux futurs.
- Chemin d’accès à la publication : chemin d’accès au dossier qui contient les fichiers en cours de publication
Étape 3 : Télécharger les artefacts de build et publier l’extension
Pour installer tfx-cli sur votre agent de build, ajoutez Use Node CLI for Azure DevOps (tfx-cli).
Pour télécharger les artefacts vers une nouvelle tâche, veuillez ajouter la tâche Télécharger les artefacts de build en utilisant les informations suivantes :
- Télécharger les artefacts produits par : si vous téléchargez l'artefact sur une nouvelle tâche à partir du même pipeline, sélectionnez Compilation actuelle. Si vous effectuez le téléchargement sur un nouveau pipeline, veuillez sélectionner « Version spécifique ».
- Type de téléchargement : choisissez un 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
Pour obtenir 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
vss-extension.jsonfichier - Nom de l’extension : nom de votre extension dans le
vss-extension.jsonfichier - Visibilité de l’extension : privé ou public
Facultatif : Installer et tester votre extension
Après avoir publié votre extension, elle doit être installée dans les organisations Azure DevOps.
Installer l’extension à l’organisation
Installez votre extension partagée en quelques étapes :
Accédez aux paramètres de l’organisation et sélectionnez Extensions.
Recherchez votre extension dans la section Extensions partagées avec moi :
- Sélectionner le lien d’extension
- Sélectionnez Obtenir gratuitement ou installer
Vérifiez que l’extension apparaît dans la liste de vos extensions installées :
- Vérifiez qu’elle est disponible dans votre bibliothèque de tâches de pipeline
Remarque
Si vous ne voyez pas l’onglet Extensions , vérifiez que vous êtes au niveau de l’administration de l’organisation (https://dev.azure.com/{organization}/_admin) et non au niveau du projet.
Tests de bout en bout
Après l’installation, effectuez des tests complets :
Créez un pipeline de test :
- Ajouter votre tâche personnalisée à un nouveau pipeline
- Configurer tous les paramètres d’entrée
- Tester avec différentes combinaisons d’entrée
Valider les fonctionnalités :
- Exécuter le pipeline et surveiller l’exécution
- Vérifier les sorties et les journaux des tâches
- Vérifier la gestion des erreurs avec des entrées non valides
Performances des tests :
- Tester avec des fichiers d’entrée volumineux (le cas échéant)
- Surveiller l’utilisation des ressources
- Valider le comportement du délai d’expiration
Questions fréquentes
Q : Comment l’annulation des tâches est-elle gérée ?
R : L’agent de pipeline envoie et SIGINT signale SIGTERM aux processus de tâche. Bien que la bibliothèque de tâches ne fournisse pas de gestion d’annulation explicite, votre tâche peut implémenter des gestionnaires de signal. Pour plus d’informations, consultez l’annulation des travaux de l’agent.
Q : Comment puis-je supprimer une tâche de mon organisation ?
R : La suppression automatique n’est pas prise en charge , car elle interrompt les pipelines existants. Au lieu de:
- Déprécier la tâche : marquer la tâche comme déconseillée
- Gestion des versions : Faire passer la version de la tâche
- Communication : informer les utilisateurs de la chronologie de dépréciation
Q : Comment puis-je mettre à niveau ma tâche vers la dernière version Node.js ?
R : Effectuez une mise à niveau vers la dernière version de Node pour améliorer les performances et la sécurité. Pour obtenir des conseils sur la migration, consultez Mise à niveau des tâches vers le nœud 20.
Prendre en charge plusieurs versions de Nœud en incluant plusieurs sections d’exécution dans task.json:
"execution": {
"Node20_1": {
"target": "index.js"
},
"Node10": {
"target": "index.js"
}
}
Les agents avec Node 20 utilisent la version préférée, tandis que les anciens agents reviennent à Node 10.
Pour mettre à niveau vos tâches :
Pour vous assurer que votre code se comporte comme prévu, testez vos tâches sur les différentes versions de Node Runner.
Dans la section d’exécution de votre tâche, mettez à jour depuis
NodeouNode10versNode16ouNode20.Pour prendre en charge les versions antérieures du serveur, vous devez laisser la
Node/Node10cible. 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": "" } }
Importante
Si vous n’ajoutez pas la prise en charge de l’exécuteur Node 20 à vos tâches personnalisées, elles échouent sur les agents installés à partir du flux de mise en production pipelines-agent-*.