Friday, December 28, 2018

Federating TFS tables across collections

UPDATE: the outlined logic will break if your TFS instance has a mix of pre-AzDevOps collections with recently (2019+) created ones. Details here. The linked gist was updated, too.

As I've mentioned earlier, Team Foundation Server stores its data in multiple databases - one database per team project collection, and also a global database called Tfs_Configuration. How is one supposed to run cross-collection queries, then?

Sunday, May 27, 2018

Can't we just do a "Hello, world"?

The Joomla! component tutorial walks you through creating a Model-View-Controller (MVC) component. However, the Absolute basics of a component page also mentions that a component doesn't have to be MVC; it claims that a flat model is supported, but then spends no time explaining how it's supposed to work.

Friday, May 25, 2018

Name means ID, ID means name

Let's take a break from TFS.

This time, it's Joomla!, a popular Web CMS, which has an expansive, if sorely underdocumented, extension interface. Once again, I've discovered a little undocumented something, and would like to share.

Monday, May 21, 2018

Constrained and dignified

Another day, another TFS discovery.

I was facing a minor usability issue. We have an extension with several custom menu commands for release definitions pipelines. Out of those, two only make sense for server administrators. For anybody else, they'd error out anyway. The menu was getting crowded, so I wanted to see if I could make the admin-only commands hidden for non-admin users.

Monday, April 30, 2018

All TFS clients

The TFS API continues to be sorely underdocumented. This time, let's talk about the .NET one for a change. You're supposed to first construct a VssConnection, then get a client class or several. There's a separate client for source control, a client for work items, one for build/release tasks, etc. Here are all client classes that I could find in TFS 2018u1:

Friday, April 27, 2018

Who am I and what are my rights (in TFS)?

Some time ago, we've discussed OAuth in TFS. Recently, I've been attacking a related problem - we have a valid OAuth-based connection (a VssConnection object), it can invoke some REST endpoints via OAuth, but which ones? Turns out, the allowed scopes are stored within an OAuth token, it just takes a bit of parsing to retrieve. The following line on an ASPX page returns the scopes for a token:

string Scopes = new System.IdentityModel.Tokens.JwtSecurityToken(Token).Payload["scp"];

There's a sample gist for that.

Friday, March 16, 2018

All OAuth scopes in TFS 2018.1

Some time ago, I've discussed dumping all OAuth scopes in TFS, both documented and undocumented.

Now I have a TFS 2018 update 1 instance, and here's the OAuth scope dump for that version. Notable addition: wiki.

UPDATE: same for TFS Azure DevOps 2019.

The same caveat applies: some of those endpoints might be VSTS-only.

Friday, February 23, 2018

Uploading extensions to TFS

When creating a TFS extension, one ends up uploading it to the server all the time. Doing so through the Web UI is tedious, so here's a script for that.

It takes two parameters:

  • Server - the URL of the TFS instance, e. g. http://tfs.acme.com:8080/tfs/
  • File - the filename of the compiled .VSIX file, wildcards allowed
Since the file name of a compiled VSIX extension contains its version, the script takes wildcards in the File parameter. If there are multiple files that match the wildcard, the one with the latest modification date will be taken.

The script looks inside the VSIX to determine the publisher, the extension ID, and the version.

The script was meant for on-prem TFS. Microsoft's TFX command line tool can do the same for VSTS, but it doesn't support NTLM auth (because Node.js' HTTP client doesn't). Mine is in Powershell, where NTLM support comes out of the box.

Friday, February 16, 2018

All OAuth scopes in TFS

Did I already complain that the API surface of Team Foundation Server is sorely underdocumented? Well, it is. In today's episode, we're going to explore the gamut of things an OAuth Web client can and cannot do.

In my work, the OAuth clients are TFS client-side extensions. In order to access the TFS API, they need to declare the set of scopes they're interested in in the extension manifest. The scopes are supposed to be documented here, but the list over there is incomplete.