📜 ⬆️ ⬇️

How we improved TFS

Earlier, when we didn’t have our corporate blog, I wrote about how we use Microsoft TFS (Visual Studio Team Services on Premises) to manage the software development life cycle and to automate testing. In particular, we have collected a large set of autotests for different systems in one package, which we run every day. I talked more about this at the DevOpsDaysMoscow conference ( presentation , video of the speech ) During the implementation, we encountered several problems:



This block describes the unique id of the task, its name, category and version. When creating a task, you must specify all these fields. The instanceNameFormat field defines how the task name in the default VSTS assembly will look. It can contain parameters from the parameter block in the form of $ (parameter name)


parameter block


The parameter block contains the input parameters of the task, their names, descriptions, and types. Parameters can be grouped for ease of presentation on the task settings page. Below the block is the AutoDefects task parameter:


 { "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" } ] } 

The parameters defining the authentication scheme are placed in a separate group, which is minimized by default.


As the types of parameters are most often used:



execution unit


contains a link to the main task executable file


 { "execution": { "Node": { "target": "testtask.ts" } } } 

localization unit


 { "messages": { "taskSucceeded": "All done", "taskFailed": "Task Failed" } } 

contains a set of localized strings for logging the task in the assembly log file. Used less frequently than blocks above. Messages for the current local settings can be obtained by calling task.loc ("messagename");


Main executable file


The main executable file is a script that executes VSTS at the start of a task. At a minimum, it should contain code for importing the necessary modules for the task to work and error handling. For example:


 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"))) 

As you can see, a task is a set of standard components that vary little from task to task. Therefore, when I created the third task, an idea appeared to automate the creation of tasks. This is how our “bootstrap” appeared, which makes life easier for the development of VSTS extensions.


How faster


What do you need to do when you create a task for VSTS, except for actually writing the code of the task itself? The steps are usually the same:


  1. Create task skeleton
  2. Build a task into an isolated component
  3. Package task in vsix for publication in VSTS

All these steps can be automated to speed development and eliminate unnecessary manual labor. To automate these steps and you can use our "bootstrap". The work scheme of our collector is similar to the task collector from Microsoft - the tasks for the assembly are listed in the file make-options.json in the project root:


 { "tasks": [ "AutoDefects", "ChainBuildsAwaiter", "ChainBuildsStarter", "TestTask" ], ... } 

Prerequisite


To create extensions you need the following software:



Task creation


TaskName is created with the command:
gulp generate –-name TaskName


As a result of running the command, the following happens:



Skeleton files contain the minimum required set of data and code.


Build Project Tasks


Assembling the project’s tasks is done by the command gulp


For all the tasks listed in make-options.json , the following happens:



Task packaging


Packing tasks is done with the gulp mkext [--all] [--exts ext1,ext2] command gulp mkext [--all] [--exts ext1,ext2]


By default, each task is packaged in a separate vsix file, if the --all parameter is specified, then all tasks are collected into one large vsix file.


By default, all tasks listed in make-options.json are packaged; if the option --exts is specified, then only the extensions listed in the option are packaged.


We openly


Bootstrap published on GitHub - forks, feature requests, pull requests are welcome.


I really hope that this article will arouse interest in Miscosoft VSTS, which in my opinion is an excellent tool for group work, not only for large companies, but also for small flexible teams.


Konstantin Neradovsky,
Head of Test Automation,
Bank opening"


')

Source: https://habr.com/ru/post/330078/


All Articles