This article is contributed. See the original author and article here.

Como criar uma extensão customizada para o Azure DevOps


Em alguns casos, é necessário criar uma extensão personalizada para o Azure DevOps, seja para adicionar funcionalidades que não estão disponíveis nativamente ou para modificar alguma funcionalidade existente que não atenda às necessidades do projeto. Neste artigo, mostraremos como criar uma extensão personalizada para o Azure DevOps e como publicá-la no Marketplace do Azure DevOps.


Antes de começar certifique:



  • Ter uma conta no Azure DevOps. Caso ainda não tenha uma, você pode criar uma seguindo as instruções disponíveis aqui.

  • Ter um editor de código instalado, como o Visual Studio Code, que pode ser baixado em code.visualstudio.com.

  • Ter a versão LTS do Node.js instalada, disponível para download em, nodejs.org. Ter o compilador de TypeScript instalado, sendo a versão recomendada 4.0.2 ou superior. Ele pode ser instalado via npm em npmjs.com.

  • Ter o CLI do TFX instalado, sendo a versão recomendada 0.14.0 ou superior. Ele pode ser instalado globalmente via npm com o comando npm i -g tfx-cli ou conferindo mais detalhes em TFX-CLI npm i -g tfx-cli.


Preparando o ambiente de desenvolvimento




  1. Crie uma pasta para a extensão, por exemplo, my-extension e dentro desta pasta crie a uma subpasta, por exemplo, task.




  2. Abra o terminal na pasta criada e execute o comando npm init -y, o parâmetro -y é para aceitar todas as opções padrão. Você vai notar que foi criado um arquivo chamado package.json e nele estão as informações da extensão.


        {
    “name”: “my-extension”,
    “version”: “1.0.0”,
    “description”: “”,
    “main”: “index.js”,
    “scripts”: {
    “build”: “tsc ./index.ts”,
    },
    “keywords”: [],
    “author”: “”,
    “license”: “ISC”
    }



  3. Adicione a azure-pipelines-task-lib como dependência da extensão, execute o comando npm i azure-pipelines-task-lib –save-dev.




  4. Adicione também as tipificações do TypeScript, execute o comando npm i @types/node –save-dev e npm i @types/q –save-dev.




  5. Crie um arquivo .gitignore na pasta raiz da extensão e adicione o seguinte conteúdo:


    node_modules



  6. Instale o compilador de TypeScript, execute o comando npm i typescript –save-dev.




  7. Crie um arquivo tsconfig.json na pasta raiz da extensão e adicione o seguinte conteúdo:


        {
    “compilerOptions”: {
    “target”: “es6”, /* Specify ECMAScript target version: ‘ES3’ (default), ‘ES5’, ‘ES2015’, ‘ES2016’, ‘ES2017’, ‘ES2018’, ‘ES2019’, ‘ES2020’, or ‘ESNEXT’. */
    “module”: “commonjs”, /* Specify module code generation: ‘none’, ‘commonjs’, ‘amd’, ‘system’, ‘umd’, ‘es2015’, ‘es2020’, or ‘ESNext’. */
    “strict”: true, /* Enable all strict type-checking options. */
    “esModuleInterop”: true, /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies ‘allowSyntheticDefaultImports’. */
    “skipLibCheck”: true, /* Skip type checking of declaration files. */
    “forceConsistentCasingInFileNames”: true /* Disallow inconsistently-cased references to the same file. */
    }
    }



  8. Crie um arquivo chamado vss-extension.json na pasta raiz da extensão my-extension e adicione o seguinte conteúdo:


        {
    “manifestVersion”: 1,
    “id”: “<>”,
    “version”: “1.0.0”,
    “publisher”: “<>”,
    “name”: “My Extension”,
    “description”: “My Extension”,
    “public”: false,
    “categories”: [
    “Azure Pipelines”
    ],
    “targets”: [
    {
    “id”: “Microsoft.VisualStudio.Services”
    }
    ],
    “icons”: {
    “default”: “images/icon.png”
    },
    “files”: [
    {
    “path”: “task”
    }
    ],
    “contributions”: [
    {
    “id”: “my-extension”,
    “description”: “My Extension”,
    “type”: “ms.vss-distributed-task.task”,
    “targets”: [
    “ms.vss-distributed-task.tasks”
    ],
    “properties”: {
    “name”: “my-extension”
    }
    }
    ]
    }

    Substitua o <> por ID único de cada extensão, você pode gerar um ID aqui. Substitua o <> pelo publisher ID criado no passo 1 da etapa de publish.




  9. Na pasta raiz da sua extensão my-extension, crie uma pasta chamada images e adicione uma imagem chamada icon.png com o tamanho de 128×128 pixels. Essa imagem será usada como ícone da sua extensão no Marketplace.




Criando a extensão


