Creating VSTS Extensions for Visual Studio Marketplace
One of the neat things about VSTS is the Visual Studio Marketplace. To quote the VSTS Support Page, the Visual Studio Marketplace is “new destination and the exclusive place for purchasing subscriptions, and for discovering extensions for Visual Studio Team Services and Visual Studio Code.”
Still excited? Want to know more? Well, the previously linked Extensions documentation will help you get up and running, however seeing as I’ve got two published I thought I’d go through the pipeline I’ve created to deliver the extensions.
There are two extensions I’ve written, both of which are published on the MarketPlace. I have shared their source code on GitHub.
How Do I Make An Extension?
Seeing as both use the same pipeline process, I’m going to go through the process for only RunPsScriptAnalyzer, purely because the actual task that is run is easier to follow, and there are less tests to focus on.
Once you’ve cloned the repo and opened it in your favourite text editor (download Visual Studio Code if you do not have one), you should see the following -
Ignore the licence and the readme for now and dive right into what the Extension will do in the “RunPsScriptAnalyzer.ps1“ file -
The function takes one argument, folder path. First it checks if PSScriptAnalyzer is installed, and if you’re going to use this extension on builds that run on the hosted build agent, then it will enter the catch statement and download NuGet as a package provider and then install PsScriptAnalyzer. The reason it is done this way and not using Install-Module is because that command requires admin permissions, which we won’t have on the hosted build agent. Finally we import the module and execute it against the folder path specified. The funky thing with the DiagnosticRecord is because when this command is wrapped up and executed as an extension it outputs the .NET class for the output as opposed to the actual messages.
So it’s all neat and tidy and whilst not providing the other options that PsScriptAnalyzer offer, we can add these at a later date if need be.
The PSScriptAnalyzer .Test.ps1 file contains a single test that will run the Function against the .ps1 file itself. This is run in the build before the extension is packaged. Hardly the most extensive of testing, yet it not only tests the function works, it also run PsScriptAnalyzer against the script in the extension. So it’s a sort of “2 in 1” deal here…
Enough Already; How Do I make An Extension?
Now we know the script to execute, and the inputs (all one of them) required, we can go about creating the files required to package up and publish the extension. There’s two files in this extension to do that -
We’ll start with the tasks file, seeing as we started with the script the extension runs. This file defines the single step that will be executed in a pipeline. Below is the task in a build pipeline in VSTS. You can see that the content in the task file is the same as the screenshot.
One of the neat things with the task.json is the fact that I was able to define the Folder Directory as a filepath type, meaning I was able to navigate through the repo to determine where I want to run the script. For those of you who have wasted many a build printing out a folder path to determine a file oath, this is seriously handy!
So, the task.json file creates the step and determines a few settings, we have a few pretty icons, and now the vss-extension.json file is used to package all this up into a vsix file type. There’s an awful of options for a manifest file, such as its properties and what they do, and you can read more on these on the extension manifest reference page. You will also need to create your publisher before you can upload extensions to the Marketplace. But in short it contains all the info the extension needs to be published and catalogued.
Now to publish. A guide on how to do this is already available on Microsoft’s docs website, however seeing as I’ve got a build set up in VSTS it makes sense to make use of the CI/CD Tools for VSTS Extensions by Microsoft DevLabs. Using this I can configure the version numbers and the publishing (either private or public) to the Marketplace. Neat! I’m using two of the tasks available – “Package” and “Publish”.
For example in the “Package” step I can override the version number with a variable, and I can choose whether or not to override the tasks version. Seeing as I have one task it makes sense to align the numbers accordingly.
Once the tests are run, these tasks are run and if all goes well my extensions are published to the Marketplace in no time. And seeing as I have a pipeline to automate deployment, I can stick the build badge in the overview.md to display the current status of the deployment pipeline. In fact I like them so much I’ll put one here -