Udostępnij za pośrednictwem


Dodawanie niestandardowego rozszerzenia zadania potoków

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

Dowiedz się, jak zainstalować rozszerzenia w organizacji na potrzeby niestandardowych zadań kompilacji lub wydania w usłudze Azure DevOps. Aby uzyskać więcej informacji, zobacz Co to jest usługa Azure Pipelines?

Uwaga

W tym artykule opisano zadania agenta w rozszerzeniach opartych na agentach. Aby uzyskać więcej informacji na temat zadań serwera i rozszerzeń opartych na serwerze, zobacz Dokumentację Zadań Serwera na GitHub.

Wymagania wstępne

Oprogramowanie/narzędzie Informacja
Organizacja Azure DevOps Utwórz organizację.
Edytor tekstu W przypadku wielu procedur używamy programu Visual Studio Code, który zapewnia obsługę funkcji IntelliSense i debugowania. Pobierz najnowszą wersję.
Node.js Pobierz najnowszą wersję.
npmjs.com 4.0.2 lub nowsze Kompilator języka TypeScript. Pobierz najnowszą wersję.
tfx-cli Spakuj rozszerzenie za pomocą międzyplatformowego interfejsu wiersza polecenia dla usługi Azure DevOps. przy użyciu npm, składnika Node.js, uruchamiając npm i -g tfx-cli.
Zestaw SDK rozszerzenia usługi Azure DevOps Zainstaluj pakiet azure-devops-extension-sdk.
home Katalog projektu Katalog home rozszerzenia zadania kompilacji lub wdrożenia powinien wyglądać jak poniższy przykład po wykonaniu kroków opisanych w tym artykule.
|--- README.md    
|--- images                        
    |--- extension-icon.png  
|--- buildandreleasetask            // where your task scripts are placed
|--- vss-extension.json             // extension's manifest

Ważne

Komputer deweloperski musi uruchomić najnowszą wersję środowiska Node , aby upewnić się, że napisany kod jest zgodny ze środowiskiem produkcyjnym na agencie i najnowszą wersją inną niż wersja zapoznawcza programu azure-pipelines-task-lib. Zaktualizuj plik task.json zgodnie z następującym poleceniem:

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

1. Tworzenie zadania niestandardowego

Wykonaj każdą część tej procedury w folderze buildandreleasetask .

Uwaga

W tym przykładzie przedstawiono sposób użycia systemu Windows z programem PowerShell. Wprowadziliśmy ją ogólną dla wszystkich platform, ale składnia pobierania zmiennych środowiskowych jest inna. Jeśli używasz komputera Mac lub systemu Linux, zastąp wszystkie wystąpienia $env:<var>=<val> ciągiem export <var>=<val>.

