- PVSM.RU - https://www.pvsm.ru -
Ранее, когда у нас не было своего корпоративного блога, я писал [1] о том, как мы используем Microsoft TFS (Visual Studio Team Servives on Premises) для управления жизненным циклом разработки ПО и для автоматизации тестирования. В частности мы собрали большой набор автотестов по разным системам в один пакет, который запускаем каждый день. Подробнее об этом я рассказывал на конференции DevOpsDaysMoscow ( презентация [2], видео выступления [3] )В ходе внедрения мы столкнулись с несколькими проблемами:
Сборки из дженкинса не публикуют результаты тестов в VSTS
все эти проблемы были успешно решены с помощью собственных расширений VSTS:
Доработка стандартной задачи запуска Jenkins job
Подробнее о проблемах и как мы искали решения — в моей прошлой статье [1]. А сегодня я хочу рассказать о том как делать эти расширения и как мы можем помочь разработчикам расширений.
Практически с самого начала мы поняли, что самый простой способ решить наши проблемы — это собственные задачи (tasks) или шаги сборки в TFS. Задачи можно писать либо на powershell, либо на typescript. Мы выбрали typescript, и вот почему — фактически это javascript, но с поддержкой типизации. О преимуществах typescript и его использовании существует множество статей, в том числе и на хабре. Для нас же основными преимуществами было следующее:
Для работы c TFS Microsoft создала и опубликовала 2 npm модуля, что опять же избавило от необходимости изобретать велосипед.
Также большой помощью оказалось то, что многие задачи от Microsoft написаны и typescript и опубликованы [4] под открытой лицензией. Кроме того, что это позволяет использовать их как примеры, это дало возможность сделать собственный форк [5] этого репозитория и сделать свой "бутсрап" набор для быстрого создания задач и автоматизации сборки и упаковки расширений.
Что представляет собой задача для VSTS? Это набор обязательных компонентов:
иконка задачи
Определение задачи содержит несколько блоков.
{
"id": "b5525419-bae1-44de-a479-d6de6a3ccb2f",
"name": "TestTask",
"friendlyName": "TestTask",
"description": "TestTask",
"helpMarkDown": "",
"category": "Build",
"author": "authorName",
"version": {
"Major": 1,
"Minor": 0,
"Patch": 0
},
"instanceNameFormat": "TestTask $(testparam)"
}
В этом блоке описывается уникальный id задачи, ее имя, категория и версия. При создании задачи необходимо указывать все эти поля. Поле instanceNameFormat определяет как будет выглядеть имя задачи в сборке VSTS по умолчанию. В нем могут быть указаны параметры из блока параметров в виде $(имя параметра)
В блоке параметров указываются входные параметры задачи, их имена, описания и типы. Параметры могут группироваться для удобства представления на странице настройки задачи. Ниже блок параметром задачи AutoDefects:
{
"groups": [
{
"name": "authentication",
"displayName": "Authentication",
"isExpanded": false
}
],
"inputs": [
{
"name": "Assignees",
"type": "filePath",
"label": "Assignees list file",
"defaultValue": "assignees.json",
"required": false,
"helpMarkDown": "Bug assignees list in json format. Format: {"testrunname":"username"}"
},
{
"name": "authtype",
"type": "pickList",
"label": "Authentication type",
"defaultValue": "oauth",
"required": false,
"helpMarkDown": "Authentication type to access the tfs rest api",
"options": {
"oauth": "OAuth",
"NTLM": "NTLM",
"Basic": "Basic"
},
"groupName" : "authentication"
},
{
"name": "Username",
"type": "string",
"label": "Username",
"defaultValue": "",
"required": false,
"helpMarkDown": "Username to access tfs rest api (NTLM and Basic types)",
"groupName" : "authentication",
"visibilityRule" : "authtype != OAuth"
},
{
"name": "Password",
"type": "string",
"label": "Password",
"defaultValue": "",
"required": false,
"helpMarkDown": "Password to access tfs rest api (NTLM and Basic types)",
"groupName" : "authentication",
"visibilityRule" : "authtype != OAuth"
}
]
}
Параметры, определяющие схему аутентификации вынесены в отдельную группу, которая свернута по умолчанию.
В качестве типов параметров чаще всего используются:
содержит ссылку на главный исполняемый файл задачи
{
"execution": {
"Node": {
"target": "testtask.ts"
}
}
}
{
"messages": {
"taskSucceeded": "All done",
"taskFailed": "Task Failed"
}
}
содержит набор локализованных строк для протоколирования работы задачи в лог файле сборки. Используется реже, чем блоки выше. Сообщения для текущих локальных настроек можно получить вызовом task.loc("messagename");
Главный исполняемый файл — это скрипт, который выполняет VSTS при старте задачи. Как минимум должен содержать код для импорта необходимых модулей для работы задачи и обработку ошибок. Например:
import tl = require('vsts-task-lib/task');
import trm = require('vsts-task-lib/toolrunner');
import path = require('path');
import fs = require('fs');
import Q = require("q");
import * as vm from 'vso-node-api';
import * as bi from 'vso-node-api/interfaces/BuildInterfaces';
import * as ci from 'vso-node-api/interfaces/CoreInterfaces';
import * as ti from 'vso-node-api/interfaces/TestInterfaces';
import * as wi from 'vso-node-api/interfaces/WorkItemTrackingInterfaces';
async function run() {
tl.setResourcePath(path.join(__dirname, 'task.json'));
let projId = tl.getVariable("System.TeamProjectId");
try {
} catch(err) {
console.log(err);
console.log(err.stack);
throw err;
}
}
run()
.then(r => tl.setResult(tl.TaskResult.Succeeded,tl.loc("taskSucceeded")))
.catch(r => tl.setResult(tl.TaskResult.Failed,tl.loc("taskFailed")))
Как видно задача представляет собой набор стандартных компонентов, которые мало меняются от задачи к задаче. Поэтому, когда я создавал третью задачу, появилась идея автоматизировать создание задач. Так появился наш "бутстрап", который значительно облегчает жизнь разработику расширений для VSTS.
Что нужно сделать когда создаешь задачу для VSTS, кроме собственно написание кода самой задачи? Шаги обычно одни и те же:
Все эти шаги могут быть автоматизированы для ускорения разработки и устранения ненужного ручного труда. Для автоматизации этих шагов и можно применять наш "бутстрап". Схема работы нашего сборщика аналогична сборщику задач от Microsoft — задачи для сборки перечисляются в файле make-options.json в корне проекта:
{
"tasks": [
"AutoDefects",
"ChainBuildsAwaiter",
"ChainBuildsStarter",
"TestTask"
],
...
}
для создания расширений Вам понадобятся следущее ПО:
npm install -g typescript
npm install -g gulp
npm install -g tfx-cli
Задача TaskName создается командой:
gulp generate –-name TaskName
В результае выполениея команды происходит следующее:
Скелетные файлы содержат минимально необходимый набор данных и кода.
Сборка задач проекта осуществляется комадной gulp
При этом для всех задач, перечисленных в make-options.json происходит следующее:
Упаковка задач осуществляется командой gulp mkext [--all] [--exts ext1,ext2]
По умолчанию каждая задача упаковывается в отдельный vsix файл, если указан параметр --all, то все задачи собираются в один большой vsix файл.
По умолчанию упаковываются все задачи, перечисленные в make-options.json, если указан параметр --exts, то упаковываются только перечисленные в параметре расширения.
Бутстрап опубликован [5] на GitHub — форки, feature requests, pull requests приветствуются.
Очень надеюсь, что эта статья вызовет интерес к Miscosoft VSTS, который на мой взгляд является отличным инструментом групповой работы не только для больших компаний, но и для небольших гибких команд.
Константин Нерадовский,
начальник отдела автоматизации тестирования,
банк "Открытие"
Автор: Открытие
Источник [6]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/microsoft/256983
Ссылки в тексте:
[1] писал: https://habrahabr.ru/post/319662/
[2] презентация: https://www.slideshare.net/KonstantinNeradovsky/visual-studio-team-services-tfs-helps-doing-devops
[3] видео выступления: https://youtu.be/rIDdHTcCkwA
[4] опубликованы: https://github.com/Microsoft/vsts-tasks/
[5] собственный форк: https://github.com/kneradovsky/viko-vsts-extensions
[6] Источник: https://habrahabr.ru/post/330078/?utm_source=habrahabr&utm_medium=rss&utm_campaign=best
Нажмите здесь для печати.