Xamarin Automatic Build Generation for Deployment
Xamarin lets you deliver native Android, iOS, and Windows apps with a single shared .NET code base.
Xamarin tools are available to download with Visual Studio and you can directly create Android, iOS and Windows apps from Visual Studio itself. Most of the common code is written in C#. So you don’t need to be well versed in Java, Objective‐C or Swift to build apps if you already know C#. If you are a beginner, then taking the Xamarin path instead of the conventional learning process can actually teach you app development for more than one platforms. But will you miss out on real native functionality?
The answer to that question is mostly No. The great set of features provided by the entire toolset makes sure you don’t miss out on any functionality. But at some point, where you might want to dive deeper, Xamarin lets you call existing code written in other platform-specific languages such as Java in Android. But that is only when you are building something very specific which cannot be implemented on different platforms.
The below blog explains the process used for the following purposes
- Generate .APK file for Android through a Batch file
- Generate .IPA file for iOS through a Batch file
- Upload .APK file and .IPA file to Hockey App through Batch file.
Pre‐Requisites
- iOS distribution certificate and mobile provisioning file installed in Mac System
- Android signing certificate in project folder
- Xamarin Native or Forms Android and the iOS project developed through Visual Studio 2017
-
GenerateAPK.sh
- Create Folder GenerateBuildsFile in your project folder
- Create a new .sh extension file with “GenerateAPK.sh” name
- Copy the below script into your .sh file
#!/bin/bash cd .. # Change the Path to the Solution Project folder SLNPath=$PWD"/" # echo $SLNPath MyPath=$SLNPath"Droid/" cd $MyPath AssemblyInfoPath=$MyPath"Properties/AssemblyInfo.cs" echo $AssemblyInfoPath # /p:AssemblyPath=AssemblyInfoPath VersionNumber=$1 BuildNumber=$2 # Build the Project in release mode MSBuild /t:Clean /p:Configuration=Release MSBuild /t:SignAndroidPackage /p:Configuration=Release /p:SetVersion=True /p:VersionNumber=$Versio # Path to the Generated Signed APK file SignedAPKPath=$MyPath"bin/Release/*Signed. apk" echo $SignedAPKPath #Make a new directory for Saving the builds mkdir $SLNPath"Builds" # New Path to save the Builds NewPath=$SLNPath"Builds" echo $NewPath mv $SignedAPKPath $NewPath"/<AppName>.apk"
- This File takes the parameters for Version Number and Build Number from the file and uses MS Build process to clean, build and generate the .apk file
- Replace “AppName” text with your project name in the file
- Open the project in Visual Studio 2017 and open properties for Xamarin.Droid project, browse and select the correct keystore file in Android Build Signing properties for release mode
- Add these lines of code in .Droid.csproj file inside Project Tag, this code uses the version number and build number dynamically
<Target Name="BeforeBuild" Condition=" $(SetVersion) == true ">
<XmlPoke XmlInputPath="Properties\AndroidManifest.xml"
Namespaces="<Namespace Prefix='android'
Uri='http://schemas.android.com/apk/res/android' />"
Query="manifest/@android:versionCode" Value="$(BuildNumber)" />
<XmlPoke XmlInputPath="Properties\AndroidManifest.xml"
Namespaces="<Namespace Prefix='android'
Uri='http://schemas.android.com/apk/res/android' />"
Query="manifest/@android:versionName" Value="$(VersionNumber)" />
</Target>
-
GenerateIPA.sh
- Create a new .sh extension file with “GenerateIPA.sh” name, Copy the below content to your sh file
#!/bin/bash cd .. # Change the Path to the Solution Project folder SLNPath=$PWD"/" echo $SLNPath # New Path to save the Builds NewPath=$SLNPath"Builds" echo $NewPath cd .. SLNPath=$PWD"/" echo $SLNPath # Navigate to the main SLN Folder cd $SLNPath VersionNumber=$1 BuildNumber=$2 # Build the Project in release mode MSBuild /p:Configuration="Release" /p:Platform="iPhone" /p:IpaPackageDir="$NewPath” /t:Clean <ProjectName>.sln MSBuild /p:Configuration= "Release" /p:Platform="iPhone" /p:SetVersion=True /p:VersionNumber=$VersionNumber /p:BuildNumber=$BuildNumber /p:IpaPackageDir="$NewPath" /t:Build <ProjectName>.sln
- This File takes the parameters for Version Number and Build Number from the file and uses MS Build process to clean, build and generate the .ipa file
- Replace “ProjectName” text with your project name
- Open your project in Visual Studio 2017, open properties for Xamarin.iOS project and select the Signing Certificate and Provisioning file in iOS Build Signing properties for release mode
- Add these lines of code in .iOS.csproj file inside Project Tag, this code uses the version number and build number dynamically:
<Target Name="BeforeBuild" Condition=" $(SetVersion) == true ">
<XmlPoke XmlInputPath="Info.plist" Query="//dict/key[. = 'CFBundleVersion']/followingsibling::s
<XmlPoke XmlInputPath="Info.plist" Query="//dict/key[. = 'CFBundleShortVersionString']/following
</Target>
- Create a new .sh extension file with “GenerateIPA.sh” name, Copy the below content to your sh file
-
UploadFile.sh File
This file contains script to upload the .apk files and .ipa file to HockeyApp with the Hockey App Token provided in BuildsScript File.
- Create a new .sh extension file with “UploadFile.sh” name. Copy the below script contents to your sh file
#!/bin/bash # locations of various tools CURL=curl SERVER_ENDPOINT=https://rink.hockeyapp.net/api/2/ # Put your HockeyApp APP_TOKEN here. Find it in your HockeyApp account settings. APP_TOKEN=$1 # ipa required, file data of the .ipa for iOS, .app.zip for OS X, or .apk file for Android IPA=$2 # dsym optional, file data of the .dSYM.zip file (iOS and OS X) or mapping.txt (Android); # note that the extension has to be .dsym.zip (caseinsensitive) for iOS and OS X and the file nam DSYM="" # notes optional, release notes as Textile or Markdown (after 5k characters note are truncated) NOTES=$3 # echo $NOTES # notes_type optional, type of release notes: # 0 for Textile # 1 for Markdown NOTES_TYPE="0" # optional, notify testers (can only be set with fullaccess tokens): # 0 to not notify testers # 1 to notify all testers that can install this app # 2 Notify all testers NOTIFY=$4 echo $NOTIFY # status optional, download status (can only be set with fullaccess tokens): # 1 to not allow users to download the version # 2 to make the version available for download STATUS="2" # strategy optional, replace or add build with same build number # add to add the build as a new build to even if it has the same build number (default) # replace to replace to a build with the same build number STRATEGY="replace" # tags optional, restrict download to commaseparated list of tags TAGS="" # teams optional, restrict download to commaseparated list of team IDs; example: # 12,23,42 with 12, 23, and 42 being the database IDs of your teams TEAMS="" # users optional, restrict download to commaseparated list of user IDs; example: # 1224,5678 with 1224 and 5678 being the database IDs of your users USERS="" # mandatory optional, set version as mandatory: # 0 for not mandatory # 1 for mandatory MANDATORY="" # release_type optional, set the release type of the app: # 2 for alpha # 0 for beta [default] # 1 for store # 3 for enterprise RELEASE_TYPE="" # private optional, set to true to enable the private download page (default is true) PRIVATE="" # owner_id optional, set to the ID of your organization OWNER_ID="" # commit_sha optional, set to the git commit sha for this build COMMIT_SHA="" # build_server_url optional, set to the URL of the build job on your build server BUILD_SERVER_URL="" # repository_url optional, set to your source repository REPOSITORY_URL="" usage() { echo "Usage: hockeyappuploader. sh IPA" echo } verify_tools() { # Windows users: this script requires curl. If not installed please get from http://cygwin # Check 'curl' tool "${CURL}" help >/dev/null if [ $? ne 0 ]; then echo "Could not run curl tool, please check settings" exit 1 fi } verify_settings() { if [ z "${APP_TOKEN}" ]; then usage echo "Please update APP_TOKEN with your private API key, as noted in the Settings exit 1 fi } # if [ $# ne 1 ]; then # usage # exit 1 # fi # before even going on, make sure all tools work verify_tools verify_settings if [ ! f "${IPA}" ]; then usage echo "Can't find file: ${IPA}" exit 2 fi /bin/echo n "Uploading ${IPA} to HockeyApp.. " JSON=$( "${CURL}" \ s ${SERVER_ENDPOINT}/apps/upload \ H "XHockeyAppToken: ${APP_TOKEN}" \ F "ipa=@${IPA}" \ F "dsym=@${DSYM}" \ F "notes=${NOTES}" \ F "notes_type=${NOTES_TYPE}" \ F "notify=${NOTIFY}" \ F "status=${STATUS}" \ F "strategy=${STRATEGY}" \ F "tags=${TAGS}" \ F "teams=${TEAMS}" \ F "users=${USERS}" \ F "mandatory=${MANDATORY}" \ F "release_type=${RELEASE_TYPE}" \ F "private=${PRIVATE}" \ F "owner_id=${OWNER_ID}" \ F "commit_sha=${COMMIT_SHA}" \ F "build_server_url=${BUILD_SERVER_URL}" \ F "repository_url=${REPOSITORY_URL}" \ ) URL=$( echo ${JSON} | sed 's/\\\//\//g' | sed n 's/.*"public_url"\s*:\s*"\([^"]*\)".*/\1/p' ) if [ z "$URL" ]; then echo "FAILED!" echo echo "Build uploaded, but no reply from server. Please contact support@hockeyapp.net" exit 1 fi echo "OK!" echo echo "Build was successfully uploaded to HockeyApp and is available at:" echo ${URL}
- Replace “<ProjectName>” text with your project name
- Create a new .sh extension file with “UploadFile.sh” name. Copy the below script contents to your sh file
-
BuildsScript.sh File
This file internally uses GenerateAPK.sh, GenerateIPA.sh, UploadFile.sh scripts to Generate and upload .apk and .ipa files to HockeyApp. Follow these steps to build the BuildScript.sh File:
- Create a new .sh extension file with “BuildsScript.sh” name, Copy the below content to your BuildsScript.sh
#!/bin/bash VersionNumber="1.0.0" BuildNumber="7" # notes optional, release notes as Textile or Markdown (after 5k characters note are truncated) NOTES=" Fixed Issue and changed Issues related to COff Debit Fixed " Platform=$1 ReleaseAndroid=false ReleaseiOS=false if [ z "${Platform}" ]; then ReleaseAndroid=true ReleaseiOS=true fi if [ "$Platform" = "android" ] ; then ReleaseAndroid=true ReleaseiOS=false fi if [ "$Platform" = "ios" ] ; then ReleaseAndroid=false ReleaseiOS=true fi # Put your HockeyApp APP_TOKEN here. Find it in your HockeyApp account settings. APP_TOKEN="" chmod 777 GenerateAPK.sh chmod 777 GenerateIPA.sh chmod 777 UploadFile.sh cd .. # Change the Path to the Solution Project folder SLNPath=$PWD"/" echo $SLNPath cd GenerateBuildsFile # Generate Android APK File if [ "$ReleaseAndroid" = true ] ; then echo 'Generation APK file' ./GenerateAPK.sh $VersionNumber $BuildNumber fi #Generate IOS IPA File if [ "$ReleaseiOS" = true ] ; then echo 'Generation IPA file' ./GenerateIPA.sh $VersionNumber $BuildNumber fi # New Path to save the Builds NewPath=$SLNPath"Builds" # echo $NewPath BuildsPath=$SLNPath"GenerateBuildsFile" # echo $BuildsPath cd $BuildsPath # optional, notify testers (can only be set with fullaccess tokens): # 0 to not notify testers # 1 to notify all testers that can install this app # 2 Notify all testers NOTIFY="2" # Path to the APK File # ipa required, file data of the .ipa for iOS, .app.zip for OS X, or .apk file for Android IPA=$NewPath"/.apk" # echo $IPA #Upload the Android APK file to Hockey APP if [ "$ReleaseAndroid" = true ] ; then echo 'Uploading APK file' ./UploadFile.sh $APP_TOKEN $IPA "$NOTES" $NOTIFY fi # Path to the IPA File # ipa required, file data of the .ipa for iOS, .app.zip for OS X, or .apk file for Android IPA=$NewPath"/.iOS.ipa" # echo $IPA #Upload the IOS file to Hockey APP if [ "$ReleaseiOS" = true ] ; then echo 'Uploading IPA file' ./UploadFile.sh $APP_TOKEN $IPA "$NOTES" $NOTIFY fi
- Replace “<ProjectName>” text with your project name
- Modify these properties in BuildsScript.sh file
- VersionNumber as your required version number (1.0.0)
- BuildNumber as your required build number (7)
- Notes as your release notes text
- APP_TOKEN ‐ Put your HockeyApp APP_TOKEN here. Find it in your HockeyApp account settings
- Bundle Identifier for Android and iOS project must match with the HockeyApp app identifier
- Create a new .sh extension file with “BuildsScript.sh” name, Copy the below content to your BuildsScript.sh
-
Usage
In order to generate and upload the builds to HockeyApp, follow these steps:
- Open Terminal in your Mac
- Navigate to your Project Folder → GenerateBuilds by running this command:
cd /
//GenerateBuildsFile - To Generate and Upload Android .apk file to HockeyApp, Run this command:
/BuildsScript.sh android
- To Generate and Upload iOS .ipa file to HockeyApp, Run this command:
./BuildsScript.sh ios
- To Generate and Upload Android .apk file and iOS .ipa file to HockeyApp, Run this command:
./BuildsScript.sh