Tworzenie ramy zadania

  1. Utwórz strukturę folderów dla zadania i zainstaluj wymagane biblioteki i zależności.

  2. Otwórz okno polecenia programu PowerShell, przejdź do buildandreleasetask folderu i uruchom następujące polecenie.

    npm init --yes
    

    npm init tworzy plik package.json. Dodaliśmy parametr , --yes aby zaakceptować wszystkie opcje domyślne npm init .

    Napiwek

    Agent nie instaluje automatycznie wymaganych modułów, ponieważ oczekuje się, że folder zadań będzie zawierał moduły węzła. Aby rozwiązać ten problem, skopiuj node_modules do buildandreleasetask. Gdy zadanie staje się większe, łatwo jest przekroczyć limit rozmiaru (50 MB) pliku VSIX. Przed skopiowanie folderu node możesz uruchomić npm install --production lub npm prune --productionalbo napisać skrypt, aby skompilować i spakować wszystko.

  3. Dodaj azure-pipelines-task-lib do biblioteki.

    npm install azure-pipelines-task-lib --save
    
  4. Upewnij się, że dla zależności zewnętrznych zainstalowano definicje typów TypeScript.

    npm install @types/node --save-dev
    npm install @types/q --save-dev
    
  5. .gitignore Utwórz plik i dodaj do niego node_modules. Proces kompilacji powinien wykonać elementy npm install i typings install, aby node_modules zostały skompilowane za każdym razem i nie muszą być załączane.

    echo node_modules > .gitignore
    
  6. Zainstaluj Mocha jako zależność programistyczną.

    npm install mocha --save-dev -g
    npm install sync-request --save-dev
    npm install @types/mocha --save-dev
    
  7. Wybierz TypeScript w wersji 2.3.4 lub 4.6.3.

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

    Uwaga

    Upewnij się, że TypeScript jest zainstalowany globalnie przy użyciu npm w twoim środowisku deweloperskim, aby polecenie tsc było dostępne. Jeśli pominiesz ten krok, język TypeScript w wersji 2.3.4 zostanie domyślnie użyty i nadal musisz zainstalować pakiet globalnie, aby mieć tsc dostępne polecenie.

  8. Utwórz tsconfig.json opcje kompilatora. Ten plik gwarantuje, że pliki TypeScript są kompilowane do plików JavaScript.

    tsc --init --target es2022
    

Utwórz zadanie

