Azure DevOps: Disable auto update of extensions on Team Foundation Server

You can install Azure DevOps extensions on Team Foundation Server from the Marketplace. And as the publishers push updates to these extensions, the installed extensions on your Team Foundation Server (TFS) also get updated. Some enterprises have a requirement of disabling this auto-update feature, here is how you can do that.

Run the below SQL script on the configuration database of your Team Foundation Server instance, the database is typically named Tfs_Configuration,

UPDATE [Tfs_Configuration].[dbo].[tbl_JobDefinition]
SET EnabledState = 2
WHERE PartitionId > 0 AND JobId = ‘A8F60BD0-BCBA-4343-82B3-FD6B40D657D8’

This script disables the update job which is resposible for auto-updating of extensions.

Reach out to vsmarketplace at microsoft dot com if you have any questions.

Azure DevOps: Test plan edit not working!

[Update 7th Feb, 2019] A fix for this is now rolled out to all rings so it should be working as expected.

If you are wondering why clicking on edit in the test plans directory page is not working, it’s a recent regression that we are working to get hotfixed as soon as possible. So if you navigate to the test plans directory page and try to click on Edit, nothing happens:

If you open the browser console you will see an error that says,

Failed to load resource: the server responded with a status of 404 ():

We have fixed the issue at our end and our waiting for the change to rollout with TFS deployment. Meanwhile, if you’d like the issue mitigated immediately please reach out to devops_tools at microsoft dot com, with your organization name.

Marketplace Extensions Vetting Process and Security Model

We get a lot of queries about the extension vetting process we have in Marketplace, as well as the security model for Azure DevOps extensions. Marketplace serves the extension ecosystem for Visual Studio Code, Visual Studio IDE and Azure DevOps; and we strive to make sure that the extensions available in the marketplace are of high quality and are secure. Here are some of the things we do in our pipeline to ensure safety:

  • We perform virus scan on both initial publish and subsequent update of an extension so that you aren’t getting malware from Marketplace. This also includes checking for npm and other dependent packages for known vulnerabilities like this.
  • We perform content scan on both initial publish and subsequent update of an extension so that you aren’t getting adult, offensive, CSAM (child sexual abuse material) and terrorist content from Marketplace.

Also, extensions can only operate within the scope and permissions it has been granted. For example: an extension which has only read permissions on work items cannot modify your features, bugs or any other type of work item. For Azure DevOps extensions, you can review the permissions that an extension requires in the Select Organization step as shown below,

extension permissions

For publishers:

  • Before a publisher can publicly list an Azure DevOps extension in Marketplace, we need to verify them. This requires that they send an email to us from their account and state their social presence (linkedin, twitter, github, organization etc.). This way we know them a little better and also get to understand that it is not a bot publishing an extension.

Apart from the above, we also rely on the community to bubble up quality extensions and report the ones that seem suspicious. We have Q&A and Ratings on each extension so that you can engage with an extension’s publisher(s) and have a meaningful dialogue. You can also use this Q&A capability to understand the software development life cycle practices the publisher follows, their test matrix and exit criteria. Do see what others are asking and if the publisher responds to them soon and in a meaningful way.

I also want to call out a few other important points,

  • There is no formal code review or evaluation process for extensions published to the Marketplace
  • Azure DevOps web extensions execute in the browser (iFrame) and can pull in scripts from other services (i.e. the extension is not limited to only the scripts it included within its package)
  • Azure DevOps web extensions run in isolation in the browser (a sandboxed iFrame) which prevents them from accessing Azure DevOps/TFS data or APIs they are not approved to access. You may have noticed that the admin is prompted to approve permissions when installing an extension that requires new permissions (e.g. “read only access to work items”). The extension is unable to do more than what it is authorized for at install time (and beyond what the current user of the extension is able to do). One way to protect yourself here is to carefully analyze the scopes being requested by the extension. If something doesn’t seem right, don’t install and contact vsmarketplace at microsoft dot com
  • There is no way for a web extension to install or run any code directly on the Azure DevOps or TFS servers. Build and Release tasks though, are a little different. These tasks get downloaded on the agent machine (which can be hosted or on-premise) and get executed. These tasks can download and invoke other code. To know more about the agent security model see this
  • Extensions should continue working after the sprintly Azure DevOps deployments and TFS upgrade since we maintain backward compatibility for all APIs that an extension can call. Any data stored by the extension (in a service provided by Azure DevOps and TFS) is not touched during these deployments/upgraded.

If you still have concerns with security, we recommend you install the extension on an isolated organization first to rest your concerns. This can be an internal test organization. After you’re satisfied with your testing, you can proceed to install the extension on your production organization. If you see compatibility issues after an update of the extension, please reach out to the publisher and report the same.

