{"id":10961,"date":"2016-01-28T03:00:00","date_gmt":"2016-01-28T03:00:00","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/visualstudioalm\/2016\/01\/28\/continuous-mobile-beta-distribution-and-crash-reporting-using-vs-team-services-hockeyapp-codepush-and-cordova-phonegap\/"},"modified":"2019-04-17T09:19:41","modified_gmt":"2019-04-17T17:19:41","slug":"continuous-mobile-beta-distribution-and-crash-reporting-using-vs-team-services-hockeyapp-codepush-and-cordova-phonegap","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/devops\/continuous-mobile-beta-distribution-and-crash-reporting-using-vs-team-services-hockeyapp-codepush-and-cordova-phonegap\/","title":{"rendered":"Continuous Mobile Beta Distribution and Crash Reporting Using VS Team Services, HockeyApp, CodePush, and Cordova \/ PhoneGap"},"content":{"rendered":"<p>Visual Studio Team Services (formerly Visual Studio Online) and Team Foundation Services 2015 supports a <a href=\"http:\/\/go.microsoft.com\/fwlink\/?LinkID=533772\">cross-platform build system<\/a> that allows you to easily configure builds that run on Windows, Linux, and even OSX. Visual Studio Team Services comes with a cloud hosted build agent that runs on Windows and iOS apps can be built either by <a href=\"https:\/\/msdn.microsoft.com\/library\/vs\/alm\/build\/agents\/xplat\">integrating your own Mac<\/a> or using <a href=\"http:\/\/go.microsoft.com\/fwlink\/?LinkID=691834\">MacinCloud\u2019s VS Team Services build agent plan<\/a>.<\/p>\n<p>Beyond just building, new <a href=\"https:\/\/marketplace.visualstudio.com\/items\/ms.hockeyapp\"><strong>HockeyApp<\/strong><\/a>** **and <a href=\"https:\/\/marketplace.visualstudio.com\/items\/ms-vsclient.code-push\"><strong>CodePush<\/strong><\/a> integrations enable you to round out your DevOps story with continuous beta distribution and crash reporting. HockeyApp is a service that allows you to deploy and collect feedback about an app from internal or external beta testers and offers top notch crash reporting both beta and production apps. CodePush is a new service in open beta that enables <a href=\"http:\/\/cordova.apache.org\/\">Apache Cordova \/ PhoneGap<\/a> and <a href=\"http:\/\/facebook.github.io\/react-native\/\">React Native<\/a> apps to update JavaScript, CSS, HTML, and other static content without an app store deployment! This is extremely useful for situations where you want to update your JavaScript app code or static content frequently during testing or even rapidly deliver fixes in a public app store environment without going through a full app store submission process.<\/p>\n<p>In honor of <a href=\"http:\/\/pgday.phonegap.com\/\"><strong>PhoneGap Day US 2016<\/strong><\/a> we will use Cordova \/ PhoneGap projects as a backdrop for discussing these great features but is worth noting that most of these same capabilities are available for <strong>native Android, iOS, Windows, and even Xamarin projects.<\/strong> In a future post we\u2019ll even outline how to apply these capabilities and more to <a href=\"https:\/\/github.com\/facebook\/react-native\">React Native<\/a>.<\/p>\n<p>Given iOS can be a difficult platform to automate, this post will focus on building and deploying the iOS version of a Cordova app using Team Services. That said, the steps outlined here are similar when targeting Android though you can use the Team Services \u201cHosted\u201d build pool rather than MacinCloud or your own Mac. Note you can also use an on-premises TFS 2015 instance if you prefer.<\/p>\n<h2>1&#46; Initial Setup<\/h2>\n<p>If you have not done so already, you\u2019ll need to create a VS Team Services account and integrate a cross-platform agent on a Mac to build iOS. In this case we\u2019ll use one in MacinCloud.<\/p>\n<ol>\n<li>First, <a href=\"https:\/\/www.visualstudio.com\/en-us\/products\/what-is-visual-studio-online-vs.aspx\">sign up for Visual Studio Team Services<\/a>.<\/li>\n<li>Next, you\u2019ll likely want to either configure an <a href=\"https:\/\/msdn.microsoft.com\/library\/vs\/alm\/build\/agents\/xplat\">on-premises Mac<\/a> as a build agent or sign up for <a href=\"http:\/\/go.microsoft.com\/fwlink\/?LinkID=691834\">MacinCloud\u2019s VS Team Services<\/a>. <a href=\"http:\/\/blogs.msdn.com\/b\/visualstudioalm\/archive\/2015\/11\/18\/macincloud-visual-studio-team-services-build-and-improvements-to-ios-build-support.aspx\">Check out our previous post<\/a> for details on setup instructions for MacinCloud. You also can opt to use <a href=\"https:\/\/build.phonegap.com\/\">PhoneGap Build<\/a> if you are already using the service.<\/li>\n<li>Finally, you can opt to <a href=\"https:\/\/msdn.microsoft.com\/en-us\/Library\/vs\/alm\/Code\/overview\">upload your app source code<\/a> to a VS Team Services Git repo. Otherwise you can configure your build to pull code from an existing TFS, GitHub, external Git, or Subversion repository instead.<\/li>\n<\/ol>\n<h2>2&#46; Configure Automated Builds &amp; Unit Tests<\/h2>\n<p>The following is an abridged summary for setting up Cordova \/ PhoneGap build steps that is covered in more detail <a href=\"http:\/\/go.microsoft.com\/fwlink\/?LinkID=691186\">in our documentation<\/a>. Note that there <strong>are also Xcode, Android, and Xamarin build steps<\/strong> that can be used in place of the Cordova ones outlined here. For iOS apps you can take a look at the <a href=\"https:\/\/msdn.microsoft.com\/en-us\/Library\/vs\/alm\/Build\/xcode\/xcode-projects\">detailed Xcode Build tutorial<\/a> for more information.<\/p>\n<p>To build a Cordova app, follow these steps:<\/p>\n<ol>\n<li>Install the <a href=\"http:\/\/go.microsoft.com\/fwlink\/?LinkID=691188\"><strong>Cordova Extension<\/strong><\/a> for Visual Studio Team Services. See <a href=\"https:\/\/github.com\/Microsoft\/vsts-cordova-tasks\">here<\/a> for alternate installation instructions for an on-premises TFS server.<\/li>\n<li>Next create a build definition, by going to the <strong>Build **tab in your Team Services project and clicking the \u201c+\u201d icon to create a new build definition. Select the **Empty<\/strong> template.<\/li>\n<li>Click <strong>Add Build Step\u2026 **and select **Cordova Build<\/strong> from the <strong>Build<\/strong>category. Use the following settings: \n<ul>\n<li><strong>Platform:<\/strong> ios<\/li>\n<li><strong>Configuration<\/strong>: debug or releas<\/li>\n<li><strong>Cordova Version<\/strong>: This is pulled from taco.json if you are using VS Tools for Apache Cordova or the TACO CLI. Otherwise you\u2019ll want to enter a version here<\/li>\n<li>i<strong>OS<\/strong>: See securing your signing keys for details. Cordova auto-matches by default but you can override with files or different identities<\/li>\n<li><strong>Advanced > Working Directory:<\/strong> Location of your Cordova project in the source repo.<\/li>\n<\/ul>\n<\/li>\n<li>Since we\u2019re building iOS, we want to be sure our Cordova command is run on a Mac. Click <strong>Add demand\u2026<\/strong> under the <strong>Demands<\/strong> section of the <strong>General<\/strong> tab and add a demand that <strong>xcode<\/strong> <strong>exists **and update<\/strong> <strong>the **Default agent queue<\/strong> to the queue your MacinCloud or on-prem Mac is connected to (ex: default).<\/li>\n<\/ol>\n<p>If you prefer, you can also use a series of <a href=\"https:\/\/msdn.microsoft.com\/en-us\/library\/vs\/alm\/build\/cordova\/cordova-command?f=255&amp;MSPPError=-2147217396\">PhoneGap Command<\/a>** **build steps provided by the Cordova Extension instead to use <a href=\"https:\/\/build.phonegap.com\/\"><strong>PhoneGap Build<\/strong><\/a> if you\u2019ve already configured your app for use with that service. See the <a href=\"http:\/\/docs.phonegap.com\/references\/phonegap-cli\/remote-usage\/\">PhoneGap CLI reference<\/a> for more information on the commands required to trigger a build. You\u2019ll still be able to take advantage of other VSTS features like using Gulp to run tests or modify the contents of the \u201cwww\u201d folder before transmission.<\/p>\n<p>However, you should be aware that the PhoneGap Build service does not support all Cordova\/PhoneGap CLI features. In addition, you will need to add a <strong>Command Line<\/strong> task under the <strong>Utilities<\/strong> category <a href=\"http:\/\/docs.build.phonegap.com\/en_US\/developer_api_read.md.html#_get_https_build_phonegap_com_api_v1_apps_id_platform\">and use curl to download your ipa<\/a> since the PhoneGap CLI does not automatically download the result of a remote build. We\u2019ll continue to assume you used the Cordova Build task for the purposes of this blog post.<\/p>\n<h4>Running Unit Tests<\/h4>\n<p>Since we\u2019re doing continuous delivery, we\u2019ll also need add in some unit tests. In this case we\u2019ll run a set of <a href=\"http:\/\/jasmine.github.io\/\">Jasmine<\/a> tests using <a href=\"http:\/\/gulpjs.com\/\">Gulp<\/a>, <a href=\"http:\/\/karma-runner.github.io\/\">Karma<\/a>, and <a href=\"http:\/\/phantomjs.org\/\">PhantomJS<\/a>.<\/p>\n<ol>\n<li>Add <a href=\"https:\/\/github.com\/Microsoft\/vsts-cordova-tasks\/tree\/master\/samples\/gulp\"><strong>this sample code<\/strong><\/a> to your project to get you started and add it to source control. See this <a href=\"http:\/\/taco.visualstudio.com\/en-us\/docs\/unit-test-03-basic-testing\/\">article<\/a> for more information on authoring tests.<\/li>\n<li>Add the <strong>npm **step from the **Package<\/strong> category with the with <strong>install<\/strong> as the Command** <strong>and<\/strong> &#8211;no-optional **under Advanced > Arguments. You may also need to add &#8211;force if you encounter EPERM errors.<\/li>\n<li>Add the <strong>Gulp<\/strong> step from the <strong>Build<\/strong> category and configure it to run the **test **task.<\/li>\n<li>Add the <strong>Publish Test Results<\/strong> task from the <strong>Test<\/strong> category and use <strong>_results\/*.xml **for Test Results Files and be sure to check **Control Options > Always Run<\/strong>.<\/li>\n<li>Move these to the top of your build definition.<\/li>\n<li>Finally, you may need to set <strong>Advanced > Working Directory<\/strong> and adjust the <strong>Gulp File Path **and<\/strong> Test Results Files** config settings for the above tasks if your Cordova project is not in the root of your source code repo.<\/li>\n<\/ol>\n<h2>3&#46; Add Continuous Beta Distribution to HockeyApp<\/h2>\n<p>Now that we have our build and unit tests and running, let\u2019s layer in the ability to deploy automatically to HockeyApp so beta testers can easily access your updated app. We\u2019ll outline a simple configuration here, but you can take a look at <a href=\"http:\/\/support.hockeyapp.net\/kb\/third-party-bug-trackers-services-and-webhooks\/how-to-use-hockeyapp-with-visual-studio-team-services-vsts-or-team-foundation-server-tfs\">HockeyApp documentation<\/a> for more configuration options.<\/p>\n<ol>\n<li>First, if you have not already, <a href=\"http:\/\/hockeyapp.net\/\">sign up for HockeyApp<\/a>. It\u2019s free to start!<\/li>\n<li>Install the <a href=\"http:\/\/go.microsoft.com\/fwlink\/?LinkID=691188\"><strong>HockeyApp Extension<\/strong><\/a> for VS Team Services. See <a href=\"http:\/\/support.hockeyapp.net\/kb\/third-party-bug-trackers-services-and-webhooks\/how-to-use-hockeyapp-with-visual-studio-team-services-vsts-or-team-foundation-server-tfs\">here<\/a> for alternate instructions for on-premises TFS instances.<\/li>\n<li>Go to Account Settings on the HockeyApp site, choose <a href=\"https:\/\/rink.hockeyapp.net\/manage\/auth_tokens\"><strong>API Tokens<\/strong><\/a><strong>,<\/strong> and grab the details of your <strong>access token<\/strong>.<\/li>\n<li>Back on the Team Services site, go to the <strong>control panel<\/strong> (via the gear icon in the upper right hand corner) and click on <strong>Services<\/strong> tab.<\/li>\n<li>Click <strong>New Service Endpoint<\/strong>, select <strong>HockeyApp<\/strong>, and enter a name along with your <strong>access token<\/strong>.<\/li>\n<li>Next, go back to the build definition you created above and add the <strong>HockeyApp **build step from the **Deploy<\/strong>category and move it after Cordova Build. Use the following settings: \n<ul>\n<li><strong>HockeyApp Connection<\/strong>: Select the name of the service endpoint you created above.<\/li>\n<li><strong>Binary File Path<\/strong>: Path to where the ipa will land. By default this is **bin\/ ios\/<configuration>\/<app name>.ipa **for the Cordova Build task.<\/li>\n<li><strong>Symbols File Path<\/strong>: This is needed for native crash statistics which we will configure later. By default these land in **bin\/ ios\/<configuration>\/<app name>.dSYM **for the Cordova Build task.<\/li>\n<li>There are a number of additional settings including the ability to simply deploy the binary to HockeyApp and then manually \u201cpublish\u201d it to end users later. We\u2019ll leave the defaults for now.<\/li>\n<\/ul>\n<\/li>\n<\/ol>\n<p>Now, you probably don\u2019t want all of your dev builds getting deployed and published to end users, so simple way avoid this problem is to use a <strong>beta<\/strong> branch. We\u2019ll setup CI to occur any time a commit happens in the beta branch so a simple merge \/ PR operation can be used to deploy.<\/p>\n<ol>\n<li>Create a branch that will contain the final bits you want to deploy to your beta users. We\u2019ll call that branch <strong>beta<\/strong> here.<\/li>\n<li>In your build definition, click on the <strong>Repository **tab and update **Default branch<\/strong> to <strong>beta<\/strong>.<\/li>\n<li>Click on the <strong>Triggers<\/strong> tab and check <strong>Continuous Integration<\/strong>.<\/li>\n<\/ol>\n<p>Now, the next time you commit a change to the beta branch your app will be automatically tested, built, and deployed to HockeyApp! In a future post we\u2019ll cover how <a href=\"https:\/\/www.visualstudio.com\/en-us\/features\/release-management-vs.aspx\">Release Management<\/a> can be used to extend this concept and introduce manual gates or even deploy to app stores.<\/p>\n<h2>4&#46; Add HockeyApp Update Notifications, Crash Reporting, and Feedback<\/h2>\n<p>Beyond just configuring app distribution, you can also notify or force users to update their app, add in crash reporting capabilities for any environment, and even wire in an integrated beta user feedback experience all via the HockeyApp SDK. Though<a> not available today, you will soon also be able to use HockeyApp to log JavaScript exceptions too! <\/a><a name=\"_msoanchor_1\" href=\"https:\/\/microsoft-my.sharepoint.com\/personal\/clantz_microsoft_com\/Documents\/_Shared%20with%20Everyone\/Blog%20Posts\/#_msocom_1\"><\/a>[CL1]<\/p>\n<p>The HockeyApp SDK is available for <a href=\"http:\/\/support.hockeyapp.net\/kb\/client-integration-android\/hockeyapp-for-android-sdk\">Android<\/a>, <a href=\"http:\/\/support.hockeyapp.net\/kb\/client-integration-ios-mac-os-x\/hockeyapp-for-ios\">iOS<\/a>, and <a href=\"http:\/\/support.hockeyapp.net\/kb\/client-integration-windows-and-windows-phone\">Windows<\/a> and cross-platform tools like <a href=\"https:\/\/www.npmjs.com\/package\/cordova-plugin-hockeyapp\">Cordova<\/a>, <a href=\"http:\/\/support.hockeyapp.net\/kb\/client-integration-cross-platform\/how-to-integrate-hockeyapp-with-unity\">Unity<\/a>, and <a href=\"http:\/\/support.hockeyapp.net\/kb\/client-integration-cross-platform\/how-to-integrate-hockeyapp-with-xamarin\">Xamarin<\/a>. Given PhoneGap Day, we\u2019ll briefly describe how to add these capabilities to your Cordova \/ PhoneGap app.<\/p>\n<ol>\n<li>Add the <a href=\"https:\/\/www.npmjs.com\/package\/cordova-plugin-hockeyapp\"><strong>cordova-plugin-hockeyapp<\/strong><\/a>** <strong>to your Cordova project using either the <a href=\"https:\/\/github.com\/peutetre\/cordova-plugin-hockeyapp\">Git URI<\/a> from **Visual Studio<\/strong>or by typing the following from the command line using the Cordova, Ionic, TACO, or PhoneGap CLIs: <\/li>\n<\/ol>\n<ul style=\"list-style-type: none\">\n<li>\n        cordova plugin add cordova-plugin-hockeyapp\n      <\/li>\n<\/ul>\n<ol>\n<li>Next, update your app code to initialize HockeyApp after the <a href=\"https:\/\/cordova.apache.org\/docs\/en\/5.4.0\/cordova\/events\/events.deviceready.html\"><strong>deviceready<\/strong><\/a> event fires as follows (replacing <strong>appId<\/strong> with the appropriate value from in the <a href=\"http:\/\/rink.hockeyapp.net\">HockeyApp portal<\/a> for your app):<\/li>\n<\/ol>\n<ul style=\"list-style-type: none\">\n<li>\n    hockeyapp.start(onSuccessCallback, onErrorCallback, appId);\n  <\/li>\n<\/ul>\n<p>Commit the resulting code to source control and you\u2019re good to go!<\/p>\n<h2>5&#46; Add CodePush<\/h2>\n<p>Since we\u2019re building a Cordova app, let\u2019s also take advantage of CodePush. CodePush will allow us to do completely out-of-band updates of our app as long as there\u2019s no native code that needs to be updated (ex: a new Cordova plugin). You can quickly push fixes to apps from app stores without re-submitting the entire app. VS Team Services can then use HockeyApp to make the latest version of your native client available to your beta testers and CodePush will constantly keep them in sync after the initial install.<\/p>\n<p>CodePush is only available for Cordova\/PhoneGap and React Native apps targeting Android and\/or iOS, so if you\u2019re using Xamarin or building a native app you should skip these steps.<\/p>\n<ol>\n<li>Install the CodePush CLI, register, and add your app to the service. From the command type (replacing <app name> with your app\u2019s name): <\/li>\n<\/ol>\n<ul style=\"list-style-type: none\">\n<li>\n        npm install -g <a href=\"mailto:code-push-cli@lates\">code-push-cli@lates<\/a>t\n      <\/li>\n<li>\n        code-push register\n      <\/li>\n<li>\n        code-push app add <app name>\n      <\/li>\n<li>\n        code-push access-key add &#8220;VSTS CI&#8221;\n      <\/li>\n<\/ul>\n<p>Take note of the<\/p>\n<pre><code>**app name** you entered and both the **deployment **and** access keys** generated as we will use this information later.\n<\/code><\/pre>\n<p>2.  Add** **<a href=\"https:\/\/www.npmjs.com\/package\/cordova-plugin-code-push\"><strong>cordova-plugin-code-push<\/strong><\/a> to your Cordova project using either the <a href=\"https:\/\/github.com\/Microsoft\/cordova-plugin-code-push.git\">Git URI<\/a>from Visual Studio or by typing the following from the command line using the Cordova, Ionic, TACO, or PhoneGap CLIs:<\/p>\n<ul style=\"list-style-type: none\">\n<li>\n        cordova plugin add cordova-plugin-code-push\n      <\/li>\n<\/ul>\n<ol>\n<li>You\u2019ll now need to make some changes to <strong>config.xml<\/strong> and your app\u2019s <a href=\"https:\/\/cordova.apache.org\/docs\/en\/5.4.0\/cordova\/events\/events.deviceready.html\"><strong>deviceready<\/strong><\/a>** **event handler to cause the app to update out-of-band. See the <a href=\"https:\/\/github.com\/Microsoft\/cordova-plugin-code-push#getting-started\">CodePush getting started<\/a> guide and the <a href=\"https:\/\/github.com\/Microsoft\/cordova-plugin-code-push\/tree\/master\/samples\"><strong>sample app<\/strong><\/a> for details.<\/li>\n<li>Commit the resulting code to source control.<\/li>\n<li>Back in Team Services, Install the <a href=\"https:\/\/marketplace.visualstudio.com\/items\/ms-vsclient.code-push\"><strong>CodePush Extension<\/strong><\/a> for Visual Studio Team Services. See <a href=\"https:\/\/github.com\/Microsoft\/code-push-vsts-extension\">here<\/a> for alternate instructions for on-premises TFS instances.<\/li>\n<li>In your build definition from above, add the <strong>CodePush<\/strong> task from the **Deploy **category after the Cordova Build task. Use the following settings: \n<ul>\n<li><strong>Access Key:<\/strong> The access key you generated above.<\/li>\n<li><strong>App Name:<\/strong> The app name you specified above.<\/li>\n<li><strong>Package Path:<\/strong> This will be <strong>platforms\/ios\/www<\/strong> under your Cordova project folder for iOS or <strong>platforms\/android\/assets\/www<\/strong> for Android.<\/li>\n<li><strong>App Store Version: **A semver compliant version number for the version of your **native<\/strong> app (what a user downloads from HockeyApp or an app store). Ex: 1.0.0<\/li>\n<li><strong>Deployment Name<\/strong>: Environment the app update is targeting. Given we\u2019re focusing on <strong>beta<\/strong> here you should use <strong>Staging<\/strong> (the default) or beta as the name.<\/li>\n<\/ul>\n<\/li>\n<\/ol>\n<p>That\u2019s it! The next time you commit to the beta branch not only will a new version of the native iOS app be generated and published to HockeyApp but users running the specified versions of the native app can be updated automatically!<\/p>\n<h2>Summary &amp; Future<\/h2>\n<p>We\u2019re committed to making it simple to add Continuous Integration and Continues Delivery practices into your mobile app workflow. We hope that you find the continuous delivery capabilities enabled by VS Team Services, HockeyApp, and CodePush useful!<\/p>\n<p>There\u2019s even more to come. The <a href=\"https:\/\/www.visualstudio.com\/en-us\/features\/release-management-vs.aspx\">VS Team Services Release Management<\/a> feature set introduces the concept of a release that moves from environment to environment and layers in the ability to setup manual gates in a continuous delivery pipeline. While frequently thought about in the context of web applications, in the app context release management really equates to managing the publishing and deployment of a dev, alpha\/beta, and app store (internal or external) version of your app to end users. We\u2019ve outlined how to handle beta distribution and what comes next is automatic deployment into app stores and this is where having the ability to specify manual gates and approvals is critical. We\u2019ll cover some exciting developments in this space along with talking about the increasingly popular React Native platform in a future post.<\/p>\n<p>We\u2019re always interested in your feedback on how we can make things even better, so please contact us via <a href=\"http:\/\/visualstudio.uservoice.com\/forums\/330519-team-services\">UserVoice<\/a> and let us know about your ideas and suggestions! You can also connect directly with the HockeyApp team via <a href=\"http:\/\/support.hockeyapp.net\/\">their site<\/a> and <a href=\"https:\/\/twitter.com\/hockeyapp\">Twitter<\/a>, the CodePush team via <a href=\"mailto:codepushfeed@microsoft.com\">email<\/a> or on <a href=\"https:\/\/discord.gg\/0ZcbPKXt5bWxFdFu\">Discord<\/a>, the Cordova team via <a href=\"mailto:vscordovatools@microsoft.com\">email<\/a>, <a href=\"http:\/\/go.microsoft.com\/fwlink\/?LinkID=699448\">StackOverflow<\/a>, or <a href=\"http:\/\/go.microsoft.com\/fwlink\/?LinkID=699449\">Twitter<\/a>, and MacinCloud via <a href=\"mailto:support@macincloud.com\">email<\/a> or <a href=\"https:\/\/twitter.com\/MacinCloud\">Twitter<\/a> with any questions, issues, or suggestions you may have.<\/p>\n<p>Get started with <a href=\"https:\/\/go.microsoft.com\/fwlink\/?LinkId=307137\">Visual Studio Team Services<\/a>, <a href=\"http:\/\/hockeyapp.net\/\">HockeyApp<\/a>, <a href=\"http:\/\/microsoft.github.io\/code-push\/\">CodePush<\/a>, and <a href=\"http:\/\/go.microsoft.com\/fwlink\/?LinkID=691834\">MacinCloud<\/a> today!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Visual Studio Team Services (formerly Visual Studio Online) and Team Foundation Services 2015 supports a cross-platform build system that allows you to easily configure builds that run on Windows, Linux, and even OSX. Visual Studio Team Services comes with a cloud hosted build agent that runs on Windows and iOS apps can be built either [&hellip;]<\/p>\n","protected":false},"author":167,"featured_media":45953,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[],"class_list":["post-10961","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-devops"],"acf":[],"blog_post_summary":"<p>Visual Studio Team Services (formerly Visual Studio Online) and Team Foundation Services 2015 supports a cross-platform build system that allows you to easily configure builds that run on Windows, Linux, and even OSX. Visual Studio Team Services comes with a cloud hosted build agent that runs on Windows and iOS apps can be built either [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/devops\/wp-json\/wp\/v2\/posts\/10961","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/devops\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/devops\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/devops\/wp-json\/wp\/v2\/users\/167"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/devops\/wp-json\/wp\/v2\/comments?post=10961"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/devops\/wp-json\/wp\/v2\/posts\/10961\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/devops\/wp-json\/wp\/v2\/media\/45953"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/devops\/wp-json\/wp\/v2\/media?parent=10961"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/devops\/wp-json\/wp\/v2\/categories?post=10961"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/devops\/wp-json\/wp\/v2\/tags?post=10961"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}