Friday, May 17, 2024

Punished for spelling out

Amazing discovery/public service announcement of the day: between v15 and v16 of the Azure DevOps' .NET client API, the definition of GitHttpClient and its base (where most of the methods are) underwent some changes that might be breaking.

I'm looking side by side at two instances of Microsoft.TeamFoundation.SourceControl.WebApi.dll - one that comes with Visual Studio 2022 and sits under Common7\IDE\CommonExtensions\Microsoft\TeamFoundation\Team Explorer, and the one that comes with the Azure DevOps agent v2.210.1 and sits under externals\vstshost. Both have the Microsoft.TeamFoundation.SourceControl.WebApi.GitHttpClient class and its base GitHttpClientBase, but look at the GetRepositoriesAsync() method:

In v15:

GetRepositoriesAsync(string, bool?, bool?, object, CancellationToken)
GetRepositoriesAsync(Guid, bool?, bool?, object, CancellationToken )
GetRepositoriesAsync(bool?, bool?, object, CancellationToken)

Meanwhile in v16:

GetRepositoriesAsync(string, bool?, bool?, bool?, object, CancellationToken)
GetRepositoriesAsync(Guid, bool?, bool?, bool?, object, CancellationToken)
GetRepositoriesAsync(bool?, bool?, bool?, object, CancellationToken)

Where there used to be two optional boolean parameters in a row, there are now three. I've found similar discrepancies in other methods. You'd think, who cares, they are all optional with default values, who spells out those anyway. PowerShell scripts striving for Windows Server 2012 R2 compatibility, that's who.

There is a known (to me) issue in PowerShell 4 - it has trouble invoking .NET methods that have optional parameters with default values other than null. And it happens so that those methods have a parameter like that - the CancellationToken. So in order to keep things compatible, you'd want to spell out the method invokation in full, all the way to the CancellationToken. And that's where you get hard to debug errors. The script would work for you locally, then when executed in an Azure DevOps task, it would tell you that there is no overload of GetRepositoriesAsync() that takes 6 arguments.

The Mirosoft.TeamFoundationServer.Client package on NuGet contains version 19 of the same assembly, and its interface matches v16.

No comments:

Post a Comment