Teraz, gdy ukończono rusztowanie, możemy utworzyć zadanie niestandardowe.

  1. task.json Utwórz plik w folderzebuildandreleasetask. Plik task.json opisuje zadanie kompilacji/wydania i jest tym, co system kompilacji/wydania wykorzystuje, aby wyświetlać opcje konfiguracji użytkownikowi oraz aby ustalić, które skrypty należy wykonać podczas kompilacji/wydania.

  2. Skopiuj poniższy kod i zastąp element {{placeholders}} informacjami o zadaniu. Najważniejszym symbolem zastępczym jest taskguid, i musi być unikatowy.

    {
     "$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. Utwórz plik index.ts przy użyciu następującego kodu jako punktu odniesienia. Ten kod jest uruchamiany po wywołaniu zadania.

    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. Aby skompilować plik index.js z index.ts, wprowadź tsc z folderu buildandreleasetask.

składniki pliku task.json

Zapoznaj się z poniższymi opisami niektórych składników task.json pliku.

Własność opis
id Unikatowy identyfikator GUID dla twojego zadania.
name Nazwa bez spacji.
friendlyName Nazwa opisowa (dozwolone spacje).
description Szczegółowy opis wykonywanych zadań.
author Krótki ciąg opisujący jednostkę tworzącą zadanie kompilacji lub wydania, na przykład: "Microsoft Corporation".
instanceNameFormat Sposób wyświetlania zadania na liście kroków kompilacji/wydania. Wartości zmiennych można używać przy użyciu zmiennej $(nazwa_zmiennej).
groups Opisuje logiczne grupowanie właściwości zadań w interfejsie użytkownika.
inputs Dane wejściowe, które mają być używane w trakcie wykonywania zadania kompilowania lub publikowania. To zadanie oczekuje danych wejściowych o nazwie samplestring.
execution Istnieje wiele opcji wykonywania dla tego zadania, w tym skryptów, takich jak Node, PowerShell, PowerShell3lub Process.
restrictions Ograniczenia stosowane do zadania dotyczą poleceń, które zadanie może wywołać, oraz zmiennych, które zadanie może ustawić. Zalecamy określenie trybu ograniczeń dla nowych zadań.

Uwaga

Utwórz element id za pomocą następującego polecenia w programie PowerShell:

(New-Guid).Guid

Aby uzyskać więcej informacji, zobacz dokumentację zadania kompilacji/wydania.

Uruchom zadanie

Uruchom zadanie za pomocą node index.js programu PowerShell.

W poniższym przykładzie zadanie kończy się niepowodzeniem, ponieważ nie podano danych wejściowych (samplestring jest to wymagane dane wejściowe).

 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

W ramach poprawki samplestring możemy ustawić dane wejściowe i ponownie uruchomić zadanie.

$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

Tym razem zadanie zakończyło się pomyślnie, ponieważ samplestring zostało dostarczone i poprawnie wygenerowało komunikat "Hello Human!"

Napiwek

Aby uzyskać informacje o różnych procesorach zadań i o tym, jak uwzględnić najnowszą wersję node w task.json, zobacz w Wskazówki dotyczące aktualizacji node runner dla autorów zadań usługi Azure Pipelines.

2. Testowanie jednostkowe skryptów zadań

Wykonuj testy jednostkowe, aby szybko przetestować skrypt zadania, a nie narzędzia zewnętrzne, które wywołuje. Przetestuj wszystkie aspekty ścieżek powodzenia i niepowodzenia.

  1. Zainstaluj narzędzia testowe. Używamy Mocha jako sterownika testowego w tej procedurze.

    npm install mocha --save-dev -g
    npm install sync-request --save-dev
    npm install @types/mocha --save-dev
    
  2. tests Utwórz folder zawierający _suite.ts plik z następującą zawartością:

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

    Napiwek

    Folder testowy powinien znajdować się w folderze buildandreleasetask. Jeśli wystąpi błąd żądania synchronizacji, możesz go obejść, dodając żądanie synchronizacji do folderu buildandreleasetask za pomocą polecenia npm i --save-dev sync-request.

  3. success.ts Utwórz plik w katalogu testowym z następującą zawartością. To tworzenie pliku symuluje uruchomienie zadania i wyśmiewa wszystkie wywołania metod zewnętrznych.

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

    Test powodzenia sprawdza, czy z odpowiednimi danymi wejściowymi kończy się powodzeniem bez błędów ani ostrzeżeń i zwraca poprawne dane wyjściowe.

  4. Aby uruchomić moduł uruchamiający pozorowanie zadania, dodaj następujący przykładowy test powodzenia do pliku _suite.ts.

         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. Utwórz plik failure.ts w twoim katalogu testowym jako symulator uruchamiania zadań z następującą zawartością:

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

    Test awarii weryfikuje, czy narzędzie w przypadku otrzymania błędnych lub niekompletnych danych wejściowych kończy się niepowodzeniem w przewidywalny sposób, zapewniając użyteczne dane wyjściowe.

  6. Aby uruchomić symulator zadań, dodaj następujący kod do pliku _suite.ts.

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

    tsc
    mocha tests/_suite.js
    

    Oba testy powinny zostać wykonane pomyślnie. Jeśli chcesz uruchomić testy z bardziej szczegółowym wyjściem (to, co zobaczyłbyś w konsoli kompilacji), ustaw zmienną środowiskową: TASK_TEST_TRACE=1.

    $env:TASK_TEST_TRACE=1
    

3. Tworzenie pliku manifestu rozszerzenia

Manifest rozszerzenia zawiera wszystkie informacje o rozszerzeniu. Zawiera on linki do plików, w tym foldery zadań i foldery obrazów. Upewnij się, że utworzono folder o nazwie 'images' z plikiem extension-icon.png. Poniższy przykład to manifest rozszerzenia zawierający zadanie kompilacji lub wydania.

Skopiuj poniższy kod .json i zapisz go jako vss-extension.json plik w home katalogu.

Nie twórz tego pliku w folderze 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"
            }
        }
    ]
}

Uwaga

Zmień wydawcę na nazwę wydawcy. Aby uzyskać więcej informacji, zobacz Tworzenie wydawcy.

Udziały

