Xamarin DevOps with VSTS - Setup iOS CI Builds With MacinCloud

This post shows how to setup Visual Studio Team Services to build a Xamarin iOS application using a MacinCloud VSTS Build Agent.

It builds upon the VSTS Team Project created in the getting started post.

I updated the Key Points section on the 2nd June 2016 to add advice when using Agent Pools other than the Default and clarification of the VSTS local Build Agent links.

Resources

Key Points

Pool Name: This must match your VSTS pool name. If you have not created a pool in VSTS, Please leave the "default" setting alone. If you did create a pool, or wish to join the agent to an existing pool, please make sure you completed Step #3 above. Notice that the "pool name" cannot be set to "hosted", as the "hosted" pool is reserved for Microsoft Hosted Agents.

  • You can set multiple MacinCloud Build Agents to use the same Agent Pool and as such can then run multiple iOS project builds at the same time.

  • You must be using the Stable update channel for these Hosted CI builds to work. I was initially using Xamarin Studio 6.1 from the Alpha Channel and the Android builds were failing so I reverted back to the Stable channel and they worked fine. This is to be expected, but worth noting none the less.

Create Xamarin.iOS Continuous Integration Build

The iOS build requires Apple hardware, if using your own Mac then refer to these links for setup instructions, basically installing a Build Agent on your Mac:-

The next steps detail how to setup the MacinCloud Visual Studio Team Services Build Agent Plan. Note that the steps found in some other posts on the internet are now out of date and there is no requirement to contact either MacinCloud or Xamarin support in order to setup the Xamarin licence on the MacinCloud Build Agent.

One thing you will need is a credit/debit card or PayPal, the Build Agent is available for a 48 hour trial for $0.99, $29 per month thereafter. After signing up to the VSTS Build Agent Plan create a MacinCloud account and login. Click on the ‘VSO/VSTS Agent’ entry under the Developer section. The available build agents will be displayed, the screenshot below shows one already configured:-

Click on the ‘Edit Agent’ button to the left of the ‘Access Token’ column. The Edit VSTS Agent dialog is shown, provide an Agent Name and enter the VSTS site Url in this example ‘thexamarinjournal’. :-

Now we need to generate a Microsoft Access Token and add the user to the Agent Pool roles. This is done back in VSTS, I found step 3 of the post MacinCloud Visual Studio Team Services Build and Improvements to iOS Build Support contained instructions for doing this.

In VSTS click on settings cog in the top right and the Control Panel will be displayed:-

Select the ‘Agent pools’ tab and then select the ‘All Pools’ entry:-

Now add your user to both the ‘Agent Pool Administrators’ and ‘Agent Pool Service Accounts’ roles. Select the ‘Agent Pool Administrators’ entry and click the ‘Add’ button. The ‘Add users and groups’ dialog is displayed:-

Enter the user in this case ‘thexamarinjournal’ and then click the ‘Save changes’ button:-

Select the ‘Agent Pool Service Accounts’ entry and repeat the previous steps to add the user.

Now we can create the Personal Access Token. Go back to the previous tab and click on the user name ‘thexamarinjournal’ in the top right and select the ‘My Profile’ entry:-

Click on the ‘Security’ tab and the ‘Personal access tokens’ list will be displayed. This should be empty, in my case using the Git Credential Manager has already created a personal access token, I won’t cover that in this post:-

Click the ‘Add’ button and the ‘Create a personal access token’ page is displayed:-

Next enter a description and set the ‘Expires in to the ‘1 year’ option. The ‘All scopes’ option should be checked.

Click the ‘Create Token’ button. The token will now be displayed with a message warning that it’s only available this one time so copy it.

Return to the MacInCloud ‘Edit VSTS Agent’ and paste the token. Note that in this instance with have left the Pool Name as ‘default’ but we might be better to rename it to something more obviously related to the iOS build:-

Click the ‘Save button:-

Certificates

The iOS Distribution and Development certificates can be downloaded from the Apple Developer Portal. Sign in.

Click on the ‘Certificates, Identifiers & Profiles’ link.

Click on the iOS Distribution entry and then click on the ‘Download’ button.

Next click on the iOS Development entry and then click on the ‘Download’ button.

Once downloaded double click on the iOS development certificate file (named ios_development.cer for example).

An ‘Add Certificates’ dialog will be displayed.

Click the ‘Add’ button to add the certificate into the KeyChain.

Next copy the Provisioning Profile file we just downloaded to the ‘HelloDevOps’ directory alongside the solution file.
Now we need to create a .P12 file from the iOS Development Certificate. To do this we can use KeyChain Access so start this from Spotlight or similar and click on the ‘My Certificates’ entry:-

Next expand the iPhone Developer entry so we can see the private key also. Use a Shift select to select both items and right click:-

Now select the ‘Export 2 items…’ option and save the .P12 file to the ‘HelloDevOps’ directory alongside the solution file..

Now we can go back to the MacinCloud portal and click on the button with the cloud icon (tooltip ‘Upload .P12 and Prov. Profile’):-

Now select the .P12 certificate file and the Provisioning Profile file enter the .P12 file password and click the ‘Save’ button.

The MacinCloud VSTS Build Agent is now setup.

Setup For Building the iOS Solution

The VSTS Xamarin.iOS build step builds an entire solution. In this instance the MacinCloud VSTS Build Agent won't be installed with Xamarin.Android so we need to make sure that we only try to build iOS/Shared Projects/PCL projects.

One option is to create new project configurations, this is detailed in the section 'Configure the solution for iOS Release' in Build your Xamarin app.

