{"id":27298,"date":"2016-08-25T10:55:33","date_gmt":"2016-08-25T17:55:33","guid":{"rendered":"https:\/\/blog.xamarin.com\/?p=27298"},"modified":"2019-04-03T23:13:49","modified_gmt":"2019-04-04T06:13:49","slug":"continuous-integration-for-ios-apps-with-visual-studio-team-services","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/xamarin\/continuous-integration-for-ios-apps-with-visual-studio-team-services\/","title":{"rendered":"Continuous Integration for iOS Apps with Visual Studio Team Services"},"content":{"rendered":"<p>\t\t\t\t<a href=\"https:\/\/www.visualstudio.com\/team-services\/\">Visual Studio Team Services<\/a> (VSTS) delivers services for teams to share code, track work, and ship software, including all of their mobile applications built with Xamarin. In the <a href=\"https:\/\/blog.xamarin.com\/continuous-integration-for-android-with-visual-studio-team-services\/\">first post<\/a> in this series, we automated a Xamarin.Android app in VSTS. We created our account, connected to our GitHub account, built and signed the app, and delivered it to HockeyApp for beta testers to start testing it. Today, we&#8217;re going to continue to automate the <a href=\"https:\/\/github.com\/jamesmontemagno\/CoffeeTipper\">Coffee Tipper<\/a> application, but this time for iOS. <\/p>\n<p><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/44\/2019\/03\/28632284-df59f83e-71e4-11e7-96d3-0830201fb432.png\" alt=\"AnyADeveloperAnyLanguage\" width=\"332\" height=\"166\" class=\"aligncenter size-full wp-image-27211\" \/><\/p>\n<h2>Getting Started<\/h2>\n<p>At this point we&#8217;ve already created our first project and have connected to our source code repository. If you haven&#8217;t gotten this far, be sure to read through the <a href=\"https:\/\/blog.xamarin.com\/continuous-integration-for-android-with-visual-studio-team-services\/\">first post in the series<\/a>. We&#8217;ll continue to edit our existing projects in VSTS, but first there are a few prerequisites. <\/p>\n<h3>Preparing an iOS Build Agent<\/h3>\n<p>Since Xamarin.Android applications can be completely built and packaged on a Windows machine, we were able to leverage VSTS&#8217; hosted solution to build our application. iOS applications must be built and compiled on a macOS device. Within VSTS, we have a few solutions available.<\/p>\n<ol>\n<li><a href=\"https:\/\/blogs.msdn.microsoft.com\/visualstudioalm\/2015\/11\/18\/macincloud-visual-studio-team-services-build-and-improvements-to-ios-build-support\/\">MacinCloud Build Agent<\/a>: Fully hosted with Xamarin support (paid plan)<\/li>\n<li>Utilize an on premise macOS machine with VSTS build agent installed<\/li>\n<\/ol>\n<p>For this post, I&#8217;m going to utilize a Mac mini that I have on-premise as my build agent. You&#8217;ll only have to set up the agent once, as it can be used by multiple applications in VSTS. It can be a bit tricky to set up since it will require installing Homebrew, .NET Core, and npm on your macOS device, so here&#8217;s a quick rundown:<\/p>\n<h4>New Agent Pool<\/h4>\n<p>Create new &#8220;On Premise&#8221; Agent Pool under the projects Settings -&gt; Agent Pools:\n<img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/44\/2019\/03\/NewAgentPool.png\" alt=\"NewAgentPool\" width=\"400\" class=\"aligncenter size-full wp-image-27300\" \/><\/p>\n<h4>Install VSTS Build Agent<\/h4>\n<p>Before we can install the VSTS Build agent we must install a few prerequisites on our macOS machine.<\/p>\n<ol>\n<li>Install <a href=\"http:\/\/brew.sh\/\">Homebrew<\/a> package manager for macOS<\/li>\n<li>Install <a href=\"https:\/\/www.microsoft.com\/net\/core#macos\">.NET Core<\/a><\/li>\n<p>Tip: after calling <code>brew install openssl<\/code> be sure to call:\n<code>mkdir -p \/usr\/local\/lib\/<\/code><\/p>\n<p>This will ensure that the \/user\/local\/lib folder is created before linking files.<\/p>\n<li>Install npm by running the following command in the terminal: <b>brew install npm<\/b><\/li>\n<li><a href=\"https:\/\/www.visualstudio.com\/en-us\/docs\/setup-admin\/team-services\/use-personal-access-tokens-to-authenticate\">Create a Personal Access Token<\/a> for the Build Agent. Select the Scope: <b>Agent Pools (read, manage)<\/b><\/li>\n<li>On the <b>Agent Pool<\/b> page where we created the new pool, tap <b>Download agent<\/b> and follow the setup steps to properly configure the Build agent.<\/li>\n<p><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/44\/2019\/03\/InstallAgent.png\" alt=\"InstallAgent\" width=\"500\" class=\"aligncenter size-full wp-image-27302\" \/>\n<\/ol>\n<p>With that, the build agent should be sitting in an open terminal window listening for jobs to come in.\n<img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/44\/2019\/03\/Listening.png\" alt=\"Listening\" width=\"500\" class=\"aligncenter size-full wp-image-27303\" \/><\/p>\n<h2>iOS Build Definition<\/h2>\n<p>Heading back to our Build Definitions, it&#8217;s time to create our new iOS definition, which tells VSTS how to go about building our iOS app. Tap on the new icon and then select Xamarin.iOS from the template list.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/44\/2019\/03\/iOS_Build_Definition.png\" alt=\"iOS_Build_Definition\" width=\"500\" class=\"aligncenter size-full wp-image-27304\" \/><\/p>\n<p>The next step is the settings for source repository. <em>Coffee Tipper<\/em> is hosted on GitHub, which is already configured, so we&#8217;ll select that and then check the <b>Continuous Integration<\/b> check box and select the new <b>On Premise<\/b> agent queue.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/44\/2019\/03\/Repo_Settings.png\" alt=\"Repo_Settings\" width=\"500\" class=\"aligncenter size-full wp-image-27305\" \/><\/p>\n<p>This will create our definition with a few build steps set up for us. Before we configure the steps, let&#8217;s finalize the repository settings to point to the <em>Coffee Tipper<\/em> repository, which can be set up under the <b>Repository<\/b> tab:<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/44\/2019\/03\/FinalizeRepo.png\" alt=\"FinalizeRepo\" width=\"500\" class=\"aligncenter size-full wp-image-27306\" \/><\/p>\n<p>Back on the <b>Build<\/b> we can start to fill in our steps. Similar to our Android setup in VSTS, we can disable the Activate, Deactivate, and Test Cloud steps for now. I like to keep them in the definition in case I need to go back and toggle them on. We&#8217;re going to focus the rest of the time on the <b>Build Xamarin.iOS Solution<\/b> step.<\/p>\n<p>This step has two main parts to configure. First is pointing to the actual <b>solution<\/b> to build. It&#8217;s important to point it to the <b>.sln<\/b> and NOT the <b>.csproj<\/b> as xbuild will take over and build the iOS projects in the solution. You&#8217;ll also notice that there is no NuGet restore step, but don&#8217;t fear&mdash;as part of this step, xbuild will automatically call NuGet restore on the entire solution.  <\/p>\n<p><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/44\/2019\/03\/BuildSLN.png\" alt=\"BuildSLN\" width=\"600\" class=\"aligncenter size-full wp-image-27308\" \/><\/p>\n<h3>Configuring Solution<\/h3>\n<p>Note here that the default build configuration is set to <b>Release<\/b> under the Variables tab. You can adjust this at any time, but this is what I&#8217;ll use for this example. To ensure that the build is successful, go into the solution&#8217;s <b>Build Configuration<\/b> in Visual Studio or Xamarin Studio, where we&#8217;ll configure the <b>Release\/iPhone<\/b> and <b>Release\/iPhoneSimulator<\/b> builds to ONLY build the projects we need. <\/p>\n<p><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/44\/2019\/03\/CopnfigSLN.png\" alt=\"CopnfigSLN\" width=\"500\" class=\"aligncenter size-full wp-image-27311\" \/><\/p>\n<h3>Signing and Provisioning<\/h3>\n<p>At this point, if we wanted to build for the iPhoneSimulator and not generate an .ipa package, we could go ahead and build. This would be good for a smoke test of the build, but we want to do a full app package build.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/44\/2019\/03\/BuildAppPackage.png\" alt=\"BuildAppPackage\" width=\"628\" height=\"400\" class=\"aligncenter size-full wp-image-27317\" \/><\/p>\n<p>Only one of these check boxes should be checked, and if we are creating the app package then we must ensure that our P12 Certificate and Provisioning Profile are installed on the machine or are temporarily installed on the machine. There are a few ways to accomplish this:<\/p>\n<ol>\n<li>If using MacinCloud, simply follow the configuration steps <a href=\"https:\/\/blogs.msdn.microsoft.com\/visualstudioalm\/2015\/11\/18\/macincloud-visual-studio-team-services-build-and-improvements-to-ios-build-support\/\">here<\/a>.<\/li>\n<li>For on-premise, we could simply use a machine that has the P12 Cert and Provisioning Profiles installed and there is nothing else to configure.<\/li>\n<li>Specify the <strong>Certificate<\/strong> and <strong>Profile<\/strong> locations in the <b>Signing &amp; Provisioning<\/b> section<\/li>\n<\/ol>\n<p>I went for the latter option, as I&#8217;m using a build machine that doesn&#8217;t have anything installed on it yet. I have exported my P12 Certificate and downloaded the Provisioning Profile for my app <a href=\"https:\/\/www.visualstudio.com\/en-us\/docs\/build\/apps\/mobile\/secure-certs\">following these directions<\/a>. We&#8217;ll store it in secure blob storage and use the command line build step to download it with a <b>curl<\/b> command much like we did for the keystore in the Android build. Since we have the actual machine we are building on, we can simply copy and paste them into the root directory from where the VSTS Agent was extracted and running from. Here are my settings:<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/44\/2019\/03\/Signing_Settings1.png\" alt=\"Signing_Settings\" width=\"1726\" height=\"453\" class=\"aligncenter size-full wp-image-27322\" \/><\/p>\n<p>Ensure that you specify the <strong>P12 Password<\/strong> and have it encrypted in the <strong>Variables<\/strong> tab.<\/p>\n<h3>Copy and Publish Artifacts<\/h3>\n<p>Before we can run, we want to make sure we can capture all of the artifacts we need to deploy to testers. Let&#8217;s add two more steps: the <strong>Copy File<\/strong> step and then the <strong>Publish Artifacts<\/strong> step.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/44\/2019\/03\/CopyandPublish.png\" alt=\"CopyandPublish\" width=\"500\" class=\"aligncenter size-full wp-image-27326\" \/><\/p>\n<h4>Copy Files<\/h4>\n<p>We know that all of the build artifacts that we want will be in our bin\/iPhone\/$(BuildConfiguration) folder and can then specify to find all of our .ipa and .dll files by using the following:<\/p>\n<p><b>**\/*.ipa\n**\/*.dll<\/b><\/p>\n<p>Then we can copy them to the built in staging directory with <b>$(Build.ArtifactStagingDirectory)<\/b> (<a href=\"https:\/\/www.visualstudio.com\/docs\/build\/define\/variables\">a predefined variable<\/a>).<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/44\/2019\/03\/CopyFiles.png\" alt=\"CopyFiles\" width=\"400\" class=\"aligncenter size-full wp-image-27329\" \/><\/p>\n<p>Finally, we can publish the artifacts so they can be used during release management by specifying the same staging directory and the name of the artifact to create.\n<img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/44\/2019\/03\/Artifacts.png\" alt=\"Artifacts\" width=\"400\" class=\"aligncenter size-full wp-image-27330\" \/><\/p>\n<h2>Queue a New Build<\/h2>\n<p>It&#8217;s now time to queue our very first build. This will pull down all of the sources, attempt to build the app, sign it, and publish the artifacts. We should see a full build readout that will tell us if anything has gone wrong or if a file can&#8217;t be found for signing. Once complete, we can tap on the build and explore all of the artifacts that are ready for publishing.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/44\/2019\/03\/SuccessfulDrop.png\" alt=\"SuccessfulDrop\" width=\"600\" class=\"aligncenter size-full wp-image-27331\" \/><\/p>\n<h2>Deploy to Testers with HockeyApp<\/h2>\n<p><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/44\/2019\/03\/hockeyapp-1.png\" alt=\"hockeyapp (1)\" width=\"100\" class=\"alignleft size-full wp-image-27332\" \/>To go one step further, we can get the app into our testers hands by deploying to HockeyApp. In the last post we saw how to add in the free <a href=\"https:\/\/marketplace.visualstudio.com\/items?itemName=ms.hockeyapp\">HockeyApp VSTS Extension<\/a> from the marketplace, which adds a new HockeyApp step into VSTS. This enables us to configure a new HockeyApp connection and specify the .ipa file to publish after the build is successful.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/44\/2019\/03\/HockeyApp.png\" alt=\"HockeyApp\" width=\"600\" class=\"aligncenter size-full wp-image-27333\" \/><\/p>\n<h2>Learn More<\/h2>\n<p>Just like that, we now have our iOS and Android applications building in Visual Studio Team Services completely signed and shipped to our testers utilizing HockeyApp. For further details on VSTS and Xamarin, be sure to read through the <a href=\"https:\/\/www.visualstudio.com\/en-us\/docs\/build\/apps\/mobile\/xamarin\">full documentation<\/a> on setting up Xamarin projects. Then take it a step further and send your app along with test scripts up to the Xamarin Test Cloud in <a href=\"https:\/\/www.visualstudio.com\/en-us\/docs\/build\/steps\/test\/xamarin-test-cloud\">one simple step<\/a>.  <\/p>\n<p>Looking for more? Checkout <a href=\"http:\/\/aka.ms\/XamarinShow\">The Xamarin Show<\/a> on Channel 9:<\/p>\n<p><iframe src=\"https:\/\/channel9.msdn.com\/Shows\/XamarinShow\/Continuous-Integration-with-Simina-Pasat\/player\" width=\"640\" height=\"360\" allowFullScreen frameBorder=\"0\"><\/iframe><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Visual Studio Team Services (VSTS) delivers services for teams to share code, track work, and ship software, including all of their mobile applications built with Xamarin. In the first post in this series, we automated a Xamarin.Android app in VSTS. We created our account, connected to our GitHub account, built and signed the app, and [&hellip;]<\/p>\n","protected":false},"author":544,"featured_media":39167,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[2],"tags":[6,4],"class_list":["post-27298","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-developers","tag-ios","tag-xamarin-platform"],"acf":[],"blog_post_summary":"<p>Visual Studio Team Services (VSTS) delivers services for teams to share code, track work, and ship software, including all of their mobile applications built with Xamarin. In the first post in this series, we automated a Xamarin.Android app in VSTS. We created our account, connected to our GitHub account, built and signed the app, and [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/wp\/v2\/posts\/27298","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/wp\/v2\/users\/544"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/wp\/v2\/comments?post=27298"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/wp\/v2\/posts\/27298\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/wp\/v2\/media\/39167"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/wp\/v2\/media?parent=27298"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/wp\/v2\/categories?post=27298"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/wp\/v2\/tags?post=27298"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}