Nieruchomość or Własność opis
id Identyfikator udziału. Musi być unikatowa w obrębie rozszerzenia. Nie musi być zgodna z nazwą zadania kompilacji lub wydania. Zazwyczaj nazwa zadania kompilacji lub wydania znajduje się w identyfikatorze wkładu.
type Typ udziału. Powinna być ms.vss-distributed-task.task.
targets Wkłady "ukierunkowane" przez ten wkład. Powinna być ms.vss-distributed-task.tasks.
properties.name Nazwa zadania. Ta nazwa musi być zgodna z nazwą folderu odpowiadającego samodzielnemu zadaniu kompilacji lub potoku wydania.

Pliki

Własność opis
path Ścieżka pliku lub folderu względem home katalogu.

Aby uzyskać więcej informacji na temat pliku manifestu rozszerzenia, takich jak jego właściwości i ich działania, zobacz odwołanie do manifestu rozszerzenia.

4. Spakuj rozszerzenie

Spakuj wszystkie pliki razem, aby uzyskać rozszerzenie w witrynie Visual Studio Marketplace. Wszystkie rozszerzenia są pakowane jako pliki vsix zgodne z systemem VSIX 2.0. Firma Microsoft udostępnia międzyplatformowy interfejs wiersza polecenia umożliwiający spakowanie rozszerzenia.

Po zainstalowaniu tfx-cli przejdź do katalogu głównego rozszerzenia i uruchom następujące polecenie:

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

Uwaga

W każdej aktualizacji należy zwiększać wersję rozszerzenia lub integracji. Podczas aktualizowania istniejącego rozszerzenia zaktualizuj wersję w manifeście lub użyj przełącznika wiersza polecenia --rev-version. Zwiększa to numer wersji poprawki rozszerzenia i zapisuje nową wersję w manifeście. Należy zaktualizować zarówno wersję zadania, jak i wersję rozszerzenia, aby mogła się odbyć aktualizacja. tfx extension create --manifest-globs vss-extension.json --rev-version aktualizuje tylko wersję rozszerzenia, a nie wersję zadania. Aby uzyskać więcej informacji, zobacz Build Task in GitHub (Zadanie kompilacji w usłudze GitHub).

Gdy spakowane rozszerzenie znajduje się w pliku vsix, możesz opublikować rozszerzenie w witrynie Marketplace.

5. Publikowanie rozszerzenia

Aby opublikować rozszerzenie, należy najpierw utworzyć wydawcę, a następnie przekazać rozszerzenie, a następnie udostępnić je.

Tworzenie wydawcy

Wszystkie rozszerzenia, w tym rozszerzenia firmy Microsoft, są identyfikowane jako dostarczane przez wydawcę. Jeśli nie jesteś jeszcze członkiem istniejącego wydawcy, utwórz go.

  1. Zaloguj się do portalu publikowania Marketplace programu Visual Studio.
  2. Jeśli nie jesteś jeszcze członkiem istniejącego wydawcy, zostanie wyświetlony monit o utworzenie wydawcy. Jeśli nie zostanie wyświetlony monit o utworzenie wydawcy, przewiń w dół strony i wybierz pozycję Publikuj rozszerzenia pod Powiązane witryny.
    • Określ identyfikator wydawcy, na przykład: mycompany-myteam.
      • Ten identyfikator jest używany jako wartość dla atrybutu publisher w pliku manifestu rozszerzeń.
    • Określ nazwę wyświetlaną wydawcy, na przykład: My Team.
  3. Przejrzyj Umowę wydawcy Marketplace i wybierz Utwórz.

Twój wydawca jest zdefiniowany. W przyszłej wersji możesz udzielić uprawnień do wyświetlania rozszerzeń wydawcy i zarządzania nimi. Łatwiej i bezpieczniej jest publikować rozszerzenia w ramach wspólnego wydawcy bez konieczności udostępniania zestawu poświadczeń między użytkownikami.

Prześlij swoje rozszerzenie

