Добавление расширения задачи настраиваемых конвейеров

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

Узнайте, как установить расширения в организации для пользовательских задач сборки или выпуска в Azure DevOps. Дополнительные сведения см. в статье "Что такое Azure Pipelines"?

Примечание.

В этой статье рассматриваются задачи агента в расширениях на основе агента. Дополнительные сведения о задачах сервера и расширениях на основе сервера см. в документации по GitHub по задачам сервера.

Необходимые компоненты

Чтобы создать расширения для Azure DevOps, вам потребуется следующее программное обеспечение и средства.

Программное обеспечение или средство Информация
Организация Azure DevOps Создайте организации.
Текстовый редактор Для многих процедур мы используем Visual Studio Code, который обеспечивает поддержку intellisense и отладки. Скачайте последнюю версию.
Node.js Скачайте последнюю версию.
npmjs.com 4.0.2 или более поздней версии Компилятор TypeScript. Скачайте последнюю версию.
tfx-cli Упаковайте расширение с помощью кроссплатформенного интерфейса командной строки для Azure DevOps. using npm, компонент Node.js, выполнив команду npm i -g tfx-cli.
Пакет SDK для расширения Azure DevOps Установите пакет azure-devops-extension-sdk.
home Каталог для проекта Каталог home расширения задачи сборки или выпуска должен выглядеть следующим образом после выполнения действий, описанных в этой статье.
|--- README.md    
|--- images                        
    |--- extension-icon.png  
|--- buildandreleasetask            // where your task scripts are placed
|--- vss-extension.json             // extension's manifest

Внимание

Компьютер разработки должен запустить последнюю версию Node , чтобы убедиться, что написанный код совместим с рабочей средой агента и последней версией, отличной от предварительной версии azure-pipelines-task-lib. Обновите файл task.json следующим образом:

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

1. Создание настраиваемой задачи

Выполните каждую часть этой процедуры в папке buildandreleasetask .

Примечание.

В этом примере пошаговые инструкции используют Windows с PowerShell. Мы сделали его универсальным для всех платформ, но синтаксис для получения переменных среды отличается. Если вы используете Mac или Linux, замените все экземпляры $env:<var>=<val> export <var>=<val>.

Создание шаблонов задач

  1. Создайте структуру папок для задачи и установите необходимые библиотеки и зависимости.

  2. Откройте командное окно PowerShell, перейдите в buildandreleasetask папку и выполните следующую команду.

    npm init --yes
    

    npm initpackage.json создает файл. Мы добавили --yes параметр для принятия всех параметров по умолчанию npm init .

    Совет

    Агент не устанавливает необходимые модули автоматически, так как ожидается, что папка задачи будет включать модули узлов. Чтобы устранить эту проблему, скопируйте в node_modules buildandreleasetask. По мере того как задача становится больше, легко превысить ограничение размера (50 МБ) файла VSIX. Прежде чем скопировать папку узла, может потребоваться выполнить npm install --production или npm prune --productionнаписать скрипт для сборки и упаковки всего.

  3. Добавьте azure-pipelines-task-lib в библиотеку.

    npm install azure-pipelines-task-lib --save
    
  4. Убедитесь, что для внешних зависимостей установлены типизированные тексты TypeScript.

    npm install @types/node --save-dev
    npm install @types/q --save-dev
    
  5. .gitignore Создайте файл и добавьте в него node_modules. Процесс сборки должен выполняться npm install и typings install таким образом, чтобы node_modules создавались каждый раз и не должны быть возвращены.

    echo node_modules > .gitignore
    
  6. Установите Mocha в качестве зависимости разработки.

    npm install mocha --save-dev -g
    npm install sync-request --save-dev
    npm install @types/mocha --save-dev
    
  7. Выберите TypeScript версии 2.3.4 или 4.6.3.

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

    Примечание.

    Убедитесь, что TypeScript устанавливается глобально с npm в среде разработки, поэтому tsc команда доступна. Если пропустить этот шаг, TypeScript версии 2.3.4 используется по умолчанию, и вам по-прежнему необходимо глобально установить пакет, чтобы tsc она была доступна.

  8. Создание tsconfig.json параметров компилятора. Этот файл гарантирует, что файлы TypeScript компилируются в файлы JavaScript.

    tsc --init --target es2022
    

