Release Management has been moving at a eager pace at Microsoft which you can see today on Visual Studio Team Services (VSTS). I have been waiting for this same experience to be available on-premises and I’m happy to say it is included with the Release Candidate of TFS 2015 Update 2!
Lots of new release management capabilities (This list from Brian Harry’s post)
- Support for installing extensions from the VS Marketplace
- Support for provisioning in SCVMM. This brings elements of Lab Management solution into RM. (available as a free extension in the marketplace)
- Support for provisioning in VMWare – Top customer request for Lab Management for a long time and now Microsoft has it. (available as a free extension in the marketplace)
- Build integration that allows you to easily see which environments a build has been deployed to.
- Test results integrated with release so you can correlate test results as your release advances through stages.
- and more…
Heck you can even create a Team Project from the Web now in Update 2! It does not configure Reporting Services or SharePoint integration but you can do that easily after the fact if it’s needed.
I’m going to update one of my Release Management demo projects from last year where I have two Azure Virtual Machines (classic) behind an Availability Group exposed as a single cloud service. I’ve still got quite a few “classic” virtual machines kicking around so I think this scenario is still relevant.
If you don’t have a Team Project to follow along you can set one up for free here. Here is a link to the Get Started with VSTS page. If you need some development tools as well you can sign up for Visual Studio Dev Essentials.
Sample Web Project
I have a sample Web Application “contoso” but you can easily create a sample in Visual Studio 2015 by following these steps:
- Create a new ASP.NET Web Application project in Visual Studio, targeting .NET Framework 4.6.1
- Choose the MVC template
- Press the Change Authentication button and select No Authentication and press OK
- Make sure the Host in the cloud checkbox is not checked
- Press OK
Let’s create a Publish Profile (.pubxml) as we’ll need that later for Build and Release Management. Perform the following steps:
- Right click the Web Application and select Publish…
- Select Custom and enter a name for your Profile e.g. WebDeploy
- Choose Web Deploy Package as the Publish Method
- Enter a Package Location to create the package e.g. C:\temp\WebPackage.zip
- Enter a Site Name e.g. Default Web Site/MyWebSite
- Click Next
- Choose Configuration (Debug or Release) <– Doesn’t matter what you pick here we’re doing this in build anyways
- Click Next
- Click Close and answer Yes when prompted to Save.
If you look in your Web Project you should see a WebDeploy.pubxml located in a folder named PublishProfiles under Properties click on it so you can edit the file and change the following values:
<DesktopBuildPackageLocation>c:\temp\WebPackage.zip</DesktopBuildPackageLocation>
<DeployIisAppPath>Default Web Site/MyWebSite</DeployIisAppPath> so they look like this now:
<DesktopBuildPackageLocation></DesktopBuildPackageLocation>
<DeployIisAppPath>#{IIS Web Application Name}#</DeployIisAppPath>
This value will be replaced using a task to replace tokens in Release Management. If you have more than one (> 1) web project in your solution then you will want to read this post How to publish one web project from a solution.
After you have made those changes and saved them check your code in to VSTS or TFS. Here are the scripts I am going to use in this post:
This script relies on a build number format and two variables:
- MajorVersion
- MinorVersion
build number format to be specified, for this build I used this one:
$(BuildDefinitionName) $(MajorVersion).$(MinorVersion).$(Year:yy)$(DayOfYear)$(Rev:.rr)
This is the script we’ll use to create our Release Definition.
Make sure you download these scripts and include them as part of your solution and check them into version control (Git or TFVC). Your solution should look something like this
Create Build Definition
Configure a Build Definition to compile the web project and produce the required artifacts you will need for your Release Definition. Here are the steps:
From the TFS/VSTS web portal click:
- (1) Build
- (2) +
- (3) Create
Note: Your defaults displayed in this dialog may not be identical as what is pictured below
You should have a build definition displayed, if you want to use the ApplyVersionToAssemblies.ps1 script as part of your build definition perform the following:
- (1) Click Add build step…
- (2) Click Utility
- (3) Locate the PowerShell task and click Add
- (4) Click Close
- (5) Drag and drop the PowerShell task immediately before the Visual Studio Build task
We need to add another Build step as well to organize our build artifacts
- (1) Click Add build step…
- (2) Click Utility
- (3) Locate the Publish Build Artifacts task and click Add
- (4) Click Close
Delete the Copy Files task (we don’t need it for this particular scenario)
- (1) Click X to the right of the Copy Files task
- (2) Click Save and enter an optional comment and click OK
So lets configure the individual tasks and setting for the Build Definition, we’ll start with the tasks in order:
Nuget Installer: No configuration required
PowerShell: Select the PowerShell script to update the version number in all AssemblyInfo files (see screenshot below)
Visual Studio Build: Add the following MSBuild Arguments to package our website:
/p:DeployOnBuild=true /p:PublishProfile=WebDeploy /p:WebPublishMethod=Package /p:PackageAsSingleFile=true /p:SkipInvalidConfigurations=true /p:PackageLocation=$(Build.ArtifactStagingDirectory)
04/14/2016 UPDATED PackageLocation value – removed double quotes and backslashes
Visual Studio Test: No configuration required
Index Sources and Publish Symbols: No configuration required
Publish Build Artifacts:
- Path to Publish: $(Build.ArtifactStagingDirectory)
- Artifact Name: Deploy
- Artifact Type: Server
Publish Build Artifacts #2:
- (1) Click the task
- (2) Click the elipsis (…) to select artifact(s)
- (3) Select the folder the PowerShell script is in
- (4) Click OK
- (5) Path to Publish: contoso.web/scripts/deploy
- (6) Artifact Name: Scripts
- (7) Artifact Type: Server
Now Click Save on your Build Definition (enter optional comment) and Click OK
Click Variables and Add the following variables:
- MajorVersion
- MinorVersion
Click General and replace the Build number format with this string:
$(BuildDefinitionName) $(MajorVersion).$(MinorVersion).$(Year:yy)$(DayOfYear)$(Rev:.rr)
Let’s Click Queue Build… to see if we’re good. The Build is successful and I can explore my Deploy and Script artifacts that were produced by the build.
Create Release Definition
Here is the link for Help Getting Started with Release Management. Let’s continue, from the TFS/VSTS web portal click:
- (1) RELEASE
- (2) +
- (3) Empty
- (4) OK
The first thing you will want to do it give it a name and then we’ll link it to the build definition we created earlier.
Enter a name for the Definition: Publish Website and click Save.
- (1) Click Link to a build definition
- (2) Select the Build Definition “Deploy Website” we created previously
- (3) Click Link
- (4) Click Save
Define a variable for the Web Application by performing the following steps:
(1) Click the elipsis (…) next to the name of the Default Environment
(2) Select Configure variables…
Enter the following values for your variable (as shown below):
- Name: IIS Web Application Name
- Value: Default Web Site/contoso-dev
- Click OK followed by Save
Let’s add a task for this environment (Default Environment)
(1) Click Add tasks…
Add the following tasks, I’ve indicated the category in brackets:
- Replace Tokens (Utility)
- Azure Resource Group Deployment (Deploy)
- Azure File Copy (Deploy)
- PowerShell on Target Machines (Deploy)
Note: For the Azure Resource Group Deployment task you will need to define a New Service Endpoint (Azure) for your Team Project if you don’t already have one.
Click on the Replace Tokens task and modify the following settings:
- Target files: **\*.xml
- Token prefix: #{
- Token suffix: }#
Click on the (1) Azure Resource Group Deployment task:
- (2) Azure Connection Type: Azure Classic
- (3) Azure Classic Subscription: <Your Service Endpoint Name Here> (If nothing here click Manage)
- (4) Action: Select Cloud Service
- (5) Cloud Service: <Cloud Service for your Classic VM>
- (6) Resource Group: rmodev-vm (this is a variable we’ll use later)
Click on (1) Azure File Copy task:
- (2) Source: $(System.DefaultWorkingDirectory)/Deploy Website
- (3) Azure Connection Type: Azure Classic
- (4) Azure Classic Subscription: <Your Service Endpoint Name here>
- (5) Destination Type: Azure VMs
- (6) Classic Storage Account: <Name of the storage account for the VM>
- (7) Cloud Service: <Cloud Service for your classic VM>
- (8) Admin Login: $(username)
- (9) Password: $(password)
- (10) Destination Folder: c:\temp
- (1) Click on PowerShell on Target Machines task:
- (2) Machines: $(rmodev-vm)
- (3) Admin Login: $(username)
- (4) Password: $(password)
- (5) Protocol: HTTPS
- (6) Test Certificate: Checked
- (7) PowerShell Script: C:\temp\Scripts\ConfigureWebServer.ps1
Click Save
Configure deployment conditions for the Default Environment by clicking on the elipsis (…)
Select Deployment conditions…
- (1) Select the After release creation option under Trigger
- (2) Click OK
- (3) Click Save
We need to create the username and password variables for the virtual machine:
- (1) Click Configuration
- (2) Click + Add variable and type password for the name
- (2) Type the password for the value
- (3) Click the lock icon to hide the characters of your password
- (4) Click + Add variable and type username for the name
- (4) enter the username for the value
Click Save
Now I think we’re ready to put the release to the test 🙂
- (1) Enter a Release Description if you’d like
- (2) Choose the build you’d like to release
- (3) Choose the deployment trigger (default is what we configured earlier)
- (4) Click Create
You will be brought to the Summary page
Click on Logs to watch your release to Default Environment
If you Click on Publish Website you can see all of the releases you’ve done
Hopefully you find this walkthrough useful and of course if you have any questions please leave a comment.
When I create the WebDeploy publish profile and do a build with VisualStudio on line I get an error:
##[error]C:\Program Files (x86)\MSBuild\Microsoft\VisualStudio\v14.0\Web\Microsoft.Web.Publishing.targets(3635,32):
Error MSB4023: Cannot evaluate the item metadata “%(RootDir)”.
The item metadata “%(FullPath)” cannot be applied to the path “”C:\a\1\a\\”\SPlan.zip”.
The given path’s format is not supported.
In the Log the build command has the parameter: /p:PackageLocation=”C:\a\1\a\\”
and the Microsoft.Web.Publishing.targets script is appending the file name to but the quotes are not removed.
LikeLike
Hello Robert,
Yes I saw this start to occur in hosted build after the last sprint deployment. Change the following msbuild parameter:
/p:PackageLocation=”$(build.artifactstagingdirectory)\\”
please change to the following:
/p:PackageLocation=$(build.artifactstagingdirectory)
Thanks for letting me know.
LikeLike
Wes,
I had figured out that issue, but now I can’t get the Powershell task to execute: I get an Access Denied message (However, I can run remote PowerShell sessions to the VM from my desktop with the same credentials). In checking the event logs on the VM I see:
Index : 104597
EntryType : FailureAudit
InstanceId : 4625
Message : An account failed to log on.
Subject:
Security ID: S-1-0-0
Account Name: –
Account Domain: –
Logon ID: 0x0
Logon Type: 3
Account For Which Logon Failed:
Security ID: S-1-0-0
Account Name: xxxxx
Account Domain: xxxxx
Failure Information:
Failure Reason: %%2304
Status: 0xc000006d
Sub Status: 0x0
It seems that NTLM authentication is failing. Any suggestions?
LikeLike
After getting side tracked for a week I am back working on this and have a few updates.
After messing with permissions I got a bit further and I was getting a 404 error message in the Powershell step. Digging deeper I found it was really a 404.7 error! (extension not recognized).
Further digging revealed that when I installed Web Deploy 3.6 from the Web Platform Installer the install did not register the .adx extension correctly. As the Platform Installer does not have an repair or uninstall and does not register it’s installs so the apps don’t show up for uninstall in the Programs and Feature list, had to spin up a new VM to proceed.
I tracked down a MSI installer for Web Deploy 3.5 and installed that on the new VM and did the rest of the setup. I was able to get the Deploy packages on the destination system and, after modifying the ConfigureWebServer.ps1 for the new package name and path, got the Powershell script to execute.
Now I am getting a message : Site ‘#{IIS Web Application Name}#’ does not exist in the Err.log. After some more fiddling it appears that the Replace Tokens step is not putting the site name in from the Configure Variables section.
The log shows:
Replacing tokens in file ‘C:’C:\a\9ad361018\SPlan Web Deploy\381e3298b\FetchManifest.xml’…
Replacing tokens in file ‘C:\a\9ad361018\SPlan web Deploy\Deploy\SPlan.SetParameters.xml’…
Replacing tokens in file ‘C:\a\9ad361018\SPlan web Deploy\Deploy\SPlan.SourceManifest.xml’…
This is a feature I really need to get the release system working (I use a different site name for the staging server).
LikeLike
Great tutorial. Any change to add release steps to on-premises servers?
LikeLike
With TFS 2015 Update 2.1 on-premises the steps should be the same.
Cheers,
Wes
LikeLike
Thanks for the reply. But these two will be different, no?
2. Azure Resource Group Deployment (Deploy)
3. Azure File Copy (Deploy)
Thanks again.
LikeLike