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ę usługi GitHub zadania serwera.

Wymagania wstępne

Aby utworzyć rozszerzenia dla usługi Azure DevOps, potrzebne jest następujące oprogramowanie i narzędzia.

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 npmpolecenia , składnik Node.js, uruchamiając polecenie 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 wydania powinien wyglądać podobnie do poniższego przykładu 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 Linux, zastąp wszystkie wystąpienia $env:<var>=<val> elementu ciągiem export <var>=<val>.

Tworzenie szkieletu 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 package.json plik. 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 element node_modules na 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 polecenie lub npm prune --production, lub 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 wpisywanie w języku 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ć zaewidencjonowane.

    echo node_modules > .gitignore
    
  6. Zainstaluj platformę Mocha jako zależność programistyczne.

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

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

    Uwaga

    Upewnij się, że język TypeScript jest instalowany globalnie z narzędziem npm w środowisku projektowym, więc tsc polecenie jest 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 tworzenie szkieletów zostało ukończone, możemy utworzyć zadanie niestandardowe.

  1. task.json Utwórz plik w folderzebuildandreleasetask. Plik task.json zawiera opis zadania kompilacji/wydania i jest używany przez system kompilacji/wydania do renderowania opcji konfiguracji dla użytkownika oraz dowiedzieć się, które skrypty do wykonania w czasie kompilacji/wydania.

  2. Skopiuj poniższy kod i zastąp element {{placeholders}} informacjami o zadaniu. Najważniejszym symbolem zastępczym taskguidjest element , który 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. index.ts Utwórz plik przy użyciu następującego kodu jako odwołania. 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. Wprowadź ciąg "tsc" z folderu, buildandreleasetask aby skompilować index.js plik z pliku index.ts.

składniki task.json

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

Właściwości opis
id Unikatowy identyfikator GUID zadania.
name Nazwa bez spacji.
friendlyName Nazwa opisowa (dozwolone spacje).
description Szczegółowy opis tego, co wykonuje zadanie.
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 podczas uruchamiania zadania kompilacji lub wydania. To zadanie oczekuje danych wejściowych o nazwie samplestring.
execution Opcje wykonywania dla tego zadania, w tym skrypty.
restrictions Ograniczenia stosowane do zadania dotyczącego poleceń usługi GitHub Codespaces mogą być wywoływane , a zmienne mogą ustawiać zadania. 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 modułach uruchamiający zadania i o tym, jak uwzględnić najnowszą wersję węzła w task.json, zobacz Wskazówki dotyczące aktualizacji modułu uruchamiającego węzły dla autorów zadań usługi Azure Pipelines.

2. Testowanie jednostkowe skryptów zadań