Hope all this information was helpful. Please reach out to vsmarketplace at microsoft dot com in case you have any more questions!

If you see a suspicious extension on Marketplace, do report it to us at vsmarketplace at microsoft dot com. You can also use the ‘Report Abuse’ link on the extensions details page to email us.









Test plan test case tree view counts have disappeared!

[Update: 6th Feb, 2019]: This issue should now be fixed in all the organizations now, you should be able to see the counts next to the test suites. Please reach out to devops_tools at microsoft dot com if you’re still having issues with this feature.

This post is a tad late but if you have reached this post via a google or bing search, you are likely wondering where the test point counts that used to appear in the suite tree have gone!?














As you can see, there’s no count against the test suites. You can follow more on this issue here,

We have fixed the issue but unfortunately the rollout has been slow because of several other issues. The good news is that the issue is now fixed in all the TFS rings (from ring0 to ring4). Ring 5 is still pending and should be done in a few more days.

If you’re still not seeing the count in your Azure DevOps organization it is likely that the org is in Ring 5. Please reach out to devops_tools @ microsoft dot com and we can enable the feature on your specific org to unblock you.

Hope this helps!

PS: Next time around I’ll try not to procrastinate a lot on these posts.



VSTS Incident Postmorten

Taylor Lafrinere from our VSTS team published two Root Cause Analyses which are really a good read. Sometime we all hit that one issue which makes you pull your hair out :-) I still remember the caching bug we hit in my previous team, where cache read/write were messing up validity check with dd/mm and mm/dd, maybe I should write about it someday. Here are RCA links,

Preliminary postmortem

Complete postmortem

The case of curious characters

We stumbled upon an interesting issue the other day at work. A was working on adding search feature to a table/grid of cells, consisting of multiple string and date fields. The implementation used a client side search utility provided by our client SDK, which internally used tries for indexing and searching on string tokens.

The feature was working well overall, but strangely the search was not working on date fields in IE (v11). It worked fine on other browsers. So if you searched for a string like ‘3/23’, it would work in Chrome and Firefox, but not in IE o_O

What is special about these date fields, we wondered, that makes this issue specific to IE? On a closer look, we found that the trie wasn’t getting properly constructed in IE. We jumped into the client SDK code, looked around but did not find anything suspicious, we also tried a bunch of other things like changing system date format, trying to enter date in a string field in another column and searching on it but the results didn’t really provide any clues.

V then stepped in and looked at the part of SDK where the trie was getting built and found that it somehow was failing to add date fields to the index. On debugging further, V found that the date string contained characters we had not expected, it wasn’t a usual string, it had stuff in it that was failing the trie construction.

How were the date fields getting added to the index?

Our implementation was calling toLocaleDateString() on the Date object and passing the string off to the search utility to build the index. It turns out that toLocaleDateString() were returning different values in Chrome vs in IE. Here’s a small piece of code that demonstrates this,

If you run this code in Chrome and IE, this is what you’ll see.




IE (v11)


What? Chrome reports length of the string as 8, which is what you’d expect. IE has got its own characters to the party. Turns out IE adds Left-to-Right markers in the string. The value 0x200E is the unicode code point for Left-to-Right mark. This marker gets added before every token in the date string, thus adding 5 characters to the string length.

The answer on this stackoverflow thread sums up the issue nicely,

Any of the output of toLocaleString, toLocaleDateString, or toLocaleTimeString are meant for human-readable display only

If the intent is anything other than to display to the user, then you should use one of these functions instead:

  • toISOString will give you an ISO8601/RFC3339 formatted timestamp
  • toGMTString or toUTCString will give you an RFC822/RFC1123 formatted timestamp
  • getTime will give you an integer Unix Timestamp with millisecond precision

To patch or not to patch

I was reading this post on designing rest APIs on, when I remembered an interesting discussion I had had a while ago when working on a feature. Warning: This might be mostly rant.

The feature in discussion here allowed the publisher of an extension to reply to reviews left by users on the extensions product page. The publisher could only create and edit a reply, delete had to be done via a support email to our team, but rest APIs were available to delete a reply that required admin permissions. As you can notice, these nicely fall into crud operations. Now, the reviews feature had already been implemented, modeled using REST. How would you model or design the new reply feature in terms of REST?

Do you consider the reply as a separate resource, and model crud operations on the new resource? Do you expect someone to HTTP GET a reply only? Does a reply make sense without the context of the review? Treat the reply like a sub-resource with its own crud operations?