Создание задачи

Теперь, когда формирование шаблонов завершено, мы можем создать настраиваемую задачу.

  1. task.json Создайте файл в папкеbuildandreleasetask. Файл task.json описывает задачу сборки и выпуска и представляет собой то, что система сборки и выпуска использует для отрисовки параметров конфигурации пользователю и чтобы узнать, какие скрипты будут выполняться во время сборки или выпуска.

  2. Скопируйте следующий код и замените {{placeholders}} сведения о задаче. Наиболее важным является заполнитель taskguid, и он должен быть уникальным.

    {
     "$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 Создайте файл с помощью следующего кода в качестве ссылки. Этот код выполняется при вызове задачи.

    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. Введите "tsc" из buildandreleasetask папки, чтобы скомпилировать index.js файл из index.ts.

компоненты task.json

См. следующие описания некоторых компонентов task.json файла.

Свойство Description
id Уникальный GUID для задачи.
name Имя без пробелов.
friendlyName Описательное имя (разрешенные пробелы).
description Подробное описание того, что делает ваша задача.
author Короткая строка, описывающая сущность, разрабатывающую задачу сборки или выпуска, например "Корпорация Майкрософт".
instanceNameFormat Как задача отображается в списке шагов сборки и выпуска. Значения переменных можно использовать с помощью $(variablename).
groups Описывает логическую группирование свойств задач в пользовательском интерфейсе.
inputs Входные данные, используемые при выполнении задачи сборки или выпуска. Эта задача ожидает входные данные с примерами имен.
execution Параметры выполнения для этой задачи, включая скрипты.
restrictions Ограничения, применяемые к задаче о задаче задач GitHub Codespaces, могут вызываться, а задача переменных может быть задана. Рекомендуется указать режим ограничения для новых задач.

Примечание.

Создайте следующую id команду в PowerShell:

(New-Guid).Guid

Дополнительные сведения см. в справочнике по задаче сборки и выпуска.

Выполнение задачи

Запустите задачу с node index.js помощью PowerShell.

В следующем примере задача завершается сбоем, так как входные данные не были предоставлены (samplestring это обязательные входные данные).

 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

В качестве исправления можно задать входные samplestring данные и снова запустить задачу.

$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

На этот раз задача завершилась успешно, так как samplestring она была предоставлена, и она правильно выдала сообщение "Hello Human!"

Совет

Сведения о различных запусках задач и о том, как включить последнюю версию узла в task.json, см . в руководстве по обновлению средства выполнения узла для авторов задач Azure Pipelines.

2. Модульное тестирование скриптов задач

Выполните модульные тесты, чтобы быстро протестировать скрипт задачи, а не внешние средства, которые он вызывает. Проверьте все аспекты путей успешности и сбоя.

  1. Установите средства тестирования. В этой процедуре мы используем Mocha в качестве тестового драйвера.

    npm install mocha --save-dev -g
    npm install sync-request --save-dev
    npm install @types/mocha --save-dev
    
  2. Создайте папку tests _suite.ts , содержащую файл со следующим содержимым:

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

    Совет

    Тестовая папка должна находиться в папке buildandreleasetask. Если вы получаете ошибку синхронизации, вы можете обойти ее, добавив запрос синхронизации в папку buildandreleasetask с помощью команды npm i --save-dev sync-request.

  3. Создайте файл в тестовом success.ts каталоге со следующим содержимым. Это создание файла имитирует выполнение задачи и макетирует все вызовы внешних методов.

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

    Тест успешного выполнения проверяет, что с соответствующими входными данными он успешно завершается без ошибок или предупреждений и возвращает правильные выходные данные.

  4. Добавьте следующий пример теста успешности в _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. Создайте файл в тестовом failure.ts каталоге в качестве средство выполнения задачи со следующим содержимым:

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

    Тест сбоя проверяет, что если средство получает плохие или неполные входные данные, он завершается ошибкой в ожидаемом порядке с полезными выходными данными.

  6. Добавьте следующий код в _suite.ts файл, чтобы запустить средство выполнения задачи.

    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. Запустите тесты.

    tsc
    mocha tests/_suite.js
    

    Оба теста должны пройти. Если вы хотите выполнить тесты с более подробными выходными данными (то, что вы увидите в консоли сборки), задайте переменную среды: TASK_TEST_TRACE=1

    $env:TASK_TEST_TRACE=1
    

3. Создание файла манифеста расширения

Манифест расширения содержит все сведения о расширении. Он содержит ссылки на файлы, включая папки задач и папки изображений. Убедитесь, что вы создали папку изображений с extension-icon.png. В следующем примере представлен манифест расширения, содержащий задачу сборки или выпуска.

Скопируйте следующий .json код и сохраните его в качестве vss-extension.json файла в каталоге home .

Не создавайте этот файл в папке 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"
            }
        }
    ]
}

