DevOps for ASP.NET Core RC2

Picking up where I left off in How to Build ASP.NET Core RC2 Code with Visual Studio Team Services, we are going to extend this to support the out of the box Visual Studio Build task, run unit tests, and deploy to Azure.

I will assume you have read and completed the previous post.  In this post, instead of calling the dotnet command line tool to build our project, we are going to use the out of the box Visual Studio Build task. To do that we are going to need to add another package to your private agent that we built in the previous post.

  1. RDP into your build agent
  2. Install the Visual Studio official MSI Installer on your build machine from here

This will make sure all the required target files are installed so we can use the out of the box Visual Studio Build task to build our solution.  I want to use this task so that in future posts we can add UI test and database projects and build everything with a single task.

On your development machine make sure you install the .NET Core RC2 SDK as well.  Instructions on how to set up your development machine are here. With your development machine running Visual Studio 2015 Update 2 and with the .NET Core RC2 SDK installed, we can begin by creating our web application.

  1. Start Visual Studio
  2. Select File / New / Project…
  3. Select .NET Core category under Visual C#
  4. Select ASP.NET Core Web Application (.NET Core) image
  5. Click OK
  6. Select Web Application
  7. Click Change Authentication
  8. Select No Authentication
  9. Click OK
  10. Make sure Host in the cloud is unchecked
  11. Click OK

With the web application created, we can now add our test project.

  1. Right-click on src folder
  2. Select Add / New Project…
  3. Select .NET Core category under Visual C#
  4. Select Class Library (.NET Core)
  5. Add .Tests to the name of the project
  6. Click OK

Now that we have our class library, we need to add xUnit.

  1. Open project.json from the class library project
  2. Replace the contents of the file with the JSON below
    {
        "version": "1.0.0-*",
        "testRunner": "xunit",
        "dependencies": {
            "xunit": "2.1.0",
            "dotnet-test-xunit": "1.0.0-rc2-build10015"
        },
        "frameworks": {
          "netcoreapp1.0": {
             "dependencies": {
                "Microsoft.NETCore.App": {
                   "type": "platform",
                   "version": "1.0.0-rc2-3002702"
                }
             },
             "imports": [
                "dnxcore50",
                "portable-net45+win8"
             ]
          }
        }
    }
  3. Save file
  4. Right-click references of the test project
  5. Select Add Reference…
  6. Select the Project / Solution section
  7. Check the box next to your web project

With the dependencies added, we can now write our first test.

  1. Open Class1.cs
  2. Add the following using statements:
    using {YourProrjectName}.Controllers;
    using Microsoft.AspNetCore.Mvc;
    using Xunit;
  3. Add the code below to the file:
    [Fact]
    public void Index()
    {
       // Arrange
       var target = new HomeController();
    
       // Act
       var result = target.Index() as ViewResult;
    
       // Assert
       Assert.NotNull(result);
    }

Now we have a web application and unit tests.  We can now check into Team Services and start creating our build and release definitions. You can use either Git or TFVC.

  1. Open Team Explorer
  2. Check your code into Team Services

With your code checked in, we can focus on our build.  We are going to need a task to zip up the publish folder to deploy to Azure.  You can get access to a zip task using the Trackyon Advantage extension.  This extension is a collection of tasks to enable DevOps for any language targeting any platform.

  1. Visit https://marketplace.visualstudio.com/items?itemName=Trackyon.trackyonadvantage
  2. Click Install
  3. Select your account
  4. Click Continue
  5. Click Confirm
  6. Click Proceed to the account

Now with Trackyon Advantage installed, we can create our build.

  1. Click the Build hubimage_thumb4 in Visual Studio Team Services
  2. Click the green plus 
  3. Select the Empty template
  4. Click Next
  5. Select your repository
  6. Check the box for Continuous integration
  7. Select Default agent queue
  8. Click Create

