Using Azure Dev Ops? Ever wondered how to publish an Xcode Archive with Xamarin iOS rather then just an IPA? If that’s the case then this short guide should help you on your way to automation glory.
Step 1- Configuring the Xamarin.iOS task to generate an archive
The first thing you’ll need is a Xamarin iOS build task pointing to your solution file. Once you’ve got your solution building and generating an ipa file, you will need to customise this build step further. The following link documents the process towards customising your build command to generate an archive, but let’s break it down for simplicity.
msbuild /p:Configuration=Release /p:ServerAddress=10.211.55.2 /p:ServerUser=xamUser /p:Platform=iPhone /p:ArchiveOnBuild=true /t:"Build" MyProject.csproj
You can happily ignore all parameters except for two, these being:
- ArchiveOnBuild which is the main boolean telling the Microsoft Build (MSBuild) system whether to actually produce the archive or not.
- “Build” which according to this Xamarin Forms post will run the build target. Apparently the ArchiveOnBuild command has some dependencies on that target running, so it’s mandatory to include it as an extra command.
Putting this into practice, below is a screenshot and the associated YAML for a Xamarin iOS Build task that will output an archive. You may notice that I’ve made the ArchiveOnBuild parameter defined by a user variable. This is done as I don’t need to produce an archive all the time, and it can add a few minutes to the build time. If your not publishing to the app store anytime soon, it’s worth making it configurable for only when you need it.
- task: XamariniOS@2
args: '/p:ArchiveOnBuild=true /t:"Build"'
Step 2 - Copying the XCode Archive from the archive directory into the artefacts folder
Now that you’ve got an XCode Archive being generated by the build machine. It’s time to copy it into your artefacts folder so that you can actually make use of it. To do this you’ll need to add a bash task directly after your Xamarin iOS build task, below is the YAML for the bash task.
- bash: |
if [ -d "$HOME/Library/Developer/Xcode/Archives" ]; then
echo "Xcode archive directory exists on this build agent, moving all the contents to the artefacts folder"
cp -R $HOME/Library/Developer/Xcode/Archives/. $BUILD_ARTIFACTSTAGINGDIRECTORY
displayName: 'Check Xcode Archive exists and copy'
Here is a break down of what this bash script does:
- First we check if the archive directory actually exists on the build agent. According to the documentation, “$HOME/Library/Developer/Xcode/Archives” is the output directory for the XCode archives. This step is beneficial since it won’t try to copy anything if you haven’t made an archive.
- Given the solution built with our custom MSBuild parameters, this folder will exist. So we print out what we’re doing, and then recursively copy the entire directory to our artefacts staging directory. An important thing to note is that since the build servers in the cloud do not maintain any files there will only be one archive in this directory. If you have a self hosted build agent, it would be a good idea to do some cleanup after this, so that the archive files get deleted after each run.
Step 3 - Publish the Artefacts and then check the folder
Finally you’ll need one more task to publish the artefacts, below is a screenshot for that task.
The order of the tasks should look like the screenshot below.
Finally run the build. If you’ve followed the steps above then you should have an artefact as the output and it should look similar to the screenshot below.
Et voilà, you just published an XCode Archive with Azure Dev Ops. You’ll notice from the screenshot above that two archives are produced. This seems to be a bug in the Microsoft Build system that is currently unresolved.