Znajdź przycisk Przekaż nowe rozszerzenie, przejdź do spakowanego pliku vsix i wybierz pozycję Przekaż.

  1. Możesz także przesłać swoje rozszerzenie za pośrednictwem interfejsu wiersza polecenia (CLI), używając polecenia tfx extension publish zamiast tfx extension create, aby pakować i publikować rozszerzenie jednym krokiem. Opcjonalnie możesz użyć --share-with aby udostępnić rozszerzenie jednemu lub większej liczbie kont po jego opublikowaniu.

    tfx extension publish --manifest-globs your-manifest.json --share-with yourOrganization
    
  2. Utwórz osobisty token dostępu (PAT).

    • Wybierz zakres „Marketplace (publikowanie)”. Ten zakres ogranicza token tylko do możliwości publikowania rozszerzeń w witrynie Marketplace.

Udostępnianie rozszerzenia

Teraz, od razu po przesłaniu rozszerzenia, znajduje się ono w witrynie Marketplace, ale nikt go nie widzi. Udostępnij ją organizacji, aby móc ją zainstalować i przetestować.

Wybierz rozszerzenie prawym przyciskiem i wybierz pozycję Udostępnij, a następnie wprowadź informacje o organizacji. Możesz również udostępnić je innym kontom, do których chcesz mieć dostęp do rozszerzenia.

Ważne

Wydawcy muszą być weryfikowani w celu publicznego udostępniania rozszerzeń. Aby uzyskać więcej informacji, zobacz Package/Publish/Install.

Teraz, gdy rozszerzenie jest współużytkowane w witrynie Marketplace, każda osoba, która chce jej używać, musi ją zainstalować.

6. Utwórz potok kompilacji i wydania, aby opublikować rozszerzenie w witrynie Marketplace

Aby zachować zadanie dopasowane do potrzeb w witrynie *Marketplace*, utwórz potok kompilacji i wydania w Azure DevOps.

Wymagania wstępne

Oprogramowanie/narzędzie

Informacje

Projekt usługi Azure DevOps

Rozszerzenie zadań Azure DevOps Extension Tasks

Zainstaluj bezpłatnie zadania rozszerzenia usługi Azure DevOps w organizacji.

Grupa zmiennych biblioteki potoków

Utwórz grupę zmiennych biblioteki potoku do przechowywania zmiennych używanych przez potok. Aby uzyskać więcej informacji, zobacz Dodawanie i używanie grup zmiennych. Grupy zmiennych można tworzyć na karcie Biblioteka usługi Azure DevOps lub za pomocą interfejsu wiersza polecenia. Użyj zmiennych w tej grupie w przepływie. Ponadto zadeklaruj następujące zmienne w grupie zmiennych:

  • publisherId: identyfikator wydawcy witryny Marketplace
  • extensionId: identyfikator rozszerzenia, zgodnie z deklaracją w pliku vss-extension.json
  • extensionName: nazwa rozszerzenia, zgodnie z deklaracją w pliku vss-extension.json
  • artifactName: nazwa artefaktu tworzonego dla pliku VSIX

Połączenie usługi

Utwórz nowe połączenie z usługą Marketplace i przyznaj uprawnienia dostępu dla wszystkich potoków.

Potok YAML

Użyj poniższego przykładu, aby utworzyć nowy potok za pomocą języka YAML. Aby uzyskać więcej informacji, zobacz Utwórz pierwszy potok i schemat 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'

Aby uzyskać więcej informacji, zobacz Określanie zdarzeń uruchamiających potoki.

Uwaga

Każde zadanie używa nowego agenta użytkownika i wymaga zainstalowania zależności.

Etapy rurociągu

Poniższa sekcja pomaga zrozumieć, jak działają etapy przetwarzania.

Etap 1. Uruchamianie i publikowanie testów jednostkowych

Ten etap uruchamia testy jednostkowe i publikuje wyniki testów w usłudze Azure DevOps.

Aby uruchomić testy jednostkowe, dodaj skrypt niestandardowy do pliku package.json, podobnie jak w poniższym przykładzie.

