Development

Implementing Custom Tasks in VSTS

I think that one of the strengths of the build and release system in Visual Studio Team Services (VSTS) is the large variety of tasks that is available. If you ever want a task that does something that the default tasks can’t do, chances are high that someone else has made a task for just that purpose already, and that it’s ready to be installed from the Visual Studio Marketplace.

But sometimes you might be out of luck, and you have to make the work yourself. What now?

Create Task Groups

The easiest way to create a reusable task is to create a Task Group from an already configured tasks in a build or release definition. You create a task group by selecting one or many tasks, right clicking, and selecting Create task group.

All configuration variables, the ones named like $(abc), that are present in the tasks of a task group are put as input parameters of the task group, each with a configurable default value and description.

Task groups are great because they are so easy to make, but have the drawback of only being available in the team project where they are created.

Implementing Custom Tasks in VSTS

If you intend to share your tasks between several team projects or even accounts, your best option is to implement a custom task. Tasks in VSTS are made up of a command executable and a task manifest. The executable can be either a full blown command line application, or a simple PowerShell script. The task manifest is a json-file that contains some metadata such as the task ID, a declaration of what the configuration GUI should contain, and how the executable is invoked.

Strangely, I have not been able to find any official documentation of how to fill in the task manifest json-file. But there is an active pull request with a schema that may be useful if you ever wonder what to write.

An easy way to get started is to copy one of the default tasks of VSTS, and modify it to your needs. Just remember to generate a new ID for your custom task!

Enter personal access token > 2lqewmdba7theldpuoqn7zgs46bmz5c2ppkazlwvk2z2segsgqrq – This is obviously a bogus token… You can add tokens to access your account at https://yourname.visualstudio.com/_details/security/tokens.

tfx build tasks upload --task-path c:\path-to-repo\MyCustomTask

If you change your mind and do not want a task anymore, you can remove it withtfx build tasks delete --task-id b8df3d76-4ee4-45a9-a659-6ead63b536b4, where the Guid is easiest found in the task.json of your task.

If you make a change to a task that you have previously uploaded, you have to bump its version before you upload it again.

Create an extension manifest-file with the name vss-extension.json, and with content like the following:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

{

"manifestVersion":1,

"id":"UniqueExtensionId",//FIXME

"name":"Your extension name",//FIXME

"version":"1.2.3",//FIXME

"publisher":"yourpublisherid",//FIXME

//"galleryFlags": ["Public"],

"targets":[

{

"id":"Microsoft.VisualStudio.Services"

}

],

"description":"A brief description which will be shown in the marketplace tile.",//FIXME

"categories":[

"Build and release"

],

"tags":[//FIXME

"some",

"tags",

"for",

"discoverability"

],

"content":{

"details":{

"path":"relativePathTo/README.md"//FIXME

},

"license":{

"path":"relativePathToLicenseFile"//FIXME

}

},

"links":{

"support":{

"uri":"https://some-uri.com"//FIXME

}

},

"branding":{

"color":"rgb(36, 43, 50)",

"theme":"dark"

},

"icons":{

"default":"relativePathTo/extension-icon.png"//FIXME

},

"files":[

{

"path":"relativePathToTaskFolder"//FIXME

}

],

"contributions":[

{

"id":"UniqueIdOfTask",//FIXME

"type":"ms.vss-distributed-task.task",

"targets":[

"ms.vss-distributed-task.tasks"

],

"properties":{

"name":"relativePathToTaskFolder"//FIXME

}

}

]

}

Then, run the command tfx extension create in a Node.js command prompt, and upload the generated .vsix-file in the publishing portal.

Or if you prefer, you can use the command tfx extension publish instead, and supply your personal access token.

If the "galleryFlags": ["Public"] setting is kept commented out, the extension will default to be a private extension, meaning that the extension will only be available in the collections you choose. Access to private extensions are managed through the publishing portal.

Once your extension is battle proven, be a good community member and make it public so that all can benefit from your work.

4 Responses

Venky Venkataraman

Hi,
Thanks for this nice writeup. Can you clarify this for me? We have written release step to copy files over WinRM that we have created as Task but now we want to share it across all the TFS projects. We have a TFS in house installation and I want to know if the steps you have described is applicable for in house TFS installation as well?
Thanks,
Venky

Johnny Larsen

I struggling passing inputs parameters to the referenced powershell file.
I have surfed the internet for help regarding passing inputs parameters from json to the referenced powershell file.
I’m using a build agents on premises.
I have doubled checked multiple times for typos, the referenced powershell file exists, because i’m getting an error from the powershell.

Do you have any ideas about what i can have misunderstood?
I’m have tried to use both Powershell and PowerShell3 as executor, and it seems that PowerShell3 isn’t supported for on-premises agents.

Thanks
Johnny

Johan Classon

Hm… One quirk of VSTS tasks is that all arguments needs to be passed in as [string]s. If you have set any other parameter type, say [int] or [switch] for example, it would not work. What I have seen, parameters are passed the same way both on-premise and on VSTS.