Or are you the kind that thinks of replies as a property of reviews? A review either has a reply or not. Creating a reply would be like updating the review so you do it via a patch review call. Editing a reply is pretty much same so that too is done via patch. In this case the patch payload has instructions on what to do for the server. If the payload says update-reply, you either create or edit the reply. If the payload says delete-reply then you delete the reply associated with that review. But is this scheme ugly?

If you think of replies as a property, a call to get reviews for a product returns all the reviews and each review object has a reply object if one exists. Do you think getting replies should be optional and done based on a request Param? Something like get /extensions/my-awesome-extension/reviews?filteroption=includeReplies

We went with the latter approach. What are your thoughts on this?

Ratings and reviews on VS Marketplace!

We’ve enabled a rating and review system on VS Marketplace for VSTS and VSCode extensions. Until now, download count of an extension served as a proxy for estimating the quality of an extension but no more!

You can see a 5 star rating on the extension on the marketplace homepage. Note that rating and review was already available for Visual Studio extensions. This enables it for VSTS and VS Code extensions as well.

Hovering over the stars shows you the exact rating and the number of people who have rated this extension.


Clicking on the extension takes you to the details page, where we show the average rating of the extension and the number of ratings on the banner,


If you notice carefully, you can see that that color of the stars on the banner will change between orang-ish or red-ish based on the background color on which it is rendered. This is done so that the stars have a nice contrast and can be seen clearly against the background. Here’s an example: red stars on a light background and orange stars on a dark background,



You can click on the stars to scroll down to the details section,


The detailed section consists of, as you can probably guess, details of the reviews. You need to be logged-in to leave a review, you can use your Microsoft Account or any other AAD backend account for this. The detailed section shows the picture and the display name associated with your profile. You can easily change this by clicking on your name at the top and then editing your profile details,



The name and picture you set here will be used in the review details section. So you have the control to change this anytime.

Clicking on the ‘Write a review’ button brings up the review submit dialog, (who’s excited about pink buttons! :-)


You need to provide a rating, that’s mandatory. The submit button will be disabled until you select a rating. The review comment is optional and you can choose not to enter any text, though I recommend entering the text as it helps the developer get more details out of the review and figure out what you like/dislike about the extension.

After you provide a rating and review comment, click on ‘submit’ and your review will magically appear in the details section!


If you see a review that’s offensive or just plain spam, use the flag icon on the review to report it. We have three categories that show up currently,


You can select the most relevant option while reporting a review. Our team will run through the reported reviews and take appropriate action based on the content of the review.

That’s it for now, stay tuned for more!

You can read more about this here,

We’d love to hear any feedback, feel free to leave a comment or ping me on twitter at @prabhuk

Visual Studio 2015 and .NET 4.6 Released (and more!)


Big release day today! Microsoft today announced the release of Visual Studio 2015, Visual Studio 2013 Update 5, TFS 2013 Update 5, .NET 4.6

Check out the blog posts below for more details on what’s new in the release.

The Visual Studio Blog

Soma’s blog post

ScottGu’s Blog

.NET Blog – Announcing .NET 4.6

Note that one big guy missing from the list is TFS 2015, it’s still in RC2 and will be RTM’ed very soon.

Take the tools out for a spin and if you have any feedbacks or suggestions send them across using Send-a-Smile, User Voice or the Visual Studio Connect Site

Using SonarQube IntelliJ plugin for Code Analysis

SonarQube provides a plugin for IntelliJ (and Eclipse as well) which is a great tool to perform dev-box code analysis before committing or checking-in your changes. It gives the developers a chance to check and make sure they aren’t introducing any new defects or technical debt in the code they have added or modified. Here’s how to set up the plugin and get going.

Install SonarQube IntelliJ Plugin

  • Launch IntelliJ and go to File -> Settings -> Plugins
  • Search for ‘sonarqube’ and install the plugin


Setting up SonarQube plugin

  • In IntelliJ go to File -> Settings -> Other Settings -> SonarQube
  • Add details about the sonar server here. The plugin will use this to download the quality profile/analyzers etc.
  • This plugin executes the analysis in preview mode where no data is pushed to the server.


Associate your IntelliJ project with Sonar project

  • Right click on the project in IntelliJ and select "Associate with SonarQube…"
  • Search for the sonar project and select it


Running the analysis

  • Make your code changes
  • Right click on the project and select Analyze -> Run Inspection by Name…


  • In the search box type "Sonarqube" and select "SonarQube Issue" from the result list
  • In the "Inspection Scope" dialog, select Custom Scope and set its value to Changed Files. This will ensure that the analysis is run on the files modified by you.



  • The plugin will run the preview analysis and display the results in the inspection tab. The inspection shows issues in two files which were modified before the analysis.