"scripts": {
    "testScript": "mocha ./TestFile --reporter xunit --reporter-option output=ResultsFile.xml"
},
  1. Dodaj "Use Node CLI for Azure DevOps (tfx-cli)", aby zainstalować tfx-cli na agencie kompilacji.

  2. Dodaj zadanie "npm" za pomocą polecenia "install" i wybierz folder z plikiem package.json.

  3. Dodaj zadanie "Bash", aby skompilować skrypt TypeScript do języka JavaScript.

  4. Dodaj zadanie "npm" z poleceniem "niestandardowym", wybierz folder zawierający testy jednostkowe i wprowadź testScript jako polecenie. Użyj następujących danych wejściowych:

    • Polecenie: niestandardowe
    • Folder roboczy zawierający package.json: /TestsDirectory
    • Polecenia i argumenty: testScript
  5. Dodaj zadanie "Publikuj wyniki testu". Jeśli używasz reportera Mocha XUnit, upewnij się, że format wyniku to "JUnit", a nie "XUnit". Ustaw folder wyszukiwania na katalog główny. Użyj następujących danych wejściowych:

    • Format wyniku testu: JUnit
    • Pliki wyników testów: **/ResultsFile.xml
    • Folder wyszukiwania: $(System.DefaultWorkingDirectory)

    Po opublikowaniu wyników testu dane wyjściowe na karcie testy powinny wyglądać podobnie do poniższego przykładu.

    Zrzut ekranu przedstawiający przykład wyniku testu.

Etap 2. Spakowanie rozszerzenia i publikowanie artefaktów kompilacji

  1. Dodaj "Use Node CLI for Azure DevOps (tfx-cli)", aby zainstalować tfx-cli na agencie kompilacji.

  2. Dodaj zadanie "npm" za pomocą polecenia "install" i wybierz folder z plikiem package.json.

  3. Dodaj zadanie "Bash", aby skompilować skrypt TypeScript do języka JavaScript.

  4. Aby wykonać zapytanie dotyczące istniejącej wersji, dodaj zadanie "Wersja rozszerzenia zapytania" przy użyciu następujących danych wejściowych:

    • Nawiązywanie połączenia z: Visual Studio Marketplace
    • Visual Studio Marketplace (połączenie z usługą): połączenie z usługą
    • Identyfikator wydawcy: identyfikator wydawcy witryny Marketplace programu Visual Studio
    • Identyfikator rozszerzenia: identyfikator rozszerzenia w pliku vss-extension.json
    • Zwiększ wersję: Poprawka
    • Zmienna wyjściowa: Task.Extension.Version
  5. Aby spakować rozszerzenia na podstawie pliku manifestu Json, dodaj zadanie "Pakowanie rozszerzenia" korzystając z następujących danych wejściowych:

    • Folder manifestów głównych: wskazuje katalog główny zawierający plik manifestu. Na przykład $(System.DefaultWorkingDirectory) to katalog główny
    • Plik manifestu: vss-extension.json
    • Identyfikator wydawcy: identyfikator wydawcy witryny Marketplace programu Visual Studio
    • Identyfikator rozszerzenia: identyfikator rozszerzenia w pliku vss-extension.json
    • Nazwa rozszerzenia: nazwa rozszerzenia w pliku vss-extension.json
    • Wersja rozszerzenia: $(Task.Extension.Version)
    • Nadpisz wersję zadań: zaznaczone (prawda)
    • Typ zastąpienia: zastąp tylko poprawkę (1.0.r)
    • Widoczność rozszerzenia: Jeśli rozszerzenie jest nadal w rozwoju, ustaw wartość na prywatną. Aby udostępnić rozszerzenie publicznie, ustaw wartość na public.
  6. Aby skopiować do opublikowanych plików, dodaj zadanie "Kopiuj pliki" przy użyciu następujących danych wejściowych:

    • Zawartość: wszystkie pliki do skopiowania w celu ich publikacji jako artefakt
    • Folder docelowy: folder, do którego pliki są kopiowane
      • Na przykład: $(Build.ArtifactStagingDirectory)
  7. Dodaj "Publikuj artefakty kompilacji", aby opublikować artefakty do użycia w innych zadaniach lub pipeline'ach. Użyj następujących danych wejściowych:

    • Ścieżka do opublikowania: ścieżka do folderu zawierającego publikowane pliki
      • Na przykład: $(Build.ArtifactStagingDirectory)
    • Nazwa artefaktu: nazwa nadana artefaktowi
    • Lokalizacja publikowania artefaktów: wybierz "Azure Pipelines", aby użyć artefaktu w przyszłych zadaniach