Примечание.

Измените имя издателя на имя издателя. Дополнительные сведения см. в статье "Создание издателя".

Участие в проекте

Свойство Description
id Идентификатор вклада. Должен быть уникальным в пределах расширения. Не нужно соответствовать имени задачи сборки или выпуска. Обычно имя задачи сборки или выпуска находится в идентификаторе вклада.
type Тип вклада. Должен быть ms.vss-distributed-task.task.task.
targets Взносы ,предназначенные для этого вклада. Должно быть ms.vss-distributed-task.tasks.
properties.name Имя задачи. Это имя должно соответствовать имени папки соответствующей автономной задачи сборки или конвейера выпуска.

Файлы

Свойство Description
path Путь к файлу или папке home относительно каталога.

Примечание.

Дополнительные сведения о файле манифеста расширения, например его свойствах и возможностях, см. в справочнике по манифесту расширения.

4. Упаковка расширения

Упаковайте все файлы вместе, чтобы получить расширение в Visual Studio Marketplace. Все расширения упаковываются в виде VSIX 2.0-совместимых vsix-файлов. Корпорация Майкрософт предоставляет кроссплатформенный интерфейс командной строки (CLI) для упаковки расширения.

После получения tfx-cli перейдите в домашний каталог расширения и выполните следующую команду:

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

Примечание.

При каждом обновлении необходимо увеличить расширение или версию интеграции. При обновлении существующего расширения обновите версию манифеста или передайте переключатель командной --rev-version строки. Это увеличивает номер версии исправления расширения и сохраняет новую версию в манифесте. Для обновления необходимо обновить версию задачи и версию расширения. tfx extension create --manifest-globs vss-extension.json --rev-version обновляет только версию расширения, а не версию задачи. Дополнительные сведения см. в разделе "Задача сборки" в GitHub.

После того как упакованое расширение находится в VSIX-файле, вы готовы опубликовать расширение в Marketplace.

5. Публикация расширения

Чтобы опубликовать расширение, сначала создайте издателя, а затем отправьте расширение и, наконец , поделитесь им.

Создание издателя

Все расширения, включая расширения от Корпорации Майкрософт, определяются как предоставляемые издателем. Если вы еще не являетесь членом существующего издателя, создайте его.

  1. Войдите на портал публикации Visual Studio Marketplace.
  2. Если вы еще не являетесь членом существующего издателя, вам будет предложено создать издателя. Если вам не будет предложено создать издателя, прокрутите вниз до нижней части страницы и выберите "Опубликовать расширения" в разделе "Связанные сайты".
    • Укажите идентификатор издателя, например: mycompany-myteam
      • Этот идентификатор используется в качестве значения атрибута publisher в файле манифеста расширений.
    • Укажите отображаемое имя издателя, например: My Team
  3. Просмотрите соглашение издателя Marketplace и нажмите кнопку "Создать".

Определяется издатель. В будущем выпуске можно предоставить разрешения для просмотра расширений издателя и управления ими. Проще и безопаснее публиковать расширения под общим издателем без необходимости совместного использования набора учетных данных для пользователей.

Отправка расширения

