The VSTS vNext Build and Release systems are a huge improvement in terms of usability and maintainability on the previous XAML based system. In a previous post I’ve covered a walkthrough that shows how to use the Build and Release systems to create a continuous delivery process to deploy Azure resource groups using the built in tasks. In this post, I’m going to walk through how to create your own VSTS build or release tasks, and how to install or publish them to other VSTS accounts.
First though, why would you want to build your own extension? Well, there are a few good reasons.
If you need to do something that’s not specifically covered by one of the existing tasks, then you need to resort to adding one or more generic “run Powershell script” tasks. The inputs will be all text only, entered as a string in the build tasks UI – these cant be validated at the time you’re editing the task at all, and to find out what parameters are expected, you need to inspect or know the Powershell script you’re running pretty well. Also, a build or release definition that consists of one or many generic Powershell script tasks is harder to maintain, and when you come to look at the definition for the first time, it’s not going to be easy to find out what the script does, without going into the script behind each task.
These kinds of VSTS extension can consist of Powershell or javascript (or both) – bear in mind that if you want to target cross platform build agents, you need to use js instead of Powershell, which will only run on Windows agents.
For this walkthrough, the build task I’m going to use is a bit of niche one, but the requirement came from a real world scenario, whereby a company use DocumentDB in Azure to store the configuration file data for each of their environments (rather than manage files as part of the code deployment). As such, they need to be able to deploy an environment-specific configuration .json document to a DocumentDB as part of their build/release management process. (DocumentDB is an Azure PaaS service which stores and indexes .json formatted documents in a no-SQL database).
DocumentDB currently doesn’t have Powershell cmdlets to do what we need to achieve:
- Connect to the DocumentDB
- enumerate the Databases to check the target exists
- enumerate the Database’s Collections for the same reason
- Create or Update the document in question.
See my previous post on how to create the powershell for those specific tasks – this post will focus on the mechanics of packaging and publishing the task to VSTS as an extension, rather than the DocumentDB piece.
Folder structure
The project assets required for a single task look like this, where the task assets are contained in the subfolder “UpdateDocumentDB”. All other assets are used only for publishing to the marketplace, or sharing with other VSTS accounts using the UI.
Path | Description |
---|---|
vss-extension.json | Manifest file that describes the package, required by the marketplace |
overview.md | A description file for the marketplace |
*.vsix | Output installation file (upload this to the publish page to make available to other accounts) |
images | Icons used in the marketplace, and when displaying the package in VSTS accounts to end users |
UpdateDocumentDB | Folder containing assets to publish for a specific task |
UpdateDocumentDB/ps_modules | Required to integrate with VSTS |
UpdateDocumentDB/icon.png | Icon for the task (used in Build/Release Configuration Builder) |
UpdateDocumentDB/task.json | Manifest file describing the task |
UpdateDocumentDB/UpdateDocumentDB.ps1 | The powershell for the actual task |
There are three ways to get your extension in place in a VSTS account:
- upload it directly using the TFX command line tool
- Build a VSIX package and upload to the VSTS extension publishing page, and install it in your own account or share it with other specific accounts
- Build a VSIX package and publish it to the Marketplace (public domain)
Task Manifest
The task manifest is fairly straightforward. The "category": "Deploy"
, parameter tells VSTS which group you want your task to appear in when adding a build or release step.
The most important parts of the manifest are the inputs, which form the UI for the build step inside VSTS, and the execute step, which tells the build agent what to do when it’s being run – in this case, we just want it to call our PowerShell script.
"execution": { "PowerShell3": { "target": "$(currentDirectory)\\UpdateDocumentDB.ps1", "argumentFormat": "", "workingDirectory":"$(currentDirectory)" } }
The parameters from the UI build step configuration will be passed into the powershell script, which uses the VSTS Tasks SDK to receive and map to parameters, eg. to
read the “sourceFile” input into a $sourceFile parameter in my script, I’d use the following:
$sourceFile = Get-VstsInput -Name sourceFile -Require
To deploy the build task alone directly into your own VSTS account (you must have the correct rights over the account to be able to do this).
You will need a Personal access token (PAT) to complete this step. PATs can be created by logging into your VSTS account online, clicking your logged in name (top right), selecting “My Security” then selecting Add under Personal Access tokens.
>tfx build tasks upload --task-path UpdateDocumentDB --service-url https://ehieu.visualstudio.com/DefaultCollection TFS Cross Platform Command Line Interface v0.3.21 Copyright Microsoft Corporation > Personal access token: Task at C:\dev\Repos\DevOps\BuildTasks\Tasks\UpdateDocumentDB uploaded successfully!
VSS-Extension manifest
There is one Extension manifest per package – and you can include multiple extensions (tasks or other extension types) within a single package. The extension manifest is used to describe your package to the marketplace, and includes all the information needed to create the package, including what files or paths to include, the documentation files, images, etc., and of course the paths to your tasks as well.
There are some good examples of vss-extension.json manifests in GitHub, (look for the Tomcat one by Microsoft for one that’s quite fully featured). Below are some of the less obvious parameters and what they do.
Parameter | Description |
---|---|
"content":{ "details":{ "path":"overview.md" } }, |
Markdown document file to show in the marketplace as the overview |
"icons": { "default": "images/icon.png", "large":"images/icon-large.png" }, |
Include 2 icons, one 128×128 and one 512×512, and you can use transparent .png format files |
"files": [ { "path": "UpdateDocumentDB" }, { "path":"images", "addressable": true } ], |
Paths to include in your package – you can specify single files or a path; if you use a path name it will include everything in that folder and subfolders recursively |
To package one or more tasks and prepare an installer to share to other accounts, you must create a VSIX file:
>tfx extension create --manifest-globs vss-extension.json TFS Cross Platform Command Line Interface v0.3.21 Copyright Microsoft Corporation Could not determine content type for extension .psd1. Defaulting to application/octet-stream. To override this, add a contentType property to this file entry in the manifest. Could not determine content type for extension .psm1. Defaulting to application/octet-stream. To override this, add a contentType property to this file entry in the manifest. === Completed operation: create extension ===
The publishing site can be accessed using the URL
https://marketplace.visualstudio.com/manage/publishers/<publisherid>
Go to https://marketplace.visualstudio.com/ and choose “Publish an extension” from the bottom navigation footer, and create a new publisher if you haven’t published before. You will need to send an email to Microsoft to verify your publisher account before you can actually publish to the public marketplace.
Once the Extension is uploaded, you need to Install it into your VSTS account and enable it. You do that through the Manage Extensions page (the shopping bag icon on the top right of the page in VSTS)
Note that sometimes the extension will still not show once you’ve installed it, and you need to disable/re-enable it using the manage extensions page to get it to show in the list of available build tasks.
Below is my full vss-extension.json manifest file
{ "manifestVersion": 1, "id": "docdb-tasks", "name": "Publishing Tasks for DocumentDB", "version": "1.0.3", "publisher": "youngr6", "targets": [ { "id": "Microsoft.VisualStudio.Services" } ], "scopes": [ "vso.build", "vso.serviceendpoint" ], "description": "A build and release extension that allows you to publish source files to a DocumentDB instance in Azure.", "categories": [ "Build and release" ], "tags": [ "Extension", "Marketplace", "Publish", "DocumentDB" ], "links": { "support": { "uri": "https://russellyoung.net" } }, "content":{ "details":{ "path":"overview.md" } }, "branding": { "color": "rgb(36, 43, 50)", "theme": "dark" }, "icons": { "default": "images/icon.png", "large":"images/icon-large.png" }, "files": [ { "path": "UpdateDocumentDB" }, { "path":"images", "addressable": true } ], "contributions": [ { "id": "UpdateDocumentDB", "type": "ms.vss-distributed-task.task", "targets": [ "ms.vss-distributed-task.tasks" ], "properties": { "name": "UpdateDocumentDB" } } ] }
Pingback: Homepage()