But it works on my PC!

The random thoughts of Richard Fennell on technology and software development

Duplicate project GUID blocking SonarQube analysis of Windows 10 Universal Projects

I have working on getting a Windows 10 Universal application analysed with SonarQube 6.x as part of a VSTS build. The problem has been that when the VSTS task to complete the SonarQube analysis ran I kept getting an error in the form

 

WARNING: Duplicate project GUID: "8ace107e-8e3c-4a1b-9920-e76eb1db5e53". Check that the project is only being built for a single platform/configuration and that that the project guid is unique. The project will not be analyzed by SonarQube. Project file: E:\Build1\_work\58\s\BlackMarble.Victory.Common.Module.csproj

… plus loads more similar lines.
The exclude flag has been set so the project will not be analyzed by SonarQube. Project file: E:\Build1\_work\58\s\BlackMarble.Victory.Ux.Common.csproj
… plus loads more similar lines.

WARNING: Duplicate project GUID: "1e7b2f4e-6de2-40ab-bff9-a0c63db47ca2". Check that the project is only being built for a single platform/configuration and that that the project guid is unique. The project will not be analyzed by SonarQube. 2017-06-09T15:50:41.9993583Z ##[error]No analysable projects were found but some duplicate project IDs were found. Possible cause: you are building multiple configurations (e.g. DEBUG|x86 and RELEASE|x64) at the same time, which is not supported by the SonarQube integration. Please build and analyse each configuration individually.
Generation of the sonar-properties file failed. Unable to complete SonarQube analysis.

Turns out the issue was that even though my CI build was only set to create an x86|Debug build the act of creating the .APPX package was causing both x64 and ARM builds to be build too, this was too much for SonarQube as it though I had a multiplatform build..

The answer was to pass a parameter into the Visual Studio build task to disable the creation of the .APPX package.

The parameter override required is /p:AppxBundle=Never. This overrides the setting of Always that was set in the .CSProj file.

 

image

Once this change was done analysis completed as expected. Just need to fix all the issues it found now!

401.1 Permission error with on-premises TFS when accessing the API with a PAT

Background

If you are creating VSTS build extensions you will need to get the build or release’s PAT token if you wish to call the VSTS REST API.

This is done using a call like this (Node)

 

import tl = require('vsts-task-lib/task');

var auth = tl.getEndpointAuthorization('SYSTEMVSSCONNECTION', false);