Найдите кнопку "Отправить новое расширение", перейдите в упакованный VSIX-файл и нажмите кнопку "Отправить".

  1. Вы также можете отправить расширение с помощью интерфейса командной строки (CLI) с помощью tfx extension publish команды, а не tfx extension create для упаковки и публикации расширения на одном шаге. Вы также можете использовать --share-with для совместного использования расширения с одной или несколькими учетными записями после публикации.

    tfx extension publish --manifest-globs your-manifest.json --share-with yourOrganization
    
  2. Создайте личный маркер доступа (PAT).

    • Выберите область "Marketplace (публикация)". Эта область ограничивает маркер только возможностью публикации расширений в Marketplace.

Общий доступ к расширению

Теперь, когда вы загрузили расширение, он находится в Marketplace, но никто не видит его. Поделитесь ею с вашей организацией, чтобы можно было установить и протестировать ее.

Выберите расширение правой кнопкой мыши и выберите "Поделиться" и введите сведения о организации. Вы также можете поделиться им с другими учетными записями, которыми вы хотите получить доступ к вашему расширению.

Внимание

Издатели должны быть проверены для общего доступа к расширениям. Дополнительные сведения см. в разделе "Package/Publish/Install".

Теперь, когда расширение предоставлено в Marketplace, любой пользователь, желающий использовать его, должен установить его.

6. Создание конвейера сборки и выпуска для публикации расширения в Marketplace

Создайте конвейер сборки и выпуска в Azure DevOps для поддержки настраиваемой задачи в Marketplace.

Необходимые компоненты

Программное обеспечение или средство

Информация

Azure DevOps Projects

Расширение задач расширения Azure DevOps

Установите бесплатно задачи расширения Azure DevOps в организации.

Группа переменных библиотек конвейера

Создайте группу переменных библиотеки конвейера для хранения переменных, используемых конвейером. Дополнительные сведения см. в разделе "Добавление и использование групп переменных". Группы переменных можно сделать на вкладке библиотеки Azure DevOps или с помощью интерфейса командной строки. Используйте переменные в этой группе в конвейере. Кроме того, объявите следующие переменные в группе переменных:

  • publisherId: идентификатор издателя Marketplace
  • extensionId: идентификатор расширения, объявленный в файле vss-extension.json
  • extensionName: имя расширения, объявленное в файле vss-extension.json
  • artifactName: имя создаваемого артефакта для VSIX-файла

Подключение службы

Создайте новое подключение службы Marketplace и предоставьте разрешения доступа для всех конвейеров.

Конвейер YAML

Используйте следующий пример, чтобы создать новый конвейер с помощью YAML. Дополнительные сведения см. в статье "Создание первого конвейера и схемы 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'

Дополнительные сведения см. в разделе "Указание событий, которые активируют конвейеры".

Примечание.

Каждое задание использует новый агент пользователя и требует установки зависимостей.

Этапы конвейера

В следующем разделе показано, как работают этапы конвейера.

Этап 1. Запуск и публикация модульных тестов

На этом этапе выполняются модульные тесты и публикуются результаты теста в Azure DevOps.

Чтобы запустить модульные тесты, добавьте пользовательский скрипт в файл package.json, как показано в следующем примере.

"scripts": {
    "testScript": "mocha ./TestFile --reporter xunit --reporter-option output=ResultsFile.xml"
},
  1. Добавьте команду Node CLI для Azure DevOps (tfx-cli), чтобы установить tfx-cli в агент сборки.

  2. Добавьте задачу npm с помощью команды "install" и нацельте папку с помощью файла package.json.

  3. Добавьте задачу "Bash", чтобы скомпилировать TypeScript в JavaScript.

  4. Добавьте задачу npm с помощью команды custom, нацелив папку, содержащую модульные тесты, и входные данные testScript в качестве команды. Используйте следующие входные данные:

    • Команда: настраиваемая
    • Рабочая папка, содержащая package.json: /TestDirectory
    • Команды и аргументы: testScript
  5. Добавьте задачу "Опубликовать результаты теста". Если вы используете репортер Mocha XUnit, убедитесь, что формат результата — JUnit, а не XUnit. Задайте папку поиска корневому каталогу. Используйте следующие входные данные:

    • Формат результатов теста: JUnit
    • Файлы результатов теста: **/ResultsFile.xml
    • Папка поиска: $(System.DefaultWorkingDirectory)

    После публикации результатов теста выходные данные на вкладке тестов должны выглядеть следующим образом.

    Снимок экрана: пример результата теста.