Depois de configurar o ambiente, você pode criar a extensão.




  1. Na pasta task crie um arquivo chamado task.json e adicione o seguinte conteúdo:


        {
    “$schema”: “https://raw.githubusercontent.com/Microsoft/azure-pipelines-task-lib/master/tasks.schema.json”,
    “id”: “<>”,
    “name”: “My Extension”,
    “friendlyName”: “My Extension”,
    “description”: “My Extension”,
    “helpMarkDown”: “”,
    “category”: “Utility”,
    “visibility”: [
    “Build”,
    “Release”
    ],
    “author”: “Your Name”,
    “version”: {
    “Major”: 1,
    “Minor”: 0,
    “Patch”: 0
    },
    “groups”: [],
    “inputs”: [],
    “execution”: {
    “Node16”: {
    “target”: “index.js”
    }
    }
    }

    Substitua o <> pelo mesmo GUID gerado no passo 8 da etapa de preparação de ambiente de desenvolvimento.


    Esse arquivo descreve a extensão que será executada no pipeline. Nesse caso, a extensão ainda não faz nada, mas você pode adicionar os inputs e a lógica para executar qualquer coisa.




  2. Na sequência crie um arquivo chamado index.js e adicione o seguinte conteúdo:


        const tl = require(‘azure-pipelines-task-lib/task’);

    async function run() {
    try {
    tl.setResult(tl.TaskResult.Succeeded, ‘My Extension Succeeded!’);
    }
    catch (err) {
    if (err instanceof Error) {
    tl.setResult(tl.TaskResult.Failed, err.message);
    }
    }
    }

    run();


    Esse arquivo é o responsável por executar a extensão. Nesse caso, ele apenas retorna uma mensagem de sucesso. Você pode adicionar a lógica para executar qualquer coisa.




  3. Adicione na pasta task uma imagem chamada icon.png com o tamanho de 32×32 pixels. Essa imagem será usada como ícone da sua extensão no Azure Pipelines.




  4. No terminal, execute o comando tsc, para compilar o código Typescript para Javascript. Esse comando irá gerar um arquivo chamado index.js na pasta task.




  5. Para executar a extensão localmente, execute o comando node index.js. Você deve ver a mensagem My Extension Succeeded!.


        C:tempmy-extensiontask> node index.js
    ##vso[task.debug]agent.TempDirectory=undefined
    ##vso[task.debug]agent.workFolder=undefined
    ##vso[task.debug]loading inputs and endpoints
    ##vso[task.debug]loading INPUT_CLEANTARGETFOLDER
    ##vso[task.debug]loading INPUT_CLIENTID
    ##vso[task.debug]loading INPUT_CLIENTSECRET
    ##vso[task.debug]loading INPUT_CONFLICTBEHAVIOUR
    ##vso[task.debug]loading INPUT_CONTENTS
    ##vso[task.debug]loading INPUT_DRIVEID
    ##vso[task.debug]loading INPUT_failOnEmptySource
    ##vso[task.debug]loading INPUT_FLATTENFOLDERS
    ##vso[task.debug]loading INPUT_SOURCEFOLDER
    ##vso[task.debug]loading INPUT_TARGETFOLDER
    ##vso[task.debug]loading INPUT_TENANTID
    ##vso[task.debug]loaded 11
    ##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]task result: Succeeded
    ##vso[task.complete result=Succeeded;]My Extension Succeeded!
    C:tempmy-extensiontask>



Publicando a extensão no Marketplace


Quando a sua extensão estiver pronta, você pode publicá-la no Marketplace. Para isso será necessário criar um editor de extensão no Marketplace.




  1. Acesse o Marketplace e clique em Publish Extension. Após fazer o login, você será redirecionado para a página de criação de um editor de extensão. Preencha os campos e clique em Create.


    Criando um editor de extensão




  2. No terminal execute o comando tfx extension create –manifest-globs vss-extension.json, na pasta My-Extension. Esse comando irá gerar um arquivo chamado publishID-1.0.0.vsix, que é o arquivo que será publicado no Marketplace.


    CreateExtension




  3. Acesse a página de publicação de extensão no Marketplace e clique New extension e seguida Azure DevOps. Selecione o arquivo my-extension-1.0.0.vsix e clique em Upload.


    UploadExtension


    Se tudo ocorrer bem, você verá algo como a imagem abaixo.


    ExtensionPublished




  4. Com a extensão publicada, será necessário compartilhá-la com a sua organização. Para isso, clique no menu de contexto da extensão e clique em Share/UnShare.


    ShareExtension


    Clique em + Organization.


    ShareExtension1


    E digite o nome da sua Organização, ao clicar fora da caixa de digitação a validação é feita e o compartilhamento é realizado.


    ShareExtension2




Instalando a extensão na sua organização


Após publicar a extensão no Marketplace, você pode instalá-la na sua organização, para isso siga os passos abaixo.




  1. Clique no menu de contexto da extensão e clique em View Extension.


    InstallExtension


    Você verá algo como a imagem abaixo.


    InstallExtension1




  2. Clique em Get it free.




  3. Verifique se sua organização está selecionada e clique em Install.


    InstallExtension2


    Se a instalação ocorrer tudo bem, você verá algo como a imagem abaixo.


    InstallExtension3


    Após a instalação, você verá a extensão na lista de extensões instaladas e poderá ser utilizada nos seus pipelines.




Conclusão


O uso de extensões customizadas no Azure DevOps desbloqueiam funcionalidades que não estão disponíveis. Neste artigo, você aprendeu como criar uma extensão customizada e como publicá-la no Marketplace. Espero que tenha gostado e que possa aplicar o conhecimento adquirido em seus projetos.


Referências



  1. Criar uma organização

  2. Referência de manifesto de extensão

  3. Build/Release Task Exemplos

  4. Extensões de pacote e publicação

Brought to you by Dr. Ware, Microsoft Office 365 Silver Partner, Charleston SC.