January 3, 2018
From time to time I need to review how I run some of my Sparkles ALM workshops and make sure I can run a number of hands-on TFS exercises for the attendees. Doing demos is great to show what the possibilities are of an integrated ALM/DevOps platform, but nothing beats doing exercises yourself via the keyboard.
A long time ago I prepared exercises myself and this took quite a bit of effort, especially if you wanted to have some existing data in TFS to play with. When Brian Keller came up with a full-blown Visual Studio ALM virtual machine, I quickly realized I had to move into that direction. In the beginning (TFS 2010 timeframe) I paid for a big hosted server on the Internet where I could run a number of VMs via Hyper-V, but this was also very time-consuming and error-prone to have it up-and-running for my workshops.
Enter the cloud … Microsoft Azure! A perfect fit right? Upload vhd, create an image and ready for VM creation!
Well, I will save you all the details but in the past I managed to get it working after overcoming lots of different obstacles and it remained a very manual process … but it worked.
With the release of the new Visual Studio ALM VM for TFS 2018, I decided to have another go at it (what else to do during your Christmas holidays?) and script my way into having automated fresh VMs in Azure. First I failed a number of times creating a working VM image for TFS and providing a custom image for Azure Dev/Test Labs. The problem here might have been that creating the general image (sysprep instructions) kills the SQL connection for TFS. In the end I decided to abandon this approach and chose to upload a specialized vhd file to Azure and create VMs from that point. Many thanks to Sachin Hridayraj from Microsoft to provide me an already sanitized vhd file for upload to my Azure subscription. Sachin runs the ALM/DevOps Hands-On-Labs at https://almvm.azurewebsites.net/.
The Microsoft ALM/DevOps Hands-On-Labs is a set of self-paced labs based on Visual Studio Team Foundation Server and Visual Studio Team Services. Evaluating your next DevOps toolchain? Want to go deep and learn how you can implement modern DevOps practices with Visual Studio, Team Services and Azure? If you said yes to any of these questions, then this VM and Hands-on-labs are what you are looking for.
My PowerShell script to create VMs based on this uploaded vhd file can be consulted on GitHubGist. It will allow you to create a number of VMs based on the original VSALM vhd file provided at https://almvm.azurewebsites.net/. Be aware of some limitations (for example: number of cores) linked to your Azure subscriptions which might block you to generate extra VMs.
Hopefully in the (near) future I might move this one final step forward to create new VMs on the fly from Azure Dev/Test Labs.
December 3, 2017
When doing TFS migrations I’m often faced with mismatches between the name of the Team Project Collection and the underlying database file name. Instead of keeping track of which TPC is linked with a specific database file name, I recommend to keep the names aligned to avoid confusion.
How to do this?
First, make sure you have a valid backup of the complete TFS environment. The easiest way is to enable a built-in TFS backup plan.
- Detach the Team Project Collection via the TFS Administration Console
- Detach the matching SQL Server database from SQL Management Studio
- Rename the underlying database (.mdf) file to match the desired name for the Team Project Collection (prefix with Tfs_).
- Attach the SQL database via the renamed .mdf file. A new log file database (.ldf) will automatically be created. You can remove the old .ldf file.
- Attach the renamed database as a Team Project Collection via the TFS Administration Console and apply the desired Team Project Collection name (without prefix Tfs_).
July 27, 2017
Lately I have to deal more with .NET Core Web Applications to setup build and release definitions in VSTS. What always comes up is how to deal with specific application settings which must me updated for a specific environment.
I have always been a big advocate of making a clear separation between build and release. The build should simply generate a generic package while the release should pick up the package and deploy it to any possible environment. At deployment time the specific enviroment values should be injected. Web Deploy has been the obvious tool in the past to make this happen with the capability to update the generated setparameters.xml file in a deployment action which injected the environment values into the web.config file.
Now with .NET Core and the typical appsettings.json file, it has become really easy in VSTS to inject custom values into the appsettings.json file.
Example of appsettings.json file in my solution:
Imagine that you would want to replace the values for the different settings (as from line 8). Note that it will also be possible to replace the values in the “Administrators” array.
First, you will need to create a build in VSTS which produces the deployment zip package (via dotnet publish command).
The VSTS release definition will link to the build output and you can use the built-in release task “Azure App Service Deploy” to deploy the build output to an Azure App Service.
The “File Transformation” section in the release task offers the possibility to define the JSON variable substitution. You will need to provide the file name from the root and the environment values (pay attention to the format of the variable names) can be set for the “DEV” environment.
Doing a file lookup from the console in the Azure Portal after deployment shows the result of the appsettings file.
Simple solutions are always the best solutions!
January 17, 2017
Visual Studio doesn’t always refresh the git remote/published branches in the Branches View.
My solution to force a sync in Visual Studio is calling the git remote “prune” command (https://git-scm.com/docs/git-remote). This command will immediately detect new remote branches or remove the “stale” branches. Instant update in Visual Studio.
September 14, 2016
Lately I have been planning a number of migrations to move small/big companies from TFS on-premises to Visual Studio Team Services (VSTS).
There are a number of options to migrate data from TFS to VSTS, but option 3 [high-fidelity database migration] is unfortunately not yet available. So, most of the time I still use custom/third-party tooling to perform the migration which is not always straightforward and may be very time-consuming.
One serious issue that popped up in a migration towards VSTS (using the TFS Integration Tools), was that the inline images in the Description field (or other html fields) of migrated work items were not properly migrated. The inline images are actually still referring to the old TFS on-premises environment because the html value of the Description field contains an <img> element with a source set to http://<tfs-on-prem>:8080/tfs/<tpc>/workitemtracking/v1.0/attachfilehandler.ashx?filenameguid=<guid>&filename=<filename>.png.
As a result, all inline images are only stored in the old TFS environment and they have not been uploaded to VSTS. The html value of the Description field has been migrated as-is. Initially you might not notice this after the migration of the selected work items because as long as the old TFS environment is still available, the inline image will be displayed. But what if the old TFS environment has been archived/destroyed?
To correct this and to upload the original images to VSTS, I have written some code (TFS API) to loop over the VSTS work items to detect image links to the old TFS environment. Using the source link of the original image, I can download the image to my local disk and upload it as an attachment to the VSTS work item. Finally, I’m replacing the original image source link with the new VSTS image link. Good to know is that once in-line images are detected inside the html field, those images are stored on the server and the temporary image file attachments may be deleted as well.
June 9, 2016
In the last couple of months I do get more requests to move TFVC version control history to a git repository in Visual Studio Team Services (VSTS). The migration from TFVC to TFVC is at the moment possible via the TFS Integration Tools and is not that straightforward to accomplish. Migrating to a git repository is much simpler and is certainly the way to go if you were already planning to adopt git in the future. The migration can be done via Git-TF which is a set of cross-platform command-line tools that facilitate sharing of changes between Team Foundation Server, Visual Studio Team Services and Git.
What do you need to get started?
- Download git via https://git-scm.com/downloads
- Download and extract Git-Tf to your computer
- Add the extracted git-tf path to the system environment variable “path”
- Create a new “git” Team Project in VSTS
- Open a command-line prompt and navigate to a directory where you want to host the local git repository
- Call git-tf clone to push all TFS changeset info from TFVC to a new local git repo. The first argument is the Team Project Collection url. You pass the TF version control path to the exact branch in the second argument and you end the command with the “deep” flag to ensure that the full history of the branch is moved into separate commits in the git repo. Pass your credentials to connect to TFS and execute the command.
- Once you have a local git repository it’s easy to push it towards an empty central VSTS git repository. First use the git remote add command to link your local git repo to the remote “origin” and afterwards you can push all changes via git push.
Navigate to the Code Hub in your VSTS Team Project and you should see all code history inside the git repo. What’s a big plus is that the original changeset date/time stamps are now part of the git commit info.
March 7, 2016
By default TFS doesn’t pay attention to the time part in work item queries when comparing datetime values. If you want to launch a query and you need to take into account the exact timestamp, you must switch off the dayPrecision parameter in the Query constructor.
using the dayPrecision parameter in the Query constructor
MSDN documentation: https://msdn.microsoft.com/en-us/library/bb133075(v=vs.120).aspx