Tuesday, 2 February 2016

Build ASP.Net 5 (RC1 Update1) Project with Visual Studio Team Services Build

Building ASP.Net 4 MVC witth VS Team Services Build and deploying it to Azure web site with VS Team Services Release, is somewhat straight forward. But building an ASP.Net 5 MVC 6 (EF 7) web application with VS Team Services hosted build services, and deploying it with VS Team Services Release, requires some addtional steps.

(Asp.Net 5 is now no more and named as ASP.Net Core 1.0. It is a name change and still the ASP.Net 5 RC1 Update1 is the available version. ASP.Net Core 1.0 is not released yet.)

Let’s look at steps required to build ASP.Net 5 RC1 Update1, MVC 6 web application with Visual Studio Team Services build.

Simple web application with ASP.Net 5 should be created and checked in to TFS.image

CI Build

First try to create a CI build which builds each changeset checked in. Create a build definition and add a Visual Studio Build step.image

When a build is triggered with above defintition it fails giving below error.

C:\Program Files (x86)\MSBuild\Microsoft\VisualStudio\v14.0\DNX\Microsoft.DNX.targets(126,5): Error : The Dnx Runtime package needs to be installed. See output window for more details.image

This is because hosted build server does not have dnx Runtime packages available in it. As explained in article here use the script to download the required packages before build. Slight modification done to support the releative path of the project, with the location of the script in the verision control.image

image

A gobal.json file added to supply the dnx version that is required to dnu restore.image

image

A new build step should be added to execute the Pre Build script, to install the dnx packages using dnu restore.image

Dnx packages (rc1 update1) get installed with the pre build step. image

But the build step still look for beta8 of dnx packages, and dnu restore does not seem to be working.image

To install the latest dnx in the hosted build server, add to “dnvm upgrade -r clr” Pre Build script.image

Because of a missing mistake in the path of the project.json location, in the script below error occured.

CS0234: The type or namespace name 'AspNet' does not exist in the namespace 'Microsoft'image

This error fixed by making sure relative path to the is correct.image