Этап 2. Упаковка расширения и публикация артефактов сборки

  1. Добавьте команду Node CLI для Azure DevOps (tfx-cli), чтобы установить tfx-cli в агент сборки.

  2. Добавьте задачу npm с помощью команды "install" и нацельте папку с помощью файла package.json.

  3. Добавьте задачу "Bash", чтобы скомпилировать TypeScript в JavaScript.

  4. Добавьте задачу "Версия расширения запроса" для запроса существующей версии расширения. Используйте следующие входные данные:

    • Подключение к: Visual Studio Marketplace
    • Visual Studio Marketplace (подключение к службе): подключение к службе
    • Идентификатор издателя: идентификатор издателя Visual Studio Marketplace
    • Идентификатор расширения: идентификатор расширения в файле vss-extension.json
    • Увеличение версии: исправление
    • Выходная переменная: Task.Extension.Version
  5. Добавьте задачу "Расширение пакета" для упаковки расширений на основе json манифеста. Используйте следующие входные данные:

    • Папка корневых манифестов: указывает на корневой каталог, содержащий файл манифеста. Например, $(System.DefaultWorkingDirectory) является корневым каталогом
    • Файлы манифеста: vss-extension.json
    • Идентификатор издателя: идентификатор издателя Visual Studio Marketplace
    • Идентификатор расширения: идентификатор расширения в файле vss-extension.json
    • Имя расширения: имя расширения в файле vss-extension.json
    • Версия расширения: $(Task.Extension.Version)
    • Переопределение версии задач: установлен (true)
    • Переопределение типа: замена только исправления (1.0.r)
    • Видимость расширения: если расширение по-прежнему находится в разработке, задайте для параметра private значение. Чтобы освободить расширение для общедоступного, задайте значение для общедоступного
  6. Добавьте задачу "Копировать файлы" для копирования опубликованных файлов. Используйте следующие входные данные:

    • Содержимое: все файлы, которые необходимо копировать для публикации в качестве артефакта
    • Целевая папка: папка, в которую копируются файлы
      • Например: $(Build.ArtifactStagingDirectory)
  7. Добавьте "Опубликовать артефакты сборки", чтобы опубликовать артефакты для использования в других заданиях или конвейерах. Используйте следующие входные данные:

    • Путь к публикации: путь к папке, содержащей опубликованные файлы
      • Например: $(Build.ArtifactStagingDirectory)
    • Имя артефакта: имя, заданное артефакту
    • Расположение публикации артефактов: выберите "Azure Pipelines", чтобы использовать артефакт в будущих заданиях

Этап 3. Скачивание артефактов сборки и публикация расширения

  1. Добавьте команду Node CLI для Azure DevOps (tfx-cli), чтобы установить tfx-cli в агент сборки.

  2. Добавьте задачу "Скачать артефакты сборки", чтобы скачать артефакты в новое задание. Используйте следующие входные данные:

    • Скачайте артефакты, созданные: если вы скачиваете артефакт на новом задании из того же конвейера, выберите "Текущая сборка". Если вы скачивание на новом конвейере, выберите "Конкретная сборка".
    • Тип скачивания: выберите "Конкретный артефакт", чтобы скачать все опубликованные файлы.
    • Имя артефакта: имя опубликованного артефакта.
    • Каталог назначения: папка, в которой должны быть скачаны файлы.
  3. Последняя задача, которую требуется, — задача "Опубликовать расширение". Используйте следующие входные данные:

    • Подключение к: Visual Studio Marketplace
    • Подключение Visual Studio Marketplace: ServiceConnection
    • Тип входного файла: VSIX-файл
    • VSIX-файл: /Publisher.*.vsix
    • Идентификатор издателя: идентификатор издателя Visual Studio Marketplace
    • Идентификатор расширения: идентификатор расширения в файле vss-extension.json
    • Имя расширения: имя расширения в файле vss-extension.json
    • Видимость расширения: частная или общедоступная

Необязательно. Установка и проверка расширения

Установите расширение, к которому вы предоставили общий доступ, всего за несколько шагов:

  1. На панели управления организации перейдитеhttps://dev.azure.com/{organization}/_admin на страницу администрирования коллекции проектов.
  2. На вкладке "Расширения" найдите расширение в группе "Расширения, к которым предоставлен доступ ко мне", и выберите ссылку расширения.
  3. Установите расширение.