Przetestuj 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. Dodaj następujący przykładowy test powodzenia do pliku _suite.ts , aby uruchomić moduł uruchamiający pozorowanie zadania.

        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 w katalogu testowym failure.ts jako moduł uruchamiający zadania makiety 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 niepowodzenia sprawdza, czy gdy narzędzie otrzymuje nieprawidłowe lub niekompletne dane wejściowe, kończy się niepowodzeniem w oczekiwany sposób z przydatnymi danymi wyjściowymi.

  6. Dodaj następujący kod do _suite.ts pliku, aby uruchomić moduł uruchamiający pozorowanie zadania.

    it('it should fail if tool returns 1', function(done: Mocha.Done) {
        this.timeout(1000);
    
        let tp = path.join(__dirname, 'failure.js');
        let tr: ttm.MockTestRunner = new ttm.MockTestRunner(tp);
    
        tr.run();
        console.log(tr.succeeded);
        assert.equal(tr.succeeded, false, 'should have failed');
        assert.equal(tr.warningIssues.length, 0, "should have no warnings");
        assert.equal(tr.errorIssues.length, 1, "should have 1 error issue");
        assert.equal(tr.errorIssues[0], 'Bad input was given', 'error issue output');
        assert.equal(tr.stdout.indexOf('Hello bad'), -1, "Should not display Hello bad");
    
        done();
    });
    
  7. Uruchom testy.

    tsc
    mocha tests/_suite.js
    

    Oba testy powinny zostać wykonane pomyślnie. Jeśli chcesz uruchomić testy z bardziej pełnymi danymi wyjściowymi (co można zobaczyć 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 images z 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

Właściwości 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 ma identyfikator współtworzenia.
type Typ udziału. Powinna być ms.vss-distributed-task.task.
targets Współtworzenie "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łaściwość opis
path Ścieżka pliku lub folderu względem home katalogu.

Uwaga

Aby uzyskać więcej informacji na temat pliku manifestu rozszerzenia, takich jak jego właściwości i ich działania, zobacz dokumentację 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 utworzeniu interfejsu wiersza polecenia tfx przejdź do katalogu macierzystego 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 przekaż --rev-version przełącznik wiersza polecenia. Zwiększa to numer wersji poprawki rozszerzenia i zapisuje nową wersję w manifeście. Należy cofnąć zarówno wersję zadania, jak i wersję rozszerzenia, aby można było przeprowadzić aktualizację. 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 witryny 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ół do dołu strony i wybierz pozycję Publikuj rozszerzenia w obszarze Powiązane witryny.
    • Określ identyfikator wydawcy, na przykład: mycompany-myteam.
      • Ten identyfikator jest używany jako wartość atrybutu w pliku manifestu publisher rozszerzeń.
    • Określ nazwę wyświetlaną wydawcy, na przykład: My Team.
  3. Przejrzyj umowę wydawcy witryny Marketplace i wybierz pozycję Utwórz.

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.

Przekazywanie rozszerzenia

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

  1. Rozszerzenie można również przekazać za pomocą interfejsu wiersza polecenia (CLI), używając tfx extension publish polecenia zamiast tfx extension create spakować i opublikować rozszerzenie w jednym kroku. Opcjonalnie możesz użyć --share-with polecenia , aby udostępnić rozszerzenie jednemu lub większej liczbie kont po jej 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, po przekazaniu rozszerzenia, znajduje się on w witrynie Marketplace, ale nikt jej 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 .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. Tworzenie potoku kompilacji i wydania w celu opublikowania rozszerzenia w witrynie Marketplace

Utwórz potok kompilacji i wydania w usłudze Azure DevOps, aby ułatwić obsługę niestandardowego zadania w witrynie Marketplace.

Wymagania wstępne

Oprogramowanie/narzędzie

Informacje

Projekt usługi Azure DevOps

Rozszerzenie 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 potoku. 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 z usługą

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 Tworzenie pierwszego potoku i schematu 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ń wyzwalających potoki.

Uwaga

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

Etapy potoku

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

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 polecenie "Use Node CLI for Azure DevOps (tfx-cli)" (Używanie interfejsu wiersza polecenia węzła dla usługi Azure DevOps (tfx-cli)", aby zainstalować interfejs wiersza polecenia 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" za pomocą polecenia "niestandardowe", wybierz folder zawierający testy jednostkowe i wprowadź dane wejściowe 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 polecenie "Use Node CLI for Azure DevOps (tfx-cli)" (Używanie interfejsu wiersza polecenia węzła dla usługi Azure DevOps (tfx-cli)", aby zainstalować interfejs wiersza polecenia 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 "Wersja rozszerzenia zapytania", aby wykonać zapytanie o istniejącą wersję rozszerzenia. Użyj 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. Dodaj zadanie "Rozszerzenie pakietu", aby spakować rozszerzenia na podstawie manifestu Json. Użyj 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
    • Pliki 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)
    • Przesłoń wersję zadań: sprawdzono (true)
    • Typ zastąpienia: zastąp tylko poprawkę (1.0.r)
    • Widoczność rozszerzenia: jeśli rozszerzenie jest nadal w programowania, ustaw wartość na prywatną. Aby zwolnić rozszerzenie do publicznej wersji, ustaw wartość na publiczną
  6. Dodaj zadanie "Kopiuj pliki", aby skopiować opublikowane pliki. Użyj następujących danych wejściowych:

    • Zawartość: wszystkie pliki do skopiowania do publikowania ich jako artefaktu
    • Folder docelowy: folder, do którego pliki są kopiowane
      • Na przykład: $(Build.ArtifactStagingDirectory)
  7. Dodaj pozycję "Publikuj artefakty kompilacji", aby opublikować artefakty do użycia w innych zadaniach lub potokach. 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 pozycję "Azure Pipelines", aby użyć artefaktu w przyszłych zadaniach

Etap 3. Pobieranie artefaktów kompilacji i publikowanie rozszerzenia

  1. Dodaj polecenie "Use Node CLI for Azure DevOps (tfx-cli)" (Używanie interfejsu wiersza polecenia węzła dla usługi Azure DevOps (tfx-cli)", aby zainstalować interfejs wiersza polecenia tfx-cli na agencie kompilacji.

  2. Dodaj zadanie "Pobierz artefakty kompilacji", aby pobrać artefakty do nowego zadania. Użyj następujących danych wejściowych:

    • Pobierz artefakty utworzone przez: Jeśli pobierasz artefakt w nowym zadaniu z tego samego potoku, wybierz pozycję "Bieżąca kompilacja". Jeśli pobierasz nowy potok, wybierz pozycję "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. Ostatnim potrzebnym zadaniem jest 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 rozszerzenia usługi 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 restricted dla parametru określono mode wartość , można wykonać tylko następujące polecenia według zadania:

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

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

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

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

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

1: Agent potoku wysyła i SIGTERM sygnalizuje SIGINT odpowiedni proces podrzędny. 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 potoki, 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 najnowszego węzła?

1: Zalecamy uaktualnienie do najnowszej wersji środowiska Node. Aby uzyskać na przykład informacje, zobacz Uaktualnianie zadań do węzła 20.

Ponieważ agenci hostowani przez firmę Microsoft i różne wersje usługi Azure DevOps Server mają różne cykle życia, mogą istnieć różne wersje modułu uruchamiającego węzły, w zależności od tego, gdzie jest uruchomione zadanie. Aby można było uruchomić to samo zadanie na agentach z różnymi wersjami modułu uruchamiającego węzły, plik task.json może zawierać wiele sekcji wykonywania. W poniższym przykładzie agenci usługi Azure Pipeline, którzy obejmują moduł uruchamiający węzeł 20, domyślnie wybiorą go, a ci, którzy nie powrócą do implementacji środowiska Node 10.

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

Aby uaktualnić zadania:

  • Przetestuj zadania w różnych wersjach modułu uruchamiającego węzły, aby upewnić się, że kod działa zgodnie z oczekiwaniami.

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

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

  • 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

Dodanie obsługi modułu uruchamiającego węzła 20 w zadaniach niestandardowych spowoduje niepowodzenie zadań na agentach zainstalowanych z kanału informacyjnego pipelines-agent-* wydania.