Continuous Integration with ASP.NET 5, GitHub and Travis CI

Standard

This post is about setting up a simple continuous integration environment for ASP.NET 5 with GitHub and Travis-CI. So when ever someone commits to the source, the build will be triggered. Once the build is succeeds, all the unit tests will be executes. If all the tests pass, the build will be successful. Otherwise the build will be treated as failed build.

  1. Creating source code and unit tests – As first step you need to create a simple ASP.NET 5 application and unit tests. In this post I am using a basic CRUD MVC application, I am using Moq and repository pattern make the solution testable.
    [HttpPost]
    public IActionResult Create(Employee employee)
    {
    	if (ModelState.IsValid)
    	{
    		_employeeRepository.Save(employee);
    		return RedirectToAction("Index");
    	}
    
    	return View("Create", employee);
    }
    

    And here is the test methods for the same

    [Fact]
    public void VerifyCreateEmployeeRedirectsToError()
    {
    	var employeeRepository = new Mock<IEmployeeRepository>();
    	employeeRepository.Setup(x => x.Save(It.IsAny<Employee>()));
    	var employee = new Employee() { Id = 1 };
    	var employeeController = new EmployeeController(employeeRepository.Object);
    	//Mocking the employeeController.ModelState.IsValid = false
    	employeeController.ModelState.AddModelError("Error", "Name is Required");
    
    	var createResult = employeeController.Create(employee) as ViewResult;
    
    	Assert.NotNull(createResult);
    	Assert.Equal("Create", createResult.ViewName);
    }
    
    [Fact]
    public void VerifyCreateEmployeeInsertData()
    {
    	var employeeRepository = new Mock<IEmployeeRepository>();
    	employeeRepository.Setup(x => x.Save(It.IsAny<Employee>())).Verifiable();
    	var employee = new Employee() { 
    		Id = 1, 
    		Name = "Employee", 
    		Designation = "Designation", 
    		JoiningDate = DateTime.Now };
    	var employeeController = new EmployeeController(employeeRepository.Object);
    	var createResult = employeeController.Create(employee) as RedirectToActionResult;
    	Assert.NotNull(createResult);
    	Assert.Equal("Index", createResult.ActionName);
    	employeeRepository.Verify();
    }
    

    I have added only two unit tests for create method. I am using almost same code as I mentioned in this post – Creating Unit Tests for ASP.NET MVC 6 Applications.

    Now you need to create the project.json file, to compile and test.

    {
    	"authors": [
    		"Anuraj"
    	],
    	"description": "ASP.NET 5 Unit Testing Sample Application",
    	"version": "1.0.0",
    	"webroot": "wwwroot",
    	"dependencies": {
    		"Microsoft.AspNet.Diagnostics": "1.0.0-beta3",
    		"Microsoft.AspNet.Hosting": "1.0.0-beta3",
    		"Microsoft.AspNet.Mvc": "6.0.0-beta3",
    		"Microsoft.AspNet.Server.WebListener": "1.0.0-beta3",
    		"Microsoft.AspNet.StaticFiles": "1.0.0-beta3",
    		"Microsoft.AspNet.Server.IIS": "1.0.0-beta3",
    		"xunit": "2.1.0-beta1-*",
            "xunit.runner.aspnet": "2.1.0-beta1-*",
    		"Moq":"1.0.0-*"
    	},
    	"commands": {
    		"web": "Microsoft.AspNet.Hosting --server Microsoft.AspNet.Server.WebListener --server.urls http://localhost:5000",
    		"test": "xunit.runner.aspnet"
    	},
    	"frameworks": {
    		"aspnet50": {}
    	}
    }
    

    I am using K Runtime with beta 3 packages. Now you can restore the packages using kpm restore command. Once everything installed, you can run the application by k web command. You can run the tests by k test command.

  2. The Travis YML file – This file is equivalent TFS build script or build workflow file. This file helps to configure the build environment. In Travis CI, C# beta support available, so when we specify the language, Travis CI will download the mono framework and compile the source code on top of that. You can find more details about C# support in Travis CI here. You need to keep the .travis.yml file in the root directory. Here is the .travis.yml which can be used for ASP.NET 5 build and executing tests.
    language: CSharp
    install:
      - curl -sSL https://raw.githubusercontent.com/aspnet/Home/master/kvminstall.sh | sh && source ~/.k/kvm/kvm.sh
      - kvm upgrade
      - kpm restore --no-cache
    script:
      - k test -parallel none
    

    The language line instructs the build agent to compile the project in C#. Because of this, build agent will download mono and execute all the steps. In the install phase, I am installing the KVM and downloading the runtime and packages using kvm upgrade, kpm restore commands. Finally, the script block will get execute, it will run the XUnit tests, once completed, Travis CI verifies the exit code of the process and based on exit code it will pass or fail the build. The -parallel none option required, it is a known issue in k test command, otherwise this command will not return exit code. You need to add this file also to the github repository.

  3. Linking GitHub and Travis CI – Once the above steps completed, now you need to tell travis ci about your github repository. You can do this by signin to Travis-CI. And from the Account page select the repository.
    Linking Travis CI and GitHub

    Linking Travis CI and GitHub

    Now we are ready with the CI environment, you can verify it by committing to the github repository. Here is the log output from Travis CI

    Travis CI build output

    Travis CI build output

