Building CSX files using VSTS

Azure Functions seem like a great idea to develop you microservices/APIs/gateways quickly and without too much overhead. They're scalable, can integrate with plenty of other Azure capabilities seamlessly and are really cheap. However, there's one problem when building your CI/CD pipeline - by default VSTS doesn't know how to build .funproj projects. Although it's easy to fix when building a project locally(by installing a SDK for Azure Functions), VSTS(and probably other build agents) is unable to do so and will greet you with sweet:

/
The imported project "C:\Program Files (x86)\MSBuild\Microsoft\VisualStudio\v14.0\AzureFunctions\Microsoft.AzureFunctions.targets" was not found. Confirm that the path in the <Import> declaration is correct, and that the file exists on disk.

The solution for this issue is pretty simple - we have to provide missing files to VSTS.

Helping VSTS

If you installed Azure Functions SDK locally you can go directly to:

/
C:\Program Files (x86)\MSBuild\Microsoft\VisualStudio\v14.0\AzureFunctions\

You will find all missing .props and .targets file needed to build Function Apps. Copy all file from the directory and paste them somewhere next to your project. 

The last thing needed to is to modify .funproj file so it searches for the correct file. Open your .funproj file with any text editor and find <Import Project="..." /> lines. Currently they point to Program Files (x86) directory, what causes VSTS to fail when it tries to build your project because they're unavailable for it. Just change them to something like <Import Project="..\.build\Microsoft.AzureFunctions.Props" Condition="'$(VSToolsPath)' != ''" /> and <Import Project="..\.build\Microsoft.AzureFunctions.targets" Condition="'$(VSToolsPath)' != ''" /> and push to your repository. Now when VSTS tries to run another build, it will go green again.

Accessing build and release logs in VSTS

VSTS becomes somehow better and better with each release, yet some activities are not so trivial to perform. Don't get me wrong - I'm not talking about hard-to-manage workarounds, rather subtle tricks just to make the job done.

Finding logs

It's fairly easy to download all build/release logs from the GUI - just go to the Logs tab and you will see big Downloads all logs as zip button. But what if I'd like to incorporate them in my build or release process? Unfortunately VSTS doesn't have an artifact source like e.g. TeamCity has, where you can access all information about a build. Fortunately it has a REST API, which happens to be quite helpful there.

REST for the rescue!

When you go to this site, you'll find an overview for the whole API, which VSTS shares. There are two categories - Build and Release - which are the most interesting for us now. Let's look at signatures, which are the most interesting for us:

Get build details
/
GET https://{instance}/DefaultCollection/{project}/_apis/build/builds/{buildId}/timeline?api-version={version}
Get release details
/
GET https://{account}.vsrm.visualstudio.com/defaultcollection/{project}/_apis/release/releases/{releaseId}?api-version={version}

To perform those requests, Authorization header is required containing your personal token. You can obtain it by going to https://{your_instance}.visualstudio.com/_details/security/tokens.

Accessing logs

Performing above requests will return detailed info about a build or a release. What is interesting, they will return URLs to the logs related to the specific build or release. Even more - you can access specific step - e.g. output for your custom Powershell script.

Typical URLs for logs:

Build
/
https://{yourInstance}.visualstudio.com/DefaultCollection/{projectId}/_apis/build/builds/{buildId}/logs/{stepId}
Release
/
https://{yourInstance}.vsrm.visualstudio.com/{projectId}/_apis/Release/releases/{releaseId}/environments/{environmentId}/tasks/{taskId}/logs?releaseDeployPhaseId={phaseId}

Summary

Although still not without a little overhead, above solution should help you when logs produced by a build or a release are needed. URLs presented may change or differ a little, but remember, that you can get them by requesting build/release info as presented.