if (auth.scheme === 'OAuth') {

var token = auth.parameters['AccessToken'];

 

or (PowerShell)

 

$vssEndPoint = Get-ServiceEndPoint -Name "SystemVssConnection" -Context $distributedTaskContext

$personalAccessToken = $vssEndpoint.Authorization.Parameters.AccessToken

 

You pop the resultant PAT into the headers of your REST web request and you are away and running.

The Problem

I hit a problem using this logic on VSTS Extension when they are run on TFS. On VSTS all was fine, but on TFS I got an unexpected 401.1 permission error on the first REST call i.e. I could not access the VSTS REST API

I tried setting fiddling with rights of my build user account, it was not that. Also I tried setting the ‘Allow scripts to access OAuth token’ property for the build/release agent

 

image

But this does not help either. This option just makes the PAT available as an environment variable, so you don’t need to use the code shown above.

And anyway – it was all worked on VSTS so it could not have been that!

Solution

The answer was I had basic authentication enabled on my Test TFS VM, as soon as this is disabled (the default) everything leapt into life.

image

Version 2.0.x of my Generate Release Notes VSTS Task has been released with release rollup support

I have just released a major update to my Generate Release Notes VSTS Build extension. This V2 update adds support to look back into past releases to find when there was a successful release to a given stage/environment and creates a rollup set of build artifacts, and hence commits/changesets and workitems, in the release notes.

 

 

This has been a long running request on GitHub for this extension which I am pleased to have been able to address.

To aid backwards compatibility, the default behaviour of the build/release tasks is as it was before, it can be used in a build or in and release, and if in a release it only consider the artifacts in the current release that ran the task.

If you want to use the new features you need to enable them. This is all on the advanced properties

 

image

 

You get new properties to enable scanning past releases until the task find a successful deployment to, by default, the same stage/environment that is currently being released too. You can override this stage name to allow more complex usage e.g. generating the releases notes for what is changed since the last release to production whist in a UAT environment.

This change also means there is new variable that can be accessed in templates, this $Releases which contains all the releases being used to get build artifacts. This can be used on release notes to show the releases being used e.g.

 

**Release notes for release $defname**
**Release Number**  : $($release.name)   
**Release completed** $("{0:dd/MM/yy HH:mm:ss}" -f [datetime]$release.modifiedOn) **Changes since last successful release to '$stagename'**  
**Including releases:**  
$(($releases | select-object -ExpandProperty name) -join ", " )  

 

Generating a content

 

Release notes for release Validate-ReleaseNotesTask.Master
Release Number : Release-69 
Release completed 05/01/17 12:40:19
Changes since last successful release to 'Environment 2' 
Including releases: 
Release-69, Release-68, Release-67, Release-66 

 

Hope you find this extension useful

Deleting unwanted orphan XAML Build Controllers on a migrated VSTS instance

Whilst working with the VSTS Data Import Service I ended up migrating a TFS TPC up to VSTS that had an old XAML Build Controller defined. I did not need this XAML build controller, in fact I needed to remove it because it was using my free private build controller slot. Problem was I could not find a way to remove it via the VSTS (or Visual Studio Team Explorer) UI, and the VM that had been running the build controller was long gone.

The way I got rid of it in the end was the TFS C# API and a quick command line tool as shown below.

Note that you will need to delete any queued builds on the controller before you can delete it. You can do this via the VSTS browser interface.

Running Test Suites within a network Isolated Lab Management environment when using TFS vNext build and release tooling

Updated 27 Sep 2016: Added solutions to known issues

Background

As I have posted many times we make use of TFS Lab Management to provide network isolated dev/test environments. Going forward I see us moving to Azure Dev Labs and/or Azure Stack with ARM templates, but that isn’t going to help me today, especially when I have already made the investment in setting up a Lab Management environments and they are ready to use.

One change we are making now is a move from the old TFS Release Management (2013 generation) to the new VSTS and TFS 2015.2 vNext Release tools. This means I need to be able to trigger automated tests on VMs within Lab Management network isolated environments with a command inside my new build/release process. I have posted on how to do this with the older generation Release Management tools, turns out it is in some ways a little simpler with the newer tooling, no need to fiddle with shadow accounts etal.

My Setup

image

Constraints

The constraints are these

  • I need to be able to trigger tests on the Client VM in the network isolated lab environment. These tests are all defined in automated test suites within Microsoft Test Manager.
  • The network isolated lab already has a TFS Test Agent deployed on all the VMs in the environment linked back to the TFS Test Controller on my corporate domain, these agents are automatically installed and managed, and are handling the ‘magic’ for the network isolation – we can’t fiddle with these without breaking the Labs 
  • The new build/release tools assume that you will auto deploy a 2015 generation Test Agent via a build task as part of the build/release process. This is a new test agent install, so removed any already installed Test Agent – we don’t want this as it breaks the existing agent/network isolation.
  • So my only options to trigger the tests by using TCM (as we did in the past) from some machine in the system. In the past (with the old tools) this had to be within the isolated network environment due to the limitation put in place by the use of shadow accounts.  
  • However, TCM (as shipped with VS 2015) does not ‘understand’ vNext builds, so it can’t seem to find them by definition name/number – we have to find builds by their drop location, and I think this needs to be a UNC share, not a drop back onto the TFS server. So using TCM.EXE (and any wrapper scripts) probably is not going to deliver what I want i.e. the test run associated with a vNext build and/or release.
  • My Solution

    The solution I adopted was to write a PowerShell script that performs the same function as the TCMEXEC.PS1 script that used to be run within the network isolated Labe Environment by the older Release Management products.

    The difference is the old script shelled out to run TCM.EXE, my new version makes calls to the new TFS REST API (and unfortunately also to the older C# API as some features notably those for Lab Management services are not exposed via REST). This script can be run from anywhere, I chose to run it on the TFS vNext build agent, as this is easiest and this machine already had Visual Studio installed so had the TFS C# API available.

    You can find this script on my VSTSPowerShell GitHub Repo.

    The usage of the script is

    TCMReplacement.ps1
          -Collectionuri http://tfsserver.domain.com:8080/tfs/defaultcollection/
    -Teamproject "My Project"
    -testplanname "My test plan" 
    -testsuitename "Automated tests"
    -configurationname "Windows 8"
    -buildid  12345
       -environmentName "Lab V.2.0" 
    -testsettingsname "Test Setting"
    -testrunname "Smoke Tests"
    -testcontroller "mytestcontroller.domain.com"
    -releaseUri "vstfs:///ReleaseManagement/Release/167"
    -releaseenvironmenturi "vstfs:///ReleaseManagement/Environment/247"

    Note

  • The last two parameters are optional, all the others are required. If the last two are not used the test results will not be associated with a release
  • The is also a pollinginterval parameter which default to 10 seconds. The script starts a test run then polls on this interval to see if it has completed.
  • If there are any failed test then the script writes to write-error as the TFS build process sees this is a failed step
  • In some ways I think this script is an improvement over the TCMEXEC script, the old one needed you to know the IDs for many of the settings (loads of poking around in Microsoft Test Manager to find them), I allow the common names of settings to be passed in which I then use to lookup the required values via the APIs (this is where I needed to use the older C# API as I could not find a way to get the Configuration ID, Environment ID or Test Settings ID via REST).

    There is nothing stopping you running this script from the command line, but I think it is more likely to make it part of release pipeline using the PowerShell on local machine task in the build system. When used this way you can get many of the parameters from environment variables. So the command arguments become something like the following (and of course you can make all the string values build variables too if you want)

     

       -Collectionuri $(SYSTEM.TEAMFOUNDATIONCOLLECTIONURI) 
    -Teamproject $(SYSTEM.TEAMPROJECT)
    -testplanname "My test plan"
       -testsuitename "Automated tests"
    -configurationname "Windows 8"
    -buildid  $(BUILD.BUILDID)
      -environmentName "Lab V.2.0"
       -testsettingsname "Test Settings"
    -testrunname "Smoke Tests"
    -testcontroller "mytestcontroller.domain.com"
    -releaseUri $(RELEASE.RELEASEURI)
    -releaseenvironmenturi $(RELEASE.ENVIRONMENTURI)

     

    Obviously this script is potentially a good candidate for a TFS build/release task, but as per my usual practice I will make sure I am happy with it’s operation before wrappering it up into an extension.

    Known Issues

  • If you run the script from the command line targeting a completed build and release the tests run and are shown in the release report as well as on the test tab as we would expect.

    image

    However, if you trigger the test run from within a release pipeline, the test runs OK and you can see the results in the test tab (and MTM), but they are not associated within the release. My guess is because the release had not completed when the data update is made. I am investigating this to try to address the issue.
  • Previously I reported there was a known issue that the test results were associated with the build, but not the release. It turns out this was due to the AD account the build/release agent was running as was missing rights on the TFS server. To fix the problem I made sure the account as configured as follows”":

    Once this was done all the test results appeared where they should

    So hopefully you will find this a useful tool if you are using network isolated environments and TFS build

    Typemock have released official VSTS build extension

    Typemock have just released an official VSTS build extension to run Typemock Isolator based tests. Given there is now an official extension I have decided to deprecate mine, it is still available in the Marketplace but I would recommend using the official one 

    The new Typemock extension includes two tasks

    SmartRunner Task

    The SmartRunner is a unit test runner, that can run nunit and mstest based tests. It handles the deployment of Typemock Isolator.  SmartRunner can run on both Shared and On Premises Agents

    Typemock with VSTests

    This task acts as a wrapper to enable Typemock Isolator and then run your tests via VSTest. This task can only be used with On Premises Agents as the build agent needs to be running with admin privileges.

    Why have I got a ‘.NETCore50’ and a ‘netcore50’ folder in my nuget package?

    I recently posted on how we were versioning our Nuget packages as part of a release pipeline. In test we noticed that the packages being produced by this process has an extra folder inside them.

    image 

    We expected there to be a netcore50 folder, but not a .NETCore50 folder. Strangely if we build the package locally we only saw the expect netcore50 folder. The addition of this folder did not appear to be causing any problem, but I did want to find out why it had appeared and remove it as it was not needed.

    Turns out the issue was the version of Nuget.exe, the automatically installed version on the on-prem TFS build agent was 3.2, my local copy 3.4. As soon as I upgraded the build box’s nuget.exe version to 3.4 the problem went away

    Experiences versioning related sets of NuGet packages within a VSTS build

    Background

    We are currently packaging up a set of UX libraries as NuGet packages to go on our internal NuGet server. The assemblies that make up the core of this framework are all in a single Visual Studio solution, however it makes sense to distribute them as a set of NuGet packages as you might not need all the parts in a given project. Hence we have a package structure as follows…

    • BM.UX.Common
    • BM.UX.Controls
    • BM.UX.Behaviours
    • etc…

    There has been much thought on the versioning strategy of these packages. We did consider independent versioning of each of these fundamental packages, but decided it was worth the effort, keeping their versions in sync was reasonable  i.e. the packages have the same version number and are released as a set.

    Now this might not be the case for future ‘extension’ packages, but it is an OK assumption for now, especially as it makes the development cycle quicker/easier. This framework is young and rapidly changing, there are often changes in a control that needs associated changes in the common assembly; it is hence good that a developers does not have to check-in a change on the common package before they can make an associated changed to the control package whist debugging a control prior to it being released.

    However, this all meant it was important to make sure the package dependencies and versions are set correctly.

    Builds

    We are using Git for this project (though this process is just as relevant for TFVC) with a development branch and a master branch. Each branch has its own CI triggered build

    • Development branch build …
      • Builds the solution
      • Runs Unit tests
      • Does SonarQube analysis
      • DOES NOT store any built artifacts
      • [Is used to validate Pull requests]
    • Master branch build …
      • Versions the code
      • Builds the solution
      • Runs Unit tests
      • Creates the NuGet Packages
      • Stores the created packages (to be picked up by a Release pipeline for publishing to our internal NuGet server)

    Versioning

    So within the Master build we need to do some versioning, this needs to be done to different files to make sure the assemblies and the NuGet packages are ‘stamped’ with the build version.

    We get this version for the build number variable, $(Build.BuildNumber), we use the format $(Major).$(Minor).$(Year:yy)$(DayOfYear).$(rev:r)  e.g. 1.2.16123.3

    Where

    • $(Major) and $(Minor) build variables we manage (actually our release pipeline updates the $(Minor) on every successful release to production using a VSTS task)
    • $(Year:yy)$(DayOfYear) gives a date in the form 16123
    • and $(rev:r) is a count of builds on a given day

    We have chosen to use this number format to version both the assemblies and Nuget packages, if you have different plans, such as semantic versioning , you will need to modify this process a bit.

    Assemblies

    The assemblies themselves are easy to version, we just need to set the correct value in their assemblyinfo.cs or assemblyinfo.vb files. I used my Assembly versioning VSTS task to do this

    NuGet Packages

    The packages turn out to be a bit more complex. Using the standard NuGet Packager task there is a checkbox to say to use the build number as the version. This works just fine versioning the actual package, adding the –Version flag to the package command to override the value in the project .nuspec file. However it does not help with managing the versions of any dependant packages in the solution, and here is why. In our build …

    1. AssemblyInfo files updated
    2. The solution is built, so we have version stamped DLLs
    3. We package the first ‘common’ Nuget package (which has no dependencies on other projects in the solution) and it is versioned using the –version setting, not the value in it’s nuspec file.
    4. We package the ‘next’ Nuget package, the package picks up the version from the –version flag (as needed), but it also needs to add a dependency to a specific version of the ‘common’ package. We pass the –IncludeReferencedProjects  argument to make sure this occurs. However, Nuget.exe gets this version number from  the ‘common’ packages .nuspec file NOT the package actually built in the previous step. So we end up with a mismatch.

    The bottom line is we need to manage the version number in the .nuspec file of each package. So more custom VSTS extensions are needed.

    Initially I reused my Update XML file task, passing in some XPath to select the node to update, and this is a very valid approach if using semantic versioning as it is a very flexible way yo build the version number. However, in the end I added an extra task to my versioning VSTS extension for Nuget to make my build neater and consistent with my other versions steps.

    Once all the versioning was done I could create the packages. I ended up with a build process as shown below

    image

    A few notes about the NuGet packaging

    • Each project I wish to create a Nuget package for has a nuspec file of the same ‘root’ name in the same folder as the csproj eg. mypackage.csproj and mypackage.nuspec. This file contains all descriptions, copyright details etc.
    • I am building each package explicitly, I could use wildcards in the ‘Path/Pattern to nuspec files’ property, I choose not to at this time. This is down to the fact I don’t want to build all the solution’s package at this point in time.
    • IMPORTANT I am passing in the .csproj file names, not the .nuspec file names to the ‘Path/Pattern to nuspec files’ property. I found I had to do this else the   –IncludeReferencedProjects  was ignored. The Nuget documentation seems to suggest as long as the .csproj and .nuspec files have the same ‘root’ name then you could reference the .nuspec file but this was not my experience
    • I still set the flag to use the build version to version the package – this is not actually needed as the .nuspec file has already been update
    • I pass in the  –IncludeReferencedProjects  argument via the advanced parameters, to pick up the project dependancies.

    Summary

    So now I have a reliable way to make sure my NuGet packages have consistent version numbers 

    New version of my generate release notes task–now with authentication options

    I have just released 1.4.7 of the release notes VSTS extension. This provides a new advanced options that allows you to switch the authentication model.

    The default remains the same i.e. use a personal access token provided by the server, but you have the option to enable use of the 'defaultcredentials' (via the advanced properties). If this is done the account the build agent is running as is used. Hopefully this should fix the 401 issues some people have been seeing when using the task with on-prem TFS.

    For most people the default PAT model should be fine

    New Build Management VSTS tasks

    Just published a new VSTS extension with a couple of tasks in it. The aim to to help formalise the end of a release process. The tasks

    • Allow you to set the retension ‘keep forever’ flag on a build (or all builds linked to a release)
    • Update increment a build variable e.g. all or part of a version number, in a build (or all builds linked to a release)

    The first just replicates functionality I used to have in house for builds

    The second one is important to me as once I have released to production a version of a product I never want to generate another build with the same base version number. For example we version stamp all our DLLs/builds with a version number in form

    $(Major).$(Minor).$(year:yy)$(dayofyear).(rev:r)     e.g. 1.2.16170.2

    Where the $(Major) and $(Minor) are build variables we set manually (we decide when we increment a major or minor release) and the second two blocks guarantee a unique build number every time. It is too easy to forget to manually increment the Major or Minor build variable during a release. This task means I don’t need to remember to set the value of one or both of these. I can either set an explicit value or just get it to auto-increment. I usually auto increment the Minor value as a default, doing a manual reset of both the Major and Minor if it is a major release.

    NOTE: You do have to add some permissions to the build service account else this second task fails with a 403 permission error – so read the WIKI