Travis CI supports build status images. You can include it in the readme.md files. You can the code for status image by clicking on the build status image, right side of the repository name.

build status image from Travis CI

build status image from Travis CI

You can find the full application, with .travis.yml and unit tests here.

Happy Programming :)

How to host ASP.NET 5 Application in Azure Web Apps

Standard

This post is about hosting ASP.NET 5 Application in Azure WebApps / Websites. If you are using Visual Studio, you can use the publish wizard. But if you are using k or dnx runtimes this option is not available. ASP.NET wiki in GitHub contains a page about FTP deploy but it is not working :( Later I found another page, which discuss about this. But I had to spent some time to make the deployment work successfully.

Here is the steps you need to follow to deploy ASP.NET app to Azure Web App.

  1. Include IIS in the project.json file – Even if you are using WebListener, you have to include the reference of IIS in your project.json file. This is important without this deployment will not work. So your project.json will look like this.
    {
        "webroot": "wwwroot",
        "dependencies": {
            "Microsoft.AspNet.Diagnostics": "1.0.0-beta3",
            "Microsoft.AspNet.Hosting": "1.0.0-beta3",
            "Microsoft.AspNet.Mvc": "6.0.0-beta3",
            "Microsoft.AspNet.Server.WebListener": "1.0.0-beta3",
            "Microsoft.AspNet.StaticFiles": "1.0.0-beta3",
            "Microsoft.AspNet.Server.IIS": "1.0.0-beta3"
        },
        "commands": {
            "web": "Microsoft.AspNet.Hosting --server Microsoft.AspNet.Server.WebListener --server.urls http://localhost:5001"
        },
        "frameworks": {
            "aspnet50": { }
        }
    }
    
  2. Bundle the application using KPM build command – I am using k runtime, I tried with dnx runtime, but I faced few issues, so switched back to k runtime. Here is the command, which will bundle the source and will make it ready for deployment. Make sure, you are bundling with the proper runtime. I am using shared mode in azure, and hence my target platform is x86. So I am bundling with x86 version of the runtime.
    kpm bundle --out C:\WebApp --runtime kre-clr-win-x86.1.0.0-beta3
    

    You can find the installed runtimes and the name from the “C:\Users\[username]\.k\runtimes” folder. I am using beta3 runtime. Once you execute this command, you will find a folder structure like this in the C:\WebApp folder.

    Bundle output - Folder structure

    Bundle output – Folder structure

    Make sure you have a bin folder inside wwwroot folder, and which contains file – AspNet.Loader.dll. And here is the web.config file, inside wwwroot folder.

    <?xml version="1.0" encoding="utf-8"?>
    <configuration>
      <appSettings>
        <add key="kpm-package-path" value="..\approot\packages" />
        <add key="bootstrapper-version" value="1.0.0-beta3" />
        <add key="runtime-path" value="..\approot\packages" />
        <add key="kre-version" value="1.0.0-beta3" />
        <add key="kre-clr" value="clr" />
        <add key="kre-app-base" value="..\approot\src\MVCApp" />
      </appSettings>
    </configuration>
    

    All the runtime, dependencies and packages are created inside approot folder. If you are deploying it in IIS, you need to point the website to the wwwroot folder.

  3. Publish files using FTP – Connect to the website FTP folder using any FTP client. Copy the contents in the C:\WebApp(output folder of kpm build) to site folder of the website. With this copy operation, You are overwriting the original site/wwwroot folder with the one in output folder and adding a new folder site/approot. Once upload finished, Remote site folder structure will look like this.

    Remote site folder structure

    Remote site folder structure

Hosting ASP.NET 5 apps in IIS and IIS Express.

As I mentioned earlier, you can host this app in IIS, by pointing the physical path to the wwwroot folder.

ASP.NET 5 - Hosting in IIS

ASP.NET 5 – Hosting in IIS

And you can do the same with IIS express as well.

iisexpress /path:C:\WebApp\wwwroot /port:5001

Happy Programming :)