Final script here.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# bootstrap DNVM into this session.
&{$Branch='dev';iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/aspnet/Home/dev/dnvminstall.ps1'))}

# load up the global.json so we can find the DNX version
$globalJson = Get-Content -Path $PSScriptRoot\..\..\EventBooking\global.json -Raw -ErrorAction Ignore | ConvertFrom-Json -ErrorAction Ignore

if($globalJson)
{
    $dnxVersion = $globalJson.sdk.version
}
else
{
    Write-Warning "Unable to locate global.json to determine using 'latest'"
    $dnxVersion = "latest"
}

# install DNX
# only installs the default (x86, clr) runtime of the framework.
# If you need additional architectures or runtimes you should add additional calls
# ex: & $env:USERPROFILE\.dnx\bin\dnvm install $dnxVersion -r coreclr
& $env:USERPROFILE\.dnx\bin\dnvm install $dnxVersion -Persistent

# run DNU restore on all project.json files in the src folder including 2>1 to redirect stderr to stdout for badly behaved tools
Get-ChildItem -Path $PSScriptRoot\..\..\EventBooking -Filter project.json -Recurse | ForEach-Object { & dnu restore $_.FullName 2>1 }

dnvm upgrade -r clr

Then works dnu restore and build succeeds.image

image

With CI build the build output is not made available. But for release bbuild we need artifacts to be able to downloaded and deployed with Visual Studio Team Services Release.image

Release Build and Publich Artifacts

Let’s clone this CI build and create a release build. The steps to publish build artifacts for an ASP.Net 5 application is explained here. Using the script available in the article, a modification added to make it work without having a Team Project namea and releative path to project is set.image

Modified script.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
param($projectName, $buildConfiguration, $buildStagingDirectory)
 
$VerbosePreference = "continue"
$ErrorActionPreference = "Stop"
     
&{$Branch='dev';iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/aspnet/Home/dev/dnvminstall.ps1'))}
$globalJson = Get-Content -Path $PSScriptRoot\..\..\EventBooking\global.json -Raw -ErrorAction Ignore | ConvertFrom-Json -ErrorAction Ignore
 
if($globalJson)
{
    $dnxVersion = $globalJson.sdk.version
}
else
{
    Write-Warning "Unable to locate global.json to determine using 'latest'"
    $dnxVersion = "latest"
}
 
& $env:USERPROFILE\.dnx\bin\dnvm install $dnxVersion -Persistent
 
$dnxRuntimePath = "$($env:USERPROFILE)\.dnx\runtimes\dnx-clr-win-x86.$dnxVersion"
     
#& "dnu" "build" "$PSScriptRoot\src\$projectName" "--configuration" "$buildConfiguration"
Write-Warning "Path is $PSScriptRoot\..\..\EventBooking\$projectName"
 
& "dnu" "publish" "$PSScriptRoot\..\..\EventBooking\$projectName" "--configuration" "$buildConfiguration" "--out" "$buildStagingDirectory" "--runtime" "$dnxRuntimePath"

THis script is added to source control to a Post Build script folder.image

A build post step added to execute the post build ASP.Net 5 publish step and below arguments passed to script.

-projectName "BookMyEvents" -buildConfiguration $(BuildConfiguration) -buildStagingDirectory $(build.stagingDirectory)

$(build.stagingDirectory) is temporary location to publish and it is a predefined agent build variable.image

image

Above will publish the ASP.net 5 application but it is not available to download yet.To get the published output available to download, add Copy and Publish Build Artifact step. For this specify the $(build.stagingDirectory) as the Copy Root and provide an Artifact Name. Set the Artifact Type to Server.image

Downloaded build artifact containes the published ASP.Net 5 application.image

image

image

In the next post let’s look at how to get the ASP.Net 5 RC1 Update 1 application, deployed as Azure web application using Visual Studio Team Services Release.

5 comments:

Smith Cole said...

Wow, what an informative post. Here described info graphically how to build asp.net 5 with visual studio. so It is easy to read and understand. Visual Studio Team Services now has Release Management Services available as public preview. Thanks a lot for sharing with us.I had some idea about asp.net when I hosted my business through Myasp.net.

Lewis said...

I had just gone through this and finally got my builds to work. But now they have taken down the dnvminstall.ps1 you reference in your script

All my builds now fail

Chaminda Chandrasekara said...

@Lewis

This is because changes made to the ASP.Net Core 1.0, and hosted build is no longer supporting what is described in this post. if you still want to get the ASP.NET 5(RC1 Update1) build done the option is to setup your own build agent, with manually setting up ASP.NET5 RC1 UPdate1 for build agent user and add it to VS Team Services.That agent would be able to build without using the script. Other option is to migrate the project to latest. Migration guides are available. https://docs.asp.net/en/latest/migration/rc1-to-rtm.html

Chaminda Chandrasekara said...

@Lewis

Let explain local build agent scenario more clearly.

1. First get a local machine connected as build agent to VS team services, or to your on premise TFS. Configure the Agent to run as windows service and use a local or your domain user as the service account.

2. Logon to build agent machine with the agent user and setup ASP.NET 5 RC1 Update 1. Make sure you have .dnx and all its content in the build agent users c:\users\profilename\.dnx for example my agent has C:\Users\chamindac\.dnx (you can copy .dnx in your dev environment to the local build agent machine)

3. Then as in the SetDNX.ps1 comment the line #&{$Branch='dev';iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/aspnet/Home/dev/dnvminstall.ps1'))}

4. add path variable set command to script after & $env:USERPROFILE\.dnx\bin\dnvm install $dnxVersion -Persistent

$env:Path += ";$env:USERPROFILE\.dnx\bin"

5. For the publishwebsite.ps1 comment the line #&{$Branch='dev';iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/aspnet/Home/dev/dnvminstall.ps1'))}

6. This should allow the build to work

Chaminda Chandrasekara said...

Here is the two scripts modified. Change as per your project paths
--------------------------------------------------------------
set dnx
--------------------------------------------------------------

# bootstrap DNVM into this session.
#&{$Branch='dev';iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/aspnet/Home/dev/dnvminstall.ps1'))}

# load up the global.json so we can find the DNX version
$globalJson = Get-Content -Path $PSScriptRoot\..\..\EventBooking\global.json -Raw -ErrorAction Ignore | ConvertFrom-Json -ErrorAction Ignore

if($globalJson)
{
$dnxVersion = $globalJson.sdk.version
}
else
{
Write-Warning "Unable to locate global.json to determine using 'latest'"
$dnxVersion = "latest"
}

# install DNX
# only installs the default (x86, clr) runtime of the framework.
# If you need additional architectures or runtimes you should add additional calls
# ex: & $env:USERPROFILE\.dnx\bin\dnvm install $dnxVersion -r coreclr
& $env:USERPROFILE\.dnx\bin\dnvm install $dnxVersion -Persistent
$env:Path += ";$env:USERPROFILE\.dnx\bin"

# run DNU restore on all project.json files in the src folder including 2>1 to redirect stderr to stdout for badly behaved tools
Get-ChildItem -Path $PSScriptRoot\..\..\EventBooking -Filter project.json -Recurse | ForEach-Object { & dnu restore $_.FullName 2>1 }

dnvm upgrade -r clr
--------------------------------------------------------------
publish script
--------------------------------------------------------------
param($projectName, $buildConfiguration, $buildStagingDirectory)

$VerbosePreference = "continue"
$ErrorActionPreference = "Stop"

#&{$Branch='dev';iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/aspnet/Home/dev/dnvminstall.ps1'))}
$globalJson = Get-Content -Path $PSScriptRoot\..\..\EventBooking\global.json -Raw -ErrorAction Ignore | ConvertFrom-Json -ErrorAction Ignore

if($globalJson)
{
$dnxVersion = $globalJson.sdk.version
}
else
{
Write-Warning "Unable to locate global.json to determine using 'latest'"
$dnxVersion = "latest"
}

& $env:USERPROFILE\.dnx\bin\dnvm install $dnxVersion -Persistent



$dnxRuntimePath = "$($env:USERPROFILE)\.dnx\runtimes\dnx-clr-win-x86.$dnxVersion"

#& "dnu" "build" "$PSScriptRoot\src\$projectName" "--configuration" "$buildConfiguration"
Write-Warning "Path is $PSScriptRoot\..\..\EventBooking\$projectName"

& "dnu" "publish" "$PSScriptRoot\..\..\EventBooking\$projectName" "--configuration" "$buildConfiguration" "--out" "$buildStagingDirectory" "--runtime" "$dnxRuntimePath"
--------------------------------------------------------------