With the build created, we need to add the required tasks.

  1. imageClick Add build step…
  2. Click Add next to Visual Studio Build task
  3. Select the Utility category
  4. Click Add next to Command Line task three (3) times
  5. Click Add next to Trackyon Zip
  6. Click Add next to Copy and Publish Build Artifacts
  7. Select the Test category
  8. Click Add next to Publish Test Results
  9. Click Close 
  10. Drag and drop one of the Command Line task to the top
  11. Drag and drop the Publish Test Results task between the other two Command Line tasks
  12. Select the first Command Line task 
    Field Value
    Tool dotnet
    Arguments restore
  13. Select the Visual Studio Build task
    Field Value
    Solution **\*.sln
    MSBuild Arguments  
    Platform $(BuildPlatform)
    Configuration $(BuildConfiguration)
  14. Select the second Command Line task 
    Field Value
    Tool dotnet
    Arguments test . -xml test-results.xml
    Working folder {Path to Test Project folder}
  15. Select the Publish Test Results task 
    Field Value
    Test Result Format XUnit
    Test Results Files **/TEST-*.xml
  16. Select the third Command Line task
    Field Value
    Tool dotnet
    Arguments publish -c $(BuildConfiguration)
    Working folder {Path to Web Project folder}
  17. Select the Trackyon Zip task
    Field Value
    Folder to Zip src/{Project Name}/bin/$(BuildConfiguration)/netcoreapp1.0/publish
    Path to final Zip File website.zip
  18. Select the Copy and Publish Build Artifacts task
    Field Value
    Contents **/*.zip
    Artifact Name drop
    Artifact Type Server
  19. Click Variables tab
  20. Add the following variables:
    Name Value
    BuildConfiguration release
    BuildPlatform any cpu
  21. Click General tab
  22. Click Add Demand
    Field Value
    Name ASP.NET_Core
    Type equals
    Value RC2

    image_thumb7
    This makes sure that only the agent that has ASP.NET Core RC2 installed is selected to run this build.
  23. Click Save
  24. Name build
  25. Click OK
  26. Click Queue build…
  27. Click OK

Once the build is done, you can verify the test results were published and browse the artifact to see the zip produced by the build.  Now from the build summary we are going to create our release to deploy our code into Azure.

  1. imageFrom the build summary, click the Create release link under Deployments
  2. Click Yes
  3. Select Azure Website Deployment
  4. Click Next
  5. Check the Continuous Deployment checkbox
  6. Select either Default or Hosted agent queue
  7. Click Create
    Field Value
    Azure Subscription Select certificated based subscription. If you do not have one click Manage and follow the directions on the Creating an Azure Service Endpoint with a Certificate blog post.
    Web App Name {Name for your site}
    Web App Location Select region near you or your users
  8. imageEnter a name for your release definition
  9. Click Save
  10. Click Release
  11. Select Create Release
  12. Select the build we just completed
  13. Click Create
  14. Click the release link
    image
  15. Click Logs to watch the release log

Once the release is complete, you can navigate to your new site running in Azure.
image

Comments (4) -

  • This worked great!  .... the first time.

    Now I'm getting this:

    2016-06-13T23:43:44.6390777Z ##[error]Microsoft.Web.Deployment.DeploymentDetailedClientServerException: Web Deploy cannot modify the file 'Site.dll' on the destination because it is locked by an external process.  In order to allow the publish operation to succeed, you may need to either restart your application to release the lock, or use the AppOffline rule handler for .Net applications on your next publish attempt.  Learn more at: go.microsoft.com/.../.

    2016-06-13T23:43:44.6390777Z ##[error]   at Microsoft.Web.Deployment.StatusThreadHandler.CheckForException()

    2016-06-13T23:43:44.6390777Z ##[error]   at Microsoft.Web.Deployment.PackageSerializer.SerializePayload(DeploymentObject obj, Int32 objectId)

    2016-06-13T23:43:44.6390777Z ##[error]   at Microsoft.Web.Deployment.PackageSerializer.SerializeChildrenDepthFirst(SerializeObjectContext objectContext)

    2016-06-13T23:43:44.6390777Z ##[error]   at Microsoft.Web.Deployment.PackageSerializer.SerializeChildrenDepthFirst(SerializeObjectContext objectContext)

    2016-06-13T23:43:44.6390777Z ##[error]   at Microsoft.Web.Deployment.PackageSerializer.SerializeChildrenDepthFirst(SerializeObjectContext objectContext)

    2016-06-13T23:43:44.6390777Z ##[error]   at Microsoft.Web.Deployment.PackageSerializer.SerializeChildrenDepthFirst(SerializeObjectContext objectContext)

    2016-06-13T23:43:44.6390777Z ##[error]   at Microsoft.Web.Deployment.PackageSerializer.SerializeChildrenDepthFirst(SerializeObjectContext objectContext)

    2016-06-13T23:43:44.6390777Z ##[error]   at Microsoft.Web.Deployment.PackageSerializer.SerializeChildrenSyncFirst(SerializeObjectContext objectContext)

    2016-06-13T23:43:44.6390777Z ##[error]   at Microsoft.Web.Deployment.PackageSerializer.SerializeChildrenSyncFirst(SerializeObjectContext objectContext)

    2016-06-13T23:43:44.6390777Z ##[error]   at Microsoft.Web.Deployment.AgentClientProvider.RemoteDestSync(DeploymentObject sourceObject, DeploymentSyncContext syncContext, Nullable`1 syncPass, String syncSessionId)

    2016-06-13T23:43:44.6390777Z ##[error]   at Microsoft.Web.Deployment.DeploymentObject.SyncToInternal(DeploymentObject destObject, DeploymentSyncOptions syncOptions, PayloadTable payloadTable, ContentRootTable contentRootTable, Nullable`1 syncPassId, String syncSessionId)

    2016-06-13T23:43:44.6390777Z ##[error]   at Microsoft.Web.Deployment.DeploymentObject.SyncTo(DeploymentProviderOptions providerOptions, DeploymentBaseOptions baseOptions, DeploymentSyncOptions syncOptions)

    2016-06-13T23:43:44.6390777Z ##[error]   at Microsoft.WindowsAzure.Commands.Utilities.Websites.WebsitesClient.PublishWebProjectFromPackageFile(String websiteName, String slot, String package, String setParametersFile, Hashtable connectionStrings, Boolean skipAppData, Boolean doNotDelete)

    2016-06-13T23:43:44.6390777Z ##[error]   at Microsoft.WindowsAzure.Commands.Websites.PublishAzureWebsiteProject.ExecuteCmdlet()

    2016-06-13T23:43:44.6390777Z ##[error]   at Microsoft.WindowsAzure.Commands.Utilities.Common.AzurePSCmdlet.ProcessRecord()


    Any way around that?  Looks like there is an outstanding issue on Git, but all workarounds seem related to deploying via a publish profile.
  • Are you still getting this error?  The technique described here
    www.donovanbrown.com/.../MicrosoftCodeAnalysisCSharpdll-Locked-Problem-Fix

    Might work for you as well.
    • I'm afraid that doesn't fix it for my team because we are using the free tier for our development environment and so deployment slots aren't an option.
    • For any who comes across this, Donovan's solution DID fix it after all.  What I didn't realize is that there is an implicit name for the production "slot" (which is, surprise surprise, "Production").  
      blogs.msdn.microsoft.com/.../

      Releases are working just fine now!

Pingbacks and trackbacks (2)+

Add comment

Loading