Etap 3. Pobieranie artefaktów kompilacji i publikowanie rozszerzenia

  1. Aby zainstalować tfx-cli na agencie kompilacji, dodaj "Use Node CLI for Azure DevOps (tfx-cli)".

  2. Aby pobrać artefakty do nowego zadania, dodaj zadanie "Pobierz artefakty kompilacji" przy użyciu następujących danych wejściowych:

    • Pobierz artefakty wygenerowane przez: Jeśli pobierasz artefakt w nowym zadaniu z tego samego potoku, wybierz opcję "Bieżąca kompilacja". Jeśli pobierasz artefakt w nowym potoku, wybierz opcję "Określona kompilacja".
    • Typ pobierania: wybierz pozycję "Określony artefakt", aby pobrać wszystkie opublikowane pliki.
    • Nazwa artefaktu: nazwa opublikowanego artefaktu.
    • Katalog docelowy: folder, w którym mają być pobierane pliki.
  3. Aby uzyskać zadanie "Publikuj rozszerzenie", użyj następujących danych wejściowych:

    • Nawiązywanie połączenia z: Visual Studio Marketplace
    • Połączenie z witryną Marketplace programu Visual Studio: ServiceConnection
    • Typ pliku wejściowego: plik VSIX
    • Plik VSIX: /Publisher.*.vsix
    • Identyfikator wydawcy: identyfikator wydawcy witryny Marketplace programu Visual Studio
    • Identyfikator rozszerzenia: identyfikator rozszerzenia w pliku vss-extension.json
    • Nazwa rozszerzenia: nazwa rozszerzenia w pliku vss-extension.json
    • Widoczność rozszerzenia: prywatna lub publiczna

Opcjonalnie: Instalowanie i testowanie rozszerzenia