Если вкладка "Расширения" не отображается , убедитесь, что вы находитесь на панели управления (страница администрирования на уровне коллекции проектов ), https://dev.azure.com/{organization}/_adminа не на странице администрирования проекта.

Если вкладка "Расширения" не отображается, расширения не включены для вашей организации. Вы можете получить ранний доступ к функции расширений, присоединившись к программе партнеров Visual Studio.

Чтобы упаковать и опубликовать расширения Azure DevOps в Visual Studio Marketplace, можно скачать задачи расширения Azure DevOps.

Вопросы и ответы

Ознакомьтесь со следующими часто задаваемыми вопросами о добавлении пользовательских задач сборки или выпуска в расширениях Azure DevOps.

Вопрос. Как ограничить использование команд Azure Pipelines для задачи?

Вы можете ограничить использование и переменные команд Azure Pipelines, которые задаются задачей. Это действие может быть полезно, чтобы предотвратить неограниченный доступ к переменным или командам vso для пользовательских скриптов, которые выполняются задачей. Рекомендуется настроить его для новых задач. Чтобы применить, может потребоваться добавить следующую инструкцию в файл task.json:

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

Если restricted для этого задано mode значение, можно выполнить только следующие команды задачей:

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

Ограничения settableVariables позволяют передавать список разрешений переменных, которые задаются setvariable по командам или prependpath командам. Он также позволяет использовать основные регулярные выражения. Например, если список разрешений: ['abc', 'test*'], параметр abcили testпеременные с любым значением или test1 предустановкой их пути будет выполнен успешно, но если вы попытаетесь задать прокси-сервер переменной, он будет предупреждать. Пустой список означает, что переменные не изменяются задачей.

Если ни один из commands ключей settableVariables не указан, соответствующее ограничение не применяется.

Функция ограничения доступна с версии агента 2.182.1 .

Вопрос. Как сигнал отмены обрабатывается задачей?

Ответ. Агент конвейера отправляет и SIGTERM сигналит SIGINT соответствующему дочернему процессу. В библиотеке задач нет явных средств для обработки. Дополнительные сведения см. в разделе об отмене заданий агента.

Вопрос. Как удалить задачу из коллекции проектов?

Ответ. Мы не поддерживаем автоматическое удаление задач. Автоматическое удаление не является безопасным и нарушает существующие конвейеры, которые уже используют такие задачи. Но вы можете пометить задачи как устаревшие. Для этого наткнулся на версию задачи и помечайте задачу как нерекомендуемую.

Вопрос. Как обновить пользовательскую задачу до последнего узла?

Ответ. Рекомендуется обновить до последней версии Узла. Примеры см. в разделе "Обновление задач до узла 20".

Так как размещенные агенты Майкрософт и различные версии Сервера Azure DevOps имеют разные жизненные циклы, в зависимости от того, где выполняется задача, могут быть разные версии runner узла. Чтобы иметь возможность выполнять одну и ту же задачу в агентах с разными версиями запуска узла, файл task.json может содержать несколько разделов выполнения. В следующем примере агенты Azure Pipeline, включающие средство выполнения Node 20, будут выбирать его по умолчанию, и те, которые не будут возвращаться к реализации Node 10.

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

Чтобы обновить задачи, выполните следующие действия.

  • Проверьте задачи в различных версиях runner узла, чтобы убедиться, что код работает должным образом.

  • В разделе выполнения задачи обновите или Node10 Node16 до Node илиNode20.

  • Чтобы поддерживать более старые версии сервера, следует оставить целевой Node/Node10 объект. Более ранние версии Сервера Azure DevOps Server могут не включать последнюю версию средства выполнения узла.

  • Вы можете предоставить общий доступ к точке входа, определенной в целевом объекте, или иметь целевые объекты, оптимизированные для используемой версии узла.

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

Внимание

Не добавляя поддержку средства выполнения Node 20 в пользовательских задачах, задачи завершаются ошибкой агентов, установленных в веб-канале pipelines-agent-* выпуска.