Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
Azure DevOps Services | Azure DevOps Server | Azure DevOps Server 2022
Dieser Leitfaden führt Sie durch das Erstellen, Testen und Veröffentlichen von benutzerdefinierten Build- oder Freigabeaufgaben als Azure DevOps-Erweiterungen. Mit benutzerdefinierten Pipelineaufgaben können Sie Azure DevOps mit speziellen Funktionen erweitern, die auf die Workflows Ihres Teams zugeschnitten sind, von einfachen Hilfsprogrammen bis hin zu komplexen Integrationen mit externen Systemen.
Erfahren Sie, wie Sie die folgenden Aufgaben ausführen:
- Einrichten der Entwicklungsumgebung und Projektstruktur
- Erstellen von Aufgabenlogik mithilfe von TypeScript und der Azure Pipelines-Aufgabenbibliothek
- Implementieren von umfassenden Komponententests mit Mock-Frameworks
- Verpacken Sie Ihre Erweiterung für die Verteilung
- Veröffentlichen im Visual Studio Marketplace
- Einrichten automatisierter CI/CD-Pipelines für die Erweiterungswartung
Weitere Informationen zu Azure-Pipelines finden Sie unter Was ist Azure-Pipelines?
Hinweis
In diesem Artikel werden Agentaufgaben in agentbasierten Erweiterungen behandelt. Informationen zu Serveraufgaben und serverbasierten Erweiterungen finden Sie unter Serveraufgabenerstellung.
Voraussetzungen
Bevor Sie beginnen, stellen Sie sicher, dass Die folgenden Anforderungen erfüllt sind:
| Komponente | Anforderung | Beschreibung |
|---|---|---|
| Azure DevOps Organisation | Erforderlich | Erstellen Sie eine Organisation, wenn Sie keine haben |
| Texteditor | Empfohlen | Visual Studio Code für IntelliSense und Debuggingunterstützung |
| Node.js | Erforderlich | Installieren der neuesten Version (Node.js 20 oder höher empfohlen) |
| TypeScript-Compiler | Erforderlich | Installieren der neuesten Version (Version 4.6.3 oder höher) |
| Azure DevOps CLI (tfx-cli) | Erforderlich | Installation mithilfe von npm i -g tfx-cli für Erweiterungen paketieren |
| Azure DevOps-Erweiterungs-SDK | Erforderlich | Installieren des Azure-devops-extension-sdk-Pakets |
| Testframework | Erforderlich | Mocha für Komponententests (während des Setups installiert) |
Projektstruktur
Erstellen Sie ein home Verzeichnis für Ihr Projekt. Nachdem Sie diese Anleitung abgeschlossen haben, sollte Ihre Erweiterung die folgende Struktur aufweisen:
|--- 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
Wichtig
Ihr Entwicklungscomputer muss die neueste Version von Node.js ausführen, um die Kompatibilität mit der Produktionsumgebung sicherzustellen. Aktualisieren Sie Ihre task.json Datei für die Verwendung von Node 20:
"execution": {
"Node20_1": {
"target": "index.js"
}
}
Erstellen einer benutzerdefinierten Aufgabe
Dieser Abschnitt führt Sie durch das Erstellen der grundlegenden Struktur und Implementierung Ihrer benutzerdefinierten Aufgabe. Alle Dateien in diesem Schritt sollten innerhalb des buildandreleasetask Ordners home im Verzeichnis Ihres Projekts erstellt werden.
Hinweis
In dieser exemplarischen Vorgehensweise wird Windows mit PowerShell verwendet. Die Schritte funktionieren auf allen Plattformen, die Umgebungsvariablensyntax unterscheidet sich jedoch. Ersetzen Sie auf einem Mac oder Linux $env:<var>=<val> durch export <var>=<val>.
Aufgabengerüst einrichten
Erstellen Sie die grundlegende Projektstruktur, und installieren Sie erforderliche Abhängigkeiten:
Um das Node.js Projekt zu initialisieren, öffnen Sie PowerShell, wechseln Sie zu Ihrem
buildandreleasetaskOrdner, und führen Sie Folgendes aus:npm init --yesDie
package.jsonDatei wird mit Standardeinstellungen erstellt. Das--yesKennzeichen akzeptiert automatisch alle Standardoptionen.Tipp
Azure Pipelines-Agents erwarten, dass Aufgabenordner Knotenmodule enthalten. Kopieren Sie
node_modulesin denbuildandreleasetaskOrdner. Zum Verwalten der VSIX-Dateigröße (Grenzwert von 50 MB) sollten Sie die Ausführungnpm install --productionodernpm prune --productionvor dem Verpacken in Betracht ziehen.Installieren Sie die Azure Pipelines-Aufgabenbibliothek:
npm install azure-pipelines-task-lib --saveTypeScript-Typdefinitionen installieren:
npm install @types/node --save-dev npm install @types/q --save-devEinrichten von Versionssteuerungsausschlüssen
echo node_modules > .gitignoreIhr Buildprozess sollte
npm installjedes Mal ausführen, um node_modules neu zu erstellen.Installieren von Testabhängigkeiten:
npm install mocha --save-dev -g npm install sync-request --save-dev npm install @types/mocha --save-devTypeScript-Compiler installieren:
npm install typescript@4.6.3 -g --save-devHinweis
Installieren Sie TypeScript global, um sicherzustellen, dass der
tscBefehl verfügbar ist. Ohne dies wird TypeScript 2.3.4 standardmäßig verwendet.Konfigurieren der TypeScript-Kompilierung:
tsc --init --target es2022Die
tsconfig.jsonDatei wird mit ES2022-Zieleinstellungen erstellt.
Implementieren der Aufgabenlogik
Erstellen Sie nach Abschluss des Gerüsts die Kernaufgabendateien, die Funktionen und Metadaten definieren:
Erstellen Sie die Aufgabendefinitionsdatei:
task.jsonim Ordnerbuildandreleasetask. Diese Datei beschreibt Ihre Aufgabe im Azure Pipelines-System, definieren Eingaben, Ausführungseinstellungen und UI-Präsentationen.{ "$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" } } }Hinweis
Ersetzen Sie
{{placeholders}}mit den tatsächlichen Informationen Ihrer Aufgabe. Dietaskguidmuss eindeutig sein. Generieren Sie eins mithilfe von PowerShell:(New-Guid).GuidUm die Aufgabenlogik zu implementieren, erstellen Sie
index.tsmit der Hauptfunktionalität Ihrer Aufgabe: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();Kompilieren von TypeScript in JavaScript:
tscDie
index.jsDatei wird aus Ihrer TypeScript-Quelle erstellt.
task.json-Komponenten
Die task.json Datei ist das Herzstück Ihrer Aufgabendefinition. Hier sind die wichtigsten Eigenschaften:
| Eigenschaft | Beschreibung | Beispiel |
|---|---|---|
id |
Eindeutiger GUID-Bezeichner für Ihre Aufgabe | Generiert mit (New-Guid).Guid |
name |
Vorgangsname ohne Leerzeichen (intern verwendet) | MyCustomTask |
friendlyName |
Anzeigename, der in der Benutzeroberfläche angezeigt wird | My Custom Task |
description |
Detaillierte Beschreibung der Aufgabenfunktionalität | Performs custom operations on files |
author |
Herausgeber- oder Autorname | My Company |
instanceNameFormat |
Wie die Aufgabe in Pipeline-Schritten dargestellt wird | Process $(inputFile) |
inputs |
Feld von Eingabeparametern | Siehe die folgenden Eingabetypen |
execution |
Spezifikation der Ausführungsumgebung |
Node20_1, PowerShell3 usw. |
restrictions |
Sicherheitseinschränkungen für Befehle und Variablen | Empfohlen für neue Aufgaben |
Sicherheitsbeschränkungen
Fügen Sie für Produktionsaufgaben Sicherheitseinschränkungen hinzu, um die Verwendung von Befehlen und den variablen Zugriff einzuschränken:
"restrictions": {
"commands": {
"mode": "restricted"
},
"settableVariables": {
"allowed": ["variable1", "test*"]
}
}
Der eingeschränkte Modus lässt nur die folgenden Befehle zu:
-
logdetaillogissuecompletesetprogress -
setsecretsetvariabledebugsettaskvariable -
prependpath,publish
Die Variable-Zulassungsliste bestimmt, welche Variablen über setvariable oder prependpath festgelegt werden können. Unterstützt grundlegende regex-Muster.
Hinweis
Für dieses Feature ist agent Version 2.182.1 oder höher erforderlich.
Eingabetypen und Beispiele
Allgemeine Eingabetypen für Vorgangsparameter:
"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"
}
]
Testen Sie Ihre Aufgabe lokal
Testen Sie vor dem Verpacken Ihre Aufgabe, um sicherzustellen, dass sie ordnungsgemäß funktioniert:
Testen mit fehlender Eingabe (sollte fehlschlagen):
node index.jsErwartete Ausgabe:
##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: samplestringTesten mit gültiger Eingabe (sollte erfolgreich sein):
$env:INPUT_SAMPLESTRING="World" node index.jsErwartete Ausgabe:
##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 WorldTesten der Fehlerbehandlung:
$env:INPUT_SAMPLESTRING="bad" node index.jsDiese Aktion sollte den Fehlerbehandlungspfad in Ihrem Code auslösen.
Tipp
Informationen zu Aufgabenläufern und Node.js Versionen finden Sie unter Node runner update guidance.
Weitere Informationen finden Sie in der Build-/Release-Aufgabenreferenz.
Implementieren von Komponententests
Durch das gründliche Testen Ihrer Aufgabe wird die Zuverlässigkeit sichergestellt und hilft, Probleme vor der Bereitstellung in Produktionspipelinen abzufangen.
Installieren von Testabhängigkeiten
Installieren Sie die erforderlichen Testtools:
npm install mocha --save-dev -g
npm install sync-request --save-dev
npm install @types/mocha --save-dev
Erstellen von Tests
Erstellen Sie einen
testsOrdner in Ihrem Aufgabenverzeichnis, der eine_suite.tsDatei enthält: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 }); });Tipp
Ihr Testordner sollte sich im Aufgabenordner befinden (z. B
buildandreleasetask. ). Wenn ein Synchronisierungsanforderungsfehler auftritt, installieren Sie ihn im Aufgabenordner:npm i --save-dev sync-request.Erstellen Sie
success.tsin Ihrem Testverzeichnis, um eine erfolgreiche Aufgabenausführung zu simulieren: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();Fügen Sie den Erfolgstest zu Ihrer
_suite.tsDatei hinzu: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 }); });Erstellen Sie
failure.tsin Ihrem Testverzeichnis, um die Fehlerbehandlung zu testen: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();Fügen Sie den Fehlertest Ihrer
_suite.tsDatei hinzu.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(); }); });
Ausführung Ihrer Tests
Führen Sie die Testsuite aus:
# Compile TypeScript
tsc
# Run tests
mocha tests/_suite.js
Beide Tests sollten bestehen. Legen Sie die Umgebungsvariable für die Ablaufverfolgung fest, um eine ausführliche Ausgabe zu erhalten (ähnlich wie bei der Buildkonsolenausgabe).
$env:TASK_TEST_TRACE=1
mocha tests/_suite.js
Testabdeckungsrichtlinien
- Testen Sie alle Eingabekombinationen: Gültige Eingaben, ungültige Eingaben, fehlende erforderliche Eingaben
- Testfehlerszenarien: Netzwerkfehler, Dateisystemfehler, Berechtigungsprobleme
- Simulierte externe Abhängigkeiten: Verlassen Sie sich nicht auf externe Dienste in Komponententests
- Überprüfen von Ausgaben: Überprüfen der Konsolenausgabe, Aufgabenergebnisse und generierter Artefakte
- Leistungstests: Erwägen Sie das Hinzufügen von Tests für Aufgaben, die große Dateien verarbeiten
Sicherheitsrichtlinien
- Eingabeüberprüfung: Eingaben immer überprüfen und bereinigungen
-
Umgang mit geheimen Schlüsseln: Verwendung
setSecretfür vertrauliche Daten - Befehlseinschränkungen: Implementieren von Befehlseinschränkungen für Produktionsaufgaben
- Minimale Berechtigungen: Nur erforderliche Berechtigungen anfordern
- Regelmäßige Updates: Beibehalten von Abhängigkeiten und Node.js Versionen auf dem aktuellen Stand
Nachdem Sie Ihre Aufgabe lokal getestet und umfassende Komponententests implementiert haben, packen Sie sie in eine Erweiterung für Azure DevOps.
Installieren von Verpackungstools
Installieren Sie die plattformübergreifende Befehlszeilenschnittstelle (tfx-cli):
npm install -g tfx-cli
Erstellen des Erweiterungsmanifests
Das Erweiterungsmanifest (vss-extension.json) enthält alle Informationen zu Ihrer Erweiterung, einschließlich Verweise auf Ihre Aufgabenordner und Bilder.
Erstellen eines Bilderordners mit einer
extension-icon.pngDateiErstellen Sie
vss-extension.jsonim Stammverzeichnis Ihrer Erweiterung (nicht im Aufgabenordner):{ "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" } } ] }
Wichtige Manifest-Eigenschaften
| Eigenschaft | Beschreibung |
|---|---|
publisher |
Ihr Marktplatz-Publisher-ID |
contributions.id |
Eindeutiger Bezeichner innerhalb der Erweiterung |
contributions.properties.name |
Muss dem Namen des Aufgabenordners entsprechen |
files.path |
Pfad zum Aufgabenordner relativ zum Manifest |
Hinweis
Ändern Sie den Wert für den Herausgeber in Ihren Herausgebernamen. Informationen zum Erstellen eines Herausgebers finden Sie unter Erstellen Ihres Herausgebers.
Verpacken Sie Ihre Erweiterung
Packen Sie Ihre Erweiterung in eine .vsix-Datei.
tfx extension create --manifest-globs vss-extension.json
Versionsverwaltung
-
Erweiterungsversion: Erhöhen Sie die Versionsnummer in
vss-extension.jsonfür jedes Update -
Aufgabenversion: Erhöhen der Version
task.jsonfür jede Aktualisierung der Aufgabe -
Auto-Inkrement: Verwenden Sie
--rev-version, um die Patchversion automatisch zu erhöhen.
tfx extension create --manifest-globs vss-extension.json --rev-version
Wichtig
Sowohl die Aufgabenversion als auch die Erweiterungsversion müssen aktualisiert werden, damit Änderungen in Azure DevOps wirksam werden.
Versionsverwaltungsstrategie
Folgen Sie den Prinzipien der semantischen Versionsverwaltung für Ihre Aufgabenaktualisierungen:
- Hauptversion: Grundlegende Änderungen an Eingaben/Ausgaben
- Nebenversion: Neue Features, abwärtskompatibel
- Patchversion: Nur Fehlerbehebungen
Aktualisierungsprozess:
- Update
task.jsonVersion - Update
vss-extension.jsonVersion - Gründliches Testen in einer Testorganisation
- Veröffentlichen und Probleme überwachen
Veröffentlichen auf Visual Studio Marketplace
Erstellen eines Herausgebers
- Melden Sie sich beim Visual Studio Marketplace-Veröffentlichungsportal an.
- Erstellen Sie einen neuen Herausgeber, wenn Sie dazu aufgefordert werden:
-
Herausgeberbezeichner: Wird in Ihrem Erweiterungsmanifest verwendet (z. B
mycompany-myteam. ) -
Anzeigename: Öffentlicher Name, der auf dem Marketplace angezeigt wird (z. B
My Team. )
-
Herausgeberbezeichner: Wird in Ihrem Erweiterungsmanifest verwendet (z. B
- Überprüfen und Akzeptieren der Marketplace-Herausgebervereinbarung
Hochladen der Erweiterung
Webschnittstellenmethode:
- Wählen Sie "Neue Erweiterung hochladen" aus.
- Wählen Sie Ihre
.vsixverpackte Datei aus. - Wählen Sie Hochladen aus.
Befehlszeilenmethode:
tfx extension publish --manifest-globs vss-extension.json --share-with yourOrganization
Erweiterung teilen
- Klicken Sie mit der rechten Maustaste auf Ihre Erweiterung auf dem Marketplace.
- Wählen Sie Freigeben aus
- Geben Sie den Namen Ihrer Organisation ein.
- Hinzufügen weiterer Organisationen nach Bedarf
Wichtig
Herausgeber müssen überprüft werden, um Erweiterungen öffentlich freizugeben. Weitere Informationen finden Sie unter "Package/Publish/Install".
Installieren in Ihrer Organisation
Installieren Sie die Erweiterung nach der Freigabe in Ihrer Azure DevOps-Organisation.
- Navigieren Sie zu Organisationseinstellungen>Erweiterungen
- Durchsuchen Sie nach Ihrer Erweiterung
- Wählen Sie "Kostenlos abrufen " und "Installieren" aus.
Paketieren und veröffentlichen Sie die Erweiterung
Überprüfen Sie Ihre Erweiterung
Überprüfen Sie nach der Installation, ob die Aufgabe ordnungsgemäß funktioniert:
- Erstellen oder Bearbeiten einer Pipeline
- Fügen Sie Ihre benutzerdefinierte Aufgabe hinzu:
- Wählen Sie im Pipeline-Editor "Aufgabe hinzufügen" aus.
- Suchen Sie nach Ihrer benutzerdefinierten Aufgabe anhand des Namens
- Fügen Sie es Ihrer Pipeline hinzu
- Aufgabenparameter konfigurieren:
- Festlegen erforderlicher Eingaben
- Konfigurieren optionaler Einstellungen
- Führen Sie die Pipeline aus, um die Funktionalität zu testen.
- Überwachen der Ausführung:
- Überprüfen von Aufgabenprotokollen auf ordnungsgemäße Ausführung
- Überprüfen der erwarteten Ausgaben
- Sicherstellen, dass keine Fehler oder Warnungen auftreten
Automatisierung der Veröffentlichung mit CI/CD
Um Ihre benutzerdefinierte Aufgabe effektiv zu verwalten, erstellen Sie automatisierte Build- und Freigabepipelinen, die Tests, Verpackungen und Veröffentlichungen verarbeiten.
CI/CD-Voraussetzungen
- Azure DevOps-Erweiterungsaufgaben: Installieren Der Erweiterung kostenlos
-
Variablengruppe: Erstellen Sie eine Pipelinebibliotheksvariablengruppe mit diesen Variablen:
-
publisherId: Ihre Marketplace-Herausgeber-ID -
extensionId: Erweiterungs-ID von vss-extension.json -
extensionName: Erweiterungsname aus vss-extension.json -
artifactName: Name für das VSIX-Artefakt
-
- Dienstverbindung: Erstellen einer Marketplace-Dienstverbindung mit Pipelinezugriffsberechtigungen
CI/CD-Pipelinebeispiel
Erstellen Sie eine YAML-Pipeline mit umfassenden Phasen für Tests, Verpackungen und Veröffentlichungen:
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'
Konfigurieren von package.json zu Testzwecken
Fügen Sie Testskripte zu Ihrem package.json hinzu:
{
"scripts": {
"test": "mocha tests/_suite.js --reporter xunit --reporter-option output=test-results.xml",
"test-verbose": "cross-env TASK_TEST_TRACE=1 npm test"
}
}
Pipelinephasen
Testen und Überprüfen
- Zweck: Sicherstellen der Codequalität und -funktionalität
- Aktionen: Installieren von Abhängigkeiten, Kompilieren von TypeScript, Ausführen von Komponententests, Veröffentlichen von Ergebnissen
- Überprüfung: Alle Tests müssen bestehen, um fortzufahren.
Erweiterung verpacken
- Zweck: Erstellen eines bereitstellenden VSIX-Pakets
- Aktionen: Aktuelle Version abfragen, Version inkrementieren, Erweiterung verpacken, Artefakte veröffentlichen
- Versionsverwaltung: Behandelt automatisch Versionserhöhungen
Auf Marketplace veröffentlichen
- Zweck: Bereitstellen auf Visual Studio Marketplace
- Bedingungen: Läuft nur nach erfolgreicher Verpackung auf dem Master-Branch
- Umgebung: Verwendet die Bereitstellungsumgebung für die Freigabeprozesse.
CI/CD-Richtlinien
- Branch-Schutz: Nur aus Haupt-/Release-Branches veröffentlichen
- Umgebungsgates: Verwenden von Bereitstellungsumgebungen für Produktionsversionen
- Versionsverwaltung: Automatisieren von Versionsinkrementierungen, um Konflikte zu vermeiden
- Testabdeckung: Sicherstellen einer umfassenden Testabdeckung vor dem Verpacken
- Sicherheit: Verwenden von Dienstverbindungen anstelle hartcodierter Anmeldeinformationen
- Überwachung: Einrichten von Warnungen für fehlgeschlagene Bereitstellungen
Führen Sie für klassische Build-Pipelines die folgenden Schritte aus, um das Verpacken und Veröffentlichen von Erweiterungen einzurichten:
Fügen Sie die
BashAufgabe hinzu, um typeScript in JavaScript zu kompilieren.Um die vorhandene Version abzufragen, fügen Sie die Abfrageerweiterungsversion-Aufgabe mithilfe der folgenden Eingaben hinzu:
- Herstellen einer Verbindung mit: Visual Studio Marketplace
- Visual Studio Marketplace (Dienst-Verbindung): Dienst-Verbindung
- Herausgeber-ID: ID Ihres Visual Studio Marketplace-Herausgebers
- Erweiterungs-ID: ID Ihrer Erweiterung in der
vss-extension.jsonDatei - Version erhöhen: Patch
- Ausgabevariable:
Task.Extension.Version
Um die Erweiterungen basierend auf manifest json zu packen, fügen Sie die Paketerweiterungsaufgabe mithilfe der folgenden Eingaben hinzu:
- Stammmanifestordner: Verweist auf das Stammverzeichnis, das die Manifestdatei enthält. Zum Beispiel ist
$(System.DefaultWorkingDirectory)das Stammverzeichnis. - Manifestdatei:
vss-extension.json - Herausgeber-ID: ID Ihres Visual Studio Marketplace-Herausgebers
- Erweiterungs-ID: ID Ihrer Erweiterung in der
vss-extension.jsonDatei - Erweiterungsname: Name der Erweiterung in der
vss-extension.jsonDatei - Erweiterungsversion:
$(Task.Extension.Version) - Aufgaben Version überschreiben: markiert (true)
- Typ überschreiben: Nur Patch ersetzen (1.0.r)
- Sichtbarkeit der Erweiterung: Wenn sich die Erweiterung noch in der Entwicklung befindet, legen Sie den Wert auf "Privat" fest. Um die Erweiterung für die Öffentlichkeit freizugeben, legen Sie den Wert auf "öffentlich" fest.
- Stammmanifestordner: Verweist auf das Stammverzeichnis, das die Manifestdatei enthält. Zum Beispiel ist
Um in veröffentlichte Dateien zu kopieren, fügen Sie die Aufgabe " Dateien kopieren " mithilfe der folgenden Eingaben hinzu:
- Inhalt: Alle Dateien, die zum Veröffentlichen als Artefakt kopiert werden sollen
- Zielordner: Der Ordner, in den die Dateien kopiert werden
- Beispiel:
$(Build.ArtifactStagingDirectory)
- Beispiel:
Fügen Sie Bauartefakte veröffentlichen hinzu, um die Artefakte zur Verwendung in anderen Aufträgen oder Pipelines zu veröffentlichen. Verwenden Sie die folgenden Eingaben:
- Pfad zur Veröffentlichung: Der Pfad zum Ordner, der die dateien enthält, die veröffentlicht werden
- Beispiel:
$(Build.ArtifactStagingDirectory)
- Beispiel:
- Artefaktname: Der dem Artefakt zugewiesene Name
- Artefakt-Veröffentlichungsort: Wählen Sie Azure Pipelines aus, um das Artefakt in zukünftigen Aufträgen zu verwenden.
- Pfad zur Veröffentlichung: Der Pfad zum Ordner, der die dateien enthält, die veröffentlicht werden
Herunterladen und Veröffentlichen von Artefakten
Um die tfx-cli auf Ihrem Build-Agent zu installieren, fügen Sie den Befehl Node CLI für Azure DevOps verwenden (tfx-cli) hinzu.
Um die Artefakte auf einen neuen Auftrag herunterzuladen, fügen Sie die Aufgabe Download build artifacts mit den folgenden Eingaben hinzu:
- Downloads von Artefakten erstellt von: Wenn Sie das Artefakt mit einem neuen Auftrag aus derselben Pipeline herunterladen, wählen Sie Aktueller Build. Wenn Sie mit einer neuen Pipeline herunterladen, wählen Sie Spezifischer Build
- Downloadtyp: Wählen Sie "Spezifisches Artefakt " aus, um alle veröffentlichten Dateien herunterzuladen.
- Artefaktname: Der Name des veröffentlichten Artefakts
- Zielverzeichnis: Der Ordner, in den die Dateien heruntergeladen werden sollen
Verwenden Sie die folgenden Eingaben, um die Aufgabe "Erweiterung veröffentlichen " abzurufen:
- Herstellen einer Verbindung mit: Visual Studio Marketplace
- Visual Studio Marketplace-Verbindung: ServiceConnection
- Eingabedateityp: VSIX-Datei
- VSIX-Datei:
/Publisher.*.vsix - Herausgeber-ID: ID Ihres Visual Studio Marketplace-Herausgebers
- Erweiterungs-ID: ID Ihrer Erweiterung in der
vss-extension.jsonDatei - Erweiterungsname: Name der Erweiterung in der
vss-extension.jsonDatei - Sichtbarkeit der Erweiterung: Entweder privat oder öffentlich
Installieren und Testen der Erweiterung
Nachdem Sie Ihre Erweiterung veröffentlicht haben, muss sie in Azure DevOps-Organisationen installiert werden.
In einer Organisation installieren
Installieren Sie Ihre freigegebene Erweiterung in einigen Schritten:
Wechseln Sie zu "Organisationseinstellungen" , und wählen Sie "Erweiterungen" aus.
Suchen Sie Ihre Erweiterung im Abschnitt "Für mich freigegebene Erweiterungen ":
- Wählen Sie den Erweiterungslink aus.
- Wählen Sie "Kostenlos abrufen" oder "Installieren" aus.
Überprüfen Sie, ob die Erweiterung in der Liste der installierten Erweiterungen angezeigt wird:
- Vergewissern Sie sich, dass sie in Ihrer Pipelineaufgabenbibliothek verfügbar ist.
Hinweis
Wenn die Registerkarte "Erweiterungen " nicht angezeigt wird, stellen Sie sicher, dass Sie sich auf der Verwaltungsebene (https://dev.azure.com/{organization}/_admin) der Organisation befinden und nicht auf Projektebene.
End-to-End-Tests
Führen Sie nach der Installation umfassende Tests durch:
Erstellen einer Testpipeline:
- Fügen Sie Ihre benutzerdefinierte Aufgabe zu einer neuen Pipeline hinzu
- Konfigurieren aller Eingabeparameter
- Testen mit verschiedenen Eingabekombinationen
Überprüfen der Funktionalität:
- Ausführen der Pipeline und Überwachen der Ausführung
- Überprüfen von Aufgabenausgängen und Protokollen
- Überprüfen der Fehlerbehandlung mit ungültigen Eingaben
Testleistung:
- Testen mit großen Eingabedateien (falls zutreffend)
- Überwachen der Ressourcennutzung
- Validieren des Timeout-Verhaltens
Häufig gestellte Fragen
F: Wie wird der Vorgangsabbruch verarbeitet?
A: Der Pipeline-Agent sendet SIGINT- und SIGTERM-Signale an die Aufgabenprozesse. Während die Aufgabenbibliothek keine explizite Abbruchbehandlung bereitstellt, kann Ihre Aufgabe Signalhandler implementieren. Ausführliche Informationen finden Sie unter Kündigung von Agentaufträgen.
F: Wie kann ich eine Aufgabe aus meiner Organisation entfernen?
A: Das automatische Löschen wird nicht unterstützt , da vorhandene Pipelines abgebrochen werden. Stattdessen:
- Aufgabe als veraltet markieren: Aufgabe als veraltet kennzeichnen
- Versionsverwaltung: Aktualisiere die Aufgabenversion
- Kommunikation: Benutzer über den Zeitplan zur Abkündigung informieren.
F: Wie kann ich meine Aufgabe auf die neueste Node.js Version aktualisieren?
A: Aktualisieren Sie auf die neueste Node-Version , um eine bessere Leistung und Sicherheit zu erzielen. Anleitungen zur Migration finden Sie unter Aktualisieren von Aufgaben auf Node 20.
Mehrere Node-Versionen unterstützen, indem Sie mehrere Ausführungsabschnitte in task.json einfügen:
"execution": {
"Node20_1": {
"target": "index.js"
},
"Node10": {
"target": "index.js"
}
}
Agents mit Node 20 verwenden die bevorzugte Version, während ältere Agents auf Node 10 zurückgreifen.
So aktualisieren Sie Ihre Aufgaben:
Um sicherzustellen, dass sich Ihr Code wie erwartet verhält, testen Sie Ihre Aufgaben in den verschiedenen Node-Läuferversionen.
Aktualisieren Sie im Ausführungsbereich Ihrer Aufgabe von
NodeoderNode10zuNode16oderNode20.Um ältere Serverversionen zu unterstützen, sollten Sie das
Node/Node10Ziel beibehalten. Ältere Azure DevOps Server-Versionen verfügen möglicherweise nicht über die neueste Node-Runner-Version.Sie können den im Ziel definierten Einstiegspunkt teilen oder die Ziele auf die verwendete Node-Version optimieren lassen.
"execution": { "Node10": { "target": "bash10.js", "argumentFormat": "" }, "Node16": { "target": "bash16.js", "argumentFormat": "" }, "Node20_1": { "target": "bash20.js", "argumentFormat": "" } }
Wichtig
Wenn Sie ihren benutzerdefinierten Aufgaben keine Unterstützung für den Node 20-Läufer hinzufügen, schlagen sie bei Agents fehl, die aus dem pipelines-agent-*Releasefeed installiert wurden.