Zainstaluj rozszerzenie, które zostało Ci udostępnione w kilku krokach:

  1. W panelu sterowania organizacji (https://dev.azure.com/{organization}/_admin) przejdź do strony administracyjnej kolekcji projektów.
  2. Na karcie Rozszerzenia znajdź rozszerzenie w grupie "Rozszerzenia udostępnione mi" i wybierz link rozszerzenia.
  3. Zainstaluj rozszerzenie.

Jeśli nie widzisz karty Rozszerzenia , upewnij się, że jesteś w panelu sterowania (strona administracyjna na poziomie https://dev.azure.com/{organization}/_adminkolekcji projektów), a nie na stronie administracyjnej projektu.

Jeśli nie widzisz karty Rozszerzenia , rozszerzenia nie są włączone dla twojej organizacji. Aby uzyskać wczesny dostęp do funkcji rozszerzeń, dołącz do programu Visual Studio Partner Program.

Aby spakować i opublikować rozszerzenia usługi Azure DevOps w witrynie Visual Studio Marketplace, możesz pobrać Zadania rozszerzeń Azure DevOps.

Często zadawane pytania

Zapoznaj się z następującymi często zadawanymi pytaniami dotyczącymi dodawania niestandardowych zadań kompilacji lub wydawania w rozszerzeniach usługi Azure DevOps.

.: Jak mogę ograniczyć użycie poleceń usługi Azure Pipelines dla zadania?

Możesz ograniczyć użycie i zmienne poleceń usługi Azure Pipelines, które są ustawiane przez zadanie. Ta akcja może być przydatna, aby zapobiec nieograniczonemu dostępowi do zmiennych/poleceń vso dla skryptów niestandardowych wykonywanych przez zadanie. Zalecamy skonfigurowanie go dla nowych zadań. Aby zastosować, może być konieczne dodanie następującej instrukcji do pliku task.json:

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

Jeśli dla parametru restricted określono wartość mode, można wykonać tylko następujące polecenia przez zadanie:

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

Ograniczenia settableVariables umożliwiają przekazanie listy dozwolonych zmiennych, które są ustawiane za pomocą poleceń setvariable lub prependpath. Umożliwia również podstawowe wyrażenia regularne. Jeśli na przykład lista dozwolonych to: ['abc', 'test*'], ustawienie abc, test lub test1 jako zmiennych z dowolną wartością lub dodanie ich na początku ścieżki powiedzie się, ale jeśli spróbujesz ustawić jako zmienną proxy, zostanie wyświetlone ostrzeżenie. Pusta lista oznacza, że żadne zmienne nie są zmieniane przez zadanie.

Jeśli pominięto klucz settableVariables lub commands, odpowiednie ograniczenie nie zostanie zastosowane.

Funkcja ograniczeń jest dostępna w wersji agenta 2.182.1 .

Q: W jaki sposób sygnał anulowania jest obsługiwany przez zadanie?

Agent potoku wysyła sygnały SIGINT i SIGTERM do odpowiedniego procesu podrzędnego. Nie ma jawnych środków w bibliotece zadań do przetworzenia. Aby uzyskać więcej informacji, zobacz Anulowanie zadań agenta.

.: Jak mogę usunąć zadanie z kolekcji projektów?

1: Nie obsługujemy automatycznego usuwania zadań. Automatyczne usuwanie nie jest bezpieczne i przerywa istniejące przepływy, które już używają takich zadań. Można jednak oznaczyć zadania jako przestarzałe. W tym celu wyrzuć wersję zadania i oznacz zadanie jako przestarzałe.

Jak mogę uaktualnić zadanie niestandardowe do najnowszej wersji Node.js?

1: Zalecamy uaktualnienie do najnowszej wersji środowiska Node. Aby uzyskać przykładowe informacje, zobacz Uaktualnianie zadań do Node 20.

Agenci hostowani przez firmę Microsoft i różne wersje Azure DevOps Server mają różne cykle życia, co prowadzi do zainstalowania różnych wersji Node runner w zależności od tego, gdzie jest uruchomione zadanie. Aby zapewnić zgodność agentów z różnymi wersjami Node runner, plik task.json może zawierać wiele sekcji wykonania. W poniższym przykładzie agenci Azure Pipeline z Node 20 runner używają go domyślnie, podczas gdy agenci bez niego wracają do używania implementacji Node 10.

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

Aby uaktualnić zadania:

  • Aby upewnić się, że kod działa zgodnie z oczekiwaniami, przetestuj zadania w różnych wersjach środowiska uruchomieniowego Node.

  • W sekcji wykonywania zadania zaktualizuj z Node lub Node10 na Node16 lub Node20.

  • Aby obsługiwać starsze wersje serwera, należy pozostawić element docelowy Node/Node10 . Starsze wersje usługi Azure DevOps Server mogą nie zawierać najnowszej wersji modułu uruchamiającego Node.js.

  • Możesz udostępnić punkt wejścia zdefiniowany w obiekcie docelowym lub mieć obiekty docelowe zoptymalizowane pod kątem używanej wersji środowiska Node.

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

Ważne

Jeśli nie dodasz obsługi runnera Node 20 do zadań niestandardowych, nie będą one działać na agentach zainstalowanych z kanału wydania pipelines-agent-*.