Another option is to create a new solution which will only contain the iOS projects and this is detailed below.

Open Xamarin Studio and create a new Blank Solution:-

Set the configuration to be the XamarinDevOps directory:-

Now close the solution in Xamarin Studio and move the solution file to sit up a directory alongside the existing solution. Delete the newly created ‘HelloDevOps.iOs’ directory.

Open the HelloDevOps.iOs solution and add the iOS and Shared Project. At the Terminal change to the ‘HelloDevOps’ directory and execute the command

git add HelloDevOps.iOS.sln

Next add the certificate files to the repository so that we can reference them in the iOS Build Definition in VSTS using the commands

git add Certificates.p12
git add Richard_Woollcott-3.mobileprovision

Now use the git command line or Xamarin Studio to commit the changes and push them back to the VSTS Remote.

In VSTS navigate to the Build page and click the ‘+’ button to create a new build definition for iOS:-

The ‘Create new build definition’ dialog is displayed. Double click the ‘Xamarin.iOS’ entry, and the settings page of the dialog is shown:-

Next check the ‘continuous integration’ option and change the ‘Default agent queue’ selection from ‘Hosted’ to ‘Default’.

Click the ‘Create’ button.

Select the 'Xamarin.iOS build step:-

To the right of the Solution field use the '...' button to browse to the iOS specific solution.

This post is focussing on getting the iOS app built, so we will not need the 'Xamarin Test Cloud' build step. We could delete it or just disable it later if we intend to setup UI tests later. Disable the ‘Xamarin Test Cloud’ build step by unchecking the ‘Enabled’ option in the ‘Control Options’ panel.

Click the 'OK button.

Next delete the build steps ‘Activate Xamarin license’ and ‘Deactivate Xamarin license’

Now select the build step ‘Build Xamarin.iOS solution HelloDevOps.iOS.sln’

Press the ‘…’ browse button to the right of the ‘P12 Certificate File’ textbox. The ’Select Path’ dialog is displayed:-

Select the ‘Certificates.P12’ file and click the ‘OK’ button.

Repeat this for the Provisioning Profile file:-

Next we want to add the P12 Certificate file password using a Secret variable to protect the password. Select the ‘Variables’ tab. Click the ‘+’ button to add a variable. Enter a name such as ‘p12password’ and the password itself. Now click the button with the padlock icon to hide the password and check the ‘Allow at Queue Time’ option.

Now select the ‘Build’ tab. Enter the variable we just created to the ‘P12 Password’, in this case ‘$(p12password):-

Click the ‘Save’ button and give the build a name:-

It's probably also worth adding a build step to restore the NuGet packages as most apps will be using NuGet packages. Click the '+ Add build step...' button. The 'Add tasks' dialog is displayed. Select the 'Package' category and then click the ‘Add’ button on the ‘NuGet Installer’ item:-

Drag the 'NuGet Installer' build step to the top of the list. The default values for the fields are fine.

Queue the build and it confirm that the ‘Queue’ option is set to ‘Default’:-

Click the ‘OK’ button and the build should be queued and the build output displayed:-

Publish The Build Artifacts

Now that the build is running ok we will need to copy and publish the build artifacts. I found the Microsoft documentation Build your Xamarin app useful.

Edit the Build Definition by clicking on the build name and then the ‘Edit’ button. Now click the ‘Add build step…’ button. The ‘Add tasks’ dialog is displayed. Select the ‘Utility’ category and then click the ‘Add’ button on the ‘Copy Files’ item. Click the 'Close' button:-

Edit the Contents field to add
**/bin/**/*.dll **/*.ipa

Next set the ‘Target Folder’ value to $(Build.ArtifactStagingDirectory).

Expand the 'Advanced' section and check the 'Clean Target Folder' option.

Edit the Build Definition by clicking on the build name and then the ‘Edit’ button. Now click the ‘Add build step…’ button. The ‘Add tasks’ dialog is displayed. Select the ‘Utility’ category and then click the ‘Add’ button on the ‘Publish Build Artifacts’ item. Click the 'Close' button:-

Edit the ‘Path to Publish’ field to $(Build.ArtifactStagingDirectory)

Edit the ‘Artifact Name’ field to drop

Edit the Artifact Type to Server.

The build results page should now have an ‘Artifacts’ tab which allows for the downloading of the build artifacts.

Click on the 'Download' link to download the zip file.

Using Finder we can open the zip folder and see that there is an .ipa file in the iOS\bin\Release folder.

Install The App On An iPhone

We can now install the application created by the CI build onto a device using iTunes.

Ensure a device is connected and start iTunes. Click on the iPhone icon and then select the Apps category.

Next Select the ‘Add to Library..’ option on the ‘File’ menu and select the .ipa file.

Click the 'Open' button:-

The HelloDevOps app is now listed in the Apps table:-

Click the ‘Install’ button on the HelloDevOps entry to install the app. The button text changes from 'Install' to 'Will Install'. And the 'Sync' button changes to 'Apply':-

Click the 'Apply' button to install the app onto the iPhone. The HelloDevOps is now installed on the iPhone and the entry in the iTunes Apps table has a 'Remove' button:-

This should complete getting the iOS app setup for basic Continuous Integration builds in VSTS.

Adding a versioning build step, unit test and UI tests would be the obvious next steps to complete the Continuous Integration Builds before starting Continuous Deployment using HockeyApp.

Richard Woollcott

Read more posts by this author.

Taunton, United Kingdom