How to change lync status using C#

Standard

Another Lync post :) This snippet will help you to change the lync status(available, away, busy etc) using C# and Lync API. As I mentioned in the earlier post, you need to install the Lync SDK.

Here is the snippet

var lyncClient = LyncClient.GetClient();
lyncClient.Self.BeginPublishContactInformation(
    new Dictionary<PublishableContactInformationType, object>() {
    { PublishableContactInformationType.Availability, ContactAvailability.Busy }
}, null, null);

In this code, I am making the availability status as Busy. You can change it to any value available in the ContactAvailability enumeration. It is always better idea to check Lync is running or not. I have not included the code for that.

Happy Programming :)

Building a Lync bot using C#

Standard

Long back I wrote an article on creating a language translation bot using Skype and C#, since Microsoft stopped Skype COM API, and I am using lync more than Skype, I thought of writing the same implementation using lync.

The implementation is pretty same, you have to get the instance of the lync instance first, attach event handlers, translate and return the text back. To make this post simple, I am not including the translation logic, I am reversing the text and sending back to the sender.

You need to install the Lync SDK to start using the lync APIs, which you can download from here. You need to add reference of Microsoft.Lync.Model and Microsoft.Lync.Utilities DLLs.

Lync References

Lync References

And here is the code snippet.

private LyncClient _lyncClient;
private ConversationManager _conversationManager;

_lyncClient = LyncClient.GetClient();
_conversationManager = _lyncClient.ConversationManager;
_conversationManager.ConversationAdded += ConversationAdded;

private void ConversationAdded(object sender, ConversationManagerEventArgs e)
{
    var conversation = e.Conversation;
    conversation.ParticipantAdded += ParticipantAdded;
}

private void ParticipantAdded(object sender, ParticipantCollectionChangedEventArgs e)
{
    var participant = e.Participant;
    if (participant.IsSelf)
    {
        return;
    }

    var instantMessageModality = 
        e.Participant.Modalities[ModalityTypes.InstantMessage] as InstantMessageModality;
    instantMessageModality.InstantMessageReceived += InstantMessageReceived;
}

private void InstantMessageReceived(object sender, MessageSentEventArgs e)
{
    var text = e.Text.Replace(Environment.NewLine, string.Empty);
    (sender as InstantMessageModality).BeginSendMessage(Reverse(text), null, null);
}

Reverse method reverses the text and send back to the user using BeginSendMessage method. You can extend the bot MEF and custom plugins.

Happy Programming :)